mirror of
https://git.do.srb2.org/STJr/SRB2.git
synced 2025-01-29 20:50:58 +00:00
* 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.
This commit is contained in:
parent
93dce12fce
commit
59ea08ee11
2 changed files with 95 additions and 86 deletions
163
src/r_things.c
163
src/r_things.c
|
@ -887,12 +887,12 @@ static void R_DrawVisSprite(vissprite_t *vis)
|
||||||
this_scale = 1;
|
this_scale = 1;
|
||||||
if (this_scale != FRACUNIT)
|
if (this_scale != FRACUNIT)
|
||||||
{
|
{
|
||||||
if (!vis->isScaled)
|
if (!(vis->cut & SC_ISSCALED))
|
||||||
{
|
{
|
||||||
vis->scale = FixedMul(vis->scale, this_scale);
|
vis->scale = FixedMul(vis->scale, this_scale);
|
||||||
vis->scalestep = FixedMul(vis->scalestep, this_scale);
|
vis->scalestep = FixedMul(vis->scalestep, this_scale);
|
||||||
vis->xiscale = FixedDiv(vis->xiscale,this_scale);
|
vis->xiscale = FixedDiv(vis->xiscale,this_scale);
|
||||||
vis->isScaled = true;
|
vis->cut |= SC_ISSCALED;
|
||||||
}
|
}
|
||||||
dc_texturemid = FixedDiv(dc_texturemid,this_scale);
|
dc_texturemid = FixedDiv(dc_texturemid,this_scale);
|
||||||
}
|
}
|
||||||
|
@ -934,7 +934,7 @@ static void R_DrawVisSprite(vissprite_t *vis)
|
||||||
sprtopscreen = (centeryfrac - FixedMul(dc_texturemid, spryscale));
|
sprtopscreen = (centeryfrac - FixedMul(dc_texturemid, spryscale));
|
||||||
dc_iscale = (0xffffffffu / (unsigned)spryscale);
|
dc_iscale = (0xffffffffu / (unsigned)spryscale);
|
||||||
}
|
}
|
||||||
if (vis->vflip)
|
if (vis->cut & SC_VFLIP)
|
||||||
R_DrawFlippedMaskedColumn(column, patch->height);
|
R_DrawFlippedMaskedColumn(column, patch->height);
|
||||||
else
|
else
|
||||||
R_DrawMaskedColumn(column);
|
R_DrawMaskedColumn(column);
|
||||||
|
@ -1013,7 +1013,7 @@ static void R_DrawPrecipitationVisSprite(vissprite_t *vis)
|
||||||
//
|
//
|
||||||
// R_SplitSprite
|
// R_SplitSprite
|
||||||
// runs through a sector's lightlist and
|
// 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;
|
INT32 i, lightnum, lindex;
|
||||||
INT16 cutfrac;
|
INT16 cutfrac;
|
||||||
|
@ -1049,7 +1049,7 @@ static void R_SplitSprite(vissprite_t *sprite, mobj_t *thing)
|
||||||
// adjust the heights.
|
// adjust the heights.
|
||||||
newsprite = M_Memcpy(R_NewVisSprite(), sprite, sizeof (vissprite_t));
|
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->cut |= SC_BOTTOM;
|
||||||
sprite->gz = testheight;
|
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;
|
newsprite->extra_colormap = sector->lightlist[i].extra_colormap;
|
||||||
|
|
||||||
/*
|
if (!(newsprite->cut & SC_FULLBRIGHT))
|
||||||
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)))
|
|
||||||
{
|
{
|
||||||
lindex = FixedMul(sprite->xscale, FixedDiv(640, vid.width))>>(LIGHTSCALESHIFT);
|
lindex = FixedMul(sprite->xscale, FixedDiv(640, vid.width))>>(LIGHTSCALESHIFT);
|
||||||
|
|
||||||
|
@ -1333,6 +1325,10 @@ static void R_ProjectSprite(mobj_t *thing)
|
||||||
fixed_t linkscale;
|
fixed_t linkscale;
|
||||||
|
|
||||||
thing = thing->tracer;
|
thing = thing->tracer;
|
||||||
|
|
||||||
|
if (thing->sprite == SPR_NULL || thing->flags2 & MF2_DONTDRAW)
|
||||||
|
return;
|
||||||
|
|
||||||
tr_x = thing->x - viewx;
|
tr_x = thing->x - viewx;
|
||||||
tr_y = thing->y - viewy;
|
tr_y = thing->y - viewy;
|
||||||
gxt = FixedMul(tr_x, viewcos);
|
gxt = FixedMul(tr_x, viewcos);
|
||||||
|
@ -1377,7 +1373,7 @@ static void R_ProjectSprite(mobj_t *thing)
|
||||||
|
|
||||||
if (thing->subsector->sector->cullheight)
|
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;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1508,6 +1504,7 @@ static void R_ProjectSprite(mobj_t *thing)
|
||||||
{
|
{
|
||||||
// full bright: goggles
|
// full bright: goggles
|
||||||
vis->colormap = colormaps;
|
vis->colormap = colormaps;
|
||||||
|
vis->cut |= SC_FULLBRIGHT;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -1520,14 +1517,11 @@ static void R_ProjectSprite(mobj_t *thing)
|
||||||
vis->colormap = spritelights[lindex];
|
vis->colormap = spritelights[lindex];
|
||||||
}
|
}
|
||||||
|
|
||||||
vis->precip = false;
|
if (vflip)
|
||||||
|
vis->cut |= SC_VFLIP;
|
||||||
vis->vflip = vflip;
|
|
||||||
|
|
||||||
vis->isScaled = false;
|
|
||||||
|
|
||||||
if (thing->subsector->sector->numlights)
|
if (thing->subsector->sector->numlights)
|
||||||
R_SplitSprite(vis, oldthing);
|
R_SplitSprite(vis);
|
||||||
|
|
||||||
// Debug
|
// Debug
|
||||||
++objectsdrawn;
|
++objectsdrawn;
|
||||||
|
@ -1688,15 +1682,12 @@ static void R_ProjectPrecipitationSprite(precipmobj_t *thing)
|
||||||
vis->transmap = NULL;
|
vis->transmap = NULL;
|
||||||
|
|
||||||
vis->mobjflags = 0;
|
vis->mobjflags = 0;
|
||||||
vis->cut = SC_NONE;
|
vis->cut = SC_PRECIP;
|
||||||
vis->extra_colormap = thing->subsector->sector->extra_colormap;
|
vis->extra_colormap = thing->subsector->sector->extra_colormap;
|
||||||
vis->heightsec = thing->subsector->sector->heightsec;
|
vis->heightsec = thing->subsector->sector->heightsec;
|
||||||
|
|
||||||
// Fullbright
|
// Fullbright
|
||||||
vis->colormap = colormaps;
|
vis->colormap = colormaps;
|
||||||
vis->precip = true;
|
|
||||||
vis->vflip = false;
|
|
||||||
vis->isScaled = false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// R_AddSprites
|
// R_AddSprites
|
||||||
|
@ -1789,7 +1780,7 @@ static vissprite_t vsprsortedhead;
|
||||||
|
|
||||||
void R_SortVisSprites(void)
|
void R_SortVisSprites(void)
|
||||||
{
|
{
|
||||||
UINT32 i;
|
UINT32 i, linkedvissprites = 0;
|
||||||
vissprite_t *ds, *dsprev, *dsnext, *dsfirst;
|
vissprite_t *ds, *dsprev, *dsnext, *dsfirst;
|
||||||
vissprite_t *best = NULL;
|
vissprite_t *best = NULL;
|
||||||
vissprite_t unsorted;
|
vissprite_t unsorted;
|
||||||
|
@ -1826,42 +1817,14 @@ void R_SortVisSprites(void)
|
||||||
}
|
}
|
||||||
unsorted.prev = ds;
|
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
|
// 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))
|
if (!(ds->cut & SC_LINKDRAW))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
// reuse dsfirst...
|
// 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
|
// don't connect if it's also a link
|
||||||
if (dsfirst->cut & SC_LINKDRAW)
|
if (dsfirst->cut & SC_LINKDRAW)
|
||||||
|
@ -1881,18 +1844,65 @@ void R_SortVisSprites(void)
|
||||||
&& dsfirst->sz < ds->sz)
|
&& dsfirst->sz < ds->sz)
|
||||||
continue;
|
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;
|
break;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// remove from chain
|
// pull the vissprites out by scale
|
||||||
ds->next->prev = ds->prev;
|
vsprsortedhead.next = vsprsortedhead.prev = &vsprsortedhead;
|
||||||
ds->prev->next = ds->next;
|
for (i = 0; i < visspritecount-linkedvissprites; i++)
|
||||||
|
{
|
||||||
if (dsfirst != &vsprsortedhead)
|
bestscale = bestdispoffset = INT32_MAX;
|
||||||
|
for (ds = unsorted.next; ds != &unsorted; ds = ds->next)
|
||||||
{
|
{
|
||||||
ds->next = dsfirst->linkdraw;
|
if (ds->cut & SC_LINKDRAW)
|
||||||
dsfirst->linkdraw = ds;
|
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)
|
void R_ClipSprites(void)
|
||||||
{
|
{
|
||||||
vissprite_t *spr;
|
vissprite_t *spr;
|
||||||
for (;clippedvissprites < visspritecount; clippedvissprites++)
|
for (; clippedvissprites < visspritecount; clippedvissprites++)
|
||||||
{
|
{
|
||||||
drawseg_t *ds;
|
drawseg_t *ds;
|
||||||
INT32 x;
|
INT32 x;
|
||||||
|
@ -2488,29 +2498,22 @@ void R_DrawMasked(void)
|
||||||
next = r2->prev;
|
next = r2->prev;
|
||||||
|
|
||||||
// Tails 08-18-2002
|
// Tails 08-18-2002
|
||||||
if (r2->sprite->precip == true)
|
if (r2->sprite->cut & SC_PRECIP)
|
||||||
R_DrawPrecipitationSprite(r2->sprite);
|
R_DrawPrecipitationSprite(r2->sprite);
|
||||||
else if (!r2->sprite->linkdraw)
|
else if (!r2->sprite->linkdraw)
|
||||||
R_DrawSprite(r2->sprite);
|
R_DrawSprite(r2->sprite);
|
||||||
else // unbundle linkdraw
|
else // unbundle linkdraw
|
||||||
{
|
{
|
||||||
vissprite_t *ds = ds = r2->sprite->linkdraw;
|
vissprite_t *ds = r2->sprite->linkdraw;
|
||||||
|
|
||||||
if (r2->sprite->dispoffset < ds->dispoffset)
|
for (;
|
||||||
{
|
(ds != NULL && r2->sprite->dispoffset > ds->dispoffset);
|
||||||
r2->sprite->next = r2->sprite->linkdraw;
|
ds = ds->next)
|
||||||
r2->sprite->linkdraw = r2->sprite;
|
R_DrawSprite(ds);
|
||||||
}
|
|
||||||
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(r2->sprite);
|
||||||
|
|
||||||
|
for (; ds != NULL; ds = ds->next)
|
||||||
R_DrawSprite(ds);
|
R_DrawSprite(ds);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -127,10 +127,19 @@ typedef struct
|
||||||
// -----------
|
// -----------
|
||||||
typedef enum
|
typedef enum
|
||||||
{
|
{
|
||||||
|
// actual cuts
|
||||||
SC_NONE = 0,
|
SC_NONE = 0,
|
||||||
SC_TOP = 1,
|
SC_TOP = 1,
|
||||||
SC_BOTTOM = 2,
|
SC_BOTTOM = 1<<1,
|
||||||
SC_LINKDRAW = 4
|
// 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;
|
} spritecut_e;
|
||||||
|
|
||||||
// A vissprite_t is a thing that will be drawn during a refresh,
|
// 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 *prev;
|
||||||
struct vissprite_s *next;
|
struct vissprite_s *next;
|
||||||
|
|
||||||
// Bonus Linkdraw pointer.
|
// Bonus linkdraw pointer.
|
||||||
struct vissprite_s *linkdraw;
|
struct vissprite_s *linkdraw;
|
||||||
|
|
||||||
mobj_t *mobj; // for easy access
|
mobj_t *mobj; // for easy access
|
||||||
|
@ -182,9 +191,6 @@ typedef struct vissprite_s
|
||||||
|
|
||||||
INT16 clipbot[MAXVIDWIDTH], cliptop[MAXVIDWIDTH];
|
INT16 clipbot[MAXVIDWIDTH], cliptop[MAXVIDWIDTH];
|
||||||
|
|
||||||
boolean precip;
|
|
||||||
boolean vflip; // Flip vertically
|
|
||||||
boolean isScaled;
|
|
||||||
INT32 dispoffset; // copy of info->dispoffset, affects ordering but not drawing
|
INT32 dispoffset; // copy of info->dispoffset, affects ordering but not drawing
|
||||||
} vissprite_t;
|
} vissprite_t;
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue