Animations, better flat management.

This commit is contained in:
Jaime Passos 2019-05-21 15:24:26 -03:00
parent 83bef14a5a
commit 62547b2a49
7 changed files with 224 additions and 176 deletions

View file

@ -564,8 +564,11 @@ INT32 P_AddLevelFlat(const char *flatname, levelflat_t *levelflat)
// store the flat lump number // store the flat lump number
levelflat->lumpnum = R_GetFlatNumForName(flatname); levelflat->lumpnum = R_GetFlatNumForName(flatname);
// Lactozilla
levelflat->texturenum = R_CheckTextureNumForName(flatname); levelflat->texturenum = R_CheckTextureNumForName(flatname);
levelflat->lasttexturenum = levelflat->texturenum;
levelflat->baselumpnum = LUMPERROR;
levelflat->basetexturenum = -1;
#ifndef ZDEBUG #ifndef ZDEBUG
CONS_Debug(DBG_SETUP, "flat #%03d: %s\n", atoi(sizeu1(numlevelflats)), levelflat->name); CONS_Debug(DBG_SETUP, "flat #%03d: %s\n", atoi(sizeu1(numlevelflats)), levelflat->name);

View file

@ -36,20 +36,22 @@ typedef struct
{ {
char name[9]; // resource name from wad char name[9]; // resource name from wad
lumpnum_t lumpnum; // lump number of the flat lumpnum_t lumpnum; // lump number of the flat
INT32 texturenum, lasttexturenum; // texture number of the flat
UINT16 width, height;
fixed_t topoffset, leftoffset;
// for flat animation // for flat animation
lumpnum_t baselumpnum; lumpnum_t baselumpnum;
INT32 basetexturenum;
INT32 animseq; // start pos. in the anim sequence INT32 animseq; // start pos. in the anim sequence
INT32 numpics; INT32 numpics;
INT32 speed; INT32 speed;
// Lactozilla // for patchflats
UINT8 *flatpatch; UINT8 *flatpatch;
UINT16 width, height;
fixed_t topoffset, leftoffset;
INT32 texturenum;
#ifdef ESLOPE #ifdef ESLOPE
// rescaled version of the above
UINT8 *resizedflat; UINT8 *resizedflat;
UINT16 resizedwidth, resizedheight; UINT16 resizedwidth, resizedheight;
#endif #endif

View file

@ -584,7 +584,19 @@ static inline void P_FindAnimatedFlat(INT32 animnum)
for (i = 0; i < numlevelflats; i++, foundflats++) for (i = 0; i < numlevelflats; i++, foundflats++)
{ {
// is that levelflat from the flat anim sequence ? // is that levelflat from the flat anim sequence ?
if (foundflats->lumpnum >= startflatnum && foundflats->lumpnum <= endflatnum) if ((anims[animnum].istexture) && (foundflats->texturenum != 0 && foundflats->texturenum != -1)
&& ((UINT16)foundflats->texturenum >= startflatnum && (UINT16)foundflats->texturenum <= endflatnum))
{
foundflats->basetexturenum = startflatnum;
foundflats->animseq = foundflats->texturenum - startflatnum;
foundflats->numpics = endflatnum - startflatnum + 1;
foundflats->speed = anims[animnum].speed;
CONS_Debug(DBG_SETUP, "animflat: #%03d name:%.8s animseq:%d numpics:%d speed:%d\n",
atoi(sizeu1(i)), foundflats->name, foundflats->animseq,
foundflats->numpics,foundflats->speed);
}
else if (foundflats->lumpnum >= startflatnum && foundflats->lumpnum <= endflatnum)
{ {
foundflats->baselumpnum = startflatnum; foundflats->baselumpnum = startflatnum;
foundflats->animseq = foundflats->lumpnum - startflatnum; foundflats->animseq = foundflats->lumpnum - startflatnum;
@ -608,10 +620,7 @@ void P_SetupLevelFlatAnims(void)
// the original game flat anim sequences // the original game flat anim sequences
for (i = 0; anims[i].istexture != -1; i++) for (i = 0; anims[i].istexture != -1; i++)
{ P_FindAnimatedFlat(i);
if (!anims[i].istexture)
P_FindAnimatedFlat(i);
}
} }
// //
@ -4794,9 +4803,12 @@ void P_UpdateSpecials(void)
{ {
if (foundflats->speed) // it is an animated flat if (foundflats->speed) // it is an animated flat
{ {
// update the levelflat texture number
if (foundflats->basetexturenum != -1)
foundflats->texturenum = foundflats->basetexturenum + ((leveltime/foundflats->speed + foundflats->animseq) % foundflats->numpics);
// update the levelflat lump number // update the levelflat lump number
foundflats->lumpnum = foundflats->baselumpnum + else if (foundflats->baselumpnum != LUMPERROR)
((leveltime/foundflats->speed + foundflats->animseq) % foundflats->numpics); foundflats->lumpnum = foundflats->baselumpnum + ((leveltime/foundflats->speed + foundflats->animseq) % foundflats->numpics);
} }
} }
} }

View file

@ -98,6 +98,7 @@ INT32 numtextures = 0; // total number of textures found,
// size of following tables // size of following tables
texture_t **textures = NULL; texture_t **textures = NULL;
textureflat_t *texflats = NULL;
static UINT32 **texturecolumnofs; // column offset lookup table for each texture static UINT32 **texturecolumnofs; // column offset lookup table for each texture
static UINT8 **texturecache; // graphics data for each generated full-size texture static UINT8 **texturecache; // graphics data for each generated full-size texture
@ -395,6 +396,7 @@ void R_LoadTextures(void)
} }
Z_Free(texturetranslation); Z_Free(texturetranslation);
Z_Free(textures); Z_Free(textures);
Z_Free(texflats);
} }
// Load patches and textures. // Load patches and textures.
@ -440,6 +442,7 @@ void R_LoadTextures(void)
// Allocate memory and initialize to 0 for all the textures we are initialising. // Allocate memory and initialize to 0 for all the textures we are initialising.
// There are actually 5 buffers allocated in one for convenience. // There are actually 5 buffers allocated in one for convenience.
textures = Z_Calloc((numtextures * sizeof(void *)) * 5, PU_STATIC, NULL); textures = Z_Calloc((numtextures * sizeof(void *)) * 5, PU_STATIC, NULL);
texflats = Z_Calloc((numtextures * sizeof(*texflats)), PU_STATIC, NULL);
// Allocate texture column offset table. // Allocate texture column offset table.
texturecolumnofs = (void *)((UINT8 *)textures + (numtextures * sizeof(void *))); texturecolumnofs = (void *)((UINT8 *)textures + (numtextures * sizeof(void *)));
@ -1015,10 +1018,10 @@ lumpnum_t R_GetFlatNumForName(const char *name)
lump = LUMPERROR; lump = LUMPERROR;
} }
// Lactozilla // Detect textures
if (lump == LUMPERROR) if (lump == LUMPERROR)
{ {
// Scan wad files backwards so patched flats take preference. // Scan wad files backwards so patched textures take preference.
for (i = numwadfiles - 1; i >= 0; i--) for (i = numwadfiles - 1; i >= 0; i--)
{ {
switch (wadfiles[i]->type) switch (wadfiles[i]->type)
@ -1683,7 +1686,6 @@ boolean R_CheckIfPatch(lumpnum_t lump)
return result; return result;
} }
// Lactozilla
void R_FlatPatch(patch_t *patch, UINT8 *flat) void R_FlatPatch(patch_t *patch, UINT8 *flat)
{ {
fixed_t col, ofs; fixed_t col, ofs;

View file

@ -48,8 +48,20 @@ typedef struct
texpatch_t patches[0]; texpatch_t patches[0];
} texture_t; } texture_t;
typedef struct
{
UINT8 *flat;
INT16 width, height;
#ifdef ESLOPE
UINT8 *resizedflat;
INT16 resizedwidth, resizedheight;
#endif
} textureflat_t;
// all loaded and prepared textures from the start of the game // all loaded and prepared textures from the start of the game
extern texture_t **textures; extern texture_t **textures;
extern textureflat_t *texflats;
extern INT32 *texturewidth; extern INT32 *texturewidth;
extern fixed_t *textureheight; // needed for texture pegging extern fixed_t *textureheight; // needed for texture pegging
@ -94,7 +106,6 @@ const char *R_ColormapNameForNum(INT32 num);
boolean R_CheckIfPatch(lumpnum_t lump); boolean R_CheckIfPatch(lumpnum_t lump);
// Lactozilla
void R_FlatPatch(patch_t *patch, UINT8 *flat); void R_FlatPatch(patch_t *patch, UINT8 *flat);
void R_FlatTexture(size_t tex, UINT8 *flat); void R_FlatTexture(size_t tex, UINT8 *flat);
void R_CropFlat(UINT8 *srcflat, UINT8 *destflat, void R_CropFlat(UINT8 *srcflat, UINT8 *destflat,

View file

@ -653,96 +653,191 @@ void R_DrawPlanes(void)
#endif #endif
} }
// Lactozilla boolean R_CheckPowersOfTwo(void)
{
return (ds_powersoftwo = ((!((ds_flatwidth & (ds_flatwidth - 1)) || (ds_flatheight & (ds_flatheight - 1)))) && (ds_flatwidth == ds_flatheight)));
}
void R_CheckFlatLength(size_t size)
{
switch (size)
{
case 4194304: // 2048x2048 lump
nflatmask = 0x3FF800;
nflatxshift = 21;
nflatyshift = 10;
nflatshiftup = 5;
ds_flatwidth = ds_flatheight = 2048;
break;
case 1048576: // 1024x1024 lump
nflatmask = 0xFFC00;
nflatxshift = 22;
nflatyshift = 12;
nflatshiftup = 6;
ds_flatwidth = ds_flatheight = 1024;
break;
case 262144:// 512x512 lump
nflatmask = 0x3FE00;
nflatxshift = 23;
nflatyshift = 14;
nflatshiftup = 7;
ds_flatwidth = ds_flatheight = 512;
break;
case 65536: // 256x256 lump
nflatmask = 0xFF00;
nflatxshift = 24;
nflatyshift = 16;
nflatshiftup = 8;
ds_flatwidth = ds_flatheight = 256;
break;
case 16384: // 128x128 lump
nflatmask = 0x3F80;
nflatxshift = 25;
nflatyshift = 18;
nflatshiftup = 9;
ds_flatwidth = ds_flatheight = 128;
break;
case 1024: // 32x32 lump
nflatmask = 0x3E0;
nflatxshift = 27;
nflatyshift = 22;
nflatshiftup = 11;
ds_flatwidth = ds_flatheight = 32;
break;
default: // 64x64 lump
nflatmask = 0xFC0;
nflatxshift = 26;
nflatyshift = 20;
nflatshiftup = 10;
ds_flatwidth = ds_flatheight = 64;
break;
}
}
static void R_GetPatchFlat(levelflat_t *levelflat, boolean leveltexture) static void R_GetPatchFlat(levelflat_t *levelflat, boolean leveltexture)
{ {
textureflat_t *texflat = &texflats[levelflat->texturenum];
patch_t *patch = NULL; patch_t *patch = NULL;
UINT8 *tex;
boolean texturechanged = (leveltexture ? (levelflat->texturenum != levelflat->lasttexturenum) : false);
if (levelflat->flatpatch == NULL) // Check if the texture changed.
if (leveltexture && (!texturechanged))
{
if (texflat != NULL && texflat->flat)
{
ds_source = texflat->flat;
ds_flatwidth = texflat->width;
ds_flatheight = texflat->height;
texturechanged = false;
}
else
texturechanged = true;
}
// If the texture changed, or the patch doesn't exist, convert either of them to a flat.
if (levelflat->flatpatch == NULL || texturechanged)
{ {
#ifdef ESLOPE #ifdef ESLOPE
INT32 resizewidth, resizeheight, newresize; INT32 resizewidth, resizeheight, newresize;
INT32 checkresizewidth, checkresizeheight; INT32 checkresizewidth, checkresizeheight;
#endif // ESLOPE #endif // ESLOPE
if (!leveltexture) if (leveltexture)
{
texture_t *texture = textures[levelflat->texturenum];
texflat->width = ds_flatwidth = texture->width;
texflat->height = ds_flatheight = texture->height;
texflat->flat = Z_Malloc(ds_flatwidth * ds_flatheight, PU_LEVEL, NULL);
memset(texflat->flat, TRANSPARENTPIXEL, ds_flatwidth * ds_flatheight);
R_FlatTexture(levelflat->texturenum, texflat->flat);
ds_source = texflat->flat;
}
else
{ {
patch = (patch_t *)ds_source; patch = (patch_t *)ds_source;
levelflat->width = ds_flatwidth = patch->width; levelflat->width = ds_flatwidth = patch->width;
levelflat->height = ds_flatheight = patch->height; levelflat->height = ds_flatheight = patch->height;
levelflat->topoffset = patch->topoffset * FRACUNIT;
levelflat->leftoffset = patch->leftoffset * FRACUNIT;
levelflat->flatpatch = Z_Malloc(ds_flatwidth * ds_flatheight, PU_LEVEL, NULL); levelflat->flatpatch = Z_Malloc(ds_flatwidth * ds_flatheight, PU_LEVEL, NULL);
memset(levelflat->flatpatch, TRANSPARENTPIXEL, ds_flatwidth * ds_flatheight); memset(levelflat->flatpatch, TRANSPARENTPIXEL, ds_flatwidth * ds_flatheight);
R_FlatPatch(patch, levelflat->flatpatch); R_FlatPatch(patch, levelflat->flatpatch);
levelflat->topoffset = patch->topoffset * FRACUNIT; ds_source = levelflat->flatpatch;
levelflat->leftoffset = patch->leftoffset * FRACUNIT;
} }
else
{
texture_t *texture = textures[levelflat->texturenum];
levelflat->width = ds_flatwidth = texture->width;
levelflat->height = ds_flatheight = texture->height;
levelflat->flatpatch = Z_Malloc(ds_flatwidth * ds_flatheight, PU_LEVEL, NULL);
memset(levelflat->flatpatch, TRANSPARENTPIXEL, ds_flatwidth * ds_flatheight);
R_FlatTexture(levelflat->texturenum, levelflat->flatpatch);
levelflat->topoffset = levelflat->leftoffset = 0;
}
ds_source = levelflat->flatpatch;
// If GZDoom has the same limitation then I'm not even going to bother.
// Crop the texture.
#ifdef ESLOPE #ifdef ESLOPE
// Scale up to nearest power of 2 // Crop the flat, if necessary.
resizewidth = resizeheight = 1; if (!R_CheckPowersOfTwo())
while (resizewidth < levelflat->width)
resizewidth <<= 1;
while (resizeheight < levelflat->height)
resizeheight <<= 1;
// Scale down to fit in 2048x2048
if (resizewidth > 2048)
resizewidth = 2048;
if (resizeheight > 2048)
resizeheight = 2048;
// A single pixel difference is negligible.
checkresizewidth = levelflat->width - 1;
if (checkresizewidth & (checkresizewidth - 1))
{ {
checkresizewidth += 2; // Scale up to nearest power of 2
resizewidth = resizeheight = 1;
while (resizewidth < ds_flatwidth)
resizewidth <<= 1;
while (resizeheight < ds_flatheight)
resizeheight <<= 1;
// Scale down to fit in 2048x2048
if (resizewidth > 2048)
resizewidth = 2048;
if (resizeheight > 2048)
resizeheight = 2048;
// A single pixel difference is negligible.
checkresizewidth = ds_flatwidth - 1;
if (checkresizewidth & (checkresizewidth - 1)) if (checkresizewidth & (checkresizewidth - 1))
{ {
while (resizewidth > levelflat->width) checkresizewidth += 2;
resizewidth >>= 1; if (checkresizewidth & (checkresizewidth - 1))
{
while (resizewidth > ds_flatwidth)
resizewidth >>= 1;
}
else
resizewidth = checkresizewidth;
} }
else else
resizewidth = checkresizewidth; resizewidth = checkresizewidth;
}
else
resizewidth = checkresizewidth;
checkresizeheight = levelflat->height - 1; checkresizeheight = ds_flatheight - 1;
if (checkresizeheight & (checkresizeheight - 1))
{
checkresizeheight += 2;
if (checkresizeheight & (checkresizeheight - 1)) if (checkresizeheight & (checkresizeheight - 1))
{ {
while (resizeheight > levelflat->height) checkresizeheight += 2;
resizeheight >>= 1; if (checkresizeheight & (checkresizeheight - 1))
{
while (resizeheight > ds_flatheight)
resizeheight >>= 1;
}
else
resizeheight = checkresizeheight;
} }
else else
resizeheight = checkresizeheight; resizeheight = checkresizeheight;
}
else
resizeheight = checkresizeheight;
levelflat->resizedwidth = levelflat->resizedheight = (newresize = min(resizewidth, resizeheight)); // Find smallest size.
levelflat->resizedflat = Z_Malloc(newresize * newresize, PU_LEVEL, NULL); newresize = min(resizewidth, resizeheight);
memset(levelflat->resizedflat, TRANSPARENTPIXEL, newresize * newresize);
R_CropFlat(levelflat->flatpatch, levelflat->resizedflat, levelflat->width, levelflat->height, min(resizewidth, newresize), min(resizeheight, newresize), newresize, newresize); // Allocate texture.
tex = Z_Malloc(newresize * newresize, PU_LEVEL, NULL);
memset(tex, TRANSPARENTPIXEL, newresize * newresize);
R_CropFlat(ds_source, tex, ds_flatwidth, ds_flatheight, min(resizewidth, newresize), min(resizeheight, newresize), newresize, newresize);
if (leveltexture)
{
texflat->resizedflat = tex;
texflat->resizedwidth = texflat->resizedheight = newresize;
}
else
{
levelflat->resizedflat = tex;
levelflat->resizedwidth = levelflat->resizedheight = newresize;
}
}
#endif // ESLOPE #endif // ESLOPE
} }
else else
@ -758,58 +853,26 @@ static void R_GetPatchFlat(levelflat_t *levelflat, boolean leveltexture)
#ifdef ESLOPE #ifdef ESLOPE
if (currentplane->slope) if (currentplane->slope)
{ {
ds_source = levelflat->resizedflat; if (R_CheckPowersOfTwo())
ds_flatwidth = levelflat->resizedwidth;
ds_flatheight = levelflat->resizedheight;
// uuuuuuuhhhhhhhh.......................
switch (ds_flatwidth * ds_flatheight)
{ {
case 4194304: // 2048x2048 lump if (leveltexture)
nflatmask = 0x3FF800; {
nflatxshift = 21; ds_source = texflat->resizedflat;
nflatyshift = 10; ds_flatwidth = texflat->resizedwidth;
nflatshiftup = 5; ds_flatheight = texflat->resizedheight;
break; }
case 1048576: // 1024x1024 lump else
nflatmask = 0xFFC00; {
nflatxshift = 22; ds_source = levelflat->resizedflat;
nflatyshift = 12; ds_flatwidth = levelflat->resizedwidth;
nflatshiftup = 6; ds_flatheight = levelflat->resizedheight;
break; }
case 262144:// 512x512 lump
nflatmask = 0x3FE00;
nflatxshift = 23;
nflatyshift = 14;
nflatshiftup = 7;
break;
case 65536: // 256x256 lump
nflatmask = 0xFF00;
nflatxshift = 24;
nflatyshift = 16;
nflatshiftup = 8;
break;
case 16384: // 128x128 lump
nflatmask = 0x3F80;
nflatxshift = 25;
nflatyshift = 18;
nflatshiftup = 9;
break;
case 1024: // 32x32 lump
nflatmask = 0x3E0;
nflatxshift = 27;
nflatyshift = 22;
nflatshiftup = 11;
break;
default: // 64x64 lump
nflatmask = 0xFC0;
nflatxshift = 26;
nflatyshift = 20;
nflatshiftup = 10;
break;
} }
R_CheckFlatLength(ds_flatwidth * ds_flatheight);
} }
#endif // ESLOPE #endif // ESLOPE
levelflat->lasttexturenum = levelflat->texturenum;
} }
void R_DrawSinglePlane(visplane_t *pl) void R_DrawSinglePlane(visplane_t *pl)
@ -966,71 +1029,24 @@ void R_DrawSinglePlane(visplane_t *pl)
currentplane = pl; currentplane = pl;
levelflat = &levelflats[pl->picnum]; levelflat = &levelflats[pl->picnum];
size = W_LumpLength(levelflat->lumpnum);
// Check if the flat is actually a texture.
if (levelflat->texturenum != 0 && levelflat->texturenum != -1) if (levelflat->texturenum != 0 && levelflat->texturenum != -1)
R_GetPatchFlat(levelflat, true); R_GetPatchFlat(levelflat, true);
// Check if the flat is actually a patch.
else if (R_CheckIfPatch(levelflat->lumpnum))
R_GetPatchFlat(levelflat, false);
// Raw flat.
else else
{ {
ds_source = (UINT8 *)W_CacheLumpNum(levelflat->lumpnum, PU_STATIC); // Stay here until Z_ChangeTag ds_source = (UINT8 *)W_CacheLumpNum(levelflat->lumpnum, PU_STATIC); // Stay here until Z_ChangeTag
size = W_LumpLength(levelflat->lumpnum); R_CheckFlatLength(size);
switch (size)
{
case 4194304: // 2048x2048 lump
nflatmask = 0x3FF800;
nflatxshift = 21;
nflatyshift = 10;
nflatshiftup = 5;
ds_flatwidth = ds_flatheight = 2048;
break;
case 1048576: // 1024x1024 lump
nflatmask = 0xFFC00;
nflatxshift = 22;
nflatyshift = 12;
nflatshiftup = 6;
ds_flatwidth = ds_flatheight = 1024;
break;
case 262144:// 512x512 lump
nflatmask = 0x3FE00;
nflatxshift = 23;
nflatyshift = 14;
nflatshiftup = 7;
ds_flatwidth = ds_flatheight = 512;
break;
case 65536: // 256x256 lump
nflatmask = 0xFF00;
nflatxshift = 24;
nflatyshift = 16;
nflatshiftup = 8;
ds_flatwidth = ds_flatheight = 256;
break;
case 16384: // 128x128 lump
nflatmask = 0x3F80;
nflatxshift = 25;
nflatyshift = 18;
nflatshiftup = 9;
ds_flatwidth = ds_flatheight = 128;
break;
case 1024: // 32x32 lump
nflatmask = 0x3E0;
nflatxshift = 27;
nflatyshift = 22;
nflatshiftup = 11;
ds_flatwidth = ds_flatheight = 32;
break;
default: // 64x64 lump
nflatmask = 0xFC0;
nflatxshift = 26;
nflatyshift = 20;
nflatshiftup = 10;
ds_flatwidth = ds_flatheight = 64;
break;
}
} }
if (R_CheckIfPatch(levelflat->lumpnum)) // Check if the flat has dimensions that are powers-of-two numbers.
R_GetPatchFlat(levelflat, false); if (R_CheckPowersOfTwo())
ds_powersoftwo = (!((ds_flatwidth & (ds_flatwidth - 1)) || (ds_flatheight & (ds_flatheight - 1)))); R_CheckFlatLength(ds_flatwidth * ds_flatheight);
if (light >= LIGHTLEVELS) if (light >= LIGHTLEVELS)
light = LIGHTLEVELS-1; light = LIGHTLEVELS-1;

View file

@ -94,6 +94,8 @@ void R_PlaneBounds(visplane_t *plane);
// Draws a single visplane. // Draws a single visplane.
void R_DrawSinglePlane(visplane_t *pl); void R_DrawSinglePlane(visplane_t *pl);
void R_CheckFlatLength(size_t size);
boolean R_CheckPowersOfTwo(void);
typedef struct planemgr_s typedef struct planemgr_s
{ {