From 714c997aace85b7f873fa0c1a97224cec691baeb Mon Sep 17 00:00:00 2001 From: Jaime Passos Date: Tue, 21 May 2019 00:28:52 -0300 Subject: [PATCH 01/13] Support for patches and textures to be used in place of sector flats Still a work in progress. --- src/dehacked.c | 9 +- src/hardware/hw_cache.c | 81 ++++++- src/hardware/hw_glob.h | 3 + src/hardware/hw_main.c | 178 ++++++++------ src/p_setup.c | 4 + src/p_setup.h | 11 + src/p_spec.c | 4 +- src/r_data.c | 204 ++++++++++++++-- src/r_data.h | 12 +- src/r_draw.c | 2 + src/r_draw.h | 13 +- src/r_draw8.c | 499 ++++++++++++++++++---------------------- src/r_plane.c | 354 ++++++++++++++++------------ src/screen.c | 2 +- 14 files changed, 841 insertions(+), 535 deletions(-) diff --git a/src/dehacked.c b/src/dehacked.c index a726ecbc1..bdef5f1be 100644 --- a/src/dehacked.c +++ b/src/dehacked.c @@ -2699,7 +2699,7 @@ static void readtexture(MYFILE *f, const char *name) char *word; char *word2; char *tmp; - INT32 i, j, value; + INT32 i, value; UINT16 width = 0, height = 0; INT16 patchcount = 0; texture_t *texture; @@ -2783,13 +2783,8 @@ static void readtexture(MYFILE *f, const char *name) while (textures[i]) i++; - // Fill the global texture buffer entries. - j = 1; - while (j << 1 <= texture->width) - j <<= 1; - textures[i] = texture; - texturewidthmask[i] = j - 1; + texturewidth[i] = texture->width; textureheight[i] = texture->height << FRACBITS; // Clean up. diff --git a/src/hardware/hw_cache.c b/src/hardware/hw_cache.c index 78fc31afc..4ae7a43b9 100644 --- a/src/hardware/hw_cache.c +++ b/src/hardware/hw_cache.c @@ -30,6 +30,7 @@ #include "../z_zone.h" #include "../v_video.h" #include "../r_draw.h" +#include "../p_setup.h" //Hurdler: 25/04/2000: used for new colormap code in hardware mode //static UINT8 *gr_colormap = NULL; // by default it must be NULL ! (because colormap tables are not initialized) @@ -551,11 +552,13 @@ void HWR_MakePatch (const patch_t *patch, GLPatch_t *grPatch, GLMipmap_t *grMipm static size_t gr_numtextures; static GLTexture_t *gr_textures; // for ALL Doom textures +static GLTexture_t *gr_textures2; void HWR_InitTextureCache(void) { gr_numtextures = 0; gr_textures = NULL; + gr_textures2 = NULL; } @@ -594,7 +597,10 @@ void HWR_FreeTextureCache(void) // texturecache info, we can free it if (gr_textures) free(gr_textures); + if (gr_textures2) + free(gr_textures2); gr_textures = NULL; + gr_textures2 = NULL; gr_numtextures = 0; } @@ -612,6 +618,9 @@ void HWR_PrepLevelCache(size_t pnumtextures) gr_textures = calloc(pnumtextures, sizeof (*gr_textures)); if (gr_textures == NULL) I_Error("3D can't alloc gr_textures"); + gr_textures2 = calloc(pnumtextures, sizeof (*gr_textures2)); + if (gr_textures2 == NULL) + I_Error("3D can't alloc gr_textures2"); } void HWR_SetPalette(RGBA_t *palette) @@ -642,7 +651,7 @@ GLTexture_t *HWR_GetTexture(INT32 tex) GLTexture_t *grtex; #ifdef PARANOIA if ((unsigned)tex >= gr_numtextures) - I_Error(" HWR_GetTexture: tex >= numtextures\n"); + I_Error("HWR_GetTexture: tex >= numtextures\n"); #endif grtex = &gr_textures[tex]; @@ -657,6 +666,35 @@ GLTexture_t *HWR_GetTexture(INT32 tex) return grtex; } +// Lactozilla +lumpnum_t gr_patchflat; + +static void HWR_LoadPatchFlat(GLMipmap_t *grMipmap, lumpnum_t flatlumpnum) +{ + patch_t *patch = (patch_t *)W_CacheLumpNum(flatlumpnum, PU_STATIC); + + grMipmap->width = (UINT16)SHORT(patch->width); + grMipmap->height = (UINT16)SHORT(patch->height); + + R_FlatPatch(patch, Z_Malloc(grMipmap->width * grMipmap->height, PU_HWRCACHE, &grMipmap->grInfo.data)); + + Z_Free(patch); +} + +static void HWR_LoadTextureFlat(GLMipmap_t *grMipmap, INT32 texturenum) +{ + // setup the texture info + grMipmap->grInfo.smallLodLog2 = GR_LOD_LOG2_64; + grMipmap->grInfo.largeLodLog2 = GR_LOD_LOG2_64; + grMipmap->grInfo.aspectRatioLog2 = GR_ASPECT_LOG2_1x1; + grMipmap->grInfo.format = GR_TEXFMT_P_8; + grMipmap->flags = TF_WRAPXY|TF_CHROMAKEYED; + + grMipmap->width = (UINT16)textures[texturenum]->width; + grMipmap->height = (UINT16)textures[texturenum]->height; + + R_FlatTexture(texturenum, Z_Malloc(grMipmap->width * grMipmap->height, PU_HWRCACHE, &grMipmap->grInfo.data)); +} static void HWR_CacheFlat(GLMipmap_t *grMipmap, lumpnum_t flatlumpnum) { @@ -695,15 +733,20 @@ static void HWR_CacheFlat(GLMipmap_t *grMipmap, lumpnum_t flatlumpnum) pflatsize = 64; break; } - grMipmap->width = (UINT16)pflatsize; - grMipmap->height = (UINT16)pflatsize; - // the flat raw data needn't be converted with palettized textures - W_ReadLump(flatlumpnum, Z_Malloc(W_LumpLength(flatlumpnum), - PU_HWRCACHE, &grMipmap->grInfo.data)); + if (R_CheckIfPatch(flatlumpnum)) + HWR_LoadPatchFlat(grMipmap, flatlumpnum); + else + { + grMipmap->width = (UINT16)pflatsize; + grMipmap->height = (UINT16)pflatsize; + + // the flat raw data needn't be converted with palettized textures + W_ReadLump(flatlumpnum, Z_Malloc(W_LumpLength(flatlumpnum), + PU_HWRCACHE, &grMipmap->grInfo.data)); + } } - // Download a Doom 'flat' to the hardware cache and make it ready for use void HWR_GetFlat(lumpnum_t flatlumpnum) { @@ -718,6 +761,30 @@ void HWR_GetFlat(lumpnum_t flatlumpnum) // The system-memory data can be purged now. Z_ChangeTag(grmip->grInfo.data, PU_HWRCACHE_UNLOCKED); + + gr_patchflat = 0; + if (R_CheckIfPatch(flatlumpnum)) + gr_patchflat = flatlumpnum; +} + +void HWR_GetTextureFlat(INT32 texturenum) +{ + GLTexture_t *grtex; +#ifdef PARANOIA + if ((unsigned)texturenum >= gr_numtextures) + I_Error("HWR_GetTextureFlat: texturenum >= numtextures\n"); +#endif + if (texturenum == 0 || texturenum == -1) + return; + grtex = &gr_textures2[texturenum]; + + if (!grtex->mipmap.grInfo.data && !grtex->mipmap.downloaded) + HWR_LoadTextureFlat(&grtex->mipmap, texturenum); + + HWD.pfnSetTexture(&grtex->mipmap); + + // The system-memory data can be purged now. + Z_ChangeTag(grtex->mipmap.grInfo.data, PU_HWRCACHE_UNLOCKED); } // diff --git a/src/hardware/hw_glob.h b/src/hardware/hw_glob.h index bdf219464..2085f7050 100644 --- a/src/hardware/hw_glob.h +++ b/src/hardware/hw_glob.h @@ -101,6 +101,7 @@ void HWR_FreeTextureCache(void); void HWR_FreeExtraSubsectors(void); void HWR_GetFlat(lumpnum_t flatlumpnum); +void HWR_GetTextureFlat(INT32 texturenum); GLTexture_t *HWR_GetTexture(INT32 tex); void HWR_GetPatch(GLPatch_t *gpatch); void HWR_GetMappedPatch(GLPatch_t *gpatch, const UINT8 *colormap); @@ -114,6 +115,8 @@ void HWR_GetFadeMask(lumpnum_t fademasklumpnum); // -------- // hw_draw.c // -------- +extern lumpnum_t gr_patchflat; + extern float gr_patch_scalex; extern float gr_patch_scaley; diff --git a/src/hardware/hw_main.c b/src/hardware/hw_main.c index 7e0b369eb..7d0e7e490 100644 --- a/src/hardware/hw_main.c +++ b/src/hardware/hw_main.c @@ -70,9 +70,9 @@ static void HWR_ProjectPrecipitationSprite(precipmobj_t *thing); #endif #ifdef SORTING -void HWR_AddTransparentFloor(lumpnum_t lumpnum, extrasubsector_t *xsub, boolean isceiling, fixed_t fixedheight, +void HWR_AddTransparentFloor(lumpnum_t lumpnum, INT32 texturenum, extrasubsector_t *xsub, boolean isceiling, fixed_t fixedheight, INT32 lightlevel, INT32 alpha, sector_t *FOFSector, FBITFIELD blend, boolean fogplane, extracolormap_t *planecolormap); -void HWR_AddTransparentPolyobjectFloor(lumpnum_t lumpnum, polyobj_t *polysector, boolean isceiling, fixed_t fixedheight, +void HWR_AddTransparentPolyobjectFloor(lumpnum_t lumpnum, INT32 texturenum, polyobj_t *polysector, boolean isceiling, fixed_t fixedheight, INT32 lightlevel, INT32 alpha, sector_t *FOFSector, FBITFIELD blend, extracolormap_t *planecolormap); #else static void HWR_Add3DWater(lumpnum_t lumpnum, extrasubsector_t *xsub, fixed_t fixedheight, @@ -522,7 +522,7 @@ static UINT8 HWR_FogBlockAlpha(INT32 light, UINT32 color) // Let's see if this c // HWR_RenderPlane : Render a floor or ceiling convex polygon // -----------------+ static void HWR_RenderPlane(sector_t *sector, extrasubsector_t *xsub, boolean isceiling, fixed_t fixedheight, - FBITFIELD PolyFlags, INT32 lightlevel, lumpnum_t lumpnum, sector_t *FOFsector, UINT8 alpha, boolean fogplane, extracolormap_t *planecolormap) + FBITFIELD PolyFlags, INT32 lightlevel, lumpnum_t lumpnum, INT32 texturenum, sector_t *FOFsector, UINT8 alpha, boolean fogplane, extracolormap_t *planecolormap) { polyvertex_t * pv; float height; //constant y for all points on the convex flat polygon @@ -530,8 +530,7 @@ static void HWR_RenderPlane(sector_t *sector, extrasubsector_t *xsub, boolean is INT32 nrPlaneVerts; //verts original define of convex flat polygon INT32 i; float flatxref,flatyref; - float fflatsize; - INT32 flatflag; + float fflatwidth, fflatheight; size_t len; float scrollx = 0.0f, scrolly = 0.0f; angle_t angle = 0; @@ -540,6 +539,7 @@ static void HWR_RenderPlane(sector_t *sector, extrasubsector_t *xsub, boolean is #ifdef ESLOPE pslope_t *slope = NULL; #endif + patch_t *patch; static FOutVector *planeVerts = NULL; static UINT16 numAllocedPlaneVerts = 0; @@ -599,38 +599,44 @@ static void HWR_RenderPlane(sector_t *sector, extrasubsector_t *xsub, boolean is switch (len) { case 4194304: // 2048x2048 lump - fflatsize = 2048.0f; - flatflag = 2047; + fflatwidth = fflatheight = 2048.0f; break; case 1048576: // 1024x1024 lump - fflatsize = 1024.0f; - flatflag = 1023; + fflatwidth = fflatheight = 1024.0f; break; case 262144:// 512x512 lump - fflatsize = 512.0f; - flatflag = 511; + fflatwidth = fflatheight = 512.0f; break; case 65536: // 256x256 lump - fflatsize = 256.0f; - flatflag = 255; + fflatwidth = fflatheight = 256.0f; break; case 16384: // 128x128 lump - fflatsize = 128.0f; - flatflag = 127; + fflatwidth = fflatheight = 128.0f; break; case 1024: // 32x32 lump - fflatsize = 32.0f; - flatflag = 31; + fflatwidth = fflatheight = 32.0f; break; default: // 64x64 lump - fflatsize = 64.0f; - flatflag = 63; + fflatwidth = fflatheight = 64.0f; break; } + if (gr_patchflat && R_CheckIfPatch(gr_patchflat)) // Just in case? + { + patch = (patch_t *)W_CacheLumpNum(gr_patchflat, PU_STATIC); + fflatwidth = patch->width; + fflatheight = patch->height; + } + + if (texturenum != 0 && texturenum != -1) + { + fflatwidth = textures[texturenum]->width; + fflatheight = textures[texturenum]->height; + } + // reference point for flat texture coord for each vertex around the polygon - flatxref = (float)(((fixed_t)pv->x & (~flatflag)) / fflatsize); - flatyref = (float)(((fixed_t)pv->y & (~flatflag)) / fflatsize); + flatxref = (float)((FLOAT_TO_FIXED(pv->x) % llrint(fflatwidth)) / fflatwidth); + flatyref = (float)((FLOAT_TO_FIXED(pv->y) % llrint(fflatheight)) / fflatheight); // transform v3d = planeVerts; @@ -639,14 +645,14 @@ static void HWR_RenderPlane(sector_t *sector, extrasubsector_t *xsub, boolean is { if (!isceiling) // it's a floor { - scrollx = FIXED_TO_FLOAT(FOFsector->floor_xoffs)/fflatsize; - scrolly = FIXED_TO_FLOAT(FOFsector->floor_yoffs)/fflatsize; + scrollx = FIXED_TO_FLOAT(FOFsector->floor_xoffs)/fflatwidth; + scrolly = FIXED_TO_FLOAT(FOFsector->floor_yoffs)/fflatheight; angle = FOFsector->floorpic_angle>>ANGLETOFINESHIFT; } else // it's a ceiling { - scrollx = FIXED_TO_FLOAT(FOFsector->ceiling_xoffs)/fflatsize; - scrolly = FIXED_TO_FLOAT(FOFsector->ceiling_yoffs)/fflatsize; + scrollx = FIXED_TO_FLOAT(FOFsector->ceiling_xoffs)/fflatwidth; + scrolly = FIXED_TO_FLOAT(FOFsector->ceiling_yoffs)/fflatheight; angle = FOFsector->ceilingpic_angle>>ANGLETOFINESHIFT; } } @@ -654,14 +660,14 @@ static void HWR_RenderPlane(sector_t *sector, extrasubsector_t *xsub, boolean is { if (!isceiling) // it's a floor { - scrollx = FIXED_TO_FLOAT(gr_frontsector->floor_xoffs)/fflatsize; - scrolly = FIXED_TO_FLOAT(gr_frontsector->floor_yoffs)/fflatsize; + scrollx = FIXED_TO_FLOAT(gr_frontsector->floor_xoffs)/fflatwidth; + scrolly = FIXED_TO_FLOAT(gr_frontsector->floor_yoffs)/fflatheight; angle = gr_frontsector->floorpic_angle>>ANGLETOFINESHIFT; } else // it's a ceiling { - scrollx = FIXED_TO_FLOAT(gr_frontsector->ceiling_xoffs)/fflatsize; - scrolly = FIXED_TO_FLOAT(gr_frontsector->ceiling_yoffs)/fflatsize; + scrollx = FIXED_TO_FLOAT(gr_frontsector->ceiling_xoffs)/fflatwidth; + scrolly = FIXED_TO_FLOAT(gr_frontsector->ceiling_yoffs)/fflatheight; angle = gr_frontsector->ceilingpic_angle>>ANGLETOFINESHIFT; } } @@ -686,8 +692,8 @@ static void HWR_RenderPlane(sector_t *sector, extrasubsector_t *xsub, boolean is for (i = 0; i < nrPlaneVerts; i++,v3d++,pv++) { // Hurdler: add scrolling texture on floor/ceiling - v3d->sow = (float)((pv->x / fflatsize) - flatxref + scrollx); - v3d->tow = (float)(flatyref - (pv->y / fflatsize) + scrolly); + v3d->sow = (float)((pv->x / fflatwidth) - flatxref + scrollx); + v3d->tow = (float)(flatyref - (pv->y / fflatheight) + scrolly); //v3d->sow = (float)(pv->x / fflatsize); //v3d->tow = (float)(pv->y / fflatsize); @@ -3145,21 +3151,21 @@ static inline void HWR_AddPolyObjectSegs(void) #ifdef POLYOBJECTS_PLANES static void HWR_RenderPolyObjectPlane(polyobj_t *polysector, boolean isceiling, fixed_t fixedheight, - FBITFIELD blendmode, UINT8 lightlevel, lumpnum_t lumpnum, sector_t *FOFsector, + FBITFIELD blendmode, UINT8 lightlevel, lumpnum_t lumpnum, INT32 texturenum, sector_t *FOFsector, UINT8 alpha, extracolormap_t *planecolormap) { float height; //constant y for all points on the convex flat polygon FOutVector *v3d; INT32 i; float flatxref,flatyref; - float fflatsize; - INT32 flatflag; + float fflatwidth, fflatheight; size_t len; float scrollx = 0.0f, scrolly = 0.0f; angle_t angle = 0; FSurfaceInfo Surf; fixed_t tempxsow, tempytow; size_t nrPlaneVerts; + patch_t *patch; static FOutVector *planeVerts = NULL; static UINT16 numAllocedPlaneVerts = 0; @@ -3190,38 +3196,44 @@ static void HWR_RenderPolyObjectPlane(polyobj_t *polysector, boolean isceiling, switch (len) { case 4194304: // 2048x2048 lump - fflatsize = 2048.0f; - flatflag = 2047; + fflatwidth = fflatheight = 2048.0f; break; case 1048576: // 1024x1024 lump - fflatsize = 1024.0f; - flatflag = 1023; + fflatwidth = fflatheight = 1024.0f; break; case 262144:// 512x512 lump - fflatsize = 512.0f; - flatflag = 511; + fflatwidth = fflatheight = 512.0f; break; case 65536: // 256x256 lump - fflatsize = 256.0f; - flatflag = 255; + fflatwidth = fflatheight = 256.0f; break; case 16384: // 128x128 lump - fflatsize = 128.0f; - flatflag = 127; + fflatwidth = fflatheight = 128.0f; break; case 1024: // 32x32 lump - fflatsize = 32.0f; - flatflag = 31; + fflatwidth = fflatheight = 32.0f; break; default: // 64x64 lump - fflatsize = 64.0f; - flatflag = 63; + fflatwidth = fflatheight = 64.0f; break; } + if (gr_patchflat && R_CheckIfPatch(gr_patchflat)) // Just in case? + { + patch = (patch_t *)W_CacheLumpNum(gr_patchflat, PU_STATIC); + fflatwidth = patch->width; + fflatheight = patch->height; + } + + if (texturenum != 0 && texturenum != -1) + { + fflatwidth = textures[texturenum]->width; + fflatheight = textures[texturenum]->height; + } + // reference point for flat texture coord for each vertex around the polygon - flatxref = (float)(((fixed_t)FIXED_TO_FLOAT(polysector->origVerts[0].x) & (~flatflag)) / fflatsize); - flatyref = (float)(((fixed_t)FIXED_TO_FLOAT(polysector->origVerts[0].y) & (~flatflag)) / fflatsize); + flatxref = (float)((polysector->origVerts[0].x % llrint(fflatwidth)) / fflatwidth); + flatyref = (float)((polysector->origVerts[0].y % llrint(fflatheight)) / fflatheight); // transform v3d = planeVerts; @@ -3230,14 +3242,14 @@ static void HWR_RenderPolyObjectPlane(polyobj_t *polysector, boolean isceiling, { if (!isceiling) // it's a floor { - scrollx = FIXED_TO_FLOAT(FOFsector->floor_xoffs)/fflatsize; - scrolly = FIXED_TO_FLOAT(FOFsector->floor_yoffs)/fflatsize; + scrollx = FIXED_TO_FLOAT(FOFsector->floor_xoffs)/fflatwidth; + scrolly = FIXED_TO_FLOAT(FOFsector->floor_yoffs)/fflatheight; angle = FOFsector->floorpic_angle>>ANGLETOFINESHIFT; } else // it's a ceiling { - scrollx = FIXED_TO_FLOAT(FOFsector->ceiling_xoffs)/fflatsize; - scrolly = FIXED_TO_FLOAT(FOFsector->ceiling_yoffs)/fflatsize; + scrollx = FIXED_TO_FLOAT(FOFsector->ceiling_xoffs)/fflatwidth; + scrolly = FIXED_TO_FLOAT(FOFsector->ceiling_yoffs)/fflatheight; angle = FOFsector->ceilingpic_angle>>ANGLETOFINESHIFT; } } @@ -3245,14 +3257,14 @@ static void HWR_RenderPolyObjectPlane(polyobj_t *polysector, boolean isceiling, { if (!isceiling) // it's a floor { - scrollx = FIXED_TO_FLOAT(gr_frontsector->floor_xoffs)/fflatsize; - scrolly = FIXED_TO_FLOAT(gr_frontsector->floor_yoffs)/fflatsize; + scrollx = FIXED_TO_FLOAT(gr_frontsector->floor_xoffs)/fflatwidth; + scrolly = FIXED_TO_FLOAT(gr_frontsector->floor_yoffs)/fflatheight; angle = gr_frontsector->floorpic_angle>>ANGLETOFINESHIFT; } else // it's a ceiling { - scrollx = FIXED_TO_FLOAT(gr_frontsector->ceiling_xoffs)/fflatsize; - scrolly = FIXED_TO_FLOAT(gr_frontsector->ceiling_yoffs)/fflatsize; + scrollx = FIXED_TO_FLOAT(gr_frontsector->ceiling_xoffs)/fflatwidth; + scrolly = FIXED_TO_FLOAT(gr_frontsector->ceiling_yoffs)/fflatheight; angle = gr_frontsector->ceilingpic_angle>>ANGLETOFINESHIFT; } } @@ -3276,8 +3288,8 @@ static void HWR_RenderPolyObjectPlane(polyobj_t *polysector, boolean isceiling, for (i = 0; i < (INT32)nrPlaneVerts; i++,v3d++) { // Hurdler: add scrolling texture on floor/ceiling - v3d->sow = (float)((FIXED_TO_FLOAT(polysector->origVerts[i].x) / fflatsize) - flatxref + scrollx); // Go from the polysector's original vertex locations - v3d->tow = (float)(flatyref - (FIXED_TO_FLOAT(polysector->origVerts[i].y) / fflatsize) + scrolly); // Means the flat is offset based on the original vertex locations + v3d->sow = (float)((FIXED_TO_FLOAT(polysector->origVerts[i].x) / fflatwidth) - flatxref + scrollx); // Go from the polysector's original vertex locations + v3d->tow = (float)(flatyref - (FIXED_TO_FLOAT(polysector->origVerts[i].y) / fflatheight) + scrolly); // Means the flat is offset based on the original vertex locations // Need to rotate before translate if (angle) // Only needs to be done if there's an altered angle @@ -3336,14 +3348,15 @@ static void HWR_AddPolyObjectPlanes(void) { FSurfaceInfo Surf; FBITFIELD blendmode = HWR_TranstableToAlpha(po_ptrs[i]->translucency, &Surf); - HWR_AddTransparentPolyobjectFloor(levelflats[polyobjsector->floorpic].lumpnum, po_ptrs[i], false, polyobjsector->floorheight, + HWR_AddTransparentPolyobjectFloor(levelflats[polyobjsector->floorpic].lumpnum, levelflats[polyobjsector->floorpic].texturenum, po_ptrs[i], false, polyobjsector->floorheight, polyobjsector->lightlevel, Surf.FlatColor.s.alpha, polyobjsector, blendmode, NULL); } else { HWR_GetFlat(levelflats[polyobjsector->floorpic].lumpnum); + HWR_GetTextureFlat(levelflats[polyobjsector->floorpic].texturenum); HWR_RenderPolyObjectPlane(po_ptrs[i], false, polyobjsector->floorheight, PF_Occlude, - polyobjsector->lightlevel, levelflats[polyobjsector->floorpic].lumpnum, + polyobjsector->lightlevel, levelflats[polyobjsector->floorpic].lumpnum, levelflats[polyobjsector->floorpic].texturenum, polyobjsector, 255, NULL); } } @@ -3358,14 +3371,15 @@ static void HWR_AddPolyObjectPlanes(void) FBITFIELD blendmode; memset(&Surf, 0x00, sizeof(Surf)); blendmode = HWR_TranstableToAlpha(po_ptrs[i]->translucency, &Surf); - HWR_AddTransparentPolyobjectFloor(levelflats[polyobjsector->ceilingpic].lumpnum, po_ptrs[i], true, polyobjsector->ceilingheight, + HWR_AddTransparentPolyobjectFloor(levelflats[polyobjsector->ceilingpic].lumpnum, levelflats[polyobjsector->ceilingpic].texturenum, po_ptrs[i], true, polyobjsector->ceilingheight, polyobjsector->lightlevel, Surf.FlatColor.s.alpha, polyobjsector, blendmode, NULL); } else { HWR_GetFlat(levelflats[polyobjsector->ceilingpic].lumpnum); + HWR_GetTextureFlat(levelflats[polyobjsector->ceilingpic].texturenum); HWR_RenderPolyObjectPlane(po_ptrs[i], true, polyobjsector->ceilingheight, PF_Occlude, - polyobjsector->lightlevel, levelflats[polyobjsector->floorpic].lumpnum, + polyobjsector->lightlevel, levelflats[polyobjsector->floorpic].lumpnum, levelflats[polyobjsector->floorpic].texturenum, polyobjsector, 255, NULL); } } @@ -3517,11 +3531,12 @@ static void HWR_Subsector(size_t num) if (sub->validcount != validcount) { HWR_GetFlat(levelflats[gr_frontsector->floorpic].lumpnum); + HWR_GetTextureFlat(levelflats[gr_frontsector->floorpic].texturenum); HWR_RenderPlane(gr_frontsector, &extrasubsectors[num], false, // Hack to make things continue to work around slopes. locFloorHeight == cullFloorHeight ? locFloorHeight : gr_frontsector->floorheight, // We now return you to your regularly scheduled rendering. - PF_Occlude, floorlightlevel, levelflats[gr_frontsector->floorpic].lumpnum, NULL, 255, false, floorcolormap); + PF_Occlude, floorlightlevel, levelflats[gr_frontsector->floorpic].lumpnum, levelflats[gr_frontsector->floorpic].texturenum, NULL, 255, false, floorcolormap); } } else @@ -3539,11 +3554,12 @@ static void HWR_Subsector(size_t num) if (sub->validcount != validcount) { HWR_GetFlat(levelflats[gr_frontsector->ceilingpic].lumpnum); + HWR_GetTextureFlat(levelflats[gr_frontsector->ceilingpic].texturenum); HWR_RenderPlane(NULL, &extrasubsectors[num], true, // Hack to make things continue to work around slopes. locCeilingHeight == cullCeilingHeight ? locCeilingHeight : gr_frontsector->ceilingheight, // We now return you to your regularly scheduled rendering. - PF_Occlude, ceilinglightlevel, levelflats[gr_frontsector->ceilingpic].lumpnum,NULL, 255, false, ceilingcolormap); + PF_Occlude, ceilinglightlevel, levelflats[gr_frontsector->ceilingpic].lumpnum, levelflats[gr_frontsector->ceilingpic].texturenum, NULL, 255, false, ceilingcolormap); } } else @@ -3602,7 +3618,7 @@ static void HWR_Subsector(size_t num) else alpha = HWR_FogBlockAlpha(*gr_frontsector->lightlist[light].lightlevel, NORMALFOG); - HWR_AddTransparentFloor(0, + HWR_AddTransparentFloor(0, 0, &extrasubsectors[num], false, *rover->bottomheight, @@ -3621,6 +3637,7 @@ static void HWR_Subsector(size_t num) rover->alpha-1, rover->master->frontsector); #else HWR_AddTransparentFloor(levelflats[*rover->bottompic].lumpnum, + levelflats[*rover->bottompic].texturenum, &extrasubsectors[num], false, *rover->bottomheight, @@ -3632,8 +3649,9 @@ static void HWR_Subsector(size_t num) else { HWR_GetFlat(levelflats[*rover->bottompic].lumpnum); + HWR_GetTextureFlat(levelflats[*rover->bottompic].texturenum); light = R_GetPlaneLight(gr_frontsector, centerHeight, dup_viewz < cullHeight ? true : false); - HWR_RenderPlane(NULL, &extrasubsectors[num], false, *rover->bottomheight, PF_Occlude, *gr_frontsector->lightlist[light].lightlevel, levelflats[*rover->bottompic].lumpnum, + HWR_RenderPlane(NULL, &extrasubsectors[num], false, *rover->bottomheight, PF_Occlude, *gr_frontsector->lightlist[light].lightlevel, levelflats[*rover->bottompic].lumpnum, levelflats[*rover->bottompic].texturenum, rover->master->frontsector, 255, false, gr_frontsector->lightlist[light].extra_colormap); } } @@ -3665,7 +3683,7 @@ static void HWR_Subsector(size_t num) else alpha = HWR_FogBlockAlpha(*gr_frontsector->lightlist[light].lightlevel, NORMALFOG); - HWR_AddTransparentFloor(0, + HWR_AddTransparentFloor(0, 0, &extrasubsectors[num], true, *rover->topheight, @@ -3684,6 +3702,7 @@ static void HWR_Subsector(size_t num) rover->alpha-1, rover->master->frontsector); #else HWR_AddTransparentFloor(levelflats[*rover->toppic].lumpnum, + levelflats[*rover->bottompic].texturenum, &extrasubsectors[num], true, *rover->topheight, @@ -3696,8 +3715,9 @@ static void HWR_Subsector(size_t num) else { HWR_GetFlat(levelflats[*rover->toppic].lumpnum); + HWR_GetTextureFlat(levelflats[*rover->toppic].texturenum); light = R_GetPlaneLight(gr_frontsector, centerHeight, dup_viewz < cullHeight ? true : false); - HWR_RenderPlane(NULL, &extrasubsectors[num], true, *rover->topheight, PF_Occlude, *gr_frontsector->lightlist[light].lightlevel, levelflats[*rover->toppic].lumpnum, + HWR_RenderPlane(NULL, &extrasubsectors[num], true, *rover->topheight, PF_Occlude, *gr_frontsector->lightlist[light].lightlevel, levelflats[*rover->toppic].lumpnum, levelflats[*rover->toppic].texturenum, rover->master->frontsector, 255, false, gr_frontsector->lightlist[light].extra_colormap); } } @@ -5021,6 +5041,7 @@ typedef struct fixed_t fixedheight; INT32 lightlevel; lumpnum_t lumpnum; + INT32 texturenum; INT32 alpha; sector_t *FOFSector; FBITFIELD blend; @@ -5039,6 +5060,7 @@ typedef struct fixed_t fixedheight; INT32 lightlevel; lumpnum_t lumpnum; + INT32 texturenum; INT32 alpha; sector_t *FOFSector; FBITFIELD blend; @@ -5071,7 +5093,7 @@ static INT32 drawcount = 0; #define MAX_TRANSPARENTFLOOR 512 // This will likely turn into a copy of HWR_Add3DWater and replace it. -void HWR_AddTransparentFloor(lumpnum_t lumpnum, extrasubsector_t *xsub, boolean isceiling, +void HWR_AddTransparentFloor(lumpnum_t lumpnum, INT32 texturenum, extrasubsector_t *xsub, boolean isceiling, fixed_t fixedheight, INT32 lightlevel, INT32 alpha, sector_t *FOFSector, FBITFIELD blend, boolean fogplane, extracolormap_t *planecolormap) { static size_t allocedplanes = 0; @@ -5090,6 +5112,7 @@ void HWR_AddTransparentFloor(lumpnum_t lumpnum, extrasubsector_t *xsub, boolean planeinfo[numplanes].fixedheight = fixedheight; planeinfo[numplanes].lightlevel = lightlevel; planeinfo[numplanes].lumpnum = lumpnum; + planeinfo[numplanes].texturenum = texturenum; planeinfo[numplanes].xsub = xsub; planeinfo[numplanes].alpha = alpha; planeinfo[numplanes].FOFSector = FOFSector; @@ -5103,7 +5126,7 @@ void HWR_AddTransparentFloor(lumpnum_t lumpnum, extrasubsector_t *xsub, boolean // Adding this for now until I can create extrasubsector info for polyobjects // When that happens it'll just be done through HWR_AddTransparentFloor and HWR_RenderPlane -void HWR_AddTransparentPolyobjectFloor(lumpnum_t lumpnum, polyobj_t *polysector, boolean isceiling, +void HWR_AddTransparentPolyobjectFloor(lumpnum_t lumpnum, INT32 texturenum, polyobj_t *polysector, boolean isceiling, fixed_t fixedheight, INT32 lightlevel, INT32 alpha, sector_t *FOFSector, FBITFIELD blend, extracolormap_t *planecolormap) { static size_t allocedpolyplanes = 0; @@ -5122,6 +5145,7 @@ void HWR_AddTransparentPolyobjectFloor(lumpnum_t lumpnum, polyobj_t *polysector, polyplaneinfo[numpolyplanes].fixedheight = fixedheight; polyplaneinfo[numpolyplanes].lightlevel = lightlevel; polyplaneinfo[numpolyplanes].lumpnum = lumpnum; + polyplaneinfo[numpolyplanes].texturenum = texturenum; polyplaneinfo[numpolyplanes].polysector = polysector; polyplaneinfo[numpolyplanes].alpha = alpha; polyplaneinfo[numpolyplanes].FOFSector = FOFSector; @@ -5283,9 +5307,12 @@ static void HWR_CreateDrawNodes(void) gr_frontsector = NULL; if (!(sortnode[sortindex[i]].plane->blend & PF_NoTexture)) + { HWR_GetFlat(sortnode[sortindex[i]].plane->lumpnum); + HWR_GetTextureFlat(sortnode[sortindex[i]].plane->texturenum); + } HWR_RenderPlane(NULL, sortnode[sortindex[i]].plane->xsub, sortnode[sortindex[i]].plane->isceiling, sortnode[sortindex[i]].plane->fixedheight, sortnode[sortindex[i]].plane->blend, sortnode[sortindex[i]].plane->lightlevel, - sortnode[sortindex[i]].plane->lumpnum, sortnode[sortindex[i]].plane->FOFSector, sortnode[sortindex[i]].plane->alpha, sortnode[sortindex[i]].plane->fogplane, sortnode[sortindex[i]].plane->planecolormap); + sortnode[sortindex[i]].plane->lumpnum, sortnode[sortindex[i]].plane->texturenum, sortnode[sortindex[i]].plane->FOFSector, sortnode[sortindex[i]].plane->alpha, sortnode[sortindex[i]].plane->fogplane, sortnode[sortindex[i]].plane->planecolormap); } else if (sortnode[sortindex[i]].polyplane) { @@ -5293,9 +5320,12 @@ static void HWR_CreateDrawNodes(void) gr_frontsector = NULL; if (!(sortnode[sortindex[i]].polyplane->blend & PF_NoTexture)) + { HWR_GetFlat(sortnode[sortindex[i]].polyplane->lumpnum); + HWR_GetTextureFlat(sortnode[sortindex[i]].polyplane->texturenum); + } HWR_RenderPolyObjectPlane(sortnode[sortindex[i]].polyplane->polysector, sortnode[sortindex[i]].polyplane->isceiling, sortnode[sortindex[i]].polyplane->fixedheight, sortnode[sortindex[i]].polyplane->blend, sortnode[sortindex[i]].polyplane->lightlevel, - sortnode[sortindex[i]].polyplane->lumpnum, sortnode[sortindex[i]].polyplane->FOFSector, sortnode[sortindex[i]].polyplane->alpha, sortnode[sortindex[i]].polyplane->planecolormap); + sortnode[sortindex[i]].polyplane->lumpnum, sortnode[sortindex[i]].polyplane->texturenum, sortnode[sortindex[i]].polyplane->FOFSector, sortnode[sortindex[i]].polyplane->alpha, sortnode[sortindex[i]].polyplane->planecolormap); } else if (sortnode[sortindex[i]].wall) { diff --git a/src/p_setup.c b/src/p_setup.c index 5e1355981..1061dbd0c 100644 --- a/src/p_setup.c +++ b/src/p_setup.c @@ -564,6 +564,8 @@ INT32 P_AddLevelFlat(const char *flatname, levelflat_t *levelflat) // store the flat lump number levelflat->lumpnum = R_GetFlatNumForName(flatname); + // Lactozilla + levelflat->texturenum = R_CheckTextureNumForName(flatname); #ifndef ZDEBUG CONS_Debug(DBG_SETUP, "flat #%03d: %s\n", atoi(sizeu1(numlevelflats)), levelflat->name); @@ -608,6 +610,8 @@ INT32 P_AddLevelFlatRuntime(const char *flatname) // store the flat lump number levelflat->lumpnum = R_GetFlatNumForName(flatname); + // Lactozilla + levelflat->texturenum = R_CheckTextureNumForName(flatname); #ifndef ZDEBUG CONS_Debug(DBG_SETUP, "flat #%03d: %s\n", atoi(sizeu1(numlevelflats)), levelflat->name); diff --git a/src/p_setup.h b/src/p_setup.h index 41c2bf133..6f54bceae 100644 --- a/src/p_setup.h +++ b/src/p_setup.h @@ -42,6 +42,17 @@ typedef struct INT32 animseq; // start pos. in the anim sequence INT32 numpics; INT32 speed; + + // Lactozilla + UINT8 *flatpatch; + UINT16 width, height; + fixed_t topoffset, leftoffset; + size_t texturenum; + +#ifdef ESLOPE + UINT8 *resizedflat; + UINT16 resizedwidth, resizedheight; +#endif } levelflat_t; extern size_t numlevelflats; diff --git a/src/p_spec.c b/src/p_spec.c index 50b8aec9d..60d784324 100644 --- a/src/p_spec.c +++ b/src/p_spec.c @@ -322,8 +322,8 @@ void P_InitPicAnims(void) if ((W_CheckNumForName(animdefs[i].startname)) == LUMPERROR) continue; - lastanim->picnum = R_FlatNumForName(animdefs[i].endname); - lastanim->basepic = R_FlatNumForName(animdefs[i].startname); + lastanim->picnum = R_GetFlatNumForName(animdefs[i].endname); + lastanim->basepic = R_GetFlatNumForName(animdefs[i].startname); } lastanim->istexture = animdefs[i].istexture; diff --git a/src/r_data.c b/src/r_data.c index a21ba49ae..496a0f944 100644 --- a/src/r_data.c +++ b/src/r_data.c @@ -101,9 +101,7 @@ texture_t **textures = NULL; static UINT32 **texturecolumnofs; // column offset lookup table for each texture static UINT8 **texturecache; // graphics data for each generated full-size texture -// texture width is a power of 2, so it can easily repeat along sidedefs using a simple mask -INT32 *texturewidthmask; - +INT32 *texturewidth; fixed_t *textureheight; // needed for texture pegging INT32 *texturetranslation; @@ -335,10 +333,14 @@ void R_CheckTextureCache(INT32 tex) UINT8 *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); - col &= texturewidthmask[tex]; data = texturecache[tex]; - if (!data) data = R_GenerateTexture(tex); @@ -376,7 +378,7 @@ void R_ParseTEXTURESLump(UINT16 wadNum, UINT16 lumpNum, INT32 *index); #define TX_END "TX_END" void R_LoadTextures(void) { - INT32 i, k, w; + INT32 i, w; UINT16 j; UINT16 texstart, texend, texturesLumpPos; patch_t *patchlump; @@ -443,9 +445,9 @@ void R_LoadTextures(void) texturecolumnofs = (void *)((UINT8 *)textures + (numtextures * sizeof(void *))); // Allocate texture referencing cache. texturecache = (void *)((UINT8 *)textures + ((numtextures * sizeof(void *)) * 2)); - // Allocate texture width mask table. - texturewidthmask = (void *)((UINT8 *)textures + ((numtextures * sizeof(void *)) * 3)); - // Allocate texture height mask table. + // Allocate texture width table. + texturewidth = (void *)((UINT8 *)textures + ((numtextures * sizeof(void *)) * 3)); + // Allocate texture height table. textureheight = (void *)((UINT8 *)textures + ((numtextures * sizeof(void *)) * 4)); // Create translation table for global animation. texturetranslation = Z_Malloc((numtextures + 1) * sizeof(*texturetranslation), PU_STATIC, NULL); @@ -513,11 +515,7 @@ void R_LoadTextures(void) Z_Unlock(patchlump); - k = 1; - while (k << 1 <= texture->width) - k <<= 1; - - texturewidthmask[i] = k - 1; + texturewidth[i] = texture->width; textureheight[i] = texture->height << FRACBITS; } } @@ -905,7 +903,7 @@ void R_ParseTEXTURESLump(UINT16 wadNum, UINT16 lumpNum, INT32 *texindex) newTexture = R_ParseTexture(true); // Store the new texture textures[*texindex] = newTexture; - texturewidthmask[*texindex] = newTexture->width - 1; + texturewidth[*texindex] = newTexture->width; textureheight[*texindex] = newTexture->height << FRACBITS; // Increment i back in R_LoadTextures() (*texindex)++; @@ -1017,6 +1015,41 @@ lumpnum_t R_GetFlatNumForName(const char *name) lump = LUMPERROR; } + // Lactozilla + if (lump == LUMPERROR) + { + // Scan wad files backwards so patched flats take preference. + for (i = numwadfiles - 1; i >= 0; i--) + { + switch (wadfiles[i]->type) + { + case RET_WAD: + if ((start = W_CheckNumForNamePwad("TX_START", (UINT16)i, 0)) == INT16_MAX) + continue; + if ((end = W_CheckNumForNamePwad("TX_END", (UINT16)i, start)) == INT16_MAX) + continue; + break; + case RET_PK3: + if ((start = W_CheckNumForFolderStartPK3("Textures/", i, 0)) == INT16_MAX) + continue; + if ((end = W_CheckNumForFolderEndPK3("Textures/", i, start)) == INT16_MAX) + continue; + break; + default: + continue; + } + + // Now find lump with specified name in that range. + lump = W_CheckNumForNamePwad(name, (UINT16)i, start); + if (lump < end) + { + lump += (i<<16); // found it, in our constraints + break; + } + lump = LUMPERROR; + } + } + if (lump == LUMPERROR) { if (strcmp(name, SKYFLATNAME)) @@ -1603,3 +1636,144 @@ void R_PrecacheLevel(void) "texturememory: %s k\n" "spritememory: %s k\n", sizeu1(flatmemory>>10), sizeu2(texturememory>>10), sizeu3(spritememory>>10)); } + +// https://github.com/coelckers/prboom-plus/blob/master/prboom2/src/r_patch.c#L350 +boolean R_CheckIfPatch(lumpnum_t lump) +{ + size_t size; + INT16 width, height; + patch_t *patch; + boolean result; + + size = W_LumpLength(lump); + + // minimum length of a valid Doom patch + if (size < 13) + return false; + + patch = (patch_t *)W_CacheLumpNum(lump, PU_STATIC); + + width = SHORT(patch->width); + height = SHORT(patch->height); + + result = (height > 0 && height <= 16384 && width > 0 && width <= 16384 && width < size / 4); + + if (result) + { + // The dimensions seem like they might be valid for a patch, so + // check the column directory for extra security. All columns + // must begin after the column directory, and none of them must + // point past the end of the patch. + INT16 x; + + for (x = 0; x < width; x++) + { + UINT32 ofs = LONG(patch->columnofs[x]); + + // Need one byte for an empty column (but there's patches that don't know that!) + if (ofs < (UINT32)width * 4 + 8 || ofs >= (UINT32)size) + { + result = false; + break; + + } + } + } + + Z_Free(patch); + return result; +} + +// Lactozilla +void R_FlatPatch(patch_t *patch, UINT8 *flat) +{ + fixed_t col, ofs; + column_t *column; + UINT8 *desttop, *dest, *deststop; + UINT8 *source; + + desttop = flat; + deststop = desttop + (patch->width * patch->height); + + for (col = 0; col < SHORT(patch->width); col++, desttop++) + { + INT32 topdelta, prevdelta = -1; + column = (column_t *)((UINT8 *)patch + LONG(patch->columnofs[col])); + + while (column->topdelta != 0xff) + { + topdelta = column->topdelta; + if (topdelta <= prevdelta) + topdelta += prevdelta; + prevdelta = topdelta; + + dest = desttop + (topdelta * patch->width); + source = (UINT8 *)(column) + 3; + for (ofs = 0; dest < deststop && ofs < column->length; ofs++) + { + if (source[ofs] != TRANSPARENTPIXEL) + *dest = source[ofs]; + dest += patch->width; + } + column = (column_t *)((UINT8 *)column + column->length + 4); + } + } +} + +void R_FlatTexture(size_t tex, UINT8 *flat) +{ + texture_t *texture = textures[tex]; + + fixed_t col, ofs; + column_t *column; + UINT8 *desttop, *dest, *deststop; + UINT8 *source; + + desttop = flat; + deststop = desttop + (texture->width * texture->height); + + for (col = 0; col < SHORT(texture->width); col++, desttop++) + { + INT32 topdelta, prevdelta = -1; + column = (column_t *)R_GetColumn(tex, col); + if (!texture->holes) + { + dest = desttop; + source = (UINT8 *)(column); + for (ofs = 0; dest < deststop && ofs < texture->height; ofs++) + { + if (source[ofs] != TRANSPARENTPIXEL) + *dest = source[ofs]; + dest += texture->width; + } + } + else + { + while (column->topdelta != 0xff) + { + 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++) + { + if (source[ofs] != TRANSPARENTPIXEL) + *dest = source[ofs]; + dest += texture->width; + } + column = (column_t *)((UINT8 *)column + column->length + 4); + } + } + } +} + +void R_CropFlat(UINT8 *origflat, UINT8 *cropflat, UINT16 origwidth, UINT16 origheight, UINT16 cropwidth, UINT16 cropheight) +{ + UINT16 x, y; + for (y = 0; y < cropheight; y++) + for (x = 0; x < cropwidth; x++) + cropflat[(y * cropwidth) + x] = origflat[(y * origwidth) + x]; +} diff --git a/src/r_data.h b/src/r_data.h index 5de51ccd4..a1e7cd127 100644 --- a/src/r_data.h +++ b/src/r_data.h @@ -51,9 +51,7 @@ typedef struct // all loaded and prepared textures from the start of the game extern texture_t **textures; -// texture width is a power of 2, so it can easily repeat along sidedefs using a simple mask -extern INT32 *texturewidthmask; - +extern INT32 *texturewidth; extern fixed_t *textureheight; // needed for texture pegging extern INT16 color8to16[256]; // remap color index to highcolor @@ -81,7 +79,6 @@ void R_PrecacheLevel(void); // Floor/ceiling opaque texture tiles, // lookup by name. For animation? lumpnum_t R_GetFlatNumForName(const char *name); -#define R_FlatNumForName(x) R_GetFlatNumForName(x) // Called by P_Ticker for switches and animations, // returns the texture number for the texture name. @@ -95,6 +92,13 @@ INT32 R_ColormapNumForName(char *name); INT32 R_CreateColormap(char *p1, char *p2, char *p3); const char *R_ColormapNameForNum(INT32 num); +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); + extern INT32 numtextures; #endif diff --git a/src/r_draw.c b/src/r_draw.c index bbc9a79b0..babcbef08 100644 --- a/src/r_draw.c +++ b/src/r_draw.c @@ -99,6 +99,8 @@ INT32 dc_numlights = 0, dc_maxlights, dc_texheight; INT32 ds_y, ds_x1, ds_x2; lighttable_t *ds_colormap; fixed_t ds_xfrac, ds_yfrac, ds_xstep, ds_ystep; +UINT16 ds_flatwidth, ds_flatheight; +boolean ds_powersoftwo; UINT8 *ds_source; // start of a 64*64 tile image UINT8 *ds_transmap; // one of the translucency tables diff --git a/src/r_draw.h b/src/r_draw.h index 12f556b7a..e82f60839 100644 --- a/src/r_draw.h +++ b/src/r_draw.h @@ -57,7 +57,9 @@ extern INT32 dc_texheight; extern INT32 ds_y, ds_x1, ds_x2; extern lighttable_t *ds_colormap; extern fixed_t ds_xfrac, ds_yfrac, ds_xstep, ds_ystep; -extern UINT8 *ds_source; // start of a 64*64 tile image +extern UINT16 ds_flatwidth, ds_flatheight; +extern boolean ds_powersoftwo; +extern UINT8 *ds_source; extern UINT8 *ds_transmap; #ifdef ESLOPE @@ -125,6 +127,8 @@ void R_FillBackScreen(void); void R_DrawViewBorder(void); #endif +#define TRANSPARENTPIXEL 247 + // ----------------- // 8bpp DRAWING CODE // ----------------- @@ -166,6 +170,13 @@ void R_DrawFogSpan_8(void); void R_DrawFogColumn_8(void); void R_DrawColumnShadowed_8(void); +#ifndef NOWATER +void R_DrawTranslucentWaterSpan_8(void); + +extern INT32 ds_bgofs; +extern INT32 ds_waterofs; +#endif + // ------------------ // 16bpp DRAWING CODE // ------------------ diff --git a/src/r_draw8.c b/src/r_draw8.c index 886b72dae..f829707d3 100644 --- a/src/r_draw8.c +++ b/src/r_draw8.c @@ -105,8 +105,6 @@ void R_DrawColumn_8(void) } } -#define TRANSPARENTPIXEL 247 - void R_Draw2sMultiPatchColumn_8(void) { INT32 count; @@ -543,80 +541,60 @@ void R_DrawTranslatedColumn_8(void) */ void R_DrawSpan_8 (void) { - UINT32 xposition; - UINT32 yposition; - UINT32 xstep, ystep; + fixed_t xposition; + fixed_t yposition; + fixed_t xstep, ystep; UINT8 *source; UINT8 *colormap; UINT8 *dest; const UINT8 *deststop = screens[0] + vid.rowbytes * vid.height; - size_t count; + UINT32 flatsize = ds_flatwidth * ds_flatheight; + size_t count = (ds_x2 - ds_x1 + 1); - // SoM: we only need 6 bits for the integer part (0 thru 63) so the rest - // can be used for the fraction part. This allows calculation of the memory address in the - // texture with two shifts, an OR and one AND. (see below) - // for texture sizes > 64 the amount of precision we can allow will decrease, but only by one - // bit per power of two (obviously) - // Ok, because I was able to eliminate the variable spot below, this function is now FASTER - // than the original span renderer. Whodathunkit? - xposition = ds_xfrac << nflatshiftup; yposition = ds_yfrac << nflatshiftup; - xstep = ds_xstep << nflatshiftup; ystep = ds_ystep << nflatshiftup; + xposition = ds_xfrac; yposition = ds_yfrac; + xstep = ds_xstep; ystep = ds_ystep; + + if (ds_powersoftwo) + { + xposition <<= nflatshiftup; yposition <<= nflatshiftup; + xstep <<= nflatshiftup; ystep <<= nflatshiftup; + } source = ds_source; colormap = ds_colormap; dest = ylookup[ds_y] + columnofs[ds_x1]; - count = ds_x2 - ds_x1 + 1; - if (dest+8 > deststop) + if (dest > deststop) return; - while (count >= 8) + if (!ds_powersoftwo) { - // SoM: Why didn't I see this earlier? the spot variable is a waste now because we don't - // have the uber complicated math to calculate it now, so that was a memory write we didn't - // need! - dest[0] = colormap[source[((yposition >> nflatyshift) & nflatmask) | (xposition >> nflatxshift)]]; - xposition += xstep; - yposition += ystep; + while (count-- && dest <= deststop) + { + fixed_t x = (xposition >> FRACBITS); + fixed_t y = (yposition >> FRACBITS); - dest[1] = colormap[source[((yposition >> nflatyshift) & nflatmask) | (xposition >> nflatxshift)]]; - xposition += xstep; - yposition += ystep; + // Carefully align all of my Friends. + if (x < 0) + x = ds_flatwidth - ((UINT32)(ds_flatwidth - x) % ds_flatwidth); + if (y < 0) + y = ds_flatheight - ((UINT32)(ds_flatheight - y) % ds_flatheight); - dest[2] = colormap[source[((yposition >> nflatyshift) & nflatmask) | (xposition >> nflatxshift)]]; - xposition += xstep; - yposition += ystep; - - dest[3] = colormap[source[((yposition >> nflatyshift) & nflatmask) | (xposition >> nflatxshift)]]; - xposition += xstep; - yposition += ystep; - - dest[4] = colormap[source[((yposition >> nflatyshift) & nflatmask) | (xposition >> nflatxshift)]]; - xposition += xstep; - yposition += ystep; - - dest[5] = colormap[source[((yposition >> nflatyshift) & nflatmask) | (xposition >> nflatxshift)]]; - xposition += xstep; - yposition += ystep; - - dest[6] = colormap[source[((yposition >> nflatyshift) & nflatmask) | (xposition >> nflatxshift)]]; - xposition += xstep; - yposition += ystep; - - dest[7] = colormap[source[((yposition >> nflatyshift) & nflatmask) | (xposition >> nflatxshift)]]; - xposition += xstep; - yposition += ystep; - - dest += 8; - count -= 8; + *dest++ = colormap[source[((y * ds_flatwidth) + x) % flatsize]]; + xposition += xstep; + yposition += ystep; + } } - while (count-- && dest <= deststop) + else { - *dest++ = colormap[source[((yposition >> nflatyshift) & nflatmask) | (xposition >> nflatxshift)]]; - xposition += xstep; - yposition += ystep; + while (count-- && dest <= deststop) + { + *dest++ = colormap[source[(((UINT32)yposition >> nflatyshift) & nflatmask) | ((UINT32)xposition >> nflatxshift)]]; + xposition += xstep; + yposition += ystep; + } } } @@ -1065,117 +1043,64 @@ void R_DrawTiltedSplat_8(void) */ void R_DrawSplat_8 (void) { - UINT32 xposition; - UINT32 yposition; - UINT32 xstep, ystep; + fixed_t xposition; + fixed_t yposition; + fixed_t xstep, ystep; UINT8 *source; UINT8 *colormap; UINT8 *dest; + const UINT8 *deststop = screens[0] + vid.rowbytes * vid.height; - size_t count; + UINT32 flatsize = ds_flatwidth * ds_flatheight; + size_t count = (ds_x2 - ds_x1 + 1); UINT32 val; - // SoM: we only need 6 bits for the integer part (0 thru 63) so the rest - // can be used for the fraction part. This allows calculation of the memory address in the - // texture with two shifts, an OR and one AND. (see below) - // for texture sizes > 64 the amount of precision we can allow will decrease, but only by one - // bit per power of two (obviously) - // Ok, because I was able to eliminate the variable spot below, this function is now FASTER - // than the original span renderer. Whodathunkit? - xposition = ds_xfrac << nflatshiftup; yposition = ds_yfrac << nflatshiftup; - xstep = ds_xstep << nflatshiftup; ystep = ds_ystep << nflatshiftup; + xposition = ds_xfrac; yposition = ds_yfrac; + xstep = ds_xstep; ystep = ds_ystep; + + if (ds_powersoftwo) + { + xposition <<= nflatshiftup; yposition <<= nflatshiftup; + xstep <<= nflatshiftup; ystep <<= nflatshiftup; + } source = ds_source; colormap = ds_colormap; dest = ylookup[ds_y] + columnofs[ds_x1]; - count = ds_x2 - ds_x1 + 1; - while (count >= 8) + if (!ds_powersoftwo) { - // SoM: Why didn't I see this earlier? the spot variable is a waste now because we don't - // have the uber complicated math to calculate it now, so that was a memory write we didn't - // need! - // - // 4194303 = (2048x2048)-1 (2048x2048 is maximum flat size) - val = ((yposition >> nflatyshift) & nflatmask) | (xposition >> nflatxshift); - val &= 4194303; - val = source[val]; - if (val != TRANSPARENTPIXEL) - dest[0] = colormap[val]; - xposition += xstep; - yposition += ystep; + while (count-- && dest <= deststop) + { + fixed_t x = (xposition >> FRACBITS); + fixed_t y = (yposition >> FRACBITS); - val = ((yposition >> nflatyshift) & nflatmask) | (xposition >> nflatxshift); - val &= 4194303; - val = source[val]; - if (val != TRANSPARENTPIXEL) - dest[1] = colormap[val]; - xposition += xstep; - yposition += ystep; + // Carefully align all of my Friends. + if (x < 0) + x = ds_flatwidth - ((UINT32)(ds_flatwidth - x) % ds_flatwidth); + if (y < 0) + y = ds_flatheight - ((UINT32)(ds_flatheight - y) % ds_flatheight); - val = ((yposition >> nflatyshift) & nflatmask) | (xposition >> nflatxshift); - val &= 4194303; - val = source[val]; - if (val != TRANSPARENTPIXEL) - dest[2] = colormap[val]; - xposition += xstep; - yposition += ystep; - - val = ((yposition >> nflatyshift) & nflatmask) | (xposition >> nflatxshift); - val &= 4194303; - val = source[val]; - if (val != TRANSPARENTPIXEL) - dest[3] = colormap[val]; - xposition += xstep; - yposition += ystep; - - val = ((yposition >> nflatyshift) & nflatmask) | (xposition >> nflatxshift); - val &= 4194303; - val = source[val]; - if (val != TRANSPARENTPIXEL) - dest[4] = colormap[val]; - xposition += xstep; - yposition += ystep; - - val = ((yposition >> nflatyshift) & nflatmask) | (xposition >> nflatxshift); - val &= 4194303; - val = source[val]; - if (val != TRANSPARENTPIXEL) - dest[5] = colormap[val]; - xposition += xstep; - yposition += ystep; - - val = ((yposition >> nflatyshift) & nflatmask) | (xposition >> nflatxshift); - val &= 4194303; - val = source[val]; - if (val != TRANSPARENTPIXEL) - dest[6] = colormap[val]; - xposition += xstep; - yposition += ystep; - - val = ((yposition >> nflatyshift) & nflatmask) | (xposition >> nflatxshift); - val &= 4194303; - val = source[val]; - if (val != TRANSPARENTPIXEL) - dest[7] = colormap[val]; - xposition += xstep; - yposition += ystep; - - dest += 8; - count -= 8; + val = source[((y * ds_flatwidth) + x) % flatsize]; + if (val != TRANSPARENTPIXEL) + *dest = colormap[val]; + dest++; + xposition += xstep; + yposition += ystep; + } } - while (count--) + else { - val = ((yposition >> nflatyshift) & nflatmask) | (xposition >> nflatxshift); - val &= 4194303; - val = source[val]; - if (val != TRANSPARENTPIXEL) - *dest = colormap[val]; - - dest++; - xposition += xstep; - yposition += ystep; + while (count-- && dest <= deststop) + { + val = source[(((UINT32)yposition >> nflatyshift) & nflatmask) | ((UINT32)xposition >> nflatxshift)]; + if (val != TRANSPARENTPIXEL) + *dest = colormap[val]; + dest++; + xposition += xstep; + yposition += ystep; + } } } @@ -1184,97 +1109,64 @@ void R_DrawSplat_8 (void) */ void R_DrawTranslucentSplat_8 (void) { - UINT32 xposition; - UINT32 yposition; - UINT32 xstep, ystep; + fixed_t xposition; + fixed_t yposition; + fixed_t xstep, ystep; UINT8 *source; UINT8 *colormap; UINT8 *dest; + const UINT8 *deststop = screens[0] + vid.rowbytes * vid.height; - size_t count; - UINT8 val; + UINT32 flatsize = ds_flatwidth * ds_flatheight; + size_t count = (ds_x2 - ds_x1 + 1); + UINT32 val; - // SoM: we only need 6 bits for the integer part (0 thru 63) so the rest - // can be used for the fraction part. This allows calculation of the memory address in the - // texture with two shifts, an OR and one AND. (see below) - // for texture sizes > 64 the amount of precision we can allow will decrease, but only by one - // bit per power of two (obviously) - // Ok, because I was able to eliminate the variable spot below, this function is now FASTER - // than the original span renderer. Whodathunkit? - xposition = ds_xfrac << nflatshiftup; yposition = ds_yfrac << nflatshiftup; - xstep = ds_xstep << nflatshiftup; ystep = ds_ystep << nflatshiftup; + xposition = ds_xfrac; yposition = ds_yfrac; + xstep = ds_xstep; ystep = ds_ystep; + + if (ds_powersoftwo) + { + xposition <<= nflatshiftup; yposition <<= nflatshiftup; + xstep <<= nflatshiftup; ystep <<= nflatshiftup; + } source = ds_source; colormap = ds_colormap; dest = ylookup[ds_y] + columnofs[ds_x1]; - count = ds_x2 - ds_x1 + 1; - while (count >= 8) + if (!ds_powersoftwo) { - // SoM: Why didn't I see this earlier? the spot variable is a waste now because we don't - // have the uber complicated math to calculate it now, so that was a memory write we didn't - // need! - val = source[((yposition >> nflatyshift) & nflatmask) | (xposition >> nflatxshift)]; - if (val != TRANSPARENTPIXEL) - dest[0] = *(ds_transmap + (colormap[val] << 8) + dest[0]); - xposition += xstep; - yposition += ystep; + while (count-- && dest <= deststop) + { + fixed_t x = (xposition >> FRACBITS); + fixed_t y = (yposition >> FRACBITS); - val = source[((yposition >> nflatyshift) & nflatmask) | (xposition >> nflatxshift)]; - if (val != TRANSPARENTPIXEL) - dest[1] = *(ds_transmap + (colormap[val] << 8) + dest[1]); - xposition += xstep; - yposition += ystep; + // Carefully align all of my Friends. + if (x < 0) + x = ds_flatwidth - ((UINT32)(ds_flatwidth - x) % ds_flatwidth); + if (y < 0) + y = ds_flatheight - ((UINT32)(ds_flatheight - y) % ds_flatheight); - val = source[((yposition >> nflatyshift) & nflatmask) | (xposition >> nflatxshift)]; - if (val != TRANSPARENTPIXEL) - dest[2] = *(ds_transmap + (colormap[val] << 8) + dest[2]); - xposition += xstep; - yposition += ystep; - - val = source[((yposition >> nflatyshift) & nflatmask) | (xposition >> nflatxshift)]; - if (val != TRANSPARENTPIXEL) - dest[3] = *(ds_transmap + (colormap[val] << 8) + dest[3]); - xposition += xstep; - yposition += ystep; - - val = source[((yposition >> nflatyshift) & nflatmask) | (xposition >> nflatxshift)]; - if (val != TRANSPARENTPIXEL) - dest[4] = *(ds_transmap + (colormap[val] << 8) + dest[4]); - xposition += xstep; - yposition += ystep; - - val = source[((yposition >> nflatyshift) & nflatmask) | (xposition >> nflatxshift)]; - if (val != TRANSPARENTPIXEL) - dest[5] = *(ds_transmap + (colormap[val] << 8) + dest[5]); - xposition += xstep; - yposition += ystep; - - val = source[((yposition >> nflatyshift) & nflatmask) | (xposition >> nflatxshift)]; - if (val != TRANSPARENTPIXEL) - dest[6] = *(ds_transmap + (colormap[val] << 8) + dest[6]); - xposition += xstep; - yposition += ystep; - - val = source[((yposition >> nflatyshift) & nflatmask) | (xposition >> nflatxshift)]; - if (val != TRANSPARENTPIXEL) - dest[7] = *(ds_transmap + (colormap[val] << 8) + dest[7]); - xposition += xstep; - yposition += ystep; - - dest += 8; - count -= 8; + val = source[((y * ds_flatwidth) + x) % flatsize]; + if (val != TRANSPARENTPIXEL) + *dest = *(ds_transmap + (colormap[val] << 8) + *dest); + dest++; + xposition += xstep; + yposition += ystep; + } } - while (count--) + else { - val = source[((yposition >> nflatyshift) & nflatmask) | (xposition >> nflatxshift)]; - if (val != TRANSPARENTPIXEL) - *dest = *(ds_transmap + (colormap[val] << 8) + *dest); - - dest++; - xposition += xstep; - yposition += ystep; + while (count-- && dest <= deststop) + { + val = source[(((UINT32)yposition >> nflatyshift) & nflatmask) | ((UINT32)xposition >> nflatxshift)]; + if (val != TRANSPARENTPIXEL) + *dest = *(ds_transmap + (colormap[val] << 8) + *dest); + dest++; + xposition += xstep; + yposition += ystep; + } } } @@ -1283,80 +1175,125 @@ void R_DrawTranslucentSplat_8 (void) */ void R_DrawTranslucentSpan_8 (void) { - UINT32 xposition; - UINT32 yposition; - UINT32 xstep, ystep; + fixed_t xposition; + fixed_t yposition; + fixed_t xstep, ystep; UINT8 *source; UINT8 *colormap; UINT8 *dest; + const UINT8 *deststop = screens[0] + vid.rowbytes * vid.height; - size_t count; + UINT32 flatsize = ds_flatwidth * ds_flatheight; + size_t count = (ds_x2 - ds_x1 + 1); + UINT32 val; - // SoM: we only need 6 bits for the integer part (0 thru 63) so the rest - // can be used for the fraction part. This allows calculation of the memory address in the - // texture with two shifts, an OR and one AND. (see below) - // for texture sizes > 64 the amount of precision we can allow will decrease, but only by one - // bit per power of two (obviously) - // Ok, because I was able to eliminate the variable spot below, this function is now FASTER - // than the original span renderer. Whodathunkit? - xposition = ds_xfrac << nflatshiftup; yposition = ds_yfrac << nflatshiftup; - xstep = ds_xstep << nflatshiftup; ystep = ds_ystep << nflatshiftup; + xposition = ds_xfrac; yposition = ds_yfrac; + xstep = ds_xstep; ystep = ds_ystep; + + if (ds_powersoftwo) + { + xposition <<= nflatshiftup; yposition <<= nflatshiftup; + xstep <<= nflatshiftup; ystep <<= nflatshiftup; + } source = ds_source; colormap = ds_colormap; dest = ylookup[ds_y] + columnofs[ds_x1]; - count = ds_x2 - ds_x1 + 1; - while (count >= 8) + if (!ds_powersoftwo) { - // SoM: Why didn't I see this earlier? the spot variable is a waste now because we don't - // have the uber complicated math to calculate it now, so that was a memory write we didn't - // need! - dest[0] = *(ds_transmap + (colormap[source[((yposition >> nflatyshift) & nflatmask) | (xposition >> nflatxshift)]] << 8) + dest[0]); - xposition += xstep; - yposition += ystep; + while (count-- && dest <= deststop) + { + fixed_t x = (xposition >> FRACBITS); + fixed_t y = (yposition >> FRACBITS); - dest[1] = *(ds_transmap + (colormap[source[((yposition >> nflatyshift) & nflatmask) | (xposition >> nflatxshift)]] << 8) + dest[1]); - xposition += xstep; - yposition += ystep; + // Carefully align all of my Friends. + if (x < 0) + x = ds_flatwidth - ((UINT32)(ds_flatwidth - x) % ds_flatwidth); + if (y < 0) + y = ds_flatheight - ((UINT32)(ds_flatheight - y) % ds_flatheight); - dest[2] = *(ds_transmap + (colormap[source[((yposition >> nflatyshift) & nflatmask) | (xposition >> nflatxshift)]] << 8) + dest[2]); - xposition += xstep; - yposition += ystep; - - dest[3] = *(ds_transmap + (colormap[source[((yposition >> nflatyshift) & nflatmask) | (xposition >> nflatxshift)]] << 8) + dest[3]); - xposition += xstep; - yposition += ystep; - - dest[4] = *(ds_transmap + (colormap[source[((yposition >> nflatyshift) & nflatmask) | (xposition >> nflatxshift)]] << 8) + dest[4]); - xposition += xstep; - yposition += ystep; - - dest[5] = *(ds_transmap + (colormap[source[((yposition >> nflatyshift) & nflatmask) | (xposition >> nflatxshift)]] << 8) + dest[5]); - xposition += xstep; - yposition += ystep; - - dest[6] = *(ds_transmap + (colormap[source[((yposition >> nflatyshift) & nflatmask) | (xposition >> nflatxshift)]] << 8) + dest[6]); - xposition += xstep; - yposition += ystep; - - dest[7] = *(ds_transmap + (colormap[source[((yposition >> nflatyshift) & nflatmask) | (xposition >> nflatxshift)]] << 8) + dest[7]); - xposition += xstep; - yposition += ystep; - - dest += 8; - count -= 8; + val = ((y * ds_flatwidth) + x) % flatsize; + *dest = *(ds_transmap + (colormap[source[val]] << 8) + *dest); + dest++; + xposition += xstep; + yposition += ystep; + } } - while (count--) + else { - *dest = *(ds_transmap + (colormap[source[((yposition >> nflatyshift) & nflatmask) | (xposition >> nflatxshift)]] << 8) + *dest); - dest++; - xposition += xstep; - yposition += ystep; + while (count-- && dest <= deststop) + { + val = (((UINT32)yposition >> nflatyshift) & nflatmask) | ((UINT32)xposition >> nflatxshift); + *dest = *(ds_transmap + (colormap[source[val]] << 8) + *dest); + dest++; + xposition += xstep; + yposition += ystep; + } } } +#ifndef NOWATER +void R_DrawTranslucentWaterSpan_8(void) +{ + fixed_t xposition; + fixed_t yposition; + fixed_t xstep, ystep; + + UINT8 *source; + UINT8 *colormap; + UINT8 *dest; + UINT8 *dsrc; + const UINT8 *deststop = screens[0] + vid.rowbytes * vid.height; + + UINT32 flatsize = ds_flatwidth * ds_flatheight; + size_t count = (ds_x2 - ds_x1 + 1); + + xposition = ds_xfrac; yposition = (ds_yfrac + ds_waterofs); + xstep = ds_xstep; ystep = ds_ystep; + + if (ds_powersoftwo) + { + xposition <<= nflatshiftup; yposition <<= nflatshiftup; + xstep <<= nflatshiftup; ystep <<= nflatshiftup; + } + + source = ds_source; + colormap = ds_colormap; + dest = ylookup[ds_y] + columnofs[ds_x1]; + dsrc = screens[1] + (ds_y+ds_bgofs)*vid.width + ds_x1; + + if (!ds_powersoftwo) + { + while (count-- && dest <= deststop) + { + fixed_t x = (xposition >> FRACBITS); + fixed_t y = (yposition >> FRACBITS); + + // Carefully align all of my Friends. + if (x < 0) + x = ds_flatwidth - ((UINT32)(ds_flatwidth - x) % ds_flatwidth); + if (y < 0) + y = ds_flatheight - ((UINT32)(ds_flatheight - y) % ds_flatheight); + + *dest++ = colormap[*(ds_transmap + (source[((y * ds_flatwidth) + x) % flatsize] << 8) + *dsrc++)]; + xposition += xstep; + yposition += ystep; + } + } + else + { + while (count-- && dest <= deststop) + { + *dest++ = colormap[*(ds_transmap + (source[(((UINT32)yposition >> nflatyshift) & nflatmask) | ((UINT32)xposition >> nflatxshift)] << 8) + *dsrc++)]; + xposition += xstep; + yposition += ystep; + } + } +} +#endif + /** \brief The R_DrawFogSpan_8 function Draws the actual span with fogging. */ diff --git a/src/r_plane.c b/src/r_plane.c index 5cb53a530..39f1d220a 100644 --- a/src/r_plane.c +++ b/src/r_plane.c @@ -173,91 +173,13 @@ void R_PortalRestoreClipValues(INT32 start, INT32 end, INT16 *ceil, INT16 *floor // viewheight #ifndef NOWATER -static INT32 bgofs; +INT32 ds_bgofs; +INT32 ds_waterofs; + static INT32 wtofs=0; -static INT32 waterofs; static boolean itswater; #endif -#ifndef NOWATER -static void R_DrawTranslucentWaterSpan_8(void) -{ - UINT32 xposition; - UINT32 yposition; - UINT32 xstep, ystep; - - UINT8 *source; - UINT8 *colormap; - UINT8 *dest; - UINT8 *dsrc; - - size_t count; - - // SoM: we only need 6 bits for the integer part (0 thru 63) so the rest - // can be used for the fraction part. This allows calculation of the memory address in the - // texture with two shifts, an OR and one AND. (see below) - // for texture sizes > 64 the amount of precision we can allow will decrease, but only by one - // bit per power of two (obviously) - // Ok, because I was able to eliminate the variable spot below, this function is now FASTER - // than the original span renderer. Whodathunkit? - xposition = ds_xfrac << nflatshiftup; yposition = (ds_yfrac + waterofs) << nflatshiftup; - xstep = ds_xstep << nflatshiftup; ystep = ds_ystep << nflatshiftup; - - source = ds_source; - colormap = ds_colormap; - dest = ylookup[ds_y] + columnofs[ds_x1]; - dsrc = screens[1] + (ds_y+bgofs)*vid.width + ds_x1; - count = ds_x2 - ds_x1 + 1; - - while (count >= 8) - { - // SoM: Why didn't I see this earlier? the spot variable is a waste now because we don't - // have the uber complicated math to calculate it now, so that was a memory write we didn't - // need! - dest[0] = colormap[*(ds_transmap + (source[((yposition >> nflatyshift) & nflatmask) | (xposition >> nflatxshift)] << 8) + *dsrc++)]; - xposition += xstep; - yposition += ystep; - - dest[1] = colormap[*(ds_transmap + (source[((yposition >> nflatyshift) & nflatmask) | (xposition >> nflatxshift)] << 8) + *dsrc++)]; - xposition += xstep; - yposition += ystep; - - dest[2] = colormap[*(ds_transmap + (source[((yposition >> nflatyshift) & nflatmask) | (xposition >> nflatxshift)] << 8) + *dsrc++)]; - xposition += xstep; - yposition += ystep; - - dest[3] = colormap[*(ds_transmap + (source[((yposition >> nflatyshift) & nflatmask) | (xposition >> nflatxshift)] << 8) + *dsrc++)]; - xposition += xstep; - yposition += ystep; - - dest[4] = colormap[*(ds_transmap + (source[((yposition >> nflatyshift) & nflatmask) | (xposition >> nflatxshift)] << 8) + *dsrc++)]; - xposition += xstep; - yposition += ystep; - - dest[5] = colormap[*(ds_transmap + (source[((yposition >> nflatyshift) & nflatmask) | (xposition >> nflatxshift)] << 8) + *dsrc++)]; - xposition += xstep; - yposition += ystep; - - dest[6] = colormap[*(ds_transmap + (source[((yposition >> nflatyshift) & nflatmask) | (xposition >> nflatxshift)] << 8) + *dsrc++)]; - xposition += xstep; - yposition += ystep; - - dest[7] = colormap[*(ds_transmap + (source[((yposition >> nflatyshift) & nflatmask) | (xposition >> nflatxshift)] << 8) + *dsrc++)]; - xposition += xstep; - yposition += ystep; - - dest += 8; - count -= 8; - } - while (count--) - { - *dest++ = colormap[*(ds_transmap + (source[((yposition >> nflatyshift) & nflatmask) | (xposition >> nflatxshift)] << 8) + *dsrc++)]; - xposition += xstep; - yposition += ystep; - } -} -#endif - void R_MapPlane(INT32 y, INT32 x1, INT32 x2) { angle_t angle, planecos, planesin; @@ -304,17 +226,17 @@ void R_MapPlane(INT32 y, INT32 x1, INT32 x2) { const INT32 yay = (wtofs + (distance>>9) ) & 8191; // ripples da water texture - bgofs = FixedDiv(FINESINE(yay), (1<<12) + (distance>>11))>>FRACBITS; + ds_bgofs = FixedDiv(FINESINE(yay), (1<<12) + (distance>>11))>>FRACBITS; angle = (currentplane->viewangle + currentplane->plangle + xtoviewangle[x1])>>ANGLETOFINESHIFT; angle = (angle + 2048) & 8191; // 90 degrees - ds_xfrac += FixedMul(FINECOSINE(angle), (bgofs<=viewheight) - bgofs = viewheight-y-1; - if (y+bgofs<0) - bgofs = -y; + if (y+ds_bgofs>=viewheight) + ds_bgofs = viewheight-y-1; + if (y+ds_bgofs<0) + ds_bgofs = -y; } #endif @@ -726,11 +648,142 @@ void R_DrawPlanes(void) } } #ifndef NOWATER - waterofs = (leveltime & 1)*16384; + ds_waterofs = (leveltime & 1)*16384; wtofs = leveltime * 140; #endif } +// Lactozilla +static void R_GetPatchFlat(levelflat_t *levelflat, boolean leveltexture) +{ + patch_t *patch = NULL; + + if (levelflat->flatpatch == NULL) + { +#ifdef ESLOPE + INT32 resizewidth, resizeheight, newresize; +#endif // ESLOPE + + if (!leveltexture) + { + patch = (patch_t *)ds_source; + levelflat->width = ds_flatwidth = patch->width; + levelflat->height = ds_flatheight = patch->height; + + levelflat->flatpatch = Z_Malloc(ds_flatwidth * ds_flatheight, PU_LEVEL, NULL); + memset(levelflat->flatpatch, TRANSPARENTPIXEL, ds_flatwidth * ds_flatheight); + R_FlatPatch(patch, levelflat->flatpatch); + + levelflat->topoffset = patch->topoffset * FRACUNIT; + levelflat->leftoffset = patch->leftoffset * FRACUNIT; + } + else + { + texture_t *texture = textures[levelflat->texturenum]; + levelflat->width = ds_flatwidth = texture->width; + levelflat->height = ds_flatheight = texture->height; + + levelflat->flatpatch = Z_Malloc(ds_flatwidth * ds_flatheight, PU_LEVEL, NULL); + memset(levelflat->flatpatch, TRANSPARENTPIXEL, ds_flatwidth * ds_flatheight); + R_FlatTexture(levelflat->texturenum, levelflat->flatpatch); + + levelflat->topoffset = levelflat->leftoffset = 0; + } + ds_source = levelflat->flatpatch; + + // If GZDoom has the same limitation then I'm not even going to bother. + // Crop the texture. +#ifdef ESLOPE + // Scale up to nearest power of 2 + resizewidth = resizeheight = 1; + while (resizewidth < levelflat->width) + 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; + + 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); +#endif // ESLOPE + } + else + { + ds_source = levelflat->flatpatch; + ds_flatwidth = levelflat->width; + ds_flatheight = levelflat->height; + + xoffs += levelflat->leftoffset; + yoffs += levelflat->topoffset; + } + +#ifdef ESLOPE + if (currentplane->slope) + { + ds_source = levelflat->resizedflat; + ds_flatwidth = levelflat->resizedwidth; + ds_flatheight = levelflat->resizedheight; + + // uuuuuuuhhhhhhhh....................... + switch (ds_flatwidth * ds_flatheight) + { + case 4194304: // 2048x2048 lump + nflatmask = 0x3FF800; + nflatxshift = 21; + nflatyshift = 10; + nflatshiftup = 5; + break; + case 1048576: // 1024x1024 lump + nflatmask = 0xFFC00; + nflatxshift = 22; + nflatyshift = 12; + nflatshiftup = 6; + break; + case 262144:// 512x512 lump + nflatmask = 0x3FE00; + nflatxshift = 23; + nflatyshift = 14; + nflatshiftup = 7; + break; + case 65536: // 256x256 lump + nflatmask = 0xFF00; + nflatxshift = 24; + nflatyshift = 16; + nflatshiftup = 8; + break; + case 16384: // 128x128 lump + nflatmask = 0x3F80; + nflatxshift = 25; + nflatyshift = 18; + nflatshiftup = 9; + break; + case 1024: // 32x32 lump + nflatmask = 0x3E0; + nflatxshift = 27; + nflatyshift = 22; + nflatshiftup = 11; + break; + default: // 64x64 lump + nflatmask = 0xFC0; + nflatxshift = 26; + nflatyshift = 20; + nflatshiftup = 10; + break; + } + } +#endif // ESLOPE +} + void R_DrawSinglePlane(visplane_t *pl) { INT32 light = 0; @@ -738,6 +791,7 @@ void R_DrawSinglePlane(visplane_t *pl) INT32 stop, angle; size_t size; ffloor_t *rover; + levelflat_t *levelflat; if (!(pl->minx <= pl->maxx)) return; @@ -878,64 +932,78 @@ void R_DrawSinglePlane(visplane_t *pl) viewangle = pl->viewangle+pl->plangle; } - currentplane = pl; - - ds_source = (UINT8 *) - W_CacheLumpNum(levelflats[pl->picnum].lumpnum, - PU_STATIC); // Stay here until Z_ChangeTag - - size = W_LumpLength(levelflats[pl->picnum].lumpnum); - - switch (size) - { - case 4194304: // 2048x2048 lump - nflatmask = 0x3FF800; - nflatxshift = 21; - nflatyshift = 10; - nflatshiftup = 5; - break; - case 1048576: // 1024x1024 lump - nflatmask = 0xFFC00; - nflatxshift = 22; - nflatyshift = 12; - nflatshiftup = 6; - break; - case 262144:// 512x512 lump' - nflatmask = 0x3FE00; - nflatxshift = 23; - nflatyshift = 14; - nflatshiftup = 7; - break; - case 65536: // 256x256 lump - nflatmask = 0xFF00; - nflatxshift = 24; - nflatyshift = 16; - nflatshiftup = 8; - break; - case 16384: // 128x128 lump - nflatmask = 0x3F80; - nflatxshift = 25; - nflatyshift = 18; - nflatshiftup = 9; - break; - case 1024: // 32x32 lump - nflatmask = 0x3E0; - nflatxshift = 27; - nflatyshift = 22; - nflatshiftup = 11; - break; - default: // 64x64 lump - nflatmask = 0xFC0; - nflatxshift = 26; - nflatyshift = 20; - nflatshiftup = 10; - break; - } - xoffs = pl->xoffs; yoffs = pl->yoffs; planeheight = abs(pl->height - pl->viewz); + currentplane = pl; + levelflat = &levelflats[pl->picnum]; + + if (levelflat->texturenum != 0 && levelflat->texturenum != -1) + R_GetPatchFlat(levelflat, true); + else + { + ds_source = (UINT8 *)W_CacheLumpNum(levelflat->lumpnum, PU_STATIC); // Stay here until Z_ChangeTag + size = W_LumpLength(levelflat->lumpnum); + + switch (size) + { + case 4194304: // 2048x2048 lump + nflatmask = 0x3FF800; + nflatxshift = 21; + nflatyshift = 10; + nflatshiftup = 5; + ds_flatwidth = ds_flatheight = 2048; + break; + case 1048576: // 1024x1024 lump + nflatmask = 0xFFC00; + nflatxshift = 22; + nflatyshift = 12; + nflatshiftup = 6; + ds_flatwidth = ds_flatheight = 1024; + break; + case 262144:// 512x512 lump + nflatmask = 0x3FE00; + nflatxshift = 23; + nflatyshift = 14; + nflatshiftup = 7; + ds_flatwidth = ds_flatheight = 512; + break; + case 65536: // 256x256 lump + nflatmask = 0xFF00; + nflatxshift = 24; + nflatyshift = 16; + nflatshiftup = 8; + ds_flatwidth = ds_flatheight = 256; + break; + case 16384: // 128x128 lump + nflatmask = 0x3F80; + nflatxshift = 25; + nflatyshift = 18; + nflatshiftup = 9; + ds_flatwidth = ds_flatheight = 128; + break; + case 1024: // 32x32 lump + nflatmask = 0x3E0; + nflatxshift = 27; + nflatyshift = 22; + nflatshiftup = 11; + ds_flatwidth = ds_flatheight = 32; + break; + default: // 64x64 lump + nflatmask = 0xFC0; + nflatxshift = 26; + nflatyshift = 20; + nflatshiftup = 10; + ds_flatwidth = ds_flatheight = 64; + break; + } + } + + if (R_CheckIfPatch(levelflat->lumpnum)) + R_GetPatchFlat(levelflat, false); + ds_powersoftwo = (!((ds_flatwidth & (ds_flatwidth - 1)) || (ds_flatheight & (ds_flatheight - 1)))); + if (light >= LIGHTLEVELS) light = LIGHTLEVELS-1; diff --git a/src/screen.c b/src/screen.c index af6aed03c..893fb851f 100644 --- a/src/screen.c +++ b/src/screen.c @@ -135,7 +135,7 @@ void SCR_SetMode(void) //fuzzcolfunc = R_DrawTranslucentColumn_8_ASM; walldrawerfunc = R_DrawWallColumn_8_MMX; twosmultipatchfunc = R_Draw2sMultiPatchColumn_8_MMX; - spanfunc = basespanfunc = R_DrawSpan_8_MMX; + //spanfunc = basespanfunc = R_DrawSpan_8_MMX; } else { From 35d6da159d91428060bf1a0c47242d9a53aa17d9 Mon Sep 17 00:00:00 2001 From: Jaime Passos Date: Tue, 21 May 2019 09:50:39 -0300 Subject: [PATCH 02/13] HOLD UP --- src/hardware/hw_cache.c | 2 -- src/r_data.c | 1 - 2 files changed, 3 deletions(-) diff --git a/src/hardware/hw_cache.c b/src/hardware/hw_cache.c index 4ae7a43b9..84ad4c55b 100644 --- a/src/hardware/hw_cache.c +++ b/src/hardware/hw_cache.c @@ -677,8 +677,6 @@ static void HWR_LoadPatchFlat(GLMipmap_t *grMipmap, lumpnum_t flatlumpnum) grMipmap->height = (UINT16)SHORT(patch->height); R_FlatPatch(patch, Z_Malloc(grMipmap->width * grMipmap->height, PU_HWRCACHE, &grMipmap->grInfo.data)); - - Z_Free(patch); } static void HWR_LoadTextureFlat(GLMipmap_t *grMipmap, INT32 texturenum) diff --git a/src/r_data.c b/src/r_data.c index 496a0f944..8ceb59dd4 100644 --- a/src/r_data.c +++ b/src/r_data.c @@ -1680,7 +1680,6 @@ boolean R_CheckIfPatch(lumpnum_t lump) } } - Z_Free(patch); return result; } From 869f1e4e8d18a6c02d4c9df095f0ff99e268e210 Mon Sep 17 00:00:00 2001 From: Jaime Passos Date: Tue, 21 May 2019 11:03:53 -0300 Subject: [PATCH 03/13] Fix warnings --- src/hardware/hw_main.c | 5 +++-- src/p_setup.h | 2 +- src/r_data.c | 37 +++++++++++++++++++++++++++++++------ src/r_data.h | 5 ++++- src/r_plane.c | 40 ++++++++++++++++++++++++++++++++++------ 5 files changed, 73 insertions(+), 16 deletions(-) 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 From dbb1575a6da394d95dcaaae108db991c8d2b8619 Mon Sep 17 00:00:00 2001 From: Jaime Passos Date: Tue, 21 May 2019 15:24:26 -0300 Subject: [PATCH 04/13] Animations, better flat management. --- src/p_setup.c | 5 +- src/p_setup.h | 10 +- src/p_spec.c | 26 ++-- src/r_data.c | 8 +- src/r_data.h | 13 +- src/r_plane.c | 336 ++++++++++++++++++++++++++------------------------ src/r_plane.h | 2 + 7 files changed, 224 insertions(+), 176 deletions(-) diff --git a/src/p_setup.c b/src/p_setup.c index 1061dbd0c..97bace860 100644 --- a/src/p_setup.c +++ b/src/p_setup.c @@ -564,8 +564,11 @@ INT32 P_AddLevelFlat(const char *flatname, levelflat_t *levelflat) // store the flat lump number levelflat->lumpnum = R_GetFlatNumForName(flatname); - // Lactozilla levelflat->texturenum = R_CheckTextureNumForName(flatname); + levelflat->lasttexturenum = levelflat->texturenum; + + levelflat->baselumpnum = LUMPERROR; + levelflat->basetexturenum = -1; #ifndef ZDEBUG CONS_Debug(DBG_SETUP, "flat #%03d: %s\n", atoi(sizeu1(numlevelflats)), levelflat->name); diff --git a/src/p_setup.h b/src/p_setup.h index eda6066d3..824584be7 100644 --- a/src/p_setup.h +++ b/src/p_setup.h @@ -36,20 +36,22 @@ typedef struct { char name[9]; // resource name from wad lumpnum_t lumpnum; // lump number of the flat + INT32 texturenum, lasttexturenum; // texture number of the flat + UINT16 width, height; + fixed_t topoffset, leftoffset; // for flat animation lumpnum_t baselumpnum; + INT32 basetexturenum; INT32 animseq; // start pos. in the anim sequence INT32 numpics; INT32 speed; - // Lactozilla + // for patchflats UINT8 *flatpatch; - UINT16 width, height; - fixed_t topoffset, leftoffset; - INT32 texturenum; #ifdef ESLOPE + // rescaled version of the above UINT8 *resizedflat; UINT16 resizedwidth, resizedheight; #endif diff --git a/src/p_spec.c b/src/p_spec.c index 60d784324..7fe18eec1 100644 --- a/src/p_spec.c +++ b/src/p_spec.c @@ -584,7 +584,19 @@ static inline void P_FindAnimatedFlat(INT32 animnum) for (i = 0; i < numlevelflats; i++, foundflats++) { // is that levelflat from the flat anim sequence ? - if (foundflats->lumpnum >= startflatnum && foundflats->lumpnum <= endflatnum) + if ((anims[animnum].istexture) && (foundflats->texturenum != 0 && foundflats->texturenum != -1) + && ((UINT16)foundflats->texturenum >= startflatnum && (UINT16)foundflats->texturenum <= endflatnum)) + { + foundflats->basetexturenum = startflatnum; + foundflats->animseq = foundflats->texturenum - startflatnum; + foundflats->numpics = endflatnum - startflatnum + 1; + foundflats->speed = anims[animnum].speed; + + CONS_Debug(DBG_SETUP, "animflat: #%03d name:%.8s animseq:%d numpics:%d speed:%d\n", + atoi(sizeu1(i)), foundflats->name, foundflats->animseq, + foundflats->numpics,foundflats->speed); + } + else if (foundflats->lumpnum >= startflatnum && foundflats->lumpnum <= endflatnum) { foundflats->baselumpnum = startflatnum; foundflats->animseq = foundflats->lumpnum - startflatnum; @@ -608,10 +620,7 @@ void P_SetupLevelFlatAnims(void) // the original game flat anim sequences for (i = 0; anims[i].istexture != -1; i++) - { - if (!anims[i].istexture) - P_FindAnimatedFlat(i); - } + P_FindAnimatedFlat(i); } // @@ -4794,9 +4803,12 @@ void P_UpdateSpecials(void) { if (foundflats->speed) // it is an animated flat { + // update the levelflat texture number + if (foundflats->basetexturenum != -1) + foundflats->texturenum = foundflats->basetexturenum + ((leveltime/foundflats->speed + foundflats->animseq) % foundflats->numpics); // update the levelflat lump number - foundflats->lumpnum = foundflats->baselumpnum + - ((leveltime/foundflats->speed + foundflats->animseq) % foundflats->numpics); + else if (foundflats->baselumpnum != LUMPERROR) + foundflats->lumpnum = foundflats->baselumpnum + ((leveltime/foundflats->speed + foundflats->animseq) % foundflats->numpics); } } } diff --git a/src/r_data.c b/src/r_data.c index 00d8de629..4157a8850 100644 --- a/src/r_data.c +++ b/src/r_data.c @@ -98,6 +98,7 @@ INT32 numtextures = 0; // total number of textures found, // size of following tables texture_t **textures = NULL; +textureflat_t *texflats = NULL; static UINT32 **texturecolumnofs; // column offset lookup table for each texture static UINT8 **texturecache; // graphics data for each generated full-size texture @@ -395,6 +396,7 @@ void R_LoadTextures(void) } Z_Free(texturetranslation); Z_Free(textures); + Z_Free(texflats); } // Load patches and textures. @@ -440,6 +442,7 @@ void R_LoadTextures(void) // Allocate memory and initialize to 0 for all the textures we are initialising. // There are actually 5 buffers allocated in one for convenience. textures = Z_Calloc((numtextures * sizeof(void *)) * 5, PU_STATIC, NULL); + texflats = Z_Calloc((numtextures * sizeof(*texflats)), PU_STATIC, NULL); // Allocate texture column offset table. texturecolumnofs = (void *)((UINT8 *)textures + (numtextures * sizeof(void *))); @@ -1015,10 +1018,10 @@ lumpnum_t R_GetFlatNumForName(const char *name) lump = LUMPERROR; } - // Lactozilla + // Detect textures if (lump == LUMPERROR) { - // Scan wad files backwards so patched flats take preference. + // Scan wad files backwards so patched textures take preference. for (i = numwadfiles - 1; i >= 0; i--) { switch (wadfiles[i]->type) @@ -1683,7 +1686,6 @@ boolean R_CheckIfPatch(lumpnum_t lump) return result; } -// Lactozilla void R_FlatPatch(patch_t *patch, UINT8 *flat) { fixed_t col, ofs; diff --git a/src/r_data.h b/src/r_data.h index 8cb41cd2f..855daa06d 100644 --- a/src/r_data.h +++ b/src/r_data.h @@ -48,8 +48,20 @@ typedef struct texpatch_t patches[0]; } texture_t; +typedef struct +{ + UINT8 *flat; + INT16 width, height; + +#ifdef ESLOPE + UINT8 *resizedflat; + INT16 resizedwidth, resizedheight; +#endif +} textureflat_t; + // all loaded and prepared textures from the start of the game extern texture_t **textures; +extern textureflat_t *texflats; extern INT32 *texturewidth; extern fixed_t *textureheight; // needed for texture pegging @@ -94,7 +106,6 @@ const char *R_ColormapNameForNum(INT32 num); 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 *srcflat, UINT8 *destflat, diff --git a/src/r_plane.c b/src/r_plane.c index 91b4f5f2c..01d0fdd37 100644 --- a/src/r_plane.c +++ b/src/r_plane.c @@ -653,96 +653,191 @@ void R_DrawPlanes(void) #endif } -// Lactozilla +boolean R_CheckPowersOfTwo(void) +{ + return (ds_powersoftwo = ((!((ds_flatwidth & (ds_flatwidth - 1)) || (ds_flatheight & (ds_flatheight - 1)))) && (ds_flatwidth == ds_flatheight))); +} + +void R_CheckFlatLength(size_t size) +{ + switch (size) + { + case 4194304: // 2048x2048 lump + nflatmask = 0x3FF800; + nflatxshift = 21; + nflatyshift = 10; + nflatshiftup = 5; + ds_flatwidth = ds_flatheight = 2048; + break; + case 1048576: // 1024x1024 lump + nflatmask = 0xFFC00; + nflatxshift = 22; + nflatyshift = 12; + nflatshiftup = 6; + ds_flatwidth = ds_flatheight = 1024; + break; + case 262144:// 512x512 lump + nflatmask = 0x3FE00; + nflatxshift = 23; + nflatyshift = 14; + nflatshiftup = 7; + ds_flatwidth = ds_flatheight = 512; + break; + case 65536: // 256x256 lump + nflatmask = 0xFF00; + nflatxshift = 24; + nflatyshift = 16; + nflatshiftup = 8; + ds_flatwidth = ds_flatheight = 256; + break; + case 16384: // 128x128 lump + nflatmask = 0x3F80; + nflatxshift = 25; + nflatyshift = 18; + nflatshiftup = 9; + ds_flatwidth = ds_flatheight = 128; + break; + case 1024: // 32x32 lump + nflatmask = 0x3E0; + nflatxshift = 27; + nflatyshift = 22; + nflatshiftup = 11; + ds_flatwidth = ds_flatheight = 32; + break; + default: // 64x64 lump + nflatmask = 0xFC0; + nflatxshift = 26; + nflatyshift = 20; + nflatshiftup = 10; + ds_flatwidth = ds_flatheight = 64; + break; + } +} + static void R_GetPatchFlat(levelflat_t *levelflat, boolean leveltexture) { + textureflat_t *texflat = &texflats[levelflat->texturenum]; patch_t *patch = NULL; + UINT8 *tex; + boolean texturechanged = (leveltexture ? (levelflat->texturenum != levelflat->lasttexturenum) : false); - if (levelflat->flatpatch == NULL) + // Check if the texture changed. + if (leveltexture && (!texturechanged)) + { + if (texflat != NULL && texflat->flat) + { + ds_source = texflat->flat; + ds_flatwidth = texflat->width; + ds_flatheight = texflat->height; + texturechanged = false; + } + else + texturechanged = true; + } + + // If the texture changed, or the patch doesn't exist, convert either of them to a flat. + if (levelflat->flatpatch == NULL || texturechanged) { #ifdef ESLOPE INT32 resizewidth, resizeheight, newresize; INT32 checkresizewidth, checkresizeheight; #endif // ESLOPE - if (!leveltexture) + if (leveltexture) + { + texture_t *texture = textures[levelflat->texturenum]; + texflat->width = ds_flatwidth = texture->width; + texflat->height = ds_flatheight = texture->height; + + texflat->flat = Z_Malloc(ds_flatwidth * ds_flatheight, PU_LEVEL, NULL); + memset(texflat->flat, TRANSPARENTPIXEL, ds_flatwidth * ds_flatheight); + R_FlatTexture(levelflat->texturenum, texflat->flat); + + ds_source = texflat->flat; + } + else { patch = (patch_t *)ds_source; levelflat->width = ds_flatwidth = patch->width; levelflat->height = ds_flatheight = patch->height; + levelflat->topoffset = patch->topoffset * FRACUNIT; + levelflat->leftoffset = patch->leftoffset * FRACUNIT; + levelflat->flatpatch = Z_Malloc(ds_flatwidth * ds_flatheight, PU_LEVEL, NULL); memset(levelflat->flatpatch, TRANSPARENTPIXEL, ds_flatwidth * ds_flatheight); R_FlatPatch(patch, levelflat->flatpatch); - levelflat->topoffset = patch->topoffset * FRACUNIT; - levelflat->leftoffset = patch->leftoffset * FRACUNIT; + ds_source = levelflat->flatpatch; } - else - { - texture_t *texture = textures[levelflat->texturenum]; - levelflat->width = ds_flatwidth = texture->width; - levelflat->height = ds_flatheight = texture->height; - levelflat->flatpatch = Z_Malloc(ds_flatwidth * ds_flatheight, PU_LEVEL, NULL); - memset(levelflat->flatpatch, TRANSPARENTPIXEL, ds_flatwidth * ds_flatheight); - R_FlatTexture(levelflat->texturenum, levelflat->flatpatch); - - levelflat->topoffset = levelflat->leftoffset = 0; - } - ds_source = levelflat->flatpatch; - - // If GZDoom has the same limitation then I'm not even going to bother. - // Crop the texture. #ifdef ESLOPE - // Scale up to nearest power of 2 - resizewidth = resizeheight = 1; - while (resizewidth < levelflat->width) - resizewidth <<= 1; - while (resizeheight < levelflat->height) - resizeheight <<= 1; - - // Scale down to fit in 2048x2048 - if (resizewidth > 2048) - resizewidth = 2048; - if (resizeheight > 2048) - resizeheight = 2048; - - // A single pixel difference is negligible. - checkresizewidth = levelflat->width - 1; - if (checkresizewidth & (checkresizewidth - 1)) + // Crop the flat, if necessary. + if (!R_CheckPowersOfTwo()) { - checkresizewidth += 2; + // Scale up to nearest power of 2 + resizewidth = resizeheight = 1; + while (resizewidth < ds_flatwidth) + resizewidth <<= 1; + while (resizeheight < ds_flatheight) + resizeheight <<= 1; + + // Scale down to fit in 2048x2048 + if (resizewidth > 2048) + resizewidth = 2048; + if (resizeheight > 2048) + resizeheight = 2048; + + // A single pixel difference is negligible. + checkresizewidth = ds_flatwidth - 1; if (checkresizewidth & (checkresizewidth - 1)) { - while (resizewidth > levelflat->width) - resizewidth >>= 1; + checkresizewidth += 2; + if (checkresizewidth & (checkresizewidth - 1)) + { + while (resizewidth > ds_flatwidth) + resizewidth >>= 1; + } + else + resizewidth = checkresizewidth; } else resizewidth = checkresizewidth; - } - else - resizewidth = checkresizewidth; - checkresizeheight = levelflat->height - 1; - if (checkresizeheight & (checkresizeheight - 1)) - { - checkresizeheight += 2; + checkresizeheight = ds_flatheight - 1; if (checkresizeheight & (checkresizeheight - 1)) { - while (resizeheight > levelflat->height) - resizeheight >>= 1; + checkresizeheight += 2; + if (checkresizeheight & (checkresizeheight - 1)) + { + while (resizeheight > ds_flatheight) + resizeheight >>= 1; + } + else + resizeheight = checkresizeheight; } 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, min(resizewidth, newresize), min(resizeheight, newresize), newresize, newresize); + // Find smallest size. + newresize = min(resizewidth, resizeheight); + + // Allocate texture. + tex = Z_Malloc(newresize * newresize, PU_LEVEL, NULL); + memset(tex, TRANSPARENTPIXEL, newresize * newresize); + R_CropFlat(ds_source, tex, ds_flatwidth, ds_flatheight, min(resizewidth, newresize), min(resizeheight, newresize), newresize, newresize); + + if (leveltexture) + { + texflat->resizedflat = tex; + texflat->resizedwidth = texflat->resizedheight = newresize; + } + else + { + levelflat->resizedflat = tex; + levelflat->resizedwidth = levelflat->resizedheight = newresize; + } + } #endif // ESLOPE } else @@ -758,58 +853,26 @@ static void R_GetPatchFlat(levelflat_t *levelflat, boolean leveltexture) #ifdef ESLOPE if (currentplane->slope) { - ds_source = levelflat->resizedflat; - ds_flatwidth = levelflat->resizedwidth; - ds_flatheight = levelflat->resizedheight; - - // uuuuuuuhhhhhhhh....................... - switch (ds_flatwidth * ds_flatheight) + if (R_CheckPowersOfTwo()) { - case 4194304: // 2048x2048 lump - nflatmask = 0x3FF800; - nflatxshift = 21; - nflatyshift = 10; - nflatshiftup = 5; - break; - case 1048576: // 1024x1024 lump - nflatmask = 0xFFC00; - nflatxshift = 22; - nflatyshift = 12; - nflatshiftup = 6; - break; - case 262144:// 512x512 lump - nflatmask = 0x3FE00; - nflatxshift = 23; - nflatyshift = 14; - nflatshiftup = 7; - break; - case 65536: // 256x256 lump - nflatmask = 0xFF00; - nflatxshift = 24; - nflatyshift = 16; - nflatshiftup = 8; - break; - case 16384: // 128x128 lump - nflatmask = 0x3F80; - nflatxshift = 25; - nflatyshift = 18; - nflatshiftup = 9; - break; - case 1024: // 32x32 lump - nflatmask = 0x3E0; - nflatxshift = 27; - nflatyshift = 22; - nflatshiftup = 11; - break; - default: // 64x64 lump - nflatmask = 0xFC0; - nflatxshift = 26; - nflatyshift = 20; - nflatshiftup = 10; - break; + if (leveltexture) + { + ds_source = texflat->resizedflat; + ds_flatwidth = texflat->resizedwidth; + ds_flatheight = texflat->resizedheight; + } + else + { + ds_source = levelflat->resizedflat; + ds_flatwidth = levelflat->resizedwidth; + ds_flatheight = levelflat->resizedheight; + } } + R_CheckFlatLength(ds_flatwidth * ds_flatheight); } #endif // ESLOPE + + levelflat->lasttexturenum = levelflat->texturenum; } void R_DrawSinglePlane(visplane_t *pl) @@ -966,71 +1029,24 @@ void R_DrawSinglePlane(visplane_t *pl) currentplane = pl; levelflat = &levelflats[pl->picnum]; + size = W_LumpLength(levelflat->lumpnum); + // Check if the flat is actually a texture. if (levelflat->texturenum != 0 && levelflat->texturenum != -1) R_GetPatchFlat(levelflat, true); + // Check if the flat is actually a patch. + else if (R_CheckIfPatch(levelflat->lumpnum)) + R_GetPatchFlat(levelflat, false); + // Raw flat. else { ds_source = (UINT8 *)W_CacheLumpNum(levelflat->lumpnum, PU_STATIC); // Stay here until Z_ChangeTag - size = W_LumpLength(levelflat->lumpnum); - - switch (size) - { - case 4194304: // 2048x2048 lump - nflatmask = 0x3FF800; - nflatxshift = 21; - nflatyshift = 10; - nflatshiftup = 5; - ds_flatwidth = ds_flatheight = 2048; - break; - case 1048576: // 1024x1024 lump - nflatmask = 0xFFC00; - nflatxshift = 22; - nflatyshift = 12; - nflatshiftup = 6; - ds_flatwidth = ds_flatheight = 1024; - break; - case 262144:// 512x512 lump - nflatmask = 0x3FE00; - nflatxshift = 23; - nflatyshift = 14; - nflatshiftup = 7; - ds_flatwidth = ds_flatheight = 512; - break; - case 65536: // 256x256 lump - nflatmask = 0xFF00; - nflatxshift = 24; - nflatyshift = 16; - nflatshiftup = 8; - ds_flatwidth = ds_flatheight = 256; - break; - case 16384: // 128x128 lump - nflatmask = 0x3F80; - nflatxshift = 25; - nflatyshift = 18; - nflatshiftup = 9; - ds_flatwidth = ds_flatheight = 128; - break; - case 1024: // 32x32 lump - nflatmask = 0x3E0; - nflatxshift = 27; - nflatyshift = 22; - nflatshiftup = 11; - ds_flatwidth = ds_flatheight = 32; - break; - default: // 64x64 lump - nflatmask = 0xFC0; - nflatxshift = 26; - nflatyshift = 20; - nflatshiftup = 10; - ds_flatwidth = ds_flatheight = 64; - break; - } + R_CheckFlatLength(size); } - if (R_CheckIfPatch(levelflat->lumpnum)) - R_GetPatchFlat(levelflat, false); - ds_powersoftwo = (!((ds_flatwidth & (ds_flatwidth - 1)) || (ds_flatheight & (ds_flatheight - 1)))); + // Check if the flat has dimensions that are powers-of-two numbers. + if (R_CheckPowersOfTwo()) + R_CheckFlatLength(ds_flatwidth * ds_flatheight); if (light >= LIGHTLEVELS) light = LIGHTLEVELS-1; diff --git a/src/r_plane.h b/src/r_plane.h index 6e6a6d49d..78aae3fa1 100644 --- a/src/r_plane.h +++ b/src/r_plane.h @@ -94,6 +94,8 @@ void R_PlaneBounds(visplane_t *plane); // Draws a single visplane. void R_DrawSinglePlane(visplane_t *pl); +void R_CheckFlatLength(size_t size); +boolean R_CheckPowersOfTwo(void); typedef struct planemgr_s { From 36036b6cfdeeacc1ded8d869dfb5dc2777e95e27 Mon Sep 17 00:00:00 2001 From: Nev3r Date: Sun, 26 May 2019 12:02:43 +0200 Subject: [PATCH 05/13] Permit textures to use the "TEXTURE" tag in addition to "WALLTEXTURE". It's pointless to make any distinctions anymore IMO, given flats can load them just fine now. --- src/r_data.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/r_data.c b/src/r_data.c index 4157a8850..738fc0727 100644 --- a/src/r_data.c +++ b/src/r_data.c @@ -850,7 +850,7 @@ int R_CountTexturesInTEXTURESLump(UINT16 wadNum, UINT16 lumpNum) texturesToken = M_GetToken(texturesText); while (texturesToken != NULL) { - if (stricmp(texturesToken, "WALLTEXTURE")==0) + if (stricmp(texturesToken, "WALLTEXTURE") == 0 || stricmp(texturesToken, "TEXTURE") == 0) { numTexturesInLump++; Z_Free(texturesToken); @@ -858,7 +858,7 @@ int R_CountTexturesInTEXTURESLump(UINT16 wadNum, UINT16 lumpNum) } else { - I_Error("Error parsing TEXTURES lump: Expected \"WALLTEXTURE\", got \"%s\"",texturesToken); + I_Error("Error parsing TEXTURES lump: Expected \"WALLTEXTURE\" or \"TEXTURE\", got \"%s\"",texturesToken); } texturesToken = M_GetToken(NULL); } @@ -899,7 +899,7 @@ void R_ParseTEXTURESLump(UINT16 wadNum, UINT16 lumpNum, INT32 *texindex) texturesToken = M_GetToken(texturesText); while (texturesToken != NULL) { - if (stricmp(texturesToken, "WALLTEXTURE")==0) + if (stricmp(texturesToken, "WALLTEXTURE") == 0 || stricmp(texturesToken, "TEXTURE") == 0) { Z_Free(texturesToken); // Get the new texture @@ -913,7 +913,7 @@ void R_ParseTEXTURESLump(UINT16 wadNum, UINT16 lumpNum, INT32 *texindex) } else { - I_Error("Error parsing TEXTURES lump: Expected \"WALLTEXTURE\", got \"%s\"",texturesToken); + I_Error("Error parsing TEXTURES lump: Expected \"WALLTEXTURE\" or \"TEXTURE\", got \"%s\"",texturesToken); } texturesToken = M_GetToken(NULL); } From 93f60267c1bd3842cdc961977b22163761f70c26 Mon Sep 17 00:00:00 2001 From: Jaime Passos Date: Sun, 26 May 2019 16:22:33 -0300 Subject: [PATCH 06/13] Minor fixes --- src/hardware/hw_cache.c | 30 ++--- src/hardware/hw_main.c | 38 ++++-- src/r_data.c | 10 +- src/r_draw8.c | 277 ++++++++++++++++++++++++++++++++++++++-- src/r_plane.c | 10 +- 5 files changed, 316 insertions(+), 49 deletions(-) diff --git a/src/hardware/hw_cache.c b/src/hardware/hw_cache.c index 84ad4c55b..504ded35b 100644 --- a/src/hardware/hw_cache.c +++ b/src/hardware/hw_cache.c @@ -679,21 +679,6 @@ static void HWR_LoadPatchFlat(GLMipmap_t *grMipmap, lumpnum_t flatlumpnum) R_FlatPatch(patch, Z_Malloc(grMipmap->width * grMipmap->height, PU_HWRCACHE, &grMipmap->grInfo.data)); } -static void HWR_LoadTextureFlat(GLMipmap_t *grMipmap, INT32 texturenum) -{ - // setup the texture info - grMipmap->grInfo.smallLodLog2 = GR_LOD_LOG2_64; - grMipmap->grInfo.largeLodLog2 = GR_LOD_LOG2_64; - grMipmap->grInfo.aspectRatioLog2 = GR_ASPECT_LOG2_1x1; - grMipmap->grInfo.format = GR_TEXFMT_P_8; - grMipmap->flags = TF_WRAPXY|TF_CHROMAKEYED; - - grMipmap->width = (UINT16)textures[texturenum]->width; - grMipmap->height = (UINT16)textures[texturenum]->height; - - R_FlatTexture(texturenum, Z_Malloc(grMipmap->width * grMipmap->height, PU_HWRCACHE, &grMipmap->grInfo.data)); -} - static void HWR_CacheFlat(GLMipmap_t *grMipmap, lumpnum_t flatlumpnum) { size_t size, pflatsize; @@ -765,6 +750,21 @@ void HWR_GetFlat(lumpnum_t flatlumpnum) gr_patchflat = flatlumpnum; } +static void HWR_LoadTextureFlat(GLMipmap_t *grMipmap, INT32 texturenum) +{ + // setup the texture info + grMipmap->grInfo.smallLodLog2 = GR_LOD_LOG2_64; + grMipmap->grInfo.largeLodLog2 = GR_LOD_LOG2_64; + grMipmap->grInfo.aspectRatioLog2 = GR_ASPECT_LOG2_1x1; + grMipmap->grInfo.format = GR_TEXFMT_P_8; + grMipmap->flags = TF_WRAPXY|TF_CHROMAKEYED; + + grMipmap->width = (UINT16)textures[texturenum]->width; + grMipmap->height = (UINT16)textures[texturenum]->height; + + R_FlatTexture(texturenum, Z_Malloc(grMipmap->width * grMipmap->height, PU_HWRCACHE, &grMipmap->grInfo.data)); +} + void HWR_GetTextureFlat(INT32 texturenum) { GLTexture_t *grtex; diff --git a/src/hardware/hw_main.c b/src/hardware/hw_main.c index 793050aa2..02e731164 100644 --- a/src/hardware/hw_main.c +++ b/src/hardware/hw_main.c @@ -531,6 +531,8 @@ static void HWR_RenderPlane(sector_t *sector, extrasubsector_t *xsub, boolean is INT32 i; float flatxref,flatyref; float fflatwidth, fflatheight; + INT32 flatflag; + boolean texflat = true; size_t len; float scrollx = 0.0f, scrolly = 0.0f; angle_t angle = 0; @@ -622,22 +624,25 @@ static void HWR_RenderPlane(sector_t *sector, extrasubsector_t *xsub, boolean is break; } - if (gr_patchflat && R_CheckIfPatch(gr_patchflat)) // Just in case? - { - patch = (patch_t *)W_CacheLumpNum(gr_patchflat, PU_STATIC); - fflatwidth = patch->width; - fflatheight = patch->height; - } + flatflag = ((INT32)fflatwidth)-1; if (texturenum != 0 && texturenum != -1) { fflatwidth = textures[texturenum]->width; fflatheight = textures[texturenum]->height; } + else if (gr_patchflat && R_CheckIfPatch(gr_patchflat)) // Just in case? + { + patch = (patch_t *)W_CacheLumpNum(gr_patchflat, PU_STATIC); + fflatwidth = SHORT(patch->width); + fflatheight = SHORT(patch->height); + } + else + texflat = false; // reference point for flat texture coord for each vertex around the polygon - flatxref = (float)((FLOAT_TO_FIXED(pv->x) % llrint(fflatwidth)) / fflatwidth); - flatyref = (float)((FLOAT_TO_FIXED(pv->y) % llrint(fflatheight)) / fflatheight); + flatxref = (float)(((fixed_t)pv->x & (~flatflag)) / fflatwidth); + flatyref = (float)(((fixed_t)pv->y & (~flatflag)) / fflatheight); // transform v3d = planeVerts; @@ -693,17 +698,24 @@ static void HWR_RenderPlane(sector_t *sector, extrasubsector_t *xsub, boolean is for (i = 0; i < nrPlaneVerts; i++,v3d++,pv++) { // Hurdler: add scrolling texture on floor/ceiling - v3d->sow = (float)((pv->x / fflatwidth) - flatxref + scrollx); - v3d->tow = (float)(flatyref - (pv->y / fflatheight) + scrolly); - - //v3d->sow = (float)(pv->x / fflatsize); - //v3d->tow = (float)(pv->y / fflatsize); + if (texflat) + { + v3d->sow = (float)(pv->x / fflatwidth) + scrollx; + v3d->tow = -(float)(pv->y / fflatheight) + scrolly; + } + else + { + v3d->sow = (float)((pv->x / fflatwidth) - flatxref + scrollx); + v3d->tow = (float)(flatyref - (pv->y / fflatheight) + scrolly); + } // Need to rotate before translate if (angle) // Only needs to be done if there's an altered angle { tempxsow = FLOAT_TO_FIXED(v3d->sow); tempytow = FLOAT_TO_FIXED(v3d->tow); + if (texflat) + tempytow = -tempytow; v3d->sow = (FIXED_TO_FLOAT(FixedMul(tempxsow, FINECOSINE(angle)) - FixedMul(tempytow, FINESINE(angle)))); v3d->tow = (FIXED_TO_FLOAT(-FixedMul(tempxsow, FINESINE(angle)) - FixedMul(tempytow, FINECOSINE(angle)))); } diff --git a/src/r_data.c b/src/r_data.c index 4157a8850..092dc069a 100644 --- a/src/r_data.c +++ b/src/r_data.c @@ -1694,7 +1694,7 @@ void R_FlatPatch(patch_t *patch, UINT8 *flat) UINT8 *source; desttop = flat; - deststop = desttop + (patch->width * patch->height); + deststop = desttop + (SHORT(patch->width) * SHORT(patch->height)); for (col = 0; col < SHORT(patch->width); col++, desttop++) { @@ -1708,13 +1708,13 @@ void R_FlatPatch(patch_t *patch, UINT8 *flat) topdelta += prevdelta; prevdelta = topdelta; - dest = desttop + (topdelta * patch->width); + dest = desttop + (topdelta * SHORT(patch->width)); source = (UINT8 *)(column) + 3; for (ofs = 0; dest < deststop && ofs < column->length; ofs++) { if (source[ofs] != TRANSPARENTPIXEL) *dest = source[ofs]; - dest += patch->width; + dest += SHORT(patch->width); } column = (column_t *)((UINT8 *)column + column->length + 4); } @@ -1733,9 +1733,8 @@ void R_FlatTexture(size_t tex, UINT8 *flat) desttop = flat; deststop = desttop + (texture->width * texture->height); - for (col = 0; col < SHORT(texture->width); col++, desttop++) + for (col = 0; col < texture->width; col++, desttop++) { - INT32 topdelta, prevdelta = -1; column = (column_t *)R_GetColumn(tex, col); if (!texture->holes) { @@ -1750,6 +1749,7 @@ void R_FlatTexture(size_t tex, UINT8 *flat) } else { + INT32 topdelta, prevdelta = -1; while (column->topdelta != 0xff) { topdelta = column->topdelta; diff --git a/src/r_draw8.c b/src/r_draw8.c index f829707d3..542572707 100644 --- a/src/r_draw8.c +++ b/src/r_draw8.c @@ -550,12 +550,18 @@ void R_DrawSpan_8 (void) UINT8 *dest; const UINT8 *deststop = screens[0] + vid.rowbytes * vid.height; - UINT32 flatsize = ds_flatwidth * ds_flatheight; size_t count = (ds_x2 - ds_x1 + 1); xposition = ds_xfrac; yposition = ds_yfrac; xstep = ds_xstep; ystep = ds_ystep; + // SoM: we only need 6 bits for the integer part (0 thru 63) so the rest + // can be used for the fraction part. This allows calculation of the memory address in the + // texture with two shifts, an OR and one AND. (see below) + // for texture sizes > 64 the amount of precision we can allow will decrease, but only by one + // bit per power of two (obviously) + // Ok, because I was able to eliminate the variable spot below, this function is now FASTER + // than the original span renderer. Whodathunkit? if (ds_powersoftwo) { xposition <<= nflatshiftup; yposition <<= nflatshiftup; @@ -566,7 +572,7 @@ void R_DrawSpan_8 (void) colormap = ds_colormap; dest = ylookup[ds_y] + columnofs[ds_x1]; - if (dest > deststop) + if (dest+8 > deststop) return; if (!ds_powersoftwo) @@ -582,13 +588,56 @@ void R_DrawSpan_8 (void) if (y < 0) y = ds_flatheight - ((UINT32)(ds_flatheight - y) % ds_flatheight); - *dest++ = colormap[source[((y * ds_flatwidth) + x) % flatsize]]; + x %= ds_flatwidth; + y %= ds_flatheight; + + *dest++ = colormap[source[((y * ds_flatwidth) + x)]]; xposition += xstep; yposition += ystep; } } else { + while (count >= 8) + { + // SoM: Why didn't I see this earlier? the spot variable is a waste now because we don't + // have the uber complicated math to calculate it now, so that was a memory write we didn't + // need! + dest[0] = colormap[source[(((UINT32)yposition >> nflatyshift) & nflatmask) | ((UINT32)xposition >> nflatxshift)]]; + xposition += xstep; + yposition += ystep; + + dest[1] = colormap[source[(((UINT32)yposition >> nflatyshift) & nflatmask) | ((UINT32)xposition >> nflatxshift)]]; + xposition += xstep; + yposition += ystep; + + dest[2] = colormap[source[(((UINT32)yposition >> nflatyshift) & nflatmask) | ((UINT32)xposition >> nflatxshift)]]; + xposition += xstep; + yposition += ystep; + + dest[3] = colormap[source[(((UINT32)yposition >> nflatyshift) & nflatmask) | ((UINT32)xposition >> nflatxshift)]]; + xposition += xstep; + yposition += ystep; + + dest[4] = colormap[source[(((UINT32)yposition >> nflatyshift) & nflatmask) | ((UINT32)xposition >> nflatxshift)]]; + xposition += xstep; + yposition += ystep; + + dest[5] = colormap[source[(((UINT32)yposition >> nflatyshift) & nflatmask) | ((UINT32)xposition >> nflatxshift)]]; + xposition += xstep; + yposition += ystep; + + dest[6] = colormap[source[(((UINT32)yposition >> nflatyshift) & nflatmask) | ((UINT32)xposition >> nflatxshift)]]; + xposition += xstep; + yposition += ystep; + + dest[7] = colormap[source[(((UINT32)yposition >> nflatyshift) & nflatmask) | ((UINT32)xposition >> nflatxshift)]]; + xposition += xstep; + yposition += ystep; + + dest += 8; + count -= 8; + } while (count-- && dest <= deststop) { *dest++ = colormap[source[(((UINT32)yposition >> nflatyshift) & nflatmask) | ((UINT32)xposition >> nflatxshift)]]; @@ -1052,13 +1101,19 @@ void R_DrawSplat_8 (void) UINT8 *dest; const UINT8 *deststop = screens[0] + vid.rowbytes * vid.height; - UINT32 flatsize = ds_flatwidth * ds_flatheight; size_t count = (ds_x2 - ds_x1 + 1); UINT32 val; xposition = ds_xfrac; yposition = ds_yfrac; xstep = ds_xstep; ystep = ds_ystep; + // SoM: we only need 6 bits for the integer part (0 thru 63) so the rest + // can be used for the fraction part. This allows calculation of the memory address in the + // texture with two shifts, an OR and one AND. (see below) + // for texture sizes > 64 the amount of precision we can allow will decrease, but only by one + // bit per power of two (obviously) + // Ok, because I was able to eliminate the variable spot below, this function is now FASTER + // than the original span renderer. Whodathunkit? if (ds_powersoftwo) { xposition <<= nflatshiftup; yposition <<= nflatshiftup; @@ -1082,7 +1137,10 @@ void R_DrawSplat_8 (void) if (y < 0) y = ds_flatheight - ((UINT32)(ds_flatheight - y) % ds_flatheight); - val = source[((y * ds_flatwidth) + x) % flatsize]; + x %= ds_flatwidth; + y %= ds_flatheight; + + val = source[((y * ds_flatwidth) + x)]; if (val != TRANSPARENTPIXEL) *dest = colormap[val]; dest++; @@ -1092,6 +1150,80 @@ void R_DrawSplat_8 (void) } else { + while (count >= 8) + { + // SoM: Why didn't I see this earlier? the spot variable is a waste now because we don't + // have the uber complicated math to calculate it now, so that was a memory write we didn't + // need! + // + // 4194303 = (2048x2048)-1 (2048x2048 is maximum flat size) + val = (((UINT32)yposition >> nflatyshift) & nflatmask) | ((UINT32)xposition >> nflatxshift); + val &= 4194303; + val = source[val]; + if (val != TRANSPARENTPIXEL) + dest[0] = colormap[val]; + xposition += xstep; + yposition += ystep; + + val = (((UINT32)yposition >> nflatyshift) & nflatmask) | ((UINT32)xposition >> nflatxshift); + val &= 4194303; + val = source[val]; + if (val != TRANSPARENTPIXEL) + dest[1] = colormap[val]; + xposition += xstep; + yposition += ystep; + + val = (((UINT32)yposition >> nflatyshift) & nflatmask) | ((UINT32)xposition >> nflatxshift); + val &= 4194303; + val = source[val]; + if (val != TRANSPARENTPIXEL) + dest[2] = colormap[val]; + xposition += xstep; + yposition += ystep; + + val = (((UINT32)yposition >> nflatyshift) & nflatmask) | ((UINT32)xposition >> nflatxshift); + val &= 4194303; + val = source[val]; + if (val != TRANSPARENTPIXEL) + dest[3] = colormap[val]; + xposition += xstep; + yposition += ystep; + + val = (((UINT32)yposition >> nflatyshift) & nflatmask) | ((UINT32)xposition >> nflatxshift); + val &= 4194303; + val = source[val]; + if (val != TRANSPARENTPIXEL) + dest[4] = colormap[val]; + xposition += xstep; + yposition += ystep; + + val = (((UINT32)yposition >> nflatyshift) & nflatmask) | ((UINT32)xposition >> nflatxshift); + val &= 4194303; + val = source[val]; + if (val != TRANSPARENTPIXEL) + dest[5] = colormap[val]; + xposition += xstep; + yposition += ystep; + + val = (((UINT32)yposition >> nflatyshift) & nflatmask) | ((UINT32)xposition >> nflatxshift); + val &= 4194303; + val = source[val]; + if (val != TRANSPARENTPIXEL) + dest[6] = colormap[val]; + xposition += xstep; + yposition += ystep; + + val = (((UINT32)yposition >> nflatyshift) & nflatmask) | ((UINT32)xposition >> nflatxshift); + val &= 4194303; + val = source[val]; + if (val != TRANSPARENTPIXEL) + dest[7] = colormap[val]; + xposition += xstep; + yposition += ystep; + + dest += 8; + count -= 8; + } while (count-- && dest <= deststop) { val = source[(((UINT32)yposition >> nflatyshift) & nflatmask) | ((UINT32)xposition >> nflatxshift)]; @@ -1118,13 +1250,19 @@ void R_DrawTranslucentSplat_8 (void) UINT8 *dest; const UINT8 *deststop = screens[0] + vid.rowbytes * vid.height; - UINT32 flatsize = ds_flatwidth * ds_flatheight; size_t count = (ds_x2 - ds_x1 + 1); UINT32 val; xposition = ds_xfrac; yposition = ds_yfrac; xstep = ds_xstep; ystep = ds_ystep; + // SoM: we only need 6 bits for the integer part (0 thru 63) so the rest + // can be used for the fraction part. This allows calculation of the memory address in the + // texture with two shifts, an OR and one AND. (see below) + // for texture sizes > 64 the amount of precision we can allow will decrease, but only by one + // bit per power of two (obviously) + // Ok, because I was able to eliminate the variable spot below, this function is now FASTER + // than the original span renderer. Whodathunkit? if (ds_powersoftwo) { xposition <<= nflatshiftup; yposition <<= nflatshiftup; @@ -1148,7 +1286,10 @@ void R_DrawTranslucentSplat_8 (void) if (y < 0) y = ds_flatheight - ((UINT32)(ds_flatheight - y) % ds_flatheight); - val = source[((y * ds_flatwidth) + x) % flatsize]; + x %= ds_flatwidth; + y %= ds_flatheight; + + val = source[((y * ds_flatwidth) + x)]; if (val != TRANSPARENTPIXEL) *dest = *(ds_transmap + (colormap[val] << 8) + *dest); dest++; @@ -1158,6 +1299,62 @@ void R_DrawTranslucentSplat_8 (void) } else { + while (count >= 8) + { + // SoM: Why didn't I see this earlier? the spot variable is a waste now because we don't + // have the uber complicated math to calculate it now, so that was a memory write we didn't + // need! + val = source[(((UINT32)yposition >> nflatyshift) & nflatmask) | ((UINT32)xposition >> nflatxshift)]; + if (val != TRANSPARENTPIXEL) + dest[0] = *(ds_transmap + (colormap[val] << 8) + dest[0]); + xposition += xstep; + yposition += ystep; + + val = source[(((UINT32)yposition >> nflatyshift) & nflatmask) | ((UINT32)xposition >> nflatxshift)]; + if (val != TRANSPARENTPIXEL) + dest[1] = *(ds_transmap + (colormap[val] << 8) + dest[1]); + xposition += xstep; + yposition += ystep; + + val = source[(((UINT32)yposition >> nflatyshift) & nflatmask) | ((UINT32)xposition >> nflatxshift)]; + if (val != TRANSPARENTPIXEL) + dest[2] = *(ds_transmap + (colormap[val] << 8) + dest[2]); + xposition += xstep; + yposition += ystep; + + val = source[(((UINT32)yposition >> nflatyshift) & nflatmask) | ((UINT32)xposition >> nflatxshift)]; + if (val != TRANSPARENTPIXEL) + dest[3] = *(ds_transmap + (colormap[val] << 8) + dest[3]); + xposition += xstep; + yposition += ystep; + + val = source[(((UINT32)yposition >> nflatyshift) & nflatmask) | ((UINT32)xposition >> nflatxshift)]; + if (val != TRANSPARENTPIXEL) + dest[4] = *(ds_transmap + (colormap[val] << 8) + dest[4]); + xposition += xstep; + yposition += ystep; + + val = source[(((UINT32)yposition >> nflatyshift) & nflatmask) | ((UINT32)xposition >> nflatxshift)]; + if (val != TRANSPARENTPIXEL) + dest[5] = *(ds_transmap + (colormap[val] << 8) + dest[5]); + xposition += xstep; + yposition += ystep; + + val = source[(((UINT32)yposition >> nflatyshift) & nflatmask) | ((UINT32)xposition >> nflatxshift)]; + if (val != TRANSPARENTPIXEL) + dest[6] = *(ds_transmap + (colormap[val] << 8) + dest[6]); + xposition += xstep; + yposition += ystep; + + val = source[(((UINT32)yposition >> nflatyshift) & nflatmask) | ((UINT32)xposition >> nflatxshift)]; + if (val != TRANSPARENTPIXEL) + dest[7] = *(ds_transmap + (colormap[val] << 8) + dest[7]); + xposition += xstep; + yposition += ystep; + + dest += 8; + count -= 8; + } while (count-- && dest <= deststop) { val = source[(((UINT32)yposition >> nflatyshift) & nflatmask) | ((UINT32)xposition >> nflatxshift)]; @@ -1184,13 +1381,19 @@ void R_DrawTranslucentSpan_8 (void) UINT8 *dest; const UINT8 *deststop = screens[0] + vid.rowbytes * vid.height; - UINT32 flatsize = ds_flatwidth * ds_flatheight; size_t count = (ds_x2 - ds_x1 + 1); UINT32 val; xposition = ds_xfrac; yposition = ds_yfrac; xstep = ds_xstep; ystep = ds_ystep; + // SoM: we only need 6 bits for the integer part (0 thru 63) so the rest + // can be used for the fraction part. This allows calculation of the memory address in the + // texture with two shifts, an OR and one AND. (see below) + // for texture sizes > 64 the amount of precision we can allow will decrease, but only by one + // bit per power of two (obviously) + // Ok, because I was able to eliminate the variable spot below, this function is now FASTER + // than the original span renderer. Whodathunkit? if (ds_powersoftwo) { xposition <<= nflatshiftup; yposition <<= nflatshiftup; @@ -1214,7 +1417,10 @@ void R_DrawTranslucentSpan_8 (void) if (y < 0) y = ds_flatheight - ((UINT32)(ds_flatheight - y) % ds_flatheight); - val = ((y * ds_flatwidth) + x) % flatsize; + x %= ds_flatwidth; + y %= ds_flatheight; + + val = ((y * ds_flatwidth) + x); *dest = *(ds_transmap + (colormap[source[val]] << 8) + *dest); dest++; xposition += xstep; @@ -1223,6 +1429,46 @@ void R_DrawTranslucentSpan_8 (void) } else { + while (count >= 8) + { + // SoM: Why didn't I see this earlier? the spot variable is a waste now because we don't + // have the uber complicated math to calculate it now, so that was a memory write we didn't + // need! + dest[0] = *(ds_transmap + (colormap[source[(((UINT32)yposition >> nflatyshift) & nflatmask) | ((UINT32)xposition >> nflatxshift)]] << 8) + dest[0]); + xposition += xstep; + yposition += ystep; + + dest[1] = *(ds_transmap + (colormap[source[(((UINT32)yposition >> nflatyshift) & nflatmask) | ((UINT32)xposition >> nflatxshift)]] << 8) + dest[1]); + xposition += xstep; + yposition += ystep; + + dest[2] = *(ds_transmap + (colormap[source[(((UINT32)yposition >> nflatyshift) & nflatmask) | ((UINT32)xposition >> nflatxshift)]] << 8) + dest[2]); + xposition += xstep; + yposition += ystep; + + dest[3] = *(ds_transmap + (colormap[source[(((UINT32)yposition >> nflatyshift) & nflatmask) | ((UINT32)xposition >> nflatxshift)]] << 8) + dest[3]); + xposition += xstep; + yposition += ystep; + + dest[4] = *(ds_transmap + (colormap[source[(((UINT32)yposition >> nflatyshift) & nflatmask) | ((UINT32)xposition >> nflatxshift)]] << 8) + dest[4]); + xposition += xstep; + yposition += ystep; + + dest[5] = *(ds_transmap + (colormap[source[(((UINT32)yposition >> nflatyshift) & nflatmask) | ((UINT32)xposition >> nflatxshift)]] << 8) + dest[5]); + xposition += xstep; + yposition += ystep; + + dest[6] = *(ds_transmap + (colormap[source[(((UINT32)yposition >> nflatyshift) & nflatmask) | ((UINT32)xposition >> nflatxshift)]] << 8) + dest[6]); + xposition += xstep; + yposition += ystep; + + dest[7] = *(ds_transmap + (colormap[source[(((UINT32)yposition >> nflatyshift) & nflatmask) | ((UINT32)xposition >> nflatxshift)]] << 8) + dest[7]); + xposition += xstep; + yposition += ystep; + + dest += 8; + count -= 8; + } while (count-- && dest <= deststop) { val = (((UINT32)yposition >> nflatyshift) & nflatmask) | ((UINT32)xposition >> nflatxshift); @@ -1247,12 +1493,18 @@ void R_DrawTranslucentWaterSpan_8(void) UINT8 *dsrc; const UINT8 *deststop = screens[0] + vid.rowbytes * vid.height; - UINT32 flatsize = ds_flatwidth * ds_flatheight; size_t count = (ds_x2 - ds_x1 + 1); xposition = ds_xfrac; yposition = (ds_yfrac + ds_waterofs); xstep = ds_xstep; ystep = ds_ystep; + // SoM: we only need 6 bits for the integer part (0 thru 63) so the rest + // can be used for the fraction part. This allows calculation of the memory address in the + // texture with two shifts, an OR and one AND. (see below) + // for texture sizes > 64 the amount of precision we can allow will decrease, but only by one + // bit per power of two (obviously) + // Ok, because I was able to eliminate the variable spot below, this function is now FASTER + // than the original span renderer. Whodathunkit? if (ds_powersoftwo) { xposition <<= nflatshiftup; yposition <<= nflatshiftup; @@ -1277,7 +1529,10 @@ void R_DrawTranslucentWaterSpan_8(void) if (y < 0) y = ds_flatheight - ((UINT32)(ds_flatheight - y) % ds_flatheight); - *dest++ = colormap[*(ds_transmap + (source[((y * ds_flatwidth) + x) % flatsize] << 8) + *dsrc++)]; + x %= ds_flatwidth; + y %= ds_flatheight; + + *dest++ = colormap[*(ds_transmap + (source[((y * ds_flatwidth) + x)] << 8) + *dsrc++)]; xposition += xstep; yposition += ystep; } diff --git a/src/r_plane.c b/src/r_plane.c index 01d0fdd37..37a76e2cd 100644 --- a/src/r_plane.c +++ b/src/r_plane.c @@ -758,8 +758,8 @@ static void R_GetPatchFlat(levelflat_t *levelflat, boolean leveltexture) else { patch = (patch_t *)ds_source; - levelflat->width = ds_flatwidth = patch->width; - levelflat->height = ds_flatheight = patch->height; + levelflat->width = ds_flatwidth = SHORT(patch->width); + levelflat->height = ds_flatheight = SHORT(patch->height); levelflat->topoffset = patch->topoffset * FRACUNIT; levelflat->leftoffset = patch->leftoffset * FRACUNIT; @@ -1031,13 +1031,13 @@ void R_DrawSinglePlane(visplane_t *pl) levelflat = &levelflats[pl->picnum]; size = W_LumpLength(levelflat->lumpnum); - // Check if the flat is actually a texture. + // Check if the flat is actually a wall texture. if (levelflat->texturenum != 0 && levelflat->texturenum != -1) R_GetPatchFlat(levelflat, true); - // Check if the flat is actually a patch. + // Maybe it's just a patch, then? else if (R_CheckIfPatch(levelflat->lumpnum)) R_GetPatchFlat(levelflat, false); - // Raw flat. + // It's a raw flat. else { ds_source = (UINT8 *)W_CacheLumpNum(levelflat->lumpnum, PU_STATIC); // Stay here until Z_ChangeTag From a4a529bdb5af0a9bd2cc5d8dfef1a2d0d08c48b6 Mon Sep 17 00:00:00 2001 From: Jaime Passos Date: Sun, 26 May 2019 17:41:10 -0300 Subject: [PATCH 07/13] Hardware renderer: Disable Glide-specific texture handling --- src/hardware/hw_cache.c | 15 +++++++++++++++ src/hardware/hw_glide.h | 2 ++ src/hardware/hw_light.c | 2 ++ src/hardware/hw_md2.c | 4 ++++ 4 files changed, 23 insertions(+) diff --git a/src/hardware/hw_cache.c b/src/hardware/hw_cache.c index 504ded35b..72b78a985 100644 --- a/src/hardware/hw_cache.c +++ b/src/hardware/hw_cache.c @@ -190,6 +190,7 @@ static void HWR_DrawPatchInCache(GLMipmap_t *mipmap, static void HWR_ResizeBlock(INT32 originalwidth, INT32 originalheight, GrTexInfo *grInfo) { +#ifdef GLIDE_API_COMPATIBILITY // Build the full textures from patches. static const GrLOD_t gr_lods[9] = { @@ -226,6 +227,9 @@ static void HWR_ResizeBlock(INT32 originalwidth, INT32 originalheight, INT32 j,k; INT32 max,min; +#else + (void)grInfo; +#endif // find a power of 2 width/height if (cv_grrounddown.value) @@ -281,6 +285,7 @@ static void HWR_ResizeBlock(INT32 originalwidth, INT32 originalheight, } else { +#ifdef GLIDE_API_COMPATIBILITY //size up to nearest power of 2 blockwidth = 1; while (blockwidth < originalwidth) @@ -298,9 +303,14 @@ static void HWR_ResizeBlock(INT32 originalwidth, INT32 originalheight, if (blockheight > 2048) blockheight = 2048; //I_Error("3D GenerateTexture : too big"); +#else + blockwidth = originalwidth; + blockheight = originalheight; +#endif } // do the boring LOD stuff.. blech! +#ifdef GLIDE_API_COMPATIBILITY if (blockwidth >= blockheight) { max = blockwidth; @@ -332,6 +342,7 @@ static void HWR_ResizeBlock(INT32 originalwidth, INT32 originalheight, if (blockwidth < blockheight) j += 4; grInfo->aspectRatioLog2 = gr_aspects[j].aspect; +#endif blocksize = blockwidth * blockheight; @@ -684,9 +695,11 @@ static void HWR_CacheFlat(GLMipmap_t *grMipmap, lumpnum_t flatlumpnum) size_t size, pflatsize; // setup the texture info +#ifdef GLIDE_API_COMPATIBILITY grMipmap->grInfo.smallLodLog2 = GR_LOD_LOG2_64; grMipmap->grInfo.largeLodLog2 = GR_LOD_LOG2_64; grMipmap->grInfo.aspectRatioLog2 = GR_ASPECT_LOG2_1x1; +#endif grMipmap->grInfo.format = GR_TEXFMT_P_8; grMipmap->flags = TF_WRAPXY|TF_CHROMAKEYED; @@ -753,9 +766,11 @@ void HWR_GetFlat(lumpnum_t flatlumpnum) static void HWR_LoadTextureFlat(GLMipmap_t *grMipmap, INT32 texturenum) { // setup the texture info +#ifdef GLIDE_API_COMPATIBILITY grMipmap->grInfo.smallLodLog2 = GR_LOD_LOG2_64; grMipmap->grInfo.largeLodLog2 = GR_LOD_LOG2_64; grMipmap->grInfo.aspectRatioLog2 = GR_ASPECT_LOG2_1x1; +#endif grMipmap->grInfo.format = GR_TEXFMT_P_8; grMipmap->flags = TF_WRAPXY|TF_CHROMAKEYED; diff --git a/src/hardware/hw_glide.h b/src/hardware/hw_glide.h index 2625d5864..bf91229ef 100644 --- a/src/hardware/hw_glide.h +++ b/src/hardware/hw_glide.h @@ -59,9 +59,11 @@ typedef FxI32 GrTextureFormat_t; typedef struct { +#ifdef GLIDE_API_COMPATIBILITY GrLOD_t smallLodLog2; GrLOD_t largeLodLog2; GrAspectRatio_t aspectRatioLog2; +#endif GrTextureFormat_t format; void *data; } GrTexInfo; diff --git a/src/hardware/hw_light.c b/src/hardware/hw_light.c index a93e96dc3..23e8a3431 100644 --- a/src/hardware/hw_light.c +++ b/src/hardware/hw_light.c @@ -1112,9 +1112,11 @@ static void HWR_SetLight(void) lightmappatch.height = 128; lightmappatch.mipmap.width = 128; lightmappatch.mipmap.height = 128; +#ifdef GLIDE_API_COMPATIBILITY lightmappatch.mipmap.grInfo.smallLodLog2 = GR_LOD_LOG2_128; lightmappatch.mipmap.grInfo.largeLodLog2 = GR_LOD_LOG2_128; lightmappatch.mipmap.grInfo.aspectRatioLog2 = GR_ASPECT_LOG2_1x1; +#endif lightmappatch.mipmap.flags = 0; //TF_WRAPXY; // DEBUG: view the overdraw ! } HWD.pfnSetTexture(&lightmappatch.mipmap); diff --git a/src/hardware/hw_md2.c b/src/hardware/hw_md2.c index cb33562d8..e3ac82fa8 100644 --- a/src/hardware/hw_md2.c +++ b/src/hardware/hw_md2.c @@ -716,10 +716,12 @@ static void md2_loadTexture(md2_t *model) grpatch->mipmap.width = (UINT16)w; grpatch->mipmap.height = (UINT16)h; +#ifdef GLIDE_API_COMPATIBILITY // not correct! grpatch->mipmap.grInfo.smallLodLog2 = GR_LOD_LOG2_256; grpatch->mipmap.grInfo.largeLodLog2 = GR_LOD_LOG2_256; grpatch->mipmap.grInfo.aspectRatioLog2 = GR_ASPECT_LOG2_1x1; +#endif } HWD.pfnSetTexture(&grpatch->mipmap); HWR_UnlockCachedPatch(grpatch); @@ -767,10 +769,12 @@ static void md2_loadBlendTexture(md2_t *model) grpatch->mipmap.width = (UINT16)w; grpatch->mipmap.height = (UINT16)h; +#ifdef GLIDE_API_COMPATIBILITY // not correct! grpatch->mipmap.grInfo.smallLodLog2 = GR_LOD_LOG2_256; grpatch->mipmap.grInfo.largeLodLog2 = GR_LOD_LOG2_256; grpatch->mipmap.grInfo.aspectRatioLog2 = GR_ASPECT_LOG2_1x1; +#endif } HWD.pfnSetTexture(&grpatch->mipmap); // We do need to do this so that it can be cleared and knows to recreate it when necessary HWR_UnlockCachedPatch(grpatch); From 0bcf89679e7fa52d04c184475b0da67164e30f14 Mon Sep 17 00:00:00 2001 From: Jaime Passos Date: Sun, 26 May 2019 18:16:13 -0300 Subject: [PATCH 08/13] Hardware renderer: Fix polyobjects --- src/hardware/hw_cache.c | 2 +- src/hardware/hw_main.c | 38 +++++++++++++++++++++++++++----------- src/p_setup.c | 5 ++++- 3 files changed, 32 insertions(+), 13 deletions(-) diff --git a/src/hardware/hw_cache.c b/src/hardware/hw_cache.c index 72b78a985..54a1f6695 100644 --- a/src/hardware/hw_cache.c +++ b/src/hardware/hw_cache.c @@ -677,7 +677,7 @@ GLTexture_t *HWR_GetTexture(INT32 tex) return grtex; } -// Lactozilla +// HWR_RenderPlane and HWR_RenderPolyObjectPlane need this to get the flat dimensions from a patch. lumpnum_t gr_patchflat; static void HWR_LoadPatchFlat(GLMipmap_t *grMipmap, lumpnum_t flatlumpnum) diff --git a/src/hardware/hw_main.c b/src/hardware/hw_main.c index 02e731164..de273cfed 100644 --- a/src/hardware/hw_main.c +++ b/src/hardware/hw_main.c @@ -3172,6 +3172,8 @@ static void HWR_RenderPolyObjectPlane(polyobj_t *polysector, boolean isceiling, INT32 i; float flatxref,flatyref; float fflatwidth, fflatheight; + INT32 flatflag; + boolean texflat = true; size_t len; float scrollx = 0.0f, scrolly = 0.0f; angle_t angle = 0; @@ -3231,22 +3233,25 @@ static void HWR_RenderPolyObjectPlane(polyobj_t *polysector, boolean isceiling, break; } - if (gr_patchflat && R_CheckIfPatch(gr_patchflat)) // Just in case? - { - patch = (patch_t *)W_CacheLumpNum(gr_patchflat, PU_STATIC); - fflatwidth = patch->width; - fflatheight = patch->height; - } + flatflag = ((INT32)fflatwidth)-1; if (texturenum != 0 && texturenum != -1) { fflatwidth = textures[texturenum]->width; fflatheight = textures[texturenum]->height; } + else if (gr_patchflat && R_CheckIfPatch(gr_patchflat)) // Just in case? + { + patch = (patch_t *)W_CacheLumpNum(gr_patchflat, PU_STATIC); + fflatwidth = SHORT(patch->width); + fflatheight = SHORT(patch->height); + } + else + texflat = false; // reference point for flat texture coord for each vertex around the polygon - flatxref = (float)((polysector->origVerts[0].x % llrint(fflatwidth)) / fflatwidth); - flatyref = (float)((polysector->origVerts[0].y % llrint(fflatheight)) / fflatheight); + flatxref = (float)((polysector->origVerts[0].x & (~flatflag)) / fflatwidth); + flatyref = (float)((polysector->origVerts[0].y & (~flatflag)) / fflatheight); // transform v3d = planeVerts; @@ -3300,15 +3305,26 @@ static void HWR_RenderPolyObjectPlane(polyobj_t *polysector, boolean isceiling, for (i = 0; i < (INT32)nrPlaneVerts; i++,v3d++) { - // Hurdler: add scrolling texture on floor/ceiling - v3d->sow = (float)((FIXED_TO_FLOAT(polysector->origVerts[i].x) / fflatwidth) - flatxref + scrollx); // Go from the polysector's original vertex locations - v3d->tow = (float)(flatyref - (FIXED_TO_FLOAT(polysector->origVerts[i].y) / fflatheight) + scrolly); // Means the flat is offset based on the original vertex locations + // Go from the polysector's original vertex locations + // Means the flat is offset based on the original vertex locations + if (texflat) + { + v3d->sow = (float)(FIXED_TO_FLOAT(polysector->origVerts[i].x) / fflatwidth) + scrollx; + v3d->tow = -(float)(FIXED_TO_FLOAT(polysector->origVerts[i].y) / fflatheight) + scrolly; + } + else + { + v3d->sow = (float)((FIXED_TO_FLOAT(polysector->origVerts[i].x) / fflatwidth) - flatxref + scrollx); + v3d->tow = (float)(flatyref - (FIXED_TO_FLOAT(polysector->origVerts[i].y) / fflatheight) + scrolly); + } // Need to rotate before translate if (angle) // Only needs to be done if there's an altered angle { tempxsow = FLOAT_TO_FIXED(v3d->sow); tempytow = FLOAT_TO_FIXED(v3d->tow); + if (texflat) + tempytow = -tempytow; v3d->sow = (FIXED_TO_FLOAT(FixedMul(tempxsow, FINECOSINE(angle)) - FixedMul(tempytow, FINESINE(angle)))); v3d->tow = (FIXED_TO_FLOAT(-FixedMul(tempxsow, FINESINE(angle)) - FixedMul(tempytow, FINECOSINE(angle)))); } diff --git a/src/p_setup.c b/src/p_setup.c index 97bace860..c1ba4c67a 100644 --- a/src/p_setup.c +++ b/src/p_setup.c @@ -613,8 +613,11 @@ INT32 P_AddLevelFlatRuntime(const char *flatname) // store the flat lump number levelflat->lumpnum = R_GetFlatNumForName(flatname); - // Lactozilla levelflat->texturenum = R_CheckTextureNumForName(flatname); + levelflat->lasttexturenum = levelflat->texturenum; + + levelflat->baselumpnum = LUMPERROR; + levelflat->basetexturenum = -1; #ifndef ZDEBUG CONS_Debug(DBG_SETUP, "flat #%03d: %s\n", atoi(sizeu1(numlevelflats)), levelflat->name); From 39857a846a47af5bad63992542636dae956e8fd3 Mon Sep 17 00:00:00 2001 From: Jaime Passos Date: Sun, 26 May 2019 23:37:23 -0300 Subject: [PATCH 09/13] PNG support --- src/doomdef.h | 2 + src/hardware/hw_cache.c | 10 +- src/r_data.c | 459 ++++++++++++++++++++++++++++++++++++++-- src/r_data.h | 14 +- src/r_plane.c | 54 +++-- src/w_wad.c | 2 - 6 files changed, 508 insertions(+), 33 deletions(-) diff --git a/src/doomdef.h b/src/doomdef.h index 527cdf05f..2bf9efa68 100644 --- a/src/doomdef.h +++ b/src/doomdef.h @@ -536,4 +536,6 @@ extern const char *compdate, *comptime, *comprevision, *compbranch; /// SRB2CB itself ported this from PrBoom+ #define NEWCLIP +//#define NO_PNG_LUMPS + #endif // __DOOMDEF__ diff --git a/src/hardware/hw_cache.c b/src/hardware/hw_cache.c index 54a1f6695..457f628d0 100644 --- a/src/hardware/hw_cache.c +++ b/src/hardware/hw_cache.c @@ -451,7 +451,10 @@ static void HWR_GenerateTexture(INT32 texnum, GLTexture_t *grtex) // Composite the columns together. for (i = 0, patch = texture->patches; i < texture->patchcount; i++, patch++) { + size_t lumplength = W_LumpLengthPwad(patch->wad, patch->lump); realpatch = W_CacheLumpNumPwad(patch->wad, patch->lump, PU_CACHE); + if (R_IsLumpPNG((UINT8 *)realpatch, lumplength)) + realpatch = R_PNGToPatch((UINT8 *)realpatch, lumplength); HWR_DrawPatchInCache(&grtex->mipmap, blockwidth, blockheight, blockwidth*format2bpp[grtex->mipmap.grInfo.format], @@ -683,11 +686,14 @@ lumpnum_t gr_patchflat; static void HWR_LoadPatchFlat(GLMipmap_t *grMipmap, lumpnum_t flatlumpnum) { patch_t *patch = (patch_t *)W_CacheLumpNum(flatlumpnum, PU_STATIC); + size_t lumplength = W_LumpLength(flatlumpnum); + if (R_IsLumpPNG((UINT8 *)patch, lumplength)) + patch = R_PNGToPatch((UINT8 *)patch, lumplength); grMipmap->width = (UINT16)SHORT(patch->width); grMipmap->height = (UINT16)SHORT(patch->height); - R_FlatPatch(patch, Z_Malloc(grMipmap->width * grMipmap->height, PU_HWRCACHE, &grMipmap->grInfo.data)); + R_PatchToFlat(patch, Z_Malloc(grMipmap->width * grMipmap->height, PU_HWRCACHE, &grMipmap->grInfo.data)); } static void HWR_CacheFlat(GLMipmap_t *grMipmap, lumpnum_t flatlumpnum) @@ -777,7 +783,7 @@ static void HWR_LoadTextureFlat(GLMipmap_t *grMipmap, INT32 texturenum) grMipmap->width = (UINT16)textures[texturenum]->width; grMipmap->height = (UINT16)textures[texturenum]->height; - R_FlatTexture(texturenum, Z_Malloc(grMipmap->width * grMipmap->height, PU_HWRCACHE, &grMipmap->grInfo.data)); + R_TextureToFlat(texturenum, Z_Malloc(grMipmap->width * grMipmap->height, PU_HWRCACHE, &grMipmap->grInfo.data)); } void HWR_GetTextureFlat(INT32 texturenum) diff --git a/src/r_data.c b/src/r_data.c index db92c11fe..ea8785afb 100644 --- a/src/r_data.c +++ b/src/r_data.c @@ -40,6 +40,28 @@ #include #endif +#ifdef HAVE_PNG + +#ifndef _MSC_VER +#ifndef _LARGEFILE64_SOURCE +#define _LARGEFILE64_SOURCE +#endif +#endif + +#ifndef _LFS64_LARGEFILE +#define _LFS64_LARGEFILE +#endif + +#ifndef _FILE_OFFSET_BITS +#define _FILE_OFFSET_BITS 0 +#endif + +#include "png.h" +#ifndef PNG_READ_SUPPORTED +#undef HAVE_PNG +#endif +#endif + // // Texture definition. // Each texture is composed of one or more patches, @@ -178,7 +200,7 @@ static inline void R_DrawColumnInCache(column_t *patch, UINT8 *cache, INT32 orig // Allocate space for full size texture, either single patch or 'composite' // Build the full textures from patches. // The texture caching system is a little more hungry of memory, but has -// been simplified for the sake of highcolor, dynamic ligthing, & speed. +// been simplified for the sake of highcolor (lol), dynamic ligthing, & speed. // // This is not optimised, but it's supposed to be executed only once // per level, when enough memory is available. @@ -195,6 +217,10 @@ static UINT8 *R_GenerateTexture(size_t texnum) column_t *patchcol; UINT32 *colofs; + UINT16 wadnum; + lumpnum_t lumpnum; + size_t lumplength; + I_Assert(texnum <= (size_t)numtextures); texture = textures[texnum]; I_Assert(texture != NULL); @@ -209,7 +235,13 @@ static UINT8 *R_GenerateTexture(size_t texnum) { boolean holey = false; patch = texture->patches; - realpatch = W_CacheLumpNumPwad(patch->wad, patch->lump, PU_CACHE); + + wadnum = patch->wad; + lumpnum = patch->lump; + lumplength = W_LumpLengthPwad(wadnum, lumpnum); + realpatch = W_CacheLumpNumPwad(wadnum, lumpnum, PU_CACHE); + if (R_IsLumpPNG((UINT8 *)realpatch, lumplength)) + realpatch = R_PNGToPatch((UINT8 *)realpatch, lumplength); // Check the patch for holes. if (texture->width > SHORT(realpatch->width) || texture->height > SHORT(realpatch->height)) @@ -238,7 +270,7 @@ static UINT8 *R_GenerateTexture(size_t texnum) if (holey) { texture->holes = true; - blocksize = W_LumpLengthPwad(patch->wad, patch->lump); + blocksize = lumplength; block = Z_Calloc(blocksize, PU_STATIC, // will change tag at end of this function &texturecache[texnum]); M_Memcpy(block, realpatch, blocksize); @@ -274,7 +306,13 @@ static UINT8 *R_GenerateTexture(size_t texnum) // Composite the columns together. for (i = 0, patch = texture->patches; i < texture->patchcount; i++, patch++) { - realpatch = W_CacheLumpNumPwad(patch->wad, patch->lump, PU_CACHE); + wadnum = patch->wad; + lumpnum = patch->lump; + lumplength = W_LumpLengthPwad(wadnum, lumpnum); + realpatch = W_CacheLumpNumPwad(wadnum, lumpnum, PU_CACHE); + if (R_IsLumpPNG((UINT8 *)realpatch, lumplength)) + realpatch = R_PNGToPatch((UINT8 *)realpatch, lumplength); + x1 = patch->originx; x2 = x1 + SHORT(realpatch->width); @@ -487,7 +525,10 @@ void R_LoadTextures(void) // Work through each lump between the markers in the WAD. for (j = 0; j < (texend - texstart); i++, j++) { - patchlump = W_CacheLumpNumPwad((UINT16)w, texstart + j, PU_CACHE); + UINT16 wadnum = (UINT16)w; + lumpnum_t lumpnum = texstart + j; + size_t lumplength = W_LumpLengthPwad(wadnum, lumpnum); + patchlump = W_CacheLumpNumPwad(wadnum, lumpnum, PU_CACHE); // Then, check the lump directly to see if it's a texture SOC, // and if it is, load it using dehacked instead. @@ -503,9 +544,19 @@ void R_LoadTextures(void) texture = textures[i] = Z_Calloc(sizeof(texture_t) + sizeof(texpatch_t), PU_STATIC, NULL); // Set texture properties. - M_Memcpy(texture->name, W_CheckNameForNumPwad((UINT16)w, texstart + j), sizeof(texture->name)); - texture->width = SHORT(patchlump->width); - texture->height = SHORT(patchlump->height); + M_Memcpy(texture->name, W_CheckNameForNumPwad(wadnum, lumpnum), sizeof(texture->name)); + if (R_IsLumpPNG((UINT8 *)patchlump, lumplength)) + { + INT16 width, height; + R_PNGDimensions((UINT8 *)patchlump, &width, &height, lumplength); + texture->width = width; + texture->height = height; + } + else + { + texture->width = SHORT(patchlump->width); + texture->height = SHORT(patchlump->height); + } texture->patchcount = 1; texture->holes = false; @@ -1178,7 +1229,6 @@ INT32 R_ColormapNumForName(char *name) // static double deltas[256][3], map[256][3]; -static UINT8 NearestColor(UINT8 r, UINT8 g, UINT8 b); static int RoundUp(double number); INT32 R_CreateColormap(char *p1, char *p2, char *p3) @@ -1358,7 +1408,7 @@ INT32 R_CreateColormap(char *p1, char *p2, char *p3) // Thanks to quake2 source! // utils3/qdata/images.c -static UINT8 NearestColor(UINT8 r, UINT8 g, UINT8 b) +UINT8 NearestColor(UINT8 r, UINT8 g, UINT8 b) { int dr, dg, db; int distortion, bestdistortion = 256 * 256 * 4, bestcolor = 0, i; @@ -1686,7 +1736,7 @@ boolean R_CheckIfPatch(lumpnum_t lump) return result; } -void R_FlatPatch(patch_t *patch, UINT8 *flat) +void R_PatchToFlat(patch_t *patch, UINT8 *flat) { fixed_t col, ofs; column_t *column; @@ -1721,7 +1771,392 @@ void R_FlatPatch(patch_t *patch, UINT8 *flat) } } -void R_FlatTexture(size_t tex, UINT8 *flat) +#ifndef NO_PNG_LUMPS +boolean R_IsLumpPNG(UINT8 *d, size_t s) +{ + if (s < 67) // http://garethrees.org/2007/11/14/pngcrush/ + return false; + // Check for PNG file signature using memcmp + // As it may be faster on CPUs with slow unaligned memory access + // Ref: http://www.libpng.org/pub/png/spec/1.2/PNG-Rationale.html#R.PNG-file-signature + return (memcmp(&d[0], "\x89\x50\x4e\x47\x0d\x0a\x1a\x0a", 8) == 0); +} + +#ifdef HAVE_PNG +typedef struct { + png_bytep buffer; + png_uint_32 bufsize; + png_uint_32 current_pos; +} png_ioread; + +static void PNG_IOReader(png_structp png_ptr, png_bytep data, png_size_t length) +{ + png_ioread *f = png_get_io_ptr(png_ptr); + if (length > (f->bufsize - f->current_pos)) + png_error(png_ptr, "read error in read_data_memory (loadpng)"); + memcpy(data, f->buffer + f->current_pos, length); + f->current_pos += length; +} + +static void PNG_error(png_structp PNG, png_const_charp pngtext) +{ + CONS_Debug(DBG_RENDER, "libpng error at %p: %s", PNG, pngtext); + //I_Error("libpng error at %p: %s", PNG, pngtext); +} + +static void PNG_warn(png_structp PNG, png_const_charp pngtext) +{ + CONS_Debug(DBG_RENDER, "libpng warning at %p: %s", PNG, pngtext); +} + +static png_bytep *PNG_Read(UINT8 *png, UINT16 *w, UINT16 *h, size_t size) +{ + png_structp png_ptr; + png_infop png_info_ptr; + png_uint_32 width, height; + int bit_depth, color_type; + png_uint_32 y; +#ifdef PNG_SETJMP_SUPPORTED +#ifdef USE_FAR_KEYWORD + jmp_buf jmpbuf; +#endif +#endif + + png_ioread png_io; + png_bytep *row_pointers; + + png_ptr = png_create_read_struct(PNG_LIBPNG_VER_STRING, NULL, + PNG_error, PNG_warn); + if (!png_ptr) + { + CONS_Debug(DBG_RENDER, "PNG_Load: Error on initialize libpng\n"); + return NULL; + } + + png_info_ptr = png_create_info_struct(png_ptr); + if (!png_info_ptr) + { + CONS_Debug(DBG_RENDER, "PNG_Load: Error on allocate for libpng\n"); + png_destroy_read_struct(&png_ptr, NULL, NULL); + return NULL; + } + +#ifdef USE_FAR_KEYWORD + if (setjmp(jmpbuf)) +#else + if (setjmp(png_jmpbuf(png_ptr))) +#endif + { + //CONS_Debug(DBG_RENDER, "libpng load error on %s\n", filename); + png_destroy_read_struct(&png_ptr, &png_info_ptr, NULL); + return NULL; + } +#ifdef USE_FAR_KEYWORD + png_memcpy(png_jmpbuf(png_ptr), jmpbuf, sizeof jmp_buf); +#endif + + // png_source is array which have png data + png_io.buffer = (png_bytep)png; + png_io.bufsize = size; + png_io.current_pos = 0; + // set our own read_function + png_set_read_fn(png_ptr, &png_io, PNG_IOReader); + +#ifdef PNG_SET_USER_LIMITS_SUPPORTED + png_set_user_limits(png_ptr, 2048, 2048); +#endif + + png_read_info(png_ptr, png_info_ptr); + + png_get_IHDR(png_ptr, png_info_ptr, &width, &height, &bit_depth, &color_type, + NULL, NULL, NULL); + + if (bit_depth == 16) + png_set_strip_16(png_ptr); + + if (color_type == PNG_COLOR_TYPE_GRAY || color_type == PNG_COLOR_TYPE_GRAY_ALPHA) + png_set_gray_to_rgb(png_ptr); + else if (color_type == PNG_COLOR_TYPE_PALETTE) + png_set_palette_to_rgb(png_ptr); + + if (png_get_valid(png_ptr, png_info_ptr, PNG_INFO_tRNS)) + png_set_tRNS_to_alpha(png_ptr); + else if (color_type != PNG_COLOR_TYPE_RGB_ALPHA && color_type != PNG_COLOR_TYPE_GRAY_ALPHA) + { +#if PNG_LIBPNG_VER < 10207 + png_set_filler(png_ptr, 0xFF, PNG_FILLER_AFTER); +#else + png_set_add_alpha(png_ptr, 0xFF, PNG_FILLER_AFTER); +#endif + } + + png_read_update_info(png_ptr, png_info_ptr); + + // Read the image + row_pointers = (png_bytep*)malloc(sizeof(png_bytep) * height); + for (y = 0; y < height; y++) + row_pointers[y] = (png_byte*)malloc(png_get_rowbytes(png_ptr, png_info_ptr)); + png_read_image(png_ptr, row_pointers); + png_destroy_read_struct(&png_ptr, &png_info_ptr, NULL); + + *w = (INT32)width; + *h = (INT32)height; + return row_pointers; +} + +// Convert a PNG to a raw image. +static UINT8 *PNG_RawConvert(UINT8 *png, UINT16 *w, UINT16 *h, size_t size) +{ + UINT8 *flat; + png_uint_32 x, y; + png_bytep *row_pointers = PNG_Read(png, w, h, size); + png_uint_32 width = *w, height = *h; + + if (!row_pointers) + return NULL; + + // Convert the image to 8bpp + flat = Z_Malloc(width * height, PU_STATIC, NULL); + memset(flat, TRANSPARENTPIXEL, width * height); + for (y = 0; y < height; y++) + { + png_bytep row = row_pointers[y]; + for (x = 0; x < width; x++) + { + png_bytep px = &(row[x * 4]); + flat[((y * width) + x)] = NearestColor((UINT8)px[0], (UINT8)px[1], (UINT8)px[2]); + } + } + free(row_pointers); + + return flat; +} + +// Get the alpha mask of the image. +static UINT8 *PNG_GetAlphaMask(UINT8 *png, size_t size) +{ + UINT8 *mask; + png_uint_32 x, y; + UINT16 width, height; + png_bytep *row_pointers = PNG_Read(png, &width, &height, size); + + if (!row_pointers) + return NULL; + + // Convert the image to 8bpp + mask = Z_Malloc(width * height, PU_STATIC, NULL); + memset(mask, 0, width * height); + for (y = 0; y < height; y++) + { + png_bytep row = row_pointers[y]; + for (x = 0; x < width; x++) + { + png_bytep px = &(row[x * 4]); + mask[((y * width) + x)] = (UINT8)px[3]; + } + } + free(row_pointers); + + return mask; +} + +// Convert a PNG to a flat. +UINT8 *R_PNGToFlat(levelflat_t *levelflat, UINT8 *png, size_t size) +{ + return PNG_RawConvert(png, &levelflat->width, &levelflat->height, size); +} + +// Convert a PNG to a patch. +// This is adapted from the "kartmaker" utility +static unsigned char imgbuf[1<<26]; +patch_t *R_PNGToPatch(UINT8 *png, size_t size) +{ + UINT16 width, height; + UINT8 *raw = PNG_RawConvert(png, &width, &height, size); + UINT8 *alphamask = PNG_GetAlphaMask(png, size); + + UINT32 x, y; + UINT8 *img; + UINT8 *imgptr = imgbuf; + UINT8 *colpointers, *startofspan; + + #define WRITE8(buf, a) ({*buf = (a); buf++;}) + #define WRITE16(buf, a) ({*buf = (a)&255; buf++; *buf = (a)>>8; buf++;}) + #define WRITE32(buf, a) ({WRITE16(buf, (a)&65535); WRITE16(buf, (a)>>16);}) + + if (!raw) + return NULL; + + // Write image size and offset + WRITE16(imgptr, width); + WRITE16(imgptr, height); + // no offsets + WRITE16(imgptr, 0); + WRITE16(imgptr, 0); + + // Leave placeholder to column pointers + colpointers = imgptr; + imgptr += width*4; + + // Write columns + for (x = 0; x < width; x++) + { + int lastStartY = 0; + int spanSize = 0; + startofspan = NULL; + + //printf("%d ", x); + // Write column pointer (@TODO may be wrong) + WRITE32(colpointers, imgptr - imgbuf); + + // Write pixels + for (y = 0; y < height; y++) + { + UINT8 paletteIndex = raw[((y * width) + x)]; + UINT8 opaque = alphamask[((y * width) + x)]; // If 1, we have a pixel + + // End span if we have a transparent pixel + if (!opaque) + { + if (startofspan) + WRITE8(imgptr, 0); + startofspan = NULL; + continue; + } + + // Start new column if we need to + if (!startofspan || spanSize == 255) + { + int writeY = y; + + // If we reached the span size limit, finish the previous span + if (startofspan) + WRITE8(imgptr, 0); + + if (y > 254) + { + // Make sure we're aligned to 254 + if (lastStartY < 254) + { + WRITE8(imgptr, 254); + WRITE8(imgptr, 0); + imgptr += 2; + lastStartY = 254; + } + + // Write stopgap empty spans if needed + writeY = y - lastStartY; + + while (writeY > 254) + { + WRITE8(imgptr, 254); + WRITE8(imgptr, 0); + imgptr += 2; + writeY -= 254; + } + } + + startofspan = imgptr; + WRITE8(imgptr, writeY);///@TODO calculate starting y pos + imgptr += 2; + spanSize = 0; + + lastStartY = y; + } + + // Write the pixel + WRITE8(imgptr, paletteIndex); + spanSize++; + startofspan[1] = spanSize; + } + + if (startofspan) + WRITE8(imgptr, 0); + + WRITE8(imgptr, 0xFF); + } + + #undef WRITE8 + #undef WRITE16 + #undef WRITE32 + + size = imgptr-imgbuf; + img = malloc(size); + memcpy(img, imgbuf, size); + return (patch_t *)img; +} + +boolean R_PNGDimensions(UINT8 *png, INT16 *width, INT16 *height, size_t size) +{ + png_structp png_ptr; + png_infop png_info_ptr; + png_uint_32 w, h; + int bit_depth, color_type; +#ifdef PNG_SETJMP_SUPPORTED +#ifdef USE_FAR_KEYWORD + jmp_buf jmpbuf; +#endif +#endif + + png_ioread png_io; + + png_ptr = png_create_read_struct(PNG_LIBPNG_VER_STRING, NULL, + PNG_error, PNG_warn); + if (!png_ptr) + { + CONS_Debug(DBG_RENDER, "PNG_Load: Error on initialize libpng\n"); + return false; + } + + png_info_ptr = png_create_info_struct(png_ptr); + if (!png_info_ptr) + { + CONS_Debug(DBG_RENDER, "PNG_Load: Error on allocate for libpng\n"); + png_destroy_read_struct(&png_ptr, NULL, NULL); + return false; + } + +#ifdef USE_FAR_KEYWORD + if (setjmp(jmpbuf)) +#else + if (setjmp(png_jmpbuf(png_ptr))) +#endif + { + //CONS_Debug(DBG_RENDER, "libpng load error on %s\n", filename); + png_destroy_read_struct(&png_ptr, &png_info_ptr, NULL); + return false; + } +#ifdef USE_FAR_KEYWORD + png_memcpy(png_jmpbuf(png_ptr), jmpbuf, sizeof jmp_buf); +#endif + + // png_source is array which have png data + png_io.buffer = (png_bytep)png; + png_io.bufsize = size; + png_io.current_pos = 0; + // set our own read_function + png_set_read_fn(png_ptr, &png_io, PNG_IOReader); + +#ifdef PNG_SET_USER_LIMITS_SUPPORTED + png_set_user_limits(png_ptr, 2048, 2048); +#endif + + png_read_info(png_ptr, png_info_ptr); + + png_get_IHDR(png_ptr, png_info_ptr, &w, &h, &bit_depth, &color_type, + NULL, NULL, NULL); + + // okay done. stop. + png_destroy_read_struct(&png_ptr, &png_info_ptr, NULL); + + *width = (INT32)w; + *height = (INT32)h; + return true; +} +#endif +#endif + +void R_TextureToFlat(size_t tex, UINT8 *flat) { texture_t *texture = textures[tex]; diff --git a/src/r_data.h b/src/r_data.h index 855daa06d..5f3f10d59 100644 --- a/src/r_data.h +++ b/src/r_data.h @@ -16,6 +16,7 @@ #include "r_defs.h" #include "r_state.h" +#include "p_setup.h" // levelflats #ifdef __GNUG__ #pragma interface @@ -105,14 +106,23 @@ INT32 R_CreateColormap(char *p1, char *p2, char *p3); const char *R_ColormapNameForNum(INT32 num); boolean R_CheckIfPatch(lumpnum_t lump); +UINT8 NearestColor(UINT8 r, UINT8 g, UINT8 b); -void R_FlatPatch(patch_t *patch, UINT8 *flat); -void R_FlatTexture(size_t tex, UINT8 *flat); +void R_PatchToFlat(patch_t *patch, UINT8 *flat); +void R_TextureToFlat(size_t tex, UINT8 *flat); void R_CropFlat(UINT8 *srcflat, UINT8 *destflat, UINT16 srcwidth, UINT16 srcheight, UINT16 resizewidth, UINT16 resizeheight, UINT16 destwidth, UINT16 destheight); +#ifndef NO_PNG_LUMPS +boolean R_IsLumpPNG(UINT8 *d, size_t s); + +UINT8 *R_PNGToFlat(levelflat_t *levelflat, UINT8 *png, size_t size); +patch_t *R_PNGToPatch(UINT8 *png, size_t size); +boolean R_PNGDimensions(UINT8 *png, INT16 *width, INT16 *height, size_t size); +#endif + extern INT32 numtextures; #endif diff --git a/src/r_plane.c b/src/r_plane.c index 37a76e2cd..d07a68759 100644 --- a/src/r_plane.c +++ b/src/r_plane.c @@ -714,7 +714,7 @@ void R_CheckFlatLength(size_t size) } } -static void R_GetPatchFlat(levelflat_t *levelflat, boolean leveltexture) +static void R_GetPatchFlat(levelflat_t *levelflat, boolean leveltexture, boolean ispng) { textureflat_t *texflat = &texflats[levelflat->texturenum]; patch_t *patch = NULL; @@ -751,23 +751,46 @@ static void R_GetPatchFlat(levelflat_t *levelflat, boolean leveltexture) texflat->flat = Z_Malloc(ds_flatwidth * ds_flatheight, PU_LEVEL, NULL); memset(texflat->flat, TRANSPARENTPIXEL, ds_flatwidth * ds_flatheight); - R_FlatTexture(levelflat->texturenum, texflat->flat); + R_TextureToFlat(levelflat->texturenum, texflat->flat); ds_source = texflat->flat; } else { patch = (patch_t *)ds_source; - levelflat->width = ds_flatwidth = SHORT(patch->width); - levelflat->height = ds_flatheight = SHORT(patch->height); +#ifndef NO_PNG_LUMPS +#ifdef HAVE_PNG + if (ispng) + { + levelflat->flatpatch = R_PNGToFlat(levelflat, ds_source, W_LumpLength(levelflat->lumpnum)); + levelflat->topoffset = levelflat->leftoffset = 0; + if (levelflat->flatpatch == NULL) + { + lumpnum_t redflr = W_CheckNumForName("REDFLR"); + levelflat->flatpatch = (UINT8 *)W_CacheLumpNum(redflr, PU_STATIC); + R_CheckFlatLength(W_LumpLength(redflr)); + R_CheckPowersOfTwo(); + } + else + { + ds_flatwidth = levelflat->width; + ds_flatheight = levelflat->height; + } + } + else +#endif +#endif + { + levelflat->width = ds_flatwidth = SHORT(patch->width); + levelflat->height = ds_flatheight = SHORT(patch->height); - levelflat->topoffset = patch->topoffset * FRACUNIT; - levelflat->leftoffset = patch->leftoffset * FRACUNIT; - - levelflat->flatpatch = Z_Malloc(ds_flatwidth * ds_flatheight, PU_LEVEL, NULL); - memset(levelflat->flatpatch, TRANSPARENTPIXEL, ds_flatwidth * ds_flatheight); - R_FlatPatch(patch, levelflat->flatpatch); + levelflat->topoffset = patch->topoffset * FRACUNIT; + levelflat->leftoffset = patch->leftoffset * FRACUNIT; + levelflat->flatpatch = Z_Malloc(ds_flatwidth * ds_flatheight, PU_LEVEL, NULL); + memset(levelflat->flatpatch, TRANSPARENTPIXEL, ds_flatwidth * ds_flatheight); + R_PatchToFlat(patch, levelflat->flatpatch); + } ds_source = levelflat->flatpatch; } @@ -1030,19 +1053,20 @@ void R_DrawSinglePlane(visplane_t *pl) currentplane = pl; levelflat = &levelflats[pl->picnum]; size = W_LumpLength(levelflat->lumpnum); + ds_source = (UINT8 *)W_CacheLumpNum(levelflat->lumpnum, PU_STATIC); // Stay here until Z_ChangeTag // Check if the flat is actually a wall texture. if (levelflat->texturenum != 0 && levelflat->texturenum != -1) - R_GetPatchFlat(levelflat, true); + R_GetPatchFlat(levelflat, true, false); // Maybe it's just a patch, then? else if (R_CheckIfPatch(levelflat->lumpnum)) - R_GetPatchFlat(levelflat, false); + R_GetPatchFlat(levelflat, false, false); + // Maybe it's a PNG?! + else if (R_IsLumpPNG(ds_source, size)) + R_GetPatchFlat(levelflat, false, true); // It's a raw flat. else - { - ds_source = (UINT8 *)W_CacheLumpNum(levelflat->lumpnum, PU_STATIC); // Stay here until Z_ChangeTag R_CheckFlatLength(size); - } // Check if the flat has dimensions that are powers-of-two numbers. if (R_CheckPowersOfTwo()) diff --git a/src/w_wad.c b/src/w_wad.c index c4f9ceca8..5e25dea97 100644 --- a/src/w_wad.c +++ b/src/w_wad.c @@ -1179,8 +1179,6 @@ void zerr(int ret) } #endif -#define NO_PNG_LUMPS - #ifdef NO_PNG_LUMPS static void ErrorIfPNG(UINT8 *d, size_t s, char *f, char *l) { From 02c3710211b408e103ce78d1d6cb3dbd93e43042 Mon Sep 17 00:00:00 2001 From: Jaime Passos Date: Tue, 25 Jun 2019 14:40:00 -0300 Subject: [PATCH 10/13] hHA --- src/p_setup.h | 6 -- src/r_data.h | 5 -- src/r_draw8.c | 229 +++++++++++++++++++++++++++++++++++++++++++++++--- src/r_plane.c | 164 ++++++++++-------------------------- 4 files changed, 264 insertions(+), 140 deletions(-) diff --git a/src/p_setup.h b/src/p_setup.h index 824584be7..a123f757a 100644 --- a/src/p_setup.h +++ b/src/p_setup.h @@ -49,12 +49,6 @@ typedef struct // for patchflats UINT8 *flatpatch; - -#ifdef ESLOPE - // rescaled version of the above - UINT8 *resizedflat; - UINT16 resizedwidth, resizedheight; -#endif } levelflat_t; extern size_t numlevelflats; diff --git a/src/r_data.h b/src/r_data.h index 855daa06d..c528fcfe1 100644 --- a/src/r_data.h +++ b/src/r_data.h @@ -52,11 +52,6 @@ typedef struct { UINT8 *flat; INT16 width, height; - -#ifdef ESLOPE - UINT8 *resizedflat; - INT16 resizedwidth, resizedheight; -#endif } textureflat_t; // all loaded and prepared textures from the start of the game diff --git a/src/r_draw8.c b/src/r_draw8.c index 542572707..1c4527a8e 100644 --- a/src/r_draw8.c +++ b/src/r_draw8.c @@ -724,7 +724,24 @@ void R_DrawTiltedSpan_8(void) colormap = planezlight[tiltlighting[ds_x1++]] + (ds_colormap - colormaps); - *dest = colormap[source[((v >> nflatyshift) & nflatmask) | (u >> nflatxshift)]]; + if (!ds_powersoftwo) + { + fixed_t x = ((u-viewx) >> FRACBITS); + fixed_t y = ((v-viewy) >> FRACBITS); + + // Carefully align all of my Friends. + if (x < 0) + x = ds_flatwidth - ((UINT32)(ds_flatwidth - x) % ds_flatwidth); + if (y < 0) + y = ds_flatheight - ((UINT32)(ds_flatheight - y) % ds_flatheight); + + x %= ds_flatwidth; + y %= ds_flatheight; + + *dest = colormap[source[((y * ds_flatwidth) + x)]]; + } + else + *dest = colormap[source[((v >> nflatyshift) & nflatmask) | (u >> nflatxshift)]]; dest++; iz += ds_sz.x; uz += ds_su.x; @@ -761,7 +778,24 @@ void R_DrawTiltedSpan_8(void) for (i = SPANSIZE-1; i >= 0; i--) { colormap = planezlight[tiltlighting[ds_x1++]] + (ds_colormap - colormaps); - *dest = colormap[source[((v >> nflatyshift) & nflatmask) | (u >> nflatxshift)]]; + if (!ds_powersoftwo) + { + fixed_t x = ((u-viewx) >> FRACBITS); + fixed_t y = ((v-viewy) >> FRACBITS); + + // Carefully align all of my Friends. + if (x < 0) + x = ds_flatwidth - ((UINT32)(ds_flatwidth - x) % ds_flatwidth); + if (y < 0) + y = ds_flatheight - ((UINT32)(ds_flatheight - y) % ds_flatheight); + + x %= ds_flatwidth; + y %= ds_flatheight; + + *dest = colormap[source[((y * ds_flatwidth) + x)]]; + } + else + *dest = colormap[source[((v >> nflatyshift) & nflatmask) | (u >> nflatxshift)]]; dest++; u += stepu; v += stepv; @@ -777,7 +811,24 @@ void R_DrawTiltedSpan_8(void) u = (INT64)(startu); v = (INT64)(startv); colormap = planezlight[tiltlighting[ds_x1++]] + (ds_colormap - colormaps); - *dest = colormap[source[((v >> nflatyshift) & nflatmask) | (u >> nflatxshift)]]; + if (!ds_powersoftwo) + { + fixed_t x = ((u-viewx) >> FRACBITS); + fixed_t y = ((v-viewy) >> FRACBITS); + + // Carefully align all of my Friends. + if (x < 0) + x = ds_flatwidth - ((UINT32)(ds_flatwidth - x) % ds_flatwidth); + if (y < 0) + y = ds_flatheight - ((UINT32)(ds_flatheight - y) % ds_flatheight); + + x %= ds_flatwidth; + y %= ds_flatheight; + + *dest = colormap[source[((y * ds_flatwidth) + x)]]; + } + else + *dest = colormap[source[((v >> nflatyshift) & nflatmask) | (u >> nflatxshift)]]; } else { @@ -798,7 +849,24 @@ void R_DrawTiltedSpan_8(void) for (; width != 0; width--) { colormap = planezlight[tiltlighting[ds_x1++]] + (ds_colormap - colormaps); - *dest = colormap[source[((v >> nflatyshift) & nflatmask) | (u >> nflatxshift)]]; + if (!ds_powersoftwo) + { + fixed_t x = ((u-viewx) >> FRACBITS); + fixed_t y = ((v-viewy) >> FRACBITS); + + // Carefully align all of my Friends. + if (x < 0) + x = ds_flatwidth - ((UINT32)(ds_flatwidth - x) % ds_flatwidth); + if (y < 0) + y = ds_flatheight - ((UINT32)(ds_flatheight - y) % ds_flatheight); + + x %= ds_flatwidth; + y %= ds_flatheight; + + *dest = colormap[source[((y * ds_flatwidth) + x)]]; + } + else + *dest = colormap[source[((v >> nflatyshift) & nflatmask) | (u >> nflatxshift)]]; dest++; u += stepu; v += stepv; @@ -859,7 +927,24 @@ void R_DrawTiltedTranslucentSpan_8(void) v = (INT64)(vz*z) + viewy; colormap = planezlight[tiltlighting[ds_x1++]] + (ds_colormap - colormaps); - *dest = *(ds_transmap + (colormap[source[((v >> nflatyshift) & nflatmask) | (u >> nflatxshift)]] << 8) + *dest); + if (!ds_powersoftwo) + { + fixed_t x = ((u-viewx) >> FRACBITS); + fixed_t y = ((v-viewy) >> FRACBITS); + + // Carefully align all of my Friends. + if (x < 0) + x = ds_flatwidth - ((UINT32)(ds_flatwidth - x) % ds_flatwidth); + if (y < 0) + y = ds_flatheight - ((UINT32)(ds_flatheight - y) % ds_flatheight); + + x %= ds_flatwidth; + y %= ds_flatheight; + + *dest = *(ds_transmap + (colormap[source[((y * ds_flatwidth) + x)]] << 8) + *dest); + } + else + *dest = *(ds_transmap + (colormap[source[((v >> nflatyshift) & nflatmask) | (u >> nflatxshift)]] << 8) + *dest); dest++; iz += ds_sz.x; uz += ds_su.x; @@ -896,7 +981,24 @@ void R_DrawTiltedTranslucentSpan_8(void) for (i = SPANSIZE-1; i >= 0; i--) { colormap = planezlight[tiltlighting[ds_x1++]] + (ds_colormap - colormaps); - *dest = *(ds_transmap + (colormap[source[((v >> nflatyshift) & nflatmask) | (u >> nflatxshift)]] << 8) + *dest); + if (!ds_powersoftwo) + { + fixed_t x = ((u-viewx) >> FRACBITS); + fixed_t y = ((v-viewy) >> FRACBITS); + + // Carefully align all of my Friends. + if (x < 0) + x = ds_flatwidth - ((UINT32)(ds_flatwidth - x) % ds_flatwidth); + if (y < 0) + y = ds_flatheight - ((UINT32)(ds_flatheight - y) % ds_flatheight); + + x %= ds_flatwidth; + y %= ds_flatheight; + + *dest = *(ds_transmap + (colormap[source[((y * ds_flatwidth) + x)]] << 8) + *dest); + } + else + *dest = *(ds_transmap + (colormap[source[((v >> nflatyshift) & nflatmask) | (u >> nflatxshift)]] << 8) + *dest); dest++; u += stepu; v += stepv; @@ -912,7 +1014,24 @@ void R_DrawTiltedTranslucentSpan_8(void) u = (INT64)(startu); v = (INT64)(startv); colormap = planezlight[tiltlighting[ds_x1++]] + (ds_colormap - colormaps); - *dest = *(ds_transmap + (colormap[source[((v >> nflatyshift) & nflatmask) | (u >> nflatxshift)]] << 8) + *dest); + if (!ds_powersoftwo) + { + fixed_t x = ((u-viewx) >> FRACBITS); + fixed_t y = ((v-viewy) >> FRACBITS); + + // Carefully align all of my Friends. + if (x < 0) + x = ds_flatwidth - ((UINT32)(ds_flatwidth - x) % ds_flatwidth); + if (y < 0) + y = ds_flatheight - ((UINT32)(ds_flatheight - y) % ds_flatheight); + + x %= ds_flatwidth; + y %= ds_flatheight; + + *dest = *(ds_transmap + (colormap[source[((y * ds_flatwidth) + x)]] << 8) + *dest); + } + else + *dest = *(ds_transmap + (colormap[source[((v >> nflatyshift) & nflatmask) | (u >> nflatxshift)]] << 8) + *dest); } else { @@ -933,7 +1052,24 @@ void R_DrawTiltedTranslucentSpan_8(void) for (; width != 0; width--) { colormap = planezlight[tiltlighting[ds_x1++]] + (ds_colormap - colormaps); - *dest = *(ds_transmap + (colormap[source[((v >> nflatyshift) & nflatmask) | (u >> nflatxshift)]] << 8) + *dest); + if (!ds_powersoftwo) + { + fixed_t x = ((u-viewx) >> FRACBITS); + fixed_t y = ((v-viewy) >> FRACBITS); + + // Carefully align all of my Friends. + if (x < 0) + x = ds_flatwidth - ((UINT32)(ds_flatwidth - x) % ds_flatwidth); + if (y < 0) + y = ds_flatheight - ((UINT32)(ds_flatheight - y) % ds_flatheight); + + x %= ds_flatwidth; + y %= ds_flatheight; + + *dest = *(ds_transmap + (colormap[source[((y * ds_flatwidth) + x)]] << 8) + *dest); + } + else + *dest = *(ds_transmap + (colormap[source[((v >> nflatyshift) & nflatmask) | (u >> nflatxshift)]] << 8) + *dest); dest++; u += stepu; v += stepv; @@ -994,9 +1130,28 @@ void R_DrawTiltedSplat_8(void) colormap = planezlight[tiltlighting[ds_x1++]] + (ds_colormap - colormaps); - val = source[((v >> nflatyshift) & nflatmask) | (u >> nflatxshift)]; + if (!ds_powersoftwo) + { + fixed_t x = ((u-viewx) >> FRACBITS); + fixed_t y = ((v-viewy) >> FRACBITS); + + // Carefully align all of my Friends. + if (x < 0) + x = ds_flatwidth - ((UINT32)(ds_flatwidth - x) % ds_flatwidth); + if (y < 0) + y = ds_flatheight - ((UINT32)(ds_flatheight - y) % ds_flatheight); + + x %= ds_flatwidth; + y %= ds_flatheight; + + val = source[((y * ds_flatwidth) + x)]; + } + else + val = source[((v >> nflatyshift) & nflatmask) | (u >> nflatxshift)]; + if (val != TRANSPARENTPIXEL) *dest = colormap[val]; + dest++; iz += ds_sz.x; uz += ds_su.x; @@ -1033,7 +1188,24 @@ void R_DrawTiltedSplat_8(void) for (i = SPANSIZE-1; i >= 0; i--) { colormap = planezlight[tiltlighting[ds_x1++]] + (ds_colormap - colormaps); - val = source[((v >> nflatyshift) & nflatmask) | (u >> nflatxshift)]; + if (!ds_powersoftwo) + { + fixed_t x = ((u-viewx) >> FRACBITS); + fixed_t y = ((v-viewy) >> FRACBITS); + + // Carefully align all of my Friends. + if (x < 0) + x = ds_flatwidth - ((UINT32)(ds_flatwidth - x) % ds_flatwidth); + if (y < 0) + y = ds_flatheight - ((UINT32)(ds_flatheight - y) % ds_flatheight); + + x %= ds_flatwidth; + y %= ds_flatheight; + + val = source[((y * ds_flatwidth) + x)]; + } + else + val = source[((v >> nflatyshift) & nflatmask) | (u >> nflatxshift)]; if (val != TRANSPARENTPIXEL) *dest = colormap[val]; dest++; @@ -1051,7 +1223,24 @@ void R_DrawTiltedSplat_8(void) u = (INT64)(startu); v = (INT64)(startv); colormap = planezlight[tiltlighting[ds_x1++]] + (ds_colormap - colormaps); - val = source[((v >> nflatyshift) & nflatmask) | (u >> nflatxshift)]; + if (!ds_powersoftwo) + { + fixed_t x = ((u-viewx) >> FRACBITS); + fixed_t y = ((v-viewy) >> FRACBITS); + + // Carefully align all of my Friends. + if (x < 0) + x = ds_flatwidth - ((UINT32)(ds_flatwidth - x) % ds_flatwidth); + if (y < 0) + y = ds_flatheight - ((UINT32)(ds_flatheight - y) % ds_flatheight); + + x %= ds_flatwidth; + y %= ds_flatheight; + + val = source[((y * ds_flatwidth) + x)]; + } + else + val = source[((v >> nflatyshift) & nflatmask) | (u >> nflatxshift)]; if (val != TRANSPARENTPIXEL) *dest = colormap[val]; } @@ -1075,6 +1264,24 @@ void R_DrawTiltedSplat_8(void) { colormap = planezlight[tiltlighting[ds_x1++]] + (ds_colormap - colormaps); val = source[((v >> nflatyshift) & nflatmask) | (u >> nflatxshift)]; + if (!ds_powersoftwo) + { + fixed_t x = ((u-viewx) >> FRACBITS); + fixed_t y = ((v-viewy) >> FRACBITS); + + // Carefully align all of my Friends. + if (x < 0) + x = ds_flatwidth - ((UINT32)(ds_flatwidth - x) % ds_flatwidth); + if (y < 0) + y = ds_flatheight - ((UINT32)(ds_flatheight - y) % ds_flatheight); + + x %= ds_flatwidth; + y %= ds_flatheight; + + val = source[((y * ds_flatwidth) + x)]; + } + else + val = source[((v >> nflatyshift) & nflatmask) | (u >> nflatxshift)]; if (val != TRANSPARENTPIXEL) *dest = colormap[val]; dest++; diff --git a/src/r_plane.c b/src/r_plane.c index 37a76e2cd..f79a5f90a 100644 --- a/src/r_plane.c +++ b/src/r_plane.c @@ -718,7 +718,6 @@ static void R_GetPatchFlat(levelflat_t *levelflat, boolean leveltexture) { textureflat_t *texflat = &texflats[levelflat->texturenum]; patch_t *patch = NULL; - UINT8 *tex; boolean texturechanged = (leveltexture ? (levelflat->texturenum != levelflat->lasttexturenum) : false); // Check if the texture changed. @@ -738,11 +737,6 @@ static void R_GetPatchFlat(levelflat_t *levelflat, boolean leveltexture) // If the texture changed, or the patch doesn't exist, convert either of them to a flat. if (levelflat->flatpatch == NULL || texturechanged) { -#ifdef ESLOPE - INT32 resizewidth, resizeheight, newresize; - INT32 checkresizewidth, checkresizeheight; -#endif // ESLOPE - if (leveltexture) { texture_t *texture = textures[levelflat->texturenum]; @@ -770,75 +764,6 @@ static void R_GetPatchFlat(levelflat_t *levelflat, boolean leveltexture) ds_source = levelflat->flatpatch; } - -#ifdef ESLOPE - // Crop the flat, if necessary. - if (!R_CheckPowersOfTwo()) - { - // Scale up to nearest power of 2 - resizewidth = resizeheight = 1; - while (resizewidth < ds_flatwidth) - resizewidth <<= 1; - while (resizeheight < ds_flatheight) - resizeheight <<= 1; - - // Scale down to fit in 2048x2048 - if (resizewidth > 2048) - resizewidth = 2048; - if (resizeheight > 2048) - resizeheight = 2048; - - // A single pixel difference is negligible. - checkresizewidth = ds_flatwidth - 1; - if (checkresizewidth & (checkresizewidth - 1)) - { - checkresizewidth += 2; - if (checkresizewidth & (checkresizewidth - 1)) - { - while (resizewidth > ds_flatwidth) - resizewidth >>= 1; - } - else - resizewidth = checkresizewidth; - } - else - resizewidth = checkresizewidth; - - checkresizeheight = ds_flatheight - 1; - if (checkresizeheight & (checkresizeheight - 1)) - { - checkresizeheight += 2; - if (checkresizeheight & (checkresizeheight - 1)) - { - while (resizeheight > ds_flatheight) - resizeheight >>= 1; - } - else - resizeheight = checkresizeheight; - } - else - resizeheight = checkresizeheight; - - // Find smallest size. - newresize = min(resizewidth, resizeheight); - - // Allocate texture. - tex = Z_Malloc(newresize * newresize, PU_LEVEL, NULL); - memset(tex, TRANSPARENTPIXEL, newresize * newresize); - R_CropFlat(ds_source, tex, ds_flatwidth, ds_flatheight, min(resizewidth, newresize), min(resizeheight, newresize), newresize, newresize); - - if (leveltexture) - { - texflat->resizedflat = tex; - texflat->resizedwidth = texflat->resizedheight = newresize; - } - else - { - levelflat->resizedflat = tex; - levelflat->resizedwidth = levelflat->resizedheight = newresize; - } - } -#endif // ESLOPE } else { @@ -850,28 +775,6 @@ static void R_GetPatchFlat(levelflat_t *levelflat, boolean leveltexture) yoffs += levelflat->topoffset; } -#ifdef ESLOPE - if (currentplane->slope) - { - if (R_CheckPowersOfTwo()) - { - if (leveltexture) - { - ds_source = texflat->resizedflat; - ds_flatwidth = texflat->resizedwidth; - ds_flatheight = texflat->resizedheight; - } - else - { - ds_source = levelflat->resizedflat; - ds_flatwidth = levelflat->resizedwidth; - ds_flatheight = levelflat->resizedheight; - } - } - R_CheckFlatLength(ds_flatwidth * ds_flatheight); - } -#endif // ESLOPE - levelflat->lasttexturenum = levelflat->texturenum; } @@ -1061,22 +964,32 @@ void R_DrawSinglePlane(visplane_t *pl) floatv3_t p, m, n; float ang; float vx, vy, vz; - float fudge; + float fudge = 0; // compiler complains when P_GetZAt is used in FLOAT_TO_FIXED directly // use this as a temp var to store P_GetZAt's return value each time fixed_t temp; - xoffs &= ((1 << (32-nflatshiftup))-1); - yoffs &= ((1 << (32-nflatshiftup))-1); + if (ds_powersoftwo) + { + // But xoffs and yoffs are zero..... ???!?!?!???!?!?! + xoffs &= ((1 << (32-nflatshiftup))-1); + yoffs &= ((1 << (32-nflatshiftup))-1); - xoffs -= (pl->slope->o.x + (1 << (31-nflatshiftup))) & ~((1 << (32-nflatshiftup))-1); - yoffs += (pl->slope->o.y + (1 << (31-nflatshiftup))) & ~((1 << (32-nflatshiftup))-1); + xoffs -= (pl->slope->o.x + (1 << (31-nflatshiftup))) & ~((1 << (32-nflatshiftup))-1); + yoffs += (pl->slope->o.y + (1 << (31-nflatshiftup))) & ~((1 << (32-nflatshiftup))-1); - // Okay, look, don't ask me why this works, but without this setup there's a disgusting-looking misalignment with the textures. -Red - fudge = ((1<slope->o.x; + yoffs = pl->slope->o.y; + } vx = FIXED_TO_FLOAT(pl->viewx+xoffs); vy = FIXED_TO_FLOAT(pl->viewy-yoffs); @@ -1111,13 +1024,16 @@ void R_DrawSinglePlane(visplane_t *pl) temp = P_GetZAt(pl->slope, pl->viewx + FLOAT_TO_FIXED(cos(ang)), pl->viewy - FLOAT_TO_FIXED(sin(ang))); n.y = FIXED_TO_FLOAT(temp) - zeroheight; - m.x /= fudge; - m.y /= fudge; - m.z /= fudge; + if (ds_powersoftwo) + { + m.x /= fudge; + m.y /= fudge; + m.z /= fudge; - n.x *= fudge; - n.y *= fudge; - n.z *= fudge; + n.x *= fudge; + n.y *= fudge; + n.z *= fudge; + } // Eh. I tried making this stuff fixed-point and it exploded on me. Here's a macro for the only floating-point vector function I recall using. #define CROSS(d, v1, v2) \ @@ -1134,14 +1050,26 @@ void R_DrawSinglePlane(visplane_t *pl) ds_sz.z *= focallengthf; // Premultiply the texture vectors with the scale factors + if (ds_powersoftwo) + { #define SFMULT 65536.f*(1< Date: Tue, 25 Jun 2019 14:41:07 -0300 Subject: [PATCH 11/13] Delete R_CropFlat --- src/r_data.c | 33 --------------------------------- src/r_data.h | 4 ---- 2 files changed, 37 deletions(-) diff --git a/src/r_data.c b/src/r_data.c index db92c11fe..0e44ec8c7 100644 --- a/src/r_data.c +++ b/src/r_data.c @@ -1770,36 +1770,3 @@ void R_FlatTexture(size_t tex, UINT8 *flat) } } } - -void R_CropFlat(UINT8 *srcflat, UINT8 *destflat, - UINT16 srcwidth, UINT16 srcheight, - UINT16 resizewidth, UINT16 resizeheight, - UINT16 destwidth, UINT16 destheight) -{ - 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 c528fcfe1..9af621142 100644 --- a/src/r_data.h +++ b/src/r_data.h @@ -103,10 +103,6 @@ boolean R_CheckIfPatch(lumpnum_t lump); void R_FlatPatch(patch_t *patch, UINT8 *flat); void R_FlatTexture(size_t tex, UINT8 *flat); -void R_CropFlat(UINT8 *srcflat, UINT8 *destflat, - UINT16 srcwidth, UINT16 srcheight, - UINT16 resizewidth, UINT16 resizeheight, - UINT16 destwidth, UINT16 destheight); extern INT32 numtextures; From 5047f4e7f08f10410f970ea50de745be7a73edb2 Mon Sep 17 00:00:00 2001 From: Jaime Passos Date: Tue, 25 Jun 2019 14:58:34 -0300 Subject: [PATCH 12/13] Fix slope flat offsets --- src/r_plane.c | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/src/r_plane.c b/src/r_plane.c index f79a5f90a..e982f41d6 100644 --- a/src/r_plane.c +++ b/src/r_plane.c @@ -972,6 +972,7 @@ void R_DrawSinglePlane(visplane_t *pl) if (ds_powersoftwo) { // But xoffs and yoffs are zero..... ???!?!?!???!?!?! + // (Except when flat alignment is involved) xoffs &= ((1 << (32-nflatshiftup))-1); yoffs &= ((1 << (32-nflatshiftup))-1); @@ -986,9 +987,10 @@ void R_DrawSinglePlane(visplane_t *pl) } else { - // The origin vector is a vertex from whatever linedef defined this slope - xoffs = -pl->slope->o.x; - yoffs = pl->slope->o.y; + // Whoops, this is actually incorrect behaviour. + // Keep xoffs and yoffs as they are if this flat has offsets + //xoffs = -pl->slope->o.x; + //yoffs = pl->slope->o.y; } vx = FIXED_TO_FLOAT(pl->viewx+xoffs); From afa6afa593d8aa721928c044e1c4f6f200649210 Mon Sep 17 00:00:00 2001 From: Jaime Passos Date: Fri, 28 Jun 2019 19:43:37 -0300 Subject: [PATCH 13/13] something something memory leaks --- src/r_data.c | 4 ++-- src/r_plane.c | 35 ++++++++++++++++++++++++----------- 2 files changed, 26 insertions(+), 13 deletions(-) diff --git a/src/r_data.c b/src/r_data.c index 9e9e70bc3..0e15c4689 100644 --- a/src/r_data.c +++ b/src/r_data.c @@ -1916,7 +1916,7 @@ static UINT8 *PNG_RawConvert(UINT8 *png, UINT16 *w, UINT16 *h, size_t size) return NULL; // Convert the image to 8bpp - flat = Z_Malloc(width * height, PU_STATIC, NULL); + flat = Z_Malloc(width * height, PU_LEVEL, NULL); memset(flat, TRANSPARENTPIXEL, width * height); for (y = 0; y < height; y++) { @@ -1944,7 +1944,7 @@ static UINT8 *PNG_GetAlphaMask(UINT8 *png, size_t size) return NULL; // Convert the image to 8bpp - mask = Z_Malloc(width * height, PU_STATIC, NULL); + mask = Z_Malloc(width * height, PU_LEVEL, NULL); memset(mask, 0, width * height); for (y = 0; y < height; y++) { diff --git a/src/r_plane.c b/src/r_plane.c index 1cbdc4b8b..4cfa4a49c 100644 --- a/src/r_plane.c +++ b/src/r_plane.c @@ -714,8 +714,9 @@ void R_CheckFlatLength(size_t size) } } -static void R_GetPatchFlat(levelflat_t *levelflat, boolean leveltexture, boolean ispng) +static UINT8 *R_GetPatchFlat(levelflat_t *levelflat, boolean leveltexture, boolean ispng) { + UINT8 *flat; textureflat_t *texflat = &texflats[levelflat->texturenum]; patch_t *patch = NULL; boolean texturechanged = (leveltexture ? (levelflat->texturenum != levelflat->lasttexturenum) : false); @@ -725,7 +726,7 @@ static void R_GetPatchFlat(levelflat_t *levelflat, boolean leveltexture, boolean { if (texflat != NULL && texflat->flat) { - ds_source = texflat->flat; + flat = texflat->flat; ds_flatwidth = texflat->width; ds_flatheight = texflat->height; texturechanged = false; @@ -746,8 +747,11 @@ static void R_GetPatchFlat(levelflat_t *levelflat, boolean leveltexture, boolean texflat->flat = Z_Malloc(ds_flatwidth * ds_flatheight, PU_LEVEL, NULL); memset(texflat->flat, TRANSPARENTPIXEL, ds_flatwidth * ds_flatheight); R_TextureToFlat(levelflat->texturenum, texflat->flat); + flat = texflat->flat; - ds_source = texflat->flat; + levelflat->flatpatch = flat; + levelflat->width = ds_flatwidth; + levelflat->height = ds_flatheight; } else { @@ -761,7 +765,7 @@ static void R_GetPatchFlat(levelflat_t *levelflat, boolean leveltexture, boolean if (levelflat->flatpatch == NULL) { lumpnum_t redflr = W_CheckNumForName("REDFLR"); - levelflat->flatpatch = (UINT8 *)W_CacheLumpNum(redflr, PU_STATIC); + levelflat->flatpatch = (UINT8 *)W_CacheLumpNum(redflr, PU_CACHE); R_CheckFlatLength(W_LumpLength(redflr)); R_CheckPowersOfTwo(); } @@ -785,12 +789,12 @@ static void R_GetPatchFlat(levelflat_t *levelflat, boolean leveltexture, boolean memset(levelflat->flatpatch, TRANSPARENTPIXEL, ds_flatwidth * ds_flatheight); R_PatchToFlat(patch, levelflat->flatpatch); } - ds_source = levelflat->flatpatch; + flat = levelflat->flatpatch; } } else { - ds_source = levelflat->flatpatch; + flat = levelflat->flatpatch; ds_flatwidth = levelflat->width; ds_flatheight = levelflat->height; @@ -799,10 +803,12 @@ static void R_GetPatchFlat(levelflat_t *levelflat, boolean leveltexture, boolean } levelflat->lasttexturenum = levelflat->texturenum; + return flat; } void R_DrawSinglePlane(visplane_t *pl) { + UINT8 *flat; INT32 light = 0; INT32 x; INT32 stop, angle; @@ -960,16 +966,25 @@ void R_DrawSinglePlane(visplane_t *pl) // Check if the flat is actually a wall texture. if (levelflat->texturenum != 0 && levelflat->texturenum != -1) - R_GetPatchFlat(levelflat, true, false); + flat = R_GetPatchFlat(levelflat, true, false); // Maybe it's just a patch, then? else if (R_CheckIfPatch(levelflat->lumpnum)) - R_GetPatchFlat(levelflat, false, false); + flat = R_GetPatchFlat(levelflat, false, false); // Maybe it's a PNG?! else if (R_IsLumpPNG(ds_source, size)) - R_GetPatchFlat(levelflat, false, true); + flat = R_GetPatchFlat(levelflat, false, true); // It's a raw flat. else + { R_CheckFlatLength(size); + flat = ds_source; + } + + Z_ChangeTag(ds_source, PU_CACHE); + ds_source = flat; + + if (ds_source == NULL) + return; // Check if the flat has dimensions that are powers-of-two numbers. if (R_CheckPowersOfTwo()) @@ -1202,8 +1217,6 @@ using the palette colors. } } #endif - - Z_ChangeTag(ds_source, PU_CACHE); } void R_PlaneBounds(visplane_t *plane)