- fixed sprite sorting in GL renderer. It was converting a float to integer

in the compare function without properly taking care of values <1 which 
  got truncated to 0.

- Update to ZDoom r2031:

- added all known maps requiring inverted sprite sorting to compatibility.txt.
- added compatibility option to invert sprite sorting. Apparently Doom.exe
  originally sorted them differently than most source port and on some maps
  which depends on this it doesn't look right (e.g. Strain MAP13)
- Fixed: Using Transfer_Heights with the SECF_UNDERWATER and
  SECF_FAKEFLOORONLY flags applied the water effect to the ceiling and not
  just the floor.
- Replaced sprite sorting with a stable sort. Performance at the start of
  nuts.wad seems the same.


git-svn-id: http://mancubus.net/svn/hosted/gzdoom/trunk@662 b0f79afe-0144-0410-b225-9a4edf0717df
This commit is contained in:
Christoph Oelckers 2009-12-18 09:11:54 +00:00
parent f531ae17a9
commit bb432d916c
12 changed files with 101 additions and 23 deletions

View file

@ -1,3 +1,16 @@
December 18, 2009 (Changes by Graf Zahl)
- added all known maps requiring inverted sprite sorting to compatibility.txt.
- added compatibility option to invert sprite sorting. Apparently Doom.exe
originally sorted them differently than most source port and on some maps
which depends on this it doesn't look right (e.g. Strain MAP13)
December 17, 2009
- Fixed: Using Transfer_Heights with the SECF_UNDERWATER and
SECF_FAKEFLOORONLY flags applied the water effect to the ceiling and not
just the floor.
- Replaced sprite sorting with a stable sort. Performance at the start of
nuts.wad seems the same.
December 16, 2009 (Changes by Graf Zahl)
- Fixed: Morphed players tried endlessly to switch to a weapon they picked up.
- fixed: P_DamageMobj just set an ice corpse's velocity to 0 to make it shatter.

View file

@ -105,6 +105,7 @@ static FCompatOption Options[] =
{ "mbfmonstermove", COMPATF_MBFMONSTERMOVE, 0 },
{ "corpsegibs", COMPATF_CORPSEGIBS, 0 },
{ "noblockfriends", COMPATF_NOBLOCKFRIENDS, 0 },
{ "spritesort", COMPATF_SPRITESORT, 0 },
{ NULL, 0, 0 }
};

View file

@ -492,12 +492,12 @@ CUSTOM_CVAR(Int, compatmode, 0, CVAR_ARCHIVE|CVAR_NOINITCALL)
break;
case 1: // Doom2.exe compatible with a few relaxed settings
v = COMPATF_SHORTTEX|COMPATF_STAIRINDEX|COMPATF_USEBLOCKING|COMPATF_NODOORLIGHT|
v = COMPATF_SHORTTEX|COMPATF_STAIRINDEX|COMPATF_USEBLOCKING|COMPATF_NODOORLIGHT|COMPATF_SPRITESORT|
COMPATF_TRACE|COMPATF_MISSILECLIP|COMPATF_SOUNDTARGET|COMPATF_DEHHEALTH|COMPATF_CROSSDROPOFF;
break;
case 2: // same as 1 but stricter (NO_PASSMOBJ and INVISIBILITY are also set)
v = COMPATF_SHORTTEX|COMPATF_STAIRINDEX|COMPATF_USEBLOCKING|COMPATF_NODOORLIGHT|
v = COMPATF_SHORTTEX|COMPATF_STAIRINDEX|COMPATF_USEBLOCKING|COMPATF_NODOORLIGHT|COMPATF_SPRITESORT|
COMPATF_TRACE|COMPATF_MISSILECLIP|COMPATF_SOUNDTARGET|COMPATF_NO_PASSMOBJ|COMPATF_LIMITPAIN|
COMPATF_DEHHEALTH|COMPATF_INVISIBILITY|COMPATF_CROSSDROPOFF|COMPATF_CORPSEGIBS;
break;
@ -546,6 +546,7 @@ CVAR (Flag, compat_mushroom, compatflags, COMPATF_MUSHROOM);
CVAR (Flag, compat_mbfmonstermove,compatflags, COMPATF_MBFMONSTERMOVE);
CVAR (Flag, compat_corpsegibs, compatflags, COMPATF_CORPSEGIBS);
CVAR (Flag, compat_noblockfriends,compatflags,COMPATF_NOBLOCKFRIENDS);
CVAR (Flag, compat_spritesort, compatflags,COMPATF_SPRITESORT);
//==========================================================================
//

View file

@ -324,6 +324,7 @@ enum
COMPATF_MBFMONSTERMOVE = 1 << 24, // Monsters are affected by friction and pushers/pullers.
COMPATF_CORPSEGIBS = 1 << 25, // Crushed monsters are turned into gibs, rather than replaced by gibs.
COMPATF_NOBLOCKFRIENDS = 1 << 26, // Friendly monsters aren't blocked by monster-blocking lines.
COMPATF_SPRITESORT = 1 << 27, // Invert sprite sorting order for sprites of equal distance
};
// Emulate old bugs for select maps. These are not exposed by a cvar

