From 0f62cd67a511f41e89275506de3ae749fa2a1c20 Mon Sep 17 00:00:00 2001 From: "alexey.lysiuk" Date: Sat, 3 Feb 2018 13:24:54 +0200 Subject: [PATCH 1/9] Added compatibility entry for Ultimate Simplicity MAP04 Now it's possible to get 100% kills on lower skill levels --- wadsrc/static/compatibility.txt | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/wadsrc/static/compatibility.txt b/wadsrc/static/compatibility.txt index ff360f96b..b7754018f 100644 --- a/wadsrc/static/compatibility.txt +++ b/wadsrc/static/compatibility.txt @@ -376,6 +376,14 @@ F481922F4881F74760F3C0437FD5EDD0 // map03 setlinespecial 1008 Door_Open 0 64 0 0 0 } +7ED9800213C00D6E7FB98652AB48B3DE // Ultimate Simplicity, map04 +{ + // Add missing map spots on easy and medium skills + // Demons will teleport into starting room making 100% kills possible + setthingskills 31 31 + setthingskills 32 31 +} + 1891E029994B023910CFE0B3209C3CDB // Ultimate Simplicity, map07 { // It is possible to get stuck on skill 0 or 1 when no shots have been fired From d5bc0a1fa9bc178d20be8411a1c3b54155486367 Mon Sep 17 00:00:00 2001 From: "alexey.lysiuk" Date: Sat, 3 Feb 2018 14:39:01 +0200 Subject: [PATCH 2/9] Uniform way to guard ACS stack and variables ACS VM stack and map/world/global variables arrays are now checked for out of bounds access --- src/p_acs.cpp | 56 +++++++++++++++++++-------------------------------- src/p_acs.h | 31 ++++++++++++++++++++++------ 2 files changed, 46 insertions(+), 41 deletions(-) diff --git a/src/p_acs.cpp b/src/p_acs.cpp index 3e5358a3c..e36cecde7 100644 --- a/src/p_acs.cpp +++ b/src/p_acs.cpp @@ -835,12 +835,12 @@ inline int uallong(const int &foo) //============================================================================ // ACS variables with world scope -int32_t ACS_WorldVars[NUM_WORLDVARS]; -FWorldGlobalArray ACS_WorldArrays[NUM_WORLDVARS]; +static BoundsCheckingArray ACS_WorldVars; +static BoundsCheckingArray ACS_WorldArrays; // ACS variables with global scope -int32_t ACS_GlobalVars[NUM_GLOBALVARS]; -FWorldGlobalArray ACS_GlobalArrays[NUM_GLOBALVARS]; +BoundsCheckingArray ACS_GlobalVars; +BoundsCheckingArray ACS_GlobalArrays; //---------------------------------------------------------------------------- // @@ -851,21 +851,7 @@ FWorldGlobalArray ACS_GlobalArrays[NUM_GLOBALVARS]; // //---------------------------------------------------------------------------- -struct FACSStackMemory -{ - int32_t& operator[](const size_t index) - { - if (index >= STACK_SIZE) - { - I_Error("Corrupted stack pointer in ACS VM"); - } - - return buffer[index]; - } - -private: - int32_t buffer[STACK_SIZE]; -}; +using FACSStackMemory = BoundsCheckingArray; struct FACSStack { @@ -1470,10 +1456,10 @@ void ACSStringPool::UnlockForLevel(int lnum) void P_MarkWorldVarStrings() { - GlobalACSStrings.MarkStringArray(ACS_WorldVars, countof(ACS_WorldVars)); - for (size_t i = 0; i < countof(ACS_WorldArrays); ++i) + GlobalACSStrings.MarkStringArray(ACS_WorldVars.Pointer(), ACS_WorldVars.Size()); + for (size_t i = 0; i < ACS_WorldArrays.Size(); ++i) { - GlobalACSStrings.MarkStringMap(ACS_WorldArrays[i]); + GlobalACSStrings.MarkStringMap(ACS_WorldArrays.Pointer()[i]); } } @@ -1485,10 +1471,10 @@ void P_MarkWorldVarStrings() void P_MarkGlobalVarStrings() { - GlobalACSStrings.MarkStringArray(ACS_GlobalVars, countof(ACS_GlobalVars)); - for (size_t i = 0; i < countof(ACS_GlobalArrays); ++i) + GlobalACSStrings.MarkStringArray(ACS_GlobalVars.Pointer(), ACS_GlobalVars.Size()); + for (size_t i = 0; i < ACS_GlobalArrays.Size(); ++i) { - GlobalACSStrings.MarkStringMap(ACS_GlobalArrays[i]); + GlobalACSStrings.MarkStringMap(ACS_GlobalArrays.Pointer()[i]); } } @@ -1571,14 +1557,14 @@ void P_ClearACSVars(bool alsoglobal) { int i; - memset (ACS_WorldVars, 0, sizeof(ACS_WorldVars)); + ACS_WorldVars.Fill(0); for (i = 0; i < NUM_WORLDVARS; ++i) { ACS_WorldArrays[i].Clear (); } if (alsoglobal) { - memset (ACS_GlobalVars, 0, sizeof(ACS_GlobalVars)); + ACS_GlobalVars.Fill(0); for (i = 0; i < NUM_GLOBALVARS; ++i) { ACS_GlobalArrays[i].Clear (); @@ -1726,10 +1712,10 @@ static void ReadArrayVars (FSerializer &file, FWorldGlobalArray *vars, size_t co void P_ReadACSVars(FSerializer &arc) { - ReadVars (arc, ACS_WorldVars, NUM_WORLDVARS, "acsworldvars"); - ReadVars (arc, ACS_GlobalVars, NUM_GLOBALVARS, "acsglobalvars"); - ReadArrayVars (arc, ACS_WorldArrays, NUM_WORLDVARS, "acsworldarrays"); - ReadArrayVars (arc, ACS_GlobalArrays, NUM_GLOBALVARS, "acsglobalarrays"); + ReadVars (arc, ACS_WorldVars.Pointer(), NUM_WORLDVARS, "acsworldvars"); + ReadVars (arc, ACS_GlobalVars.Pointer(), NUM_GLOBALVARS, "acsglobalvars"); + ReadArrayVars (arc, ACS_WorldArrays.Pointer(), NUM_WORLDVARS, "acsworldarrays"); + ReadArrayVars (arc, ACS_GlobalArrays.Pointer(), NUM_GLOBALVARS, "acsglobalarrays"); GlobalACSStrings.ReadStrings(arc, "acsglobalstrings"); } @@ -1741,10 +1727,10 @@ void P_ReadACSVars(FSerializer &arc) void P_WriteACSVars(FSerializer &arc) { - WriteVars (arc, ACS_WorldVars, NUM_WORLDVARS, "acsworldvars"); - WriteVars (arc, ACS_GlobalVars, NUM_GLOBALVARS, "acsglobalvars"); - WriteArrayVars (arc, ACS_WorldArrays, NUM_WORLDVARS, "acsworldarrays"); - WriteArrayVars (arc, ACS_GlobalArrays, NUM_GLOBALVARS, "acsglobalarrays"); + WriteVars (arc, ACS_WorldVars.Pointer(), NUM_WORLDVARS, "acsworldvars"); + WriteVars (arc, ACS_GlobalVars.Pointer(), NUM_GLOBALVARS, "acsglobalvars"); + WriteArrayVars (arc, ACS_WorldArrays.Pointer(), NUM_WORLDVARS, "acsworldarrays"); + WriteArrayVars (arc, ACS_GlobalArrays.Pointer(), NUM_GLOBALVARS, "acsglobalarrays"); GlobalACSStrings.WriteStrings(arc, "acsglobalstrings"); } diff --git a/src/p_acs.h b/src/p_acs.h index 4f53ce1a3..7b0d18bd8 100644 --- a/src/p_acs.h +++ b/src/p_acs.h @@ -60,13 +60,32 @@ struct InitIntToZero }; typedef TMap, InitIntToZero> FWorldGlobalArray; -// ACS variables with world scope -extern int32_t ACS_WorldVars[NUM_WORLDVARS]; -extern FWorldGlobalArray ACS_WorldArrays[NUM_WORLDVARS]; +// Type of elements count is unsigned int instead of size_t to match ACSStringPool interface +template +struct BoundsCheckingArray +{ + T &operator[](const unsigned int index) + { + if (index >= N) + { + I_Error("Out of bounds memory access in ACS VM"); + } + + return buffer[index]; + } + + T *Pointer() { return buffer; } + unsigned int Size() const { return N; } + + void Fill(const T &value) { std::fill(std::begin(buffer), std::end(buffer), value); } + +private: + T buffer[N]; +}; // ACS variables with global scope -extern int32_t ACS_GlobalVars[NUM_GLOBALVARS]; -extern FWorldGlobalArray ACS_GlobalArrays[NUM_GLOBALVARS]; +extern BoundsCheckingArray ACS_GlobalVars; +extern BoundsCheckingArray ACS_GlobalArrays; #define LIBRARYID_MASK 0xFFF00000 #define LIBRARYID_SHIFT 20 @@ -359,7 +378,7 @@ public: ACSProfileInfo *GetFunctionProfileData(ScriptFunction *func) { return GetFunctionProfileData((int)(func - (ScriptFunction *)Functions)); } const char *LookupString (uint32_t index) const; - int32_t *MapVars[NUM_MAPVARS]; + BoundsCheckingArray MapVars; static FBehavior *StaticLoadModule (int lumpnum, FileReader * fr=NULL, int len=0); static void StaticLoadDefaultModules (); From af7648a151a73e12fa0a10e6595b2517cadb4d63 Mon Sep 17 00:00:00 2001 From: "alexey.lysiuk" Date: Sat, 3 Feb 2018 16:26:49 +0200 Subject: [PATCH 3/9] Made PlayerRespawn skill definition consistent Now it works the same as AllowRespawn map definition in MAPINFO --- src/g_level.cpp | 3 ++- wadsrc/static/zscript/shared/player.txt | 2 +- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/src/g_level.cpp b/src/g_level.cpp index 17f76a67d..d6c712b24 100644 --- a/src/g_level.cpp +++ b/src/g_level.cpp @@ -648,7 +648,8 @@ void G_ChangeLevel(const char *levelname, int position, int flags, int nextSkill // If this is co-op, respawn any dead players now so they can // keep their inventory on the next map. - if ((multiplayer || level.flags2 & LEVEL2_ALLOWRESPAWN || sv_singleplayerrespawn) && !deathmatch && player->playerstate == PST_DEAD) + if ((multiplayer || level.flags2 & LEVEL2_ALLOWRESPAWN || sv_singleplayerrespawn || !!G_SkillProperty(SKILLP_PlayerRespawn)) + && !deathmatch && player->playerstate == PST_DEAD) { // Copied from the end of P_DeathThink [[ player->cls = NULL; // Force a new class if the player is using a random class diff --git a/wadsrc/static/zscript/shared/player.txt b/wadsrc/static/zscript/shared/player.txt index d43a59ce2..8ecce11cb 100644 --- a/wadsrc/static/zscript/shared/player.txt +++ b/wadsrc/static/zscript/shared/player.txt @@ -528,7 +528,7 @@ class PlayerPawn : Actor native if (level.time >= player.respawn_time || ((player.cmd.buttons & BT_USE) && player.Bot == NULL)) { player.cls = NULL; // Force a new class if the player is using a random class - player.playerstate = (multiplayer || (level.AllowRespawn) || sv_singleplayerrespawn)? PST_REBORN : PST_ENTER; + player.playerstate = (multiplayer || level.AllowRespawn || sv_singleplayerrespawn || G_SkillPropertyInt(SKILLP_PlayerRespawn)) ? PST_REBORN : PST_ENTER; if (special1 > 2) { special1 = 0; From 364ce773e3f9ba659772348d00e6a18adb55e2ce Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Sun, 4 Feb 2018 08:49:41 +0100 Subject: [PATCH 4/9] - Update to UDMF spec. --- specs/udmf_zdoom.txt | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/specs/udmf_zdoom.txt b/specs/udmf_zdoom.txt index 185160461..185d2a6de 100644 --- a/specs/udmf_zdoom.txt +++ b/specs/udmf_zdoom.txt @@ -283,6 +283,7 @@ Note: All fields default to false unless mentioned otherwise. For things with ACS specials (80-86 and 226), if arg0str is present and non-null, it will be used as the name of the script to execute, and arg0 will be ignored. + On dynamic lights, arg0str can be used to set a color by name, this will supersede all args which are normally used to define a color. } @@ -426,6 +427,9 @@ floor_reflect and ceiling_reflect. 1.28 28.01.2017 sector material colors. +1.29 04.02.2018 +arg0str in dynamic lights. + =============================================================================== EOF =============================================================================== From ef867c3415cef8fbfb93c9a2bf3f84d4da324442 Mon Sep 17 00:00:00 2001 From: ZZYZX Date: Sun, 4 Feb 2018 09:57:06 +0200 Subject: [PATCH 5/9] Fixed arg0str for dynamic light actors --- src/p_mobj.cpp | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/p_mobj.cpp b/src/p_mobj.cpp index e0c9530d3..8e5e1d3a2 100644 --- a/src/p_mobj.cpp +++ b/src/p_mobj.cpp @@ -6101,6 +6101,9 @@ AActor *P_SpawnMapThing (FMapThing *mthing, int position) if (mthing->arg0str != NAME_None) { PalEntry color = V_GetColor(nullptr, mthing->arg0str); + light->args[0] = color.r; + light->args[1] = color.g; + light->args[2] = color.b; } else if (light->lightflags & LF_SPOT) { From 32287511e238f56a5b05e2cdad22d3a18cdbc29a Mon Sep 17 00:00:00 2001 From: Rachael Alexanderson Date: Sun, 4 Feb 2018 04:11:02 -0500 Subject: [PATCH 6/9] - change type 9854 to SpotLightFlickerRandomAttitive since its old definition was just a duplicate of another one. --- wadsrc/static/mapinfo/common.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/wadsrc/static/mapinfo/common.txt b/wadsrc/static/mapinfo/common.txt index 1c1559b06..b79ecd5f4 100644 --- a/wadsrc/static/mapinfo/common.txt +++ b/wadsrc/static/mapinfo/common.txt @@ -118,7 +118,7 @@ DoomEdNums 9851 = SpotLightPulseAdditive 9852 = SpotLightFlickerAdditive 9853 = SectorSpotLightAdditive - 9854 = SpotLightFlickerRandomSubtractive + 9854 = SpotLightFlickerRandomAdditive 9860 = SpotLightSubtractive 9861 = SpotLightPulseSubtractive 9862 = SpotLightFlickerSubtractive From 18ad975c7ae8f9548ef3bad3422f18db0d3ae980 Mon Sep 17 00:00:00 2001 From: "alexey.lysiuk" Date: Sun, 4 Feb 2018 17:42:39 +0200 Subject: [PATCH 7/9] Added compatibility entry for Ultimate Simplicity MAP11 This eliminates potential blocker in level progression --- wadsrc/static/compatibility.txt | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/wadsrc/static/compatibility.txt b/wadsrc/static/compatibility.txt index b7754018f..b78b4e664 100644 --- a/wadsrc/static/compatibility.txt +++ b/wadsrc/static/compatibility.txt @@ -394,6 +394,13 @@ F481922F4881F74760F3C0437FD5EDD0 // map03 setlinespecial 411 NoiseAlert 0 0 0 0 0 } +F0E6F30F57B0425F17E43600AA813E80 // Ultimate Simplicity, map11 +{ + // If door (sector #309) is closed it cannot be open again + // from one side potentially blocking level progression + clearlinespecial 2445 +} + 952CC8D03572E17BA550B01B366EFBB9 // Cheogsh map01 { // make the blue key spawn above the 3D floor From ed230080696916286af4884fc1db69522ee0dd76 Mon Sep 17 00:00:00 2001 From: "alexey.lysiuk" Date: Wed, 7 Feb 2018 11:37:02 +0200 Subject: [PATCH 8/9] Fixed crash in stereoscopic modes caused by camera without player https://forum.zdoom.org/viewtopic.php?t=55039&start=381#p1039251 --- src/gl/scene/gl_scene.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/gl/scene/gl_scene.cpp b/src/gl/scene/gl_scene.cpp index a0bcb4882..178b39ff7 100644 --- a/src/gl/scene/gl_scene.cpp +++ b/src/gl/scene/gl_scene.cpp @@ -842,7 +842,7 @@ sector_t * GLSceneDrawer::RenderViewpoint (AActor * camera, GL_IRECT * bounds, f stereo3dMode.SetUp(); for (int eye_ix = 0; eye_ix < stereo3dMode.eye_count(); ++eye_ix) { - if (eye_ix > 0) + if (eye_ix > 0 && camera->player) SetFixedColormap(camera->player); // reiterate color map for each eye, so night vision goggles work in both eyes const s3d::EyePose * eye = stereo3dMode.getEyePose(eye_ix); eye->SetUp(); From 7cbe8669b687b1c560bab4f69d2fd1d832b4286f Mon Sep 17 00:00:00 2001 From: Magnus Norddahl Date: Sat, 10 Feb 2018 00:06:47 +0100 Subject: [PATCH 9/9] - fix decals not getting lit by lights not having a target while still having the LF_DONTLIGHTSELF flag - fix decal light not being calculated from the center of the decal --- src/gl/scene/gl_decal.cpp | 2 +- src/gl/scene/gl_spritelight.cpp | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/gl/scene/gl_decal.cpp b/src/gl/scene/gl_decal.cpp index cf2310209..0f3bc7ffb 100644 --- a/src/gl/scene/gl_decal.cpp +++ b/src/gl/scene/gl_decal.cpp @@ -289,7 +289,7 @@ void GLWall::DrawDecal(DBaseDecal *decal) // Note: This should be replaced with proper shader based lighting. double x, y; decal->GetXY(seg->sidedef, x, y); - gl_SetDynSpriteLight(NULL, x, y, zpos, sub); + gl_SetDynSpriteLight(nullptr, x, y, zpos - decalheight * 0.5f, sub); } // alpha color only has an effect when using an alpha texture. diff --git a/src/gl/scene/gl_spritelight.cpp b/src/gl/scene/gl_spritelight.cpp index ac7e6971e..1415ce16c 100644 --- a/src/gl/scene/gl_spritelight.cpp +++ b/src/gl/scene/gl_spritelight.cpp @@ -74,7 +74,7 @@ void gl_SetDynSpriteLight(AActor *self, float x, float y, float z, subsector_t * while (node) { light=node->lightsource; - if (light->visibletoplayer && !(light->flags2&MF2_DORMANT) && (!(light->lightflags&LF_DONTLIGHTSELF) || light->target != self) && !(light->lightflags&LF_DONTLIGHTACTORS)) + if (light->visibletoplayer && !(light->flags2&MF2_DORMANT) && (!(light->lightflags&LF_DONTLIGHTSELF) || light->target != self || !self) && !(light->lightflags&LF_DONTLIGHTACTORS)) { float dist; FVector3 L;