diff --git a/src/r_main.c b/src/r_main.c index 8e0989f3b..6104b7ca3 100644 --- a/src/r_main.c +++ b/src/r_main.c @@ -1061,8 +1061,7 @@ void R_RenderPlayerView(player_t *player) masks[nummasks - 1].drawsegs[1] = ds_p - drawsegs; masks[nummasks - 1].vissprites[1] = visspritecount; - - R_ClipSprites(); + R_ClipSprites(drawsegs, NULL); #ifdef TIMING RDMSR(0x10, &mycount); mytotal += mycount; // 64bit add @@ -1108,7 +1107,8 @@ void R_RenderPlayerView(player_t *player) R_RenderBSPNode((INT32)numnodes - 1); masks[nummasks - 1].drawsegs[1] = ds_p - drawsegs; masks[nummasks - 1].vissprites[1] = visspritecount; - R_ClipSprites(); + + R_ClipSprites(ds_p - (masks[nummasks - 1].drawsegs[1] - masks[nummasks - 1].drawsegs[0]), portal); Portal_Remove(portal); } diff --git a/src/r_portal.c b/src/r_portal.c index b3d363f63..4825bb511 100644 --- a/src/r_portal.c +++ b/src/r_portal.c @@ -17,6 +17,7 @@ #include "doomstat.h" #include "p_spec.h" // Skybox viewpoints #include "z_zone.h" +#include "r_things.h" UINT8 portalrender; /**< When rendering a portal, it establishes the depth of the current BSP traversal. */ sector_t *portalcullsector; @@ -98,9 +99,9 @@ void Portal_ClipApply (const portal_t* portal) portal_t* Portal_Add (const INT16 x1, const INT16 x2) { portal_t *portal = Z_Malloc(sizeof(portal_t), PU_LEVEL, NULL); - INT16 *ceilingclipsave = Z_Malloc(sizeof(INT16)*(x2-x1), PU_LEVEL, NULL); - INT16 *floorclipsave = Z_Malloc(sizeof(INT16)*(x2-x1), PU_LEVEL, NULL); - fixed_t *frontscalesave = Z_Malloc(sizeof(fixed_t)*(x2-x1), PU_LEVEL, NULL); + INT16 *ceilingclipsave = Z_Malloc(sizeof(INT16)*(x2-x1 + 1), PU_LEVEL, NULL); + INT16 *floorclipsave = Z_Malloc(sizeof(INT16)*(x2-x1 + 1), PU_LEVEL, NULL); + fixed_t *frontscalesave = Z_Malloc(sizeof(fixed_t)*(x2-x1 + 1), PU_LEVEL, NULL); // Linked list. if (!portal_base) @@ -199,15 +200,7 @@ static void Portal_ClipVisplane (const visplane_t* plane, portal_t* portal) for (i = 0; i < end - start; i++) { - if (plane->bottom[i + start] == 0) - { - portal->ceilingclip[i] = 0; - portal->floorclip[i] = 0; - continue; - } - - - portal->ceilingclip[i] = plane->top[i + start] - 1; + portal->ceilingclip[i] = plane->top[i + start]; portal->floorclip[i] = plane->bottom[i + start] + 1; portal->frontscale[i] = INT32_MAX; } @@ -230,6 +223,25 @@ void Portal_AddSkybox (const visplane_t* plane) if (!(start < end)) return; + /** Trims a visplane's horizontal gap to match its render area. + * + * Visplanes' minx/maxx may sometimes exceed the area they're + * covering. This merely adjusts the boundaries to the next + * valid area. + */ + + while (plane->bottom[start] == 0 && plane->top[start] == 65535 && start < end) + { + start++; + } + + + while (plane->bottom[end - 1] == 0 && plane->top[start] == 65535 && end > start) + { + end--; + } + + portal = Portal_Add(start, end); Portal_ClipVisplane(plane, portal); diff --git a/src/r_portal.h b/src/r_portal.h index fad62a298..f7d2fb2fe 100644 --- a/src/r_portal.h +++ b/src/r_portal.h @@ -11,6 +11,9 @@ /// \file r_portal.h /// \brief Software renderer portal struct, functions, linked list extern. +#ifndef __R_PORTAL__ +#define __R_PORTAL__ + #include "r_data.h" #include "r_plane.h" // visplanes @@ -52,3 +55,5 @@ void Portal_AddSkybox (const visplane_t* plane); void Portal_ClipRange (portal_t* portal); void Portal_ClipApply (const portal_t* portal); + +#endif diff --git a/src/r_things.c b/src/r_things.c index 8be926adf..e0cf34dba 100644 --- a/src/r_things.c +++ b/src/r_things.c @@ -2185,7 +2185,7 @@ static void R_DrawPrecipitationSprite(vissprite_t *spr) // R_ClipSprites // Clips vissprites without drawing, so that portals can work. -Red -void R_ClipSprites(void) +void R_ClipSprites(drawseg_t* dsstart, portal_t* portal) { vissprite_t *spr; for (; clippedvissprites < visspritecount; clippedvissprites++) @@ -2211,7 +2211,7 @@ void R_ClipSprites(void) // and buggy, by going past LEFT end of array: // for (ds = ds_p-1; ds >= drawsegs; ds--) old buggy code - for (ds = ds_p; ds-- > drawsegs ;) + for (ds = ds_p; ds-- > dsstart;) { // determine if the drawseg obscures the sprite if (ds->x1 > spr->x2 || @@ -2223,34 +2223,37 @@ void R_ClipSprites(void) continue; } - if (ds->portalpass > 0 && ds->portalpass <= portalrender) - continue; // is a portal + if (ds->portalpass != 66) + { + if (ds->portalpass > 0 && ds->portalpass <= portalrender) + continue; // is a portal + + if (ds->scale1 > ds->scale2) + { + lowscale = ds->scale2; + scale = ds->scale1; + } + else + { + lowscale = ds->scale1; + scale = ds->scale2; + } + + if (scale < spr->sortscale || + (lowscale < spr->sortscale && + !R_PointOnSegSide (spr->gx, spr->gy, ds->curline))) + { + // masked mid texture? + /*if (ds->maskedtexturecol) + R_RenderMaskedSegRange (ds, r1, r2);*/ + // seg is behind sprite + continue; + } + } r1 = ds->x1 < spr->x1 ? spr->x1 : ds->x1; r2 = ds->x2 > spr->x2 ? spr->x2 : ds->x2; - if (ds->scale1 > ds->scale2) - { - lowscale = ds->scale2; - scale = ds->scale1; - } - else - { - lowscale = ds->scale1; - scale = ds->scale2; - } - - if (scale < spr->sortscale || - (lowscale < spr->sortscale && - !R_PointOnSegSide (spr->gx, spr->gy, ds->curline))) - { - // masked mid texture? - /*if (ds->maskedtexturecol) - R_RenderMaskedSegRange (ds, r1, r2);*/ - // seg is behind sprite - continue; - } - // clip this piece of the sprite silhouette = ds->silhouette; @@ -2367,6 +2370,17 @@ void R_ClipSprites(void) //Fab : 26-04-98: was -1, now clips against console bottom spr->cliptop[x] = (INT16)con_clipviewtop; } + + if (portal) + { + for (x = spr->x1; x <= spr->x2; x++) + { + if (spr->clipbot[x] > portal->floorclip[x - portal->start]) + spr->clipbot[x] = portal->floorclip[x - portal->start]; + if (spr->cliptop[x] < portal->ceilingclip[x - portal->start]) + spr->cliptop[x] = portal->ceilingclip[x - portal->start]; + } + } } } @@ -2444,12 +2458,13 @@ void R_DrawMasked(maskcount_t* masks, UINT8 nummasks) R_CreateDrawNodes(&masks[i], &heads[i], false); } - for (i = 0; i < nummasks; i++) - CONS_Printf("Mask no.%d:\ndrawsegs: %d\n vissprites: %d\n\n", i, masks[i].drawsegs[1] - masks[i].drawsegs[0], masks[i].vissprites[1] - masks[i].vissprites[0]); + //for (i = 0; i < nummasks; i++) + // CONS_Printf("Mask no.%d:\ndrawsegs: %d\n vissprites: %d\n\n", i, masks[i].drawsegs[1] - masks[i].drawsegs[0], masks[i].vissprites[1] - masks[i].vissprites[0]); for (; nummasks > 0; nummasks--) { viewz = masks[nummasks - 1].viewz; + R_DrawMaskedList(&heads[nummasks - 1]); R_ClearDrawNodes(&heads[nummasks - 1]); } diff --git a/src/r_things.h b/src/r_things.h index 08a13c1ce..27c45def4 100644 --- a/src/r_things.h +++ b/src/r_things.h @@ -16,6 +16,7 @@ #include "sounds.h" #include "r_plane.h" +#include "r_portal.h" // "Left" and "Right" character symbols for additional rotation functionality #define ROT_L ('L' - '0') @@ -54,7 +55,7 @@ void R_AddSpriteDefs(UINT16 wadnum); void R_AddSprites(sector_t *sec, INT32 lightlevel); void R_InitSprites(void); void R_ClearSprites(void); -void R_ClipSprites(void); +void R_ClipSprites(drawseg_t* dsstart, portal_t* portal); /** Used to count the amount of masked elements * per portal to later group them in separate