From 410b55ebcd6d8688eba09873ba1f46ec3d150828 Mon Sep 17 00:00:00 2001 From: Monster Iestyn Date: Mon, 28 Nov 2016 22:21:54 +0000 Subject: [PATCH] Work on FLIPX/FLIPX support: *Added FLIPX/FLIPY support for multi-patch textures and single-patch textures without holes *Added FLIPY support for single-patch textures with holes; I'll sort FLIPX support out later --- src/r_data.c | 57 ++++++++++++++++++++++++++++++++++++++++++++++---- src/r_data.h | 1 + src/r_segs.c | 35 +++++++++++++++++++++++++++++-- src/r_things.c | 2 +- src/r_things.h | 1 + 5 files changed, 89 insertions(+), 7 deletions(-) diff --git a/src/r_data.c b/src/r_data.c index b39ede58c..f4910fa00 100644 --- a/src/r_data.c +++ b/src/r_data.c @@ -173,6 +173,43 @@ static inline void R_DrawColumnInCache(column_t *patch, UINT8 *cache, INT32 orig } } +static inline void R_DrawFlippedColumnInCache(column_t *patch, UINT8 *cache, INT32 originy, INT32 cacheheight, INT32 patchheight) +{ + INT32 count, position; + UINT8 *source, *dest; + INT32 topdelta, prevdelta = -1; + + while (patch->topdelta != 0xff) + { + topdelta = patch->topdelta; + if (topdelta <= prevdelta) + topdelta += prevdelta; + prevdelta = topdelta; + topdelta = patchheight-patch->length-topdelta; + source = (UINT8 *)patch + 2 + patch->length; // patch + 3 + (patch->length-1) + count = patch->length; + position = originy + topdelta; + + if (position < 0) + { + count += position; + position = 0; + } + + if (position + count > cacheheight) + count = cacheheight - position; + + dest = cache + position; + if (count > 0) + { + for (; dest < cache + position + count; --source) + *dest++ = *source; + } + + patch = (column_t *)((UINT8 *)patch + patch->length + 4); + } +} + // // R_GenerateTexture // @@ -191,7 +228,7 @@ static UINT8 *R_GenerateTexture(size_t texnum) texture_t *texture; texpatch_t *patch; patch_t *realpatch; - int x, x1, x2, i; + int x, x1, x2, i, width, height; size_t blocksize; column_t *patchcol; UINT32 *colofs; @@ -239,6 +276,7 @@ static UINT8 *R_GenerateTexture(size_t texnum) if (holey) { texture->holes = true; + texture->flip = patch->flip; blocksize = W_LumpLengthPwad(patch->wad, patch->lump); block = Z_Calloc(blocksize, PU_STATIC, // will change tag at end of this function &texturecache[texnum]); @@ -259,6 +297,7 @@ static UINT8 *R_GenerateTexture(size_t texnum) // multi-patch textures (or 'composite') texture->holes = false; + texture->flip = 0; blocksize = (texture->width * 4) + (texture->width * texture->height); texturememory += blocksize; block = Z_Malloc(blocksize+1, PU_STATIC, &texturecache[texnum]); @@ -277,7 +316,9 @@ static UINT8 *R_GenerateTexture(size_t texnum) { realpatch = W_CacheLumpNumPwad(patch->wad, patch->lump, PU_CACHE); x1 = patch->originx; - x2 = x1 + SHORT(realpatch->width); + width = SHORT(realpatch->width); + height = SHORT(realpatch->height); + x2 = x1 + width; if (x1 < 0) x = 0; @@ -289,11 +330,17 @@ static UINT8 *R_GenerateTexture(size_t texnum) for (; x < x2; x++) { - patchcol = (column_t *)((UINT8 *)realpatch + LONG(realpatch->columnofs[x-x1])); + if (patch->flip & 1) + patchcol = (column_t *)((UINT8 *)realpatch + LONG(realpatch->columnofs[(x1+width-1)-x])); + else + patchcol = (column_t *)((UINT8 *)realpatch + LONG(realpatch->columnofs[x-x1])); // generate column ofset lookup colofs[x] = LONG((x * texture->height) + (texture->width*4)); - R_DrawColumnInCache(patchcol, block + LONG(colofs[x]), patch->originy, texture->height); + if (patch->flip & 2) + R_DrawFlippedColumnInCache(patchcol, block + LONG(colofs[x]), patch->originy, texture->height, height); + else + R_DrawColumnInCache(patchcol, block + LONG(colofs[x]), patch->originy, texture->height); } } @@ -469,6 +516,7 @@ void R_LoadTextures(void) texture->height = SHORT(patchlump->height)*patchcount; texture->patchcount = patchcount; texture->holes = false; + texture->flip = 0; // Allocate information for the texture's patches. for (k = 0; k < patchcount; k++) @@ -479,6 +527,7 @@ void R_LoadTextures(void) patch->originy = (INT16)(k*patchlump->height); patch->wad = (UINT16)w; patch->lump = texstart + j; + patch->flip = 0; } Z_Unlock(patchlump); diff --git a/src/r_data.h b/src/r_data.h index 1384ecac0..72054da5d 100644 --- a/src/r_data.h +++ b/src/r_data.h @@ -43,6 +43,7 @@ typedef struct char name[8]; INT16 width, height; boolean holes; + UINT8 flip; // 1 = flipx, 2 = flipy, 3 = both // All the patches[patchcount] are drawn back to front into the cached texture. INT16 patchcount; diff --git a/src/r_segs.c b/src/r_segs.c index 257be2989..91fb0e5bd 100644 --- a/src/r_segs.c +++ b/src/r_segs.c @@ -276,6 +276,13 @@ static void R_Render2sidedMultiPatchColumn(column_t *column) } } +// quick wrapper for R_DrawFlippedMaskedColumn so it can be set as a colfunc_2s value +// uses column2s_length for texture->height as above +static void R_DrawFlippedMaskedSegColumn(column_t *column) +{ + R_DrawFlippedMaskedColumn(column, column2s_length); +} + void R_RenderMaskedSegRange(drawseg_t *ds, INT32 x1, INT32 x2) { size_t pindex; @@ -347,7 +354,15 @@ void R_RenderMaskedSegRange(drawseg_t *ds, INT32 x1, INT32 x2) // handle case where multipatch texture is drawn on a 2sided wall, multi-patch textures // are not stored per-column with post info in SRB2 if (textures[texnum]->holes) - colfunc_2s = R_DrawMaskedColumn; // render the usual 2sided single-patch packed texture + { + if (textures[texnum]->flip & 2) // vertically flipped? + { + colfunc_2s = R_DrawFlippedMaskedSegColumn; + column2s_length = textures[texnum]->height; + } + else + colfunc_2s = R_DrawMaskedColumn; // render the usual 2sided single-patch packed texture + } else { colfunc_2s = R_Render2sidedMultiPatchColumn; // render multipatch with no holes (no post_t info) @@ -700,6 +715,14 @@ static void R_DrawRepeatMaskedColumn(column_t *col) } while (sprtopscreen < sprbotscreen); } +static void R_DrawRepeatFlippedMaskedColumn(column_t *col) +{ + do { + R_DrawFlippedMaskedColumn(col, column2s_length); + sprtopscreen += dc_texheight*spryscale; + } while (sprtopscreen < sprbotscreen); +} + // // R_RenderThickSideRange // Renders all the thick sides in the given range. @@ -1027,7 +1050,15 @@ void R_RenderThickSideRange(drawseg_t *ds, INT32 x1, INT32 x2, ffloor_t *pfloor) //faB: handle case where multipatch texture is drawn on a 2sided wall, multi-patch textures // are not stored per-column with post info anymore in Doom Legacy if (textures[texnum]->holes) - colfunc_2s = R_DrawRepeatMaskedColumn; //render the usual 2sided single-patch packed texture + { + if (textures[texnum]->flip & 2) // vertically flipped? + { + colfunc_2s = R_DrawRepeatFlippedMaskedColumn; + column2s_length = textures[texnum]->height; + } + else + colfunc_2s = R_DrawRepeatMaskedColumn; // render the usual 2sided single-patch packed texture + } else { colfunc_2s = R_Render2sidedMultiPatchColumn; //render multipatch with no holes (no post_t info) diff --git a/src/r_things.c b/src/r_things.c index 9f6cad529..5d560b53d 100644 --- a/src/r_things.c +++ b/src/r_things.c @@ -712,7 +712,7 @@ void R_DrawMaskedColumn(column_t *column) dc_texturemid = basetexturemid; } -static void R_DrawFlippedMaskedColumn(column_t *column, INT32 texheight) +void R_DrawFlippedMaskedColumn(column_t *column, INT32 texheight) { INT32 topscreen; INT32 bottomscreen; diff --git a/src/r_things.h b/src/r_things.h index 20dd25abf..572884d21 100644 --- a/src/r_things.h +++ b/src/r_things.h @@ -46,6 +46,7 @@ extern fixed_t windowtop; extern fixed_t windowbottom; void R_DrawMaskedColumn(column_t *column); +void R_DrawFlippedMaskedColumn(column_t *column, INT32 texheight); void R_SortVisSprites(void); //faB: find sprites in wadfile, replace existing, add new ones