mirror of
https://github.com/nzp-team/fteqw.git
synced 2024-11-29 15:12:19 +00:00
preliminary quake 64 remastered bsp support (mipmaps currently busted), reduce missing anims in bsp to warning (needed for q64)
git-svn-id: https://svn.code.sf.net/p/fteqw/code/trunk@6031 fc73d0e0-1445-4013-8a0c-d673dee63da5
This commit is contained in:
parent
f9533ee8fc
commit
ee1a93d01b
3 changed files with 150 additions and 73 deletions
|
@ -67,12 +67,14 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||||
|
|
||||||
//=============================================================================
|
//=============================================================================
|
||||||
|
|
||||||
|
#define BSPVERSIONQTEST 23
|
||||||
#define BSPVERSIONPREREL 28
|
#define BSPVERSIONPREREL 28
|
||||||
#define BSPVERSION 29
|
#define BSPVERSION 29
|
||||||
//HalfLife support
|
//HalfLife support
|
||||||
#define BSPVERSIONHL 30
|
#define BSPVERSIONHL 30
|
||||||
#define BSPVERSION_LONG1 (('B' << 24) | ('S' << 16) | ('P' << 8) | '2') /*RMQ support (2PSB). 32bits instead of shorts for all but bbox sizes*/
|
#define BSPVERSION_LONG1 (('B' << 24) | ('S' << 16) | ('P' << 8) | '2') /*RMQ support (2PSB). 32bits instead of shorts for all but bbox sizes*/
|
||||||
#define BSPVERSION_LONG2 (('B' << 0) | ('S' << 8) | ('P' << 16) | ('2'<<24)) /*BSP2 support. 32bits instead of shorts for everything*/
|
#define BSPVERSION_LONG2 (('B' << 0) | ('S' << 8) | ('P' << 16) | ('2'<<24)) /*BSP2 support. 32bits instead of shorts for everything*/
|
||||||
|
#define BSPVERSIONQ64 (('Q' << 24) | ('6' << 16) | ('4' << 8) | (' ' << 0)) /* Remastered BSP format used for Quake 64 addon */
|
||||||
|
|
||||||
typedef struct
|
typedef struct
|
||||||
{
|
{
|
||||||
|
@ -135,6 +137,13 @@ typedef struct miptex_s
|
||||||
unsigned offsets[MIPLEVELS]; // four mip maps stored
|
unsigned offsets[MIPLEVELS]; // four mip maps stored
|
||||||
} miptex_t;
|
} miptex_t;
|
||||||
|
|
||||||
|
typedef struct q64miptex_s
|
||||||
|
{
|
||||||
|
char name[16];
|
||||||
|
unsigned width, height, scale;
|
||||||
|
unsigned offsets[MIPLEVELS]; // four mip maps stored
|
||||||
|
} q64miptex_t;
|
||||||
|
|
||||||
|
|
||||||
typedef struct
|
typedef struct
|
||||||
{
|
{
|
||||||
|
|
|
@ -701,6 +701,7 @@ void Mod_Init (qboolean initial)
|
||||||
Mod_RegisterModelFormatMagic(NULL, "Half-Life Map (bsp)", BSPVERSIONHL, Mod_LoadBrushModel);
|
Mod_RegisterModelFormatMagic(NULL, "Half-Life Map (bsp)", BSPVERSIONHL, Mod_LoadBrushModel);
|
||||||
Mod_RegisterModelFormatMagic(NULL, "Quake1 Map (bsp)", BSPVERSION, Mod_LoadBrushModel);
|
Mod_RegisterModelFormatMagic(NULL, "Quake1 Map (bsp)", BSPVERSION, Mod_LoadBrushModel);
|
||||||
Mod_RegisterModelFormatMagic(NULL, "Quake1 Prerelease Map (bsp)", BSPVERSIONPREREL, Mod_LoadBrushModel);
|
Mod_RegisterModelFormatMagic(NULL, "Quake1 Prerelease Map (bsp)", BSPVERSIONPREREL, Mod_LoadBrushModel);
|
||||||
|
Mod_RegisterModelFormatMagic(NULL, "Quake 64 Remastered Map (bsp)", BSPVERSIONQ64, Mod_LoadBrushModel);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1584,7 +1585,7 @@ typedef struct
|
||||||
Mod_LoadLighting
|
Mod_LoadLighting
|
||||||
=================
|
=================
|
||||||
*/
|
*/
|
||||||
void Mod_LoadLighting (model_t *loadmodel, bspx_header_t *bspx, 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, subbsp_t subbsp)
|
||||||
{
|
{
|
||||||
qboolean luxtmp = true;
|
qboolean luxtmp = true;
|
||||||
qboolean exptmp = true;
|
qboolean exptmp = true;
|
||||||
|
@ -1619,6 +1620,24 @@ void Mod_LoadLighting (model_t *loadmodel, bspx_header_t *bspx, qbyte *mod_base,
|
||||||
litdata = mod_base + l->fileofs;
|
litdata = mod_base + l->fileofs;
|
||||||
samples = l->filelen/3;
|
samples = l->filelen/3;
|
||||||
}
|
}
|
||||||
|
else if (subbsp == sb_quake64)
|
||||||
|
{
|
||||||
|
qbyte *q64l = mod_base + l->fileofs;
|
||||||
|
qbyte* newl;
|
||||||
|
int i;
|
||||||
|
|
||||||
|
samples = l->filelen / 2;
|
||||||
|
litdata = ZG_Malloc(&loadmodel->memgroup, samples * 3);
|
||||||
|
littmp = false;
|
||||||
|
|
||||||
|
// q64 lightmap format: byte 0 RRRR RGGG byte 1 GGBB BBBA
|
||||||
|
for (i = 0, newl = litdata; i < samples; ++i, q64l += 2, newl += 3)
|
||||||
|
{
|
||||||
|
newl[0] = (q64l[0] & 0xF8) | ((q64l[0] & 0xF8) >> 5);
|
||||||
|
newl[1] = ((q64l[0] & 0x07) << 5) | ((q64l[1] & 0xC0) >> 3) | (q64l[0] & 0x07);
|
||||||
|
newl[2] = ((q64l[1] & 0x3E) << 2) | ((q64l[1] & 0x3E) >> 3);
|
||||||
|
}
|
||||||
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
lumdata = mod_base + l->fileofs;
|
lumdata = mod_base + l->fileofs;
|
||||||
|
@ -3216,12 +3235,12 @@ void Mod_SetParent (mnode_t *node, mnode_t *parent)
|
||||||
Mod_LoadEdges
|
Mod_LoadEdges
|
||||||
=================
|
=================
|
||||||
*/
|
*/
|
||||||
qboolean Mod_LoadEdges (model_t *loadmodel, qbyte *mod_base, lump_t *l, qboolean lm)
|
qboolean Mod_LoadEdges (model_t *loadmodel, qbyte *mod_base, lump_t *l, subbsp_t subbsp)
|
||||||
{
|
{
|
||||||
medge_t *out;
|
medge_t *out;
|
||||||
int i, count;
|
int i, count;
|
||||||
|
|
||||||
if (lm)
|
if (subbsp == sb_long1 || subbsp == sb_long2)
|
||||||
{
|
{
|
||||||
dledge_t *in = (void *)(mod_base + l->fileofs);
|
dledge_t *in = (void *)(mod_base + l->fileofs);
|
||||||
count = l->filelen / sizeof(*in);
|
count = l->filelen / sizeof(*in);
|
||||||
|
@ -3270,12 +3289,12 @@ qboolean Mod_LoadEdges (model_t *loadmodel, qbyte *mod_base, lump_t *l, qboolean
|
||||||
Mod_LoadMarksurfaces
|
Mod_LoadMarksurfaces
|
||||||
=================
|
=================
|
||||||
*/
|
*/
|
||||||
qboolean Mod_LoadMarksurfaces (model_t *loadmodel, qbyte *mod_base, lump_t *l, qboolean lm)
|
qboolean Mod_LoadMarksurfaces (model_t *loadmodel, qbyte *mod_base, lump_t *l, subbsp_t subbsp)
|
||||||
{
|
{
|
||||||
int i, j, count;
|
int i, j, count;
|
||||||
msurface_t **out;
|
msurface_t **out;
|
||||||
|
|
||||||
if (lm)
|
if (subbsp == sb_long1 || subbsp == sb_long2)
|
||||||
{
|
{
|
||||||
int *inl;
|
int *inl;
|
||||||
inl = (void *)(mod_base + l->fileofs);
|
inl = (void *)(mod_base + l->fileofs);
|
||||||
|
@ -3382,7 +3401,7 @@ static void Mod_LoadVisibility (model_t *loadmodel, qbyte *mod_base, lump_t *l,
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifndef SERVERONLY
|
#ifndef SERVERONLY
|
||||||
static void Mod_LoadMiptex(model_t *loadmodel, texture_t *tx, miptex_t *mt, size_t miptexsize)
|
static void Mod_LoadMiptex(model_t *loadmodel, texture_t *tx, miptex_t *mt, int mtsize, qbyte *ptr, size_t miptexsize)
|
||||||
{
|
{
|
||||||
unsigned int legacysize =
|
unsigned int legacysize =
|
||||||
(mt->width>>0)*(mt->height>>0) +
|
(mt->width>>0)*(mt->height>>0) +
|
||||||
|
@ -3405,22 +3424,22 @@ static void Mod_LoadMiptex(model_t *loadmodel, texture_t *tx, miptex_t *mt, size
|
||||||
//if the gpu doesn't support npot, or its too big, or can't use the pixelformat then the engine will simply have to fall back on the paletted data. lets hope it was present.
|
//if the gpu doesn't support npot, or its too big, or can't use the pixelformat then the engine will simply have to fall back on the paletted data. lets hope it was present.
|
||||||
size_t extofs;
|
size_t extofs;
|
||||||
if (!mt->offsets[0])
|
if (!mt->offsets[0])
|
||||||
extofs = sizeof(miptex_t);
|
extofs = mtsize;
|
||||||
else if (mt->offsets[0] == sizeof(miptex_t) &&
|
else if (mt->offsets[0] == mtsize &&
|
||||||
mt->offsets[1] == mt->offsets[0]+(mt->width>>0)*(mt->height>>0) &&
|
mt->offsets[1] == mt->offsets[0]+(mt->width>>0)*(mt->height>>0) &&
|
||||||
mt->offsets[2] == mt->offsets[1]+(mt->width>>1)*(mt->height>>1) &&
|
mt->offsets[2] == mt->offsets[1]+(mt->width>>1)*(mt->height>>1) &&
|
||||||
mt->offsets[3] == mt->offsets[2]+(mt->width>>2)*(mt->height>>2))
|
mt->offsets[3] == mt->offsets[2]+(mt->width>>2)*(mt->height>>2))
|
||||||
{
|
{
|
||||||
extofs = mt->offsets[3]+(mt->width>>3)*(mt->height>>3);
|
extofs = mt->offsets[3]+(mt->width>>3)*(mt->height>>3);
|
||||||
if (loadmodel->fromgame == fg_halflife && *(short*)((qbyte *)mt + mt->offsets[3] + (mt->width>>3)*(mt->height>>3)) == 256)
|
if (loadmodel->fromgame == fg_halflife && *(short*)(ptr + mt->offsets[3] + (mt->width>>3)*(mt->height>>3)) == 256)
|
||||||
{
|
{
|
||||||
pal = (qbyte*)mt + extofs+2;
|
pal = ptr + extofs+2;
|
||||||
extofs += 2+256*3;
|
extofs += 2+256*3;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
extofs = miptexsize; //the numbers don't match what we expect... something weird is going on here... don't misinterpret it.
|
extofs = miptexsize; //the numbers don't match what we expect... something weird is going on here... don't misinterpret it.
|
||||||
if (extofs+4 <= miptexsize && ((qbyte*)mt)[extofs+0] == 0 && ((qbyte*)mt)[extofs+1]==0xfb && ((qbyte*)mt)[extofs+2]==0x2b && ((qbyte*)mt)[extofs+3]==0xaf)
|
if (extofs+4 <= miptexsize && ptr[extofs+0] == 0 && ptr[extofs+1]==0xfb && ptr[extofs+2]==0x2b && ptr[extofs+3]==0xaf)
|
||||||
{
|
{
|
||||||
unsigned int extsize;
|
unsigned int extsize;
|
||||||
extofs += 4;
|
extofs += 4;
|
||||||
|
@ -3429,7 +3448,7 @@ static void Mod_LoadMiptex(model_t *loadmodel, texture_t *tx, miptex_t *mt, size
|
||||||
size_t sz, w, h;
|
size_t sz, w, h;
|
||||||
unsigned int bb,bw,bh,bd;
|
unsigned int bb,bw,bh,bd;
|
||||||
int mip;
|
int mip;
|
||||||
qbyte *extdata = (void*)((qbyte*)mt+extofs);
|
qbyte *extdata = (void*)(ptr+extofs);
|
||||||
char *extfmt = (char*)(extdata+4);
|
char *extfmt = (char*)(extdata+4);
|
||||||
extsize = (extdata[0]<<0)|(extdata[1]<<8)|(extdata[2]<<16)|(extdata[3]<<24);
|
extsize = (extdata[0]<<0)|(extdata[1]<<8)|(extdata[2]<<16)|(extdata[3]<<24);
|
||||||
if (extsize<8 || extofs+extsize>miptexsize) break; //not a valid entry... something weird is happening here
|
if (extsize<8 || extofs+extsize>miptexsize) break; //not a valid entry... something weird is happening here
|
||||||
|
@ -3581,7 +3600,7 @@ static void Mod_LoadMiptex(model_t *loadmodel, texture_t *tx, miptex_t *mt, size
|
||||||
for (m = 0; m < 4; m++)
|
for (m = 0; m < 4; m++)
|
||||||
{
|
{
|
||||||
if (mt->offsets[m])
|
if (mt->offsets[m])
|
||||||
memcpy(tx->srcdata+legacysize, (qbyte *)mt + mt->offsets[m], (mt->width>>m)*(mt->height>>m));
|
memcpy(tx->srcdata+legacysize, ptr + mt->offsets[m], (mt->width>>m)*(mt->height>>m));
|
||||||
else
|
else
|
||||||
memset(tx->srcdata+legacysize, 0, (mt->width>>m)*(mt->height>>m));
|
memset(tx->srcdata+legacysize, 0, (mt->width>>m)*(mt->height>>m));
|
||||||
legacysize += (mt->width>>m)*(mt->height>>m);
|
legacysize += (mt->width>>m)*(mt->height>>m);
|
||||||
|
@ -3594,16 +3613,16 @@ static void Mod_LoadMiptex(model_t *loadmodel, texture_t *tx, miptex_t *mt, size
|
||||||
Mod_LoadTextures
|
Mod_LoadTextures
|
||||||
=================
|
=================
|
||||||
*/
|
*/
|
||||||
static qboolean Mod_LoadTextures (model_t *loadmodel, qbyte *mod_base, lump_t *l)
|
static qboolean Mod_LoadTextures (model_t *loadmodel, qbyte *mod_base, lump_t *l, subbsp_t subbsp)
|
||||||
{
|
{
|
||||||
int i, j, num, max, altmax;
|
int i, j, num, max, altmax;
|
||||||
miptex_t *mt;
|
|
||||||
texture_t *tx, *tx2;
|
texture_t *tx, *tx2;
|
||||||
texture_t *anims[10];
|
texture_t *anims[10];
|
||||||
texture_t *altanims[10];
|
texture_t *altanims[10];
|
||||||
dmiptexlump_t *m;
|
dmiptexlump_t *m;
|
||||||
unsigned int *sizes;
|
unsigned int *sizes;
|
||||||
unsigned int e, o;
|
unsigned int e, o;
|
||||||
|
int mtsize;
|
||||||
|
|
||||||
TRACE(("dbg: Mod_LoadTextures: inittexturedescs\n"));
|
TRACE(("dbg: Mod_LoadTextures: inittexturedescs\n"));
|
||||||
|
|
||||||
|
@ -3632,8 +3651,15 @@ TRACE(("dbg: Mod_LoadTextures: inittexturedescs\n"));
|
||||||
loadmodel->textures = ZG_Malloc(&loadmodel->memgroup, m->nummiptex * sizeof(*loadmodel->textures));
|
loadmodel->textures = ZG_Malloc(&loadmodel->memgroup, m->nummiptex * sizeof(*loadmodel->textures));
|
||||||
sizes = alloca(sizeof(*sizes)*m->nummiptex);
|
sizes = alloca(sizeof(*sizes)*m->nummiptex);
|
||||||
|
|
||||||
|
mtsize = subbsp == sb_quake64 ? sizeof(q64miptex_t) : sizeof(miptex_t);
|
||||||
|
|
||||||
for (i=m->nummiptex, e = l->filelen; i-->0; )
|
for (i=m->nummiptex, e = l->filelen; i-->0; )
|
||||||
{
|
{
|
||||||
|
qbyte* ptr;
|
||||||
|
miptex_t* mt;
|
||||||
|
miptex_t tmp;
|
||||||
|
int scale;
|
||||||
|
|
||||||
o = LittleLong(m->dataofs[i]);
|
o = LittleLong(m->dataofs[i]);
|
||||||
if (o >= l->filelen) //e1m2, this happens
|
if (o >= l->filelen) //e1m2, this happens
|
||||||
{
|
{
|
||||||
|
@ -3645,9 +3671,30 @@ TRACE(("dbg: Mod_LoadTextures: inittexturedescs\n"));
|
||||||
}
|
}
|
||||||
if (o >= e)
|
if (o >= e)
|
||||||
e = l->filelen; //something doesn't make sense. try to avoid making too many assumptions.
|
e = l->filelen; //something doesn't make sense. try to avoid making too many assumptions.
|
||||||
mt = (miptex_t *)((qbyte *)m + o);
|
|
||||||
|
|
||||||
TRACE(("dbg: Mod_LoadTextures: texture %s\n", mt->name));
|
ptr = (qbyte*)m + o;
|
||||||
|
|
||||||
|
if (subbsp == sb_quake64)
|
||||||
|
{
|
||||||
|
q64miptex_t *q64mt = (q64miptex_t*)ptr;
|
||||||
|
memcpy(tmp.name, q64mt->name, sizeof(tmp.name));
|
||||||
|
mt = &tmp;
|
||||||
|
mt->width = LittleLong(q64mt->width);
|
||||||
|
mt->height = LittleLong(q64mt->height);
|
||||||
|
for (j = 0; j < MIPLEVELS; j++)
|
||||||
|
mt->offsets[j] = LittleLong(q64mt->offsets[j]);
|
||||||
|
scale = LittleLong (q64mt->scale);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
mt = (miptex_t*)ptr;
|
||||||
|
mt->width = LittleLong(mt->width);
|
||||||
|
mt->height = LittleLong(mt->height);
|
||||||
|
for (j = 0; j < MIPLEVELS; j++)
|
||||||
|
mt->offsets[j] = LittleLong(mt->offsets[j]);
|
||||||
|
}
|
||||||
|
|
||||||
|
TRACE(("dbg: Mod_LoadTextures: texture %s\n", mt->name));
|
||||||
|
|
||||||
if (!*mt->name) //I HATE MAPPERS!
|
if (!*mt->name) //I HATE MAPPERS!
|
||||||
{
|
{
|
||||||
|
@ -3655,11 +3702,6 @@ TRACE(("dbg: Mod_LoadTextures: inittexturedescs\n"));
|
||||||
Con_DPrintf(CON_WARNING "warning: unnamed texture in %s, renaming to %s\n", loadmodel->name, mt->name);
|
Con_DPrintf(CON_WARNING "warning: unnamed texture in %s, renaming to %s\n", loadmodel->name, mt->name);
|
||||||
}
|
}
|
||||||
|
|
||||||
mt->width = LittleLong (mt->width);
|
|
||||||
mt->height = LittleLong (mt->height);
|
|
||||||
for (j=0 ; j<MIPLEVELS ; j++)
|
|
||||||
mt->offsets[j] = LittleLong (mt->offsets[j]);
|
|
||||||
|
|
||||||
if ( (mt->width & 15) || (mt->height & 15) )
|
if ( (mt->width & 15) || (mt->height & 15) )
|
||||||
Con_DPrintf (CON_WARNING "Warning: Texture %s is not 16 aligned", mt->name);
|
Con_DPrintf (CON_WARNING "Warning: Texture %s is not 16 aligned", mt->name);
|
||||||
if (mt->width < 1 || mt->height < 1)
|
if (mt->width < 1 || mt->height < 1)
|
||||||
|
@ -3670,9 +3712,14 @@ TRACE(("dbg: Mod_LoadTextures: inittexturedescs\n"));
|
||||||
Q_strncpyz(tx->name, mt->name, min(sizeof(mt->name)+1, sizeof(tx->name)));
|
Q_strncpyz(tx->name, mt->name, min(sizeof(mt->name)+1, sizeof(tx->name)));
|
||||||
tx->vwidth = mt->width;
|
tx->vwidth = mt->width;
|
||||||
tx->vheight = mt->height;
|
tx->vheight = mt->height;
|
||||||
|
if (subbsp == sb_quake64)
|
||||||
|
{
|
||||||
|
tx->vwidth <<= scale;
|
||||||
|
tx->vheight <<= scale;
|
||||||
|
}
|
||||||
|
|
||||||
#ifndef SERVERONLY
|
#ifndef SERVERONLY
|
||||||
Mod_LoadMiptex(loadmodel, tx, mt, e-o);
|
Mod_LoadMiptex(loadmodel, tx, mt, mtsize, ptr, e-o);
|
||||||
#else
|
#else
|
||||||
(void)e;
|
(void)e;
|
||||||
#endif
|
#endif
|
||||||
|
@ -3684,6 +3731,8 @@ TRACE(("dbg: Mod_LoadTextures: inittexturedescs\n"));
|
||||||
//
|
//
|
||||||
for (i=0 ; i<m->nummiptex ; i++)
|
for (i=0 ; i<m->nummiptex ; i++)
|
||||||
{
|
{
|
||||||
|
qboolean animvalid = true;
|
||||||
|
|
||||||
tx = loadmodel->textures[i];
|
tx = loadmodel->textures[i];
|
||||||
if (!tx || tx->name[0] != '+')
|
if (!tx || tx->name[0] != '+')
|
||||||
continue;
|
continue;
|
||||||
|
@ -3714,8 +3763,8 @@ TRACE(("dbg: Mod_LoadTextures: inittexturedescs\n"));
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
Con_Printf (CON_ERROR "Bad animating texture %s\n", tx->name);
|
Con_Printf (CON_WARNING "Bad animating texture name %s\n", tx->name);
|
||||||
return false;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
for (j=i+1 ; j<m->nummiptex ; j++)
|
for (j=i+1 ; j<m->nummiptex ; j++)
|
||||||
|
@ -3745,42 +3794,54 @@ TRACE(("dbg: Mod_LoadTextures: inittexturedescs\n"));
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
Con_Printf (CON_ERROR "Bad animating texture %s\n", tx->name);
|
continue;
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#define ANIM_CYCLE 2
|
#define ANIM_CYCLE 2
|
||||||
// link them all together
|
// validate
|
||||||
for (j=0 ; j<max ; j++)
|
for (j = 0; j < max; j++)
|
||||||
{
|
{
|
||||||
tx2 = anims[j];
|
if (!anims[j])
|
||||||
if (!tx2)
|
|
||||||
{
|
{
|
||||||
Con_Printf (CON_ERROR "Missing frame %i of %s\n",j, tx->name);
|
Con_Printf(CON_WARNING "Missing frame %i of %s\n", j, tx->name);
|
||||||
return false;
|
animvalid = false;
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
tx2->anim_total = max * ANIM_CYCLE;
|
|
||||||
tx2->anim_min = j * ANIM_CYCLE;
|
|
||||||
tx2->anim_max = (j+1) * ANIM_CYCLE;
|
|
||||||
tx2->anim_next = anims[ (j+1)%max ];
|
|
||||||
if (altmax)
|
|
||||||
tx2->alternate_anims = altanims[0];
|
|
||||||
}
|
}
|
||||||
for (j=0 ; j<altmax ; j++)
|
for (j = 0; j < altmax && animvalid; j++)
|
||||||
{
|
{
|
||||||
tx2 = altanims[j];
|
if (!altanims[j])
|
||||||
if (!tx2)
|
|
||||||
{
|
{
|
||||||
Con_Printf (CON_ERROR "Missing frame %i of %s\n",j, tx->name);
|
Con_Printf(CON_WARNING "Missing alt frame %i of %s\n", j, tx->name);
|
||||||
return false;
|
animvalid = false;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// link them all together
|
||||||
|
if (animvalid)
|
||||||
|
{
|
||||||
|
for (j = 0; j < max; j++)
|
||||||
|
{
|
||||||
|
tx2 = anims[j];
|
||||||
|
tx2->anim_total = max * ANIM_CYCLE;
|
||||||
|
tx2->anim_min = j * ANIM_CYCLE;
|
||||||
|
tx2->anim_max = (j + 1) * ANIM_CYCLE;
|
||||||
|
tx2->anim_next = anims[(j + 1) % max];
|
||||||
|
if (altmax)
|
||||||
|
tx2->alternate_anims = altanims[0];
|
||||||
|
}
|
||||||
|
for (j = 0; j < altmax; j++)
|
||||||
|
{
|
||||||
|
tx2 = altanims[j];
|
||||||
|
tx2->anim_total = altmax * ANIM_CYCLE;
|
||||||
|
tx2->anim_min = j * ANIM_CYCLE;
|
||||||
|
tx2->anim_max = (j + 1) * ANIM_CYCLE;
|
||||||
|
tx2->anim_next = altanims[(j + 1) % altmax];
|
||||||
|
if (max)
|
||||||
|
tx2->alternate_anims = anims[0];
|
||||||
}
|
}
|
||||||
tx2->anim_total = altmax * ANIM_CYCLE;
|
|
||||||
tx2->anim_min = j * ANIM_CYCLE;
|
|
||||||
tx2->anim_max = (j+1) * ANIM_CYCLE;
|
|
||||||
tx2->anim_next = altanims[ (j+1)%altmax ];
|
|
||||||
if (max)
|
|
||||||
tx2->alternate_anims = anims[0];
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -4015,7 +4076,7 @@ void CalcSurfaceExtents (model_t *mod, msurface_t *s);
|
||||||
Mod_LoadFaces
|
Mod_LoadFaces
|
||||||
=================
|
=================
|
||||||
*/
|
*/
|
||||||
static qboolean Mod_LoadFaces (model_t *loadmodel, bspx_header_t *bspx, 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, subbsp_t subbsp)
|
||||||
{
|
{
|
||||||
dsface_t *ins;
|
dsface_t *ins;
|
||||||
dlface_t *inl;
|
dlface_t *inl;
|
||||||
|
@ -4042,7 +4103,7 @@ static qboolean Mod_LoadFaces (model_t *loadmodel, bspx_header_t *bspx, qbyte *m
|
||||||
lmscale >>= 1;
|
lmscale >>= 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (lm)
|
if (subbsp == sb_long1 || subbsp == sb_long2)
|
||||||
{
|
{
|
||||||
ins = NULL;
|
ins = NULL;
|
||||||
inl = (void *)(mod_base + l->fileofs);
|
inl = (void *)(mod_base + l->fileofs);
|
||||||
|
@ -4070,7 +4131,7 @@ static qboolean Mod_LoadFaces (model_t *loadmodel, bspx_header_t *bspx, qbyte *m
|
||||||
loadmodel->surfaces = out;
|
loadmodel->surfaces = out;
|
||||||
loadmodel->numsurfaces = count;
|
loadmodel->numsurfaces = count;
|
||||||
|
|
||||||
Mod_LoadLighting (loadmodel, bspx, mod_base, lightlump, false, &overrides);
|
Mod_LoadLighting (loadmodel, bspx, mod_base, lightlump, false, &overrides, subbsp);
|
||||||
|
|
||||||
switch(loadmodel->lightmaps.fmt)
|
switch(loadmodel->lightmaps.fmt)
|
||||||
{
|
{
|
||||||
|
@ -4090,7 +4151,7 @@ static qboolean Mod_LoadFaces (model_t *loadmodel, bspx_header_t *bspx, qbyte *m
|
||||||
|
|
||||||
for ( surfnum=0 ; surfnum<count ; surfnum++, out++)
|
for ( surfnum=0 ; surfnum<count ; surfnum++, out++)
|
||||||
{
|
{
|
||||||
if (lm)
|
if (subbsp == sb_long1 || subbsp == sb_long2)
|
||||||
{
|
{
|
||||||
planenum = LittleLong(inl->planenum);
|
planenum = LittleLong(inl->planenum);
|
||||||
side = LittleLong(inl->side);
|
side = LittleLong(inl->side);
|
||||||
|
@ -4112,6 +4173,10 @@ static qboolean Mod_LoadFaces (model_t *loadmodel, bspx_header_t *bspx, qbyte *m
|
||||||
for (i=0 ; i<countof(out->styles) ; i++)
|
for (i=0 ; i<countof(out->styles) ; i++)
|
||||||
out->styles[i] = (i >= countof(ins->styles) || (lightstyleindex_t)ins->styles[i]>=INVALID_LIGHTSTYLE || ins->styles[i]==255)?INVALID_LIGHTSTYLE:ins->styles[i];
|
out->styles[i] = (i >= countof(ins->styles) || (lightstyleindex_t)ins->styles[i]>=INVALID_LIGHTSTYLE || ins->styles[i]==255)?INVALID_LIGHTSTYLE:ins->styles[i];
|
||||||
lofs = LittleLong(ins->lightofs);
|
lofs = LittleLong(ins->lightofs);
|
||||||
|
if (subbsp == sb_quake64)
|
||||||
|
{
|
||||||
|
lofs >>= 1;
|
||||||
|
}
|
||||||
ins++;
|
ins++;
|
||||||
}
|
}
|
||||||
// (*meshlist)[surfnum].vbofirstvert = out->firstedge;
|
// (*meshlist)[surfnum].vbofirstvert = out->firstedge;
|
||||||
|
@ -4207,12 +4272,12 @@ static qboolean Mod_LoadFaces (model_t *loadmodel, bspx_header_t *bspx, qbyte *m
|
||||||
Mod_LoadNodes
|
Mod_LoadNodes
|
||||||
=================
|
=================
|
||||||
*/
|
*/
|
||||||
static qboolean Mod_LoadNodes (model_t *loadmodel, qbyte *mod_base, lump_t *l, int lm)
|
static qboolean Mod_LoadNodes (model_t *loadmodel, qbyte *mod_base, lump_t *l, subbsp_t subbsp)
|
||||||
{
|
{
|
||||||
int i, j, count, p;
|
int i, j, count, p;
|
||||||
mnode_t *out;
|
mnode_t *out;
|
||||||
|
|
||||||
if (lm == 2)
|
if (subbsp == sb_long2)
|
||||||
{
|
{
|
||||||
dl2node_t *in;
|
dl2node_t *in;
|
||||||
in = (void *)(mod_base + l->fileofs);
|
in = (void *)(mod_base + l->fileofs);
|
||||||
|
@ -4251,7 +4316,7 @@ static qboolean Mod_LoadNodes (model_t *loadmodel, qbyte *mod_base, lump_t *l, i
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (lm)
|
else if (subbsp == sb_long1)
|
||||||
{
|
{
|
||||||
dl1node_t *in;
|
dl1node_t *in;
|
||||||
in = (void *)(mod_base + l->fileofs);
|
in = (void *)(mod_base + l->fileofs);
|
||||||
|
@ -4349,7 +4414,7 @@ static qboolean Mod_LoadNodes (model_t *loadmodel, qbyte *mod_base, lump_t *l, i
|
||||||
Mod_LoadLeafs
|
Mod_LoadLeafs
|
||||||
=================
|
=================
|
||||||
*/
|
*/
|
||||||
static qboolean Mod_LoadLeafs (model_t *loadmodel, qbyte *mod_base, lump_t *l, int lm, qboolean isnotmap, qbyte *ptr, size_t len)
|
static qboolean Mod_LoadLeafs (model_t *loadmodel, qbyte *mod_base, lump_t *l, subbsp_t subbsp, qboolean isnotmap, qbyte *ptr, size_t len)
|
||||||
{
|
{
|
||||||
mleaf_t *out;
|
mleaf_t *out;
|
||||||
int i, j, count, p;
|
int i, j, count, p;
|
||||||
|
@ -4360,7 +4425,7 @@ static qboolean Mod_LoadLeafs (model_t *loadmodel, qbyte *mod_base, lump_t *l, i
|
||||||
len = l->filelen;
|
len = l->filelen;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (lm==2)
|
if (subbsp == sb_long2)
|
||||||
{
|
{
|
||||||
dl2leaf_t *in;
|
dl2leaf_t *in;
|
||||||
in = (void *)ptr;
|
in = (void *)ptr;
|
||||||
|
@ -4419,7 +4484,7 @@ static qboolean Mod_LoadLeafs (model_t *loadmodel, qbyte *mod_base, lump_t *l, i
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (lm)
|
else if (subbsp == sb_long1)
|
||||||
{
|
{
|
||||||
dl1leaf_t *in;
|
dl1leaf_t *in;
|
||||||
in = (void *)(ptr);
|
in = (void *)(ptr);
|
||||||
|
@ -4548,7 +4613,7 @@ static qboolean Mod_LoadLeafs (model_t *loadmodel, qbyte *mod_base, lump_t *l, i
|
||||||
Mod_LoadClipnodes
|
Mod_LoadClipnodes
|
||||||
=================
|
=================
|
||||||
*/
|
*/
|
||||||
static qboolean Mod_LoadClipnodes (model_t *loadmodel, qbyte *mod_base, lump_t *l, qboolean lm, qboolean hexen2map)
|
static qboolean Mod_LoadClipnodes (model_t *loadmodel, qbyte *mod_base, lump_t *l, subbsp_t subbsp, qboolean hexen2map)
|
||||||
{
|
{
|
||||||
dsclipnode_t *ins;
|
dsclipnode_t *ins;
|
||||||
dlclipnode_t *inl;
|
dlclipnode_t *inl;
|
||||||
|
@ -4556,7 +4621,7 @@ static qboolean Mod_LoadClipnodes (model_t *loadmodel, qbyte *mod_base, lump_t *
|
||||||
int i, count;
|
int i, count;
|
||||||
hull_t *hull;
|
hull_t *hull;
|
||||||
|
|
||||||
if (lm)
|
if (subbsp == sb_long1 || subbsp == sb_long2)
|
||||||
{
|
{
|
||||||
ins = NULL;
|
ins = NULL;
|
||||||
inl = (void *)(mod_base + l->fileofs);
|
inl = (void *)(mod_base + l->fileofs);
|
||||||
|
@ -4744,7 +4809,7 @@ static qboolean Mod_LoadClipnodes (model_t *loadmodel, qbyte *mod_base, lump_t *
|
||||||
hull->available = false;
|
hull->available = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (lm)
|
if (subbsp == sb_long1 || subbsp == sb_long2)
|
||||||
{
|
{
|
||||||
for (i=0 ; i<count ; i++, out++, inl++)
|
for (i=0 ; i<count ; i++, out++, inl++)
|
||||||
{
|
{
|
||||||
|
@ -5153,7 +5218,6 @@ static qboolean QDECL Mod_LoadBrushModel (model_t *mod, void *buffer, size_t fsi
|
||||||
model_t *submod;
|
model_t *submod;
|
||||||
unsigned int chksum;
|
unsigned int chksum;
|
||||||
qboolean noerrors;
|
qboolean noerrors;
|
||||||
int longm = false;
|
|
||||||
char loadname[32];
|
char loadname[32];
|
||||||
qbyte *mod_base = buffer;
|
qbyte *mod_base = buffer;
|
||||||
qboolean hexen2map = false;
|
qboolean hexen2map = false;
|
||||||
|
@ -5161,6 +5225,7 @@ static qboolean QDECL Mod_LoadBrushModel (model_t *mod, void *buffer, size_t fsi
|
||||||
qboolean using_rbe = true;
|
qboolean using_rbe = true;
|
||||||
qboolean misaligned = false;
|
qboolean misaligned = false;
|
||||||
bspx_header_t *bspx;
|
bspx_header_t *bspx;
|
||||||
|
subbsp_t subbsp = sb_none;
|
||||||
|
|
||||||
COM_FileBase (mod->name, loadname, sizeof(loadname));
|
COM_FileBase (mod->name, loadname, sizeof(loadname));
|
||||||
mod->type = mod_brush;
|
mod->type = mod_brush;
|
||||||
|
@ -5192,18 +5257,20 @@ static qboolean QDECL Mod_LoadBrushModel (model_t *mod, void *buffer, size_t fsi
|
||||||
|
|
||||||
switch(header.version)
|
switch(header.version)
|
||||||
{
|
{
|
||||||
|
case BSPVERSIONQ64:
|
||||||
|
subbsp = sb_quake64;
|
||||||
case BSPVERSION:
|
case BSPVERSION:
|
||||||
case BSPVERSIONPREREL:
|
case BSPVERSIONPREREL:
|
||||||
mod->fromgame = fg_quake;
|
mod->fromgame = fg_quake;
|
||||||
mod->engineflags |= MDLF_NEEDOVERBRIGHT;
|
mod->engineflags |= MDLF_NEEDOVERBRIGHT;
|
||||||
break;
|
break;
|
||||||
case BSPVERSION_LONG1:
|
case BSPVERSION_LONG1:
|
||||||
longm = true;
|
subbsp = sb_long1;
|
||||||
mod->fromgame = fg_quake;
|
mod->fromgame = fg_quake;
|
||||||
mod->engineflags |= MDLF_NEEDOVERBRIGHT;
|
mod->engineflags |= MDLF_NEEDOVERBRIGHT;
|
||||||
break;
|
break;
|
||||||
case BSPVERSION_LONG2:
|
case BSPVERSION_LONG2:
|
||||||
longm = 2;
|
subbsp = sb_long2;
|
||||||
mod->fromgame = fg_quake;
|
mod->fromgame = fg_quake;
|
||||||
mod->engineflags |= MDLF_NEEDOVERBRIGHT;
|
mod->engineflags |= MDLF_NEEDOVERBRIGHT;
|
||||||
break;
|
break;
|
||||||
|
@ -5290,14 +5357,14 @@ static qboolean QDECL Mod_LoadBrushModel (model_t *mod, void *buffer, size_t fsi
|
||||||
TRACE(("Loading verts\n"));
|
TRACE(("Loading verts\n"));
|
||||||
noerrors = noerrors && Mod_LoadVertexes (mod, mod_base, &header.lumps[LUMP_VERTEXES]);
|
noerrors = noerrors && Mod_LoadVertexes (mod, mod_base, &header.lumps[LUMP_VERTEXES]);
|
||||||
TRACE(("Loading edges\n"));
|
TRACE(("Loading edges\n"));
|
||||||
noerrors = noerrors && Mod_LoadEdges (mod, mod_base, &header.lumps[LUMP_EDGES], longm);
|
noerrors = noerrors && Mod_LoadEdges (mod, mod_base, &header.lumps[LUMP_EDGES], subbsp);
|
||||||
TRACE(("Loading Surfedges\n"));
|
TRACE(("Loading Surfedges\n"));
|
||||||
noerrors = noerrors && Mod_LoadSurfedges (mod, mod_base, &header.lumps[LUMP_SURFEDGES]);
|
noerrors = noerrors && Mod_LoadSurfedges (mod, mod_base, &header.lumps[LUMP_SURFEDGES]);
|
||||||
}
|
}
|
||||||
if (!isDedicated)
|
if (!isDedicated)
|
||||||
{
|
{
|
||||||
TRACE(("Loading Textures\n"));
|
TRACE(("Loading Textures\n"));
|
||||||
noerrors = noerrors && Mod_LoadTextures (mod, mod_base, &header.lumps[LUMP_TEXTURES]);
|
noerrors = noerrors && Mod_LoadTextures (mod, mod_base, &header.lumps[LUMP_TEXTURES], subbsp);
|
||||||
}
|
}
|
||||||
TRACE(("Loading Submodels\n"));
|
TRACE(("Loading Submodels\n"));
|
||||||
noerrors = noerrors && Mod_LoadSubmodels (mod, mod_base, &header.lumps[LUMP_MODELS], &hexen2map);
|
noerrors = noerrors && Mod_LoadSubmodels (mod, mod_base, &header.lumps[LUMP_MODELS], &hexen2map);
|
||||||
|
@ -5310,23 +5377,23 @@ 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, bspx, 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], subbsp);
|
||||||
}
|
}
|
||||||
if (!isDedicated)
|
if (!isDedicated)
|
||||||
{
|
{
|
||||||
TRACE(("Loading MarkSurfaces\n"));
|
TRACE(("Loading MarkSurfaces\n"));
|
||||||
noerrors = noerrors && Mod_LoadMarksurfaces (mod, mod_base, &header.lumps[LUMP_MARKSURFACES], longm);
|
noerrors = noerrors && Mod_LoadMarksurfaces (mod, mod_base, &header.lumps[LUMP_MARKSURFACES], subbsp);
|
||||||
}
|
}
|
||||||
if (noerrors)
|
if (noerrors)
|
||||||
{
|
{
|
||||||
TRACE(("Loading Vis\n"));
|
TRACE(("Loading Vis\n"));
|
||||||
Mod_LoadVisibility (mod, mod_base, &header.lumps[LUMP_VISIBILITY], vispatch.visptr, vispatch.vislen);
|
Mod_LoadVisibility (mod, mod_base, &header.lumps[LUMP_VISIBILITY], vispatch.visptr, vispatch.vislen);
|
||||||
}
|
}
|
||||||
noerrors = noerrors && Mod_LoadLeafs (mod, mod_base, &header.lumps[LUMP_LEAFS], longm, isnotmap, vispatch.leafptr, vispatch.leaflen);
|
noerrors = noerrors && Mod_LoadLeafs (mod, mod_base, &header.lumps[LUMP_LEAFS], subbsp, isnotmap, vispatch.leafptr, vispatch.leaflen);
|
||||||
TRACE(("Loading Nodes\n"));
|
TRACE(("Loading Nodes\n"));
|
||||||
noerrors = noerrors && Mod_LoadNodes (mod, mod_base, &header.lumps[LUMP_NODES], longm);
|
noerrors = noerrors && Mod_LoadNodes (mod, mod_base, &header.lumps[LUMP_NODES], subbsp);
|
||||||
TRACE(("Loading Clipnodes\n"));
|
TRACE(("Loading Clipnodes\n"));
|
||||||
noerrors = noerrors && Mod_LoadClipnodes (mod, mod_base, &header.lumps[LUMP_CLIPNODES], longm, hexen2map);
|
noerrors = noerrors && Mod_LoadClipnodes (mod, mod_base, &header.lumps[LUMP_CLIPNODES], subbsp, hexen2map);
|
||||||
if (noerrors)
|
if (noerrors)
|
||||||
{
|
{
|
||||||
TRACE(("Loading hull 0\n"));
|
TRACE(("Loading hull 0\n"));
|
||||||
|
|
|
@ -875,6 +875,7 @@ typedef struct {
|
||||||
|
|
||||||
typedef enum {mod_brush, mod_sprite, mod_alias, mod_dummy, mod_halflife, mod_heightmap} modtype_t;
|
typedef enum {mod_brush, mod_sprite, mod_alias, mod_dummy, mod_halflife, mod_heightmap} modtype_t;
|
||||||
typedef enum {fg_quake, fg_quake2, fg_quake3, fg_halflife, fg_new, fg_doom, fg_doom3} fromgame_t; //useful when we have very similar model types. (eg quake/halflife bsps)
|
typedef enum {fg_quake, fg_quake2, fg_quake3, fg_halflife, fg_new, fg_doom, fg_doom3} fromgame_t; //useful when we have very similar model types. (eg quake/halflife bsps)
|
||||||
|
typedef enum {sb_none, sb_quake64, sb_long1, sb_long2} subbsp_t; // used to denote bsp specifics for load processing only (no runtime changes)
|
||||||
|
|
||||||
#define MF_ROCKET (1u<<0) // leave a trail
|
#define MF_ROCKET (1u<<0) // leave a trail
|
||||||
#define MF_GRENADE (1u<<1) // leave a trail
|
#define MF_GRENADE (1u<<1) // leave a trail
|
||||||
|
|
Loading…
Reference in a new issue