From 714c997aace85b7f873fa0c1a97224cec691baeb Mon Sep 17 00:00:00 2001 From: Jaime Passos Date: Tue, 21 May 2019 00:28:52 -0300 Subject: [PATCH 01/51] 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/51] 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/51] 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/51] 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/51] 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/51] 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/51] 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/51] 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/51] 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/51] 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/51] 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/51] 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/51] 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) From 46993268aecf7b239441ffdd0612d6c02be33ded Mon Sep 17 00:00:00 2001 From: mazmazz Date: Sun, 4 Aug 2019 20:02:38 -0400 Subject: [PATCH 14/51] * Added FORCERESETMUSIC level header * cv_resetmusicbyheader toggle to disable said override * Never reset music during time attack * Change cv_resetmusic default back to off --- src/dehacked.c | 14 ++++++++++++++ src/doomstat.h | 2 ++ src/g_game.c | 2 +- src/lua_maplib.c | 2 ++ src/m_menu.c | 13 +++++++++++-- src/p_setup.c | 5 +++-- src/s_sound.c | 7 +++++-- src/s_sound.h | 9 +++++++++ 8 files changed, 47 insertions(+), 7 deletions(-) diff --git a/src/dehacked.c b/src/dehacked.c index 2f28a74cf..92b0ee841 100644 --- a/src/dehacked.c +++ b/src/dehacked.c @@ -1181,6 +1181,20 @@ static void readlevelheader(MYFILE *f, INT32 num) mapheaderinfo[num-1]->muspostbosspos = (UINT32)get_number(word2); else if (fastcmp(word, "MUSICPOSTBOSSFADEIN")) mapheaderinfo[num-1]->muspostbossfadein = (UINT32)get_number(word2); + else if (fastcmp(word, "FORCERESETMUSIC")) + { + // This is a weird one because "FALSE"/"NO" could either apply to "leave to default preference" (cv_resetmusic) + // or "force off". Let's assume it means "force off", and let an unspecified value mean "default preference" + if (fastcmp(word2, "OFF") || word2[0] == 'F' || word2[0] == 'N') i = 0; + else if (fastcmp(word2, "ON") || word2[0] == 'T' || word2[0] == 'Y') i = 1; + else i = -1; // (fastcmp(word2, "DEFAULT")) + + if (i >= -1 && i <= 1) // -1 to force off, 1 to force on, 0 to honor default. + // This behavior can be disabled with cv_resetmusicbyheader + mapheaderinfo[num-1]->musforcereset = (SINT8)i; + else + deh_warning("Level header %d: invalid forceresetmusic option %d", num, i); + } else if (fastcmp(word, "FORCECHARACTER")) { strlcpy(mapheaderinfo[num-1]->forcecharacter, word2, SKINNAMESIZE+1); diff --git a/src/doomstat.h b/src/doomstat.h index b6c376d1c..a70a122a6 100644 --- a/src/doomstat.h +++ b/src/doomstat.h @@ -333,6 +333,8 @@ typedef struct UINT32 muspostbosspos; ///< Post-bossdeath position UINT32 muspostbossfadein; ///< Post-bossdeath fade-in milliseconds. + SINT8 musforcereset; ///< Force resetmusic (-1 for default; 0 for force off; 1 for force on) + // Lua stuff. // (This is not ifdeffed so the map header structure can stay identical, just in case.) UINT8 numCustomOptions; ///< Internal. For Lua custom value support. diff --git a/src/g_game.c b/src/g_game.c index dad873fe7..3c623e7f1 100644 --- a/src/g_game.c +++ b/src/g_game.c @@ -2310,7 +2310,7 @@ void G_PlayerReborn(INT32 player) } // This is in S_Start, but this was not here previously. - // if (cv_resetmusic.value) + // if (RESETMUSIC) // S_StopMusic(); S_ChangeMusicEx(mapmusname, mapmusflags, true, mapmusposition, 0, 0); } diff --git a/src/lua_maplib.c b/src/lua_maplib.c index 74b259921..dbb69b7e2 100644 --- a/src/lua_maplib.c +++ b/src/lua_maplib.c @@ -2017,6 +2017,8 @@ static int mapheaderinfo_get(lua_State *L) lua_pushinteger(L, header->muspostbosspos); else if (fastcmp(field,"muspostbossfadein")) lua_pushinteger(L, header->muspostbossfadein); + else if (fastcmp(field,"musforcereset")) + lua_pushinteger(L, header->musforcereset); else if (fastcmp(field,"forcecharacter")) lua_pushstring(L, header->forcecharacter); else if (fastcmp(field,"weather")) diff --git a/src/m_menu.c b/src/m_menu.c index a3e986fdf..57ce6a3ca 100644 --- a/src/m_menu.c +++ b/src/m_menu.c @@ -1322,6 +1322,12 @@ static menuitem_t OP_SoundOptionsMenu[] = #define OPENMPT_MENUOFFSET 0 #endif +#ifdef HAVE_MIXERX +#define MIXERX_MENUOFFSET 81 +#else +#define MIXERX_MENUOFFSET 0 +#endif + static menuitem_t OP_SoundAdvancedMenu[] = { #ifdef HAVE_OPENMPT @@ -1333,12 +1339,15 @@ static menuitem_t OP_SoundAdvancedMenu[] = {IT_HEADER, NULL, "MIDI Settings", NULL, OPENMPT_MENUOFFSET+10}, {IT_STRING | IT_CVAR, NULL, "MIDI Player", &cv_midiplayer, OPENMPT_MENUOFFSET+22}, {IT_STRING | IT_CVAR | IT_CV_STRING, NULL, "FluidSynth Sound Font File", &cv_midisoundfontpath, OPENMPT_MENUOFFSET+34}, - {IT_STRING | IT_CVAR | IT_CV_STRING, NULL, "TiMidity++ Config Folder", &cv_miditimiditypath, OPENMPT_MENUOFFSET+61} + {IT_STRING | IT_CVAR | IT_CV_STRING, NULL, "TiMidity++ Config Folder", &cv_miditimiditypath, OPENMPT_MENUOFFSET+61}, #endif + + {IT_HEADER, NULL, "Miscellaneous", NULL, OPENMPT_MENUOFFSET+MIXERX_MENUOFFSET+10}, + {IT_STRING | IT_CVAR, NULL, "Let Levels Force Reset Music", &cv_resetmusicbyheader, OPENMPT_MENUOFFSET+MIXERX_MENUOFFSET+22}, }; #undef OPENMPT_MENUOFFSET - +#undef MIXERX_MENUOFFSET #endif static menuitem_t OP_DataOptionsMenu[] = diff --git a/src/p_setup.c b/src/p_setup.c index d0cd14b22..29f63f1bb 100644 --- a/src/p_setup.c +++ b/src/p_setup.c @@ -221,6 +221,7 @@ static void P_ClearSingleMapHeaderInfo(INT16 i) mapheaderinfo[num]->muspostbosstrack = 0; mapheaderinfo[num]->muspostbosspos = 0; mapheaderinfo[num]->muspostbossfadein = 0; + mapheaderinfo[num]->musforcereset = -1; mapheaderinfo[num]->forcecharacter[0] = '\0'; mapheaderinfo[num]->weather = 0; mapheaderinfo[num]->skynum = 1; @@ -2692,7 +2693,7 @@ boolean P_SetupLevel(boolean skipprecip) S_StartSound(NULL, sfx_s3kaf); // Fade music! Time it to S3KAF: 0.25 seconds is snappy. - if (cv_resetmusic.value || + if (RESETMUSIC || strnicmp(S_MusicName(), (mapmusflags & MUSIC_RELOADRESET) ? mapheaderinfo[gamemap-1]->musname : mapmusname, 7)) S_FadeOutStopMusic(MUSICRATE/4); //FixedMul(FixedDiv(F_GetWipeLength(wipedefs[wipe_speclevel_towhite])*NEWTICRATERATIO, NEWTICRATE), MUSICRATE) @@ -2725,7 +2726,7 @@ boolean P_SetupLevel(boolean skipprecip) // Fade out music here. Deduct 2 tics so the fade volume actually reaches 0. // But don't halt the music! S_Start will take care of that. This dodges a MIDI crash bug. - if (!titlemapinaction && (cv_resetmusic.value || + if (!titlemapinaction && (RESETMUSIC || strnicmp(S_MusicName(), (mapmusflags & MUSIC_RELOADRESET) ? mapheaderinfo[gamemap-1]->musname : mapmusname, 7))) S_FadeMusic(0, FixedMul( diff --git a/src/s_sound.c b/src/s_sound.c index 2c6faf041..bcb20833a 100644 --- a/src/s_sound.c +++ b/src/s_sound.c @@ -108,7 +108,9 @@ consvar_t cv_closedcaptioning = {"closedcaptioning", "Off", CV_SAVE|CV_CALL, CV_ consvar_t cv_numChannels = {"snd_channels", "32", CV_SAVE|CV_CALL, CV_Unsigned, SetChannelsNum, 0, NULL, NULL, 0, 0, NULL}; static consvar_t surround = {"surround", "Off", CV_SAVE, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL}; -consvar_t cv_resetmusic = {"resetmusic", "Yes", CV_SAVE, CV_YesNo, NULL, 0, NULL, NULL, 0, 0, NULL}; + +consvar_t cv_resetmusic = {"resetmusic", "Off", CV_SAVE, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL}; +consvar_t cv_resetmusicbyheader = {"resetmusicbyheader", "Yes", CV_SAVE, CV_YesNo, NULL, 0, NULL, NULL, 0, 0, NULL}; // Sound system toggles, saved into the config consvar_t cv_gamedigimusic = {"digimusic", "On", CV_SAVE|CV_CALL|CV_NOINIT, CV_OnOff, GameDigiMusic_OnChange, 0, NULL, NULL, 0, 0, NULL}; @@ -275,6 +277,7 @@ void S_RegisterSoundStuff(void) CV_RegisterVar(&surround); CV_RegisterVar(&cv_samplerate); CV_RegisterVar(&cv_resetmusic); + CV_RegisterVar(&cv_resetmusicbyheader); CV_RegisterVar(&cv_gamesounds); CV_RegisterVar(&cv_gamedigimusic); CV_RegisterVar(&cv_gamemidimusic); @@ -2096,7 +2099,7 @@ void S_StartEx(boolean reset) mapmusposition = mapheaderinfo[gamemap-1]->muspos; } - if (cv_resetmusic.value || reset) + if (RESETMUSIC || reset) S_StopMusic(); S_ChangeMusicEx(mapmusname, mapmusflags, true, mapmusposition, 0, 0); diff --git a/src/s_sound.h b/src/s_sound.h index e0737eff7..48128527c 100644 --- a/src/s_sound.h +++ b/src/s_sound.h @@ -31,7 +31,16 @@ openmpt_module *openmpt_mhandle; extern consvar_t stereoreverse; extern consvar_t cv_soundvolume, cv_closedcaptioning, cv_digmusicvolume, cv_midimusicvolume; extern consvar_t cv_numChannels; + extern consvar_t cv_resetmusic; +extern consvar_t cv_resetmusicbyheader; + +#define RESETMUSIC (!modeattacking && \ + (cv_resetmusicbyheader.value ? \ + (mapheaderinfo[gamemap-1]->musforcereset != -1 ? mapheaderinfo[gamemap-1]->musforcereset : cv_resetmusic.value) \ + : cv_resetmusic.value) \ + ) + extern consvar_t cv_gamedigimusic; extern consvar_t cv_gamemidimusic; extern consvar_t cv_gamesounds; From 1f2baf5b6bad77edf176c2a4e9115bb0c70cd0bb Mon Sep 17 00:00:00 2001 From: toaster Date: Thu, 22 Aug 2019 22:30:36 +0100 Subject: [PATCH 15/51] Make polyobjects agree with sector lighting/colormap like a FOF. Caution: has weird retry/reload bug. Ask sphere for sample map/coords. --- src/hardware/hw_main.c | 19 ++++++++++++------- src/r_bsp.c | 10 +++++----- 2 files changed, 17 insertions(+), 12 deletions(-) diff --git a/src/hardware/hw_main.c b/src/hardware/hw_main.c index c600800fd..c6a8b16e5 100644 --- a/src/hardware/hw_main.c +++ b/src/hardware/hw_main.c @@ -3333,6 +3333,7 @@ static void HWR_AddPolyObjectPlanes(void) { size_t i; sector_t *polyobjsector; + INT32 light = 0; // Polyobject Planes need their own function for drawing because they don't have extrasubsectors by themselves // It should be okay because polyobjects should always be convex anyway @@ -3351,19 +3352,22 @@ static void HWR_AddPolyObjectPlanes(void) && polyobjsector->floorheight >= gr_frontsector->floorheight && (viewz < polyobjsector->floorheight)) { + light = R_GetPlaneLight(gr_frontsector, polyobjsector->floorheight, true); if (po_ptrs[i]->translucency > 0) { FSurfaceInfo Surf; - FBITFIELD blendmode = HWR_TranstableToAlpha(po_ptrs[i]->translucency, &Surf); + FBITFIELD blendmode; + memset(&Surf, 0x00, sizeof(Surf)); + blendmode = HWR_TranstableToAlpha(po_ptrs[i]->translucency, &Surf); HWR_AddTransparentPolyobjectFloor(levelflats[polyobjsector->floorpic].lumpnum, po_ptrs[i], false, polyobjsector->floorheight, - polyobjsector->lightlevel, Surf.FlatColor.s.alpha, polyobjsector, blendmode, NULL); + (light == -1 ? gr_frontsector->lightlevel : *gr_frontsector->lightlist[light].lightlevel), Surf.FlatColor.s.alpha, polyobjsector, blendmode, (light == -1 ? gr_frontsector->extra_colormap : *gr_frontsector->lightlist[light].extra_colormap)); } else { HWR_GetFlat(levelflats[polyobjsector->floorpic].lumpnum); HWR_RenderPolyObjectPlane(po_ptrs[i], false, polyobjsector->floorheight, PF_Occlude, - polyobjsector->lightlevel, levelflats[polyobjsector->floorpic].lumpnum, - polyobjsector, 255, NULL); + (light == -1 ? gr_frontsector->lightlevel : *gr_frontsector->lightlist[light].lightlevel), levelflats[polyobjsector->floorpic].lumpnum, + polyobjsector, 255, (light == -1 ? gr_frontsector->extra_colormap : *gr_frontsector->lightlist[light].extra_colormap)); } } @@ -3371,6 +3375,7 @@ static void HWR_AddPolyObjectPlanes(void) && polyobjsector->ceilingheight <= gr_frontsector->ceilingheight && (viewz > polyobjsector->ceilingheight)) { + light = R_GetPlaneLight(gr_frontsector, polyobjsector->ceilingheight, true); if (po_ptrs[i]->translucency > 0) { FSurfaceInfo Surf; @@ -3378,14 +3383,14 @@ static void HWR_AddPolyObjectPlanes(void) 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, - polyobjsector->lightlevel, Surf.FlatColor.s.alpha, polyobjsector, blendmode, NULL); + (light == -1 ? gr_frontsector->lightlevel : *gr_frontsector->lightlist[light].lightlevel), Surf.FlatColor.s.alpha, polyobjsector, blendmode, (light == -1 ? gr_frontsector->extra_colormap : *gr_frontsector->lightlist[light].extra_colormap)); } else { HWR_GetFlat(levelflats[polyobjsector->ceilingpic].lumpnum); HWR_RenderPolyObjectPlane(po_ptrs[i], true, polyobjsector->ceilingheight, PF_Occlude, - polyobjsector->lightlevel, levelflats[polyobjsector->floorpic].lumpnum, - polyobjsector, 255, NULL); + (light == -1 ? gr_frontsector->lightlevel : *gr_frontsector->lightlist[light].lightlevel), levelflats[polyobjsector->floorpic].lumpnum, + polyobjsector, 255, (light == -1 ? gr_frontsector->extra_colormap : *gr_frontsector->lightlist[light].extra_colormap)); } } } diff --git a/src/r_bsp.c b/src/r_bsp.c index d521d9f4d..23e751420 100644 --- a/src/r_bsp.c +++ b/src/r_bsp.c @@ -1088,9 +1088,9 @@ static void R_Subsector(size_t num) { light = R_GetPlaneLight(frontsector, polysec->floorheight, viewz < polysec->floorheight); ffloor[numffloors].plane = R_FindPlane(polysec->floorheight, polysec->floorpic, - polysec->lightlevel, polysec->floor_xoffs, polysec->floor_yoffs, + (light == -1 ? frontsector->lightlevel : *frontsector->lightlist[light].lightlevel), polysec->floor_xoffs, polysec->floor_yoffs, polysec->floorpic_angle-po->angle, - NULL, NULL, po + (light == -1 ? frontsector->extra_colormap : *frontsector->lightlist[light].extra_colormap), NULL, po #ifdef ESLOPE , NULL // will ffloors be slopable eventually? #endif @@ -1115,10 +1115,10 @@ static void R_Subsector(size_t num) && polysec->ceilingheight <= ceilingcenterz && (viewz > polysec->ceilingheight)) { - light = R_GetPlaneLight(frontsector, polysec->ceilingheight, viewz < polysec->ceilingheight); + light = R_GetPlaneLight(frontsector, polysec->floorheight, viewz < polysec->floorheight); ffloor[numffloors].plane = R_FindPlane(polysec->ceilingheight, polysec->ceilingpic, - polysec->lightlevel, polysec->ceiling_xoffs, polysec->ceiling_yoffs, polysec->ceilingpic_angle-po->angle, - NULL, NULL, po + (light == -1 ? frontsector->lightlevel : *frontsector->lightlist[light].lightlevel), polysec->ceiling_xoffs, polysec->ceiling_yoffs, polysec->ceilingpic_angle-po->angle, + (light == -1 ? frontsector->extra_colormap : *frontsector->lightlist[light].extra_colormap), NULL, po #ifdef ESLOPE , NULL // will ffloors be slopable eventually? #endif From fbec4af086956df517ed631220d16778f9dfa425 Mon Sep 17 00:00:00 2001 From: Steel Titanium Date: Sat, 24 Aug 2019 17:17:55 -0400 Subject: [PATCH 16/51] Fallback graphic for firework display, if the character lacks one. --- src/f_finale.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/f_finale.c b/src/f_finale.c index da042abeb..056b7f815 100644 --- a/src/f_finale.c +++ b/src/f_finale.c @@ -1595,11 +1595,11 @@ void F_StartEnding(void) sprframe = &sprdef->spriteframes[4]; endfwrk[2] = W_CachePatchNum(sprframe->lumppat[0], PU_LEVEL); } - else // eh, yknow what? too lazy to put MISSINGs here. eggman wins if you don't give your character an ending firework display. + else // Show a star if your character doesn't have an ending firework display. (Basically the MISSINGs for this) { - endfwrk[0] = W_CachePatchName("ENDFWRK0", PU_LEVEL); - endfwrk[1] = W_CachePatchName("ENDFWRK1", PU_LEVEL); - endfwrk[2] = W_CachePatchName("ENDFWRK2", PU_LEVEL); + endfwrk[0] = W_CachePatchName("ENDFWRK3", PU_LEVEL); + endfwrk[1] = W_CachePatchName("ENDFWRK4", PU_LEVEL); + endfwrk[2] = W_CachePatchName("ENDFWRK5", PU_LEVEL); } endbrdr[0] = W_CachePatchName("ENDBRDR2", PU_LEVEL); From 141631220028cba50baa5fb15dd8c6f25ccff86c Mon Sep 17 00:00:00 2001 From: Steel Titanium Date: Mon, 26 Aug 2019 20:38:32 -0400 Subject: [PATCH 17/51] Move some cvars out of D_ClientServerInit and save them Ported over from Kart --- src/d_clisrv.c | 15 +++++---------- src/d_clisrv.h | 1 + src/d_netcmd.c | 7 +++++++ 3 files changed, 13 insertions(+), 10 deletions(-) diff --git a/src/d_clisrv.c b/src/d_clisrv.c index 556d86384..aaca4a84f 100644 --- a/src/d_clisrv.c +++ b/src/d_clisrv.c @@ -152,7 +152,7 @@ ticcmd_t netcmds[BACKUPTICS][MAXPLAYERS]; static textcmdtic_t *textcmds[TEXTCMD_HASH_SIZE] = {NULL}; -static consvar_t cv_showjoinaddress = {"showjoinaddress", "On", 0, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL}; +consvar_t cv_showjoinaddress = {"showjoinaddress", "On", CV_SAVE, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL}; static CV_PossibleValue_t playbackspeed_cons_t[] = {{1, "MIN"}, {10, "MAX"}, {0, NULL}}; consvar_t cv_playbackspeed = {"playbackspeed", "1", 0, playbackspeed_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL}; @@ -2938,13 +2938,13 @@ static void Got_KickCmd(UINT8 **p, INT32 playernum) CL_RemovePlayer(pnum, kickreason); } -consvar_t cv_allownewplayer = {"allowjoin", "On", CV_NETVAR, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL }; -consvar_t cv_joinnextround = {"joinnextround", "Off", CV_NETVAR, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL}; /// \todo not done +consvar_t cv_allownewplayer = {"allowjoin", "On", CV_SAVE|CV_NETVAR, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL }; +consvar_t cv_joinnextround = {"joinnextround", "Off", CV_SAVE|CV_NETVAR, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL}; /// \todo not done static CV_PossibleValue_t maxplayers_cons_t[] = {{2, "MIN"}, {32, "MAX"}, {0, NULL}}; consvar_t cv_maxplayers = {"maxplayers", "8", CV_SAVE, maxplayers_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL}; static CV_PossibleValue_t resynchattempts_cons_t[] = {{0, "MIN"}, {20, "MAX"}, {0, NULL}}; -consvar_t cv_resynchattempts = {"resynchattempts", "10", 0, resynchattempts_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL }; -consvar_t cv_blamecfail = {"blamecfail", "Off", 0, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL }; +consvar_t cv_resynchattempts = {"resynchattempts", "10", CV_SAVE, resynchattempts_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL }; +consvar_t cv_blamecfail = {"blamecfail", "Off", CV_SAVE, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL }; // max file size to send to a player (in kilobytes) static CV_PossibleValue_t maxsend_cons_t[] = {{0, "MIN"}, {51200, "MAX"}, {0, NULL}}; @@ -2985,11 +2985,6 @@ void D_ClientServerInit(void) RegisterNetXCmd(XD_KICK, Got_KickCmd); RegisterNetXCmd(XD_ADDPLAYER, Got_AddPlayer); #ifndef NONET - CV_RegisterVar(&cv_allownewplayer); - CV_RegisterVar(&cv_joinnextround); - CV_RegisterVar(&cv_showjoinaddress); - CV_RegisterVar(&cv_resynchattempts); - CV_RegisterVar(&cv_blamecfail); #ifdef DUMPCONSISTENCY CV_RegisterVar(&cv_dumpconsistency); #endif diff --git a/src/d_clisrv.h b/src/d_clisrv.h index a6783fb3d..cfa58aad7 100644 --- a/src/d_clisrv.h +++ b/src/d_clisrv.h @@ -441,6 +441,7 @@ extern INT32 mapchangepending; // Points inside doomcom extern doomdata_t *netbuffer; +extern consvar_t cv_showjoinaddress; extern consvar_t cv_playbackspeed; #define BASEPACKETSIZE offsetof(doomdata_t, u) diff --git a/src/d_netcmd.c b/src/d_netcmd.c index 3e82fc60c..63ad35355 100644 --- a/src/d_netcmd.c +++ b/src/d_netcmd.c @@ -556,9 +556,16 @@ void D_RegisterServerCommands(void) // d_clisrv CV_RegisterVar(&cv_maxplayers); + CV_RegisterVar(&cv_resynchattempts); CV_RegisterVar(&cv_maxsend); CV_RegisterVar(&cv_noticedownload); CV_RegisterVar(&cv_downloadspeed); +#ifndef NONET + CV_RegisterVar(&cv_allownewplayer); + CV_RegisterVar(&cv_joinnextround); + CV_RegisterVar(&cv_showjoinaddress); + CV_RegisterVar(&cv_blamecfail); +#endif COM_AddCommand("ping", Command_Ping_f); CV_RegisterVar(&cv_nettimeout); From b2712af2d07e0f4b68fcc9700e77b0837bece817 Mon Sep 17 00:00:00 2001 From: Steel Titanium Date: Mon, 26 Aug 2019 21:49:12 -0400 Subject: [PATCH 18/51] Reorder the main multiplayer menu --- src/m_menu.c | 28 ++++++++++++---------------- 1 file changed, 12 insertions(+), 16 deletions(-) diff --git a/src/m_menu.c b/src/m_menu.c index 128b15a76..63b372810 100644 --- a/src/m_menu.c +++ b/src/m_menu.c @@ -884,12 +884,12 @@ static menuitem_t MP_SplitServerMenu[] = static menuitem_t MP_MainMenu[] = { - {IT_HEADER, NULL, "Host a game", NULL, 0}, - {IT_STRING|IT_CALL, NULL, "Internet/LAN...", M_StartServerMenu, 12}, - {IT_STRING|IT_CALL, NULL, "Splitscreen...", M_StartSplitServerMenu, 22}, - {IT_HEADER, NULL, "Join a game", NULL, 40}, - {IT_STRING|IT_CALL, NULL, "Server browser...", M_ConnectMenu, 52}, - {IT_STRING|IT_KEYHANDLER, NULL, "Specify IPv4 address:", M_HandleConnectIP, 62}, + {IT_HEADER, NULL, "Join a game", NULL, 0}, + {IT_STRING|IT_CALL, NULL, "Server browser...", M_ConnectMenu, 12}, + {IT_STRING|IT_KEYHANDLER, NULL, "Specify IPv4 address:", M_HandleConnectIP, 22}, + {IT_HEADER, NULL, "Host a game", NULL, 54}, + {IT_STRING|IT_CALL, NULL, "Internet/LAN...", M_StartServerMenu, 66}, + {IT_STRING|IT_CALL, NULL, "Splitscreen...", M_StartSplitServerMenu, 76}, {IT_HEADER, NULL, "Player setup", NULL, 94}, {IT_STRING|IT_CALL, NULL, "Player 1...", M_SetupMultiPlayer, 106}, {IT_STRING|IT_CALL, NULL, "Player 2... ", M_SetupMultiPlayer2, 116}, @@ -9259,20 +9259,16 @@ static void M_DrawMPMainMenu(void) // use generic drawer for cursor, items and title M_DrawGenericMenu(); -#if MAXPLAYERS == 32 - V_DrawRightAlignedString(BASEVIDWIDTH-x, y+12, - ((itemOn == 1) ? V_YELLOWMAP : 0), "(2-32 players)"); -#else -Update the maxplayers label... -#endif + V_DrawRightAlignedString(BASEVIDWIDTH-x, y+66, + ((itemOn == 4) ? V_YELLOWMAP : 0), va("(2-%d players)", MAXPLAYERS)); - V_DrawRightAlignedString(BASEVIDWIDTH-x, y+22, - ((itemOn == 2) ? V_YELLOWMAP : 0), "(2 players)"); + V_DrawRightAlignedString(BASEVIDWIDTH-x, y+76, + ((itemOn == 5) ? V_YELLOWMAP : 0), "(2 players)"); V_DrawRightAlignedString(BASEVIDWIDTH-x, y+116, ((itemOn == 8) ? V_YELLOWMAP : 0), "(splitscreen)"); - y += 62; + y += 22; V_DrawFill(x+5, y+4+5, /*16*8 + 6,*/ BASEVIDWIDTH - 2*(x+5), 8+6, 159); @@ -9280,7 +9276,7 @@ Update the maxplayers label... V_DrawString(x+8,y+12, V_MONOSPACE, setupm_ip); // draw text cursor for name - if (itemOn == 5 //0 + if (itemOn == 2 //0 && skullAnimCounter < 4) //blink cursor V_DrawCharacter(x+8+V_StringWidth(setupm_ip, V_MONOSPACE),y+12,'_',false); } From a98862b3ed72e1f353c6d8d40d730f35d6fdb88e Mon Sep 17 00:00:00 2001 From: Steel Titanium Date: Mon, 26 Aug 2019 22:00:07 -0400 Subject: [PATCH 19/51] Allow letters to be used on ipv4 address field --- src/m_menu.c | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/src/m_menu.c b/src/m_menu.c index 63b372810..586a85629 100644 --- a/src/m_menu.c +++ b/src/m_menu.c @@ -9247,7 +9247,7 @@ static void M_StartServerMenu(INT32 choice) // CONNECT VIA IP // ============== -static char setupm_ip[16]; +static char setupm_ip[28]; // Draw the funky Connect IP menu. Tails 11-19-2002 // So much work for such a little thing! @@ -9273,12 +9273,12 @@ static void M_DrawMPMainMenu(void) V_DrawFill(x+5, y+4+5, /*16*8 + 6,*/ BASEVIDWIDTH - 2*(x+5), 8+6, 159); // draw name string - V_DrawString(x+8,y+12, V_MONOSPACE, setupm_ip); + V_DrawString(x+8,y+12, V_ALLOWLOWERCASE, setupm_ip); // draw text cursor for name if (itemOn == 2 //0 && skullAnimCounter < 4) //blink cursor - V_DrawCharacter(x+8+V_StringWidth(setupm_ip, V_MONOSPACE),y+12,'_',false); + V_DrawCharacter(x+8+V_StringWidth(setupm_ip, V_ALLOWLOWERCASE),y+12,'_',false); } // Tails 11-19-2002 @@ -9349,10 +9349,11 @@ static void M_HandleConnectIP(INT32 choice) default: l = strlen(setupm_ip); - if (l >= 16-1) + if (l >= 28-1) break; - if (choice == 46 || (choice >= 48 && choice <= 57)) // Rudimentary number and period enforcing + // Rudimentary number and period enforcing - also allows letters so hostnames can be used instead + if ((choice >= '-' && choice <= ':') || (choice >= 'A' && choice <= 'Z') || (choice >= 'a' && choice <= 'z')) { S_StartSound(NULL,sfx_menu1); // Tails setupm_ip[l] = (char)choice; From b4d81266750d8389b060f8f506dcfecaa0404eea Mon Sep 17 00:00:00 2001 From: Steel Titanium Date: Tue, 27 Aug 2019 18:05:30 -0400 Subject: [PATCH 20/51] Rename offline mode to private mode --- src/m_menu.c | 26 +++++++++++++++++++++----- 1 file changed, 21 insertions(+), 5 deletions(-) diff --git a/src/m_menu.c b/src/m_menu.c index 586a85629..926e74438 100644 --- a/src/m_menu.c +++ b/src/m_menu.c @@ -948,7 +948,7 @@ enum static menuitem_t MP_RoomMenu[] = { - {IT_STRING | IT_CALL, NULL, "", M_ChooseRoom, 9}, + {IT_STRING | IT_CALL, NULL, "", M_ChooseRoom, 9}, {IT_DISABLED, NULL, "", M_ChooseRoom, 18}, {IT_DISABLED, NULL, "", M_ChooseRoom, 27}, {IT_DISABLED, NULL, "", M_ChooseRoom, 36}, @@ -8872,7 +8872,7 @@ static void M_DrawConnectMenu(void) // Room name if (ms_RoomId < 0) V_DrawRightAlignedString(BASEVIDWIDTH - currentMenu->x, currentMenu->y + MP_ConnectMenu[mp_connect_room].alphaKey, - V_YELLOWMAP, (itemOn == mp_connect_room) ? "" : ""); else V_DrawRightAlignedString(BASEVIDWIDTH - currentMenu->x, currentMenu->y + MP_ConnectMenu[mp_connect_room].alphaKey, V_YELLOWMAP, room_list[menuRoomIndex].name); @@ -9022,7 +9022,14 @@ static void M_ConnectMenu(INT32 choice) // first page of servers serverlistpage = 0; - M_SetupNextMenu(&MP_ConnectDef); + if (ms_RoomId < 0) + { + M_RoomMenu(0); // Select a room instead of staring at an empty list + // This prevents us from returning to the modified game alert. + currentMenu->prevMenu = &MP_MainDef; + } + else + M_SetupNextMenu(&MP_ConnectDef); itemOn = 0; M_Refresh(0); } @@ -9081,7 +9088,16 @@ static void M_ChooseRoom(INT32 choice) } serverlistpage = 0; - M_SetupNextMenu(currentMenu->prevMenu); + /* + We were on the Multiplayer menu? That means that we must have been trying to + view the server browser, but we hadn't selected a room yet. So we need to go + to the browser next, not back there. + */ + if (currentMenu->prevMenu == &MP_MainDef) + M_SetupNextMenu(&MP_ConnectDef); + else + M_SetupNextMenu(currentMenu->prevMenu); + if (currentMenu == &MP_ConnectDef) M_Refresh(0); } @@ -9140,7 +9156,7 @@ static void M_DrawServerMenu(void) M_DrawLevelPlatterHeader(currentMenu->y - lsheadingheight/2, "Server settings", true, false); if (ms_RoomId < 0) V_DrawRightAlignedString(BASEVIDWIDTH - currentMenu->x, currentMenu->y + MP_ServerMenu[mp_server_room].alphaKey, - V_YELLOWMAP, (itemOn == mp_server_room) ? "" : ""); else V_DrawRightAlignedString(BASEVIDWIDTH - currentMenu->x, currentMenu->y + MP_ServerMenu[mp_server_room].alphaKey, V_YELLOWMAP, room_list[menuRoomIndex].name); From 7e47117afa7802e12e6716ac25098c1507e69223 Mon Sep 17 00:00:00 2001 From: Steel Titanium Date: Wed, 28 Aug 2019 20:24:30 -0400 Subject: [PATCH 21/51] Add warning message when attempting to use the master server browser while `modifiedgame` is true. --- src/m_menu.c | 19 +++++++++++++++++-- 1 file changed, 17 insertions(+), 2 deletions(-) diff --git a/src/m_menu.c b/src/m_menu.c index 926e74438..e29568536 100644 --- a/src/m_menu.c +++ b/src/m_menu.c @@ -265,6 +265,7 @@ static void M_ServerOptions(INT32 choice); #ifndef NONET static void M_StartServerMenu(INT32 choice); static void M_ConnectMenu(INT32 choice); +static void M_ConnectMenuModChecks(INT32 choice); static void M_Refresh(INT32 choice); static void M_Connect(INT32 choice); static void M_ChooseRoom(INT32 choice); @@ -885,7 +886,7 @@ static menuitem_t MP_SplitServerMenu[] = static menuitem_t MP_MainMenu[] = { {IT_HEADER, NULL, "Join a game", NULL, 0}, - {IT_STRING|IT_CALL, NULL, "Server browser...", M_ConnectMenu, 12}, + {IT_STRING|IT_CALL, NULL, "Server browser...", M_ConnectMenuModChecks, 12}, {IT_STRING|IT_KEYHANDLER, NULL, "Specify IPv4 address:", M_HandleConnectIP, 22}, {IT_HEADER, NULL, "Host a game", NULL, 54}, {IT_STRING|IT_CALL, NULL, "Internet/LAN...", M_StartServerMenu, 66}, @@ -5603,7 +5604,7 @@ static boolean M_AddonsRefresh(void) { S_StartSound(NULL, sfx_lose); if (refreshdirmenu & REFRESHDIR_MAX) - message = va("%c%s\x80\nMaximum number of add-ons reached.\nA file could not be loaded.\nIf you want to play with this add-on, restart the game to clear existing ones.\n\n(Press a key)\n", ('\x80' + (highlightflags>>V_CHARCOLORSHIFT)), refreshdirname); + message = va("%c%s\x80\nMaximum number of add-ons reached.\nA file could not be loaded.\nif you wish to play with this add-on, restart the game to clear existing ones.\n\n(Press a key)\n", ('\x80' + (highlightflags>>V_CHARCOLORSHIFT)), refreshdirname); else message = va("%c%s\x80\nA file was not loaded.\nCheck the console log for more information.\n\n(Press a key)\n", ('\x80' + (highlightflags>>V_CHARCOLORSHIFT)), refreshdirname); } @@ -9034,6 +9035,20 @@ static void M_ConnectMenu(INT32 choice) M_Refresh(0); } +static void M_ConnectMenuModChecks(INT32 choice) +{ + (void)choice; + // okay never mind we want to COMMUNICATE to the player pre-emptively instead of letting them try and then get confused when it doesn't work + + if (modifiedgame) + { + M_StartMessage(M_GetText("Add-ons are currently loaded.\n\nYou will only be able to join a server if\nit has the same ones loaded in the same order, which may be unlikely.\n\nIf you wish to play on other servers,\nrestart the game to clear existing add-ons.\n\n(Press a key)\n"),M_ConnectMenu,MM_EVENTHANDLER); + return; + } + + M_ConnectMenu(-1); +} + static UINT32 roomIds[NUM_LIST_ROOMS]; static void M_RoomMenu(INT32 choice) From 8655b8f1f15f0b138d9c85af07a6f1b4a7a4dff1 Mon Sep 17 00:00:00 2001 From: Steel Titanium Date: Thu, 29 Aug 2019 01:57:58 -0400 Subject: [PATCH 22/51] Add spawn object linedef special. Note that spawning a object within a random range does not fully work yet and crashes the game --- src/p_setup.c | 1 + src/p_spec.c | 21 +++++++++++++++++++++ 2 files changed, 22 insertions(+) diff --git a/src/p_setup.c b/src/p_setup.c index d0cd14b22..65335be3f 100644 --- a/src/p_setup.c +++ b/src/p_setup.c @@ -1480,6 +1480,7 @@ static void P_LoadRawSideDefs2(void *data) case 425: // Calls P_SetMobjState on calling mobj case 434: // Custom Power case 442: // Calls P_SetMobjState on mobjs of a given type in the tagged sectors + case 461: // Spawns an object on the map based on texture offsets { char process[8*3+1]; memset(process,0,8*3+1); diff --git a/src/p_spec.c b/src/p_spec.c index 37a1652f0..325f5ebe7 100644 --- a/src/p_spec.c +++ b/src/p_spec.c @@ -3953,6 +3953,27 @@ static void P_ProcessLineSpecial(line_t *line, mobj_t *mo, sector_t *callsec) } break; + case 461: // Spawns an object on the map based on texture offsets + { + const mobjtype_t type = (mobjtype_t)(sides[line->sidenum[0]].toptexture); + + fixed_t x, y, z; + x = sides[line->sidenum[0]].textureoffset; + y = sides[line->sidenum[0]].rowoffset; + z = line->frontsector->floorheight; + + if (line->flags & ML_NOCLIMB) // If noclimb is set, spawn randomly within a range + { + x = P_RandomRange(sides[line->sidenum[0]].textureoffset, sides[line->sidenum[1]].textureoffset); + y = P_RandomRange(sides[line->sidenum[0]].rowoffset, sides[line->sidenum[1]].rowoffset); + z = P_RandomRange(line->frontsector->floorheight, line->frontsector->ceilingheight); + } + + CONS_Printf("mobjtype_t: %d\n", type); + P_SpawnMobj(x, y, z, type); + } + break; + #ifdef POLYOBJECTS case 480: // Polyobj_DoorSlide case 481: // Polyobj_DoorSwing From 10ea0f21ae3b61b2584b599adab57a5b65b29c82 Mon Sep 17 00:00:00 2001 From: Steel Titanium Date: Thu, 29 Aug 2019 23:56:15 -0400 Subject: [PATCH 23/51] Fix spawning within random range --- src/p_spec.c | 21 ++++++++++++++++----- 1 file changed, 16 insertions(+), 5 deletions(-) diff --git a/src/p_spec.c b/src/p_spec.c index 325f5ebe7..014a09845 100644 --- a/src/p_spec.c +++ b/src/p_spec.c @@ -3964,13 +3964,24 @@ static void P_ProcessLineSpecial(line_t *line, mobj_t *mo, sector_t *callsec) if (line->flags & ML_NOCLIMB) // If noclimb is set, spawn randomly within a range { - x = P_RandomRange(sides[line->sidenum[0]].textureoffset, sides[line->sidenum[1]].textureoffset); - y = P_RandomRange(sides[line->sidenum[0]].rowoffset, sides[line->sidenum[1]].rowoffset); - z = P_RandomRange(line->frontsector->floorheight, line->frontsector->ceilingheight); + if (line->sidenum[1] != 0xffff) // Make sure the linedef has a back side + { + x = P_RandomRange(sides[line->sidenum[0]].textureoffset>>FRACBITS, sides[line->sidenum[1]].textureoffset>>FRACBITS)<sidenum[0]].rowoffset>>FRACBITS, sides[line->sidenum[1]].rowoffset>>FRACBITS)<frontsector->floorheight>>FRACBITS, line->frontsector->ceilingheight>>FRACBITS)<special); + break; + } } - CONS_Printf("mobjtype_t: %d\n", type); - P_SpawnMobj(x, y, z, type); + mobj_t *mobj = P_SpawnMobj(x, y, z, type); + if (mobj) + CONS_Debug(DBG_GAMELOGIC, "Linedef Type %d - Spawn Object: %d spawned at (%d, %d, %d)\n", line->special, mobj->type, mobj->x>>FRACBITS, mobj->y>>FRACBITS, mobj->z>>FRACBITS); //TODO: Convert mobj->type to a string somehow. + else + CONS_Alert(CONS_ERROR,"Linedef Type %d - Spawn Object: Object did not spawn!\n", line->special); } break; From 5c295d285b5c52a12e9cabc5bb23a33ec41ea15b Mon Sep 17 00:00:00 2001 From: Steel Titanium Date: Fri, 30 Aug 2019 00:36:10 -0400 Subject: [PATCH 24/51] Capitalize the 'if' --- src/m_menu.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/m_menu.c b/src/m_menu.c index e29568536..e71877d53 100644 --- a/src/m_menu.c +++ b/src/m_menu.c @@ -5604,7 +5604,7 @@ static boolean M_AddonsRefresh(void) { S_StartSound(NULL, sfx_lose); if (refreshdirmenu & REFRESHDIR_MAX) - message = va("%c%s\x80\nMaximum number of add-ons reached.\nA file could not be loaded.\nif you wish to play with this add-on, restart the game to clear existing ones.\n\n(Press a key)\n", ('\x80' + (highlightflags>>V_CHARCOLORSHIFT)), refreshdirname); + message = va("%c%s\x80\nMaximum number of add-ons reached.\nA file could not be loaded.\nIf you wish to play with this add-on, restart the game to clear existing ones.\n\n(Press a key)\n", ('\x80' + (highlightflags>>V_CHARCOLORSHIFT)), refreshdirname); else message = va("%c%s\x80\nA file was not loaded.\nCheck the console log for more information.\n\n(Press a key)\n", ('\x80' + (highlightflags>>V_CHARCOLORSHIFT)), refreshdirname); } From 8167a88becac105af29808d1f25f52f19095e00d Mon Sep 17 00:00:00 2001 From: Steel Titanium Date: Fri, 30 Aug 2019 00:38:58 -0400 Subject: [PATCH 25/51] Rename private mode to unlisted mode --- src/m_menu.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/m_menu.c b/src/m_menu.c index e71877d53..5f5e987bd 100644 --- a/src/m_menu.c +++ b/src/m_menu.c @@ -949,7 +949,7 @@ enum static menuitem_t MP_RoomMenu[] = { - {IT_STRING | IT_CALL, NULL, "", M_ChooseRoom, 9}, + {IT_STRING | IT_CALL, NULL, "", M_ChooseRoom, 9}, {IT_DISABLED, NULL, "", M_ChooseRoom, 18}, {IT_DISABLED, NULL, "", M_ChooseRoom, 27}, {IT_DISABLED, NULL, "", M_ChooseRoom, 36}, @@ -8873,7 +8873,7 @@ static void M_DrawConnectMenu(void) // Room name if (ms_RoomId < 0) V_DrawRightAlignedString(BASEVIDWIDTH - currentMenu->x, currentMenu->y + MP_ConnectMenu[mp_connect_room].alphaKey, - V_YELLOWMAP, (itemOn == mp_connect_room) ? "" : ""); else V_DrawRightAlignedString(BASEVIDWIDTH - currentMenu->x, currentMenu->y + MP_ConnectMenu[mp_connect_room].alphaKey, V_YELLOWMAP, room_list[menuRoomIndex].name); @@ -9171,7 +9171,7 @@ static void M_DrawServerMenu(void) M_DrawLevelPlatterHeader(currentMenu->y - lsheadingheight/2, "Server settings", true, false); if (ms_RoomId < 0) V_DrawRightAlignedString(BASEVIDWIDTH - currentMenu->x, currentMenu->y + MP_ServerMenu[mp_server_room].alphaKey, - V_YELLOWMAP, (itemOn == mp_server_room) ? "" : ""); else V_DrawRightAlignedString(BASEVIDWIDTH - currentMenu->x, currentMenu->y + MP_ServerMenu[mp_server_room].alphaKey, V_YELLOWMAP, room_list[menuRoomIndex].name); From 6a9da63d7f2429492028d72fba08444c1060bd80 Mon Sep 17 00:00:00 2001 From: toaster Date: Fri, 30 Aug 2019 19:19:54 +0100 Subject: [PATCH 26/51] Motor's new Eggman sprites, along with some other sweet bits of boss polish. What else can I say? Just play it. --- src/dehacked.c | 63 ++------ src/hardware/hw_light.c | 7 +- src/info.c | 333 ++++++++++++++-------------------------- src/info.h | 73 +++------ src/p_enemy.c | 234 ++++++++++++++++++++-------- src/p_inter.c | 6 + src/p_mobj.c | 114 ++++++++------ src/r_draw.c | 11 +- 8 files changed, 408 insertions(+), 433 deletions(-) diff --git a/src/dehacked.c b/src/dehacked.c index 04ac2ef4b..cf767a4b5 100644 --- a/src/dehacked.c +++ b/src/dehacked.c @@ -4585,10 +4585,10 @@ static const char *const STATE_LIST[] = { // array length left dynamic for sanit "S_SONIC3KBOSSEXPLOSION6", "S_JETFUME1", - "S_JETFUME2", // Boss 1 "S_EGGMOBILE_STND", + "S_EGGMOBILE_ROFL", "S_EGGMOBILE_LATK1", "S_EGGMOBILE_LATK2", "S_EGGMOBILE_LATK3", @@ -4598,7 +4598,6 @@ static const char *const STATE_LIST[] = { // array length left dynamic for sanit "S_EGGMOBILE_LATK7", "S_EGGMOBILE_LATK8", "S_EGGMOBILE_LATK9", - "S_EGGMOBILE_LATK10", "S_EGGMOBILE_RATK1", "S_EGGMOBILE_RATK2", "S_EGGMOBILE_RATK3", @@ -4608,7 +4607,6 @@ static const char *const STATE_LIST[] = { // array length left dynamic for sanit "S_EGGMOBILE_RATK7", "S_EGGMOBILE_RATK8", "S_EGGMOBILE_RATK9", - "S_EGGMOBILE_RATK10", "S_EGGMOBILE_PANIC1", "S_EGGMOBILE_PANIC2", "S_EGGMOBILE_PANIC3", @@ -4616,6 +4614,14 @@ static const char *const STATE_LIST[] = { // array length left dynamic for sanit "S_EGGMOBILE_PANIC5", "S_EGGMOBILE_PANIC6", "S_EGGMOBILE_PANIC7", + "S_EGGMOBILE_PANIC8", + "S_EGGMOBILE_PANIC9", + "S_EGGMOBILE_PANIC10", + "S_EGGMOBILE_PANIC11", + "S_EGGMOBILE_PANIC12", + "S_EGGMOBILE_PANIC13", + "S_EGGMOBILE_PANIC14", + "S_EGGMOBILE_PANIC15", "S_EGGMOBILE_PAIN", "S_EGGMOBILE_PAIN2", "S_EGGMOBILE_DIE1", @@ -4626,6 +4632,8 @@ static const char *const STATE_LIST[] = { // array length left dynamic for sanit "S_EGGMOBILE_FLEE2", "S_EGGMOBILE_BALL", "S_EGGMOBILE_TARGET", + "S_BOSSEGLZ1", + "S_BOSSEGLZ2", // Boss 2 "S_EGGMOBILE2_STND", @@ -4657,11 +4665,7 @@ static const char *const STATE_LIST[] = { // array length left dynamic for sanit // Boss 3 "S_EGGMOBILE3_STND", - "S_EGGMOBILE3_LAUGH1", - "S_EGGMOBILE3_LAUGH2", - "S_EGGMOBILE3_LAUGH3", - "S_EGGMOBILE3_LAUGH4", - "S_EGGMOBILE3_LAUGH5", + "S_EGGMOBILE3_SHOCK", "S_EGGMOBILE3_ATK1", "S_EGGMOBILE3_ATK2", "S_EGGMOBILE3_ATK3A", @@ -4670,21 +4674,7 @@ static const char *const STATE_LIST[] = { // array length left dynamic for sanit "S_EGGMOBILE3_ATK3D", "S_EGGMOBILE3_ATK4", "S_EGGMOBILE3_ATK5", - "S_EGGMOBILE3_LAUGH6", - "S_EGGMOBILE3_LAUGH7", - "S_EGGMOBILE3_LAUGH8", - "S_EGGMOBILE3_LAUGH9", - "S_EGGMOBILE3_LAUGH10", - "S_EGGMOBILE3_LAUGH11", - "S_EGGMOBILE3_LAUGH12", - "S_EGGMOBILE3_LAUGH13", - "S_EGGMOBILE3_LAUGH14", - "S_EGGMOBILE3_LAUGH15", - "S_EGGMOBILE3_LAUGH16", - "S_EGGMOBILE3_LAUGH17", - "S_EGGMOBILE3_LAUGH18", - "S_EGGMOBILE3_LAUGH19", - "S_EGGMOBILE3_LAUGH20", + "S_EGGMOBILE3_ROFL", "S_EGGMOBILE3_PAIN", "S_EGGMOBILE3_PAIN2", "S_EGGMOBILE3_DIE1", @@ -4694,15 +4684,6 @@ static const char *const STATE_LIST[] = { // array length left dynamic for sanit "S_EGGMOBILE3_FLEE1", "S_EGGMOBILE3_FLEE2", - // Boss 3 Propeller - "S_PROPELLER1", - "S_PROPELLER2", - "S_PROPELLER3", - "S_PROPELLER4", - "S_PROPELLER5", - "S_PROPELLER6", - "S_PROPELLER7", - // Boss 3 pinch "S_FAKEMOBILE_INIT", "S_FAKEMOBILE", @@ -4715,6 +4696,9 @@ static const char *const STATE_LIST[] = { // array length left dynamic for sanit "S_FAKEMOBILE_DIE1", "S_FAKEMOBILE_DIE2", + "S_BOSSSEBH1", + "S_BOSSSEBH2", + // Boss 4 "S_EGGMOBILE4_STND", "S_EGGMOBILE4_LATK1", @@ -5118,16 +5102,6 @@ static const char *const STATE_LIST[] = { // array length left dynamic for sanit "S_MSSHIELD_F1", "S_MSSHIELD_F2", - "S_MSSHIELD_F3", - "S_MSSHIELD_F4", - "S_MSSHIELD_F5", - "S_MSSHIELD_F6", - "S_MSSHIELD_F7", - "S_MSSHIELD_F8", - "S_MSSHIELD_F9", - "S_MSSHIELD_F10", - "S_MSSHIELD_F11", - "S_MSSHIELD_F12", // Ring "S_RING", @@ -7211,6 +7185,7 @@ static const char *const MOBJTYPE_LIST[] = { // array length left dynamic for s "MT_EGGTRAP", "MT_BOSS3WAYPOINT", "MT_BOSS9GATHERPOINT", + "MT_BOSSJUNK", // Boss 1 "MT_EGGMOBILE", @@ -7222,15 +7197,11 @@ static const char *const MOBJTYPE_LIST[] = { // array length left dynamic for s // Boss 2 "MT_EGGMOBILE2", "MT_EGGMOBILE2_POGO", - "MT_BOSSTANK1", - "MT_BOSSTANK2", - "MT_BOSSSPIGOT", "MT_GOOP", "MT_GOOPTRAIL", // Boss 3 "MT_EGGMOBILE3", - "MT_PROPELLER", "MT_FAKEMOBILE", "MT_SHOCK", diff --git a/src/hardware/hw_light.c b/src/hardware/hw_light.c index a52d72869..edfe328b8 100644 --- a/src/hardware/hw_light.c +++ b/src/hardware/hw_light.c @@ -186,17 +186,16 @@ light_t *t_lspr[NUMSPRITES] = // Boss 1, (Greenflower) &lspr[NOLIGHT], // SPR_EGGM + &lspr[NOLIGHT], // SPR_EGLZ // Boss 2, (Techno Hill) &lspr[NOLIGHT], // SPR_EGGN - &lspr[NOLIGHT], // SPR_TNKA - &lspr[NOLIGHT], // SPR_TNKB - &lspr[NOLIGHT], // SPR_SPNK + &lspr[NOLIGHT], // SPR_TANK &lspr[NOLIGHT], // SPR_GOOP // Boss 3 (Deep Sea) &lspr[NOLIGHT], // SPR_EGGO - &lspr[NOLIGHT], // SPR_PRPL + &lspr[NOLIGHT], // SPR_SEBH &lspr[NOLIGHT], // SPR_FAKE // Boss 4 (Castle Eggman) diff --git a/src/info.c b/src/info.c index 18f0e838a..5baf28943 100644 --- a/src/info.c +++ b/src/info.c @@ -73,18 +73,17 @@ char sprnames[NUMSPRITES + 1][5] = "JETF", // Boss jet fumes // Boss 1 (Greenflower) - "EGGM", + "EGGM", // Boss 1 + "EGLZ", // Boss 1 Junk // Boss 2 (Techno Hill) "EGGN", // Boss 2 - "TNKA", // Boss 2 Tank 1 - "TNKB", // Boss 2 Tank 2 - "SPNK", // Boss 2 Spigot + "TANK", // Boss 2 Junk "GOOP", // Boss 2 Goop // Boss 3 (Deep Sea) "EGGO", // Boss 3 - "PRPL", // Boss 3 Propeller + "SEBH", // Boss 3 Junk "FAKE", // Boss 3 Fakemobile // Boss 4 (Castle Eggman) @@ -1179,49 +1178,58 @@ state_t states[NUMSTATES] = {SPR_BOM3, FF_FULLBRIGHT|4, 3, {NULL}, 0, 0, S_SONIC3KBOSSEXPLOSION6}, // S_SONIC3KBOSSEXPLOSION5 {SPR_BOM3, FF_FULLBRIGHT|5, 4, {NULL}, 0, 0, S_NULL}, // S_SONIC3KBOSSEXPLOSION6 - {SPR_JETF, FF_FULLBRIGHT, 1, {NULL}, 0, 0, S_JETFUME2}, // S_JETFUME1 - {SPR_NULL, 0, 1, {NULL}, 0, 0, S_JETFUME1}, // S_JETFUME2 + {SPR_JETF, FF_ANIMATE|FF_FULLBRIGHT, -1, {NULL}, 2, 1, S_NULL}, // S_JETFUME1 // Boss 1 {SPR_EGGM, 0, 1, {A_Boss1Chase}, 0, 0, S_EGGMOBILE_STND}, // S_EGGMOBILE_STND + {SPR_EGGM, FF_ANIMATE|17, 35, {A_FaceTarget}, 1, 2, S_EGGMOBILE_STND}, // S_EGGMOBILE_ROFL {SPR_EGGM, 1, 3, {A_FaceTarget}, 0, 0, S_EGGMOBILE_LATK2}, // S_EGGMOBILE_LATK1 {SPR_EGGM, 2, 15, {NULL}, 0, 0, S_EGGMOBILE_LATK3}, // S_EGGMOBILE_LATK2 - {SPR_EGGM, 3, 2, {A_FaceTarget}, 0, 0, S_EGGMOBILE_LATK4}, // S_EGGMOBILE_LATK3 - {SPR_EGGM, 4, 1, {NULL}, 0, 0, S_EGGMOBILE_LATK5}, // S_EGGMOBILE_LATK4 - {SPR_EGGM, 5, 1, {NULL}, 0, 0, S_EGGMOBILE_LATK6}, // S_EGGMOBILE_LATK5 - {SPR_EGGM, 6, 1, {NULL}, 0, 0, S_EGGMOBILE_LATK7}, // S_EGGMOBILE_LATK6 - {SPR_EGGM, 7, 1, {NULL}, 0, 0, S_EGGMOBILE_LATK8}, // S_EGGMOBILE_LATK7 - {SPR_EGGM, 8, 45, {A_Boss1Laser}, MT_LASER, 0, S_EGGMOBILE_LATK9}, // S_EGGMOBILE_LATK8 - {SPR_EGGM, 9, 10, {NULL}, 0, 0, S_EGGMOBILE_LATK10}, // S_EGGMOBILE_LATK9 - {SPR_EGGM, 10, 2, {NULL}, 0, 0, S_EGGMOBILE_STND}, // S_EGGMOBILE_LATK10 - {SPR_EGGM, 11, 3, {A_FaceTarget}, 0, 0, S_EGGMOBILE_RATK2}, // S_EGGMOBILE_RATK1 - {SPR_EGGM, 12, 15, {NULL}, 0, 0, S_EGGMOBILE_RATK3}, // S_EGGMOBILE_RATK2 - {SPR_EGGM, 13, 2, {A_FaceTarget}, 0, 0, S_EGGMOBILE_RATK4}, // S_EGGMOBILE_RATK3 - {SPR_EGGM, 14, 1, {NULL}, 0, 0, S_EGGMOBILE_RATK5}, // S_EGGMOBILE_RATK4 - {SPR_EGGM, 15, 1, {NULL}, 0, 0, S_EGGMOBILE_RATK6}, // S_EGGMOBILE_RATK5 - {SPR_EGGM, 16, 1, {NULL}, 0, 0, S_EGGMOBILE_RATK7}, // S_EGGMOBILE_RATK6 - {SPR_EGGM, 17, 1, {NULL}, 0, 0, S_EGGMOBILE_RATK8}, // S_EGGMOBILE_RATK7 - {SPR_EGGM, 18, 45, {A_Boss1Laser}, MT_LASER, 1, S_EGGMOBILE_RATK9}, // S_EGGMOBILE_RATK8 - {SPR_EGGM, 19, 10, {NULL}, 0, 0, S_EGGMOBILE_RATK10}, // S_EGGMOBILE_RATK9 - {SPR_EGGM, 20, 2, {NULL}, 0, 0, S_EGGMOBILE_STND}, // S_EGGMOBILE_RATK10 - {SPR_EGGM, 3, 12, {NULL}, 0, 0, S_EGGMOBILE_PANIC2}, // S_EGGMOBILE_PANIC1 - {SPR_EGGM, 4, 45, {A_Boss1Laser}, MT_LASER, 2, S_EGGMOBILE_PANIC3}, // S_EGGMOBILE_PANIC2 - {SPR_EGGM, 3, 8, {NULL}, 0, 0, S_EGGMOBILE_PANIC4}, // S_EGGMOBILE_PANIC3 - {SPR_EGGM, 4, 45, {A_Boss1Laser}, MT_LASER, 2, S_EGGMOBILE_PANIC5 }, // S_EGGMOBILE_PANIC4 - {SPR_EGGM, 3, 8, {NULL}, 0, 0, S_EGGMOBILE_PANIC6}, // S_EGGMOBILE_PANIC5 - {SPR_EGGM, 4, 45, {A_Boss1Laser}, MT_LASER, 2, S_EGGMOBILE_PANIC7 }, // S_EGGMOBILE_PANIC6 - {SPR_EGGM, 0, 35, {NULL}, 0, 0, S_EGGMOBILE_STND }, // S_EGGMOBILE_PANIC7 - {SPR_EGGM, 21, 24, {A_Pain}, 0, 0, S_EGGMOBILE_PAIN2}, // S_EGGMOBILE_PAIN - {SPR_EGGM, 21, 16, {A_SkullAttack}, 1, 1, S_EGGMOBILE_STND}, // S_EGGMOBILE_PAIN2 - {SPR_EGGM, 22, 2, {A_Fall}, 0, 0, S_EGGMOBILE_DIE2}, // S_EGGMOBILE_DIE1 - {SPR_EGGM, 22, 2, {A_BossScream}, 0, 0, S_EGGMOBILE_DIE3}, // S_EGGMOBILE_DIE2 - {SPR_EGGM, 22, 0, {A_Repeat}, 17, S_EGGMOBILE_DIE2, S_EGGMOBILE_DIE4}, // S_EGGMOBILE_DIE3 - {SPR_EGGM, 22, -1, {A_BossDeath}, 0, 0, S_NULL}, // S_EGGMOBILE_DIE4 - {SPR_EGGM, 23, 2, {A_BossScream}, 0, 0, S_EGGMOBILE_FLEE2}, // S_EGGMOBILE_FLEE1 - {SPR_EGGM, 24, 2, {A_BossScream}, 0, 0, S_EGGMOBILE_FLEE1}, // S_EGGMOBILE_FLEE2 + {SPR_EGGM, 3, 2, {NULL}, 0, 0, S_EGGMOBILE_LATK4}, // S_EGGMOBILE_LATK3 + {SPR_EGGM, 4, 2, {A_FaceTarget}, 0, 0, S_EGGMOBILE_LATK5}, // S_EGGMOBILE_LATK4 + {SPR_EGGM, 6, 0, {A_PrepareRepeat}, 45, 0, S_EGGMOBILE_LATK6}, // S_EGGMOBILE_LATK5 + {SPR_EGGM, 5, 1, {A_Boss1Laser}, MT_LASER, 0, S_EGGMOBILE_LATK7}, // S_EGGMOBILE_LATK6 + {SPR_EGGM, 6, 1, {A_Boss1Laser}, MT_LASER, (1<<16), S_EGGMOBILE_LATK8}, // S_EGGMOBILE_LATK7 + {SPR_EGGM, 5, 0, {A_Repeat}, 45, S_EGGMOBILE_LATK6, S_EGGMOBILE_LATK9}, // S_EGGMOBILE_LATK8 + {SPR_EGGM, 8, 2, {NULL}, 0, 0, S_EGGMOBILE_ROFL}, // S_EGGMOBILE_LATK9 + {SPR_EGGM, 9, 3, {A_FaceTarget}, 0, 0, S_EGGMOBILE_RATK2}, // S_EGGMOBILE_RATK1 + {SPR_EGGM, 10, 15, {NULL}, 0, 0, S_EGGMOBILE_RATK3}, // S_EGGMOBILE_RATK2 + {SPR_EGGM, 11, 2, {NULL}, 0, 0, S_EGGMOBILE_RATK4}, // S_EGGMOBILE_RATK3 + {SPR_EGGM, 12, 2, {A_FaceTarget}, 0, 0, S_EGGMOBILE_RATK5}, // S_EGGMOBILE_RATK4 + {SPR_EGGM, 14, 0, {A_PrepareRepeat}, 45, 0, S_EGGMOBILE_RATK6}, // S_EGGMOBILE_RATK5 + {SPR_EGGM, 13, 1, {A_Boss1Laser}, MT_LASER, 1, S_EGGMOBILE_RATK7}, // S_EGGMOBILE_RATK6 + {SPR_EGGM, 14, 1, {A_Boss1Laser}, MT_LASER, 1|(1<<16), S_EGGMOBILE_RATK8}, // S_EGGMOBILE_RATK7 + {SPR_EGGM, 13, 0, {A_Repeat}, 45, S_EGGMOBILE_RATK6, S_EGGMOBILE_RATK9}, // S_EGGMOBILE_RATK8 + {SPR_EGGM, 16, 2, {NULL}, 0, 0, S_EGGMOBILE_ROFL}, // S_EGGMOBILE_RATK9 + {SPR_EGGM, 0, 0, {A_PrepareRepeat}, 45, 0, S_EGGMOBILE_PANIC2}, // S_EGGMOBILE_PANIC1 + {SPR_EGGM, FF_ANIMATE|1, 16, {A_FaceTarget}, 3, 4, S_EGGMOBILE_PANIC3}, // S_EGGMOBILE_PANIC2 + {SPR_EGGM, 7, 1, {A_Boss1Laser}, MT_LASER, 2, S_EGGMOBILE_PANIC4}, // S_EGGMOBILE_PANIC3 + {SPR_EGGM, 6, 1, {A_Boss1Laser}, MT_LASER, 2|(1<<16), S_EGGMOBILE_PANIC5}, // S_EGGMOBILE_PANIC4 + {SPR_EGGM, 6, 0, {A_Repeat}, 45, S_EGGMOBILE_PANIC3, S_EGGMOBILE_PANIC6}, // S_EGGMOBILE_PANIC5 + {SPR_EGGM, 0, 0, {A_PrepareRepeat}, 45, 0, S_EGGMOBILE_PANIC7}, // S_EGGMOBILE_PANIC6 + {SPR_EGGM, FF_ANIMATE|9, 16, {A_FaceTarget}, 3, 4, S_EGGMOBILE_PANIC8}, // S_EGGMOBILE_PANIC7 + {SPR_EGGM, 15, 1, {A_Boss1Laser}, MT_LASER, 2, S_EGGMOBILE_PANIC9}, // S_EGGMOBILE_PANIC8 + {SPR_EGGM, 14, 1, {A_Boss1Laser}, MT_LASER, 2|(1<<16), S_EGGMOBILE_PANIC10}, // S_EGGMOBILE_PANIC9 + {SPR_EGGM, 14, 0, {A_Repeat}, 45, S_EGGMOBILE_PANIC8, S_EGGMOBILE_PANIC11}, // S_EGGMOBILE_PANIC10 + {SPR_EGGM, 0, 0, {A_PrepareRepeat}, 45, 0, S_EGGMOBILE_PANIC12}, // S_EGGMOBILE_PANIC11 + {SPR_EGGM, FF_ANIMATE|1, 16, {A_FaceTarget}, 3, 4, S_EGGMOBILE_PANIC13}, // S_EGGMOBILE_PANIC12 + {SPR_EGGM, 7, 1, {A_Boss1Laser}, MT_LASER, 2, S_EGGMOBILE_PANIC14}, // S_EGGMOBILE_PANIC13 + {SPR_EGGM, 6, 1, {A_Boss1Laser}, MT_LASER, 2|(1<<16), S_EGGMOBILE_PANIC15}, // S_EGGMOBILE_PANIC14 + {SPR_EGGM, 6, 0, {A_Repeat}, 45, S_EGGMOBILE_PANIC13, S_EGGMOBILE_ROFL}, // S_EGGMOBILE_PANIC15 + {SPR_EGGM, 19, 24, {A_Pain}, 0, 0, S_EGGMOBILE_PAIN2}, // S_EGGMOBILE_PAIN + {SPR_EGGM, 19, 16, {A_SkullAttack}, 3, 1, S_EGGMOBILE_STND}, // S_EGGMOBILE_PAIN2 + {SPR_EGGM, 20, 2, {A_Fall}, 17, 0, S_EGGMOBILE_DIE2}, // S_EGGMOBILE_DIE1 + {SPR_EGGM, 20, 2, {A_BossScream}, 0, 0, S_EGGMOBILE_DIE3}, // S_EGGMOBILE_DIE2 + {SPR_EGGM, 20, 0, {A_Repeat}, 17, S_EGGMOBILE_DIE2, S_EGGMOBILE_DIE4}, // S_EGGMOBILE_DIE3 + {SPR_EGGM, 20, -1, {A_BossDeath}, 0, 0, S_NULL}, // S_EGGMOBILE_DIE4 + {SPR_EGGM, 21, 2, {A_BossScream}, 0, 0, S_EGGMOBILE_FLEE2}, // S_EGGMOBILE_FLEE1 + {SPR_EGGM, 22, 2, {A_BossScream}, 0, 0, S_EGGMOBILE_FLEE1}, // S_EGGMOBILE_FLEE2 {SPR_UNID, 1, 1, {A_UnidusBall}, 2, 0, S_EGGMOBILE_BALL}, // S_EGGMOBILE_BALL {SPR_NULL, 0, 1, {A_FocusTarget}, 0, 0, S_EGGMOBILE_TARGET}, // S_EGGMOBILE_TARGET + {SPR_EGLZ, 0, 35, {NULL}, 0, 0, S_NULL}, // S_BOSSEGLZ1 + {SPR_EGLZ, 1, 35, {NULL}, 0, 0, S_NULL}, // S_BOSSEGLZ2 + // Boss 2 {SPR_EGGN, 0, -1, {NULL}, 0, 0, S_NULL}, // S_EGGMOBILE2_STND {SPR_EGGN, 1, 4, {NULL}, 0, 0, S_EGGMOBILE2_POGO2}, // S_EGGMOBILE2_POGO1 @@ -1240,9 +1248,9 @@ state_t states[NUMSTATES] = {SPR_EGGN, 6, 2, {A_BossScream}, 0, 0, S_EGGMOBILE2_FLEE2}, // S_EGGMOBILE2_FLEE1 {SPR_EGGN, 7, 2, {A_BossScream}, 0, 0, S_EGGMOBILE2_FLEE1}, // S_EGGMOBILE2_FLEE2 - {SPR_TNKA, 0, 35, {NULL}, 0, 0, S_NULL}, // S_BOSSTANK1 - {SPR_TNKB, 0, 35, {NULL}, 0, 0, S_NULL}, // S_BOSSTANK2 - {SPR_SPNK, 0, 35, {NULL}, 0, 0, S_NULL}, // S_BOSSSPIGOT + {SPR_TANK, 0, 35, {NULL}, 0, 0, S_NULL}, // S_BOSSTANK1 + {SPR_TANK, 1, 35, {NULL}, 0, 0, S_NULL}, // S_BOSSTANK2 + {SPR_TANK, 2, 35, {NULL}, 0, 0, S_NULL}, // S_BOSSSPIGOT // Boss 2 Goop {SPR_GOOP, 0, 2, {A_SpawnObjectRelative}, 0, MT_GOOPTRAIL, S_GOOP2}, // S_GOOP1 @@ -1252,34 +1260,16 @@ state_t states[NUMSTATES] = // Boss 3 {SPR_EGGO, 0, 1, {NULL}, 0, 0, S_EGGMOBILE3_STND}, // S_EGGMOBILE3_STND - {SPR_EGGO, 6, 4, {NULL}, 0, 0, S_EGGMOBILE3_LAUGH2}, // S_EGGMOBILE3_LAUGH1 - {SPR_EGGO, 7, 4, {NULL}, 0, 0, S_EGGMOBILE3_LAUGH3}, // S_EGGMOBILE3_LAUGH2 - {SPR_EGGO, 6, 4, {NULL}, 0, 0, S_EGGMOBILE3_LAUGH4}, // S_EGGMOBILE3_LAUGH3 - {SPR_EGGO, 7, 4, {NULL}, 0, 0, S_EGGMOBILE3_LAUGH5}, // S_EGGMOBILE3_LAUGH4 - {SPR_EGGO, 6, 4, {NULL}, 0, 0, S_EGGMOBILE3_ATK1}, // S_EGGMOBILE3_LAUGH5 - {SPR_EGGO, 1, 2, {NULL}, 0, 0, S_EGGMOBILE3_ATK2}, // S_EGGMOBILE3_ATK1 + {SPR_EGGO, FF_ANIMATE, 24, {NULL}, 1, 2, S_EGGMOBILE3_ATK2}, // S_EGGMOBILE3_SHOCK + {SPR_EGGO, 6|FF_ANIMATE, 24, {NULL}, 1, 2, S_EGGMOBILE3_ATK2}, // S_EGGMOBILE3_ATK1 {SPR_EGGO, 2, 2, {NULL}, 0, 0, S_EGGMOBILE3_ATK3A}, // S_EGGMOBILE3_ATK2 {SPR_EGGO, 3, 2, {A_BossFireShot}, MT_TORPEDO, 2, S_EGGMOBILE3_ATK3B}, // S_EGGMOBILE3_ATK3A {SPR_EGGO, 3, 2, {A_BossFireShot}, MT_TORPEDO, 4, S_EGGMOBILE3_ATK3C}, // S_EGGMOBILE3_ATK3B {SPR_EGGO, 3, 2, {A_BossFireShot}, MT_TORPEDO, 3, S_EGGMOBILE3_ATK3D}, // S_EGGMOBILE3_ATK3C {SPR_EGGO, 3, 2, {A_BossFireShot}, MT_TORPEDO, 5, S_EGGMOBILE3_ATK4}, // S_EGGMOBILE3_ATK3D {SPR_EGGO, 4, 2, {NULL}, 0, 0, S_EGGMOBILE3_ATK5}, // S_EGGMOBILE3_ATK4 - {SPR_EGGO, 5, 2, {NULL}, 0, 0, S_EGGMOBILE3_LAUGH6}, // S_EGGMOBILE3_ATK5 - {SPR_EGGO, 7, 4, {NULL}, 0, 0, S_EGGMOBILE3_LAUGH7}, // S_EGGMOBILE3_LAUGH6 - {SPR_EGGO, 6, 4, {NULL}, 0, 0, S_EGGMOBILE3_LAUGH8}, // S_EGGMOBILE3_LAUGH7 - {SPR_EGGO, 7, 4, {NULL}, 0, 0, S_EGGMOBILE3_LAUGH9}, // S_EGGMOBILE3_LAUGH8 - {SPR_EGGO, 6, 4, {NULL}, 0, 0, S_EGGMOBILE3_LAUGH10}, // S_EGGMOBILE3_LAUGH9 - {SPR_EGGO, 7, 4, {NULL}, 0, 0, S_EGGMOBILE3_LAUGH11}, // S_EGGMOBILE3_LAUGH10 - {SPR_EGGO, 6, 4, {NULL}, 0, 0, S_EGGMOBILE3_LAUGH12}, // S_EGGMOBILE3_LAUGH11 - {SPR_EGGO, 7, 4, {NULL}, 0, 0, S_EGGMOBILE3_LAUGH13}, // S_EGGMOBILE3_LAUGH12 - {SPR_EGGO, 6, 4, {NULL}, 0, 0, S_EGGMOBILE3_LAUGH14}, // S_EGGMOBILE3_LAUGH13 - {SPR_EGGO, 7, 4, {NULL}, 0, 0, S_EGGMOBILE3_LAUGH15}, // S_EGGMOBILE3_LAUGH14 - {SPR_EGGO, 6, 4, {NULL}, 0, 0, S_EGGMOBILE3_LAUGH16}, // S_EGGMOBILE3_LAUGH15 - {SPR_EGGO, 7, 4, {NULL}, 0, 0, S_EGGMOBILE3_LAUGH17}, // S_EGGMOBILE3_LAUGH16 - {SPR_EGGO, 6, 4, {NULL}, 0, 0, S_EGGMOBILE3_LAUGH18}, // S_EGGMOBILE3_LAUGH17 - {SPR_EGGO, 7, 4, {NULL}, 0, 0, S_EGGMOBILE3_LAUGH19}, // S_EGGMOBILE3_LAUGH18 - {SPR_EGGO, 6, 4, {NULL}, 0, 0, S_EGGMOBILE3_LAUGH20}, // S_EGGMOBILE3_LAUGH19 - {SPR_EGGO, 7, 4, {NULL}, 0, 0, S_EGGMOBILE3_STND}, // S_EGGMOBILE3_LAUGH20 + {SPR_EGGO, 5, 2, {NULL}, 0, 0, S_EGGMOBILE3_ROFL}, // S_EGGMOBILE3_ATK5 + {SPR_EGGO, 6|FF_ANIMATE, 60, {NULL}, 1, 2, S_EGGMOBILE3_STND}, // S_EGGMOBILE3_ROFL {SPR_EGGO, 8, 1, {A_Boss3TakeDamage}, 0, 0, S_EGGMOBILE3_PAIN2}, // S_EGGMOBILE3_PAIN {SPR_EGGO, 8, 23, {A_Pain}, 0, 0, S_EGGMOBILE3_STND}, // S_EGGMOBILE3_PAIN2 {SPR_EGGO, 9, 2, {A_Fall}, 0, 0, S_EGGMOBILE3_DIE2}, // S_EGGMOBILE3_DIE1 @@ -1289,17 +1279,8 @@ state_t states[NUMSTATES] = {SPR_EGGO, 10, 2, {A_BossScream}, 0, 0, S_EGGMOBILE3_FLEE2}, // S_EGGMOBILE3_FLEE1 {SPR_EGGO, 11, 2, {A_BossScream}, 0, 0, S_EGGMOBILE3_FLEE1}, // S_EGGMOBILE3_FLEE2 - // Boss 3 Propeller - {SPR_PRPL, 0, 1, {NULL}, 0, 0, S_PROPELLER2}, // S_PROPELLER1 - {SPR_PRPL, 1, 1, {NULL}, 0, 0, S_PROPELLER3}, // S_PROPELLER2 - {SPR_PRPL, 2, 1, {NULL}, 0, 0, S_PROPELLER4}, // S_PROPELLER3 - {SPR_PRPL, 3, 1, {NULL}, 0, 0, S_PROPELLER5}, // S_PROPELLER4 - {SPR_PRPL, 4, 1, {NULL}, 0, 0, S_PROPELLER6}, // S_PROPELLER5 - {SPR_PRPL, 5, 1, {NULL}, 0, 0, S_PROPELLER7}, // S_PROPELLER6 - {SPR_PRPL, 6, 1, {NULL}, 0, 0, S_PROPELLER1}, // S_PROPELLER7 - // Boss 3 Pinch - {SPR_FAKE, 0, 1, {A_BossJetFume}, 1, 0, S_FAKEMOBILE}, // S_FAKEMOBILE_INIT + {SPR_FAKE, 0, 1, {NULL}, 0, 0, S_FAKEMOBILE}, // S_FAKEMOBILE_INIT {SPR_FAKE, 0, 1, {A_Boss3Path}, 0, 0, S_FAKEMOBILE}, // S_FAKEMOBILE {SPR_FAKE, 0, 22, {NULL}, 0, 0, S_FAKEMOBILE_ATK2}, // S_FAKEMOBILE_ATK1 {SPR_FAKE, 0, 2, {NULL}, 0, 0, S_FAKEMOBILE_ATK3A}, // S_FAKEMOBILE_ATK2 @@ -1307,33 +1288,36 @@ state_t states[NUMSTATES] = {SPR_FAKE, 0, 2, {A_BossFireShot}, MT_TORPEDO2, 4, S_FAKEMOBILE_ATK3C}, // S_FAKEMOBILE_ATK3B {SPR_FAKE, 0, 2, {A_BossFireShot}, MT_TORPEDO2, 3, S_FAKEMOBILE_ATK3D}, // S_FAKEMOBILE_ATK3C {SPR_FAKE, 0, 2, {A_BossFireShot}, MT_TORPEDO2, 5, S_FAKEMOBILE}, // S_FAKEMOBILE_ATK3D - {SPR_FAKE, 0, 1, {NULL}, 0, 0, S_FAKEMOBILE_DIE2}, // S_FAKEMOBILE_DIE1 + {SPR_FAKE, 1, 1, {NULL}, 0, 0, S_FAKEMOBILE_DIE2}, // S_FAKEMOBILE_DIE1 {SPR_NULL, 0, 1, {NULL}, 0, 0, S_FAKEMOBILE_DIE1}, // S_FAKEMOBILE_DIE2 + {SPR_SEBH, 0, 35, {NULL}, 0, 0, S_NULL}, // S_BOSSSEBH1 + {SPR_SEBH, 1, 35, {NULL}, 0, 0, S_NULL}, // S_BOSSSEBH2 + // Boss 4 {SPR_EGGP, 0, -1, {NULL}, 0, 0, S_NULL}, // S_EGGMOBILE4_STND {SPR_EGGP, 1, 3, {NULL}, 0, 0, S_EGGMOBILE4_LATK2}, // S_EGGMOBILE4_LATK1 {SPR_EGGP, 2, 15, {NULL}, 0, 0, S_EGGMOBILE4_LATK3}, // S_EGGMOBILE4_LATK2 {SPR_EGGP, 3, 2, {NULL}, 0, 0, S_EGGMOBILE4_LATK4}, // S_EGGMOBILE4_LATK3 - {SPR_EGGP, 4, 4, {NULL}, 0, 0, S_EGGMOBILE4_LATK5}, // S_EGGMOBILE4_LATK4 - {SPR_EGGP, 4, 50, {A_Boss4Reverse}, sfx_mswing, 0, S_EGGMOBILE4_LATK6}, // S_EGGMOBILE4_LATK5 - {SPR_EGGP, 5, 2, {NULL}, 0, 0, S_EGGMOBILE4_STND}, // S_EGGMOBILE4_LATK6 - {SPR_EGGP, 6, 3, {NULL}, 0, 0, S_EGGMOBILE4_RATK2}, // S_EGGMOBILE4_RATK1 - {SPR_EGGP, 7, 15, {NULL}, 0, 0, S_EGGMOBILE4_RATK3}, // S_EGGMOBILE4_RATK2 - {SPR_EGGP, 8, 2, {NULL}, 0, 0, S_EGGMOBILE4_RATK4}, // S_EGGMOBILE4_RATK3 - {SPR_EGGP, 9, 4, {NULL}, 0, 0, S_EGGMOBILE4_RATK5}, // S_EGGMOBILE4_RATK4 - {SPR_EGGP, 9,150, {A_Boss4SpeedUp}, sfx_mswing, 0, S_EGGMOBILE4_RATK6}, // S_EGGMOBILE4_RATK5 - {SPR_EGGP,10, 2, {NULL}, 0, 0, S_EGGMOBILE4_STND}, // S_EGGMOBILE4_RATK6 - {SPR_EGGP, 0, 20, {A_Boss4Raise}, sfx_doord1, 0, S_EGGMOBILE4_RAISE2}, // S_EGGMOBILE4_RAISE1 - {SPR_EGGP,13|FF_ANIMATE, -1, {NULL}, 1, 10, S_NULL}, // S_EGGMOBILE4_RAISE2 - {SPR_EGGP,11, 0, {A_Boss4Reverse}, sfx_alarm, sfx_s3k60, S_EGGMOBILE4_PAIN2}, // S_EGGMOBILE4_PAIN1 - {SPR_EGGP,11, 24, {A_Pain}, 0, 0, S_EGGMOBILE4_STND}, // S_EGGMOBILE4_PAIN2 - {SPR_EGGP,12, 2, {A_Fall}, 0, 0, S_EGGMOBILE4_DIE2}, // S_EGGMOBILE4_DIE1 - {SPR_EGGP,12, 2, {A_BossScream}, 0, 0, S_EGGMOBILE4_DIE3}, // S_EGGMOBILE4_DIE2 - {SPR_EGGP,12, 0, {A_Repeat}, 17, S_EGGMOBILE4_DIE2, S_EGGMOBILE4_DIE4}, // S_EGGMOBILE4_DIE3 - {SPR_EGGP,12, -1, {A_BossDeath}, 0, 0, S_NULL}, // S_EGGMOBILE4_DIE4 - {SPR_EGGP,13, 2, {A_BossScream}, 0, 0, S_EGGMOBILE4_FLEE2}, // S_EGGMOBILE4_FLEE1 - {SPR_EGGP,14, 2, {A_BossScream}, 0, 0, S_EGGMOBILE4_FLEE1}, // S_EGGMOBILE4_FLEE2 + {SPR_EGGP, 4, 2, {NULL}, 0, 0, S_EGGMOBILE4_LATK5}, // S_EGGMOBILE4_LATK4 + {SPR_EGGP, 5, 50, {A_Boss4Reverse}, sfx_mswing, 0, S_EGGMOBILE4_LATK6}, // S_EGGMOBILE4_LATK5 + {SPR_EGGP, 6, 2, {NULL}, 0, 0, S_EGGMOBILE4_STND}, // S_EGGMOBILE4_LATK6 + {SPR_EGGP, 7, 3, {NULL}, 0, 0, S_EGGMOBILE4_RATK2}, // S_EGGMOBILE4_RATK1 + {SPR_EGGP, 8, 15, {NULL}, 0, 0, S_EGGMOBILE4_RATK3}, // S_EGGMOBILE4_RATK2 + {SPR_EGGP, 9, 2, {NULL}, 0, 0, S_EGGMOBILE4_RATK4}, // S_EGGMOBILE4_RATK3 + {SPR_EGGP,10, 2, {NULL}, 0, 0, S_EGGMOBILE4_RATK5}, // S_EGGMOBILE4_RATK4 + {SPR_EGGP,11,150, {A_Boss4SpeedUp}, sfx_mswing, 0, S_EGGMOBILE4_RATK6}, // S_EGGMOBILE4_RATK5 + {SPR_EGGP,12, 2, {NULL}, 0, 0, S_EGGMOBILE4_STND}, // S_EGGMOBILE4_RATK6 + {SPR_EGGP,13, 20, {A_Boss4Raise}, sfx_doord1, 0, S_EGGMOBILE4_RAISE2}, // S_EGGMOBILE4_RAISE1 + {SPR_EGGP,15|FF_ANIMATE, -1, {NULL}, 1, 10, S_NULL}, // S_EGGMOBILE4_RAISE2 + {SPR_EGGP,13, 0, {A_Boss4Reverse}, sfx_alarm, sfx_s3k60, S_EGGMOBILE4_PAIN2}, // S_EGGMOBILE4_PAIN1 + {SPR_EGGP,13, 24, {A_Pain}, 0, 0, S_EGGMOBILE4_STND}, // S_EGGMOBILE4_PAIN2 + {SPR_EGGP,14, 2, {A_Fall}, 0, 0, S_EGGMOBILE4_DIE2}, // S_EGGMOBILE4_DIE1 + {SPR_EGGP,14, 2, {A_BossScream}, 0, 0, S_EGGMOBILE4_DIE3}, // S_EGGMOBILE4_DIE2 + {SPR_EGGP,14, 0, {A_Repeat}, 17, S_EGGMOBILE4_DIE2, S_EGGMOBILE4_DIE4}, // S_EGGMOBILE4_DIE3 + {SPR_EGGP,14, -1, {A_BossDeath}, 0, 0, S_NULL}, // S_EGGMOBILE4_DIE4 + {SPR_EGGP,15, 2, {A_BossScream}, 0, 0, S_EGGMOBILE4_FLEE2}, // S_EGGMOBILE4_FLEE1 + {SPR_EGGP,16, 2, {A_BossScream}, 0, 0, S_EGGMOBILE4_FLEE1}, // S_EGGMOBILE4_FLEE2 {SPR_BMCE, 0, -1, {NULL}, 0, 0, S_NULL}, // S_EGGMOBILE4_MACE {SPR_BMCE, 0, 2, {A_BossScream}, 1, 0, S_EGGMOBILE4_MACE_DIE2}, // S_EGGMOBILE4_MACE_DIE1 {SPR_NULL, 0, 2, {A_BossScream}, 1, 0, S_EGGMOBILE4_MACE_DIE3}, // S_EGGMOBILE4_MACE_DIE2 @@ -1732,18 +1716,8 @@ state_t states[NUMSTATES] = {SPR_METL, 11, 1, {A_BossScream}, 0, 0, S_METALSONIC_FLEE2}, // S_METALSONIC_FLEE1 {SPR_METL, 11, 7, {NULL}, 0, 0, S_METALSONIC_FLEE1}, // S_METALSONIC_FLEE2 - {SPR_MSCF, FF_FULLBRIGHT|FF_TRANS30| 0, 1, {NULL}, 0, 0, S_MSSHIELD_F2}, // S_MSSHIELD_F1 - {SPR_MSCF, FF_FULLBRIGHT|FF_TRANS30| 1, 1, {NULL}, 0, 0, S_MSSHIELD_F3}, // S_MSSHIELD_F2 - {SPR_MSCF, FF_FULLBRIGHT|FF_TRANS30| 2, 1, {NULL}, 0, 0, S_MSSHIELD_F4}, // S_MSSHIELD_F3 - {SPR_MSCF, FF_FULLBRIGHT|FF_TRANS30| 3, 1, {NULL}, 0, 0, S_MSSHIELD_F5}, // S_MSSHIELD_F4 - {SPR_MSCF, FF_FULLBRIGHT|FF_TRANS30| 4, 1, {NULL}, 0, 0, S_MSSHIELD_F6}, // S_MSSHIELD_F5 - {SPR_MSCF, FF_FULLBRIGHT|FF_TRANS30| 5, 1, {NULL}, 0, 0, S_MSSHIELD_F7}, // S_MSSHIELD_F6 - {SPR_MSCF, FF_FULLBRIGHT|FF_TRANS30| 6, 1, {NULL}, 0, 0, S_MSSHIELD_F8}, // S_MSSHIELD_F7 - {SPR_MSCF, FF_FULLBRIGHT|FF_TRANS30| 7, 1, {NULL}, 0, 0, S_MSSHIELD_F9}, // S_MSSHIELD_F8 - {SPR_MSCF, FF_FULLBRIGHT|FF_TRANS30| 8, 1, {NULL}, 0, 0, S_MSSHIELD_F10}, // S_MSSHIELD_F9 - {SPR_MSCF, FF_FULLBRIGHT|FF_TRANS30| 9, 1, {NULL}, 0, 0, S_MSSHIELD_F11}, // S_MSSHIELD_F10 - {SPR_MSCF, FF_FULLBRIGHT|FF_TRANS30|10, 1, {NULL}, 0, 0, S_MSSHIELD_F12}, // S_MSSHIELD_F11 - {SPR_MSCF, FF_FULLBRIGHT|FF_TRANS30|11, 1, {NULL}, 0, 0, S_MSSHIELD_F1}, // S_MSSHIELD_F12 + {SPR_MSCF, FF_FULLBRIGHT|FF_TRANS30|FF_ANIMATE, -1, {NULL}, 11, 1, S_NULL}, // S_MSSHIELD_F1 + {SPR_MSCF, FF_FULLBRIGHT|FF_ANIMATE|12, -1, {NULL}, 8, 2, S_NULL}, // S_MSSHIELD_F2 // Ring {SPR_RING, FF_ANIMATE|FF_GLOBALANIM, -1, {NULL}, 23, 1, S_RING}, // S_RING @@ -5144,6 +5118,33 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] = S_NULL // raisestate }, + { // MT_BOSSJUNK + -1, // doomednum + S_BOSSEGLZ1, // spawnstate + 1, // spawnhealth + S_NULL, // seestate + sfx_None, // seesound + 8, // reactiontime + sfx_None, // attacksound + S_NULL, // painstate + 0, // painchance + sfx_None, // painsound + S_NULL, // meleestate + S_NULL, // missilestate + S_NULL, // deathstate + S_NULL, // xdeathstate + sfx_None, // deathsound + 0, // speed + 8*FRACUNIT, // radius + 64*FRACUNIT, // height + 2, // display offset + 100, // mass + 1, // damage + sfx_None, // activesound + MF_SCENERY|MF_NOBLOCKMAP|MF_NOCLIPHEIGHT, // flags + S_NULL // raisestate + }, + { // MT_EGGMOBILE 200, // doomednum S_EGGMOBILE_STND, // spawnstate @@ -5333,87 +5334,6 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] = S_EGGMOBILE2_POGO5 // raisestate }, - { // MT_BOSSTANK1 - -1, // doomednum - S_BOSSTANK1, // spawnstate - 1, // spawnhealth - S_NULL, // seestate - sfx_None, // seesound - 8, // reactiontime - sfx_None, // attacksound - S_NULL, // painstate - 0, // painchance - sfx_None, // painsound - S_NULL, // meleestate - S_NULL, // missilestate - S_NULL, // deathstate - S_NULL, // xdeathstate - sfx_None, // deathsound - 0, // speed - 8*FRACUNIT, // radius - 64*FRACUNIT, // height - 0, // display offset - 100, // mass - 1, // damage - sfx_None, // activesound - MF_SCENERY|MF_NOBLOCKMAP|MF_NOCLIPHEIGHT, // flags - S_NULL // raisestate - }, - - { // MT_BOSSTANK2 - -1, // doomednum - S_BOSSTANK2, // spawnstate - 1, // spawnhealth - S_NULL, // seestate - sfx_None, // seesound - 8, // reactiontime - sfx_None, // attacksound - S_NULL, // painstate - 0, // painchance - sfx_None, // painsound - S_NULL, // meleestate - S_NULL, // missilestate - S_NULL, // deathstate - S_NULL, // xdeathstate - sfx_None, // deathsound - 0, // speed - 8*FRACUNIT, // radius - 64*FRACUNIT, // height - 0, // display offset - 100, // mass - 1, // damage - sfx_None, // activesound - MF_SCENERY|MF_NOBLOCKMAP|MF_NOCLIPHEIGHT, // flags - S_NULL // raisestate - }, - - { // MT_BOSSSPIGOT - -1, // doomednum - S_BOSSSPIGOT, // spawnstate - 1, // spawnhealth - S_NULL, // seestate - sfx_None, // seesound - 8, // reactiontime - sfx_None, // attacksound - S_NULL, // painstate - 0, // painchance - sfx_None, // painsound - S_NULL, // meleestate - S_NULL, // missilestate - S_NULL, // deathstate - S_NULL, // xdeathstate - sfx_None, // deathsound - 0, // speed - 8*FRACUNIT, // radius - 24*FRACUNIT, // height - 0, // display offset - 100, // mass - 1, // damage - sfx_None, // activesound - MF_SCENERY|MF_NOBLOCKMAP|MF_NOCLIPHEIGHT, // flags - S_NULL // raisestate - }, - { // MT_GOOP -1, // doomednum S_GOOP1, // spawnstate @@ -5477,10 +5397,10 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] = 0, // reactiontime sfx_None, // attacksound S_EGGMOBILE3_PAIN, // painstate - MT_PROPELLER, // painchance + MT_NULL, // painchance sfx_dmpain, // painsound S_NULL, // meleestate - S_EGGMOBILE3_LAUGH1,// missilestate + S_EGGMOBILE3_SHOCK, // missilestate S_EGGMOBILE3_DIE1, // deathstate S_EGGMOBILE3_FLEE1, // xdeathstate sfx_s3kb4, // deathsound @@ -5492,34 +5412,7 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] = 3, // damage sfx_telept, // activesound MF_SPECIAL|MF_SHOOTABLE|MF_NOGRAVITY|MF_BOSS|MF_NOCLIPHEIGHT, // flags - S_EGGMOBILE3_LAUGH20 // raisestate - }, - - { // MT_PROPELLER - -1, // doomednum - S_PROPELLER1, // spawnstate - 1000, // spawnhealth - S_NULL, // seestate - sfx_None, // seesound - 8, // reactiontime - sfx_None, // attacksound - S_NULL, // painstate - 0, // painchance - sfx_None, // painsound - S_NULL, // meleestate - S_NULL, // missilestate - S_NULL, // deathstate - S_NULL, // xdeathstate - sfx_None, // deathsound - 1, // speed - 4*FRACUNIT, // radius - 4*FRACUNIT, // height - 0, // display offset - 4, // mass - 0, // damage - sfx_None, // activesound - MF_NOBLOCKMAP|MF_NOGRAVITY|MF_NOCLIP|MF_NOCLIPHEIGHT, // flags - S_NULL // raisestate + S_EGGMOBILE3_ROFL // raisestate }, { // MT_FAKEMOBILE @@ -5531,7 +5424,7 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] = 0, // reactiontime sfx_None, // attacksound S_NULL, // painstate - MT_PROPELLER, // painchance + MT_NULL, // painchance sfx_s3k7b, // painsound S_NULL, // meleestate S_FAKEMOBILE_ATK1, // missilestate @@ -9211,7 +9104,7 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] = 0, // mass 20, // damage sfx_None, // activesound - MF_PAIN|MF_NOGRAVITY|MF_NOCLIPHEIGHT, // flags + MF_PAIN|MF_NOGRAVITY|MF_NOCLIPHEIGHT|MF_NOCLIP, // flags S_NULL // raisestate }, diff --git a/src/info.h b/src/info.h index 593c1fb7c..a9d4bdde0 100644 --- a/src/info.h +++ b/src/info.h @@ -319,18 +319,17 @@ typedef enum sprite SPR_JETF, // Boss jet fumes // Boss 1 (Greenflower) - SPR_EGGM, + SPR_EGGM, // Boss 1 + SPR_EGLZ, // Boss 1 Junk // Boss 2 (Techno Hill) SPR_EGGN, // Boss 2 - SPR_TNKA, // Boss 2 Tank 1 - SPR_TNKB, // Boss 2 Tank 2 - SPR_SPNK, // Boss 2 Spigot + SPR_TANK, // Boss 2 Junk SPR_GOOP, // Boss 2 Goop // Boss 3 (Deep Sea) SPR_EGGO, // Boss 3 - SPR_PRPL, // Boss 3 Propeller + SPR_SEBH, // Boss 3 Junk SPR_FAKE, // Boss 3 Fakemobile // Boss 4 (Castle Eggman) @@ -1333,10 +1332,10 @@ typedef enum state S_SONIC3KBOSSEXPLOSION6, S_JETFUME1, - S_JETFUME2, // Boss 1 S_EGGMOBILE_STND, + S_EGGMOBILE_ROFL, S_EGGMOBILE_LATK1, S_EGGMOBILE_LATK2, S_EGGMOBILE_LATK3, @@ -1346,7 +1345,6 @@ typedef enum state S_EGGMOBILE_LATK7, S_EGGMOBILE_LATK8, S_EGGMOBILE_LATK9, - S_EGGMOBILE_LATK10, S_EGGMOBILE_RATK1, S_EGGMOBILE_RATK2, S_EGGMOBILE_RATK3, @@ -1356,7 +1354,6 @@ typedef enum state S_EGGMOBILE_RATK7, S_EGGMOBILE_RATK8, S_EGGMOBILE_RATK9, - S_EGGMOBILE_RATK10, S_EGGMOBILE_PANIC1, S_EGGMOBILE_PANIC2, S_EGGMOBILE_PANIC3, @@ -1364,6 +1361,14 @@ typedef enum state S_EGGMOBILE_PANIC5, S_EGGMOBILE_PANIC6, S_EGGMOBILE_PANIC7, + S_EGGMOBILE_PANIC8, + S_EGGMOBILE_PANIC9, + S_EGGMOBILE_PANIC10, + S_EGGMOBILE_PANIC11, + S_EGGMOBILE_PANIC12, + S_EGGMOBILE_PANIC13, + S_EGGMOBILE_PANIC14, + S_EGGMOBILE_PANIC15, S_EGGMOBILE_PAIN, S_EGGMOBILE_PAIN2, S_EGGMOBILE_DIE1, @@ -1375,6 +1380,9 @@ typedef enum state S_EGGMOBILE_BALL, S_EGGMOBILE_TARGET, + S_BOSSEGLZ1, + S_BOSSEGLZ2, + // Boss 2 S_EGGMOBILE2_STND, S_EGGMOBILE2_POGO1, @@ -1405,11 +1413,7 @@ typedef enum state // Boss 3 S_EGGMOBILE3_STND, - S_EGGMOBILE3_LAUGH1, - S_EGGMOBILE3_LAUGH2, - S_EGGMOBILE3_LAUGH3, - S_EGGMOBILE3_LAUGH4, - S_EGGMOBILE3_LAUGH5, + S_EGGMOBILE3_SHOCK, S_EGGMOBILE3_ATK1, S_EGGMOBILE3_ATK2, S_EGGMOBILE3_ATK3A, @@ -1418,21 +1422,7 @@ typedef enum state S_EGGMOBILE3_ATK3D, S_EGGMOBILE3_ATK4, S_EGGMOBILE3_ATK5, - S_EGGMOBILE3_LAUGH6, - S_EGGMOBILE3_LAUGH7, - S_EGGMOBILE3_LAUGH8, - S_EGGMOBILE3_LAUGH9, - S_EGGMOBILE3_LAUGH10, - S_EGGMOBILE3_LAUGH11, - S_EGGMOBILE3_LAUGH12, - S_EGGMOBILE3_LAUGH13, - S_EGGMOBILE3_LAUGH14, - S_EGGMOBILE3_LAUGH15, - S_EGGMOBILE3_LAUGH16, - S_EGGMOBILE3_LAUGH17, - S_EGGMOBILE3_LAUGH18, - S_EGGMOBILE3_LAUGH19, - S_EGGMOBILE3_LAUGH20, + S_EGGMOBILE3_ROFL, S_EGGMOBILE3_PAIN, S_EGGMOBILE3_PAIN2, S_EGGMOBILE3_DIE1, @@ -1442,15 +1432,6 @@ typedef enum state S_EGGMOBILE3_FLEE1, S_EGGMOBILE3_FLEE2, - // Boss 3 Propeller - S_PROPELLER1, - S_PROPELLER2, - S_PROPELLER3, - S_PROPELLER4, - S_PROPELLER5, - S_PROPELLER6, - S_PROPELLER7, - // Boss 3 Pinch S_FAKEMOBILE_INIT, S_FAKEMOBILE, @@ -1463,6 +1444,9 @@ typedef enum state S_FAKEMOBILE_DIE1, S_FAKEMOBILE_DIE2, + S_BOSSSEBH1, + S_BOSSSEBH2, + // Boss 4 S_EGGMOBILE4_STND, S_EGGMOBILE4_LATK1, @@ -1866,16 +1850,6 @@ typedef enum state S_MSSHIELD_F1, S_MSSHIELD_F2, - S_MSSHIELD_F3, - S_MSSHIELD_F4, - S_MSSHIELD_F5, - S_MSSHIELD_F6, - S_MSSHIELD_F7, - S_MSSHIELD_F8, - S_MSSHIELD_F9, - S_MSSHIELD_F10, - S_MSSHIELD_F11, - S_MSSHIELD_F12, // Ring S_RING, @@ -3981,6 +3955,7 @@ typedef enum mobj_type MT_EGGTRAP, MT_BOSS3WAYPOINT, MT_BOSS9GATHERPOINT, + MT_BOSSJUNK, // Boss 1 MT_EGGMOBILE, @@ -3992,15 +3967,11 @@ typedef enum mobj_type // Boss 2 MT_EGGMOBILE2, MT_EGGMOBILE2_POGO, - MT_BOSSTANK1, - MT_BOSSTANK2, - MT_BOSSSPIGOT, MT_GOOP, MT_GOOPTRAIL, // Boss 3 MT_EGGMOBILE3, - MT_PROPELLER, MT_FAKEMOBILE, MT_SHOCK, diff --git a/src/p_enemy.c b/src/p_enemy.c index e3f169784..d4ec3fb96 100644 --- a/src/p_enemy.c +++ b/src/p_enemy.c @@ -3003,16 +3003,19 @@ void A_Boss7FireMissiles(mobj_t *actor) // 0 - Boss 1 Left side // 1 - Boss 1 Right side // 2 - Triple laser -// >3 - Boss 1 Middle +// 3 - Boss 1 Middle +// >=3 - Generic middle // void A_Boss1Laser(mobj_t *actor) { fixed_t x, y, z, floorz, speed; INT32 locvar1 = var1; - INT32 locvar2 = var2; + INT32 locvar2 = (var2 & 65535); + INT32 upperend = (var2>>16); INT32 i; angle_t angle; mobj_t *point; + tic_t dur; #ifdef HAVE_BLUA if (LUA_CallAction("A_Boss1Laser", actor)) @@ -3021,19 +3024,24 @@ void A_Boss1Laser(mobj_t *actor) if (!actor->target) return; + if ((upperend & 1) && (actor->extravalue2 > 1)) + actor->extravalue2--; + + dur = actor->extravalue2; + switch (locvar2) { case 0: - x = actor->x + P_ReturnThrustX(actor, actor->angle+ANGLE_90, FixedMul(43*FRACUNIT, actor->scale)); - y = actor->y + P_ReturnThrustY(actor, actor->angle+ANGLE_90, FixedMul(43*FRACUNIT, actor->scale)); + x = actor->x + P_ReturnThrustX(actor, actor->angle+ANGLE_90, FixedMul(44*FRACUNIT, actor->scale)); + y = actor->y + P_ReturnThrustY(actor, actor->angle+ANGLE_90, FixedMul(44*FRACUNIT, actor->scale)); if (actor->eflags & MFE_VERTICALFLIP) z = actor->z + actor->height - FixedMul(56*FRACUNIT, actor->scale) - mobjinfo[locvar1].height; else z = actor->z + FixedMul(56*FRACUNIT, actor->scale); break; case 1: - x = actor->x + P_ReturnThrustX(actor, actor->angle-ANGLE_90, FixedMul(43*FRACUNIT, actor->scale)); - y = actor->y + P_ReturnThrustY(actor, actor->angle-ANGLE_90, FixedMul(43*FRACUNIT, actor->scale)); + x = actor->x + P_ReturnThrustX(actor, actor->angle-ANGLE_90, FixedMul(44*FRACUNIT, actor->scale)); + y = actor->y + P_ReturnThrustY(actor, actor->angle-ANGLE_90, FixedMul(44*FRACUNIT, actor->scale)); if (actor->eflags & MFE_VERTICALFLIP) z = actor->z + actor->height - FixedMul(56*FRACUNIT, actor->scale) - mobjinfo[locvar1].height; else @@ -3048,6 +3056,11 @@ void A_Boss1Laser(mobj_t *actor) A_Boss1Laser(actor); return; break; + case 3: + x = actor->x + P_ReturnThrustX(actor, actor->angle, FixedMul(42*FRACUNIT, actor->scale)); + y = actor->y + P_ReturnThrustY(actor, actor->angle, FixedMul(42*FRACUNIT, actor->scale)); + z = actor->z + actor->height/2; + break; default: x = actor->x; y = actor->y; @@ -3055,7 +3068,7 @@ void A_Boss1Laser(mobj_t *actor) break; } - if (!(actor->flags2 & MF2_FIRING) && actor->tics > 1) + if (!(actor->flags2 & MF2_FIRING) && dur > 1) { actor->angle = R_PointToAngle2(x, y, actor->target->x, actor->target->y); if (mobjinfo[locvar1].seesound) @@ -3064,7 +3077,7 @@ void A_Boss1Laser(mobj_t *actor) { point = P_SpawnMobj(x + P_ReturnThrustX(actor, actor->angle, actor->radius), y + P_ReturnThrustY(actor, actor->angle, actor->radius), actor->z - actor->height / 2, MT_EGGMOBILE_TARGET); point->angle = actor->angle; - point->fuse = actor->tics+1; + point->fuse = dur+1; P_SetTarget(&point->target, actor->target); P_SetTarget(&actor->target, point); } @@ -3073,9 +3086,9 @@ void A_Boss1Laser(mobj_t *actor) else if (actor->target && !(actor->spawnpoint && actor->spawnpoint->options & MTF_AMBUSH)) actor->angle = R_PointToAngle2(x, y, actor->target->x, actor->target->y);*/ - if (actor->spawnpoint && actor->spawnpoint->options & MTF_AMBUSH) - angle = FixedAngle(FixedDiv(actor->tics*160*FRACUNIT, actor->state->tics*FRACUNIT) + 10*FRACUNIT); - else + /*if (actor->spawnpoint && actor->spawnpoint->options & MTF_AMBUSH) + angle = FixedAngle(FixedDiv(dur*160*FRACUNIT, actor->state->tics*FRACUNIT) + 10*FRACUNIT); + else*/ angle = R_PointToAngle2(z + (mobjinfo[locvar1].height>>1), 0, actor->target->z, R_PointToDist2(x, y, actor->target->x, actor->target->y)); point = P_SpawnMobj(x, y, z, locvar1); @@ -3109,7 +3122,7 @@ void A_Boss1Laser(mobj_t *actor) point->fuse = TICRATE; } - if (actor->tics > 1) + if (dur > 1) actor->flags2 |= MF2_FIRING; else actor->flags2 &= ~MF2_FIRING; @@ -3253,6 +3266,7 @@ void A_Boss4Raise(mobj_t *actor) // 0 - Fly at the player // 1 - Fly away from the player // 2 - Strafe in relation to the player +// 3 - Dynamic mode - don't get too close to walls // var2: // 0 - Fly horizontally and vertically // 1 - Fly horizontal-only (momz = 0) @@ -3283,16 +3297,83 @@ void A_SkullAttack(mobj_t *actor) S_StartSound(actor, actor->info->activesound); A_FaceTarget(actor); + dist = P_AproxDistance(dest->x - actor->x, dest->y - actor->y); + if (locvar1 == 1) actor->angle += ANGLE_180; else if (locvar1 == 2) actor->angle += (P_RandomChance(FRACUNIT/2)) ? ANGLE_90 : -ANGLE_90; + else if (locvar1 == 3) + { + statenum_t oldspawnstate = mobjinfo[MT_NULL].spawnstate; + UINT32 oldflags = mobjinfo[MT_NULL].flags; + fixed_t oldradius = mobjinfo[MT_NULL].radius; + fixed_t oldheight = mobjinfo[MT_NULL].height; + mobj_t *check; + INT32 i, j, k; + boolean allow; + angle_t testang; + + mobjinfo[MT_NULL].spawnstate = S_INVISIBLE; + mobjinfo[MT_NULL].flags = MF_NOGRAVITY|MF_NOTHINK|MF_NOCLIPTHING|MF_NOBLOCKMAP; + mobjinfo[MT_NULL].radius = mobjinfo[actor->type].radius; + mobjinfo[MT_NULL].height = mobjinfo[actor->type].height; + + if (P_RandomChance(FRACUNIT/2)) // port priority 1? + { + i = 9; + j = 27; + } + else + { + i = 27; + j = 9; + } + +#define dostuff(q) check = P_SpawnMobjFromMobj(actor, 0, 0, 0, MT_NULL);\ + testang = actor->angle + ((i+(q))*ANG10);\ + allow = (P_TryMove(check,\ + P_ReturnThrustX(check, testang, dist + 2*actor->radius),\ + P_ReturnThrustY(check, testang, dist + 2*actor->radius),\ + true));\ + P_RemoveMobj(check);\ + if (allow)\ + break; + + if (P_RandomChance(FRACUNIT/2)) // port priority 2? + { + for (k = 0; k < 9; k++) + { + dostuff(i+k) + dostuff(i-k) + dostuff(j+k) + dostuff(j-k) + } + } + else + { + for (k = 0; k < 9; k++) + { + dostuff(i-k) + dostuff(i+k) + dostuff(j-k) + dostuff(j+k) + } + } + actor->angle = testang; + +#undef dostuff + + mobjinfo[MT_NULL].spawnstate = oldspawnstate; + mobjinfo[MT_NULL].flags = oldflags; + mobjinfo[MT_NULL].radius = oldradius; + mobjinfo[MT_NULL].height = oldheight; + } an = actor->angle >> ANGLETOFINESHIFT; actor->momx = FixedMul(speed, FINECOSINE(an)); actor->momy = FixedMul(speed, FINESINE(an)); - dist = P_AproxDistance(dest->x - actor->x, dest->y - actor->y); dist = dist / speed; if (dist < 1) @@ -3442,11 +3523,13 @@ void A_Pain(mobj_t *actor) // // Description: Changes a dying object's flags to reflect its having fallen to the ground. // -// var1 = unused +// var1 = value to set repeat to if nonzero // var2 = unused // void A_Fall(mobj_t *actor) { + INT32 locvar1 = var1; + #ifdef HAVE_BLUA if (LUA_CallAction("A_Fall", actor)) return; @@ -3459,6 +3542,9 @@ void A_Fall(mobj_t *actor) // So change this if corpse objects // are meant to be obstacles. + + if (locvar1) + actor->extravalue2 = locvar1; } #define LIVESBOXDISPLAYPLAYER // Use displayplayer instead of closest player @@ -3854,6 +3940,72 @@ bossjustdie: else if (P_MobjWasRemoved(mo)) return; #endif + + // Spawn your junk + switch (mo->type) + { + default: + break; + case MT_EGGMOBILE: // twin laser pods + { + mo2 = P_SpawnMobjFromMobj(mo, + P_ReturnThrustX(mo, mo->angle - ANGLE_90, 32<angle - ANGLE_90, 32<angle = mo->angle; + P_InstaThrust(mo2, mo2->angle - ANGLE_90, 4*mo2->scale); + P_SetObjectMomZ(mo2, 4*FRACUNIT, false); + P_SetMobjState(mo2, S_BOSSEGLZ1); + + mo2 = P_SpawnMobjFromMobj(mo, + P_ReturnThrustX(mo, mo->angle + ANGLE_90, 32<angle + ANGLE_90, 32<angle = mo->angle; + P_InstaThrust(mo2, mo2->angle + ANGLE_90, 4*mo2->scale); + P_SetObjectMomZ(mo2, 4*FRACUNIT, false); + P_SetMobjState(mo2, S_BOSSEGLZ2); + } + break; + case MT_EGGMOBILE2: // twin tanks + spigot + { + mo2 = P_SpawnMobjFromMobj(mo, + P_ReturnThrustX(mo, mo->angle - ANGLE_90, 32<angle - ANGLE_90, 32<angle = mo->angle; + P_InstaThrust(mo2, mo2->angle - ANGLE_90, 4*mo2->scale); + P_SetObjectMomZ(mo2, 4*FRACUNIT, false); + P_SetMobjState(mo2, S_BOSSTANK1); + + mo2 = P_SpawnMobjFromMobj(mo, + P_ReturnThrustX(mo, mo->angle + ANGLE_90, 32<angle + ANGLE_90, 32<angle = mo->angle; + P_InstaThrust(mo2, mo2->angle + ANGLE_90, 4*mo2->scale); + P_SetObjectMomZ(mo2, 4*FRACUNIT, false); + P_SetMobjState(mo2, S_BOSSTANK2); + + mo2 = P_SpawnMobjFromMobj(mo, 0, 0, + mobjinfo[MT_EGGMOBILE2].height + (32<angle = mo->angle; + P_SetObjectMomZ(mo2, 4*FRACUNIT, false); + mo2->momz += mo->momz; + P_SetMobjState(mo2, S_BOSSSPIGOT); + } + break; + case MT_EGGMOBILE3: + { + mo2 = P_SpawnMobjFromMobj(mo, 0, 0, 0, MT_BOSSJUNK); + mo2->angle = mo->angle; + P_SetMobjState(mo2, S_BOSSSEBH1); + } + break; + } + + // now do another switch case for escaping switch (mo->type) { case MT_BLACKEGGMAN: @@ -3951,7 +4103,7 @@ bossjustdie: mo->movedir = 0; mo->extravalue1 = 35; mo->flags2 |= MF2_BOSSFLEE; - mo->momz = 2*mo->scale; + mo->momz = P_MobjFlip(mo)*2*mo->scale; if (mo->target) { @@ -3969,50 +4121,6 @@ bossjustdie: break; } } - - if (mo->type == MT_EGGMOBILE2) - { - mo2 = P_SpawnMobj(mo->x + P_ReturnThrustX(mo, mo->angle - ANGLE_90, FixedMul(32*FRACUNIT, mo->scale)), - mo->y + P_ReturnThrustY(mo, mo->angle - ANGLE_90, FixedMul(32*FRACUNIT, mo->scale)), - mo->z + mo->height/2 + ((mo->eflags & MFE_VERTICALFLIP)? FixedMul(8*FRACUNIT, mo->scale)-mobjinfo[MT_BOSSTANK1].height : -FixedMul(8*FRACUNIT, mo->scale)), MT_BOSSTANK1); // Right tank - mo2->angle = mo->angle; - mo2->destscale = mo->scale; - P_SetScale(mo2, mo2->destscale); - if (mo->eflags & MFE_VERTICALFLIP) - { - mo2->eflags |= MFE_VERTICALFLIP; - mo2->flags2 |= MF2_OBJECTFLIP; - } - P_InstaThrust(mo2, mo2->angle - ANGLE_90, FixedMul(4*FRACUNIT, mo2->scale)); - P_SetObjectMomZ(mo2, 4*FRACUNIT, false); - - mo2 = P_SpawnMobj(mo->x + P_ReturnThrustX(mo, mo->angle + ANGLE_90, FixedMul(32*FRACUNIT, mo->scale)), - mo->y + P_ReturnThrustY(mo, mo->angle + ANGLE_90, FixedMul(32*FRACUNIT, mo->scale)), - mo->z + mo->height/2 + ((mo->eflags & MFE_VERTICALFLIP)? FixedMul(8*FRACUNIT, mo->scale)-mobjinfo[MT_BOSSTANK2].height : -FixedMul(8*FRACUNIT, mo->scale)), MT_BOSSTANK2); // Left tank - mo2->angle = mo->angle; - mo2->destscale = mo->scale; - P_SetScale(mo2, mo2->destscale); - if (mo->eflags & MFE_VERTICALFLIP) - { - mo2->eflags |= MFE_VERTICALFLIP; - mo2->flags2 |= MF2_OBJECTFLIP; - } - P_InstaThrust(mo2, mo2->angle + ANGLE_90, FixedMul(4*FRACUNIT, mo2->scale)); - P_SetObjectMomZ(mo2, 4*FRACUNIT, false); - - mo2 = P_SpawnMobj(mo->x, mo->y, - mo->z + ((mo->eflags & MFE_VERTICALFLIP)? mobjinfo[MT_BOSSSPIGOT].height-FixedMul(32*FRACUNIT,mo->scale): mo->height + FixedMul(32*FRACUNIT, mo->scale)), MT_BOSSSPIGOT); - mo2->angle = mo->angle; - mo2->destscale = mo->scale; - P_SetScale(mo2, mo2->destscale); - if (mo->eflags & MFE_VERTICALFLIP) - { - mo2->eflags |= MFE_VERTICALFLIP; - mo2->flags2 |= MF2_OBJECTFLIP; - } - P_SetObjectMomZ(mo2, 4*FRACUNIT, false); - return; - } } // Function: A_CustomPower @@ -8699,7 +8807,7 @@ void A_SetObjectFlags2(mobj_t *actor) // // var1: // 0 - Triple jet fume pattern -// 1 - Boss 3's propeller +// 1 - Unused (formerly Boss 3's propeller) // 2 - Metal Sonic jet fume // 3 - Boss 4 jet flame // var2 = unused @@ -8759,7 +8867,7 @@ void A_BossJetFume(mobj_t *actor) P_SetTarget(&actor->tracer, filler); } - else if (locvar1 == 1) // Boss 3 propeller + /*else if (locvar1 == 1) // Boss 3 propeller { fixed_t jetx, jety, jetz; @@ -8779,14 +8887,14 @@ void A_BossJetFume(mobj_t *actor) filler->angle = actor->angle - ANGLE_180; P_SetTarget(&actor->tracer, filler); - } + }*/ else if (locvar1 == 2) // Metal Sonic jet fumes { filler = P_SpawnMobj(actor->x, actor->y, actor->z, MT_JETFUME1); P_SetTarget(&filler->target, actor); filler->fuse = 59; P_SetTarget(&actor->tracer, filler); - filler->destscale = actor->scale/2; + filler->destscale = actor->scale/3; P_SetScale(filler, filler->destscale); if (actor->eflags & MFE_VERTICALFLIP) filler->flags2 |= MF2_OBJECTFLIP; diff --git a/src/p_inter.c b/src/p_inter.c index 0030e8e58..ae610d0fc 100644 --- a/src/p_inter.c +++ b/src/p_inter.c @@ -2594,6 +2594,7 @@ void P_KillMobj(mobj_t *target, mobj_t *inflictor, mobj_t *source, UINT8 damaget case MT_EGGMOBILE3: { + mobj_t *mo2; thinker_t *th; UINT32 i = 0; // to check how many clones we've removed @@ -2614,6 +2615,11 @@ void P_KillMobj(mobj_t *target, mobj_t *inflictor, mobj_t *source, UINT8 damaget mo->scalespeed = (mo->scale - mo->destscale)/(2*TICRATE); mo->momz = mo->info->speed; mo->angle = FixedAngle((P_RandomKey(36)*10)<angle = mo->angle; + P_SetMobjState(mo2, S_BOSSSEBH2); + if (++i == 2) // we've already removed 2 of these, let's stop now break; else diff --git a/src/p_mobj.c b/src/p_mobj.c index 1ee90d250..e5edc99c4 100644 --- a/src/p_mobj.c +++ b/src/p_mobj.c @@ -4359,12 +4359,6 @@ static void P_Boss3Thinker(mobj_t *mobj) if (mobj->flags2 & MF2_FRET) mobj->movedir = 1; - if (!mobj->tracer) - { - var1 = 1; - A_BossJetFume(mobj); - } - if (mobj->health <= 0) return; /* @@ -4493,7 +4487,7 @@ static void P_Boss3Thinker(mobj_t *mobj) if (mobj->health <= mobj->info->damage) // pinch phase mobj->movecount--; // limited number of shots before diving again if (mobj->movecount) - P_SetMobjState(mobj, mobj->info->missilestate); + P_SetMobjState(mobj, mobj->info->missilestate+1); } } else if (mobj->threshold >= 0) // Traveling mode @@ -4592,6 +4586,15 @@ static void P_Boss3Thinker(mobj_t *mobj) ang += (ANGLE_MAX/64); } S_StartSound(mobj, sfx_fizzle); + + // look for a new target + P_BossTargetPlayer(mobj, false); + + if (mobj->target && mobj->target->player) + { + A_FaceTarget(mobj); + P_SetMobjState(mobj, mobj->info->missilestate); + } } else if (mobj->flags2 & (MF2_STRONGBOX|MF2_CLASSICPUSH)) // just hit the bottom of your tube { @@ -5527,8 +5530,7 @@ static void P_Boss9Thinker(mobj_t *mobj) mobj->tracer->destscale = FRACUNIT + (4*TICRATE - mobj->fuse)*(FRACUNIT/2)/TICRATE + FixedMul(FINECOSINE(angle>>ANGLETOFINESHIFT),FRACUNIT/2); P_SetScale(mobj->tracer, mobj->tracer->destscale); } - else - mobj->tracer->frame &= ~FF_TRANSMASK; // this causes a flicker but honestly i like it this way + P_TeleportMove(mobj->tracer, mobj->x, mobj->y, mobj->z + mobj->height/2 - mobj->tracer->height/2); mobj->tracer->momx = mobj->momx; mobj->tracer->momy = mobj->momy; @@ -5645,12 +5647,12 @@ static void P_Boss9Thinker(mobj_t *mobj) if (mobj->health > mobj->info->damage) { - P_SetScale(missile, FRACUNIT/2); + P_SetScale(missile, FRACUNIT/3); missile->color = SKINCOLOR_GOLD; // sonic cd electric power } else { - P_SetScale(missile, FRACUNIT/4); + P_SetScale(missile, FRACUNIT/5); missile->color = SKINCOLOR_MAGENTA; // sonic OVA/4 purple power } missile->destscale = missile->scale*2; @@ -5940,9 +5942,7 @@ static void P_Boss9Thinker(mobj_t *mobj) P_SetTarget(&mobj->tracer, shield); P_SetTarget(&shield->target, mobj); shield->height -= 20*FRACUNIT; // different offset... - shield->color = SKINCOLOR_MAGENTA; - shield->colorized = true; - P_SetMobjState(shield, S_FIRS1); + P_SetMobjState(shield, S_MSSHIELD_F2); //P_LinedefExecute(LE_PINCHPHASE, mobj, NULL); -- why does this happen twice? see case 2... } mobj->fuse = 4*TICRATE; @@ -7093,9 +7093,7 @@ void P_MobjThinker(mobj_t *mobj) switch (mobj->type) { - case MT_BOSSTANK1: - case MT_BOSSTANK2: - case MT_BOSSSPIGOT: + case MT_BOSSJUNK: mobj->flags2 ^= MF2_DONTDRAW; break; case MT_MACEPOINT: @@ -7681,12 +7679,22 @@ void P_MobjThinker(mobj_t *mobj) switch (mobj->type) { case MT_EGGMOBILE: - if (mobj->health < mobj->info->damage+1 && leveltime & 1 && mobj->health > 0) - P_SpawnMobj(mobj->x, mobj->y, mobj->z, MT_SMOKE); + if (mobj->health < mobj->info->damage+1 && leveltime & 2) + { + fixed_t rad = mobj->radius>>FRACBITS; + fixed_t hei = mobj->height>>FRACBITS; + mobj_t *particle = P_SpawnMobjFromMobj(mobj, + P_RandomRange(rad, -rad)<momz += mobj->momz; + } if (mobj->flags2 & MF2_SKULLFLY) #if 1 P_SpawnGhostMobj(mobj); -#else +#else // all the way back from final demo... MT_THOK isn't even the same size anymore! { mobj_t *spawnmobj; spawnmobj = P_SpawnMobj(mobj->x, mobj->y, mobj->z, mobj->info->painchance); @@ -7697,12 +7705,48 @@ void P_MobjThinker(mobj_t *mobj) P_Boss1Thinker(mobj); break; case MT_EGGMOBILE2: + if (mobj->health < mobj->info->damage+1 && leveltime & 2) + { + fixed_t rad = mobj->radius>>FRACBITS; + fixed_t hei = mobj->height>>FRACBITS; + mobj_t *particle = P_SpawnMobjFromMobj(mobj, + P_RandomRange(rad, -rad)<momz += mobj->momz; + } P_Boss2Thinker(mobj); break; case MT_EGGMOBILE3: + if (mobj->health < mobj->info->damage+1 && leveltime & 2) + { + fixed_t rad = mobj->radius>>FRACBITS; + fixed_t hei = mobj->height>>FRACBITS; + mobj_t *particle = P_SpawnMobjFromMobj(mobj, + P_RandomRange(rad, -rad)<momz += mobj->momz; + } P_Boss3Thinker(mobj); break; case MT_EGGMOBILE4: + if (mobj->health < mobj->info->damage+1 && leveltime & 2) + { + fixed_t rad = mobj->radius>>FRACBITS; + fixed_t hei = mobj->height>>FRACBITS; + mobj_t *particle = P_SpawnMobjFromMobj(mobj, + P_RandomRange(rad, -rad)<momz += mobj->momz; + } P_Boss4Thinker(mobj); break; case MT_FANG: @@ -8318,30 +8362,6 @@ void P_MobjThinker(mobj_t *mobj) mobj->fuse++; } break; - case MT_PROPELLER: - { - fixed_t jetx, jety; - - if (!mobj->target // if you have no target - || (!(mobj->target->flags & MF_BOSS) && mobj->target->health <= 0)) // or your target isn't a boss and it's popped now - { // then remove yourself as well! - P_RemoveMobj(mobj); - return; - } - - jetx = mobj->target->x + P_ReturnThrustX(mobj->target, mobj->target->angle, FixedMul(-60*FRACUNIT, mobj->target->scale)); - jety = mobj->target->y + P_ReturnThrustY(mobj->target, mobj->target->angle, FixedMul(-60*FRACUNIT, mobj->target->scale)); - - P_UnsetThingPosition(mobj); - mobj->x = jetx; - mobj->y = jety; - mobj->z = mobj->target->z + FixedMul(17*FRACUNIT, mobj->target->scale); - mobj->angle = mobj->target->angle - ANGLE_180; - mobj->floorz = mobj->z; - mobj->ceilingz = mobj->z+mobj->height; - P_SetThingPosition(mobj); - } - break; case MT_JETFLAME: { if (!mobj->target // if you have no target @@ -9038,9 +9058,9 @@ void P_MobjThinker(mobj_t *mobj) { if (mobj->state->action.acp1 == (actionf_p1)A_Boss1Laser) { - var1 = mobj->state->var1; - var2 = mobj->state->var2; - mobj->state->action.acp1(mobj); + /*var1 = mobj->state->var1; + var2 = mobj->state->var2 & 65535; + mobj->state->action.acp1(mobj);*/ } else if (leveltime & 1) // Fire mode { diff --git a/src/r_draw.c b/src/r_draw.c index d8b720caf..396ed0344 100644 --- a/src/r_draw.c +++ b/src/r_draw.c @@ -557,9 +557,16 @@ static void R_GenerateTranslationColormap(UINT8 *dest_colormap, INT32 skinnum, U // White! if (skinnum == TC_BOSS) - dest_colormap[31] = 0; + { + for (i = 0; i < 16; i++) + dest_colormap[31-i] = i; + } else if (skinnum == TC_METALSONIC) - dest_colormap[159] = 0; + { + for (i = 0; i < 6; i++) + dest_colormap[Color_Index[SKINCOLOR_BLUE-1][12-i]] = Color_Index[SKINCOLOR_BLUE-1][i]; + dest_colormap[159] = dest_colormap[253] = dest_colormap[254] = 0; + } return; } else if (color == SKINCOLOR_NONE) From fe99c64511c71553d9ac5b945439b9986fd73151 Mon Sep 17 00:00:00 2001 From: toaster Date: Sun, 1 Sep 2019 11:43:30 +0100 Subject: [PATCH 27/51] Give the Spectator Eggrobos the ability to move left and right relative to their angle, with initial direction depending on MTF_OBJECTSPECIAL/MTF_AMBUSH flag presence. (May need more tweaking before putting in CEZ3) --- src/p_mobj.c | 37 +++++++++++++++++++++---------------- 1 file changed, 21 insertions(+), 16 deletions(-) diff --git a/src/p_mobj.c b/src/p_mobj.c index e5edc99c4..1f42e3664 100644 --- a/src/p_mobj.c +++ b/src/p_mobj.c @@ -8425,6 +8425,17 @@ void P_MobjThinker(mobj_t *mobj) } else { + + fixed_t basex = mobj->cusval, basey = mobj->cvmem; + + if (mobj->spawnpoint && mobj->spawnpoint->options & (MTF_AMBUSH|MTF_OBJECTSPECIAL)) + { + angle_t sideang = mobj->movedir + ((mobj->spawnpoint->options & MTF_AMBUSH) ? ANGLE_90 : -ANGLE_90); + fixed_t oscillate = FixedMul(FINESINE(((leveltime*ANG1)>>(ANGLETOFINESHIFT+2)) & FINEMASK), 250*mobj->scale); + basex += P_ReturnThrustX(mobj, sideang, oscillate); + basey += P_ReturnThrustY(mobj, sideang, oscillate); + } + mobj->z = mobj->threshold + FixedMul(FINESINE(((leveltime + mobj->movecount)*ANG2>>(ANGLETOFINESHIFT-2)) & FINEMASK), 8*mobj->scale); if (mobj->state != &states[mobj->info->meleestate]) { @@ -8453,8 +8464,8 @@ void P_MobjThinker(mobj_t *mobj) if (players[i].mo->z + players[i].mo->height < mobj->z - 8*mobj->scale) continue; compdist = P_AproxDistance( - players[i].mo->x + players[i].mo->momx - mobj->cusval, - players[i].mo->y + players[i].mo->momy - mobj->cvmem); + players[i].mo->x + players[i].mo->momx - basex, + players[i].mo->y + players[i].mo->momy - basey); if (compdist >= dist) continue; dist = compdist; @@ -8468,14 +8479,14 @@ void P_MobjThinker(mobj_t *mobj) mobj->angle = R_PointToAngle2(mobj->x, mobj->y, mobj->target->x, mobj->target->y); if (P_AproxDistance( - mobj->x - mobj->cusval, - mobj->y - mobj->cvmem) + mobj->x - basex, + mobj->y - basey) < mobj->scale) S_StartSound(mobj, mobj->info->seesound); P_TeleportMove(mobj, - (15*(mobj->x>>4)) + (mobj->cusval>>4) + P_ReturnThrustX(mobj, mobj->angle, SPECTATORRADIUS>>4), - (15*(mobj->y>>4)) + (mobj->cvmem>>4) + P_ReturnThrustY(mobj, mobj->angle, SPECTATORRADIUS>>4), + (15*(mobj->x>>4)) + (basex>>4) + P_ReturnThrustX(mobj, mobj->angle, SPECTATORRADIUS>>4), + (15*(mobj->y>>4)) + (basey>>4) + P_ReturnThrustY(mobj, mobj->angle, SPECTATORRADIUS>>4), mobj->z); } else @@ -8498,18 +8509,12 @@ void P_MobjThinker(mobj_t *mobj) if (!didmove) { - if (P_AproxDistance( - mobj->x - mobj->cusval, - mobj->y - mobj->cvmem) - < mobj->scale) - P_TeleportMove(mobj, - mobj->cusval, - mobj->cvmem, - mobj->z); + if (P_AproxDistance(mobj->x - basex, mobj->y - basey) < mobj->scale) + P_TeleportMove(mobj, basex, basey, mobj->z); else P_TeleportMove(mobj, - (15*(mobj->x>>4)) + (mobj->cusval>>4), - (15*(mobj->y>>4)) + (mobj->cvmem>>4), + (15*(mobj->x>>4)) + (basex>>4), + (15*(mobj->y>>4)) + (basey>>4), mobj->z); } } From f6d2b5109b8a16f91b21fd0dcf9c169a825321d2 Mon Sep 17 00:00:00 2001 From: Jaime Passos Date: Tue, 3 Sep 2019 02:12:17 -0300 Subject: [PATCH 28/51] PRBoom sky dome --- src/hardware/hw_drv.h | 2 + src/hardware/hw_main.c | 182 +++++++++++++---------- src/hardware/hw_main.h | 1 + src/hardware/r_opengl/r_opengl.c | 243 +++++++++++++++++++++++++++++++ src/r_main.c | 1 + src/sdl/hwsym_sdl.c | 1 + src/sdl/i_video.c | 1 + src/v_video.c | 1 + src/win32/win_dll.c | 2 + 9 files changed, 361 insertions(+), 73 deletions(-) diff --git a/src/hardware/hw_drv.h b/src/hardware/hw_drv.h index e2fa90eb0..e0507bc70 100644 --- a/src/hardware/hw_drv.h +++ b/src/hardware/hw_drv.h @@ -47,6 +47,7 @@ EXPORT void HWRAPI(SetPalette) (RGBA_t *ppal, RGBA_t *pgamma); EXPORT void HWRAPI(FinishUpdate) (INT32 waitvbl); EXPORT void HWRAPI(Draw2DLine) (F2DCoord *v1, F2DCoord *v2, RGBA_t Color); EXPORT void HWRAPI(DrawPolygon) (FSurfaceInfo *pSurf, FOutVector *pOutVerts, FUINT iNumPts, FBITFIELD PolyFlags); +EXPORT void HWRAPI(RenderSkyDome) (INT32 tex, INT32 texture_width, INT32 texture_height, FTransform transform); EXPORT void HWRAPI(SetBlend) (FBITFIELD PolyFlags); EXPORT void HWRAPI(ClearBuffer) (FBOOLEAN ColorMask, FBOOLEAN DepthMask, FRGBAFloat *ClearColor); EXPORT void HWRAPI(SetTexture) (FTextureInfo *TexInfo); @@ -89,6 +90,7 @@ struct hwdriver_s FinishUpdate pfnFinishUpdate; Draw2DLine pfnDraw2DLine; DrawPolygon pfnDrawPolygon; + RenderSkyDome pfnRenderSkyDome; SetBlend pfnSetBlend; ClearBuffer pfnClearBuffer; SetTexture pfnSetTexture; diff --git a/src/hardware/hw_main.c b/src/hardware/hw_main.c index c600800fd..b326786f8 100644 --- a/src/hardware/hw_main.c +++ b/src/hardware/hw_main.c @@ -5805,86 +5805,122 @@ static void HWR_ProjectPrecipitationSprite(precipmobj_t *thing) // ========================================================================== // // ========================================================================== -static void HWR_DrawSkyBackground(void) +static void HWR_DrawSkyBackground(player_t *player) { - FOutVector v[4]; - angle_t angle; - float dimensionmultiply; - float aspectratio; - float angleturn; - - HWR_GetTexture(texturetranslation[skytexture]); - aspectratio = (float)vid.width/(float)vid.height; - - //Hurdler: the sky is the only texture who need 4.0f instead of 1.0 - // because it's called just after clearing the screen - // and thus, the near clipping plane is set to 3.99 - // Sryder: Just use the near clipping plane value then - - // 3--2 - // | /| - // |/ | - // 0--1 - v[0].x = v[3].x = -ZCLIP_PLANE-1; - v[1].x = v[2].x = ZCLIP_PLANE+1; - v[0].y = v[1].y = -ZCLIP_PLANE-1; - v[2].y = v[3].y = ZCLIP_PLANE+1; - - v[0].z = v[1].z = v[2].z = v[3].z = ZCLIP_PLANE+1; - - // X - - // NOTE: This doesn't work right with texture widths greater than 1024 - // software doesn't draw any further than 1024 for skies anyway, but this doesn't overlap properly - // The only time this will probably be an issue is when a sky wider than 1024 is used as a sky AND a regular wall texture - - angle = (dup_viewangle + gr_xtoviewangle[0]); - - dimensionmultiply = ((float)textures[texturetranslation[skytexture]]->width/256.0f); - - v[0].sow = v[3].sow = (-1.0f * angle) / ((ANGLE_90-1)*dimensionmultiply); // left - v[2].sow = v[1].sow = v[0].sow + (1.0f/dimensionmultiply); // right (or left + 1.0f) - // use +angle and -1.0f above instead if you wanted old backwards behavior - - // Y - angle = aimingangle; - dimensionmultiply = ((float)textures[texturetranslation[skytexture]]->height/(128.0f*aspectratio)); - - if (splitscreen) + if (cv_grskydome.value) { - dimensionmultiply *= 2; - angle *= 2; - } + FTransform transform; + const float fpov = FIXED_TO_FLOAT(cv_grfov.value+player->fovadd); + postimg_t *type; - // Middle of the sky should always be at angle 0 - // need to keep correct aspect ratio with X - if (atransform.flip) - { - // During vertical flip the sky should be flipped and it's y movement should also be flipped obviously - v[3].tow = v[2].tow = -(0.5f-(0.5f/dimensionmultiply)); // top - v[0].tow = v[1].tow = v[3].tow - (1.0f/dimensionmultiply); // bottom (or top - 1.0f) + if (splitscreen && player == &players[secondarydisplayplayer]) + type = &postimgtype2; + else + type = &postimgtype; + + memset(&transform, 0x00, sizeof(FTransform)); + + //04/01/2000: Hurdler: added for T&L + // It should replace all other gr_viewxxx when finished + transform.anglex = (float)(aimingangle>>ANGLETOFINESHIFT)*(360.0f/(float)FINEANGLES); + transform.angley = (float)((viewangle-ANGLE_270)>>ANGLETOFINESHIFT)*(360.0f/(float)FINEANGLES); + + if (*type == postimg_flip) + transform.flip = true; + else + transform.flip = false; + + transform.scalex = 1; + transform.scaley = (float)vid.width/vid.height; + transform.scalez = 1; + transform.fovxangle = fpov; // Tails + transform.fovyangle = fpov; // Tails + transform.splitscreen = splitscreen; + + HWR_GetTexture(texturetranslation[skytexture]); + HWD.pfnRenderSkyDome(skytexture, textures[skytexture]->width, textures[skytexture]->height, transform); } else { - v[0].tow = v[1].tow = -(0.5f-(0.5f/dimensionmultiply)); // bottom - v[3].tow = v[2].tow = v[0].tow - (1.0f/dimensionmultiply); // top (or bottom - 1.0f) - } + FOutVector v[4]; + angle_t angle; + float dimensionmultiply; + float aspectratio; + float angleturn; - angleturn = (((float)ANGLE_45-1.0f)*aspectratio)*dimensionmultiply; + HWR_GetTexture(texturetranslation[skytexture]); + aspectratio = (float)vid.width/(float)vid.height; - if (angle > ANGLE_180) // Do this because we don't want the sky to suddenly teleport when crossing over 0 to 360 and vice versa - { - angle = InvAngle(angle); - v[3].tow = v[2].tow += ((float) angle / angleturn); - v[0].tow = v[1].tow += ((float) angle / angleturn); - } - else - { - v[3].tow = v[2].tow -= ((float) angle / angleturn); - v[0].tow = v[1].tow -= ((float) angle / angleturn); - } + //Hurdler: the sky is the only texture who need 4.0f instead of 1.0 + // because it's called just after clearing the screen + // and thus, the near clipping plane is set to 3.99 + // Sryder: Just use the near clipping plane value then - HWD.pfnDrawPolygon(NULL, v, 4, 0); + // 3--2 + // | /| + // |/ | + // 0--1 + v[0].x = v[3].x = -ZCLIP_PLANE-1; + v[1].x = v[2].x = ZCLIP_PLANE+1; + v[0].y = v[1].y = -ZCLIP_PLANE-1; + v[2].y = v[3].y = ZCLIP_PLANE+1; + + v[0].z = v[1].z = v[2].z = v[3].z = ZCLIP_PLANE+1; + + // X + + // NOTE: This doesn't work right with texture widths greater than 1024 + // software doesn't draw any further than 1024 for skies anyway, but this doesn't overlap properly + // The only time this will probably be an issue is when a sky wider than 1024 is used as a sky AND a regular wall texture + + angle = (dup_viewangle + gr_xtoviewangle[0]); + + dimensionmultiply = ((float)textures[texturetranslation[skytexture]]->width/256.0f); + + v[0].sow = v[3].sow = (-1.0f * angle) / ((ANGLE_90-1)*dimensionmultiply); // left + v[2].sow = v[1].sow = v[0].sow + (1.0f/dimensionmultiply); // right (or left + 1.0f) + // use +angle and -1.0f above instead if you wanted old backwards behavior + + // Y + angle = aimingangle; + dimensionmultiply = ((float)textures[texturetranslation[skytexture]]->height/(128.0f*aspectratio)); + + if (splitscreen) + { + dimensionmultiply *= 2; + angle *= 2; + } + + // Middle of the sky should always be at angle 0 + // need to keep correct aspect ratio with X + if (atransform.flip) + { + // During vertical flip the sky should be flipped and it's y movement should also be flipped obviously + v[3].tow = v[2].tow = -(0.5f-(0.5f/dimensionmultiply)); // top + v[0].tow = v[1].tow = v[3].tow - (1.0f/dimensionmultiply); // bottom (or top - 1.0f) + } + else + { + v[0].tow = v[1].tow = -(0.5f-(0.5f/dimensionmultiply)); // bottom + v[3].tow = v[2].tow = v[0].tow - (1.0f/dimensionmultiply); // top (or bottom - 1.0f) + } + + angleturn = (((float)ANGLE_45-1.0f)*aspectratio)*dimensionmultiply; + + if (angle > ANGLE_180) // Do this because we don't want the sky to suddenly teleport when crossing over 0 to 360 and vice versa + { + angle = InvAngle(angle); + v[3].tow = v[2].tow += ((float) angle / angleturn); + v[0].tow = v[1].tow += ((float) angle / angleturn); + } + else + { + v[3].tow = v[2].tow -= ((float) angle / angleturn); + v[0].tow = v[1].tow -= ((float) angle / angleturn); + } + + HWD.pfnDrawPolygon(NULL, v, 4, 0); + } } @@ -6036,7 +6072,7 @@ if (0) } if (drawsky) - HWR_DrawSkyBackground(); + HWR_DrawSkyBackground(player); //Hurdler: it doesn't work in splitscreen mode drawsky = splitscreen; @@ -6253,7 +6289,7 @@ if (0) } if (!skybox && drawsky) // Don't draw the regular sky if there's a skybox - HWR_DrawSkyBackground(); + HWR_DrawSkyBackground(player); //Hurdler: it doesn't work in splitscreen mode drawsky = splitscreen; diff --git a/src/hardware/hw_main.h b/src/hardware/hw_main.h index f8524990f..31e97cc13 100644 --- a/src/hardware/hw_main.h +++ b/src/hardware/hw_main.h @@ -98,6 +98,7 @@ extern consvar_t cv_voodoocompatibility; extern consvar_t cv_grfovchange; extern consvar_t cv_grsolvetjoin; extern consvar_t cv_grspritebillboarding; +extern consvar_t cv_grskydome; extern float gr_viewwidth, gr_viewheight, gr_baseviewwindowy; diff --git a/src/hardware/r_opengl/r_opengl.c b/src/hardware/r_opengl/r_opengl.c index dfee19857..ae6ff7d09 100644 --- a/src/hardware/r_opengl/r_opengl.c +++ b/src/hardware/r_opengl/r_opengl.c @@ -1427,6 +1427,249 @@ EXPORT void HWRAPI(DrawPolygon) (FSurfaceInfo *pSurf, Clamp2D(GL_TEXTURE_WRAP_T); } +// PRBoom sky dome +typedef struct vbo_vertex_s +{ + float x, y, z; + float u, v; + unsigned char r, g, b, a; +} vbo_vertex_t; + +typedef struct +{ + int mode; + int vertexcount; + int vertexindex; + int use_texture; +} GLSkyLoopDef; + +typedef struct +{ + int id; + int rows, columns; + int loopcount; + GLSkyLoopDef *loops; + vbo_vertex_t *data; +} GLSkyVBO; + +// The texture offset to be applied to the texture coordinates in SkyVertex(). +static int rows, columns; +static boolean yflip; +static int texw, texh; +static float yAdd; +static boolean foglayer; +static float delta = 0.0f; +static int gl_sky_detail = 16; +static INT32 lasttex = -1; + +static RGBA_t SkyColor; + +#define MAP_COEFF 128.0f +#define MAP_SCALE (MAP_COEFF*(float)FRACUNIT) + +static void SkyVertex(vbo_vertex_t *vbo, int r, int c) +{ + static fixed_t scale = 10000 << FRACBITS; + static angle_t maxSideAngle = ANGLE_180 / 3; + + angle_t topAngle = (angle_t)(c / (float)columns * ANGLE_MAX); + angle_t sideAngle = maxSideAngle * (rows - r) / rows; + fixed_t height = FINESINE(sideAngle>>ANGLETOFINESHIFT); + fixed_t realRadius = FixedMul(scale, FINECOSINE(sideAngle>>ANGLETOFINESHIFT)); + fixed_t x = FixedMul(realRadius, FINECOSINE(topAngle>>ANGLETOFINESHIFT)); + fixed_t y = (!yflip) ? FixedMul(scale, height) : FixedMul(scale, height) * -1; + fixed_t z = FixedMul(realRadius, FINESINE(topAngle>>ANGLETOFINESHIFT)); + float timesRepeat; + + timesRepeat = (short)(4 * (256.0f / texw)); + if (timesRepeat == 0.0f) + timesRepeat = 1.0f; + + if (!foglayer) + { + vbo->r = 255; + vbo->g = 255; + vbo->b = 255; + vbo->a = (r == 0 ? 0 : 255); + + // And the texture coordinates. + if (!yflip) // Flipped Y is for the lower hemisphere. + { + vbo->u = (-timesRepeat * c / (float)columns); + vbo->v = (r / (float)rows) * 1.f + yAdd; + } + else + { + vbo->u = (-timesRepeat * c / (float)columns); + vbo->v = ((rows-r)/(float)rows) * 1.f + yAdd; + } + + //if (SkyBox.wall.flag == GLDWF_SKYFLIP) + // vbo->u = -vbo->u; + } + + if (r != 4) + y += FRACUNIT * 300; + + // And finally the vertex. + vbo->x = (float)x/(float)MAP_SCALE; + vbo->y = (float)y/(float)MAP_SCALE + delta; + vbo->z = (float)z/(float)MAP_SCALE; +} + +GLSkyVBO sky_vbo; + +static void gld_BuildSky(int row_count, int col_count) +{ + int c, r; + vbo_vertex_t *vertex_p; + int vertex_count = 2 * row_count * (col_count * 2 + 2) + col_count * 2; + + GLSkyVBO *vbo = &sky_vbo; + + if ((vbo->columns != col_count) || (vbo->rows != row_count)) + { + free(vbo->loops); + free(vbo->data); + memset(vbo, 0, sizeof(&vbo)); + } + + if (!vbo->data) + { + memset(vbo, 0, sizeof(&vbo)); + vbo->loops = malloc((row_count * 2 + 2) * sizeof(vbo->loops[0])); + // create vertex array + vbo->data = malloc(vertex_count * sizeof(vbo->data[0])); + } + + vbo->columns = col_count; + vbo->rows = row_count; + + vertex_p = &vbo->data[0]; + vbo->loopcount = 0; + + memset(&SkyColor, 0xFF, sizeof(SkyColor)); + + for (yflip = 0; yflip < 2; yflip++) + { + vbo->loops[vbo->loopcount].mode = GL_TRIANGLE_FAN; + vbo->loops[vbo->loopcount].vertexindex = vertex_p - &vbo->data[0]; + vbo->loops[vbo->loopcount].vertexcount = col_count; + vbo->loops[vbo->loopcount].use_texture = false; + vbo->loopcount++; + + yAdd = 0.5f; + /*if (yflip == 0) + SkyColor = &sky->CeilingSkyColor[vbo_idx]; + else + SkyColor = &sky->FloorSkyColor[vbo_idx];*/ + + delta = 0.0f; + foglayer = true; + for (c = 0; c < col_count; c++) + { + SkyVertex(vertex_p, 1, c); + vertex_p->r = SkyColor.s.red; + vertex_p->g = SkyColor.s.green; + vertex_p->b = SkyColor.s.blue; + vertex_p->a = 255; + vertex_p++; + } + foglayer = false; + + delta = (yflip ? 5.0f : -5.0f) / MAP_COEFF; + + for (r = 0; r < row_count; r++) + { + vbo->loops[vbo->loopcount].mode = GL_TRIANGLE_STRIP; + vbo->loops[vbo->loopcount].vertexindex = vertex_p - &vbo->data[0]; + vbo->loops[vbo->loopcount].vertexcount = 2 * col_count + 2; + vbo->loops[vbo->loopcount].use_texture = true; + vbo->loopcount++; + + for (c = 0; c <= col_count; c++) + { + SkyVertex(vertex_p++, r + (yflip ? 1 : 0), (c ? c : 0)); + SkyVertex(vertex_p++, r + (yflip ? 0 : 1), (c ? c : 0)); + } + } + } +} + +static void RenderDomeForReal(INT32 skytexture) +{ + int i, j; + GLSkyVBO *vbo = &sky_vbo; + + //pglRotatef(-180.0f + sky->x_offset, 0.f, 1.f, 0.f); + pglRotatef(-180.0f, 0.f, 1.f, 0.f); + + rows = 4; + columns = 4 * gl_sky_detail; + + if (lasttex != skytexture) + { + lasttex = skytexture; + gld_BuildSky(rows, columns); + } + + pglScalef(1.0f, (float)texh / 230.0f, 1.0f); + + for (j = 0; j < 2; j++) + { + //gld_EnableTexture2D(GL_TEXTURE0_ARB, j != 0); + for (i = 0; i < vbo->loopcount; i++) + { + GLSkyLoopDef *loop = &vbo->loops[i]; + + if (j == 0 ? loop->use_texture : !loop->use_texture) + continue; + else + { + int k; + pglBegin(loop->mode); + for (k = loop->vertexindex; k < (loop->vertexindex + loop->vertexcount); k++) + { + vbo_vertex_t *v = &vbo->data[k]; + if (loop->use_texture) + pglTexCoord2f(v->u, v->v); + pglColor4f(v->r, v->g, v->b, v->a); + pglVertex3f(v->x, v->y, v->z); + } + pglEnd(); + } + } + } + + pglScalef(1.0f, 1.0f, 1.0f); + + // current color is undefined after glDrawArrays + pglColor4f(1.0f, 1.0f, 1.0f, 1.0f); +} + +EXPORT void HWRAPI(RenderSkyDome) (INT32 tex, INT32 texture_width, INT32 texture_height, FTransform transform) +{ + GLint shading_mode = GL_FLAT; + pglGetIntegerv(GL_SHADE_MODEL, &shading_mode); + pglShadeModel(GL_SMOOTH); + + pglDepthMask(false); + pglDisable(GL_DEPTH_TEST); + pglDisable(GL_ALPHA_TEST); + + SetBlend(PF_Translucent|PF_Clip|PF_NoZClip|PF_NoDepthTest|PF_Modulated); + + texw = texture_width; + texh = texture_height; + SetTransform(&transform); + RenderDomeForReal(tex); + + pglEnable(GL_ALPHA_TEST); + pglEnable(GL_DEPTH_TEST); + pglDepthMask(true); + + pglShadeModel(shading_mode); +} // ========================================================================== // diff --git a/src/r_main.c b/src/r_main.c index db351e991..5135e57ce 100644 --- a/src/r_main.c +++ b/src/r_main.c @@ -1215,6 +1215,7 @@ void R_RegisterEngineStuff(void) #endif CV_RegisterVar(&cv_grmd2); CV_RegisterVar(&cv_grspritebillboarding); + CV_RegisterVar(&cv_grskydome); #endif #ifdef HWRENDER diff --git a/src/sdl/hwsym_sdl.c b/src/sdl/hwsym_sdl.c index 05ac6450e..103398405 100644 --- a/src/sdl/hwsym_sdl.c +++ b/src/sdl/hwsym_sdl.c @@ -79,6 +79,7 @@ void *hwSym(const char *funcName,void *handle) GETFUNC(Init); GETFUNC(Draw2DLine); GETFUNC(DrawPolygon); + GETFUNC(RenderSkyDome); GETFUNC(SetBlend); GETFUNC(ClearBuffer); GETFUNC(SetTexture); diff --git a/src/sdl/i_video.c b/src/sdl/i_video.c index 5a4fd7a02..b526e6124 100644 --- a/src/sdl/i_video.c +++ b/src/sdl/i_video.c @@ -1499,6 +1499,7 @@ void I_StartupGraphics(void) HWD.pfnFinishUpdate = NULL; HWD.pfnDraw2DLine = hwSym("Draw2DLine",NULL); HWD.pfnDrawPolygon = hwSym("DrawPolygon",NULL); + HWD.pfnRenderSkyDome = hwSym("RenderSkyDome",NULL); HWD.pfnSetBlend = hwSym("SetBlend",NULL); HWD.pfnClearBuffer = hwSym("ClearBuffer",NULL); HWD.pfnSetTexture = hwSym("SetTexture",NULL); diff --git a/src/v_video.c b/src/v_video.c index 2ec06a787..2dbb21bb3 100644 --- a/src/v_video.c +++ b/src/v_video.c @@ -112,6 +112,7 @@ static CV_PossibleValue_t CV_MD2[] = {{0, "Off"}, {1, "On"}, {2, "Old"}, {0, NUL // console variables in development consvar_t cv_grmd2 = {"gr_md2", "Off", CV_SAVE, CV_MD2, NULL, 0, NULL, NULL, 0, 0, NULL}; consvar_t cv_grspritebillboarding = {"gr_spritebillboarding", "Off", CV_SAVE, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL}; +consvar_t cv_grskydome = {"gr_skydome", "On", CV_SAVE, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL}; #endif // local copy of the palette for V_GetColor() diff --git a/src/win32/win_dll.c b/src/win32/win_dll.c index 71eda0437..ce007af25 100644 --- a/src/win32/win_dll.c +++ b/src/win32/win_dll.c @@ -102,6 +102,7 @@ static loadfunc_t hwdFuncTable[] = { {"FinishUpdate@4", &hwdriver.pfnFinishUpdate}, {"Draw2DLine@12", &hwdriver.pfnDraw2DLine}, {"DrawPolygon@16", &hwdriver.pfnDrawPolygon}, + {"RenderSkyDome@16", &hwdriver.pfnRenderDome}, {"SetBlend@4", &hwdriver.pfnSetBlend}, {"ClearBuffer@12", &hwdriver.pfnClearBuffer}, {"SetTexture@4", &hwdriver.pfnSetTexture}, @@ -133,6 +134,7 @@ static loadfunc_t hwdFuncTable[] = { {"FinishUpdate", &hwdriver.pfnFinishUpdate}, {"Draw2DLine", &hwdriver.pfnDraw2DLine}, {"DrawPolygon", &hwdriver.pfnDrawPolygon}, + {"RenderSkyDome", &hwdriver.pfnRenderDome}, {"SetBlend", &hwdriver.pfnSetBlend}, {"ClearBuffer", &hwdriver.pfnClearBuffer}, {"SetTexture", &hwdriver.pfnSetTexture}, From f0b4a609a819d7925e0aaba3f86a57dcb2fb9fd9 Mon Sep 17 00:00:00 2001 From: Jaime Passos Date: Tue, 3 Sep 2019 23:44:04 -0300 Subject: [PATCH 29/51] Very tiny fix --- src/hardware/r_opengl/r_opengl.c | 19 ++++--------------- 1 file changed, 4 insertions(+), 15 deletions(-) diff --git a/src/hardware/r_opengl/r_opengl.c b/src/hardware/r_opengl/r_opengl.c index ae6ff7d09..a44556f1d 100644 --- a/src/hardware/r_opengl/r_opengl.c +++ b/src/hardware/r_opengl/r_opengl.c @@ -1649,26 +1649,15 @@ static void RenderDomeForReal(INT32 skytexture) EXPORT void HWRAPI(RenderSkyDome) (INT32 tex, INT32 texture_width, INT32 texture_height, FTransform transform) { - GLint shading_mode = GL_FLAT; - pglGetIntegerv(GL_SHADE_MODEL, &shading_mode); - pglShadeModel(GL_SMOOTH); - - pglDepthMask(false); - pglDisable(GL_DEPTH_TEST); - pglDisable(GL_ALPHA_TEST); - - SetBlend(PF_Translucent|PF_Clip|PF_NoZClip|PF_NoDepthTest|PF_Modulated); + SetBlend(PF_Translucent|PF_NoDepthTest|PF_Modulated); + SetTransform(&transform); texw = texture_width; texh = texture_height; - SetTransform(&transform); RenderDomeForReal(tex); - pglEnable(GL_ALPHA_TEST); - pglEnable(GL_DEPTH_TEST); - pglDepthMask(true); - - pglShadeModel(shading_mode); + // HWR_DrawSkyBackground left no blend flags after rendering the sky + SetBlend(0); } // ========================================================================== From c6f3e4d53dd3bbd9b330e9930bf3a1f572d8d327 Mon Sep 17 00:00:00 2001 From: Jaime Passos Date: Wed, 4 Sep 2019 13:59:09 -0300 Subject: [PATCH 30/51] Make sky dome look a bit better --- src/hardware/r_opengl/r_opengl.c | 33 ++++++++++++++------------------ 1 file changed, 14 insertions(+), 19 deletions(-) diff --git a/src/hardware/r_opengl/r_opengl.c b/src/hardware/r_opengl/r_opengl.c index a44556f1d..5b2dffc1a 100644 --- a/src/hardware/r_opengl/r_opengl.c +++ b/src/hardware/r_opengl/r_opengl.c @@ -1456,7 +1456,7 @@ typedef struct static int rows, columns; static boolean yflip; static int texw, texh; -static float yAdd; +static float yMult, yAdd; static boolean foglayer; static float delta = 0.0f; static int gl_sky_detail = 16; @@ -1487,30 +1487,24 @@ static void SkyVertex(vbo_vertex_t *vbo, int r, int c) if (!foglayer) { + boolean flip = yflip; vbo->r = 255; vbo->g = 255; vbo->b = 255; vbo->a = (r == 0 ? 0 : 255); + // Flip Y coordinate anyway for the top part of the hemisphere + if (r <= 1) + flip = !flip; + // And the texture coordinates. - if (!yflip) // Flipped Y is for the lower hemisphere. - { - vbo->u = (-timesRepeat * c / (float)columns); - vbo->v = (r / (float)rows) * 1.f + yAdd; - } + vbo->u = (-timesRepeat * c / (float)columns); + if (!flip) // Flipped Y is for the lower hemisphere. + vbo->v = (r / (float)rows) * 1.f * yMult + yAdd; else - { - vbo->u = (-timesRepeat * c / (float)columns); - vbo->v = ((rows-r)/(float)rows) * 1.f + yAdd; - } - - //if (SkyBox.wall.flag == GLDWF_SKYFLIP) - // vbo->u = -vbo->u; + vbo->v = ((rows-r)/(float)rows) * 1.f * yMult + yAdd; } - if (r != 4) - y += FRACUNIT * 300; - // And finally the vertex. vbo->x = (float)x/(float)MAP_SCALE; vbo->y = (float)y/(float)MAP_SCALE + delta; @@ -1550,7 +1544,8 @@ static void gld_BuildSky(int row_count, int col_count) memset(&SkyColor, 0xFF, sizeof(SkyColor)); - for (yflip = 0; yflip < 2; yflip++) + // Why not? + for (yflip = false; yflip <= true; yflip++) { vbo->loops[vbo->loopcount].mode = GL_TRIANGLE_FAN; vbo->loops[vbo->loopcount].vertexindex = vertex_p - &vbo->data[0]; @@ -1559,6 +1554,7 @@ static void gld_BuildSky(int row_count, int col_count) vbo->loopcount++; yAdd = 0.5f; + yMult = 1.0f; /*if (yflip == 0) SkyColor = &sky->CeilingSkyColor[vbo_idx]; else @@ -1584,7 +1580,7 @@ static void gld_BuildSky(int row_count, int col_count) vbo->loops[vbo->loopcount].mode = GL_TRIANGLE_STRIP; vbo->loops[vbo->loopcount].vertexindex = vertex_p - &vbo->data[0]; vbo->loops[vbo->loopcount].vertexcount = 2 * col_count + 2; - vbo->loops[vbo->loopcount].use_texture = true; + vbo->loops[vbo->loopcount].use_texture = true; //(r > 1) ? true : false; vbo->loopcount++; for (c = 0; c <= col_count; c++) @@ -1617,7 +1613,6 @@ static void RenderDomeForReal(INT32 skytexture) for (j = 0; j < 2; j++) { - //gld_EnableTexture2D(GL_TEXTURE0_ARB, j != 0); for (i = 0; i < vbo->loopcount; i++) { GLSkyLoopDef *loop = &vbo->loops[i]; From 6aedca899f7410633050462b841dd9b2c96dc176 Mon Sep 17 00:00:00 2001 From: Jaime Passos Date: Thu, 5 Sep 2019 17:42:36 -0300 Subject: [PATCH 31/51] 2.2 skies aren't flipped --- src/hardware/r_opengl/r_opengl.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/hardware/r_opengl/r_opengl.c b/src/hardware/r_opengl/r_opengl.c index 5b2dffc1a..2fe6741e2 100644 --- a/src/hardware/r_opengl/r_opengl.c +++ b/src/hardware/r_opengl/r_opengl.c @@ -1597,8 +1597,7 @@ static void RenderDomeForReal(INT32 skytexture) int i, j; GLSkyVBO *vbo = &sky_vbo; - //pglRotatef(-180.0f + sky->x_offset, 0.f, 1.f, 0.f); - pglRotatef(-180.0f, 0.f, 1.f, 0.f); + pglRotatef(270.f, 0.f, 1.f, 0.f); rows = 4; columns = 4 * gl_sky_detail; From 2a85ed0bdd2a9505a03d41d04871af51d6de340b Mon Sep 17 00:00:00 2001 From: Jaime Passos Date: Fri, 6 Sep 2019 19:26:05 -0300 Subject: [PATCH 32/51] test --- src/hardware/hw_main.c | 4 ++-- src/r_plane.c | 2 -- 2 files changed, 2 insertions(+), 4 deletions(-) diff --git a/src/hardware/hw_main.c b/src/hardware/hw_main.c index 62e77ae77..0df79c415 100644 --- a/src/hardware/hw_main.c +++ b/src/hardware/hw_main.c @@ -3700,7 +3700,7 @@ static void HWR_Subsector(size_t num) 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, levelflats[*rover->bottompic].texturenum, - rover->master->frontsector, 255, false, gr_frontsector->lightlist[light].extra_colormap); + rover->master->frontsector, 255, false, *gr_frontsector->lightlist[light].extra_colormap); } } @@ -3766,7 +3766,7 @@ static void HWR_Subsector(size_t num) 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, levelflats[*rover->toppic].texturenum, - rover->master->frontsector, 255, false, gr_frontsector->lightlist[light].extra_colormap); + rover->master->frontsector, 255, false, *gr_frontsector->lightlist[light].extra_colormap); } } } diff --git a/src/r_plane.c b/src/r_plane.c index 645405b53..57c8079f1 100644 --- a/src/r_plane.c +++ b/src/r_plane.c @@ -1010,8 +1010,6 @@ void R_DrawSinglePlane(visplane_t *pl) if (ds_powersoftwo) { - - } if (hack) { /* From 02a7d8e0a2ec70f71e0a0ac5fd22c4faeece433a Mon Sep 17 00:00:00 2001 From: Jaime Passos Date: Fri, 6 Sep 2019 19:37:07 -0300 Subject: [PATCH 33/51] Fix tilted spans. --- src/r_draw8.c | 48 ++++++++++++++++++++++++------------------------ 1 file changed, 24 insertions(+), 24 deletions(-) diff --git a/src/r_draw8.c b/src/r_draw8.c index 1c4527a8e..77406f83c 100644 --- a/src/r_draw8.c +++ b/src/r_draw8.c @@ -726,8 +726,8 @@ void R_DrawTiltedSpan_8(void) if (!ds_powersoftwo) { - fixed_t x = ((u-viewx) >> FRACBITS); - fixed_t y = ((v-viewy) >> FRACBITS); + fixed_t x = (((fixed_t)u-viewx) >> FRACBITS); + fixed_t y = (((fixed_t)v-viewy) >> FRACBITS); // Carefully align all of my Friends. if (x < 0) @@ -780,8 +780,8 @@ void R_DrawTiltedSpan_8(void) colormap = planezlight[tiltlighting[ds_x1++]] + (ds_colormap - colormaps); if (!ds_powersoftwo) { - fixed_t x = ((u-viewx) >> FRACBITS); - fixed_t y = ((v-viewy) >> FRACBITS); + fixed_t x = (((fixed_t)u-viewx) >> FRACBITS); + fixed_t y = (((fixed_t)v-viewy) >> FRACBITS); // Carefully align all of my Friends. if (x < 0) @@ -813,8 +813,8 @@ void R_DrawTiltedSpan_8(void) colormap = planezlight[tiltlighting[ds_x1++]] + (ds_colormap - colormaps); if (!ds_powersoftwo) { - fixed_t x = ((u-viewx) >> FRACBITS); - fixed_t y = ((v-viewy) >> FRACBITS); + fixed_t x = (((fixed_t)u-viewx) >> FRACBITS); + fixed_t y = (((fixed_t)v-viewy) >> FRACBITS); // Carefully align all of my Friends. if (x < 0) @@ -851,8 +851,8 @@ void R_DrawTiltedSpan_8(void) colormap = planezlight[tiltlighting[ds_x1++]] + (ds_colormap - colormaps); if (!ds_powersoftwo) { - fixed_t x = ((u-viewx) >> FRACBITS); - fixed_t y = ((v-viewy) >> FRACBITS); + fixed_t x = (((fixed_t)u-viewx) >> FRACBITS); + fixed_t y = (((fixed_t)v-viewy) >> FRACBITS); // Carefully align all of my Friends. if (x < 0) @@ -929,8 +929,8 @@ void R_DrawTiltedTranslucentSpan_8(void) colormap = planezlight[tiltlighting[ds_x1++]] + (ds_colormap - colormaps); if (!ds_powersoftwo) { - fixed_t x = ((u-viewx) >> FRACBITS); - fixed_t y = ((v-viewy) >> FRACBITS); + fixed_t x = (((fixed_t)u-viewx) >> FRACBITS); + fixed_t y = (((fixed_t)v-viewy) >> FRACBITS); // Carefully align all of my Friends. if (x < 0) @@ -983,8 +983,8 @@ void R_DrawTiltedTranslucentSpan_8(void) colormap = planezlight[tiltlighting[ds_x1++]] + (ds_colormap - colormaps); if (!ds_powersoftwo) { - fixed_t x = ((u-viewx) >> FRACBITS); - fixed_t y = ((v-viewy) >> FRACBITS); + fixed_t x = (((fixed_t)u-viewx) >> FRACBITS); + fixed_t y = (((fixed_t)v-viewy) >> FRACBITS); // Carefully align all of my Friends. if (x < 0) @@ -1016,8 +1016,8 @@ void R_DrawTiltedTranslucentSpan_8(void) colormap = planezlight[tiltlighting[ds_x1++]] + (ds_colormap - colormaps); if (!ds_powersoftwo) { - fixed_t x = ((u-viewx) >> FRACBITS); - fixed_t y = ((v-viewy) >> FRACBITS); + fixed_t x = (((fixed_t)u-viewx) >> FRACBITS); + fixed_t y = (((fixed_t)v-viewy) >> FRACBITS); // Carefully align all of my Friends. if (x < 0) @@ -1054,8 +1054,8 @@ void R_DrawTiltedTranslucentSpan_8(void) colormap = planezlight[tiltlighting[ds_x1++]] + (ds_colormap - colormaps); if (!ds_powersoftwo) { - fixed_t x = ((u-viewx) >> FRACBITS); - fixed_t y = ((v-viewy) >> FRACBITS); + fixed_t x = (((fixed_t)u-viewx) >> FRACBITS); + fixed_t y = (((fixed_t)v-viewy) >> FRACBITS); // Carefully align all of my Friends. if (x < 0) @@ -1132,8 +1132,8 @@ void R_DrawTiltedSplat_8(void) if (!ds_powersoftwo) { - fixed_t x = ((u-viewx) >> FRACBITS); - fixed_t y = ((v-viewy) >> FRACBITS); + fixed_t x = (((fixed_t)u-viewx) >> FRACBITS); + fixed_t y = (((fixed_t)v-viewy) >> FRACBITS); // Carefully align all of my Friends. if (x < 0) @@ -1190,8 +1190,8 @@ void R_DrawTiltedSplat_8(void) colormap = planezlight[tiltlighting[ds_x1++]] + (ds_colormap - colormaps); if (!ds_powersoftwo) { - fixed_t x = ((u-viewx) >> FRACBITS); - fixed_t y = ((v-viewy) >> FRACBITS); + fixed_t x = (((fixed_t)u-viewx) >> FRACBITS); + fixed_t y = (((fixed_t)v-viewy) >> FRACBITS); // Carefully align all of my Friends. if (x < 0) @@ -1225,8 +1225,8 @@ void R_DrawTiltedSplat_8(void) colormap = planezlight[tiltlighting[ds_x1++]] + (ds_colormap - colormaps); if (!ds_powersoftwo) { - fixed_t x = ((u-viewx) >> FRACBITS); - fixed_t y = ((v-viewy) >> FRACBITS); + fixed_t x = (((fixed_t)u-viewx) >> FRACBITS); + fixed_t y = (((fixed_t)v-viewy) >> FRACBITS); // Carefully align all of my Friends. if (x < 0) @@ -1266,8 +1266,8 @@ void R_DrawTiltedSplat_8(void) val = source[((v >> nflatyshift) & nflatmask) | (u >> nflatxshift)]; if (!ds_powersoftwo) { - fixed_t x = ((u-viewx) >> FRACBITS); - fixed_t y = ((v-viewy) >> FRACBITS); + fixed_t x = (((fixed_t)u-viewx) >> FRACBITS); + fixed_t y = (((fixed_t)v-viewy) >> FRACBITS); // Carefully align all of my Friends. if (x < 0) From d38ba4d88ca9d00b254e4728dd997454994c6847 Mon Sep 17 00:00:00 2001 From: Jaime Passos Date: Fri, 6 Sep 2019 19:41:29 -0300 Subject: [PATCH 34/51] define stuff idk --- src/hardware/hw_cache.c | 4 ++++ src/r_data.c | 7 +++++++ src/r_plane.c | 8 +++++--- 3 files changed, 16 insertions(+), 3 deletions(-) diff --git a/src/hardware/hw_cache.c b/src/hardware/hw_cache.c index 12e43c0e5..2b458c9d9 100644 --- a/src/hardware/hw_cache.c +++ b/src/hardware/hw_cache.c @@ -664,8 +664,10 @@ static void HWR_GenerateTexture(INT32 texnum, GLTexture_t *grtex) { size_t lumplength = W_LumpLengthPwad(patch->wad, patch->lump); realpatch = W_CacheLumpNumPwad(patch->wad, patch->lump, PU_CACHE); +#ifndef NO_PNG_LUMPS if (R_IsLumpPNG((UINT8 *)realpatch, lumplength)) realpatch = R_PNGToPatch((UINT8 *)realpatch, lumplength); +#endif HWR_DrawTexturePatchInCache(&grtex->mipmap, blockwidth, blockheight, texture, patch, @@ -892,8 +894,10 @@ 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); +#ifndef NO_PNG_LUMPS if (R_IsLumpPNG((UINT8 *)patch, lumplength)) patch = R_PNGToPatch((UINT8 *)patch, lumplength); +#endif grMipmap->width = (UINT16)SHORT(patch->width); grMipmap->height = (UINT16)SHORT(patch->height); diff --git a/src/r_data.c b/src/r_data.c index d37b39315..8c6b4926a 100644 --- a/src/r_data.c +++ b/src/r_data.c @@ -376,8 +376,10 @@ static UINT8 *R_GenerateTexture(size_t texnum) lumpnum = patch->lump; lumplength = W_LumpLengthPwad(wadnum, lumpnum); realpatch = W_CacheLumpNumPwad(wadnum, lumpnum, PU_CACHE); +#ifndef NO_PNG_LUMPS if (R_IsLumpPNG((UINT8 *)realpatch, lumplength)) realpatch = R_PNGToPatch((UINT8 *)realpatch, lumplength); +#endif // Check the patch for holes. if (texture->width > SHORT(realpatch->width) || texture->height > SHORT(realpatch->height)) @@ -468,8 +470,10 @@ static UINT8 *R_GenerateTexture(size_t texnum) lumpnum = patch->lump; lumplength = W_LumpLengthPwad(wadnum, lumpnum); realpatch = W_CacheLumpNumPwad(wadnum, lumpnum, PU_CACHE); +#ifndef NO_PNG_LUMPS if (R_IsLumpPNG((UINT8 *)realpatch, lumplength)) realpatch = R_PNGToPatch((UINT8 *)realpatch, lumplength); +#endif x1 = patch->originx; width = SHORT(realpatch->width); @@ -734,6 +738,8 @@ void R_LoadTextures(void) // Set texture properties. M_Memcpy(texture->name, W_CheckNameForNumPwad(wadnum, lumpnum), sizeof(texture->name)); + +#ifndef NO_PNG_LUMPS if (R_IsLumpPNG((UINT8 *)patchlump, lumplength)) { INT16 width, height; @@ -742,6 +748,7 @@ void R_LoadTextures(void) texture->height = height; } else +#endif { texture->width = SHORT(patchlump->width); texture->height = SHORT(patchlump->height); diff --git a/src/r_plane.c b/src/r_plane.c index 57c8079f1..92b3fe770 100644 --- a/src/r_plane.c +++ b/src/r_plane.c @@ -963,12 +963,14 @@ void R_DrawSinglePlane(visplane_t *pl) // Check if the flat is actually a wall texture. if (levelflat->texturenum != 0 && levelflat->texturenum != -1) flat = R_GetPatchFlat(levelflat, true, false); - // Maybe it's just a patch, then? - else if (R_CheckIfPatch(levelflat->lumpnum)) - flat = R_GetPatchFlat(levelflat, false, false); +#ifndef NO_PNG_LUMPS // Maybe it's a PNG?! else if (R_IsLumpPNG(ds_source, size)) flat = R_GetPatchFlat(levelflat, false, true); +#endif + // Maybe it's just a patch, then? + else if (R_CheckIfPatch(levelflat->lumpnum)) + flat = R_GetPatchFlat(levelflat, false, false); // It's a raw flat. else { From 5d85e82fa66ea58c939b7c048d05174819d03c97 Mon Sep 17 00:00:00 2001 From: toaster Date: Sat, 7 Sep 2019 20:08:05 +0100 Subject: [PATCH 35/51] Fix detection of GRADE_ constants in SOC. --- src/dehacked.c | 61 +++++++++++++++++++++++++++++++++++++++++--------- 1 file changed, 51 insertions(+), 10 deletions(-) diff --git a/src/dehacked.c b/src/dehacked.c index 5db61a5b5..186d36fb2 100644 --- a/src/dehacked.c +++ b/src/dehacked.c @@ -2957,6 +2957,17 @@ static void readunlockable(MYFILE *f, INT32 num) Z_Free(s); } +static const char NIGHTSGRADE_LIST[] = { + 'F', // GRADE_F + 'E', // GRADE_E + 'D', // GRADE_D + 'C', // GRADE_C + 'B', // GRADE_B + 'A', // GRADE_A + 'S', // GRADE_S + '\0' +}; + #define PARAMCHECK(n) do { if (!params[n]) { deh_warning("Too few parameters, need %d", n); return; }} while (0) static void readcondition(UINT8 set, UINT32 id, char *word2) { @@ -3058,7 +3069,21 @@ static void readcondition(UINT8 set, UINT32 id, char *word2) PARAMCHECK(2); // one optional one ty = UC_NIGHTSSCORE + offset; - re = atoi(params[2 + !!(params[3])]); + i = (params[3] ? 3 : 2); + if (fastncmp("GRADE_",params[i],6)) + { + char *p = params[i]+6; + for (re = 0; NIGHTSGRADE_LIST[re]; re++) + if (*p == NIGHTSGRADE_LIST[re]) + break; + if (!NIGHTSGRADE_LIST[re]) + { + deh_warning("Invalid NiGHTS grade %s\n", params[i]); + return; + } + } + else + re = atoi(params[i]); // Convert to map number if it appears to be one if (params[1][0] >= 'A' && params[1][0] <= 'Z') @@ -8474,15 +8499,6 @@ struct { {"LF2_NOVISITNEEDED",LF2_NOVISITNEEDED}, {"LF2_WIDEICON",LF2_WIDEICON}, - // NiGHTS grades - {"GRADE_F",GRADE_F}, - {"GRADE_E",GRADE_E}, - {"GRADE_D",GRADE_D}, - {"GRADE_C",GRADE_C}, - {"GRADE_B",GRADE_B}, - {"GRADE_A",GRADE_A}, - {"GRADE_S",GRADE_S}, - // Emeralds {"EMERALD1",EMERALD1}, {"EMERALD2",EMERALD2}, @@ -9304,6 +9320,19 @@ static fixed_t find_const(const char **rword) free(word); return 0; } + else if (fastncmp("GRADE_",word,6)) + { + char *p = word+6; + for (i = 0; NIGHTSGRADE_LIST[i]; i++) + if (*p == NIGHTSGRADE_LIST[i]) + { + free(word); + return i; + } + const_warning("NiGHTS grade",word); + free(word); + return 0; + } for (i = 0; INT_CONST[i].n; i++) if (fastcmp(word,INT_CONST[i].n)) { free(word); @@ -9752,6 +9781,18 @@ static inline int lib_getenum(lua_State *L) if (mathlib) return luaL_error(L, "skincolor '%s' could not be found.\n", word); return 0; } + else if (fastncmp("GRADE_",word,6)) + { + p = word+6; + for (i = 0; NIGHTSGRADE_LIST[i]; i++) + if (*p == NIGHTSGRADE_LIST[i]) + { + lua_pushinteger(L, i); + return 1; + } + if (mathlib) return luaL_error(L, "NiGHTS grade '%s' could not be found.\n", word); + return 0; + } else if (fastncmp("MN_",word,3)) { p = word+3; for (i = 0; i < NUMMENUTYPES; i++) From f461b76bb0ed9fc96f0e4cb17fd5b990ba5694f4 Mon Sep 17 00:00:00 2001 From: Jaime Passos Date: Sat, 7 Sep 2019 16:54:26 -0300 Subject: [PATCH 36/51] fix translucency --- src/doomdef.h | 4 ++- src/hardware/hw_cache.c | 14 +++++++++-- src/r_data.c | 54 ++++++++--------------------------------- src/r_plane.c | 2 -- 4 files changed, 25 insertions(+), 49 deletions(-) diff --git a/src/doomdef.h b/src/doomdef.h index 952bea318..4a0174369 100644 --- a/src/doomdef.h +++ b/src/doomdef.h @@ -616,6 +616,8 @@ extern const char *compdate, *comptime, *comprevision, *compbranch; /// SRB2CB itself ported this from PrBoom+ #define NEWCLIP -//#define NO_PNG_LUMPS +#ifndef HAVE_PNG +#define NO_PNG_LUMPS +#endif #endif // __DOOMDEF__ diff --git a/src/hardware/hw_cache.c b/src/hardware/hw_cache.c index 2b458c9d9..c9a75a4f3 100644 --- a/src/hardware/hw_cache.c +++ b/src/hardware/hw_cache.c @@ -892,8 +892,10 @@ lumpnum_t gr_patchflat; static void HWR_LoadPatchFlat(GLMipmap_t *grMipmap, lumpnum_t flatlumpnum) { + UINT8 *flat; patch_t *patch = (patch_t *)W_CacheLumpNum(flatlumpnum, PU_STATIC); size_t lumplength = W_LumpLength(flatlumpnum); + #ifndef NO_PNG_LUMPS if (R_IsLumpPNG((UINT8 *)patch, lumplength)) patch = R_PNGToPatch((UINT8 *)patch, lumplength); @@ -902,7 +904,10 @@ static void HWR_LoadPatchFlat(GLMipmap_t *grMipmap, lumpnum_t flatlumpnum) grMipmap->width = (UINT16)SHORT(patch->width); grMipmap->height = (UINT16)SHORT(patch->height); - R_PatchToFlat(patch, Z_Malloc(grMipmap->width * grMipmap->height, PU_HWRCACHE, &grMipmap->grInfo.data)); + flat = Z_Malloc(grMipmap->width * grMipmap->height, PU_HWRCACHE, &grMipmap->grInfo.data); + memset(flat, TRANSPARENTPIXEL, grMipmap->width * grMipmap->height); + + R_PatchToFlat(patch, flat); } static void HWR_CacheFlat(GLMipmap_t *grMipmap, lumpnum_t flatlumpnum) @@ -980,6 +985,8 @@ void HWR_GetFlat(lumpnum_t flatlumpnum) static void HWR_LoadTextureFlat(GLMipmap_t *grMipmap, INT32 texturenum) { + UINT8 *flat; + // setup the texture info #ifdef GLIDE_API_COMPATIBILITY grMipmap->grInfo.smallLodLog2 = GR_LOD_LOG2_64; @@ -992,7 +999,10 @@ static void HWR_LoadTextureFlat(GLMipmap_t *grMipmap, INT32 texturenum) grMipmap->width = (UINT16)textures[texturenum]->width; grMipmap->height = (UINT16)textures[texturenum]->height; - R_TextureToFlat(texturenum, Z_Malloc(grMipmap->width * grMipmap->height, PU_HWRCACHE, &grMipmap->grInfo.data)); + flat = Z_Malloc(grMipmap->width * grMipmap->height, PU_HWRCACHE, &grMipmap->grInfo.data); + memset(flat, TRANSPARENTPIXEL, grMipmap->width * grMipmap->height); + + R_TextureToFlat(texturenum, flat); } void HWR_GetTextureFlat(INT32 texturenum) diff --git a/src/r_data.c b/src/r_data.c index 8c6b4926a..fb30005bf 100644 --- a/src/r_data.c +++ b/src/r_data.c @@ -376,9 +376,13 @@ static UINT8 *R_GenerateTexture(size_t texnum) lumpnum = patch->lump; lumplength = W_LumpLengthPwad(wadnum, lumpnum); realpatch = W_CacheLumpNumPwad(wadnum, lumpnum, PU_CACHE); + #ifndef NO_PNG_LUMPS if (R_IsLumpPNG((UINT8 *)realpatch, lumplength)) + { realpatch = R_PNGToPatch((UINT8 *)realpatch, lumplength); + goto multipatch; + } #endif // Check the patch for holes. @@ -436,6 +440,9 @@ static UINT8 *R_GenerateTexture(size_t texnum) } // multi-patch textures (or 'composite') +#ifndef NO_PNG_LUMPS + multipatch: +#endif texture->holes = false; texture->flip = 0; blocksize = (texture->width * 4) + (texture->width * texture->height); @@ -2441,7 +2448,6 @@ boolean R_CheckIfPatch(lumpnum_t lump) { result = false; break; - } } } @@ -2475,8 +2481,7 @@ void R_PatchToFlat(patch_t *patch, UINT8 *flat) source = (UINT8 *)(column) + 3; for (ofs = 0; dest < deststop && ofs < column->length; ofs++) { - if (source[ofs] != TRANSPARENTPIXEL) - *dest = source[ofs]; + *dest = source[ofs]; dest += SHORT(patch->width); } column = (column_t *)((UINT8 *)column + column->length + 4); @@ -2637,7 +2642,8 @@ static UINT8 *PNG_RawConvert(UINT8 *png, UINT16 *w, UINT16 *h, size_t size) 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]); + if ((UINT8)px[3]) + flat[((y * width) + x)] = NearestColor((UINT8)px[0], (UINT8)px[1], (UINT8)px[2]); } } free(row_pointers); @@ -2645,34 +2651,6 @@ static UINT8 *PNG_RawConvert(UINT8 *png, UINT16 *w, UINT16 *h, size_t size) 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_LEVEL, 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) { @@ -2680,13 +2658,11 @@ UINT8 *R_PNGToFlat(levelflat_t *levelflat, UINT8 *png, size_t 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; @@ -2726,16 +2702,6 @@ patch_t *R_PNGToPatch(UINT8 *png, size_t size) 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) diff --git a/src/r_plane.c b/src/r_plane.c index 92b3fe770..c28405726 100644 --- a/src/r_plane.c +++ b/src/r_plane.c @@ -754,7 +754,6 @@ static UINT8 *R_GetPatchFlat(levelflat_t *levelflat, boolean leveltexture, boole { patch = (patch_t *)ds_source; #ifndef NO_PNG_LUMPS -#ifdef HAVE_PNG if (ispng) { levelflat->flatpatch = R_PNGToFlat(levelflat, ds_source, W_LumpLength(levelflat->lumpnum)); @@ -773,7 +772,6 @@ static UINT8 *R_GetPatchFlat(levelflat_t *levelflat, boolean leveltexture, boole } } else -#endif #endif { levelflat->width = ds_flatwidth = SHORT(patch->width); From d26ff197dc0bc204b3cd925778fd630ea16c5173 Mon Sep 17 00:00:00 2001 From: toaster Date: Sat, 7 Sep 2019 22:11:33 +0100 Subject: [PATCH 37/51] * Store gravflip (resolves #206) and destscale in starposts. (Using the same field, taking advantage of the fact that object scale will always be positive!) * Update the function signature of P_MixUp to accomodate both it and drawangle instead of doing it outside of the function. * If the player is spawning from the start of the stage and it's from the ceiling, be in fall frames as requested (resolves #191). --- src/d_clisrv.c | 2 ++ src/d_clisrv.h | 1 + src/d_player.h | 1 + src/g_game.c | 8 +++++++- src/lua_playerlib.c | 4 ++++ src/m_cheat.c | 3 +++ src/p_enemy.c | 16 +++++++--------- src/p_inter.c | 12 ++++++++++++ src/p_local.h | 2 +- src/p_mobj.c | 33 +++++++++++++++++++++++---------- src/p_saveg.c | 2 ++ src/p_spec.c | 2 +- src/p_telept.c | 5 ++++- 13 files changed, 68 insertions(+), 23 deletions(-) diff --git a/src/d_clisrv.c b/src/d_clisrv.c index 01e94485d..78e07a397 100644 --- a/src/d_clisrv.c +++ b/src/d_clisrv.c @@ -579,6 +579,7 @@ static inline void resynch_write_player(resynch_pak *rsp, const size_t i) rsp->starpostnum = LONG(players[i].starpostnum); rsp->starposttime = (tic_t)LONG(players[i].starposttime); rsp->starpostangle = (angle_t)LONG(players[i].starpostangle); + rsp->starpostscale = (fixed_t)LONG(players[i].starpostscale); rsp->maxlink = LONG(players[i].maxlink); rsp->dashspeed = (fixed_t)LONG(players[i].dashspeed); @@ -714,6 +715,7 @@ static void resynch_read_player(resynch_pak *rsp) players[i].starpostnum = LONG(rsp->starpostnum); players[i].starposttime = (tic_t)LONG(rsp->starposttime); players[i].starpostangle = (angle_t)LONG(rsp->starpostangle); + players[i].starpostscale = (fixed_t)LONG(rsp->starpostscale); players[i].maxlink = LONG(rsp->maxlink); players[i].dashspeed = (fixed_t)LONG(rsp->dashspeed); diff --git a/src/d_clisrv.h b/src/d_clisrv.h index a2f140f33..3bfabfc03 100644 --- a/src/d_clisrv.h +++ b/src/d_clisrv.h @@ -228,6 +228,7 @@ typedef struct INT32 starpostnum; tic_t starposttime; angle_t starpostangle; + fixed_t starpostscale; INT32 maxlink; fixed_t dashspeed; diff --git a/src/d_player.h b/src/d_player.h index 5860cf1de..69080bd9d 100644 --- a/src/d_player.h +++ b/src/d_player.h @@ -441,6 +441,7 @@ typedef struct player_s INT32 starpostnum; // The number of the last starpost you hit tic_t starposttime; // Your time when you hit the starpost angle_t starpostangle; // Angle that the starpost is facing - you respawn facing this way + fixed_t starpostscale; // Scale of the player; if negative, player is gravflipped ///////////////// // NiGHTS Stuff// diff --git a/src/g_game.c b/src/g_game.c index d5faf6846..89a96f3d0 100644 --- a/src/g_game.c +++ b/src/g_game.c @@ -2083,6 +2083,7 @@ static inline void G_PlayerFinishLevel(INT32 player) p->mo->flags2 &= ~MF2_SHADOW; // cancel invisibility P_FlashPal(p, 0, 0); // Resets + p->starpostscale = 0; p->starpostangle = 0; p->starposttime = 0; p->starpostx = 0; @@ -2129,6 +2130,7 @@ void G_PlayerReborn(INT32 player) INT16 starpostz; INT32 starpostnum; INT32 starpostangle; + fixed_t starpostscale; fixed_t jumpfactor; fixed_t height; fixed_t spinheight; @@ -2184,6 +2186,7 @@ void G_PlayerReborn(INT32 player) starpostz = players[player].starpostz; starpostnum = players[player].starpostnum; starpostangle = players[player].starpostangle; + starpostscale = players[player].starpostscale; jumpfactor = players[player].jumpfactor; height = players[player].height; spinheight = players[player].spinheight; @@ -2239,6 +2242,7 @@ void G_PlayerReborn(INT32 player) p->starpostz = starpostz; p->starpostnum = starpostnum; p->starpostangle = starpostangle; + p->starpostscale = starpostscale; p->jumpfactor = jumpfactor; p->height = height; p->spinheight = spinheight; @@ -2657,6 +2661,7 @@ void G_DoReborn(INT32 playernum) { if (!playeringame[i]) continue; + players[i].starpostscale = 0; players[i].starpostangle = 0; players[i].starposttime = 0; players[i].starpostx = 0; @@ -2779,6 +2784,7 @@ void G_AddPlayer(INT32 playernum) if (!(cv_coopstarposts.value && (gametype == GT_COOP) && (p->starpostnum < players[i].starpostnum))) continue; + p->starpostscale = players[i].starpostscale; p->starposttime = players[i].starposttime; p->starpostx = players[i].starpostx; p->starposty = players[i].starposty; @@ -3866,7 +3872,7 @@ void G_InitNew(UINT8 pultmode, const char *mapname, boolean resetplayer, boolean for (i = 0; i < MAXPLAYERS; i++) { players[i].playerstate = PST_REBORN; - players[i].starpostangle = players[i].starpostnum = players[i].starposttime = 0; + players[i].starpostscale = players[i].starpostangle = players[i].starpostnum = players[i].starposttime = 0; players[i].starpostx = players[i].starposty = players[i].starpostz = 0; if (netgame || multiplayer) diff --git a/src/lua_playerlib.c b/src/lua_playerlib.c index addd707e1..dd9959afb 100644 --- a/src/lua_playerlib.c +++ b/src/lua_playerlib.c @@ -262,6 +262,8 @@ static int player_get(lua_State *L) lua_pushinteger(L, plr->starposttime); else if (fastcmp(field,"starpostangle")) lua_pushangle(L, plr->starpostangle); + else if (fastcmp(field,"starpostscale")) + lua_pushfixed(L, plr->starpostscale); else if (fastcmp(field,"angle_pos")) lua_pushangle(L, plr->angle_pos); else if (fastcmp(field,"old_angle_pos")) @@ -570,6 +572,8 @@ static int player_set(lua_State *L) plr->starposttime = (tic_t)luaL_checkinteger(L, 3); else if (fastcmp(field,"starpostangle")) plr->starpostangle = luaL_checkangle(L, 3); + else if (fastcmp(field,"starpostscale")) + plr->starpostscale = luaL_checkfixed(L, 3); else if (fastcmp(field,"angle_pos")) plr->angle_pos = luaL_checkangle(L, 3); else if (fastcmp(field,"old_angle_pos")) diff --git a/src/m_cheat.c b/src/m_cheat.c index da449b2f7..ae2703ee2 100644 --- a/src/m_cheat.c +++ b/src/m_cheat.c @@ -831,6 +831,9 @@ void Command_Savecheckpoint_f(void) players[consoleplayer].starposty = players[consoleplayer].mo->y>>FRACBITS; players[consoleplayer].starpostz = players[consoleplayer].mo->floorz>>FRACBITS; players[consoleplayer].starpostangle = players[consoleplayer].mo->angle; + players[consoleplayer].starpostscale = players[consoleplayer].mo->destscale; + if (players[consoleplayer].mo->flags2 & MF2_OBJECTFLIP) + players[consoleplayer].starpostscale *= -1; CONS_Printf(M_GetText("Temporary checkpoint created at %d, %d, %d\n"), players[consoleplayer].starpostx, players[consoleplayer].starposty, players[consoleplayer].starpostz); } diff --git a/src/p_enemy.c b/src/p_enemy.c index b60e5e68b..6e49d165d 100644 --- a/src/p_enemy.c +++ b/src/p_enemy.c @@ -6358,6 +6358,7 @@ void A_MixUp(mobj_t *actor) INT32 starpostnum; tic_t starposttime; angle_t starpostangle; + fixed_t starpostscale; INT32 mflags2; @@ -6405,6 +6406,7 @@ void A_MixUp(mobj_t *actor) starposty = players[one].starposty; starpostz = players[one].starpostz; starpostangle = players[one].starpostangle; + starpostscale = players[one].starpostscale; starpostnum = players[one].starpostnum; starposttime = players[one].starposttime; @@ -6413,15 +6415,11 @@ void A_MixUp(mobj_t *actor) P_MixUp(players[one].mo, players[two].mo->x, players[two].mo->y, players[two].mo->z, players[two].mo->angle, players[two].starpostx, players[two].starposty, players[two].starpostz, players[two].starpostnum, players[two].starposttime, players[two].starpostangle, - players[two].mo->flags2); - - players[one].drawangle = players[two].drawangle; + players[two].starpostscale, players[two].drawangle, players[two].mo->flags2); P_MixUp(players[two].mo, x, y, z, angle, starpostx, starposty, starpostz, starpostnum, starposttime, starpostangle, - mflags2); - - players[two].drawangle = drawangle; + starpostscale, drawangle, mflags2); //carry set after mixup. Stupid P_ResetPlayer() takes away some of the stuff we look for... //but not all of it! So we need to make sure they aren't set wrong or anything. @@ -6448,6 +6446,7 @@ void A_MixUp(mobj_t *actor) INT32 starpostnum[MAXPLAYERS]; tic_t starposttime[MAXPLAYERS]; angle_t starpostangle[MAXPLAYERS]; + fixed_t starpostscale[MAXPLAYERS]; INT32 flags2[MAXPLAYERS]; @@ -6485,6 +6484,7 @@ void A_MixUp(mobj_t *actor) starpostnum[counter] = players[i].starpostnum; starposttime[counter] = players[i].starposttime; starpostangle[counter] = players[i].starpostangle; + starpostscale[counter] = players[i].starpostscale; flags2[counter] = players[i].mo->flags2; @@ -6525,9 +6525,7 @@ void A_MixUp(mobj_t *actor) P_MixUp(players[i].mo, position[teleportfrom][0], position[teleportfrom][1], position[teleportfrom][2], anglepos[teleportfrom][0], spposition[teleportfrom][0], spposition[teleportfrom][1], spposition[teleportfrom][2], starpostnum[teleportfrom], starposttime[teleportfrom], starpostangle[teleportfrom], - flags2[teleportfrom]); - - players[i].drawangle = anglepos[teleportfrom][1]; + starpostscale[teleportfrom], anglepos[teleportfrom][1], flags2[teleportfrom]); //...carry after. same reasoning. players[i].powers[pw_carry] = transcarry[teleportfrom]; diff --git a/src/p_inter.c b/src/p_inter.c index 0030e8e58..53481d6c5 100644 --- a/src/p_inter.c +++ b/src/p_inter.c @@ -1427,6 +1427,12 @@ void P_TouchSpecialThing(mobj_t *special, mobj_t *toucher, boolean heightcheck) players[i].starposty = player->mo->y>>FRACBITS; players[i].starpostz = special->z>>FRACBITS; players[i].starpostangle = special->angle; + players[i].starpostscale = player->mo->destscale; + if (special->flags2 & MF2_OBJECTFLIP) + { + players[i].starpostscale *= -1; + players[i].starpostz += (special->height - P_GetPlayerHeight(player))>>FRACBITS; + } players[i].starpostnum = special->health; if (cv_coopstarposts.value == 2 && (players[i].playerstate == PST_DEAD || players[i].spectator) && P_GetLives(&players[i])) @@ -1443,6 +1449,12 @@ void P_TouchSpecialThing(mobj_t *special, mobj_t *toucher, boolean heightcheck) player->starposty = toucher->y>>FRACBITS; player->starpostz = special->z>>FRACBITS; player->starpostangle = special->angle; + player->starpostscale = player->mo->destscale; + if (special->flags2 & MF2_OBJECTFLIP) + { + player->starpostscale *= -1; + player->starpostz += (special->height - P_GetPlayerHeight(player))>>FRACBITS; + } player->starpostnum = special->health; S_StartSound(toucher, special->info->painsound); } diff --git a/src/p_local.h b/src/p_local.h index 3a0146e54..662eb691a 100644 --- a/src/p_local.h +++ b/src/p_local.h @@ -509,7 +509,7 @@ extern INT32 ceilmovesound; void P_MixUp(mobj_t *thing, fixed_t x, fixed_t y, fixed_t z, angle_t angle, INT16 starpostx, INT16 starposty, INT16 starpostz, INT32 starpostnum, tic_t starposttime, angle_t starpostangle, - INT32 flags2); + fixed_t starpostscale, angle_t drawangle, INT32 flags2); boolean P_Teleport(mobj_t *thing, fixed_t x, fixed_t y, fixed_t z, angle_t angle, boolean flash, boolean dontstopmove); boolean P_SetMobjStateNF(mobj_t *mobj, statenum_t state); boolean P_CheckMissileSpawn(mobj_t *th); diff --git a/src/p_mobj.c b/src/p_mobj.c index 1ee90d250..130808712 100644 --- a/src/p_mobj.c +++ b/src/p_mobj.c @@ -10521,10 +10521,6 @@ void P_AfterPlayerSpawn(INT32 playernum) else p->viewz = p->mo->z + p->viewheight; - if (p->powers[pw_carry] != CR_NIGHTSMODE) - P_SetPlayerMobjState(p->mo, S_PLAY_STND); - p->pflags &= ~PF_SPINNING; - if (playernum == consoleplayer) { // wake up the status bar @@ -10609,6 +10605,8 @@ void P_MovePlayerToSpawn(INT32 playernum, mapthing_t *mthing) mobj->eflags |= MFE_VERTICALFLIP; mobj->flags2 |= MF2_OBJECTFLIP; } + if (mthing->options & MTF_AMBUSH) + P_SetPlayerMobjState(mobj, S_PLAY_FALL); } else z = floor; @@ -10627,7 +10625,12 @@ void P_MovePlayerToSpawn(INT32 playernum, mapthing_t *mthing) P_SetThingPosition(mobj); mobj->z = z; - if (mobj->z == mobj->floorz) + if (mobj->flags2 & MF2_OBJECTFLIP) + { + if (mobj->z + mobj->height == mobj->ceilingz) + mobj->eflags |= MFE_ONGROUND; + } + else if (mobj->z == mobj->floorz) mobj->eflags |= MFE_ONGROUND; mobj->angle = angle; @@ -10663,16 +10666,26 @@ void P_MovePlayerToStarpost(INT32 playernum) sector->ceilingheight; z = p->starpostz << FRACBITS; - if (z < floor) - z = floor; - else if (z > ceiling - mobjinfo[MT_PLAYER].height) - z = ceiling - mobjinfo[MT_PLAYER].height; + + P_SetScale(mobj, (mobj->destscale = abs(p->starpostscale))); mobj->floorz = floor; mobj->ceilingz = ceiling; + if (z <= floor) + z = floor; + else if (z >= ceiling - mobj->height) + z = ceiling - mobj->height; + mobj->z = z; - if (mobj->z == mobj->floorz) + + if (p->starpostscale < 0) + { + mobj->flags2 |= MF2_OBJECTFLIP; + if (mobj->z + mobj->height == mobj->ceilingz) + mobj->eflags |= MFE_ONGROUND; + } + else if (mobj->z == mobj->floorz) mobj->eflags |= MFE_ONGROUND; mobj->angle = p->starpostangle; diff --git a/src/p_saveg.c b/src/p_saveg.c index 7c073b151..12f14e99d 100644 --- a/src/p_saveg.c +++ b/src/p_saveg.c @@ -189,6 +189,7 @@ static void P_NetArchivePlayers(void) WRITEINT16(save_p, players[i].starpostz); WRITEINT32(save_p, players[i].starpostnum); WRITEANGLE(save_p, players[i].starpostangle); + WRITEFIXED(save_p, players[i].starpostscale); WRITEANGLE(save_p, players[i].angle_pos); WRITEANGLE(save_p, players[i].old_angle_pos); @@ -397,6 +398,7 @@ static void P_NetUnArchivePlayers(void) players[i].starpostz = READINT16(save_p); players[i].starpostnum = READINT32(save_p); players[i].starpostangle = READANGLE(save_p); + players[i].starpostscale = READFIXED(save_p); players[i].angle_pos = READANGLE(save_p); players[i].old_angle_pos = READANGLE(save_p); diff --git a/src/p_spec.c b/src/p_spec.c index 37a1652f0..fbf896a2b 100644 --- a/src/p_spec.c +++ b/src/p_spec.c @@ -4942,7 +4942,7 @@ DoneSection2: CONS_Printf(M_GetText("%s started lap %u\n"), player_names[player-players], (UINT32)player->laps+1); // Reset starposts (checkpoints) info - player->starpostangle = player->starposttime = player->starpostnum = 0; + player->starpostscale = player->starpostangle = player->starposttime = player->starpostnum = 0; player->starpostx = player->starposty = player->starpostz = 0; P_ResetStarposts(); diff --git a/src/p_telept.c b/src/p_telept.c index e80dd0428..632b81e04 100644 --- a/src/p_telept.c +++ b/src/p_telept.c @@ -33,7 +33,7 @@ void P_MixUp(mobj_t *thing, fixed_t x, fixed_t y, fixed_t z, angle_t angle, INT16 starpostx, INT16 starposty, INT16 starpostz, INT32 starpostnum, tic_t starposttime, angle_t starpostangle, - INT32 flags2) + fixed_t starpostscale, angle_t drawangle, INT32 flags2) { const INT32 takeflags2 = MF2_TWOD|MF2_OBJECTFLIP; @@ -89,8 +89,11 @@ void P_MixUp(mobj_t *thing, fixed_t x, fixed_t y, fixed_t z, angle_t angle, thing->player->starpostz = starpostz; thing->player->starposttime = starposttime; thing->player->starpostangle = starpostangle; + thing->player->starpostscale = starpostscale; thing->player->starpostnum = starpostnum; + thing->player->drawangle = drawangle; + // Reset map starposts for the player's new info. P_ResetStarposts(); P_ClearStarPost(starpostnum); From ff293c3f6fa9e193480c769184e1591ab8c86f80 Mon Sep 17 00:00:00 2001 From: Jaime Passos Date: Sat, 7 Sep 2019 18:20:49 -0300 Subject: [PATCH 38/51] fix non powers of two spans --- src/r_plane.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/r_plane.c b/src/r_plane.c index c28405726..a5b167015 100644 --- a/src/r_plane.c +++ b/src/r_plane.c @@ -1010,6 +1010,8 @@ void R_DrawSinglePlane(visplane_t *pl) if (ds_powersoftwo) { + // 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< Date: Sat, 7 Sep 2019 18:56:08 -0300 Subject: [PATCH 39/51] probably want to Z_Free this............... --- src/r_data.c | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/src/r_data.c b/src/r_data.c index fb30005bf..5858117a5 100644 --- a/src/r_data.c +++ b/src/r_data.c @@ -2511,7 +2511,7 @@ 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)"); + png_error(png_ptr, "PNG_IOReader: buffer overrun"); memcpy(data, f->buffer + f->current_pos, length); f->current_pos += length; } @@ -2573,11 +2573,10 @@ static png_bytep *PNG_Read(UINT8 *png, UINT16 *w, UINT16 *h, size_t size) png_memcpy(png_jmpbuf(png_ptr), jmpbuf, sizeof jmp_buf); #endif - // png_source is array which have png data + // set our own read_function 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 @@ -2631,7 +2630,7 @@ static UINT8 *PNG_RawConvert(UINT8 *png, UINT16 *w, UINT16 *h, size_t size) png_uint_32 width = *w, height = *h; if (!row_pointers) - return NULL; + I_Error("PNG_RawConvert: conversion failed"); // Convert the image to 8bpp flat = Z_Malloc(width * height, PU_LEVEL, NULL); @@ -2674,7 +2673,7 @@ patch_t *R_PNGToPatch(UINT8 *png, size_t size) #define WRITE32(buf, a) ({WRITE16(buf, (a)&65535); WRITE16(buf, (a)>>16);}) if (!raw) - return NULL; + I_Error("R_PNGToPatch: conversion failed"); // Write image size and offset WRITE16(imgptr, width); @@ -2762,6 +2761,9 @@ patch_t *R_PNGToPatch(UINT8 *png, size_t size) size = imgptr-imgbuf; img = malloc(size); memcpy(img, imgbuf, size); + + Z_Free(raw); + return (patch_t *)img; } @@ -2809,11 +2811,10 @@ boolean R_PNGDimensions(UINT8 *png, INT16 *width, INT16 *height, size_t size) png_memcpy(png_jmpbuf(png_ptr), jmpbuf, sizeof jmp_buf); #endif - // png_source is array which have png data + // set our own read_function 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 From a67dd633ffd928b5af1f15899c1b474b58a7aa55 Mon Sep 17 00:00:00 2001 From: Jaime Passos Date: Sat, 7 Sep 2019 19:02:50 -0300 Subject: [PATCH 40/51] if that function can't return NULL why should i do this? --- src/r_plane.c | 14 ++------------ 1 file changed, 2 insertions(+), 12 deletions(-) diff --git a/src/r_plane.c b/src/r_plane.c index a5b167015..de5bf9f00 100644 --- a/src/r_plane.c +++ b/src/r_plane.c @@ -758,18 +758,8 @@ static UINT8 *R_GetPatchFlat(levelflat_t *levelflat, boolean leveltexture, boole { 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_CACHE); - R_CheckFlatLength(W_LumpLength(redflr)); - R_CheckPowersOfTwo(); - } - else - { - ds_flatwidth = levelflat->width; - ds_flatheight = levelflat->height; - } + ds_flatwidth = levelflat->width; + ds_flatheight = levelflat->height; } else #endif From 4adff344024825ccf0ed25419aca0d46030e5381 Mon Sep 17 00:00:00 2001 From: Jaime Passos Date: Sat, 7 Sep 2019 22:43:29 -0300 Subject: [PATCH 41/51] opengl patch translucency --- src/hardware/hw_cache.c | 87 +++++++++++++++++++++++++++++++++++++++-- 1 file changed, 83 insertions(+), 4 deletions(-) diff --git a/src/hardware/hw_cache.c b/src/hardware/hw_cache.c index 6bc2c712e..fb25dc58e 100644 --- a/src/hardware/hw_cache.c +++ b/src/hardware/hw_cache.c @@ -60,6 +60,47 @@ static const INT32 format2bpp[16] = 2, //14 GR_TEXFMT_AP_88 }; +static RGBA_t astblendpixel(RGBA_t background, RGBA_t foreground, int style, UINT8 alpha) +{ + RGBA_t output; + output.s.alpha = 0xFF; + + if (style == AST_TRANSLUCENT) + { + if (alpha == 0) + output.rgba = background.rgba; + else if (alpha == 0xFF) + output.rgba = foreground.rgba; + else if (alpha < 0xFF) + { + UINT8 beta = (0xFF - alpha); + output.s.red = ((background.s.red * beta) + (foreground.s.red * alpha)) / 0xFF; + output.s.green = ((background.s.green * beta) + (foreground.s.green * alpha)) / 0xFF; + output.s.blue = ((background.s.blue * beta) + (foreground.s.blue * alpha)) / 0xFF; + } + // write foreground pixel alpha + // if there's no pixel in here + if (!background.rgba) + output.s.alpha = foreground.s.alpha; + } + + return output; +} + +static UINT8 astblendpixel_8bpp(UINT8 background, UINT8 foreground, int style, UINT8 alpha) +{ + if ((style == AST_TRANSLUCENT) && (alpha <= (10*255/11))) // Alpha style set to translucent? Is the alpha small enough for translucency? + { + UINT8 *mytransmap; + if (alpha < 255/11) // Is the patch way too translucent? Don't render then. + return background; + // The equation's not exact but it works as intended. I'll call it a day for now. + mytransmap = transtables + ((8*(alpha) + 255/8)/(255 - 255/11) << FF_TRANSSHIFT); + if (background != 0xFF) + return *(mytransmap + (background<<8) + foreground); + } + return background; +} // This code was originally placed directly in HWR_DrawPatchInCache. // It is now split from it for my sanity! (and the sanity of others) @@ -138,18 +179,37 @@ static void HWR_DrawColumnInCache(const column_t *patchcol, UINT8 *block, GLMipm // Alam: SRB2 uses Mingw, HUGS switch (bpp) { - case 2 : texelu16 = (UINT16)((alpha<<8) | texel); + case 2 : // uhhhhhhhh.......... + if ((originPatch != NULL) && originPatch->style) + texel = astblendpixel_8bpp(*(dest+1), texel, originPatch->style, originPatch->alpha); + texelu16 = (UINT16)((alpha<<8) | texel); memcpy(dest, &texelu16, sizeof(UINT16)); break; case 3 : colortemp = V_GetColor(texel); + if ((originPatch != NULL) && originPatch->style) + { + RGBA_t rgbatexel; + rgbatexel.rgba = *(UINT32 *)dest; + colortemp = astblendpixel(rgbatexel, colortemp, originPatch->style, originPatch->alpha); + } memcpy(dest, &colortemp, sizeof(RGBA_t)-sizeof(UINT8)); break; case 4 : colortemp = V_GetColor(texel); colortemp.s.alpha = alpha; + if ((originPatch != NULL) && originPatch->style) + { + RGBA_t rgbatexel; + rgbatexel.rgba = *(UINT32 *)dest; + colortemp = astblendpixel(rgbatexel, colortemp, originPatch->style, originPatch->alpha); + } memcpy(dest, &colortemp, sizeof(RGBA_t)); break; // default is 1 - default: *dest = texel; + default: + if ((originPatch != NULL) && originPatch->style) + *dest = astblendpixel_8bpp(*dest, texel, originPatch->style, originPatch->alpha); + else + *dest = texel; break; } @@ -233,18 +293,37 @@ static void HWR_DrawFlippedColumnInCache(const column_t *patchcol, UINT8 *block, // Alam: SRB2 uses Mingw, HUGS switch (bpp) { - case 2 : texelu16 = (UINT16)((alpha<<8) | texel); + case 2 : // uhhhhhhhh.......... + if ((originPatch != NULL) && originPatch->style) + texel = astblendpixel_8bpp(*(dest+1), texel, originPatch->style, originPatch->alpha); + texelu16 = (UINT16)((alpha<<8) | texel); memcpy(dest, &texelu16, sizeof(UINT16)); break; case 3 : colortemp = V_GetColor(texel); + if ((originPatch != NULL) && originPatch->style) + { + RGBA_t rgbatexel; + rgbatexel.rgba = *(UINT32 *)dest; + colortemp = astblendpixel(rgbatexel, colortemp, originPatch->style, originPatch->alpha); + } memcpy(dest, &colortemp, sizeof(RGBA_t)-sizeof(UINT8)); break; case 4 : colortemp = V_GetColor(texel); colortemp.s.alpha = alpha; + if ((originPatch != NULL) && originPatch->style) + { + RGBA_t rgbatexel; + rgbatexel.rgba = *(UINT32 *)dest; + colortemp = astblendpixel(rgbatexel, colortemp, originPatch->style, originPatch->alpha); + } memcpy(dest, &colortemp, sizeof(RGBA_t)); break; // default is 1 - default: *dest = texel; + default: + if ((originPatch != NULL) && originPatch->style) + *dest = astblendpixel_8bpp(*dest, texel, originPatch->style, originPatch->alpha); + else + *dest = texel; break; } From b7c9f15225413018b526802eecedff95e3753fbf Mon Sep 17 00:00:00 2001 From: mazmazz Date: Sat, 7 Sep 2019 22:00:38 -0400 Subject: [PATCH 42/51] Fix NiGHTS attack menu not drawing correct background --- src/m_menu.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/m_menu.c b/src/m_menu.c index 128b15a76..d9a6bfea6 100644 --- a/src/m_menu.c +++ b/src/m_menu.c @@ -8479,8 +8479,8 @@ static void M_NightsAttack(INT32 choice) M_PatchSkinNameTable(); G_SetGamestate(GS_TIMEATTACK); // do this before M_SetupNextMenu so that menu meta state knows that we're switching - M_SetupNextMenu(&SP_NightsAttackDef); titlemapinaction = TITLEMAP_OFF; // Nope don't give us HOMs please + M_SetupNextMenu(&SP_NightsAttackDef); if (!M_CanShowLevelInList(cv_nextmap.value-1, -1) && levelselect.rows[0].maplist[0]) CV_SetValue(&cv_nextmap, levelselect.rows[0].maplist[0]); else From ff1fa3f92babee4290ebadc1578e8525c9213008 Mon Sep 17 00:00:00 2001 From: Jaime Passos Date: Sun, 8 Sep 2019 13:21:00 -0300 Subject: [PATCH 43/51] Implement all the other alpha blend styles --- src/hardware/hw_cache.c | 85 +++++-------------------- src/r_data.c | 133 ++++++++++++++++++++++++++++++++++------ src/r_data.h | 7 ++- 3 files changed, 138 insertions(+), 87 deletions(-) diff --git a/src/hardware/hw_cache.c b/src/hardware/hw_cache.c index fb25dc58e..5eb6d9104 100644 --- a/src/hardware/hw_cache.c +++ b/src/hardware/hw_cache.c @@ -60,48 +60,6 @@ static const INT32 format2bpp[16] = 2, //14 GR_TEXFMT_AP_88 }; -static RGBA_t astblendpixel(RGBA_t background, RGBA_t foreground, int style, UINT8 alpha) -{ - RGBA_t output; - output.s.alpha = 0xFF; - - if (style == AST_TRANSLUCENT) - { - if (alpha == 0) - output.rgba = background.rgba; - else if (alpha == 0xFF) - output.rgba = foreground.rgba; - else if (alpha < 0xFF) - { - UINT8 beta = (0xFF - alpha); - output.s.red = ((background.s.red * beta) + (foreground.s.red * alpha)) / 0xFF; - output.s.green = ((background.s.green * beta) + (foreground.s.green * alpha)) / 0xFF; - output.s.blue = ((background.s.blue * beta) + (foreground.s.blue * alpha)) / 0xFF; - } - // write foreground pixel alpha - // if there's no pixel in here - if (!background.rgba) - output.s.alpha = foreground.s.alpha; - } - - return output; -} - -static UINT8 astblendpixel_8bpp(UINT8 background, UINT8 foreground, int style, UINT8 alpha) -{ - if ((style == AST_TRANSLUCENT) && (alpha <= (10*255/11))) // Alpha style set to translucent? Is the alpha small enough for translucency? - { - UINT8 *mytransmap; - if (alpha < 255/11) // Is the patch way too translucent? Don't render then. - return background; - // The equation's not exact but it works as intended. I'll call it a day for now. - mytransmap = transtables + ((8*(alpha) + 255/8)/(255 - 255/11) << FF_TRANSSHIFT); - if (background != 0xFF) - return *(mytransmap + (background<<8) + foreground); - } - return background; -} - // This code was originally placed directly in HWR_DrawPatchInCache. // It is now split from it for my sanity! (and the sanity of others) // -- Monster Iestyn (13/02/19) @@ -180,34 +138,34 @@ static void HWR_DrawColumnInCache(const column_t *patchcol, UINT8 *block, GLMipm switch (bpp) { case 2 : // uhhhhhhhh.......... - if ((originPatch != NULL) && originPatch->style) - texel = astblendpixel_8bpp(*(dest+1), texel, originPatch->style, originPatch->alpha); + if ((originPatch != NULL) && (originPatch->style != AST_COPY)) + texel = ASTBlendPixel_8bpp(*(dest+1), texel, originPatch->style, originPatch->alpha); texelu16 = (UINT16)((alpha<<8) | texel); memcpy(dest, &texelu16, sizeof(UINT16)); break; case 3 : colortemp = V_GetColor(texel); - if ((originPatch != NULL) && originPatch->style) + if ((originPatch != NULL) && (originPatch->style != AST_COPY)) { RGBA_t rgbatexel; rgbatexel.rgba = *(UINT32 *)dest; - colortemp = astblendpixel(rgbatexel, colortemp, originPatch->style, originPatch->alpha); + colortemp = ASTBlendPixel(rgbatexel, colortemp, originPatch->style, originPatch->alpha); } memcpy(dest, &colortemp, sizeof(RGBA_t)-sizeof(UINT8)); break; case 4 : colortemp = V_GetColor(texel); colortemp.s.alpha = alpha; - if ((originPatch != NULL) && originPatch->style) + if ((originPatch != NULL) && (originPatch->style != AST_COPY)) { RGBA_t rgbatexel; rgbatexel.rgba = *(UINT32 *)dest; - colortemp = astblendpixel(rgbatexel, colortemp, originPatch->style, originPatch->alpha); + colortemp = ASTBlendPixel(rgbatexel, colortemp, originPatch->style, originPatch->alpha); } memcpy(dest, &colortemp, sizeof(RGBA_t)); break; // default is 1 default: - if ((originPatch != NULL) && originPatch->style) - *dest = astblendpixel_8bpp(*dest, texel, originPatch->style, originPatch->alpha); + if ((originPatch != NULL) && (originPatch->style != AST_COPY)) + *dest = ASTBlendPixel_8bpp(*dest, texel, originPatch->style, originPatch->alpha); else *dest = texel; break; @@ -294,34 +252,34 @@ static void HWR_DrawFlippedColumnInCache(const column_t *patchcol, UINT8 *block, switch (bpp) { case 2 : // uhhhhhhhh.......... - if ((originPatch != NULL) && originPatch->style) - texel = astblendpixel_8bpp(*(dest+1), texel, originPatch->style, originPatch->alpha); + if ((originPatch != NULL) && (originPatch->style != AST_COPY)) + texel = ASTBlendPixel_8bpp(*(dest+1), texel, originPatch->style, originPatch->alpha); texelu16 = (UINT16)((alpha<<8) | texel); memcpy(dest, &texelu16, sizeof(UINT16)); break; case 3 : colortemp = V_GetColor(texel); - if ((originPatch != NULL) && originPatch->style) + if ((originPatch != NULL) && (originPatch->style != AST_COPY)) { RGBA_t rgbatexel; rgbatexel.rgba = *(UINT32 *)dest; - colortemp = astblendpixel(rgbatexel, colortemp, originPatch->style, originPatch->alpha); + colortemp = ASTBlendPixel(rgbatexel, colortemp, originPatch->style, originPatch->alpha); } memcpy(dest, &colortemp, sizeof(RGBA_t)-sizeof(UINT8)); break; case 4 : colortemp = V_GetColor(texel); colortemp.s.alpha = alpha; - if ((originPatch != NULL) && originPatch->style) + if ((originPatch != NULL) && (originPatch->style != AST_COPY)) { RGBA_t rgbatexel; rgbatexel.rgba = *(UINT32 *)dest; - colortemp = astblendpixel(rgbatexel, colortemp, originPatch->style, originPatch->alpha); + colortemp = ASTBlendPixel(rgbatexel, colortemp, originPatch->style, originPatch->alpha); } memcpy(dest, &colortemp, sizeof(RGBA_t)); break; // default is 1 default: - if ((originPatch != NULL) && originPatch->style) - *dest = astblendpixel_8bpp(*dest, texel, originPatch->style, originPatch->alpha); + if ((originPatch != NULL) && (originPatch->style != AST_COPY)) + *dest = ASTBlendPixel_8bpp(*dest, texel, originPatch->style, originPatch->alpha); else *dest = texel; break; @@ -410,16 +368,7 @@ static void HWR_DrawTexturePatchInCache(GLMipmap_t *mipmap, if (texture->width <= 0 || texture->height <= 0) return; - /*if ((patch->style == AST_TRANSLUCENT) && (patch->alpha <= (10*255/11))) // Alpha style set to translucent? Is the alpha small enough for translucency? - { - if (patch->alpha < 255/11) // Is the patch way too translucent? Don't render then. - continue; - ColumnDrawerPointer = (patch->flip & 2) ? HWR_DrawTransFlippedColumnInCache : HWR_DrawTransColumnInCache; - } - else*/ - { - ColumnDrawerPointer = (patch->flip & 2) ? HWR_DrawFlippedColumnInCache : HWR_DrawColumnInCache; - } + ColumnDrawerPointer = (patch->flip & 2) ? HWR_DrawFlippedColumnInCache : HWR_DrawColumnInCache; x1 = patch->originx; width = SHORT(realpatch->width); diff --git a/src/r_data.c b/src/r_data.c index 6889bddde..335a390d0 100644 --- a/src/r_data.c +++ b/src/r_data.c @@ -220,15 +220,110 @@ static inline void R_DrawFlippedColumnInCache(column_t *patch, UINT8 *cache, tex } } +RGBA_t ASTBlendPixel(RGBA_t background, RGBA_t foreground, int style, UINT8 alpha) +{ + RGBA_t output; + if (style == AST_TRANSLUCENT) + { + if (alpha == 0) + output.rgba = background.rgba; + else if (alpha == 0xFF) + output.rgba = foreground.rgba; + else if (alpha < 0xFF) + { + UINT8 beta = (0xFF - alpha); + output.s.red = ((background.s.red * beta) + (foreground.s.red * alpha)) / 0xFF; + output.s.green = ((background.s.green * beta) + (foreground.s.green * alpha)) / 0xFF; + output.s.blue = ((background.s.blue * beta) + (foreground.s.blue * alpha)) / 0xFF; + } + // write foreground pixel alpha + // if there's no pixel in here + if (!background.rgba) + output.s.alpha = foreground.s.alpha; + } +#define clamp(c) max(min(c, 0xFF), 0x00); + else + { + float falpha = ((float)alpha / 256.0f); + float fr = ((float)foreground.s.red * falpha); + float fg = ((float)foreground.s.green * falpha); + float fb = ((float)foreground.s.blue * falpha); + if (style == AST_ADD) + { + output.s.red = clamp((int)(background.s.red + fr)); + output.s.green = clamp((int)(background.s.green + fg)); + output.s.blue = clamp((int)(background.s.blue + fb)); + } + else if (style == AST_SUBTRACT) + { + output.s.red = clamp((int)(background.s.red - fr)); + output.s.green = clamp((int)(background.s.green - fg)); + output.s.blue = clamp((int)(background.s.blue - fb)); + } + else if (style == AST_REVERSESUBTRACT) + { + output.s.red = clamp((int)((-background.s.red) + fr)); + output.s.green = clamp((int)((-background.s.green) + fg)); + output.s.blue = clamp((int)((-background.s.blue) + fb)); + } + else if (style == AST_MODULATE) + { + fr = ((float)foreground.s.red / 256.0f); + fg = ((float)foreground.s.green / 256.0f); + fb = ((float)foreground.s.blue / 256.0f); + output.s.red = clamp((int)(background.s.red * fr)); + output.s.green = clamp((int)(background.s.green * fg)); + output.s.blue = clamp((int)(background.s.blue * fb)); + } + // just copy the pixel + else if (style == AST_COPY) + return background; + } +#undef clamp + // unimplemented blend modes return the background pixel + output = background; + output.s.alpha = 0xFF; + return output; +} + +UINT8 ASTBlendPixel_8bpp(UINT8 background, UINT8 foreground, int style, UINT8 alpha) +{ + if ((style == AST_TRANSLUCENT) && (alpha <= (10*255/11))) // Alpha style set to translucent? Is the alpha small enough for translucency? + { + UINT8 *mytransmap; + if (alpha < 255/11) // Is the patch way too translucent? Don't render then. + return background; + // The equation's not exact but it works as intended. I'll call it a day for now. + mytransmap = transtables + ((8*(alpha) + 255/8)/(255 - 255/11) << FF_TRANSSHIFT); + if (background != 0xFF) + return *(mytransmap + (background<<8) + foreground); + } + // just copy the pixel + else if (style == AST_COPY) + return background; + // use ASTBlendPixel for all other blend modes + // and find the nearest colour in the palette + else if (style != AST_TRANSLUCENT) + { + RGBA_t texel; + RGBA_t bg = V_GetColor(background); + RGBA_t fg = V_GetColor(foreground); + texel = ASTBlendPixel(bg, fg, style, alpha); + return NearestColor(texel.s.red, texel.s.green, texel.s.blue); + } + // fallback if all above fails, somehow + // return the background pixel + return background; +} + // -// R_DrawTransColumnInCache +// R_DrawBlendColumnInCache // Draws a translucent column into the cache, applying a half-cooked equation to get a proper translucency value (Needs code in R_GenerateTexture()). // -static inline void R_DrawTransColumnInCache(column_t *patch, UINT8 *cache, texpatch_t *originPatch, INT32 cacheheight, INT32 patchheight) +static inline void R_DrawBlendColumnInCache(column_t *patch, UINT8 *cache, texpatch_t *originPatch, INT32 cacheheight, INT32 patchheight) { INT32 count, position; UINT8 *source, *dest; - UINT8 *mytransmap = transtables + ((8*(originPatch->alpha) + 255/8)/(255 - 255/11) << FF_TRANSSHIFT); // The equation's not exact but it works as intended. I'll call it a day for now. INT32 topdelta, prevdelta = -1; INT32 originy = originPatch->originy; @@ -258,7 +353,8 @@ static inline void R_DrawTransColumnInCache(column_t *patch, UINT8 *cache, texpa if (count > 0) { for (; dest < cache + position + count; source++, dest++) - if (*dest != 0xFF) *dest = *(mytransmap + ((*dest)<<8) + (*source)); + if (*dest != 0xFF) + *dest = ASTBlendPixel_8bpp(*dest, *source, originPatch->style, originPatch->alpha); } patch = (column_t *)((UINT8 *)patch + patch->length + 4); @@ -269,11 +365,10 @@ static inline void R_DrawTransColumnInCache(column_t *patch, UINT8 *cache, texpa // R_DrawTransColumnInCache // Similar to the one above except that the column is inverted. // -static inline void R_DrawTransFlippedColumnInCache(column_t *patch, UINT8 *cache, texpatch_t *originPatch, INT32 cacheheight, INT32 patchheight) +static inline void R_DrawBlendFlippedColumnInCache(column_t *patch, UINT8 *cache, texpatch_t *originPatch, INT32 cacheheight, INT32 patchheight) { INT32 count, position; UINT8 *source, *dest; - UINT8 *mytransmap = transtables + ((8*(originPatch->alpha) + 255/8)/(255 - 255/11) << FF_TRANSSHIFT); // The equation's not exact but it works as intended. I'll call it a day for now. INT32 topdelta, prevdelta = -1; INT32 originy = originPatch->originy; @@ -302,7 +397,8 @@ static inline void R_DrawTransFlippedColumnInCache(column_t *patch, UINT8 *cache if (count > 0) { for (; dest < cache + position + count; --source, dest++) - if (*dest != 0xFF) *dest = *(mytransmap + ((*dest)<<8) + (*source)); + if (*dest != 0xFF) + *dest = ASTBlendPixel_8bpp(*dest, *source, originPatch->style, originPatch->alpha); } patch = (column_t *)((UINT8 *)patch + patch->length + 4); @@ -422,16 +518,10 @@ static UINT8 *R_GenerateTexture(size_t texnum) for (i = 0, patch = texture->patches; i < texture->patchcount; i++, patch++) { static void (*ColumnDrawerPointer)(column_t *, UINT8 *, texpatch_t *, INT32, INT32); // Column drawing function pointer. - if ((patch->style == AST_TRANSLUCENT) && (patch->alpha <= (10*255/11))) // Alpha style set to translucent? Is the alpha small enough for translucency? - { - if (patch->alpha < 255/11) // Is the patch way too translucent? Don't render then. - continue; - ColumnDrawerPointer = (patch->flip & 2) ? R_DrawTransFlippedColumnInCache : R_DrawTransColumnInCache; - } + if (patch->style != AST_COPY) + ColumnDrawerPointer = (patch->flip & 2) ? R_DrawBlendFlippedColumnInCache : R_DrawBlendColumnInCache; else - { ColumnDrawerPointer = (patch->flip & 2) ? R_DrawFlippedColumnInCache : R_DrawColumnInCache; - } realpatch = W_CacheLumpNumPwad(patch->wad, patch->lump, PU_CACHE); x1 = patch->originx; @@ -848,8 +938,16 @@ static texpatch_t *R_ParsePatch(boolean actuallyLoadPatch) { Z_Free(texturesToken); texturesToken = M_GetToken(NULL); - if(stricmp(texturesToken, "TRANSLUCENT")==0) + if (stricmp(texturesToken, "TRANSLUCENT")==0) style = AST_TRANSLUCENT; + else if (stricmp(texturesToken, "ADD")==0) + style = AST_ADD; + else if (stricmp(texturesToken, "SUBTRACT")==0) + style = AST_SUBTRACT; + else if (stricmp(texturesToken, "REVERSESUBTRACT")==0) + style = AST_REVERSESUBTRACT; + else if (stricmp(texturesToken, "MODULATE")==0) + style = AST_MODULATE; } else if (stricmp(texturesToken, "FLIPX")==0) flip |= 1; @@ -1615,7 +1713,6 @@ extracolormap_t *R_ColormapForName(char *name) // static double deltas[256][3], map[256][3]; -static UINT8 NearestColor(UINT8 r, UINT8 g, UINT8 b); static int RoundUp(double number); lighttable_t *R_CreateLightTable(extracolormap_t *extra_colormap) @@ -2027,7 +2124,7 @@ extracolormap_t *R_AddColormaps(extracolormap_t *exc_augend, extracolormap_t *ex // 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; diff --git a/src/r_data.h b/src/r_data.h index b6b0a16a1..af1c9114a 100644 --- a/src/r_data.h +++ b/src/r_data.h @@ -22,7 +22,12 @@ #endif // Possible alpha types for a patch. -enum patchalphastyle {AST_COPY, AST_TRANSLUCENT}; // , AST_ADD, AST_SUBTRACT, AST_REVERSESUBTRACT, AST_MODULATE, AST_OVERLAY}; +enum patchalphastyle {AST_COPY, AST_TRANSLUCENT, AST_ADD, AST_SUBTRACT, AST_REVERSESUBTRACT, AST_MODULATE, AST_OVERLAY}; + +RGBA_t ASTBlendPixel(RGBA_t background, RGBA_t foreground, int style, UINT8 alpha); +UINT8 ASTBlendPixel_8bpp(UINT8 background, UINT8 foreground, int style, UINT8 alpha); + +UINT8 NearestColor(UINT8 r, UINT8 g, UINT8 b); // moved here for r_sky.c (texpatch_t is used) From 11e3f5ec964112a8799b08a76eb3eef994baee4f Mon Sep 17 00:00:00 2001 From: toaster Date: Sun, 8 Sep 2019 21:21:36 +0100 Subject: [PATCH 44/51] Change flipped starpostz to define the top of the player object, for cases where scale on contact with starpost is different to spawn scale. --- src/m_cheat.c | 3 +++ src/p_inter.c | 4 ++-- src/p_mobj.c | 26 ++++++++++++++------------ 3 files changed, 19 insertions(+), 14 deletions(-) diff --git a/src/m_cheat.c b/src/m_cheat.c index ae2703ee2..bb757839a 100644 --- a/src/m_cheat.c +++ b/src/m_cheat.c @@ -833,7 +833,10 @@ void Command_Savecheckpoint_f(void) players[consoleplayer].starpostangle = players[consoleplayer].mo->angle; players[consoleplayer].starpostscale = players[consoleplayer].mo->destscale; if (players[consoleplayer].mo->flags2 & MF2_OBJECTFLIP) + { players[consoleplayer].starpostscale *= -1; + players[consoleplayer].starpostz += players[consoleplayer].mo->height; + } CONS_Printf(M_GetText("Temporary checkpoint created at %d, %d, %d\n"), players[consoleplayer].starpostx, players[consoleplayer].starposty, players[consoleplayer].starpostz); } diff --git a/src/p_inter.c b/src/p_inter.c index 53481d6c5..cc9250e42 100644 --- a/src/p_inter.c +++ b/src/p_inter.c @@ -1431,7 +1431,7 @@ void P_TouchSpecialThing(mobj_t *special, mobj_t *toucher, boolean heightcheck) if (special->flags2 & MF2_OBJECTFLIP) { players[i].starpostscale *= -1; - players[i].starpostz += (special->height - P_GetPlayerHeight(player))>>FRACBITS; + players[i].starpostz += special->height>>FRACBITS; } players[i].starpostnum = special->health; @@ -1453,7 +1453,7 @@ void P_TouchSpecialThing(mobj_t *special, mobj_t *toucher, boolean heightcheck) if (special->flags2 & MF2_OBJECTFLIP) { player->starpostscale *= -1; - player->starpostz += (special->height - P_GetPlayerHeight(player))>>FRACBITS; + player->starpostz += special->height>>FRACBITS; } player->starpostnum = special->health; S_StartSound(toucher, special->info->painsound); diff --git a/src/p_mobj.c b/src/p_mobj.c index 130808712..5843b9f43 100644 --- a/src/p_mobj.c +++ b/src/p_mobj.c @@ -10669,24 +10669,26 @@ void P_MovePlayerToStarpost(INT32 playernum) P_SetScale(mobj, (mobj->destscale = abs(p->starpostscale))); - mobj->floorz = floor; - mobj->ceilingz = ceiling; - - if (z <= floor) - z = floor; - else if (z >= ceiling - mobj->height) - z = ceiling - mobj->height; - - mobj->z = z; - if (p->starpostscale < 0) { mobj->flags2 |= MF2_OBJECTFLIP; - if (mobj->z + mobj->height == mobj->ceilingz) + if (z >= ceiling) + { mobj->eflags |= MFE_ONGROUND; + z = ceiling; + } + z -= mobj->height; } - else if (mobj->z == mobj->floorz) + else if (z <= floor) + { mobj->eflags |= MFE_ONGROUND; + z = floor; + } + + mobj->floorz = floor; + mobj->ceilingz = ceiling; + + mobj->z = z; mobj->angle = p->starpostangle; From ba50a03d9c13328124769006fd99d7dec2e6c939 Mon Sep 17 00:00:00 2001 From: toaster Date: Sun, 8 Sep 2019 21:28:02 +0100 Subject: [PATCH 45/51] Update SPR2_XTRA references for adjusted player.dta content. --- src/f_finale.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/f_finale.c b/src/f_finale.c index 056b7f815..e44add4d1 100644 --- a/src/f_finale.c +++ b/src/f_finale.c @@ -1584,15 +1584,15 @@ void F_StartEnding(void) UINT8 skinnum = players[consoleplayer].skin; spritedef_t *sprdef; spriteframe_t *sprframe; - if (skins[skinnum].sprites[SPR2_XTRA].numframes >= 5) + if (skins[skinnum].sprites[SPR2_XTRA].numframes >= 7) { sprdef = &skins[skinnum].sprites[SPR2_XTRA]; // character head, skin specific - sprframe = &sprdef->spriteframes[2]; - endfwrk[0] = W_CachePatchNum(sprframe->lumppat[0], PU_LEVEL); - sprframe = &sprdef->spriteframes[3]; - endfwrk[1] = W_CachePatchNum(sprframe->lumppat[0], PU_LEVEL); sprframe = &sprdef->spriteframes[4]; + endfwrk[0] = W_CachePatchNum(sprframe->lumppat[0], PU_LEVEL); + sprframe = &sprdef->spriteframes[5]; + endfwrk[1] = W_CachePatchNum(sprframe->lumppat[0], PU_LEVEL); + sprframe = &sprdef->spriteframes[6]; endfwrk[2] = W_CachePatchNum(sprframe->lumppat[0], PU_LEVEL); } else // Show a star if your character doesn't have an ending firework display. (Basically the MISSINGs for this) From 1bf78a242341c2a770690bf16b8968567d0906e6 Mon Sep 17 00:00:00 2001 From: Steel Titanium Date: Sun, 8 Sep 2019 17:14:47 -0400 Subject: [PATCH 46/51] Move mobj_t declaration to top of the block --- src/p_spec.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/p_spec.c b/src/p_spec.c index 014a09845..74bea7266 100644 --- a/src/p_spec.c +++ b/src/p_spec.c @@ -3956,6 +3956,7 @@ static void P_ProcessLineSpecial(line_t *line, mobj_t *mo, sector_t *callsec) case 461: // Spawns an object on the map based on texture offsets { const mobjtype_t type = (mobjtype_t)(sides[line->sidenum[0]].toptexture); + mobj_t *mobj; fixed_t x, y, z; x = sides[line->sidenum[0]].textureoffset; @@ -3977,7 +3978,7 @@ static void P_ProcessLineSpecial(line_t *line, mobj_t *mo, sector_t *callsec) } } - mobj_t *mobj = P_SpawnMobj(x, y, z, type); + mobj = P_SpawnMobj(x, y, z, type); if (mobj) CONS_Debug(DBG_GAMELOGIC, "Linedef Type %d - Spawn Object: %d spawned at (%d, %d, %d)\n", line->special, mobj->type, mobj->x>>FRACBITS, mobj->y>>FRACBITS, mobj->z>>FRACBITS); //TODO: Convert mobj->type to a string somehow. else From 0a69190848f196103840c5ba255a198144fcb439 Mon Sep 17 00:00:00 2001 From: Jaime Passos Date: Mon, 9 Sep 2019 15:39:10 -0300 Subject: [PATCH 47/51] Missing arguments --- src/hardware/hw_main.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/hardware/hw_main.c b/src/hardware/hw_main.c index 07ae7ed2b..4a075d376 100644 --- a/src/hardware/hw_main.c +++ b/src/hardware/hw_main.c @@ -3400,7 +3400,7 @@ static void HWR_AddPolyObjectPlanes(void) FBITFIELD blendmode; memset(&Surf, 0x00, sizeof(Surf)); 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, (light == -1 ? gr_frontsector->lightlevel : *gr_frontsector->lightlist[light].lightlevel), Surf.FlatColor.s.alpha, polyobjsector, blendmode, (light == -1 ? gr_frontsector->extra_colormap : *gr_frontsector->lightlist[light].extra_colormap)); } else @@ -3408,7 +3408,7 @@ static void HWR_AddPolyObjectPlanes(void) HWR_GetFlat(levelflats[polyobjsector->floorpic].lumpnum); HWR_GetTextureFlat(levelflats[polyobjsector->floorpic].texturenum); HWR_RenderPolyObjectPlane(po_ptrs[i], false, polyobjsector->floorheight, PF_Occlude, - (light == -1 ? gr_frontsector->lightlevel : *gr_frontsector->lightlist[light].lightlevel), levelflats[polyobjsector->floorpic].lumpnum, + (light == -1 ? gr_frontsector->lightlevel : *gr_frontsector->lightlist[light].lightlevel), levelflats[polyobjsector->floorpic].lumpnum, levelflats[polyobjsector->floorpic].texturenum, polyobjsector, 255, (light == -1 ? gr_frontsector->extra_colormap : *gr_frontsector->lightlist[light].extra_colormap)); } } @@ -3424,7 +3424,7 @@ 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->floorpic].texturenum, po_ptrs[i], true, polyobjsector->ceilingheight, (light == -1 ? gr_frontsector->lightlevel : *gr_frontsector->lightlist[light].lightlevel), Surf.FlatColor.s.alpha, polyobjsector, blendmode, (light == -1 ? gr_frontsector->extra_colormap : *gr_frontsector->lightlist[light].extra_colormap)); } else @@ -3432,7 +3432,7 @@ static void HWR_AddPolyObjectPlanes(void) HWR_GetFlat(levelflats[polyobjsector->ceilingpic].lumpnum); HWR_GetTextureFlat(levelflats[polyobjsector->ceilingpic].texturenum); HWR_RenderPolyObjectPlane(po_ptrs[i], true, polyobjsector->ceilingheight, PF_Occlude, - (light == -1 ? gr_frontsector->lightlevel : *gr_frontsector->lightlist[light].lightlevel), levelflats[polyobjsector->floorpic].lumpnum, + (light == -1 ? gr_frontsector->lightlevel : *gr_frontsector->lightlist[light].lightlevel), levelflats[polyobjsector->floorpic].lumpnum, levelflats[polyobjsector->floorpic].texturenum, polyobjsector, 255, (light == -1 ? gr_frontsector->extra_colormap : *gr_frontsector->lightlist[light].extra_colormap)); } } From 043bb86acdf81ef0ecbd388aed57fe0fa29c8747 Mon Sep 17 00:00:00 2001 From: Nev3r Date: Mon, 9 Sep 2019 18:40:21 +0000 Subject: [PATCH 48/51] Revert "Merge branch 'flats-png_port' into 'master'" This reverts merge request !322 --- src/doomdef.h | 4 - src/hardware/hw_cache.c | 114 +---- src/hardware/hw_glide.h | 2 - src/hardware/hw_glob.h | 3 - src/hardware/hw_light.c | 2 - src/hardware/hw_main.c | 207 ++++----- src/hardware/hw_md2.c | 4 - src/p_setup.c | 10 - src/p_setup.h | 7 - src/p_spec.c | 30 +- src/r_data.c | 643 ++-------------------------- src/r_data.h | 27 +- src/r_draw.c | 2 - src/r_draw.h | 13 +- src/r_draw8.c | 913 +++++++++++----------------------------- src/r_plane.c | 450 +++++++++----------- src/r_plane.h | 2 - src/screen.c | 2 +- src/w_wad.c | 2 + 19 files changed, 582 insertions(+), 1855 deletions(-) diff --git a/src/doomdef.h b/src/doomdef.h index 4a0174369..6e7db2143 100644 --- a/src/doomdef.h +++ b/src/doomdef.h @@ -616,8 +616,4 @@ extern const char *compdate, *comptime, *comprevision, *compbranch; /// SRB2CB itself ported this from PrBoom+ #define NEWCLIP -#ifndef HAVE_PNG -#define NO_PNG_LUMPS -#endif - #endif // __DOOMDEF__ diff --git a/src/hardware/hw_cache.c b/src/hardware/hw_cache.c index c9a75a4f3..6bc2c712e 100644 --- a/src/hardware/hw_cache.c +++ b/src/hardware/hw_cache.c @@ -30,7 +30,6 @@ #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) @@ -421,7 +420,6 @@ static void HWR_DrawTexturePatchInCache(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] = { @@ -458,9 +456,6 @@ 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) @@ -516,7 +511,6 @@ 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) @@ -534,14 +528,9 @@ 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; @@ -573,7 +562,6 @@ static void HWR_ResizeBlock(INT32 originalwidth, INT32 originalheight, if (blockwidth < blockheight) j += 4; grInfo->aspectRatioLog2 = gr_aspects[j].aspect; -#endif blocksize = blockwidth * blockheight; @@ -662,12 +650,7 @@ 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); -#ifndef NO_PNG_LUMPS - if (R_IsLumpPNG((UINT8 *)realpatch, lumplength)) - realpatch = R_PNGToPatch((UINT8 *)realpatch, lumplength); -#endif HWR_DrawTexturePatchInCache(&grtex->mipmap, blockwidth, blockheight, texture, patch, @@ -773,13 +756,11 @@ 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; } @@ -818,10 +799,7 @@ 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; } @@ -839,9 +817,6 @@ 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) @@ -872,7 +847,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]; @@ -887,39 +862,15 @@ GLTexture_t *HWR_GetTexture(INT32 tex) return grtex; } -// 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) -{ - UINT8 *flat; - patch_t *patch = (patch_t *)W_CacheLumpNum(flatlumpnum, PU_STATIC); - size_t lumplength = W_LumpLength(flatlumpnum); - -#ifndef NO_PNG_LUMPS - if (R_IsLumpPNG((UINT8 *)patch, lumplength)) - patch = R_PNGToPatch((UINT8 *)patch, lumplength); -#endif - - grMipmap->width = (UINT16)SHORT(patch->width); - grMipmap->height = (UINT16)SHORT(patch->height); - - flat = Z_Malloc(grMipmap->width * grMipmap->height, PU_HWRCACHE, &grMipmap->grInfo.data); - memset(flat, TRANSPARENTPIXEL, grMipmap->width * grMipmap->height); - - R_PatchToFlat(patch, flat); -} 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; @@ -949,20 +900,15 @@ static void HWR_CacheFlat(GLMipmap_t *grMipmap, lumpnum_t flatlumpnum) pflatsize = 64; break; } + grMipmap->width = (UINT16)pflatsize; + grMipmap->height = (UINT16)pflatsize; - 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)); - } + // 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) { @@ -977,52 +923,6 @@ 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; -} - -static void HWR_LoadTextureFlat(GLMipmap_t *grMipmap, INT32 texturenum) -{ - UINT8 *flat; - - // 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; - - grMipmap->width = (UINT16)textures[texturenum]->width; - grMipmap->height = (UINT16)textures[texturenum]->height; - - flat = Z_Malloc(grMipmap->width * grMipmap->height, PU_HWRCACHE, &grMipmap->grInfo.data); - memset(flat, TRANSPARENTPIXEL, grMipmap->width * grMipmap->height); - - R_TextureToFlat(texturenum, flat); -} - -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_glide.h b/src/hardware/hw_glide.h index bf91229ef..2625d5864 100644 --- a/src/hardware/hw_glide.h +++ b/src/hardware/hw_glide.h @@ -59,11 +59,9 @@ 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_glob.h b/src/hardware/hw_glob.h index c7b06edfd..9656e54e9 100644 --- a/src/hardware/hw_glob.h +++ b/src/hardware/hw_glob.h @@ -101,7 +101,6 @@ 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); @@ -115,8 +114,6 @@ 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_light.c b/src/hardware/hw_light.c index 1de20cad7..edfe328b8 100644 --- a/src/hardware/hw_light.c +++ b/src/hardware/hw_light.c @@ -1225,11 +1225,9 @@ 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_main.c b/src/hardware/hw_main.c index 07ae7ed2b..c6a8b16e5 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, INT32 texturenum, extrasubsector_t *xsub, boolean isceiling, fixed_t fixedheight, +void HWR_AddTransparentFloor(lumpnum_t lumpnum, 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, INT32 texturenum, polyobj_t *polysector, boolean isceiling, fixed_t fixedheight, +void HWR_AddTransparentPolyobjectFloor(lumpnum_t lumpnum, 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, INT32 texturenum, sector_t *FOFsector, UINT8 alpha, boolean fogplane, extracolormap_t *planecolormap) + FBITFIELD PolyFlags, INT32 lightlevel, lumpnum_t lumpnum, 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,9 +530,8 @@ 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 fflatwidth, fflatheight; + float fflatsize; INT32 flatflag; - boolean texflat = true; size_t len; float scrollx = 0.0f, scrolly = 0.0f; angle_t angle = 0; @@ -541,7 +540,6 @@ 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; @@ -582,10 +580,9 @@ static void HWR_RenderPlane(sector_t *sector, extrasubsector_t *xsub, boolean is if (nrPlaneVerts < 3) //not even a triangle ? return; - // This check is so inconsistent between functions, it hurts. - if (nrPlaneVerts > INT16_MAX) // FIXME: exceeds plVerts size + if (nrPlaneVerts > (INT32)UINT16_MAX) // FIXME: exceeds plVerts size { - CONS_Debug(DBG_RENDER, "polygon size of %d exceeds max value of %d vertices\n", nrPlaneVerts, INT16_MAX); + CONS_Debug(DBG_RENDER, "polygon size of %d exceeds max value of %d vertices\n", nrPlaneVerts, UINT16_MAX); return; } @@ -602,47 +599,38 @@ static void HWR_RenderPlane(sector_t *sector, extrasubsector_t *xsub, boolean is switch (len) { case 4194304: // 2048x2048 lump - fflatwidth = fflatheight = 2048.0f; + fflatsize = 2048.0f; + flatflag = 2047; break; case 1048576: // 1024x1024 lump - fflatwidth = fflatheight = 1024.0f; + fflatsize = 1024.0f; + flatflag = 1023; break; case 262144:// 512x512 lump - fflatwidth = fflatheight = 512.0f; + fflatsize = 512.0f; + flatflag = 511; break; case 65536: // 256x256 lump - fflatwidth = fflatheight = 256.0f; + fflatsize = 256.0f; + flatflag = 255; break; case 16384: // 128x128 lump - fflatwidth = fflatheight = 128.0f; + fflatsize = 128.0f; + flatflag = 127; break; case 1024: // 32x32 lump - fflatwidth = fflatheight = 32.0f; + fflatsize = 32.0f; + flatflag = 31; break; default: // 64x64 lump - fflatwidth = fflatheight = 64.0f; + fflatsize = 64.0f; + flatflag = 63; break; } - 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)(((fixed_t)pv->x & (~flatflag)) / fflatwidth); - flatyref = (float)(((fixed_t)pv->y & (~flatflag)) / fflatheight); + flatxref = (float)(((fixed_t)pv->x & (~flatflag)) / fflatsize); + flatyref = (float)(((fixed_t)pv->y & (~flatflag)) / fflatsize); // transform v3d = planeVerts; @@ -651,14 +639,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)/fflatwidth; - scrolly = FIXED_TO_FLOAT(FOFsector->floor_yoffs)/fflatheight; + scrollx = FIXED_TO_FLOAT(FOFsector->floor_xoffs)/fflatsize; + scrolly = FIXED_TO_FLOAT(FOFsector->floor_yoffs)/fflatsize; angle = FOFsector->floorpic_angle; } else // it's a ceiling { - scrollx = FIXED_TO_FLOAT(FOFsector->ceiling_xoffs)/fflatwidth; - scrolly = FIXED_TO_FLOAT(FOFsector->ceiling_yoffs)/fflatheight; + scrollx = FIXED_TO_FLOAT(FOFsector->ceiling_xoffs)/fflatsize; + scrolly = FIXED_TO_FLOAT(FOFsector->ceiling_yoffs)/fflatsize; angle = FOFsector->ceilingpic_angle; } } @@ -666,14 +654,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)/fflatwidth; - scrolly = FIXED_TO_FLOAT(gr_frontsector->floor_yoffs)/fflatheight; + scrollx = FIXED_TO_FLOAT(gr_frontsector->floor_xoffs)/fflatsize; + scrolly = FIXED_TO_FLOAT(gr_frontsector->floor_yoffs)/fflatsize; angle = gr_frontsector->floorpic_angle; } else // it's a ceiling { - scrollx = FIXED_TO_FLOAT(gr_frontsector->ceiling_xoffs)/fflatwidth; - scrolly = FIXED_TO_FLOAT(gr_frontsector->ceiling_yoffs)/fflatheight; + scrollx = FIXED_TO_FLOAT(gr_frontsector->ceiling_xoffs)/fflatsize; + scrolly = FIXED_TO_FLOAT(gr_frontsector->ceiling_yoffs)/fflatsize; angle = gr_frontsector->ceilingpic_angle; } } @@ -692,24 +680,17 @@ 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 - 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); - } + v3d->sow = (float)((pv->x / fflatsize) - flatxref + scrollx); + v3d->tow = (float)(-(pv->y / fflatsize) + flatyref + scrolly); + + //v3d->sow = (float)(pv->x / fflatsize); + //v3d->tow = (float)(pv->y / fflatsize); // 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)))); } @@ -3183,23 +3164,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, INT32 texturenum, sector_t *FOFsector, + FBITFIELD blendmode, UINT8 lightlevel, lumpnum_t lumpnum, 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 fflatwidth, fflatheight; + float fflatsize; INT32 flatflag; - boolean texflat = true; 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; @@ -3230,47 +3209,38 @@ static void HWR_RenderPolyObjectPlane(polyobj_t *polysector, boolean isceiling, switch (len) { case 4194304: // 2048x2048 lump - fflatwidth = fflatheight = 2048.0f; + fflatsize = 2048.0f; + flatflag = 2047; break; case 1048576: // 1024x1024 lump - fflatwidth = fflatheight = 1024.0f; + fflatsize = 1024.0f; + flatflag = 1023; break; case 262144:// 512x512 lump - fflatwidth = fflatheight = 512.0f; + fflatsize = 512.0f; + flatflag = 511; break; case 65536: // 256x256 lump - fflatwidth = fflatheight = 256.0f; + fflatsize = 256.0f; + flatflag = 255; break; case 16384: // 128x128 lump - fflatwidth = fflatheight = 128.0f; + fflatsize = 128.0f; + flatflag = 127; break; case 1024: // 32x32 lump - fflatwidth = fflatheight = 32.0f; + fflatsize = 32.0f; + flatflag = 31; break; default: // 64x64 lump - fflatwidth = fflatheight = 64.0f; + fflatsize = 64.0f; + flatflag = 63; break; } - 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 & (~flatflag)) / fflatwidth); - flatyref = (float)((polysector->origVerts[0].y & (~flatflag)) / fflatheight); + 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); // transform v3d = planeVerts; @@ -3279,14 +3249,14 @@ static void HWR_RenderPolyObjectPlane(polyobj_t *polysector, boolean isceiling, { if (!isceiling) // it's a floor { - scrollx = FIXED_TO_FLOAT(FOFsector->floor_xoffs)/fflatwidth; - scrolly = FIXED_TO_FLOAT(FOFsector->floor_yoffs)/fflatheight; + scrollx = FIXED_TO_FLOAT(FOFsector->floor_xoffs)/fflatsize; + scrolly = FIXED_TO_FLOAT(FOFsector->floor_yoffs)/fflatsize; angle = FOFsector->floorpic_angle>>ANGLETOFINESHIFT; } else // it's a ceiling { - scrollx = FIXED_TO_FLOAT(FOFsector->ceiling_xoffs)/fflatwidth; - scrolly = FIXED_TO_FLOAT(FOFsector->ceiling_yoffs)/fflatheight; + scrollx = FIXED_TO_FLOAT(FOFsector->ceiling_xoffs)/fflatsize; + scrolly = FIXED_TO_FLOAT(FOFsector->ceiling_yoffs)/fflatsize; angle = FOFsector->ceilingpic_angle>>ANGLETOFINESHIFT; } } @@ -3294,14 +3264,14 @@ static void HWR_RenderPolyObjectPlane(polyobj_t *polysector, boolean isceiling, { if (!isceiling) // it's a floor { - scrollx = FIXED_TO_FLOAT(gr_frontsector->floor_xoffs)/fflatwidth; - scrolly = FIXED_TO_FLOAT(gr_frontsector->floor_yoffs)/fflatheight; + scrollx = FIXED_TO_FLOAT(gr_frontsector->floor_xoffs)/fflatsize; + scrolly = FIXED_TO_FLOAT(gr_frontsector->floor_yoffs)/fflatsize; angle = gr_frontsector->floorpic_angle>>ANGLETOFINESHIFT; } else // it's a ceiling { - scrollx = FIXED_TO_FLOAT(gr_frontsector->ceiling_xoffs)/fflatwidth; - scrolly = FIXED_TO_FLOAT(gr_frontsector->ceiling_yoffs)/fflatheight; + scrollx = FIXED_TO_FLOAT(gr_frontsector->ceiling_xoffs)/fflatsize; + scrolly = FIXED_TO_FLOAT(gr_frontsector->ceiling_yoffs)/fflatsize; angle = gr_frontsector->ceilingpic_angle>>ANGLETOFINESHIFT; } } @@ -3324,26 +3294,15 @@ static void HWR_RenderPolyObjectPlane(polyobj_t *polysector, boolean isceiling, for (i = 0; i < (INT32)nrPlaneVerts; i++,v3d++) { - // 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); - } + // 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 // 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)))); } @@ -3406,7 +3365,6 @@ static void HWR_AddPolyObjectPlanes(void) else { HWR_GetFlat(levelflats[polyobjsector->floorpic].lumpnum); - HWR_GetTextureFlat(levelflats[polyobjsector->floorpic].texturenum); HWR_RenderPolyObjectPlane(po_ptrs[i], false, polyobjsector->floorheight, PF_Occlude, (light == -1 ? gr_frontsector->lightlevel : *gr_frontsector->lightlist[light].lightlevel), levelflats[polyobjsector->floorpic].lumpnum, polyobjsector, 255, (light == -1 ? gr_frontsector->extra_colormap : *gr_frontsector->lightlist[light].extra_colormap)); @@ -3430,7 +3388,6 @@ static void HWR_AddPolyObjectPlanes(void) else { HWR_GetFlat(levelflats[polyobjsector->ceilingpic].lumpnum); - HWR_GetTextureFlat(levelflats[polyobjsector->ceilingpic].texturenum); HWR_RenderPolyObjectPlane(po_ptrs[i], true, polyobjsector->ceilingheight, PF_Occlude, (light == -1 ? gr_frontsector->lightlevel : *gr_frontsector->lightlist[light].lightlevel), levelflats[polyobjsector->floorpic].lumpnum, polyobjsector, 255, (light == -1 ? gr_frontsector->extra_colormap : *gr_frontsector->lightlist[light].extra_colormap)); @@ -3584,12 +3541,11 @@ 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, levelflats[gr_frontsector->floorpic].texturenum, NULL, 255, false, floorcolormap); + PF_Occlude, floorlightlevel, levelflats[gr_frontsector->floorpic].lumpnum, NULL, 255, false, floorcolormap); } } else @@ -3607,12 +3563,11 @@ 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, levelflats[gr_frontsector->ceilingpic].texturenum, NULL, 255, false, ceilingcolormap); + PF_Occlude, ceilinglightlevel, levelflats[gr_frontsector->ceilingpic].lumpnum,NULL, 255, false, ceilingcolormap); } } else @@ -3671,7 +3626,7 @@ static void HWR_Subsector(size_t num) else alpha = HWR_FogBlockAlpha(*gr_frontsector->lightlist[light].lightlevel, NORMALFOG); - HWR_AddTransparentFloor(0, 0, + HWR_AddTransparentFloor(0, &extrasubsectors[num], false, *rover->bottomheight, @@ -3690,7 +3645,6 @@ 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, @@ -3702,9 +3656,8 @@ 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, levelflats[*rover->bottompic].texturenum, + HWR_RenderPlane(NULL, &extrasubsectors[num], false, *rover->bottomheight, PF_Occlude, *gr_frontsector->lightlist[light].lightlevel, levelflats[*rover->bottompic].lumpnum, rover->master->frontsector, 255, false, *gr_frontsector->lightlist[light].extra_colormap); } } @@ -3736,7 +3689,7 @@ static void HWR_Subsector(size_t num) else alpha = HWR_FogBlockAlpha(*gr_frontsector->lightlist[light].lightlevel, NORMALFOG); - HWR_AddTransparentFloor(0, 0, + HWR_AddTransparentFloor(0, &extrasubsectors[num], true, *rover->topheight, @@ -3755,7 +3708,6 @@ 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, @@ -3768,9 +3720,8 @@ 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, levelflats[*rover->toppic].texturenum, + HWR_RenderPlane(NULL, &extrasubsectors[num], true, *rover->topheight, PF_Occlude, *gr_frontsector->lightlist[light].lightlevel, levelflats[*rover->toppic].lumpnum, rover->master->frontsector, 255, false, *gr_frontsector->lightlist[light].extra_colormap); } } @@ -5099,7 +5050,6 @@ typedef struct fixed_t fixedheight; INT32 lightlevel; lumpnum_t lumpnum; - INT32 texturenum; INT32 alpha; sector_t *FOFSector; FBITFIELD blend; @@ -5118,7 +5068,6 @@ typedef struct fixed_t fixedheight; INT32 lightlevel; lumpnum_t lumpnum; - INT32 texturenum; INT32 alpha; sector_t *FOFSector; FBITFIELD blend; @@ -5149,7 +5098,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, INT32 texturenum, extrasubsector_t *xsub, boolean isceiling, +void HWR_AddTransparentFloor(lumpnum_t lumpnum, 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; @@ -5168,7 +5117,6 @@ void HWR_AddTransparentFloor(lumpnum_t lumpnum, INT32 texturenum, extrasubsector 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; @@ -5182,7 +5130,7 @@ void HWR_AddTransparentFloor(lumpnum_t lumpnum, INT32 texturenum, extrasubsector // 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, INT32 texturenum, polyobj_t *polysector, boolean isceiling, +void HWR_AddTransparentPolyobjectFloor(lumpnum_t lumpnum, 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; @@ -5201,7 +5149,6 @@ void HWR_AddTransparentPolyobjectFloor(lumpnum_t lumpnum, INT32 texturenum, poly 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; @@ -5363,12 +5310,9 @@ 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->texturenum, 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->FOFSector, sortnode[sortindex[i]].plane->alpha, sortnode[sortindex[i]].plane->fogplane, sortnode[sortindex[i]].plane->planecolormap); } else if (sortnode[sortindex[i]].polyplane) { @@ -5376,12 +5320,9 @@ 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->texturenum, sortnode[sortindex[i]].polyplane->FOFSector, sortnode[sortindex[i]].polyplane->alpha, sortnode[sortindex[i]].polyplane->planecolormap); + sortnode[sortindex[i]].polyplane->lumpnum, 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/hardware/hw_md2.c b/src/hardware/hw_md2.c index 7b6367cf3..d4728315a 100644 --- a/src/hardware/hw_md2.c +++ b/src/hardware/hw_md2.c @@ -747,12 +747,10 @@ 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); @@ -800,12 +798,10 @@ 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); diff --git a/src/p_setup.c b/src/p_setup.c index 60e036a87..65335be3f 100644 --- a/src/p_setup.c +++ b/src/p_setup.c @@ -573,11 +573,6 @@ INT32 P_AddLevelFlat(const char *flatname, levelflat_t *levelflat) // store the flat lump number levelflat->lumpnum = R_GetFlatNumForName(flatname); - 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); @@ -622,11 +617,6 @@ INT32 P_AddLevelFlatRuntime(const char *flatname) // store the flat lump number levelflat->lumpnum = R_GetFlatNumForName(flatname); - 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 7e3a149eb..7e8a5d7e6 100644 --- a/src/p_setup.h +++ b/src/p_setup.h @@ -37,19 +37,12 @@ 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; - - // for patchflats - UINT8 *flatpatch; } levelflat_t; extern size_t numlevelflats; diff --git a/src/p_spec.c b/src/p_spec.c index 256ca3453..7742554cd 100644 --- a/src/p_spec.c +++ b/src/p_spec.c @@ -205,8 +205,8 @@ void P_InitPicAnims(void) if ((W_CheckNumForName(animdefs[i].startname)) == LUMPERROR) continue; - lastanim->picnum = R_GetFlatNumForName(animdefs[i].endname); - lastanim->basepic = R_GetFlatNumForName(animdefs[i].startname); + lastanim->picnum = R_FlatNumForName(animdefs[i].endname); + lastanim->basepic = R_FlatNumForName(animdefs[i].startname); } lastanim->istexture = animdefs[i].istexture; @@ -464,19 +464,7 @@ static inline void P_FindAnimatedFlat(INT32 animnum) for (i = 0; i < numlevelflats; i++, foundflats++) { // is that levelflat from the flat anim sequence ? - 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) + if (foundflats->lumpnum >= startflatnum && foundflats->lumpnum <= endflatnum) { foundflats->baselumpnum = startflatnum; foundflats->animseq = foundflats->lumpnum - startflatnum; @@ -500,7 +488,10 @@ void P_SetupLevelFlatAnims(void) // the original game flat anim sequences for (i = 0; anims[i].istexture != -1; i++) - P_FindAnimatedFlat(i); + { + if (!anims[i].istexture) + P_FindAnimatedFlat(i); + } } // @@ -5678,12 +5669,9 @@ 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 - else if (foundflats->baselumpnum != LUMPERROR) - foundflats->lumpnum = foundflats->baselumpnum + ((leveltime/foundflats->speed + foundflats->animseq) % foundflats->numpics); + foundflats->lumpnum = foundflats->baselumpnum + + ((leveltime/foundflats->speed + foundflats->animseq) % foundflats->numpics); } } } diff --git a/src/r_data.c b/src/r_data.c index 5858117a5..6889bddde 100644 --- a/src/r_data.c +++ b/src/r_data.c @@ -40,28 +40,6 @@ #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, @@ -120,11 +98,12 @@ 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 -INT32 *texturewidth; +// texture width is a power of 2, so it can easily repeat along sidedefs using a simple mask +INT32 *texturewidthmask; + fixed_t *textureheight; // needed for texture pegging INT32 *texturetranslation; @@ -336,7 +315,7 @@ static inline void R_DrawTransFlippedColumnInCache(column_t *patch, UINT8 *cache // 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 (lol), dynamic ligthing, & speed. +// been simplified for the sake of highcolor, dynamic ligthing, & speed. // // This is not optimised, but it's supposed to be executed only once // per level, when enough memory is available. @@ -353,10 +332,6 @@ 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); @@ -371,19 +346,7 @@ static UINT8 *R_GenerateTexture(size_t texnum) { boolean holey = false; patch = texture->patches; - - wadnum = patch->wad; - lumpnum = patch->lump; - lumplength = W_LumpLengthPwad(wadnum, lumpnum); - realpatch = W_CacheLumpNumPwad(wadnum, lumpnum, PU_CACHE); - -#ifndef NO_PNG_LUMPS - if (R_IsLumpPNG((UINT8 *)realpatch, lumplength)) - { - realpatch = R_PNGToPatch((UINT8 *)realpatch, lumplength); - goto multipatch; - } -#endif + realpatch = W_CacheLumpNumPwad(patch->wad, patch->lump, PU_CACHE); // Check the patch for holes. if (texture->width > SHORT(realpatch->width) || texture->height > SHORT(realpatch->height)) @@ -413,7 +376,7 @@ static UINT8 *R_GenerateTexture(size_t texnum) { texture->holes = true; texture->flip = patch->flip; - blocksize = lumplength; + blocksize = W_LumpLengthPwad(patch->wad, patch->lump); block = Z_Calloc(blocksize, PU_STATIC, // will change tag at end of this function &texturecache[texnum]); M_Memcpy(block, realpatch, blocksize); @@ -440,9 +403,6 @@ static UINT8 *R_GenerateTexture(size_t texnum) } // multi-patch textures (or 'composite') -#ifndef NO_PNG_LUMPS - multipatch: -#endif texture->holes = false; texture->flip = 0; blocksize = (texture->width * 4) + (texture->width * texture->height); @@ -473,15 +433,7 @@ static UINT8 *R_GenerateTexture(size_t texnum) ColumnDrawerPointer = (patch->flip & 2) ? R_DrawFlippedColumnInCache : R_DrawColumnInCache; } - wadnum = patch->wad; - lumpnum = patch->lump; - lumplength = W_LumpLengthPwad(wadnum, lumpnum); - realpatch = W_CacheLumpNumPwad(wadnum, lumpnum, PU_CACHE); -#ifndef NO_PNG_LUMPS - if (R_IsLumpPNG((UINT8 *)realpatch, lumplength)) - realpatch = R_PNGToPatch((UINT8 *)realpatch, lumplength); -#endif - + realpatch = W_CacheLumpNumPwad(patch->wad, patch->lump, PU_CACHE); x1 = patch->originx; width = SHORT(realpatch->width); height = SHORT(realpatch->height); @@ -557,14 +509,10 @@ 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); @@ -602,7 +550,7 @@ void R_ParseTEXTURESLump(UINT16 wadNum, UINT16 lumpNum, INT32 *index); #define TX_END "TX_END" void R_LoadTextures(void) { - INT32 i, w; + INT32 i, k, w; UINT16 j; UINT16 texstart, texend, texturesLumpPos; patch_t *patchlump; @@ -619,7 +567,6 @@ void R_LoadTextures(void) } Z_Free(texturetranslation); Z_Free(textures); - Z_Free(texflats); } // Load patches and textures. @@ -680,16 +627,15 @@ 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 *))); // Allocate texture referencing cache. - texturecache = (void *)((UINT8 *)textures + ((numtextures * sizeof(void *)) * 2)); - // Allocate texture width table. - texturewidth = (void *)((UINT8 *)textures + ((numtextures * sizeof(void *)) * 3)); - // Allocate texture height table. - textureheight = (void *)((UINT8 *)textures + ((numtextures * sizeof(void *)) * 4)); + 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. + textureheight = (void *)((UINT8 *)textures + ((numtextures * sizeof(void *)) * 4)); // Create translation table for global animation. texturetranslation = Z_Malloc((numtextures + 1) * sizeof(*texturetranslation), PU_STATIC, NULL); @@ -727,39 +673,20 @@ void R_LoadTextures(void) // Work through each lump between the markers in the WAD. for (j = 0; j < (texend - texstart); j++) { - UINT16 wadnum = (UINT16)w; - lumpnum_t lumpnum = texstart + j; - size_t lumplength; - if (wadfiles[w]->type == RET_PK3) { - if (W_IsLumpFolder(wadnum, lumpnum)) // Check if lump is a folder + if (W_IsLumpFolder((UINT16)w, texstart + j)) // Check if lump is a folder continue; // If it is then SKIP IT } - - lumplength = W_LumpLengthPwad(wadnum, lumpnum); - patchlump = W_CacheLumpNumPwad(wadnum, lumpnum, PU_CACHE); + patchlump = W_CacheLumpNumPwad((UINT16)w, texstart + j, PU_CACHE); //CONS_Printf("\n\"%s\" is a single patch, dimensions %d x %d",W_CheckNameForNumPwad((UINT16)w,texstart+j),patchlump->width, patchlump->height); texture = textures[i] = Z_Calloc(sizeof(texture_t) + sizeof(texpatch_t), PU_STATIC, NULL); // Set texture properties. - M_Memcpy(texture->name, W_CheckNameForNumPwad(wadnum, lumpnum), sizeof(texture->name)); - -#ifndef NO_PNG_LUMPS - if (R_IsLumpPNG((UINT8 *)patchlump, lumplength)) - { - INT16 width, height; - R_PNGDimensions((UINT8 *)patchlump, &width, &height, lumplength); - texture->width = width; - texture->height = height; - } - else -#endif - { - texture->width = SHORT(patchlump->width); - texture->height = SHORT(patchlump->height); - } + M_Memcpy(texture->name, W_CheckNameForNumPwad((UINT16)w, texstart + j), sizeof(texture->name)); + texture->width = SHORT(patchlump->width); + texture->height = SHORT(patchlump->height); texture->patchcount = 1; texture->holes = false; texture->flip = 0; @@ -774,7 +701,11 @@ void R_LoadTextures(void) Z_Unlock(patchlump); - texturewidth[i] = texture->width; + k = 1; + while (k << 1 <= texture->width) + k <<= 1; + + texturewidthmask[i] = k - 1; textureheight[i] = texture->height << FRACBITS; i++; } @@ -1166,7 +1097,7 @@ int R_CountTexturesInTEXTURESLump(UINT16 wadNum, UINT16 lumpNum) texturesToken = M_GetToken(texturesText); while (texturesToken != NULL) { - if (stricmp(texturesToken, "WALLTEXTURE") == 0 || stricmp(texturesToken, "TEXTURE") == 0) + if (stricmp(texturesToken, "WALLTEXTURE")==0) { numTexturesInLump++; Z_Free(texturesToken); @@ -1174,7 +1105,7 @@ int R_CountTexturesInTEXTURESLump(UINT16 wadNum, UINT16 lumpNum) } else { - I_Error("Error parsing TEXTURES lump: Expected \"WALLTEXTURE\" or \"TEXTURE\", got \"%s\"",texturesToken); + I_Error("Error parsing TEXTURES lump: Expected \"WALLTEXTURE\", got \"%s\"",texturesToken); } texturesToken = M_GetToken(NULL); } @@ -1215,21 +1146,21 @@ void R_ParseTEXTURESLump(UINT16 wadNum, UINT16 lumpNum, INT32 *texindex) texturesToken = M_GetToken(texturesText); while (texturesToken != NULL) { - if (stricmp(texturesToken, "WALLTEXTURE") == 0 || stricmp(texturesToken, "TEXTURE") == 0) + if (stricmp(texturesToken, "WALLTEXTURE")==0) { Z_Free(texturesToken); // Get the new texture newTexture = R_ParseTexture(true); // Store the new texture textures[*texindex] = newTexture; - texturewidth[*texindex] = newTexture->width; + texturewidthmask[*texindex] = newTexture->width - 1; textureheight[*texindex] = newTexture->height << FRACBITS; // Increment i back in R_LoadTextures() (*texindex)++; } else { - I_Error("Error parsing TEXTURES lump: Expected \"WALLTEXTURE\" or \"TEXTURE\", got \"%s\"",texturesToken); + I_Error("Error parsing TEXTURES lump: Expected \"WALLTEXTURE\", got \"%s\"",texturesToken); } texturesToken = M_GetToken(NULL); } @@ -1336,41 +1267,6 @@ lumpnum_t R_GetFlatNumForName(const char *name) lump = LUMPERROR; } - // Detect textures - if (lump == LUMPERROR) - { - // Scan wad files backwards so patched textures 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)) @@ -1719,6 +1615,7 @@ extracolormap_t *R_ColormapForName(char *name) // static double deltas[256][3], map[256][3]; +static UINT8 NearestColor(UINT8 r, UINT8 g, UINT8 b); static int RoundUp(double number); lighttable_t *R_CreateLightTable(extracolormap_t *extra_colormap) @@ -2130,7 +2027,7 @@ extracolormap_t *R_AddColormaps(extracolormap_t *exc_augend, extracolormap_t *ex // Thanks to quake2 source! // utils3/qdata/images.c -UINT8 NearestColor(UINT8 r, UINT8 g, UINT8 b) +static UINT8 NearestColor(UINT8 r, UINT8 g, UINT8 b) { int dr, dg, db; int distortion, bestdistortion = 256 * 256 * 4, bestcolor = 0, i; @@ -2409,479 +2306,3 @@ 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 < (INT16)(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; - } - } - } - - return result; -} - -void R_PatchToFlat(patch_t *patch, UINT8 *flat) -{ - fixed_t col, ofs; - column_t *column; - UINT8 *desttop, *dest, *deststop; - UINT8 *source; - - desttop = flat; - deststop = desttop + (SHORT(patch->width) * SHORT(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 * SHORT(patch->width)); - source = (UINT8 *)(column) + 3; - for (ofs = 0; dest < deststop && ofs < column->length; ofs++) - { - *dest = source[ofs]; - dest += SHORT(patch->width); - } - column = (column_t *)((UINT8 *)column + column->length + 4); - } - } -} - -#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, "PNG_IOReader: buffer overrun"); - 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 - - // set our own read_function - png_io.buffer = (png_bytep)png; - png_io.bufsize = size; - png_io.current_pos = 0; - 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) - I_Error("PNG_RawConvert: conversion failed"); - - // Convert the image to 8bpp - flat = Z_Malloc(width * height, PU_LEVEL, 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]); - if ((UINT8)px[3]) - flat[((y * width) + x)] = NearestColor((UINT8)px[0], (UINT8)px[1], (UINT8)px[2]); - } - } - free(row_pointers); - - return flat; -} - -// 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. -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); - - 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) - I_Error("R_PNGToPatch: conversion failed"); - - // 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)]; - - // 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); - - Z_Free(raw); - - 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 - - // set our own read_function - png_io.buffer = (png_bytep)png; - png_io.bufsize = size; - png_io.current_pos = 0; - 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]; - - 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 < texture->width; col++, desttop++) - { - 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 - { - INT32 topdelta, prevdelta = -1; - 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); - } - } - } -} diff --git a/src/r_data.h b/src/r_data.h index b29bf4557..b6b0a16a1 100644 --- a/src/r_data.h +++ b/src/r_data.h @@ -16,7 +16,6 @@ #include "r_defs.h" #include "r_state.h" -#include "p_setup.h" // levelflats #ifdef __GNUG__ #pragma interface @@ -56,17 +55,12 @@ typedef struct texpatch_t patches[0]; } texture_t; -typedef struct -{ - UINT8 *flat; - INT16 width, height; -} textureflat_t; - // all loaded and prepared textures from the start of the game extern texture_t **textures; -extern textureflat_t *texflats; -extern INT32 *texturewidth; +// texture width is a power of 2, so it can easily repeat along sidedefs using a simple mask +extern INT32 *texturewidthmask; + extern fixed_t *textureheight; // needed for texture pegging extern INT16 color8to16[256]; // remap color index to highcolor @@ -94,6 +88,7 @@ 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. @@ -153,20 +148,6 @@ const char *R_NameForColormap(extracolormap_t *extra_colormap); #define R_PutRgbaRGB(r, g, b) (R_PutRgbaR(r) + R_PutRgbaG(g) + R_PutRgbaB(b)) #define R_PutRgbaRGBA(r, g, b, a) (R_PutRgbaRGB(r, g, b) + R_PutRgbaA(a)) -boolean R_CheckIfPatch(lumpnum_t lump); -UINT8 NearestColor(UINT8 r, UINT8 g, UINT8 b); - -void R_PatchToFlat(patch_t *patch, UINT8 *flat); -void R_TextureToFlat(size_t tex, UINT8 *flat); - -#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_draw.c b/src/r_draw.c index 1754403c4..396ed0344 100644 --- a/src/r_draw.c +++ b/src/r_draw.c @@ -99,8 +99,6 @@ 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 3c1429722..82498eb11 100644 --- a/src/r_draw.h +++ b/src/r_draw.h @@ -57,9 +57,7 @@ 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 UINT16 ds_flatwidth, ds_flatheight; -extern boolean ds_powersoftwo; -extern UINT8 *ds_source; +extern UINT8 *ds_source; // start of a 64*64 tile image extern UINT8 *ds_transmap; #ifdef ESLOPE @@ -130,8 +128,6 @@ void R_FillBackScreen(void); void R_DrawViewBorder(void); #endif -#define TRANSPARENTPIXEL 255 - // ----------------- // 8bpp DRAWING CODE // ----------------- @@ -173,13 +169,6 @@ 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 77406f83c..8a2d37fb3 100644 --- a/src/r_draw8.c +++ b/src/r_draw8.c @@ -105,6 +105,8 @@ void R_DrawColumn_8(void) } } +#define TRANSPARENTPIXEL 255 + void R_Draw2sMultiPatchColumn_8(void) { INT32 count; @@ -541,19 +543,16 @@ void R_DrawTranslatedColumn_8(void) */ void R_DrawSpan_8 (void) { - fixed_t xposition; - fixed_t yposition; - fixed_t xstep, ystep; + UINT32 xposition; + UINT32 yposition; + UINT32 xstep, ystep; UINT8 *source; UINT8 *colormap; UINT8 *dest; const UINT8 *deststop = screens[0] + vid.rowbytes * vid.height; - size_t count = (ds_x2 - ds_x1 + 1); - - xposition = ds_xfrac; yposition = ds_yfrac; - xstep = ds_xstep; ystep = ds_ystep; + 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 @@ -562,88 +561,62 @@ void R_DrawSpan_8 (void) // 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; - xstep <<= nflatshiftup; ystep <<= nflatshiftup; - } + xposition = ds_xfrac << nflatshiftup; yposition = ds_yfrac << nflatshiftup; + xstep = ds_xstep << nflatshiftup; ystep = ds_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) return; - if (!ds_powersoftwo) + while (count >= 8) { - while (count-- && dest <= deststop) - { - fixed_t x = (xposition >> FRACBITS); - fixed_t y = (yposition >> FRACBITS); + // 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; - // 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[1] = colormap[source[((yposition >> nflatyshift) & nflatmask) | (xposition >> nflatxshift)]]; + xposition += xstep; + yposition += ystep; - x %= ds_flatwidth; - y %= ds_flatheight; + dest[2] = colormap[source[((yposition >> nflatyshift) & nflatmask) | (xposition >> nflatxshift)]]; + xposition += xstep; + yposition += ystep; - *dest++ = colormap[source[((y * ds_flatwidth) + x)]]; - 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; } - else + while (count-- && dest <= deststop) { - 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)]]; - xposition += xstep; - yposition += ystep; - } + *dest++ = colormap[source[((yposition >> nflatyshift) & nflatmask) | (xposition >> nflatxshift)]]; + xposition += xstep; + yposition += ystep; } } @@ -724,24 +697,7 @@ void R_DrawTiltedSpan_8(void) colormap = planezlight[tiltlighting[ds_x1++]] + (ds_colormap - colormaps); - if (!ds_powersoftwo) - { - fixed_t x = (((fixed_t)u-viewx) >> FRACBITS); - fixed_t y = (((fixed_t)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 = colormap[source[((v >> nflatyshift) & nflatmask) | (u >> nflatxshift)]]; dest++; iz += ds_sz.x; uz += ds_su.x; @@ -778,24 +734,7 @@ void R_DrawTiltedSpan_8(void) for (i = SPANSIZE-1; i >= 0; i--) { colormap = planezlight[tiltlighting[ds_x1++]] + (ds_colormap - colormaps); - if (!ds_powersoftwo) - { - fixed_t x = (((fixed_t)u-viewx) >> FRACBITS); - fixed_t y = (((fixed_t)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 = colormap[source[((v >> nflatyshift) & nflatmask) | (u >> nflatxshift)]]; dest++; u += stepu; v += stepv; @@ -811,24 +750,7 @@ void R_DrawTiltedSpan_8(void) u = (INT64)(startu); v = (INT64)(startv); colormap = planezlight[tiltlighting[ds_x1++]] + (ds_colormap - colormaps); - if (!ds_powersoftwo) - { - fixed_t x = (((fixed_t)u-viewx) >> FRACBITS); - fixed_t y = (((fixed_t)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 = colormap[source[((v >> nflatyshift) & nflatmask) | (u >> nflatxshift)]]; } else { @@ -849,24 +771,7 @@ void R_DrawTiltedSpan_8(void) for (; width != 0; width--) { colormap = planezlight[tiltlighting[ds_x1++]] + (ds_colormap - colormaps); - if (!ds_powersoftwo) - { - fixed_t x = (((fixed_t)u-viewx) >> FRACBITS); - fixed_t y = (((fixed_t)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 = colormap[source[((v >> nflatyshift) & nflatmask) | (u >> nflatxshift)]]; dest++; u += stepu; v += stepv; @@ -927,24 +832,7 @@ void R_DrawTiltedTranslucentSpan_8(void) v = (INT64)(vz*z) + viewy; colormap = planezlight[tiltlighting[ds_x1++]] + (ds_colormap - colormaps); - if (!ds_powersoftwo) - { - fixed_t x = (((fixed_t)u-viewx) >> FRACBITS); - fixed_t y = (((fixed_t)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 = *(ds_transmap + (colormap[source[((v >> nflatyshift) & nflatmask) | (u >> nflatxshift)]] << 8) + *dest); dest++; iz += ds_sz.x; uz += ds_su.x; @@ -981,24 +869,7 @@ void R_DrawTiltedTranslucentSpan_8(void) for (i = SPANSIZE-1; i >= 0; i--) { colormap = planezlight[tiltlighting[ds_x1++]] + (ds_colormap - colormaps); - if (!ds_powersoftwo) - { - fixed_t x = (((fixed_t)u-viewx) >> FRACBITS); - fixed_t y = (((fixed_t)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 = *(ds_transmap + (colormap[source[((v >> nflatyshift) & nflatmask) | (u >> nflatxshift)]] << 8) + *dest); dest++; u += stepu; v += stepv; @@ -1014,24 +885,7 @@ void R_DrawTiltedTranslucentSpan_8(void) u = (INT64)(startu); v = (INT64)(startv); colormap = planezlight[tiltlighting[ds_x1++]] + (ds_colormap - colormaps); - if (!ds_powersoftwo) - { - fixed_t x = (((fixed_t)u-viewx) >> FRACBITS); - fixed_t y = (((fixed_t)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 = *(ds_transmap + (colormap[source[((v >> nflatyshift) & nflatmask) | (u >> nflatxshift)]] << 8) + *dest); } else { @@ -1052,24 +906,7 @@ void R_DrawTiltedTranslucentSpan_8(void) for (; width != 0; width--) { colormap = planezlight[tiltlighting[ds_x1++]] + (ds_colormap - colormaps); - if (!ds_powersoftwo) - { - fixed_t x = (((fixed_t)u-viewx) >> FRACBITS); - fixed_t y = (((fixed_t)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 = *(ds_transmap + (colormap[source[((v >> nflatyshift) & nflatmask) | (u >> nflatxshift)]] << 8) + *dest); dest++; u += stepu; v += stepv; @@ -1130,28 +967,9 @@ void R_DrawTiltedSplat_8(void) colormap = planezlight[tiltlighting[ds_x1++]] + (ds_colormap - colormaps); - if (!ds_powersoftwo) - { - fixed_t x = (((fixed_t)u-viewx) >> FRACBITS); - fixed_t y = (((fixed_t)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)]; - + val = source[((v >> nflatyshift) & nflatmask) | (u >> nflatxshift)]; if (val != TRANSPARENTPIXEL) *dest = colormap[val]; - dest++; iz += ds_sz.x; uz += ds_su.x; @@ -1188,24 +1006,7 @@ void R_DrawTiltedSplat_8(void) for (i = SPANSIZE-1; i >= 0; i--) { colormap = planezlight[tiltlighting[ds_x1++]] + (ds_colormap - colormaps); - if (!ds_powersoftwo) - { - fixed_t x = (((fixed_t)u-viewx) >> FRACBITS); - fixed_t y = (((fixed_t)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)]; + val = source[((v >> nflatyshift) & nflatmask) | (u >> nflatxshift)]; if (val != TRANSPARENTPIXEL) *dest = colormap[val]; dest++; @@ -1223,24 +1024,7 @@ void R_DrawTiltedSplat_8(void) u = (INT64)(startu); v = (INT64)(startv); colormap = planezlight[tiltlighting[ds_x1++]] + (ds_colormap - colormaps); - if (!ds_powersoftwo) - { - fixed_t x = (((fixed_t)u-viewx) >> FRACBITS); - fixed_t y = (((fixed_t)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)]; + val = source[((v >> nflatyshift) & nflatmask) | (u >> nflatxshift)]; if (val != TRANSPARENTPIXEL) *dest = colormap[val]; } @@ -1264,24 +1048,6 @@ 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 = (((fixed_t)u-viewx) >> FRACBITS); - fixed_t y = (((fixed_t)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++; @@ -1299,21 +1065,17 @@ void R_DrawTiltedSplat_8(void) */ void R_DrawSplat_8 (void) { - fixed_t xposition; - fixed_t yposition; - fixed_t xstep, ystep; + UINT32 xposition; + UINT32 yposition; + UINT32 xstep, ystep; UINT8 *source; UINT8 *colormap; UINT8 *dest; - const UINT8 *deststop = screens[0] + vid.rowbytes * vid.height; - size_t count = (ds_x2 - ds_x1 + 1); + size_t count; 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) @@ -1321,125 +1083,99 @@ void R_DrawSplat_8 (void) // 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; - xstep <<= nflatshiftup; ystep <<= nflatshiftup; - } + xposition = ds_xfrac << nflatshiftup; yposition = ds_yfrac << nflatshiftup; + xstep = ds_xstep << nflatshiftup; ystep = ds_ystep << nflatshiftup; source = ds_source; colormap = ds_colormap; dest = ylookup[ds_y] + columnofs[ds_x1]; + count = ds_x2 - ds_x1 + 1; - if (!ds_powersoftwo) + while (count >= 8) { - while (count-- && dest <= deststop) - { - fixed_t x = (xposition >> FRACBITS); - fixed_t y = (yposition >> FRACBITS); + // 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; - // 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[1] = colormap[val]; + xposition += xstep; + yposition += ystep; - x %= ds_flatwidth; - 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 = source[((y * ds_flatwidth) + x)]; - if (val != TRANSPARENTPIXEL) - *dest = colormap[val]; - dest++; - 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; } - else + while (count--) { - 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 = ((yposition >> nflatyshift) & nflatmask) | (xposition >> nflatxshift); + val &= 4194303; + val = source[val]; + if (val != TRANSPARENTPIXEL) + *dest = colormap[val]; - 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)]; - if (val != TRANSPARENTPIXEL) - *dest = colormap[val]; - dest++; - xposition += xstep; - yposition += ystep; - } + dest++; + xposition += xstep; + yposition += ystep; } } @@ -1448,20 +1184,16 @@ void R_DrawSplat_8 (void) */ void R_DrawTranslucentSplat_8 (void) { - fixed_t xposition; - fixed_t yposition; - fixed_t xstep, ystep; + UINT32 xposition; + UINT32 yposition; + UINT32 xstep, ystep; UINT8 *source; UINT8 *colormap; UINT8 *dest; - const UINT8 *deststop = screens[0] + vid.rowbytes * vid.height; - size_t count = (ds_x2 - ds_x1 + 1); - UINT32 val; - - xposition = ds_xfrac; yposition = ds_yfrac; - xstep = ds_xstep; ystep = ds_ystep; + size_t count; + UINT8 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 @@ -1470,107 +1202,79 @@ void R_DrawTranslucentSplat_8 (void) // 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; - xstep <<= nflatshiftup; ystep <<= nflatshiftup; - } + xposition = ds_xfrac << nflatshiftup; yposition = ds_yfrac << nflatshiftup; + xstep = ds_xstep << nflatshiftup; ystep = ds_ystep << nflatshiftup; source = ds_source; colormap = ds_colormap; dest = ylookup[ds_y] + columnofs[ds_x1]; + count = ds_x2 - ds_x1 + 1; - if (!ds_powersoftwo) + while (count >= 8) { - while (count-- && dest <= deststop) - { - fixed_t x = (xposition >> FRACBITS); - fixed_t y = (yposition >> FRACBITS); + // 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; - // 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[1] = *(ds_transmap + (colormap[val] << 8) + dest[1]); + xposition += xstep; + yposition += ystep; - x %= ds_flatwidth; - 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[((y * ds_flatwidth) + x)]; - if (val != TRANSPARENTPIXEL) - *dest = *(ds_transmap + (colormap[val] << 8) + *dest); - dest++; - 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; } - else + while (count--) { - 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[((yposition >> nflatyshift) & nflatmask) | (xposition >> nflatxshift)]; + if (val != TRANSPARENTPIXEL) + *dest = *(ds_transmap + (colormap[val] << 8) + *dest); - 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)]; - if (val != TRANSPARENTPIXEL) - *dest = *(ds_transmap + (colormap[val] << 8) + *dest); - dest++; - xposition += xstep; - yposition += ystep; - } + dest++; + xposition += xstep; + yposition += ystep; } } @@ -1579,20 +1283,15 @@ void R_DrawTranslucentSplat_8 (void) */ void R_DrawTranslucentSpan_8 (void) { - fixed_t xposition; - fixed_t yposition; - fixed_t xstep, ystep; + UINT32 xposition; + UINT32 yposition; + UINT32 xstep, ystep; UINT8 *source; UINT8 *colormap; UINT8 *dest; - const UINT8 *deststop = screens[0] + vid.rowbytes * vid.height; - size_t count = (ds_x2 - ds_x1 + 1); - UINT32 val; - - xposition = ds_xfrac; yposition = ds_yfrac; - xstep = ds_xstep; ystep = ds_ystep; + 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 @@ -1601,161 +1300,63 @@ void R_DrawTranslucentSpan_8 (void) // 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; - xstep <<= nflatshiftup; ystep <<= nflatshiftup; - } + xposition = ds_xfrac << nflatshiftup; yposition = ds_yfrac << nflatshiftup; + xstep = ds_xstep << nflatshiftup; ystep = ds_ystep << nflatshiftup; source = ds_source; colormap = ds_colormap; dest = ylookup[ds_y] + columnofs[ds_x1]; + count = ds_x2 - ds_x1 + 1; - if (!ds_powersoftwo) + while (count >= 8) { - while (count-- && dest <= deststop) - { - fixed_t x = (xposition >> FRACBITS); - fixed_t y = (yposition >> FRACBITS); + // 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; - // 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[1] = *(ds_transmap + (colormap[source[((yposition >> nflatyshift) & nflatmask) | (xposition >> nflatxshift)]] << 8) + dest[1]); + xposition += xstep; + yposition += ystep; - x %= ds_flatwidth; - y %= ds_flatheight; + dest[2] = *(ds_transmap + (colormap[source[((yposition >> nflatyshift) & nflatmask) | (xposition >> nflatxshift)]] << 8) + dest[2]); + xposition += xstep; + yposition += ystep; - val = ((y * ds_flatwidth) + x); - *dest = *(ds_transmap + (colormap[source[val]] << 8) + *dest); - dest++; - 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; } - else + while (count--) { - 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); - *dest = *(ds_transmap + (colormap[source[val]] << 8) + *dest); - dest++; - xposition += xstep; - yposition += ystep; - } + *dest = *(ds_transmap + (colormap[source[((yposition >> nflatyshift) & nflatmask) | (xposition >> nflatxshift)]] << 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; - - 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; - 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); - - x %= ds_flatwidth; - y %= ds_flatheight; - - *dest++ = colormap[*(ds_transmap + (source[((y * ds_flatwidth) + x)] << 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 de5bf9f00..2f6f97240 100644 --- a/src/r_plane.c +++ b/src/r_plane.c @@ -127,13 +127,91 @@ void R_InitPlanes(void) // viewheight #ifndef NOWATER -INT32 ds_bgofs; -INT32 ds_waterofs; - +static INT32 bgofs; 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; @@ -180,17 +258,17 @@ void R_MapPlane(INT32 y, INT32 x1, INT32 x2) { const INT32 yay = (wtofs + (distance>>9) ) & 8191; // ripples da water texture - ds_bgofs = FixedDiv(FINESINE(yay), (1<<12) + (distance>>11))>>FRACBITS; + 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), (ds_bgofs<=viewheight) - ds_bgofs = viewheight-y-1; - if (y+ds_bgofs<0) - ds_bgofs = -y; + if (y+bgofs>=viewheight) + bgofs = viewheight-y-1; + if (y+bgofs<0) + bgofs = -y; } #endif @@ -602,7 +680,7 @@ void R_DrawPlanes(void) } } #ifndef NOWATER - ds_waterofs = (leveltime & 1)*16384; + waterofs = (leveltime & 1)*16384; wtofs = leveltime * 140; #endif } @@ -650,156 +728,13 @@ static void R_DrawSkyPlane(visplane_t *pl) } } -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 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); - - // Check if the texture changed. - if (leveltexture && (!texturechanged)) - { - if (texflat != NULL && texflat->flat) - { - flat = 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) - { - 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_TextureToFlat(levelflat->texturenum, texflat->flat); - flat = texflat->flat; - - levelflat->flatpatch = flat; - levelflat->width = ds_flatwidth; - levelflat->height = ds_flatheight; - } - else - { - patch = (patch_t *)ds_source; -#ifndef NO_PNG_LUMPS - if (ispng) - { - levelflat->flatpatch = R_PNGToFlat(levelflat, ds_source, W_LumpLength(levelflat->lumpnum)); - levelflat->topoffset = levelflat->leftoffset = 0; - ds_flatwidth = levelflat->width; - ds_flatheight = levelflat->height; - } - else -#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_PatchToFlat(patch, levelflat->flatpatch); - } - flat = levelflat->flatpatch; - } - } - else - { - flat = levelflat->flatpatch; - ds_flatwidth = levelflat->width; - ds_flatheight = levelflat->height; - - xoffs += levelflat->leftoffset; - yoffs += levelflat->topoffset; - } - - levelflat->lasttexturenum = levelflat->texturenum; - return flat; -} - void R_DrawSinglePlane(visplane_t *pl) { - UINT8 *flat; INT32 light = 0; INT32 x; INT32 stop, angle; size_t size; ffloor_t *rover; - levelflat_t *levelflat; if (!(pl->minx <= pl->maxx)) return; @@ -939,43 +874,64 @@ 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]; - 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) - flat = R_GetPatchFlat(levelflat, true, false); -#ifndef NO_PNG_LUMPS - // Maybe it's a PNG?! - else if (R_IsLumpPNG(ds_source, size)) - flat = R_GetPatchFlat(levelflat, false, true); -#endif - // Maybe it's just a patch, then? - else if (R_CheckIfPatch(levelflat->lumpnum)) - flat = R_GetPatchFlat(levelflat, false, false); - // 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()) - R_CheckFlatLength(ds_flatwidth * ds_flatheight); - if (light >= LIGHTLEVELS) light = LIGHTLEVELS-1; @@ -989,63 +945,60 @@ void R_DrawSinglePlane(visplane_t *pl) floatv3_t p, m, n; float ang; float vx, vy, vz; - 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; + // Okay, look, don't ask me why this works, but without this setup there's a disgusting-looking misalignment with the textures. -Red + const float fudge = ((1<plangle & (ANGLE_90-1)); yoffs *= 1; - if (ds_powersoftwo) + if (hack) { - // 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<>ANGLETOFINESHIFT); - const fixed_t sinecomponent = FINESINE(hack>>ANGLETOFINESHIFT); + /* + Essentially: We can't & the components along the regular axes when the plane is rotated. + This is because the distance on each regular axis in order to loop is different. + We rotate them, & the components, add them together, & them again, and then rotate them back. + These three seperate & operations are done per axis in order to prevent overflows. + toast 10/04/17 + */ + const fixed_t cosinecomponent = FINECOSINE(hack>>ANGLETOFINESHIFT); + const fixed_t sinecomponent = FINESINE(hack>>ANGLETOFINESHIFT); - const fixed_t modmask = ((1 << (32-nflatshiftup)) - 1); + const fixed_t modmask = ((1 << (32-nflatshiftup)) - 1); - fixed_t ox = (FixedMul(pl->slope->o.x,cosinecomponent) & modmask) - (FixedMul(pl->slope->o.y,sinecomponent) & modmask); - fixed_t oy = (-FixedMul(pl->slope->o.x,sinecomponent) & modmask) - (FixedMul(pl->slope->o.y,cosinecomponent) & modmask); + fixed_t ox = (FixedMul(pl->slope->o.x,cosinecomponent) & modmask) - (FixedMul(pl->slope->o.y,sinecomponent) & modmask); + fixed_t oy = (-FixedMul(pl->slope->o.x,sinecomponent) & modmask) - (FixedMul(pl->slope->o.y,cosinecomponent) & modmask); - temp = ox & modmask; - oy &= modmask; - ox = FixedMul(temp,cosinecomponent)+FixedMul(oy,-sinecomponent); // negative sine for opposite direction - oy = -FixedMul(temp,-sinecomponent)+FixedMul(oy,cosinecomponent); + temp = ox & modmask; + oy &= modmask; + ox = FixedMul(temp,cosinecomponent)+FixedMul(oy,-sinecomponent); // negative sine for opposite direction + oy = -FixedMul(temp,-sinecomponent)+FixedMul(oy,cosinecomponent); - temp = xoffs; - xoffs = (FixedMul(temp,cosinecomponent) & modmask) + (FixedMul(yoffs,sinecomponent) & modmask); - yoffs = (-FixedMul(temp,sinecomponent) & modmask) + (FixedMul(yoffs,cosinecomponent) & modmask); + temp = xoffs; + xoffs = (FixedMul(temp,cosinecomponent) & modmask) + (FixedMul(yoffs,sinecomponent) & modmask); + yoffs = (-FixedMul(temp,sinecomponent) & modmask) + (FixedMul(yoffs,cosinecomponent) & modmask); - temp = xoffs & modmask; - yoffs &= modmask; - xoffs = FixedMul(temp,cosinecomponent)+FixedMul(yoffs,-sinecomponent); // ditto - yoffs = -FixedMul(temp,-sinecomponent)+FixedMul(yoffs,cosinecomponent); + temp = xoffs & modmask; + yoffs &= modmask; + xoffs = FixedMul(temp,cosinecomponent)+FixedMul(yoffs,-sinecomponent); // ditto + yoffs = -FixedMul(temp,-sinecomponent)+FixedMul(yoffs,cosinecomponent); - xoffs -= (pl->slope->o.x - ox); - yoffs += (pl->slope->o.y + oy); - } - else - { - 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 = (fixed_t)(xoffs*fudge); - yoffs = (fixed_t)(yoffs/fudge); + xoffs -= (pl->slope->o.x - ox); + yoffs += (pl->slope->o.y + oy); } + else + { + 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 = (fixed_t)(xoffs*fudge); + yoffs = (fixed_t)(yoffs/fudge); vx = FIXED_TO_FLOAT(pl->viewx+xoffs); vy = FIXED_TO_FLOAT(pl->viewy-yoffs); @@ -1080,16 +1033,13 @@ 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; - if (ds_powersoftwo) - { - m.x /= fudge; - m.y /= fudge; - m.z /= fudge; + 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) \ @@ -1106,26 +1056,14 @@ 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: Mon, 9 Sep 2019 15:02:13 -0400 Subject: [PATCH 49/51] Be clear on what FALLTHRU we really want --- src/d_main.c | 2 +- src/g_game.c | 2 +- src/sdl/i_system.c | 2 +- src/win32/win_sys.c | 2 +- src/win32/win_vid.c | 2 +- 5 files changed, 5 insertions(+), 5 deletions(-) diff --git a/src/d_main.c b/src/d_main.c index eaeae4b10..9fa506bee 100644 --- a/src/d_main.c +++ b/src/d_main.c @@ -287,7 +287,7 @@ static void D_Display(void) F_TitleScreenDrawer(); break; } - // Intentional fall-through + /* FALLTHRU */ case GS_LEVEL: if (!gametic) break; diff --git a/src/g_game.c b/src/g_game.c index 89a96f3d0..2b7a1c981 100644 --- a/src/g_game.c +++ b/src/g_game.c @@ -4583,7 +4583,7 @@ void G_GhostTicker(void) default: case GHC_RETURNSKIN: g->mo->skin = g->oldmo.skin; - // fallthru + /* FALLTHRU */ case GHC_NORMAL: // Go back to skin color g->mo->color = g->oldmo.color; break; diff --git a/src/sdl/i_system.c b/src/sdl/i_system.c index 98166a1ce..c4fb1c0fc 100644 --- a/src/sdl/i_system.c +++ b/src/sdl/i_system.c @@ -530,7 +530,7 @@ static void Impl_HandleKeyboardConsoleEvent(KEY_EVENT_RECORD evt, HANDLE co) break; case VK_RETURN: entering_con_command = false; - // Fall through. + /* FALLTHRU */ default: event.data1 = MapVirtualKey(evt.wVirtualKeyCode,2); // convert in to char } diff --git a/src/win32/win_sys.c b/src/win32/win_sys.c index d10f73b58..93b3ff523 100644 --- a/src/win32/win_sys.c +++ b/src/win32/win_sys.c @@ -327,7 +327,7 @@ static inline VOID I_GetConsoleEvents(VOID) break; case VK_RETURN: entering_con_command = false; - // Fall through. + /* FALLTHRU */ default: ev.data1 = MapVirtualKey(input.Event.KeyEvent.wVirtualKeyCode,2); // convert in to char } diff --git a/src/win32/win_vid.c b/src/win32/win_vid.c index e2f32fa61..11c7a6744 100644 --- a/src/win32/win_vid.c +++ b/src/win32/win_vid.c @@ -322,9 +322,9 @@ static inline boolean I_SkipFrame(void) case GS_LEVEL: if (!paused) return false; - /* FALLTHRU */ //case GS_TIMEATTACK: -- sorry optimisation but now we have a cool level platter and that being laggardly looks terrible #ifndef CLIENT_LOADINGSCREEN + /* FALLTHRU */ case GS_WAITINGPLAYERS: #endif return skip; // Skip odd frames From 470ac5fed29d7e18eae67713d06810d01c52eea2 Mon Sep 17 00:00:00 2001 From: Alam Ed Arias Date: Mon, 9 Sep 2019 15:05:17 -0400 Subject: [PATCH 50/51] Revert "Revert "Merge branch 'flats-png_port' into 'master'"" This reverts commit 043bb86acdf81ef0ecbd388aed57fe0fa29c8747. --- src/doomdef.h | 4 + src/hardware/hw_cache.c | 114 ++++- src/hardware/hw_glide.h | 2 + src/hardware/hw_glob.h | 3 + src/hardware/hw_light.c | 2 + src/hardware/hw_main.c | 207 +++++---- src/hardware/hw_md2.c | 4 + src/p_setup.c | 10 + src/p_setup.h | 7 + src/p_spec.c | 30 +- src/r_data.c | 643 ++++++++++++++++++++++++++-- src/r_data.h | 27 +- src/r_draw.c | 2 + src/r_draw.h | 13 +- src/r_draw8.c | 913 +++++++++++++++++++++++++++++----------- src/r_plane.c | 450 +++++++++++--------- src/r_plane.h | 2 + src/screen.c | 2 +- src/w_wad.c | 2 - 19 files changed, 1855 insertions(+), 582 deletions(-) diff --git a/src/doomdef.h b/src/doomdef.h index 6e7db2143..4a0174369 100644 --- a/src/doomdef.h +++ b/src/doomdef.h @@ -616,4 +616,8 @@ extern const char *compdate, *comptime, *comprevision, *compbranch; /// SRB2CB itself ported this from PrBoom+ #define NEWCLIP +#ifndef HAVE_PNG +#define NO_PNG_LUMPS +#endif + #endif // __DOOMDEF__ diff --git a/src/hardware/hw_cache.c b/src/hardware/hw_cache.c index 6bc2c712e..c9a75a4f3 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) @@ -420,6 +421,7 @@ static void HWR_DrawTexturePatchInCache(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] = { @@ -456,6 +458,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) @@ -511,6 +516,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) @@ -528,9 +534,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; @@ -562,6 +573,7 @@ static void HWR_ResizeBlock(INT32 originalwidth, INT32 originalheight, if (blockwidth < blockheight) j += 4; grInfo->aspectRatioLog2 = gr_aspects[j].aspect; +#endif blocksize = blockwidth * blockheight; @@ -650,7 +662,12 @@ 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); +#ifndef NO_PNG_LUMPS + if (R_IsLumpPNG((UINT8 *)realpatch, lumplength)) + realpatch = R_PNGToPatch((UINT8 *)realpatch, lumplength); +#endif HWR_DrawTexturePatchInCache(&grtex->mipmap, blockwidth, blockheight, texture, patch, @@ -756,11 +773,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; } @@ -799,7 +818,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; } @@ -817,6 +839,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) @@ -847,7 +872,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]; @@ -862,15 +887,39 @@ GLTexture_t *HWR_GetTexture(INT32 tex) return grtex; } +// 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) +{ + UINT8 *flat; + patch_t *patch = (patch_t *)W_CacheLumpNum(flatlumpnum, PU_STATIC); + size_t lumplength = W_LumpLength(flatlumpnum); + +#ifndef NO_PNG_LUMPS + if (R_IsLumpPNG((UINT8 *)patch, lumplength)) + patch = R_PNGToPatch((UINT8 *)patch, lumplength); +#endif + + grMipmap->width = (UINT16)SHORT(patch->width); + grMipmap->height = (UINT16)SHORT(patch->height); + + flat = Z_Malloc(grMipmap->width * grMipmap->height, PU_HWRCACHE, &grMipmap->grInfo.data); + memset(flat, TRANSPARENTPIXEL, grMipmap->width * grMipmap->height); + + R_PatchToFlat(patch, flat); +} 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; @@ -900,15 +949,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) { @@ -923,6 +977,52 @@ 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; +} + +static void HWR_LoadTextureFlat(GLMipmap_t *grMipmap, INT32 texturenum) +{ + UINT8 *flat; + + // 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; + + grMipmap->width = (UINT16)textures[texturenum]->width; + grMipmap->height = (UINT16)textures[texturenum]->height; + + flat = Z_Malloc(grMipmap->width * grMipmap->height, PU_HWRCACHE, &grMipmap->grInfo.data); + memset(flat, TRANSPARENTPIXEL, grMipmap->width * grMipmap->height); + + R_TextureToFlat(texturenum, flat); +} + +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_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_glob.h b/src/hardware/hw_glob.h index 9656e54e9..c7b06edfd 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_light.c b/src/hardware/hw_light.c index edfe328b8..1de20cad7 100644 --- a/src/hardware/hw_light.c +++ b/src/hardware/hw_light.c @@ -1225,9 +1225,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_main.c b/src/hardware/hw_main.c index c6a8b16e5..07ae7ed2b 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,9 @@ 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; + float fflatwidth, fflatheight; INT32 flatflag; + boolean texflat = true; size_t len; float scrollx = 0.0f, scrolly = 0.0f; angle_t angle = 0; @@ -540,6 +541,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; @@ -580,9 +582,10 @@ static void HWR_RenderPlane(sector_t *sector, extrasubsector_t *xsub, boolean is if (nrPlaneVerts < 3) //not even a triangle ? return; - if (nrPlaneVerts > (INT32)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; } @@ -599,38 +602,47 @@ 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; } + 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)(((fixed_t)pv->x & (~flatflag)) / fflatsize); - flatyref = (float)(((fixed_t)pv->y & (~flatflag)) / fflatsize); + flatxref = (float)(((fixed_t)pv->x & (~flatflag)) / fflatwidth); + flatyref = (float)(((fixed_t)pv->y & (~flatflag)) / fflatheight); // transform v3d = planeVerts; @@ -639,14 +651,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; } 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; } } @@ -654,14 +666,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; } 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; } } @@ -680,17 +692,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 / fflatsize) - flatxref + scrollx); - v3d->tow = (float)(-(pv->y / fflatsize) + flatyref + 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)))); } @@ -3164,21 +3183,23 @@ 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; + float fflatwidth, fflatheight; INT32 flatflag; + boolean texflat = true; 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; @@ -3209,38 +3230,47 @@ 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; } + 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)(((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 & (~flatflag)) / fflatwidth); + flatyref = (float)((polysector->origVerts[0].y & (~flatflag)) / fflatheight); // transform v3d = planeVerts; @@ -3249,14 +3279,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; } } @@ -3264,14 +3294,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; } } @@ -3294,15 +3324,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) / 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 + // 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)))); } @@ -3365,6 +3406,7 @@ static void HWR_AddPolyObjectPlanes(void) else { HWR_GetFlat(levelflats[polyobjsector->floorpic].lumpnum); + HWR_GetTextureFlat(levelflats[polyobjsector->floorpic].texturenum); HWR_RenderPolyObjectPlane(po_ptrs[i], false, polyobjsector->floorheight, PF_Occlude, (light == -1 ? gr_frontsector->lightlevel : *gr_frontsector->lightlist[light].lightlevel), levelflats[polyobjsector->floorpic].lumpnum, polyobjsector, 255, (light == -1 ? gr_frontsector->extra_colormap : *gr_frontsector->lightlist[light].extra_colormap)); @@ -3388,6 +3430,7 @@ static void HWR_AddPolyObjectPlanes(void) else { HWR_GetFlat(levelflats[polyobjsector->ceilingpic].lumpnum); + HWR_GetTextureFlat(levelflats[polyobjsector->ceilingpic].texturenum); HWR_RenderPolyObjectPlane(po_ptrs[i], true, polyobjsector->ceilingheight, PF_Occlude, (light == -1 ? gr_frontsector->lightlevel : *gr_frontsector->lightlist[light].lightlevel), levelflats[polyobjsector->floorpic].lumpnum, polyobjsector, 255, (light == -1 ? gr_frontsector->extra_colormap : *gr_frontsector->lightlist[light].extra_colormap)); @@ -3541,11 +3584,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 @@ -3563,11 +3607,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 @@ -3626,7 +3671,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, @@ -3645,6 +3690,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, @@ -3656,8 +3702,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); } } @@ -3689,7 +3736,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, @@ -3708,6 +3755,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, @@ -3720,8 +3768,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); } } @@ -5050,6 +5099,7 @@ typedef struct fixed_t fixedheight; INT32 lightlevel; lumpnum_t lumpnum; + INT32 texturenum; INT32 alpha; sector_t *FOFSector; FBITFIELD blend; @@ -5068,6 +5118,7 @@ typedef struct fixed_t fixedheight; INT32 lightlevel; lumpnum_t lumpnum; + INT32 texturenum; INT32 alpha; sector_t *FOFSector; FBITFIELD blend; @@ -5098,7 +5149,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; @@ -5117,6 +5168,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; @@ -5130,7 +5182,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; @@ -5149,6 +5201,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; @@ -5310,9 +5363,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) { @@ -5320,9 +5376,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/hardware/hw_md2.c b/src/hardware/hw_md2.c index d4728315a..7b6367cf3 100644 --- a/src/hardware/hw_md2.c +++ b/src/hardware/hw_md2.c @@ -747,10 +747,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); @@ -798,10 +800,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); diff --git a/src/p_setup.c b/src/p_setup.c index 65335be3f..60e036a87 100644 --- a/src/p_setup.c +++ b/src/p_setup.c @@ -573,6 +573,11 @@ INT32 P_AddLevelFlat(const char *flatname, levelflat_t *levelflat) // store the flat lump number levelflat->lumpnum = R_GetFlatNumForName(flatname); + 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); @@ -617,6 +622,11 @@ INT32 P_AddLevelFlatRuntime(const char *flatname) // store the flat lump number levelflat->lumpnum = R_GetFlatNumForName(flatname); + 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 7e8a5d7e6..7e3a149eb 100644 --- a/src/p_setup.h +++ b/src/p_setup.h @@ -37,12 +37,19 @@ 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; + + // for patchflats + UINT8 *flatpatch; } levelflat_t; extern size_t numlevelflats; diff --git a/src/p_spec.c b/src/p_spec.c index 7742554cd..256ca3453 100644 --- a/src/p_spec.c +++ b/src/p_spec.c @@ -205,8 +205,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; @@ -464,7 +464,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; @@ -488,10 +500,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); } // @@ -5669,9 +5678,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 6889bddde..5858117a5 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, @@ -98,12 +120,11 @@ 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 -// 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; @@ -315,7 +336,7 @@ static inline void R_DrawTransFlippedColumnInCache(column_t *patch, UINT8 *cache // 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. @@ -332,6 +353,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); @@ -346,7 +371,19 @@ 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); + +#ifndef NO_PNG_LUMPS + if (R_IsLumpPNG((UINT8 *)realpatch, lumplength)) + { + realpatch = R_PNGToPatch((UINT8 *)realpatch, lumplength); + goto multipatch; + } +#endif // Check the patch for holes. if (texture->width > SHORT(realpatch->width) || texture->height > SHORT(realpatch->height)) @@ -376,7 +413,7 @@ static UINT8 *R_GenerateTexture(size_t texnum) { texture->holes = true; texture->flip = patch->flip; - 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); @@ -403,6 +440,9 @@ static UINT8 *R_GenerateTexture(size_t texnum) } // multi-patch textures (or 'composite') +#ifndef NO_PNG_LUMPS + multipatch: +#endif texture->holes = false; texture->flip = 0; blocksize = (texture->width * 4) + (texture->width * texture->height); @@ -433,7 +473,15 @@ static UINT8 *R_GenerateTexture(size_t texnum) ColumnDrawerPointer = (patch->flip & 2) ? R_DrawFlippedColumnInCache : R_DrawColumnInCache; } - 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); +#ifndef NO_PNG_LUMPS + if (R_IsLumpPNG((UINT8 *)realpatch, lumplength)) + realpatch = R_PNGToPatch((UINT8 *)realpatch, lumplength); +#endif + x1 = patch->originx; width = SHORT(realpatch->width); height = SHORT(realpatch->height); @@ -509,10 +557,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); @@ -550,7 +602,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; @@ -567,6 +619,7 @@ void R_LoadTextures(void) } Z_Free(texturetranslation); Z_Free(textures); + Z_Free(texflats); } // Load patches and textures. @@ -627,15 +680,16 @@ 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 *))); // 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. - textureheight = (void *)((UINT8 *)textures + ((numtextures * sizeof(void *)) * 4)); + texturecache = (void *)((UINT8 *)textures + ((numtextures * sizeof(void *)) * 2)); + // 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); @@ -673,20 +727,39 @@ void R_LoadTextures(void) // Work through each lump between the markers in the WAD. for (j = 0; j < (texend - texstart); j++) { + UINT16 wadnum = (UINT16)w; + lumpnum_t lumpnum = texstart + j; + size_t lumplength; + if (wadfiles[w]->type == RET_PK3) { - if (W_IsLumpFolder((UINT16)w, texstart + j)) // Check if lump is a folder + if (W_IsLumpFolder(wadnum, lumpnum)) // Check if lump is a folder continue; // If it is then SKIP IT } - patchlump = W_CacheLumpNumPwad((UINT16)w, texstart + j, PU_CACHE); + + lumplength = W_LumpLengthPwad(wadnum, lumpnum); + patchlump = W_CacheLumpNumPwad(wadnum, lumpnum, PU_CACHE); //CONS_Printf("\n\"%s\" is a single patch, dimensions %d x %d",W_CheckNameForNumPwad((UINT16)w,texstart+j),patchlump->width, patchlump->height); 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)); + +#ifndef NO_PNG_LUMPS + if (R_IsLumpPNG((UINT8 *)patchlump, lumplength)) + { + INT16 width, height; + R_PNGDimensions((UINT8 *)patchlump, &width, &height, lumplength); + texture->width = width; + texture->height = height; + } + else +#endif + { + texture->width = SHORT(patchlump->width); + texture->height = SHORT(patchlump->height); + } texture->patchcount = 1; texture->holes = false; texture->flip = 0; @@ -701,11 +774,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; i++; } @@ -1097,7 +1166,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); @@ -1105,7 +1174,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); } @@ -1146,21 +1215,21 @@ 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 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)++; } 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); } @@ -1267,6 +1336,41 @@ lumpnum_t R_GetFlatNumForName(const char *name) lump = LUMPERROR; } + // Detect textures + if (lump == LUMPERROR) + { + // Scan wad files backwards so patched textures 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)) @@ -1615,7 +1719,6 @@ extracolormap_t *R_ColormapForName(char *name) // static double deltas[256][3], map[256][3]; -static UINT8 NearestColor(UINT8 r, UINT8 g, UINT8 b); static int RoundUp(double number); lighttable_t *R_CreateLightTable(extracolormap_t *extra_colormap) @@ -2027,7 +2130,7 @@ extracolormap_t *R_AddColormaps(extracolormap_t *exc_augend, extracolormap_t *ex // 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; @@ -2306,3 +2409,479 @@ 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 < (INT16)(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; + } + } + } + + return result; +} + +void R_PatchToFlat(patch_t *patch, UINT8 *flat) +{ + fixed_t col, ofs; + column_t *column; + UINT8 *desttop, *dest, *deststop; + UINT8 *source; + + desttop = flat; + deststop = desttop + (SHORT(patch->width) * SHORT(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 * SHORT(patch->width)); + source = (UINT8 *)(column) + 3; + for (ofs = 0; dest < deststop && ofs < column->length; ofs++) + { + *dest = source[ofs]; + dest += SHORT(patch->width); + } + column = (column_t *)((UINT8 *)column + column->length + 4); + } + } +} + +#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, "PNG_IOReader: buffer overrun"); + 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 + + // set our own read_function + png_io.buffer = (png_bytep)png; + png_io.bufsize = size; + png_io.current_pos = 0; + 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) + I_Error("PNG_RawConvert: conversion failed"); + + // Convert the image to 8bpp + flat = Z_Malloc(width * height, PU_LEVEL, 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]); + if ((UINT8)px[3]) + flat[((y * width) + x)] = NearestColor((UINT8)px[0], (UINT8)px[1], (UINT8)px[2]); + } + } + free(row_pointers); + + return flat; +} + +// 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. +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); + + 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) + I_Error("R_PNGToPatch: conversion failed"); + + // 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)]; + + // 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); + + Z_Free(raw); + + 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 + + // set our own read_function + png_io.buffer = (png_bytep)png; + png_io.bufsize = size; + png_io.current_pos = 0; + 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]; + + 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 < texture->width; col++, desttop++) + { + 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 + { + INT32 topdelta, prevdelta = -1; + 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); + } + } + } +} diff --git a/src/r_data.h b/src/r_data.h index b6b0a16a1..b29bf4557 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 @@ -55,12 +56,17 @@ typedef struct texpatch_t patches[0]; } texture_t; +typedef struct +{ + UINT8 *flat; + INT16 width, height; +} textureflat_t; + // all loaded and prepared textures from the start of the game extern texture_t **textures; +extern textureflat_t *texflats; -// 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 @@ -88,7 +94,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. @@ -148,6 +153,20 @@ const char *R_NameForColormap(extracolormap_t *extra_colormap); #define R_PutRgbaRGB(r, g, b) (R_PutRgbaR(r) + R_PutRgbaG(g) + R_PutRgbaB(b)) #define R_PutRgbaRGBA(r, g, b, a) (R_PutRgbaRGB(r, g, b) + R_PutRgbaA(a)) +boolean R_CheckIfPatch(lumpnum_t lump); +UINT8 NearestColor(UINT8 r, UINT8 g, UINT8 b); + +void R_PatchToFlat(patch_t *patch, UINT8 *flat); +void R_TextureToFlat(size_t tex, UINT8 *flat); + +#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_draw.c b/src/r_draw.c index 396ed0344..1754403c4 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 82498eb11..3c1429722 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 @@ -128,6 +130,8 @@ void R_FillBackScreen(void); void R_DrawViewBorder(void); #endif +#define TRANSPARENTPIXEL 255 + // ----------------- // 8bpp DRAWING CODE // ----------------- @@ -169,6 +173,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 8a2d37fb3..77406f83c 100644 --- a/src/r_draw8.c +++ b/src/r_draw8.c @@ -105,8 +105,6 @@ void R_DrawColumn_8(void) } } -#define TRANSPARENTPIXEL 255 - void R_Draw2sMultiPatchColumn_8(void) { INT32 count; @@ -543,16 +541,19 @@ 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; + 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 @@ -561,62 +562,88 @@ void R_DrawSpan_8 (void) // 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; + 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) 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; + x %= ds_flatwidth; + y %= ds_flatheight; - 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)]]; + xposition += xstep; + yposition += ystep; + } } - while (count-- && dest <= deststop) + else { - *dest++ = colormap[source[((yposition >> nflatyshift) & nflatmask) | (xposition >> nflatxshift)]]; - xposition += xstep; - yposition += ystep; + 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)]]; + xposition += xstep; + yposition += ystep; + } } } @@ -697,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 = (((fixed_t)u-viewx) >> FRACBITS); + fixed_t y = (((fixed_t)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; @@ -734,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 = (((fixed_t)u-viewx) >> FRACBITS); + fixed_t y = (((fixed_t)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; @@ -750,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 = (((fixed_t)u-viewx) >> FRACBITS); + fixed_t y = (((fixed_t)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 { @@ -771,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 = (((fixed_t)u-viewx) >> FRACBITS); + fixed_t y = (((fixed_t)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; @@ -832,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 = (((fixed_t)u-viewx) >> FRACBITS); + fixed_t y = (((fixed_t)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; @@ -869,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 = (((fixed_t)u-viewx) >> FRACBITS); + fixed_t y = (((fixed_t)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; @@ -885,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 = (((fixed_t)u-viewx) >> FRACBITS); + fixed_t y = (((fixed_t)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 { @@ -906,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 = (((fixed_t)u-viewx) >> FRACBITS); + fixed_t y = (((fixed_t)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; @@ -967,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 = (((fixed_t)u-viewx) >> FRACBITS); + fixed_t y = (((fixed_t)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; @@ -1006,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 = (((fixed_t)u-viewx) >> FRACBITS); + fixed_t y = (((fixed_t)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++; @@ -1024,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 = (((fixed_t)u-viewx) >> FRACBITS); + fixed_t y = (((fixed_t)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]; } @@ -1048,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 = (((fixed_t)u-viewx) >> FRACBITS); + fixed_t y = (((fixed_t)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++; @@ -1065,17 +1299,21 @@ 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; + 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) @@ -1083,99 +1321,125 @@ void R_DrawSplat_8 (void) // 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; + 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; + x %= ds_flatwidth; + y %= ds_flatheight; - 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)]; + 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]; + 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; - dest++; - 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)]; + if (val != TRANSPARENTPIXEL) + *dest = colormap[val]; + dest++; + xposition += xstep; + yposition += ystep; + } } } @@ -1184,16 +1448,20 @@ 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; + 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 @@ -1202,79 +1470,107 @@ void R_DrawTranslucentSplat_8 (void) // 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; + 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; + x %= ds_flatwidth; + y %= ds_flatheight; - 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)]; + 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); + 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; - dest++; - 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)]; + if (val != TRANSPARENTPIXEL) + *dest = *(ds_transmap + (colormap[val] << 8) + *dest); + dest++; + xposition += xstep; + yposition += ystep; + } } } @@ -1283,15 +1579,20 @@ 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; + 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 @@ -1300,63 +1601,161 @@ void R_DrawTranslucentSpan_8 (void) // 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; + 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; + x %= ds_flatwidth; + y %= ds_flatheight; - 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); + *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 >= 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); + *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; + + 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; + 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); + + x %= ds_flatwidth; + y %= ds_flatheight; + + *dest++ = colormap[*(ds_transmap + (source[((y * ds_flatwidth) + x)] << 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 2f6f97240..de5bf9f00 100644 --- a/src/r_plane.c +++ b/src/r_plane.c @@ -127,91 +127,13 @@ void R_InitPlanes(void) // 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; @@ -258,17 +180,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 @@ -680,7 +602,7 @@ void R_DrawPlanes(void) } } #ifndef NOWATER - waterofs = (leveltime & 1)*16384; + ds_waterofs = (leveltime & 1)*16384; wtofs = leveltime * 140; #endif } @@ -728,13 +650,156 @@ static void R_DrawSkyPlane(visplane_t *pl) } } +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 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); + + // Check if the texture changed. + if (leveltexture && (!texturechanged)) + { + if (texflat != NULL && texflat->flat) + { + flat = 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) + { + 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_TextureToFlat(levelflat->texturenum, texflat->flat); + flat = texflat->flat; + + levelflat->flatpatch = flat; + levelflat->width = ds_flatwidth; + levelflat->height = ds_flatheight; + } + else + { + patch = (patch_t *)ds_source; +#ifndef NO_PNG_LUMPS + if (ispng) + { + levelflat->flatpatch = R_PNGToFlat(levelflat, ds_source, W_LumpLength(levelflat->lumpnum)); + levelflat->topoffset = levelflat->leftoffset = 0; + ds_flatwidth = levelflat->width; + ds_flatheight = levelflat->height; + } + else +#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_PatchToFlat(patch, levelflat->flatpatch); + } + flat = levelflat->flatpatch; + } + } + else + { + flat = levelflat->flatpatch; + ds_flatwidth = levelflat->width; + ds_flatheight = levelflat->height; + + xoffs += levelflat->leftoffset; + yoffs += levelflat->topoffset; + } + + levelflat->lasttexturenum = levelflat->texturenum; + return flat; +} + void R_DrawSinglePlane(visplane_t *pl) { + UINT8 *flat; INT32 light = 0; INT32 x; INT32 stop, angle; size_t size; ffloor_t *rover; + levelflat_t *levelflat; if (!(pl->minx <= pl->maxx)) return; @@ -874,64 +939,43 @@ 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]; + 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) + flat = R_GetPatchFlat(levelflat, true, false); +#ifndef NO_PNG_LUMPS + // Maybe it's a PNG?! + else if (R_IsLumpPNG(ds_source, size)) + flat = R_GetPatchFlat(levelflat, false, true); +#endif + // Maybe it's just a patch, then? + else if (R_CheckIfPatch(levelflat->lumpnum)) + flat = R_GetPatchFlat(levelflat, false, false); + // 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()) + R_CheckFlatLength(ds_flatwidth * ds_flatheight); + if (light >= LIGHTLEVELS) light = LIGHTLEVELS-1; @@ -945,60 +989,63 @@ void R_DrawSinglePlane(visplane_t *pl) floatv3_t p, m, n; float ang; float vx, vy, vz; + 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; - // Okay, look, don't ask me why this works, but without this setup there's a disgusting-looking misalignment with the textures. -Red - const float fudge = ((1<plangle & (ANGLE_90-1)); yoffs *= 1; - if (hack) + if (ds_powersoftwo) { - /* - Essentially: We can't & the components along the regular axes when the plane is rotated. - This is because the distance on each regular axis in order to loop is different. - We rotate them, & the components, add them together, & them again, and then rotate them back. - These three seperate & operations are done per axis in order to prevent overflows. - toast 10/04/17 - */ - const fixed_t cosinecomponent = FINECOSINE(hack>>ANGLETOFINESHIFT); - const fixed_t sinecomponent = FINESINE(hack>>ANGLETOFINESHIFT); + // 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<>ANGLETOFINESHIFT); + const fixed_t sinecomponent = FINESINE(hack>>ANGLETOFINESHIFT); - const fixed_t modmask = ((1 << (32-nflatshiftup)) - 1); + const fixed_t modmask = ((1 << (32-nflatshiftup)) - 1); - fixed_t ox = (FixedMul(pl->slope->o.x,cosinecomponent) & modmask) - (FixedMul(pl->slope->o.y,sinecomponent) & modmask); - fixed_t oy = (-FixedMul(pl->slope->o.x,sinecomponent) & modmask) - (FixedMul(pl->slope->o.y,cosinecomponent) & modmask); + fixed_t ox = (FixedMul(pl->slope->o.x,cosinecomponent) & modmask) - (FixedMul(pl->slope->o.y,sinecomponent) & modmask); + fixed_t oy = (-FixedMul(pl->slope->o.x,sinecomponent) & modmask) - (FixedMul(pl->slope->o.y,cosinecomponent) & modmask); - temp = ox & modmask; - oy &= modmask; - ox = FixedMul(temp,cosinecomponent)+FixedMul(oy,-sinecomponent); // negative sine for opposite direction - oy = -FixedMul(temp,-sinecomponent)+FixedMul(oy,cosinecomponent); + temp = ox & modmask; + oy &= modmask; + ox = FixedMul(temp,cosinecomponent)+FixedMul(oy,-sinecomponent); // negative sine for opposite direction + oy = -FixedMul(temp,-sinecomponent)+FixedMul(oy,cosinecomponent); - temp = xoffs; - xoffs = (FixedMul(temp,cosinecomponent) & modmask) + (FixedMul(yoffs,sinecomponent) & modmask); - yoffs = (-FixedMul(temp,sinecomponent) & modmask) + (FixedMul(yoffs,cosinecomponent) & modmask); + temp = xoffs; + xoffs = (FixedMul(temp,cosinecomponent) & modmask) + (FixedMul(yoffs,sinecomponent) & modmask); + yoffs = (-FixedMul(temp,sinecomponent) & modmask) + (FixedMul(yoffs,cosinecomponent) & modmask); - temp = xoffs & modmask; - yoffs &= modmask; - xoffs = FixedMul(temp,cosinecomponent)+FixedMul(yoffs,-sinecomponent); // ditto - yoffs = -FixedMul(temp,-sinecomponent)+FixedMul(yoffs,cosinecomponent); + temp = xoffs & modmask; + yoffs &= modmask; + xoffs = FixedMul(temp,cosinecomponent)+FixedMul(yoffs,-sinecomponent); // ditto + yoffs = -FixedMul(temp,-sinecomponent)+FixedMul(yoffs,cosinecomponent); - xoffs -= (pl->slope->o.x - ox); - yoffs += (pl->slope->o.y + oy); + xoffs -= (pl->slope->o.x - ox); + yoffs += (pl->slope->o.y + oy); + } + else + { + 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 = (fixed_t)(xoffs*fudge); + yoffs = (fixed_t)(yoffs/fudge); } - else - { - 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 = (fixed_t)(xoffs*fudge); - yoffs = (fixed_t)(yoffs/fudge); vx = FIXED_TO_FLOAT(pl->viewx+xoffs); vy = FIXED_TO_FLOAT(pl->viewy-yoffs); @@ -1033,13 +1080,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) \ @@ -1056,14 +1106,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, 10 Sep 2019 17:25:21 -0300 Subject: [PATCH 51/51] Enable usage of R_DrawSpan_8_MMX if drawing a flat with powers-of-two dimensions --- src/r_plane.c | 12 +++++++++++- src/screen.c | 5 +++-- src/screen.h | 1 + 3 files changed, 15 insertions(+), 3 deletions(-) diff --git a/src/r_plane.c b/src/r_plane.c index de5bf9f00..51a69336e 100644 --- a/src/r_plane.c +++ b/src/r_plane.c @@ -652,7 +652,13 @@ static void R_DrawSkyPlane(visplane_t *pl) boolean R_CheckPowersOfTwo(void) { - return (ds_powersoftwo = ((!((ds_flatwidth & (ds_flatwidth - 1)) || (ds_flatheight & (ds_flatheight - 1)))) && (ds_flatwidth == ds_flatheight))); + if (ds_flatwidth & (ds_flatwidth - 1)) + ds_powersoftwo = false; + else if (ds_flatheight & (ds_flatheight - 1)) + ds_powersoftwo = false; + else if (ds_flatwidth == ds_flatheight) + ds_powersoftwo = true; + return ds_powersoftwo; } void R_CheckFlatLength(size_t size) @@ -974,7 +980,11 @@ void R_DrawSinglePlane(visplane_t *pl) // Check if the flat has dimensions that are powers-of-two numbers. if (R_CheckPowersOfTwo()) + { R_CheckFlatLength(ds_flatwidth * ds_flatheight); + if (spanfunc == basespanfunc) + spanfunc = mmxspanfunc; + } if (light >= LIGHTLEVELS) light = LIGHTLEVELS-1; diff --git a/src/screen.c b/src/screen.c index 4bace5239..547036a60 100644 --- a/src/screen.c +++ b/src/screen.c @@ -49,6 +49,7 @@ void (*fuzzcolfunc)(void); // standard fuzzy effect column drawer void (*transcolfunc)(void); // translation column drawer void (*shadecolfunc)(void); // smokie test.. void (*spanfunc)(void); // span drawer, use a 64x64 tile +void (*mmxspanfunc)(void); // span drawer in MMX assembly void (*splatfunc)(void); // span drawer w/ transparency void (*basespanfunc)(void); // default span func for color mode void (*transtransfunc)(void); // translucent translated column drawer @@ -112,7 +113,7 @@ void SCR_SetMode(void) // if (true)//vid.bpp == 1) //Always run in 8bpp. todo: remove all 16bpp code? { - spanfunc = basespanfunc = R_DrawSpan_8; + spanfunc = basespanfunc = mmxspanfunc = R_DrawSpan_8; splatfunc = R_DrawSplat_8; transcolfunc = R_DrawTranslatedColumn_8; transtransfunc = R_DrawTranslatedTranslucentColumn_8; @@ -133,7 +134,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; + mmxspanfunc = R_DrawSpan_8_MMX; } else { diff --git a/src/screen.h b/src/screen.h index 7aa6fdb63..3554b5520 100644 --- a/src/screen.h +++ b/src/screen.h @@ -123,6 +123,7 @@ extern void (*transcolfunc)(void); extern void (*shadecolfunc)(void); extern void (*spanfunc)(void); extern void (*basespanfunc)(void); +extern void (*mmxspanfunc)(void); extern void (*splatfunc)(void); extern void (*transtransfunc)(void); extern void (*twosmultipatchfunc)(void);