Skip to content

Commit

Permalink
composite all textures, whether single-patched or not (#97)
Browse files Browse the repository at this point in the history
* composite all textures, whether single-patched or not

With this commit, Crispy now composes all textures, whether they are
single-patched or not. It generates to composites per texture, one for
rendering mid-textures on 2S wall which may contain translucent areas,
and another one for rendering textures on 1S walls and the sky,
respectively.

No column is ever read directly from a patch lump anymore. This keeps
the Medusa bug fixed but also fixes graphical glitches with e.g.
single-patched textures that are shorter than the patch, etc.

* initialize opaque texture column offset earlier

* compose tall patch compliant texture columns

Once we pass the 254 pixel boundary, the topdelta value becomes relative.
  • Loading branch information
fabiangreffrath committed Nov 24, 2020
1 parent 59a3488 commit 55b86f0
Show file tree
Hide file tree
Showing 3 changed files with 76 additions and 17 deletions.
90 changes: 74 additions & 16 deletions Source/r_data.c
Expand Up @@ -108,11 +108,14 @@ int firstspritelump, lastspritelump, numspritelumps;
int numtextures;
texture_t **textures;
int *texturewidthmask;
int *texturewidth;
fixed_t *textureheight; //needed for texture pegging (and TFE fix - killough)
int *texturecompositesize;
short **texturecolumnlump;
unsigned **texturecolumnofs; // killough 4/9/98: make 32-bit
unsigned **texturecolumnofs2;
byte **texturecomposite;
byte **texturecomposite2;
int *flattranslation; // for global animation
int *texturetranslation;

Expand Down Expand Up @@ -199,11 +202,15 @@ static void R_GenerateComposite(int texnum)
texpatch_t *patch = texture->patches;
short *collump = texturecolumnlump[texnum];
unsigned *colofs = texturecolumnofs[texnum]; // killough 4/9/98: make 32-bit
unsigned *colofs2 = texturecolumnofs2[texnum];
int i = texture->patchcount;
// killough 4/9/98: marks to identify transparent regions in merged textures
byte *marks = calloc(texture->width, texture->height), *source;

// [crispy] initialize composite background
// [FG] memory block for opaque textures
byte *block2 = Z_Malloc(texture->width * texture->height, PU_STATIC,
(void **) &texturecomposite2[texnum]);
// [FG] initialize composite background to palette index 0 (usually black)
memset(block, 0, texturecompositesize[texnum]);

for (; --i >=0; patch++)
Expand All @@ -217,10 +224,13 @@ static void R_GenerateComposite(int texnum)
if (x2 > texture->width)
x2 = texture->width;
for (x = x1; x < x2 ; x++)
if (collump[x] == -1) // Column has multiple patches?
// [crispy] generate composites for single-patched columns as well
// if (collump[x] == -1) // Column has multiple patches?
// killough 1/25/98, 4/9/98: Fix medusa bug.
R_DrawColumnInCache((column_t*)((byte*) realpatch + LONG(cofs[x])),
block + colofs[x], patch->originy,
// [FG] single-patched columns are normally not composited
// but directly read from the patch lump ignoring their originy
block + colofs[x], collump[x] == -1 ? patch->originy : 0,
texture->height, marks + x*texture->height);
}

Expand All @@ -229,40 +239,54 @@ static void R_GenerateComposite(int texnum)

