diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 3451b000b..e7e819626 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -819,7 +819,6 @@ set( FASTMATH_PCH_SOURCES swrenderer/drawers/r_thread.cpp swrenderer/scene/r_3dfloors.cpp swrenderer/scene/r_bsp.cpp - swrenderer/scene/r_plane.cpp swrenderer/scene/r_segs.cpp swrenderer/scene/r_things.cpp swrenderer/scene/r_walldraw.cpp diff --git a/src/swrenderer/drawers/r_draw.cpp b/src/swrenderer/drawers/r_draw.cpp index 9d991a039..99a37a18a 100644 --- a/src/swrenderer/drawers/r_draw.cpp +++ b/src/swrenderer/drawers/r_draw.cpp @@ -58,7 +58,6 @@ namespace swrenderer { double dc_texturemid; FLightNode *dc_light_list; - visplane_light *ds_light_list; int ylookup[MAXHEIGHT]; uint8_t shadetables[NUMCOLORMAPS * 16 * 256]; diff --git a/src/swrenderer/drawers/r_draw.h b/src/swrenderer/drawers/r_draw.h index 47d232cff..6715589b3 100644 --- a/src/swrenderer/drawers/r_draw.h +++ b/src/swrenderer/drawers/r_draw.h @@ -20,7 +20,6 @@ EXTERN_CVAR(Bool, r_dynlights); namespace swrenderer { struct vissprite_t; - struct visplane_light; struct ShadeConstants { @@ -38,7 +37,6 @@ namespace swrenderer extern double dc_texturemid; extern FLightNode *dc_light_list; - extern visplane_light *ds_light_list; namespace drawerargs { diff --git a/src/swrenderer/drawers/r_draw_rgba.cpp b/src/swrenderer/drawers/r_draw_rgba.cpp index 21f7da828..309a3e2bd 100644 --- a/src/swrenderer/drawers/r_draw_rgba.cpp +++ b/src/swrenderer/drawers/r_draw_rgba.cpp @@ -36,7 +36,6 @@ #include "r_data/r_translate.h" #include "v_palette.h" #include "r_data/colormaps.h" -#include "swrenderer/scene/r_plane.h" #include "r_draw_rgba.h" #include "r_drawers.h" #include "gl/data/gl_matrix.h" diff --git a/src/swrenderer/plane/r_flatplane.cpp b/src/swrenderer/plane/r_flatplane.cpp index 51d7b88cc..354396cc7 100644 --- a/src/swrenderer/plane/r_flatplane.cpp +++ b/src/swrenderer/plane/r_flatplane.cpp @@ -28,7 +28,6 @@ #include "swrenderer/segments/r_clipsegment.h" #include "swrenderer/segments/r_drawsegment.h" #include "swrenderer/scene/r_portal.h" -#include "swrenderer/scene/r_plane.h" #include "swrenderer/r_memory.h" namespace swrenderer @@ -43,6 +42,7 @@ namespace swrenderer fixed_t xscale, yscale; double xstepscale, ystepscale; double basexfrac, baseyfrac; + visplane_light *ds_light_list; } void R_DrawNormalPlane(visplane_t *pl, double _xscale, double _yscale, fixed_t alpha, bool additive, bool masked) @@ -178,6 +178,9 @@ namespace swrenderer } } } + + ds_light_list = pl->lights; + R_MapVisPlane(pl, R_MapPlane, R_StepPlane); } diff --git a/src/swrenderer/plane/r_fogboundary.cpp b/src/swrenderer/plane/r_fogboundary.cpp index 3dff9fa60..fb140db71 100644 --- a/src/swrenderer/plane/r_fogboundary.cpp +++ b/src/swrenderer/plane/r_fogboundary.cpp @@ -28,7 +28,6 @@ #include "swrenderer/segments/r_clipsegment.h" #include "swrenderer/segments/r_drawsegment.h" #include "swrenderer/scene/r_portal.h" -#include "swrenderer/scene/r_plane.h" #include "swrenderer/r_memory.h" #ifdef _MSC_VER diff --git a/src/swrenderer/plane/r_slopeplane.cpp b/src/swrenderer/plane/r_slopeplane.cpp index b2dccead8..3742f2f40 100644 --- a/src/swrenderer/plane/r_slopeplane.cpp +++ b/src/swrenderer/plane/r_slopeplane.cpp @@ -28,7 +28,6 @@ #include "swrenderer/segments/r_clipsegment.h" #include "swrenderer/segments/r_drawsegment.h" #include "swrenderer/scene/r_portal.h" -#include "swrenderer/scene/r_plane.h" #include "swrenderer/r_memory.h" #ifdef _MSC_VER diff --git a/src/swrenderer/plane/r_visibleplane.cpp b/src/swrenderer/plane/r_visibleplane.cpp index 79f7ea2e7..f175f0063 100644 --- a/src/swrenderer/plane/r_visibleplane.cpp +++ b/src/swrenderer/plane/r_visibleplane.cpp @@ -7,8 +7,6 @@ #include "w_wad.h" #include "doomdef.h" #include "doomstat.h" -#include "swrenderer/r_main.h" -#include "swrenderer/scene/r_things.h" #include "r_sky.h" #include "stats.h" #include "v_video.h" @@ -17,8 +15,19 @@ #include "cmdlib.h" #include "d_net.h" #include "g_level.h" +#include "gl/dynlights/gl_dynlight.h" +#include "swrenderer/r_main.h" #include "swrenderer/scene/r_bsp.h" -#include "r_visibleplane.h" +#include "swrenderer/scene/r_things.h" +#include "swrenderer/scene/r_3dfloors.h" +#include "swrenderer/scene/r_portal.h" +#include "swrenderer/plane/r_flatplane.h" +#include "swrenderer/plane/r_slopeplane.h" +#include "swrenderer/plane/r_skyplane.h" +#include "swrenderer/plane/r_visibleplane.h" +#include "swrenderer/drawers/r_draw.h" + +CVAR(Bool, tilt, false, 0); namespace swrenderer { @@ -32,6 +41,8 @@ namespace swrenderer enum { max_plane_lights = 32 * 1024 }; visplane_light plane_lights[max_plane_lights]; int next_plane_light = 0; + + short spanend[MAXHEIGHT]; } void R_DeinitPlanes() @@ -39,12 +50,12 @@ namespace swrenderer // do not use R_ClearPlanes because at this point the screen pointer is no longer valid. for (int i = 0; i <= MAXVISPLANES; i++) // new code -- killough { - for (*freehead = visplanes[i], visplanes[i] = NULL; *freehead; ) + for (*freehead = visplanes[i], visplanes[i] = nullptr; *freehead; ) { freehead = &(*freehead)->next; } } - for (visplane_t *pl = freetail; pl != NULL; ) + for (visplane_t *pl = freetail; pl != nullptr; ) { visplane_t *next = pl->next; free(pl); @@ -56,13 +67,13 @@ namespace swrenderer { visplane_t *check = freetail; - if (check == NULL) + if (check == nullptr) { check = (visplane_t *)M_Malloc(sizeof(*check) + 3 + sizeof(*check->top)*(MAXWIDTH * 2)); memset(check, 0, sizeof(*check) + 3 + sizeof(*check->top)*(MAXWIDTH * 2)); check->bottom = check->top + MAXWIDTH + 2; } - else if (NULL == (freetail = freetail->next)) + else if (nullptr == (freetail = freetail->next)) { freehead = &freetail; } @@ -88,13 +99,13 @@ namespace swrenderer M_Free(pl); pl = next; } - freetail = NULL; + freetail = nullptr; freehead = &freetail; for (i = 0; i < MAXVISPLANES; i++) { pl = visplanes[i]; - visplanes[i] = NULL; + visplanes[i] = nullptr; while (pl) { visplane_t *next = pl->next; @@ -103,4 +114,460 @@ namespace swrenderer } } } + + void R_ClearPlanes(bool fullclear) + { + int i; + + // Don't clear fake planes if not doing a full clear. + if (!fullclear) + { + for (i = 0; i <= MAXVISPLANES - 1; i++) // new code -- killough + { + for (visplane_t **probe = &visplanes[i]; *probe != nullptr; ) + { + if ((*probe)->sky < 0) + { // fake: move past it + probe = &(*probe)->next; + } + else + { // not fake: move to freelist + visplane_t *vis = *probe; + *freehead = vis; + *probe = vis->next; + vis->next = nullptr; + freehead = &vis->next; + } + } + } + } + else + { + for (i = 0; i <= MAXVISPLANES; i++) // new code -- killough + { + for (*freehead = visplanes[i], visplanes[i] = nullptr; *freehead; ) + { + freehead = &(*freehead)->next; + } + } + + next_plane_light = 0; + } + } + + void R_AddPlaneLights(visplane_t *plane, FLightNode *node) + { + if (!r_dynlights) + return; + + while (node) + { + if (!(node->lightsource->flags2&MF2_DORMANT)) + { + bool found = false; + visplane_light *light_node = plane->lights; + while (light_node) + { + if (light_node->lightsource == node->lightsource) + { + found = true; + break; + } + light_node = light_node->next; + } + if (!found) + { + if (next_plane_light == max_plane_lights) + return; + + visplane_light *newlight = &plane_lights[next_plane_light++]; + newlight->next = plane->lights; + newlight->lightsource = node->lightsource; + plane->lights = newlight; + } + } + node = node->nextLight; + } + } + + visplane_t *R_FindPlane(const secplane_t &height, FTextureID picnum, int lightlevel, double Alpha, bool additive, const FTransform &xxform, int sky, FSectorPortal *portal) + { + secplane_t plane; + visplane_t *check; + unsigned hash; // killough + bool isskybox; + const FTransform *xform = &xxform; + fixed_t alpha = FLOAT2FIXED(Alpha); + //angle_t angle = (xform.Angle + xform.baseAngle).BAMs(); + + FTransform nulltransform; + + if (picnum == skyflatnum) // killough 10/98 + { // most skies map together + lightlevel = 0; + xform = &nulltransform; + nulltransform.xOffs = nulltransform.yOffs = nulltransform.baseyOffs = 0; + nulltransform.xScale = nulltransform.yScale = 1; + nulltransform.Angle = nulltransform.baseAngle = 0.0; + additive = false; + // [RH] Map floor skies and ceiling skies to separate visplanes. This isn't + // always necessary, but it is needed if a floor and ceiling sky are in the + // same column but separated by a wall. If they both try to reside in the + // same visplane, then only the floor sky will be drawn. + plane.set(0., 0., height.fC(), 0.); + isskybox = portal != nullptr && !(portal->mFlags & PORTSF_INSKYBOX); + } + else if (portal != nullptr && !(portal->mFlags & PORTSF_INSKYBOX)) + { + plane = height; + isskybox = true; + } + else + { + plane = height; + isskybox = false; + // kg3D - hack, store alpha in sky + // i know there is ->alpha, but this also allows to identify fake plane + // and ->alpha is for stacked sectors + if (fake3D & (FAKE3D_FAKEFLOOR | FAKE3D_FAKECEILING)) sky = 0x80000000 | fakeAlpha; + else sky = 0; // not skyflatnum so it can't be a sky + portal = nullptr; + alpha = OPAQUE; + } + + // New visplane algorithm uses hash table -- killough + hash = isskybox ? MAXVISPLANES : visplane_hash(picnum.GetIndex(), lightlevel, height); + + for (check = visplanes[hash]; check; check = check->next) // killough + { + if (isskybox) + { + if (portal == check->portal && plane == check->height) + { + if (portal->mType != PORTS_SKYVIEWPOINT) + { // This skybox is really a stacked sector, so we need to + // check even more. + if (check->extralight == stacked_extralight && + check->visibility == stacked_visibility && + check->viewpos == stacked_viewpos && + ( + // headache inducing logic... :( + (portal->mType != PORTS_STACKEDSECTORTHING) || + ( + check->Alpha == alpha && + check->Additive == additive && + (alpha == 0 || // if alpha is > 0 everything needs to be checked + (plane == check->height && + picnum == check->picnum && + lightlevel == check->lightlevel && + basecolormap == check->colormap && // [RH] Add more checks + *xform == check->xform + ) + ) && + check->viewangle == stacked_angle + ) + ) + ) + { + return check; + } + } + else + { + return check; + } + } + } + else + if (plane == check->height && + picnum == check->picnum && + lightlevel == check->lightlevel && + basecolormap == check->colormap && // [RH] Add more checks + *xform == check->xform && + sky == check->sky && + CurrentPortalUniq == check->CurrentPortalUniq && + MirrorFlags == check->MirrorFlags && + CurrentSkybox == check->CurrentSkybox && + ViewPos == check->viewpos + ) + { + return check; + } + } + + check = new_visplane(hash); // killough + + check->height = plane; + check->picnum = picnum; + check->lightlevel = lightlevel; + check->xform = *xform; + check->colormap = basecolormap; // [RH] Save colormap + check->sky = sky; + check->portal = portal; + check->left = viewwidth; // Was SCREENWIDTH -- killough 11/98 + check->right = 0; + check->extralight = stacked_extralight; + check->visibility = stacked_visibility; + check->viewpos = stacked_viewpos; + check->viewangle = stacked_angle; + check->Alpha = alpha; + check->Additive = additive; + check->CurrentPortalUniq = CurrentPortalUniq; + check->MirrorFlags = MirrorFlags; + check->CurrentSkybox = CurrentSkybox; + + fillshort(check->top, viewwidth, 0x7fff); + + return check; + } + + visplane_t *R_CheckPlane(visplane_t *pl, int start, int stop) + { + int intrl, intrh; + int unionl, unionh; + int x; + + assert(start >= 0 && start < viewwidth); + assert(stop > start && stop <= viewwidth); + + if (start < pl->left) + { + intrl = pl->left; + unionl = start; + } + else + { + unionl = pl->left; + intrl = start; + } + + if (stop > pl->right) + { + intrh = pl->right; + unionh = stop; + } + else + { + unionh = pl->right; + intrh = stop; + } + + for (x = intrl; x < intrh && pl->top[x] == 0x7fff; x++) + ; + + if (x >= intrh) + { + // use the same visplane + pl->left = unionl; + pl->right = unionh; + } + else + { + // make a new visplane + unsigned hash; + + if (pl->portal != nullptr && !(pl->portal->mFlags & PORTSF_INSKYBOX) && viewactive) + { + hash = MAXVISPLANES; + } + else + { + hash = visplane_hash(pl->picnum.GetIndex(), pl->lightlevel, pl->height); + } + visplane_t *new_pl = new_visplane(hash); + + new_pl->height = pl->height; + new_pl->picnum = pl->picnum; + new_pl->lightlevel = pl->lightlevel; + new_pl->xform = pl->xform; + new_pl->colormap = pl->colormap; + new_pl->portal = pl->portal; + new_pl->extralight = pl->extralight; + new_pl->visibility = pl->visibility; + new_pl->viewpos = pl->viewpos; + new_pl->viewangle = pl->viewangle; + new_pl->sky = pl->sky; + new_pl->Alpha = pl->Alpha; + new_pl->Additive = pl->Additive; + new_pl->CurrentPortalUniq = pl->CurrentPortalUniq; + new_pl->MirrorFlags = pl->MirrorFlags; + new_pl->CurrentSkybox = pl->CurrentSkybox; + new_pl->lights = pl->lights; + pl = new_pl; + pl->left = start; + pl->right = stop; + fillshort(pl->top, viewwidth, 0x7fff); + } + return pl; + } + + int R_DrawPlanes() + { + visplane_t *pl; + int i; + int vpcount = 0; + + drawerargs::ds_color = 3; + + for (i = 0; i < MAXVISPLANES; i++) + { + for (pl = visplanes[i]; pl; pl = pl->next) + { + // kg3D - draw only correct planes + if (pl->CurrentPortalUniq != CurrentPortalUniq || pl->CurrentSkybox != CurrentSkybox) + continue; + // kg3D - draw only real planes now + if (pl->sky >= 0) { + vpcount++; + R_DrawSinglePlane(pl, OPAQUE, false, false); + } + } + } + return vpcount; + } + + void R_DrawHeightPlanes(double height) + { + visplane_t *pl; + int i; + + drawerargs::ds_color = 3; + + DVector3 oViewPos = ViewPos; + DAngle oViewAngle = ViewAngle; + + for (i = 0; i < MAXVISPLANES; i++) + { + for (pl = visplanes[i]; pl; pl = pl->next) + { + if (pl->CurrentSkybox != CurrentSkybox || pl->CurrentPortalUniq != CurrentPortalUniq) + continue; + + if (pl->sky < 0 && pl->height.Zat0() == height) + { + ViewPos = pl->viewpos; + ViewAngle = pl->viewangle; + MirrorFlags = pl->MirrorFlags; + + R_DrawSinglePlane(pl, pl->sky & 0x7FFFFFFF, pl->Additive, true); + } + } + } + ViewPos = oViewPos; + ViewAngle = oViewAngle; + } + + void R_DrawSinglePlane(visplane_t *pl, fixed_t alpha, bool additive, bool masked) + { + if (pl->left >= pl->right) + return; + + if (r_drawflat) // no texture mapping + { + drawerargs::ds_color += 4; + R_DrawColoredPlane(pl); + } + else if (pl->picnum == skyflatnum) // sky flat + { + R_DrawSkyPlane(pl); + } + else // regular flat + { + FTexture *tex = TexMan(pl->picnum, true); + + if (tex->UseType == FTexture::TEX_Null) + { + return; + } + + if (!masked && !additive) + { // If we're not supposed to see through this plane, draw it opaque. + alpha = OPAQUE; + } + else if (!tex->bMasked) + { // Don't waste time on a masked texture if it isn't really masked. + masked = false; + } + R_SetSpanTexture(tex); + double xscale = pl->xform.xScale * tex->Scale.X; + double yscale = pl->xform.yScale * tex->Scale.Y; + + basecolormap = pl->colormap; + + if (r_drawflat || (!pl->height.isSlope() && !tilt)) + { + R_DrawNormalPlane(pl, xscale, yscale, alpha, additive, masked); + } + else + { + R_DrawTiltedPlane(pl, xscale, yscale, alpha, additive, masked); + } + } + NetUpdate(); + } + + void R_MapVisPlane(visplane_t *pl, void(*mapfunc)(int y, int x1, int x2), void(*stepfunc)()) + { + // t1/b1 are at x + // t2/b2 are at x+1 + // spanend[y] is at the right edge + + int x = pl->right - 1; + int t2 = pl->top[x]; + int b2 = pl->bottom[x]; + + if (b2 > t2) + { + fillshort(spanend + t2, b2 - t2, x); + } + + for (--x; x >= pl->left; --x) + { + int t1 = pl->top[x]; + int b1 = pl->bottom[x]; + const int xr = x + 1; + int stop; + + // Draw any spans that have just closed + stop = MIN(t1, b2); + while (t2 < stop) + { + int y = t2++; + int x2 = spanend[y]; + mapfunc(y, xr, x2); + } + stop = MAX(b1, t2); + while (b2 > stop) + { + int y = --b2; + int x2 = spanend[y]; + mapfunc(y, xr, x2); + } + + // Mark any spans that have just opened + stop = MIN(t2, b1); + while (t1 < stop) + { + spanend[t1++] = x; + } + stop = MAX(b2, t2); + while (b1 > stop) + { + spanend[--b1] = x; + } + + t2 = pl->top[x]; + b2 = pl->bottom[x]; + + if (stepfunc) + stepfunc(); + } + // Draw any spans that are still open + while (t2 < b2) + { + int y = --b2; + int x2 = spanend[y]; + mapfunc(y, pl->left, x2); + } + } } diff --git a/src/swrenderer/plane/r_visibleplane.h b/src/swrenderer/plane/r_visibleplane.h index 28e703505..1c2ee717f 100644 --- a/src/swrenderer/plane/r_visibleplane.h +++ b/src/swrenderer/plane/r_visibleplane.h @@ -63,5 +63,17 @@ namespace swrenderer void R_DeinitPlanes(); visplane_t *new_visplane(unsigned hash); + void R_PlaneInitData(); + void R_ClearPlanes(bool fullclear); + + void R_AddPlaneLights(visplane_t *plane, FLightNode *node); + + visplane_t *R_FindPlane(const secplane_t &height, FTextureID picnum, int lightlevel, double Alpha, bool additive, const FTransform &xxform, int sky, FSectorPortal *portal); + visplane_t *R_CheckPlane(visplane_t *pl, int start, int stop); + + int R_DrawPlanes(); + void R_DrawHeightPlanes(double height); + void R_DrawSinglePlane(visplane_t *pl, fixed_t alpha, bool additive, bool masked); + void R_MapVisPlane(visplane_t *pl, void(*mapfunc)(int y, int x1, int x2), void(*stepfunc)()); } diff --git a/src/swrenderer/r_main.cpp b/src/swrenderer/r_main.cpp index 37295fe7b..42e8e98dc 100644 --- a/src/swrenderer/r_main.cpp +++ b/src/swrenderer/r_main.cpp @@ -37,7 +37,6 @@ #include "r_main.h" #include "scene/r_things.h" #include "drawers/r_draw.h" -#include "scene/r_plane.h" #include "plane/r_flatplane.h" #include "scene/r_bsp.h" #include "segments/r_drawsegment.h" diff --git a/src/swrenderer/scene/r_3dfloors.cpp b/src/swrenderer/scene/r_3dfloors.cpp index f2d7f88e8..5b487d8d8 100644 --- a/src/swrenderer/scene/r_3dfloors.cpp +++ b/src/swrenderer/scene/r_3dfloors.cpp @@ -11,7 +11,6 @@ #include "c_dispatch.h" #include "swrenderer/r_main.h" #include "r_bsp.h" -#include "r_plane.h" #include "r_segs.h" #include "c_cvars.h" #include "r_3dfloors.h" diff --git a/src/swrenderer/scene/r_bsp.cpp b/src/swrenderer/scene/r_bsp.cpp index ba939390f..debee35c6 100644 --- a/src/swrenderer/scene/r_bsp.cpp +++ b/src/swrenderer/scene/r_bsp.cpp @@ -33,12 +33,12 @@ #include "p_setup.h" #include "swrenderer/r_main.h" -#include "r_plane.h" #include "swrenderer/drawers/r_draw.h" -#include "r_things.h" +#include "swrenderer/plane/r_visibleplane.h" #include "swrenderer/things/r_particle.h" -#include "r_3dfloors.h" #include "swrenderer/segments/r_clipsegment.h" +#include "r_things.h" +#include "r_3dfloors.h" #include "r_portal.h" #include "a_sharedglobal.h" #include "g_level.h" diff --git a/src/swrenderer/scene/r_plane.cpp b/src/swrenderer/scene/r_plane.cpp deleted file mode 100644 index f18d1e533..000000000 --- a/src/swrenderer/scene/r_plane.cpp +++ /dev/null @@ -1,609 +0,0 @@ -// Emacs style mode select -*- C++ -*- -//----------------------------------------------------------------------------- -// -// $Id:$ -// -// Copyright (C) 1993-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: -// Here is a core component: drawing the floors and ceilings, -// while maintaining a per column clipping list only. -// Moreover, the sky areas have to be determined. -// -// MAXVISPLANES is no longer a limit on the number of visplanes, -// but a limit on the number of hash slots; larger numbers mean -// better performance usually but after a point they are wasted, -// and memory and time overheads creep in. -// -// Lee Killough -// -// [RH] Further modified to significantly increase accuracy and add slopes. -// -//----------------------------------------------------------------------------- - -#include -#include - -#include "templates.h" -#include "i_system.h" -#include "w_wad.h" - -#include "doomdef.h" -#include "doomstat.h" - -#include "swrenderer/r_main.h" -#include "swrenderer/scene/r_things.h" -#include "r_sky.h" -#include "stats.h" - -#include "v_video.h" -#include "a_sharedglobal.h" -#include "c_console.h" -#include "cmdlib.h" -#include "d_net.h" -#include "g_level.h" -#include "r_bsp.h" -#include "r_plane.h" -#include "r_segs.h" -#include "r_3dfloors.h" -#include "v_palette.h" -#include "r_data/colormaps.h" -#include "swrenderer/drawers/r_draw_rgba.h" -#include "gl/dynlights/gl_dynlight.h" -#include "r_walldraw.h" -#include "swrenderer/segments/r_clipsegment.h" -#include "swrenderer/segments/r_drawsegment.h" -#include "r_portal.h" -#include "swrenderer/plane/r_skyplane.h" -#include "swrenderer/plane/r_flatplane.h" -#include "swrenderer/plane/r_slopeplane.h" -#include "swrenderer/r_memory.h" - -#ifdef _MSC_VER -#pragma warning(disable:4244) -#endif - -CVAR(Bool, tilt, false, 0); - -namespace swrenderer -{ - using namespace drawerargs; - - -namespace -{ - short spanend[MAXHEIGHT]; -} - -void R_DrawSinglePlane (visplane_t *, fixed_t alpha, bool additive, bool masked); - - -//========================================================================== - - -//========================================================================== - -namespace -{ - enum { max_plane_lights = 32 * 1024 }; - visplane_light plane_lights[max_plane_lights]; - int next_plane_light = 0; -} - -void R_AddPlaneLights(visplane_t *plane, FLightNode *node) -{ - if (!r_dynlights) - return; - - while (node) - { - if (!(node->lightsource->flags2&MF2_DORMANT)) - { - bool found = false; - visplane_light *light_node = plane->lights; - while (light_node) - { - if (light_node->lightsource == node->lightsource) - { - found = true; - break; - } - light_node = light_node->next; - } - if (!found) - { - if (next_plane_light == max_plane_lights) - return; - - visplane_light *newlight = &plane_lights[next_plane_light++]; - newlight->next = plane->lights; - newlight->lightsource = node->lightsource; - plane->lights = newlight; - } - } - node = node->nextLight; - } -} - -//========================================================================== -// -// R_ClearPlanes -// -// Called at the beginning of each frame. -// -//========================================================================== - -void R_ClearPlanes (bool fullclear) -{ - int i; - - // Don't clear fake planes if not doing a full clear. - if (!fullclear) - { - for (i = 0; i <= MAXVISPLANES-1; i++) // new code -- killough - { - for (visplane_t **probe = &visplanes[i]; *probe != NULL; ) - { - if ((*probe)->sky < 0) - { // fake: move past it - probe = &(*probe)->next; - } - else - { // not fake: move to freelist - visplane_t *vis = *probe; - *freehead = vis; - *probe = vis->next; - vis->next = NULL; - freehead = &vis->next; - } - } - } - } - else - { - for (i = 0; i <= MAXVISPLANES; i++) // new code -- killough - { - for (*freehead = visplanes[i], visplanes[i] = NULL; *freehead; ) - { - freehead = &(*freehead)->next; - } - } - - next_plane_light = 0; - } -} - -//========================================================================== -// -// R_FindPlane -// -// killough 2/28/98: Add offsets -//========================================================================== - -visplane_t *R_FindPlane (const secplane_t &height, FTextureID picnum, int lightlevel, double Alpha, bool additive, - const FTransform &xxform, - int sky, FSectorPortal *portal) -{ - secplane_t plane; - visplane_t *check; - unsigned hash; // killough - bool isskybox; - const FTransform *xform = &xxform; - fixed_t alpha = FLOAT2FIXED(Alpha); - //angle_t angle = (xform.Angle + xform.baseAngle).BAMs(); - - FTransform nulltransform; - - if (picnum == skyflatnum) // killough 10/98 - { // most skies map together - lightlevel = 0; - xform = &nulltransform; - nulltransform.xOffs = nulltransform.yOffs = nulltransform.baseyOffs = 0; - nulltransform.xScale = nulltransform.yScale = 1; - nulltransform.Angle = nulltransform.baseAngle = 0.0; - additive = false; - // [RH] Map floor skies and ceiling skies to separate visplanes. This isn't - // always necessary, but it is needed if a floor and ceiling sky are in the - // same column but separated by a wall. If they both try to reside in the - // same visplane, then only the floor sky will be drawn. - plane.set(0., 0., height.fC(), 0.); - isskybox = portal != NULL && !(portal->mFlags & PORTSF_INSKYBOX); - } - else if (portal != NULL && !(portal->mFlags & PORTSF_INSKYBOX)) - { - plane = height; - isskybox = true; - } - else - { - plane = height; - isskybox = false; - // kg3D - hack, store alpha in sky - // i know there is ->alpha, but this also allows to identify fake plane - // and ->alpha is for stacked sectors - if (fake3D & (FAKE3D_FAKEFLOOR|FAKE3D_FAKECEILING)) sky = 0x80000000 | fakeAlpha; - else sky = 0; // not skyflatnum so it can't be a sky - portal = NULL; - alpha = OPAQUE; - } - - // New visplane algorithm uses hash table -- killough - hash = isskybox ? MAXVISPLANES : visplane_hash (picnum.GetIndex(), lightlevel, height); - - for (check = visplanes[hash]; check; check = check->next) // killough - { - if (isskybox) - { - if (portal == check->portal && plane == check->height) - { - if (portal->mType != PORTS_SKYVIEWPOINT) - { // This skybox is really a stacked sector, so we need to - // check even more. - if (check->extralight == stacked_extralight && - check->visibility == stacked_visibility && - check->viewpos == stacked_viewpos && - ( - // headache inducing logic... :( - (portal->mType != PORTS_STACKEDSECTORTHING) || - ( - check->Alpha == alpha && - check->Additive == additive && - (alpha == 0 || // if alpha is > 0 everything needs to be checked - (plane == check->height && - picnum == check->picnum && - lightlevel == check->lightlevel && - basecolormap == check->colormap && // [RH] Add more checks - *xform == check->xform - ) - ) && - check->viewangle == stacked_angle - ) - ) - ) - { - return check; - } - } - else - { - return check; - } - } - } - else - if (plane == check->height && - picnum == check->picnum && - lightlevel == check->lightlevel && - basecolormap == check->colormap && // [RH] Add more checks - *xform == check->xform && - sky == check->sky && - CurrentPortalUniq == check->CurrentPortalUniq && - MirrorFlags == check->MirrorFlags && - CurrentSkybox == check->CurrentSkybox && - ViewPos == check->viewpos - ) - { - return check; - } - } - - check = new_visplane (hash); // killough - - check->height = plane; - check->picnum = picnum; - check->lightlevel = lightlevel; - check->xform = *xform; - check->colormap = basecolormap; // [RH] Save colormap - check->sky = sky; - check->portal = portal; - check->left = viewwidth; // Was SCREENWIDTH -- killough 11/98 - check->right = 0; - check->extralight = stacked_extralight; - check->visibility = stacked_visibility; - check->viewpos = stacked_viewpos; - check->viewangle = stacked_angle; - check->Alpha = alpha; - check->Additive = additive; - check->CurrentPortalUniq = CurrentPortalUniq; - check->MirrorFlags = MirrorFlags; - check->CurrentSkybox = CurrentSkybox; - - fillshort (check->top, viewwidth, 0x7fff); - - return check; -} - -//========================================================================== -// -// R_CheckPlane -// -//========================================================================== - -visplane_t *R_CheckPlane (visplane_t *pl, int start, int stop) -{ - int intrl, intrh; - int unionl, unionh; - int x; - - assert (start >= 0 && start < viewwidth); - assert (stop > start && stop <= viewwidth); - - if (start < pl->left) - { - intrl = pl->left; - unionl = start; - } - else - { - unionl = pl->left; - intrl = start; - } - - if (stop > pl->right) - { - intrh = pl->right; - unionh = stop; - } - else - { - unionh = pl->right; - intrh = stop; - } - - for (x = intrl; x < intrh && pl->top[x] == 0x7fff; x++) - ; - - if (x >= intrh) - { - // use the same visplane - pl->left = unionl; - pl->right = unionh; - } - else - { - // make a new visplane - unsigned hash; - - if (pl->portal != NULL && !(pl->portal->mFlags & PORTSF_INSKYBOX) && viewactive) - { - hash = MAXVISPLANES; - } - else - { - hash = visplane_hash (pl->picnum.GetIndex(), pl->lightlevel, pl->height); - } - visplane_t *new_pl = new_visplane (hash); - - new_pl->height = pl->height; - new_pl->picnum = pl->picnum; - new_pl->lightlevel = pl->lightlevel; - new_pl->xform = pl->xform; - new_pl->colormap = pl->colormap; - new_pl->portal = pl->portal; - new_pl->extralight = pl->extralight; - new_pl->visibility = pl->visibility; - new_pl->viewpos = pl->viewpos; - new_pl->viewangle = pl->viewangle; - new_pl->sky = pl->sky; - new_pl->Alpha = pl->Alpha; - new_pl->Additive = pl->Additive; - new_pl->CurrentPortalUniq = pl->CurrentPortalUniq; - new_pl->MirrorFlags = pl->MirrorFlags; - new_pl->CurrentSkybox = pl->CurrentSkybox; - new_pl->lights = pl->lights; - pl = new_pl; - pl->left = start; - pl->right = stop; - fillshort (pl->top, viewwidth, 0x7fff); - } - return pl; -} - -//========================================================================== -// -// R_DrawPlanes -// -// At the end of each frame. -// -//========================================================================== - -int R_DrawPlanes () -{ - visplane_t *pl; - int i; - int vpcount = 0; - - ds_color = 3; - - for (i = 0; i < MAXVISPLANES; i++) - { - for (pl = visplanes[i]; pl; pl = pl->next) - { - // kg3D - draw only correct planes - if(pl->CurrentPortalUniq != CurrentPortalUniq || pl->CurrentSkybox != CurrentSkybox) - continue; - // kg3D - draw only real planes now - if(pl->sky >= 0) { - vpcount++; - R_DrawSinglePlane (pl, OPAQUE, false, false); - } - } - } - return vpcount; -} - -// kg3D - draw all visplanes with "height" -void R_DrawHeightPlanes(double height) -{ - visplane_t *pl; - int i; - - ds_color = 3; - - DVector3 oViewPos = ViewPos; - DAngle oViewAngle = ViewAngle; - - for (i = 0; i < MAXVISPLANES; i++) - { - for (pl = visplanes[i]; pl; pl = pl->next) - { - // kg3D - draw only correct planes - if(pl->CurrentSkybox != CurrentSkybox || pl->CurrentPortalUniq != CurrentPortalUniq) - continue; - if(pl->sky < 0 && pl->height.Zat0() == height) { - ViewPos = pl->viewpos; - ViewAngle = pl->viewangle; - MirrorFlags = pl->MirrorFlags; - R_DrawSinglePlane (pl, pl->sky & 0x7FFFFFFF, pl->Additive, true); - } - } - } - ViewPos = oViewPos; - ViewAngle = oViewAngle; -} - - -//========================================================================== -// -// R_DrawSinglePlane -// -// Draws a single visplane. -// -//========================================================================== - -void R_DrawSinglePlane (visplane_t *pl, fixed_t alpha, bool additive, bool masked) -{ - if (pl->left >= pl->right) - return; - - if (r_drawflat) - { // [RH] no texture mapping - ds_color += 4; - R_DrawColoredPlane(pl); - } - else if (pl->picnum == skyflatnum) - { // sky flat - R_DrawSkyPlane (pl); - } - else - { // regular flat - FTexture *tex = TexMan(pl->picnum, true); - - if (tex->UseType == FTexture::TEX_Null) - { - return; - } - - if (!masked && !additive) - { // If we're not supposed to see through this plane, draw it opaque. - alpha = OPAQUE; - } - else if (!tex->bMasked) - { // Don't waste time on a masked texture if it isn't really masked. - masked = false; - } - R_SetSpanTexture(tex); - double xscale = pl->xform.xScale * tex->Scale.X; - double yscale = pl->xform.yScale * tex->Scale.Y; - - basecolormap = pl->colormap; - - if (r_drawflat || (!pl->height.isSlope() && !tilt)) - { - R_DrawNormalPlane(pl, xscale, yscale, alpha, additive, masked); - } - else - { - R_DrawTiltedPlane(pl, xscale, yscale, alpha, additive, masked); - } - } - NetUpdate (); -} - -//========================================================================== -// -// R_MapVisPlane -// -// t1/b1 are at x -// t2/b2 are at x+1 -// spanend[y] is at the right edge -// -//========================================================================== - -void R_MapVisPlane (visplane_t *pl, void (*mapfunc)(int y, int x1, int x2), void(*stepfunc)()) -{ - int x = pl->right - 1; - int t2 = pl->top[x]; - int b2 = pl->bottom[x]; - - ds_light_list = pl->lights; - - if (b2 > t2) - { - fillshort (spanend+t2, b2-t2, x); - } - - for (--x; x >= pl->left; --x) - { - int t1 = pl->top[x]; - int b1 = pl->bottom[x]; - const int xr = x+1; - int stop; - - // Draw any spans that have just closed - stop = MIN (t1, b2); - while (t2 < stop) - { - int y = t2++; - int x2 = spanend[y]; - mapfunc (y, xr, x2); - } - stop = MAX (b1, t2); - while (b2 > stop) - { - int y = --b2; - int x2 = spanend[y]; - mapfunc (y, xr, x2); - } - - // Mark any spans that have just opened - stop = MIN (t2, b1); - while (t1 < stop) - { - spanend[t1++] = x; - } - stop = MAX (b2, t2); - while (b1 > stop) - { - spanend[--b1] = x; - } - - t2 = pl->top[x]; - b2 = pl->bottom[x]; - - if (stepfunc) - stepfunc(); - } - // Draw any spans that are still open - while (t2 < b2) - { - int y = --b2; - int x2 = spanend[y]; - mapfunc (y, pl->left, x2); - } - - ds_light_list = nullptr; -} - -} diff --git a/src/swrenderer/scene/r_plane.h b/src/swrenderer/scene/r_plane.h deleted file mode 100644 index aad67beda..000000000 --- a/src/swrenderer/scene/r_plane.h +++ /dev/null @@ -1,44 +0,0 @@ -// Emacs style mode select -*- C++ -*- -//----------------------------------------------------------------------------- -// -// $Id:$ -// -// Copyright (C) 1993-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. -// -// DESCRIPTION: -// Refresh, visplane stuff (floor, ceilings). -// -//----------------------------------------------------------------------------- - - -#ifndef __R_PLANE_H__ -#define __R_PLANE_H__ - -#include "swrenderer/plane/r_visibleplane.h" - -namespace swrenderer -{ - -void R_ClearPlanes (bool fullclear); - -void R_AddPlaneLights(visplane_t *plane, FLightNode *light_head); - -int R_DrawPlanes (); -void R_DrawSinglePlane(visplane_t *pl, fixed_t alpha, bool additive, bool masked); -void R_MapVisPlane (visplane_t *pl, void (*mapfunc)(int y, int x1, int x2), void (*stepfunc)()); - -visplane_t *R_FindPlane(const secplane_t &height, FTextureID picnum, int lightlevel, double alpha, bool additive, const FTransform &xform, int sky, FSectorPortal *portal); -visplane_t *R_CheckPlane(visplane_t *pl, int start, int stop); - -} - -#endif // __R_PLANE_H__ diff --git a/src/swrenderer/scene/r_portal.cpp b/src/swrenderer/scene/r_portal.cpp index e48a47c86..acb87dbb2 100644 --- a/src/swrenderer/scene/r_portal.cpp +++ b/src/swrenderer/scene/r_portal.cpp @@ -30,14 +30,14 @@ #include "p_maputl.h" #include "p_setup.h" #include "version.h" -#include "swrenderer/drawers/r_draw_rgba.h" #include "r_utility.h" -#include "r_plane.h" -#include "swrenderer/segments/r_clipsegment.h" -#include "swrenderer/segments/r_drawsegment.h" #include "r_things.h" #include "r_3dfloors.h" #include "r_segs.h" +#include "swrenderer/drawers/r_draw_rgba.h" +#include "swrenderer/segments/r_clipsegment.h" +#include "swrenderer/segments/r_drawsegment.h" +#include "swrenderer/plane/r_visibleplane.h" #include "swrenderer/r_main.h" #include "swrenderer/r_memory.h" diff --git a/src/swrenderer/scene/r_segs.cpp b/src/swrenderer/scene/r_segs.cpp index 6a87ab756..051012973 100644 --- a/src/swrenderer/scene/r_segs.cpp +++ b/src/swrenderer/scene/r_segs.cpp @@ -42,7 +42,6 @@ #include "d_net.h" #include "g_level.h" #include "r_bsp.h" -#include "r_plane.h" #include "swrenderer/plane/r_fogboundary.h" #include "r_segs.h" #include "r_3dfloors.h" diff --git a/src/swrenderer/scene/r_segs.h b/src/swrenderer/scene/r_segs.h index cf73ce82a..f4ca36e4f 100644 --- a/src/swrenderer/scene/r_segs.h +++ b/src/swrenderer/scene/r_segs.h @@ -27,6 +27,7 @@ namespace swrenderer { struct drawseg_t; +struct visplane_t; bool R_StoreWallRange(int start, int stop); void R_RenderMaskedSegRange (drawseg_t *ds, int x1, int x2); diff --git a/src/swrenderer/scene/r_things.cpp b/src/swrenderer/scene/r_things.cpp index e11510f32..0dbf47fa4 100644 --- a/src/swrenderer/scene/r_things.cpp +++ b/src/swrenderer/scene/r_things.cpp @@ -56,7 +56,6 @@ #include "d_netinf.h" #include "p_effect.h" #include "r_bsp.h" -#include "r_plane.h" #include "r_segs.h" #include "r_3dfloors.h" #include "swrenderer/drawers/r_draw_rgba.h" diff --git a/src/swrenderer/scene/r_walldraw.cpp b/src/swrenderer/scene/r_walldraw.cpp index 3b6e40253..21b734872 100644 --- a/src/swrenderer/scene/r_walldraw.cpp +++ b/src/swrenderer/scene/r_walldraw.cpp @@ -37,7 +37,6 @@ #include "g_level.h" #include "swrenderer/drawers/r_draw.h" #include "r_bsp.h" -#include "r_plane.h" #include "r_segs.h" #include "r_3dfloors.h" #include "v_palette.h" diff --git a/src/swrenderer/segments/r_clipsegment.cpp b/src/swrenderer/segments/r_clipsegment.cpp index 83920a137..d92633ea9 100644 --- a/src/swrenderer/segments/r_clipsegment.cpp +++ b/src/swrenderer/segments/r_clipsegment.cpp @@ -7,7 +7,6 @@ #include "p_lnspec.h" #include "p_setup.h" #include "swrenderer/r_main.h" -#include "swrenderer/scene/r_plane.h" #include "swrenderer/drawers/r_draw.h" #include "swrenderer/scene/r_things.h" #include "swrenderer/scene/r_3dfloors.h" diff --git a/src/swrenderer/segments/r_drawsegment.cpp b/src/swrenderer/segments/r_drawsegment.cpp index 42af7d032..9c7dde091 100644 --- a/src/swrenderer/segments/r_drawsegment.cpp +++ b/src/swrenderer/segments/r_drawsegment.cpp @@ -7,7 +7,6 @@ #include "p_lnspec.h" #include "p_setup.h" #include "swrenderer/r_main.h" -#include "swrenderer/scene/r_plane.h" #include "swrenderer/drawers/r_draw.h" #include "swrenderer/scene/r_things.h" #include "swrenderer/scene/r_3dfloors.h" diff --git a/src/swrenderer/segments/r_portalsegment.cpp b/src/swrenderer/segments/r_portalsegment.cpp index db31f5edf..22e137fff 100644 --- a/src/swrenderer/segments/r_portalsegment.cpp +++ b/src/swrenderer/segments/r_portalsegment.cpp @@ -7,7 +7,6 @@ #include "p_lnspec.h" #include "p_setup.h" #include "swrenderer/r_main.h" -#include "swrenderer/scene/r_plane.h" #include "swrenderer/drawers/r_draw.h" #include "swrenderer/scene/r_things.h" #include "swrenderer/scene/r_3dfloors.h" diff --git a/src/swrenderer/things/r_decal.cpp b/src/swrenderer/things/r_decal.cpp index 857e3bc36..c4a90b414 100644 --- a/src/swrenderer/things/r_decal.cpp +++ b/src/swrenderer/things/r_decal.cpp @@ -18,7 +18,6 @@ #include "d_net.h" #include "g_level.h" #include "swrenderer/scene/r_bsp.h" -#include "swrenderer/scene/r_plane.h" #include "r_decal.h" #include "swrenderer/scene/r_3dfloors.h" #include "swrenderer/drawers/r_draw.h" diff --git a/src/swrenderer/things/r_particle.cpp b/src/swrenderer/things/r_particle.cpp index d8a32d9ad..83ebd6db3 100644 --- a/src/swrenderer/things/r_particle.cpp +++ b/src/swrenderer/things/r_particle.cpp @@ -28,7 +28,6 @@ #include "d_netinf.h" #include "p_effect.h" #include "swrenderer/scene/r_bsp.h" -#include "swrenderer/scene/r_plane.h" #include "swrenderer/scene/r_segs.h" #include "swrenderer/scene/r_3dfloors.h" #include "swrenderer/drawers/r_draw_rgba.h" diff --git a/src/swrenderer/things/r_playersprite.cpp b/src/swrenderer/things/r_playersprite.cpp index 13d78495f..bc1df5246 100644 --- a/src/swrenderer/things/r_playersprite.cpp +++ b/src/swrenderer/things/r_playersprite.cpp @@ -28,7 +28,6 @@ #include "d_netinf.h" #include "p_effect.h" #include "swrenderer/scene/r_bsp.h" -#include "swrenderer/scene/r_plane.h" #include "swrenderer/scene/r_segs.h" #include "swrenderer/scene/r_3dfloors.h" #include "swrenderer/drawers/r_draw_rgba.h" diff --git a/src/swrenderer/things/r_wallsprite.cpp b/src/swrenderer/things/r_wallsprite.cpp index c5fb8125c..9d7e03c2a 100644 --- a/src/swrenderer/things/r_wallsprite.cpp +++ b/src/swrenderer/things/r_wallsprite.cpp @@ -28,7 +28,6 @@ #include "d_netinf.h" #include "p_effect.h" #include "swrenderer/scene/r_bsp.h" -#include "swrenderer/scene/r_plane.h" #include "swrenderer/scene/r_segs.h" #include "swrenderer/scene/r_3dfloors.h" #include "swrenderer/drawers/r_draw_rgba.h"