diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 7610d957cb..3601815dc9 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -1150,6 +1150,7 @@ set (PCH_SOURCES p_pusher.cpp p_saveg.cpp p_scroll.cpp + p_secnodes.cpp p_sectors.cpp p_setup.cpp p_sight.cpp diff --git a/src/actor.h b/src/actor.h index 5445c92be7..ffe3cc1a41 100644 --- a/src/actor.h +++ b/src/actor.h @@ -1148,8 +1148,8 @@ public: // a linked list of sectors where this object appears struct msecnode_t *touching_sectorlist; // phares 3/14/98 - struct msecnode_t *render_sectorlist; // same for cross-sectorportal rendering - struct portnode_t *render_portallist; // and for cross-lineportal + struct msecnode_t *touching_sectorportallist; // same for cross-sectorportal rendering + struct portnode_t *touching_lineportallist; // and for cross-lineportal struct msecnode_t *touching_rendersectors; // this is the list of sectors that this thing interesects with it's max(radius, renderradius). int validcount; diff --git a/src/gl/data/gl_setup.cpp b/src/gl/data/gl_setup.cpp index 376b4aa6d2..3b72c98635 100644 --- a/src/gl/data/gl_setup.cpp +++ b/src/gl/data/gl_setup.cpp @@ -302,9 +302,9 @@ static void PrepareSectorData() static void PrepareTransparentDoors(sector_t * sector) { bool solidwall=false; - int notextures=0; - int nobtextures=0; - int selfref=0; + unsigned int notextures=0; + unsigned int nobtextures=0; + unsigned int selfref=0; sector_t * nextsec=NULL; #ifdef _DEBUG diff --git a/src/gl/dynlights/gl_glow.cpp b/src/gl/dynlights/gl_glow.cpp index e0ed6d0f66..2e324b63e0 100644 --- a/src/gl/dynlights/gl_glow.cpp +++ b/src/gl/dynlights/gl_glow.cpp @@ -125,7 +125,7 @@ int gl_CheckSpriteGlow(sector_t *sector, int lightlevel, const DVector3 &pos) } } } - else if (c != -1) + else if (c != ~0u) { bottomglowcolor[0] = c.r / 255.f; bottomglowcolor[1] = c.g / 255.f; @@ -171,7 +171,7 @@ bool gl_GetWallGlow(sector_t *sector, float *topglowcolor, float *bottomglowcolo } } } - else if (c != -1) + else if (c != ~0u) { topglowcolor[0] = c.r / 255.f; topglowcolor[1] = c.g / 255.f; @@ -195,7 +195,7 @@ bool gl_GetWallGlow(sector_t *sector, float *topglowcolor, float *bottomglowcolo } } } - else if (c != -1) + else if (c != ~0u) { bottomglowcolor[0] = c.r / 255.f; bottomglowcolor[1] = c.g / 255.f; @@ -214,4 +214,4 @@ CCMD(setglow) auto s = players[0].mo->Sector; s->planes[sector_t::floor].GlowHeight = 128; s->planes[sector_t::floor].GlowColor = 0xff0000; -} \ No newline at end of file +} diff --git a/src/gl/hqnx/common.h b/src/gl/hqnx/common.h index c3e7005717..fa807df771 100644 --- a/src/gl/hqnx/common.h +++ b/src/gl/hqnx/common.h @@ -48,9 +48,9 @@ static inline uint32_t rgb_to_yuv(uint32_t c) /* Test if there is difference in color */ static inline int yuv_diff(uint32_t yuv1, uint32_t yuv2) { - return (( abs((int64_t)(yuv1 & Ymask) - (int64_t)(yuv2 & Ymask)) > trY ) || - ( abs((int64_t)(yuv1 & Umask) - (int64_t)(yuv2 & Umask)) > trU ) || - ( abs((int64_t)(yuv1 & Vmask) - (int64_t)(yuv2 & Vmask)) > trV ) ); + return (( abs((int32_t)(yuv1 & Ymask) - (int32_t)(yuv2 & Ymask)) > trY ) || + ( abs((int32_t)(yuv1 & Umask) - (int32_t)(yuv2 & Umask)) > trU ) || + ( abs((int32_t)(yuv1 & Vmask) - (int32_t)(yuv2 & Vmask)) > trV ) ); } static inline int Diff(uint32_t c1, uint32_t c2) diff --git a/src/gl/renderer/gl_colormap.h b/src/gl/renderer/gl_colormap.h index 96107b6165..4c755856bc 100644 --- a/src/gl/renderer/gl_colormap.h +++ b/src/gl/renderer/gl_colormap.h @@ -5,7 +5,7 @@ #include "v_palette.h" #include "r_data/colormaps.h" -extern DWORD gl_fixedcolormap; +extern int gl_fixedcolormap; struct lightlist_t; diff --git a/src/gl/renderer/gl_lightdata.h b/src/gl/renderer/gl_lightdata.h index a1abf8c823..7af5e7a4f8 100644 --- a/src/gl/renderer/gl_lightdata.h +++ b/src/gl/renderer/gl_lightdata.h @@ -35,7 +35,7 @@ inline bool gl_isWhite(PalEntry color) return color.r + color.g + color.b == 3*0xff; } -extern DWORD gl_fixedcolormap; +extern int gl_fixedcolormap; inline bool gl_isFullbright(PalEntry color, int lightlevel) { @@ -61,4 +61,4 @@ inline void FColormap::CopyFrom3DLight(lightlist_t *light) -#endif \ No newline at end of file +#endif diff --git a/src/gl/renderer/gl_postprocess.cpp b/src/gl/renderer/gl_postprocess.cpp index f35071854f..30c0000d33 100644 --- a/src/gl/renderer/gl_postprocess.cpp +++ b/src/gl/renderer/gl_postprocess.cpp @@ -323,7 +323,7 @@ void FGLRenderer::UpdateCameraExposure() glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); // Find the average value: - for (int i = 0; i + 1 < mBuffers->ExposureLevels.Size(); i++) + for (unsigned int i = 0; i + 1 < mBuffers->ExposureLevels.Size(); i++) { const auto &level = mBuffers->ExposureLevels[i]; const auto &next = mBuffers->ExposureLevels[i + 1]; diff --git a/src/gl/renderer/gl_renderbuffers.cpp b/src/gl/renderer/gl_renderbuffers.cpp index b14ee98525..fad79767c6 100644 --- a/src/gl/renderer/gl_renderbuffers.cpp +++ b/src/gl/renderer/gl_renderbuffers.cpp @@ -448,7 +448,7 @@ void FGLRenderBuffers::CreateExposureLevels(int width, int height) void FGLRenderBuffers::CreateEyeBuffers(int eye) { - if (mEyeFBs.Size() > eye) + if (mEyeFBs.Size() > unsigned(eye)) return; GLint activeTex, textureBinding, frameBufferBinding; @@ -457,7 +457,7 @@ void FGLRenderBuffers::CreateEyeBuffers(int eye) glGetIntegerv(GL_TEXTURE_BINDING_2D, &textureBinding); glGetIntegerv(GL_FRAMEBUFFER_BINDING, &frameBufferBinding); - while (mEyeFBs.Size() <= eye) + while (mEyeFBs.Size() <= unsigned(eye)) { GLuint texture = Create2DTexture("EyeTexture", GL_RGBA16F, mWidth, mHeight); mEyeTextures.Push(texture); @@ -482,7 +482,7 @@ GLuint FGLRenderBuffers::Create2DTexture(const FString &name, GLuint format, int glBindTexture(GL_TEXTURE_2D, handle); FGLDebug::LabelObject(GL_TEXTURE, handle, name); - GLenum dataformat, datatype; + GLenum dataformat = 0, datatype = 0; switch (format) { case GL_RGBA8: dataformat = GL_RGBA; datatype = GL_UNSIGNED_BYTE; break; diff --git a/src/gl/scene/gl_bsp.cpp b/src/gl/scene/gl_bsp.cpp index 9e5ea258d7..d646daa53f 100644 --- a/src/gl/scene/gl_bsp.cpp +++ b/src/gl/scene/gl_bsp.cpp @@ -383,7 +383,7 @@ static inline void RenderThings(subsector_t * sub, sector_t * sector) GLRenderer->ProcessSprite(thing, sector, false); } - for (msecnode_t *node = sec->render_thinglist; node; node = node->m_snext) + for (msecnode_t *node = sec->sectorportal_thinglist; node; node = node->m_snext) { AActor *thing = node->m_thing; FIntCVar *cvar = thing->GetClass()->distancecheck; diff --git a/src/gl/scene/gl_scene.cpp b/src/gl/scene/gl_scene.cpp index 1cf4642502..13cd2eac44 100644 --- a/src/gl/scene/gl_scene.cpp +++ b/src/gl/scene/gl_scene.cpp @@ -88,7 +88,7 @@ extern int viewpitch; extern bool NoInterpolateView; extern bool r_showviewer; -DWORD gl_fixedcolormap; +int gl_fixedcolormap; area_t in_area; TArray currentmapsection; int camtexcount; diff --git a/src/gl/scene/gl_sprite.cpp b/src/gl/scene/gl_sprite.cpp index 102337eccc..7ed4199a13 100644 --- a/src/gl/scene/gl_sprite.cpp +++ b/src/gl/scene/gl_sprite.cpp @@ -1189,7 +1189,7 @@ void gl_RenderActorsInPortal(FGLLinePortal *glport) if (port2 != nullptr && port->mDestination == port2->mOrigin && port->mOrigin == port2->mDestination) { - for (portnode_t *node = port->render_thinglist; node != nullptr; node = node->m_snext) + for (portnode_t *node = port->lineportal_thinglist; node != nullptr; node = node->m_snext) { AActor *th = node->m_thing; diff --git a/src/gl/scene/gl_walls.cpp b/src/gl/scene/gl_walls.cpp index 4d258b3a03..5ac29dcad6 100644 --- a/src/gl/scene/gl_walls.cpp +++ b/src/gl/scene/gl_walls.cpp @@ -1245,7 +1245,7 @@ void GLWall::ClipFFloors(seg_t * seg, F3DFloor * ffloor, sector_t * frontsector, { TArray & frontffloors = frontsector->e->XFloor.ffloors; - int flags = ffloor->flags & (FF_SWIMMABLE | FF_TRANSLUCENT); + const unsigned int flags = ffloor->flags & (FF_SWIMMABLE | FF_TRANSLUCENT); for (unsigned int i = 0; i < frontffloors.Size(); i++) { diff --git a/src/gl/shaders/gl_presentshader.h b/src/gl/shaders/gl_presentshader.h index 6f9e1bfd7d..dcf42cdf8b 100644 --- a/src/gl/shaders/gl_presentshader.h +++ b/src/gl/shaders/gl_presentshader.h @@ -6,6 +6,7 @@ class FPresentShaderBase { public: + virtual ~FPresentShaderBase() {} virtual void Bind() = 0; FBufferedUniform1f InvGamma; @@ -26,4 +27,4 @@ public: FBufferedUniformSampler InputTexture; }; -#endif \ No newline at end of file +#endif diff --git a/src/gl/system/gl_debug.cpp b/src/gl/system/gl_debug.cpp index a8b1bab5dd..25651721e3 100644 --- a/src/gl/system/gl_debug.cpp +++ b/src/gl/system/gl_debug.cpp @@ -143,7 +143,7 @@ void FGLDebug::SetupBreakpointMode() void FGLDebug::UpdateLoggingLevel() { - int level = gl_debug_level; + const GLenum level = gl_debug_level; if (level != mCurrentLevel) { glDebugMessageControl(GL_DONT_CARE, GL_DONT_CARE, GL_DEBUG_SEVERITY_HIGH, 0, nullptr, level > 0); diff --git a/src/gl/textures/gl_material.cpp b/src/gl/textures/gl_material.cpp index 4be2e96198..8bb8ee6f0a 100644 --- a/src/gl/textures/gl_material.cpp +++ b/src/gl/textures/gl_material.cpp @@ -285,7 +285,7 @@ const FHardwareTexture *FGLTexture::Bind(int texunit, int clampmode, int transla if (translation <= 0) translation = -translation; else { - alphatrans = (gl.legacyMode && translation == TRANSLATION(TRANSLATION_Standard, 8)); + alphatrans = (gl.legacyMode && DWORD(translation) == TRANSLATION(TRANSLATION_Standard, 8)); translation = GLTranslationPalette::GetInternalTranslation(translation); } diff --git a/src/p_blockmap.h b/src/p_blockmap.h index b2cee1bdda..e6474b4ea2 100644 --- a/src/p_blockmap.h +++ b/src/p_blockmap.h @@ -31,6 +31,13 @@ extern double bmaporgx; extern double bmaporgy; // origin of block map extern FBlockNode** blocklinks; // for thing chains + // mapblocks are used to check movement + // against lines and things +enum +{ + MAPBLOCKUNITS = 128 +}; + inline int GetBlockX(double xpos) { return int((xpos - bmaporgx) / MAPBLOCKUNITS); diff --git a/src/p_local.h b/src/p_local.h index c66792549c..6bb65ad977 100644 --- a/src/p_local.h +++ b/src/p_local.h @@ -38,9 +38,11 @@ class APlayerPawn; struct line_t; struct sector_t; struct msecnode_t; +struct portnode_t; struct secplane_t; struct FCheckPosition; struct FTranslatedLineTarget; +struct FLinePortal; #include @@ -48,10 +50,6 @@ struct FTranslatedLineTarget; #define BONUSADD 6 -// mapblocks are used to check movement -// against lines and things -#define MAPBLOCKUNITS 128 - // Inspired by Maes extern int bmapnegx; extern int bmapnegy; @@ -393,8 +391,14 @@ int P_RadiusAttack (AActor *spot, AActor *source, int damage, int distance, FName damageType, int flags, int fulldamagedistance=0); void P_DelSeclist(msecnode_t *, msecnode_t *sector_t::*seclisthead); -msecnode_t *P_AddSecnode(sector_t *s, AActor *thing, msecnode_t *nextnode, msecnode_t *&sec_thinglist); -msecnode_t* P_DelSecnode(msecnode_t *, msecnode_t *sector_t::*head); +void P_DelSeclist(portnode_t *, portnode_t *FLinePortal::*seclisthead); + +template +nodetype *P_AddSecnode(linktype *s, AActor *thing, nodetype *nextnode, nodetype *&sec_thinglist); + +template +nodetype* P_DelSecnode(nodetype *, nodetype *linktype::*head); + msecnode_t *P_CreateSecNodeList(AActor *thing, double radius, msecnode_t *sector_list, msecnode_t *sector_t::*seclisthead); double P_GetMoveFactor(const AActor *mo, double *frictionp); // phares 3/6/98 double P_GetFriction(const AActor *mo, double *frictionfactor); diff --git a/src/p_map.cpp b/src/p_map.cpp index 5bbb9c3f92..7f6a47b66f 100644 --- a/src/p_map.cpp +++ b/src/p_map.cpp @@ -6448,413 +6448,6 @@ bool P_ChangeSector(sector_t *sector, int crunch, double amt, int floorOrCeil, b return cpos.nofit; } -//============================================================================= -// phares 3/21/98 -// -// Maintain a freelist of msecnode_t's to reduce memory allocs and frees. -//============================================================================= - -msecnode_t *headsecnode = NULL; - -//============================================================================= -// -// P_GetSecnode -// -// Retrieve a node from the freelist. The calling routine -// should make sure it sets all fields properly. -// -//============================================================================= - -msecnode_t *P_GetSecnode() -{ - msecnode_t *node; - - if (headsecnode) - { - node = headsecnode; - headsecnode = headsecnode->m_snext; - } - else - { - node = (msecnode_t *)M_Malloc(sizeof(*node)); - } - return node; -} - -//============================================================================= -// -// P_PutSecnode -// -// Returns a node to the freelist. -// -//============================================================================= - -void P_PutSecnode(msecnode_t *node) -{ - node->m_snext = headsecnode; - headsecnode = node; -} - -//============================================================================= -// phares 3/16/98 -// -// P_AddSecnode -// -// Searches the current list to see if this sector is -// already there. If not, it adds a sector node at the head of the list of -// sectors this object appears in. This is called when creating a list of -// nodes that will get linked in later. Returns a pointer to the new node. -// -//============================================================================= - -msecnode_t *P_AddSecnode(sector_t *s, AActor *thing, msecnode_t *nextnode, msecnode_t *&sec_thinglist) -{ - msecnode_t *node; - - if (s == 0) - { - I_FatalError("AddSecnode of 0 for %s\n", thing->GetClass()->TypeName.GetChars()); - } - - node = nextnode; - while (node) - { - if (node->m_sector == s) // Already have a node for this sector? - { - node->m_thing = thing; // Yes. Setting m_thing says 'keep it'. - return nextnode; - } - node = node->m_tnext; - } - - // Couldn't find an existing node for this sector. Add one at the head - // of the list. - - node = P_GetSecnode(); - - // killough 4/4/98, 4/7/98: mark new nodes unvisited. - node->visited = 0; - - node->m_sector = s; // sector - node->m_thing = thing; // mobj - node->m_tprev = NULL; // prev node on Thing thread - node->m_tnext = nextnode; // next node on Thing thread - if (nextnode) - nextnode->m_tprev = node; // set back link on Thing - - // Add new node at head of sector thread starting at s->touching_thinglist - - node->m_sprev = NULL; // prev node on sector thread - node->m_snext = sec_thinglist; // next node on sector thread - if (sec_thinglist) - node->m_snext->m_sprev = node; - sec_thinglist = node; - return node; -} - -//============================================================================= -// -// P_DelSecnode -// -// Deletes a sector node from the list of -// sectors this object appears in. Returns a pointer to the next node -// on the linked list, or NULL. -// -//============================================================================= - -msecnode_t *P_DelSecnode(msecnode_t *node, msecnode_t *sector_t::*listhead) -{ - msecnode_t* tp; // prev node on thing thread - msecnode_t* tn; // next node on thing thread - msecnode_t* sp; // prev node on sector thread - msecnode_t* sn; // next node on sector thread - - if (node) - { - // Unlink from the Thing thread. The Thing thread begins at - // sector_list and not from AActor->touching_sectorlist. - - tp = node->m_tprev; - tn = node->m_tnext; - if (tp) - tp->m_tnext = tn; - if (tn) - tn->m_tprev = tp; - - // Unlink from the sector thread. This thread begins at - // sector_t->touching_thinglist. - - sp = node->m_sprev; - sn = node->m_snext; - if (sp) - sp->m_snext = sn; - else - node->m_sector->*listhead = sn; - if (sn) - sn->m_sprev = sp; - - // Return this node to the freelist - - P_PutSecnode(node); - return tn; - } - return NULL; -} // phares 3/13/98 - -//============================================================================= -// -// P_DelSeclist -// -// Delete an entire sector list -// -//============================================================================= - -void P_DelSeclist(msecnode_t *node, msecnode_t *sector_t::*sechead) -{ - while (node) - node = P_DelSecnode(node, sechead); -} - -//============================================================================= -// phares 3/14/98 -// -// P_CreateSecNodeList -// -// Alters/creates the sector_list that shows what sectors the object resides in -// -//============================================================================= - -msecnode_t *P_CreateSecNodeList(AActor *thing, double radius, msecnode_t *sector_list, msecnode_t *sector_t::*seclisthead) -{ - msecnode_t *node; - - // First, clear out the existing m_thing fields. As each node is - // added or verified as needed, m_thing will be set properly. When - // finished, delete all nodes where m_thing is still NULL. These - // represent the sectors the Thing has vacated. - - node = sector_list; - while (node) - { - node->m_thing = NULL; - node = node->m_tnext; - } - - FBoundingBox box(thing->X(), thing->Y(), radius); - FBlockLinesIterator it(box); - line_t *ld; - - while ((ld = it.Next())) - { - if (!box.inRange(ld) || box.BoxOnLineSide(ld) != -1) - continue; - - // This line crosses through the object. - - // Collect the sector(s) from the line and add to the - // sector_list you're examining. If the Thing ends up being - // allowed to move to this position, then the sector_list - // will be attached to the Thing's AActor at touching_sectorlist. - - sector_list = P_AddSecnode(ld->frontsector, thing, sector_list, ld->frontsector->*seclisthead); - - // Don't assume all lines are 2-sided, since some Things - // like MT_TFOG are allowed regardless of whether their radius takes - // them beyond an impassable linedef. - - // killough 3/27/98, 4/4/98: - // Use sidedefs instead of 2s flag to determine two-sidedness. - - if (ld->backsector) - sector_list = P_AddSecnode(ld->backsector, thing, sector_list, ld->backsector->*seclisthead); - } - - // Add the sector of the (x,y) point to sector_list. - - sector_list = P_AddSecnode(thing->Sector, thing, sector_list, thing->Sector->*seclisthead); - - // Now delete any nodes that won't be used. These are the ones where - // m_thing is still NULL. - - node = sector_list; - while (node) - { - if (node->m_thing == NULL) - { - if (node == sector_list) - sector_list = node->m_tnext; - node = P_DelSecnode(node, seclisthead); - } - else - { - node = node->m_tnext; - } - } - return sector_list; -} - -//============================================================================= -// -// P_DelPortalnode -// -// Same for line portal nodes -// -//============================================================================= - -portnode_t *P_DelPortalnode(portnode_t *node) -{ - portnode_t* tp; // prev node on thing thread - portnode_t* tn; // next node on thing thread - portnode_t* sp; // prev node on sector thread - portnode_t* sn; // next node on sector thread - - if (node) - { - // Unlink from the Thing thread. The Thing thread begins at - // sector_list and not from AActor->touching_sectorlist. - - tp = node->m_tprev; - tn = node->m_tnext; - if (tp) - tp->m_tnext = tn; - if (tn) - tn->m_tprev = tp; - - // Unlink from the sector thread. This thread begins at - // sector_t->touching_thinglist. - - sp = node->m_sprev; - sn = node->m_snext; - if (sp) - sp->m_snext = sn; - else - node->m_portal->render_thinglist = sn; - if (sn) - sn->m_sprev = sp; - - // Return this node to the freelist (use the same one as for msecnodes, since both types are the same size.) - P_PutSecnode(reinterpret_cast(node)); - return tn; - } - return NULL; -} - - -//============================================================================= -// -// P_AddPortalnode -// -//============================================================================= - -portnode_t *P_AddPortalnode(FLinePortal *s, AActor *thing, portnode_t *nextnode) -{ - portnode_t *node; - - if (s == 0) - { - I_FatalError("AddSecnode of 0 for %s\n", thing->GetClass()->TypeName.GetChars()); - } - - node = reinterpret_cast(P_GetSecnode()); - - // killough 4/4/98, 4/7/98: mark new nodes unvisited. - node->visited = 0; - - node->m_portal = s; // portal - node->m_thing = thing; // mobj - node->m_tprev = NULL; // prev node on Thing thread - node->m_tnext = nextnode; // next node on Thing thread - if (nextnode) - nextnode->m_tprev = node; // set back link on Thing - - // Add new node at head of portal thread starting at s->touching_thinglist - - node->m_sprev = NULL; // prev node on portal thread - node->m_snext = s->render_thinglist; // next node on portal thread - if (s->render_thinglist) - node->m_snext->m_sprev = node; - s->render_thinglist = node; - return node; -} - - -//========================================================================== -// -// Handle the lists used to render actors from other portal areas -// -//========================================================================== - -void AActor::UpdateRenderSectorList() -{ - static const double SPRITE_SPACE = 64.; - if (Pos() != OldRenderPos && !(flags & MF_NOSECTOR)) - { - // Only check if the map contains line portals - ClearRenderLineList(); - if (PortalBlockmap.containsLines && Pos().XY() != OldRenderPos.XY()) - { - int bx = GetBlockX(X()); - int by = GetBlockY(Y()); - FBoundingBox bb(X(), Y(), MIN(radius*1.5, 128.)); // Don't go further than 128 map units, even for large actors - // Are there any portals near the actor's position? - if (bx >= 0 && by >= 0 && bx < bmapwidth && by < bmapheight && PortalBlockmap(bx, by).neighborContainsLines) - { - // Go through the entire list. In most cases this is faster than setting up a blockmap iterator - for (auto &p : linePortals) - { - if (p.mType == PORTT_VISUAL) continue; - if (bb.inRange(p.mOrigin) && bb.BoxOnLineSide(p.mOrigin)) - { - render_portallist = P_AddPortalnode(&p, this, render_portallist); - } - } - } - } - sector_t *sec = Sector; - double lasth = -FLT_MAX; - ClearRenderSectorList(); - while (!sec->PortalBlocksMovement(sector_t::ceiling)) - { - double planeh = sec->GetPortalPlaneZ(sector_t::ceiling); - if (planeh <= lasth) break; // broken setup. - if (Top() + SPRITE_SPACE < planeh) break; - lasth = planeh; - DVector2 newpos = Pos() + sec->GetPortalDisplacement(sector_t::ceiling); - sec = P_PointInSector(newpos); - render_sectorlist = P_AddSecnode(sec, this, render_sectorlist, sec->render_thinglist); - } - sec = Sector; - lasth = FLT_MAX; - while (!sec->PortalBlocksMovement(sector_t::floor)) - { - double planeh = sec->GetPortalPlaneZ(sector_t::floor); - if (planeh >= lasth) break; // broken setup. - if (Z() - SPRITE_SPACE > planeh) break; - lasth = planeh; - DVector2 newpos = Pos() + sec->GetPortalDisplacement(sector_t::floor); - sec = P_PointInSector(newpos); - render_sectorlist = P_AddSecnode(sec, this, render_sectorlist, sec->render_thinglist); - } - } -} - -void AActor::ClearRenderSectorList() -{ - msecnode_t *node = render_sectorlist; - while (node) - node = P_DelSecnode(node, §or_t::render_thinglist); - render_sectorlist = NULL; -} - -void AActor::ClearRenderLineList() -{ - portnode_t *node = render_portallist; - while (node) - node = P_DelPortalnode(node); - render_portallist = NULL; -} - - //========================================================================== // // diff --git a/src/p_pspr.cpp b/src/p_pspr.cpp index 41abd254a1..c6f871acef 100644 --- a/src/p_pspr.cpp +++ b/src/p_pspr.cpp @@ -138,10 +138,10 @@ DPSprite::DPSprite(player_t *owner, AActor *caller, int id) : x(.0), y(.0), oldx(.0), oldy(.0), firstTic(true), - Sprite(0), Flags(0), Caller(caller), Owner(owner), + Sprite(0), ID(id), processPending(true), alpha(1), diff --git a/src/p_secnodes.cpp b/src/p_secnodes.cpp new file mode 100644 index 0000000000..8edfc0c700 --- /dev/null +++ b/src/p_secnodes.cpp @@ -0,0 +1,444 @@ +// Emacs style mode select -*- C++ -*- +//----------------------------------------------------------------------------- +// +// $Id:$ +// +// Copyright (C) 1998-1996 by id Software, Inc. +// +// This source is available for distribution and/or modification +// only under the terms of the DOOM Source Code License as +// published by id Software. All rights reserved. +// +// The source is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// FITNESS FOR A PARTICULAR PURPOSE. See the DOOM Source Code License +// for more details. +// +// $Log:$ +// +// DESCRIPTION: +// Boom secnodes +// +//----------------------------------------------------------------------------- + +#include "r_state.h" +#include "p_maputl.h" +#include "p_blockmap.h" +#include "memarena.h" + +//============================================================================= +// phares 3/21/98 +// +// Maintain a freelist of msecnode_t's to reduce memory allocs and frees. +//============================================================================= + +msecnode_t *headsecnode = nullptr; +FMemArena secnodearena; + +//============================================================================= +// +// P_GetSecnode +// +// Retrieve a node from the freelist. The calling routine +// should make sure it sets all fields properly. +// +//============================================================================= + +msecnode_t *P_GetSecnode() +{ + msecnode_t *node; + + if (headsecnode) + { + node = headsecnode; + headsecnode = headsecnode->m_snext; + } + else + { + node = (msecnode_t *)secnodearena.Alloc(sizeof(*node)); + } + return node; +} + +//============================================================================= +// +// P_PutSecnode +// +// Returns a node to the freelist. +// +//============================================================================= + +void P_PutSecnode(msecnode_t *node) +{ + node->m_snext = headsecnode; + headsecnode = node; +} + +//============================================================================= +// phares 3/16/98 +// +// P_AddSecnode +// +// Searches the current list to see if this sector is +// already there. If not, it adds a sector node at the head of the list of +// sectors this object appears in. This is called when creating a list of +// nodes that will get linked in later. Returns a pointer to the new node. +// +//============================================================================= + +template +nodetype *P_AddSecnode(linktype *s, AActor *thing, nodetype *nextnode, nodetype *&sec_thinglist) +{ + nodetype *node; + + if (s == 0) + { + I_FatalError("AddSecnode of 0 for %s\n", thing->GetClass()->TypeName.GetChars()); + } + + node = nextnode; + while (node) + { + if (node->m_sector == s) // Already have a node for this sector? + { + node->m_thing = thing; // Yes. Setting m_thing says 'keep it'. + return nextnode; + } + node = node->m_tnext; + } + + // Couldn't find an existing node for this sector. Add one at the head + // of the list. + + node = (nodetype*)P_GetSecnode(); + + // killough 4/4/98, 4/7/98: mark new nodes unvisited. + node->visited = 0; + + node->m_sector = s; // sector + node->m_thing = thing; // mobj + node->m_tprev = nullptr; // prev node on Thing thread + node->m_tnext = nextnode; // next node on Thing thread + if (nextnode) + nextnode->m_tprev = node; // set back link on Thing + + // Add new node at head of sector thread starting at s->touching_thinglist + + node->m_sprev = nullptr; // prev node on sector thread + node->m_snext = sec_thinglist; // next node on sector thread + if (sec_thinglist) + node->m_snext->m_sprev = node; + sec_thinglist = node; + return node; +} + +template msecnode_t *P_AddSecnode(sector_t *s, AActor *thing, msecnode_t *nextnode, msecnode_t *&sec_thinglist); +template portnode_t *P_AddSecnode(FLinePortal *s, AActor *thing, portnode_t *nextnode, portnode_t *&sec_thinglist); + +//============================================================================= +// +// P_DelSecnode +// +// Deletes a sector node from the list of +// sectors this object appears in. Returns a pointer to the next node +// on the linked list, or nullptr. +// +//============================================================================= + +template +nodetype *P_DelSecnode(nodetype *node, nodetype *linktype::*listhead) +{ + nodetype* tp; // prev node on thing thread + nodetype* tn; // next node on thing thread + nodetype* sp; // prev node on sector thread + nodetype* sn; // next node on sector thread + + if (node) + { + // Unlink from the Thing thread. The Thing thread begins at + // sector_list and not from AActor->touching_sectorlist. + + tp = node->m_tprev; + tn = node->m_tnext; + if (tp) + tp->m_tnext = tn; + if (tn) + tn->m_tprev = tp; + + // Unlink from the sector thread. This thread begins at + // sector_t->touching_thinglist. + + sp = node->m_sprev; + sn = node->m_snext; + if (sp) + sp->m_snext = sn; + else + node->m_sector->*listhead = sn; + if (sn) + sn->m_sprev = sp; + + // Return this node to the freelist + + P_PutSecnode((msecnode_t*)node); + return tn; + } + return nullptr; +} // phares 3/13/98 + +template msecnode_t *P_DelSecnode(msecnode_t *node, msecnode_t *sector_t::*listhead); +template portnode_t *P_DelSecnode(portnode_t *node, portnode_t *FLinePortal::*listhead); + +//============================================================================= +// +// P_DelSeclist +// +// Delete an entire sector list +// +//============================================================================= + +void P_DelSeclist(msecnode_t *node, msecnode_t *sector_t::*sechead) +{ + while (node) + node = P_DelSecnode(node, sechead); +} + +void P_DelSeclist(portnode_t *node, portnode_t *FLinePortal::*sechead) +{ + while (node) + node = P_DelSecnode(node, sechead); +} + + +//============================================================================= +// phares 3/14/98 +// +// P_CreateSecNodeList +// +// Alters/creates the sector_list that shows what sectors the object resides in +// +//============================================================================= + +msecnode_t *P_CreateSecNodeList(AActor *thing, double radius, msecnode_t *sector_list, msecnode_t *sector_t::*seclisthead) +{ + msecnode_t *node; + + // First, clear out the existing m_thing fields. As each node is + // added or verified as needed, m_thing will be set properly. When + // finished, delete all nodes where m_thing is still nullptr. These + // represent the sectors the Thing has vacated. + + node = sector_list; + while (node) + { + node->m_thing = nullptr; + node = node->m_tnext; + } + + FBoundingBox box(thing->X(), thing->Y(), radius); + FBlockLinesIterator it(box); + line_t *ld; + + while ((ld = it.Next())) + { + if (!box.inRange(ld) || box.BoxOnLineSide(ld) != -1) + continue; + + // This line crosses through the object. + + // Collect the sector(s) from the line and add to the + // sector_list you're examining. If the Thing ends up being + // allowed to move to this position, then the sector_list + // will be attached to the Thing's AActor at touching_sectorlist. + + sector_list = P_AddSecnode(ld->frontsector, thing, sector_list, ld->frontsector->*seclisthead); + + // Don't assume all lines are 2-sided, since some Things + // like MT_TFOG are allowed regardless of whether their radius takes + // them beyond an impassable linedef. + + // killough 3/27/98, 4/4/98: + // Use sidedefs instead of 2s flag to determine two-sidedness. + + if (ld->backsector) + sector_list = P_AddSecnode(ld->backsector, thing, sector_list, ld->backsector->*seclisthead); + } + + // Add the sector of the (x,y) point to sector_list. + + sector_list = P_AddSecnode(thing->Sector, thing, sector_list, thing->Sector->*seclisthead); + + // Now delete any nodes that won't be used. These are the ones where + // m_thing is still nullptr. + + node = sector_list; + while (node) + { + if (node->m_thing == nullptr) + { + if (node == sector_list) + sector_list = node->m_tnext; + node = P_DelSecnode(node, seclisthead); + } + else + { + node = node->m_tnext; + } + } + return sector_list; +} + +//============================================================================= +// +// P_DelPortalnode +// +// Same for line portal nodes +// +//============================================================================= + +portnode_t *P_DelPortalnode(portnode_t *node) +{ + portnode_t* tp; // prev node on thing thread + portnode_t* tn; // next node on thing thread + portnode_t* sp; // prev node on sector thread + portnode_t* sn; // next node on sector thread + + if (node) + { + // Unlink from the Thing thread. The Thing thread begins at + // sector_list and not from AActor->touching_sectorlist. + + tp = node->m_tprev; + tn = node->m_tnext; + if (tp) + tp->m_tnext = tn; + if (tn) + tn->m_tprev = tp; + + // Unlink from the sector thread. This thread begins at + // sector_t->touching_thinglist. + + sp = node->m_sprev; + sn = node->m_snext; + if (sp) + sp->m_snext = sn; + else + node->m_sector->lineportal_thinglist = sn; + if (sn) + sn->m_sprev = sp; + + // Return this node to the freelist (use the same one as for msecnodes, since both types are the same size.) + P_PutSecnode(reinterpret_cast(node)); + return tn; + } + return nullptr; +} + + +//============================================================================= +// +// P_AddPortalnode +// +//============================================================================= + +portnode_t *P_AddPortalnode(FLinePortal *s, AActor *thing, portnode_t *nextnode) +{ + portnode_t *node; + + if (s == 0) + { + I_FatalError("AddSecnode of 0 for %s\n", thing->GetClass()->TypeName.GetChars()); + } + + node = reinterpret_cast(P_GetSecnode()); + + // killough 4/4/98, 4/7/98: mark new nodes unvisited. + node->visited = 0; + + node->m_sector = s; // portal + node->m_thing = thing; // mobj + node->m_tprev = nullptr; // prev node on Thing thread + node->m_tnext = nextnode; // next node on Thing thread + if (nextnode) + nextnode->m_tprev = node; // set back link on Thing + + // Add new node at head of portal thread starting at s->touching_thinglist + + node->m_sprev = nullptr; // prev node on portal thread + node->m_snext = s->lineportal_thinglist; // next node on portal thread + if (s->lineportal_thinglist) + node->m_snext->m_sprev = node; + s->lineportal_thinglist = node; + return node; +} + +//========================================================================== +// +// Handle the lists used to render actors from other portal areas +// +//========================================================================== + +void AActor::UpdateRenderSectorList() +{ + static const double SPRITE_SPACE = 64.; + if (Pos() != OldRenderPos && !(flags & MF_NOSECTOR)) + { + // Only check if the map contains line portals + ClearRenderLineList(); + if (PortalBlockmap.containsLines && Pos().XY() != OldRenderPos.XY()) + { + int bx = GetBlockX(X()); + int by = GetBlockY(Y()); + FBoundingBox bb(X(), Y(), MIN(radius*1.5, 128.)); // Don't go further than 128 map units, even for large actors + // Are there any portals near the actor's position? + if (bx >= 0 && by >= 0 && bx < bmapwidth && by < bmapheight && PortalBlockmap(bx, by).neighborContainsLines) + { + // Go through the entire list. In most cases this is faster than setting up a blockmap iterator + for (auto &p : linePortals) + { + if (p.mType == PORTT_VISUAL) continue; + if (bb.inRange(p.mOrigin) && bb.BoxOnLineSide(p.mOrigin)) + { + touching_lineportallist = P_AddPortalnode(&p, this, touching_lineportallist); + } + } + } + } + sector_t *sec = Sector; + double lasth = -FLT_MAX; + ClearRenderSectorList(); + while (!sec->PortalBlocksMovement(sector_t::ceiling)) + { + double planeh = sec->GetPortalPlaneZ(sector_t::ceiling); + if (planeh <= lasth) break; // broken setup. + if (Top() + SPRITE_SPACE < planeh) break; + lasth = planeh; + DVector2 newpos = Pos() + sec->GetPortalDisplacement(sector_t::ceiling); + sec = P_PointInSector(newpos); + touching_sectorportallist = P_AddSecnode(sec, this, touching_sectorportallist, sec->sectorportal_thinglist); + } + sec = Sector; + lasth = FLT_MAX; + while (!sec->PortalBlocksMovement(sector_t::floor)) + { + double planeh = sec->GetPortalPlaneZ(sector_t::floor); + if (planeh >= lasth) break; // broken setup. + if (Z() - SPRITE_SPACE > planeh) break; + lasth = planeh; + DVector2 newpos = Pos() + sec->GetPortalDisplacement(sector_t::floor); + sec = P_PointInSector(newpos); + touching_sectorportallist = P_AddSecnode(sec, this, touching_sectorportallist, sec->sectorportal_thinglist); + } + } +} + +void AActor::ClearRenderSectorList() +{ + P_DelSeclist(touching_sectorportallist, §or_t::sectorportal_thinglist); + touching_sectorportallist = nullptr; +} + +void AActor::ClearRenderLineList() +{ + P_DelSeclist(touching_lineportallist, &FLinePortal::lineportal_thinglist); + touching_lineportallist = nullptr; +} diff --git a/src/p_sectors.cpp b/src/p_sectors.cpp index 2850f22645..c2488b9988 100644 --- a/src/p_sectors.cpp +++ b/src/p_sectors.cpp @@ -1337,7 +1337,7 @@ DEFINE_FIELD_X(Sector, sector_t, bottommap) DEFINE_FIELD_X(Sector, sector_t, midmap) DEFINE_FIELD_X(Sector, sector_t, topmap) DEFINE_FIELD_X(Sector, sector_t, touching_thinglist) -DEFINE_FIELD_X(Sector, sector_t, render_thinglist) +DEFINE_FIELD_X(Sector, sector_t, sectorportal_thinglist) DEFINE_FIELD_X(Sector, sector_t, gravity) DEFINE_FIELD_X(Sector, sector_t, damagetype) DEFINE_FIELD_X(Sector, sector_t, damageamount) diff --git a/src/p_setup.cpp b/src/p_setup.cpp index de83577642..88694a8cfa 100644 --- a/src/p_setup.cpp +++ b/src/p_setup.cpp @@ -1508,7 +1508,7 @@ void P_LoadSectors (MapData *map, FMissingTextureTracker &missingtex) tagManager.AddSectorTag(i, LittleShort(ms->tag)); ss->thinglist = nullptr; ss->touching_thinglist = nullptr; // phares 3/14/98 - ss->render_thinglist = nullptr; + ss->sectorportal_thinglist = nullptr; ss->touching_renderthings = nullptr; ss->seqType = defSeqType; ss->SeqName = NAME_None; @@ -3088,7 +3088,7 @@ line_t** linebuffer; static void P_GroupLines (bool buildmap) { cycle_t times[16]; - int* linesDoneInEachSector; + unsigned int* linesDoneInEachSector; int i; int total; line_t* li; @@ -3156,7 +3156,7 @@ static void P_GroupLines (bool buildmap) times[3].Clock(); linebuffer = new line_t *[total]; line_t **lineb_p = linebuffer; - linesDoneInEachSector = new int[numsectors]; + linesDoneInEachSector = new unsigned int[numsectors]; memset (linesDoneInEachSector, 0, sizeof(int)*numsectors); for (sector = sectors, i = 0; i < numsectors; i++, sector++) @@ -3552,6 +3552,7 @@ void P_FreeLevelData () P_ClearUDMFKeys(); } +extern FMemArena secnodearena; extern msecnode_t *headsecnode; void P_FreeExtraLevelData() @@ -3569,19 +3570,11 @@ void P_FreeExtraLevelData() } FBlockNode::FreeBlocks = NULL; } - { - msecnode_t *node = headsecnode; - - while (node != NULL) - { - msecnode_t *next = node->m_snext; - M_Free (node); - node = next; - } - headsecnode = NULL; - } + secnodearena.FreeAllBlocks(); + headsecnode = nullptr; } + // // P_SetupLevel // diff --git a/src/p_udmf.cpp b/src/p_udmf.cpp index 51bd780f5b..256385c65d 100644 --- a/src/p_udmf.cpp +++ b/src/p_udmf.cpp @@ -1297,7 +1297,7 @@ public: sec->SetAlpha(sector_t::ceiling, 1.); sec->thinglist = nullptr; sec->touching_thinglist = nullptr; // phares 3/14/98 - sec->render_thinglist = nullptr; + sec->sectorportal_thinglist = nullptr; sec->touching_renderthings = nullptr; sec->seqType = (level.flags & LEVEL_SNDSEQTOTALCTRL) ? 0 : -1; sec->nextsec = -1; //jff 2/26/98 add fields to support locking out @@ -1695,7 +1695,7 @@ public: sec->ceilingplane.set(n.X, n.Y, n.Z, cp[3]); } - if (lightcolor == -1 && fadecolor == -1 && desaturation == -1 && fogdensity == -1) + if (lightcolor == ~0u && fadecolor == ~0u && desaturation == -1 && fogdensity == -1) { // [RH] Sectors default to white light with the default fade. // If they are outside (have a sky ceiling), they use the outside fog. @@ -1714,8 +1714,8 @@ public: } else { - if (lightcolor == -1) lightcolor = PalEntry(255,255,255); - if (fadecolor == -1) + if (lightcolor == ~0u) lightcolor = PalEntry(255,255,255); + if (fadecolor == ~0u) { if (level.outsidefog != 0xff000000 && (sec->GetTexture(sector_t::ceiling) == skyflatnum || (sec->special & 0xff) == Sector_Outside)) fadecolor = level.outsidefog; diff --git a/src/p_user.cpp b/src/p_user.cpp index c8f30e0d76..8bd23830d7 100644 --- a/src/p_user.cpp +++ b/src/p_user.cpp @@ -95,9 +95,19 @@ static int PredictionLerptics; static player_t PredictionPlayerBackup; static BYTE PredictionActorBackup[sizeof(APlayerPawn)]; -static TArray PredictionTouchingSectorsBackup; static TArray PredictionSectorListBackup; -static TArray PredictionSector_sprev_Backup; + +static TArray PredictionTouchingSectorsBackup; +static TArray PredictionTouchingSectors_sprev_Backup; + +static TArray PredictionRenderSectorsBackup; +static TArray PredictionRenderSectors_sprev_Backup; + +static TArray PredictionPortalSectorsBackup; +static TArray PredictionPortalSectors_sprev_Backup; + +static TArray PredictionPortalLinesBackup; +static TArray PredictionPortalLines_sprev_Backup; // [GRB] Custom player classes TArray PlayerClasses; @@ -2776,6 +2786,100 @@ bool P_LerpCalculate(AActor *pmo, PredictPos from, PredictPos to, PredictPos &re return (delta.LengthSquared() > cl_predict_lerpthreshold && scale <= 1.00f); } +template +void BackupNodeList(AActor *act, nodetype *head, nodetype *linktype::*otherlist, TArray &prevbackup, TArray &otherbackup) +{ + // The ordering of the touching_sectorlist needs to remain unchanged + // Also store a copy of all previous sector_thinglist nodes + prevbackup.Clear(); + otherbackup.Clear(); + + for (auto mnode = head; mnode != nullptr; mnode = mnode->m_tnext) + { + otherbackup.Push(mnode->m_sector); + + for (auto snode = mnode->m_sector->*otherlist; snode; snode = snode->m_snext) + { + if (snode->m_thing == act) + { + prevbackup.Push(snode->m_sprev); + break; + } + } + } +} + +template +nodetype *RestoreNodeList(AActor *act, nodetype *head, nodetype *linktype::*otherlist, TArray &prevbackup, TArray &otherbackup) +{ + // Destroy old refrences + nodetype *node = head; + while (node) + { + node->m_thing = NULL; + node = node->m_tnext; + } + + // Make the sector_list match the player's touching_sectorlist before it got predicted. + P_DelSeclist(head, otherlist); + head = NULL; + for (auto i = otherbackup.Size(); i-- > 0;) + { + head = P_AddSecnode(otherbackup[i], act, head, otherbackup[i]->*otherlist); + } + //act->touching_sectorlist = ctx.sector_list; // Attach to thing + //ctx.sector_list = NULL; // clear for next time + + // In the old code this block never executed because of the commented-out NULL assignment above. Needs to be checked + node = head; + while (node) + { + if (node->m_thing == NULL) + { + if (node == head) + head = node->m_tnext; + node = P_DelSecnode(node, otherlist); + } + else + { + node = node->m_tnext; + } + } + + nodetype *snode; + + // Restore sector thinglist order + for (auto i = otherbackup.Size(); i-- > 0;) + { + // If we were already the head node, then nothing needs to change + if (prevbackup[i] == NULL) + continue; + + for (snode = otherbackup[i]->*otherlist; snode; snode = snode->m_snext) + { + if (snode->m_thing == act) + { + if (snode->m_sprev) + snode->m_sprev->m_snext = snode->m_snext; + else + snode->m_sector->*otherlist = snode->m_snext; + if (snode->m_snext) + snode->m_snext->m_sprev = snode->m_sprev; + + snode->m_sprev = prevbackup[i]; + + // At the moment, we don't exist in the list anymore, but we do know what our previous node is, so we set its current m_snext->m_sprev to us. + if (snode->m_sprev->m_snext) + snode->m_sprev->m_snext->m_sprev = snode; + snode->m_snext = snode->m_sprev->m_snext; + snode->m_sprev->m_snext = snode; + break; + } + } + } + return head; +} + void P_PredictPlayer (player_t *player) { int maxtic; @@ -2810,28 +2914,10 @@ void P_PredictPlayer (player_t *player) act->flags2 &= ~MF2_PUSHWALL; player->cheats |= CF_PREDICTING; - // The ordering of the touching_sectorlist needs to remain unchanged - // Also store a copy of all previous sector_thinglist nodes - msecnode_t *mnode = act->touching_sectorlist; - msecnode_t *snode; - PredictionSector_sprev_Backup.Clear(); - PredictionTouchingSectorsBackup.Clear (); - - while (mnode != NULL) - { - PredictionTouchingSectorsBackup.Push (mnode->m_sector); - - for (snode = mnode->m_sector->touching_thinglist; snode; snode = snode->m_snext) - { - if (snode->m_thing == act) - { - PredictionSector_sprev_Backup.Push(snode->m_sprev); - break; - } - } - - mnode = mnode->m_tnext; - } + BackupNodeList(act, act->touching_sectorlist, §or_t::touching_thinglist, PredictionTouchingSectors_sprev_Backup, PredictionTouchingSectorsBackup); + BackupNodeList(act, act->touching_rendersectors, §or_t::touching_renderthings, PredictionRenderSectors_sprev_Backup, PredictionRenderSectorsBackup); + BackupNodeList(act, act->touching_sectorportallist, §or_t::sectorportal_thinglist, PredictionPortalSectors_sprev_Backup, PredictionPortalSectorsBackup); + BackupNodeList(act, act->touching_lineportallist, &FLinePortal::lineportal_thinglist, PredictionPortalLines_sprev_Backup, PredictionPortalLinesBackup); // Keep an ordered list off all actors in the linked sector. PredictionSectorListBackup.Clear(); @@ -2941,6 +3027,12 @@ void P_UnPredictPlayer () player->camera = savedcamera; FLinkContext ctx; + // Unlink from all list, includeing those which are not being handled by UnlinkFromWorld. + auto sectorportal_list = act->touching_sectorportallist; + auto lineportal_list = act->touching_lineportallist; + act->touching_sectorportallist = nullptr; + act->touching_lineportallist = nullptr; + act->UnlinkFromWorld(&ctx); memcpy(&act->snext, PredictionActorBackup, sizeof(APlayerPawn) - ((BYTE *)&act->snext - (BYTE *)act)); @@ -2969,71 +3061,10 @@ void P_UnPredictPlayer () *link = me; } - // Destroy old refrences - msecnode_t *node = ctx.sector_list; - while (node) - { - node->m_thing = NULL; - node = node->m_tnext; - } - - // Make the sector_list match the player's touching_sectorlist before it got predicted. - P_DelSeclist(ctx.sector_list, §or_t::touching_thinglist); - ctx.sector_list = NULL; - for (i = PredictionTouchingSectorsBackup.Size(); i-- > 0;) - { - ctx.sector_list = P_AddSecnode(PredictionTouchingSectorsBackup[i], act, ctx.sector_list, PredictionTouchingSectorsBackup[i]->touching_thinglist); - } - act->touching_sectorlist = ctx.sector_list; // Attach to thing - ctx.sector_list = NULL; // clear for next time - - // Huh??? - node = ctx.sector_list; - while (node) - { - if (node->m_thing == NULL) - { - if (node == ctx.sector_list) - ctx.sector_list = node->m_tnext; - node = P_DelSecnode(node, §or_t::touching_thinglist); - } - else - { - node = node->m_tnext; - } - } - - msecnode_t *snode; - - // Restore sector thinglist order - for (i = PredictionTouchingSectorsBackup.Size(); i-- > 0;) - { - // If we were already the head node, then nothing needs to change - if (PredictionSector_sprev_Backup[i] == NULL) - continue; - - for (snode = PredictionTouchingSectorsBackup[i]->touching_thinglist; snode; snode = snode->m_snext) - { - if (snode->m_thing == act) - { - if (snode->m_sprev) - snode->m_sprev->m_snext = snode->m_snext; - else - snode->m_sector->touching_thinglist = snode->m_snext; - if (snode->m_snext) - snode->m_snext->m_sprev = snode->m_sprev; - - snode->m_sprev = PredictionSector_sprev_Backup[i]; - - // At the moment, we don't exist in the list anymore, but we do know what our previous node is, so we set its current m_snext->m_sprev to us. - if (snode->m_sprev->m_snext) - snode->m_sprev->m_snext->m_sprev = snode; - snode->m_snext = snode->m_sprev->m_snext; - snode->m_sprev->m_snext = snode; - break; - } - } - } + act->touching_sectorlist = RestoreNodeList(act, ctx.sector_list, §or_t::touching_thinglist, PredictionTouchingSectors_sprev_Backup, PredictionTouchingSectorsBackup); + act->touching_rendersectors = RestoreNodeList(act, ctx.render_list, §or_t::touching_renderthings, PredictionRenderSectors_sprev_Backup, PredictionRenderSectorsBackup); + act->touching_sectorportallist = RestoreNodeList(act, sectorportal_list, §or_t::sectorportal_thinglist, PredictionPortalSectors_sprev_Backup, PredictionPortalSectorsBackup); + act->touching_lineportallist = RestoreNodeList(act, lineportal_list, &FLinePortal::lineportal_thinglist, PredictionPortalLines_sprev_Backup, PredictionPortalLinesBackup); } // Now fix the pointers in the blocknode chain diff --git a/src/portal.h b/src/portal.h index 44d636e4bd..f5c8f8c885 100644 --- a/src/portal.h +++ b/src/portal.h @@ -191,7 +191,7 @@ struct FLinePortal DAngle mAngleDiff; double mSinRot; double mCosRot; - portnode_t *render_thinglist; + portnode_t *lineportal_thinglist; }; extern TArray linePortals; diff --git a/src/r_defs.h b/src/r_defs.h index 80edeeebd6..3a7d4c97f9 100644 --- a/src/r_defs.h +++ b/src/r_defs.h @@ -1048,7 +1048,7 @@ public: // list of mobjs that are at least partially in the sector // thinglist is a subset of touching_thinglist struct msecnode_t *touching_thinglist; // phares 3/14/98 - struct msecnode_t *render_thinglist; // for cross-portal rendering. + struct msecnode_t *sectorportal_thinglist; // for cross-portal rendering. struct msecnode_t *touching_renderthings; // this is used to allow wide things to be rendered not only from their main sector. double gravity; // [RH] Sector gravity (1.0 is normal) @@ -1371,7 +1371,7 @@ struct msecnode_t // use the same memory layout as msecnode_t so both can be used from the same freelist. struct portnode_t { - FLinePortal *m_portal; // a portal containing this object + FLinePortal *m_sector; // a portal containing this object (no, this isn't a sector, but if we want to use templates it needs the same variable names as msecnode_t.) AActor *m_thing; // this object struct portnode_t *m_tprev; // prev msecnode_t for this thing struct portnode_t *m_tnext; // next msecnode_t for this thing diff --git a/src/scripting/codegeneration/codegen.cpp b/src/scripting/codegeneration/codegen.cpp index ed0c272700..7a6997746a 100644 --- a/src/scripting/codegeneration/codegen.cpp +++ b/src/scripting/codegeneration/codegen.cpp @@ -3980,7 +3980,7 @@ ExpEmit FxConcat::Emit(VMFunctionBuilder *build) } else { - int cast; + int cast = 0; strng = ExpEmit(build, REGT_STRING); if (op1.Konst) { diff --git a/src/textures/warptexture.cpp b/src/textures/warptexture.cpp index 91c7b9fc43..3f1c40e683 100644 --- a/src/textures/warptexture.cpp +++ b/src/textures/warptexture.cpp @@ -43,7 +43,7 @@ FWarpTexture::FWarpTexture (FTexture *source, int warptype) -: GenTime (0), SourcePic (source), Pixels (0), Spans (0), Speed (1.f) +: GenTime (0), Speed (1.f), SourcePic (source), Pixels (0), Spans (0) { CopyInfo(source); if (warptype == 2) SetupMultipliers(256, 128); diff --git a/wadsrc/static/zscript/base.txt b/wadsrc/static/zscript/base.txt index 38fa79b768..23a8305375 100644 --- a/wadsrc/static/zscript/base.txt +++ b/wadsrc/static/zscript/base.txt @@ -283,7 +283,7 @@ struct Sector native native uint bottommap, midmap, topmap; //struct msecnode_t *touching_thinglist; - //struct msecnode_t *render_thinglist; + //struct msecnode_t *sectorportal_thinglist; native double gravity; native Name damagetype;