mirror of
https://git.do.srb2.org/STJr/SRB2.git
synced 2024-11-29 07:32:02 +00:00
Merge branch 'multi-linkdraw' into 'next'
Improve multiple MF2_LINKDRAW objects in Software See merge request STJr/SRB2!1843
This commit is contained in:
commit
e0477a86b9
2 changed files with 51 additions and 23 deletions
|
@ -1066,7 +1066,7 @@ static void R_SplitSprite(vissprite_t *sprite)
|
||||||
if (testheight <= sprite->gz)
|
if (testheight <= sprite->gz)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
cutfrac = (INT16)((centeryfrac - FixedMul(testheight - viewz, sprite->sortscale))>>FRACBITS);
|
cutfrac = (INT16)((centeryfrac - FixedMul(testheight - viewz, sprite->linkscale))>>FRACBITS);
|
||||||
if (cutfrac < 0)
|
if (cutfrac < 0)
|
||||||
continue;
|
continue;
|
||||||
if (cutfrac > viewheight)
|
if (cutfrac > viewheight)
|
||||||
|
@ -1436,6 +1436,7 @@ static void R_ProjectSprite(mobj_t *thing)
|
||||||
fixed_t tx, tz;
|
fixed_t tx, tz;
|
||||||
fixed_t xscale, yscale; //added : 02-02-98 : aaargll..if I were a math-guy!!!
|
fixed_t xscale, yscale; //added : 02-02-98 : aaargll..if I were a math-guy!!!
|
||||||
fixed_t sortscale, sortsplat = 0;
|
fixed_t sortscale, sortsplat = 0;
|
||||||
|
fixed_t linkscale = 0;
|
||||||
fixed_t sort_x = 0, sort_y = 0, sort_z;
|
fixed_t sort_x = 0, sort_y = 0, sort_z;
|
||||||
|
|
||||||
INT32 x1, x2;
|
INT32 x1, x2;
|
||||||
|
@ -1817,12 +1818,16 @@ static void R_ProjectSprite(mobj_t *thing)
|
||||||
ang = (viewangle >> ANGLETOFINESHIFT);
|
ang = (viewangle >> ANGLETOFINESHIFT);
|
||||||
sort_x = FixedMul(FixedMul(FixedMul(spritexscale, this_scale), sort_z), FINECOSINE(ang));
|
sort_x = FixedMul(FixedMul(FixedMul(spritexscale, this_scale), sort_z), FINECOSINE(ang));
|
||||||
sort_y = FixedMul(FixedMul(FixedMul(spriteyscale, this_scale), sort_z), FINESINE(ang));
|
sort_y = FixedMul(FixedMul(FixedMul(spriteyscale, this_scale), sort_z), FINESINE(ang));
|
||||||
|
|
||||||
|
tr_x = (interp.x + sort_x) - viewx;
|
||||||
|
tr_y = (interp.y + sort_y) - viewy;
|
||||||
|
sort_z = FixedMul(tr_x, viewcos) + FixedMul(tr_y, viewsin);
|
||||||
|
sortscale = FixedDiv(projectiony, sort_z);
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((thing->flags2 & MF2_LINKDRAW) && thing->tracer) // toast 16/09/16 (SYMMETRY)
|
if ((thing->flags2 & MF2_LINKDRAW) && thing->tracer) // toast 16/09/16 (SYMMETRY)
|
||||||
{
|
{
|
||||||
interpmobjstate_t tracer_interp = {0};
|
interpmobjstate_t tracer_interp = {0};
|
||||||
fixed_t linkscale;
|
|
||||||
|
|
||||||
thing = thing->tracer;
|
thing = thing->tracer;
|
||||||
|
|
||||||
|
@ -1849,15 +1854,14 @@ static void R_ProjectSprite(mobj_t *thing)
|
||||||
if (sortscale < linkscale)
|
if (sortscale < linkscale)
|
||||||
dispoffset *= -1; // if it's physically behind, make sure it's ordered behind (if dispoffset > 0)
|
dispoffset *= -1; // if it's physically behind, make sure it's ordered behind (if dispoffset > 0)
|
||||||
|
|
||||||
sortscale = linkscale; // now make sure it's linked
|
//sortscale = linkscale; // now make sure it's linked
|
||||||
|
// No need to do that, linkdraw already excludes it from regular sorting.
|
||||||
|
|
||||||
cut |= SC_LINKDRAW;
|
cut |= SC_LINKDRAW;
|
||||||
}
|
}
|
||||||
else if (splat)
|
else
|
||||||
{
|
{
|
||||||
tr_x = (interp.x + sort_x) - viewx;
|
linkscale = sortscale;
|
||||||
tr_y = (interp.y + sort_y) - viewy;
|
|
||||||
sort_z = FixedMul(tr_x, viewcos) + FixedMul(tr_y, viewsin);
|
|
||||||
sortscale = FixedDiv(projectiony, sort_z);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Calculate the splat's sortscale
|
// Calculate the splat's sortscale
|
||||||
|
@ -2048,6 +2052,7 @@ static void R_ProjectSprite(mobj_t *thing)
|
||||||
vis->mobjflags = thing->flags;
|
vis->mobjflags = thing->flags;
|
||||||
vis->sortscale = sortscale;
|
vis->sortscale = sortscale;
|
||||||
vis->sortsplat = sortsplat;
|
vis->sortsplat = sortsplat;
|
||||||
|
vis->linkscale = linkscale;
|
||||||
vis->dispoffset = dispoffset; // Monster Iestyn: 23/11/15
|
vis->dispoffset = dispoffset; // Monster Iestyn: 23/11/15
|
||||||
vis->gx = interp.x;
|
vis->gx = interp.x;
|
||||||
vis->gy = interp.y;
|
vis->gy = interp.y;
|
||||||
|
@ -2078,8 +2083,10 @@ static void R_ProjectSprite(mobj_t *thing)
|
||||||
vis->x2 = x2 >= portalclipend ? portalclipend-1 : x2;
|
vis->x2 = x2 >= portalclipend ? portalclipend-1 : x2;
|
||||||
|
|
||||||
vis->sector = thing->subsector->sector;
|
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);
|
// Using linkscale here improves cut detection for LINKDRAW.
|
||||||
|
vis->szt = (INT16)((centeryfrac - FixedMul(vis->gzt - viewz, linkscale))>>FRACBITS);
|
||||||
|
vis->sz = (INT16)((centeryfrac - FixedMul(vis->gz - viewz, linkscale))>>FRACBITS);
|
||||||
vis->cut = cut;
|
vis->cut = cut;
|
||||||
|
|
||||||
if (thing->subsector->sector->numlights)
|
if (thing->subsector->sector->numlights)
|
||||||
|
@ -2414,6 +2421,21 @@ void R_AddSprites(sector_t *sec, INT32 lightlevel)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static boolean R_SortVisSpriteFunc(vissprite_t *ds, fixed_t bestscale, INT32 bestdispoffset)
|
||||||
|
{
|
||||||
|
if (ds->sortscale < bestscale)
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
// order visprites of same scale by dispoffset, smallest first
|
||||||
|
else if (ds->sortscale == bestscale && ds->dispoffset < bestdispoffset)
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
//
|
//
|
||||||
// R_SortVisSprites
|
// R_SortVisSprites
|
||||||
//
|
//
|
||||||
|
@ -2504,7 +2526,7 @@ static void R_SortVisSprites(vissprite_t* vsprsortedhead, UINT32 start, UINT32 e
|
||||||
// reusing dsnext...
|
// reusing dsnext...
|
||||||
dsnext = dsfirst->linkdraw;
|
dsnext = dsfirst->linkdraw;
|
||||||
|
|
||||||
if (!dsnext || ds->dispoffset < dsnext->dispoffset)
|
if (dsnext == NULL || R_SortVisSpriteFunc(ds, dsnext->sortscale, dsnext->dispoffset) == true)
|
||||||
{
|
{
|
||||||
ds->next = dsnext;
|
ds->next = dsnext;
|
||||||
dsfirst->linkdraw = ds;
|
dsfirst->linkdraw = ds;
|
||||||
|
@ -2512,8 +2534,13 @@ static void R_SortVisSprites(vissprite_t* vsprsortedhead, UINT32 start, UINT32 e
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
for (; dsnext->next != NULL; dsnext = dsnext->next)
|
for (; dsnext->next != NULL; dsnext = dsnext->next)
|
||||||
if (ds->dispoffset < dsnext->next->dispoffset)
|
{
|
||||||
|
if (R_SortVisSpriteFunc(ds, dsnext->next->sortscale, dsnext->next->dispoffset) == true)
|
||||||
|
{
|
||||||
break;
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
ds->next = dsnext->next;
|
ds->next = dsnext->next;
|
||||||
dsnext->next = ds;
|
dsnext->next = ds;
|
||||||
}
|
}
|
||||||
|
@ -2532,18 +2559,12 @@ static void R_SortVisSprites(vissprite_t* vsprsortedhead, UINT32 start, UINT32 e
|
||||||
I_Error("R_SortVisSprites: no link or discardal made for linkdraw!");
|
I_Error("R_SortVisSprites: no link or discardal made for linkdraw!");
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
if (ds->sortscale < bestscale)
|
if (R_SortVisSpriteFunc(ds, bestscale, bestdispoffset) == true)
|
||||||
{
|
{
|
||||||
bestscale = ds->sortscale;
|
bestscale = ds->sortscale;
|
||||||
bestdispoffset = ds->dispoffset;
|
bestdispoffset = ds->dispoffset;
|
||||||
best = ds;
|
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->next->prev = best->prev;
|
||||||
best->prev->next = best->next;
|
best->prev->next = best->next;
|
||||||
|
@ -3289,14 +3310,20 @@ static void R_DrawMaskedList (drawnode_t* head)
|
||||||
vissprite_t *ds = r2->sprite->linkdraw;
|
vissprite_t *ds = r2->sprite->linkdraw;
|
||||||
|
|
||||||
for (;
|
for (;
|
||||||
(ds != NULL && r2->sprite->dispoffset > ds->dispoffset);
|
(ds != NULL && r2->sprite->dispoffset > ds->dispoffset);
|
||||||
ds = ds->next)
|
ds = ds->next)
|
||||||
|
{
|
||||||
R_DrawSprite(ds);
|
R_DrawSprite(ds);
|
||||||
|
}
|
||||||
|
|
||||||
R_DrawSprite(r2->sprite);
|
R_DrawSprite(r2->sprite);
|
||||||
|
|
||||||
for (; ds != NULL; ds = ds->next)
|
for (;
|
||||||
|
ds != NULL;
|
||||||
|
ds = ds->next)
|
||||||
|
{
|
||||||
R_DrawSprite(ds);
|
R_DrawSprite(ds);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
R_DoneWithNode(r2);
|
R_DoneWithNode(r2);
|
||||||
|
|
|
@ -159,8 +159,9 @@ typedef struct vissprite_s
|
||||||
fixed_t startfrac; // horizontal position of x1
|
fixed_t startfrac; // horizontal position of x1
|
||||||
fixed_t xscale, scale; // projected horizontal and vertical scales
|
fixed_t xscale, scale; // projected horizontal and vertical scales
|
||||||
fixed_t thingscale; // the object's scale
|
fixed_t thingscale; // the object's scale
|
||||||
fixed_t sortscale; // sortscale only differs from scale for paper sprites, floor sprites, and MF2_LINKDRAW
|
fixed_t sortscale; // sortscale only differs from scale for paper sprites and floor sprites
|
||||||
fixed_t sortsplat; // the sortscale from behind the floor sprite
|
fixed_t sortsplat; // the sortscale from behind the floor sprite
|
||||||
|
fixed_t linkscale; // the sortscale for MF2_LINKDRAW sprites
|
||||||
fixed_t scalestep; // only for paper sprites, 0 otherwise
|
fixed_t scalestep; // only for paper sprites, 0 otherwise
|
||||||
fixed_t paperoffset, paperdistance; // for paper sprites, offset/dist relative to the angle
|
fixed_t paperoffset, paperdistance; // for paper sprites, offset/dist relative to the angle
|
||||||
fixed_t xiscale; // negative if flipped
|
fixed_t xiscale; // negative if flipped
|
||||||
|
|
Loading…
Reference in a new issue