From ee7eb3253a70933098cebc2054caea8c22eb02cb Mon Sep 17 00:00:00 2001 From: "alexey.lysiuk" Date: Tue, 15 Sep 2015 16:45:20 +0300 Subject: [PATCH 1/2] Added compatibility flag for point-on-line algorithm It's possible to use original but buggy implementations of P_PointOnLineSide() and P_PointOnDivlineSide() function See http://forum.zdoom.org/viewtopic.php?f=2&t=49544 --- src/compatibility.cpp | 1 + src/d_main.cpp | 4 +++- src/doomdef.h | 1 + src/g_mapinfo.cpp | 1 + src/p_local.h | 10 ++++++++-- wadsrc/static/menudef.txt | 1 + 6 files changed, 15 insertions(+), 3 deletions(-) diff --git a/src/compatibility.cpp b/src/compatibility.cpp index d60677f64..498fefb2a 100644 --- a/src/compatibility.cpp +++ b/src/compatibility.cpp @@ -145,6 +145,7 @@ static FCompatOption Options[] = { "badangles", COMPATF2_BADANGLES, SLOT_COMPAT2 }, { "floormove", COMPATF2_FLOORMOVE, SLOT_COMPAT2 }, { "soundcutoff", COMPATF2_SOUNDCUTOFF, SLOT_COMPAT2 }, + { "pointonline", COMPATF2_POINTONLINE, SLOT_COMPAT2 }, { NULL, 0, 0 } }; diff --git a/src/d_main.cpp b/src/d_main.cpp index 98be13e33..3b3cce1f4 100644 --- a/src/d_main.cpp +++ b/src/d_main.cpp @@ -561,7 +561,7 @@ CUSTOM_CVAR(Int, compatmode, 0, CVAR_ARCHIVE|CVAR_NOINITCALL) COMPATF_TRACE|COMPATF_MISSILECLIP|COMPATF_SOUNDTARGET|COMPATF_NO_PASSMOBJ|COMPATF_LIMITPAIN| COMPATF_DEHHEALTH|COMPATF_INVISIBILITY|COMPATF_CROSSDROPOFF|COMPATF_CORPSEGIBS|COMPATF_HITSCAN| COMPATF_WALLRUN|COMPATF_NOTOSSDROPS|COMPATF_LIGHT|COMPATF_MASKEDMIDTEX; - w = COMPATF2_BADANGLES|COMPATF2_FLOORMOVE; + w = COMPATF2_BADANGLES|COMPATF2_FLOORMOVE|COMPATF2_POINTONLINE; break; case 3: // Boom compat mode @@ -580,6 +580,7 @@ CUSTOM_CVAR(Int, compatmode, 0, CVAR_ARCHIVE|CVAR_NOINITCALL) case 6: // Boom with some added settings to reenable some 'broken' behavior v = COMPATF_TRACE|COMPATF_SOUNDTARGET|COMPATF_BOOMSCROLL|COMPATF_MISSILECLIP|COMPATF_NO_PASSMOBJ| COMPATF_INVISIBILITY|COMPATF_CORPSEGIBS|COMPATF_HITSCAN|COMPATF_WALLRUN|COMPATF_NOTOSSDROPS; + w = COMPATF2_POINTONLINE; break; } @@ -622,6 +623,7 @@ CVAR (Flag, compat_maskedmidtex, compatflags, COMPATF_MASKEDMIDTEX); CVAR (Flag, compat_badangles, compatflags2, COMPATF2_BADANGLES); CVAR (Flag, compat_floormove, compatflags2, COMPATF2_FLOORMOVE); CVAR (Flag, compat_soundcutoff, compatflags2, COMPATF2_SOUNDCUTOFF); +CVAR (Flag, compat_pointonline, compatflags2, COMPATF2_POINTONLINE); //========================================================================== // diff --git a/src/doomdef.h b/src/doomdef.h index c8aa66c17..802591386 100644 --- a/src/doomdef.h +++ b/src/doomdef.h @@ -340,6 +340,7 @@ enum COMPATF2_BADANGLES = 1 << 0, // It is impossible to face directly NSEW. COMPATF2_FLOORMOVE = 1 << 1, // Use the same floor motion behavior as Doom. COMPATF2_SOUNDCUTOFF = 1 << 2, // Cut off sounds when an actor vanishes instead of making it owner-less + COMPATF2_POINTONLINE = 1 << 3, // Use original but buggy P_PointOnLineSide() and P_PointOnDivlineSide() }; // 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 49493667e..ac938797d 100644 --- a/src/g_mapinfo.cpp +++ b/src/g_mapinfo.cpp @@ -1333,6 +1333,7 @@ MapFlagHandlers[] = { "compat_badangles", MITYPE_COMPATFLAG, 0, COMPATF2_BADANGLES }, { "compat_floormove", MITYPE_COMPATFLAG, 0, COMPATF2_FLOORMOVE }, { "compat_soundcutoff", MITYPE_COMPATFLAG, 0, COMPATF2_SOUNDCUTOFF }, + { "compat_pointonline", MITYPE_COMPATFLAG, 0, COMPATF2_POINTONLINE }, { "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/p_local.h b/src/p_local.h index a8aaaeb0d..0e06ad72b 100644 --- a/src/p_local.h +++ b/src/p_local.h @@ -240,7 +240,10 @@ fixed_t P_AproxDistance (fixed_t dx, fixed_t dy); inline int P_PointOnLineSide (fixed_t x, fixed_t y, const line_t *line) { - return DMulScale32 (y-line->v1->y, line->dx, line->v1->x-x, line->dy) > 0; + const SDWORD result = DMulScale32 (y-line->v1->y, line->dx, line->v1->x-x, line->dy); + return (compatflags2 & COMPATF2_POINTONLINE) + ? result >= 0 + : result > 0; } //========================================================================== @@ -254,7 +257,10 @@ inline int P_PointOnLineSide (fixed_t x, fixed_t y, const line_t *line) inline int P_PointOnDivlineSide (fixed_t x, fixed_t y, const divline_t *line) { - return DMulScale32 (y-line->y, line->dx, line->x-x, line->dy) > 0; + const SDWORD result = DMulScale32 (y-line->y, line->dx, line->x-x, line->dy); + return (compatflags2 & COMPATF2_POINTONLINE) + ? result >= 0 + : result > 0; } //========================================================================== diff --git a/wadsrc/static/menudef.txt b/wadsrc/static/menudef.txt index f15f91dff..b1ca44de7 100644 --- a/wadsrc/static/menudef.txt +++ b/wadsrc/static/menudef.txt @@ -1303,6 +1303,7 @@ OptionMenu "CompatibilityOptions" Option "Find shortest textures like Doom", "compat_SHORTTEX", "YesNo" Option "Use buggier stair building", "compat_stairs", "YesNo" Option "Use Doom's floor motion behavior", "compat_floormove", "YesNo" + Option "Use Doom's point-on-line algorithm", "compat_pointonline", "YesNo" StaticText " " StaticText "Physics Behavior",1 From 39b18a3447c3960c31043dd73ec5f2dbf5e2bcca Mon Sep 17 00:00:00 2001 From: "alexey.lysiuk" Date: Tue, 15 Sep 2015 18:21:05 +0300 Subject: [PATCH 2/2] Improved point-on-line compatibility feature P_PointOnLineSide() and P_PointOnDivlineSide() functions from the initial Doom source code release are used in compatibility mode --- src/p_local.h | 16 +++++---- src/p_maputl.cpp | 89 ++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 98 insertions(+), 7 deletions(-) diff --git a/src/p_local.h b/src/p_local.h index 0e06ad72b..cb404eb8c 100644 --- a/src/p_local.h +++ b/src/p_local.h @@ -240,10 +240,11 @@ fixed_t P_AproxDistance (fixed_t dx, fixed_t dy); inline int P_PointOnLineSide (fixed_t x, fixed_t y, const line_t *line) { - const SDWORD result = DMulScale32 (y-line->v1->y, line->dx, line->v1->x-x, line->dy); - return (compatflags2 & COMPATF2_POINTONLINE) - ? result >= 0 - : result > 0; + extern int P_VanillaPointOnLineSide(fixed_t x, fixed_t y, const line_t* line); + + return compatflags2 & COMPATF2_POINTONLINE + ? P_VanillaPointOnLineSide(x, y, line) + : DMulScale32 (y-line->v1->y, line->dx, line->v1->x-x, line->dy) > 0; } //========================================================================== @@ -257,10 +258,11 @@ inline int P_PointOnLineSide (fixed_t x, fixed_t y, const line_t *line) inline int P_PointOnDivlineSide (fixed_t x, fixed_t y, const divline_t *line) { - const SDWORD result = DMulScale32 (y-line->y, line->dx, line->x-x, line->dy); + extern int P_VanillaPointOnDivlineSide(fixed_t x, fixed_t y, const divline_t* line); + return (compatflags2 & COMPATF2_POINTONLINE) - ? result >= 0 - : result > 0; + ? P_VanillaPointOnDivlineSide(x, y, line) + : (DMulScale32 (y-line->y, line->dx, line->x-x, line->dy) > 0); } //========================================================================== diff --git a/src/p_maputl.cpp b/src/p_maputl.cpp index 3a4a4c6a0..0a39460e7 100644 --- a/src/p_maputl.cpp +++ b/src/p_maputl.cpp @@ -1523,3 +1523,92 @@ static AActor *RoughBlockCheck (AActor *mo, int index, void *param) } return NULL; } + +//=========================================================================== +// +// P_VanillaPointOnLineSide +// P_PointOnLineSide() from the initial Doom source code release +// +//=========================================================================== + +int P_VanillaPointOnLineSide(fixed_t x, fixed_t y, const line_t* line) +{ + fixed_t dx; + fixed_t dy; + fixed_t left; + fixed_t right; + + if (!line->dx) + { + if (x <= line->v1->x) + return line->dy > 0; + + return line->dy < 0; + } + if (!line->dy) + { + if (y <= line->v1->y) + return line->dx < 0; + + return line->dx > 0; + } + + dx = (x - line->v1->x); + dy = (y - line->v1->y); + + left = FixedMul ( line->dy>>FRACBITS , dx ); + right = FixedMul ( dy , line->dx>>FRACBITS ); + + if (right < left) + return 0; // front side + return 1; // back side +} + +//=========================================================================== +// +// P_VanillaPointOnDivlineSide +// P_PointOnDivlineSide() from the initial Doom source code release +// +//=========================================================================== + +int P_VanillaPointOnDivlineSide(fixed_t x, fixed_t y, const divline_t* line) +{ + fixed_t dx; + fixed_t dy; + fixed_t left; + fixed_t right; + + if (!line->dx) + { + if (x <= line->x) + return line->dy > 0; + + return line->dy < 0; + } + if (!line->dy) + { + if (y <= line->y) + return line->dx < 0; + + return line->dx > 0; + } + + dx = (x - line->x); + dy = (y - line->y); + + // try to quickly decide by looking at sign bits + if ( (line->dy ^ line->dx ^ dx ^ dy)&0x80000000 ) + { + if ( (line->dy ^ dx) & 0x80000000 ) + return 1; // (left is negative) + return 0; + } + + left = FixedMul ( line->dy>>8, dx>>8 ); + right = FixedMul ( dy>>8 , line->dx>>8 ); + + if (right < left) + return 0; // front side + return 1; // back side +} +