diff --git a/Source/r_data.c b/Source/r_data.c index 240b77dd3..523838095 100644 --- a/Source/r_data.c +++ b/Source/r_data.c @@ -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; @@ -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++) @@ -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); } @@ -229,21 +239,27 @@ 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 { @@ -251,18 +267,26 @@ static void R_GenerateComposite(int texnum) 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 } } @@ -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); } // @@ -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. @@ -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 @@ -352,7 +379,8 @@ static void R_GenerateLookup(int texnum, int *const errors) x1 = 0; for (x = x1 ; x 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])); @@ -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; @@ -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; @@ -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); @@ -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; @@ -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<width; totalwidth += texture->width; } diff --git a/Source/r_data.h b/Source/r_data.h index 5f02d04d3..00ee64cdc 100644 --- a/Source/r_data.h +++ b/Source/r_data.h @@ -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); diff --git a/Source/r_segs.c b/Source/r_segs.c index 978f1bacf..478795661 100644 --- a/Source/r_segs.c +++ b/Source/r_segs.c @@ -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 }