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(); } } } 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) 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 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). 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)); } } 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; diff --git a/src/posix/cocoa/i_input.mm b/src/posix/cocoa/i_input.mm index c3f6d4116..87abe4298 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 1e6e9cc19..03613636d 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" @@ -54,8 +51,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 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; }; 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; 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; } } diff --git a/src/v_2ddrawer.cpp b/src/v_2ddrawer.cpp index 8a2df8313..e359be374 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; +} //========================================================================== // @@ -318,6 +360,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 c1c08d3b7..ec88dc908 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 5deaada9e..59192cd8b 100644 --- a/src/v_draw.cpp +++ b/src/v_draw.cpp @@ -190,6 +190,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 @@ -1451,7 +1495,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()); } diff --git a/src/v_video.h b/src/v_video.h index ec17b86fa..2480a5e32 100644 --- a/src/v_video.h +++ b/src/v_video.h @@ -492,6 +492,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/shaders/glsl/main.fp b/wadsrc/static/shaders/glsl/main.fp index 441d5f987..2a2f88ccd 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)); } //=========================================================================== 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); 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 { diff --git a/wadsrc/static/zscript/shared/randomspawner.txt b/wadsrc/static/zscript/shared/randomspawner.txt index 24892aeec..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 || bouncecount >= MAX_RANDOMSPAWNERS_RECURSION) // Prevents infinite recursions + 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,6 +154,13 @@ class RandomSpawner : Actor { Super.PostBeginPlay(); + if (bouncecount >= MAX_RANDOMSPAWNERS_RECURSION) // Prevents infinite recursions + { + Spawn("Unknown", Pos, NO_REPLACE); // Show that there's a problem. + Destroy(); + return; + } + Actor newmobj = null; bool boss = false;