source = malloc(texture->height); // temporary column
for (i=0; i < texture->width; i++)
if (collump[i] == -1) // process only multipatched columns
// [FG] generate composites for all columns
// if (collump[i] == -1) // process only multipatched columns
{
column_t *col = (column_t *)(block + colofs[i] - 3); // cached column
const byte *mark = marks + i * texture->height;
int j = 0;
// [crispy] absolut topdelta for first 254 pixels, then relative
int abstop, reltop = 0;
boolean relative = false;

// save column in temporary so we can shuffle it around
memcpy(source, (byte *) col + 3, texture->height);
// [FG] copy composited columns to opaque texture
memcpy(block2 + colofs2[i], source, texture->height);

for (;;) // reconstruct the column by scanning transparency marks
{
unsigned len; // killough 12/98

while (j < texture->height && !mark[j]) // skip transparent cells
j++;
while (j < texture->height && reltop < 254 && !mark[j]) // skip transparent cells
j++, reltop++;

if (j >= texture->height) // if at end of column
{
col->topdelta = -1; // end-of-column marker
break;
}

col->topdelta = j; // starting offset of post
// [crispy] absolut topdelta for first 254 pixels, then relative
col->topdelta = relative ? reltop : j; // starting offset of post

// [crispy] once we pass the 254 boundary, topdelta becomes relative
if ((abstop = j) >= 254)
{
relative = true;
reltop = 0;
}

// killough 12/98:
// Use 32-bit len counter, to support tall 1s multipatched textures

for (len = 0; j < texture->height && mark[j]; j++)
for (len = 0; j < texture->height && reltop < 254 && mark[j]; j++, reltop++)
len++; // count opaque cells

col->length = len; // killough 12/98: intentionally truncate length

// copy opaque cells from the temporary back into the column
memcpy((byte *) col + 3, source + col->topdelta, len);
memcpy((byte *) col + 3, source + abstop, len);
col = (column_t *)((byte *) col + len + 4); // next post
}
}
Expand All @@ -273,6 +297,7 @@ static void R_GenerateComposite(int texnum)
// it is purgable from zone memory.

Z_ChangeTag(block, PU_CACHE);
Z_ChangeTag(block2, PU_CACHE);
}

//
Expand All @@ -289,6 +314,7 @@ static void R_GenerateLookup(int texnum, int *const errors)

short *collump = texturecolumnlump[texnum];
unsigned *colofs = texturecolumnofs[texnum]; // killough 4/9/98: make 32-bit
unsigned *colofs2 = texturecolumnofs2[texnum];

// killough 4/9/98: keep count of posts in addition to patches.
// Part of fix for medusa bug for multipatched 2s normals.
Expand Down Expand Up @@ -333,7 +359,8 @@ static void R_GenerateLookup(int texnum, int *const errors)
// only one post per column. This avoids crashes while allowing
// for arbitrarily tall multipatched 1s textures.

if (texture->patchcount > 1 && texture->height < 256)
// [FG] generate composites for all textures
// if (texture->patchcount > 1 && texture->height < 256)
{
// killough 12/98: Warn about a common column construction bug
unsigned limit = texture->height*3+3; // absolute column size limit
Expand All @@ -352,7 +379,8 @@ static void R_GenerateLookup(int texnum, int *const errors)
x1 = 0;

for (x = x1 ; x<x2 ; x++)
if (count[x].patches > 1) // Only multipatched columns
// [FG] generate composites for all columns
// if (count[x].patches > 1) // Only multipatched columns
{
const column_t *col =
(column_t*)((byte*) realpatch+LONG(cofs[x]));
Expand Down Expand Up @@ -384,6 +412,7 @@ static void R_GenerateLookup(int texnum, int *const errors)
// with only a single patch are all done.

texturecomposite[texnum] = 0;
texturecomposite2[texnum] = 0;

{
int x = texture->width;
Expand Down Expand Up @@ -418,11 +447,15 @@ static void R_GenerateLookup(int texnum, int *const errors)
// require, and it's bounded above by this limit.

collump[x] = -1; // mark lump as multipatched
// [FG] moved up here, the rest in this loop
// applies to single-patched textures as well
}
colofs[x] = csize + 3; // three header bytes in a column
// killough 12/98: add room for one extra post
csize += 4*count[x].posts+5; // 1 stop byte plus 4 bytes per post
}
csize += height; // height bytes of texture data
// [FG] initialize opaque texture column offset
colofs2[x] = x * height;
}