View file

@ -1359,6 +1359,7 @@ MapFlagHandlers[] =
{ "compat_mbfmonstermove", MITYPE_COMPATFLAG, COMPATF_MBFMONSTERMOVE},
{ "compat_corpsegibs", MITYPE_COMPATFLAG, COMPATF_CORPSEGIBS},
{ "compat_noblockfriends", MITYPE_COMPATFLAG, COMPATF_NOBLOCKFRIENDS},
{ "compat_spritesort", MITYPE_COMPATFLAG, COMPATF_SPRITESORT},
{ "cd_start_track", MITYPE_EATNEXT, 0, 0 },
{ "cd_end1_track", MITYPE_EATNEXT, 0, 0 },
{ "cd_end2_track", MITYPE_EATNEXT, 0, 0 },

View file

@ -558,7 +558,6 @@ void GLDrawList::SortSpriteIntoWall(SortNode * head,SortNode * sort)
//
//
//==========================================================================
CVAR(Bool, gl_spritesortback, false, 0)
inline int GLDrawList::CompareSprites(SortNode * a,SortNode * b)
{
@ -566,8 +565,9 @@ inline int GLDrawList::CompareSprites(SortNode * a,SortNode * b)
GLSprite * s2=&sprites[drawitems[b->itemindex].index];
float res = s2->scale-s1->scale;
if (fabs(res)>FLT_EPSILON) return res;
return gl_spritesortback? s1->index-s2->index : s2->index-s1->index;
if (res > FLT_EPSILON) return 1;
else if (res < FLT_EPSILON) return -1;
else return (i_compatflags & COMPATF_SPRITESORT)? s1->index-s2->index : s2->index-s1->index;
}
//==========================================================================

View file

@ -1126,6 +1126,7 @@ static menuitem_t CompatibilityItems[] = {
{ bitflag, "Monster movement is affected by effects", {&compatflags}, {0}, {0}, {0}, {(value_t *)COMPATF_MBFMONSTERMOVE} },
{ bitflag, "Crushed monsters can be resurrected", {&compatflags}, {0}, {0}, {0}, {(value_t *)COMPATF_CORPSEGIBS} },
{ bitflag, "Friendly monsters aren't blocked", {&compatflags}, {0}, {0}, {0}, {(value_t *)COMPATF_NOBLOCKFRIENDS} },
{ bitflag, "Invert sprite sorting", {&compatflags}, {0}, {0}, {0}, {(value_t *)COMPATF_SPRITESORT} },
{ discrete, "Interpolate monster movement", {&nomonsterinterpolation}, {2.0}, {0.0}, {0.0}, {NoYes} },
};

View file

@ -3358,7 +3358,7 @@ void AActor::Tick ()
bool AActor::UpdateWaterLevel (fixed_t oldz, bool dosplash)
{
BYTE lastwaterlevel = waterlevel;
fixed_t fh=FIXED_MIN;
fixed_t fh = FIXED_MIN;
bool reset=false;
waterlevel = 0;
@ -3393,18 +3393,21 @@ bool AActor::UpdateWaterLevel (fixed_t oldz, bool dosplash)
}
}
}
else if (z + height > hsec->ceilingplane.ZatPoint (x, y))
else if (!(hsec->MoreFlags & SECF_FAKEFLOORONLY) && (z + height > hsec->ceilingplane.ZatPoint (x, y)))
{
waterlevel = 3;
}
else
{
waterlevel=0;
waterlevel = 0;
}
}
// even non-swimmable deep water must be checked here to do the splashes correctly
// But the water level must be reset when this function returns
if (!(hsec->MoreFlags&SECF_UNDERWATERMASK)) reset=true;
if (!(hsec->MoreFlags&SECF_UNDERWATERMASK))
{
reset = true;
}
}
#ifdef _3DFLOORS
else
@ -3449,8 +3452,11 @@ bool AActor::UpdateWaterLevel (fixed_t oldz, bool dosplash)
{
P_HitWater(this, Sector, FIXED_MIN, FIXED_MIN, fh, true);
}
boomwaterlevel=waterlevel;
if (reset) waterlevel=lastwaterlevel;
boomwaterlevel = waterlevel;
if (reset)
{
waterlevel = lastwaterlevel;
}
return false; // we did the splash ourselves
}

View file

