diff --git a/src/r_things.c b/src/r_things.c index 23db60386..1fdc7f038 100644 --- a/src/r_things.c +++ b/src/r_things.c @@ -1958,6 +1958,11 @@ static void R_ProjectSprite(mobj_t *thing) ang = (viewangle >> ANGLETOFINESHIFT); sort_x = FixedMul(FixedMul(FixedMul(spritexscale, this_scale), sort_z), FINECOSINE(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((intptr_t)projectiony, sort_z); } if ((thing->flags2 & MF2_LINKDRAW) && thing->tracer) // toast 16/09/16 (SYMMETRY) @@ -1995,7 +2000,9 @@ static void R_ProjectSprite(mobj_t *thing) if (sortscale < linkscale) 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; } else if (splat) @@ -2556,6 +2563,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 // @@ -2650,7 +2672,7 @@ static void R_SortVisSprites(vissprite_t* vsprsortedhead, UINT32 start, UINT32 e // reusing dsnext... dsnext = dsfirst->linkdraw; - if (!dsnext || ds->dispoffset < dsnext->dispoffset) + if (dsnext == NULL || R_SortVisSpriteFunc(ds, dsnext->sortscale, dsnext->dispoffset) == true) { ds->next = dsnext; dsfirst->linkdraw = ds; @@ -2658,8 +2680,13 @@ static void R_SortVisSprites(vissprite_t* vsprsortedhead, UINT32 start, UINT32 e else { 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; + } + } + ds->next = dsnext->next; dsnext->next = ds; } @@ -2678,18 +2705,12 @@ static void R_SortVisSprites(vissprite_t* vsprsortedhead, UINT32 start, UINT32 e I_Error("R_SortVisSprites: no link or discardal made for linkdraw!"); #endif - if (ds->sortscale < bestscale) + if (R_SortVisSpriteFunc(ds, bestscale, bestdispoffset) == true) { 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; @@ -3520,14 +3541,20 @@ static void R_DrawMaskedList (drawnode_t* head) vissprite_t *ds = r2->sprite->linkdraw; for (; - (ds != NULL && r2->sprite->dispoffset > ds->dispoffset); - ds = ds->next) + (ds != NULL && r2->sprite->dispoffset > ds->dispoffset); + ds = ds->next) + { R_DrawSprite(ds); + } R_DrawSprite(r2->sprite); - for (; ds != NULL; ds = ds->next) + for (; + ds != NULL; + ds = ds->next) + { R_DrawSprite(ds); + } } R_DoneWithNode(r2);