Provide some cleaner method to generate textures as flats.

R_GenerateTextureAsFlat
This commit is contained in:
Jaime Passos 2020-01-07 16:51:02 -03:00
parent 9c66740e2b
commit c7eed47340
2 changed files with 47 additions and 39 deletions

View file

@ -39,7 +39,7 @@
#include <errno.h> #include <errno.h>
// //
// MAPTEXTURE_T CACHING // TEXTURE_T CACHING
// When a texture is first needed, it counts the number of composite columns // When a texture is first needed, it counts the number of composite columns
// required in the texture and allocates space for a column directory and // required in the texture and allocates space for a column directory and
// any new columns. // any new columns.
@ -52,7 +52,6 @@ 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;
UINT32 **texturecolumnofs; // column offset lookup table for each texture UINT32 **texturecolumnofs; // column offset lookup table for each texture
UINT8 **texturecache; // graphics data for each generated full-size texture UINT8 **texturecache; // graphics data for each generated full-size texture
@ -451,6 +450,32 @@ done:
return blocktex; return blocktex;
} }
//
// R_GenerateTextureAsFlat
//
// Generates a flat picture for a texture.
//
UINT8 *R_GenerateTextureAsFlat(size_t texnum)
{
texture_t *texture = textures[texnum];
UINT8 *converted = NULL;
size_t size = (texture->width * texture->height);
// The flat picture for this texture was not generated yet.
if (!texture->flat)
{
// Well, let's do it now, then.
texture->flat = Z_Malloc(size, PU_STATIC, NULL);
// Picture_TextureToFlat handles everything for us.
converted = (UINT8 *)Picture_TextureToFlat(texnum);
M_Memcpy(texture->flat, converted, size);
Z_Free(converted);
}
return texture->flat;
}
// //
// R_GetTextureNum // R_GetTextureNum
// //
@ -509,46 +534,34 @@ void *R_GetFlat(lumpnum_t flatlumpnum)
// //
void *R_GetLevelFlat(levelflat_t *levelflat) void *R_GetLevelFlat(levelflat_t *levelflat)
{ {
boolean isleveltexture = (levelflat->type == LEVELFLAT_TEXTURE);
texture_t *texture = (isleveltexture ? textures[levelflat->u.texture.num] : NULL);
boolean texturechanged = (isleveltexture ? (levelflat->u.texture.num != levelflat->u.texture.lastnum) : false);
UINT8 *flatdata = NULL; UINT8 *flatdata = NULL;
boolean leveltexture = (levelflat->type == LEVELFLAT_TEXTURE);
textureflat_t *texflat = &texflats[levelflat->u.texture.num];
boolean texturechanged = (leveltexture ? (levelflat->u.texture.num != levelflat->u.texture.lastnum) : false);
// Check if the texture changed. // Check if the texture changed.
if (leveltexture && (!texturechanged)) if (isleveltexture && (!texturechanged))
{ {
if (texflat != NULL && texflat->flat) if (texture->flat)
{ {
flatdata = texflat->flat; flatdata = texture->flat;
ds_flatwidth = texflat->width; ds_flatwidth = texture->width;
ds_flatheight = texflat->height; ds_flatheight = texture->height;
texturechanged = false; texturechanged = false;
} }
else else
texturechanged = true; texturechanged = true;
} }
// If the texture changed, or the patch doesn't exist, convert either of them to a flat. // If the texture changed, or the flat wasn't generated, convert.
if (levelflat->picture == NULL || texturechanged) if (levelflat->picture == NULL || texturechanged)
{ {
// Level texture // Level texture
if (leveltexture) if (isleveltexture)
{ {
UINT8 *converted; levelflat->picture = R_GenerateTextureAsFlat(levelflat->u.texture.num);
size_t size; ds_flatwidth = levelflat->width = texture->width;
texture_t *texture = textures[levelflat->u.texture.num]; ds_flatheight = levelflat->height = texture->height;
texflat->width = ds_flatwidth = texture->width;
texflat->height = ds_flatheight = texture->height;
size = (texflat->width * texflat->height);
texflat->flat = Z_Malloc(size, PU_LEVEL, NULL);
converted = (UINT8 *)Picture_TextureToFlat(levelflat->u.texture.num);
M_Memcpy(texflat->flat, converted, size);
Z_Free(converted);
levelflat->picture = texflat->flat;
levelflat->width = ds_flatwidth;
levelflat->height = ds_flatheight;
} }
else else
{ {
@ -714,12 +727,13 @@ void R_LoadTextures(void)
{ {
for (i = 0; i < numtextures; i++) for (i = 0; i < numtextures; i++)
{ {
if (textures[i]->flat)
Z_Free(textures[i]->flat);
Z_Free(textures[i]); Z_Free(textures[i]);
Z_Free(texturecache[i]); Z_Free(texturecache[i]);
} }
Z_Free(texturetranslation); Z_Free(texturetranslation);
Z_Free(textures); Z_Free(textures);
Z_Free(texflats);
} }
// Load patches and textures. // Load patches and textures.
@ -816,7 +830,6 @@ countflats:
// 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 *)));

View file

@ -47,8 +47,8 @@ enum
#endif #endif
}; };
// A maptexturedef_t describes a rectangular texture, // A texture_t describes a rectangular texture,
// which is composed of one or more mappatch_t structures // which is composed of one or more texpatch_t structures
// that arrange graphic patches. // that arrange graphic patches.
typedef struct typedef struct
{ {
@ -58,21 +58,15 @@ typedef struct
INT16 width, height; INT16 width, height;
boolean holes; boolean holes;
UINT8 flip; // 1 = flipx, 2 = flipy, 3 = both UINT8 flip; // 1 = flipx, 2 = flipy, 3 = both
void *flat; // The texture, as a flat.
// All the patches[patchcount] are drawn back to front into the cached texture. // All the patches[patchcount] are drawn back to front into the cached texture.
INT16 patchcount; INT16 patchcount;
texpatch_t patches[0]; texpatch_t patches[0];
} texture_t; } texture_t;
typedef struct
{
UINT8 *flat;
INT16 width, height;
} 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
@ -86,14 +80,15 @@ void R_FlushTextureCache(void);
// Texture generation // Texture generation
UINT8 *R_GenerateTexture(size_t texnum); UINT8 *R_GenerateTexture(size_t texnum);
UINT8 *R_GenerateTextureAsFlat(size_t texnum);
INT32 R_GetTextureNum(INT32 texnum); INT32 R_GetTextureNum(INT32 texnum);
void R_CheckTextureCache(INT32 tex); void R_CheckTextureCache(INT32 tex);
void R_ClearTextureNumCache(boolean btell); void R_ClearTextureNumCache(boolean btell);
// Retrieve texture data. // Retrieve texture data.
void *R_GetLevelFlat(levelflat_t *levelflat);
UINT8 *R_GetColumn(fixed_t tex, INT32 col); UINT8 *R_GetColumn(fixed_t tex, INT32 col);
void *R_GetFlat(lumpnum_t flatnum); void *R_GetFlat(lumpnum_t flatnum);
void *R_GetLevelFlat(levelflat_t *levelflat);
boolean R_CheckPowersOfTwo(void); boolean R_CheckPowersOfTwo(void);
void R_CheckFlatLength(size_t size); void R_CheckFlatLength(size_t size);