diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 1564c9e60..1444f1cf3 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -896,7 +896,6 @@ add_executable( zdoom WIN32 r_drawt.cpp r_main.cpp r_plane.cpp - r_polymost.cpp r_segs.cpp r_sky.cpp r_things.cpp diff --git a/src/d_main.cpp b/src/d_main.cpp index 90391433a..ab33bfaec 100644 --- a/src/d_main.cpp +++ b/src/d_main.cpp @@ -108,10 +108,6 @@ #include "r_renderer.h" #include "p_local.h" -#ifdef USE_POLYMOST -#include "r_polymost.h" -#endif - EXTERN_CVAR(Bool, hud_althud) void DrawHUD(); @@ -186,9 +182,6 @@ CUSTOM_CVAR (Int, fraglimit, 0, CVAR_SERVERINFO) } } -#ifdef USE_POLYMOST -CVAR(Bool, testpolymost, false, 0) -#endif CVAR (Float, timelimit, 0.f, CVAR_SERVERINFO); CVAR (Int, wipetype, 1, CVAR_ARCHIVE); CVAR (Int, snd_drawoutput, 0, 0); @@ -282,10 +275,6 @@ void D_ProcessEvents (void) continue; // console ate the event if (M_Responder (ev)) continue; // menu ate the event - #ifdef USE_POLYMOST - if (testpolymost) - Polymost_Responder (ev); - #endif G_Responder (ev); } } @@ -307,9 +296,6 @@ void D_PostEvent (const event_t *ev) } events[eventhead] = *ev; if (ev->type == EV_Mouse && !paused && menuactive == MENU_Off && ConsoleState != c_down && ConsoleState != c_falling -#ifdef USE_POLYMOST - && !testpolymost -#endif ) { if (Button_Mlook.bDown || freelook) @@ -743,15 +729,7 @@ void D_Display () hw2d = false; -#ifdef USE_POLYMOST - if (testpolymost) - { - drawpolymosttest(); - C_DrawConsole(hw2d); - M_Drawer(); - } - else -#endif + { unsigned int nowtime = I_FPSTime(); TexMan.UpdateAnimations(nowtime); diff --git a/src/r_main.cpp b/src/r_main.cpp index a726bc714..bc3c4c7c0 100644 --- a/src/r_main.cpp +++ b/src/r_main.cpp @@ -72,8 +72,6 @@ // EXTERNAL FUNCTION PROTOTYPES -------------------------------------------- void R_SpanInitData (); -void RP_RenderBSPNode (void *node); -bool RP_SetupFrame (bool backside); void R_DeinitSprites(); // PUBLIC FUNCTION PROTOTYPES ---------------------------------------------- @@ -94,14 +92,12 @@ extern "C" int fuzzviewheight; static float CurrentVisibility = 8.f; static fixed_t MaxVisForWall; static fixed_t MaxVisForFloor; -static bool polyclipped; extern bool r_showviewer; bool r_dontmaplines; // PUBLIC DATA DEFINITIONS ------------------------------------------------- CVAR (String, r_viewsize, "", CVAR_NOSET) -CVAR (Int, r_polymost, 0, 0) CVAR (Bool, r_shadercolormaps, true, CVAR_ARCHIVE) fixed_t r_BaseVisibility; @@ -612,14 +608,6 @@ void R_SetupFreelook() } } -void R_SetupPolymost() -{ - if (r_polymost) - { - polyclipped = RP_SetupFrame (false); - } -} - //========================================================================== // // R_EnterMirror @@ -812,11 +800,8 @@ void R_RenderActorView (AActor *actor, bool dontmaplines) } // Link the polyobjects right before drawing the scene to reduce the amounts of calls to this function PO_LinkToSubsectors(); - if (r_polymost < 2) - { - R_RenderBSPNode (nodes + numnodes - 1); // The head node is the last node output. - R_3D_ResetClip(); // reset clips (floor/ceiling) - } + R_RenderBSPNode (nodes + numnodes - 1); // The head node is the last node output. + R_3D_ResetClip(); // reset clips (floor/ceiling) camera->renderflags = savedflags; WallCycles.Unclock(); @@ -843,16 +828,6 @@ void R_RenderActorView (AActor *actor, bool dontmaplines) MaskedCycles.Unclock(); NetUpdate (); - - if (r_polymost) - { - RP_RenderBSPNode (nodes + numnodes - 1); - if (polyclipped) - { - RP_SetupFrame (true); - RP_RenderBSPNode (nodes + numnodes - 1); - } - } } WallMirrors.Clear (); interpolator.RestoreInterpolations (); diff --git a/src/r_polymost.cpp b/src/r_polymost.cpp deleted file mode 100644 index e7963faa2..000000000 --- a/src/r_polymost.cpp +++ /dev/null @@ -1,1599 +0,0 @@ -/************************************************************************************************** -"POLYMOST" code written by Ken Silverman -Ken Silverman's official web site: http://www.advsys.net/ken -This file has been modified (severely) from Ken Silverman's original release - -Motivation: -When 3D Realms released the Duke Nukem 3D source code, I thought somebody would do a OpenGL or -Direct3D port. Well, after a few months passed, I saw no sign of somebody working on a true -hardware-accelerated port of Build, just people saying it wasn't possible. Eventually, I realized -the only way this was going to happen was for me to do it myself. First, I needed to port Build to -Windows. I could have done it myself, but instead I thought I'd ask my Australian buddy, Jonathon -Fowler, if he would upgrade his Windows port to my favorite compiler (MSVC) - which he did. Once -that was done, I was ready to start the "POLYMOST" project. - -About: -This source file is basically a complete rewrite of the entire rendering part of the Build engine. -There are small pieces in ENGINE.C to activate this code, and other minor hacks in other source -files, but most of it is in here. If you're looking for polymost-related code in the other source -files, you should find most of them by searching for either "polymost" or "rendmode". Speaking of -rendmode, there are now 4 rendering modes in Build: - - rendmode 0: The original code I wrote from 1993-1997 - rendmode 1: Solid-color rendering: my debug code before I did texture mapping - rendmode 2: Software rendering before I started the OpenGL code (Note: this is just a quick - hack to make testing easier - it's not optimized to my usual standards!) - rendmode 3: The OpenGL code - -The original Build engine did hidden surface removal by using a vertical span buffer on the tops -and bottoms of walls. This worked nice back in the day, but it it's not suitable for a polygon -engine. So I decided to write a brand new hidden surface removal algorithm - using the same idea -as the original Build - but one that worked with vectors instead of already rasterized data. - -Brief history: -06/20/2000: I release Build Source code -04/01/2003: 3D Realms releases Duke Nukem 3D source code -10/04/2003: Jonathon Fowler gets his Windows port working in Visual C -10/04/2003: I start writing POLYMOST.BAS, a new hidden surface removal algorithm for Build that - works on a polygon level instead of spans. -10/16/2003: Ported POLYMOST.BAS to C inside JonoF KenBuild's ENGINE.C; later this code was split - out of ENGINE.C and put in this file, POLYMOST.C. -12/10/2003: Started OpenGL code for POLYMOST (rendmode 3) -12/23/2003: 1st public release -01/01/2004: 2nd public release: fixed stray lines, status bar, mirrors, sky, and lots of other bugs. - ----------------------------------------------------------------------------------------------------- - -Todo list (in approximate chronological order): - -High priority: - * BOTH: Do accurate software sorting/chopping for sprites: drawing in wrong order is bad :/ - * BOTH: Fix hall of mirrors near "zenith". Call polymost_drawrooms twice? - * OPENGL: drawmapview() - -Low priority: - * SOFT6D: Do back-face culling of sprites during up/down/tilt transformation (top of drawpoly) - * SOFT6D: Fix depth shading: use saturation&LUT - * SOFT6D: Optimize using hyperbolic mapping (similar to KUBE algo) - * SOFT6D: Slab6-style voxel sprites. How to accelerate? :/ - * OPENGL: KENBUILD: Write flipping code for floor mirrors - * BOTH: KENBUILD: Parallaxing sky modes 1&2 - * BOTH: Masked/1-way walls don't clip correctly to sectors of intersecting ceiling/floor slopes - * BOTH: Editart x-center is not working correctly with Duke's camera/turret sprites - * BOTH: Get rid of horizontal line above Duke full-screen status bar - * BOTH: Combine ceilings/floors into a single triangle strip (should lower poly count by 2x) - * BOTH: Optimize/clean up texture-map setup equations - -**************************************************************************************************/ - -#include -#include -#include -#include "doomtype.h" -#include "r_polymost.h" -#include "c_cvars.h" -#include "c_dispatch.h" -#include "r_main.h" -#include "r_draw.h" -#include "templates.h" -#include "r_sky.h" -#include "g_level.h" -#include "r_bsp.h" -#include "v_palette.h" -#include "v_font.h" -#include "v_video.h" -#include "r_data/colormaps.h" - -EXTERN_CVAR (Int, r_polymost) - -#define SCISDIST 1.0 //1.0: Close plane clipping distance - -static double gyxscale, gxyaspect, gviewxrange, ghalfx, grhalfxdown10, grhalfxdown10x, ghoriz; -static double gcosang, gsinang, gcosang2, gsinang2; -static double gchang, gshang, gctang, gstang; -//static float gtang = 0.0; -CVAR (Float, gtang, 0, 0); -double guo, gux, guy; //Screen-based texture mapping parameters -double gvo, gvx, gvy; -double gdo, gdx, gdy; - -#ifdef _MSC_VER -#pragma warning (disable:4244) -#endif - -PolyClipper::PolyClipper () - : vsps (&EmptyList) -{ - UsedList.Next = UsedList.Prev = &UsedList; -} - -PolyClipper::~PolyClipper () -{ - vspgroup *probe = vsps.NextGroup; - while (probe != NULL) - { - vspgroup *next = probe->NextGroup; - delete probe; - probe = next; - } -} - -PolyClipper::vspgroup::vspgroup (vsptype *sentinel) -{ - int i; - - NextGroup = NULL; - vsp[0].Prev = sentinel; - vsp[0].Next = &vsp[1]; - for (i = 1; i < GROUP_SIZE-1; ++i) - { - vsp[i].Next = &vsp[i+1]; - vsp[i].Prev = &vsp[i-1]; - } - vsp[i].Next = sentinel; - vsp[i].Prev = &vsp[i-1]; - sentinel->Next = &vsp[0]; - sentinel->Prev = &vsp[i]; -} - - /*Init viewport boundary (must be 4 point convex loop): - // (px[0],py[0]).----.(px[1],py[1]) - // / \ - // / \ - // (px[3],py[3]).--------------.(px[2],py[2]) - */ -void PolyClipper::InitMosts (double *px, double *py, int n) -{ - int i, j, k, imin; - int vcnt; - vsptype *vsp[8]; - - EmptyAll (); - vcnt = 1; // 0 is dummy solid node - - if (n < 3) return; - imin = (px[1] < px[0]); - for(i=n-1;i>=2;i--) if (px[i] < px[imin]) imin = i; - - vsp[0] = &UsedList; - vsp[vcnt] = GetVsp (); - vsp[vcnt]->X = px[imin]; - vsp[vcnt]->Cy[0] = vsp[vcnt]->Fy[0] = py[imin]; - vsp[vcnt]->CTag = vsp[vcnt]->FTag = 1; - vcnt++; - i = imin+1; if (i >= n) i = 0; - j = imin-1; if (j < 0) j = n-1; - do - { - if (px[i] < px[j]) - { - if ((vcnt > 1) && (px[i] - vsp[vcnt-1]->X < 0.00001)) vcnt--; - else vsp[vcnt] = GetVsp (); - vsp[vcnt]->X = px[i]; - vsp[vcnt]->Cy[0] = py[i]; - k = j+1; if (k >= n) k = 0; - //(px[k],py[k]) - //(px[i],?) - //(px[j],py[j]) - vsp[vcnt]->Fy[0] = (px[i]-px[k])*(py[j]-py[k])/(px[j]-px[k]) + py[k]; - if (vcnt > 1) - { - vsp[vcnt]->CTag = vsp[vcnt-1]->CTag + 1; - vsp[vcnt]->FTag = vsp[vcnt-1]->FTag; - } - vcnt++; - i++; if (i >= n) i = 0; - } - else if (px[j] < px[i]) - { - if ((vcnt > 1) && (px[j] - vsp[vcnt-1]->X < 0.00001)) vcnt--; - else vsp[vcnt] = GetVsp (); - vsp[vcnt]->X = px[j]; - vsp[vcnt]->Fy[0] = py[j]; - k = i-1; if (k < 0) k = n-1; - //(px[k],py[k]) - //(px[j],?) - //(px[i],py[i]) - vsp[vcnt]->Cy[0] = (px[j]-px[k])*(py[i]-py[k])/(px[i]-px[k]) + py[k]; - if (vcnt > 1) - { - vsp[vcnt]->FTag = vsp[vcnt-1]->FTag + 1; - vsp[vcnt]->CTag = vsp[vcnt-1]->CTag; - } - vcnt++; - j--; if (j < 0) j = n-1; - } - else - { - if ((vcnt > 1) && (px[i] - vsp[vcnt-1]->X < 0.00001)) vcnt--; - else vsp[vcnt] = GetVsp (); - vsp[vcnt]->X = px[i]; - vsp[vcnt]->Cy[0] = py[i]; - vsp[vcnt]->Fy[0] = py[j]; - if (vcnt > 1) - { - vsp[vcnt]->CTag = vsp[vcnt-1]->CTag + 1; - vsp[vcnt]->FTag = vsp[vcnt-1]->FTag + 1; - } - vcnt++; - i++; if (i >= n) i = 0; if (i == j) break; - j--; if (j < 0) j = n-1; - } - } while (i != j); - if (px[i] > vsp[vcnt-1]->X) - { - vsp[vcnt] = GetVsp (); - vsp[vcnt]->X = px[i]; - vsp[vcnt]->Cy[0] = vsp[vcnt]->Fy[0] = py[i]; - vsp[vcnt]->CTag = vsp[vcnt-1]->CTag + 1; - vsp[vcnt]->FTag = vsp[vcnt-1]->FTag + 1; - vcnt++; - } - - assert (vcnt < 8); - - vsp[vcnt-1]->CTag = vsp[vcnt-1]->FTag = vcnt-1; - for(i=0;iCy[1] = vsp[i+1]->Cy[0]; //vsp[i]->CTag = i; - vsp[i]->Fy[1] = vsp[i+1]->Fy[0]; //vsp[i]->FTag = i; - vsp[i]->Next = vsp[i+1]; vsp[i]->Prev = vsp[i-1]; - } - vsp[vcnt-1]->Next = &UsedList; UsedList.Prev = vsp[vcnt-1]; - GTag = vcnt; -} - -void PolyClipper::EmptyAll () -{ - if (UsedList.Next != &UsedList) - { - if (EmptyList.Next != &EmptyList) - { - // Move the used list to the start of the empty list - UsedList.Prev->Next = EmptyList.Next; - EmptyList.Next = UsedList.Next; - UsedList.Next->Prev = &EmptyList; - } - else - { - // The empty list is empty, so we can just move the - // used list to the empty list. - EmptyList.Next = UsedList.Next; - EmptyList.Prev = UsedList.Prev; - } - UsedList.Next = UsedList.Prev = &UsedList; - } -} - -void PolyClipper::AddGroup () -{ - vspgroup *group = new vspgroup (&EmptyList); - group->NextGroup = vsps.NextGroup; - vsps.NextGroup = group; -} - -PolyClipper::vsptype *PolyClipper::GetVsp () -{ - vsptype *vsp; - - if (EmptyList.Next == &EmptyList) - { - AddGroup (); - } - vsp = EmptyList.Next; - EmptyList.Next = vsp->Next; - vsp->Next->Prev = &EmptyList; - return vsp; -} - -void PolyClipper::FreeVsp (vsptype *vsp) -{ - vsp->Next->Prev = vsp->Prev; - vsp->Prev->Next = vsp->Next; - - vsp->Next = EmptyList.Next; - vsp->Next->Prev = vsp; - vsp->Prev = &EmptyList; - EmptyList.Next = vsp; -} - -PolyClipper::vsptype *PolyClipper::vsinsaft (vsptype *i) -{ - vsptype *r; - - // Get an element from the empty list - r = GetVsp (); - - *r = *i; // Copy i to r - - // Insert r after i - r->Prev = i; - r->Next = i->Next; - i->Next->Prev = r; - i->Next = r; - - return r; -} - -bool PolyClipper::TestVisibleMost (float x0, float x1) -{ - vsptype *i, *newi; - - for (i = UsedList.Next; i != &UsedList; i = newi) - { - newi = i->Next; - if ((x0 < newi->X) && (i->X < x1) && (i->CTag >= 0)) return true; - } - return false; -} - -int PolyClipper::DoMost (float x0, float y0, float x1, float y1, pmostcallbacktype callback, void *callbackdata) -{ - double dpx[4], dpy[4]; - float f, slop, dx0, dx1, nx, nx0, ny0, nx1, ny1; - double dx, d, n, t; - float spx[4], spy[4], cy[2], cv[2]; - int j, k, z, scnt, dir, spt[4]; - vsptype *vsp, *nvsp, *vcnt = NULL, *ni; - int did = 1; - - if (x0 < x1) - { - dir = 1; //clip dmost (floor) - y0 -= .01f; y1 -= .01f; - } - else - { - if (x0 == x1) return 0; - f = x0; x0 = x1; x1 = f; - f = y0; y0 = y1; y1 = f; - dir = 0; //clip umost (ceiling) - //y0 += .01f; y1 += .01f; //necessary? - } - - slop = (y1-y0)/(x1-x0); - for (vsp = UsedList.Next; vsp != &UsedList; vsp = nvsp) - { - nvsp = vsp->Next; nx0 = vsp->X; nx1 = nvsp->X; - if ((x0 >= nx1) || (nx0 >= x1) || (vsp->CTag <= 0)) continue; - dx = nx1-nx0; - cy[0] = vsp->Cy[0]; cv[0] = vsp->Cy[1]-cy[0]; - cy[1] = vsp->Fy[0]; cv[1] = vsp->Fy[1]-cy[1]; - - scnt = 0; - - //Test if left edge requires split (x0,y0) (nx0,cy(0)), - if ((x0 > nx0) && (x0 < nx1)) - { - t = (x0-nx0)*cv[dir] - (y0-cy[dir])*dx; - if (((!dir) && (t < 0)) || ((dir) && (t > 0))) - { spx[scnt] = x0; spy[scnt] = y0; spt[scnt] = -1; scnt++; } - } - - //Test for intersection on umost (j == 0) and dmost (j == 1) - for(j=0;j<2;j++) - { - d = (y0-y1)*dx - (x0-x1)*cv[j]; - n = (y0-cy[j])*dx - (x0-nx0)*cv[j]; - if ((fabsf(n) <= fabsf(d)) && (d*n >= 0) && (d != 0)) - { - t = n/d; nx = (x1-x0)*t + x0; - if ((nx > nx0) && (nx < nx1)) - { - spx[scnt] = nx; spy[scnt] = (y1-y0)*t + y0; - spt[scnt] = j; scnt++; - } - } - } - - //Nice hack to avoid full sort later :) - if ((scnt >= 2) && (spx[scnt-1] < spx[scnt-2])) - { - f = spx[scnt-1]; spx[scnt-1] = spx[scnt-2]; spx[scnt-2] = f; - f = spy[scnt-1]; spy[scnt-1] = spy[scnt-2]; spy[scnt-2] = f; - j = spt[scnt-1]; spt[scnt-1] = spt[scnt-2]; spt[scnt-2] = j; - } - - //Test if right edge requires split - if ((x1 > nx0) && (x1 < nx1)) - { - t = (x1-nx0)*cv[dir] - (y1-cy[dir])*dx; - if (((!dir) && (t < 0)) || ((dir) && (t > 0))) - { spx[scnt] = x1; spy[scnt] = y1; spt[scnt] = -1; scnt++; } - } - - vsp->Tag = nvsp->Tag = -1; - for(z = 0; z <= scnt; z++, vsp = vcnt) - { - if (z < scnt) - { - vcnt = vsinsaft(vsp); - t = (spx[z]-nx0)/dx; - vsp->Cy[1] = t*cv[0] + cy[0]; - vsp->Fy[1] = t*cv[1] + cy[1]; - vcnt->X = spx[z]; - vcnt->Cy[0] = vsp->Cy[1]; - vcnt->Fy[0] = vsp->Fy[1]; - vcnt->Tag = spt[z]; - } - - ni = vsp->Next; if (ni == &UsedList) continue; //this 'if' fixes many bugs! - dx0 = vsp->X; if (x0 > dx0) continue; - dx1 = ni->X; if (x1 < dx1) continue; - ny0 = (dx0-x0)*slop + y0; - ny1 = (dx1-x0)*slop + y0; - - // dx0 dx1 - // ³ ³ - //---------------------------- - // t0+=0 t1+=0 - // vsp[i].cy[0] vsp[i].cy[1] - //============================ - // t0+=1 t1+=3 - //============================ - // vsp[i].fy[0] vsp[i].fy[1] - // t0+=2 t1+=6 - // - // ny0 ? ny1 ? - - k = 1+3; - if ((vsp->Tag == 0) || (ny0 <= vsp->Cy[0]+.01)) k--; - if ((vsp->Tag == 1) || (ny0 >= vsp->Fy[0]-.01)) k++; - if ((ni->Tag == 0) || (ny1 <= vsp->Cy[1]+.01)) k -= 3; - if ((ni->Tag == 1) || (ny1 >= vsp->Fy[1]-.01)) k += 3; - - if (!dir) - { - switch(k) - { - case 1: case 2: - dpx[0] = dx0; dpy[0] = vsp->Cy[0]; - dpx[1] = dx1; dpy[1] = vsp->Cy[1]; - dpx[2] = dx0; dpy[2] = ny0; - if(callback) callback(dpx,dpy,3,callbackdata); - vsp->Cy[0] = ny0; vsp->CTag = GTag; break; - case 3: case 6: - dpx[0] = dx0; dpy[0] = vsp->Cy[0]; - dpx[1] = dx1; dpy[1] = vsp->Cy[1]; - dpx[2] = dx1; dpy[2] = ny1; - if(callback) callback(dpx,dpy,3,callbackdata); - vsp->Cy[1] = ny1; vsp->CTag = GTag; break; - case 4: case 5: case 7: - dpx[0] = dx0; dpy[0] = vsp->Cy[0]; - dpx[1] = dx1; dpy[1] = vsp->Cy[1]; - dpx[2] = dx1; dpy[2] = ny1; - dpx[3] = dx0; dpy[3] = ny0; - if(callback) callback(dpx,dpy,4,callbackdata); - vsp->Cy[0] = ny0; vsp->Cy[1] = ny1; vsp->CTag = GTag; break; - case 8: - dpx[0] = dx0; dpy[0] = vsp->Cy[0]; - dpx[1] = dx1; dpy[1] = vsp->Cy[1]; - dpx[2] = dx1; dpy[2] = vsp->Fy[1]; - dpx[3] = dx0; dpy[3] = vsp->Fy[0]; - if(callback) callback(dpx,dpy,4,callbackdata); - vsp->CTag = vsp->FTag = -1; break; - default: did = 0; break; - } - } - else - { - switch(k) - { - case 7: case 6: - dpx[0] = dx0; dpy[0] = ny0; - dpx[1] = dx1; dpy[1] = vsp->Fy[1]; - dpx[2] = dx0; dpy[2] = vsp->Fy[0]; - if(callback) callback(dpx,dpy,3,callbackdata); - vsp->Fy[0] = ny0; vsp->FTag = GTag; break; - case 5: case 2: - dpx[0] = dx0; dpy[0] = vsp->Fy[0]; - dpx[1] = dx1; dpy[1] = ny1; - dpx[2] = dx1; dpy[2] = vsp->Fy[1]; - if(callback) callback(dpx,dpy,3,callbackdata); - vsp->Fy[1] = ny1; vsp->FTag = GTag; break; - case 4: case 3: case 1: - dpx[0] = dx0; dpy[0] = ny0; - dpx[1] = dx1; dpy[1] = ny1; - dpx[2] = dx1; dpy[2] = vsp->Fy[1]; - dpx[3] = dx0; dpy[3] = vsp->Fy[0]; - if(callback) callback(dpx,dpy,4,callbackdata); - vsp->Fy[0] = ny0; vsp->Fy[1] = ny1; vsp->FTag = GTag; break; - case 0: - dpx[0] = dx0; dpy[0] = vsp->Cy[0]; - dpx[1] = dx1; dpy[1] = vsp->Cy[1]; - dpx[2] = dx1; dpy[2] = vsp->Fy[1]; - dpx[3] = dx0; dpy[3] = vsp->Fy[0]; - if(callback) callback(dpx,dpy,4,callbackdata); - vsp->CTag = vsp->FTag = -1; break; - default: did = 0; break; - } - } - } - } - - GTag++; - - //Combine neighboring vertical strips with matching collinear top&bottom edges - //This prevents x-splits from propagating through the entire scan - vsp = UsedList.Next; - while (vsp->Next != &UsedList) - { - ni = vsp->Next; - if ((vsp->Cy[0] >= vsp->Fy[0]) && (vsp->Cy[1] >= vsp->Fy[1])) - { vsp->CTag = vsp->FTag = -1; } - if ((vsp->CTag == ni->CTag) && (vsp->FTag == ni->FTag)) - { vsp->Cy[1] = ni->Cy[1]; vsp->Fy[1] = ni->Fy[1]; FreeVsp (ni); } - else vsp = ni; - } - return did; -} - -#include "d_event.h" -static int pmx, pmy; -static int pt, px0, py0, px1, py1; -static struct polypt { float x, y; } polypts[80]; -static BYTE polysize[32]; -static int numpoly, polypt; -PolyClipper TestPoly; - -void drawline2d (float x1, float y1, float x2, float y2, BYTE col) -{ - float dx, dy, fxresm1, fyresm1, f; - long i, x, y, xi, yi, xup16, yup16; - - //Always draw lines in same direction - if ((y2 > y1) || ((y2 == y1) && (x2 > x1))) { f = x1; x1 = x2; x2 = f; f = y1; y1 = y2; y2 = f; } - - dx = x2-x1; dy = y2-y1; if ((dx == 0) && (dy == 0)) return; - fxresm1 = (float)RenderTarget->GetWidth()-.5; fyresm1 = (float)RenderTarget->GetHeight()-.5; - if (x1 >= fxresm1) { if (x2 >= fxresm1) return; y1 += (fxresm1-x1)*dy/dx; x1 = fxresm1; } - else if (x1 < 0) { if (x2 < 0) return; y1 += ( 0-x1)*dy/dx; x1 = 0; } - if (x2 >= fxresm1) { y2 += (fxresm1-x2)*dy/dx; x2 = fxresm1; } - else if (x2 < 0) { y2 += ( 0-x2)*dy/dx; x2 = 0; } - if (y1 >= fyresm1) { if (y2 >= fyresm1) return; x1 += (fyresm1-y1)*dx/dy; y1 = fyresm1; } - else if (y1 < 0) { if (y2 < 0) return; x1 += ( 0-y1)*dx/dy; y1 = 0; } - if (y2 >= fyresm1) { x2 += (fyresm1-y2)*dx/dy; y2 = fyresm1; } - else if (y2 < 0) { x2 += ( 0-y2)*dx/dy; y2 = 0; } - - dx = x2-x1; dy = y2-y1; - i = (long)(MAX(fabsf(dx)+1,fabsf(dy)+1)); f = 65536.f/((float)i); - x = (long)(x1*65536.f)+32768; xi = (long)(dx*f); xup16 = (RenderTarget->GetWidth()<<16); - y = (long)(y1*65536.f)+32768; yi = (long)(dy*f); yup16 = (RenderTarget->GetHeight()<<16); - do - { - if (((unsigned long)x < (unsigned long)xup16) && ((unsigned long)y < (unsigned long)yup16)) - *(ylookup[y>>16]+(x>>16)+dc_destorg) = col; - x += xi; y += yi; i--; - } while (i >= 0); -} - -static int maskhack; - -void fillconvpoly (float x[], float y[], int n, int col, int bcol) -{ - int mini = y[0] >= y[1], maxi = 1 - mini; - int i, j, y2, oz, z, yy, zz, ncol; - float area, xi, xx; - static int lastx[MAXHEIGHT+2]; - - for (z = 2; z < n; ++z) - { - if (y[z] < y[mini]) mini = z; - if (y[z] > y[maxi]) maxi = z; - } - - area = 0; zz = n - 1; - for (z = 0; z < n; ++z) - { - area += (x[zz] - x[z]) * (y[z] + y[zz]); zz = z; - } - if (area <= 0) return; - - i = maxi; y2 = int(y[i]); - do - { - j = i + 1; if (j == n) j = 0; - yy = int(ceilf(y[j])); - if (yy < 0) yy = 0; - if (yy < y2) - { - xi = (x[j] - x[i]) / (y[j] - y[i]); - xx = (y2 - y[j]) * xi + x[j]; - if (y2 >= RenderTarget->GetHeight()) { xx = xx - (y2 - RenderTarget->GetHeight() + 1)*xi; y2 = RenderTarget->GetHeight()-1; } - for (; y2 >= yy; --y2) - { - lastx[y2] = MAX (0, int(ceilf(xx))); xx = xx - xi; - } - } - i = j; - } while (i != mini); - if (y2 == yy) lastx[yy] = lastx[yy+1]; - do - { - j = i + 1; if (j == n) j = 0; - y2 = int(y[j]); - if (y2 >= RenderTarget->GetHeight()) y2 = RenderTarget->GetHeight()-1; - if (y2 > yy) - { - xi = (x[j] - x[i]) / (y[j] - y[i]); - xx = (yy - y[i]) * xi + x[i]; - if (yy < 0) { xx = xx - xi*yy; yy = 0; } - ncol = col; if (yy & 1) ncol = ncol ^ maskhack; - for (; yy <= y2; ++yy) - { - //drawline2d(lastx[yy], yy, int(ceilf(xx)), yy, ncol); xx = xx + xi; - int xxx = MIN(RenderTarget->GetWidth(), int(ceilf(xx))); - if (yy < RenderTarget->GetHeight() && lastx[yy] < xxx) memset(RenderTarget->GetBuffer()+yy*RenderTarget->GetPitch()+lastx[yy], ncol, xxx-lastx[yy]); - xx = xx + xi; - ncol = ncol ^ maskhack; - } - } - i = j; - } while (i != maxi); - - if (col != bcol) - { - oz = n - 1; - for (z = 0; z < n; ++z) - { - drawline2d(x[oz], y[oz], x[z], y[z], bcol); - oz = z; - } - } -} - -void drawtri(float x0, float y0, float x1, float y1, float x2, float y2, int col, int bcol) -{ - float x[3], y[3]; - x[0] = x0; y[0] = y0; - x[1] = x1; y[1] = y1; - x[2] = x2; y[2] = y2; - fillconvpoly(x, y, 3, col, bcol); -} - -void drawquad(float x0, float y0, float x1, float y1, float x2, float y2, float x3, float y3, int col, int bcol) -{ - float x[4], y[4]; - x[0] = x0; y[0] = y0; - x[1] = x1; y[1] = y1; - x[2] = x2; y[2] = y2; - x[3] = x3; y[3] = y3; - fillconvpoly(x, y, 4, col, bcol); // 2 triangles - if (col != bcol) - { - if (fabsf(y0-y2) < fabsf(y1-y3)) - drawline2d(x0,y0,x2,y2,bcol); - else - drawline2d(x1,y1,x3,y3,bcol); - } -} - -void printnum(int x, int y, int num) -{ - char foo[16]; mysnprintf (foo, countof(foo), "%d", num); - RenderTarget->DrawText (SmallFont, CR_WHITE, x, y, foo, TAG_DONE); -} - -void drawpolymosttest() -{ - float cx0 = 0, cy0 = 0, fx0 = 0, fy0 = 0; - int ccol, fcol; - PolyClipper::vsptype *vsp, *ovsp = &TestPoly.UsedList, *nvsp; - - fcol = 0; ccol = 0; - - RenderTarget->Clear(0, 0, RenderTarget->GetWidth(), RenderTarget->GetHeight(), 0, 0); - for (vsp = ovsp->Next; vsp->Next != &TestPoly.UsedList; ovsp = vsp, vsp = nvsp) - { - nvsp = vsp->Next; - if (vsp->CTag == -1 && vsp->FTag == -1) - { // Hide spans that have been clipped away - vsp->Cy[0] = vsp->Cy[1] = vsp->Fy[0] = vsp->Fy[1] = RenderTarget->GetHeight()/2; - } - - if (vsp->CTag != ovsp->CTag) cx0 = vsp->X, cy0 = vsp->Cy[0]; - if (vsp->CTag != nvsp->CTag) - { // fill the ceiling region - maskhack = 0x18; - drawquad(cx0, 0, nvsp->X, 0, nvsp->X, vsp->Cy[1], cx0, cy0, ccol, ccol); - maskhack = 0; ccol ^= 0x18; - printnum(int(cx0 + nvsp->X) / 2, 2, vsp->CTag); - } - - if(vsp->FTag != ovsp->FTag) fx0 = vsp->X, fy0 = vsp->Fy[0]; - if(vsp->FTag != nvsp->FTag) - { // fill the floor region - maskhack = 0x78; - drawquad(fx0, fy0+1, nvsp->X, vsp->Fy[1]+1, nvsp->X, RenderTarget->GetHeight(), fx0, RenderTarget->GetHeight(), fcol, fcol); - maskhack = 0; fcol ^= 0x78; - printnum(int(fx0 + nvsp->X) / 2, RenderTarget->GetHeight()-10, vsp->FTag); - } - - // fill the unclipped middle region - drawquad(vsp->X, vsp->Cy[0], nvsp->X, vsp->Cy[1], nvsp->X, vsp->Fy[1], vsp->X, vsp->Fy[0], 0xC4, 0xE6); - } - - int x = (pmx + 3) & ~7, y = (pmy + 3) & ~7; - - drawline2d (x - 3, y, x + 3, y, 30); - drawline2d (x, y - 3, x, y + 3, 30); - printnum ( 0, 20, x); - printnum (50, 20, y); - - if (pt > 0 && px0 != px1) - { - if (px0 < px1) - { - drawline2d (px0, py0, px0, RenderTarget->GetHeight()-1, 47); - drawline2d (px1, py1, px1, RenderTarget->GetHeight()-1, 47); - } - else - { - drawline2d (px0, py0, px0, 0, 47); - drawline2d (px1, py1, px1, 0, 47); - } - drawline2d (px0, py0, px1, py1, 47); - } - if (pt == 2) - { - int i = 0; - for (x = 0; x < numpoly; ++x) - { - if (polysize[x] == 3) - { - drawtri (polypts[i ].x, polypts[i ].y, - polypts[i+1].x, polypts[i+1].y, - polypts[i+2].x, polypts[i+2].y, 0x7f, 0x9f); - i += 3; - } - else - { - drawquad (polypts[i ].x, polypts[i ].y, - polypts[i+1].x, polypts[i+1].y, - polypts[i+2].x, polypts[i+2].y, - polypts[i+3].x, polypts[i+3].y, 0x7f, 0x9f); - i += 4; - } - } - } -} - -CCMD(initpolymosttest) -{ - double px[4], py[4]; - int test = 0; - - if (argv.argc() > 1) - test = atoi(argv[1]); - - // Box - px[0] = px[3] = 0; - px[1] = px[2] = screen->GetWidth(); - py[0] = py[1] = screen->GetHeight()/4; - py[2] = py[3] = screen->GetHeight()*3/4; - - switch (test) - { - case 1: // Shorter top edge - px[0] = px[1]/6; - px[1] = px[1]*5/6; - break; - - case 2: // Shorter bottom edge - px[3] = px[2]/6; - px[2] = px[2]*5/6; - break; - - case 3: // Shorter left edge - py[0] = screen->GetHeight()*3/8; - py[3] = screen->GetHeight()*5/8; - break; - - case 4: // Shorter right edge - py[1] = screen->GetHeight()*3/8; - py[2] = screen->GetHeight()*5/8; - break; - - case 5: - px[0] = -1.0048981460288360/2+50; py[0] = -1.0/2+50; - px[1] = 643.00492866407262/2+50; py[1] = -1.0/2+50; - px[2] = 643.00492866407262/2+50; py[2] = 483/2+50; - px[3] = -1.0048981460288360/2+50; py[3] = 483/2+50; - break; - } - TestPoly.InitMosts (px, py, 4); - pmx = screen->GetWidth()/2; - pmy = screen->GetHeight()/2; - pt = 0; -} - -static void testpolycallback (double *dpx, double *dpy, int n, void *foo) -{ - if (numpoly == sizeof(polysize)) return; - if (size_t(polypt + n) > countof(polypts)) return; - polysize[numpoly++] = n; - for (int i = 0; i < n; ++i) - { - polypts[polypt + i].x = dpx[i]; - polypts[polypt + i].y = dpy[i]; - } - polypt += n; -} - -void Polymost_Responder (event_t *ev) -{ - if (ev->type == EV_Mouse && pt < 2) - { - pmx = clamp (pmx + ev->x, 0, screen->GetWidth()-1); - pmy = clamp (pmy - ev->y, 0, screen->GetHeight()-1); - int x = (pmx + 3) & ~7, y = (pmy + 3) & ~7; - if (pt == 0) px0 = x, py0 = y; - if (pt <= 1) px1 = x, py1 = y; - } - else if (ev->type == EV_KeyDown && ev->data1 == KEY_MOUSE1) - { - if (pt == 0) pt = 1; else pt = 0; - } - else if (ev->type == EV_KeyUp && ev->data1 == KEY_MOUSE1) - { - if (pt == 1) { if (px0 != px1) pt++; else pt--; } - if (pt == 2) - { - numpoly = polypt = 0; - TestPoly.DoMost (px0, py0, px1, py1, testpolycallback, NULL); - } - } -} - - - - - - - - -extern fixed_t WallSZ1, WallSZ2, WallTX1, WallTX2, WallTY1, WallTY2, WallCX1, WallCX2, WallCY1, WallCY2; -extern int WallSX1, WallSX2; -extern float WallUoverZorg, WallUoverZstep, WallInvZorg, WallInvZstep, WallDepthScale, WallDepthOrg; -extern fixed_t rw_backcz1, rw_backcz2; -extern fixed_t rw_backfz1, rw_backfz2; -extern fixed_t rw_frontcz1, rw_frontcz2; -extern fixed_t rw_frontfz1, rw_frontfz2; -extern fixed_t rw_offset; -extern bool rw_markmirror; -extern bool rw_havehigh; -extern bool rw_havelow; -extern bool markfloor; -extern bool markceiling; -extern FTexture *toptexture; -extern FTexture *bottomtexture; -extern FTexture *midtexture; -extern bool rw_mustmarkfloor, rw_mustmarkceiling; -extern void R_NewWall(bool); -//extern void R_GetExtraLight (int *light, const secplane_t &plane, FExtraLight *el); -extern int doorclosed; -extern int viewpitch; -#include "p_lnspec.h" - -PolyClipper Mosts; -static bool drawback; - -bool RP_SetupFrame (bool backside) -{ - double ox, oy, oz, ox2, oy2, oz2, r, px[6], py[6], pz[6], px2[6], py2[6], pz2[6], sx[6], sy[6]; - int i, j, n, n2; - - drawback = backside; - if (backside) - { - viewangle += ANGLE_180; - viewsin = finesine[viewangle>>ANGLETOFINESHIFT]; - viewcos = finecosine[viewangle>>ANGLETOFINESHIFT]; - viewtansin = FixedMul (FocalTangent, viewsin); - viewtancos = FixedMul (FocalTangent, viewcos); - } - //Polymost supports true look up/down :) Here, we convert horizon to angle. - //gchang&gshang are cos&sin of this angle (respectively) -// gyxscale = ((double)xdimenscale)/131072.0; - gyxscale = double(InvZtoScale)/65536.0;///131072.0/320.0; -// gxyaspect = ((double)xyaspect*(double)viewingrange)*(5.0/(65536.0*262144.0)); -// gviewxrange = ((double)viewingrange)*((double)xdimen)/(32768.0*128.0); - gcosang = double(viewcos)/65536.0; - gsinang = double(viewsin)/65536.0; - gcosang2 = gcosang*double(FocalTangent)/65536.0; - gsinang2 = gsinang*double(FocalTangent)/65536.0; - ghalfx = (double)viewwidth*0.5; grhalfxdown10 = 1.0/(((double)ghalfx)*1024); - - //global cos/sin height angle - angle_t pitch = (angle_t)viewpitch; - if (backside) pitch = ANGLE_180 - pitch; - - gshang = double(finesine[pitch>>ANGLETOFINESHIFT])/65536.0; - gchang = double(finecosine[pitch>>ANGLETOFINESHIFT])/65536.0; - ghoriz = double(viewheight)*0.5; - - //global cos/sin tilt angle - gctang = cos(gtang); - gstang = sin(gtang); - if (fabs(gstang) < .001) //This hack avoids nasty precision bugs in domost() - { gstang = 0; if (gctang > 0) gctang = 1.0; else gctang = -1.0; } - - // Generate viewport trapezoid - px[0] = px[3] = 0-1; px[1] = px[2] = viewwidth+3; - py[0] = py[1] = 0-1; py[2] = py[3] = viewheight+3; n = 4; - for(i=0;i= n) j = 0; - if (pz[i] >= SCISDIST/16) { px2[n2] = px[i]; py2[n2] = py[i]; pz2[n2] = pz[i]; n2++; } - if ((pz[i] >= SCISDIST/16) != (pz[j] >= SCISDIST/16)) - { - clipped = true; - r = (SCISDIST/16-pz[i])/(pz[j]-pz[i]); - px2[n2] = (px[j]-px[i])*r + px[i]; - py2[n2] = (py[j]-py[i])*r + py[i]; - pz2[n2] = SCISDIST/16; - if (backside) py2[n2] -= r; - n2++; - } - } - if (n2 < 3) { return true; } - for(i=0;i= (dpx[2]-dpx[1])*(dpy[0]-dpy[1])) return; //for triangle - } - else - { - f = 0; //f is area of polygon / 2 - for(i=n-2,j=n-1,k=0;klinedef == NULL) return; - - //Offset&Rotate 3D coordinates to screen 3D space - x = double(line->v1->x - viewx); y = double(line->v1->y - viewy); - xp0 = x*gsinang - y*gcosang; - yp0 = x*gcosang2 + y*gsinang2; - x = double(line->v2->x - viewx); y = double(line->v2->y - viewy); - xp1 = x*gsinang - y*gcosang; - yp1 = x*gcosang2 + y*gsinang2; - - oxp0 = xp0; oyp0 = yp0; - - //Clip to close parallel-screen plane - // [RH] Why oh why does clipping the left side of the wall against - // a small SCISDIST not work for me? Strictly speaking, it's not - // the clipping of the left side that's the problem, because if I - // rotate the view 180 degrees so the right side of the wall is on - // the left of the screen, then clipping the right side becomes - // problematic. -#define WCLIPDIST (SCISDIST*256.0) - if (yp0 < WCLIPDIST) - { - if (yp1 < WCLIPDIST) return; - t0 = (WCLIPDIST-yp0)/(yp1-yp0); - xp0 = (xp1-xp0)*t0+xp0; - yp0 = WCLIPDIST; - nx0 = (line->v2->x - line->v1->x)*t0 + line->v1->x; - ny0 = (line->v2->y - line->v1->y)*t0 + line->v1->y; - } - else { t0 = 0.f; nx0 = line->v1->x; ny0 = line->v1->y; } - if (yp1 < WCLIPDIST) - { - t1 = (WCLIPDIST-oyp0)/(yp1-oyp0); - xp1 = (xp1-oxp0)*t1+oxp0; - yp1 = WCLIPDIST; - nx1 = (line->v2->x - line->v1->x)*t1 + line->v1->x; - ny1 = (line->v2->y - line->v1->y)*t1 + line->v1->y; - } - else { t1 = 1.f; nx1 = line->v2->x; ny1 = line->v2->y; } - - ryp0 = 1.0/yp0; ryp1 = 1.0/yp1; - - //Generate screen coordinates for front side of wall - x0 = ghalfx*xp0*ryp0 + ghalfx; - x1 = ghalfx*xp1*ryp1 + ghalfx; - if (x1 <= x0) return; - - ryp0 *= gyxscale; ryp1 *= gyxscale; - fixed_t fnx0 = fixed_t(nx0), fny0 = fixed_t(ny0); - fixed_t fnx1 = fixed_t(nx1), fny1 = fixed_t(ny1); - - fcz0 = frontsector->ceilingplane.ZatPoint (fnx0, fny0); - ffz0 = frontsector->floorplane.ZatPoint (fnx0, fny0); - fcz1 = frontsector->ceilingplane.ZatPoint (fnx1, fny1); - ffz1 = frontsector->floorplane.ZatPoint (fnx1, fny1); - bool cc = (t0>0 && x1 > 0); - cy0 = ghoriz - double(fcz0 - viewz) * ryp0; - fy0 = ghoriz - double(ffz0 - viewz) * ryp0; - cy1 = ghoriz - double(fcz1 - viewz) * ryp1; - fy1 = ghoriz - double(ffz1 - viewz) * ryp1; - -/* - tx1 = line->v1->x - viewx; - tx2 = line->v2->x - viewx; - ty1 = line->v1->y - viewy; - ty2 = line->v2->y - viewy; - // Reject lines not facing viewer - if (DMulScale32 (ty1, tx1-tx2, tx1, ty2-ty1) >= 0) - return; - - WallTX1 = DMulScale20 (tx1, viewsin, -ty1, viewcos); - WallTX2 = DMulScale20 (tx2, viewsin, -ty2, viewcos); - - WallTY1 = DMulScale20 (tx1, viewtancos, ty1, viewtansin); - WallTY2 = DMulScale20 (tx2, viewtancos, ty2, viewtansin); - - if (MirrorFlags & RF_XFLIP) - { - int t = 256-WallTX1; - WallTX1 = 256-WallTX2; - WallTX2 = t; - swap (WallTY1, WallTY2); - } - - if (WallTX1 >= -WallTY1) - { - if (WallTX1 > WallTY1) return; // left edge is off the right side - if (WallTY1 == 0) return; - WallSX1 = (centerxfrac + Scale (WallTX1, centerxfrac, WallTY1)) >> FRACBITS; - if (WallTX1 >= 0) WallSX1 = MIN (viewwidth, WallSX1+1); // fix for signed divide - WallSZ1 = WallTY1; - } - else - { - if (WallTX2 < -WallTY2) return; // wall is off the left side - fixed_t den = WallTX1 - WallTX2 - WallTY2 + WallTY1; - if (den == 0) return; - WallSX1 = 0; - WallSZ1 = WallTY1 + Scale (WallTY2 - WallTY1, WallTX1 + WallTY1, den); - } - - if (WallSZ1 < 32) - return; - - if (WallTX2 <= WallTY2) - { - if (WallTX2 < -WallTY2) return; // right edge is off the left side - if (WallTY2 == 0) return; - WallSX2 = (centerxfrac + Scale (WallTX2, centerxfrac, WallTY2)) >> FRACBITS; - if (WallTX2 >= 0) WallSX2 = MIN (viewwidth, WallSX2+1); // fix for signed divide - WallSZ2 = WallTY2; - } - else - { - if (WallTX1 > WallTY1) return; // wall is off the right side - fixed_t den = WallTY2 - WallTY1 - WallTX2 + WallTX1; - if (den == 0) return; - WallSX2 = viewwidth; - WallSZ2 = WallTY1 + Scale (WallTY2 - WallTY1, WallTX1 - WallTY1, den); - } - - if (WallSZ2 < 32 || WallSX2 <= WallSX1) - return; - - if (WallSX1 > WindowRight || WallSX2 < WindowLeft) - return; - if (line->linedef == NULL) - { - return; - } -*/ - - vertex_t *v1, *v2; - - v1 = line->linedef->v1; - v2 = line->linedef->v2; - - if ((v1 == line->v1 && v2 == line->v2) || (v2 == line->v1 && v1 == line->v2)) - { // The seg is the entire wall. - if (MirrorFlags & RF_XFLIP) - { - WallUoverZorg = (float)WallTX2 * WallTMapScale; - WallUoverZstep = (float)(-WallTY2) * 32.f; - WallInvZorg = (float)(WallTX2 - WallTX1) * WallTMapScale; - WallInvZstep = (float)(WallTY1 - WallTY2) * 32.f; - } - else - { - WallUoverZorg = (float)WallTX1 * WallTMapScale; - WallUoverZstep = (float)(-WallTY1) * 32.f; - WallInvZorg = (float)(WallTX1 - WallTX2) * WallTMapScale; - WallInvZstep = (float)(WallTY2 - WallTY1) * 32.f; - } - } - else - { // The seg is only part of the wall. - if (line->linedef->sidedef[0] != line->sidedef) - { - swapvalues (v1, v2); - } - tx1 = v1->x - viewx; - tx2 = v2->x - viewx; - ty1 = v1->y - viewy; - ty2 = v2->y - viewy; - - fixed_t fullx1 = DMulScale20 (tx1, viewsin, -ty1, viewcos); - fixed_t fullx2 = DMulScale20 (tx2, viewsin, -ty2, viewcos); - fixed_t fully1 = DMulScale20 (tx1, viewtancos, ty1, viewtansin); - fixed_t fully2 = DMulScale20 (tx2, viewtancos, ty2, viewtansin); - - if (MirrorFlags & RF_XFLIP) - { - fullx1 = -fullx1; - fullx2 = -fullx2; - } - - WallUoverZorg = (float)fullx1 * WallTMapScale; - WallUoverZstep = (float)(-fully1) * 32.f; - WallInvZorg = (float)(fullx1 - fullx2) * WallTMapScale; - WallInvZstep = (float)(fully2 - fully1) * 32.f; - } - WallDepthScale = WallInvZstep * WallTMapScale2; - WallDepthOrg = -WallUoverZstep * WallTMapScale2; - - backsector = line->backsector; - - rw_mustmarkfloor = rw_mustmarkceiling = false; - rw_havehigh = rw_havelow = false; - - // Single sided line? - if (backsector == NULL) - { - solid = true; - } - else - { - // killough 3/8/98, 4/4/98: hack for invisible ceilings / deep water - backsector = R_FakeFlat (backsector, &tempsec, NULL, NULL, true); - - doorclosed = 0; // killough 4/16/98 - - bcz0 = backsector->ceilingplane.ZatPoint (fnx0, fny0); - bfz0 = backsector->floorplane.ZatPoint (fnx0, fny0); - bcz1 = backsector->ceilingplane.ZatPoint (fnx1, fny1); - bfz1 = backsector->floorplane.ZatPoint (fnx1, fny1); - ocy0 = ghoriz - double(bcz0 - viewz) * ryp0; - ofy0 = ghoriz - double(bfz0 - viewz) * ryp0; - ocy1 = ghoriz - double(bcz1 - viewz) * ryp1; - ofy1 = ghoriz - double(bfz1 - viewz) * ryp1; - - if (fcz0 > bcz0 || fcz1 > bcz1) - { - rw_havehigh = true; - } - if (ffz0 < bfz0 ||ffz1 < bfz1) - { - rw_havelow = true; - } - - // Closed door. - if ((bcz0 <= ffz0 && bcz1 <= ffz1) || (bfz0 >= fcz0 && bfz1 >= fcz1)) - { - solid = true; - } - else if ( - (backsector->GetTexture(sector_t::ceiling) != skyflatnum || - frontsector->GetTexture(sector_t::ceiling) != skyflatnum) - - // if door is closed because back is shut: - && bcz0 <= bfz0 && bcz1 <= bfz1 - - // preserve a kind of transparent door/lift special effect: - && bcz0 >= fcz0 && bcz1 >= fcz1 - - && ((bfz0 <= ffz0 && bfz1 <= ffz1) || line->sidedef->GetTexture(side_t::bottom).isValid())) - { - // killough 1/18/98 -- This function is used to fix the automap bug which - // showed lines behind closed doors simply because the door had a dropoff. - // - // It assumes that Doom has already ruled out a door being closed because - // of front-back closure (e.g. front floor is taller than back ceiling). - - // This fixes the automap floor height bug -- killough 1/18/98: - // killough 4/7/98: optimize: save result in doorclosed for use in r_segs.c - doorclosed = true; - solid = true; - } - else if (frontsector->ceilingplane != backsector->ceilingplane || - frontsector->floorplane != backsector->floorplane) - { - // Window. - solid = false; - } - else if (backsector->lightlevel != frontsector->lightlevel - || backsector->GetTexture(sector_t::floor) != frontsector->GetTexture(sector_t::floor) - || backsector->GetTexture(sector_t::ceiling) != frontsector->GetTexture(sector_t::ceiling) - || curline->sidedef->GetTexture(side_t::mid).isValid() - - // killough 3/7/98: Take flats offsets into account: - || backsector->GetXOffset(sector_t::floor) != frontsector->GetXOffset(sector_t::floor) - || backsector->GetYOffset(sector_t::floor) != frontsector->GetYOffset(sector_t::floor) - || backsector->GetXOffset(sector_t::ceiling) != frontsector->GetXOffset(sector_t::ceiling) - || backsector->GetYOffset(sector_t::ceiling) != frontsector->GetYOffset(sector_t::ceiling) - - || backsector->GetPlaneLight(sector_t::floor) != frontsector->GetPlaneLight(sector_t::floor) - || backsector->GetPlaneLight(sector_t::ceiling) != frontsector->GetPlaneLight(sector_t::ceiling) - || backsector->GetFlags(sector_t::floor) != frontsector->GetFlags(sector_t::floor) - || backsector->GetFlags(sector_t::ceiling) != frontsector->GetFlags(sector_t::ceiling) - - // [RH] Also consider colormaps - || backsector->ColorMap != frontsector->ColorMap - - // [RH] and scaling - || backsector->GetXScale(sector_t::floor) != frontsector->GetXScale(sector_t::floor) - || backsector->GetYScale(sector_t::floor) != frontsector->GetYScale(sector_t::floor) - || backsector->GetXScale(sector_t::ceiling) != frontsector->GetXScale(sector_t::ceiling) - || backsector->GetYScale(sector_t::ceiling) != frontsector->GetYScale(sector_t::ceiling) - - // [RH] and rotation - || backsector->GetAngle(sector_t::floor) != frontsector->GetAngle(sector_t::floor) - || backsector->GetAngle(sector_t::ceiling) != frontsector->GetAngle(sector_t::ceiling) - ) - { - solid = false; - } - else - { - // Reject empty lines used for triggers and special events. - // Identical floor and ceiling on both sides, identical light levels - // on both sides, and no middle texture. - return; - } - } - - if (line->linedef->special == Line_Horizon) - { - // Be aware: Line_Horizon does not work properly with sloped planes - fcz1 = fcz0 = ffz1 = ffz0 = viewz; - markceiling = markfloor = true; - } - - // must be fixed in case the polymost renderer ever gets developed further! - rw_offset = line->sidedef->GetTextureXOffset(side_t::mid); - - R_NewWall (false); - if (rw_markmirror) - { - WallMirrors.Push (ds_p - drawsegs); - } - - // render it - if (markceiling) - { - Mosts.DoMost (x1, cy1, x0, cy0, wireframe, !cc||1?(void *)0xc3:(void*)0xca); - } - if (markfloor) - { - Mosts.DoMost (x0, fy0, x1, fy1, wireframe, (void *)0xd3); - } - if (midtexture) - { // one sided line - //if(line->linedef-lines==1)Printf ("%g %g %g -> %g %g %g : %g %g -> %g %g\n", yp0, x0, fy0, yp1, x1, fy1, nx0, ny0, nx1, ny1); - if (viewpitch > 0) - Mosts.DoMost (x0, -10000, x1, -10000, wireframe, !cc||1?(void *)0x83:(void*)0x93); - else - Mosts.DoMost (x1, 10000, x0, 10000, wireframe, !cc||1?(void *)0x83:(void*)0x93); - } - else - { // two sided line - if (toptexture != NULL && toptexture->UseType != FTexture::TEX_Null) - { // top wall - Mosts.DoMost (x1, ocy1, x0, ocy0, wireframe, (void *)0xa3); - } - if (bottomtexture != NULL && bottomtexture->UseType != FTexture::TEX_Null) - { // bottom wall - Mosts.DoMost (x0, ofy0, x1, ofy1, wireframe, (void *)0x93); -/* float bfz2 = float(-(rw_backfz2 - viewz)) / 65536.f; - float bfz1 = float(-(rw_backfz1 - viewz)) / 65536.f; - Mosts.DoMost (WallSX1, bfz1 * izs / sz1 + ghoriz, - WallSX2, bfz2 * izs / sz2 + ghoriz, - wireframe, (void *)0x93);*/ - } - } -} - -void RP_Subsector (subsector_t *sub) -{ - int count; - seg_t* line; - sector_t tempsec; // killough 3/7/98: deep water hack - int floorlightlevel; // killough 3/16/98: set floor lightlevel - int ceilinglightlevel; // killough 4/11/98 - - frontsector = sub->sector; - count = sub->numlines; - line = sub->firstline; - - // killough 3/8/98, 4/4/98: Deep water / fake ceiling effect - frontsector = R_FakeFlat(frontsector, &tempsec, &floorlightlevel, - &ceilinglightlevel, false); // killough 4/11/98 - - basecolormap = frontsector->ColorMap; - //R_GetExtraLight (&ceilinglightlevel, frontsector->ceilingplane, frontsector->ExtraLights); - - // [RH] set foggy flag - foggy = level.fadeto || frontsector->ColorMap->Fade || (level.flags & LEVEL_HASFADETABLE); - r_actualextralight = foggy ? 0 : extralight << 4; - basecolormap = frontsector->ColorMap; -/* ceilingplane = frontsector->ceilingplane.ZatPoint (viewx, viewy) > viewz || - frontsector->ceilingpic == skyflatnum || - (frontsector->CeilingSkyBox != NULL && frontsector->CeilingSkyBox->bAlways) || - (frontsector->heightsec && - !(frontsector->heightsec->MoreFlags & SECF_IGNOREHEIGHTSEC) && - frontsector->heightsec->floorpic == skyflatnum) ? - R_FindPlane(frontsector->ceilingplane, // killough 3/8/98 - frontsector->ceilingpic, - ceilinglightlevel + r_actualextralight, // killough 4/11/98 - frontsector->ceiling_xoffs, // killough 3/7/98 - frontsector->ceiling_yoffs + frontsector->base_ceiling_yoffs, - frontsector->ceiling_xscale, - frontsector->ceiling_yscale, - frontsector->ceiling_angle + frontsector->base_ceiling_angle, - frontsector->sky, - frontsector->CeilingSkyBox, - ) : NULL;*/ - - basecolormap = frontsector->ColorMap; - //R_GetExtraLight (&floorlightlevel, frontsector->floorplane, frontsector->ExtraLights); - - // killough 3/7/98: Add (x,y) offsets to flats, add deep water check - // killough 3/16/98: add floorlightlevel - // killough 10/98: add support for skies transferred from sidedefs -/* floorplane = frontsector->floorplane.ZatPoint (viewx, viewy) < viewz || // killough 3/7/98 - frontsector->floorpic == skyflatnum || - (frontsector->FloorSkyBox != NULL && frontsector->FloorSkyBox->bAlways) || - (frontsector->heightsec && - !(frontsector->heightsec->MoreFlags & SECF_IGNOREHEIGHTSEC) && - frontsector->heightsec->ceilingpic == skyflatnum) ? - R_FindPlane(frontsector->floorplane, - frontsector->floorpic, - floorlightlevel + r_actualextralight, // killough 3/16/98 - frontsector->floor_xoffs, // killough 3/7/98 - frontsector->floor_yoffs + frontsector->base_floor_yoffs, - frontsector->floor_xscale, - frontsector->floor_yscale, - frontsector->floor_angle + frontsector->base_floor_angle, - frontsector->sky, - frontsector->FloorSkyBox - ) : NULL;*/ - - // killough 9/18/98: Fix underwater slowdown, by passing real sector - // instead of fake one. Improve sprite lighting by basing sprite - // lightlevels on floor & ceiling lightlevels in the surrounding area. - // [RH] Handle sprite lighting like Duke 3D: If the ceiling is a sky, sprites are lit by - // it, otherwise they are lit by the floor. -// R_AddSprites (sub->sector, frontsector->ceilingpic == skyflatnum ? -// ceilinglightlevel : floorlightlevel, FakeSide); - - // [RH] Add particles -// int shade = LIGHT2SHADE((floorlightlevel + ceilinglightlevel)/2 + r_actualextralight); -// for (WORD i = ParticlesInSubsec[sub-subsectors]; i != NO_PARTICLE; i = Particles[i].snext) -// { -// R_ProjectParticle (Particles + i, subsectors[sub-subsectors].sector, shade, FakeSide); -// } - -#if 0 - if (sub->poly) - { // Render the polyobj in the subsector first - int polyCount = sub->poly->numsegs; - seg_t **polySeg = sub->poly->segs; - while (polyCount--) - { - RP_AddLine (*polySeg++); - } - } -#endif - - while (count--) - { - if (line->sidedef == NULL || !(line->sidedef->Flags & WALLF_POLYOBJ)) - { - RP_AddLine (line); - } - line++; - } -} - -extern "C" const int checkcoord[12][4]; - -static bool RP_CheckBBox (fixed_t *bspcoord) -{ - int boxx; - int boxy; - int boxpos; - - fixed_t x1, y1, x2, y2; - double x, y, xp0, yp0, xp1, yp1, t, sx0, sx1; - - // Find the corners of the box - // that define the edges from current viewpoint. - if (viewx <= bspcoord[BOXLEFT]) - boxx = 0; - else if (viewx < bspcoord[BOXRIGHT]) - boxx = 1; - else - boxx = 2; - - if (viewy >= bspcoord[BOXTOP]) - boxy = 0; - else if (viewy > bspcoord[BOXBOTTOM]) - boxy = 1; - else - boxy = 2; - - boxpos = (boxy<<2)+boxx; - if (boxpos == 5) - return true; - - x1 = bspcoord[checkcoord[boxpos][0]] - viewx; - y1 = bspcoord[checkcoord[boxpos][1]] - viewy; - x2 = bspcoord[checkcoord[boxpos][2]] - viewx; - y2 = bspcoord[checkcoord[boxpos][3]] - viewy; - - // check clip list for an open space - - // Sitting on a line? - if (DMulScale32 (y1, x1-x2, x1, y2-y1) >= 0) - return true; - - //Offset&Rotate 3D coordinates to screen 3D space - x = double(x1); y = double(y1); - xp0 = x*gsinang - y*gcosang; - yp0 = x*gcosang2 + y*gsinang2; - x = double(x2); y = double(y2); - xp1 = x*gsinang - y*gcosang; - yp1 = x*gcosang2 + y*gsinang2; - - //Clip to close parallel-screen plane - if (yp0 < SCISDIST) - { - if (yp1 < SCISDIST) return false; - t = (SCISDIST-yp0)/(yp1-yp0); - xp0 = (xp1-xp0)*t+xp0; - yp0 = SCISDIST; - } - if (yp1 < SCISDIST) - { - t = (SCISDIST-yp0)/(yp1-yp0); - xp1 = (xp1-xp0)*t+xp0; - yp1 = SCISDIST; - } - - //Generate screen coordinates for front side of wall - sx0 = ghalfx*xp0/yp0 + ghalfx; - sx1 = ghalfx*xp1/yp1 + ghalfx; - - // Does not cross a pixel. - if (sx1 <= sx0) - return false; - - return Mosts.TestVisibleMost (sx0, sx1); -} - -void RP_RenderBSPNode (void *node) -{ - if (numnodes == 0) - { - RP_Subsector (subsectors); - return; - } - while (!((size_t)node & 1)) // Keep going until found a subsector - { - node_t *bsp = (node_t *)node; - - // Decide which side the view point is on. - int side = R_PointOnSide (viewx, viewy, bsp); - - // Recursively divide front space (toward the viewer). - RP_RenderBSPNode (bsp->children[side]); - - // Possibly divide back space (away from the viewer). - side ^= 1; - if (!RP_CheckBBox (bsp->bbox[side])) - return; - - node = bsp->children[side]; - } - RP_Subsector ((subsector_t *)((BYTE *)node - 1)); -} - diff --git a/src/r_polymost.h b/src/r_polymost.h deleted file mode 100644 index 8afbefb22..000000000 --- a/src/r_polymost.h +++ /dev/null @@ -1,55 +0,0 @@ -/************************************************************************************************** -"POLYMOST" code written by Ken Silverman -**************************************************************************************************/ - -#include "c_cvars.h" - -typedef void (*pmostcallbacktype)(double *dpx, double *dpy, int n, void *userdata); - -class PolyClipper -{ -public: - PolyClipper(); - ~PolyClipper(); - - void InitMosts (double *px, double *py, int n); - bool TestVisibleMost (float x0, float x1); - int DoMost (float x0, float y0, float x1, float y1, pmostcallbacktype callback, void *callbackdata); - -private: - struct vsptype - { - float X, Cy[2], Fy[2]; - int Tag, CTag, FTag; - vsptype *Next, *Prev; - }; - - enum { GROUP_SIZE = 128 }; - - struct vspgroup - { - vspgroup (vsptype *sentinel); - - vspgroup *NextGroup; - vsptype vsp[GROUP_SIZE]; - }; - - vsptype EmptyList; - vsptype UsedList; - vspgroup vsps; - vsptype Solid; - - int GTag; - - vsptype *vsinsaft (vsptype *vsp); - void EmptyAll (); - void AddGroup (); - vsptype *GetVsp (); - void FreeVsp (vsptype *vsp); - - friend void drawpolymosttest(); - -}; - -extern void drawpolymosttest(); -struct event_t; void Polymost_Responder (event_t *ev); diff --git a/src/r_swrenderer.cpp b/src/r_swrenderer.cpp index 56f816d6f..fb54b6f0a 100644 --- a/src/r_swrenderer.cpp +++ b/src/r_swrenderer.cpp @@ -40,7 +40,6 @@ #include "r_bsp.h" #include "r_swrenderer.h" #include "r_3dfloors.h" -#include "r_polymost.h" #include "textures/textures.h" #include "r_data/voxels.h" @@ -49,7 +48,6 @@ class FArchive; void R_SWRSetWindow(int windowSize, int fullWidth, int fullHeight, int stHeight, int trueratio); void R_SetupColormap(player_t *); void R_SetupFreelook(); -void R_SetupPolymost(); void R_InitRenderer(); extern float LastFOV; @@ -245,7 +243,6 @@ void FSoftwareRenderer::SetupFrame(player_t *player) { R_SetupColormap(player); R_SetupFreelook(); - R_SetupPolymost(); } //========================================================================== diff --git a/zdoom.vcproj b/zdoom.vcproj index 3cbfac13a..cabc6c84f 100644 --- a/zdoom.vcproj +++ b/zdoom.vcproj @@ -2309,10 +2309,6 @@ RelativePath=".\src\r_plane.cpp" > - - @@ -2353,10 +2349,6 @@ RelativePath=".\src\r_plane.h" > - -