From 1d937b9f3c83b1af4f6a933174a1331ee3bbbc68 Mon Sep 17 00:00:00 2001 From: "alexey.lysiuk" Date: Sat, 30 Jun 2018 11:41:51 +0300 Subject: [PATCH 01/16] - removed Class identifier workaround from Cocoa backend --- src/posix/cocoa/i_input.mm | 5 ----- src/posix/cocoa/i_main.mm | 5 ----- src/posix/cocoa/i_video.mm | 5 ----- src/posix/osx/iwadpicker_cocoa.mm | 5 ----- 4 files changed, 20 deletions(-) diff --git a/src/posix/cocoa/i_input.mm b/src/posix/cocoa/i_input.mm index c6fc86e44..b019e56ff 100644 --- a/src/posix/cocoa/i_input.mm +++ b/src/posix/cocoa/i_input.mm @@ -35,9 +35,6 @@ #import -// Avoid collision between DObject class and Objective-C -#define Class ObjectClass - #include "c_console.h" #include "c_cvars.h" #include "c_dispatch.h" @@ -49,8 +46,6 @@ #include "v_video.h" #include "events.h" -#undef Class - EXTERN_CVAR(Int, m_use_mouse) diff --git a/src/posix/cocoa/i_main.mm b/src/posix/cocoa/i_main.mm index e1b388d3d..66d610af7 100644 --- a/src/posix/cocoa/i_main.mm +++ b/src/posix/cocoa/i_main.mm @@ -36,9 +36,6 @@ #include -// Avoid collision between DObject class and Objective-C -#define Class ObjectClass - #include "c_console.h" #include "c_cvars.h" #include "cmdlib.h" @@ -48,8 +45,6 @@ #include "st_console.h" #include "version.h" -#undef Class - #define ZD_UNUSED(VARIABLE) ((void)(VARIABLE)) diff --git a/src/posix/cocoa/i_video.mm b/src/posix/cocoa/i_video.mm index c6ee90eb1..0477772fb 100644 --- a/src/posix/cocoa/i_video.mm +++ b/src/posix/cocoa/i_video.mm @@ -35,9 +35,6 @@ #include "i_common.h" -// Avoid collision between DObject class and Objective-C -#define Class ObjectClass - #include "bitmap.h" #include "c_dispatch.h" #include "doomstat.h" @@ -55,8 +52,6 @@ #include "gl/system/gl_framebuffer.h" #include "gl/textures/gl_samplers.h" -#undef Class - @implementation NSWindow(ExitAppOnClose) diff --git a/src/posix/osx/iwadpicker_cocoa.mm b/src/posix/osx/iwadpicker_cocoa.mm index 2b25f680e..2e42b4c5a 100644 --- a/src/posix/osx/iwadpicker_cocoa.mm +++ b/src/posix/osx/iwadpicker_cocoa.mm @@ -33,9 +33,6 @@ ** */ -// Avoid collision between DObject class and Objective-C -#define Class ObjectClass - #include "cmdlib.h" #include "d_main.h" #include "version.h" @@ -44,8 +41,6 @@ #include "m_misc.h" #include "gameconfigfile.h" -#undef Class - #include #include From 5d27c16f30fd1ff2ed54eac1511222e55712a8ff Mon Sep 17 00:00:00 2001 From: "alexey.lysiuk" Date: Sat, 30 Jun 2018 11:44:22 +0300 Subject: [PATCH 02/16] - disabled default values for out parameters https://forum.zdoom.org/viewtopic.php?t=61128 --- src/scripting/zscript/zcc_compile.cpp | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/scripting/zscript/zcc_compile.cpp b/src/scripting/zscript/zcc_compile.cpp index 08131d15f..cc8424b50 100644 --- a/src/scripting/zscript/zcc_compile.cpp +++ b/src/scripting/zscript/zcc_compile.cpp @@ -2524,6 +2524,11 @@ void ZCCCompiler::CompileFunction(ZCC_StructWork *c, ZCC_FuncDeclarator *f, bool } else if (p->Default != nullptr) { + if (flags & VARF_Out) + { + Error(p, "Out parameters cannot have default values"); + } + flags |= VARF_Optional; hasoptionals = true; From 43b94d829e2ec6d2af2906daec5722f1c0250e6a Mon Sep 17 00:00:00 2001 From: "alexey.lysiuk" Date: Sat, 30 Jun 2018 15:11:21 +0300 Subject: [PATCH 03/16] - fixed crash when actor is destroyed during spawning This only applies to spawning via summon... CCMDs Now 'summon decal 0' no longer crashes the game --- src/d_net.cpp | 19 ++++++++++--------- 1 file changed, 10 insertions(+), 9 deletions(-) diff --git a/src/d_net.cpp b/src/d_net.cpp index 2e8e9aca2..85a093cb8 100644 --- a/src/d_net.cpp +++ b/src/d_net.cpp @@ -2364,16 +2364,17 @@ void Net_DoCommand (int type, uint8_t **stream, int player) spawned->flags &= ~MF_FRIENDLY; spawned->health = spawned->SpawnHealth(); } - } - if (type >= DEM_SUMMON2 && type <= DEM_SUMMONFOE2) - { - spawned->Angles.Yaw = source->Angles.Yaw - angle; - spawned->tid = tid; - spawned->special = special; - for(i = 0; i < 5; i++) { - spawned->args[i] = args[i]; + + if (type >= DEM_SUMMON2 && type <= DEM_SUMMONFOE2) + { + spawned->Angles.Yaw = source->Angles.Yaw - angle; + spawned->tid = tid; + spawned->special = special; + for(i = 0; i < 5; i++) { + spawned->args[i] = args[i]; + } + if(tid) spawned->AddToHash(); } - if(tid) spawned->AddToHash(); } } } From 0a139e90fb624cf1ba337a9c83950b4a10a1d7f9 Mon Sep 17 00:00:00 2001 From: "alexey.lysiuk" Date: Sat, 30 Jun 2018 20:27:04 +0300 Subject: [PATCH 04/16] - restored initial clamping for blend colors https://forum.zdoom.org/viewtopic.php?t=61134 --- src/v_draw.cpp | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/v_draw.cpp b/src/v_draw.cpp index 49e445995..20d49bc10 100644 --- a/src/v_draw.cpp +++ b/src/v_draw.cpp @@ -1418,7 +1418,11 @@ void DFrameBuffer::DrawBlend(sector_t * viewsector) V_AddBlend(player->BlendR, player->BlendG, player->BlendB, player->BlendA, blend); } - screen->Dim(PalEntry(255, uint8_t(blend[0] * 255), uint8_t(blend[1] * 255), uint8_t(blend[2] * 255)), blend[3], 0, 0, screen->GetWidth(), screen->GetHeight()); + const float br = clamp(blend[0] * 255.f, 0.f, 255.f); + const float bg = clamp(blend[1] * 255.f, 0.f, 255.f); + const float bb = clamp(blend[2] * 255.f, 0.f, 255.f); + const PalEntry bcolor(255, uint8_t(br), uint8_t(bg), uint8_t(bb)); + screen->Dim(bcolor, blend[3], 0, 0, screen->GetWidth(), screen->GetHeight()); } From 6d6ee1281ef246c764bc493d2f6e69c3861a7e89 Mon Sep 17 00:00:00 2001 From: Magnus Norddahl Date: Sun, 1 Jul 2018 14:41:35 +0200 Subject: [PATCH 05/16] - softpoly: fix normal walls not getting rendered for subsectors with poly objects in them --- src/polyrenderer/scene/poly_scene.cpp | 38 ++++++++++----------------- 1 file changed, 14 insertions(+), 24 deletions(-) diff --git a/src/polyrenderer/scene/poly_scene.cpp b/src/polyrenderer/scene/poly_scene.cpp index 284f24b1a..2f5e36702 100644 --- a/src/polyrenderer/scene/poly_scene.cpp +++ b/src/polyrenderer/scene/poly_scene.cpp @@ -148,8 +148,6 @@ void RenderPolyScene::RenderSubsector(PolyRenderThread *thread, subsector_t *sub sector_t *frontsector = sub->sector; frontsector->MoreFlags |= SECMF_DRAWN; - bool mainBSP = sub->polys == nullptr; - if (sub->polys) { if (sub->BSP == nullptr || sub->BSP->bDirty) @@ -172,35 +170,27 @@ void RenderPolyScene::RenderSubsector(PolyRenderThread *thread, subsector_t *sub { RenderPolyNode(thread, &sub->BSP->Nodes.Last(), subsectorDepth, frontsector); } - - Render3DFloorPlane::RenderPlanes(thread, sub, CurrentViewpoint->StencilValue, subsectorDepth, thread->TranslucentObjects); - RenderPolyPlane::RenderPlanes(thread, sub, CurrentViewpoint->StencilValue, Cull.MaxCeilingHeight, Cull.MinFloorHeight, thread->SectorPortals, CurrentViewpoint->SectorPortalsStart); } - else + + PolyTransferHeights fakeflat(sub); + + Render3DFloorPlane::RenderPlanes(thread, sub, CurrentViewpoint->StencilValue, subsectorDepth, thread->TranslucentObjects); + RenderPolyPlane::RenderPlanes(thread, fakeflat, CurrentViewpoint->StencilValue, Cull.MaxCeilingHeight, Cull.MinFloorHeight, thread->SectorPortals, CurrentViewpoint->SectorPortalsStart); + + for (uint32_t i = 0; i < sub->numlines; i++) { - PolyTransferHeights fakeflat(sub); - - Render3DFloorPlane::RenderPlanes(thread, sub, CurrentViewpoint->StencilValue, subsectorDepth, thread->TranslucentObjects); - RenderPolyPlane::RenderPlanes(thread, fakeflat, CurrentViewpoint->StencilValue, Cull.MaxCeilingHeight, Cull.MinFloorHeight, thread->SectorPortals, CurrentViewpoint->SectorPortalsStart); - - for (uint32_t i = 0; i < sub->numlines; i++) + if (Cull.IsLineSegVisible(subsectorDepth, i)) { - if (Cull.IsLineSegVisible(subsectorDepth, i)) - { - seg_t *line = &sub->firstline[i]; - RenderLine(thread, sub, line, fakeflat.FrontSector, subsectorDepth); - } + seg_t *line = &sub->firstline[i]; + RenderLine(thread, sub, line, fakeflat.FrontSector, subsectorDepth); } } - if (mainBSP) + int subsectorIndex = sub->Index(); + for (int i = ParticlesInSubsec[subsectorIndex]; i != NO_PARTICLE; i = Particles[i].snext) { - int subsectorIndex = sub->Index(); - for (int i = ParticlesInSubsec[subsectorIndex]; i != NO_PARTICLE; i = Particles[i].snext) - { - particle_t *particle = Particles + i; - thread->TranslucentObjects.push_back(thread->FrameMemory->NewObject(particle, sub, subsectorDepth, CurrentViewpoint->StencilValue)); - } + particle_t *particle = Particles + i; + thread->TranslucentObjects.push_back(thread->FrameMemory->NewObject(particle, sub, subsectorDepth, CurrentViewpoint->StencilValue)); } } From 2e5b7a7d8bb03e2b9557aad9f37638ad7cd613d8 Mon Sep 17 00:00:00 2001 From: Magnus Norddahl Date: Sun, 1 Jul 2018 20:53:50 +0200 Subject: [PATCH 06/16] - softpoly: fix sprites still lit when dynlights off --- src/polyrenderer/scene/poly_sprite.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/polyrenderer/scene/poly_sprite.cpp b/src/polyrenderer/scene/poly_sprite.cpp index 3b1b4347b..7c0676a2e 100644 --- a/src/polyrenderer/scene/poly_sprite.cpp +++ b/src/polyrenderer/scene/poly_sprite.cpp @@ -372,7 +372,7 @@ FTexture *RenderPolySprite::GetSpriteTexture(AActor *thing, /*out*/ bool &flipX) void RenderPolySprite::SetDynlight(AActor *thing, PolyDrawArgs &args) { bool fullbrightSprite = ((thing->renderflags & RF_FULLBRIGHT) || (thing->flags5 & MF5_BRIGHT)); - if (fullbrightSprite) + if (fullbrightSprite || !r_dynlights) { args.SetDynLightColor(0); return; From c29651da95ce7c4c6e64625a17737c12c13c5903 Mon Sep 17 00:00:00 2001 From: "alexey.lysiuk" Date: Mon, 2 Jul 2018 17:31:48 +0300 Subject: [PATCH 07/16] - restored initial grayscale conversion in fragment shader Accidental change of red color multiplier was discovered during investigation of https://forum.zdoom.org/viewtopic.php?t=61126 --- wadsrc/static/shaders/glsl/main.fp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/wadsrc/static/shaders/glsl/main.fp b/wadsrc/static/shaders/glsl/main.fp index 0fdd3abdd..013a1881e 100644 --- a/wadsrc/static/shaders/glsl/main.fp +++ b/wadsrc/static/shaders/glsl/main.fp @@ -25,7 +25,7 @@ vec3 ProcessMaterial(vec3 material, vec3 color); float grayscale(vec4 color) { - return dot(color.rgb, vec3(0.4, 0.56, 0.14)); + return dot(color.rgb, vec3(0.3, 0.56, 0.14)); } //=========================================================================== From 158890e0cec882b8bc43cd6508363ed0f4194bf2 Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Mon, 2 Jul 2018 19:12:48 +0200 Subject: [PATCH 08/16] - fixed : Decals used the wrong texture variant. --- src/hwrenderer/scene/hw_decal.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/hwrenderer/scene/hw_decal.cpp b/src/hwrenderer/scene/hw_decal.cpp index fca5b9ef3..f9c59a79f 100644 --- a/src/hwrenderer/scene/hw_decal.cpp +++ b/src/hwrenderer/scene/hw_decal.cpp @@ -112,7 +112,7 @@ void GLWall::ProcessDecal(HWDrawInfo *di, DBaseDecal *decal, const FVector3 &nor zpos = decal->Z + frontsector->GetPlaneTexZ(sector_t::ceiling); } } - FMaterial *tex = FMaterial::ValidateTexture(texture, true); + FMaterial *tex = FMaterial::ValidateTexture(texture, false); // now clip the decal to the actual polygon From e5249f302afa80db44f0f685d2ea1e45b52d21c1 Mon Sep 17 00:00:00 2001 From: Marisa Kirisame Date: Sat, 16 Jun 2018 19:24:08 +0200 Subject: [PATCH 09/16] UE1: Clean up and restructure model class. UE1: Add support for Deus Ex format vertex data. UE1: Group triangles by skin index AND type/flags (preparation for per-surface render style support). UE1: Add handling of Weapon Triangle (preparation for model attachment support). UE1: Support flat shaded triangle flag. --- src/r_data/models/models_ue1.cpp | 178 ++++++++++++++++++++----------- src/r_data/models/models_ue1.h | 35 +++++- 2 files changed, 145 insertions(+), 68 deletions(-) diff --git a/src/r_data/models/models_ue1.cpp b/src/r_data/models/models_ue1.cpp index 682b5c37e..2b763077f 100644 --- a/src/r_data/models/models_ue1.cpp +++ b/src/r_data/models/models_ue1.cpp @@ -28,11 +28,11 @@ float unpackuvert( uint32_t n, int c ) { switch( c ) { - case 2: + case 0: return ((int16_t)((n&0x7ff)<<5))/128.f; case 1: return ((int16_t)(((n>>11)&0x7ff)<<5))/128.f; - case 0: + case 2: return ((int16_t)(((n>>22)&0x3ff)<<6))/128.f; default: return 0.f; @@ -41,66 +41,74 @@ float unpackuvert( uint32_t n, int c ) bool FUE1Model::Load( const char *filename, int lumpnum, const char *buffer, int length ) { - mLumpNum = lumpnum; int lumpnum2; - FMemLump lump2; - const char *buffer2; FString realfilename = Wads.GetLumpFullName(lumpnum); if ( (size_t)realfilename.IndexOf("_d.3d") == realfilename.Len()-5 ) { realfilename.Substitute("_d.3d","_a.3d"); lumpnum2 = Wads.CheckNumForFullName(realfilename); - lump2 = Wads.ReadLump(lumpnum2); - buffer2 = (char*)lump2.GetMem(); - // map structures - dhead = (d3dhead*)(buffer); - dpolys = (d3dpoly*)(buffer+sizeof(d3dhead)); - ahead = (a3dhead*)(buffer2); - averts = (uint32_t*)(buffer2+sizeof(a3dhead)); + mDataLump = lumpnum; + mAnivLump = lumpnum2; } else { realfilename.Substitute("_a.3d","_d.3d"); lumpnum2 = Wads.CheckNumForFullName(realfilename); - lump2 = Wads.ReadLump(lumpnum2); - buffer2 = (char*)lump2.GetMem(); - // map structures - dhead = (d3dhead*)(buffer2); - dpolys = (d3dpoly*)(buffer2+sizeof(d3dhead)); - ahead = (a3dhead*)(buffer); - averts = (uint32_t*)(buffer+sizeof(a3dhead)); + mAnivLump = lumpnum; + mDataLump = lumpnum2; } - // set counters - numVerts = dhead->numverts; - numFrames = ahead->numframes; - numPolys = dhead->numpolys; - numGroups = 0; - groupIndices.Reset(); - uint8_t used[256] = {0}; - for ( int i=0; iframesize/dhead->numverts) == 8 ) + { + averts = NULL; + dxverts = (dxvert*)(buffer2+sizeof(a3dhead)); + } + else + { + averts = (uint32_t*)(buffer2+sizeof(a3dhead)); + dxverts = NULL; + } + weaponPoly = -1; + // set counters + numVerts = dhead->numverts; + numFrames = ahead->numframes; + numPolys = dhead->numpolys; + numGroups = 0; // populate vertex arrays for ( int i=0; isurfaceskinIDs[curMDLIndex][i].isValid() ) - sskin = TexMan(curSpriteMDLFrame->surfaceskinIDs[curMDLIndex][i]); + if ( curSpriteMDLFrame->surfaceskinIDs[curMDLIndex][groups[i].texNum].isValid() ) + sskin = TexMan(curSpriteMDLFrame->surfaceskinIDs[curMDLIndex][groups[i].texNum]); if ( !sskin ) { vofs += vsize; continue; } } + // TODO: Handle per-group render styles and other flags once functions for it are implemented + // Future note: poly renderstyles should always be enforced unless the actor itself has a style other than Normal renderer->SetMaterial(sskin,false,translation); GetVertexBuffer(renderer)->SetupFrame(renderer,vofs+frame*fsize,vofs+frame2*fsize,vsize); renderer->DrawArrays(0,vsize); @@ -207,6 +251,8 @@ void FUE1Model::BuildVertexBuffer( FModelRenderer *renderer ) { if (GetVertexBuffer(renderer)) return; + if ( !mDataLoaded ) + LoadGeometry(); int vsize = 0; for ( int i=0; iSet(V.Pos.X,V.Pos.Y,V.Pos.Z,C.X,C.Y); - vert->SetNormal(V.Normal.X,V.Normal.Y,V.Normal.Z); + if ( groups[j].type&PT_Curvy ) // use facet normal + { + vert->SetNormal(polys[groups[j].P[k]].Normal.X, + polys[groups[j].P[k]].Normal.Y, + polys[groups[j].P[k]].Normal.Z); + } + else vert->SetNormal(V.Normal.X,V.Normal.Y,V.Normal.Z); } } } @@ -238,8 +290,8 @@ void FUE1Model::BuildVertexBuffer( FModelRenderer *renderer ) void FUE1Model::AddSkins( uint8_t *hitlist ) { for ( int i=0; isurfaceskinIDs[curMDLIndex][i].isValid() ) - hitlist[curSpriteMDLFrame->surfaceskinIDs[curMDLIndex][i].GetIndex()] |= FTextureManager::HIT_Flat; + if ( curSpriteMDLFrame->surfaceskinIDs[curMDLIndex][groups[i].texNum].isValid() ) + hitlist[curSpriteMDLFrame->surfaceskinIDs[curMDLIndex][groups[i].texNum].GetIndex()] |= FTextureManager::HIT_Flat; } FUE1Model::~FUE1Model() diff --git a/src/r_data/models/models_ue1.h b/src/r_data/models/models_ue1.h index dc6209fa2..fb67758f7 100644 --- a/src/r_data/models/models_ue1.h +++ b/src/r_data/models/models_ue1.h @@ -5,6 +5,23 @@ class FUE1Model : public FModel { public: + enum EPolyType + { + PT_Normal = 0, // normal renderstyle + PT_TwoSided = 1, // like normal, but don't cull backfaces + PT_Translucent = 2, // additive blending + PT_Masked = 3, // draw with alpha testing + PT_Modulated = 4, // overlay-like blending (rgb values below 128 darken, 128 is unchanged, and above 128 lighten) + // types mask + PT_Type = 7, + // flags + PT_WeaponTriangle = 0x08, // this poly is used for positioning a weapon attachment and should not be drawn + PT_Unlit = 0x10, // this poly is fullbright + PT_Curvy = 0x20, // this poly uses the facet normal + PT_EnvironmentMap = 0x40, // vertex UVs are remapped to their view-space X and Z normals, fake cubemap look + PT_NoSmooth = 0x80 // this poly forcibly uses nearest filtering + }; + bool Load(const char * fn, int lumpnum, const char * buffer, int length) override; int FindFrame(const char * name) override; void RenderFrame(FModelRenderer *renderer, FTexture * skin, int frame, int frame2, double inter, int translation=0) override; @@ -14,7 +31,9 @@ public: void UnloadGeometry(); FUE1Model() { - mLumpNum = -1; + mDataLump = -1; + mAnivLump = -1; + mDataLoaded = false; dhead = NULL; dpolys = NULL; ahead = NULL; @@ -27,7 +46,8 @@ public: ~FUE1Model(); private: - int mLumpNum; + int mDataLump, mAnivLump; + bool mDataLoaded; // raw data structures struct d3dhead @@ -54,6 +74,11 @@ private: d3dpoly * dpolys; a3dhead * ahead; uint32_t * averts; + struct dxvert + { + int16_t x, y, z, pad; + }; + dxvert * dxverts; // converted data structures struct UE1Vertex @@ -64,21 +89,21 @@ private: { int V[3]; FVector2 C[3]; - int texNum; + FVector3 Normal; }; struct UE1Group { TArray P; - int numPolys; + int numPolys, texNum, type; }; int numVerts; int numFrames; int numPolys; int numGroups; + int weaponPoly; // for future model attachment support, unused for now TArray verts; TArray polys; TArray groups; - TArray groupIndices; }; From 2a59327aebcdea245c96dddcb255ed15f8c38c05 Mon Sep 17 00:00:00 2001 From: David Carlier Date: Thu, 5 Jul 2018 21:10:07 +0100 Subject: [PATCH 10/16] foo being allocated with metadata based allocator needs to be freed similarly. --- src/textures/formats/rawpagetexture.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/textures/formats/rawpagetexture.cpp b/src/textures/formats/rawpagetexture.cpp index d2beade83..0d42544fe 100644 --- a/src/textures/formats/rawpagetexture.cpp +++ b/src/textures/formats/rawpagetexture.cpp @@ -97,7 +97,7 @@ static bool CheckIfRaw(FileReader & data) } else if (ofs >= 64000-1) // Need one byte for an empty column { - free (foo); + M_Free (foo); return true; } else @@ -108,14 +108,14 @@ static bool CheckIfRaw(FileReader & data) { if (foo2[ofs] == 255) { - free (foo); + M_Free (foo); return true; } ofs += foo2[ofs+1] + 4; } if (ofs >= 64000) { - free (foo); + M_Free (foo); return true; } } From 55ae431c02b42349dd1062146a74a7919418e141 Mon Sep 17 00:00:00 2001 From: "alexey.lysiuk" Date: Sat, 7 Jul 2018 12:04:41 +0300 Subject: [PATCH 11/16] - fixed crash on setting particular CVARs Game crashed when any of gl_brightfog, gl_lightadditivesurfaces, gl_notexturefill CVARs is set with no level loaded There was impossible to reset settings to defaults because of this --- src/g_level.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/g_level.cpp b/src/g_level.cpp index d5a9e9489..5997e489e 100644 --- a/src/g_level.cpp +++ b/src/g_level.cpp @@ -106,17 +106,17 @@ void G_VerifySkill(); CUSTOM_CVAR(Bool, gl_brightfog, false, CVAR_ARCHIVE | CVAR_NOINITCALL) { - if (level.info->brightfog == -1) level.brightfog = self; + if (level.info == nullptr || level.info->brightfog == -1) level.brightfog = self; } CUSTOM_CVAR(Bool, gl_lightadditivesurfaces, false, CVAR_ARCHIVE | CVAR_NOINITCALL) { - if (level.info->lightadditivesurfaces == -1) level.lightadditivesurfaces = self; + if (level.info == nullptr || level.info->lightadditivesurfaces == -1) level.lightadditivesurfaces = self; } CUSTOM_CVAR(Bool, gl_notexturefill, false, CVAR_NOINITCALL) { - if (level.info->notexturefill == -1) level.notexturefill = self; + if (level.info == nullptr || level.info->notexturefill == -1) level.notexturefill = self; } CUSTOM_CVAR(Int, gl_lightmode, 3, CVAR_ARCHIVE | CVAR_NOINITCALL) From 6239796b92d958d7988f0e0bdb724d90f2599dea Mon Sep 17 00:00:00 2001 From: argv-minus-one Date: Sun, 8 Jul 2018 17:04:19 -0700 Subject: [PATCH 12/16] Move RandomSpawner's recursion check into PostBeginPlay. Previously, a RandomSpawner with infinite recursion would hang the game, because the recursion check was happening before the recursion counter (bouncecount) was set. --- wadsrc/static/zscript/shared/randomspawner.txt | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/wadsrc/static/zscript/shared/randomspawner.txt b/wadsrc/static/zscript/shared/randomspawner.txt index 24892aeec..28313bbb7 100644 --- a/wadsrc/static/zscript/shared/randomspawner.txt +++ b/wadsrc/static/zscript/shared/randomspawner.txt @@ -84,7 +84,7 @@ class RandomSpawner : Actor } } // So now we can spawn the dropped item. - if (di == null || bouncecount >= MAX_RANDOMSPAWNERS_RECURSION) // Prevents infinite recursions + if (di == null) { Spawn("Unknown", Pos, NO_REPLACE); // Show that there's a problem. Destroy(); @@ -131,6 +131,13 @@ class RandomSpawner : Actor Actor newmobj = null; bool boss = false; + if (bouncecount >= MAX_RANDOMSPAWNERS_RECURSION) // Prevents infinite recursions + { + Spawn("Unknown", Pos, NO_REPLACE); // Show that there's a problem. + Destroy(); + return; + } + if (Species == 'None') { Destroy(); From ce1aa7e96220ee69431a576225e87a7a711c18e9 Mon Sep 17 00:00:00 2001 From: argv-minus-one Date: Sun, 8 Jul 2018 17:29:35 -0700 Subject: [PATCH 13/16] Move RandomSpawner's random selection logic into a virtual method. With this, one can use its self-replacement code (which copies a bunch of its state into the replacement actor, and monitors for boss death if appropriate), but select the replacement class based on some other criteria (map number, the player's RPG stats, the player's class, etc). --- .../static/zscript/shared/randomspawner.txt | 100 +++++++++++------- 1 file changed, 63 insertions(+), 37 deletions(-) diff --git a/wadsrc/static/zscript/shared/randomspawner.txt b/wadsrc/static/zscript/shared/randomspawner.txt index 28313bbb7..be7118c5c 100644 --- a/wadsrc/static/zscript/shared/randomspawner.txt +++ b/wadsrc/static/zscript/shared/randomspawner.txt @@ -27,18 +27,16 @@ class RandomSpawner : Actor return GetDefaultByType(pclass).bIsMonster; } - - // To handle "RandomSpawning" missiles, the code has to be split in two parts. - // If the following code is not done in BeginPlay, missiles will use the - // random spawner's velocity (0...) instead of their own. - override void BeginPlay() + + // Override this to decide what to spawn in some other way. + // Return the class name, or 'None' to spawn nothing, or 'Unknown' to spawn an error marker. + virtual Name ChooseSpawn() { DropItem di; // di will be our drop item list iterator DropItem drop; // while drop stays as the reference point. int n = 0; bool nomonsters = sv_nomonsters || level.nomonsters; - Super.BeginPlay(); drop = di = GetDropItems(); if (di != null) { @@ -57,8 +55,7 @@ class RandomSpawner : Actor } if (n == 0) { // Nothing left to spawn. They must have all been monsters, and monsters are disabled. - Destroy(); - return; + return 'None'; } // Then we reset the iterator to the start position... di = drop; @@ -83,40 +80,69 @@ class RandomSpawner : Actor di = di.Next; } } - // So now we can spawn the dropped item. if (di == null) { - Spawn("Unknown", Pos, NO_REPLACE); // Show that there's a problem. - Destroy(); - return; + return 'Unknown'; } else if (random[randomspawn]() <= di.Probability) // prob 255 = always spawn, prob 0 = almost never spawn. { - // Handle replacement here so as to get the proper speed and flags for missiles - Class cls = di.Name; - if (cls != null) + return di.Name; + } + else + { + return 'None'; + } + } + else + { + return 'None'; + } + } + + // To handle "RandomSpawning" missiles, the code has to be split in two parts. + // If the following code is not done in BeginPlay, missiles will use the + // random spawner's velocity (0...) instead of their own. + override void BeginPlay() + { + Super.BeginPlay(); + let s = ChooseSpawn(); + + if (s == 'Unknown') // Spawn error markers immediately. + { + Spawn(s, Pos, NO_REPLACE); + Destroy(); + } + else if (s == 'None') // ChooseSpawn chose to spawn nothing. + { + Destroy(); + } + else + { + // So now we can spawn the dropped item. + // Handle replacement here so as to get the proper speed and flags for missiles + Class cls = s; + if (cls != null) + { + Class rep = GetReplacement(cls); + if (rep != null) { - Class rep = GetReplacement(cls); - if (rep != null) - { - cls = rep; - } - } - if (cls != null) - { - Species = Name(cls); - readonly defmobj = GetDefaultByType(cls); - Speed = defmobj.Speed; - bMissile |= defmobj.bMissile; - bSeekerMissile |= defmobj.bSeekerMissile; - bSpectral |= defmobj.bSpectral; - } - else - { - A_Log(TEXTCOLOR_RED .. "Unknown item class ".. di.Name .." to drop from a random spawner\n"); - Species = 'None'; + cls = rep; } } + if (cls != null) + { + Species = Name(cls); + readonly defmobj = GetDefaultByType(cls); + Speed = defmobj.Speed; + bMissile |= defmobj.bMissile; + bSeekerMissile |= defmobj.bSeekerMissile; + bSpectral |= defmobj.bSpectral; + } + else + { + A_Log(TEXTCOLOR_RED .. "Unknown item class ".. s .." to drop from a random spawner\n"); + Species = 'None'; + } } } @@ -128,9 +154,6 @@ class RandomSpawner : Actor { Super.PostBeginPlay(); - Actor newmobj = null; - bool boss = false; - if (bouncecount >= MAX_RANDOMSPAWNERS_RECURSION) // Prevents infinite recursions { Spawn("Unknown", Pos, NO_REPLACE); // Show that there's a problem. @@ -138,6 +161,9 @@ class RandomSpawner : Actor return; } + Actor newmobj = null; + bool boss = false; + if (Species == 'None') { Destroy(); From 23a4daac23ed864961b769d5d6fb0fe139beb802 Mon Sep 17 00:00:00 2001 From: "alexey.lysiuk" Date: Wed, 11 Jul 2018 17:26:09 +0300 Subject: [PATCH 14/16] - skipped owned items in proximity test https://forum.zdoom.org/viewtopic.php?t=61224 --- src/p_things.cpp | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/src/p_things.cpp b/src/p_things.cpp index 2f5bd5555..4012a5872 100644 --- a/src/p_things.cpp +++ b/src/p_things.cpp @@ -737,6 +737,15 @@ int P_Thing_CheckProximity(AActor *self, PClass *classname, double distance, int else if (classname != mo->GetClass()) continue; + if (mo->IsKindOf(RUNTIME_CLASS(AInventory))) + { + // Skip owned item because its position could remain unchanged since attachment to owner + // Most likely it is the last location of this item in the world before pick up + AInventory *const inventory = static_cast(mo); + if (inventory != nullptr && inventory->Owner != nullptr) + continue; + } + // [MC]Make sure it's in range and respect the desire for Z or not. The function forces it to use // Z later for ensuring CLOSEST and FARTHEST flags are respected perfectly. // Ripped from sphere checking in A_RadiusGive (along with a number of things). From dfe635dd4a52d5643845445e6c510ec674d4153d Mon Sep 17 00:00:00 2001 From: Erick Tenorio Date: Wed, 11 Jul 2018 19:21:51 -0500 Subject: [PATCH 15/16] TNT.WAD fixes MAP07 - Dropping onto the outdoor lava will now raise triangle sectors. Should be impossible to get stuck in them now. MAP08 - Fix (what I presume to be an unintentional) missing texture. --- wadsrc/static/zscript/level_compatibility.txt | 20 +++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/wadsrc/static/zscript/level_compatibility.txt b/wadsrc/static/zscript/level_compatibility.txt index d91f1b19b..08ac52a15 100644 --- a/wadsrc/static/zscript/level_compatibility.txt +++ b/wadsrc/static/zscript/level_compatibility.txt @@ -135,6 +135,26 @@ class LevelCompatibility play } break; } + + case '0F898F0688AECD42F2CD102FAE06F271': // TNT: Evilution MAP07 + { + // Dropping onto the outdoor lava now also raises the + // triangle sectors. + SetLineSpecial(320, Floor_RaiseToNearest, 16, 32); + SetLineActivation(320, SPAC_Cross); + SetLineSpecial(959, Floor_RaiseToNearest, 16, 32); + SetLineActivation(959, SPAC_Cross); + SetLineSpecial(960, Floor_RaiseToNearest, 16, 32); + SetLineActivation(960, SPAC_Cross); + break; + } + + case '1E785E841A5247B6223C042EC712EBB3': // TNT: Evilution MAP08 + { + // Missing texture when lowering sector to red keycard + SetWallTexture(480, Line.back, Side.Bottom, "METAL2"); + break; + } case 'DFC18B92BF3E8142B8684ECD8BD2EF06': // TNT: Evilution map15 { From 2d0fb4ed2ec5146f1a0d935abe6679065f40fd7b Mon Sep 17 00:00:00 2001 From: Marisa Kirisame Date: Thu, 7 Jun 2018 20:58:31 +0200 Subject: [PATCH 16/16] Adds 2D shape (triangle array) drawer, usable from ZScript. Handles most drawtexture parameters excluding those related to scaling, at the moment. --- src/v_2ddrawer.cpp | 97 ++++++++++++++++++++++++++++++++++ src/v_2ddrawer.h | 20 +++++++ src/v_draw.cpp | 44 +++++++++++++++ src/v_video.h | 2 + wadsrc/static/zscript/base.txt | 16 ++++++ 5 files changed, 179 insertions(+) diff --git a/src/v_2ddrawer.cpp b/src/v_2ddrawer.cpp index bbf9105fe..72c2ccc69 100644 --- a/src/v_2ddrawer.cpp +++ b/src/v_2ddrawer.cpp @@ -31,9 +31,51 @@ #include "r_utility.h" #include "v_video.h" #include "g_levellocals.h" +#include "vm.h" EXTERN_CVAR(Float, transsouls) +IMPLEMENT_CLASS(DShape2D, false, false) + +DEFINE_ACTION_FUNCTION(DShape2D, Clear) +{ + PARAM_SELF_PROLOGUE(DShape2D); + PARAM_INT(which); + if ( which&C_Verts ) self->mVertices.Clear(); + if ( which&C_Coords ) self->mCoords.Clear(); + if ( which&C_Indices ) self->mIndices.Clear(); + return 0; +} + +DEFINE_ACTION_FUNCTION(DShape2D, PushVertex) +{ + PARAM_SELF_PROLOGUE(DShape2D); + PARAM_FLOAT(x); + PARAM_FLOAT(y); + self->mVertices.Push(DVector2(x,y)); + return 0; +} + +DEFINE_ACTION_FUNCTION(DShape2D, PushCoord) +{ + PARAM_SELF_PROLOGUE(DShape2D); + PARAM_FLOAT(u); + PARAM_FLOAT(v); + self->mCoords.Push(DVector2(u,v)); + return 0; +} + +DEFINE_ACTION_FUNCTION(DShape2D, PushTriangle) +{ + PARAM_SELF_PROLOGUE(DShape2D); + PARAM_INT(a); + PARAM_INT(b); + PARAM_INT(c); + self->mIndices.Push(a); + self->mIndices.Push(b); + self->mIndices.Push(c); + return 0; +} //========================================================================== // @@ -314,6 +356,61 @@ void F2DDrawer::AddTexture(FTexture *img, DrawParms &parms) // //========================================================================== +void F2DDrawer::AddShape( FTexture *img, DShape2D *shape, DrawParms &parms ) +{ + if (parms.style.BlendOp == STYLEOP_None) return; // not supposed to be drawn. + + PalEntry vertexcolor; + + RenderCommand dg; + + dg.mType = DrawTypeTriangles; + dg.mVertCount = shape->mVertices.Size(); + dg.mFlags |= DTF_Wrap; + dg.mTexture = img; + + dg.mTranslation = 0; + SetStyle(img, parms, vertexcolor, dg); + + if (!img->bHasCanvas && parms.remap != nullptr && !parms.remap->Inactive) + dg.mTranslation = parms.remap; + + double minx = 16383, miny = 16383, maxx = -16384, maxy = -16384; + for ( int i=0; imVertices[i].X < minx ) minx = shape->mVertices[i].X; + if ( shape->mVertices[i].Y < miny ) miny = shape->mVertices[i].Y; + if ( shape->mVertices[i].X > maxx ) maxx = shape->mVertices[i].X; + if ( shape->mVertices[i].Y > maxy ) maxy = shape->mVertices[i].Y; + } + if (minx < (double)parms.lclip || miny < (double)parms.uclip || maxx >(double)parms.rclip || maxy >(double)parms.dclip) + { + dg.mScissor[0] = parms.lclip; + dg.mScissor[1] = parms.uclip; + dg.mScissor[2] = parms.rclip; + dg.mScissor[3] = parms.dclip; + dg.mFlags |= DTF_Scissor; + } + else + memset(dg.mScissor, 0, sizeof(dg.mScissor)); + + dg.mVertIndex = (int)mVertices.Reserve(dg.mVertCount); + TwoDVertex *ptr = &mVertices[dg.mVertIndex]; + for ( int i=0; imVertices[i].X, shape->mVertices[i].Y, 0, shape->mCoords[i].X, shape->mCoords[i].Y, vertexcolor); + dg.mIndexIndex = mIndices.Size(); + dg.mIndexCount += shape->mIndices.Size(); + for ( int i=0; imIndices.Size()); i+=3 ) + AddIndices(dg.mVertIndex, 3, shape->mIndices[i], shape->mIndices[i+1], shape->mIndices[i+2]); + AddCommand(&dg); +} + +//========================================================================== +// +// +// +//========================================================================== + void F2DDrawer::AddPoly(FTexture *texture, FVector2 *points, int npoints, double originx, double originy, double scalex, double scaley, DAngle rotation, const FColormap &colormap, PalEntry flatcolor, int lightlevel) diff --git a/src/v_2ddrawer.h b/src/v_2ddrawer.h index 96fb51782..7502fcb1f 100644 --- a/src/v_2ddrawer.h +++ b/src/v_2ddrawer.h @@ -9,6 +9,25 @@ struct DrawParms; +// intermediate struct for shape drawing + +enum EClearWhich +{ + C_Verts = 1, + C_Coords = 2, + C_Indices = 4, +}; + +class DShape2D : public DObject +{ + + DECLARE_CLASS(DShape2D,DObject) +public: + TArray mIndices; + TArray mVertices; + TArray mCoords; +}; + class F2DDrawer { public: @@ -117,6 +136,7 @@ public: public: void AddTexture(FTexture *img, DrawParms &parms); + void AddShape(FTexture *img, DShape2D *shape, DrawParms &parms); void AddPoly(FTexture *texture, FVector2 *points, int npoints, double originx, double originy, double scalex, double scaley, DAngle rotation, const FColormap &colormap, PalEntry flatcolor, int lightlevel); diff --git a/src/v_draw.cpp b/src/v_draw.cpp index 20d49bc10..80b8ffcd8 100644 --- a/src/v_draw.cpp +++ b/src/v_draw.cpp @@ -189,6 +189,50 @@ void DFrameBuffer::DrawTextureParms(FTexture *img, DrawParms &parms) m2DDrawer.AddTexture(img, parms); } +//========================================================================== +// +// ZScript arbitrary textured shape drawing functions +// +//========================================================================== + +void DFrameBuffer::DrawShape(FTexture *img, DShape2D *shape, int tags_first, ...) +{ + Va_List tags; + va_start(tags.list, tags_first); + DrawParms parms; + + bool res = ParseDrawTextureTags(img, 0, 0, tags_first, tags, &parms, false); + va_end(tags.list); + if (!res) return; + m2DDrawer.AddShape(img, shape, parms); +} + +void DFrameBuffer::DrawShape(FTexture *img, DShape2D *shape, VMVa_List &args) +{ + DrawParms parms; + uint32_t tag = ListGetInt(args); + + bool res = ParseDrawTextureTags(img, 0, 0, tag, args, &parms, false); + if (!res) return; + m2DDrawer.AddShape(img, shape, parms); +} + +DEFINE_ACTION_FUNCTION(_Screen, DrawShape) +{ + PARAM_PROLOGUE; + PARAM_INT(texid); + PARAM_BOOL(animate); + PARAM_POINTER(shape, DShape2D); + + if (!screen->HasBegun2D()) ThrowAbortException(X_OTHER, "Attempt to draw to screen outside a draw function"); + + FTexture *tex = animate ? TexMan(FSetTextureID(texid)) : TexMan[FSetTextureID(texid)]; + VMVa_List args = { param + 3, 0, numparam - 3 }; + + screen->DrawShape(tex, shape, args); + return 0; +} + //========================================================================== // // Clipping rect diff --git a/src/v_video.h b/src/v_video.h index 9e4df8013..e329939ab 100644 --- a/src/v_video.h +++ b/src/v_video.h @@ -484,6 +484,8 @@ public: bool SetTextureParms(DrawParms *parms, FTexture *img, double x, double y) const; void DrawTexture(FTexture *img, double x, double y, int tags, ...); void DrawTexture(FTexture *img, double x, double y, VMVa_List &); + void DrawShape(FTexture *img, DShape2D *shape, int tags, ...); + void DrawShape(FTexture *img, DShape2D *shape, VMVa_List &); void FillBorder(FTexture *img); // Fills the border around a 4:3 part of the screen on non-4:3 displays void VirtualToRealCoords(double &x, double &y, double &w, double &h, double vwidth, double vheight, bool vbottom = false, bool handleaspect = true) const; diff --git a/wadsrc/static/zscript/base.txt b/wadsrc/static/zscript/base.txt index e2c111e3f..e1ecc9fed 100644 --- a/wadsrc/static/zscript/base.txt +++ b/wadsrc/static/zscript/base.txt @@ -165,6 +165,21 @@ enum DrawTextureTags }; +class Shape2D : Object native +{ + enum EClearWhich + { + C_Verts = 1, + C_Coords = 2, + C_Indices = 4, + }; + + native void Clear( int which = C_Verts|C_Coords|C_Indices ); + native void PushVertex( Vector2 v ); + native void PushCoord( Vector2 c ); + native void PushTriangle( int a, int b, int c ); +} + struct Screen native { native static Color PaletteColor(int index); @@ -174,6 +189,7 @@ struct Screen native native static void Dim(Color col, double amount, int x, int y, int w, int h); native static vararg void DrawTexture(TextureID tex, bool animate, double x, double y, ...); + native static vararg void DrawShape(TextureID tex, bool animate, Shape2D s, ...); native static vararg void DrawChar(Font font, int normalcolor, double x, double y, int character, ...); native static vararg void DrawText(Font font, int normalcolor, double x, double y, String text, ...); native static void DrawLine(int x0, int y0, int x1, int y1, Color color);