mirror of
https://github.com/nzp-team/fteqw.git
synced 2024-11-23 04:11:53 +00:00
added env_cubemap support. doesn't currently render its own cubemaps yet.
git-svn-id: https://svn.code.sf.net/p/fteqw/code/trunk@5277 fc73d0e0-1445-4013-8a0c-d673dee63da5
This commit is contained in:
parent
bb68e5c5cd
commit
8b03acacbe
13 changed files with 649 additions and 50 deletions
|
@ -2641,7 +2641,7 @@ static void SCR_ScreenShot_f (void)
|
||||||
Con_Printf (CON_ERROR "Couldn't write %s\n", sysname);
|
Con_Printf (CON_ERROR "Couldn't write %s\n", sysname);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void *SCR_ScreenShot_Capture(int fbwidth, int fbheight, int *stride, enum uploadfmt *fmt)
|
void *SCR_ScreenShot_Capture(int fbwidth, int fbheight, int *stride, enum uploadfmt *fmt)
|
||||||
{
|
{
|
||||||
int width, height;
|
int width, height;
|
||||||
void *buf;
|
void *buf;
|
||||||
|
@ -2997,7 +2997,7 @@ void SCR_ScreenShot_Cubemap_f(void)
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
firstside = strcmp(Cmd_Argv(0), "envmap")?0:6;
|
firstside = (!strcmp(Cmd_Argv(0), "envmap"))?6:0;
|
||||||
|
|
||||||
r_refdef.stereomethod = STEREO_OFF;
|
r_refdef.stereomethod = STEREO_OFF;
|
||||||
Q_strncpyz(olddrawviewmodel, r_drawviewmodel.string, sizeof(olddrawviewmodel));
|
Q_strncpyz(olddrawviewmodel, r_drawviewmodel.string, sizeof(olddrawviewmodel));
|
||||||
|
|
|
@ -1002,6 +1002,15 @@ void FPS_Preset_f (void)
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!stricmp("hdr", arg))
|
||||||
|
{
|
||||||
|
Cbuf_InsertText(
|
||||||
|
"set vid_srgb 2\n"
|
||||||
|
"set r_hdr_irisadaptation 1\n"
|
||||||
|
, RESTRICT_LOCAL, false);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
if (!stricmp("tenebrae", arg))
|
if (!stricmp("tenebrae", arg))
|
||||||
{ //for the luls. combine with the tenebrae mod for maximum effect.
|
{ //for the luls. combine with the tenebrae mod for maximum effect.
|
||||||
Cbuf_InsertText(
|
Cbuf_InsertText(
|
||||||
|
|
|
@ -517,7 +517,8 @@ typedef struct
|
||||||
unsigned char *styles;
|
unsigned char *styles;
|
||||||
unsigned char *shifts;
|
unsigned char *shifts;
|
||||||
} lightmapoverrides_t;
|
} lightmapoverrides_t;
|
||||||
void Mod_LoadLighting (struct model_s *loadmodel, qbyte *mod_base, lump_t *l, qboolean interleaveddeluxe, lightmapoverrides_t *overrides);
|
typedef struct bspx_header_s bspx_header_t;
|
||||||
|
void Mod_LoadLighting (struct model_s *loadmodel, bspx_header_t *bspx, qbyte *mod_base, lump_t *l, qboolean interleaveddeluxe, lightmapoverrides_t *overrides);
|
||||||
|
|
||||||
struct mleaf_s *Mod_PointInLeaf (struct model_s *model, float *p);
|
struct mleaf_s *Mod_PointInLeaf (struct model_s *model, float *p);
|
||||||
|
|
||||||
|
|
|
@ -387,9 +387,9 @@ qbyte *Skin_Cache8 (qwskin_t *skin)
|
||||||
skin->width = 320;
|
skin->width = 320;
|
||||||
skin->height = 200;
|
skin->height = 200;
|
||||||
|
|
||||||
skin->skindata = out = BZ_Malloc(320*200);
|
skin->skindata = out = BZ_Malloc(skin->width*skin->height);
|
||||||
|
|
||||||
memset (out, bv, 320*200);
|
memset (out, bv, skin->width*skin->height);
|
||||||
|
|
||||||
skin->loadstate = SKIN_LOADED;
|
skin->loadstate = SKIN_LOADED;
|
||||||
|
|
||||||
|
|
|
@ -2733,7 +2733,7 @@ void Cmd_ExecuteString (const char *text, int level)
|
||||||
if (MP_ConsoleCommand(text))
|
if (MP_ConsoleCommand(text))
|
||||||
return; //let the csqc handle it if it wants.
|
return; //let the csqc handle it if it wants.
|
||||||
#endif
|
#endif
|
||||||
#if defined(MENU_NATIVECODE)
|
#if defined(MENU_NATIVECODE) && !defined(SERVERONLY)
|
||||||
if (mn_entry && mn_entry->ConsoleCommand(text, cmd_argc, (char const*const*)cmd_argv))
|
if (mn_entry && mn_entry->ConsoleCommand(text, cmd_argc, (char const*const*)cmd_argv))
|
||||||
return;
|
return;
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -2555,12 +2555,12 @@ static qboolean CModQ3_LoadFogs (model_t *mod, qbyte *mod_base, lump_t *l)
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
texid_t *Mod_CubemapForOrigin(model_t *wmodel, vec3_t org)
|
image_t *Mod_CubemapForOrigin(model_t *wmodel, vec3_t org)
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
menvmap_t *e;
|
menvmap_t *e;
|
||||||
float bestdist = FLT_MAX, dist;
|
float bestdist = FLT_MAX, dist;
|
||||||
texid_t *ret = NULL;
|
image_t *ret = NULL;
|
||||||
vec3_t move;
|
vec3_t move;
|
||||||
if (!wmodel || wmodel->loadstate != MLS_LOADED)
|
if (!wmodel || wmodel->loadstate != MLS_LOADED)
|
||||||
return NULL;
|
return NULL;
|
||||||
|
@ -2974,7 +2974,6 @@ static qboolean CModQ3_LoadRFaces (model_t *mod, qbyte *mod_base, lump_t *l)
|
||||||
out->fog = NULL;
|
out->fog = NULL;
|
||||||
else
|
else
|
||||||
out->fog = mod->fogs + LittleLong(in->fognum);
|
out->fog = mod->fogs + LittleLong(in->fognum);
|
||||||
|
|
||||||
if (prv->surfaces[LittleLong(in->shadernum)].c.flags & (Q3SURF_NODRAW | Q3SURF_SKIP))
|
if (prv->surfaces[LittleLong(in->shadernum)].c.flags & (Q3SURF_NODRAW | Q3SURF_SKIP))
|
||||||
{
|
{
|
||||||
out->mesh = &mesh[surfnum];
|
out->mesh = &mesh[surfnum];
|
||||||
|
@ -4017,6 +4016,7 @@ static cmodel_t *CM_LoadMap (model_t *mod, qbyte *filein, size_t filelen, qboole
|
||||||
model_t *wmod = mod;
|
model_t *wmod = mod;
|
||||||
char loadname[32];
|
char loadname[32];
|
||||||
qbyte *mod_base = (qbyte *)filein;
|
qbyte *mod_base = (qbyte *)filein;
|
||||||
|
bspx_header_t *bspx = NULL;
|
||||||
#ifdef Q3BSPS
|
#ifdef Q3BSPS
|
||||||
extern cvar_t gl_overbright;
|
extern cvar_t gl_overbright;
|
||||||
#endif
|
#endif
|
||||||
|
@ -4147,7 +4147,7 @@ static cmodel_t *CM_LoadMap (model_t *mod, qbyte *filein, size_t filelen, qboole
|
||||||
|
|
||||||
prv->faces = NULL;
|
prv->faces = NULL;
|
||||||
|
|
||||||
Q1BSPX_Setup(mod, mod_base, filelen, header.lumps, Q3LUMPS_TOTAL);
|
bspx = BSPX_Setup(mod, mod_base, filelen, header.lumps, Q3LUMPS_TOTAL);
|
||||||
|
|
||||||
//q3 maps have built in 4-fold overbright.
|
//q3 maps have built in 4-fold overbright.
|
||||||
//if we're not rendering with that, we need to brighten the lightmaps in order to keep the darker parts the same brightness. we loose the 2 upper bits. those bright areas become uniform and indistinct.
|
//if we're not rendering with that, we need to brighten the lightmaps in order to keep the darker parts the same brightness. we loose the 2 upper bits. those bright areas become uniform and indistinct.
|
||||||
|
@ -4440,6 +4440,8 @@ static cmodel_t *CM_LoadMap (model_t *mod, qbyte *filein, size_t filelen, qboole
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
BSPX_LoadEnvmaps(mod, bspx, mod_base);
|
||||||
|
|
||||||
if (map_autoopenportals.value)
|
if (map_autoopenportals.value)
|
||||||
memset (prv->portalopen, 1, sizeof(prv->portalopen)); //open them all. Used for progs that havn't got a clue.
|
memset (prv->portalopen, 1, sizeof(prv->portalopen)); //open them all. Used for progs that havn't got a clue.
|
||||||
else
|
else
|
||||||
|
|
|
@ -1362,7 +1362,7 @@ unsigned int Q1BSP_PointContents(model_t *model, vec3_t axis[3], vec3_t point)
|
||||||
return contents;
|
return contents;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Q1BSP_LoadBrushes(model_t *model)
|
void Q1BSP_LoadBrushes(model_t *model, bspx_header_t *bspx, void *mod_base)
|
||||||
{
|
{
|
||||||
struct {
|
struct {
|
||||||
unsigned int ver;
|
unsigned int ver;
|
||||||
|
@ -1395,7 +1395,7 @@ void Q1BSP_LoadBrushes(model_t *model)
|
||||||
|
|
||||||
model->engineflags &= ~MDLF_HASBRUSHES;
|
model->engineflags &= ~MDLF_HASBRUSHES;
|
||||||
|
|
||||||
permodel = Q1BSPX_FindLump("BRUSHLIST", &lumpsizeremaining);
|
permodel = BSPX_FindLump(bspx, mod_base, "BRUSHLIST", &lumpsizeremaining);
|
||||||
if (!permodel)
|
if (!permodel)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
@ -2183,17 +2183,15 @@ typedef struct {
|
||||||
int fileofs; // from file start
|
int fileofs; // from file start
|
||||||
int filelen;
|
int filelen;
|
||||||
} bspx_lump_t;
|
} bspx_lump_t;
|
||||||
typedef struct {
|
struct bspx_header_s {
|
||||||
char id[4]; // 'BSPX'
|
char id[4]; // 'BSPX'
|
||||||
int numlumps;
|
int numlumps;
|
||||||
bspx_lump_t lumps[1];
|
bspx_lump_t lumps[1];
|
||||||
} bspx_header_t;
|
};
|
||||||
static char *bspxbase;
|
|
||||||
static bspx_header_t *bspxheader;
|
|
||||||
//supported lumps:
|
//supported lumps:
|
||||||
//RGBLIGHTING (.lit)
|
//RGBLIGHTING (.lit)
|
||||||
//LIGHTINGDIR (.lux)
|
//LIGHTINGDIR (.lux)
|
||||||
void *Q1BSPX_FindLump(char *lumpname, int *lumpsize)
|
void *BSPX_FindLump(bspx_header_t *bspxheader, void *mod_base, char *lumpname, int *lumpsize)
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
*lumpsize = 0;
|
*lumpsize = 0;
|
||||||
|
@ -2205,28 +2203,25 @@ void *Q1BSPX_FindLump(char *lumpname, int *lumpsize)
|
||||||
if (!strncmp(bspxheader->lumps[i].lumpname, lumpname, 24))
|
if (!strncmp(bspxheader->lumps[i].lumpname, lumpname, 24))
|
||||||
{
|
{
|
||||||
*lumpsize = bspxheader->lumps[i].filelen;
|
*lumpsize = bspxheader->lumps[i].filelen;
|
||||||
return bspxbase + bspxheader->lumps[i].fileofs;
|
return (char*)mod_base + bspxheader->lumps[i].fileofs;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
void Q1BSPX_Setup(model_t *mod, char *filebase, unsigned int filelen, lump_t *lumps, int numlumps)
|
bspx_header_t *BSPX_Setup(model_t *mod, char *filebase, unsigned int filelen, lump_t *lumps, int numlumps)
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
int offs = 0;
|
int offs = 0;
|
||||||
bspx_header_t *h;
|
bspx_header_t *h;
|
||||||
|
|
||||||
bspxbase = filebase;
|
|
||||||
bspxheader = NULL;
|
|
||||||
|
|
||||||
for (i = 0; i < numlumps; i++, lumps++)
|
for (i = 0; i < numlumps; i++, lumps++)
|
||||||
{
|
{
|
||||||
if (offs < lumps->fileofs + lumps->filelen)
|
if (offs < lumps->fileofs + lumps->filelen)
|
||||||
offs = lumps->fileofs + lumps->filelen;
|
offs = lumps->fileofs + lumps->filelen;
|
||||||
}
|
}
|
||||||
offs = (offs + 3) & ~3;
|
offs = (offs + 3) & ~3;
|
||||||
if (offs + sizeof(*bspxheader) > filelen)
|
if (offs + sizeof(*h) > filelen)
|
||||||
return; /*no space for it*/
|
return NULL; /*no space for it*/
|
||||||
h = (bspx_header_t*)(filebase + offs);
|
h = (bspx_header_t*)(filebase + offs);
|
||||||
|
|
||||||
i = LittleLong(h->numlumps);
|
i = LittleLong(h->numlumps);
|
||||||
|
@ -2234,15 +2229,580 @@ void Q1BSPX_Setup(model_t *mod, char *filebase, unsigned int filelen, lump_t *lu
|
||||||
if (*(int*)h->id != (('B'<<0)|('S'<<8)|('P'<<16)|('X'<<24)) ||
|
if (*(int*)h->id != (('B'<<0)|('S'<<8)|('P'<<16)|('X'<<24)) ||
|
||||||
i < 0 ||
|
i < 0 ||
|
||||||
offs + sizeof(*h) + sizeof(h->lumps[0])*(i-1) > filelen)
|
offs + sizeof(*h) + sizeof(h->lumps[0])*(i-1) > filelen)
|
||||||
return;
|
return NULL;
|
||||||
h->numlumps = i;
|
h->numlumps = i;
|
||||||
while(i-->0)
|
while(i-->0)
|
||||||
{
|
{
|
||||||
h->lumps[i].fileofs = LittleLong(h->lumps[i].fileofs);
|
h->lumps[i].fileofs = LittleLong(h->lumps[i].fileofs);
|
||||||
h->lumps[i].filelen = LittleLong(h->lumps[i].filelen);
|
h->lumps[i].filelen = LittleLong(h->lumps[i].filelen);
|
||||||
if (h->lumps[i].fileofs + h->lumps[i].filelen > filelen)
|
if (h->lumps[i].fileofs + h->lumps[i].filelen > filelen)
|
||||||
return;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
bspxheader = h;
|
return h;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
void *SCR_ScreenShot_Capture(int fbwidth, int fbheight, int *stride, enum uploadfmt *fmt);
|
||||||
|
void BSPX_RenderEnvmaps(model_t *mod)
|
||||||
|
{
|
||||||
|
int c, i;
|
||||||
|
|
||||||
|
void *buffer;
|
||||||
|
int stride, cubesize;
|
||||||
|
uploadfmt_t fmt;
|
||||||
|
char filename[MAX_QPATH];
|
||||||
|
char olddrawviewmodel[64]; //hack, so we can set r_drawviewmodel to 0 so that it doesn't appear in screenshots even if the csqc is generating new data.
|
||||||
|
vec3_t oldangles;
|
||||||
|
const struct
|
||||||
|
{
|
||||||
|
vec3_t angle;
|
||||||
|
const char *postfix;
|
||||||
|
qboolean verticalflip;
|
||||||
|
qboolean horizontalflip;
|
||||||
|
} sides[] =
|
||||||
|
{
|
||||||
|
{{0, 0, 90}, "_px", true},
|
||||||
|
{{0, 180, -90}, "_nx", true},
|
||||||
|
{{0, 90, 0}, "_py", true}, //upside down
|
||||||
|
{{0, 270, 0}, "_ny", false, true},
|
||||||
|
{{-90, 0, 90}, "_pz", true},
|
||||||
|
{{90, 0, 90}, "_nz", true},
|
||||||
|
};
|
||||||
|
char base[MAX_QPATH];
|
||||||
|
COM_FileBase(cl.worldmodel->name, base, sizeof(base));
|
||||||
|
|
||||||
|
r_refdef.stereomethod = STEREO_OFF;
|
||||||
|
Q_strncpyz(olddrawviewmodel, r_drawviewmodel.string, sizeof(olddrawviewmodel));
|
||||||
|
Cvar_Set(&r_drawviewmodel, "0");
|
||||||
|
|
||||||
|
VectorCopy(cl.playerview->viewangles, oldangles);
|
||||||
|
|
||||||
|
for (c = 0; c < mod->numenvmaps; c++)
|
||||||
|
{
|
||||||
|
cubesize = mod->envmaps[c].cubesize;
|
||||||
|
if (cubesize < 1)
|
||||||
|
cubesize = 32;
|
||||||
|
|
||||||
|
VectorCopy(mod->envmaps[c].origin, r_refdef.vieworg);
|
||||||
|
|
||||||
|
for (i = 0; i < 6; i++)
|
||||||
|
{
|
||||||
|
Q_snprintfz(filename, sizeof(filename), "%s/%i_%i_%i%s.tga", base, (int)mod->envmaps[c].origin[0], (int)mod->envmaps[c].origin[1], (int)mod->envmaps[c].origin[2], sides[i].postfix);
|
||||||
|
|
||||||
|
VectorCopy(sides[i].angle, cl.playerview->simangles);
|
||||||
|
VectorCopy(cl.playerview->simangles, cl.playerview->viewangles);
|
||||||
|
|
||||||
|
buffer = SCR_ScreenShot_Capture(cubesize, cubesize, &stride, &fmt);
|
||||||
|
if (buffer)
|
||||||
|
{
|
||||||
|
char sysname[1024];
|
||||||
|
if (sides[i].horizontalflip)
|
||||||
|
{
|
||||||
|
int y, x, p;
|
||||||
|
int pxsize;
|
||||||
|
char *bad = buffer;
|
||||||
|
char *in = buffer, *out;
|
||||||
|
switch(fmt)
|
||||||
|
{
|
||||||
|
case TF_RGBA32:
|
||||||
|
case TF_BGRA32:
|
||||||
|
case TF_RGBX32:
|
||||||
|
case TF_BGRX32:
|
||||||
|
pxsize = 4;
|
||||||
|
break;
|
||||||
|
case TF_RGB24:
|
||||||
|
case TF_BGR24:
|
||||||
|
pxsize = 3;
|
||||||
|
break;
|
||||||
|
case TF_RGBA16F:
|
||||||
|
pxsize = 8;
|
||||||
|
break;
|
||||||
|
case TF_RGBA32F:
|
||||||
|
pxsize = 16;
|
||||||
|
break;
|
||||||
|
default: //erk!
|
||||||
|
pxsize = 1;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
buffer = out = BZ_Malloc(cubesize*cubesize*pxsize);
|
||||||
|
for (y = 0; y < cubesize; y++, in += abs(stride), out += cubesize*pxsize)
|
||||||
|
{
|
||||||
|
for (x = 0; x < cubesize*pxsize; x+=pxsize)
|
||||||
|
{
|
||||||
|
for (p = 0; p < pxsize; p++)
|
||||||
|
out[x+p] = in[(cubesize-1)*pxsize-x+p];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
BZ_Free(bad);
|
||||||
|
if (stride < 0)
|
||||||
|
stride = -cubesize*pxsize;
|
||||||
|
else
|
||||||
|
stride = cubesize*pxsize;
|
||||||
|
}
|
||||||
|
if (sides[i].verticalflip)
|
||||||
|
stride = -stride;
|
||||||
|
if (SCR_ScreenShot(filename, FS_GAMEONLY, &buffer, 1, stride, cubesize, cubesize, fmt))
|
||||||
|
{
|
||||||
|
FS_NativePath(filename, FS_GAMEONLY, sysname, sizeof(sysname));
|
||||||
|
Con_Printf ("Wrote %s\n", sysname);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
FS_NativePath(filename, FS_GAMEONLY, sysname, sizeof(sysname));
|
||||||
|
Con_Printf ("Failed to write %s\n", sysname);
|
||||||
|
}
|
||||||
|
BZ_Free(buffer);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Cvar_Set(&r_drawviewmodel, olddrawviewmodel);
|
||||||
|
|
||||||
|
VectorCopy(oldangles, cl.playerview->viewangles);
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
|
||||||
|
void BSPX_LoadEnvmaps(model_t *mod, bspx_header_t *bspx, void *mod_base)
|
||||||
|
{
|
||||||
|
unsigned int *envidx, idx;
|
||||||
|
int i;
|
||||||
|
char base[MAX_QPATH];
|
||||||
|
char imagename[MAX_QPATH];
|
||||||
|
menvmap_t *out;
|
||||||
|
int count;
|
||||||
|
denvmap_t *in = BSPX_FindLump(bspx, mod_base, "ENVMAP", &count);
|
||||||
|
if (count%sizeof(*in))
|
||||||
|
return; //erk
|
||||||
|
count /= sizeof(*in);
|
||||||
|
if (!count)
|
||||||
|
return;
|
||||||
|
out = ZG_Malloc(&mod->memgroup, sizeof(*out)*count);
|
||||||
|
|
||||||
|
mod->envmaps = out;
|
||||||
|
mod->numenvmaps = count;
|
||||||
|
|
||||||
|
COM_FileBase(mod->name, base, sizeof(base));
|
||||||
|
for (i = 0; i < count; i++)
|
||||||
|
{
|
||||||
|
out[i].origin[0] = LittleFloat(in[i].origin[0]);
|
||||||
|
out[i].origin[1] = LittleFloat(in[i].origin[1]);
|
||||||
|
out[i].origin[2] = LittleFloat(in[i].origin[2]);
|
||||||
|
out[i].cubesize = LittleLong(in[i].cubesize);
|
||||||
|
|
||||||
|
Q_snprintfz(imagename, sizeof(imagename), "%s/%i_%i_%i", base, (int)mod->envmaps[i].origin[0], (int)mod->envmaps[i].origin[1], (int)mod->envmaps[i].origin[2]);
|
||||||
|
out[i].image = Image_GetTexture(imagename, NULL, IF_CUBEMAP|IF_NOREPLACE, NULL, NULL, out[i].cubesize, out[i].cubesize, PTI_INVALID);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
//now update surface lists.
|
||||||
|
envidx = BSPX_FindLump(bspx, mod_base, "SURFENVMAP", &i);
|
||||||
|
if (i/sizeof(*envidx) == mod->numsurfaces)
|
||||||
|
{
|
||||||
|
for (i = 0; i < mod->numsurfaces; i++)
|
||||||
|
{
|
||||||
|
idx = LittleLong(envidx[i]);
|
||||||
|
if (idx < (unsigned int)count)
|
||||||
|
mod->surfaces[i].envmap = out[idx].image;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#if 1//ndef SERVERONLY
|
||||||
|
|
||||||
|
struct bspxrw
|
||||||
|
{
|
||||||
|
fromgame_t fg;
|
||||||
|
const char *fname;
|
||||||
|
char *origfile;
|
||||||
|
qofs_t origsize;
|
||||||
|
int lumpofs;
|
||||||
|
|
||||||
|
size_t corelumps;
|
||||||
|
size_t totallumps;
|
||||||
|
|
||||||
|
struct
|
||||||
|
{
|
||||||
|
char lumpname[24]; // up to 23 chars, zero-padded
|
||||||
|
void *data; // from file start
|
||||||
|
qofs_t filelen;
|
||||||
|
} *lumps;
|
||||||
|
};
|
||||||
|
void Mod_BSPXRW_Free(struct bspxrw *ctx)
|
||||||
|
{
|
||||||
|
FS_FreeFile(ctx->origfile);
|
||||||
|
Z_Free(ctx->lumps);
|
||||||
|
ctx->corelumps = ctx->totallumps = 0;
|
||||||
|
ctx->origfile = NULL;
|
||||||
|
}
|
||||||
|
void Mod_BSPXRW_Write(struct bspxrw *ctx)
|
||||||
|
{
|
||||||
|
#if 1
|
||||||
|
vfsfile_t *f = FS_OpenVFS(ctx->fname, "wb", FS_GAMEONLY);
|
||||||
|
if (f)
|
||||||
|
{
|
||||||
|
qofs_t bspxofs;
|
||||||
|
size_t i, j;
|
||||||
|
int pad, paddata = 0;
|
||||||
|
int nxlumps = ctx->totallumps-ctx->corelumps;
|
||||||
|
lump_t *lumps = alloca(sizeof(*lumps)*ctx->corelumps);
|
||||||
|
bspx_lump_t *xlumps = alloca(sizeof(*xlumps)*(ctx->totallumps-ctx->corelumps));
|
||||||
|
//bsp header info
|
||||||
|
VFS_WRITE(f, ctx->origfile, ctx->lumpofs);
|
||||||
|
VFS_WRITE(f, lumps, sizeof(lumps[0])*ctx->corelumps); //placeholder
|
||||||
|
//orig lumps
|
||||||
|
for (i = 0; i < ctx->corelumps; i++)
|
||||||
|
{
|
||||||
|
lumps[i].fileofs = VFS_TELL(f);
|
||||||
|
lumps[i].filelen = ctx->lumps[i].filelen;
|
||||||
|
|
||||||
|
VFS_WRITE(f, ctx->lumps[i].data, ctx->lumps[i].filelen);
|
||||||
|
//ALL lumps must be 4-aligned, so pad if needed.
|
||||||
|
pad = ((ctx->lumps[i].filelen+3)&~3)-ctx->lumps[i].filelen;
|
||||||
|
VFS_WRITE(f, &paddata, pad);
|
||||||
|
}
|
||||||
|
//bspx header
|
||||||
|
VFS_WRITE(f, "BSPX", 4);
|
||||||
|
VFS_WRITE(f, &nxlumps, sizeof(nxlumps));
|
||||||
|
bspxofs = VFS_TELL(f);
|
||||||
|
VFS_WRITE(f, xlumps, sizeof(xlumps[0])*(ctx->totallumps-ctx->corelumps)); //placeholder
|
||||||
|
//bspx data
|
||||||
|
for (i = 0; i < nxlumps; i++)
|
||||||
|
{
|
||||||
|
j = ctx->corelumps+i;
|
||||||
|
xlumps[i].fileofs = VFS_TELL(f);
|
||||||
|
xlumps[i].filelen = ctx->lumps[j].filelen;
|
||||||
|
memcpy(xlumps[i].lumpname, ctx->lumps[j].lumpname, sizeof(xlumps[i].lumpname));
|
||||||
|
|
||||||
|
VFS_WRITE(f, ctx->lumps[j].data, ctx->lumps[j].filelen);
|
||||||
|
//ALL lumps must be 4-aligned, so pad if needed.
|
||||||
|
pad = ((ctx->lumps[j].filelen+3)&~3)-ctx->lumps[j].filelen;
|
||||||
|
VFS_WRITE(f, &paddata, pad);
|
||||||
|
}
|
||||||
|
|
||||||
|
//now rewrite both sets of offsets.
|
||||||
|
VFS_SEEK(f, ctx->lumpofs);
|
||||||
|
VFS_WRITE(f, lumps, sizeof(lumps[0])*ctx->corelumps);
|
||||||
|
VFS_SEEK(f, bspxofs);
|
||||||
|
VFS_WRITE(f, xlumps, sizeof(xlumps[0])*(ctx->totallumps-ctx->corelumps));
|
||||||
|
|
||||||
|
VFS_CLOSE(f);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
Mod_BSPXRW_Free(ctx);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Mod_BSPXRW_SetLump(struct bspxrw *ctx, const char *lumpname, void *data, size_t datasize)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
for (i = 0; i < ctx->totallumps; i++)
|
||||||
|
{
|
||||||
|
if (!strcmp(ctx->lumps[i].lumpname, lumpname))
|
||||||
|
{ //replace the existing lump
|
||||||
|
ctx->lumps[i].data = data;
|
||||||
|
ctx->lumps[i].filelen = datasize;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Z_ReallocElements(&ctx->lumps, &ctx->totallumps, ctx->totallumps+1, sizeof(*ctx->lumps));
|
||||||
|
Q_strncpyz(ctx->lumps[i].lumpname, lumpname, sizeof(ctx->lumps[i].lumpname));
|
||||||
|
ctx->lumps[i].data = data;
|
||||||
|
ctx->lumps[i].filelen = datasize;
|
||||||
|
}
|
||||||
|
|
||||||
|
qboolean Mod_BSPXRW_Read(struct bspxrw *ctx, const char *fname)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
lump_t *l;
|
||||||
|
const char **corelumpnames = NULL;
|
||||||
|
bspx_header_t *bspxheader;
|
||||||
|
#ifdef Q3BSPS
|
||||||
|
static const char *q3corelumpnames[Q3LUMPS_TOTAL] = {"entities","shaders","planes","nodes","leafs","leafsurfs","leafbrushes","submodels","brushes","brushsides","verts","indexes","fogs","surfaces","lightmaps","lightgrid","visibility"
|
||||||
|
#ifdef RFBSPS
|
||||||
|
,"lightgrididx"
|
||||||
|
#endif
|
||||||
|
};
|
||||||
|
#endif
|
||||||
|
ctx->fname = fname;
|
||||||
|
ctx->origfile = FS_MallocFile(ctx->fname, FS_GAME, &ctx->origsize);
|
||||||
|
if (!ctx->origfile)
|
||||||
|
return false;
|
||||||
|
ctx->lumps = 0;
|
||||||
|
ctx->totallumps = 0;
|
||||||
|
|
||||||
|
i = LittleLong(*(int*)ctx->origfile);
|
||||||
|
switch(i)
|
||||||
|
{
|
||||||
|
case 29:
|
||||||
|
case 30:
|
||||||
|
ctx->fg = ((i==30)?fg_halflife:fg_quake);
|
||||||
|
ctx->lumpofs = 4;
|
||||||
|
ctx->corelumps = 0;
|
||||||
|
break;
|
||||||
|
case IDBSPHEADER:
|
||||||
|
i = LittleLong(*(int*)(ctx->origfile+4));
|
||||||
|
ctx->lumpofs = 8;
|
||||||
|
switch(i)
|
||||||
|
{
|
||||||
|
#ifdef Q2BSPS
|
||||||
|
case BSPVERSION_Q2:
|
||||||
|
// case BSPVERSION_Q2W:
|
||||||
|
ctx->fg = fg_quake2;
|
||||||
|
ctx->corelumps = Q2HEADER_LUMPS;
|
||||||
|
break;
|
||||||
|
#endif
|
||||||
|
#ifdef Q3BSPS
|
||||||
|
case BSPVERSION_Q3:
|
||||||
|
case BSPVERSION_RTCW:
|
||||||
|
ctx->fg = fg_quake3;
|
||||||
|
ctx->corelumps = 17;
|
||||||
|
corelumpnames = q3corelumpnames;
|
||||||
|
break;
|
||||||
|
#endif
|
||||||
|
default:
|
||||||
|
Mod_BSPXRW_Free(ctx);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
#ifdef RFBSPS
|
||||||
|
case ('R'<<0)+('B'<<8)+('S'<<16)+('P'<<24):
|
||||||
|
case ('F'<<0)+('B'<<8)+('S'<<16)+('P'<<24):
|
||||||
|
i = LittleLong(*(int*)(ctx->origfile+4));
|
||||||
|
ctx->lumpofs = 8;
|
||||||
|
switch(i)
|
||||||
|
{
|
||||||
|
case BSPVERSION_RBSP:
|
||||||
|
ctx->fg = fg_quake3;
|
||||||
|
ctx->corelumps = 18;
|
||||||
|
corelumpnames = q3corelumpnames;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
Mod_BSPXRW_Free(ctx);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
#endif
|
||||||
|
default:
|
||||||
|
Mod_BSPXRW_Free(ctx);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
l = (lump_t*)(ctx->origfile+ctx->lumpofs);
|
||||||
|
for (i = 0; i < ctx->corelumps; i++)
|
||||||
|
{
|
||||||
|
Z_ReallocElements(&ctx->lumps, &ctx->totallumps, ctx->totallumps+1, sizeof(*ctx->lumps));
|
||||||
|
ctx->lumps[ctx->totallumps-1].data = ctx->origfile+l[i].fileofs;
|
||||||
|
ctx->lumps[ctx->totallumps-1].filelen = l[i].filelen;
|
||||||
|
if (corelumpnames)
|
||||||
|
Q_snprintfz(ctx->lumps[ctx->totallumps-1].lumpname, sizeof(ctx->lumps[0].lumpname), "%s", corelumpnames[i]);
|
||||||
|
else
|
||||||
|
Q_snprintfz(ctx->lumps[ctx->totallumps-1].lumpname, sizeof(ctx->lumps[0].lumpname), "lump%u", i);
|
||||||
|
}
|
||||||
|
|
||||||
|
bspxheader = BSPX_Setup(NULL, ctx->origfile, ctx->origsize, l, ctx->corelumps);
|
||||||
|
if (bspxheader)
|
||||||
|
{
|
||||||
|
for (i = 0; i < bspxheader->numlumps; i++)
|
||||||
|
{
|
||||||
|
Z_ReallocElements(&ctx->lumps, &ctx->totallumps, ctx->totallumps+1, sizeof(*ctx->lumps));
|
||||||
|
ctx->lumps[ctx->totallumps-1].data = ctx->origfile+bspxheader->lumps[i].fileofs;
|
||||||
|
ctx->lumps[ctx->totallumps-1].filelen = bspxheader->lumps[i].filelen;
|
||||||
|
memcpy(ctx->lumps[ctx->totallumps-1].lumpname, bspxheader->lumps[i].lumpname, sizeof(ctx->lumps[0].lumpname));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
unsigned int Mod_NearestCubeForSurf(msurface_t *surf, denvmap_t *envmap, size_t nenvmap)
|
||||||
|
{ //this is slow, yes.
|
||||||
|
size_t n, v;
|
||||||
|
unsigned int best = ~0;
|
||||||
|
float bestdist = FLT_MAX, dist;
|
||||||
|
vec3_t diff, mid;
|
||||||
|
|
||||||
|
if (surf->mesh)
|
||||||
|
{
|
||||||
|
VectorClear(mid);
|
||||||
|
for (v = 0; v < surf->mesh->numvertexes; v++)
|
||||||
|
VectorAdd(mid, surf->mesh->xyz_array[v], mid);
|
||||||
|
VectorScale(mid, 1.0/surf->mesh->numvertexes, mid);
|
||||||
|
|
||||||
|
for (n = 0; n < nenvmap; n++)
|
||||||
|
{
|
||||||
|
VectorSubtract(mid, envmap[n].origin, diff);
|
||||||
|
dist = DotProduct(diff,diff);
|
||||||
|
if (bestdist > dist)
|
||||||
|
{
|
||||||
|
best = n;
|
||||||
|
bestdist = dist;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return best;
|
||||||
|
}
|
||||||
|
|
||||||
|
int QDECL envmapsort(const void *av, const void *bv)
|
||||||
|
{ //sorts cubemaps in order of size, to make texturearrays easier, if ever. The loader can then just make runs.
|
||||||
|
const denvmap_t *a=av, *b=bv;
|
||||||
|
if (a->cubesize == b->cubesize)
|
||||||
|
return 0;
|
||||||
|
if (a->cubesize > b->cubesize)
|
||||||
|
return 1;
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
void Mod_FindCubemaps_f(void)
|
||||||
|
{
|
||||||
|
struct bspxrw bspctx;
|
||||||
|
if (Mod_BSPXRW_Read(&bspctx, cl.worldmodel->name))
|
||||||
|
{
|
||||||
|
const char *entlump = Mod_GetEntitiesString(cl.worldmodel), *lmp;
|
||||||
|
int nest;
|
||||||
|
char key[1024];
|
||||||
|
char value[1024];
|
||||||
|
|
||||||
|
qboolean isenvmap;
|
||||||
|
float size;
|
||||||
|
vec3_t origin;
|
||||||
|
|
||||||
|
denvmap_t *envmap = NULL; //*nenvmap
|
||||||
|
size_t nenvmap = 0;
|
||||||
|
unsigned int *envmapidx = NULL; //*numsurfaces
|
||||||
|
size_t nenvmapidx = 0, i;
|
||||||
|
|
||||||
|
//find targetnames, and store their origins so that we can deal with spotlights.
|
||||||
|
for (lmp = entlump; ;)
|
||||||
|
{
|
||||||
|
lmp = COM_Parse(lmp);
|
||||||
|
if (com_token[0] != '{')
|
||||||
|
break;
|
||||||
|
|
||||||
|
isenvmap = false;
|
||||||
|
size = 128;
|
||||||
|
VectorClear(origin);
|
||||||
|
|
||||||
|
nest = 1;
|
||||||
|
while (1)
|
||||||
|
{
|
||||||
|
lmp = COM_ParseOut(lmp, key, sizeof(key));
|
||||||
|
if (!lmp)
|
||||||
|
break; // error
|
||||||
|
if (key[0] == '{')
|
||||||
|
{
|
||||||
|
nest++;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (key[0] == '}')
|
||||||
|
{
|
||||||
|
nest--;
|
||||||
|
if (!nest)
|
||||||
|
break; // end of entity
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (nest!=1)
|
||||||
|
continue;
|
||||||
|
if (key[0] == '_')
|
||||||
|
memmove(key, key+1, strlen(key));
|
||||||
|
while (key[strlen(key)-1] == ' ') // remove trailing spaces
|
||||||
|
key[strlen(key)-1] = 0;
|
||||||
|
lmp = COM_ParseOut(lmp, value, sizeof(value));
|
||||||
|
if (!lmp)
|
||||||
|
break; // error
|
||||||
|
|
||||||
|
// now that we have the key pair worked out...
|
||||||
|
if (!strcmp("classname", key) && !strcmp(value, "env_cubemap"))
|
||||||
|
isenvmap = true;
|
||||||
|
else if (!strcmp("origin", key))
|
||||||
|
sscanf(value, "%f %f %f", &origin[0], &origin[1], &origin[2]);
|
||||||
|
else if (!strcmp("size", key))
|
||||||
|
sscanf(value, "%f", &size);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (isenvmap)
|
||||||
|
{
|
||||||
|
int e = nenvmap;
|
||||||
|
if (ZF_ReallocElements(&envmap, &nenvmap, nenvmap+1, sizeof(*envmap)))
|
||||||
|
{
|
||||||
|
VectorCopy(origin, envmap[e].origin);
|
||||||
|
envmap[e].cubesize = size;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (nenvmap)
|
||||||
|
{
|
||||||
|
qsort(envmap, nenvmap, sizeof(*envmap), envmapsort);
|
||||||
|
if (ZF_ReallocElements(&envmapidx, &nenvmapidx, cl.worldmodel->numsurfaces, sizeof(*envmapidx)))
|
||||||
|
{
|
||||||
|
for(i = 0; i < cl.worldmodel->numsurfaces; i++)
|
||||||
|
envmapidx[i] = Mod_NearestCubeForSurf(cl.worldmodel->surfaces+i, envmap, nenvmap);
|
||||||
|
}
|
||||||
|
|
||||||
|
Mod_BSPXRW_SetLump(&bspctx, "ENVMAP", envmap, nenvmap*sizeof(*envmap));
|
||||||
|
Mod_BSPXRW_SetLump(&bspctx, "SURFENVMAP", envmapidx, cl.worldmodel->numsurfaces*sizeof(*envmapidx));
|
||||||
|
Mod_BSPXRW_Write(&bspctx);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Con_Printf("No cubemaps found on map\n");
|
||||||
|
Mod_BSPXRW_Free(&bspctx);
|
||||||
|
}
|
||||||
|
|
||||||
|
Z_Free(envmapidx);
|
||||||
|
Z_Free(envmap);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
void Mod_Realign_f(void)
|
||||||
|
{
|
||||||
|
struct bspxrw bspctx;
|
||||||
|
if (Mod_BSPXRW_Read(&bspctx, cl.worldmodel->name))
|
||||||
|
Mod_BSPXRW_Write(&bspctx);
|
||||||
|
}
|
||||||
|
void Mod_BSPX_List_f(void)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
struct bspxrw ctx;
|
||||||
|
char *fname = Cmd_Argv(1);
|
||||||
|
if (!*fname && cl.worldmodel)
|
||||||
|
fname = cl.worldmodel->name;
|
||||||
|
if (Mod_BSPXRW_Read(&ctx, fname))
|
||||||
|
{
|
||||||
|
for (i = 0; i < ctx.corelumps; i++)
|
||||||
|
{
|
||||||
|
Con_Printf("%s: %u\n", ctx.lumps[i].lumpname, ctx.lumps[i].filelen);
|
||||||
|
}
|
||||||
|
for ( ; i < ctx.totallumps; i++)
|
||||||
|
{
|
||||||
|
Con_Printf("%s: %u\n", ctx.lumps[i].lumpname, ctx.lumps[i].filelen);
|
||||||
|
}
|
||||||
|
Mod_BSPXRW_Free(&ctx);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
void Mod_BSPX_Strip_f(void)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
struct bspxrw ctx;
|
||||||
|
qboolean found = false;
|
||||||
|
if (Cmd_Argc() != 3)
|
||||||
|
Con_Printf("%s FILENAME NAME: removes an extended lump from the named bsp file\n", Cmd_Argv(0));
|
||||||
|
else if (Mod_BSPXRW_Read(&ctx, Cmd_Argv(1)))
|
||||||
|
{
|
||||||
|
for (i = ctx.corelumps; i < ctx.totallumps;)
|
||||||
|
{
|
||||||
|
if (!Q_strcasecmp(ctx.lumps[i].lumpname, Cmd_Argv(2)))
|
||||||
|
{
|
||||||
|
found = true;
|
||||||
|
memmove(&ctx.lumps[i], &ctx.lumps[i+1], sizeof(ctx.lumps[0])*(ctx.totallumps-(i+1)));
|
||||||
|
ctx.totallumps--;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
i++;
|
||||||
|
}
|
||||||
|
if (found)
|
||||||
|
Mod_BSPXRW_Write(&ctx);
|
||||||
|
else
|
||||||
|
Mod_BSPXRW_Free(&ctx);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
|
@ -2060,6 +2060,7 @@ static void BE_ApplyUniforms(program_t *prog, int permu)
|
||||||
case SP_LIGHTCUBEMATRIX:
|
case SP_LIGHTCUBEMATRIX:
|
||||||
case SP_LIGHTSHADOWMAPPROJ:
|
case SP_LIGHTSHADOWMAPPROJ:
|
||||||
case SP_LIGHTSHADOWMAPSCALE:
|
case SP_LIGHTSHADOWMAPSCALE:
|
||||||
|
case SP_LIGHTDIRECTION:
|
||||||
|
|
||||||
case SP_RENDERTEXTURESCALE:
|
case SP_RENDERTEXTURESCALE:
|
||||||
|
|
||||||
|
|
|
@ -1738,6 +1738,7 @@ void R_GAlias_GenerateBatches(entity_t *e, batch_t **batches)
|
||||||
|
|
||||||
b->buildmeshes = R_GAlias_DrawBatch;
|
b->buildmeshes = R_GAlias_DrawBatch;
|
||||||
b->ent = e;
|
b->ent = e;
|
||||||
|
b->envmap = Mod_CubemapForOrigin(cl.worldmodel, e->origin);
|
||||||
#if defined(Q3BSPS) || defined(RFBSPS)
|
#if defined(Q3BSPS) || defined(RFBSPS)
|
||||||
b->fog = Mod_FogForOrigin(cl.worldmodel, e->origin);
|
b->fog = Mod_FogForOrigin(cl.worldmodel, e->origin);
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -1256,7 +1256,12 @@ static void Shader_BindTextureForPass(int tmu, const shaderpass_t *pass)
|
||||||
t = shaderstate.curtexnums->fullbright;
|
t = shaderstate.curtexnums->fullbright;
|
||||||
break;
|
break;
|
||||||
case T_GEN_REFLECTCUBE:
|
case T_GEN_REFLECTCUBE:
|
||||||
t = (shaderstate.curtexnums && TEXLOADED(shaderstate.curtexnums->reflectcube))?shaderstate.curtexnums->reflectcube:shaderstate.tex_reflectcube;
|
if (shaderstate.curtexnums && TEXLOADED(shaderstate.curtexnums->reflectcube))
|
||||||
|
t = shaderstate.curtexnums->reflectcube;
|
||||||
|
else if (shaderstate.curbatch->envmap)
|
||||||
|
t = shaderstate.curbatch->envmap;
|
||||||
|
else
|
||||||
|
t = shaderstate.tex_reflectcube;
|
||||||
GL_LazyBind(tmu, GL_TEXTURE_CUBE_MAP_ARB, t);
|
GL_LazyBind(tmu, GL_TEXTURE_CUBE_MAP_ARB, t);
|
||||||
return;
|
return;
|
||||||
case T_GEN_REFLECTMASK:
|
case T_GEN_REFLECTMASK:
|
||||||
|
|
|
@ -736,6 +736,11 @@ void Mod_Purge(enum mod_purge_e ptype)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Mod_FindCubemaps_f(void);
|
||||||
|
void Mod_Realign_f(void);
|
||||||
|
void Mod_BSPX_List_f(void);
|
||||||
|
void Mod_BSPX_Strip_f(void);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
===============
|
===============
|
||||||
Mod_Init
|
Mod_Init
|
||||||
|
@ -771,6 +776,11 @@ void Mod_Init (qboolean initial)
|
||||||
Cvar_Register(&temp_lit2support, NULL);
|
Cvar_Register(&temp_lit2support, NULL);
|
||||||
Cmd_AddCommand("sv_saveentfile", Mod_SaveEntFile_f);
|
Cmd_AddCommand("sv_saveentfile", Mod_SaveEntFile_f);
|
||||||
Cmd_AddCommand("version_modelformats", Mod_PrintFormats_f);
|
Cmd_AddCommand("version_modelformats", Mod_PrintFormats_f);
|
||||||
|
|
||||||
|
Cmd_AddCommandD("map_findcubemaps", Mod_FindCubemaps_f, "Scans the entities of a map to find reflection envmap sites and determines the nearest one to each surface.");
|
||||||
|
Cmd_AddCommandD("map_realign", Mod_Realign_f, "Reads the named bsp and writes it back out with only alignment changes.");
|
||||||
|
Cmd_AddCommandD("map_bspx_list", Mod_BSPX_List_f, "Lists all lumps (and their sizes) in the specified bsp.");
|
||||||
|
Cmd_AddCommandD("map_bspx_strip", Mod_BSPX_Strip_f, "Strips a named extension lump from a bsp file.");
|
||||||
}
|
}
|
||||||
|
|
||||||
if (initial)
|
if (initial)
|
||||||
|
@ -1677,7 +1687,7 @@ typedef struct
|
||||||
Mod_LoadLighting
|
Mod_LoadLighting
|
||||||
=================
|
=================
|
||||||
*/
|
*/
|
||||||
void Mod_LoadLighting (model_t *loadmodel, qbyte *mod_base, lump_t *l, qboolean interleaveddeluxe, lightmapoverrides_t *overrides)
|
void Mod_LoadLighting (model_t *loadmodel, bspx_header_t *bspx, qbyte *mod_base, lump_t *l, qboolean interleaveddeluxe, lightmapoverrides_t *overrides)
|
||||||
{
|
{
|
||||||
qboolean luxtmp = true;
|
qboolean luxtmp = true;
|
||||||
qboolean exptmp = true;
|
qboolean exptmp = true;
|
||||||
|
@ -1718,11 +1728,11 @@ void Mod_LoadLighting (model_t *loadmodel, qbyte *mod_base, lump_t *l, qboolean
|
||||||
samples >>= 1;
|
samples >>= 1;
|
||||||
if (!samples)
|
if (!samples)
|
||||||
{
|
{
|
||||||
expdata = Q1BSPX_FindLump("LIGHTING_E5BGR9", &samples); //expressed as a big-endian packed int - 0xEBGR type thing, except misaligned and 32bit.
|
expdata = BSPX_FindLump(bspx, mod_base, "LIGHTING_E5BGR9", &samples); //expressed as a big-endian packed int - 0xEBGR type thing, except misaligned and 32bit.
|
||||||
samples /= 4;
|
samples /= 4;
|
||||||
if (!samples)
|
if (!samples)
|
||||||
{
|
{
|
||||||
litdata = Q1BSPX_FindLump("RGBLIGHTING", &samples); //RGB packed data
|
litdata = BSPX_FindLump(bspx, mod_base, "RGBLIGHTING", &samples); //RGB packed data
|
||||||
samples /= 3;
|
samples /= 3;
|
||||||
if (!samples)
|
if (!samples)
|
||||||
return;
|
return;
|
||||||
|
@ -1853,13 +1863,13 @@ void Mod_LoadLighting (model_t *loadmodel, qbyte *mod_base, lump_t *l, qboolean
|
||||||
{
|
{
|
||||||
int size;
|
int size;
|
||||||
/*FIXME: bspx support for extents+lmscale, may require style+offset lumps too, not sure what to do here*/
|
/*FIXME: bspx support for extents+lmscale, may require style+offset lumps too, not sure what to do here*/
|
||||||
expdata = Q1BSPX_FindLump("LIGHTING_E5BGR9", &size);
|
expdata = BSPX_FindLump(bspx, mod_base, "LIGHTING_E5BGR9", &size);
|
||||||
exptmp = true;
|
exptmp = true;
|
||||||
if (size != samples*4)
|
if (size != samples*4)
|
||||||
{
|
{
|
||||||
expdata = NULL;
|
expdata = NULL;
|
||||||
|
|
||||||
litdata = Q1BSPX_FindLump("RGBLIGHTING", &size);
|
litdata = BSPX_FindLump(bspx, mod_base, "RGBLIGHTING", &size);
|
||||||
littmp = true;
|
littmp = true;
|
||||||
if (size != samples*3)
|
if (size != samples*3)
|
||||||
litdata = NULL;
|
litdata = NULL;
|
||||||
|
@ -1944,7 +1954,7 @@ void Mod_LoadLighting (model_t *loadmodel, qbyte *mod_base, lump_t *l, qboolean
|
||||||
if (!luxdata)
|
if (!luxdata)
|
||||||
{
|
{
|
||||||
int size;
|
int size;
|
||||||
luxdata = Q1BSPX_FindLump("LIGHTINGDIR", &size);
|
luxdata = BSPX_FindLump(bspx, mod_base, "LIGHTINGDIR", &size);
|
||||||
if (size != samples*3)
|
if (size != samples*3)
|
||||||
luxdata = NULL;
|
luxdata = NULL;
|
||||||
luxtmp = true;
|
luxtmp = true;
|
||||||
|
@ -2024,7 +2034,7 @@ void Mod_LoadLighting (model_t *loadmodel, qbyte *mod_base, lump_t *l, qboolean
|
||||||
if (overrides && !overrides->shifts)
|
if (overrides && !overrides->shifts)
|
||||||
{
|
{
|
||||||
int size;
|
int size;
|
||||||
overrides->shifts = Q1BSPX_FindLump("LMSHIFT", &size);
|
overrides->shifts = BSPX_FindLump(bspx, mod_base, "LMSHIFT", &size);
|
||||||
if (size != loadmodel->numsurfaces)
|
if (size != loadmodel->numsurfaces)
|
||||||
overrides->shifts = NULL;
|
overrides->shifts = NULL;
|
||||||
|
|
||||||
|
@ -2032,14 +2042,14 @@ void Mod_LoadLighting (model_t *loadmodel, qbyte *mod_base, lump_t *l, qboolean
|
||||||
if (!overrides->offsets)
|
if (!overrides->offsets)
|
||||||
{
|
{
|
||||||
int size;
|
int size;
|
||||||
overrides->offsets = Q1BSPX_FindLump("LMOFFSET", &size);
|
overrides->offsets = BSPX_FindLump(bspx, mod_base, "LMOFFSET", &size);
|
||||||
if (size != loadmodel->numsurfaces * sizeof(int))
|
if (size != loadmodel->numsurfaces * sizeof(int))
|
||||||
overrides->offsets = NULL;
|
overrides->offsets = NULL;
|
||||||
}
|
}
|
||||||
if (!overrides->styles)
|
if (!overrides->styles)
|
||||||
{
|
{
|
||||||
int size;
|
int size;
|
||||||
overrides->styles = Q1BSPX_FindLump("LMSTYLE", &size);
|
overrides->styles = BSPX_FindLump(bspx, mod_base, "LMSTYLE", &size);
|
||||||
if (size != loadmodel->numsurfaces * sizeof(qbyte)*MAXQ1LIGHTMAPS)
|
if (size != loadmodel->numsurfaces * sizeof(qbyte)*MAXQ1LIGHTMAPS)
|
||||||
overrides->styles = NULL;
|
overrides->styles = NULL;
|
||||||
}
|
}
|
||||||
|
@ -2305,7 +2315,7 @@ qboolean Mod_LoadVertexes (model_t *loadmodel, qbyte *mod_base, lump_t *l)
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
qboolean Mod_LoadVertexNormals (model_t *loadmodel, qbyte *mod_base, lump_t *l)
|
qboolean Mod_LoadVertexNormals (model_t *loadmodel, bspx_header_t *bspx, qbyte *mod_base, lump_t *l)
|
||||||
{
|
{
|
||||||
float *in;
|
float *in;
|
||||||
float *out;
|
float *out;
|
||||||
|
@ -2323,7 +2333,7 @@ qboolean Mod_LoadVertexNormals (model_t *loadmodel, qbyte *mod_base, lump_t *l)
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
in = Q1BSPX_FindLump("VERTEXNORMALS", &count);
|
in = BSPX_FindLump(bspx, mod_base, "VERTEXNORMALS", &count);
|
||||||
if (in)
|
if (in)
|
||||||
count /= sizeof(vec3_t);
|
count /= sizeof(vec3_t);
|
||||||
else
|
else
|
||||||
|
@ -3765,7 +3775,7 @@ void CalcSurfaceExtents (model_t *mod, msurface_t *s);
|
||||||
Mod_LoadFaces
|
Mod_LoadFaces
|
||||||
=================
|
=================
|
||||||
*/
|
*/
|
||||||
static qboolean Mod_LoadFaces (model_t *loadmodel, qbyte *mod_base, lump_t *l, lump_t *lightlump, qboolean lm)
|
static qboolean Mod_LoadFaces (model_t *loadmodel, bspx_header_t *bspx, qbyte *mod_base, lump_t *l, lump_t *lightlump, qboolean lm)
|
||||||
{
|
{
|
||||||
dsface_t *ins;
|
dsface_t *ins;
|
||||||
dlface_t *inl;
|
dlface_t *inl;
|
||||||
|
@ -3820,7 +3830,7 @@ static qboolean Mod_LoadFaces (model_t *loadmodel, qbyte *mod_base, lump_t *l, l
|
||||||
loadmodel->surfaces = out;
|
loadmodel->surfaces = out;
|
||||||
loadmodel->numsurfaces = count;
|
loadmodel->numsurfaces = count;
|
||||||
|
|
||||||
Mod_LoadLighting (loadmodel, mod_base, lightlump, false, &overrides);
|
Mod_LoadLighting (loadmodel, bspx, mod_base, lightlump, false, &overrides);
|
||||||
|
|
||||||
switch(loadmodel->lightmaps.fmt)
|
switch(loadmodel->lightmaps.fmt)
|
||||||
{
|
{
|
||||||
|
@ -5075,6 +5085,7 @@ static qboolean QDECL Mod_LoadBrushModel (model_t *mod, void *buffer, size_t fsi
|
||||||
qboolean isnotmap;
|
qboolean isnotmap;
|
||||||
qboolean using_rbe = true;
|
qboolean using_rbe = true;
|
||||||
qboolean misaligned = false;
|
qboolean misaligned = false;
|
||||||
|
bspx_header_t *bspx;
|
||||||
|
|
||||||
COM_FileBase (mod->name, loadname, sizeof(loadname));
|
COM_FileBase (mod->name, loadname, sizeof(loadname));
|
||||||
mod->type = mod_brush;
|
mod->type = mod_brush;
|
||||||
|
@ -5176,12 +5187,13 @@ static qboolean QDECL Mod_LoadBrushModel (model_t *mod, void *buffer, size_t fsi
|
||||||
ofs += header.lumps[i].filelen;
|
ofs += header.lumps[i].filelen;
|
||||||
}
|
}
|
||||||
BZ_Free(tmp);
|
BZ_Free(tmp);
|
||||||
|
bspx = NULL;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
Q1BSPX_Setup(mod, mod_base, fsize, header.lumps, HEADER_LUMPS);
|
bspx = BSPX_Setup(mod, mod_base, fsize, header.lumps, HEADER_LUMPS);
|
||||||
|
|
||||||
if (1)//mod_ebfs.value)
|
/*if (1)//mod_ebfs.value)
|
||||||
{
|
{
|
||||||
char *id;
|
char *id;
|
||||||
id = (char *)mod_base + sizeof(dheader_t);
|
id = (char *)mod_base + sizeof(dheader_t);
|
||||||
|
@ -5189,7 +5201,7 @@ static qboolean QDECL Mod_LoadBrushModel (model_t *mod, void *buffer, size_t fsi
|
||||||
{ //EBFS detected.
|
{ //EBFS detected.
|
||||||
COM_LoadMapPackFile(mod->name, sizeof(dheader_t));
|
COM_LoadMapPackFile(mod->name, sizeof(dheader_t));
|
||||||
}
|
}
|
||||||
}
|
}*/
|
||||||
}
|
}
|
||||||
|
|
||||||
noerrors = true;
|
noerrors = true;
|
||||||
|
@ -5229,7 +5241,7 @@ static qboolean QDECL Mod_LoadBrushModel (model_t *mod, void *buffer, size_t fsi
|
||||||
TRACE(("Loading Texinfo\n"));
|
TRACE(("Loading Texinfo\n"));
|
||||||
noerrors = noerrors && Mod_LoadTexinfo (mod, mod_base, &header.lumps[LUMP_TEXINFO]);
|
noerrors = noerrors && Mod_LoadTexinfo (mod, mod_base, &header.lumps[LUMP_TEXINFO]);
|
||||||
TRACE(("Loading Faces\n"));
|
TRACE(("Loading Faces\n"));
|
||||||
noerrors = noerrors && Mod_LoadFaces (mod, mod_base, &header.lumps[LUMP_FACES], &header.lumps[LUMP_LIGHTING], longm);
|
noerrors = noerrors && Mod_LoadFaces (mod, bspx, mod_base, &header.lumps[LUMP_FACES], &header.lumps[LUMP_LIGHTING], longm);
|
||||||
}
|
}
|
||||||
if (!isDedicated)
|
if (!isDedicated)
|
||||||
{
|
{
|
||||||
|
@ -5270,7 +5282,7 @@ static qboolean QDECL Mod_LoadBrushModel (model_t *mod, void *buffer, size_t fsi
|
||||||
}
|
}
|
||||||
|
|
||||||
TRACE(("LoadBrushModel %i\n", __LINE__));
|
TRACE(("LoadBrushModel %i\n", __LINE__));
|
||||||
Q1BSP_LoadBrushes(mod);
|
Q1BSP_LoadBrushes(mod, bspx, mod_base);
|
||||||
TRACE(("LoadBrushModel %i\n", __LINE__));
|
TRACE(("LoadBrushModel %i\n", __LINE__));
|
||||||
Q1BSP_SetModelFuncs(mod);
|
Q1BSP_SetModelFuncs(mod);
|
||||||
TRACE(("LoadBrushModel %i\n", __LINE__));
|
TRACE(("LoadBrushModel %i\n", __LINE__));
|
||||||
|
|
|
@ -391,12 +391,17 @@ typedef struct mfog_s
|
||||||
mplane_t **planes;
|
mplane_t **planes;
|
||||||
} mfog_t;
|
} mfog_t;
|
||||||
|
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
vec3_t origin;
|
||||||
|
int cubesize; //pixels
|
||||||
|
} denvmap_t;
|
||||||
typedef struct
|
typedef struct
|
||||||
{
|
{
|
||||||
vec3_t origin;
|
vec3_t origin;
|
||||||
int cubesize; //pixels
|
int cubesize; //pixels
|
||||||
|
|
||||||
texid_t *image;
|
texid_t image;
|
||||||
} menvmap_t;
|
} menvmap_t;
|
||||||
|
|
||||||
#define LMSHIFT_DEFAULT 4
|
#define LMSHIFT_DEFAULT 4
|
||||||
|
@ -537,10 +542,12 @@ typedef struct hull_s
|
||||||
|
|
||||||
void Q1BSP_CheckHullNodes(hull_t *hull);
|
void Q1BSP_CheckHullNodes(hull_t *hull);
|
||||||
void Q1BSP_SetModelFuncs(struct model_s *mod);
|
void Q1BSP_SetModelFuncs(struct model_s *mod);
|
||||||
void Q1BSP_LoadBrushes(struct model_s *model);
|
void Q1BSP_LoadBrushes(struct model_s *model, bspx_header_t *bspx, void *mod_base);
|
||||||
void Q1BSP_Init(void);
|
void Q1BSP_Init(void);
|
||||||
void *Q1BSPX_FindLump(char *lumpname, int *lumpsize);
|
|
||||||
void Q1BSPX_Setup(struct model_s *mod, char *filebase, unsigned int filelen, lump_t *lumps, int numlumps);
|
void BSPX_LoadEnvmaps(struct model_s *mod, bspx_header_t *bspx, void *mod_base);
|
||||||
|
void *BSPX_FindLump(bspx_header_t *bspxheader, void *mod_base, char *lumpname, int *lumpsize);
|
||||||
|
bspx_header_t *BSPX_Setup(struct model_s *mod, char *filebase, unsigned int filelen, lump_t *lumps, int numlumps);
|
||||||
|
|
||||||
typedef struct fragmentdecal_s fragmentdecal_t;
|
typedef struct fragmentdecal_s fragmentdecal_t;
|
||||||
void Fragment_ClipPoly(fragmentdecal_t *dec, int numverts, float *inverts, shader_t *surfshader);
|
void Fragment_ClipPoly(fragmentdecal_t *dec, int numverts, float *inverts, shader_t *surfshader);
|
||||||
|
|
|
@ -719,6 +719,7 @@ program_t *Shader_FindGeneric(char *name, int qrtype);
|
||||||
const char *Shader_NameForGeneric(program_t *prog);
|
const char *Shader_NameForGeneric(program_t *prog);
|
||||||
void Shader_ReleaseGeneric(program_t *prog);
|
void Shader_ReleaseGeneric(program_t *prog);
|
||||||
|
|
||||||
|
image_t *Mod_CubemapForOrigin(model_t *wmodel, vec3_t org);
|
||||||
mfog_t *Mod_FogForOrigin(model_t *wmodel, vec3_t org);
|
mfog_t *Mod_FogForOrigin(model_t *wmodel, vec3_t org);
|
||||||
|
|
||||||
#define BEF_FORCEDEPTHWRITE 1
|
#define BEF_FORCEDEPTHWRITE 1
|
||||||
|
|
Loading…
Reference in a new issue