@ -23,6 +23,7 @@
#include <stdio.h>
#include <stdlib.h>
#include <algorithm>
#include "templates.h"
#include "doomdef.h"
@ -1883,13 +1884,9 @@ void R_DrawRemainingPlayerSprites()
// gain compared to the old function.
//
// Sort vissprites by depth, far to near
static int STACK_ARGS sv_compare (const void *arg1, const void *arg2)
static bool sv_compare(vissprite_t *a, vissprite_t *b)
{
int diff = (*(vissprite_t **)arg2)->idepth - (*(vissprite_t **)arg1)->idepth;
// If two sprites are the same distance, then the higher one gets precedence
if (diff == 0)
return (*(vissprite_t **)arg2)->gzt - (*(vissprite_t **)arg1)->gzt;
return diff;
return a->idepth > b->idepth;
}
#if 0
@ -2023,7 +2020,16 @@ void R_SplitVisSprites ()
}
#endif
void R_SortVisSprites (int (STACK_ARGS *compare)(const void *, const void *), size_t first)
#ifdef __GNUC__
static void swap(vissprite_t *&a, vissprite_t *&b)
{
vissprite_t *t = a;
a = b;
b = t;
}
#endif
void R_SortVisSprites (bool (*compare)(vissprite_t *, vissprite_t *), size_t first)
{
int i;
vissprite_t **spr;
@ -2041,12 +2047,25 @@ void R_SortVisSprites (int (STACK_ARGS *compare)(const void *, const void *), si
spritesortersize = MaxVisSprites;
}
for (i = 0, spr = firstvissprite; i < vsprcount; i++, spr++)
if (!(i_compatflags & COMPATF_SPRITESORT))
{
spritesorter[i] = *spr;
for (i = 0, spr = firstvissprite; i < vsprcount; i++, spr++)
{
spritesorter[i] = *spr;
}
}
else
{
// If the compatibility option is on sprites of equal distance need to
// be sorted in inverse order. This is most easily achieved by
// filling the sort array backwards before the sort.
for (i = 0, spr = firstvissprite + vsprcount-1; i < vsprcount; i++, spr--)
{
spritesorter[i] = *spr;
}
}
qsort (spritesorter, vsprcount, sizeof (vissprite_t *), compare);
std::stable_sort(&spritesorter[0], &spritesorter[vsprcount], compare);
}

View file

@ -3,5 +3,5 @@
// This file was automatically generated by the
// updaterevision tool. Do not edit by hand.
#define ZD_SVN_REVISION_STRING "2027"
#define ZD_SVN_REVISION_NUMBER 2027
#define ZD_SVN_REVISION_STRING "2031"
#define ZD_SVN_REVISION_NUMBER 2031

View file

@ -7,6 +7,7 @@ ACTOR Blood
Mass 5
+NOBLOCKMAP
+NOTELEPORT
+ALLOWPARTICLES
States
{
Spawn:
@ -30,6 +31,7 @@ ACTOR BloodSplatter
+DROPOFF
+NOTELEPORT
+CANNOTPUSH
+ALLOWPARTICLES
Mass 5
States
{
@ -53,6 +55,7 @@ ACTOR AxeBlood
+DROPOFF
+NOTELEPORT
+CANNOTPUSH
+ALLOWPARTICLES
Mass 5
States
{

View file

@ -91,3 +91,35 @@ F84AB4557464A383E93F37CD3A82AC48 // MM2 map03
corpsegibs
vileghosts
}
// invert the sorting order of overlapping sprites at the same spot
551D6B416EB3324790BC0F0F74B49600 // Strain map13
2F49C29691F8565F0B99B27FCF2627E6 // Astrostein 1 MAP01
55A741F9C2955C2B06F2387E45ED6C62 // MAP02
4E7286B735671A942C54FAC6CB52A8C3 // MAP03
825772094FF3569FC3722145F82F820A // MAP04
CB6CF6BE0EA4A6AB9830FBB7F9192B80 // MAP05
AB24CCF84C2FE1A543FE033589BD1FBC // MAP06
6BE0908B4DAFF53AA0A7493C04A608A4 // MAP07
305275E5E07755E17AAB064981279295 // MAP08
A8FBF3600088E79D02283C40D12B7F26 // MAP09
A8FBF3600088E79D02283C40D12B7F26 // MAP09
F0C95C76237DF617560577767EC21E1C // MAP10
2A2AF2CDAB7E7A66D28AFC3AA6243DCC // Astrostein 2 map01
0667DA831EB293D3387579565C11F0DD // map02
76DA72420EBE0A53D861373D7123DE33 // map03
5A4F8186580FFE41BCD80960B7F19CA8 // map04
E3A1EE2A0A2FB27496074057E3FA82F0 // map05
1CA60DE4062F41DC1A39396228913882 // map06
DABC3033A734DEF402A8FEF6C2FEDCC2 // map07
2E8211EA051EA8C3241859D1854386D6 // map08
EAD27C506AFC856BE07DDDDED20D7ED0 // map09
7DA47B044E2D5D17EAE2960BBFAEDE1A // Astrostein 3 map10
46E0F4529E8E396DEDC8DB83443078A7 // map13
2742D556921FBE753C16175F0C980091 // map14
AB1A6C1D3898D4259C0645306939374C // map15
0599F0D0CC1F41F52B7E8214D0348EEA // map17
CA267398C9B3A8F79349D3394F8B2106 // map20
{
spritesort
}