From fb3769a7307924a4e6d18466d8e4394697313200 Mon Sep 17 00:00:00 2001 From: MajorCooke Date: Wed, 2 Mar 2016 19:02:20 -0600 Subject: [PATCH 01/26] Added offsetforward to A_CheckLOF. - offsetforward is to A_SpawnItemEx's x offset property, just like offsetwidth is to y offset. --- src/thingdef/thingdef_codeptr.cpp | 14 ++++++++++---- wadsrc/static/actors/actor.txt | 2 +- 2 files changed, 11 insertions(+), 5 deletions(-) diff --git a/src/thingdef/thingdef_codeptr.cpp b/src/thingdef/thingdef_codeptr.cpp index 8f5d563ef..801efa503 100644 --- a/src/thingdef/thingdef_codeptr.cpp +++ b/src/thingdef/thingdef_codeptr.cpp @@ -3734,6 +3734,7 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_CheckLOF) PARAM_FIXED_OPT (offsetheight) { offsetheight = 0; } PARAM_FIXED_OPT (offsetwidth) { offsetwidth = 0; } PARAM_INT_OPT (ptr_target) { ptr_target = AAPTR_DEFAULT; } + PARAM_FIXED_OPT (offsetforward) { offsetforward = 0; } target = COPY_AAPTR(self, ptr_target == AAPTR_DEFAULT ? AAPTR_TARGET|AAPTR_PLAYER_GETTARGET|AAPTR_NULL : ptr_target); // no player-support by default @@ -3751,6 +3752,7 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_CheckLOF) } if (flags & CLOFF_MUL_WIDTH) { + offsetforward = FixedMul(self->radius, offsetforward); offsetwidth = FixedMul(self->radius, offsetwidth); } @@ -3797,9 +3799,13 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_CheckLOF) ang >>= ANGLETOFINESHIFT; + //pos = self->Vec2Offset( + //FixedMul(xofs, finecosine[ang]) + FixedMul(yofs, finesine[ang]), + //FixedMul(xofs, finesine[ang]) - FixedMul(yofs, finecosine[ang])); + fixedvec2 xy = self->Vec2Offset( - FixedMul(offsetwidth, finesine[ang]), - -FixedMul(offsetwidth, finecosine[ang])); + FixedMul(offsetforward, finecosine[ang]) + FixedMul(offsetwidth, finesine[ang]), + FixedMul(offsetforward, finesine[ang]) - FixedMul(offsetwidth, finecosine[ang])); pos.x = xy.x; pos.y = xy.y; @@ -3826,8 +3832,8 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_CheckLOF) angle_t ang = self->angle >> ANGLETOFINESHIFT; fixedvec2 xy = self->Vec2Offset( - FixedMul(offsetwidth, finesine[ang]), - -FixedMul(offsetwidth, finecosine[ang])); + FixedMul(offsetforward, finecosine[ang]) + FixedMul(offsetwidth, finesine[ang]), + FixedMul(offsetforward, finesine[ang]) - FixedMul(offsetwidth, finecosine[ang])); pos.x = xy.x; pos.y = xy.y; diff --git a/wadsrc/static/actors/actor.txt b/wadsrc/static/actors/actor.txt index ad7e9e930..58ff4827f 100644 --- a/wadsrc/static/actors/actor.txt +++ b/wadsrc/static/actors/actor.txt @@ -251,7 +251,7 @@ ACTOR Actor native //: Thinker action native A_LookEx(int flags = 0, float minseedist = 0, float maxseedist = 0, float maxheardist = 0, float fov = 0, state label = ""); action native A_ClearLastHeard(); action native A_ClearTarget(); - action native state A_CheckLOF(state jump, int flags = 0, float range = 0, float minrange = 0, float angle = 0, float pitch = 0, float offsetheight = 0, float offsetwidth = 0, int ptr_target = AAPTR_DEFAULT); + action native state A_CheckLOF(state jump, int flags = 0, float range = 0, float minrange = 0, float angle = 0, float pitch = 0, float offsetheight = 0, float offsetwidth = 0, int ptr_target = AAPTR_DEFAULT, float offsetforward = 0); action native state A_JumpIfTargetInLOS (state label, float/*angle*/ fov = 0, int flags = 0, float dist_max = 0, float dist_close = 0); action native state A_JumpIfInTargetLOS (state label, float/*angle*/ fov = 0, int flags = 0, float dist_max = 0, float dist_close = 0); action native bool A_SelectWeapon(class whichweapon); From 7f672039bfd73f2f0d3fce53d0cc51991c685fd3 Mon Sep 17 00:00:00 2001 From: MajorCooke Date: Wed, 2 Mar 2016 19:16:28 -0600 Subject: [PATCH 02/26] Cleanup. --- src/thingdef/thingdef_codeptr.cpp | 4 ---- 1 file changed, 4 deletions(-) diff --git a/src/thingdef/thingdef_codeptr.cpp b/src/thingdef/thingdef_codeptr.cpp index 801efa503..ad5dfb32e 100644 --- a/src/thingdef/thingdef_codeptr.cpp +++ b/src/thingdef/thingdef_codeptr.cpp @@ -3799,10 +3799,6 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_CheckLOF) ang >>= ANGLETOFINESHIFT; - //pos = self->Vec2Offset( - //FixedMul(xofs, finecosine[ang]) + FixedMul(yofs, finesine[ang]), - //FixedMul(xofs, finesine[ang]) - FixedMul(yofs, finecosine[ang])); - fixedvec2 xy = self->Vec2Offset( FixedMul(offsetforward, finecosine[ang]) + FixedMul(offsetwidth, finesine[ang]), FixedMul(offsetforward, finesine[ang]) - FixedMul(offsetwidth, finecosine[ang])); From 59ad6206de43e1b1a17f2a384a27dbd15f72006b Mon Sep 17 00:00:00 2001 From: MajorCooke Date: Wed, 2 Mar 2016 20:35:54 -0600 Subject: [PATCH 03/26] Added CBF_NOACTORS to A_CheckBlock. - Self explanatory, doesn't count actors as blocking them. --- src/thingdef/thingdef_codeptr.cpp | 9 ++++++--- wadsrc/static/actors/constants.txt | 1 + 2 files changed, 7 insertions(+), 3 deletions(-) diff --git a/src/thingdef/thingdef_codeptr.cpp b/src/thingdef/thingdef_codeptr.cpp index ad5dfb32e..5f518fab0 100644 --- a/src/thingdef/thingdef_codeptr.cpp +++ b/src/thingdef/thingdef_codeptr.cpp @@ -6683,12 +6683,13 @@ The SET pointer flags only affect the caller, not the pointer. ===========================================================================*/ enum CBF { - CBF_NOLINES = 1 << 0, //Don't check actors. + CBF_NOLINES = 1 << 0, //Don't check lines. CBF_SETTARGET = 1 << 1, //Sets the caller/pointer's target to the actor blocking it. Actors only. CBF_SETMASTER = 1 << 2, //^ but with master. CBF_SETTRACER = 1 << 3, //^ but with tracer. CBF_SETONPTR = 1 << 4, //Sets the pointer change on the actor doing the checking instead of self. CBF_DROPOFF = 1 << 5, //Check for dropoffs. + CBF_NOACTORS = 1 << 6, //Don't check actors. }; DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_CheckBlock) @@ -6731,8 +6732,10 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_CheckBlock) { ACTION_RETURN_STATE(NULL); } - //[MC] Easiest way to tell if an actor is blocking it, use the pointers. - if (mobj->BlockingMobj || (!(flags & CBF_NOLINES) && mobj->BlockingLine != NULL)) + //[MC] I don't know why I let myself be persuaded not to include a flag. + //If an actor is loaded with pointers, they don't really have any options to spare. + + if ((!(flags & CBF_NOACTORS) && (mobj->BlockingMobj)) || (!(flags & CBF_NOLINES) && mobj->BlockingLine != NULL)) { ACTION_RETURN_STATE(block); } diff --git a/wadsrc/static/actors/constants.txt b/wadsrc/static/actors/constants.txt index e5733e033..3060c2c2d 100644 --- a/wadsrc/static/actors/constants.txt +++ b/wadsrc/static/actors/constants.txt @@ -526,6 +526,7 @@ enum CBF_SETTRACER = 1 << 3, //^ but with tracer. CBF_SETONPTR = 1 << 4, //Sets the pointer change on the actor doing the checking instead of self. CBF_DROPOFF = 1 << 5, //Check for dropoffs. + CBF_NOACTORS = 1 << 6, //Don't check actors. }; enum From 81a5273b586f580b50a13d13195bc75f5abf2dc9 Mon Sep 17 00:00:00 2001 From: MaxED Date: Thu, 3 Mar 2016 11:27:37 +0300 Subject: [PATCH 04/26] Added "Miscellaneous Options" -> "Save/Load confirmation" option (defaults to true). When disabled, confirmation dialog won't be shown when performing quicksave/quickload. --- src/g_game.cpp | 1 + src/menu/messagebox.cpp | 26 ++++++++++++++++++++++---- wadsrc/static/language.enu | 1 + wadsrc/static/menudef.txt | 1 + 4 files changed, 25 insertions(+), 4 deletions(-) diff --git a/src/g_game.cpp b/src/g_game.cpp index 2532acd0f..627853acb 100644 --- a/src/g_game.cpp +++ b/src/g_game.cpp @@ -2064,6 +2064,7 @@ FString G_BuildSaveName (const char *prefix, int slot) CVAR (Int, autosavenum, 0, CVAR_NOSET|CVAR_ARCHIVE|CVAR_GLOBALCONFIG) static int nextautosave = -1; CVAR (Int, disableautosave, 0, CVAR_ARCHIVE|CVAR_GLOBALCONFIG) +CVAR (Bool, saveloadconfirmation, true, CVAR_ARCHIVE | CVAR_GLOBALCONFIG) // [mxd] CUSTOM_CVAR (Int, autosavecount, 4, CVAR_ARCHIVE|CVAR_GLOBALCONFIG) { if (self < 0) diff --git a/src/menu/messagebox.cpp b/src/menu/messagebox.cpp index 2d07ee51d..601c3e736 100644 --- a/src/menu/messagebox.cpp +++ b/src/menu/messagebox.cpp @@ -47,6 +47,7 @@ extern FSaveGameNode *quickSaveSlot; +EXTERN_CVAR (Bool, saveloadconfirmation) // [mxd] class DMessageBoxMenu : public DMenu { @@ -588,13 +589,22 @@ CCMD (quicksave) if (gamestate != GS_LEVEL) return; - S_Sound (CHAN_VOICE | CHAN_UI, "menu/activate", snd_menuvolume, ATTN_NONE); if (quickSaveSlot == NULL) { + S_Sound(CHAN_VOICE | CHAN_UI, "menu/activate", snd_menuvolume, ATTN_NONE); M_StartControlPanel(false); M_SetMenu(NAME_Savegamemenu); return; } + + // [mxd]. Just save the game, no questions asked. + if (!saveloadconfirmation) + { + G_SaveGame(quickSaveSlot->Filename.GetChars(), quickSaveSlot->Title); + return; + } + + S_Sound(CHAN_VOICE | CHAN_UI, "menu/activate", snd_menuvolume, ATTN_NONE); DMenu *newmenu = new DQuickSaveMenu(false); newmenu->mParentMenu = DMenu::CurrentMenu; M_ActivateMenu(newmenu); @@ -666,22 +676,30 @@ void DQuickLoadMenu::HandleResult(bool res) CCMD (quickload) { // F9 - M_StartControlPanel (true); - if (netgame) { + M_StartControlPanel(true); M_StartMessage (GStrings("QLOADNET"), 1); return; } if (quickSaveSlot == NULL) { - M_StartControlPanel(false); + M_StartControlPanel(true); // signal that whatever gets loaded should be the new quicksave quickSaveSlot = (FSaveGameNode *)1; M_SetMenu(NAME_Loadgamemenu); return; } + + // [mxd]. Just load the game, no questions asked. + if (!saveloadconfirmation) + { + G_LoadGame(quickSaveSlot->Filename.GetChars()); + return; + } + + M_StartControlPanel(true); DMenu *newmenu = new DQuickLoadMenu(false); newmenu->mParentMenu = DMenu::CurrentMenu; M_ActivateMenu(newmenu); diff --git a/wadsrc/static/language.enu b/wadsrc/static/language.enu index 95b7fad1a..e507a8d68 100644 --- a/wadsrc/static/language.enu +++ b/wadsrc/static/language.enu @@ -1853,6 +1853,7 @@ MISCMNU_QUERYIWAD = "Show IWAD selection dialog"; MISCMNU_ALLCHEATS = "Enable cheats from all games"; MISCMNU_ENABLEAUTOSAVES = "Enable autosaves"; MISCMNU_AUTOSAVECOUNT = "Number of autosaves"; +MISCMNU_SAVELOADCONFIRMATION = "Save/Load confirmation"; MISCMNU_DEHLOAD = "Load *.deh/*.bex lumps"; MISCMNU_CACHENODES = "Cache nodes"; MISCMNU_CACHETIME = "Time threshold for node caching"; diff --git a/wadsrc/static/menudef.txt b/wadsrc/static/menudef.txt index a36ecc764..a1f654b97 100644 --- a/wadsrc/static/menudef.txt +++ b/wadsrc/static/menudef.txt @@ -892,6 +892,7 @@ OptionMenu "MiscOptions" StaticText " " Option "$MISCMNU_ALLCHEATS", "allcheats", "OnOff" Option "$MISCMNU_ENABLEAUTOSAVES", "disableautosave", "Autosave" + Option "$MISCMNU_SAVELOADCONFIRMATION", "saveloadconfirmation", "OnOff" Slider "$MISCMNU_AUTOSAVECOUNT", "autosavecount", 1, 20, 1, 0 Option "$MISCMNU_DEHLOAD", "dehload", "dehopt" StaticText " " From d8c009bb41142e5731305c857a5a880db94649cf Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Thu, 3 Mar 2016 10:23:04 +0100 Subject: [PATCH 05/26] - fixed: A_Blast read the blast radius as an int, but used it as fixed_t. Also changed the definition of this parameter to float. --- src/g_hexen/a_blastradius.cpp | 2 +- wadsrc/static/actors/actor.txt | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/g_hexen/a_blastradius.cpp b/src/g_hexen/a_blastradius.cpp index 7c148cd89..f7fbee36a 100644 --- a/src/g_hexen/a_blastradius.cpp +++ b/src/g_hexen/a_blastradius.cpp @@ -100,7 +100,7 @@ DEFINE_ACTION_FUNCTION_PARAMS (AActor, A_Blast) PARAM_ACTION_PROLOGUE; PARAM_INT_OPT (blastflags) { blastflags = 0; } PARAM_INT_OPT (strength) { strength = 255; } - PARAM_INT_OPT (radius) { radius = 255; } + PARAM_FIXED_OPT (radius) { radius = 255*FRACUNIT; } PARAM_FIXED_OPT (speed) { speed = 20; } PARAM_CLASS_OPT (blasteffect, AActor) { blasteffect = PClass::FindActor("BlastEffect"); } PARAM_SOUND_OPT (blastsound) { blastsound = "BlastRadius"; } diff --git a/wadsrc/static/actors/actor.txt b/wadsrc/static/actors/actor.txt index 58ff4827f..d8f20dfe5 100644 --- a/wadsrc/static/actors/actor.txt +++ b/wadsrc/static/actors/actor.txt @@ -240,7 +240,7 @@ ACTOR Actor native //: Thinker action native A_CustomMeleeAttack(int damage = 0, sound meleesound = "", sound misssound = "", name damagetype = "none", bool bleed = true); action native A_CustomComboAttack(class missiletype, float spawnheight, int damage, sound meleesound = "", name damagetype = "none", bool bleed = true); action native A_Burst(class chunktype); - action native A_Blast(int flags = 0, int strength = 255, int radius = 255, float speed = 20, class blasteffect = "BlastEffect", sound blastsound = "BlastRadius"); + action native A_Blast(int flags = 0, int strength = 255, float radius = 255, float speed = 20, class blasteffect = "BlastEffect", sound blastsound = "BlastRadius"); action native A_RadiusThrust(int force = 128, int distance = -1, int flags = RTF_AFFECTSOURCE, int fullthrustdistance = 0); action native A_Explode(int damage = -1, int distance = -1, int flags = XF_HURTSOURCE, bool alert = false, int fulldamagedistance = 0, int nails = 0, int naildamage = 10, class pufftype = "BulletPuff"); action native A_Stop(); From 4d2b9fbe1b4fc848aaf62ab07a4cb29dd512fac0 Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Thu, 3 Mar 2016 10:47:11 +0100 Subject: [PATCH 06/26] - don't freeze if the menu item search can't find anything selectable. --- src/menu/listmenu.cpp | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/menu/listmenu.cpp b/src/menu/listmenu.cpp index 45b46b623..bcb61d6eb 100644 --- a/src/menu/listmenu.cpp +++ b/src/menu/listmenu.cpp @@ -156,7 +156,9 @@ bool DListMenu::Responder (event_t *ev) bool DListMenu::MenuEvent (int mkey, bool fromcontroller) { + int oldSelect = mDesc->mSelectedItem; int startedAt = mDesc->mSelectedItem; + if (startedAt < 0) startedAt = 0; switch (mkey) { @@ -166,6 +168,7 @@ bool DListMenu::MenuEvent (int mkey, bool fromcontroller) if (--mDesc->mSelectedItem < 0) mDesc->mSelectedItem = mDesc->mItems.Size()-1; } while (!mDesc->mItems[mDesc->mSelectedItem]->Selectable() && mDesc->mSelectedItem != startedAt); + if (mDesc->mSelectedItem == startedAt) mDesc->mSelectedItem = oldSelect; S_Sound (CHAN_VOICE | CHAN_UI, "menu/cursor", snd_menuvolume, ATTN_NONE); return true; @@ -175,6 +178,7 @@ bool DListMenu::MenuEvent (int mkey, bool fromcontroller) if (++mDesc->mSelectedItem >= (int)mDesc->mItems.Size()) mDesc->mSelectedItem = 0; } while (!mDesc->mItems[mDesc->mSelectedItem]->Selectable() && mDesc->mSelectedItem != startedAt); + if (mDesc->mSelectedItem == startedAt) mDesc->mSelectedItem = oldSelect; S_Sound (CHAN_VOICE | CHAN_UI, "menu/cursor", snd_menuvolume, ATTN_NONE); return true; From 74c326e9b236754f705b05ece38b4abe3b437633 Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Thu, 3 Mar 2016 10:52:56 +0100 Subject: [PATCH 07/26] - fixed: An option value with an invalid value type would eat all key events when being selected. --- src/menu/optionmenuitems.h | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/menu/optionmenuitems.h b/src/menu/optionmenuitems.h index 89334dc90..0f315d5f6 100644 --- a/src/menu/optionmenuitems.h +++ b/src/menu/optionmenuitems.h @@ -230,6 +230,10 @@ public: SetSelection(Selection); S_Sound (CHAN_VOICE | CHAN_UI, "menu/change", snd_menuvolume, ATTN_NONE); } + else + { + return FOptionMenuItem::MenuEvent(mkey, fromcontroller); + } return true; } From ede07f93b245c18bfab4aae31748c2b95bb46a23 Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Thu, 3 Mar 2016 11:11:25 +0100 Subject: [PATCH 08/26] - fixed: Failure to open bots.cfg would throw an exception that prevented the level from starting. Catch it in FCajunMaster::LoadBots instead and handle it non-disruptively. --- src/b_game.cpp | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/src/b_game.cpp b/src/b_game.cpp index be827eaca..9681aa7a8 100644 --- a/src/b_game.cpp +++ b/src/b_game.cpp @@ -60,6 +60,7 @@ Everything that is changed is marked (maybe commented) with "Added by MC" #include "d_net.h" #include "d_netinf.h" #include "d_player.h" +#include "doomerrors.h" static FRandom pr_botspawn ("BotSpawn"); @@ -496,7 +497,15 @@ bool FCajunMaster::LoadBots () DPrintf ("No " BOTFILENAME ", so no bots\n"); return false; } - sc.OpenFile(tmp); + try + { + sc.OpenFile(tmp); + } + catch (CRecoverableError &err) + { + Printf("%s. So no bots\n", err.GetMessage()); + return false; + } while (sc.GetString ()) { From 14a0567343a3160944963471eb45cff78e4dbb46 Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Thu, 3 Mar 2016 11:58:04 +0100 Subject: [PATCH 09/26] - optimized the portal translation functions by precalculating the rotation angle, sine and cosine. --- src/p_map.cpp | 31 +++++++++----------- src/p_maputl.cpp | 11 ++++--- src/portal.cpp | 76 +++++++++++++++++++++++------------------------- src/portal.h | 11 ++++--- src/r_main.cpp | 6 ++-- 5 files changed, 66 insertions(+), 69 deletions(-) diff --git a/src/p_map.cpp b/src/p_map.cpp index 0fe73229c..0151d4803 100644 --- a/src/p_map.cpp +++ b/src/p_map.cpp @@ -1041,8 +1041,8 @@ static bool PIT_CheckPortal(FMultiBlockLinesIterator &mit, FMultiBlockLinesItera line_t *lp = cres.line->getPortalDestination(); fixed_t zofs = 0; - P_TranslatePortalXY(cres.line, lp, cres.position.x, cres.position.y); - P_TranslatePortalZ(cres.line, lp, zofs); + P_TranslatePortalXY(cres.line, cres.position.x, cres.position.y); + P_TranslatePortalZ(cres.line, zofs); // fudge a bit with the portal line so that this gets included in the checks that normally only get run on two-sided lines sector_t *sec = lp->backsector; @@ -2325,14 +2325,13 @@ bool P_TryMove(AActor *thing, fixed_t x, fixed_t y, } else if (!portalcrossed) { - line_t *out = port->mDestination; fixedvec3 pos = { tm.x, tm.y, thing->Z() }; fixedvec3 oldthingpos = thing->Pos(); fixedvec2 thingpos = oldthingpos; - P_TranslatePortalXY(ld, out, pos.x, pos.y); - P_TranslatePortalXY(ld, out, thingpos.x, thingpos.y); - P_TranslatePortalZ(ld, out, pos.z); + P_TranslatePortalXY(ld, pos.x, pos.y); + P_TranslatePortalXY(ld, thingpos.x, thingpos.y); + P_TranslatePortalZ(ld, pos.z); thing->SetXYZ(thingpos.x, thingpos.y, pos.z); if (!P_CheckPosition(thing, pos.x, pos.y, true)) // check if some actor blocks us on the other side. (No line checks, because of the mess that'd create.) { @@ -2342,8 +2341,8 @@ bool P_TryMove(AActor *thing, fixed_t x, fixed_t y, } thing->UnlinkFromWorld(); thing->SetXYZ(pos); - P_TranslatePortalVXVY(ld, out, thing->velx, thing->vely); - P_TranslatePortalAngle(ld, out, thing->angle); + P_TranslatePortalVXVY(ld, thing->velx, thing->vely); + P_TranslatePortalAngle(ld, thing->angle); thing->LinkToWorld(); P_FindFloorCeiling(thing); thing->ClearInterpolation(); @@ -2355,7 +2354,6 @@ bool P_TryMove(AActor *thing, fixed_t x, fixed_t y, { divline_t dl1 = { besthit.oldrefpos.x,besthit. oldrefpos.y, besthit.refpos.x - besthit.oldrefpos.x, besthit.refpos.y - besthit.oldrefpos.y }; fixedvec3a hit = { dl1.x + FixedMul(dl1.dx, bestfrac), dl1.y + FixedMul(dl1.dy, bestfrac), 0, 0 }; - line_t *out = port->mDestination; R_AddInterpolationPoint(hit); if (port->mType == PORTT_LINKED) @@ -2365,10 +2363,10 @@ bool P_TryMove(AActor *thing, fixed_t x, fixed_t y, } else { - P_TranslatePortalXY(ld, out, hit.x, hit.y); - P_TranslatePortalZ(ld, out, hit.z); + P_TranslatePortalXY(ld, hit.x, hit.y); + P_TranslatePortalZ(ld, hit.z); players[consoleplayer].viewz += hit.z; // needs to be done here because otherwise the renderer will not catch the change. - P_TranslatePortalAngle(ld, out, hit.angle); + P_TranslatePortalAngle(ld, hit.angle); } R_AddInterpolationPoint(hit); } @@ -3700,7 +3698,6 @@ struct aim_t aim_t newtrace = Clone(); FLinePortal *port = li->getPortal(); - line_t *dest = port->mDestination; newtrace.toppitch = toppitch; newtrace.bottompitch = bottompitch; @@ -3708,9 +3705,9 @@ struct aim_t newtrace.unlinked = (port->mType != PORTT_LINKED); newtrace.startpos = startpos; newtrace.aimtrace = aimtrace; - P_TranslatePortalXY(li, dest, newtrace.startpos.x, newtrace.startpos.y); - P_TranslatePortalZ(li, dest, newtrace.startpos.z); - P_TranslatePortalVXVY(li, dest, newtrace.aimtrace.x, newtrace.aimtrace.y); + P_TranslatePortalXY(li, newtrace.startpos.x, newtrace.startpos.y); + P_TranslatePortalZ(li, newtrace.startpos.z); + P_TranslatePortalVXVY(li, newtrace.aimtrace.x, newtrace.aimtrace.y); newtrace.startfrac = frac + FixedDiv(FRACUNIT, attackrange); // this is to skip the transition line to the portal which would produce a bogus opening @@ -3718,7 +3715,7 @@ struct aim_t fixed_t y = newtrace.startpos.y + FixedMul(newtrace.aimtrace.y, newtrace.startfrac); newtrace.lastsector = P_PointInSector(x, y); - P_TranslatePortalZ(li, dest, limitz); + P_TranslatePortalZ(li, limitz); Printf("-----Entering line portal from sector %d to sector %d\n", lastsector->sectornum, newtrace.lastsector->sectornum); newtrace.AimTraverse(); SetResult(linetarget, newtrace.linetarget); diff --git a/src/p_maputl.cpp b/src/p_maputl.cpp index 2a8c0efda..c6453285e 100644 --- a/src/p_maputl.cpp +++ b/src/p_maputl.cpp @@ -1660,14 +1660,13 @@ int FPathTraverse::PortalRelocate(intercept_t *in, int flags, fixedvec3 *optpos) fixed_t hity = trace.y; fixed_t endx = trace.x + trace.dx; fixed_t endy = trace.y + trace.dy; - line_t *out = in->d.line->getPortalDestination(); - - P_TranslatePortalXY(in->d.line, out, hitx, hity); - P_TranslatePortalXY(in->d.line, out, endx, endy); + + P_TranslatePortalXY(in->d.line, hitx, hity); + P_TranslatePortalXY(in->d.line, endx, endy); if (optpos != NULL) { - P_TranslatePortalXY(in->d.line, out, optpos->x, optpos->y); - P_TranslatePortalZ(in->d.line, out, optpos->z); + P_TranslatePortalXY(in->d.line, optpos->x, optpos->y); + P_TranslatePortalZ(in->d.line, optpos->z); } intercepts.Resize(intercept_index); init(hitx, hity, endx, endy, flags, in->frac); diff --git a/src/portal.cpp b/src/portal.cpp index 01afb0bc4..f9c3cec2a 100644 --- a/src/portal.cpp +++ b/src/portal.cpp @@ -265,9 +265,17 @@ void P_SpawnLinePortal(line_t* line) if (port->mDestination != NULL) { port->mDefFlags = port->mType == PORTT_VISUAL ? PORTF_VISIBLE : port->mType == PORTT_TELEPORT ? PORTF_TYPETELEPORT : PORTF_TYPEINTERACTIVE; - - } + + // Get the angle between the two linedefs, for rotating + // orientation and velocity. Rotate 180 degrees, and flip + // the position across the exit linedef, if reversed. + + double angle = atan2(dst->dy, dst->dx) - atan2(line->dy, line->dx) + M_PI; + port->mSinRot = FLOAT2FIXED(sin(angle)); + port->mCosRot = FLOAT2FIXED(cos(angle)); + port->mAngleDiff = RAD2ANGLE(angle); + } else if (line->args[2] == PORTT_LINKEDEE && line->args[0] == 0) { @@ -546,30 +554,22 @@ bool P_ClipLineToPortal(line_t* line, line_t* portal, fixed_t viewx, fixed_t vie // //============================================================================ -void P_TranslatePortalXY(line_t* src, line_t* dst, fixed_t& x, fixed_t& y) +void P_TranslatePortalXY(line_t* src, fixed_t& x, fixed_t& y) { - if (!src || !dst) - return; + if (!src) return; + FLinePortal *port = src->getPortal(); + if (!port) return; - fixed_t nposx, nposy; // offsets from line - - // Get the angle between the two linedefs, for rotating - // orientation and velocity. Rotate 180 degrees, and flip - // the position across the exit linedef, if reversed. - - double angle = atan2(dst->dy, dst->dx) - atan2(src->dy, src->dx) + M_PI; - fixed_t s = FLOAT2FIXED(sin(angle)); - fixed_t c = FLOAT2FIXED(cos(angle)); - - nposx = x - src->v1->x; - nposy = y - src->v1->y; + // offsets from line + fixed_t nposx = x - src->v1->x; + fixed_t nposy = y - src->v1->y; // Rotate position along normal to match exit linedef - fixed_t tx = FixedMul(nposx, c) - FixedMul(nposy, s); - fixed_t ty = FixedMul(nposy, c) + FixedMul(nposx, s); + fixed_t tx = FixedMul(nposx, port->mCosRot) - FixedMul(nposy, port->mSinRot); + fixed_t ty = FixedMul(nposy, port->mCosRot) + FixedMul(nposx, port->mSinRot); - tx += dst->v2->x; - ty += dst->v2->y; + tx += port->mDestination->v2->x; + ty += port->mDestination->v2->y; x = tx; y = ty; @@ -581,16 +581,16 @@ void P_TranslatePortalXY(line_t* src, line_t* dst, fixed_t& x, fixed_t& y) // //============================================================================ -void P_TranslatePortalVXVY(line_t* src, line_t* dst, fixed_t& vx, fixed_t& vy) +void P_TranslatePortalVXVY(line_t* src, fixed_t& vx, fixed_t& vy) { - double angle = atan2(dst->dy, dst->dx) - atan2(src->dy, src->dx) + M_PI; - fixed_t s = FLOAT2FIXED(sin(angle)); - fixed_t c = FLOAT2FIXED(cos(angle)); + if (!src) return; + FLinePortal *port = src->getPortal(); + if (!port) return; fixed_t orig_velx = vx; fixed_t orig_vely = vy; - vx = FixedMul(orig_velx, c) - FixedMul(orig_vely, s); - vy = FixedMul(orig_vely, c) + FixedMul(orig_velx, s); + vx = FixedMul(orig_velx, port->mCosRot) - FixedMul(orig_vely, port->mSinRot); + vy = FixedMul(orig_vely, port->mCosRot) + FixedMul(orig_velx, port->mSinRot); } //============================================================================ @@ -599,15 +599,12 @@ void P_TranslatePortalVXVY(line_t* src, line_t* dst, fixed_t& vx, fixed_t& vy) // //============================================================================ -void P_TranslatePortalAngle(line_t* src, line_t* dst, angle_t& angle) +void P_TranslatePortalAngle(line_t* src, angle_t& angle) { - if (!src || !dst) - return; - - // Get the angle between the two linedefs, for rotating - // orientation and velocity. Rotate 180 degrees, and flip - // the position across the exit linedef, if reversed. - angle += RAD2ANGLE(atan2(dst->dy, dst->dx) - atan2(src->dy, src->dx)) + ANGLE_180; + if (!src) return; + FLinePortal *port = src->getPortal(); + if (!port) return; + angle += port->mAngleDiff; } //============================================================================ @@ -616,12 +613,14 @@ void P_TranslatePortalAngle(line_t* src, line_t* dst, angle_t& angle) // //============================================================================ -void P_TranslatePortalZ(line_t* src, line_t* dst, fixed_t& z) +void P_TranslatePortalZ(line_t* src, fixed_t& z) { // args[2] = 0 - no adjustment // args[2] = 1 - adjust by floor difference // args[2] = 2 - adjust by ceiling difference + // This cannot be precalculated because heights may change. + line_t *dst = src->getPortalDestination(); switch (src->getPortalAlignment()) { case PORG_FLOOR: @@ -704,7 +703,6 @@ fixedvec2 P_GetOffsetPosition(fixed_t x, fixed_t y, fixed_t dx, fixed_t dy) // hit a portal line. line_t *line = in->d.line; FLinePortal *port = line->getPortal(); - line_t* out = port->mDestination; // Teleport portals are intentionally ignored since skipping this stuff is their entire reason for existence. if (port->mFlags & PORTF_INTERACTIVE) @@ -723,8 +721,8 @@ fixedvec2 P_GetOffsetPosition(fixed_t x, fixed_t y, fixed_t dx, fixed_t dy) { // interactive ones are more complex because the vector may be rotated. // Note: There is no z-translation here, there's just too much code in the engine that wouldn't be able to handle interactive portals with a height difference. - P_TranslatePortalXY(line, out, hit.x, hit.y); - P_TranslatePortalXY(line, out, dest.x, dest.y); + P_TranslatePortalXY(line, hit.x, hit.y); + P_TranslatePortalXY(line, dest.x, dest.y); } // update the fields, end this trace and restart from the new position dx = dest.x - hit.x; diff --git a/src/portal.h b/src/portal.h index 127a9ec3b..b8a5d3ba3 100644 --- a/src/portal.h +++ b/src/portal.h @@ -173,6 +173,9 @@ struct FLinePortal BYTE mFlags; BYTE mDefFlags; BYTE mAlign; + angle_t mAngleDiff; + fixed_t mSinRot; + fixed_t mCosRot; }; extern TArray linePortals; @@ -192,10 +195,10 @@ inline int P_NumPortalGroups() /* code ported from prototype */ bool P_ClipLineToPortal(line_t* line, line_t* portal, fixed_t viewx, fixed_t viewy, bool partial = true, bool samebehind = true); -void P_TranslatePortalXY(line_t* src, line_t* dst, fixed_t& x, fixed_t& y); -void P_TranslatePortalVXVY(line_t* src, line_t* dst, fixed_t& vx, fixed_t& vy); -void P_TranslatePortalAngle(line_t* src, line_t* dst, angle_t& angle); -void P_TranslatePortalZ(line_t* src, line_t* dst, fixed_t& z); +void P_TranslatePortalXY(line_t* src, fixed_t& x, fixed_t& y); +void P_TranslatePortalVXVY(line_t* src, fixed_t& vx, fixed_t& vy); +void P_TranslatePortalAngle(line_t* src, angle_t& angle); +void P_TranslatePortalZ(line_t* src, fixed_t& z); void P_NormalizeVXVY(fixed_t& vx, fixed_t& vy); fixed_t P_PointLineDistance(line_t* line, fixed_t x, fixed_t y); fixedvec2 P_GetOffsetPosition(fixed_t x, fixed_t y, fixed_t dx, fixed_t dy); diff --git a/src/r_main.cpp b/src/r_main.cpp index 12dd3916b..c445787a0 100644 --- a/src/r_main.cpp +++ b/src/r_main.cpp @@ -732,9 +732,9 @@ void R_EnterPortal (PortalDrawseg* pds, int depth) } else { - P_TranslatePortalXY(pds->src, pds->dst, viewx, viewy); - P_TranslatePortalZ(pds->src, pds->dst, viewz); - P_TranslatePortalAngle(pds->src, pds->dst, viewangle); + P_TranslatePortalXY(pds->src, viewx, viewy); + P_TranslatePortalZ(pds->src, viewz); + P_TranslatePortalAngle(pds->src, viewangle); } viewsin = finesine[viewangle>>ANGLETOFINESHIFT]; From ec258c9588a6bbeabf8768188dbb8f8260ff069d Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Thu, 3 Mar 2016 13:07:11 +0100 Subject: [PATCH 10/26] - redid P_ClipLineToPortal with revised visibility rules: * any line completely parallel to the portal is rejected * any line with one end on the same straight line than the portal is solely decided by the other vertex. * any line with both ends behind the portal cannot be visible inside, so there's no need to check for an intersection with the view range. * due to the above P_IntersectLines could be removed as it was redundant. * for any line that does intersect with the portal straight, do a reverse check: If both ends of the portal lie on the other side of the line than the viewpoint, the line is between viewpoint and portal and needs to be rejected. This fixes nearly all the phantom wall glitches in the demo map. --- src/portal.cpp | 98 +++++++++++++++++++------------------------------- 1 file changed, 37 insertions(+), 61 deletions(-) diff --git a/src/portal.cpp b/src/portal.cpp index f9c3cec2a..49a1592a3 100644 --- a/src/portal.cpp +++ b/src/portal.cpp @@ -468,47 +468,6 @@ void P_ClearPortals() } -//============================================================================ -// -// Calculate the intersection between two lines. -// [ZZ] lots of floats here to avoid overflowing a lot -// -//============================================================================ - -bool P_IntersectLines(fixed_t o1x, fixed_t o1y, fixed_t p1x, fixed_t p1y, - fixed_t o2x, fixed_t o2y, fixed_t p2x, fixed_t p2y, - fixed_t& rx, fixed_t& ry) -{ - double xx = FIXED2DBL(o2x) - FIXED2DBL(o1x); - double xy = FIXED2DBL(o2y) - FIXED2DBL(o1y); - - double d1x = FIXED2DBL(p1x) - FIXED2DBL(o1x); - double d1y = FIXED2DBL(p1y) - FIXED2DBL(o1y); - - if (d1x > d1y) - { - d1y = d1y / d1x * 32767.0f; - d1x = 32767.0; - } - else - { - d1x = d1x / d1y * 32767.0f; - d1y = 32767.0; - } - - double d2x = FIXED2DBL(p2x) - FIXED2DBL(o2x); - double d2y = FIXED2DBL(p2y) - FIXED2DBL(o2y); - - double cross = d1x*d2y - d1y*d2x; - if (fabs(cross) < 1e-8) - return false; - - double t1 = (xx * d2y - xy * d2x)/cross; - rx = o1x + FLOAT2FIXED(d1x * t1); - ry = o1y + FLOAT2FIXED(d1y * t1); - return true; -} - inline int P_PointOnLineSideExplicit (fixed_t x, fixed_t y, fixed_t x1, fixed_t y1, fixed_t x2, fixed_t y2) { return DMulScale32 (y-y1, x2-x1, x1-x, y2-y1) > 0; @@ -517,35 +476,52 @@ inline int P_PointOnLineSideExplicit (fixed_t x, fixed_t y, fixed_t x1, fixed_t //============================================================================ // // check if this line is between portal and the viewer. clip away if it is. -// (this may need some fixing) // //============================================================================ +inline int P_GetLineSide(fixed_t x, fixed_t y, const line_t *line) +{ + return DMulScale32(y - line->v1->y, line->dx, line->v1->x - x, line->dy); +} + bool P_ClipLineToPortal(line_t* line, line_t* portal, fixed_t viewx, fixed_t viewy, bool partial, bool samebehind) { - bool behind1 = !!P_PointOnLineSidePrecise(line->v1->x, line->v1->y, portal); - bool behind2 = !!P_PointOnLineSidePrecise(line->v2->x, line->v2->y, portal); + int behind1 = P_GetLineSide(line->v1->x, line->v1->y, portal); + int behind2 = P_GetLineSide(line->v2->x, line->v2->y, portal); - // [ZZ] update 16.12.2014: if a vertex equals to one of portal's vertices, it's treated as being behind the portal. - // this is required in order to clip away diagonal lines around the portal (example: 1-sided triangle shape with a mirror on it's side) - if ((line->v1->x == portal->v1->x && line->v1->y == portal->v1->y) || - (line->v1->x == portal->v2->x && line->v1->y == portal->v2->y)) - behind1 = samebehind; - if ((line->v2->x == portal->v1->x && line->v2->y == portal->v1->y) || - (line->v2->x == portal->v2->x && line->v2->y == portal->v2->y)) - behind2 = samebehind; - - if (behind1 && behind2) + if (behind1 == 0 && behind2 == 0) { - // line is behind the portal plane. now check if it's in front of two view plane borders (i.e. if it will get in the way of rendering) - fixed_t dummyx, dummyy; - bool infront1 = P_IntersectLines(line->v1->x, line->v1->y, line->v2->x, line->v2->y, viewx, viewy, portal->v1->x, portal->v1->y, dummyx, dummyy); - bool infront2 = P_IntersectLines(line->v1->x, line->v1->y, line->v2->x, line->v2->y, viewx, viewy, portal->v2->x, portal->v2->y, dummyx, dummyy); - if (infront1 && infront2) - return true; + // The line is parallel to the portal and cannot possibly be visible. + return true; } + // If one point lies on the same straight line than the portal, the other vertex will determine sidedness alone. + else if (behind2 == 0) behind2 = behind1; + else if (behind1 == 0) behind1 = behind2; - return false; + if (behind1 > 0 && behind2 > 0) + { + // The line is behind the portal, i.e. between viewer and portal line, and must be rejected + return true; + } + else if (behind1 < 0 && behind2 < 0) + { + // The line is in front of the portal, i.e. the portal is between viewer and line. This line must not be rejected + return false; + } + else + { + // The line intersects with the portal straight, so we need to do another check to see how both ends of the portal lie in relation to the viewer. + int viewside = P_PointOnLineSidePrecise(viewx, viewy, line); + int p1side = P_GetLineSide(portal->v1->x, portal->v1->y, line); + int p2side = P_GetLineSide(portal->v2->x, portal->v2->y, line); + // Do the same handling of points on the portal straight than above. + if (p1side == 0) p1side = p2side; + else if (p2side == 0) p2side = p1side; + p1side = p1side > 0; + p2side = p2side > 0; + // If the portal is on the other side of the line than the viewpoint, there is no possibility to see this line inside the portal. + return (p1side == p2side && viewside != p1side); + } } //============================================================================ From b8abafb486ac512f26efe68ad64119c2383e3f3b Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Thu, 3 Mar 2016 13:31:21 +0100 Subject: [PATCH 11/26] - disabled all the debug messages in P_AimLineAttack but left them in with a CVAR check so that the debug output can be reenabled, should some problem require it in the future. --- src/p_map.cpp | 34 +++++++++++++++++++++++----------- 1 file changed, 23 insertions(+), 11 deletions(-) diff --git a/src/p_map.cpp b/src/p_map.cpp index 0151d4803..1970e1a4b 100644 --- a/src/p_map.cpp +++ b/src/p_map.cpp @@ -3436,6 +3436,8 @@ bool P_BounceActor(AActor *mo, AActor *BlockingMobj, bool ontop) // //============================================================================ +CVAR(Bool, aimdebug, false, 0) + struct AimTarget : public FTranslatedLineTarget { angle_t pitch; @@ -3678,12 +3680,14 @@ struct aim_t newtrace.startfrac = frac + FixedDiv(FRACUNIT, attackrange); // this is to skip the transition line to the portal which would produce a bogus opening newtrace.lastsector = P_PointInSector(newtrace.startpos.x + FixedMul(aimtrace.x, newtrace.startfrac) , newtrace.startpos.y + FixedMul(aimtrace.y, newtrace.startfrac)); newtrace.limitz = portal->threshold; - Printf("-----Entering %s portal from sector %d to sector %d\n", position ? "ceiling" : "floor", lastsector->sectornum, newtrace.lastsector->sectornum); + if (aimdebug) + Printf("-----Entering %s portal from sector %d to sector %d\n", position ? "ceiling" : "floor", lastsector->sectornum, newtrace.lastsector->sectornum); newtrace.AimTraverse(); SetResult(linetarget, newtrace.linetarget); SetResult(thing_friend, newtrace.thing_friend); SetResult(thing_other, newtrace.thing_other); - Printf("-----Exiting %s portal\n", position ? "ceiling" : "floor"); + if (aimdebug) + Printf("-----Exiting %s portal\n", position ? "ceiling" : "floor"); } //============================================================================ @@ -3716,7 +3720,8 @@ struct aim_t newtrace.lastsector = P_PointInSector(x, y); P_TranslatePortalZ(li, limitz); - Printf("-----Entering line portal from sector %d to sector %d\n", lastsector->sectornum, newtrace.lastsector->sectornum); + if (aimdebug) + Printf("-----Entering line portal from sector %d to sector %d\n", lastsector->sectornum, newtrace.lastsector->sectornum); newtrace.AimTraverse(); SetResult(linetarget, newtrace.linetarget); SetResult(thing_friend, newtrace.thing_friend); @@ -3771,9 +3776,11 @@ struct aim_t FPathTraverse it(startpos.x, startpos.y, aimtrace.x, aimtrace.y, PT_ADDLINES | PT_ADDTHINGS | PT_COMPATIBLE | PT_DELTA, startfrac); intercept_t *in; - Printf("Start AimTraverse, start = %f,%f,%f, vect = %f,%f,%f\n", - startpos.x / 65536., startpos.y / 65536., startpos.y / 65536., - aimtrace.x / 65536., aimtrace.y / 65536.); + if (aimdebug) + Printf("Start AimTraverse, start = %f,%f,%f, vect = %f,%f,%f\n", + startpos.x / 65536., startpos.y / 65536., startpos.y / 65536., + aimtrace.x / 65536., aimtrace.y / 65536.); + while ((in = it.Next())) { line_t* li; @@ -3791,7 +3798,8 @@ struct aim_t li = in->d.line; int frontflag = P_PointOnLineSidePrecise(startpos.x, startpos.y, li); - Printf("Found line %d: toppitch = %f, bottompitch = %f\n", int(li - lines), ANGLE2DBL(toppitch), ANGLE2DBL(bottompitch)); + if (aimdebug) + Printf("Found line %d: toppitch = %f, bottompitch = %f\n", int(li - lines), ANGLE2DBL(toppitch), ANGLE2DBL(bottompitch)); if (li->isLinePortal() && frontflag == 0) { @@ -3834,7 +3842,8 @@ struct aim_t if (!AimTraverse3DFloors(it.Trace(), in, frontflag, &planestocheck)) return; - Printf("After line %d: toppitch = %f, bottompitch = %f, planestocheck = %d\n", int(li - lines), ANGLE2DBL(toppitch), ANGLE2DBL(bottompitch), planestocheck); + if (aimdebug) + Printf("After line %d: toppitch = %f, bottompitch = %f, planestocheck = %d\n", int(li - lines), ANGLE2DBL(toppitch), ANGLE2DBL(bottompitch), planestocheck); sector_t *entersec = frontflag ? li->frontsector : li->backsector; sector_t *exitsec = frontflag ? li->backsector : li->frontsector; @@ -3990,20 +3999,23 @@ struct aim_t if (sv_smartaim < 3) { // don't autoaim at barrels and other shootable stuff unless no monsters have been found - Printf("Hit other %s at %f,%f,%f\n", th->GetClass()->TypeName.GetChars(), th->X() / 65536., th->Y() / 65536., th->Z() / 65536.); + if (aimdebug) + Printf("Hit other %s at %f,%f,%f\n", th->GetClass()->TypeName.GetChars(), th->X() / 65536., th->Y() / 65536., th->Z() / 65536.); SetResult(thing_other, in->frac, th, thingpitch); } } else { - Printf("Hit target %s at %f,%f,%f\n", th->GetClass()->TypeName.GetChars(), th->X() / 65536., th->Y() / 65536., th->Z() / 65536.); + if (aimdebug) + Printf("Hit target %s at %f,%f,%f\n", th->GetClass()->TypeName.GetChars(), th->X() / 65536., th->Y() / 65536., th->Z() / 65536.); SetResult(linetarget, in->frac, th, thingpitch); return; } } else { - Printf("Hit target %s at %f,%f,%f\n", th->GetClass()->TypeName.GetChars(), th->X() / 65536., th->Y() / 65536., th->Z() / 65536.); + if (aimdebug) + Printf("Hit target %s at %f,%f,%f\n", th->GetClass()->TypeName.GetChars(), th->X() / 65536., th->Y() / 65536., th->Z() / 65536.); SetResult(linetarget, in->frac, th, thingpitch); return; } From 2587e82a671ee9b35fe3fc7a1f8062f4b5b47785 Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Thu, 3 Mar 2016 16:15:42 +0100 Subject: [PATCH 12/26] . removed some redundant computation of a trace's hit position. --- src/p_map.cpp | 15 ++++----------- 1 file changed, 4 insertions(+), 11 deletions(-) diff --git a/src/p_map.cpp b/src/p_map.cpp index 1970e1a4b..e36cb9316 100644 --- a/src/p_map.cpp +++ b/src/p_map.cpp @@ -4281,12 +4281,7 @@ AActor *P_LineAttack(AActor *t1, angle_t angle, fixed_t distance, trace.Sector->heightsec == NULL && trace.HitType == TRACE_HitFloor) { - // Using the puff's position is not accurate enough. - // Instead make it splash at the actual hit position - hitx = t1->X() + FixedMul(vx, trace.Distance); - hity = t1->Y() + FixedMul(vy, trace.Distance); - hitz = shootz + FixedMul(vz, trace.Distance); - P_HitWater(puff, P_PointInSector(hitx, hity), hitx, hity, hitz); + P_HitWater(puff, trace.Sector, trace.X, trace.Y, trace.Z); } } else @@ -4852,8 +4847,7 @@ void P_RailAttack(AActor *source, int damage, int offset_xy, fixed_t offset_z, i trace.CrossedWater == NULL && trace.Sector->heightsec == NULL) { - thepuff->SetOrigin(trace.X, trace.Y, trace.Z, false); - P_HitWater(thepuff, trace.Sector); + P_HitWater(thepuff, trace.Sector, trace.X, trace.Y, trace.Z); } if (trace.Crossed3DWater || trace.CrossedWater) { @@ -6458,11 +6452,10 @@ static void SpawnDeepSplash(AActor *t1, const FTraceResults &trace, AActor *puff if (hitdist >= 0 && hitdist <= trace.Distance) { - fixed_t hitx = t1->X() + FixedMul(vx, hitdist); - fixed_t hity = t1->Y() + FixedMul(vy, hitdist); + fixedvec2 hitpos = t1->Vec2Offset(FixedMul(vx, hitdist), FixedMul(vy, hitdist)); fixed_t hitz = shootz + FixedMul(vz, hitdist); - P_HitWater(puff != NULL ? puff : t1, P_PointInSector(hitx, hity), hitx, hity, hitz); + P_HitWater(puff != NULL ? puff : t1, P_PointInSector(hitpos.x, hitpos.y), hitpos.x, hitpos.y, hitz); } } } From 6d68f69674966b7e48941488448d7edb930abcdd Mon Sep 17 00:00:00 2001 From: Randy Heit Date: Thu, 3 Mar 2016 13:27:52 -0600 Subject: [PATCH 13/26] Use lambdas for more concise code --- src/zscript/zcc_expr.cpp | 342 ++++++--------------------------------- 1 file changed, 50 insertions(+), 292 deletions(-) diff --git a/src/zscript/zcc_expr.cpp b/src/zscript/zcc_expr.cpp index 3ab977a2f..69a25970b 100644 --- a/src/zscript/zcc_expr.cpp +++ b/src/zscript/zcc_expr.cpp @@ -181,142 +181,11 @@ ZCC_OpProto *ZCC_OpInfoType::FindBestProto( return best_proto; } -static ZCC_ExprConstant *EvalIncFloat64(ZCC_ExprConstant *val) -{ - val->DoubleVal++; - return val; -} - -static ZCC_ExprConstant *EvalIncInt32(ZCC_ExprConstant *val) -{ - val->IntVal++; - return val; -} - -static ZCC_ExprConstant *EvalDecFloat64(ZCC_ExprConstant *val) -{ - val->DoubleVal--; - return val; -} - -static ZCC_ExprConstant *EvalDecInt32(ZCC_ExprConstant *val) -{ - val->IntVal--; - return val; -} - -static ZCC_ExprConstant *EvalNegateFloat64(ZCC_ExprConstant *val) -{ - val->DoubleVal = -val->DoubleVal; - return val; -} - -static ZCC_ExprConstant *EvalNegateInt32(ZCC_ExprConstant *val) -{ - val->IntVal = -val->IntVal; - return val; -} - static ZCC_ExprConstant *EvalIdentity(ZCC_ExprConstant *val) { return val; } -static ZCC_ExprConstant *EvalBitNot(ZCC_ExprConstant *val) -{ - val->IntVal = ~val->IntVal; - return val; -} - -static ZCC_ExprConstant *EvalBoolNot(ZCC_ExprConstant *val) -{ - val->IntVal = !val->IntVal; - return val; -} - -static ZCC_ExprConstant *EvalAddFloat64(ZCC_ExprConstant *l, ZCC_ExprConstant *r, FSharedStringArena &) -{ - l->DoubleVal += r->DoubleVal; - return l; -} - -static ZCC_ExprConstant *EvalAddInt32(ZCC_ExprConstant *l, ZCC_ExprConstant *r, FSharedStringArena &) -{ - l->IntVal += r->IntVal; - return l; -} - -static ZCC_ExprConstant *EvalSubFloat64(ZCC_ExprConstant *l, ZCC_ExprConstant *r, FSharedStringArena &) -{ - l->DoubleVal -= r->DoubleVal; - return l; -} - -static ZCC_ExprConstant *EvalSubInt32(ZCC_ExprConstant *l, ZCC_ExprConstant *r, FSharedStringArena &) -{ - l->IntVal -= r->IntVal; - return l; -} - -static ZCC_ExprConstant *EvalMulFloat64(ZCC_ExprConstant *l, ZCC_ExprConstant *r, FSharedStringArena &) -{ - l->DoubleVal *= r->DoubleVal; - return l; -} - -static ZCC_ExprConstant *EvalMulUInt32(ZCC_ExprConstant *l, ZCC_ExprConstant *r, FSharedStringArena &) -{ - l->UIntVal *= r->UIntVal; - return l; -} - -static ZCC_ExprConstant *EvalMulSInt32(ZCC_ExprConstant *l, ZCC_ExprConstant *r, FSharedStringArena &) -{ - l->IntVal *= r->IntVal; - return l; -} - -static ZCC_ExprConstant *EvalDivFloat64(ZCC_ExprConstant *l, ZCC_ExprConstant *r, FSharedStringArena &) -{ - l->DoubleVal /= r->DoubleVal; - return l; -} - -static ZCC_ExprConstant *EvalDivUInt32(ZCC_ExprConstant *l, ZCC_ExprConstant *r, FSharedStringArena &) -{ - l->UIntVal /= r->UIntVal; - return l; -} - -static ZCC_ExprConstant *EvalDivSInt32(ZCC_ExprConstant *l, ZCC_ExprConstant *r, FSharedStringArena &) -{ - l->IntVal /= r->IntVal; - return l; -} - -static ZCC_ExprConstant *EvalModFloat64(ZCC_ExprConstant *l, ZCC_ExprConstant *r, FSharedStringArena &) -{ - l->DoubleVal = luai_nummod(l->DoubleVal, r->DoubleVal); - return l; -} - -static ZCC_ExprConstant *EvalModUInt32(ZCC_ExprConstant *l, ZCC_ExprConstant *r, FSharedStringArena &) -{ - l->UIntVal %= r->UIntVal; - return l; -} - -static ZCC_ExprConstant *EvalModSInt32(ZCC_ExprConstant *l, ZCC_ExprConstant *r, FSharedStringArena &) -{ - l->IntVal %= r->IntVal; - return l; -} - -static ZCC_ExprConstant *EvalPow(ZCC_ExprConstant *l, ZCC_ExprConstant *r, FSharedStringArena &) -{ - l->DoubleVal = pow(l->DoubleVal, r->DoubleVal); - return l; -} static ZCC_ExprConstant *EvalConcat(ZCC_ExprConstant *l, ZCC_ExprConstant *r, FSharedStringArena &strings) { @@ -325,117 +194,6 @@ static ZCC_ExprConstant *EvalConcat(ZCC_ExprConstant *l, ZCC_ExprConstant *r, FS return l; } -static ZCC_ExprConstant *EvalBitAnd(ZCC_ExprConstant *l, ZCC_ExprConstant *r, FSharedStringArena &) -{ - l->IntVal &= r->IntVal; - return l; -} - -static ZCC_ExprConstant *EvalBitOr(ZCC_ExprConstant *l, ZCC_ExprConstant *r, FSharedStringArena &) -{ - l->IntVal |= r->IntVal; - return l; -} - -static ZCC_ExprConstant *EvalBitXor(ZCC_ExprConstant *l, ZCC_ExprConstant *r, FSharedStringArena &) -{ - l->IntVal ^= r->IntVal; - return l; -} - -static ZCC_ExprConstant *EvalBoolAnd(ZCC_ExprConstant *l, ZCC_ExprConstant *r, FSharedStringArena &) -{ - l->IntVal = l->IntVal && r->IntVal; - return l; -} - -static ZCC_ExprConstant *EvalBoolOr(ZCC_ExprConstant *l, ZCC_ExprConstant *r, FSharedStringArena &) -{ - l->IntVal = l->IntVal || r->IntVal; - return l; -} - -static ZCC_ExprConstant *EvalSHL(ZCC_ExprConstant *l, ZCC_ExprConstant *r, FSharedStringArena &) -{ - l->IntVal <<= r->UIntVal; - return l; -} - -static ZCC_ExprConstant *EvalSHR_S(ZCC_ExprConstant *l, ZCC_ExprConstant *r, FSharedStringArena &) -{ - l->IntVal >>= r->UIntVal; - return l; -} - -static ZCC_ExprConstant *EvalSHR_U(ZCC_ExprConstant *l, ZCC_ExprConstant *r, FSharedStringArena &) -{ - l->UIntVal >>= r->UIntVal; - return l; -} - -static ZCC_ExprConstant *EvalLTSInt32(ZCC_ExprConstant *l, ZCC_ExprConstant *r, FSharedStringArena &) -{ - l->IntVal = l->IntVal < r->IntVal; - l->Type = TypeBool; - return l; -} - -static ZCC_ExprConstant *EvalLTUInt32(ZCC_ExprConstant *l, ZCC_ExprConstant *r, FSharedStringArena &) -{ - l->IntVal = l->UIntVal < r->UIntVal; - l->Type = TypeBool; - return l; -} - -static ZCC_ExprConstant *EvalLTFloat64(ZCC_ExprConstant *l, ZCC_ExprConstant *r, FSharedStringArena &) -{ - l->IntVal = l->DoubleVal < r->DoubleVal; - l->Type = TypeBool; - return l; -} - -static ZCC_ExprConstant *EvalLTEQSInt32(ZCC_ExprConstant *l, ZCC_ExprConstant *r, FSharedStringArena &) -{ - l->IntVal = l->IntVal <= r->IntVal; - l->Type = TypeBool; - return l; -} - -static ZCC_ExprConstant *EvalLTEQUInt32(ZCC_ExprConstant *l, ZCC_ExprConstant *r, FSharedStringArena &) -{ - l->IntVal = l->UIntVal <= r->UIntVal; - l->Type = TypeBool; - return l; -} - -static ZCC_ExprConstant *EvalLTEQFloat64(ZCC_ExprConstant *l, ZCC_ExprConstant *r, FSharedStringArena &) -{ - l->IntVal = l->DoubleVal <= r->DoubleVal; - l->Type = TypeBool; - return l; -} - -static ZCC_ExprConstant *EvalEQEQSInt32(ZCC_ExprConstant *l, ZCC_ExprConstant *r, FSharedStringArena &) -{ - l->IntVal = l->IntVal == r->IntVal; - l->Type = TypeBool; - return l; -} - -static ZCC_ExprConstant *EvalEQEQUInt32(ZCC_ExprConstant *l, ZCC_ExprConstant *r, FSharedStringArena &) -{ - l->IntVal = l->UIntVal == r->UIntVal; - l->Type = TypeBool; - return l; -} - -static ZCC_ExprConstant *EvalEQEQFloat64(ZCC_ExprConstant *l, ZCC_ExprConstant *r, FSharedStringArena &) -{ - l->IntVal = l->DoubleVal == r->DoubleVal; - l->Type = TypeBool; - return l; -} - static ZCC_ExprConstant *EvalLTGTEQSInt32(ZCC_ExprConstant *l, ZCC_ExprConstant *r, FSharedStringArena &) { l->IntVal = l->IntVal < r->IntVal ? -1 : l->IntVal == r->IntVal ? 0 : 1; @@ -471,25 +229,25 @@ void ZCC_InitOperators() { PEX_PostDec , (PType **)&TypeUInt32, EvalIdentity }, { PEX_PostDec , (PType **)&TypeFloat64, EvalIdentity }, - { PEX_PreInc , (PType **)&TypeSInt32, EvalIncInt32 }, - { PEX_PreInc , (PType **)&TypeUInt32, EvalIncInt32 }, - { PEX_PreInc , (PType **)&TypeFloat64, EvalIncFloat64 }, + { PEX_PreInc , (PType **)&TypeSInt32, [](auto *val) { val->IntVal += 1; return val; } }, + { PEX_PreInc , (PType **)&TypeUInt32, [](auto *val) { val->UIntVal += 1; return val; } }, + { PEX_PreInc , (PType **)&TypeFloat64, [](auto *val) { val->DoubleVal += 1; return val; } }, - { PEX_PreDec , (PType **)&TypeSInt32, EvalDecInt32 }, - { PEX_PreDec , (PType **)&TypeUInt32, EvalDecInt32 }, - { PEX_PreDec , (PType **)&TypeFloat64, EvalDecFloat64 }, + { PEX_PreDec , (PType **)&TypeSInt32, [](auto *val) { val->IntVal -= 1; return val; } }, + { PEX_PreDec , (PType **)&TypeUInt32, [](auto *val) { val->UIntVal -= 1; return val; } }, + { PEX_PreDec , (PType **)&TypeFloat64, [](auto *val) { val->DoubleVal -= 1; return val; } }, - { PEX_Negate , (PType **)&TypeSInt32, EvalNegateInt32 }, - { PEX_Negate , (PType **)&TypeFloat64, EvalNegateFloat64 }, + { PEX_Negate , (PType **)&TypeSInt32, [](auto *val) { val->IntVal = -val->IntVal; return val; } }, + { PEX_Negate , (PType **)&TypeFloat64, [](auto *val) { val->DoubleVal = -val->DoubleVal; return val; } }, { PEX_AntiNegate , (PType **)&TypeSInt32, EvalIdentity }, { PEX_AntiNegate , (PType **)&TypeUInt32, EvalIdentity }, { PEX_AntiNegate , (PType **)&TypeFloat64, EvalIdentity }, - { PEX_BitNot , (PType **)&TypeSInt32, EvalBitNot }, - { PEX_BitNot , (PType **)&TypeUInt32, EvalBitNot }, + { PEX_BitNot , (PType **)&TypeSInt32, [](auto *val) { val->IntVal = ~val->IntVal; return val; } }, + { PEX_BitNot , (PType **)&TypeUInt32, [](auto *val) { val->UIntVal = ~val->UIntVal; return val; } }, - { PEX_BoolNot , (PType **)&TypeBool, EvalBoolNot }, + { PEX_BoolNot , (PType **)&TypeBool, [](auto *val) { val->IntVal = !val->IntVal; return val; } }, }; for (size_t i = 0; i < countof(UnaryOpInit); ++i) { @@ -499,62 +257,62 @@ void ZCC_InitOperators() // Binary operators static const OpProto2 BinaryOpInit[] = { - { PEX_Add , (PType **)&TypeSInt32, (PType **)&TypeSInt32, (PType **)&TypeSInt32, EvalAddInt32 }, - { PEX_Add , (PType **)&TypeUInt32, (PType **)&TypeUInt32, (PType **)&TypeUInt32, EvalAddInt32 }, - { PEX_Add , (PType **)&TypeFloat64, (PType **)&TypeFloat64, (PType **)&TypeFloat64, EvalAddFloat64 }, + { PEX_Add , (PType **)&TypeSInt32, (PType **)&TypeSInt32, (PType **)&TypeSInt32, [](auto *l, auto *r, auto &) { l->IntVal += r->IntVal; return l; } }, + { PEX_Add , (PType **)&TypeUInt32, (PType **)&TypeUInt32, (PType **)&TypeUInt32, [](auto *l, auto *r, auto &) { l->UIntVal += r->UIntVal; return l; } }, + { PEX_Add , (PType **)&TypeFloat64, (PType **)&TypeFloat64, (PType **)&TypeFloat64, [](auto *l, auto *r, auto &) { l->DoubleVal += r->DoubleVal; return l; } }, - { PEX_Sub , (PType **)&TypeSInt32, (PType **)&TypeSInt32, (PType **)&TypeSInt32, EvalSubInt32 }, - { PEX_Sub , (PType **)&TypeUInt32, (PType **)&TypeUInt32, (PType **)&TypeUInt32, EvalSubInt32 }, - { PEX_Sub , (PType **)&TypeFloat64, (PType **)&TypeFloat64, (PType **)&TypeFloat64, EvalSubFloat64 }, + { PEX_Sub , (PType **)&TypeSInt32, (PType **)&TypeSInt32, (PType **)&TypeSInt32, [](auto *l, auto *r, auto &) { l->IntVal -= r->IntVal; return l; } }, + { PEX_Sub , (PType **)&TypeUInt32, (PType **)&TypeUInt32, (PType **)&TypeUInt32, [](auto *l, auto *r, auto &) { l->UIntVal -= r->UIntVal; return l; } }, + { PEX_Sub , (PType **)&TypeFloat64, (PType **)&TypeFloat64, (PType **)&TypeFloat64, [](auto *l, auto *r, auto &) { l->DoubleVal -= r->DoubleVal; return l; } }, - { PEX_Mul , (PType **)&TypeSInt32, (PType **)&TypeSInt32, (PType **)&TypeSInt32, EvalMulSInt32 }, - { PEX_Mul , (PType **)&TypeUInt32, (PType **)&TypeUInt32, (PType **)&TypeUInt32, EvalMulUInt32 }, - { PEX_Mul , (PType **)&TypeFloat64, (PType **)&TypeFloat64, (PType **)&TypeFloat64, EvalMulFloat64 }, + { PEX_Mul , (PType **)&TypeSInt32, (PType **)&TypeSInt32, (PType **)&TypeSInt32, [](auto *l, auto *r, auto &) { l->IntVal *= r->IntVal; return l; } }, + { PEX_Mul , (PType **)&TypeUInt32, (PType **)&TypeUInt32, (PType **)&TypeUInt32, [](auto *l, auto *r, auto &) { l->UIntVal *= r->UIntVal; return l; } }, + { PEX_Mul , (PType **)&TypeFloat64, (PType **)&TypeFloat64, (PType **)&TypeFloat64, [](auto *l, auto *r, auto &) { l->DoubleVal *= r->DoubleVal; return l; } }, - { PEX_Div , (PType **)&TypeSInt32, (PType **)&TypeSInt32, (PType **)&TypeSInt32, EvalDivSInt32 }, - { PEX_Div , (PType **)&TypeUInt32, (PType **)&TypeUInt32, (PType **)&TypeUInt32, EvalDivUInt32 }, - { PEX_Div , (PType **)&TypeFloat64, (PType **)&TypeFloat64, (PType **)&TypeFloat64, EvalDivFloat64 }, + { PEX_Div , (PType **)&TypeSInt32, (PType **)&TypeSInt32, (PType **)&TypeSInt32, [](auto *l, auto *r, auto &) { l->IntVal /= r->IntVal; return l; } }, + { PEX_Div , (PType **)&TypeUInt32, (PType **)&TypeUInt32, (PType **)&TypeUInt32, [](auto *l, auto *r, auto &) { l->UIntVal /= r->UIntVal; return l; } }, + { PEX_Div , (PType **)&TypeFloat64, (PType **)&TypeFloat64, (PType **)&TypeFloat64, [](auto *l, auto *r, auto &) { l->DoubleVal /= r->DoubleVal; return l; } }, - { PEX_Mod , (PType **)&TypeSInt32, (PType **)&TypeSInt32, (PType **)&TypeSInt32, EvalModSInt32 }, - { PEX_Mod , (PType **)&TypeUInt32, (PType **)&TypeUInt32, (PType **)&TypeUInt32, EvalModUInt32 }, - { PEX_Mod , (PType **)&TypeFloat64, (PType **)&TypeFloat64, (PType **)&TypeFloat64, EvalModFloat64 }, + { PEX_Mod , (PType **)&TypeSInt32, (PType **)&TypeSInt32, (PType **)&TypeSInt32, [](auto *l, auto *r, auto &) { l->IntVal %= r->IntVal; return l; } }, + { PEX_Mod , (PType **)&TypeUInt32, (PType **)&TypeUInt32, (PType **)&TypeUInt32, [](auto *l, auto *r, auto &) { l->UIntVal %= r->UIntVal; return l; } }, + { PEX_Mod , (PType **)&TypeFloat64, (PType **)&TypeFloat64, (PType **)&TypeFloat64, [](auto *l, auto *r, auto &) { l->DoubleVal = luai_nummod(l->DoubleVal, r->DoubleVal); return l; } }, - { PEX_Pow , (PType **)&TypeFloat64, (PType **)&TypeFloat64, (PType **)&TypeFloat64, EvalPow }, + { PEX_Pow , (PType **)&TypeFloat64, (PType **)&TypeFloat64, (PType **)&TypeFloat64, [](auto *l, auto *r, auto &) { l->DoubleVal = pow(l->DoubleVal, r->DoubleVal); return l; } }, { PEX_Concat , (PType **)&TypeString, (PType **)&TypeString, (PType **)&TypeString, EvalConcat }, - { PEX_BitAnd , (PType **)&TypeSInt32, (PType **)&TypeSInt32, (PType **)&TypeSInt32, EvalBitAnd }, - { PEX_BitAnd , (PType **)&TypeUInt32, (PType **)&TypeUInt32, (PType **)&TypeUInt32, EvalBitAnd }, + { PEX_BitAnd , (PType **)&TypeSInt32, (PType **)&TypeSInt32, (PType **)&TypeSInt32, [](auto *l, auto *r, auto &) { l->IntVal &= r->IntVal; return l; } }, + { PEX_BitAnd , (PType **)&TypeUInt32, (PType **)&TypeUInt32, (PType **)&TypeUInt32, [](auto *l, auto *r, auto &) { l->UIntVal &= r->UIntVal; return l; } }, - { PEX_BitOr , (PType **)&TypeSInt32, (PType **)&TypeSInt32, (PType **)&TypeSInt32, EvalBitOr }, - { PEX_BitOr , (PType **)&TypeUInt32, (PType **)&TypeUInt32, (PType **)&TypeUInt32, EvalBitOr }, + { PEX_BitOr , (PType **)&TypeSInt32, (PType **)&TypeSInt32, (PType **)&TypeSInt32, [](auto *l, auto *r, auto &) { l->IntVal |= r->IntVal; return l; } }, + { PEX_BitOr , (PType **)&TypeUInt32, (PType **)&TypeUInt32, (PType **)&TypeUInt32, [](auto *l, auto *r, auto &) { l->UIntVal |= r->UIntVal; return l; } }, - { PEX_BitXor , (PType **)&TypeSInt32, (PType **)&TypeSInt32, (PType **)&TypeSInt32, EvalBitXor }, - { PEX_BitXor , (PType **)&TypeUInt32, (PType **)&TypeUInt32, (PType **)&TypeUInt32, EvalBitXor }, + { PEX_BitXor , (PType **)&TypeSInt32, (PType **)&TypeSInt32, (PType **)&TypeSInt32, [](auto *l, auto *r, auto &) { l->IntVal ^= r->IntVal; return l; } }, + { PEX_BitXor , (PType **)&TypeUInt32, (PType **)&TypeUInt32, (PType **)&TypeUInt32, [](auto *l, auto *r, auto &) { l->UIntVal ^= r->UIntVal; return l; } }, - { PEX_BoolAnd , (PType **)&TypeSInt32, (PType **)&TypeSInt32, (PType **)&TypeSInt32, EvalBoolAnd }, - { PEX_BoolAnd , (PType **)&TypeUInt32, (PType **)&TypeUInt32, (PType **)&TypeUInt32, EvalBoolAnd }, + { PEX_BoolAnd , (PType **)&TypeSInt32, (PType **)&TypeSInt32, (PType **)&TypeSInt32, [](auto *l, auto *r, auto &) { l->IntVal = l->IntVal && r->IntVal; l->Type = TypeBool; return l; } }, + { PEX_BoolAnd , (PType **)&TypeUInt32, (PType **)&TypeUInt32, (PType **)&TypeUInt32, [](auto *l, auto *r, auto &) { l->IntVal = l->UIntVal && r->UIntVal; l->Type = TypeBool; return l; } }, - { PEX_BoolOr , (PType **)&TypeSInt32, (PType **)&TypeSInt32, (PType **)&TypeSInt32, EvalBoolOr }, - { PEX_BoolOr , (PType **)&TypeUInt32, (PType **)&TypeUInt32, (PType **)&TypeUInt32, EvalBoolOr }, + { PEX_BoolOr , (PType **)&TypeSInt32, (PType **)&TypeSInt32, (PType **)&TypeSInt32, [](auto *l, auto *r, auto &) { l->IntVal = l->IntVal || r->IntVal; l->Type = TypeBool; return l; } }, + { PEX_BoolOr , (PType **)&TypeUInt32, (PType **)&TypeUInt32, (PType **)&TypeUInt32, [](auto *l, auto *r, auto &) { l->IntVal = l->UIntVal || r->UIntVal; l->Type = TypeBool; return l; } }, - { PEX_LeftShift , (PType **)&TypeSInt32, (PType **)&TypeSInt32, (PType **)&TypeUInt32, EvalSHL }, - { PEX_LeftShift , (PType **)&TypeUInt32, (PType **)&TypeUInt32, (PType **)&TypeUInt32, EvalSHL }, + { PEX_LeftShift , (PType **)&TypeSInt32, (PType **)&TypeSInt32, (PType **)&TypeUInt32, [](auto *l, auto *r, auto &) { l->IntVal <<= r->UIntVal; return l; } }, + { PEX_LeftShift , (PType **)&TypeUInt32, (PType **)&TypeUInt32, (PType **)&TypeUInt32, [](auto *l, auto *r, auto &) { l->UIntVal <<= r->UIntVal; return l; } }, - { PEX_RightShift , (PType **)&TypeSInt32, (PType **)&TypeSInt32, (PType **)&TypeUInt32, EvalSHR_S }, - { PEX_RightShift , (PType **)&TypeUInt32, (PType **)&TypeUInt32, (PType **)&TypeUInt32, EvalSHR_U }, + { PEX_RightShift , (PType **)&TypeSInt32, (PType **)&TypeSInt32, (PType **)&TypeUInt32, [](auto *l, auto *r, auto &) { l->IntVal >>= r->UIntVal; return l; } }, + { PEX_RightShift , (PType **)&TypeUInt32, (PType **)&TypeUInt32, (PType **)&TypeUInt32, [](auto *l, auto *r, auto &) { l->UIntVal >>= r->UIntVal; return l; } }, - { PEX_LT , (PType **)&TypeBool, (PType **)&TypeSInt32, (PType **)&TypeSInt32, EvalLTSInt32 }, - { PEX_LT , (PType **)&TypeBool, (PType **)&TypeUInt32, (PType **)&TypeUInt32, EvalLTUInt32 }, - { PEX_LT , (PType **)&TypeBool, (PType **)&TypeFloat64, (PType **)&TypeFloat64, EvalLTFloat64 }, + { PEX_LT , (PType **)&TypeBool, (PType **)&TypeSInt32, (PType **)&TypeSInt32, [](auto *l, auto *r, auto &) { l->IntVal = l->IntVal < r->IntVal; l->Type = TypeBool; return l; } }, + { PEX_LT , (PType **)&TypeBool, (PType **)&TypeUInt32, (PType **)&TypeUInt32, [](auto *l, auto *r, auto &) { l->IntVal = l->UIntVal < r->UIntVal; l->Type = TypeBool; return l; } }, + { PEX_LT , (PType **)&TypeBool, (PType **)&TypeFloat64, (PType **)&TypeFloat64, [](auto *l, auto *r, auto &) { l->IntVal = l->DoubleVal < r->DoubleVal; l->Type = TypeBool; return l; } }, - { PEX_LTEQ , (PType **)&TypeBool, (PType **)&TypeSInt32, (PType **)&TypeSInt32, EvalLTEQSInt32 }, - { PEX_LTEQ , (PType **)&TypeBool, (PType **)&TypeUInt32, (PType **)&TypeUInt32, EvalLTEQUInt32 }, - { PEX_LTEQ , (PType **)&TypeBool, (PType **)&TypeFloat64, (PType **)&TypeFloat64, EvalLTEQFloat64 }, + { PEX_LTEQ , (PType **)&TypeBool, (PType **)&TypeSInt32, (PType **)&TypeSInt32, [](auto *l, auto *r, auto &) { l->IntVal = l->IntVal <= r->IntVal; l->Type = TypeBool; return l; } }, + { PEX_LTEQ , (PType **)&TypeBool, (PType **)&TypeUInt32, (PType **)&TypeUInt32, [](auto *l, auto *r, auto &) { l->IntVal = l->UIntVal <= r->UIntVal; l->Type = TypeBool; return l; } }, + { PEX_LTEQ , (PType **)&TypeBool, (PType **)&TypeFloat64, (PType **)&TypeFloat64, [](auto *l, auto *r, auto &) { l->IntVal = l->DoubleVal <= r->DoubleVal; l->Type = TypeBool; return l; } }, - { PEX_EQEQ , (PType **)&TypeBool, (PType **)&TypeSInt32, (PType **)&TypeSInt32, EvalEQEQSInt32 }, - { PEX_EQEQ , (PType **)&TypeBool, (PType **)&TypeUInt32, (PType **)&TypeUInt32, EvalEQEQUInt32 }, - { PEX_EQEQ , (PType **)&TypeBool, (PType **)&TypeFloat64, (PType **)&TypeFloat64, EvalEQEQFloat64 }, + { PEX_EQEQ , (PType **)&TypeBool, (PType **)&TypeSInt32, (PType **)&TypeSInt32, [](auto *l, auto *r, auto &) { l->IntVal = l->IntVal == r->IntVal; l->Type = TypeBool; return l; } }, + { PEX_EQEQ , (PType **)&TypeBool, (PType **)&TypeUInt32, (PType **)&TypeUInt32, [](auto *l, auto *r, auto &) { l->IntVal = l->UIntVal == r->UIntVal; l->Type = TypeBool; return l; } }, + { PEX_EQEQ , (PType **)&TypeBool, (PType **)&TypeFloat64, (PType **)&TypeFloat64, [](auto *l, auto *r, auto &) { l->IntVal = l->DoubleVal == r->DoubleVal; l->Type = TypeBool; return l; } }, { PEX_LTGTEQ , (PType **)&TypeSInt32, (PType **)&TypeSInt32, (PType **)&TypeSInt32, EvalLTGTEQSInt32 }, { PEX_LTGTEQ , (PType **)&TypeSInt32, (PType **)&TypeUInt32, (PType **)&TypeUInt32, EvalLTGTEQUInt32 }, From e3d35f4fe8ada73dced41746f4b94045787d7ce4 Mon Sep 17 00:00:00 2001 From: Randy Heit Date: Thu, 3 Mar 2016 15:09:19 -0600 Subject: [PATCH 14/26] PClassPointer should use its own type as the metatype in the type table - I don't remember why I thought using PPointer as the metatype for PClassPointer would be preferable, but it means that PPointer's MatchID can potentially be called for PClassPointer entries. --- src/dobjtype.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/dobjtype.cpp b/src/dobjtype.cpp index 3647de77c..b8a5cbcf9 100644 --- a/src/dobjtype.cpp +++ b/src/dobjtype.cpp @@ -496,7 +496,7 @@ void PType::StaticInit() RUNTIME_CLASS(PSound)->TypeTableType = RUNTIME_CLASS(PSound); RUNTIME_CLASS(PColor)->TypeTableType = RUNTIME_CLASS(PColor); RUNTIME_CLASS(PPointer)->TypeTableType = RUNTIME_CLASS(PPointer); - RUNTIME_CLASS(PClassPointer)->TypeTableType = RUNTIME_CLASS(PPointer); // not sure about this yet + RUNTIME_CLASS(PClassPointer)->TypeTableType = RUNTIME_CLASS(PClassPointer); RUNTIME_CLASS(PEnum)->TypeTableType = RUNTIME_CLASS(PEnum); RUNTIME_CLASS(PArray)->TypeTableType = RUNTIME_CLASS(PArray); RUNTIME_CLASS(PDynArray)->TypeTableType = RUNTIME_CLASS(PDynArray); @@ -1430,11 +1430,11 @@ void PClassPointer::GetTypeIDs(intptr_t &id1, intptr_t &id2) const PClassPointer *NewClassPointer(PClass *restrict) { size_t bucket; - PType *ptype = TypeTable.FindType(RUNTIME_CLASS(PPointer), (intptr_t)RUNTIME_CLASS(PClass), (intptr_t)restrict, &bucket); + PType *ptype = TypeTable.FindType(RUNTIME_CLASS(PClassPointer), (intptr_t)RUNTIME_CLASS(PClass), (intptr_t)restrict, &bucket); if (ptype == NULL) { ptype = new PClassPointer(restrict); - TypeTable.AddType(ptype, RUNTIME_CLASS(PPointer), (intptr_t)RUNTIME_CLASS(PClass), (intptr_t)restrict, bucket); + TypeTable.AddType(ptype, RUNTIME_CLASS(PClassPointer), (intptr_t)RUNTIME_CLASS(PClass), (intptr_t)restrict, bucket); } return static_cast(ptype); } From 97821a3036f7ba8281f88d39bf2d750bf84c5c61 Mon Sep 17 00:00:00 2001 From: Michael Labbe Date: Wed, 2 Mar 2016 02:31:12 -0800 Subject: [PATCH 15/26] 21:9 aspect ratio support - vid_aspect 6 forces 21:9 --- src/g_shared/shared_sbar.cpp | 4 ++-- src/posix/sdl/hardware.cpp | 4 ++-- src/r_main.cpp | 4 ++-- src/r_utility.cpp | 2 +- src/v_draw.cpp | 2 +- src/v_video.cpp | 19 ++++++++++++++----- src/v_video.h | 8 +++++++- src/win32/hardware.cpp | 4 ++-- 8 files changed, 31 insertions(+), 16 deletions(-) diff --git a/src/g_shared/shared_sbar.cpp b/src/g_shared/shared_sbar.cpp index dabddbaa0..d0153a98f 100644 --- a/src/g_shared/shared_sbar.cpp +++ b/src/g_shared/shared_sbar.cpp @@ -1058,7 +1058,7 @@ void DBaseStatusBar::RefreshBackground () const int x, x2, y, ratio; ratio = CheckRatio (SCREENWIDTH, SCREENHEIGHT); - x = (!(ratio & 3) || !Scaled) ? ST_X : SCREENWIDTH*(48-BaseRatioSizes[ratio][3])/(48*2); + x = (!IsRatioWidescreen(ratio) || !Scaled) ? ST_X : SCREENWIDTH*(48-BaseRatioSizes[ratio][3])/(48*2); y = x == ST_X && x > 0 ? ST_Y : ::ST_Y; if(!CompleteBorder) @@ -1078,7 +1078,7 @@ void DBaseStatusBar::RefreshBackground () const { if(!CompleteBorder) { - x2 = !(ratio & 3) || !Scaled ? ST_X+HorizontalResolution : + x2 = !IsRatioWidescreen(ratio) || !Scaled ? ST_X+HorizontalResolution : SCREENWIDTH - (SCREENWIDTH*(48-BaseRatioSizes[ratio][3])+48*2-1)/(48*2); } else diff --git a/src/posix/sdl/hardware.cpp b/src/posix/sdl/hardware.cpp index 75d663266..213ca044d 100644 --- a/src/posix/sdl/hardware.cpp +++ b/src/posix/sdl/hardware.cpp @@ -308,7 +308,7 @@ CUSTOM_CVAR (Float, vid_winscale, 1.f, CVAR_ARCHIVE|CVAR_GLOBALCONFIG) CCMD (vid_listmodes) { - static const char *ratios[5] = { "", " - 16:9", " - 16:10", "", " - 5:4" }; + static const char *ratios[6] = { "", " - 16:9", " - 16:10", "", " - 5:4", " - 21:9" }; int width, height, bits; bool letterbox; @@ -325,7 +325,7 @@ CCMD (vid_listmodes) int ratio = CheckRatio (width, height); Printf (thisMode ? PRINT_BOLD : PRINT_HIGH, "%s%4d x%5d x%3d%s%s\n", - thisMode || !(ratio & 3) ? "" : TEXTCOLOR_GOLD, + thisMode || !IsRatioWidescreen(ratio) ? "" : TEXTCOLOR_GOLD, width, height, bits, ratios[ratio], thisMode || !letterbox ? "" : TEXTCOLOR_BROWN " LB" diff --git a/src/r_main.cpp b/src/r_main.cpp index c445787a0..43c22b0f9 100644 --- a/src/r_main.cpp +++ b/src/r_main.cpp @@ -363,7 +363,7 @@ void R_SWRSetWindow(int windowSize, int fullWidth, int fullHeight, int stHeight, virtwidth = virtwidth2 = fullWidth; virtheight = virtheight2 = fullHeight; - if (trueratio & 4) + if (Is54Aspect(trueratio)) { virtheight2 = virtheight2 * BaseRatioSizes[trueratio][3] / 48; } @@ -372,7 +372,7 @@ void R_SWRSetWindow(int windowSize, int fullWidth, int fullHeight, int stHeight, virtwidth2 = virtwidth2 * BaseRatioSizes[trueratio][3] / 48; } - if (WidescreenRatio & 4) + if (Is54Aspect(WidescreenRatio)) { virtheight = virtheight * BaseRatioSizes[WidescreenRatio][3] / 48; } diff --git a/src/r_utility.cpp b/src/r_utility.cpp index 089c65379..d301b45fc 100644 --- a/src/r_utility.cpp +++ b/src/r_utility.cpp @@ -434,7 +434,7 @@ void R_SetWindow (int windowSize, int fullWidth, int fullHeight, int stHeight) centery = viewheight/2; centerx = viewwidth/2; - if (WidescreenRatio & 4) + if (Is54Aspect(WidescreenRatio)) { centerxwide = centerx; } diff --git a/src/v_draw.cpp b/src/v_draw.cpp index de096e3a9..eeb1a7d9c 100644 --- a/src/v_draw.cpp +++ b/src/v_draw.cpp @@ -816,7 +816,7 @@ void DCanvas::FillBorder (FTexture *img) return; } int bordtop, bordbottom, bordleft, bordright, bord; - if (myratio & 4) + if (Is54Aspect(myratio)) { // Screen is taller than it is wide bordleft = bordright = 0; bord = Height - Height * BaseRatioSizes[myratio][3] / 48; diff --git a/src/v_video.cpp b/src/v_video.cpp index 73681fdc2..b69bba63f 100644 --- a/src/v_video.cpp +++ b/src/v_video.cpp @@ -1397,7 +1397,7 @@ void V_CalcCleanFacs (int designwidth, int designheight, int realwidth, int real int cx1, cy1, cx2, cy2; ratio = CheckRatio(realwidth, realheight); - if (ratio & 4) + if (Is54Aspect(ratio)) { cwidth = realwidth; cheight = realheight * BaseRatioSizes[ratio][3] / 48; @@ -1645,12 +1645,14 @@ CUSTOM_CVAR (Int, vid_aspect, 0, CVAR_GLOBALCONFIG|CVAR_ARCHIVE) // 2: 16:10 // 3: 17:10 // 4: 5:4 +// 5: 17:10 (redundant) +// 6: 21:9 int CheckRatio (int width, int height, int *trueratio) { int fakeratio = -1; int ratio; - if ((vid_aspect >= 1) && (vid_aspect <= 5)) + if ((vid_aspect >= 1) && (vid_aspect <= 6)) { // [SP] User wants to force aspect ratio; let them. fakeratio = int(vid_aspect); @@ -1661,7 +1663,7 @@ int CheckRatio (int width, int height, int *trueratio) else if (fakeratio == 5) { fakeratio = 3; - } + } } if (vid_nowidescreen) { @@ -1702,6 +1704,11 @@ int CheckRatio (int width, int height, int *trueratio) { ratio = 4; } + // test for 21:9 (actually 64:27, 21:9 is a semi-accurate ratio used in marketing) + else if (abs (height * 64/27 - width) < 30) + { + ratio = 6; + } // Assume anything else is 4:3. (Which is probably wrong these days...) else { @@ -1724,13 +1731,15 @@ int CheckRatio (int width, int height, int *trueratio) // base_width = 240 * x / y // multiplier = 320 / base_width // base_height = 200 * multiplier -const int BaseRatioSizes[5][4] = +const int BaseRatioSizes[7][4] = { { 960, 600, 0, 48 }, // 4:3 320, 200, multiplied by three { 1280, 450, 0, 48*3/4 }, // 16:9 426.6667, 150, multiplied by three { 1152, 500, 0, 48*5/6 }, // 16:10 386, 166.6667, multiplied by three { 1224, 471, 0, 48*40/51 }, // 17:10 408, 156.8627, multiplied by three - { 960, 640, (int)(6.5*FRACUNIT), 48*15/16 } // 5:4 320, 213.3333, multiplied by three + { 960, 640, (int)(6.5*FRACUNIT), 48*15/16 }, // 5:4 320, 213.3333, multiplied by three + { 1224, 471, 0, 48*40/51 }, // 17:10 408, 156.8627, multiplied by three (REDUNDANT) + { 568, 113, 0, 48*5/8 } // 21:9 }; void IVideo::DumpAdapters () diff --git a/src/v_video.h b/src/v_video.h index 0497b607e..7e0b09258 100644 --- a/src/v_video.h +++ b/src/v_video.h @@ -503,8 +503,14 @@ extern "C" void ASM_PatchPitch (void); int CheckRatio (int width, int height, int *trueratio=NULL); static inline int CheckRatio (double width, double height) { return CheckRatio(int(width), int(height)); } -extern const int BaseRatioSizes[5][4]; +extern const int BaseRatioSizes[7][4]; +inline bool IsRatioWidescreen(int ratio) { + return (ratio & 3)!=0; +} +inline bool Is54Aspect(int ratio) { + return ratio == 4; +} #endif // __V_VIDEO_H__ diff --git a/src/win32/hardware.cpp b/src/win32/hardware.cpp index d8a4fa974..cb4250b60 100644 --- a/src/win32/hardware.cpp +++ b/src/win32/hardware.cpp @@ -338,7 +338,7 @@ CUSTOM_CVAR (Float, vid_winscale, 1.f, CVAR_ARCHIVE|CVAR_GLOBALCONFIG) CCMD (vid_listmodes) { - static const char *ratios[5] = { "", " - 16:9", " - 16:10", " - 17:10", " - 5:4" }; + static const char *ratios[6] = { "", " - 16:9", " - 16:10", " - 17:10", " - 5:4", " - 21:9" }; int width, height, bits; bool letterbox; @@ -356,7 +356,7 @@ CCMD (vid_listmodes) int ratio = CheckRatio (width, height); Printf (thisMode ? PRINT_BOLD : PRINT_HIGH, "%s%4d x%5d x%3d%s%s\n", - thisMode || !(ratio & 3) ? "" : TEXTCOLOR_GOLD, + thisMode || !IsRatioWidescreen(ratio) ? "" : TEXTCOLOR_GOLD, width, height, bits, ratios[ratio], thisMode || !letterbox ? "" : TEXTCOLOR_BROWN " LB" From 73c7e513912704e91fac53fab72f874767a5b594 Mon Sep 17 00:00:00 2001 From: Michael Labbe Date: Wed, 2 Mar 2016 12:07:11 -0800 Subject: [PATCH 16/26] fix: 21:9 AR stretching in intermission, end level screens --- src/v_draw.cpp | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/src/v_draw.cpp b/src/v_draw.cpp index eeb1a7d9c..ca9f9ae72 100644 --- a/src/v_draw.cpp +++ b/src/v_draw.cpp @@ -744,6 +744,13 @@ void DCanvas::VirtualToRealCoords(double &x, double &y, double &w, double &h, double vwidth, double vheight, bool vbottom, bool handleaspect) const { int myratio = handleaspect ? CheckRatio (Width, Height) : 0; + + // if 21:9 AR, map to 16:9 for all callers. + // this allows for black bars and stops the stretching of fullscreen images + if (myratio == 6) { + myratio = 2; + } + double right = x + w; double bottom = y + h; From afb1d438c2611c4e7564c5114868eced67dd6cc0 Mon Sep 17 00:00:00 2001 From: Michael Labbe Date: Wed, 2 Mar 2016 12:33:06 -0800 Subject: [PATCH 17/26] 21:9 fix for black bars overlapping fullscreen images --- src/v_draw.cpp | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/src/v_draw.cpp b/src/v_draw.cpp index ca9f9ae72..bf3a65cdf 100644 --- a/src/v_draw.cpp +++ b/src/v_draw.cpp @@ -818,6 +818,13 @@ void DCanvas::VirtualToRealCoordsInt(int &x, int &y, int &w, int &h, void DCanvas::FillBorder (FTexture *img) { int myratio = CheckRatio (Width, Height); + + // if 21:9 AR, fill borders akin to 16:9, since all fullscreen + // images are being drawn to that scale. + if (myratio == 6) { + myratio = 2; + } + if (myratio == 0) { // This is a 4:3 display, so no border to show return; From 3ac49682184b9092e3b02a898c674b6e392d3ffd Mon Sep 17 00:00:00 2001 From: Michael Labbe Date: Wed, 2 Mar 2016 12:35:45 -0800 Subject: [PATCH 18/26] Slightly improve 21:9 ar --- src/v_video.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/v_video.cpp b/src/v_video.cpp index b69bba63f..c22402301 100644 --- a/src/v_video.cpp +++ b/src/v_video.cpp @@ -1739,7 +1739,7 @@ const int BaseRatioSizes[7][4] = { 1224, 471, 0, 48*40/51 }, // 17:10 408, 156.8627, multiplied by three { 960, 640, (int)(6.5*FRACUNIT), 48*15/16 }, // 5:4 320, 213.3333, multiplied by three { 1224, 471, 0, 48*40/51 }, // 17:10 408, 156.8627, multiplied by three (REDUNDANT) - { 568, 113, 0, 48*5/8 } // 21:9 + { 568, 113, 0, 48*9/16 } // 21:9 }; void IVideo::DumpAdapters () From a4705c84047baee72f23db8709a686e8a663a843 Mon Sep 17 00:00:00 2001 From: Michael Labbe Date: Wed, 2 Mar 2016 12:49:28 -0800 Subject: [PATCH 19/26] vid_listmodes crash fix --- src/posix/sdl/hardware.cpp | 2 +- src/win32/hardware.cpp | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/posix/sdl/hardware.cpp b/src/posix/sdl/hardware.cpp index 213ca044d..b0664319a 100644 --- a/src/posix/sdl/hardware.cpp +++ b/src/posix/sdl/hardware.cpp @@ -308,7 +308,7 @@ CUSTOM_CVAR (Float, vid_winscale, 1.f, CVAR_ARCHIVE|CVAR_GLOBALCONFIG) CCMD (vid_listmodes) { - static const char *ratios[6] = { "", " - 16:9", " - 16:10", "", " - 5:4", " - 21:9" }; + static const char *ratios[6] = { "", " - 16:9", " - 16:10", "", " - 5:4", "", " - 21:9" }; int width, height, bits; bool letterbox; diff --git a/src/win32/hardware.cpp b/src/win32/hardware.cpp index cb4250b60..8cc770556 100644 --- a/src/win32/hardware.cpp +++ b/src/win32/hardware.cpp @@ -338,7 +338,7 @@ CUSTOM_CVAR (Float, vid_winscale, 1.f, CVAR_ARCHIVE|CVAR_GLOBALCONFIG) CCMD (vid_listmodes) { - static const char *ratios[6] = { "", " - 16:9", " - 16:10", " - 17:10", " - 5:4", " - 21:9" }; + static const char *ratios[7] = { "", " - 16:9", " - 16:10", " - 17:10", " - 5:4", " - 17:10", " - 21:9" }; int width, height, bits; bool letterbox; From a28c8091fc329bb1ef8acc12f281f360851c559f Mon Sep 17 00:00:00 2001 From: Michael Labbe Date: Wed, 2 Mar 2016 13:58:29 -0800 Subject: [PATCH 20/26] UI support for 21:9 - Can specify aspect ratio 21:9 in video menu - menu_screenratios cvar can now force 21:9 --- src/menu/videomenu.cpp | 4 ++-- wadsrc/static/menudef.txt | 3 +++ 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/src/menu/videomenu.cpp b/src/menu/videomenu.cpp index 59f794fc0..1328e2f7a 100644 --- a/src/menu/videomenu.cpp +++ b/src/menu/videomenu.cpp @@ -85,7 +85,7 @@ static BYTE BitTranslate[32]; CUSTOM_CVAR (Int, menu_screenratios, -1, CVAR_ARCHIVE) { - if (self < -1 || self > 4) + if (self < -1 || self > 6) { self = -1; } @@ -216,7 +216,7 @@ static void BuildModesList (int hiwidth, int hiheight, int hi_bits) bool letterbox=false; int ratiomatch; - if (menu_screenratios >= 0 && menu_screenratios <= 4) + if (menu_screenratios >= 0 && menu_screenratios <= 6) { ratiomatch = menu_screenratios; } diff --git a/wadsrc/static/menudef.txt b/wadsrc/static/menudef.txt index a1f654b97..19b5cd771 100644 --- a/wadsrc/static/menudef.txt +++ b/wadsrc/static/menudef.txt @@ -1678,6 +1678,7 @@ OptionValue ForceRatios 5.0, "17:10" 2.0, "16:10" 4.0, "5:4" + 6.0, "21:9" } OptionValue Ratios { @@ -1685,6 +1686,7 @@ OptionValue Ratios 1.0, "16:9" 2.0, "16:10" 3.0, "17:10" + 6.0, "21:9" -1, "$OPTVAL_ALL" } OptionValue RatiosTFT @@ -1694,6 +1696,7 @@ OptionValue RatiosTFT 1.0, "16:9" 2.0, "16:10" 3.0, "17:10" + 6.0, "21:9" -1, "$OPTVAL_ALL" } From 79f07143410af621bde29efaba21d4a4d340e1dc Mon Sep 17 00:00:00 2001 From: Randy Heit Date: Thu, 3 Mar 2016 17:32:30 -0600 Subject: [PATCH 21/26] Update ratios[] tables for SDL and Cocoa --- src/posix/cocoa/i_video.mm | 2 +- src/posix/sdl/hardware.cpp | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/posix/cocoa/i_video.mm b/src/posix/cocoa/i_video.mm index 2d10a9ccb..342579274 100644 --- a/src/posix/cocoa/i_video.mm +++ b/src/posix/cocoa/i_video.mm @@ -1170,7 +1170,7 @@ CCMD(vid_listmodes) return; } - static const char* const ratios[5] = { "", " - 16:9", " - 16:10", " - 17:10", " - 5:4" }; + static const char* const ratios[7] = { "", " - 16:9", " - 16:10", " - 17:10", " - 5:4", "", " - 21:9" }; int width, height; bool letterbox; diff --git a/src/posix/sdl/hardware.cpp b/src/posix/sdl/hardware.cpp index b0664319a..6142eb1d8 100644 --- a/src/posix/sdl/hardware.cpp +++ b/src/posix/sdl/hardware.cpp @@ -308,7 +308,7 @@ CUSTOM_CVAR (Float, vid_winscale, 1.f, CVAR_ARCHIVE|CVAR_GLOBALCONFIG) CCMD (vid_listmodes) { - static const char *ratios[6] = { "", " - 16:9", " - 16:10", "", " - 5:4", "", " - 21:9" }; + static const char *ratios[7] = { "", " - 16:9", " - 16:10", "", " - 5:4", "", " - 21:9" }; int width, height, bits; bool letterbox; From 16d8af6b77cb8468c5191750150bfd684c7a1158 Mon Sep 17 00:00:00 2001 From: Randy Heit Date: Thu, 3 Mar 2016 17:59:55 -0600 Subject: [PATCH 22/26] Add some 21:9 resolutions --- src/posix/cocoa/i_video.mm | 4 ++++ src/posix/sdl/sdlvideo.cpp | 4 ++++ 2 files changed, 8 insertions(+) diff --git a/src/posix/cocoa/i_video.mm b/src/posix/cocoa/i_video.mm index 342579274..89b3714d1 100644 --- a/src/posix/cocoa/i_video.mm +++ b/src/posix/cocoa/i_video.mm @@ -357,6 +357,7 @@ VideoModes[] = { 1152, 648 }, // 16:9 { 1152, 720 }, // 16:10 { 1152, 864 }, + { 1280, 540 }, // 21:9 { 1280, 720 }, // 16:9 { 1280, 854 }, { 1280, 800 }, // 16:10 @@ -379,15 +380,18 @@ VideoModes[] = { 2048, 1152 }, // 16:9, iMac Retina 4K 21.5", HiDPI off { 2048, 1536 }, { 2304, 1440 }, // 16:10, MacBook Retina 12" + { 2560, 1080 }, // 21:9 { 2560, 1440 }, { 2560, 1600 }, { 2560, 2048 }, { 2880, 1800 }, // 16:10, MacBook Pro Retina 15" { 3200, 1800 }, + { 3440, 1440 }, // 21:9 { 3840, 2160 }, { 3840, 2400 }, { 4096, 2160 }, { 4096, 2304 }, // 16:9, iMac Retina 4K 21.5" + { 5120, 2160 }, // 21:9 { 5120, 2880 } // 16:9, iMac Retina 5K 27" }; diff --git a/src/posix/sdl/sdlvideo.cpp b/src/posix/sdl/sdlvideo.cpp index 9da52c2dd..04c3a3f2e 100644 --- a/src/posix/sdl/sdlvideo.cpp +++ b/src/posix/sdl/sdlvideo.cpp @@ -162,6 +162,7 @@ static MiniModeInfo WinModes[] = { 1152, 648 }, // 16:9 { 1152, 720 }, // 16:10 { 1152, 864 }, + { 1280, 540 }, // 21:9 { 1280, 720 }, // 16:9 { 1280, 854 }, { 1280, 800 }, // 16:10 @@ -182,14 +183,17 @@ static MiniModeInfo WinModes[] = { 1920, 1080 }, { 1920, 1200 }, { 2048, 1536 }, + { 2560, 1080 }, // 21:9 { 2560, 1440 }, { 2560, 1600 }, { 2560, 2048 }, { 2880, 1800 }, { 3200, 1800 }, + { 3440, 1440 }, // 21:9 { 3840, 2160 }, { 3840, 2400 }, { 4096, 2160 }, + { 5120, 2160 }, // 21:9 { 5120, 2880 } }; From 3c2ed52442cb3eac66ddaeb191b598da1d47fe23 Mon Sep 17 00:00:00 2001 From: Randy Heit Date: Thu, 3 Mar 2016 18:00:06 -0600 Subject: [PATCH 23/26] Fix 21:9 base width and height values --- src/v_video.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/v_video.cpp b/src/v_video.cpp index c22402301..52b8fdc86 100644 --- a/src/v_video.cpp +++ b/src/v_video.cpp @@ -1738,8 +1738,8 @@ const int BaseRatioSizes[7][4] = { 1152, 500, 0, 48*5/6 }, // 16:10 386, 166.6667, multiplied by three { 1224, 471, 0, 48*40/51 }, // 17:10 408, 156.8627, multiplied by three { 960, 640, (int)(6.5*FRACUNIT), 48*15/16 }, // 5:4 320, 213.3333, multiplied by three - { 1224, 471, 0, 48*40/51 }, // 17:10 408, 156.8627, multiplied by three (REDUNDANT) - { 568, 113, 0, 48*9/16 } // 21:9 + { 1224, 471, 0, 48*40/51 }, // 17:10 408, 156.8627, multiplied by three (REDUNDANT) + { 1707, 338, 0, 48*9/16 } // 21:9 568.8889, 337.5, multiplied by three }; void IVideo::DumpAdapters () From 81b634a798a1ef49963b921e9373e0ed2c293851 Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Thu, 3 Mar 2016 16:33:42 +0100 Subject: [PATCH 24/26] - preparation for making Trace portal aware: Added a new flag Trace_PortalRestrict, so that I could disable portals without static offset for P_LinePickActor and A_CheckLOF, because both depend on the target info being retainable which requires a static offset. --- src/p_map.cpp | 2 +- src/p_trace.h | 1 + src/thingdef/thingdef_codeptr.cpp | 2 +- 3 files changed, 3 insertions(+), 2 deletions(-) diff --git a/src/p_map.cpp b/src/p_map.cpp index e36cb9316..4d30246f3 100644 --- a/src/p_map.cpp +++ b/src/p_map.cpp @@ -4460,7 +4460,7 @@ AActor *P_LinePickActor(AActor *t1, angle_t angle, fixed_t distance, int pitch, TData.hitGhosts = true; if (Trace(t1->X(), t1->Y(), shootz, t1->Sector, vx, vy, vz, distance, - actorMask, wallMask, t1, trace, TRACE_NoSky, CheckForActor, &TData)) + actorMask, wallMask, t1, trace, TRACE_NoSky | TRACE_PortalRestrict, CheckForActor, &TData)) { if (trace.HitType == TRACE_HitActor) { diff --git a/src/p_trace.h b/src/p_trace.h index 55447e021..ef082f788 100644 --- a/src/p_trace.h +++ b/src/p_trace.h @@ -84,6 +84,7 @@ enum TRACE_NoSky = 1, // Hitting the sky returns TRACE_HitNone TRACE_PCross = 2, // Trigger SPAC_PCROSS lines TRACE_Impact = 4, // Trigger SPAC_IMPACT lines + TRACE_PortalRestrict= 8, // Cannot go through portals without a static link offset. }; // return values from callback diff --git a/src/thingdef/thingdef_codeptr.cpp b/src/thingdef/thingdef_codeptr.cpp index 5f518fab0..98dd60f2d 100644 --- a/src/thingdef/thingdef_codeptr.cpp +++ b/src/thingdef/thingdef_codeptr.cpp @@ -3870,7 +3870,7 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_CheckLOF) lof_data.Flags = flags; lof_data.BadActor = false; - Trace(pos.x, pos.y, pos.z, sec, vx, vy, vz, range, ActorFlags::FromInt(0xFFFFFFFF), ML_BLOCKEVERYTHING, self, trace, 0, + Trace(pos.x, pos.y, pos.z, sec, vx, vy, vz, range, ActorFlags::FromInt(0xFFFFFFFF), ML_BLOCKEVERYTHING, self, trace, TRACE_PortalRestrict, CheckLOFTraceFunc, &lof_data); if (trace.HitType == TRACE_HitActor || From 9f805daa735bec6cbefef769393da791abf786ba Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Thu, 3 Mar 2016 20:29:43 +0100 Subject: [PATCH 25/26] - added missing handling of ALF_PORTALRESTRICT flag. --- src/p_map.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/src/p_map.cpp b/src/p_map.cpp index 4d30246f3..09a209496 100644 --- a/src/p_map.cpp +++ b/src/p_map.cpp @@ -3702,6 +3702,7 @@ struct aim_t aim_t newtrace = Clone(); FLinePortal *port = li->getPortal(); + if (port->mType != PORTT_LINKED && (flags & ALF_PORTALRESTRICT)) return; newtrace.toppitch = toppitch; newtrace.bottompitch = bottompitch; From 0c37a90e32b8c7e1f0ae8f208d90c5ed663d8074 Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Fri, 4 Mar 2016 01:12:38 +0100 Subject: [PATCH 26/26] - moved the initial 3D floor check from Trace to TraceTraverse, because that's where it will be needed for handling portals. --- src/p_trace.cpp | 159 ++++++++++++++++++++++++++---------------------- src/p_trace.h | 3 + 2 files changed, 88 insertions(+), 74 deletions(-) diff --git a/src/p_trace.cpp b/src/p_trace.cpp index c283b7b12..297bf52bc 100644 --- a/src/p_trace.cpp +++ b/src/p_trace.cpp @@ -56,6 +56,7 @@ struct FTraceInfo void *TraceCallbackData; DWORD TraceFlags; int inshootthrough; + fixed_t startfrac; // These are required for 3D-floor checking // to create a fake sector with a floor @@ -108,78 +109,8 @@ bool Trace (fixed_t x, fixed_t y, fixed_t z, sector_t *sector, res.Crossed3DWater = NULL; */ - // Do a 3D floor check in the starting sector - TDeletingArray &ff = sector->e->XFloor.ffloors; - - if (ff.Size()) - { - memcpy(&inf.DummySector[0],sector,sizeof(sector_t)); - inf.CurSector=sector=&inf.DummySector[0]; - inf.sectorsel=1; - fixed_t bf = sector->floorplane.ZatPoint (x, y); - fixed_t bc = sector->ceilingplane.ZatPoint (x, y); - - for(unsigned int i=0;iflags&FF_EXISTS)) - continue; - - if (rover->flags&FF_SWIMMABLE && res.Crossed3DWater == NULL) - { - if (inf.Check3DFloorPlane(rover, false)) - res.Crossed3DWater = rover; - } - - if (!(rover->flags&FF_SHOOTTHROUGH)) - { - fixed_t ff_bottom=rover->bottom.plane->ZatPoint(x, y); - fixed_t ff_top=rover->top.plane->ZatPoint(x, y); - // clip to the part of the sector we are in - if (z>ff_top) - { - // above - if (bffloorplane=*rover->top.plane; - sector->SetTexture(sector_t::floor, *rover->top.texture, false); - bf=ff_top; - } - } - else if (zff_bottom) - { - sector->ceilingplane=*rover->bottom.plane; - sector->SetTexture(sector_t::ceiling, *rover->bottom.texture, false); - bc=ff_bottom; - } - } - else - { - // inside - if (bffloorplane=*rover->bottom.plane; - sector->SetTexture(sector_t::floor, *rover->bottom.texture, false); - bf=ff_bottom; - } - - if (bc>ff_top) - { - sector->ceilingplane=*rover->top.plane; - sector->SetTexture(sector_t::ceiling, *rover->top.texture, false); - bc=ff_top; - } - inf.inshootthrough = false; - } - } - } - } - // check for overflows and clip if necessary - SQWORD xd = (SQWORD)x + ( ( SQWORD(vx) * SQWORD(maxDist) )>>16); + SQWORD xd = (SQWORD)x + ((SQWORD(vx) * SQWORD(maxDist)) >> 16); if (xd>SQWORD(32767)*FRACUNIT) { @@ -191,15 +122,15 @@ bool Trace (fixed_t x, fixed_t y, fixed_t z, sector_t *sector, } - SQWORD yd = (SQWORD)y + ( ( SQWORD(vy) * SQWORD(maxDist) )>>16); + SQWORD yd = (SQWORD)y + ((SQWORD(vy) * SQWORD(maxDist)) >> 16); if (yd>SQWORD(32767)*FRACUNIT) { - maxDist = inf.MaxDist=FixedDiv(FIXED_MAX-y,vy); + maxDist = inf.MaxDist = FixedDiv(FIXED_MAX - y, vy); } else if (yd<-SQWORD(32767)*FRACUNIT) { - maxDist = inf.MaxDist=FixedDiv(FIXED_MIN-y,vy); + maxDist = inf.MaxDist = FixedDiv(FIXED_MIN - y, vy); } // recalculate the trace's end points for robustness @@ -250,6 +181,86 @@ bool Trace (fixed_t x, fixed_t y, fixed_t z, sector_t *sector, bool FTraceInfo::TraceTraverse (int ptflags) { + // Do a 3D floor check in the starting sector + TDeletingArray &ff = CurSector->e->XFloor.ffloors; + + if (ff.Size()) + { + memcpy(&DummySector[0], CurSector, sizeof(sector_t)); + CurSector = &DummySector[0]; + sectorsel = 1; + + fixed_t sdist = FixedMul(MaxDist, startfrac); + fixed_t x = StartX + FixedMul(Vx, sdist); + fixed_t y = StartY + FixedMul(Vy, sdist); + fixed_t z = StartZ + FixedMul(Vz, sdist); + + fixed_t bf = CurSector->floorplane.ZatPoint(x, y); + fixed_t bc = CurSector->ceilingplane.ZatPoint(x, y); + + for (auto rover : ff) + { + if (!(rover->flags&FF_EXISTS)) + continue; + + if (rover->flags&FF_SWIMMABLE && Results->Crossed3DWater == NULL) + { + if (Check3DFloorPlane(rover, false)) + Results->Crossed3DWater = rover; + } + + if (!(rover->flags&FF_SHOOTTHROUGH)) + { + fixed_t ff_bottom = rover->bottom.plane->ZatPoint(x, y); + fixed_t ff_top = rover->top.plane->ZatPoint(x, y); + // clip to the part of the sector we are in + if (z>ff_top) + { + // above + if (bffloorplane = *rover->top.plane; + CurSector->SetTexture(sector_t::floor, *rover->top.texture, false); + CurSector->SkyBoxes[sector_t::floor] == NULL; + bf = ff_top; + } + } + else if (zff_bottom) + { + CurSector->ceilingplane = *rover->bottom.plane; + CurSector->SetTexture(sector_t::ceiling, *rover->bottom.texture, false); + bc = ff_bottom; + CurSector->SkyBoxes[sector_t::ceiling] == NULL; + } + } + else + { + // inside + if (bffloorplane = *rover->bottom.plane; + CurSector->SetTexture(sector_t::floor, *rover->bottom.texture, false); + CurSector->SkyBoxes[sector_t::floor] == NULL; + bf = ff_bottom; + } + + if (bc>ff_top) + { + CurSector->ceilingplane = *rover->top.plane; + CurSector->SetTexture(sector_t::ceiling, *rover->top.texture, false); + CurSector->SkyBoxes[sector_t::ceiling] == NULL; + bc = ff_top; + } + inshootthrough = false; + } + } + } + } + + FPathTraverse it(StartX, StartY, FixedMul (Vx, MaxDist), FixedMul (Vy, MaxDist), ptflags | PT_DELTA); intercept_t *in; diff --git a/src/p_trace.h b/src/p_trace.h index ef082f788..1b0815833 100644 --- a/src/p_trace.h +++ b/src/p_trace.h @@ -65,6 +65,9 @@ struct FTraceResults sector_t *Sector; FTextureID HitTexture; fixed_t X, Y, Z; + fixedvec3 SrcFromTarget; + angle_t SrcAngleToTarget; + fixed_t Distance; fixed_t Fraction;