From 93dce12fceda1f2e1d942b0dc04c8050fa10190b Mon Sep 17 00:00:00 2001 From: toasterbabe Date: Sun, 25 Jun 2017 20:46:30 +0100 Subject: [PATCH 1/5] Seriously improves the reliability of the linkdraw system (in Software, the only rendering engine which actually does anything with this information), reducing the number of visual errors it produces significantly. Of particular note: Standing in shallow pools of water as Smiles will now reliably associate the bottom half of the tails following mobj with the underwater portion of Smiles' body, and the flicking ends with his un-submerged head. Deliberately engineered to only affect objects with MF2_LINKDRAW applied. --- src/r_things.c | 114 +++++++++++++++++++++++++++++++++++++------------ src/r_things.h | 6 ++- 2 files changed, 91 insertions(+), 29 deletions(-) diff --git a/src/r_things.c b/src/r_things.c index d71a7e7a1..ad1ac1362 100644 --- a/src/r_things.c +++ b/src/r_things.c @@ -1049,6 +1049,8 @@ static void R_SplitSprite(vissprite_t *sprite, mobj_t *thing) // adjust the heights. newsprite = M_Memcpy(R_NewVisSprite(), sprite, sizeof (vissprite_t)); + newsprite->cut |= (sprite->cut & SC_LINKDRAW); + sprite->cut |= SC_BOTTOM; sprite->gz = testheight; @@ -1109,6 +1111,7 @@ static void R_SplitSprite(vissprite_t *sprite, mobj_t *thing) // static void R_ProjectSprite(mobj_t *thing) { + mobj_t *oldthing = thing; fixed_t tr_x, tr_y; fixed_t gxt, gyt; fixed_t tx, tz; @@ -1128,6 +1131,8 @@ static void R_ProjectSprite(mobj_t *thing) vissprite_t *vis; + spritecut_e cut = SC_NONE; + angle_t ang = 0; // compiler complaints fixed_t iscale; fixed_t scalestep; @@ -1326,24 +1331,10 @@ static void R_ProjectSprite(mobj_t *thing) if ((thing->flags2 & MF2_LINKDRAW) && thing->tracer) // toast 16/09/16 (SYMMETRY) { fixed_t linkscale; -#if 0 // support for chains of linkdraw - probably not network safe to modify mobjs during rendering - mobj_t *link, *link2; - for (link = thing->tracer; (link->tracer && (link->flags2 & MF2_LINKDRAW)); link = link->tracer) - link->flags2 &= ~MF2_LINKDRAW; // to prevent infinite loops, otherwise would just be a ; - - for (link2 = thing->tracer; (link2->tracer && (link2 != link)); link2 = link2->tracer) - link->flags2 |= MF2_LINKDRAW; // only needed for correction of the above - - if (link->flags2 & MF2_LINKDRAW) - link->flags2 &= ~MF2_LINKDRAW; // let's try and make sure this doesn't happen again... - - tr_x = link->x - viewx; - tr_y = link->y - viewy; -#else - tr_x = thing->tracer->x - viewx; - tr_y = thing->tracer->y - viewy; -#endif + thing = thing->tracer; + tr_x = thing->x - viewx; + tr_y = thing->y - viewy; gxt = FixedMul(tr_x, viewcos); gyt = -FixedMul(tr_y, viewsin); tz = gxt-gyt; @@ -1356,6 +1347,7 @@ static void R_ProjectSprite(mobj_t *thing) dispoffset *= -1; // if it's physically behind, make sure it's ordered behind (if dispoffset > 0) sortscale = linkscale; // now make sure it's linked + cut = SC_LINKDRAW; } // PORTAL SPRITE CLIPPING @@ -1374,18 +1366,18 @@ static void R_ProjectSprite(mobj_t *thing) // When vertical flipped, draw sprites from the top down, at least as far as offsets are concerned. // sprite height - sprite topoffset is the proper inverse of the vertical offset, of course. // remember gz and gzt should be seperated by sprite height, not thing height - thing height can be shorter than the sprite itself sometimes! - gz = thing->z + thing->height - FixedMul(spritecachedinfo[lump].topoffset, this_scale); + gz = oldthing->z + oldthing->height - FixedMul(spritecachedinfo[lump].topoffset, this_scale); gzt = gz + FixedMul(spritecachedinfo[lump].height, this_scale); } else { - gzt = thing->z + FixedMul(spritecachedinfo[lump].topoffset, this_scale); + gzt = oldthing->z + FixedMul(spritecachedinfo[lump].topoffset, this_scale); gz = gzt - FixedMul(spritecachedinfo[lump].height, this_scale); } if (thing->subsector->sector->cullheight) { - if (R_DoCulling(thing->subsector->sector->cullheight, viewsector->cullheight, viewz, gz, gzt)) + if (R_DoCulling(oldthing->subsector->sector->cullheight, viewsector->cullheight, viewz, gz, gzt)) return; } @@ -1469,7 +1461,7 @@ static void R_ProjectSprite(mobj_t *thing) vis->sector = thing->subsector->sector; vis->szt = (INT16)((centeryfrac - FixedMul(vis->gzt - viewz, sortscale))>>FRACBITS); vis->sz = (INT16)((centeryfrac - FixedMul(vis->gz - viewz, sortscale))>>FRACBITS); - vis->cut = SC_NONE; + vis->cut = cut; if (thing->subsector->sector->numlights) vis->extra_colormap = thing->subsector->sector->lightlist[light].extra_colormap; else @@ -1506,12 +1498,12 @@ static void R_ProjectSprite(mobj_t *thing) // specific translucency if (!cv_translucency.value) ; // no translucency - else if (thing->flags2 & MF2_SHADOW) // actually only the player should use this (temporary invisibility) + else if (oldthing->flags2 & MF2_SHADOW) // actually only the player should use this (temporary invisibility) vis->transmap = transtables + ((tr_trans80-1)<frame & FF_TRANSMASK) - vis->transmap = transtables + (thing->frame & FF_TRANSMASK) - 0x10000; + else if (oldthing->frame & FF_TRANSMASK) + vis->transmap = transtables + (oldthing->frame & FF_TRANSMASK) - 0x10000; - if (((thing->frame & FF_FULLBRIGHT) || (thing->flags2 & MF2_SHADOW)) + if (((oldthing->frame & FF_FULLBRIGHT) || (oldthing->flags2 & MF2_SHADOW)) && (!vis->extra_colormap || !vis->extra_colormap->fog)) { // full bright: goggles @@ -1535,7 +1527,7 @@ static void R_ProjectSprite(mobj_t *thing) vis->isScaled = false; if (thing->subsector->sector->numlights) - R_SplitSprite(vis, thing); + R_SplitSprite(vis, oldthing); // Debug ++objectsdrawn; @@ -1559,7 +1551,7 @@ static void R_ProjectPrecipitationSprite(precipmobj_t *thing) fixed_t iscale; //SoM: 3/17/2000 - fixed_t gz ,gzt; + fixed_t gz, gzt; // transform the origin point tr_x = thing->x - viewx; @@ -1821,13 +1813,17 @@ void R_SortVisSprites(void) ds->next = dsnext; ds->prev = dsprev; + ds->linkdraw = NULL; } // Fix first and last. ds still points to the last one after the loop dsfirst->prev = &unsorted; unsorted.next = dsfirst; if (ds) + { ds->next = &unsorted; + ds->linkdraw = NULL; + } unsorted.prev = ds; // pull the vissprites out by scale @@ -1857,6 +1853,47 @@ void R_SortVisSprites(void) vsprsortedhead.prev->next = best; vsprsortedhead.prev = best; } + + // bundle linkdraw + for (ds = vsprsortedhead.prev; ds != &vsprsortedhead; ds = ds->prev) + { + if (!(ds->cut & SC_LINKDRAW)) + continue; + + // reuse dsfirst... + for (dsfirst = vsprsortedhead.prev; dsfirst != &vsprsortedhead; dsfirst = dsfirst->prev) + { + // don't connect if it's also a link + if (dsfirst->cut & SC_LINKDRAW) + continue; + + // don't connect if it's not the tracer + if (dsfirst->mobj != ds->mobj) + continue; + + // don't connect if the tracer's top is cut off, but lower than the link's top + if ((dsfirst->cut & SC_TOP) + && dsfirst->szt > ds->szt) + continue; + + // don't connect if the tracer's bottom is cut off, but higher than the link's bottom + if ((dsfirst->cut & SC_BOTTOM) + && dsfirst->sz < ds->sz) + continue; + + break; + } + + // remove from chain + ds->next->prev = ds->prev; + ds->prev->next = ds->next; + + if (dsfirst != &vsprsortedhead) + { + ds->next = dsfirst->linkdraw; + dsfirst->linkdraw = ds; + } + } } // @@ -2453,8 +2490,29 @@ void R_DrawMasked(void) // Tails 08-18-2002 if (r2->sprite->precip == true) R_DrawPrecipitationSprite(r2->sprite); - else + else if (!r2->sprite->linkdraw) R_DrawSprite(r2->sprite); + else // unbundle linkdraw + { + vissprite_t *ds = ds = r2->sprite->linkdraw; + + if (r2->sprite->dispoffset < ds->dispoffset) + { + r2->sprite->next = r2->sprite->linkdraw; + r2->sprite->linkdraw = r2->sprite; + } + else + { + for (; ds->next != NULL; ds = ds->next) + if (r2->sprite->dispoffset < ds->next->dispoffset) + break; + r2->sprite->next = ds->next; + ds->next = r2->sprite; + } + + for (ds = r2->sprite->linkdraw; ds != NULL; ds = ds->next) + R_DrawSprite(ds); + } R_DoneWithNode(r2); r2 = next; diff --git a/src/r_things.h b/src/r_things.h index 3907fd2ae..7db991bd3 100644 --- a/src/r_things.h +++ b/src/r_things.h @@ -129,7 +129,8 @@ typedef enum { SC_NONE = 0, SC_TOP = 1, - SC_BOTTOM = 2 + SC_BOTTOM = 2, + SC_LINKDRAW = 4 } spritecut_e; // A vissprite_t is a thing that will be drawn during a refresh, @@ -140,6 +141,9 @@ typedef struct vissprite_s struct vissprite_s *prev; struct vissprite_s *next; + // Bonus Linkdraw pointer. + struct vissprite_s *linkdraw; + mobj_t *mobj; // for easy access INT32 x1, x2; From 59ea08ee111c89c91b6b986a2d9983f2ccfad302 Mon Sep 17 00:00:00 2001 From: toasterbabe Date: Mon, 26 Jun 2017 14:44:10 +0100 Subject: [PATCH 2/5] * Change the order of operations such that linkdraw sprites aren't ever used for ordering comparisons with non-linkdraw sprites. * Refactor of the unbundling to not involve modifying the next/prev links. * Make the booleans in vissprite_t use flags stored in sprite->cut instead. * Make the linkdrawn sprites much more linked - ie, same brightness (unless independently fullbright), same colormap, and don't draw if the tracer isn't being drawn. * Other minor corrections. --- src/r_things.c | 163 +++++++++++++++++++++++++------------------------ src/r_things.h | 18 ++++-- 2 files changed, 95 insertions(+), 86 deletions(-) diff --git a/src/r_things.c b/src/r_things.c index ad1ac1362..8c8a35276 100644 --- a/src/r_things.c +++ b/src/r_things.c @@ -887,12 +887,12 @@ static void R_DrawVisSprite(vissprite_t *vis) this_scale = 1; if (this_scale != FRACUNIT) { - if (!vis->isScaled) + if (!(vis->cut & SC_ISSCALED)) { vis->scale = FixedMul(vis->scale, this_scale); vis->scalestep = FixedMul(vis->scalestep, this_scale); vis->xiscale = FixedDiv(vis->xiscale,this_scale); - vis->isScaled = true; + vis->cut |= SC_ISSCALED; } dc_texturemid = FixedDiv(dc_texturemid,this_scale); } @@ -934,7 +934,7 @@ static void R_DrawVisSprite(vissprite_t *vis) sprtopscreen = (centeryfrac - FixedMul(dc_texturemid, spryscale)); dc_iscale = (0xffffffffu / (unsigned)spryscale); } - if (vis->vflip) + if (vis->cut & SC_VFLIP) R_DrawFlippedMaskedColumn(column, patch->height); else R_DrawMaskedColumn(column); @@ -1013,7 +1013,7 @@ static void R_DrawPrecipitationVisSprite(vissprite_t *vis) // // R_SplitSprite // runs through a sector's lightlist and -static void R_SplitSprite(vissprite_t *sprite, mobj_t *thing) +static void R_SplitSprite(vissprite_t *sprite) { INT32 i, lightnum, lindex; INT16 cutfrac; @@ -1049,7 +1049,7 @@ static void R_SplitSprite(vissprite_t *sprite, mobj_t *thing) // adjust the heights. newsprite = M_Memcpy(R_NewVisSprite(), sprite, sizeof (vissprite_t)); - newsprite->cut |= (sprite->cut & SC_LINKDRAW); + newsprite->cut |= (sprite->cut & SC_FLAGMASK); sprite->cut |= SC_BOTTOM; sprite->gz = testheight; @@ -1083,15 +1083,7 @@ static void R_SplitSprite(vissprite_t *sprite, mobj_t *thing) newsprite->extra_colormap = sector->lightlist[i].extra_colormap; -/* - if (thing->frame & FF_TRANSMASK) - ; - else if (thing->flags2 & MF2_SHADOW) - ; - else -*/ - if (!((thing->frame & (FF_FULLBRIGHT|FF_TRANSMASK) || thing->flags2 & MF2_SHADOW) - && (!newsprite->extra_colormap || !newsprite->extra_colormap->fog))) + if (!(newsprite->cut & SC_FULLBRIGHT)) { lindex = FixedMul(sprite->xscale, FixedDiv(640, vid.width))>>(LIGHTSCALESHIFT); @@ -1333,6 +1325,10 @@ static void R_ProjectSprite(mobj_t *thing) fixed_t linkscale; thing = thing->tracer; + + if (thing->sprite == SPR_NULL || thing->flags2 & MF2_DONTDRAW) + return; + tr_x = thing->x - viewx; tr_y = thing->y - viewy; gxt = FixedMul(tr_x, viewcos); @@ -1377,7 +1373,7 @@ static void R_ProjectSprite(mobj_t *thing) if (thing->subsector->sector->cullheight) { - if (R_DoCulling(oldthing->subsector->sector->cullheight, viewsector->cullheight, viewz, gz, gzt)) + if (R_DoCulling(thing->subsector->sector->cullheight, viewsector->cullheight, viewz, gz, gzt)) return; } @@ -1508,6 +1504,7 @@ static void R_ProjectSprite(mobj_t *thing) { // full bright: goggles vis->colormap = colormaps; + vis->cut |= SC_FULLBRIGHT; } else { @@ -1520,14 +1517,11 @@ static void R_ProjectSprite(mobj_t *thing) vis->colormap = spritelights[lindex]; } - vis->precip = false; - - vis->vflip = vflip; - - vis->isScaled = false; + if (vflip) + vis->cut |= SC_VFLIP; if (thing->subsector->sector->numlights) - R_SplitSprite(vis, oldthing); + R_SplitSprite(vis); // Debug ++objectsdrawn; @@ -1688,15 +1682,12 @@ static void R_ProjectPrecipitationSprite(precipmobj_t *thing) vis->transmap = NULL; vis->mobjflags = 0; - vis->cut = SC_NONE; + vis->cut = SC_PRECIP; vis->extra_colormap = thing->subsector->sector->extra_colormap; vis->heightsec = thing->subsector->sector->heightsec; // Fullbright vis->colormap = colormaps; - vis->precip = true; - vis->vflip = false; - vis->isScaled = false; } // R_AddSprites @@ -1789,7 +1780,7 @@ static vissprite_t vsprsortedhead; void R_SortVisSprites(void) { - UINT32 i; + UINT32 i, linkedvissprites = 0; vissprite_t *ds, *dsprev, *dsnext, *dsfirst; vissprite_t *best = NULL; vissprite_t unsorted; @@ -1826,42 +1817,14 @@ void R_SortVisSprites(void) } unsorted.prev = ds; - // pull the vissprites out by scale - vsprsortedhead.next = vsprsortedhead.prev = &vsprsortedhead; - for (i = 0; i < visspritecount; i++) - { - bestscale = bestdispoffset = INT32_MAX; - for (ds = unsorted.next; ds != &unsorted; ds = ds->next) - { - if (ds->sortscale < bestscale) - { - bestscale = ds->sortscale; - bestdispoffset = ds->dispoffset; - best = ds; - } - // order visprites of same scale by dispoffset, smallest first - else if (ds->sortscale == bestscale && ds->dispoffset < bestdispoffset) - { - bestdispoffset = ds->dispoffset; - best = ds; - } - } - best->next->prev = best->prev; - best->prev->next = best->next; - best->next = &vsprsortedhead; - best->prev = vsprsortedhead.prev; - vsprsortedhead.prev->next = best; - vsprsortedhead.prev = best; - } - // bundle linkdraw - for (ds = vsprsortedhead.prev; ds != &vsprsortedhead; ds = ds->prev) + for (ds = unsorted.prev; ds != &unsorted; ds = ds->prev) { if (!(ds->cut & SC_LINKDRAW)) continue; // reuse dsfirst... - for (dsfirst = vsprsortedhead.prev; dsfirst != &vsprsortedhead; dsfirst = dsfirst->prev) + for (dsfirst = unsorted.prev; dsfirst != &unsorted; dsfirst = dsfirst->prev) { // don't connect if it's also a link if (dsfirst->cut & SC_LINKDRAW) @@ -1881,18 +1844,65 @@ void R_SortVisSprites(void) && dsfirst->sz < ds->sz) continue; + // remove from chain + ds->next->prev = ds->prev; + ds->prev->next = ds->next; + linkedvissprites++; + + if (!(ds->cut & SC_FULLBRIGHT)) + ds->colormap = dsfirst->colormap; + ds->extra_colormap = dsfirst->extra_colormap; + + // reusing dsnext... + dsnext = dsfirst->linkdraw; + + if (!dsnext || ds->dispoffset < dsnext->dispoffset) + { + ds->next = dsnext; + dsfirst->linkdraw = ds; + } + else + { + for (; dsnext->next != NULL; dsnext = dsnext->next) + if (ds->dispoffset < dsnext->next->dispoffset) + break; + ds->next = dsnext->next; + dsnext->next = ds; + } + break; } + } - // remove from chain - ds->next->prev = ds->prev; - ds->prev->next = ds->next; - - if (dsfirst != &vsprsortedhead) + // pull the vissprites out by scale + vsprsortedhead.next = vsprsortedhead.prev = &vsprsortedhead; + for (i = 0; i < visspritecount-linkedvissprites; i++) + { + bestscale = bestdispoffset = INT32_MAX; + for (ds = unsorted.next; ds != &unsorted; ds = ds->next) { - ds->next = dsfirst->linkdraw; - dsfirst->linkdraw = ds; + if (ds->cut & SC_LINKDRAW) + I_Error("No link made!"); // testing + + if (ds->sortscale < bestscale) + { + bestscale = ds->sortscale; + bestdispoffset = ds->dispoffset; + best = ds; + } + // order visprites of same scale by dispoffset, smallest first + else if (ds->sortscale == bestscale && ds->dispoffset < bestdispoffset) + { + bestdispoffset = ds->dispoffset; + best = ds; + } } + best->next->prev = best->prev; + best->prev->next = best->next; + best->next = &vsprsortedhead; + best->prev = vsprsortedhead.prev; + vsprsortedhead.prev->next = best; + vsprsortedhead.prev = best; } } @@ -2267,7 +2277,7 @@ static void R_DrawPrecipitationSprite(vissprite_t *spr) void R_ClipSprites(void) { vissprite_t *spr; - for (;clippedvissprites < visspritecount; clippedvissprites++) + for (; clippedvissprites < visspritecount; clippedvissprites++) { drawseg_t *ds; INT32 x; @@ -2488,29 +2498,22 @@ void R_DrawMasked(void) next = r2->prev; // Tails 08-18-2002 - if (r2->sprite->precip == true) + if (r2->sprite->cut & SC_PRECIP) R_DrawPrecipitationSprite(r2->sprite); else if (!r2->sprite->linkdraw) R_DrawSprite(r2->sprite); else // unbundle linkdraw { - vissprite_t *ds = ds = r2->sprite->linkdraw; + vissprite_t *ds = r2->sprite->linkdraw; - if (r2->sprite->dispoffset < ds->dispoffset) - { - r2->sprite->next = r2->sprite->linkdraw; - r2->sprite->linkdraw = r2->sprite; - } - else - { - for (; ds->next != NULL; ds = ds->next) - if (r2->sprite->dispoffset < ds->next->dispoffset) - break; - r2->sprite->next = ds->next; - ds->next = r2->sprite; - } + for (; + (ds != NULL && r2->sprite->dispoffset > ds->dispoffset); + ds = ds->next) + R_DrawSprite(ds); - for (ds = r2->sprite->linkdraw; ds != NULL; ds = ds->next) + R_DrawSprite(r2->sprite); + + for (; ds != NULL; ds = ds->next) R_DrawSprite(ds); } diff --git a/src/r_things.h b/src/r_things.h index 7db991bd3..c6eed746d 100644 --- a/src/r_things.h +++ b/src/r_things.h @@ -127,10 +127,19 @@ typedef struct // ----------- typedef enum { + // actual cuts SC_NONE = 0, SC_TOP = 1, - SC_BOTTOM = 2, - SC_LINKDRAW = 4 + SC_BOTTOM = 1<<1, + // other flags + SC_PRECIP = 1<<2, + SC_LINKDRAW = 1<<3, + SC_FULLBRIGHT = 1<<4, + SC_VFLIP = 1<<5, + SC_ISSCALED = 1>>6, + // masks + SC_CUTMASK = SC_TOP|SC_BOTTOM, + SC_FLAGMASK = ~SC_CUTMASK } spritecut_e; // A vissprite_t is a thing that will be drawn during a refresh, @@ -141,7 +150,7 @@ typedef struct vissprite_s struct vissprite_s *prev; struct vissprite_s *next; - // Bonus Linkdraw pointer. + // Bonus linkdraw pointer. struct vissprite_s *linkdraw; mobj_t *mobj; // for easy access @@ -182,9 +191,6 @@ typedef struct vissprite_s INT16 clipbot[MAXVIDWIDTH], cliptop[MAXVIDWIDTH]; - boolean precip; - boolean vflip; // Flip vertically - boolean isScaled; INT32 dispoffset; // copy of info->dispoffset, affects ordering but not drawing } vissprite_t; From dda9148e5626b504528be07b221a0602321c2836 Mon Sep 17 00:00:00 2001 From: toasterbabe Date: Mon, 26 Jun 2017 15:53:20 +0100 Subject: [PATCH 3/5] Fix issue with precipitation not modifying its mobj reference, resulting in Smiles' tails disappearing in CEZ3. Also, as a result, safeguard some stuff against referencing stuff that's outside of *precipmobj_t's domain. --- src/r_things.c | 23 +++++------------------ 1 file changed, 5 insertions(+), 18 deletions(-) diff --git a/src/r_things.c b/src/r_things.c index 8c8a35276..f4deb1711 100644 --- a/src/r_things.c +++ b/src/r_things.c @@ -817,7 +817,7 @@ static void R_DrawVisSprite(vissprite_t *vis) colfunc = basecolfunc; // hack: this isn't resetting properly somewhere. dc_colormap = vis->colormap; - if ((vis->mobj->flags & MF_BOSS) && (vis->mobj->flags2 & MF2_FRET) && (leveltime & 1)) // Bosses "flash" + if (!(vis->cut & SC_PRECIP) && (vis->mobj->flags & MF_BOSS) && (vis->mobj->flags2 & MF2_FRET) && (leveltime & 1)) // Bosses "flash" { // translate certain pixels to white colfunc = transcolfunc; @@ -832,7 +832,7 @@ static void R_DrawVisSprite(vissprite_t *vis) { colfunc = transtransfunc; dc_transmap = vis->transmap; - if (vis->mobj->skin && vis->mobj->sprite == SPR_PLAY) // MT_GHOST LOOKS LIKE A PLAYER SO USE THE PLAYER TRANSLATION TABLES. >_> + if (!(vis->cut & SC_PRECIP) && vis->mobj->skin && vis->mobj->sprite == SPR_PLAY) // MT_GHOST LOOKS LIKE A PLAYER SO USE THE PLAYER TRANSLATION TABLES. >_> { size_t skinnum = (skin_t*)vis->mobj->skin-skins; dc_translation = R_GetTranslationColormap((INT32)skinnum, vis->mobj->color, GTC_CACHE); @@ -851,7 +851,7 @@ static void R_DrawVisSprite(vissprite_t *vis) colfunc = transcolfunc; // New colormap stuff for skins Tails 06-07-2002 - if (vis->mobj->skin && vis->mobj->sprite == SPR_PLAY) // This thing is a player! + if (!(vis->cut & SC_PRECIP) && vis->mobj->skin && vis->mobj->sprite == SPR_PLAY) // This thing is a player! { size_t skinnum = (skin_t*)vis->mobj->skin-skins; dc_translation = R_GetTranslationColormap((INT32)skinnum, vis->mobj->color, GTC_CACHE); @@ -881,7 +881,7 @@ static void R_DrawVisSprite(vissprite_t *vis) frac = vis->startfrac; windowtop = windowbottom = sprbotscreen = INT32_MAX; - if (vis->mobj->skin && ((skin_t *)vis->mobj->skin)->flags & SF_HIRES) + if (!(vis->cut & SC_PRECIP) && vis->mobj->skin && ((skin_t *)vis->mobj->skin)->flags & SF_HIRES) this_scale = FixedMul(this_scale, ((skin_t *)vis->mobj->skin)->highresscale); if (this_scale <= 0) this_scale = 1; @@ -1681,6 +1681,7 @@ static void R_ProjectPrecipitationSprite(precipmobj_t *thing) else vis->transmap = NULL; + vis->mobj = (mobj_t *)thing; vis->mobjflags = 0; vis->cut = SC_PRECIP; vis->extra_colormap = thing->subsector->sector->extra_colormap; @@ -2137,20 +2138,6 @@ static void R_CreateDrawNodes(void) } else if (r2->seg) { -#if 0 //#ifdef POLYOBJECTS_PLANES - if (r2->seg->curline->polyseg && rover->mobj && P_MobjInsidePolyobj(r2->seg->curline->polyseg, rover->mobj)) { - // Determine if we need to sort in front of the polyobj, based on the planes. This fixes the issue where - // polyobject planes render above the object standing on them. (A bit hacky... but it works.) -Red - mobj_t *mo = rover->mobj; - sector_t *po = r2->seg->curline->backsector; - - if (po->ceilingheight < viewz && mo->z+mo->height > po->ceilingheight) - continue; - - if (po->floorheight > viewz && mo->z < po->floorheight) - continue; - } -#endif if (rover->x1 > r2->seg->x2 || rover->x2 < r2->seg->x1) continue; From b2fc2e03ba6ae28fba112b5512d6dfe918f6b5c7 Mon Sep 17 00:00:00 2001 From: toasterbabe Date: Mon, 26 Jun 2017 16:11:50 +0100 Subject: [PATCH 4/5] * Always remove linkdraw vissprites from unsorted drawing chain. * Make the related I_Error more descriptive and "#define PARANOIA"'d only. --- src/r_things.c | 19 ++++++++++++------- 1 file changed, 12 insertions(+), 7 deletions(-) diff --git a/src/r_things.c b/src/r_things.c index f4deb1711..406cebdef 100644 --- a/src/r_things.c +++ b/src/r_things.c @@ -1845,11 +1845,16 @@ void R_SortVisSprites(void) && dsfirst->sz < ds->sz) continue; - // remove from chain - ds->next->prev = ds->prev; - ds->prev->next = ds->next; - linkedvissprites++; + break; + } + // remove from chain + ds->next->prev = ds->prev; + ds->prev->next = ds->next; + linkedvissprites++; + + if (dsfirst != &unsorted) + { if (!(ds->cut & SC_FULLBRIGHT)) ds->colormap = dsfirst->colormap; ds->extra_colormap = dsfirst->extra_colormap; @@ -1870,8 +1875,6 @@ void R_SortVisSprites(void) ds->next = dsnext->next; dsnext->next = ds; } - - break; } } @@ -1882,8 +1885,10 @@ void R_SortVisSprites(void) bestscale = bestdispoffset = INT32_MAX; for (ds = unsorted.next; ds != &unsorted; ds = ds->next) { +#ifdef PARANOIA if (ds->cut & SC_LINKDRAW) - I_Error("No link made!"); // testing + I_Error("R_SortVisSprites: no link or discardal made for linkdraw!"); +#endif if (ds->sortscale < bestscale) { From fe4dcee9ad3a99e2c18f95d25d7b3bf5b3dc1044 Mon Sep 17 00:00:00 2001 From: toasterbabe Date: Mon, 26 Jun 2017 16:30:23 +0100 Subject: [PATCH 5/5] fix inaccurate SC_FULLBRIGHT declarations --- src/r_things.c | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/src/r_things.c b/src/r_things.c index 406cebdef..53dcc3314 100644 --- a/src/r_things.c +++ b/src/r_things.c @@ -1083,7 +1083,7 @@ static void R_SplitSprite(vissprite_t *sprite) newsprite->extra_colormap = sector->lightlist[i].extra_colormap; - if (!(newsprite->cut & SC_FULLBRIGHT)) + if (!((newsprite->cut & SC_FULLBRIGHT) && (!newsprite->extra_colormap || !newsprite->extra_colormap->fog))) { lindex = FixedMul(sprite->xscale, FixedDiv(640, vid.width))>>(LIGHTSCALESHIFT); @@ -1499,12 +1499,14 @@ static void R_ProjectSprite(mobj_t *thing) else if (oldthing->frame & FF_TRANSMASK) vis->transmap = transtables + (oldthing->frame & FF_TRANSMASK) - 0x10000; - if (((oldthing->frame & FF_FULLBRIGHT) || (oldthing->flags2 & MF2_SHADOW)) + if ((oldthing->frame & FF_FULLBRIGHT) || (oldthing->flags2 & MF2_SHADOW)) + vis->cut |= SC_FULLBRIGHT; + + if (vis->cut & SC_FULLBRIGHT && (!vis->extra_colormap || !vis->extra_colormap->fog)) { // full bright: goggles vis->colormap = colormaps; - vis->cut |= SC_FULLBRIGHT; } else {