texturecompositesize[texnum] = csize;
Expand All @@ -443,11 +476,27 @@ static void R_GenerateLookup(int texnum, int *const errors)

byte *R_GetColumn(int tex, int col)
{
int lump = texturecolumnlump[tex][col &= texturewidthmask[tex]];
int ofs = texturecolumnofs[tex][col];
int ofs;

col &= texturewidthmask[tex];
ofs = texturecolumnofs2[tex][col];

if (!texturecomposite2[tex])
R_GenerateComposite(tex);

return texturecomposite2[tex] + ofs;
}

// [FG] wrapping column getter function for composited translucent mid-textures on 2S walls
byte *R_GetColumnMod(int tex, int col)
{
int ofs;

while (col < 0)
col += texturewidth[tex];

if (lump > 0)
return (byte *) W_CacheLumpNum(lump, PU_CACHE) + ofs;
col %= texturewidth[tex];
ofs = texturecolumnofs[tex][col];

if (!texturecomposite[tex])
R_GenerateComposite(tex);
Expand Down Expand Up @@ -542,12 +591,18 @@ void R_InitTextures (void)
Z_Malloc(numtextures*sizeof*texturecolumnlump, PU_STATIC, 0);
texturecolumnofs =
Z_Malloc(numtextures*sizeof*texturecolumnofs, PU_STATIC, 0);
texturecolumnofs2 =
Z_Malloc(numtextures*sizeof*texturecolumnofs2, PU_STATIC, 0);
texturecomposite =
Z_Malloc(numtextures*sizeof*texturecomposite, PU_STATIC, 0);
texturecomposite2 =
Z_Malloc(numtextures*sizeof*texturecomposite2, PU_STATIC, 0);
texturecompositesize =
Z_Malloc(numtextures*sizeof*texturecompositesize, PU_STATIC, 0);
texturewidthmask =
Z_Malloc(numtextures*sizeof*texturewidthmask, PU_STATIC, 0);
texturewidth =
Z_Malloc(numtextures*sizeof*texturewidth, PU_STATIC, 0);
textureheight = Z_Malloc(numtextures*sizeof*textureheight, PU_STATIC, 0);

totalwidth = 0;
Expand Down Expand Up @@ -623,11 +678,14 @@ void R_InitTextures (void)
Z_Malloc(texture->width*sizeof**texturecolumnlump, PU_STATIC,0);
texturecolumnofs[i] =
Z_Malloc(texture->width*sizeof**texturecolumnofs, PU_STATIC,0);
texturecolumnofs2[i] =
Z_Malloc(texture->width*sizeof**texturecolumnofs2, PU_STATIC,0);

for (j=1; j*2 <= texture->width; j<<=1)
;
texturewidthmask[i] = j-1;
textureheight[i] = texture->height<<FRACBITS;
texturewidth[i] = texture->width;

totalwidth += texture->width;
}
Expand Down
1 change: 1 addition & 0 deletions Source/r_data.h
Expand Up @@ -35,6 +35,7 @@

// Retrieve column data for span blitting.
byte *R_GetColumn(int tex, int col);
byte *R_GetColumnMod(int tex, int col);

// I/O, setting up the stuff.
void R_InitData (void);
Expand Down
2 changes: 1 addition & 1 deletion Source/r_segs.c
Expand Up @@ -201,7 +201,7 @@ void R_RenderMaskedSegRange(drawseg_t *ds, int x1, int x2)

// draw the texture
col = (column_t *)((byte *)
R_GetColumn(texnum,maskedtexturecol[dc_x]) - 3);
R_GetColumnMod(texnum,maskedtexturecol[dc_x]) - 3);
R_DrawMaskedColumn (col);
maskedtexturecol[dc_x] = D_MAXINT; // [FG] 32-bit integer math
}
Expand Down

0 comments on commit 55b86f0

Please sign in to comment.