diff --git a/docs/rh-log.txt b/docs/rh-log.txt index c3c5da73..f778dc3e 100644 --- a/docs/rh-log.txt +++ b/docs/rh-log.txt @@ -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. diff --git a/src/compatibility.cpp b/src/compatibility.cpp index 059a8a4b..f4fbaa52 100644 --- a/src/compatibility.cpp +++ b/src/compatibility.cpp @@ -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 } }; diff --git a/src/d_main.cpp b/src/d_main.cpp index 0aa0b1ba..65687594 100644 --- a/src/d_main.cpp +++ b/src/d_main.cpp @@ -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); //========================================================================== // diff --git a/src/doomdef.h b/src/doomdef.h index 868479fa..485f15a5 100644 --- a/src/doomdef.h +++ b/src/doomdef.h @@ -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 diff --git a/src/g_mapinfo.cpp b/src/g_mapinfo.cpp index eeb22236..800fa895 100644 --- a/src/g_mapinfo.cpp +++ b/src/g_mapinfo.cpp @@ -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 }, diff --git a/src/gl/scene/gl_drawinfo.cpp b/src/gl/scene/gl_drawinfo.cpp index 31a37634..e077de75 100644 --- a/src/gl/scene/gl_drawinfo.cpp +++ b/src/gl/scene/gl_drawinfo.cpp @@ -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; } //========================================================================== diff --git a/src/m_options.cpp b/src/m_options.cpp index 00ba7299..fa597878 100644 --- a/src/m_options.cpp +++ b/src/m_options.cpp @@ -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} }, }; diff --git a/src/p_mobj.cpp b/src/p_mobj.cpp index b275539b..0d3ab7ac 100644 --- a/src/p_mobj.cpp +++ b/src/p_mobj.cpp @@ -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 } diff --git a/src/r_things.cpp b/src/r_things.cpp index 155c8435..a2f18de5 100644 --- a/src/r_things.cpp +++ b/src/r_things.cpp @@ -23,6 +23,7 @@ #include #include +#include #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); } diff --git a/src/svnrevision.h b/src/svnrevision.h index 6ef5f406..f30aa054 100644 --- a/src/svnrevision.h +++ b/src/svnrevision.h @@ -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 diff --git a/wadsrc/static/actors/shared/blood.txt b/wadsrc/static/actors/shared/blood.txt index 5a7ae201..1a294c6a 100644 --- a/wadsrc/static/actors/shared/blood.txt +++ b/wadsrc/static/actors/shared/blood.txt @@ -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 { diff --git a/wadsrc/static/compatibility.txt b/wadsrc/static/compatibility.txt index b2a168ce..a4fd9065 100644 --- a/wadsrc/static/compatibility.txt +++ b/wadsrc/static/compatibility.txt @@ -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 +}