diff --git a/src/hardware/hw_main.c b/src/hardware/hw_main.c index 7d0e7e490..793050aa2 100644 --- a/src/hardware/hw_main.c +++ b/src/hardware/hw_main.c @@ -580,9 +580,10 @@ static void HWR_RenderPlane(sector_t *sector, extrasubsector_t *xsub, boolean is if (nrPlaneVerts < 3) //not even a triangle ? return; - if (nrPlaneVerts > UINT16_MAX) // FIXME: exceeds plVerts size + // This check is so inconsistent between functions, it hurts. + if (nrPlaneVerts > INT16_MAX) // FIXME: exceeds plVerts size { - CONS_Debug(DBG_RENDER, "polygon size of %d exceeds max value of %d vertices\n", nrPlaneVerts, UINT16_MAX); + CONS_Debug(DBG_RENDER, "polygon size of %d exceeds max value of %d vertices\n", nrPlaneVerts, INT16_MAX); return; } diff --git a/src/p_setup.h b/src/p_setup.h index 6f54bceae..eda6066d3 100644 --- a/src/p_setup.h +++ b/src/p_setup.h @@ -47,7 +47,7 @@ typedef struct UINT8 *flatpatch; UINT16 width, height; fixed_t topoffset, leftoffset; - size_t texturenum; + INT32 texturenum; #ifdef ESLOPE UINT8 *resizedflat; diff --git a/src/r_data.c b/src/r_data.c index 8ceb59dd4..00d8de629 100644 --- a/src/r_data.c +++ b/src/r_data.c @@ -1656,7 +1656,7 @@ boolean R_CheckIfPatch(lumpnum_t lump) width = SHORT(patch->width); height = SHORT(patch->height); - result = (height > 0 && height <= 16384 && width > 0 && width <= 16384 && width < size / 4); + result = (height > 0 && height <= 16384 && width > 0 && width <= 16384 && width < (INT16)(size / 4)); if (result) { @@ -1769,10 +1769,35 @@ void R_FlatTexture(size_t tex, UINT8 *flat) } } -void R_CropFlat(UINT8 *origflat, UINT8 *cropflat, UINT16 origwidth, UINT16 origheight, UINT16 cropwidth, UINT16 cropheight) +void R_CropFlat(UINT8 *srcflat, UINT8 *destflat, + UINT16 srcwidth, UINT16 srcheight, + UINT16 resizewidth, UINT16 resizeheight, + UINT16 destwidth, UINT16 destheight) { - UINT16 x, y; - for (y = 0; y < cropheight; y++) - for (x = 0; x < cropwidth; x++) - cropflat[(y * cropwidth) + x] = origflat[(y * origwidth) + x]; + UINT16 y; + UINT16 position = 0; + for (y = 0; y < destheight; y++) + { + if (position > (srcwidth * srcheight)) + break; + if (srcwidth != resizewidth) + { + if (resizewidth > srcwidth) + { + UINT8 *pos2 = srcflat+position; + UINT8 lastpixel = *(pos2-1); + M_Memcpy(destflat, srcflat+position, destwidth); + memset(pos2, lastpixel, resizewidth-srcwidth); + } + else + M_Memcpy(destflat, srcflat+position, resizewidth); + } + else + M_Memcpy(destflat, srcflat+position, destwidth); + destflat += destwidth; + position += srcwidth; + } + + while (y++ < min(resizeheight, srcheight)) + memset(destflat + (y * destwidth), *(destflat - 1), destwidth); } diff --git a/src/r_data.h b/src/r_data.h index a1e7cd127..8cb41cd2f 100644 --- a/src/r_data.h +++ b/src/r_data.h @@ -97,7 +97,10 @@ boolean R_CheckIfPatch(lumpnum_t lump); // Lactozilla void R_FlatPatch(patch_t *patch, UINT8 *flat); void R_FlatTexture(size_t tex, UINT8 *flat); -void R_CropFlat(UINT8 *origflat, UINT8 *cropflat, UINT16 origwidth, UINT16 origheight, UINT16 cropwidth, UINT16 cropheight); +void R_CropFlat(UINT8 *srcflat, UINT8 *destflat, + UINT16 srcwidth, UINT16 srcheight, + UINT16 resizewidth, UINT16 resizeheight, + UINT16 destwidth, UINT16 destheight); extern INT32 numtextures; diff --git a/src/r_plane.c b/src/r_plane.c index 39f1d220a..91b4f5f2c 100644 --- a/src/r_plane.c +++ b/src/r_plane.c @@ -662,6 +662,7 @@ static void R_GetPatchFlat(levelflat_t *levelflat, boolean leveltexture) { #ifdef ESLOPE INT32 resizewidth, resizeheight, newresize; + INT32 checkresizewidth, checkresizeheight; #endif // ESLOPE if (!leveltexture) @@ -700,21 +701,48 @@ static void R_GetPatchFlat(levelflat_t *levelflat, boolean leveltexture) resizewidth <<= 1; while (resizeheight < levelflat->height) resizeheight <<= 1; + // Scale down to fit in 2048x2048 if (resizewidth > 2048) resizewidth = 2048; if (resizeheight > 2048) resizeheight = 2048; - // Then scale down to fit the actual flat dimensions - while (resizewidth > levelflat->width) - resizewidth >>= 1; - while (resizeheight > levelflat->height) - resizeheight >>= 1; + + // A single pixel difference is negligible. + checkresizewidth = levelflat->width - 1; + if (checkresizewidth & (checkresizewidth - 1)) + { + checkresizewidth += 2; + if (checkresizewidth & (checkresizewidth - 1)) + { + while (resizewidth > levelflat->width) + resizewidth >>= 1; + } + else + resizewidth = checkresizewidth; + } + else + resizewidth = checkresizewidth; + + checkresizeheight = levelflat->height - 1; + if (checkresizeheight & (checkresizeheight - 1)) + { + checkresizeheight += 2; + if (checkresizeheight & (checkresizeheight - 1)) + { + while (resizeheight > levelflat->height) + resizeheight >>= 1; + } + else + resizeheight = checkresizeheight; + } + else + resizeheight = checkresizeheight; levelflat->resizedwidth = levelflat->resizedheight = (newresize = min(resizewidth, resizeheight)); levelflat->resizedflat = Z_Malloc(newresize * newresize, PU_LEVEL, NULL); memset(levelflat->resizedflat, TRANSPARENTPIXEL, newresize * newresize); - R_CropFlat(levelflat->flatpatch, levelflat->resizedflat, levelflat->width, levelflat->height, newresize, newresize); + R_CropFlat(levelflat->flatpatch, levelflat->resizedflat, levelflat->width, levelflat->height, min(resizewidth, newresize), min(resizeheight, newresize), newresize, newresize); #endif // ESLOPE } else