Patch refactor

This commit is contained in:
Lactozilla 2023-07-30 20:56:28 -03:00
parent 2ef231c073
commit 821460d208
14 changed files with 479 additions and 337 deletions

View file

@ -1772,10 +1772,10 @@ static void CON_DrawBackpic(void)
// then fill the sides with a solid color.
if (x > 0)
{
column_t *column = (column_t *)((UINT8 *)(con_backpic->columns) + (con_backpic->columnofs[0]));
if (!column->topdelta)
column_t *column = &con_backpic->columns[0];
if (column->num_posts && !column->posts[0].topdelta)
{
UINT8 *source = (UINT8 *)(column) + 3;
UINT8 *source = column->pixels;
INT32 color = (source[0] | V_NOSCALESTART);
// left side
V_DrawFill(0, 0, x, con_curlines, color);

View file

@ -50,6 +50,109 @@ static void HWR_DrawColumnInCache(const column_t *patchcol, UINT8 *block, GLMipm
fixed_t yfracstep, fixed_t scale_y,
texpatch_t *originPatch, INT32 patchheight,
INT32 bpp)
{
fixed_t yfrac, position, count;
UINT8 *dest;
const UINT8 *source;
INT32 originy = 0;
// for writing a pixel to dest
RGBA_t colortemp;
UINT8 alpha;
UINT8 texel;
UINT16 texelu16;
(void)patchheight; // This parameter is unused
if (originPatch) // originPatch can be NULL here, unlike in the software version
originy = originPatch->originy;
for (size_t i = 0; i < patchcol->num_posts; i++)
{
post_t *post = &patchcol->posts[i];
source = patchcol->pixels + post->data_offset;
count = ((post->length * scale_y) + (FRACUNIT/2)) >> FRACBITS;
position = originy + post->topdelta;
yfrac = 0;
if (position < 0)
{
yfrac = -position<<FRACBITS;
count += (((position * scale_y) + (FRACUNIT/2)) >> FRACBITS);
position = 0;
}
position = ((position * scale_y) + (FRACUNIT/2)) >> FRACBITS;
if (position < 0)
position = 0;
if (position + count >= pblockheight)
count = pblockheight - position;
dest = block + (position*blockmodulo);
while (count > 0)
{
count--;
texel = source[yfrac>>FRACBITS];
alpha = 0xFF;
// Make pixel transparent if chroma keyed
if ((mipmap->flags & TF_CHROMAKEYED) && (texel == HWR_PATCHES_CHROMAKEY_COLORINDEX))
alpha = 0x00;
if (mipmap->colormap)
texel = mipmap->colormap->data[texel];
switch (bpp)
{
case 2:
if ((originPatch != NULL) && (originPatch->style != AST_COPY))
texel = ASTBlendPaletteIndexes(*(dest+1), texel, originPatch->style, originPatch->alpha);
texelu16 = (UINT16)((alpha<<8) | texel);
memcpy(dest, &texelu16, sizeof(UINT16));
break;
case 3:
colortemp = V_GetColor(texel);
if ((originPatch != NULL) && (originPatch->style != AST_COPY))
{
RGBA_t rgbatexel;
rgbatexel.rgba = *(UINT32 *)dest;
colortemp.rgba = ASTBlendTexturePixel(rgbatexel, colortemp, originPatch->style, originPatch->alpha);
}
memcpy(dest, &colortemp, sizeof(RGBA_t)-sizeof(UINT8));
break;
case 4:
colortemp = V_GetColor(texel);
colortemp.s.alpha = alpha;
if ((originPatch != NULL) && (originPatch->style != AST_COPY))
{
RGBA_t rgbatexel;
rgbatexel.rgba = *(UINT32 *)dest;
colortemp.rgba = ASTBlendTexturePixel(rgbatexel, colortemp, originPatch->style, originPatch->alpha);
}
memcpy(dest, &colortemp, sizeof(RGBA_t));
break;
// default is 1
default:
if ((originPatch != NULL) && (originPatch->style != AST_COPY))
*dest = ASTBlendPaletteIndexes(*dest, texel, originPatch->style, originPatch->alpha);
else
*dest = texel;
break;
}
dest += blockmodulo;
yfrac += yfracstep;
}
}
}
static void HWR_DrawPostsInCache(const doompost_t *patchcol, UINT8 *block, GLMipmap_t *mipmap,
INT32 pblockheight, INT32 blockmodulo,
fixed_t yfracstep, fixed_t scale_y,
texpatch_t *originPatch, INT32 patchheight,
INT32 bpp)
{
fixed_t yfrac, position, count;
UINT8 *dest;
@ -106,57 +209,55 @@ static void HWR_DrawColumnInCache(const column_t *patchcol, UINT8 *block, GLMipm
if ((mipmap->flags & TF_CHROMAKEYED) && (texel == HWR_PATCHES_CHROMAKEY_COLORINDEX))
alpha = 0x00;
//Hurdler: 25/04/2000: now support colormap in hardware mode
if (mipmap->colormap)
texel = mipmap->colormap->data[texel];
// hope compiler will get this switch out of the loops (dreams...)
// gcc do it ! but vcc not ! (why don't use cygwin gcc for win32 ?)
// Alam: SRB2 uses Mingw, HUGS
switch (bpp)
{
case 2 : // uhhhhhhhh..........
if ((originPatch != NULL) && (originPatch->style != AST_COPY))
texel = ASTBlendPaletteIndexes(*(dest+1), texel, originPatch->style, originPatch->alpha);
texelu16 = (UINT16)((alpha<<8) | texel);
memcpy(dest, &texelu16, sizeof(UINT16));
break;
case 3 : colortemp = V_GetColor(texel);
if ((originPatch != NULL) && (originPatch->style != AST_COPY))
{
RGBA_t rgbatexel;
rgbatexel.rgba = *(UINT32 *)dest;
colortemp.rgba = ASTBlendTexturePixel(rgbatexel, colortemp, originPatch->style, originPatch->alpha);
}
memcpy(dest, &colortemp, sizeof(RGBA_t)-sizeof(UINT8));
break;
case 4 : colortemp = V_GetColor(texel);
colortemp.s.alpha = alpha;
if ((originPatch != NULL) && (originPatch->style != AST_COPY))
{
RGBA_t rgbatexel;
rgbatexel.rgba = *(UINT32 *)dest;
colortemp.rgba = ASTBlendTexturePixel(rgbatexel, colortemp, originPatch->style, originPatch->alpha);
}
memcpy(dest, &colortemp, sizeof(RGBA_t));
break;
case 2:
if ((originPatch != NULL) && (originPatch->style != AST_COPY))
texel = ASTBlendPaletteIndexes(*(dest+1), texel, originPatch->style, originPatch->alpha);
texelu16 = (UINT16)((alpha<<8) | texel);
memcpy(dest, &texelu16, sizeof(UINT16));
break;
case 3:
colortemp = V_GetColor(texel);
if ((originPatch != NULL) && (originPatch->style != AST_COPY))
{
RGBA_t rgbatexel;
rgbatexel.rgba = *(UINT32 *)dest;
colortemp.rgba = ASTBlendTexturePixel(rgbatexel, colortemp, originPatch->style, originPatch->alpha);
}
memcpy(dest, &colortemp, sizeof(RGBA_t)-sizeof(UINT8));
break;
case 4:
colortemp = V_GetColor(texel);
colortemp.s.alpha = alpha;
if ((originPatch != NULL) && (originPatch->style != AST_COPY))
{
RGBA_t rgbatexel;
rgbatexel.rgba = *(UINT32 *)dest;
colortemp.rgba = ASTBlendTexturePixel(rgbatexel, colortemp, originPatch->style, originPatch->alpha);
}
memcpy(dest, &colortemp, sizeof(RGBA_t));
break;
// default is 1
default:
if ((originPatch != NULL) && (originPatch->style != AST_COPY))
*dest = ASTBlendPaletteIndexes(*dest, texel, originPatch->style, originPatch->alpha);
else
*dest = texel;
break;
if ((originPatch != NULL) && (originPatch->style != AST_COPY))
*dest = ASTBlendPaletteIndexes(*dest, texel, originPatch->style, originPatch->alpha);
else
*dest = texel;
break;
}
dest += blockmodulo;
yfrac += yfracstep;
}
patchcol = (const column_t *)((const UINT8 *)patchcol + patchcol->length + 4);
patchcol = (const doompost_t *)((const UINT8 *)patchcol + patchcol->length + 4);
}
}
static void HWR_DrawFlippedColumnInCache(const column_t *patchcol, UINT8 *block, GLMipmap_t *mipmap,
static void HWR_DrawFlippedPostsInCache(const doompost_t *patchcol, UINT8 *block, GLMipmap_t *mipmap,
INT32 pblockheight, INT32 blockmodulo,
fixed_t yfracstep, fixed_t scale_y,
texpatch_t *originPatch, INT32 patchheight,
@ -216,57 +317,54 @@ static void HWR_DrawFlippedColumnInCache(const column_t *patchcol, UINT8 *block,
if ((mipmap->flags & TF_CHROMAKEYED) && (texel == HWR_PATCHES_CHROMAKEY_COLORINDEX))
alpha = 0x00;
//Hurdler: 25/04/2000: now support colormap in hardware mode
if (mipmap->colormap)
texel = mipmap->colormap->data[texel];
// hope compiler will get this switch out of the loops (dreams...)
// gcc do it ! but vcc not ! (why don't use cygwin gcc for win32 ?)
// Alam: SRB2 uses Mingw, HUGS
switch (bpp)
{
case 2 : // uhhhhhhhh..........
if ((originPatch != NULL) && (originPatch->style != AST_COPY))
texel = ASTBlendPaletteIndexes(*(dest+1), texel, originPatch->style, originPatch->alpha);
texelu16 = (UINT16)((alpha<<8) | texel);
memcpy(dest, &texelu16, sizeof(UINT16));
break;
case 3 : colortemp = V_GetColor(texel);
if ((originPatch != NULL) && (originPatch->style != AST_COPY))
{
RGBA_t rgbatexel;
rgbatexel.rgba = *(UINT32 *)dest;
colortemp.rgba = ASTBlendTexturePixel(rgbatexel, colortemp, originPatch->style, originPatch->alpha);
}
memcpy(dest, &colortemp, sizeof(RGBA_t)-sizeof(UINT8));
break;
case 4 : colortemp = V_GetColor(texel);
colortemp.s.alpha = alpha;
if ((originPatch != NULL) && (originPatch->style != AST_COPY))
{
RGBA_t rgbatexel;
rgbatexel.rgba = *(UINT32 *)dest;
colortemp.rgba = ASTBlendTexturePixel(rgbatexel, colortemp, originPatch->style, originPatch->alpha);
}
memcpy(dest, &colortemp, sizeof(RGBA_t));
break;
case 2:
if ((originPatch != NULL) && (originPatch->style != AST_COPY))
texel = ASTBlendPaletteIndexes(*(dest+1), texel, originPatch->style, originPatch->alpha);
texelu16 = (UINT16)((alpha<<8) | texel);
memcpy(dest, &texelu16, sizeof(UINT16));
break;
case 3:
colortemp = V_GetColor(texel);
if ((originPatch != NULL) && (originPatch->style != AST_COPY))
{
RGBA_t rgbatexel;
rgbatexel.rgba = *(UINT32 *)dest;
colortemp.rgba = ASTBlendTexturePixel(rgbatexel, colortemp, originPatch->style, originPatch->alpha);
}
memcpy(dest, &colortemp, sizeof(RGBA_t)-sizeof(UINT8));
break;
case 4:
colortemp = V_GetColor(texel);
colortemp.s.alpha = alpha;
if ((originPatch != NULL) && (originPatch->style != AST_COPY))
{
RGBA_t rgbatexel;
rgbatexel.rgba = *(UINT32 *)dest;
colortemp.rgba = ASTBlendTexturePixel(rgbatexel, colortemp, originPatch->style, originPatch->alpha);
}
memcpy(dest, &colortemp, sizeof(RGBA_t));
break;
// default is 1
default:
if ((originPatch != NULL) && (originPatch->style != AST_COPY))
*dest = ASTBlendPaletteIndexes(*dest, texel, originPatch->style, originPatch->alpha);
else
*dest = texel;
break;
if ((originPatch != NULL) && (originPatch->style != AST_COPY))
*dest = ASTBlendPaletteIndexes(*dest, texel, originPatch->style, originPatch->alpha);
else
*dest = texel;
break;
}
dest += blockmodulo;
yfrac -= yfracstep;
}
patchcol = (const column_t *)((const UINT8 *)patchcol + patchcol->length + 4);
patchcol = (const doompost_t *)((const UINT8 *)patchcol + patchcol->length + 4);
}
}
// Simplified patch caching function
// for use by sprites and other patches that are not part of a wall texture
// no alpha or flipping should be present since we do not want non-texture graphics to have them
@ -307,7 +405,7 @@ static void HWR_DrawPatchInCache(GLMipmap_t *mipmap,
// Draw each column to the block cache
for (; ncols--; block += bpp, xfrac += xfracstep)
{
patchcol = (const column_t *)((const UINT8 *)realpatch->columns + (realpatch->columnofs[xfrac>>FRACBITS]));
patchcol = &realpatch->columns[xfrac>>FRACBITS];
HWR_DrawColumnInCache(patchcol, block, mipmap,
pblockheight, blockmodulo,
@ -327,13 +425,13 @@ static void HWR_DrawTexturePatchInCache(GLMipmap_t *mipmap,
INT32 col, ncols;
fixed_t xfrac, xfracstep;
fixed_t yfracstep, scale_y;
const column_t *patchcol;
const doompost_t *patchcol;
UINT8 *block = mipmap->data;
INT32 bpp;
INT32 blockmodulo;
INT32 width, height;
// Column drawing function pointer.
static void (*ColumnDrawerPointer)(const column_t *patchcol, UINT8 *block, GLMipmap_t *mipmap,
static void (*ColumnDrawerPointer)(const doompost_t *patchcol, UINT8 *block, GLMipmap_t *mipmap,
INT32 pblockheight, INT32 blockmodulo,
fixed_t yfracstep, fixed_t scale_y,
texpatch_t *originPatch, INT32 patchheight,
@ -342,7 +440,7 @@ static void HWR_DrawTexturePatchInCache(GLMipmap_t *mipmap,
if (texture->width <= 0 || texture->height <= 0)
return;
ColumnDrawerPointer = (patch->flip & 2) ? HWR_DrawFlippedColumnInCache : HWR_DrawColumnInCache;
ColumnDrawerPointer = (patch->flip & 2) ? HWR_DrawFlippedPostsInCache : HWR_DrawPostsInCache;
x1 = patch->originx;
width = SHORT(realpatch->width);
@ -372,14 +470,6 @@ static void HWR_DrawTexturePatchInCache(GLMipmap_t *mipmap,
col = x * pblockwidth / texture->width;
ncols = ((x2 - x) * pblockwidth) / texture->width;
/*
CONS_Debug(DBG_RENDER, "patch %dx%d texture %dx%d block %dx%d\n",
width, height,
texture->width, texture->height,
pblockwidth, pblockheight);
CONS_Debug(DBG_RENDER, " col %d ncols %d x %d\n", col, ncols, x);
*/
// source advance
xfrac = 0;
if (x1 < 0)
@ -401,9 +491,9 @@ static void HWR_DrawTexturePatchInCache(GLMipmap_t *mipmap,
for (block += col*bpp; ncols--; block += bpp, xfrac += xfracstep)
{
if (patch->flip & 1)
patchcol = (const column_t *)((const UINT8 *)realpatch + LONG(realpatch->columnofs[(width-1)-(xfrac>>FRACBITS)]));
patchcol = (const doompost_t *)((const UINT8 *)realpatch + LONG(realpatch->columnofs[(width-1)-(xfrac>>FRACBITS)]));
else
patchcol = (const column_t *)((const UINT8 *)realpatch + LONG(realpatch->columnofs[xfrac>>FRACBITS]));
patchcol = (const doompost_t *)((const UINT8 *)realpatch + LONG(realpatch->columnofs[xfrac>>FRACBITS]));
ColumnDrawerPointer(patchcol, block, mipmap,
pblockheight, blockmodulo,

View file

@ -131,6 +131,7 @@ void HWR_DrawStretchyFixedPatch(patch_t *gpatch, fixed_t x, fixed_t y, fixed_t p
float cy = FIXED_TO_FLOAT(y);
UINT8 alphalevel = ((option & V_ALPHAMASK) >> V_ALPHASHIFT);
UINT8 blendmode = ((option & V_BLENDMASK) >> V_BLENDSHIFT);
UINT8 opacity = 0xFF;
GLPatch_t *hwrPatch;
// 3--2
@ -149,6 +150,14 @@ void HWR_DrawStretchyFixedPatch(patch_t *gpatch, fixed_t x, fixed_t y, fixed_t p
hwrPatch = ((GLPatch_t *)gpatch->hardware);
if (alphalevel)
{
if (alphalevel == 10) opacity = softwaretranstogl_lo[st_translucency]; // V_HUDTRANSHALF
else if (alphalevel == 11) opacity = softwaretranstogl[st_translucency]; // V_HUDTRANS
else if (alphalevel == 12) opacity = softwaretranstogl_hi[st_translucency]; // V_HUDTRANSDOUBLE
else opacity = softwaretranstogl[10-alphalevel];
}
dupx = (float)vid.dupx;
dupy = (float)vid.dupy;
@ -269,13 +278,13 @@ void HWR_DrawStretchyFixedPatch(patch_t *gpatch, fixed_t x, fixed_t y, fixed_t p
// if it's meant to cover the whole screen, black out the rest (ONLY IF TOP LEFT ISN'T TRANSPARENT)
// cx and cy are possibly *slightly* off from float maths
// This is done before here compared to software because we directly alter cx and cy to centre
if (cx >= -0.1f && cx <= 0.1f && gpatch->width == BASEVIDWIDTH && cy >= -0.1f && cy <= 0.1f && gpatch->height == BASEVIDHEIGHT)
if (opacity == 0xFF && cx >= -0.1f && cx <= 0.1f && gpatch->width == BASEVIDWIDTH && cy >= -0.1f && cy <= 0.1f && gpatch->height == BASEVIDHEIGHT)
{
const column_t *column = (const column_t *)((const UINT8 *)(gpatch->columns) + (gpatch->columnofs[0]));
if (!column->topdelta)
const column_t *column = &gpatch->columns[0];
if (column->num_posts && !column->posts[0].topdelta)
{
const UINT8 *source = (const UINT8 *)(column) + 3;
HWR_DrawFill(0, 0, BASEVIDWIDTH, BASEVIDHEIGHT, (column->topdelta == 0xff ? 31 : source[0]));
const UINT8 *source = column->pixels;
HWR_DrawFill(0, 0, BASEVIDWIDTH, BASEVIDHEIGHT, source[0]);
}
}
// centre screen
@ -353,11 +362,7 @@ void HWR_DrawStretchyFixedPatch(patch_t *gpatch, fixed_t x, fixed_t y, fixed_t p
{
FSurfaceInfo Surf;
Surf.PolyColor.s.red = Surf.PolyColor.s.green = Surf.PolyColor.s.blue = 0xff;
if (alphalevel == 10) Surf.PolyColor.s.alpha = softwaretranstogl_lo[st_translucency]; // V_HUDTRANSHALF
else if (alphalevel == 11) Surf.PolyColor.s.alpha = softwaretranstogl[st_translucency]; // V_HUDTRANS
else if (alphalevel == 12) Surf.PolyColor.s.alpha = softwaretranstogl_hi[st_translucency]; // V_HUDTRANSDOUBLE
else Surf.PolyColor.s.alpha = softwaretranstogl[10-alphalevel];
Surf.PolyColor.s.alpha = opacity;
flags |= PF_Modulated;
HWD.pfnDrawPolygon(&Surf, v, 4, flags);
}

View file

@ -719,14 +719,26 @@ typedef struct
{
UINT8 topdelta; // -1 is the last post in a column
UINT8 length; // length data bytes follows
} ATTRPACK post_t;
} ATTRPACK doompost_t;
#if defined(_MSC_VER)
#pragma pack()
#endif
// column_t is a list of 0 or more post_t, (UINT8)-1 terminated
typedef post_t column_t;
typedef struct
{
size_t topdelta;
size_t length;
size_t data_offset;
} post_t;
// column_t is a list of 0 or more post_t
typedef struct
{
size_t num_posts;
post_t *posts;
UINT8 *pixels;
} column_t;
//
// OTHER TYPES
@ -800,8 +812,9 @@ typedef struct
INT16 width, height;
INT16 leftoffset, topoffset;
INT32 *columnofs; // Column offsets. This is relative to patch->columns
UINT8 *columns; // Software column data
UINT8 *pixels;
column_t *columns;
post_t *posts;
void *hardware; // OpenGL patch, allocated whenever necessary
void *flats[4]; // The patch as flats

View file

@ -27,40 +27,89 @@
patch_t *Patch_Create(softwarepatch_t *source, size_t srcsize, void *dest)
{
patch_t *patch = (dest == NULL) ? Z_Calloc(sizeof(patch_t), PU_PATCH, NULL) : (patch_t *)(dest);
if (!source)
return patch;
if (source)
{
INT32 col, colsize;
size_t size = sizeof(INT32) * SHORT(source->width);
size_t offs = (sizeof(INT16) * 4) + size;
(void)srcsize;
patch->width = SHORT(source->width);
patch->height = SHORT(source->height);
patch->leftoffset = SHORT(source->leftoffset);
patch->topoffset = SHORT(source->topoffset);
patch->columnofs = Z_Calloc(size, PU_PATCH_DATA, NULL);
patch->width = SHORT(source->width);
patch->height = SHORT(source->height);
patch->leftoffset = SHORT(source->leftoffset);
patch->topoffset = SHORT(source->topoffset);
for (col = 0; col < source->width; col++)
{
// This makes the column offsets relative to the column data itself,
// instead of the entire patch data
patch->columnofs[col] = LONG(source->columnofs[col]) - offs;
}
size_t total_pixels = 0;
size_t total_posts = 0;
if (!srcsize)
I_Error("Patch_Create: no source size!");
Patch_CalcDataSizes(source, &total_pixels, &total_posts);
colsize = (INT32)(srcsize) - (INT32)offs;
if (colsize <= 0)
I_Error("Patch_Create: no column data!");
patch->columns = Z_Calloc(sizeof(column_t) * patch->width, PU_PATCH_DATA, NULL);
patch->posts = Z_Calloc(sizeof(post_t) * total_posts, PU_PATCH_DATA, NULL);
patch->pixels = Z_Calloc(sizeof(UINT8) * total_pixels, PU_PATCH_DATA, NULL);
patch->columns = Z_Calloc(colsize, PU_PATCH_DATA, NULL);
M_Memcpy(patch->columns, ((UINT8 *)source + LONG(source->columnofs[0])), colsize);
}
Patch_MakeColumns(source, patch->width, patch->pixels, patch->columns, patch->posts, false);
return patch;
}
void Patch_CalcDataSizes(softwarepatch_t *source, size_t *total_pixels, size_t *total_posts)
{
for (INT32 i = 0; i < source->width; i++)
{
doompost_t *src_posts = (doompost_t*)((UINT8 *)source + LONG(source->columnofs[i]));
for (doompost_t *post = src_posts; post->topdelta != 0xff ;)
{
(*total_posts)++;
(*total_pixels) += post->length;
post = (doompost_t *)((UINT8 *)post + post->length + 4);
}
}
}
void Patch_MakeColumns(softwarepatch_t *source, size_t num_columns, UINT8 *pixels, column_t *columns, post_t *posts, boolean flip)
{
column_t *column = flip ? columns + (num_columns - 1) : columns;
for (size_t i = 0; i < num_columns; i++)
{
size_t prevdelta = 0;
size_t data_offset = 0;
column->pixels = pixels;
column->posts = posts;
column->num_posts = 0;
doompost_t *src_posts = (doompost_t*)((UINT8 *)source + LONG(source->columnofs[i]));
for (doompost_t *post = src_posts; post->topdelta != 0xff ;)
{
size_t topdelta = post->topdelta;
if (topdelta <= prevdelta)
topdelta += prevdelta;
prevdelta = topdelta;
posts->topdelta = topdelta;
posts->length = (size_t)post->length;
posts->data_offset = data_offset;
memcpy(pixels, (UINT8 *)post + 3, post->length);
data_offset += posts->length;
pixels += posts->length;
column->num_posts++;
posts++;
post = (doompost_t *)((UINT8 *)post + post->length + 4);
}
if (flip)
column--;
else
column++;
}
}
//
// Frees a patch from memory.
//
@ -96,10 +145,12 @@ static void Patch_FreeData(patch_t *patch)
}
#endif
if (patch->columnofs)
Z_Free(patch->columnofs);
if (patch->pixels)
Z_Free(patch->pixels);
if (patch->columns)
Z_Free(patch->columns);
if (patch->posts)
Z_Free(patch->posts);
}
void Patch_Free(patch_t *patch)

View file

@ -19,6 +19,8 @@
// Patch functions
patch_t *Patch_Create(softwarepatch_t *source, size_t srcsize, void *dest);
void Patch_CalcDataSizes(softwarepatch_t *source, size_t *total_pixels, size_t *total_posts);
void Patch_MakeColumns(softwarepatch_t *source, size_t num_columns, UINT8 *pixels, column_t *columns, post_t *posts, boolean flip);
void Patch_Free(patch_t *patch);
#define Patch_FreeTag(tagnum) Patch_FreeTags(tagnum, tagnum)

View file

@ -538,8 +538,6 @@ void *Picture_GetPatchPixel(
INT32 x, INT32 y,
pictureflags_t flags)
{
fixed_t ofs;
column_t *column;
INT32 inbpp = Picture_FormatBPP(informat);
softwarepatch_t *doompatch = (softwarepatch_t *)patch;
boolean isdoompatch = Picture_IsDoomPatchFormat(informat);
@ -550,30 +548,30 @@ void *Picture_GetPatchPixel(
width = (isdoompatch ? SHORT(doompatch->width) : patch->width);
if (x >= 0 && x < width)
if (x < 0 || x >= width)
return NULL;
INT32 colx = (flags & PICFLAGS_XFLIP) ? (width-1)-x : x;
UINT8 *s8 = NULL;
UINT16 *s16 = NULL;
UINT32 *s32 = NULL;
if (isdoompatch)
{
INT32 colx = (flags & PICFLAGS_XFLIP) ? (width-1)-x : x;
INT32 topdelta, prevdelta = -1;
INT32 colofs = (isdoompatch ? LONG(doompatch->columnofs[colx]) : patch->columnofs[colx]);
INT32 prevdelta = -1;
INT32 colofs = LONG(doompatch->columnofs[colx]);
// Column offsets are pointers, so no casting is required.
if (isdoompatch)
column = (column_t *)((UINT8 *)doompatch + colofs);
else
column = (column_t *)((UINT8 *)patch->columns + colofs);
doompost_t *column = (doompost_t *)((UINT8 *)doompatch + colofs);
while (column->topdelta != 0xff)
{
UINT8 *s8 = NULL;
UINT16 *s16 = NULL;
UINT32 *s32 = NULL;
topdelta = column->topdelta;
INT32 topdelta = column->topdelta;
if (topdelta <= prevdelta)
topdelta += prevdelta;
prevdelta = topdelta;
ofs = (y - topdelta);
size_t ofs = y - topdelta;
if (y >= topdelta && ofs < column->length)
{
@ -592,12 +590,38 @@ void *Picture_GetPatchPixel(
}
if (inbpp == PICDEPTH_32BPP)
column = (column_t *)((UINT32 *)column + column->length);
column = (doompost_t *)((UINT32 *)column + column->length);
else if (inbpp == PICDEPTH_16BPP)
column = (column_t *)((UINT16 *)column + column->length);
column = (doompost_t *)((UINT16 *)column + column->length);
else
column = (column_t *)((UINT8 *)column + column->length);
column = (column_t *)((UINT8 *)column + 4);
column = (doompost_t *)((UINT8 *)column + column->length);
column = (doompost_t *)((UINT8 *)column + 4);
}
}
else
{
column_t *column = &patch->columns[colx];
for (size_t i = 0; i < column->num_posts; i++)
{
post_t *post = &column->posts[i];
size_t ofs = y - post->topdelta;
if (y >= (INT32)post->topdelta && ofs < post->length)
{
s8 = column->pixels + post->data_offset;
switch (inbpp)
{
case PICDEPTH_32BPP:
s32 = (UINT32 *)s8;
return &s32[ofs];
case PICDEPTH_16BPP:
s16 = (UINT16 *)s8;
return &s16[ofs];
default: // PICDEPTH_8BPP
return &s8[ofs];
}
}
}
}
@ -738,29 +762,25 @@ boolean Picture_CheckIfDoomPatch(softwarepatch_t *patch, size_t size)
/** Converts a texture to a flat.
*
* \param trickytex The texture number.
* \param texnum The texture number.
* \return The converted flat.
*/
void *Picture_TextureToFlat(size_t trickytex)
void *Picture_TextureToFlat(size_t texnum)
{
texture_t *texture;
size_t tex;
UINT8 *converted;
size_t flatsize;
fixed_t col, ofs;
column_t *column;
UINT8 *desttop, *dest, *deststop;
UINT8 *source;
if (trickytex >= (unsigned)numtextures)
if (texnum >= (unsigned)numtextures)
I_Error("Picture_TextureToFlat: invalid texture number!");
// Check the texture cache
// If the texture's not there, it'll be generated right now
tex = trickytex;
texture = textures[tex];
R_CheckTextureCache(tex);
texture = textures[texnum];
R_CheckTextureCache(texnum);
// Allocate the flat
flatsize = (texture->width * texture->height);
@ -770,41 +790,37 @@ void *Picture_TextureToFlat(size_t trickytex)
// Now we're gonna write to it
desttop = converted;
deststop = desttop + flatsize;
for (col = 0; col < texture->width; col++, desttop++)
if (!texture->holes)
{
// no post_t info
if (!texture->holes)
for (size_t col = 0; col < (size_t)texture->width; col++, desttop++)
{
column = (column_t *)(R_GetColumn(tex, col));
source = (UINT8 *)(column);
source = R_GetColumn(texnum, col)->pixels;
dest = desttop;
for (ofs = 0; dest < deststop && ofs < texture->height; ofs++)
for (size_t ofs = 0; dest < deststop && ofs < (size_t)texture->height; ofs++)
{
if (source[ofs] != TRANSPARENTPIXEL)
*dest = source[ofs];
dest += texture->width;
}
}
else
}
else
{
for (size_t col = 0; col < (size_t)texture->width; col++, desttop++)
{
INT32 topdelta, prevdelta = -1;
column = (column_t *)((UINT8 *)R_GetColumn(tex, col) - 3);
while (column->topdelta != 0xff)
column_t *column = (column_t *)R_GetColumn(texnum, col);
for (size_t i = 0; i < column->num_posts; i++)
{
topdelta = column->topdelta;
if (topdelta <= prevdelta)
topdelta += prevdelta;
prevdelta = topdelta;
dest = desttop + (topdelta * texture->width);
source = (UINT8 *)column + 3;
for (ofs = 0; dest < deststop && ofs < column->length; ofs++)
post_t *post = &column->posts[i];
dest = desttop + (post->topdelta * texture->width);
source = column->pixels + post->data_offset;
for (size_t ofs = 0; dest < deststop && ofs < post->length; ofs++)
{
if (source[ofs] != TRANSPARENTPIXEL)
*dest = source[ofs];
dest += texture->width;
}
column = (column_t *)((UINT8 *)column + column->length + 4);
}
}
}

View file

@ -75,7 +75,7 @@ void *Picture_GetPatchPixel(
INT32 x, INT32 y,
pictureflags_t flags);
void *Picture_TextureToFlat(size_t trickytex);
void *Picture_TextureToFlat(size_t texnum);
INT32 Picture_FormatBPP(pictureformat_t format);
boolean Picture_IsPatchFormat(pictureformat_t format);

View file

@ -669,9 +669,7 @@ static void R_DrawSkyPlane(visplane_t *pl)
angle = (pl->viewangle + xtoviewangle[x])>>ANGLETOSKYSHIFT;
dc_iscale = FixedMul(skyscale, FINECOSINE(xtoviewangle[x]>>ANGLETOFINESHIFT));
dc_x = x;
dc_source =
R_GetColumn(texturetranslation[skytexture],
-angle); // get negative of angle for each column to display sky correct way round! --Monster Iestyn 27/01/18
dc_source = R_GetColumn(texturetranslation[skytexture], -angle)->pixels; // get negative of angle for each column to display sky correct way round! --Monster Iestyn 27/01/18
colfunc();
}
}

View file

@ -86,10 +86,7 @@ static fixed_t *maskedtextureheight = NULL;
static void R_Render2sidedMultiPatchColumn(column_t *column)
{
INT32 topscreen, bottomscreen;
topscreen = sprtopscreen; // + spryscale*column->topdelta; topdelta is 0 for the wall
bottomscreen = topscreen + spryscale * lengthcol;
INT32 bottomscreen = sprtopscreen + spryscale * lengthcol;
dc_yl = (sprtopscreen+FRACUNIT-1)>>FRACBITS;
dc_yh = (bottomscreen-1)>>FRACBITS;
@ -110,7 +107,7 @@ static void R_Render2sidedMultiPatchColumn(column_t *column)
if (dc_yl <= dc_yh && dc_yh < vid.height && dc_yh > 0)
{
dc_source = (UINT8 *)column + 3;
dc_source = column->pixels;
if (colfunc == colfuncs[BASEDRAWFUNC])
(colfuncs[COLDRAWFUNC_TWOSMULTIPATCH])();
@ -382,7 +379,7 @@ void R_RenderMaskedSegRange(drawseg_t *ds, INT32 x1, INT32 x2)
dc_iscale = 0xffffffffu / (unsigned)spryscale;
// draw the texture
col = (column_t *)((UINT8 *)R_GetColumn(texnum, maskedtexturecol[dc_x]) - 3);
col = R_GetColumn(texnum, maskedtexturecol[dc_x]);
for (i = 0; i < dc_numlights; i++)
{
@ -457,7 +454,7 @@ void R_RenderMaskedSegRange(drawseg_t *ds, INT32 x1, INT32 x2)
dc_iscale = 0xffffffffu / (unsigned)spryscale;
// draw the texture
col = (column_t *)((UINT8 *)R_GetColumn(texnum, maskedtexturecol[dc_x]) - 3);
col = R_GetColumn(texnum, maskedtexturecol[dc_x]);
#if 0 // Disabling this allows inside edges to render below the planes, for until the clipping is fixed to work right when POs are near the camera. -Red
if (curline->dontrenderme && curline->polyseg && (curline->polyseg->flags & POF_RENDERPLANES))
@ -897,7 +894,7 @@ void R_RenderThickSideRange(drawseg_t *ds, INT32 x1, INT32 x2, ffloor_t *pfloor)
dc_iscale = 0xffffffffu / (unsigned)spryscale;
// Get data for the column
col = (column_t *)((UINT8 *)R_GetColumn(texnum,maskedtexturecol[dc_x]) - 3);
col = R_GetColumn(texnum,maskedtexturecol[dc_x]);
// SoM: New code does not rely on R_DrawColumnShadowed_8 which
// will (hopefully) put less strain on the stack.
@ -1336,7 +1333,7 @@ static void R_RenderSegLoop (void)
dc_yl = yl;
dc_yh = yh;
dc_texturemid = rw_midtexturemid;
dc_source = R_GetColumn(midtexture,texturecolumn + (rw_offset_mid>>FRACBITS));
dc_source = R_GetColumn(midtexture,texturecolumn + (rw_offset_mid>>FRACBITS))->pixels;
dc_texheight = textureheight[midtexture]>>FRACBITS;
//profile stuff ---------------------------------------------------------
@ -1397,7 +1394,7 @@ static void R_RenderSegLoop (void)
dc_yl = yl;
dc_yh = mid;
dc_texturemid = rw_toptexturemid;
dc_source = R_GetColumn(toptexture,texturecolumn + (rw_offset_top>>FRACBITS));
dc_source = R_GetColumn(toptexture,texturecolumn + (rw_offset_top>>FRACBITS))->pixels;
dc_texheight = textureheight[toptexture]>>FRACBITS;
colfunc();
ceilingclip[rw_x] = (INT16)mid;
@ -1433,8 +1430,7 @@ static void R_RenderSegLoop (void)
dc_yl = mid;
dc_yh = yh;
dc_texturemid = rw_bottomtexturemid;
dc_source = R_GetColumn(bottomtexture,
texturecolumn + (rw_offset_bot>>FRACBITS));
dc_source = R_GetColumn(bottomtexture, texturecolumn + (rw_offset_bot>>FRACBITS))->pixels;
dc_texheight = textureheight[bottomtexture]>>FRACBITS;
colfunc();
floorclip[rw_x] = (INT16)mid;

View file

@ -48,7 +48,7 @@ INT32 numtextures = 0; // total number of textures found,
// size of following tables
texture_t **textures = NULL;
UINT32 **texturecolumnofs; // column offset lookup table for each texture
column_t **texturecolumns; // columns for each texture
UINT8 **texturecache; // graphics data for each generated full-size texture
INT32 *texturewidth;
@ -78,7 +78,7 @@ static INT32 tidcachelen = 0;
// R_DrawColumnInCache
// Clip and draw a column from a patch into a cached post.
//
static inline void R_DrawColumnInCache(column_t *patch, UINT8 *cache, texpatch_t *originPatch, INT32 cacheheight, INT32 patchheight)
static inline void R_DrawColumnInCache(doompost_t *patch, UINT8 *cache, texpatch_t *originPatch, INT32 cacheheight, INT32 patchheight)
{
INT32 count, position;
UINT8 *source;
@ -110,7 +110,7 @@ static inline void R_DrawColumnInCache(column_t *patch, UINT8 *cache, texpatch_t
if (count > 0)
M_Memcpy(cache + position, source, count);
patch = (column_t *)((UINT8 *)patch + patch->length + 4);
patch = (doompost_t *)((UINT8 *)patch + patch->length + 4);
}
}
@ -118,7 +118,7 @@ static inline void R_DrawColumnInCache(column_t *patch, UINT8 *cache, texpatch_t
// R_DrawFlippedColumnInCache
// Similar to R_DrawColumnInCache; it draws the column inverted, however.
//
static inline void R_DrawFlippedColumnInCache(column_t *patch, UINT8 *cache, texpatch_t *originPatch, INT32 cacheheight, INT32 patchheight)
static inline void R_DrawFlippedColumnInCache(doompost_t *patch, UINT8 *cache, texpatch_t *originPatch, INT32 cacheheight, INT32 patchheight)
{
INT32 count, position;
UINT8 *source, *dest;
@ -153,7 +153,7 @@ static inline void R_DrawFlippedColumnInCache(column_t *patch, UINT8 *cache, tex
*dest++ = *source;
}
patch = (column_t *)((UINT8 *)patch + patch->length + 4);
patch = (doompost_t *)((UINT8 *)patch + patch->length + 4);
}
}
@ -161,7 +161,7 @@ static inline void R_DrawFlippedColumnInCache(column_t *patch, UINT8 *cache, tex
// R_DrawBlendColumnInCache
// Draws a translucent column into the cache, applying a half-cooked equation to get a proper translucency value (Needs code in R_GenerateTexture()).
//
static inline void R_DrawBlendColumnInCache(column_t *patch, UINT8 *cache, texpatch_t *originPatch, INT32 cacheheight, INT32 patchheight)
static inline void R_DrawBlendColumnInCache(doompost_t *patch, UINT8 *cache, texpatch_t *originPatch, INT32 cacheheight, INT32 patchheight)
{
INT32 count, position;
UINT8 *source, *dest;
@ -198,7 +198,7 @@ static inline void R_DrawBlendColumnInCache(column_t *patch, UINT8 *cache, texpa
*dest = ASTBlendPaletteIndexes(*dest, *source, originPatch->style, originPatch->alpha);
}
patch = (column_t *)((UINT8 *)patch + patch->length + 4);
patch = (doompost_t *)((UINT8 *)patch + patch->length + 4);
}
}
@ -206,7 +206,7 @@ static inline void R_DrawBlendColumnInCache(column_t *patch, UINT8 *cache, texpa
// R_DrawBlendFlippedColumnInCache
// Similar to the one above except that the column is inverted.
//
static inline void R_DrawBlendFlippedColumnInCache(column_t *patch, UINT8 *cache, texpatch_t *originPatch, INT32 cacheheight, INT32 patchheight)
static inline void R_DrawBlendFlippedColumnInCache(doompost_t *patch, UINT8 *cache, texpatch_t *originPatch, INT32 cacheheight, INT32 patchheight)
{
INT32 count, position;
UINT8 *source, *dest;
@ -242,7 +242,7 @@ static inline void R_DrawBlendFlippedColumnInCache(column_t *patch, UINT8 *cache
*dest = ASTBlendPaletteIndexes(*dest, *source, originPatch->style, originPatch->alpha);
}
patch = (column_t *)((UINT8 *)patch + patch->length + 4);
patch = (doompost_t *)((UINT8 *)patch + patch->length + 4);
}
}
@ -263,16 +263,8 @@ UINT8 *R_GenerateTexture(size_t texnum)
UINT8 *blocktex;
texture_t *texture;
texpatch_t *patch;
softwarepatch_t *realpatch;
UINT8 *pdata;
int x, x1, x2, i, width, height;
size_t blocksize;
column_t *patchcol;
UINT8 *colofs;
UINT16 wadnum;
lumpnum_t lumpnum;
size_t lumplength;
I_Assert(texnum <= (size_t)numtextures);
texture = textures[texnum];
@ -289,11 +281,11 @@ UINT8 *R_GenerateTexture(size_t texnum)
boolean holey = false;
patch = texture->patches;
wadnum = patch->wad;
lumpnum = patch->lump;
lumplength = W_LumpLengthPwad(wadnum, lumpnum);
pdata = W_CacheLumpNumPwad(wadnum, lumpnum, PU_CACHE);
realpatch = (softwarepatch_t *)pdata;
UINT16 wadnum = patch->wad;
lumpnum_t lumpnum = patch->lump;
size_t lumplength = W_LumpLengthPwad(wadnum, lumpnum);
UINT8 *pdata = W_CacheLumpNumPwad(wadnum, lumpnum, PU_CACHE);
softwarepatch_t *realpatch = (softwarepatch_t *)pdata;
#ifndef NO_PNG_LUMPS
if (Picture_IsLumpPNG((UINT8 *)realpatch, lumplength))
@ -307,10 +299,10 @@ UINT8 *R_GenerateTexture(size_t texnum)
// Check the patch for holes.
if (texture->width > SHORT(realpatch->width) || texture->height > SHORT(realpatch->height))
holey = true;
colofs = (UINT8 *)realpatch->columnofs;
UINT8 *colofs = (UINT8 *)realpatch->columnofs;
for (x = 0; x < texture->width && !holey; x++)
{
column_t *col = (column_t *)((UINT8 *)realpatch + LONG(*(UINT32 *)&colofs[x<<2]));
doompost_t *col = (doompost_t *)((UINT8 *)realpatch + LONG(*(UINT32 *)&colofs[x<<2]));
INT32 topdelta, prevdelta = -1, y = 0;
while (col->topdelta != 0xff)
{
@ -321,7 +313,7 @@ UINT8 *R_GenerateTexture(size_t texnum)
if (topdelta > y)
break;
y = topdelta + col->length + 1;
col = (column_t *)((UINT8 *)col + col->length + 4);
col = (doompost_t *)((UINT8 *)col + col->length + 4);
}
if (y < texture->height)
holey = true; // this texture is HOLEy! D:
@ -332,26 +324,26 @@ UINT8 *R_GenerateTexture(size_t texnum)
{
texture->holes = true;
texture->flip = patch->flip;
blocksize = lumplength;
block = Z_Calloc(blocksize, PU_STATIC, // will change tag at end of this function
&texturecache[texnum]);
M_Memcpy(block, realpatch, blocksize);
size_t total_pixels = 0;
size_t total_posts = 0;
Patch_CalcDataSizes(realpatch, &total_pixels, &total_posts);
blocksize = (sizeof(column_t) * texture->width) + (sizeof(post_t) * total_posts) + (sizeof(UINT8) * total_pixels);
texturememory += blocksize;
// use the patch's column lookup
colofs = (block + 8);
texturecolumnofs[texnum] = (UINT32 *)colofs;
block = Z_Calloc(blocksize, PU_STATIC, &texturecache[texnum]);
blocktex = block;
if (patch->flip & 1) // flip the patch horizontally
{
UINT8 *realcolofs = (UINT8 *)realpatch->columnofs;
for (x = 0; x < texture->width; x++)
*(UINT32 *)&colofs[x<<2] = realcolofs[( texture->width-1-x )<<2]; // swap with the offset of the other side of the texture
}
// we can't as easily flip the patch vertically sadly though,
// we have wait until the texture itself is drawn to do that
for (x = 0; x < texture->width; x++)
*(UINT32 *)&colofs[x<<2] = LONG(LONG(*(UINT32 *)&colofs[x<<2]) + 3);
UINT8 *pixels = block;
column_t *columns = (column_t *)(block + (sizeof(UINT8) * total_pixels));
post_t *posts = (post_t *)(block + (sizeof(UINT8) * total_pixels) + (sizeof(column_t) * texture->width));
texturecolumns[texnum] = columns;
Patch_MakeColumns(realpatch, texture->width, pixels, columns, posts, texture->flip);
goto done;
}
@ -362,35 +354,44 @@ UINT8 *R_GenerateTexture(size_t texnum)
multipatch:
texture->holes = false;
texture->flip = 0;
blocksize = (texture->width * 4) + (texture->width * texture->height);
size_t total_pixels = texture->width * texture->height;
blocksize = (sizeof(column_t) * texture->width) + (sizeof(UINT8) * total_pixels);
texturememory += blocksize;
block = Z_Malloc(blocksize+1, PU_STATIC, &texturecache[texnum]);
memset(block, TRANSPARENTPIXEL, blocksize+1); // Transparency hack
block = Z_Malloc(blocksize, PU_STATIC, &texturecache[texnum]);
blocktex = block;
memset(blocktex, TRANSPARENTPIXEL, total_pixels); // Transparency hack
// columns lookup table
colofs = block;
texturecolumnofs[texnum] = (UINT32 *)colofs;
column_t *columns = (column_t *)(block + (sizeof(UINT8) * total_pixels));
texturecolumns[texnum] = columns;
// texture data after the lookup table
blocktex = block + (texture->width*4);
size_t data_offset = 0;
for (x = 0; x < texture->width; x++)
{
column_t *column = &columns[x];
column->num_posts = 0;
column->posts = NULL;
column->pixels = blocktex + data_offset;
data_offset += texture->height;
}
// Composite the columns together.
for (i = 0, patch = texture->patches; i < texture->patchcount; i++, patch++)
{
boolean dealloc = true;
static void (*ColumnDrawerPointer)(column_t *, UINT8 *, texpatch_t *, INT32, INT32); // Column drawing function pointer.
static void (*columnDrawer)(doompost_t *, UINT8 *, texpatch_t *, INT32, INT32); // Column drawing function pointer.
if (patch->style != AST_COPY)
ColumnDrawerPointer = (patch->flip & 2) ? R_DrawBlendFlippedColumnInCache : R_DrawBlendColumnInCache;
columnDrawer = (patch->flip & 2) ? R_DrawBlendFlippedColumnInCache : R_DrawBlendColumnInCache;
else
ColumnDrawerPointer = (patch->flip & 2) ? R_DrawFlippedColumnInCache : R_DrawColumnInCache;
columnDrawer = (patch->flip & 2) ? R_DrawFlippedColumnInCache : R_DrawColumnInCache;
wadnum = patch->wad;
lumpnum = patch->lump;
pdata = W_CacheLumpNumPwad(wadnum, lumpnum, PU_CACHE);
lumplength = W_LumpLengthPwad(wadnum, lumpnum);
realpatch = (softwarepatch_t *)pdata;
dealloc = true;
UINT16 wadnum = patch->wad;
lumpnum_t lumpnum = patch->lump;
size_t lumplength = W_LumpLengthPwad(wadnum, lumpnum);
UINT8 *pdata = W_CacheLumpNumPwad(wadnum, lumpnum, PU_CACHE);
softwarepatch_t *realpatch = (softwarepatch_t *)pdata;
boolean dealloc = true;
#ifndef NO_PNG_LUMPS
if (Picture_IsLumpPNG((UINT8 *)realpatch, lumplength))
@ -441,14 +442,13 @@ UINT8 *R_GenerateTexture(size_t texnum)
for (; x < x2; x++)
{
doompost_t *patchcol;
if (patch->flip & 1)
patchcol = (column_t *)((UINT8 *)realpatch + LONG(realpatch->columnofs[(x1+width-1)-x]));
patchcol = (doompost_t *)((UINT8 *)realpatch + LONG(realpatch->columnofs[(x1+width-1)-x]));
else
patchcol = (column_t *)((UINT8 *)realpatch + LONG(realpatch->columnofs[x-x1]));
patchcol = (doompost_t *)((UINT8 *)realpatch + LONG(realpatch->columnofs[x-x1]));
// generate column ofset lookup
*(UINT32 *)&colofs[x<<2] = LONG((x * texture->height) + (texture->width*4));
ColumnDrawerPointer(patchcol, block + LONG(*(UINT32 *)&colofs[x<<2]), patch, texture->height, height);
columnDrawer(patchcol, columns[x].pixels, patch, texture->height, height);
}
if (dealloc)
@ -513,24 +513,19 @@ void R_CheckTextureCache(INT32 tex)
R_GenerateTexture(tex);
}
//
// R_GetColumn
//
UINT8 *R_GetColumn(fixed_t tex, INT32 col)
column_t *R_GetColumn(fixed_t tex, INT32 col)
{
UINT8 *data;
INT32 width = texturewidth[tex];
if (width & (width - 1))
col = (UINT32)col % width;
else
col &= (width - 1);
data = texturecache[tex];
UINT8 *data = texturecache[tex];
if (!data)
data = R_GenerateTexture(tex);
R_GenerateTexture(tex);
return data + LONG(texturecolumnofs[tex][col]);
return &texturecolumns[tex][col];
}
void *R_GetFlat(lumpnum_t flatlumpnum)
@ -1016,7 +1011,7 @@ static void R_AllocateTextures(INT32 add)
recallocuser(&textures, oldsize, newsize);
// Allocate texture column offset table.
recallocuser(&texturecolumnofs, oldsize, newsize);
recallocuser(&texturecolumns, oldsize, newsize);
// Allocate texture referencing cache.
recallocuser(&texturecache, oldsize, newsize);
// Allocate texture width table.

View file

@ -72,7 +72,7 @@ extern texture_t **textures;
extern INT32 *texturewidth;
extern fixed_t *textureheight; // needed for texture pegging
extern UINT32 **texturecolumnofs; // column offset lookup table for each texture
extern column_t **texturecolumns; // columns for each texture
extern UINT8 **texturecache; // graphics data for each generated full-size texture
// Load TEXTURES definitions, create lookup tables
@ -89,7 +89,7 @@ void R_ClearTextureNumCache(boolean btell);
// Retrieve texture data.
void *R_GetLevelFlat(levelflat_t *levelflat);
UINT8 *R_GetColumn(fixed_t tex, INT32 col);
column_t *R_GetColumn(fixed_t tex, INT32 col);
void *R_GetFlat(lumpnum_t flatnum);
boolean R_CheckPowersOfTwo(void);

View file

@ -639,23 +639,14 @@ fixed_t windowtop = 0, windowbottom = 0;
void R_DrawMaskedColumn(column_t *column)
{
INT32 topscreen;
INT32 bottomscreen;
fixed_t basetexturemid;
INT32 topdelta, prevdelta = 0;
fixed_t basetexturemid = dc_texturemid;
basetexturemid = dc_texturemid;
for (; column->topdelta != 0xff ;)
for (size_t i = 0; i < column->num_posts; i++)
{
// calculate unclipped screen coordinates
// for post
topdelta = column->topdelta;
if (topdelta <= prevdelta)
topdelta += prevdelta;
prevdelta = topdelta;
topscreen = sprtopscreen + spryscale*topdelta;
bottomscreen = topscreen + spryscale*column->length;
post_t *post = &column->posts[i];
INT32 topscreen = sprtopscreen + spryscale*post->topdelta;
INT32 bottomscreen = topscreen + spryscale*post->length;
dc_yl = (topscreen+FRACUNIT-1)>>FRACBITS;
dc_yh = (bottomscreen-1)>>FRACBITS;
@ -679,8 +670,8 @@ void R_DrawMaskedColumn(column_t *column)
if (dc_yl <= dc_yh && dc_yh > 0)
{
dc_source = (UINT8 *)column + 3;
dc_texturemid = basetexturemid - (topdelta<<FRACBITS);
dc_source = column->pixels + post->data_offset;
dc_texturemid = basetexturemid - (post->topdelta<<FRACBITS);
// Drawn by R_DrawColumn.
// This stuff is a likely cause of the splitscreen water crash bug.
@ -693,7 +684,6 @@ void R_DrawMaskedColumn(column_t *column)
I_Error("R_DrawMaskedColumn: Invalid ylookup for dc_yl %d", dc_yl);
#endif
}
column = (column_t *)((UINT8 *)column + column->length + 4);
}
dc_texturemid = basetexturemid;
@ -706,21 +696,15 @@ void R_DrawFlippedMaskedColumn(column_t *column)
INT32 topscreen;
INT32 bottomscreen;
fixed_t basetexturemid = dc_texturemid;
INT32 topdelta, prevdelta = -1;
UINT8 *d,*s;
for (; column->topdelta != 0xff ;)
for (size_t i = 0; i < column->num_posts; i++)
{
// calculate unclipped screen coordinates
// for post
topdelta = column->topdelta;
if (topdelta <= prevdelta)
topdelta += prevdelta;
prevdelta = topdelta;
topdelta = lengthcol-column->length-topdelta;
post_t *post = &column->posts[i];
INT32 topdelta = lengthcol-post->length-post->topdelta;
topscreen = sprtopscreen + spryscale*topdelta;
bottomscreen = sprbotscreen == INT32_MAX ? topscreen + spryscale*column->length
: sprbotscreen + spryscale*column->length;
bottomscreen = sprbotscreen == INT32_MAX ? topscreen + spryscale*post->length
: sprbotscreen + spryscale*post->length;
dc_yl = (topscreen+FRACUNIT-1)>>FRACBITS;
dc_yh = (bottomscreen-1)>>FRACBITS;
@ -744,8 +728,8 @@ void R_DrawFlippedMaskedColumn(column_t *column)
if (dc_yl <= dc_yh && dc_yh > 0)
{
dc_source = ZZ_Alloc(column->length);
for (s = (UINT8 *)column+2+column->length, d = dc_source; d < dc_source+column->length; --s)
dc_source = ZZ_Alloc(post->length);
for (s = column->pixels+post->data_offset+post->length, d = dc_source; d < dc_source+post->length; --s)
*d++ = *s;
dc_texturemid = basetexturemid - (topdelta<<FRACBITS);
@ -758,7 +742,6 @@ void R_DrawFlippedMaskedColumn(column_t *column)
#endif
Z_Free(dc_source);
}
column = (column_t *)((UINT8 *)column + column->length + 4);
}
dc_texturemid = basetexturemid;
@ -950,7 +933,7 @@ static void R_DrawVisSprite(vissprite_t *vis)
sprtopscreen = (centeryfrac - FixedMul(dc_texturemid, spryscale));
dc_iscale = (0xffffffffu / (unsigned)spryscale);
column = (column_t *)((UINT8 *)patch->columns + (patch->columnofs[texturecolumn]));
column = &patch->columns[texturecolumn];
localcolfunc (column);
}
@ -968,9 +951,9 @@ static void R_DrawVisSprite(vissprite_t *vis)
texturecolumn = frac>>FRACBITS;
if (texturecolumn < 0 || texturecolumn >= pwidth)
I_Error("R_DrawSpriteRange: bad texturecolumn at %d from end", vis->x2 - dc_x);
column = (column_t *)((UINT8 *)patch->columns + (patch->columnofs[texturecolumn]));
column = &patch->columns[texturecolumn];
#else
column = (column_t *)((UINT8 *)patch->columns + (patch->columnofs[frac>>FRACBITS]));
column = &patch->columns[frac>>FRACBITS];
#endif
sprtopscreen = (centeryfrac - FixedMul(dc_texturemid, spryscale));
@ -990,9 +973,9 @@ static void R_DrawVisSprite(vissprite_t *vis)
texturecolumn = frac>>FRACBITS;
if (texturecolumn < 0 || texturecolumn >= pwidth)
I_Error("R_DrawSpriteRange: bad texturecolumn at %d from end", vis->x2 - dc_x);
column = (column_t *)((UINT8 *)patch->columns + (patch->columnofs[texturecolumn]));
column = &patch->columns[texturecolumn];
#else
column = (column_t *)((UINT8 *)patch->columns + (patch->columnofs[frac>>FRACBITS]));
column = &patch->columns[frac>>FRACBITS];
#endif
localcolfunc (column);
}
@ -1057,9 +1040,9 @@ static void R_DrawPrecipitationVisSprite(vissprite_t *vis)
if (texturecolumn < 0 || texturecolumn >= patch->width)
I_Error("R_DrawPrecipitationSpriteRange: bad texturecolumn");
column = (column_t *)((UINT8 *)patch->columns + (patch->columnofs[texturecolumn]));
column = &patch->columns[texturecolumn];
#else
column = (column_t *)((UINT8 *)patch->columns + (patch->columnofs[frac>>FRACBITS]));
column = &patch->columns[frac>>FRACBITS];
#endif
R_DrawMaskedColumn(column);
}

View file

@ -516,7 +516,7 @@ void V_DrawStretchyFixedPatch(fixed_t x, fixed_t y, fixed_t pscale, fixed_t vsca
fixed_t col, ofs, colfrac, rowfrac, fdup, vdup;
INT32 dupx, dupy;
const column_t *column;
column_t *column;
UINT8 *desttop, *dest, *deststart, *destend;
const UINT8 *source, *deststop;
fixed_t pwidth; // patch width
@ -703,12 +703,12 @@ void V_DrawStretchyFixedPatch(fixed_t x, fixed_t y, fixed_t pscale, fixed_t vsca
if (!(scrn & V_SCALEPATCHMASK))
{
// if it's meant to cover the whole screen, black out the rest (ONLY IF TOP LEFT ISN'T TRANSPARENT)
if (x == 0 && patch->width == BASEVIDWIDTH && y == 0 && patch->height == BASEVIDHEIGHT)
if (!v_translevel && x == 0 && patch->width == BASEVIDWIDTH && y == 0 && patch->height == BASEVIDHEIGHT)
{
column = (const column_t *)((const UINT8 *)(patch->columns) + (patch->columnofs[0]));
if (!column->topdelta)
column = &patch->columns[0];
if (column->num_posts && !column->posts[0].topdelta)
{
source = (const UINT8 *)(column) + 3;
source = column->pixels;
V_DrawFill(0, 0, BASEVIDWIDTH, BASEVIDHEIGHT, source[0]);
}
}
@ -758,7 +758,6 @@ void V_DrawStretchyFixedPatch(fixed_t x, fixed_t y, fixed_t pscale, fixed_t vsca
for (col = 0; (col>>FRACBITS) < patch->width; col += colfrac, ++offx, desttop++)
{
INT32 topdelta, prevdelta = -1;
if (scrn & V_FLIP) // offx is measured from right edge instead of left
{
if (x+pwidth-offx < 0) // don't draw off the left of the screen (WRAP PREVENTION)
@ -773,27 +772,24 @@ void V_DrawStretchyFixedPatch(fixed_t x, fixed_t y, fixed_t pscale, fixed_t vsca
if (x+offx >= vid.width) // don't draw off the right of the screen (WRAP PREVENTION)
break;
}
column = (const column_t *)((const UINT8 *)(patch->columns) + (patch->columnofs[col>>FRACBITS]));
while (column->topdelta != 0xff)
column = &patch->columns[col>>FRACBITS];
for (size_t i = 0; i < column->num_posts; i++)
{
topdelta = column->topdelta;
if (topdelta <= prevdelta)
topdelta += prevdelta;
prevdelta = topdelta;
source = (const UINT8 *)(column) + 3;
post_t *post = &column->posts[i];
source = column->pixels + post->data_offset;
dest = desttop;
if (scrn & V_FLIP)
dest = deststart + (destend - desttop);
dest += FixedInt(FixedMul(topdelta<<FRACBITS,vdup))*vid.width;
dest += FixedInt(FixedMul(post->topdelta<<FRACBITS,vdup))*vid.width;
for (ofs = 0; dest < deststop && (ofs>>FRACBITS) < column->length; ofs += rowfrac)
for (ofs = 0; dest < deststop && (size_t)(ofs>>FRACBITS) < post->length; ofs += rowfrac)
{
if (dest >= screens[scrn&V_PARAMMASK]) // don't draw off the top of the screen (CRASH PREVENTION)
*dest = patchdrawfunc(dest, source, ofs);
dest += vid.width;
}
column = (const column_t *)((const UINT8 *)column + column->length + 4);
}
}
}
@ -808,7 +804,7 @@ void V_DrawCroppedPatch(fixed_t x, fixed_t y, fixed_t pscale, fixed_t vscale, IN
fixed_t col, ofs, colfrac, rowfrac, fdup, vdup;
INT32 dupx, dupy;
const column_t *column;
column_t *column;
UINT8 *desttop, *dest;
const UINT8 *source, *deststop;
@ -1044,20 +1040,18 @@ void V_DrawCroppedPatch(fixed_t x, fixed_t y, fixed_t pscale, fixed_t vscale, IN
for (col = sx; (col>>FRACBITS) < patch->width && (col - sx) < w; col += colfrac, ++x, desttop++)
{
INT32 topdelta, prevdelta = -1;
if (x < 0) // don't draw off the left of the screen (WRAP PREVENTION)
continue;
if (x >= vid.width) // don't draw off the right of the screen (WRAP PREVENTION)
break;
column = (const column_t *)((const UINT8 *)(patch->columns) + (patch->columnofs[col>>FRACBITS]));
while (column->topdelta != 0xff)
column = &patch->columns[col>>FRACBITS];
for (size_t i = 0; i < column->num_posts; i++)
{
topdelta = column->topdelta;
if (topdelta <= prevdelta)
topdelta += prevdelta;
prevdelta = topdelta;
source = (const UINT8 *)(column) + 3;
post_t *post = &column->posts[i];
INT32 topdelta = post->topdelta;
source = column->pixels + post->data_offset;
dest = desttop;
if ((topdelta<<FRACBITS)-sy > 0)
{
@ -1067,13 +1061,12 @@ void V_DrawCroppedPatch(fixed_t x, fixed_t y, fixed_t pscale, fixed_t vscale, IN
else
ofs = sy-(topdelta<<FRACBITS);
for (; dest < deststop && (ofs>>FRACBITS) < column->length && ((ofs - sy) + (topdelta<<FRACBITS)) < h; ofs += rowfrac)
for (; dest < deststop && (size_t)(ofs>>FRACBITS) < post->length && ((ofs - sy) + (topdelta<<FRACBITS)) < h; ofs += rowfrac)
{
if (dest >= screens[scrn&V_PARAMMASK]) // don't draw off the top of the screen (CRASH PREVENTION)
*dest = patchdrawfunc(dest, source, ofs);
dest += vid.width;
}
column = (const column_t *)((const UINT8 *)column + column->length + 4);
}
}
}