diff --git a/src/d_clisrv.c b/src/d_clisrv.c index 72f60aa9f..10a5c1367 100644 --- a/src/d_clisrv.c +++ b/src/d_clisrv.c @@ -4463,6 +4463,7 @@ static void Local_Maketic(INT32 realtics) void SV_SpawnPlayer(INT32 playernum, INT32 x, INT32 y, angle_t angle) { tic_t tic; + UINT8 numadjust = 0; (void)x; (void)y; @@ -4472,7 +4473,21 @@ void SV_SpawnPlayer(INT32 playernum, INT32 x, INT32 y, angle_t angle) // spawning, but will be applied afterwards. for (tic = server ? maketic : (neededtic - 1); tic >= gametic; tic--) + { + if (numadjust++ == BACKUPTICS) + { + DEBFILE(va("SV_SpawnPlayer: All netcmds for player %d adjusted!\n", playernum)); + // We already adjusted them all, waste of time doing the same thing over and over + // This shouldn't happen normally though, either gametic was 0 (which is handled now anyway) + // or maketic >= gametic + BACKUPTICS + // -- Monster Iestyn 16/01/18 + break; + } netcmds[tic%BACKUPTICS][playernum].angleturn = (INT16)((angle>>16) | TICCMD_RECEIVED); + + if (!tic) // failsafe for gametic == 0 -- Monster Iestyn 16/01/18 + break; + } } // create missed tic diff --git a/src/d_netcmd.c b/src/d_netcmd.c index b1e3bc9d2..6f0406a21 100644 --- a/src/d_netcmd.c +++ b/src/d_netcmd.c @@ -1535,7 +1535,12 @@ static void Command_Playdemo_f(void) CONS_Printf(M_GetText("Playing back demo '%s'.\n"), name); - G_DoPlayDemo(name); + // Internal if no extension, external if one exists + // If external, convert the file name to a path in SRB2's home directory + if (FIL_CheckExtension(name)) + G_DoPlayDemo(va("%s"PATHSEP"%s", srb2home, name)); + else + G_DoPlayDemo(name); } static void Command_Timedemo_f(void) diff --git a/src/hardware/hw_main.c b/src/hardware/hw_main.c index 864cd04b6..597990a62 100644 --- a/src/hardware/hw_main.c +++ b/src/hardware/hw_main.c @@ -1409,9 +1409,9 @@ static void HWR_SplitFog(sector_t *sector, wallVert3D *wallVerts, FSurfaceInfo* HWR_AddTransparentWall(wallVerts, Surf, 0, PF_Translucent|PF_NoTexture, true, lightnum, colormap); } -// HWR_DrawSkyWalls +// HWR_DrawSkyWall // Draw walls into the depth buffer so that anything behind is culled properly -static void HWR_DrawSkyWall(wallVert3D *wallVerts, FSurfaceInfo *Surf, fixed_t bottom, fixed_t top) +static void HWR_DrawSkyWall(wallVert3D *wallVerts, FSurfaceInfo *Surf) { HWD.pfnSetTexture(NULL); // no texture @@ -1419,9 +1419,7 @@ static void HWR_DrawSkyWall(wallVert3D *wallVerts, FSurfaceInfo *Surf, fixed_t b wallVerts[0].t = wallVerts[1].t = 0; wallVerts[0].s = wallVerts[3].s = 0; wallVerts[2].s = wallVerts[1].s = 0; - // set top/bottom coords - wallVerts[2].y = wallVerts[3].y = FIXED_TO_FLOAT(top); // No real way to find the correct height of this - wallVerts[0].y = wallVerts[1].y = FIXED_TO_FLOAT(bottom); // worldlow/bottom because it needs to cover up the lower thok barrier wall + // this no longer sets top/bottom coords, this should be done before caling the function HWR_ProjectWall(wallVerts, Surf, PF_Invisible|PF_Clip|PF_NoTexture, 255, NULL); // PF_Invisible so it's not drawn into the colour buffer // PF_NoTexture for no texture @@ -1542,8 +1540,10 @@ static void HWR_StoreWallRange(double startfrac, double endfrac) if (gr_backsector) { - INT32 gr_toptexture, gr_bottomtexture; + INT32 gr_toptexture = 0, gr_bottomtexture = 0; // two sided line + boolean bothceilingssky = false; // turned on if both back and front ceilings are sky + boolean bothfloorssky = false; // likewise, but for floors #ifdef ESLOPE SLOPEPARAMS(gr_backsector->c_slope, worldhigh, worldhighslope, gr_backsector->ceilingheight) @@ -1556,17 +1556,23 @@ static void HWR_StoreWallRange(double startfrac, double endfrac) // hack to allow height changes in outdoor areas // This is what gets rid of the upper textures if there should be sky - if (gr_frontsector->ceilingpic == skyflatnum && - gr_backsector->ceilingpic == skyflatnum) + if (gr_frontsector->ceilingpic == skyflatnum + && gr_backsector->ceilingpic == skyflatnum) { - worldtop = worldhigh; -#ifdef ESLOPE - worldtopslope = worldhighslope; -#endif + bothceilingssky = true; } - gr_toptexture = R_GetTextureNum(gr_sidedef->toptexture); - gr_bottomtexture = R_GetTextureNum(gr_sidedef->bottomtexture); + // likewise, but for floors and upper textures + if (gr_frontsector->floorpic == skyflatnum + && gr_backsector->floorpic == skyflatnum) + { + bothfloorssky = true; + } + + if (!bothceilingssky) + gr_toptexture = R_GetTextureNum(gr_sidedef->toptexture); + if (!bothfloorssky) + gr_bottomtexture = R_GetTextureNum(gr_sidedef->bottomtexture); // check TOP TEXTURE if (( @@ -2008,84 +2014,42 @@ static void HWR_StoreWallRange(double startfrac, double endfrac) }*/ } - // Isn't this just the most lovely mess +#if 1 + // Sky culling + // No longer so much a mess as before! if (!gr_curline->polyseg) // Don't do it for polyobjects { - if (gr_frontsector->ceilingpic == skyflatnum || gr_backsector->ceilingpic == skyflatnum) + if (gr_frontsector->ceilingpic == skyflatnum) { - fixed_t depthwallheight; - - if (!gr_sidedef->toptexture || (gr_frontsector->ceilingpic == skyflatnum && gr_backsector->ceilingpic == skyflatnum)) // when both sectors are sky, the top texture isn't drawn - depthwallheight = gr_frontsector->ceilingheight < gr_backsector->ceilingheight ? gr_frontsector->ceilingheight : gr_backsector->ceilingheight; - else - depthwallheight = gr_frontsector->ceilingheight > gr_backsector->ceilingheight ? gr_frontsector->ceilingheight : gr_backsector->ceilingheight; - - if (gr_frontsector->ceilingheight-gr_frontsector->floorheight <= 0) // current sector is a thok barrier + if (gr_backsector->ceilingpic != skyflatnum) // don't cull if back sector is also sky { - if (gr_backsector->ceilingheight-gr_backsector->floorheight <= 0) // behind sector is also a thok barrier - { - if (!gr_sidedef->bottomtexture) // Only extend further down if there's no texture - HWR_DrawSkyWall(wallVerts, &Surf, worldbottom < worldlow ? worldbottom : worldlow, INT32_MAX); - else - HWR_DrawSkyWall(wallVerts, &Surf, worldbottom > worldlow ? worldbottom : worldlow, INT32_MAX); - } - // behind sector is not a thok barrier - else if (gr_backsector->ceilingheight <= gr_frontsector->ceilingheight) // behind sector ceiling is lower or equal to current sector - HWR_DrawSkyWall(wallVerts, &Surf, depthwallheight, INT32_MAX); - // gr_front/backsector heights need to be used here because of the worldtop being set to worldhigh earlier on - } - else if (gr_backsector->ceilingheight-gr_backsector->floorheight <= 0) // behind sector is a thok barrier, current sector is not - { - if (gr_backsector->ceilingheight >= gr_frontsector->ceilingheight // thok barrier ceiling height is equal to or greater than current sector ceiling height - || gr_backsector->floorheight <= gr_frontsector->floorheight // thok barrier ceiling height is equal to or less than current sector floor height - || gr_backsector->ceilingpic != skyflatnum) // thok barrier is not a sky - HWR_DrawSkyWall(wallVerts, &Surf, depthwallheight, INT32_MAX); - } - else // neither sectors are thok barriers - { - if ((gr_backsector->ceilingheight < gr_frontsector->ceilingheight && !gr_sidedef->toptexture) // no top texture and sector behind is lower - || gr_backsector->ceilingpic != skyflatnum) // behind sector is not a sky - HWR_DrawSkyWall(wallVerts, &Surf, depthwallheight, INT32_MAX); + wallVerts[2].y = wallVerts[3].y = FIXED_TO_FLOAT(INT32_MAX); // draw to top of map space +#ifdef ESLOPE + wallVerts[0].y = FIXED_TO_FLOAT(worldtop); + wallVerts[1].y = FIXED_TO_FLOAT(worldtopslope); +#else + wallVerts[0].y = wallVerts[1].y = FIXED_TO_FLOAT(worldtop); +#endif + HWR_DrawSkyWall(wallVerts, &Surf); } } - // And now for sky floors! - if (gr_frontsector->floorpic == skyflatnum || gr_backsector->floorpic == skyflatnum) + + if (gr_frontsector->floorpic == skyflatnum) { - fixed_t depthwallheight; - - if (!gr_sidedef->bottomtexture) - depthwallheight = worldbottom > worldlow ? worldbottom : worldlow; - else - depthwallheight = worldbottom < worldlow ? worldbottom : worldlow; - - if (gr_frontsector->ceilingheight-gr_frontsector->floorheight <= 0) // current sector is a thok barrier + if (gr_backsector->floorpic != skyflatnum) // don't cull if back sector is also sky { - if (gr_backsector->ceilingheight-gr_backsector->floorheight <= 0) // behind sector is also a thok barrier - { - if (!gr_sidedef->toptexture) // Only extend up if there's no texture - HWR_DrawSkyWall(wallVerts, &Surf, INT32_MIN, worldtop > worldhigh ? worldtop : worldhigh); - else - HWR_DrawSkyWall(wallVerts, &Surf, INT32_MIN, worldtop < worldhigh ? worldtop : worldhigh); - } - // behind sector is not a thok barrier - else if (gr_backsector->floorheight >= gr_frontsector->floorheight) // behind sector floor is greater or equal to current sector - HWR_DrawSkyWall(wallVerts, &Surf, INT32_MIN, depthwallheight); - } - else if (gr_backsector->ceilingheight-gr_backsector->floorheight <= 0) // behind sector is a thok barrier, current sector is not - { - if (gr_backsector->floorheight <= gr_frontsector->floorheight // thok barrier floor height is equal to or less than current sector floor height - || gr_backsector->ceilingheight >= gr_frontsector->ceilingheight // thok barrier floor height is equal to or greater than current sector ceiling height - || gr_backsector->floorpic != skyflatnum) // thok barrier is not a sky - HWR_DrawSkyWall(wallVerts, &Surf, INT32_MIN, depthwallheight); - } - else // neither sectors are thok barriers - { - if ((gr_backsector->floorheight > gr_frontsector->floorheight && !gr_sidedef->bottomtexture) // no bottom texture and sector behind is higher - || gr_backsector->floorpic != skyflatnum) // behind sector is not a sky - HWR_DrawSkyWall(wallVerts, &Surf, INT32_MIN, depthwallheight); +#ifdef ESLOPE + wallVerts[3].y = FIXED_TO_FLOAT(worldbottom); + wallVerts[2].y = FIXED_TO_FLOAT(worldbottomslope); +#else + wallVerts[2].y = wallVerts[3].y = FIXED_TO_FLOAT(worldbottom); +#endif + wallVerts[0].y = wallVerts[1].y = FIXED_TO_FLOAT(INT32_MIN); // draw to bottom of map space + HWR_DrawSkyWall(wallVerts, &Surf); } } } +#endif } else { @@ -2156,9 +2120,27 @@ static void HWR_StoreWallRange(double startfrac, double endfrac) if (!gr_curline->polyseg) { if (gr_frontsector->ceilingpic == skyflatnum) // It's a single-sided line with sky for its sector - HWR_DrawSkyWall(wallVerts, &Surf, worldtop, INT32_MAX); + { + wallVerts[2].y = wallVerts[3].y = FIXED_TO_FLOAT(INT32_MAX); // draw to top of map space +#ifdef ESLOPE + wallVerts[0].y = FIXED_TO_FLOAT(worldtop); + wallVerts[1].y = FIXED_TO_FLOAT(worldtopslope); +#else + wallVerts[0].y = wallVerts[1].y = FIXED_TO_FLOAT(worldtop); +#endif + HWR_DrawSkyWall(wallVerts, &Surf); + } if (gr_frontsector->floorpic == skyflatnum) - HWR_DrawSkyWall(wallVerts, &Surf, INT32_MIN, worldbottom); + { +#ifdef ESLOPE + wallVerts[3].y = FIXED_TO_FLOAT(worldbottom); + wallVerts[2].y = FIXED_TO_FLOAT(worldbottomslope); +#else + wallVerts[2].y = wallVerts[3].y = FIXED_TO_FLOAT(worldbottom); +#endif + wallVerts[0].y = wallVerts[1].y = FIXED_TO_FLOAT(INT32_MIN); // draw to bottom of map space + HWR_DrawSkyWall(wallVerts, &Surf); + } } } @@ -2451,6 +2433,12 @@ static boolean CheckClip(seg_t * seg, sector_t * afrontsector, sector_t * abacks { fixed_t frontf1,frontf2, frontc1, frontc2; // front floor/ceiling ends fixed_t backf1, backf2, backc1, backc2; // back floor ceiling ends + boolean bothceilingssky = false, bothfloorssky = false; + + if (abacksector->ceilingpic == skyflatnum && afrontsector->ceilingpic == skyflatnum) + bothceilingssky = true; + if (abacksector->floorpic == skyflatnum && afrontsector->floorpic == skyflatnum) + bothfloorssky = true; // GZDoom method of sloped line clipping @@ -2483,62 +2471,45 @@ static boolean CheckClip(seg_t * seg, sector_t * afrontsector, sector_t * abacks backf1 = backf2 = abacksector->floorheight; backc1 = backc2 = abacksector->ceilingheight; } - - // now check for closed sectors! - if (backc1 <= frontf1 && backc2 <= frontf2) + // properly render skies (consider door "open" if both ceilings are sky) + // same for floors + if (!bothceilingssky && !bothfloorssky) { - checkforemptylines = false; - if (!seg->sidedef->toptexture) - return false; - - if (abacksector->ceilingpic == skyflatnum && afrontsector->ceilingpic == skyflatnum) - return false; - - return true; - } - - if (backf1 >= frontc1 && backf2 >= frontc2) - { - checkforemptylines = false; - if (!seg->sidedef->bottomtexture) - return false; - - // properly render skies (consider door "open" if both floors are sky): - if (abacksector->ceilingpic == skyflatnum && afrontsector->ceilingpic == skyflatnum) - return false; - - return true; - } - - if (backc1 <= backf1 && backc2 <= backf2) - { - checkforemptylines = false; - // preserve a kind of transparent door/lift special effect: - if (backc1 < frontc1 || backc2 < frontc2) + // now check for closed sectors! + if ((backc1 <= frontf1 && backc2 <= frontf2) + || (backf1 >= frontc1 && backf2 >= frontc2)) { - if (!seg->sidedef->toptexture) - return false; + checkforemptylines = false; + return true; } - if (backf1 > frontf1 || backf2 > frontf2) + + if (backc1 <= backf1 && backc2 <= backf2) { - if (!seg->sidedef->bottomtexture) - return false; + // preserve a kind of transparent door/lift special effect: + if (((backc1 >= frontc1 && backc2 >= frontc2) || seg->sidedef->toptexture) + && ((backf1 <= frontf1 && backf2 <= frontf2) || seg->sidedef->bottomtexture)) + { + checkforemptylines = false; + return true; + } } - if (abacksector->ceilingpic == skyflatnum && afrontsector->ceilingpic == skyflatnum) - return false; - - if (abacksector->floorpic == skyflatnum && afrontsector->floorpic == skyflatnum) - return false; - - return true; } - if (backc1 != frontc1 || backc2 != frontc2 - || backf1 != frontf1 || backf2 != frontf2) + if (!bothceilingssky) { + if (backc1 != frontc1 || backc2 != frontc2) { checkforemptylines = false; return false; } + } + + if (!bothfloorssky) { + if (backf1 != frontf1 || backf2 != frontf2) + { + checkforemptylines = false; + return false; + } + } return false; } @@ -2841,6 +2812,7 @@ static void HWR_AddLine(seg_t * line) #ifndef NEWCLIP INT32 x1, x2; angle_t span, tspan; + boolean bothceilingssky = false, bothfloorssky = false; #endif // SoM: Backsector needs to be run through R_FakeFlat @@ -2966,7 +2938,30 @@ static void HWR_AddLine(seg_t * line) } else { + boolean bothceilingssky = false, bothfloorssky = false; + gr_backsector = R_FakeFlat(gr_backsector, &tempsec, NULL, NULL, true); + + if (gr_backsector->ceilingpic == skyflatnum && gr_frontsector->ceilingpic == skyflatnum) + bothceilingssky = true; + if (gr_backsector->floorpic == skyflatnum && gr_frontsector->floorpic == skyflatnum) + bothfloorssky = true; + + if (bothceilingssky && bothfloorssky) // everything's sky? let's save us a bit of time then + { + if ( +#ifdef POLYOBJECTS + !line->polyseg && +#endif + !line->sidedef->midtexture + && ((!gr_frontsector->ffloors && !gr_backsector->ffloors) + || (gr_frontsector->tag == gr_backsector->tag))) + return; // line is empty, don't even bother + // treat like wide open window instead + HWR_ProcessSeg(); // Doesn't need arguments because they're defined globally :D + return; + } + if (CheckClip(line, gr_frontsector, gr_backsector)) { gld_clipper_SafeAddClipRange(angle2, angle1); @@ -2989,6 +2984,25 @@ static void HWR_AddLine(seg_t * line) gr_backsector = R_FakeFlat(gr_backsector, &tempsec, NULL, NULL, true); + if (gr_backsector->ceilingpic == skyflatnum && gr_frontsector->ceilingpic == skyflatnum) + bothceilingssky = true; + if (gr_backsector->floorpic == skyflatnum && gr_frontsector->floorpic == skyflatnum) + bothfloorssky = true; + + if (bothceilingssky && bothfloorssky) // everything's sky? let's save us a bit of time then + { + if ( +#ifdef POLYOBJECTS + !line->polyseg && +#endif + !line->sidedef->midtexture + && ((!gr_frontsector->ffloors && !gr_backsector->ffloors) + || (gr_frontsector->tag == gr_backsector->tag))) + return; // line is empty, don't even bother + + goto clippass; // treat like wide open window instead + } + #ifdef ESLOPE if (gr_frontsector->f_slope || gr_frontsector->c_slope || gr_backsector->f_slope || gr_backsector->c_slope) { @@ -3007,47 +3021,58 @@ static void HWR_AddLine(seg_t * line) SLOPEPARAMS( gr_backsector->f_slope, backf1, backf2, gr_backsector->floorheight) SLOPEPARAMS( gr_backsector->c_slope, backc1, backc2, gr_backsector->ceilingheight) #undef SLOPEPARAMS - - // Closed door. - if ((backc1 <= frontf1 && backc2 <= frontf2) - || (backf1 >= frontc1 && backf2 >= frontc2)) + // if both ceilings are skies, consider it always "open" + // same for floors + if (!bothceilingssky && !bothfloorssky) { - goto clipsolid; - } + // Closed door. + if ((backc1 <= frontf1 && backc2 <= frontf2) + || (backf1 >= frontc1 && backf2 >= frontc2)) + { + goto clipsolid; + } - // Check for automap fix. - if (backc1 <= backf1 && backc2 <= backf2 - && ((backc1 >= frontc1 && backc2 >= frontc2) || gr_curline->sidedef->toptexture) - && ((backf1 <= frontf1 && backf2 >= frontf2) || gr_curline->sidedef->bottomtexture) - && (gr_backsector->ceilingpic != skyflatnum || gr_frontsector->ceilingpic != skyflatnum)) - goto clipsolid; + // Check for automap fix. + if (backc1 <= backf1 && backc2 <= backf2 + && ((backc1 >= frontc1 && backc2 >= frontc2) || gr_curline->sidedef->toptexture) + && ((backf1 <= frontf1 && backf2 >= frontf2) || gr_curline->sidedef->bottomtexture)) + goto clipsolid; + } // Window. - if (backc1 != frontc1 || backc2 != frontc2 - || backf1 != frontf1 || backf2 != frontf2) - { - goto clippass; - } + if (!bothceilingssky) // ceilings are always the "same" when sky + if (backc1 != frontc1 || backc2 != frontc2) + goto clippass; + if (!bothfloorssky) // floors are always the "same" when sky + if (backf1 != frontf1 || backf2 != frontf2) + goto clippass; } else #endif { - // Closed door. - if (gr_backsector->ceilingheight <= gr_frontsector->floorheight || - gr_backsector->floorheight >= gr_frontsector->ceilingheight) - goto clipsolid; + // if both ceilings are skies, consider it always "open" + // same for floors + if (!bothceilingssky && !bothfloorssky) + { + // Closed door. + if (gr_backsector->ceilingheight <= gr_frontsector->floorheight || + gr_backsector->floorheight >= gr_frontsector->ceilingheight) + goto clipsolid; - // Check for automap fix. - if (gr_backsector->ceilingheight <= gr_backsector->floorheight - && ((gr_backsector->ceilingheight >= gr_frontsector->ceilingheight) || gr_curline->sidedef->toptexture) - && ((gr_backsector->floorheight <= gr_backsector->floorheight) || gr_curline->sidedef->bottomtexture) - && (gr_backsector->ceilingpic != skyflatnum || gr_frontsector->ceilingpic != skyflatnum)) - goto clipsolid; + // Check for automap fix. + if (gr_backsector->ceilingheight <= gr_backsector->floorheight + && ((gr_backsector->ceilingheight >= gr_frontsector->ceilingheight) || gr_curline->sidedef->toptexture) + && ((gr_backsector->floorheight <= gr_backsector->floorheight) || gr_curline->sidedef->bottomtexture)) + goto clipsolid; + } // Window. - if (gr_backsector->ceilingheight != gr_frontsector->ceilingheight || - gr_backsector->floorheight != gr_frontsector->floorheight) - goto clippass; + if (!bothceilingssky) // ceilings are always the "same" when sky + if (gr_backsector->ceilingheight != gr_frontsector->ceilingheight) + goto clippass; + if (!bothfloorssky) // floors are always the "same" when sky + if (gr_backsector->floorheight != gr_frontsector->floorheight) + goto clippass; } // Reject empty lines used for triggers and special events. @@ -5521,8 +5546,9 @@ static void HWR_DrawSkyBackground(player_t *player) dimensionmultiply = ((float)textures[texturetranslation[skytexture]]->width/256.0f); - v[0].sow = v[3].sow = ((float) angle / ((ANGLE_90-1)*dimensionmultiply)); - v[2].sow = v[1].sow = (-1.0f/dimensionmultiply)+((float) angle / ((ANGLE_90-1)*dimensionmultiply)); + v[0].sow = v[3].sow = ((float) (-angle) / ((ANGLE_90-1)*dimensionmultiply)); // left + v[2].sow = v[1].sow = v[0].sow + (1.0f/dimensionmultiply); // right (or left + 1.0f) + // use +angle and -1.0f above instead if you wanted old backwards behavior // Y angle = aimingangle; @@ -5536,13 +5562,13 @@ static void HWR_DrawSkyBackground(player_t *player) if (atransform.flip) { // During vertical flip the sky should be flipped and it's y movement should also be flipped obviously - v[3].tow = v[2].tow = -(0.5f-(0.5f/dimensionmultiply)); - v[0].tow = v[1].tow = (-1.0f/dimensionmultiply)-(0.5f-(0.5f/dimensionmultiply)); + v[3].tow = v[2].tow = -(0.5f-(0.5f/dimensionmultiply)); // top + v[0].tow = v[1].tow = v[3].tow - (1.0f/dimensionmultiply); // bottom (or top - 1.0f) } else { - v[3].tow = v[2].tow = (-1.0f/dimensionmultiply)-(0.5f-(0.5f/dimensionmultiply)); - v[0].tow = v[1].tow = -(0.5f-(0.5f/dimensionmultiply)); + v[0].tow = v[1].tow = -(0.5f-(0.5f/dimensionmultiply)); // bottom + v[3].tow = v[2].tow = v[0].tow - (1.0f/dimensionmultiply); // top (or bottom - 1.0f) } if (angle > ANGLE_180) // Do this because we don't want the sky to suddenly teleport when crossing over 0 to 360 and vice versa diff --git a/src/lua_script.c b/src/lua_script.c index 853ed5a2f..fdaa12c78 100644 --- a/src/lua_script.c +++ b/src/lua_script.c @@ -854,11 +854,19 @@ static void ArchiveTables(void) lua_pushnil(gL); while (lua_next(gL, -2)) { - ArchiveValue(TABLESINDEX, -2); // key should be either a number or a string, ArchiveValue can handle this. + // Write key + e = ArchiveValue(TABLESINDEX, -2); // key should be either a number or a string, ArchiveValue can handle this. + if (e == 2) // invalid key type (function, thread, lightuserdata, or anything we don't recognise) + { + lua_pushvalue(gL, -2); + CONS_Alert(CONS_ERROR, "Index '%s' (%s) of table %d could not be archived!\n", lua_tostring(gL, -1), luaL_typename(gL, -1), i); + lua_pop(gL, 1); + } + // Write value e = ArchiveValue(TABLESINDEX, -1); if (e == 1) n++; // the table contained a new table we'll have to archive. :( - else if (e == 2) + else if (e == 2) // invalid value type { lua_pushvalue(gL, -2); CONS_Alert(CONS_ERROR, "Type of value for table %d entry '%s' (%s) could not be archived!\n", i, lua_tostring(gL, -1), luaL_typename(gL, -1)); @@ -1016,11 +1024,17 @@ static void UnArchiveTables(void) lua_rawgeti(gL, TABLESINDEX, i); while (true) { - if (UnArchiveValue(TABLESINDEX) == 1) + if (UnArchiveValue(TABLESINDEX) == 1) // read key break; - if (UnArchiveValue(TABLESINDEX) == 2) + if (UnArchiveValue(TABLESINDEX) == 2) // read value n++; - lua_rawset(gL, -3); + if (lua_isnil(gL, -2)) // if key is nil (if a function etc was accidentally saved) + { + CONS_Alert(CONS_ERROR, "A nil key in table %d was found! (Invalid key type or corrupted save?)\n", i); + lua_pop(gL, 2); // pop key and value instead of setting them in the table, to prevent Lua panic errors + } + else + lua_rawset(gL, -3); } lua_pop(gL, 1); } diff --git a/src/r_bsp.c b/src/r_bsp.c index ad4975cde..183def25a 100644 --- a/src/r_bsp.c +++ b/src/r_bsp.c @@ -220,10 +220,7 @@ static INT32 R_DoorClosed(void) // preserve a kind of transparent door/lift special effect: && (backsector->ceilingheight >= frontsector->ceilingheight || curline->sidedef->toptexture) - && (backsector->floorheight <= frontsector->floorheight || curline->sidedef->bottomtexture) - - // properly render skies (consider door "open" if both ceilings are sky): - && (backsector->ceilingpic != skyflatnum || frontsector->ceilingpic != skyflatnum); + && (backsector->floorheight <= frontsector->floorheight || curline->sidedef->bottomtexture); } // @@ -404,6 +401,7 @@ static void R_AddLine(seg_t *line) INT32 x1, x2; angle_t angle1, angle2, span, tspan; static sector_t tempsec; // ceiling/water hack + boolean bothceilingssky = false, bothfloorssky = false; if (line->polyseg && !(line->polyseg->flags & POF_RENDERSIDES)) return; @@ -490,6 +488,25 @@ static void R_AddLine(seg_t *line) doorclosed = 0; + if (backsector->ceilingpic == skyflatnum && frontsector->ceilingpic == skyflatnum) + bothceilingssky = true; + if (backsector->floorpic == skyflatnum && frontsector->floorpic == skyflatnum) + bothfloorssky = true; + + if (bothceilingssky && bothfloorssky) // everything's sky? let's save us a bit of time then + { + if ( +#ifdef POLYOBJECTS + !line->polyseg && +#endif + !line->sidedef->midtexture + && ((!frontsector->ffloors && !backsector->ffloors) + || (frontsector->tag == backsector->tag))) + return; // line is empty, don't even bother + + goto clippass; // treat like wide open window instead + } + // Closed door. #ifdef ESLOPE if (frontsector->f_slope || frontsector->c_slope || backsector->f_slope || backsector->c_slope) @@ -508,48 +525,59 @@ static void R_AddLine(seg_t *line) SLOPEPARAMS( backsector->f_slope, backf1, backf2, backsector->floorheight) SLOPEPARAMS( backsector->c_slope, backc1, backc2, backsector->ceilingheight) #undef SLOPEPARAMS - if ((backc1 <= frontf1 && backc2 <= frontf2) - || (backf1 >= frontc1 && backf2 >= frontc2)) + // if both ceilings are skies, consider it always "open" + // same for floors + if (!bothceilingssky && !bothfloorssky) { - goto clipsolid; + if ((backc1 <= frontf1 && backc2 <= frontf2) + || (backf1 >= frontc1 && backf2 >= frontc2)) + { + goto clipsolid; + } + + // Check for automap fix. Store in doorclosed for r_segs.c + doorclosed = (backc1 <= backf1 && backc2 <= backf2 + && ((backc1 >= frontc1 && backc2 >= frontc2) || curline->sidedef->toptexture) + && ((backf1 <= frontf1 && backf2 >= frontf2) || curline->sidedef->bottomtexture)); + + if (doorclosed) + goto clipsolid; } - // Check for automap fix. Store in doorclosed for r_segs.c - doorclosed = (backc1 <= backf1 && backc2 <= backf2 - && ((backc1 >= frontc1 && backc2 >= frontc2) || curline->sidedef->toptexture) - && ((backf1 <= frontf1 && backf2 >= frontf2) || curline->sidedef->bottomtexture) - && (backsector->ceilingpic != skyflatnum || frontsector->ceilingpic != skyflatnum)); - - if (doorclosed) - goto clipsolid; - // Window. - if (backc1 != frontc1 || backc2 != frontc2 - || backf1 != frontf1 || backf2 != frontf2) - { - goto clippass; - } + if (!bothceilingssky) // ceilings are always the "same" when sky + if (backc1 != frontc1 || backc2 != frontc2) + goto clippass; + if (!bothfloorssky) // floors are always the "same" when sky + if (backf1 != frontf1 || backf2 != frontf2) + goto clippass; } else #endif { - if (backsector->ceilingheight <= frontsector->floorheight - || backsector->floorheight >= frontsector->ceilingheight) + // if both ceilings are skies, consider it always "open" + // same for floors + if (!bothceilingssky && !bothfloorssky) { - goto clipsolid; - } + if (backsector->ceilingheight <= frontsector->floorheight + || backsector->floorheight >= frontsector->ceilingheight) + { + goto clipsolid; + } - // Check for automap fix. Store in doorclosed for r_segs.c - doorclosed = R_DoorClosed(); - if (doorclosed) - goto clipsolid; + // Check for automap fix. Store in doorclosed for r_segs.c + doorclosed = R_DoorClosed(); + if (doorclosed) + goto clipsolid; + } // Window. - if (backsector->ceilingheight != frontsector->ceilingheight - || backsector->floorheight != frontsector->floorheight) - { - goto clippass; - } + if (!bothceilingssky) // ceilings are always the "same" when sky + if (backsector->ceilingheight != frontsector->ceilingheight) + goto clippass; + if (!bothfloorssky) // floors are always the "same" when sky + if (backsector->floorheight != frontsector->floorheight) + goto clippass; } // Reject empty lines used for triggers and special events. @@ -922,7 +950,8 @@ static void R_Subsector(size_t num) #ifdef ESLOPE frontsector->f_slope ? P_GetZAt(frontsector->f_slope, viewx, viewy) : #endif - frontsector->floorheight) < viewz || (frontsector->heightsec != -1 + frontsector->floorheight) < viewz || frontsector->floorpic == skyflatnum + || (frontsector->heightsec != -1 && sectors[frontsector->heightsec].ceilingpic == skyflatnum))) { floorplane = R_FindPlane(frontsector->floorheight, frontsector->floorpic, floorlightlevel, diff --git a/src/r_plane.c b/src/r_plane.c index 670152eda..bc510bbb5 100644 --- a/src/r_plane.c +++ b/src/r_plane.c @@ -625,7 +625,7 @@ visplane_t *R_CheckPlane(visplane_t *pl, INT32 start, INT32 stop) // overlap. void R_ExpandPlane(visplane_t *pl, INT32 start, INT32 stop) { - INT32 unionl, unionh; +// INT32 unionl, unionh; // INT32 x; #ifdef POLYOBJECTS_PLANES @@ -634,6 +634,9 @@ void R_ExpandPlane(visplane_t *pl, INT32 start, INT32 stop) return; #endif + if (pl->minx > start) pl->minx = start; + if (pl->maxx < stop) pl->maxx = stop; +/* if (start < pl->minx) { unionl = start; @@ -651,15 +654,16 @@ void R_ExpandPlane(visplane_t *pl, INT32 start, INT32 stop) { unionh = pl->maxx; } -/* for (x = start; x <= stop; x++) if (pl->top[x] != 0xffff || pl->bottom[x] != 0x0000) break; if (x <= stop) I_Error("R_ExpandPlane: planes in same subsector overlap?!\nminx: %d, maxx: %d, start: %d, stop: %d\n", pl->minx, pl->maxx, start, stop); -*/ + pl->minx = unionl, pl->maxx = unionh; +*/ + } // @@ -694,10 +698,10 @@ void R_MakeSpans(INT32 x, INT32 t1, INT32 b1, INT32 t2, INT32 b2) void R_DrawPlanes(void) { visplane_t *pl; - INT32 x; - INT32 angle; INT32 i; + // Note: are these two lines really needed? + // R_DrawSinglePlane and R_DrawSkyPlane do span/column drawer resets themselves anyway spanfunc = basespanfunc; wallcolfunc = walldrawerfunc; @@ -705,45 +709,6 @@ void R_DrawPlanes(void) { for (pl = visplanes[i]; pl; pl = pl->next) { - // sky flat - if (pl->picnum == skyflatnum) - { - if (!viewsky) - { - skyVisible = true; - continue; - } - - // use correct aspect ratio scale - dc_iscale = skyscale; - - // Sky is always drawn full bright, - // i.e. colormaps[0] is used. - // Because of this hack, sky is not affected - // by INVUL inverse mapping. - dc_colormap = colormaps; - dc_texturemid = skytexturemid; - dc_texheight = textureheight[skytexture] - >>FRACBITS; - for (x = pl->minx; x <= pl->maxx; x++) - { - dc_yl = pl->top[x]; - dc_yh = pl->bottom[x]; - - if (dc_yl <= dc_yh) - { - angle = (pl->viewangle + xtoviewangle[x])>>ANGLETOSKYSHIFT; - dc_iscale = FixedMul(skyscale, FINECOSINE(xtoviewangle[x]>>ANGLETOFINESHIFT)); - dc_x = x; - dc_source = - R_GetColumn(texturetranslation[skytexture], - angle); - wallcolfunc(); - } - } - continue; - } - if (pl->ffloor != NULL #ifdef POLYOBJECTS_PLANES || pl->polyobj != NULL @@ -760,6 +725,59 @@ void R_DrawPlanes(void) #endif } +// R_DrawSkyPlane +// +// Draws the sky within the plane's top/bottom bounds +// Note: this uses column drawers instead of span drawers, since the sky is always a texture +// +static void R_DrawSkyPlane(visplane_t *pl) +{ + INT32 x; + INT32 angle; + + // If we're not supposed to draw the sky (e.g. for skyboxes), don't do anything! + // This probably utterly ruins sky rendering for FOFs and polyobjects, unfortunately + if (!viewsky) + { + // Mark that the sky was visible here for next tic + // (note: this is a hack and it sometimes can cause HOMs to appear for a tic IIRC) + skyVisible = true; + return; + } + + // Reset column drawer function (note: couldn't we just call walldrawerfunc directly?) + // (that is, unless we'll need to switch drawers in future for some reason) + wallcolfunc = walldrawerfunc; + + // use correct aspect ratio scale + dc_iscale = skyscale; + + // Sky is always drawn full bright, + // i.e. colormaps[0] is used. + // Because of this hack, sky is not affected + // by sector colormaps (INVUL inverse mapping is not implemented in SRB2 so is irrelevant). + dc_colormap = colormaps; + dc_texturemid = skytexturemid; + dc_texheight = textureheight[skytexture] + >>FRACBITS; + for (x = pl->minx; x <= pl->maxx; x++) + { + dc_yl = pl->top[x]; + dc_yh = pl->bottom[x]; + + if (dc_yl <= dc_yh) + { + angle = (pl->viewangle + xtoviewangle[x])>>ANGLETOSKYSHIFT; + dc_iscale = FixedMul(skyscale, FINECOSINE(xtoviewangle[x]>>ANGLETOFINESHIFT)); + dc_x = x; + dc_source = + R_GetColumn(texturetranslation[skytexture], + -angle); // get negative of angle for each column to display sky correct way round! --Monster Iestyn 27/01/18 + wallcolfunc(); + } + } +} + void R_DrawSinglePlane(visplane_t *pl) { INT32 light = 0; @@ -771,6 +789,13 @@ void R_DrawSinglePlane(visplane_t *pl) if (!(pl->minx <= pl->maxx)) return; + // sky flat + if (pl->picnum == skyflatnum) + { + R_DrawSkyPlane(pl); + return; + } + #ifndef NOWATER itswater = false; #endif diff --git a/src/r_segs.c b/src/r_segs.c index ecf707e0f..5395f414a 100644 --- a/src/r_segs.c +++ b/src/r_segs.c @@ -1321,6 +1321,18 @@ void R_RenderThickSideRange(drawseg_t *ds, INT32 x1, INT32 x2, ffloor_t *pfloor) #undef CLAMPMIN } +// R_ExpandPlaneY +// +// A simple function to modify a vsplane's top and bottom for a particular column +// Sort of like R_ExpandPlane in r_plane.c, except this is vertical expansion +static inline void R_ExpandPlaneY(visplane_t *pl, INT32 x, INT16 top, INT16 bottom) +{ + // Expand the plane, don't shrink it! + // note: top and bottom default to 0xFFFF and 0x0000 respectively, which is totally compatible with this + if (pl->top[x] > top) pl->top[x] = top; + if (pl->bottom[x] < bottom) pl->bottom[x] = bottom; +} + // // R_RenderSegLoop // Draws zero, one, or two textures (and possibly a masked @@ -1344,7 +1356,6 @@ UINT32 nombre = 100000; #endif //profile stuff --------------------------------------------------------- - static void R_RenderSegLoop (void) { angle_t angle; @@ -1366,7 +1377,6 @@ static void R_RenderSegLoop (void) // mark floor / ceiling areas yl = (topfrac+HEIGHTUNIT-1)>>HEIGHTBITS; - // no space above wall? top = ceilingclip[rw_x]+1; // no space above wall? @@ -1375,16 +1385,19 @@ static void R_RenderSegLoop (void) if (markceiling) { +#if 0 bottom = yl-1; if (bottom >= floorclip[rw_x]) bottom = floorclip[rw_x]-1; if (top <= bottom) - { - ceilingplane->top[rw_x] = (INT16)top; - ceilingplane->bottom[rw_x] = (INT16)bottom; - } +#else + bottom = yl > floorclip[rw_x] ? floorclip[rw_x] : yl; + + if (top <= --bottom && ceilingplane) +#endif + R_ExpandPlaneY(ceilingplane, rw_x, top, bottom); } @@ -1397,24 +1410,10 @@ static void R_RenderSegLoop (void) if (markfloor) { -#if 0 // Old Doom Legacy code - bottom = floorclip[rw_x]-1; - if (top <= ceilingclip[rw_x]) - top = ceilingclip[rw_x]+1; - if (top <= bottom && floorplane) - { - floorplane->top[rw_x] = (INT16)top; - floorplane->bottom[rw_x] = (INT16)bottom; - } -#else // Spiffy new PRBoom code - top = yh < ceilingclip[rw_x] ? ceilingclip[rw_x] : yh; + top = yh < ceilingclip[rw_x] ? ceilingclip[rw_x] : yh; if (++top <= bottom && floorplane) - { - floorplane->top[rw_x] = (INT16)top; - floorplane->bottom[rw_x] = (INT16)bottom; - } -#endif + R_ExpandPlaneY(floorplane, rw_x, top, bottom); } if (numffloors) @@ -1428,14 +1427,6 @@ static void R_RenderSegLoop (void) #ifdef POLYOBJECTS_PLANES if (ffloor[i].polyobj && (!curline->polyseg || ffloor[i].polyobj != curline->polyseg)) continue; - - // FIXME hack to fix planes disappearing when a seg goes behind the camera. This NEEDS to be changed to be done properly. -Red - if (curline->polyseg) { - if (ffloor[i].plane->minx > rw_x) - ffloor[i].plane->minx = rw_x; - else if (ffloor[i].plane->maxx < rw_x) - ffloor[i].plane->maxx = rw_x; - } #endif if (ffloor[i].height < viewz) @@ -1451,7 +1442,7 @@ static void R_RenderSegLoop (void) #ifdef POLYOBJECTS_PLANES // Polyobject-specific hack to fix plane leaking -Red - if (curline->polyseg && ffloor[i].polyobj && ffloor[i].polyobj == curline->polyseg && top_w >= bottom_w) { + if (ffloor[i].polyobj && top_w >= bottom_w) { ffloor[i].plane->top[rw_x] = ffloor[i].plane->bottom[rw_x] = 0xFFFF; } else #endif @@ -1475,7 +1466,7 @@ static void R_RenderSegLoop (void) #ifdef POLYOBJECTS_PLANES // Polyobject-specific hack to fix plane leaking -Red - if (curline->polyseg && ffloor[i].polyobj && ffloor[i].polyobj == curline->polyseg && top_w >= bottom_w) { + if (ffloor[i].polyobj && top_w >= bottom_w) { ffloor[i].plane->top[rw_x] = ffloor[i].plane->bottom[rw_x] = 0xFFFF; } else #endif @@ -1908,29 +1899,26 @@ void R_StoreWallRange(INT32 start, INT32 stop) } } - if (frontsector->c_slope) { - worldtop = P_GetZAt(frontsector->c_slope, segleft.x, segleft.y) - viewz; - worldtopslope = P_GetZAt(frontsector->c_slope, segright.x, segright.y) - viewz; - } else { - worldtopslope = -#else - { -#endif - worldtop = frontsector->ceilingheight - viewz; - } +#define SLOPEPARAMS(slope, end1, end2, normalheight) \ + if (slope) { \ + end1 = P_GetZAt(slope, segleft.x, segleft.y); \ + end2 = P_GetZAt(slope, segright.x, segright.y); \ + } else \ + end1 = end2 = normalheight; -#ifdef ESLOPE - if (frontsector->f_slope) { - worldbottom = P_GetZAt(frontsector->f_slope, segleft.x, segleft.y) - viewz; - worldbottomslope = P_GetZAt(frontsector->f_slope, segright.x, segright.y) - viewz; - } else { - worldbottomslope = + SLOPEPARAMS(frontsector->c_slope, worldtop, worldtopslope, frontsector->ceilingheight) + SLOPEPARAMS(frontsector->f_slope, worldbottom, worldbottomslope, frontsector->floorheight) + // subtract viewz from these to turn them into + // positions relative to the camera's z position + worldtop -= viewz; + worldtopslope -= viewz; + worldbottom -= viewz; + worldbottomslope -= viewz; #else - { + worldtop = frontsector->ceilingheight - viewz; + worldbottom = frontsector->floorheight - viewz; #endif - worldbottom = frontsector->floorheight - viewz; - } midtexture = toptexture = bottomtexture = maskedtexture = 0; ds_p->maskedtexturecol = NULL; @@ -2032,125 +2020,128 @@ void R_StoreWallRange(INT32 start, INT32 stop) else { // two sided line + boolean bothceilingssky = false; // turned on if both back and front ceilings are sky + boolean bothfloorssky = false; // likewise, but for floors #ifdef ESLOPE - if (backsector->c_slope) { - worldhigh = P_GetZAt(backsector->c_slope, segleft.x, segleft.y) - viewz; - worldhighslope = P_GetZAt(backsector->c_slope, segright.x, segright.y) - viewz; - } else { - worldhighslope = + SLOPEPARAMS(backsector->c_slope, worldhigh, worldhighslope, backsector->ceilingheight) + SLOPEPARAMS(backsector->f_slope, worldlow, worldlowslope, backsector->floorheight) + worldhigh -= viewz; + worldhighslope -= viewz; + worldlow -= viewz; + worldlowslope -= viewz; #else - { + worldhigh = backsector->ceilingheight - viewz; + worldlow = backsector->floorheight - viewz; #endif - worldhigh = backsector->ceilingheight - viewz; - } - - -#ifdef ESLOPE - if (backsector->f_slope) { - worldlow = P_GetZAt(backsector->f_slope, segleft.x, segleft.y) - viewz; - worldlowslope = P_GetZAt(backsector->f_slope, segright.x, segright.y) - viewz; - } else { - worldlowslope = -#else - { -#endif - worldlow = backsector->floorheight - viewz; - } - // hack to allow height changes in outdoor areas + // This is what gets rid of the upper textures if there should be sky if (frontsector->ceilingpic == skyflatnum && backsector->ceilingpic == skyflatnum) { -#ifdef ESLOPE - worldtopslope = worldhighslope = -#endif - worldtop = worldhigh; + bothceilingssky = true; + } + + // likewise, but for floors and upper textures + if (frontsector->floorpic == skyflatnum + && backsector->floorpic == skyflatnum) + { + bothfloorssky = true; } ds_p->sprtopclip = ds_p->sprbottomclip = NULL; ds_p->silhouette = 0; - if ( -#ifdef ESLOPE - worldbottomslope > worldlowslope || -#endif - worldbottom > worldlow) + if (!bothfloorssky) { - ds_p->silhouette = SIL_BOTTOM; + if ( #ifdef ESLOPE - if ((backsector->f_slope ? P_GetZAt(backsector->f_slope, viewx, viewy) : backsector->floorheight) > viewz) + worldbottomslope > worldlowslope || +#endif + worldbottom > worldlow) + { + ds_p->silhouette = SIL_BOTTOM; +#ifdef ESLOPE + if ((backsector->f_slope ? P_GetZAt(backsector->f_slope, viewx, viewy) : backsector->floorheight) > viewz) + ds_p->bsilheight = INT32_MAX; + else + ds_p->bsilheight = (frontsector->f_slope ? INT32_MAX : frontsector->floorheight); +#else + ds_p->bsilheight = frontsector->floorheight; +#endif + } +#ifdef ESLOPE + else if ((backsector->f_slope ? P_GetZAt(backsector->f_slope, viewx, viewy) : backsector->floorheight) > viewz) +#else + else if (backsector->floorheight > viewz) +#endif + { + ds_p->silhouette = SIL_BOTTOM; ds_p->bsilheight = INT32_MAX; - else - ds_p->bsilheight = (frontsector->f_slope ? INT32_MAX : frontsector->floorheight); -#else - ds_p->bsilheight = frontsector->floorheight; -#endif - } -#ifdef ESLOPE - else if ((backsector->f_slope ? P_GetZAt(backsector->f_slope, viewx, viewy) : backsector->floorheight) > viewz) -#else - else if (backsector->floorheight > viewz) -#endif - { - ds_p->silhouette = SIL_BOTTOM; - ds_p->bsilheight = INT32_MAX; - // ds_p->sprbottomclip = negonearray; + // ds_p->sprbottomclip = negonearray; + } } - if ( -#ifdef ESLOPE - worldtopslope < worldhighslope || -#endif - worldtop < worldhigh) + if (!bothceilingssky) { - ds_p->silhouette |= SIL_TOP; + if ( #ifdef ESLOPE - if ((backsector->c_slope ? P_GetZAt(backsector->c_slope, viewx, viewy) : backsector->ceilingheight) < viewz) + worldtopslope < worldhighslope || +#endif + worldtop < worldhigh) + { + ds_p->silhouette |= SIL_TOP; +#ifdef ESLOPE + if ((backsector->c_slope ? P_GetZAt(backsector->c_slope, viewx, viewy) : backsector->ceilingheight) < viewz) + ds_p->tsilheight = INT32_MIN; + else + ds_p->tsilheight = (frontsector->c_slope ? INT32_MIN : frontsector->ceilingheight); +#else + ds_p->tsilheight = frontsector->ceilingheight; +#endif + } +#ifdef ESLOPE + else if ((backsector->c_slope ? P_GetZAt(backsector->c_slope, viewx, viewy) : backsector->ceilingheight) < viewz) +#else + else if (backsector->ceilingheight < viewz) +#endif + { + ds_p->silhouette |= SIL_TOP; ds_p->tsilheight = INT32_MIN; - else - ds_p->tsilheight = (frontsector->c_slope ? INT32_MIN : frontsector->ceilingheight); -#else - ds_p->tsilheight = frontsector->ceilingheight; -#endif - } -#ifdef ESLOPE - else if ((backsector->c_slope ? P_GetZAt(backsector->c_slope, viewx, viewy) : backsector->ceilingheight) < viewz) -#else - else if (backsector->ceilingheight < viewz) -#endif - { - ds_p->silhouette |= SIL_TOP; - ds_p->tsilheight = INT32_MIN; - // ds_p->sprtopclip = screenheightarray; + // ds_p->sprtopclip = screenheightarray; + } } -#ifdef ESLOPE - if (worldhigh <= worldbottom && worldhighslope <= worldbottomslope) -#else - if (worldhigh <= worldbottom) -#endif + if (!bothceilingssky && !bothfloorssky) { - ds_p->sprbottomclip = negonearray; - ds_p->bsilheight = INT32_MAX; - ds_p->silhouette |= SIL_BOTTOM; - } +#ifdef ESLOPE + if (worldhigh <= worldbottom && worldhighslope <= worldbottomslope) +#else + if (worldhigh <= worldbottom) +#endif + { + ds_p->sprbottomclip = negonearray; + ds_p->bsilheight = INT32_MAX; + ds_p->silhouette |= SIL_BOTTOM; + } #ifdef ESLOPE - if (worldlow >= worldtop && worldlowslope >= worldtopslope) + if (worldlow >= worldtop && worldlowslope >= worldtopslope) #else - if (worldlow >= worldtop) + if (worldlow >= worldtop) #endif - { - ds_p->sprtopclip = screenheightarray; - ds_p->tsilheight = INT32_MIN; - ds_p->silhouette |= SIL_TOP; + { + ds_p->sprtopclip = screenheightarray; + ds_p->tsilheight = INT32_MIN; + ds_p->silhouette |= SIL_TOP; + } } //SoM: 3/25/2000: This code fixes an automap bug that didn't check // frontsector->ceiling and backsector->floor to see if a door was closed. // Without the following code, sprites get displayed behind closed doors. + if (!bothceilingssky && !bothfloorssky) { #ifdef ESLOPE if (doorclosed || (worldhigh <= worldbottom && worldhighslope <= worldbottomslope)) @@ -2174,7 +2165,13 @@ void R_StoreWallRange(INT32 start, INT32 stop) } } - if (worldlow != worldbottom + if (bothfloorssky) + { + // see double ceiling skies comment + // this is the same but for upside down thok barriers where the floor is sky and the ceiling is normal + markfloor = false; + } + else if (worldlow != worldbottom #ifdef ESLOPE || worldlowslope != worldbottomslope || backsector->f_slope != frontsector->f_slope @@ -2186,7 +2183,7 @@ void R_StoreWallRange(INT32 start, INT32 stop) || backsector->floor_yoffs != frontsector->floor_yoffs || backsector->floorpic_angle != frontsector->floorpic_angle //SoM: 3/22/2000: Prevents bleeding. - || frontsector->heightsec != -1 + || (frontsector->heightsec != -1 && frontsector->floorpic != skyflatnum) || backsector->floorlightsec != frontsector->floorlightsec //SoM: 4/3/2000: Check for colormaps || frontsector->extra_colormap != backsector->extra_colormap @@ -2200,7 +2197,14 @@ void R_StoreWallRange(INT32 start, INT32 stop) markfloor = false; } - if (worldhigh != worldtop + if (bothceilingssky) + { + // double ceiling skies are special + // we don't want to lower the ceiling clipping, (no new plane is drawn anyway) + // so we can see the floor of thok barriers always regardless of sector properties + markceiling = false; + } + else if (worldhigh != worldtop #ifdef ESLOPE || worldhighslope != worldtopslope || backsector->c_slope != frontsector->c_slope @@ -2226,19 +2230,28 @@ void R_StoreWallRange(INT32 start, INT32 stop) markceiling = false; } - if (backsector->ceilingheight <= frontsector->floorheight || - backsector->floorheight >= frontsector->ceilingheight) + if (!bothceilingssky && !bothfloorssky) { - // closed door - markceiling = markfloor = true; +#ifdef ESLOPE + if ((worldhigh <= worldbottom && worldhighslope <= worldbottomslope) + || (worldlow >= worldtop && worldlowslope >= worldtopslope)) +#else + if (backsector->ceilingheight <= frontsector->floorheight + || backsector->floorheight >= frontsector->ceilingheight) +#endif + { + // closed door + markceiling = markfloor = true; + } } // check TOP TEXTURE - if (worldhigh < worldtop + if (!bothceilingssky // never draw the top texture if on + && (worldhigh < worldtop #ifdef ESLOPE || worldhighslope < worldtopslope #endif - ) + )) { fixed_t texheight; // top texture @@ -2287,11 +2300,12 @@ void R_StoreWallRange(INT32 start, INT32 stop) } } // check BOTTOM TEXTURE - if (worldlow > worldbottom + if (!bothfloorssky // never draw the bottom texture if on + && (worldlow > worldbottom #ifdef ESLOPE || worldlowslope > worldbottomslope #endif - ) //seulement si VISIBLE!!! + )) //seulement si VISIBLE!!! { // bottom texture bottomtexture = R_GetTextureNum(sidedef->bottomtexture); @@ -2364,16 +2378,8 @@ void R_StoreWallRange(INT32 start, INT32 stop) continue; #ifdef ESLOPE - if (*rover->t_slope) { - high1 = P_GetZAt(*rover->t_slope, segleft.x, segleft.y); - highslope1 = P_GetZAt(*rover->t_slope, segright.x, segright.y); - } else - high1 = highslope1 = *rover->topheight; - if (*rover->b_slope) { - low1 = P_GetZAt(*rover->b_slope, segleft.x, segleft.y); - lowslope1 = P_GetZAt(*rover->b_slope, segright.x, segright.y); - } else - low1 = lowslope1 = *rover->bottomheight; + SLOPEPARAMS(*rover->t_slope, high1, highslope1, *rover->topheight) + SLOPEPARAMS(*rover->b_slope, low1, lowslope1, *rover->bottomheight) if ((high1 < lowcut && highslope1 < lowcutslope) || (low1 > highcut && lowslope1 > highcutslope)) continue; @@ -2405,16 +2411,8 @@ void R_StoreWallRange(INT32 start, INT32 stop) } #ifdef ESLOPE - if (*r2->t_slope) { - high2 = P_GetZAt(*r2->t_slope, segleft.x, segleft.y); - highslope2 = P_GetZAt(*r2->t_slope, segright.x, segright.y); - } else - high2 = highslope2 = *r2->topheight; - if (*r2->b_slope) { - low2 = P_GetZAt(*r2->b_slope, segleft.x, segleft.y); - lowslope2 = P_GetZAt(*r2->b_slope, segright.x, segright.y); - } else - low2 = lowslope2 = *r2->bottomheight; + SLOPEPARAMS(*r2->t_slope, high2, highslope2, *r2->topheight) + SLOPEPARAMS(*r2->b_slope, low2, lowslope2, *r2->bottomheight) if ((high2 < lowcut || highslope2 < lowcutslope) || (low2 > highcut || lowslope2 > highcutslope)) continue; @@ -2447,16 +2445,8 @@ void R_StoreWallRange(INT32 start, INT32 stop) continue; #ifdef ESLOPE - if (*rover->t_slope) { - high1 = P_GetZAt(*rover->t_slope, segleft.x, segleft.y); - highslope1 = P_GetZAt(*rover->t_slope, segright.x, segright.y); - } else - high1 = highslope1 = *rover->topheight; - if (*rover->b_slope) { - low1 = P_GetZAt(*rover->b_slope, segleft.x, segleft.y); - lowslope1 = P_GetZAt(*rover->b_slope, segright.x, segright.y); - } else - low1 = lowslope1 = *rover->bottomheight; + SLOPEPARAMS(*rover->t_slope, high1, highslope1, *rover->topheight) + SLOPEPARAMS(*rover->b_slope, low1, lowslope1, *rover->bottomheight) if ((high1 < lowcut && highslope1 < lowcutslope) || (low1 > highcut && lowslope1 > highcutslope)) continue; @@ -2488,17 +2478,9 @@ void R_StoreWallRange(INT32 start, INT32 stop) } #ifdef ESLOPE - if (*r2->t_slope) { - high2 = P_GetZAt(*r2->t_slope, segleft.x, segleft.y); - highslope2 = P_GetZAt(*r2->t_slope, segright.x, segright.y); - } else - high2 = highslope2 = *r2->topheight; - if (*r2->b_slope) { - low2 = P_GetZAt(*r2->b_slope, segleft.x, segleft.y); - lowslope2 = P_GetZAt(*r2->b_slope, segright.x, segright.y); - } else - low2 = lowslope2 = *r2->bottomheight; - + SLOPEPARAMS(*r2->t_slope, high2, highslope2, *r2->topheight) + SLOPEPARAMS(*r2->b_slope, low2, lowslope2, *r2->bottomheight) +#undef SLOPEPARAMS if ((high2 < lowcut || highslope2 < lowcutslope) || (low2 > highcut || lowslope2 > highcutslope)) continue; if ((high1 > high2 || highslope1 > highslope2) || (low1 < low2 || lowslope1 < lowslope2)) @@ -2677,7 +2659,8 @@ void R_StoreWallRange(INT32 start, INT32 stop) // and doesn't need to be marked. if (frontsector->heightsec == -1) { - if (( + if (frontsector->floorpic != skyflatnum + && ( #ifdef ESLOPE frontsector->f_slope ? P_GetZAt(frontsector->f_slope, viewx, viewy) : #endif @@ -2687,12 +2670,12 @@ void R_StoreWallRange(INT32 start, INT32 stop) markfloor = false; } - if (( + if (frontsector->ceilingpic != skyflatnum + && ( #ifdef ESLOPE frontsector->c_slope ? P_GetZAt(frontsector->c_slope, viewx, viewy) : #endif - frontsector->ceilingheight) <= viewz && - frontsector->ceilingpic != skyflatnum) + frontsector->ceilingheight) <= viewz) { // below view plane markceiling = false; @@ -3150,6 +3133,22 @@ void R_StoreWallRange(INT32 start, INT32 stop) for (i = 0; i < numffloors; i++) R_ExpandPlane(ffloor[i].plane, rw_x, rw_stopx - 1); } +#ifdef POLYOBJECTS_PLANES + // FIXME hack to fix planes disappearing when a seg goes behind the camera. This NEEDS to be changed to be done properly. -Red + if (curline->polyseg) + { + for (i = 0; i < numffloors; i++) + { + if (!ffloor[i].polyobj || ffloor[i].polyobj != curline->polyseg) + continue; + if (ffloor[i].plane->minx > rw_x) + ffloor[i].plane->minx = rw_x; + + if (ffloor[i].plane->maxx < rw_stopx - 1) + ffloor[i].plane->maxx = rw_stopx - 1; + } + } +#endif } #ifdef WALLSPLATS