From e55e7b9a38134be754b8b5b6d05477818a646b12 Mon Sep 17 00:00:00 2001 From: Randy Heit Date: Thu, 31 Jul 2014 18:22:33 -0500 Subject: [PATCH 01/14] Don't weed out wall and floor sprites when spawning Build sprites --- src/p_buildmap.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/p_buildmap.cpp b/src/p_buildmap.cpp index 63e38c616..54bf92527 100644 --- a/src/p_buildmap.cpp +++ b/src/p_buildmap.cpp @@ -728,7 +728,7 @@ static int LoadSprites (spritetype *sprites, Xsprite *xsprites, int numsprites, } else { - if (sprites[i].cstat & (16|32|32768)) continue; + if (sprites[i].cstat & 32768) continue; if (sprites[i].xrepeat == 0 || sprites[i].yrepeat == 0) continue; mapthings[count].type = 9988; From 4cf468452cea77af73cfe137c890192f87172d51 Mon Sep 17 00:00:00 2001 From: Randy Heit Date: Thu, 31 Jul 2014 19:15:08 -0500 Subject: [PATCH 02/14] Remove slopetype from line_t. - Recomputing it in the only two places where it's used is trivial, so it's basically a waste of space to precompute it. --- src/m_bbox.cpp | 39 ++++++++++++++++++--------------------- src/p_map.cpp | 36 ++++++++++++++++++------------------ src/p_setup.cpp | 7 ------- src/po_man.cpp | 12 ------------ src/r_defs.h | 13 ------------- 5 files changed, 36 insertions(+), 71 deletions(-) diff --git a/src/m_bbox.cpp b/src/m_bbox.cpp index 6d3a5b744..199da8d68 100644 --- a/src/m_bbox.cpp +++ b/src/m_bbox.cpp @@ -54,19 +54,8 @@ int FBoundingBox::BoxOnLineSide (const line_t *ld) const int p1; int p2; - switch (ld->slopetype) - { - case ST_HORIZONTAL: - p1 = m_Box[BOXTOP] > ld->v1->y; - p2 = m_Box[BOXBOTTOM] > ld->v1->y; - if (ld->dx < 0) - { - p1 ^= 1; - p2 ^= 1; - } - break; - - case ST_VERTICAL: + if (ld->dx == 0) + { // ST_VERTICAL p1 = m_Box[BOXRIGHT] < ld->v1->x; p2 = m_Box[BOXLEFT] < ld->v1->x; if (ld->dy < 0) @@ -74,18 +63,26 @@ int FBoundingBox::BoxOnLineSide (const line_t *ld) const p1 ^= 1; p2 ^= 1; } - break; - - case ST_POSITIVE: + } + else if (ld->dy == 0) + { // ST_HORIZONTAL: + p1 = m_Box[BOXTOP] > ld->v1->y; + p2 = m_Box[BOXBOTTOM] > ld->v1->y; + if (ld->dx < 0) + { + p1 ^= 1; + p2 ^= 1; + } + } + else if ((ld->dy ^ ld->dx) >= 0) + { // ST_POSITIVE: p1 = P_PointOnLineSide (m_Box[BOXLEFT], m_Box[BOXTOP], ld); p2 = P_PointOnLineSide (m_Box[BOXRIGHT], m_Box[BOXBOTTOM], ld); - break; - - case ST_NEGATIVE: - default: // Just to assure GCC that p1 and p2 really do get initialized + } + else + { // ST_NEGATIVE: p1 = P_PointOnLineSide (m_Box[BOXRIGHT], m_Box[BOXTOP], ld); p2 = P_PointOnLineSide (m_Box[BOXLEFT], m_Box[BOXBOTTOM], ld); - break; } return (p1 == p2) ? p1 : -1; diff --git a/src/p_map.cpp b/src/p_map.cpp index db0c09202..96b2b6195 100644 --- a/src/p_map.cpp +++ b/src/p_map.cpp @@ -2244,24 +2244,8 @@ void FSlide::HitSlideLine (line_t* ld) slidemo->z <= slidemo->floorz && P_GetFriction (slidemo, NULL) > ORIG_FRICTION; - if (ld->slopetype == ST_HORIZONTAL) - { - if (icyfloor && (abs(tmymove) > abs(tmxmove))) - { - tmxmove /= 2; // absorb half the velocity - tmymove = -tmymove/2; - if (slidemo->player && slidemo->health > 0 && !(slidemo->player->cheats & CF_PREDICTING)) - { - S_Sound (slidemo, CHAN_VOICE, "*grunt", 1, ATTN_IDLE); // oooff! - } - } - else - tmymove = 0; // no more movement in the Y direction - return; - } - - if (ld->slopetype == ST_VERTICAL) - { + if (ld->dx == 0) + { // ST_VERTICAL if (icyfloor && (abs(tmxmove) > abs(tmymove))) { tmxmove = -tmxmove/2; // absorb half the velocity @@ -2276,6 +2260,22 @@ void FSlide::HitSlideLine (line_t* ld) return; } + if (ld->dy == 0) + { // ST_HORIZONTAL + if (icyfloor && (abs(tmymove) > abs(tmxmove))) + { + tmxmove /= 2; // absorb half the velocity + tmymove = -tmymove/2; + if (slidemo->player && slidemo->health > 0 && !(slidemo->player->cheats & CF_PREDICTING)) + { + S_Sound (slidemo, CHAN_VOICE, "*grunt", 1, ATTN_IDLE); // oooff! + } + } + else + tmymove = 0; // no more movement in the Y direction + return; + } + // The wall is angled. Bounce if the angle of approach is // phares // less than 45 degrees. // phares diff --git a/src/p_setup.cpp b/src/p_setup.cpp index f84862ef0..a6dbca868 100644 --- a/src/p_setup.cpp +++ b/src/p_setup.cpp @@ -1888,13 +1888,6 @@ void P_AdjustLine (line_t *ld) ld->dx = v2->x - v1->x; ld->dy = v2->y - v1->y; - if (ld->dx == 0) - ld->slopetype = ST_VERTICAL; - else if (ld->dy == 0) - ld->slopetype = ST_HORIZONTAL; - else - ld->slopetype = ((ld->dy ^ ld->dx) >= 0) ? ST_POSITIVE : ST_NEGATIVE; - if (v1->x < v2->x) { ld->bbox[BOXLEFT] = v1->x; diff --git a/src/po_man.cpp b/src/po_man.cpp index d844133b0..e19acc53a 100644 --- a/src/po_man.cpp +++ b/src/po_man.cpp @@ -950,18 +950,6 @@ void FPolyObj::UpdateBBox () // Update the line's slopetype line->dx = line->v2->x - line->v1->x; line->dy = line->v2->y - line->v1->y; - if (!line->dx) - { - line->slopetype = ST_VERTICAL; - } - else if (!line->dy) - { - line->slopetype = ST_HORIZONTAL; - } - else - { - line->slopetype = ((line->dy ^ line->dx) >= 0) ? ST_POSITIVE : ST_NEGATIVE; - } } CalcCenter(); } diff --git a/src/r_defs.h b/src/r_defs.h index 2e9c0876b..dd2136508 100644 --- a/src/r_defs.h +++ b/src/r_defs.h @@ -882,18 +882,6 @@ struct side_t FArchive &operator<< (FArchive &arc, side_t::part &p); -// -// Move clipping aid for LineDefs. -// -enum slopetype_t -{ - ST_HORIZONTAL, - ST_VERTICAL, - ST_POSITIVE, - ST_NEGATIVE -}; - - struct line_t { vertex_t *v1, *v2; // vertices, from v1 to v2 @@ -908,7 +896,6 @@ struct line_t side_t *sidedef[2]; //DWORD sidenum[2]; // sidenum[1] will be NO_SIDE if one sided fixed_t bbox[4]; // bounding box, for the extent of the LineDef. - slopetype_t slopetype; // To aid move clipping. sector_t *frontsector, *backsector; int validcount; // if == validcount, already checked int locknumber; // [Dusk] lock number for special From bbc3b69a7c227e319bbaf24bbccd9350ef4136ed Mon Sep 17 00:00:00 2001 From: Randy Heit Date: Thu, 31 Jul 2014 19:43:36 -0500 Subject: [PATCH 03/14] Remove polymost stuff - Maybe it will be back someday, but it's been essentially dead for nearly 10 years, so don't hold your breath. --- src/CMakeLists.txt | 1 - src/d_main.cpp | 24 +- src/r_main.cpp | 29 +- src/r_polymost.cpp | 1599 ------------------------------------------ src/r_polymost.h | 55 -- src/r_swrenderer.cpp | 3 - zdoom.vcproj | 8 - 7 files changed, 3 insertions(+), 1716 deletions(-) delete mode 100644 src/r_polymost.cpp delete mode 100644 src/r_polymost.h 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" > - - From bc450808b29e2ebfeaf7f2e2aace8f87aab3f7e1 Mon Sep 17 00:00:00 2001 From: Randy Heit Date: Thu, 31 Jul 2014 20:11:59 -0500 Subject: [PATCH 04/14] Consolidate wall texturing vars into two structs - All transformation and clipping values go into FWallCoords. - All texture mapping values go into FWallTMapVals. --- src/r_bsp.cpp | 116 ++++++++--------- src/r_bsp.h | 22 +++- src/r_segs.cpp | 329 +++++++++++++++++++++++-------------------------- 3 files changed, 226 insertions(+), 241 deletions(-) diff --git a/src/r_bsp.cpp b/src/r_bsp.cpp index 31dfe9907..c1ddb2a3c 100644 --- a/src/r_bsp.cpp +++ b/src/r_bsp.cpp @@ -92,18 +92,8 @@ drawseg_t* ds_p; size_t FirstInterestingDrawseg; TArray InterestingDrawsegs; -fixed_t WallTX1, WallTX2; // x coords at left, right of wall in view space -fixed_t WallTY1, WallTY2; // y coords at left, right of wall in view space - -fixed_t WallCX1, WallCX2; // x coords at left, right of wall in camera space -fixed_t WallCY1, WallCY2; // y coords at left, right of wall in camera space - -int WallSX1, WallSX2; // x coords at left, right of wall in screen space -fixed_t WallSZ1, WallSZ2; // depth at left, right of wall in screen space - -float WallDepthOrg, WallDepthScale; -float WallUoverZorg, WallUoverZstep; -float WallInvZorg, WallInvZstep; +FWallCoords WallC; +FWallTmapVals WallT; static BYTE FakeSide; @@ -419,7 +409,7 @@ sector_t *R_FakeFlat(sector_t *sec, sector_t *tempsec, rw_frontcz2 <= s->floorplane.ZatPoint (curline->v2->x, curline->v2->y)) { // Check that the window is actually visible - for (int z = WallSX1; z < WallSX2; ++z) + for (int z = WallC.SX1; z < WallC.SX2; ++z) { if (floorclip[z] > ceilingclip[z]) { @@ -549,66 +539,66 @@ void R_AddLine (seg_t *line) if (DMulScale32 (ty1, tx1-tx2, tx1, ty2-ty1) >= 0) return; - WallTX1 = DMulScale20 (tx1, viewsin, -ty1, viewcos); - WallTX2 = DMulScale20 (tx2, viewsin, -ty2, viewcos); + WallC.TX1 = DMulScale20 (tx1, viewsin, -ty1, viewcos); + WallC.TX2 = DMulScale20 (tx2, viewsin, -ty2, viewcos); - WallTY1 = DMulScale20 (tx1, viewtancos, ty1, viewtansin); - WallTY2 = DMulScale20 (tx2, viewtancos, ty2, viewtansin); + WallC.TY1 = DMulScale20 (tx1, viewtancos, ty1, viewtansin); + WallC.TY2 = DMulScale20 (tx2, viewtancos, ty2, viewtansin); if (MirrorFlags & RF_XFLIP) { - int t = 256-WallTX1; - WallTX1 = 256-WallTX2; - WallTX2 = t; - swapvalues (WallTY1, WallTY2); + int t = 256-WallC.TX1; + WallC.TX1 = 256-WallC.TX2; + WallC.TX2 = t; + swapvalues (WallC.TY1, WallC.TY2); } - if (WallTX1 >= -WallTY1) + if (WallC.TX1 >= -WallC.TY1) { - 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; + if (WallC.TX1 > WallC.TY1) return; // left edge is off the right side + if (WallC.TY1 == 0) return; + WallC.SX1 = (centerxfrac + Scale (WallC.TX1, centerxfrac, WallC.TY1)) >> FRACBITS; + if (WallC.TX1 >= 0) WallC.SX1 = MIN (viewwidth, WallC.SX1+1); // fix for signed divide + WallC.SZ1 = WallC.TY1; } else { - if (WallTX2 < -WallTY2) return; // wall is off the left side - fixed_t den = WallTX1 - WallTX2 - WallTY2 + WallTY1; + if (WallC.TX2 < -WallC.TY2) return; // wall is off the left side + fixed_t den = WallC.TX1 - WallC.TX2 - WallC.TY2 + WallC.TY1; if (den == 0) return; - WallSX1 = 0; - WallSZ1 = WallTY1 + Scale (WallTY2 - WallTY1, WallTX1 + WallTY1, den); + WallC.SX1 = 0; + WallC.SZ1 = WallC.TY1 + Scale (WallC.TY2 - WallC.TY1, WallC.TX1 + WallC.TY1, den); } - if (WallSZ1 < 32) + if (WallC.SZ1 < 32) return; - if (WallTX2 <= WallTY2) + if (WallC.TX2 <= WallC.TY2) { - 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; + if (WallC.TX2 < -WallC.TY2) return; // right edge is off the left side + if (WallC.TY2 == 0) return; + WallC.SX2 = (centerxfrac + Scale (WallC.TX2, centerxfrac, WallC.TY2)) >> FRACBITS; + if (WallC.TX2 >= 0) WallC.SX2 = MIN (viewwidth, WallC.SX2+1); // fix for signed divide + WallC.SZ2 = WallC.TY2; } else { - if (WallTX1 > WallTY1) return; // wall is off the right side - fixed_t den = WallTY2 - WallTY1 - WallTX2 + WallTX1; + if (WallC.TX1 > WallC.TY1) return; // wall is off the right side + fixed_t den = WallC.TY2 - WallC.TY1 - WallC.TX2 + WallC.TX1; if (den == 0) return; - WallSX2 = viewwidth; - WallSZ2 = WallTY1 + Scale (WallTY2 - WallTY1, WallTX1 - WallTY1, den); + WallC.SX2 = viewwidth; + WallC.SZ2 = WallC.TY1 + Scale (WallC.TY2 - WallC.TY1, WallC.TX1 - WallC.TY1, den); } - if (WallSZ2 < 32 || WallSX2 <= WallSX1) + if (WallC.SZ2 < 32 || WallC.SX2 <= WallC.SX1) return; - if (WallSX1 > WindowRight || WallSX2 < WindowLeft) + if (WallC.SX1 > WindowRight || WallC.SX2 < WindowLeft) return; if (line->linedef == NULL) { - if (R_CheckClipWallSegment (WallSX1, WallSX2)) + if (R_CheckClipWallSegment (WallC.SX1, WallC.SX2)) { InSubsector->flags |= SSECF_DRAWN; } @@ -624,17 +614,17 @@ void R_AddLine (seg_t *line) { // 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; + WallT.UoverZorg = (float)WallC.TX2 * WallTMapScale; + WallT.UoverZstep = (float)(-WallC.TY2) * 32.f; + WallT.InvZorg = (float)(WallC.TX2 - WallC.TX1) * WallTMapScale; + WallT.InvZstep = (float)(WallC.TY1 - WallC.TY2) * 32.f; } else { - WallUoverZorg = (float)WallTX1 * WallTMapScale; - WallUoverZstep = (float)(-WallTY1) * 32.f; - WallInvZorg = (float)(WallTX1 - WallTX2) * WallTMapScale; - WallInvZstep = (float)(WallTY2 - WallTY1) * 32.f; + WallT.UoverZorg = (float)WallC.TX1 * WallTMapScale; + WallT.UoverZstep = (float)(-WallC.TY1) * 32.f; + WallT.InvZorg = (float)(WallC.TX1 - WallC.TX2) * WallTMapScale; + WallT.InvZstep = (float)(WallC.TY2 - WallC.TY1) * 32.f; } } else @@ -659,13 +649,13 @@ void R_AddLine (seg_t *line) fullx2 = -fullx2; } - WallUoverZorg = (float)fullx1 * WallTMapScale; - WallUoverZstep = (float)(-fully1) * 32.f; - WallInvZorg = (float)(fullx1 - fullx2) * WallTMapScale; - WallInvZstep = (float)(fully2 - fully1) * 32.f; + WallT.UoverZorg = (float)fullx1 * WallTMapScale; + WallT.UoverZstep = (float)(-fully1) * 32.f; + WallT.InvZorg = (float)(fullx1 - fullx2) * WallTMapScale; + WallT.InvZstep = (float)(fully2 - fully1) * 32.f; } - WallDepthScale = WallInvZstep * WallTMapScale2; - WallDepthOrg = -WallUoverZstep * WallTMapScale2; + WallT.DepthScale = WallT.InvZstep * WallTMapScale2; + WallT.DepthOrg = -WallT.UoverZstep * WallTMapScale2; if (!(fake3D & FAKE3D_FAKEBACK)) { @@ -791,7 +781,7 @@ void R_AddLine (seg_t *line) // mark their subsectors as visible for automap texturing. if (hasglnodes && !(InSubsector->flags & SSECF_DRAWN)) { - if (R_CheckClipWallSegment(WallSX1, WallSX2)) + if (R_CheckClipWallSegment(WallC.SX1, WallC.SX2)) { InSubsector->flags |= SSECF_DRAWN; } @@ -805,8 +795,8 @@ void R_AddLine (seg_t *line) if (line->linedef->special == Line_Horizon) { // Be aware: Line_Horizon does not work properly with sloped planes - clearbufshort (walltop+WallSX1, WallSX2 - WallSX1, centery); - clearbufshort (wallbottom+WallSX1, WallSX2 - WallSX1, centery); + clearbufshort (walltop+WallC.SX1, WallC.SX2 - WallC.SX1, centery); + clearbufshort (wallbottom+WallC.SX1, WallC.SX2 - WallC.SX1, centery); } else { @@ -831,7 +821,7 @@ void R_AddLine (seg_t *line) #endif } - if (R_ClipWallSegment (WallSX1, WallSX2, solid)) + if (R_ClipWallSegment (WallC.SX1, WallC.SX2, solid)) { InSubsector->flags |= SSECF_DRAWN; } diff --git a/src/r_bsp.h b/src/r_bsp.h index da20fb90c..d2fcb67e1 100644 --- a/src/r_bsp.h +++ b/src/r_bsp.h @@ -26,6 +26,25 @@ #include "tarray.h" #include +struct FWallCoords +{ + fixed_t TX1, TX2; // x coords at left, right of wall in view space + fixed_t TY1, TY2; // y coords at left, right of wall in view space + + fixed_t CX1, CX2; // x coords at left, right of wall in camera space + fixed_t CY1, CY2; // y coords at left, right of wall in camera space + + int SX1, SX2; // x coords at left, right of wall in screen space + fixed_t SZ1, SZ2; // depth at left, right of wall in screen space +}; + +struct FWallTmapVals +{ + float DepthOrg, DepthScale; + float UoverZorg, UoverZstep; + float InvZorg, InvZstep; +}; + enum { FAKED_Center, @@ -33,7 +52,6 @@ enum FAKED_AboveCeiling }; - struct drawseg_t { seg_t* curline; @@ -58,7 +76,7 @@ struct drawseg_t int fake; // ident fake drawseg, don't draw and clip sprites // backups ptrdiff_t bkup; // sprtopclip backup, for mid and fake textures - float WallUoverZorg, WallUoverZstep, WallInvZorg, WallInvZstep, WallDepthScale, WallDepthOrg; + FWallTmapVals tmapvals; }; diff --git a/src/r_segs.cpp b/src/r_segs.cpp index 4fec863ff..e1896b883 100644 --- a/src/r_segs.cpp +++ b/src/r_segs.cpp @@ -90,9 +90,8 @@ int OWallMost (short *mostbuf, fixed_t z); int WallMost (short *mostbuf, const secplane_t &plane); void PrepWall (fixed_t *swall, fixed_t *lwall, fixed_t walxrepeat); void PrepLWall (fixed_t *lwall, fixed_t walxrepeat); -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 FWallCoords WallC; +extern FWallTmapVals WallT; int wallshade; @@ -389,10 +388,10 @@ void R_RenderMaskedSegRange (drawseg_t *ds, int x1, int x2) goto clearfog; } - WallSZ1 = ds->sz1; - WallSZ2 = ds->sz2; - WallSX1 = ds->sx1; - WallSX2 = ds->sx2; + WallC.SZ1 = ds->sz1; + WallC.SZ2 = ds->sz2; + WallC.SX1 = ds->sx1; + WallC.SX2 = ds->sx2; if (fake3D & FAKE3D_CLIPTOP) { @@ -480,10 +479,10 @@ void R_RenderMaskedSegRange (drawseg_t *ds, int x1, int x2) } else { // Texture does wrap vertically. - WallSZ1 = ds->sz1; - WallSZ2 = ds->sz2; - WallSX1 = ds->sx1; - WallSX2 = ds->sx2; + WallC.SZ1 = ds->sz1; + WallC.SZ2 = ds->sz2; + WallC.SX1 = ds->sx1; + WallC.SX2 = ds->sx2; if (CurrentSkybox) { // Midtex clipping doesn't work properly with skyboxes, since you're normally below the floor @@ -600,20 +599,15 @@ void R_RenderFakeWall(drawseg_t *ds, int x1, int x2, F3DFloor *rover) else if (fixedcolormap != NULL) dc_colormap = fixedcolormap; - WallSZ1 = ds->sz1; - WallSZ2 = ds->sz2; - WallSX1 = ds->sx1; - WallSX2 = ds->sx2; - WallTX1 = ds->cx; - WallTY1 = ds->cy; - WallTX2 = WallTX1 + ds->cdx; - WallTY2 = WallTY1 + ds->cdy; - WallDepthScale = ds->WallDepthScale; - WallDepthOrg = ds->WallDepthOrg; - WallUoverZorg = ds->WallUoverZorg; - WallUoverZstep = ds->WallUoverZstep; - WallInvZorg = ds->WallInvZorg; - WallInvZstep = ds->WallInvZstep; + WallC.SZ1 = ds->sz1; + WallC.SZ2 = ds->sz2; + WallC.SX1 = ds->sx1; + WallC.SX2 = ds->sx2; + WallC.TX1 = ds->cx; + WallC.TY1 = ds->cy; + WallC.TX2 = ds->cx + ds->cdx; + WallC.TY2 = ds->cy + ds->cdy; + WallT = ds->tmapvals; OWallMost(wallupper, sclipTop - viewz); OWallMost(walllower, sclipBottom - viewz); @@ -1227,8 +1221,8 @@ void wallscan_striped (int x1, int x2, short *uwal, short *dwal, fixed_t *swal, up = uwal; down = most1; - assert(WallSX1 <= x1); - assert(WallSX2 > x2); + assert(WallC.SX1 <= x1); + assert(WallC.SX2 > x2); // kg3D - fake floors instead of zdoom light list for (unsigned int i = 0; i < frontsector->e->XFloor.lightlist.Size(); i++) @@ -2048,7 +2042,7 @@ void R_NewWall (bool needlights) { if (rw_havehigh) { // front ceiling is above back ceiling - memcpy (&walltop[WallSX1], &wallupper[WallSX1], (WallSX2 - WallSX1)*sizeof(walltop[0])); + memcpy (&walltop[WallC.SX1], &wallupper[WallC.SX1], (WallC.SX2 - WallC.SX1)*sizeof(walltop[0])); rw_havehigh = false; } else if (rw_havelow && frontsector->ceilingplane != backsector->ceilingplane) @@ -2280,8 +2274,8 @@ void R_NewWall (bool needlights) wallshade = LIGHT2SHADE(curline->sidedef->GetLightLevel(foggy, frontsector->lightlevel) + r_actualextralight); GlobVis = r_WallVisibility; - rw_lightleft = SafeDivScale12 (GlobVis, WallSZ1); - rw_lightstep = (SafeDivScale12 (GlobVis, WallSZ2) - rw_lightleft) / (WallSX2 - WallSX1); + rw_lightleft = SafeDivScale12 (GlobVis, WallC.SZ1); + rw_lightstep = (SafeDivScale12 (GlobVis, WallC.SZ2) - rw_lightleft) / (WallC.SX2 - WallC.SX1); } else { @@ -2355,24 +2349,19 @@ void R_StoreWallRange (int start, int stop) } rw_offset = sidedef->GetTextureXOffset(side_t::mid); - rw_light = rw_lightleft + rw_lightstep * (start - WallSX1); + rw_light = rw_lightleft + rw_lightstep * (start - WallC.SX1); - ds_p->sx1 = WallSX1; - ds_p->sx2 = WallSX2; - ds_p->sz1 = WallSZ1; - ds_p->sz2 = WallSZ2; - ds_p->cx = WallTX1; - ds_p->cy = WallTY1; - ds_p->cdx = WallTX2 - WallTX1; - ds_p->cdy = WallTY2 - WallTY1; - ds_p->WallDepthScale = WallDepthScale; - ds_p->WallDepthOrg = WallDepthOrg; - ds_p->WallUoverZorg = WallUoverZorg; - ds_p->WallUoverZstep = WallUoverZstep; - ds_p->WallInvZorg = WallInvZorg; - ds_p->WallInvZstep = WallInvZstep; - ds_p->siz1 = (DWORD)DivScale32 (1, WallSZ1) >> 1; - ds_p->siz2 = (DWORD)DivScale32 (1, WallSZ2) >> 1; + ds_p->sx1 = WallC.SX1; + ds_p->sx2 = WallC.SX2; + ds_p->sz1 = WallC.SZ1; + ds_p->sz2 = WallC.SZ2; + ds_p->cx = WallC.TX1; + ds_p->cy = WallC.TY1; + ds_p->cdx = WallC.TX2 - WallC.TX1; + ds_p->cdy = WallC.TY2 - WallC.TY1; + ds_p->tmapvals = WallT; + ds_p->siz1 = (DWORD)DivScale32 (1, WallC.SZ1) >> 1; + ds_p->siz2 = (DWORD)DivScale32 (1, WallC.SZ2) >> 1; ds_p->x1 = rw_x = start; ds_p->x2 = stop-1; ds_p->curline = curline; @@ -2465,7 +2454,7 @@ void R_StoreWallRange (int start, int stop) if ((TexMan(sidedef->GetTexture(side_t::mid), true)->UseType != FTexture::TEX_Null || ds_p->bFakeBoundary || IsFogBoundary (frontsector, backsector)) && (rw_ceilstat != 12 || !sidedef->GetTexture(side_t::top).isValid()) && (rw_floorstat != 3 || !sidedef->GetTexture(side_t::bottom).isValid()) && - (WallSZ1 >= TOO_CLOSE_Z && WallSZ2 >= TOO_CLOSE_Z)) + (WallC.SZ1 >= TOO_CLOSE_Z && WallC.SZ2 >= TOO_CLOSE_Z)) { fixed_t *swal; fixed_t *lwal; @@ -2613,59 +2602,59 @@ int OWallMost (short *mostbuf, fixed_t z) fixed_t s1, s2, s3, s4; z = -(z >> 4); - s1 = MulScale16 (globaluclip, WallSZ1); s2 = MulScale16 (globaluclip, WallSZ2); - s3 = MulScale16 (globaldclip, WallSZ1); s4 = MulScale16 (globaldclip, WallSZ2); + s1 = MulScale16 (globaluclip, WallC.SZ1); s2 = MulScale16 (globaluclip, WallC.SZ2); + s3 = MulScale16 (globaldclip, WallC.SZ1); s4 = MulScale16 (globaldclip, WallC.SZ2); bad = (zs3)<<2)+((z>s4)<<3); #if 1 if ((bad&3) == 3) { - memset (&mostbuf[WallSX1], 0, (WallSX2 - WallSX1)*sizeof(mostbuf[0])); + memset (&mostbuf[WallC.SX1], 0, (WallC.SX2 - WallC.SX1)*sizeof(mostbuf[0])); return bad; } if ((bad&12) == 12) { - clearbufshort (&mostbuf[WallSX1], WallSX2 - WallSX1, viewheight); + clearbufshort (&mostbuf[WallC.SX1], WallC.SX2 - WallC.SX1, viewheight); return bad; } #endif - ix1 = WallSX1; iy1 = WallSZ1; - ix2 = WallSX2; iy2 = WallSZ2; + ix1 = WallC.SX1; iy1 = WallC.SZ1; + ix2 = WallC.SX2; iy2 = WallC.SZ2; #if 1 if (bad & 3) { int t = DivScale30 (z-s1, s2-s1); - int inty = WallSZ1 + MulScale30 (WallSZ2 - WallSZ1, t); - int xcross = WallSX1 + Scale (MulScale30 (WallSZ2, t), WallSX2 - WallSX1, inty); + int inty = WallC.SZ1 + MulScale30 (WallC.SZ2 - WallC.SZ1, t); + int xcross = WallC.SX1 + Scale (MulScale30 (WallC.SZ2, t), WallC.SX2 - WallC.SX1, inty); if ((bad & 3) == 2) { - if (WallSX1 <= xcross) { iy2 = inty; ix2 = xcross; } - if (WallSX2 > xcross) memset (&mostbuf[xcross], 0, (WallSX2-xcross)*sizeof(mostbuf[0])); + if (WallC.SX1 <= xcross) { iy2 = inty; ix2 = xcross; } + if (WallC.SX2 > xcross) memset (&mostbuf[xcross], 0, (WallC.SX2-xcross)*sizeof(mostbuf[0])); } else { - if (xcross <= WallSX2) { iy1 = inty; ix1 = xcross; } - if (xcross > WallSX1) memset (&mostbuf[WallSX1], 0, (xcross-WallSX1)*sizeof(mostbuf[0])); + if (xcross <= WallC.SX2) { iy1 = inty; ix1 = xcross; } + if (xcross > WallC.SX1) memset (&mostbuf[WallC.SX1], 0, (xcross-WallC.SX1)*sizeof(mostbuf[0])); } } if (bad & 12) { int t = DivScale30 (z-s3, s4-s3); - int inty = WallSZ1 + MulScale30 (WallSZ2 - WallSZ1, t); - int xcross = WallSX1 + Scale (MulScale30 (WallSZ2, t), WallSX2 - WallSX1, inty); + int inty = WallC.SZ1 + MulScale30 (WallC.SZ2 - WallC.SZ1, t); + int xcross = WallC.SX1 + Scale (MulScale30 (WallC.SZ2, t), WallC.SX2 - WallC.SX1, inty); if ((bad & 12) == 8) { - if (WallSX1 <= xcross) { iy2 = inty; ix2 = xcross; } - if (WallSX2 > xcross) clearbufshort (&mostbuf[xcross], WallSX2 - xcross, viewheight); + if (WallC.SX1 <= xcross) { iy2 = inty; ix2 = xcross; } + if (WallC.SX2 > xcross) clearbufshort (&mostbuf[xcross], WallC.SX2 - xcross, viewheight); } else { - if (xcross <= WallSX2) { iy1 = inty; ix1 = xcross; } - if (xcross > WallSX1) clearbufshort (&mostbuf[WallSX1], xcross - WallSX1, viewheight); + if (xcross <= WallC.SX2) { iy1 = inty; ix1 = xcross; } + if (xcross > WallC.SX1) clearbufshort (&mostbuf[WallC.SX1], xcross - WallC.SX1, viewheight); } } @@ -2683,12 +2672,12 @@ int OWallMost (short *mostbuf, fixed_t z) double max = viewheight; double zz = z / 65536.0; #if 0 - double z1 = zz * InvZtoScale / WallSZ1; - double z2 = zz * InvZtoScale / WallSZ2 - z1; - z2 /= (WallSX2 - WallSX1); + double z1 = zz * InvZtoScale / WallC.SZ1; + double z2 = zz * InvZtoScale / WallC.SZ2 - z1; + z2 /= (WallC.SX2 - WallC.SX1); z1 += centeryfrac / 65536.0; - for (int x = WallSX1; x < WallSX2; ++x) + for (int x = WallC.SX1; x < WallC.SX2; ++x) { mostbuf[x] = xs_RoundToInt(clamp(z1, 0.0, max)); z1 += z2; @@ -2696,18 +2685,18 @@ int OWallMost (short *mostbuf, fixed_t z) #else double top, bot, i; - i = WallSX1 - centerx; - top = WallUoverZorg + WallUoverZstep * i; - bot = WallInvZorg + WallInvZstep * i; + i = WallC.SX1 - centerx; + top = WallT.UoverZorg + WallT.UoverZstep * i; + bot = WallT.InvZorg + WallT.InvZstep * i; double cy = centeryfrac / 65536.0; - for (int x = WallSX1; x < WallSX2; x++) + for (int x = WallC.SX1; x < WallC.SX2; x++) { double frac = top / bot; - double scale = frac * WallDepthScale + WallDepthOrg; + double scale = frac * WallT.DepthScale + WallT.DepthOrg; mostbuf[x] = xs_RoundToInt(clamp(zz / scale + cy, 0.0, max)); - top += WallUoverZstep; - bot += WallInvZstep; + top += WallT.UoverZstep; + bot += WallT.InvZstep; } #endif #endif @@ -2734,21 +2723,21 @@ int WallMost (short *mostbuf, const secplane_t &plane) { x = curline->v2->x; y = curline->v2->y; - if (WallSX1 == 0 && 0 != (den = WallTX1 - WallTX2 + WallTY1 - WallTY2)) + if (WallC.SX1 == 0 && 0 != (den = WallC.TX1 - WallC.TX2 + WallC.TY1 - WallC.TY2)) { - int frac = SafeDivScale30 (WallTY1 + WallTX1, den); + int frac = SafeDivScale30 (WallC.TY1 + WallC.TX1, den); x -= MulScale30 (frac, x - curline->v1->x); y -= MulScale30 (frac, y - curline->v1->y); } z1 = viewz - plane.ZatPoint (x, y); - if (WallSX2 > WallSX1 + 1) + if (WallC.SX2 > WallC.SX1 + 1) { x = curline->v1->x; y = curline->v1->y; - if (WallSX2 == viewwidth && 0 != (den = WallTX1 - WallTX2 - WallTY1 + WallTY2)) + if (WallC.SX2 == viewwidth && 0 != (den = WallC.TX1 - WallC.TX2 - WallC.TY1 + WallC.TY2)) { - int frac = SafeDivScale30 (WallTY2 - WallTX2, den); + int frac = SafeDivScale30 (WallC.TY2 - WallC.TX2, den); x += MulScale30 (frac, curline->v2->x - x); y += MulScale30 (frac, curline->v2->y - y); } @@ -2763,21 +2752,21 @@ int WallMost (short *mostbuf, const secplane_t &plane) { x = curline->v1->x; y = curline->v1->y; - if (WallSX1 == 0 && 0 != (den = WallTX1 - WallTX2 + WallTY1 - WallTY2)) + if (WallC.SX1 == 0 && 0 != (den = WallC.TX1 - WallC.TX2 + WallC.TY1 - WallC.TY2)) { - int frac = SafeDivScale30 (WallTY1 + WallTX1, den); + int frac = SafeDivScale30 (WallC.TY1 + WallC.TX1, den); x += MulScale30 (frac, curline->v2->x - x); y += MulScale30 (frac, curline->v2->y - y); } z1 = viewz - plane.ZatPoint (x, y); - if (WallSX2 > WallSX1 + 1) + if (WallC.SX2 > WallC.SX1 + 1) { x = curline->v2->x; y = curline->v2->y; - if (WallSX2 == viewwidth && 0 != (den = WallTX1 - WallTX2 - WallTY1 + WallTY2)) + if (WallC.SX2 == viewwidth && 0 != (den = WallC.TX1 - WallC.TX2 - WallC.TY1 + WallC.TY2)) { - int frac = SafeDivScale30 (WallTY2 - WallTX2, den); + int frac = SafeDivScale30 (WallC.TY2 - WallC.TX2, den); x -= MulScale30 (frac, x - curline->v1->x); y -= MulScale30 (frac, y - curline->v1->y); } @@ -2789,12 +2778,12 @@ int WallMost (short *mostbuf, const secplane_t &plane) } } - s1 = MulScale12 (globaluclip, WallSZ1); s2 = MulScale12 (globaluclip, WallSZ2); - s3 = MulScale12 (globaldclip, WallSZ1); s4 = MulScale12 (globaldclip, WallSZ2); + s1 = MulScale12 (globaluclip, WallC.SZ1); s2 = MulScale12 (globaluclip, WallC.SZ2); + s3 = MulScale12 (globaldclip, WallC.SZ1); s4 = MulScale12 (globaldclip, WallC.SZ2); bad = (z1s3)<<2)+((z2>s4)<<3); - ix1 = WallSX1; ix2 = WallSX2; - iy1 = WallSZ1; iy2 = WallSZ2; + ix1 = WallC.SX1; ix2 = WallC.SX2; + iy1 = WallC.SZ1; iy2 = WallC.SZ2; oz1 = z1; oz2 = z2; if ((bad&3) == 3) @@ -2814,9 +2803,9 @@ int WallMost (short *mostbuf, const secplane_t &plane) { //inty = intz / (globaluclip>>16) int t = SafeDivScale30 (oz1-s1, s2-s1+oz1-oz2); - int inty = WallSZ1 + MulScale30 (WallSZ2-WallSZ1,t); + int inty = WallC.SZ1 + MulScale30 (WallC.SZ2-WallC.SZ1,t); int intz = oz1 + MulScale30 (oz2-oz1,t); - int xcross = WallSX1 + Scale (MulScale30 (WallSZ2, t), WallSX2-WallSX1, inty); + int xcross = WallC.SX1 + Scale (MulScale30 (WallC.SZ2, t), WallC.SX2-WallC.SX1, inty); //t = divscale30((x1<<4)-xcross*yb1[w],xcross*(yb2[w]-yb1[w])-((x2-x1)<<4)); //inty = yb1[w] + mulscale30(yb2[w]-yb1[w],t); @@ -2824,13 +2813,13 @@ int WallMost (short *mostbuf, const secplane_t &plane) if ((bad&3) == 2) { - if (WallSX1 <= xcross) { z2 = intz; iy2 = inty; ix2 = xcross; } - memset (&mostbuf[xcross], 0, (WallSX2-xcross)*sizeof(mostbuf[0])); + if (WallC.SX1 <= xcross) { z2 = intz; iy2 = inty; ix2 = xcross; } + memset (&mostbuf[xcross], 0, (WallC.SX2-xcross)*sizeof(mostbuf[0])); } else { - if (xcross <= WallSX2) { z1 = intz; iy1 = inty; ix1 = xcross; } - memset (&mostbuf[WallSX1], 0, (xcross-WallSX1)*sizeof(mostbuf[0])); + if (xcross <= WallC.SX2) { z1 = intz; iy1 = inty; ix1 = xcross; } + memset (&mostbuf[WallC.SX1], 0, (xcross-WallC.SX1)*sizeof(mostbuf[0])); } } @@ -2838,9 +2827,9 @@ int WallMost (short *mostbuf, const secplane_t &plane) { //inty = intz / (globaldclip>>16) int t = SafeDivScale30 (oz1-s3, s4-s3+oz1-oz2); - int inty = WallSZ1 + MulScale30 (WallSZ2-WallSZ1,t); + int inty = WallC.SZ1 + MulScale30 (WallC.SZ2-WallC.SZ1,t); int intz = oz1 + MulScale30 (oz2-oz1,t); - int xcross = WallSX1 + Scale (MulScale30 (WallSZ2, t), WallSX2-WallSX1,inty); + int xcross = WallC.SX1 + Scale (MulScale30 (WallC.SZ2, t), WallC.SX2-WallC.SX1,inty); //t = divscale30((x1<<4)-xcross*yb1[w],xcross*(yb2[w]-yb1[w])-((x2-x1)<<4)); //inty = yb1[w] + mulscale30(yb2[w]-yb1[w],t); @@ -2848,13 +2837,13 @@ int WallMost (short *mostbuf, const secplane_t &plane) if ((bad&12) == 8) { - if (WallSX1 <= xcross) { z2 = intz; iy2 = inty; ix2 = xcross; } - if (WallSX2 > xcross) clearbufshort (&mostbuf[xcross], WallSX2-xcross, viewheight); + if (WallC.SX1 <= xcross) { z2 = intz; iy2 = inty; ix2 = xcross; } + if (WallC.SX2 > xcross) clearbufshort (&mostbuf[xcross], WallC.SX2-xcross, viewheight); } else { - if (xcross <= WallSX2) { z1 = intz; iy1 = inty; ix1 = xcross; } - if (xcross > WallSX1) clearbufshort (&mostbuf[WallSX1], xcross-WallSX1, viewheight); + if (xcross <= WallC.SX2) { z1 = intz; iy1 = inty; ix1 = xcross; } + if (xcross > WallC.SX1) clearbufshort (&mostbuf[WallC.SX1], xcross-WallC.SX1, viewheight); } } @@ -2884,9 +2873,9 @@ static void PrepWallRoundFix(fixed_t *lwall, fixed_t walxrepeat) fixed_t fix = (MirrorFlags & RF_XFLIP) ? walxrepeat-1 : 0; int x; - if (WallSX1 > 0) + if (WallC.SX1 > 0) { - for (x = WallSX1; x < WallSX2; x++) + for (x = WallC.SX1; x < WallC.SX2; x++) { if ((unsigned)lwall[x] >= (unsigned)walxrepeat) { @@ -2899,7 +2888,7 @@ static void PrepWallRoundFix(fixed_t *lwall, fixed_t walxrepeat) } } fix = walxrepeat - 1 - fix; - for (x = WallSX2-1; x >= WallSX1; x--) + for (x = WallC.SX2-1; x >= WallC.SX1; x--) { if ((unsigned)lwall[x] >= (unsigned)walxrepeat) { @@ -2917,11 +2906,11 @@ void PrepWall (fixed_t *swall, fixed_t *lwall, fixed_t walxrepeat) double top, bot, i; double xrepeat = fabs((double)walxrepeat); - i = WallSX1 - centerx; - top = WallUoverZorg + WallUoverZstep * i; - bot = WallInvZorg + WallInvZstep * i; + i = WallC.SX1 - centerx; + top = WallT.UoverZorg + WallT.UoverZstep * i; + bot = WallT.InvZorg + WallT.InvZstep * i; - for (int x = WallSX1; x < WallSX2; x++) + for (int x = WallC.SX1; x < WallC.SX2; x++) { double frac = top / bot; if (walxrepeat < 0) @@ -2932,9 +2921,9 @@ void PrepWall (fixed_t *swall, fixed_t *lwall, fixed_t walxrepeat) { lwall[x] = xs_RoundToInt(frac * xrepeat); } - swall[x] = xs_RoundToInt(frac * WallDepthScale + WallDepthOrg); - top += WallUoverZstep; - bot += WallInvZstep; + swall[x] = xs_RoundToInt(frac * WallT.DepthScale + WallT.DepthOrg); + top += WallT.UoverZstep; + bot += WallT.InvZstep; } PrepWallRoundFix(lwall, walxrepeat); } @@ -2945,14 +2934,14 @@ void PrepLWall (fixed_t *lwall, fixed_t walxrepeat) double xrepeat = fabs((double)walxrepeat); double topstep; - i = WallSX1 - centerx; - top = WallUoverZorg + WallUoverZstep * i; - bot = WallInvZorg + WallInvZstep * i; + i = WallC.SX1 - centerx; + top = WallT.UoverZorg + WallT.UoverZstep * i; + bot = WallT.InvZorg + WallT.InvZstep * i; top *= xrepeat; - topstep = WallUoverZstep * xrepeat; + topstep = WallT.UoverZstep * xrepeat; - for (int x = WallSX1; x < WallSX2; x++) + for (int x = WallC.SX1; x < WallC.SX2; x++) { if (walxrepeat < 0) { @@ -2963,7 +2952,7 @@ void PrepLWall (fixed_t *lwall, fixed_t walxrepeat) lwall[x] = xs_RoundToInt(top / bot); } top += topstep; - bot += WallInvZstep; + bot += WallT.InvZstep; } PrepWallRoundFix(lwall, walxrepeat); } @@ -3044,14 +3033,7 @@ static void R_RenderDecal (side_t *wall, DBaseDecal *decal, drawseg_t *clipper, // to a wall, we use the wall's angle instead of the decal's. This is // pretty much the same as what R_AddLine() does. - fixed_t savetx1, savetx2, savety1, savety2, savesz1, savesz2; - - savetx1 = WallTX1; - savetx2 = WallTX2; - savety1 = WallTY1; - savety2 = WallTY2; - savesz1 = WallSZ1; - savesz2 = WallSZ2; + FWallCoords savecoord = WallC; x2 = WallSpriteTile->GetWidth(); x1 = WallSpriteTile->LeftOffset; @@ -3068,76 +3050,76 @@ static void R_RenderDecal (side_t *wall, DBaseDecal *decal, drawseg_t *clipper, ly = decaly - FixedMul (x1, finesine[ang]) - viewy; ly2 = decaly + FixedMul (x2, finesine[ang]) - viewy; - WallTX1 = DMulScale20 (lx, viewsin, -ly, viewcos); - WallTX2 = DMulScale20 (lx2, viewsin, -ly2, viewcos); + WallC.TX1 = DMulScale20 (lx, viewsin, -ly, viewcos); + WallC.TX2 = DMulScale20 (lx2, viewsin, -ly2, viewcos); - WallTY1 = DMulScale20 (lx, viewtancos, ly, viewtansin); - WallTY2 = DMulScale20 (lx2, viewtancos, ly2, viewtansin); + WallC.TY1 = DMulScale20 (lx, viewtancos, ly, viewtansin); + WallC.TY2 = DMulScale20 (lx2, viewtancos, ly2, viewtansin); if (MirrorFlags & RF_XFLIP) { - int t = 256-WallTX1; - WallTX1 = 256-WallTX2; - WallTX2 = t; - swapvalues (WallTY1, WallTY2); + int t = 256-WallC.TX1; + WallC.TX1 = 256-WallC.TX2; + WallC.TX2 = t; + swapvalues (WallC.TY1, WallC.TY2); } - if (WallTX1 >= -WallTY1) + if (WallC.TX1 >= -WallC.TY1) { - if (WallTX1 > WallTY1) goto done; // left edge is off the right side - if (WallTY1 == 0) goto done; - x1 = (centerxfrac + Scale (WallTX1, centerxfrac, WallTY1)) >> FRACBITS; - if (WallTX1 >= 0) x1 = MIN (viewwidth, x1+1); // fix for signed divide - WallSZ1 = WallTY1; + if (WallC.TX1 > WallC.TY1) goto done; // left edge is off the right side + if (WallC.TY1 == 0) goto done; + x1 = (centerxfrac + Scale (WallC.TX1, centerxfrac, WallC.TY1)) >> FRACBITS; + if (WallC.TX1 >= 0) x1 = MIN (viewwidth, x1+1); // fix for signed divide + WallC.SZ1 = WallC.TY1; } else { - if (WallTX2 < -WallTY2) goto done; // wall is off the left side - fixed_t den = WallTX1 - WallTX2 - WallTY2 + WallTY1; + if (WallC.TX2 < -WallC.TY2) goto done; // wall is off the left side + fixed_t den = WallC.TX1 - WallC.TX2 - WallC.TY2 + WallC.TY1; if (den == 0) goto done; x1 = 0; - WallSZ1 = WallTY1 + Scale (WallTY2 - WallTY1, WallTX1 + WallTY1, den); + WallC.SZ1 = WallC.TY1 + Scale (WallC.TY2 - WallC.TY1, WallC.TX1 + WallC.TY1, den); } - if (WallSZ1 < TOO_CLOSE_Z) + if (WallC.SZ1 < TOO_CLOSE_Z) goto done; - if (WallTX2 <= WallTY2) + if (WallC.TX2 <= WallC.TY2) { - if (WallTX2 < -WallTY2) goto done; // right edge is off the left side - if (WallTY2 == 0) goto done; - x2 = (centerxfrac + Scale (WallTX2, centerxfrac, WallTY2)) >> FRACBITS; - if (WallTX2 >= 0) x2 = MIN (viewwidth, x2+1); // fix for signed divide - WallSZ2 = WallTY2; + if (WallC.TX2 < -WallC.TY2) goto done; // right edge is off the left side + if (WallC.TY2 == 0) goto done; + x2 = (centerxfrac + Scale (WallC.TX2, centerxfrac, WallC.TY2)) >> FRACBITS; + if (WallC.TX2 >= 0) x2 = MIN (viewwidth, x2+1); // fix for signed divide + WallC.SZ2 = WallC.TY2; } else { - if (WallTX1 > WallTY1) goto done; // wall is off the right side - fixed_t den = WallTY2 - WallTY1 - WallTX2 + WallTX1; + if (WallC.TX1 > WallC.TY1) goto done; // wall is off the right side + fixed_t den = WallC.TY2 - WallC.TY1 - WallC.TX2 + WallC.TX1; if (den == 0) goto done; x2 = viewwidth; - WallSZ2 = WallTY1 + Scale (WallTY2 - WallTY1, WallTX1 - WallTY1, den); + WallC.SZ2 = WallC.TY1 + Scale (WallC.TY2 - WallC.TY1, WallC.TX1 - WallC.TY1, den); } - if (x1 >= x2 || x1 > clipper->x2 || x2 <= clipper->x1 || WallSZ2 < TOO_CLOSE_Z) + if (x1 >= x2 || x1 > clipper->x2 || x2 <= clipper->x1 || WallC.SZ2 < TOO_CLOSE_Z) goto done; if (MirrorFlags & RF_XFLIP) { - WallUoverZorg = (float)WallTX2 * WallTMapScale; - WallUoverZstep = (float)(-WallTY2) * 32.f; - WallInvZorg = (float)(WallTX2 - WallTX1) * WallTMapScale; - WallInvZstep = (float)(WallTY1 - WallTY2) * 32.f; + WallT.UoverZorg = (float)WallC.TX2 * WallTMapScale; + WallT.UoverZstep = (float)(-WallC.TY2) * 32.f; + WallT.InvZorg = (float)(WallC.TX2 - WallC.TX1) * WallTMapScale; + WallT.InvZstep = (float)(WallC.TY1 - WallC.TY2) * 32.f; } else { - WallUoverZorg = (float)WallTX1 * WallTMapScale; - WallUoverZstep = (float)(-WallTY1) * 32.f; - WallInvZorg = (float)(WallTX1 - WallTX2) * WallTMapScale; - WallInvZstep = (float)(WallTY2 - WallTY1) * 32.f; + WallT.UoverZorg = (float)WallC.TX1 * WallTMapScale; + WallT.UoverZstep = (float)(-WallC.TY1) * 32.f; + WallT.InvZorg = (float)(WallC.TX1 - WallC.TX2) * WallTMapScale; + WallT.InvZstep = (float)(WallC.TY2 - WallC.TY1) * 32.f; } - WallDepthScale = WallInvZstep * WallTMapScale2; - WallDepthOrg = -WallUoverZstep * WallTMapScale2; + WallT.DepthScale = WallT.InvZstep * WallTMapScale2; + WallT.DepthOrg = -WallT.UoverZstep * WallTMapScale2; // Get the top and bottom clipping arrays switch (decal->RenderFlags & RF_CLIPMASK) @@ -3210,11 +3192,11 @@ static void R_RenderDecal (side_t *wall, DBaseDecal *decal, drawseg_t *clipper, goto done; } - swapvalues (x1, WallSX1); - swapvalues (x2, WallSX2); + swapvalues (x1, WallC.SX1); + swapvalues (x2, WallC.SX2); PrepWall (swall, lwall, WallSpriteTile->GetWidth() << FRACBITS); - swapvalues (x1, WallSX1); - swapvalues (x2, WallSX2); + swapvalues (x1, WallC.SX1); + swapvalues (x2, WallC.SX2); if (flipx) { @@ -3239,7 +3221,7 @@ static void R_RenderDecal (side_t *wall, DBaseDecal *decal, drawseg_t *clipper, rereadcolormap = false; } - rw_light = rw_lightleft + (x1 - WallSX1) * rw_lightstep; + rw_light = rw_lightleft + (x1 - WallC.SX1) * rw_lightstep; if (fixedlightlev >= 0) dc_colormap = usecolormap->Maps + fixedlightlev; else if (fixedcolormap != NULL) @@ -3346,12 +3328,7 @@ static void R_RenderDecal (side_t *wall, DBaseDecal *decal, drawseg_t *clipper, R_FinishSetPatchStyle (); done: - WallTX1 = savetx1; - WallTX2 = savetx2; - WallTY1 = savety1; - WallTY2 = savety2; - WallSZ1 = savesz1; - WallSZ2 = savesz2; + WallC = savecoord; } static void WallSpriteColumn (void (*drawfunc)(const BYTE *column, const FTexture::Span *spans)) From fc63e9db3ca384e8d6228d56739f7bc95646ffc8 Mon Sep 17 00:00:00 2001 From: Randy Heit Date: Thu, 31 Jul 2014 20:23:04 -0500 Subject: [PATCH 05/14] Pass WallC as a parameter to (O)WallMost instead of referencing it globally --- src/r_bsp.cpp | 11 ++-- src/r_segs.cpp | 136 ++++++++++++++++++++++++------------------------- src/r_segs.h | 3 ++ 3 files changed, 75 insertions(+), 75 deletions(-) diff --git a/src/r_bsp.cpp b/src/r_bsp.cpp index c1ddb2a3c..97938bf79 100644 --- a/src/r_bsp.cpp +++ b/src/r_bsp.cpp @@ -51,13 +51,12 @@ #include "doomstat.h" #include "r_state.h" #include "r_bsp.h" +#include "r_segs.h" #include "v_palette.h" #include "r_sky.h" #include "po_man.h" #include "r_data/colormaps.h" -int WallMost (short *mostbuf, const secplane_t &plane); - seg_t* curline; side_t* sidedef; line_t* linedef; @@ -693,12 +692,12 @@ void R_AddLine (seg_t *line) if (rw_frontcz1 > rw_backcz1 || rw_frontcz2 > rw_backcz2) { rw_havehigh = true; - WallMost (wallupper, backsector->ceilingplane); + WallMost (wallupper, backsector->ceilingplane, &WallC); } if (rw_frontfz1 < rw_backfz1 || rw_frontfz2 < rw_backfz2) { rw_havelow = true; - WallMost (walllower, backsector->floorplane); + WallMost (walllower, backsector->floorplane, &WallC); } // Closed door. @@ -800,8 +799,8 @@ void R_AddLine (seg_t *line) } else { - rw_ceilstat = WallMost (walltop, frontsector->ceilingplane); - rw_floorstat = WallMost (wallbottom, frontsector->floorplane); + rw_ceilstat = WallMost (walltop, frontsector->ceilingplane, &WallC); + rw_floorstat = WallMost (wallbottom, frontsector->floorplane, &WallC); // [RH] treat off-screen walls as solid #if 0 // Maybe later... diff --git a/src/r_segs.cpp b/src/r_segs.cpp index e1896b883..9567e0874 100644 --- a/src/r_segs.cpp +++ b/src/r_segs.cpp @@ -86,8 +86,6 @@ fixed_t rw_offset_top; fixed_t rw_offset_mid; fixed_t rw_offset_bottom; -int OWallMost (short *mostbuf, fixed_t z); -int WallMost (short *mostbuf, const secplane_t &plane); void PrepWall (fixed_t *swall, fixed_t *lwall, fixed_t walxrepeat); void PrepLWall (fixed_t *lwall, fixed_t walxrepeat); extern FWallCoords WallC; @@ -217,13 +215,13 @@ void ClipMidtex(int x1, int x2) { short most[MAXWIDTH]; - WallMost(most, curline->frontsector->ceilingplane); + WallMost(most, curline->frontsector->ceilingplane, &WallC); for (int i = x1; i <= x2; ++i) { if (wallupper[i] < most[i]) wallupper[i] = most[i]; } - WallMost(most, curline->frontsector->floorplane); + WallMost(most, curline->frontsector->floorplane, &WallC); for (int i = x1; i <= x2; ++i) { if (walllower[i] > most[i]) @@ -395,19 +393,19 @@ void R_RenderMaskedSegRange (drawseg_t *ds, int x1, int x2) if (fake3D & FAKE3D_CLIPTOP) { - OWallMost (wallupper, textop < sclipTop - viewz ? textop : sclipTop - viewz); + OWallMost(wallupper, textop < sclipTop - viewz ? textop : sclipTop - viewz, &WallC); } else { - OWallMost (wallupper, textop); + OWallMost(wallupper, textop, &WallC); } if (fake3D & FAKE3D_CLIPBOTTOM) { - OWallMost (walllower, textop - texheight > sclipBottom - viewz ? textop - texheight : sclipBottom - viewz); + OWallMost(walllower, textop - texheight > sclipBottom - viewz ? textop - texheight : sclipBottom - viewz, &WallC); } else { - OWallMost (walllower, textop - texheight); + OWallMost(walllower, textop - texheight, &WallC); } for (i = x1; i <= x2; i++) @@ -497,7 +495,7 @@ void R_RenderMaskedSegRange (drawseg_t *ds, int x1, int x2) if (fake3D & FAKE3D_CLIPTOP) { - OWallMost (wallupper, sclipTop - viewz); + OWallMost(wallupper, sclipTop - viewz, &WallC); for (i = x1; i <= x2; i++) { if (wallupper[i] < mceilingclip[i]) @@ -507,7 +505,7 @@ void R_RenderMaskedSegRange (drawseg_t *ds, int x1, int x2) } if (fake3D & FAKE3D_CLIPBOTTOM) { - OWallMost (walllower, sclipBottom - viewz); + OWallMost(walllower, sclipBottom - viewz, &WallC); for (i = x1; i <= x2; i++) { if (walllower[i] > mfloorclip[i]) @@ -609,8 +607,8 @@ void R_RenderFakeWall(drawseg_t *ds, int x1, int x2, F3DFloor *rover) WallC.TY2 = ds->cy + ds->cdy; WallT = ds->tmapvals; - OWallMost(wallupper, sclipTop - viewz); - OWallMost(walllower, sclipBottom - viewz); + OWallMost(wallupper, sclipTop - viewz, &WallC); + OWallMost(walllower, sclipBottom - viewz, &WallC); for (i = x1; i <= x2; i++) { @@ -1227,7 +1225,7 @@ void wallscan_striped (int x1, int x2, short *uwal, short *dwal, fixed_t *swal, // kg3D - fake floors instead of zdoom light list for (unsigned int i = 0; i < frontsector->e->XFloor.lightlist.Size(); i++) { - int j = WallMost (most3, frontsector->e->XFloor.lightlist[i].plane); + int j = WallMost (most3, frontsector->e->XFloor.lightlist[i].plane, &WallC); if (j != 3) { for (int j = x1; j <= x2; ++j) @@ -1309,7 +1307,7 @@ void wallscan_np2(int x1, int x2, short *uwal, short *dwal, fixed_t *swal, fixed dc_texturemid = FixedMul(partition - viewz, yrepeat) + texheight; while (partition > bot) { - int j = OWallMost(most3, partition - viewz); + int j = OWallMost(most3, partition - viewz, &WallC); if (j != 3) { for (int j = x1; j <= x2; ++j) @@ -1333,7 +1331,7 @@ void wallscan_np2(int x1, int x2, short *uwal, short *dwal, fixed_t *swal, fixed dc_texturemid = FixedMul(partition - viewz, yrepeat) + texheight; while (partition < top) { - int j = OWallMost(most3, partition - viewz); + int j = OWallMost(most3, partition - viewz, &WallC); if (j != 12) { for (int j = x1; j <= x2; ++j) @@ -2052,7 +2050,7 @@ void R_NewWall (bool needlights) // wall but nothing to draw for it. // Recalculate walltop so that the wall is clipped by the back sector's // ceiling instead of the front sector's ceiling. - WallMost (walltop, backsector->ceilingplane); + WallMost (walltop, backsector->ceilingplane, &WallC); } // Putting sky ceilings on the front and back of a line alters the way unpegged // positioning works. @@ -2596,65 +2594,65 @@ void R_StoreWallRange (int start, int stop) ds_p++; } -int OWallMost (short *mostbuf, fixed_t z) +int OWallMost (short *mostbuf, fixed_t z, const FWallCoords *wallc) { int bad, y, ix1, ix2, iy1, iy2; fixed_t s1, s2, s3, s4; z = -(z >> 4); - s1 = MulScale16 (globaluclip, WallC.SZ1); s2 = MulScale16 (globaluclip, WallC.SZ2); - s3 = MulScale16 (globaldclip, WallC.SZ1); s4 = MulScale16 (globaldclip, WallC.SZ2); + s1 = MulScale16 (globaluclip, wallc->SZ1); s2 = MulScale16 (globaluclip, wallc->SZ2); + s3 = MulScale16 (globaldclip, wallc->SZ1); s4 = MulScale16 (globaldclip, wallc->SZ2); bad = (zs3)<<2)+((z>s4)<<3); #if 1 if ((bad&3) == 3) { - memset (&mostbuf[WallC.SX1], 0, (WallC.SX2 - WallC.SX1)*sizeof(mostbuf[0])); + memset (&mostbuf[wallc->SX1], 0, (wallc->SX2 - wallc->SX1)*sizeof(mostbuf[0])); return bad; } if ((bad&12) == 12) { - clearbufshort (&mostbuf[WallC.SX1], WallC.SX2 - WallC.SX1, viewheight); + clearbufshort (&mostbuf[wallc->SX1], wallc->SX2 - wallc->SX1, viewheight); return bad; } #endif - ix1 = WallC.SX1; iy1 = WallC.SZ1; - ix2 = WallC.SX2; iy2 = WallC.SZ2; + ix1 = wallc->SX1; iy1 = wallc->SZ1; + ix2 = wallc->SX2; iy2 = wallc->SZ2; #if 1 if (bad & 3) { int t = DivScale30 (z-s1, s2-s1); - int inty = WallC.SZ1 + MulScale30 (WallC.SZ2 - WallC.SZ1, t); - int xcross = WallC.SX1 + Scale (MulScale30 (WallC.SZ2, t), WallC.SX2 - WallC.SX1, inty); + int inty = wallc->SZ1 + MulScale30 (wallc->SZ2 - wallc->SZ1, t); + int xcross = wallc->SX1 + Scale (MulScale30 (wallc->SZ2, t), wallc->SX2 - wallc->SX1, inty); if ((bad & 3) == 2) { - if (WallC.SX1 <= xcross) { iy2 = inty; ix2 = xcross; } - if (WallC.SX2 > xcross) memset (&mostbuf[xcross], 0, (WallC.SX2-xcross)*sizeof(mostbuf[0])); + if (wallc->SX1 <= xcross) { iy2 = inty; ix2 = xcross; } + if (wallc->SX2 > xcross) memset (&mostbuf[xcross], 0, (wallc->SX2-xcross)*sizeof(mostbuf[0])); } else { - if (xcross <= WallC.SX2) { iy1 = inty; ix1 = xcross; } - if (xcross > WallC.SX1) memset (&mostbuf[WallC.SX1], 0, (xcross-WallC.SX1)*sizeof(mostbuf[0])); + if (xcross <= wallc->SX2) { iy1 = inty; ix1 = xcross; } + if (xcross > wallc->SX1) memset (&mostbuf[wallc->SX1], 0, (xcross-wallc->SX1)*sizeof(mostbuf[0])); } } if (bad & 12) { int t = DivScale30 (z-s3, s4-s3); - int inty = WallC.SZ1 + MulScale30 (WallC.SZ2 - WallC.SZ1, t); - int xcross = WallC.SX1 + Scale (MulScale30 (WallC.SZ2, t), WallC.SX2 - WallC.SX1, inty); + int inty = wallc->SZ1 + MulScale30 (wallc->SZ2 - wallc->SZ1, t); + int xcross = wallc->SX1 + Scale (MulScale30 (wallc->SZ2, t), wallc->SX2 - wallc->SX1, inty); if ((bad & 12) == 8) { - if (WallC.SX1 <= xcross) { iy2 = inty; ix2 = xcross; } - if (WallC.SX2 > xcross) clearbufshort (&mostbuf[xcross], WallC.SX2 - xcross, viewheight); + if (wallc->SX1 <= xcross) { iy2 = inty; ix2 = xcross; } + if (wallc->SX2 > xcross) clearbufshort (&mostbuf[xcross], wallc->SX2 - xcross, viewheight); } else { - if (xcross <= WallC.SX2) { iy1 = inty; ix1 = xcross; } - if (xcross > WallC.SX1) clearbufshort (&mostbuf[WallC.SX1], xcross - WallC.SX1, viewheight); + if (xcross <= wallc->SX2) { iy1 = inty; ix1 = xcross; } + if (xcross > wallc->SX1) clearbufshort (&mostbuf[wallc->SX1], xcross - wallc->SX1, viewheight); } } @@ -2672,12 +2670,12 @@ int OWallMost (short *mostbuf, fixed_t z) double max = viewheight; double zz = z / 65536.0; #if 0 - double z1 = zz * InvZtoScale / WallC.SZ1; - double z2 = zz * InvZtoScale / WallC.SZ2 - z1; - z2 /= (WallC.SX2 - WallC.SX1); + double z1 = zz * InvZtoScale / wallc->SZ1; + double z2 = zz * InvZtoScale / wallc->SZ2 - z1; + z2 /= (wallc->SX2 - wallc->SX1); z1 += centeryfrac / 65536.0; - for (int x = WallC.SX1; x < WallC.SX2; ++x) + for (int x = wallc->SX1; x < wallc->SX2; ++x) { mostbuf[x] = xs_RoundToInt(clamp(z1, 0.0, max)); z1 += z2; @@ -2685,12 +2683,12 @@ int OWallMost (short *mostbuf, fixed_t z) #else double top, bot, i; - i = WallC.SX1 - centerx; + i = wallc->SX1 - centerx; top = WallT.UoverZorg + WallT.UoverZstep * i; bot = WallT.InvZorg + WallT.InvZstep * i; double cy = centeryfrac / 65536.0; - for (int x = WallC.SX1; x < WallC.SX2; x++) + for (int x = wallc->SX1; x < wallc->SX2; x++) { double frac = top / bot; double scale = frac * WallT.DepthScale + WallT.DepthOrg; @@ -2708,11 +2706,11 @@ int OWallMost (short *mostbuf, fixed_t z) return bad; } -int WallMost (short *mostbuf, const secplane_t &plane) +int WallMost (short *mostbuf, const secplane_t &plane, const FWallCoords *wallc) { if ((plane.a | plane.b) == 0) { - return OWallMost (mostbuf, ((plane.c < 0) ? plane.d : -plane.d) - viewz); + return OWallMost (mostbuf, ((plane.c < 0) ? plane.d : -plane.d) - viewz, wallc); } fixed_t x, y, den, z1, z2, oz1, oz2; @@ -2723,21 +2721,21 @@ int WallMost (short *mostbuf, const secplane_t &plane) { x = curline->v2->x; y = curline->v2->y; - if (WallC.SX1 == 0 && 0 != (den = WallC.TX1 - WallC.TX2 + WallC.TY1 - WallC.TY2)) + if (wallc->SX1 == 0 && 0 != (den = wallc->TX1 - wallc->TX2 + wallc->TY1 - wallc->TY2)) { - int frac = SafeDivScale30 (WallC.TY1 + WallC.TX1, den); + int frac = SafeDivScale30 (wallc->TY1 + wallc->TX1, den); x -= MulScale30 (frac, x - curline->v1->x); y -= MulScale30 (frac, y - curline->v1->y); } z1 = viewz - plane.ZatPoint (x, y); - if (WallC.SX2 > WallC.SX1 + 1) + if (wallc->SX2 > wallc->SX1 + 1) { x = curline->v1->x; y = curline->v1->y; - if (WallC.SX2 == viewwidth && 0 != (den = WallC.TX1 - WallC.TX2 - WallC.TY1 + WallC.TY2)) + if (wallc->SX2 == viewwidth && 0 != (den = wallc->TX1 - wallc->TX2 - wallc->TY1 + wallc->TY2)) { - int frac = SafeDivScale30 (WallC.TY2 - WallC.TX2, den); + int frac = SafeDivScale30 (wallc->TY2 - wallc->TX2, den); x += MulScale30 (frac, curline->v2->x - x); y += MulScale30 (frac, curline->v2->y - y); } @@ -2752,21 +2750,21 @@ int WallMost (short *mostbuf, const secplane_t &plane) { x = curline->v1->x; y = curline->v1->y; - if (WallC.SX1 == 0 && 0 != (den = WallC.TX1 - WallC.TX2 + WallC.TY1 - WallC.TY2)) + if (wallc->SX1 == 0 && 0 != (den = wallc->TX1 - wallc->TX2 + wallc->TY1 - wallc->TY2)) { - int frac = SafeDivScale30 (WallC.TY1 + WallC.TX1, den); + int frac = SafeDivScale30 (wallc->TY1 + wallc->TX1, den); x += MulScale30 (frac, curline->v2->x - x); y += MulScale30 (frac, curline->v2->y - y); } z1 = viewz - plane.ZatPoint (x, y); - if (WallC.SX2 > WallC.SX1 + 1) + if (wallc->SX2 > wallc->SX1 + 1) { x = curline->v2->x; y = curline->v2->y; - if (WallC.SX2 == viewwidth && 0 != (den = WallC.TX1 - WallC.TX2 - WallC.TY1 + WallC.TY2)) + if (wallc->SX2 == viewwidth && 0 != (den = wallc->TX1 - wallc->TX2 - wallc->TY1 + wallc->TY2)) { - int frac = SafeDivScale30 (WallC.TY2 - WallC.TX2, den); + int frac = SafeDivScale30 (wallc->TY2 - wallc->TX2, den); x -= MulScale30 (frac, x - curline->v1->x); y -= MulScale30 (frac, y - curline->v1->y); } @@ -2778,12 +2776,12 @@ int WallMost (short *mostbuf, const secplane_t &plane) } } - s1 = MulScale12 (globaluclip, WallC.SZ1); s2 = MulScale12 (globaluclip, WallC.SZ2); - s3 = MulScale12 (globaldclip, WallC.SZ1); s4 = MulScale12 (globaldclip, WallC.SZ2); + s1 = MulScale12 (globaluclip, wallc->SZ1); s2 = MulScale12 (globaluclip, wallc->SZ2); + s3 = MulScale12 (globaldclip, wallc->SZ1); s4 = MulScale12 (globaldclip, wallc->SZ2); bad = (z1s3)<<2)+((z2>s4)<<3); - ix1 = WallC.SX1; ix2 = WallC.SX2; - iy1 = WallC.SZ1; iy2 = WallC.SZ2; + ix1 = wallc->SX1; ix2 = wallc->SX2; + iy1 = wallc->SZ1; iy2 = wallc->SZ2; oz1 = z1; oz2 = z2; if ((bad&3) == 3) @@ -2803,9 +2801,9 @@ int WallMost (short *mostbuf, const secplane_t &plane) { //inty = intz / (globaluclip>>16) int t = SafeDivScale30 (oz1-s1, s2-s1+oz1-oz2); - int inty = WallC.SZ1 + MulScale30 (WallC.SZ2-WallC.SZ1,t); + int inty = wallc->SZ1 + MulScale30 (wallc->SZ2-wallc->SZ1,t); int intz = oz1 + MulScale30 (oz2-oz1,t); - int xcross = WallC.SX1 + Scale (MulScale30 (WallC.SZ2, t), WallC.SX2-WallC.SX1, inty); + int xcross = wallc->SX1 + Scale (MulScale30 (wallc->SZ2, t), wallc->SX2-wallc->SX1, inty); //t = divscale30((x1<<4)-xcross*yb1[w],xcross*(yb2[w]-yb1[w])-((x2-x1)<<4)); //inty = yb1[w] + mulscale30(yb2[w]-yb1[w],t); @@ -2813,13 +2811,13 @@ int WallMost (short *mostbuf, const secplane_t &plane) if ((bad&3) == 2) { - if (WallC.SX1 <= xcross) { z2 = intz; iy2 = inty; ix2 = xcross; } - memset (&mostbuf[xcross], 0, (WallC.SX2-xcross)*sizeof(mostbuf[0])); + if (wallc->SX1 <= xcross) { z2 = intz; iy2 = inty; ix2 = xcross; } + memset (&mostbuf[xcross], 0, (wallc->SX2-xcross)*sizeof(mostbuf[0])); } else { - if (xcross <= WallC.SX2) { z1 = intz; iy1 = inty; ix1 = xcross; } - memset (&mostbuf[WallC.SX1], 0, (xcross-WallC.SX1)*sizeof(mostbuf[0])); + if (xcross <= wallc->SX2) { z1 = intz; iy1 = inty; ix1 = xcross; } + memset (&mostbuf[wallc->SX1], 0, (xcross-wallc->SX1)*sizeof(mostbuf[0])); } } @@ -2827,9 +2825,9 @@ int WallMost (short *mostbuf, const secplane_t &plane) { //inty = intz / (globaldclip>>16) int t = SafeDivScale30 (oz1-s3, s4-s3+oz1-oz2); - int inty = WallC.SZ1 + MulScale30 (WallC.SZ2-WallC.SZ1,t); + int inty = wallc->SZ1 + MulScale30 (wallc->SZ2-wallc->SZ1,t); int intz = oz1 + MulScale30 (oz2-oz1,t); - int xcross = WallC.SX1 + Scale (MulScale30 (WallC.SZ2, t), WallC.SX2-WallC.SX1,inty); + int xcross = wallc->SX1 + Scale (MulScale30 (wallc->SZ2, t), wallc->SX2-wallc->SX1,inty); //t = divscale30((x1<<4)-xcross*yb1[w],xcross*(yb2[w]-yb1[w])-((x2-x1)<<4)); //inty = yb1[w] + mulscale30(yb2[w]-yb1[w],t); @@ -2837,13 +2835,13 @@ int WallMost (short *mostbuf, const secplane_t &plane) if ((bad&12) == 8) { - if (WallC.SX1 <= xcross) { z2 = intz; iy2 = inty; ix2 = xcross; } - if (WallC.SX2 > xcross) clearbufshort (&mostbuf[xcross], WallC.SX2-xcross, viewheight); + if (wallc->SX1 <= xcross) { z2 = intz; iy2 = inty; ix2 = xcross; } + if (wallc->SX2 > xcross) clearbufshort (&mostbuf[xcross], wallc->SX2-xcross, viewheight); } else { - if (xcross <= WallC.SX2) { z1 = intz; iy1 = inty; ix1 = xcross; } - if (xcross > WallC.SX1) clearbufshort (&mostbuf[WallC.SX1], xcross-WallC.SX1, viewheight); + if (xcross <= wallc->SX2) { z1 = intz; iy1 = inty; ix1 = xcross; } + if (xcross > wallc->SX1) clearbufshort (&mostbuf[wallc->SX1], xcross-wallc->SX1, viewheight); } } diff --git a/src/r_segs.h b/src/r_segs.h index d46a3a523..838b019a9 100644 --- a/src/r_segs.h +++ b/src/r_segs.h @@ -31,6 +31,9 @@ extern short *openings; extern ptrdiff_t lastopening; extern size_t maxopenings; +int OWallMost (short *mostbuf, fixed_t z, const FWallCoords *wallc); +int WallMost (short *mostbuf, const secplane_t &plane, const FWallCoords *wallc); + ptrdiff_t R_NewOpening (ptrdiff_t len); void R_CheckDrawSegs (); From b0b9c57e8525bdfb2a0cb8d5c152168c8b52ca96 Mon Sep 17 00:00:00 2001 From: Randy Heit Date: Thu, 31 Jul 2014 20:32:21 -0500 Subject: [PATCH 06/14] Pass x1 and x2 to Prep(L)Wall as params --- src/r_segs.cpp | 44 ++++++++++++++++++++------------------------ 1 file changed, 20 insertions(+), 24 deletions(-) diff --git a/src/r_segs.cpp b/src/r_segs.cpp index 9567e0874..b2a5d930f 100644 --- a/src/r_segs.cpp +++ b/src/r_segs.cpp @@ -86,8 +86,8 @@ fixed_t rw_offset_top; fixed_t rw_offset_mid; fixed_t rw_offset_bottom; -void PrepWall (fixed_t *swall, fixed_t *lwall, fixed_t walxrepeat); -void PrepLWall (fixed_t *lwall, fixed_t walxrepeat); +void PrepWall (fixed_t *swall, fixed_t *lwall, fixed_t walxrepeat, int x1, int x2); +void PrepLWall (fixed_t *lwall, fixed_t walxrepeat, int x1, int x2); extern FWallCoords WallC; extern FWallTmapVals WallT; @@ -621,7 +621,7 @@ void R_RenderFakeWall(drawseg_t *ds, int x1, int x2, F3DFloor *rover) walllower[i] = mfloorclip[i]; } - PrepLWall (lwall, curline->sidedef->TexelLength*xscale); + PrepLWall (lwall, curline->sidedef->TexelLength*xscale, ds->sx1, ds->sx2); wallscan_np2_ds(ds, x1, x2, wallupper, walllower, MaskedSWall, lwall, yscale); R_FinishSetPatchStyle(); } @@ -1831,7 +1831,7 @@ void R_RenderSegLoop () yscale = FixedMul(rw_pic->yScale, rw_midtexturescaley); if (xscale != lwallscale) { - PrepLWall (lwall, curline->sidedef->TexelLength*xscale); + PrepLWall (lwall, curline->sidedef->TexelLength*xscale, WallC.SX1, WallC.SX2); lwallscale = xscale; } if (midtexture->bWorldPanning) @@ -1874,7 +1874,7 @@ void R_RenderSegLoop () yscale = FixedMul(rw_pic->yScale, rw_toptexturescaley); if (xscale != lwallscale) { - PrepLWall (lwall, curline->sidedef->TexelLength*xscale); + PrepLWall (lwall, curline->sidedef->TexelLength*xscale, WallC.SX1, WallC.SX2); lwallscale = xscale; } if (toptexture->bWorldPanning) @@ -1920,7 +1920,7 @@ void R_RenderSegLoop () yscale = FixedMul(rw_pic->yScale, rw_bottomtexturescaley); if (xscale != lwallscale) { - PrepLWall (lwall, curline->sidedef->TexelLength*xscale); + PrepLWall (lwall, curline->sidedef->TexelLength*xscale, WallC.SX1, WallC.SX2); lwallscale = xscale; } if (bottomtexture->bWorldPanning) @@ -2265,7 +2265,7 @@ void R_NewWall (bool needlights) bottomtexture ? FixedMul(bottomtexture->xScale, sidedef->GetTextureXScale(side_t::bottom)) : FRACUNIT; - PrepWall (swall, lwall, sidedef->TexelLength * lwallscale); + PrepWall (swall, lwall, sidedef->TexelLength * lwallscale, WallC.SX1, WallC.SX2); if (fixedcolormap == NULL && fixedlightlev < 0) { @@ -2864,16 +2864,16 @@ int WallMost (short *mostbuf, const secplane_t &plane, const FWallCoords *wallc) return bad; } -static void PrepWallRoundFix(fixed_t *lwall, fixed_t walxrepeat) +static void PrepWallRoundFix(fixed_t *lwall, fixed_t walxrepeat, int x1, int x2) { // fix for rounding errors walxrepeat = abs(walxrepeat); fixed_t fix = (MirrorFlags & RF_XFLIP) ? walxrepeat-1 : 0; int x; - if (WallC.SX1 > 0) + if (x1 > 0) { - for (x = WallC.SX1; x < WallC.SX2; x++) + for (x = x1; x < x2; x++) { if ((unsigned)lwall[x] >= (unsigned)walxrepeat) { @@ -2886,7 +2886,7 @@ static void PrepWallRoundFix(fixed_t *lwall, fixed_t walxrepeat) } } fix = walxrepeat - 1 - fix; - for (x = WallC.SX2-1; x >= WallC.SX1; x--) + for (x = x2-1; x >= x1; x--) { if ((unsigned)lwall[x] >= (unsigned)walxrepeat) { @@ -2899,16 +2899,16 @@ static void PrepWallRoundFix(fixed_t *lwall, fixed_t walxrepeat) } } -void PrepWall (fixed_t *swall, fixed_t *lwall, fixed_t walxrepeat) +void PrepWall (fixed_t *swall, fixed_t *lwall, fixed_t walxrepeat, int x1, int x2) { // swall = scale, lwall = texturecolumn double top, bot, i; double xrepeat = fabs((double)walxrepeat); - i = WallC.SX1 - centerx; + i = x1 - centerx; top = WallT.UoverZorg + WallT.UoverZstep * i; bot = WallT.InvZorg + WallT.InvZstep * i; - for (int x = WallC.SX1; x < WallC.SX2; x++) + for (int x = x1; x < x2; x++) { double frac = top / bot; if (walxrepeat < 0) @@ -2923,23 +2923,23 @@ void PrepWall (fixed_t *swall, fixed_t *lwall, fixed_t walxrepeat) top += WallT.UoverZstep; bot += WallT.InvZstep; } - PrepWallRoundFix(lwall, walxrepeat); + PrepWallRoundFix(lwall, walxrepeat, x1, x2); } -void PrepLWall (fixed_t *lwall, fixed_t walxrepeat) +void PrepLWall (fixed_t *lwall, fixed_t walxrepeat, int x1, int x2) { // lwall = texturecolumn double top, bot, i; double xrepeat = fabs((double)walxrepeat); double topstep; - i = WallC.SX1 - centerx; + i = x1 - centerx; top = WallT.UoverZorg + WallT.UoverZstep * i; bot = WallT.InvZorg + WallT.InvZstep * i; top *= xrepeat; topstep = WallT.UoverZstep * xrepeat; - for (int x = WallC.SX1; x < WallC.SX2; x++) + for (int x = x1; x < x2; x++) { if (walxrepeat < 0) { @@ -2952,7 +2952,7 @@ void PrepLWall (fixed_t *lwall, fixed_t walxrepeat) top += topstep; bot += WallT.InvZstep; } - PrepWallRoundFix(lwall, walxrepeat); + PrepWallRoundFix(lwall, walxrepeat, x1, x2); } // pass = 0: when seg is first drawn @@ -3190,11 +3190,7 @@ static void R_RenderDecal (side_t *wall, DBaseDecal *decal, drawseg_t *clipper, goto done; } - swapvalues (x1, WallC.SX1); - swapvalues (x2, WallC.SX2); - PrepWall (swall, lwall, WallSpriteTile->GetWidth() << FRACBITS); - swapvalues (x1, WallC.SX1); - swapvalues (x2, WallC.SX2); + PrepWall (swall, lwall, WallSpriteTile->GetWidth() << FRACBITS, x1, x2); if (flipx) { From a600a816c3587db91a06b71ec3cbff6b40f4360c Mon Sep 17 00:00:00 2001 From: Randy Heit Date: Thu, 31 Jul 2014 21:02:22 -0500 Subject: [PATCH 07/14] Consolidate some common code for texture mapping setup - R_AddLine() and R_RenderDecal() had nearly identical code for setting up texture mapping. These have now been spun off into methods of FWallCoords and FWallTmapVals. --- src/r_bsp.cpp | 199 +++++++++++++++++++++++++++---------------------- src/r_bsp.h | 6 ++ src/r_segs.cpp | 70 ++--------------- 3 files changed, 122 insertions(+), 153 deletions(-) diff --git a/src/r_bsp.cpp b/src/r_bsp.cpp index 97938bf79..02a89f371 100644 --- a/src/r_bsp.cpp +++ b/src/r_bsp.cpp @@ -538,58 +538,7 @@ void R_AddLine (seg_t *line) if (DMulScale32 (ty1, tx1-tx2, tx1, ty2-ty1) >= 0) return; - WallC.TX1 = DMulScale20 (tx1, viewsin, -ty1, viewcos); - WallC.TX2 = DMulScale20 (tx2, viewsin, -ty2, viewcos); - - WallC.TY1 = DMulScale20 (tx1, viewtancos, ty1, viewtansin); - WallC.TY2 = DMulScale20 (tx2, viewtancos, ty2, viewtansin); - - if (MirrorFlags & RF_XFLIP) - { - int t = 256-WallC.TX1; - WallC.TX1 = 256-WallC.TX2; - WallC.TX2 = t; - swapvalues (WallC.TY1, WallC.TY2); - } - - if (WallC.TX1 >= -WallC.TY1) - { - if (WallC.TX1 > WallC.TY1) return; // left edge is off the right side - if (WallC.TY1 == 0) return; - WallC.SX1 = (centerxfrac + Scale (WallC.TX1, centerxfrac, WallC.TY1)) >> FRACBITS; - if (WallC.TX1 >= 0) WallC.SX1 = MIN (viewwidth, WallC.SX1+1); // fix for signed divide - WallC.SZ1 = WallC.TY1; - } - else - { - if (WallC.TX2 < -WallC.TY2) return; // wall is off the left side - fixed_t den = WallC.TX1 - WallC.TX2 - WallC.TY2 + WallC.TY1; - if (den == 0) return; - WallC.SX1 = 0; - WallC.SZ1 = WallC.TY1 + Scale (WallC.TY2 - WallC.TY1, WallC.TX1 + WallC.TY1, den); - } - - if (WallC.SZ1 < 32) - return; - - if (WallC.TX2 <= WallC.TY2) - { - if (WallC.TX2 < -WallC.TY2) return; // right edge is off the left side - if (WallC.TY2 == 0) return; - WallC.SX2 = (centerxfrac + Scale (WallC.TX2, centerxfrac, WallC.TY2)) >> FRACBITS; - if (WallC.TX2 >= 0) WallC.SX2 = MIN (viewwidth, WallC.SX2+1); // fix for signed divide - WallC.SZ2 = WallC.TY2; - } - else - { - if (WallC.TX1 > WallC.TY1) return; // wall is off the right side - fixed_t den = WallC.TY2 - WallC.TY1 - WallC.TX2 + WallC.TX1; - if (den == 0) return; - WallC.SX2 = viewwidth; - WallC.SZ2 = WallC.TY1 + Scale (WallC.TY2 - WallC.TY1, WallC.TX1 - WallC.TY1, den); - } - - if (WallC.SZ2 < 32 || WallC.SX2 <= WallC.SX1) + if (WallC.Init(tx1, ty1, tx2, ty2, 32)) return; if (WallC.SX1 > WindowRight || WallC.SX2 < WindowLeft) @@ -611,20 +560,7 @@ void R_AddLine (seg_t *line) if ((v1 == line->v1 && v2 == line->v2) || (v2 == line->v1 && v1 == line->v2)) { // The seg is the entire wall. - if (MirrorFlags & RF_XFLIP) - { - WallT.UoverZorg = (float)WallC.TX2 * WallTMapScale; - WallT.UoverZstep = (float)(-WallC.TY2) * 32.f; - WallT.InvZorg = (float)(WallC.TX2 - WallC.TX1) * WallTMapScale; - WallT.InvZstep = (float)(WallC.TY1 - WallC.TY2) * 32.f; - } - else - { - WallT.UoverZorg = (float)WallC.TX1 * WallTMapScale; - WallT.UoverZstep = (float)(-WallC.TY1) * 32.f; - WallT.InvZorg = (float)(WallC.TX1 - WallC.TX2) * WallTMapScale; - WallT.InvZstep = (float)(WallC.TY2 - WallC.TY1) * 32.f; - } + WallT.InitFromWallCoords(&WallC); } else { // The seg is only part of the wall. @@ -632,29 +568,8 @@ void R_AddLine (seg_t *line) { 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; - } - - WallT.UoverZorg = (float)fullx1 * WallTMapScale; - WallT.UoverZstep = (float)(-fully1) * 32.f; - WallT.InvZorg = (float)(fullx1 - fullx2) * WallTMapScale; - WallT.InvZstep = (float)(fully2 - fully1) * 32.f; + WallT.InitFromLine(v1->x - viewx, v1->y - viewy, v2->x - viewx, v2->y - viewy); } - WallT.DepthScale = WallT.InvZstep * WallTMapScale2; - WallT.DepthOrg = -WallT.UoverZstep * WallTMapScale2; if (!(fake3D & FAKE3D_FAKEBACK)) { @@ -826,6 +741,114 @@ void R_AddLine (seg_t *line) } } +// +// FWallCoords :: Init +// +// Transform and clip coordinates. Returns true if it was clipped away +// +bool FWallCoords::Init(int x1, int y1, int x2, int y2, int too_close) +{ + TX1 = DMulScale20(x1, viewsin, -y1, viewcos); + TX2 = DMulScale20(x2, viewsin, -y2, viewcos); + + TY1 = DMulScale20(x1, viewtancos, y1, viewtansin); + TY2 = DMulScale20(x2, viewtancos, y2, viewtansin); + + if (MirrorFlags & RF_XFLIP) + { + int t = 256 - TX1; + TX1 = 256 - TX2; + TX2 = t; + swapvalues(TY1, TY2); + } + + if (TX1 >= -TY1) + { + if (TX1 > TY1) return true; // left edge is off the right side + if (TY1 == 0) return true; + SX1 = (centerxfrac + Scale(TX1, centerxfrac, TY1)) >> FRACBITS; + if (TX1 >= 0) SX1 = MIN(viewwidth, SX1+1); // fix for signed divide + SZ1 = TY1; + } + else + { + if (TX2 < -TY2) return true; // wall is off the left side + fixed_t den = TX1 - TX2 - TY2 + TY1; + if (den == 0) return true; + SX1 = 0; + SZ1 = TY1 + Scale(TY2 - TY1, TX1 + TY1, den); + } + + if (SZ1 < too_close) + return true; + + if (TX2 <= TY2) + { + if (TX2 < -TY2) return true; // right edge is off the left side + if (TY2 == 0) return true; + SX2 = (centerxfrac + Scale(TX2, centerxfrac, TY2)) >> FRACBITS; + if (TX2 >= 0) SX2 = MIN(viewwidth, SX2+1); // fix for signed divide + SZ2 = TY2; + } + else + { + if (TX1 > TY1) return true; // wall is off the right side + fixed_t den = TY2 - TY1 - TX2 + TX1; + if (den == 0) return true; + SX2 = viewwidth; + SZ2 = TY1 + Scale(TY2 - TY1, TX1 - TY1, den); + } + + if (SZ2 < too_close || SX2 <= SX1) + return true; + + return false; +} + +void FWallTmapVals::InitFromWallCoords(const FWallCoords *wallc) +{ + if (MirrorFlags & RF_XFLIP) + { + UoverZorg = (float)wallc->TX2 * WallTMapScale; + UoverZstep = (float)(-wallc->TY2) * 32.f; + InvZorg = (float)(wallc->TX2 - wallc->TX1) * WallTMapScale; + InvZstep = (float)(wallc->TY1 - wallc->TY2) * 32.f; + } + else + { + UoverZorg = (float)wallc->TX1 * WallTMapScale; + UoverZstep = (float)(-wallc->TY1) * 32.f; + InvZorg = (float)(wallc->TX1 - wallc->TX2) * WallTMapScale; + InvZstep = (float)(wallc->TY2 - wallc->TY1) * 32.f; + } + InitDepth(); +} + +void FWallTmapVals::InitFromLine(int tx1, int ty1, int tx2, int ty2) +{ // Coordinates should have already had viewx,viewy subtracted + 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; + } + + UoverZorg = (float)fullx1 * WallTMapScale; + UoverZstep = (float)(-fully1) * 32.f; + InvZorg = (float)(fullx1 - fullx2) * WallTMapScale; + InvZstep = (float)(fully2 - fully1) * 32.f; + InitDepth(); +} + +void FWallTmapVals::InitDepth() +{ + DepthScale = InvZstep * WallTMapScale2; + DepthOrg = -UoverZstep * WallTMapScale2; +} // // R_CheckBBox diff --git a/src/r_bsp.h b/src/r_bsp.h index d2fcb67e1..53a0b2b0b 100644 --- a/src/r_bsp.h +++ b/src/r_bsp.h @@ -36,6 +36,8 @@ struct FWallCoords int SX1, SX2; // x coords at left, right of wall in screen space fixed_t SZ1, SZ2; // depth at left, right of wall in screen space + + bool Init(int x1, int y1, int x2, int y2, int too_close); }; struct FWallTmapVals @@ -43,6 +45,10 @@ struct FWallTmapVals float DepthOrg, DepthScale; float UoverZorg, UoverZstep; float InvZorg, InvZstep; + + void InitFromWallCoords(const FWallCoords *wallc); + void InitFromLine(int x1, int y1, int x2, int y2); + void InitDepth(); }; enum diff --git a/src/r_segs.cpp b/src/r_segs.cpp index b2a5d930f..f985a732d 100644 --- a/src/r_segs.cpp +++ b/src/r_segs.cpp @@ -3048,76 +3048,16 @@ static void R_RenderDecal (side_t *wall, DBaseDecal *decal, drawseg_t *clipper, ly = decaly - FixedMul (x1, finesine[ang]) - viewy; ly2 = decaly + FixedMul (x2, finesine[ang]) - viewy; - WallC.TX1 = DMulScale20 (lx, viewsin, -ly, viewcos); - WallC.TX2 = DMulScale20 (lx2, viewsin, -ly2, viewcos); - - WallC.TY1 = DMulScale20 (lx, viewtancos, ly, viewtansin); - WallC.TY2 = DMulScale20 (lx2, viewtancos, ly2, viewtansin); - - if (MirrorFlags & RF_XFLIP) - { - int t = 256-WallC.TX1; - WallC.TX1 = 256-WallC.TX2; - WallC.TX2 = t; - swapvalues (WallC.TY1, WallC.TY2); - } - - if (WallC.TX1 >= -WallC.TY1) - { - if (WallC.TX1 > WallC.TY1) goto done; // left edge is off the right side - if (WallC.TY1 == 0) goto done; - x1 = (centerxfrac + Scale (WallC.TX1, centerxfrac, WallC.TY1)) >> FRACBITS; - if (WallC.TX1 >= 0) x1 = MIN (viewwidth, x1+1); // fix for signed divide - WallC.SZ1 = WallC.TY1; - } - else - { - if (WallC.TX2 < -WallC.TY2) goto done; // wall is off the left side - fixed_t den = WallC.TX1 - WallC.TX2 - WallC.TY2 + WallC.TY1; - if (den == 0) goto done; - x1 = 0; - WallC.SZ1 = WallC.TY1 + Scale (WallC.TY2 - WallC.TY1, WallC.TX1 + WallC.TY1, den); - } - - if (WallC.SZ1 < TOO_CLOSE_Z) + if (WallC.Init(lx, ly, lx2, ly2, TOO_CLOSE_Z)) goto done; - if (WallC.TX2 <= WallC.TY2) - { - if (WallC.TX2 < -WallC.TY2) goto done; // right edge is off the left side - if (WallC.TY2 == 0) goto done; - x2 = (centerxfrac + Scale (WallC.TX2, centerxfrac, WallC.TY2)) >> FRACBITS; - if (WallC.TX2 >= 0) x2 = MIN (viewwidth, x2+1); // fix for signed divide - WallC.SZ2 = WallC.TY2; - } - else - { - if (WallC.TX1 > WallC.TY1) goto done; // wall is off the right side - fixed_t den = WallC.TY2 - WallC.TY1 - WallC.TX2 + WallC.TX1; - if (den == 0) goto done; - x2 = viewwidth; - WallC.SZ2 = WallC.TY1 + Scale (WallC.TY2 - WallC.TY1, WallC.TX1 - WallC.TY1, den); - } + x1 = WallC.SX1; + x2 = WallC.SX2; - if (x1 >= x2 || x1 > clipper->x2 || x2 <= clipper->x1 || WallC.SZ2 < TOO_CLOSE_Z) + if (x1 > clipper->x2 || x2 <= clipper->x1) goto done; - if (MirrorFlags & RF_XFLIP) - { - WallT.UoverZorg = (float)WallC.TX2 * WallTMapScale; - WallT.UoverZstep = (float)(-WallC.TY2) * 32.f; - WallT.InvZorg = (float)(WallC.TX2 - WallC.TX1) * WallTMapScale; - WallT.InvZstep = (float)(WallC.TY1 - WallC.TY2) * 32.f; - } - else - { - WallT.UoverZorg = (float)WallC.TX1 * WallTMapScale; - WallT.UoverZstep = (float)(-WallC.TY1) * 32.f; - WallT.InvZorg = (float)(WallC.TX1 - WallC.TX2) * WallTMapScale; - WallT.InvZstep = (float)(WallC.TY2 - WallC.TY1) * 32.f; - } - WallT.DepthScale = WallT.InvZstep * WallTMapScale2; - WallT.DepthOrg = -WallT.UoverZstep * WallTMapScale2; + WallT.InitFromWallCoords(&WallC); // Get the top and bottom clipping arrays switch (decal->RenderFlags & RF_CLIPMASK) From 15251e7a2167ab4e8ff54f6a9a9910ccf3140f7a Mon Sep 17 00:00:00 2001 From: Randy Heit Date: Thu, 31 Jul 2014 22:18:08 -0500 Subject: [PATCH 08/14] Set face/wall/floor flags from Build sprites --- src/p_buildmap.cpp | 21 ++++++++++----------- 1 file changed, 10 insertions(+), 11 deletions(-) diff --git a/src/p_buildmap.cpp b/src/p_buildmap.cpp index 54bf92527..32651b5bb 100644 --- a/src/p_buildmap.cpp +++ b/src/p_buildmap.cpp @@ -732,11 +732,10 @@ static int LoadSprites (spritetype *sprites, Xsprite *xsprites, int numsprites, if (sprites[i].xrepeat == 0 || sprites[i].yrepeat == 0) continue; mapthings[count].type = 9988; - mapthings[count].args[0] = sprites[i].picnum & 255; - mapthings[count].args[1] = sprites[i].picnum >> 8; + mapthings[count].args[0] = sprites[i].picnum; mapthings[count].args[2] = sprites[i].xrepeat; mapthings[count].args[3] = sprites[i].yrepeat; - mapthings[count].args[4] = (sprites[i].cstat & 14) | ((sprites[i].cstat >> 9) & 1); + mapthings[count].args[4] = sprites[i].cstat; } count++; } @@ -874,22 +873,22 @@ void ACustomSprite::BeginPlay () char name[9]; Super::BeginPlay (); - mysnprintf (name, countof(name), "BTIL%04d", (args[0] + args[1]*256) & 0xffff); + mysnprintf (name, countof(name), "BTIL%04d", args[0] & 0xffff); picnum = TexMan.GetTexture (name, FTexture::TEX_Build); scaleX = args[2] * (FRACUNIT/64); scaleY = args[3] * (FRACUNIT/64); - if (args[4] & 2) + int cstat = args[4]; + if (cstat & 2) { RenderStyle = STYLE_Translucent; - if (args[4] & 1) - alpha = TRANSLUC66; - else - alpha = TRANSLUC33; + alpha = (cstat & 512) ? TRANSLUC66 : TRANSLUC33; } - if (args[4] & 4) + if (cstat & 4) renderflags |= RF_XFLIP; - if (args[4] & 8) + if (cstat & 8) renderflags |= RF_YFLIP; + // set face/wall/floor flags + renderflags |= ((cstat >> 4) & 3) << 12; } From 9716a61219d7cd26225ccbf18605bd2766a29632 Mon Sep 17 00:00:00 2001 From: Edward Richardson Date: Sat, 2 Aug 2014 19:32:38 +1200 Subject: [PATCH 09/14] Add CVar for drawing weapons in the althud --- src/g_shared/shared_hud.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/g_shared/shared_hud.cpp b/src/g_shared/shared_hud.cpp index 964a28e2b..3806e5f9d 100644 --- a/src/g_shared/shared_hud.cpp +++ b/src/g_shared/shared_hud.cpp @@ -70,6 +70,7 @@ CVAR (Bool, hud_showmonsters, true,CVAR_ARCHIVE); // Show monster stats on HUD CVAR (Bool, hud_showitems, false,CVAR_ARCHIVE); // Show item stats on HUD CVAR (Bool, hud_showstats, false, CVAR_ARCHIVE); // for stamina and accuracy. CVAR (Bool, hud_showscore, false, CVAR_ARCHIVE); // for user maintained score +CVAR (Bool, hud_showweapons, true, CVAR_ARCHIVE); // Show weapons collected CVAR (Int , hud_showtime, 0, CVAR_ARCHIVE); // Show time on HUD CVAR (Int , hud_timecolor, CR_GOLD,CVAR_ARCHIVE); // Color of in-game time on HUD @@ -972,7 +973,7 @@ void DrawHUD() CPlayer->mo->FindInventory(), 5, hudheight-20); i=DrawKeys(CPlayer, hudwidth-4, hudheight-10); i=DrawAmmo(CPlayer, hudwidth-5, i); - DrawWeapons(CPlayer, hudwidth-5, i); + if (hud_showweapons) DrawWeapons(CPlayer, hudwidth - 5, i); DrawInventory(CPlayer, 144, hudheight-28); if (CPlayer->camera && CPlayer->camera->player) { From 6ef67e1d3e078c193245e3d9bc96e1931704d4f6 Mon Sep 17 00:00:00 2001 From: "alexey.lysiuk" Date: Sat, 2 Aug 2014 13:14:25 +0300 Subject: [PATCH 10/14] Fixed build on compilers other than MSVC No more "Call to 'LittleShort' is ambiguous" error --- src/p_acs.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/p_acs.cpp b/src/p_acs.cpp index 16e511b23..2ca6fe909 100644 --- a/src/p_acs.cpp +++ b/src/p_acs.cpp @@ -1677,7 +1677,7 @@ void FBehavior::SerializeVarSet (FArchive &arc, SDWORD *vars, int max) static int ParseLocalArrayChunk(void *chunk, ACSLocalArrays *arrays, int offset) { - unsigned count = (LittleShort(((unsigned *)chunk)[1]) - 2) / 4; + unsigned count = (LittleShort(static_cast(((unsigned *)chunk)[1]) - 2)) / 4; int *sizes = (int *)((BYTE *)chunk + 10); arrays->Count = count; if (count > 0) From a1b579e5fccd16b7aaf73d0bb0c8c4018fc11830 Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Sun, 3 Aug 2014 01:20:12 +0200 Subject: [PATCH 11/14] - added menu entry for newly added hud_showweapons CVAR. --- wadsrc/static/menudef.txt | 1 + 1 file changed, 1 insertion(+) diff --git a/wadsrc/static/menudef.txt b/wadsrc/static/menudef.txt index 7099e6cc7..324c94e6b 100644 --- a/wadsrc/static/menudef.txt +++ b/wadsrc/static/menudef.txt @@ -816,6 +816,7 @@ OptionMenu "AltHUDOptions" Option "Show item count", "hud_showitems", "OnOff" Option "Show stamina and accuracy", "hud_showstats", "OnOff" Option "Show berserk", "hud_berserk_health", "OnOff" + Option "Show weapons", "hud_showweapons", "OnOff" Option "Show time", "hud_showtime", "AltHUDTime" Option "Time color", "hud_timecolor", "TextColors" Slider "Red ammo display below %", "hud_ammo_red", 0, 100, 1, 0 From d0043bed78082c7faf749236c9939d90a081b25e Mon Sep 17 00:00:00 2001 From: Randy Heit Date: Sat, 2 Aug 2014 22:35:57 -0500 Subject: [PATCH 12/14] Q&D port of decal code to draw generic wall sprites - This still doesn't use all the sprite properties correctly. It also looks like they're going to need different code to build the clipping arrays. But at least wall sprites are drawn at the proper angle now! --- src/r_bsp.h | 8 ++ src/r_segs.cpp | 36 +------ src/r_segs.h | 9 ++ src/r_things.cpp | 252 +++++++++++++++++++++++++++++++++++++++++++++-- src/r_things.h | 21 +++- 5 files changed, 279 insertions(+), 47 deletions(-) diff --git a/src/r_bsp.h b/src/r_bsp.h index 53a0b2b0b..d15beca0c 100644 --- a/src/r_bsp.h +++ b/src/r_bsp.h @@ -26,6 +26,11 @@ #include "tarray.h" #include +// The 3072 below is just an arbitrary value picked to avoid +// drawing lines the player is too close to that would overflow +// the texture calculations. +#define TOO_CLOSE_Z 3072 + struct FWallCoords { fixed_t TX1, TX2; // x coords at left, right of wall in view space @@ -51,6 +56,9 @@ struct FWallTmapVals void InitDepth(); }; +extern FWallCoords WallC; +extern FWallTmapVals WallT; + enum { FAKED_Center, diff --git a/src/r_segs.cpp b/src/r_segs.cpp index f985a732d..25395a596 100644 --- a/src/r_segs.cpp +++ b/src/r_segs.cpp @@ -64,11 +64,6 @@ CVAR(Bool, r_np2, true, 0) #define HEIGHTBITS 12 #define HEIGHTSHIFT (FRACBITS-HEIGHTBITS) -// The 3072 below is just an arbitrary value picked to avoid -// drawing lines the player is too close to that would overflow -// the texture calculations. -#define TOO_CLOSE_Z 3072 - extern fixed_t globaluclip, globaldclip; @@ -86,10 +81,6 @@ fixed_t rw_offset_top; fixed_t rw_offset_mid; fixed_t rw_offset_bottom; -void PrepWall (fixed_t *swall, fixed_t *lwall, fixed_t walxrepeat, int x1, int x2); -void PrepLWall (fixed_t *lwall, fixed_t walxrepeat, int x1, int x2); -extern FWallCoords WallC; -extern FWallTmapVals WallT; int wallshade; @@ -139,7 +130,6 @@ static fixed_t rw_bottomtexturescaley; FTexture *rw_pic; static fixed_t *maskedtexturecol; -static FTexture *WallSpriteTile; static void R_RenderDecal (side_t *wall, DBaseDecal *first, drawseg_t *clipper, int pass); static void WallSpriteColumn (void (*drawfunc)(const BYTE *column, const FTexture::Span *spans)); @@ -3216,8 +3206,7 @@ static void R_RenderDecal (side_t *wall, DBaseDecal *decal, drawseg_t *clipper, { // calculate lighting dc_colormap = usecolormap->Maps + (GETPALOOKUP (rw_light, wallshade) << COLORMAPSHIFT); } - - WallSpriteColumn (R_DrawMaskedColumn); + R_WallSpriteColumn (R_DrawMaskedColumn); dc_x++; } @@ -3230,7 +3219,7 @@ static void R_RenderDecal (side_t *wall, DBaseDecal *decal, drawseg_t *clipper, rt_initcols(); for (int zz = 4; zz; --zz) { - WallSpriteColumn (R_DrawMaskedColumnHoriz); + R_WallSpriteColumn (R_DrawMaskedColumnHoriz); dc_x++; } rt_draw4cols (dc_x - 4); @@ -3242,8 +3231,7 @@ static void R_RenderDecal (side_t *wall, DBaseDecal *decal, drawseg_t *clipper, { // calculate lighting dc_colormap = usecolormap->Maps + (GETPALOOKUP (rw_light, wallshade) << COLORMAPSHIFT); } - - WallSpriteColumn (R_DrawMaskedColumn); + R_WallSpriteColumn (R_DrawMaskedColumn); dc_x++; } } @@ -3264,21 +3252,3 @@ static void R_RenderDecal (side_t *wall, DBaseDecal *decal, drawseg_t *clipper, done: WallC = savecoord; } - -static void WallSpriteColumn (void (*drawfunc)(const BYTE *column, const FTexture::Span *spans)) -{ - unsigned int texturecolumn = lwall[dc_x] >> FRACBITS; - dc_iscale = MulScale16 (swall[dc_x], rw_offset); - spryscale = SafeDivScale32 (1, dc_iscale); - if (sprflipvert) - sprtopscreen = centeryfrac + FixedMul (dc_texturemid, spryscale); - else - sprtopscreen = centeryfrac - FixedMul (dc_texturemid, spryscale); - - const BYTE *column; - const FTexture::Span *spans; - column = WallSpriteTile->GetColumn (texturecolumn, &spans); - dc_texturefrac = 0; - drawfunc (column, spans); - rw_light += rw_lightstep; -} diff --git a/src/r_segs.h b/src/r_segs.h index 838b019a9..b8bf96511 100644 --- a/src/r_segs.h +++ b/src/r_segs.h @@ -33,6 +33,8 @@ extern size_t maxopenings; int OWallMost (short *mostbuf, fixed_t z, const FWallCoords *wallc); int WallMost (short *mostbuf, const secplane_t &plane, const FWallCoords *wallc); +void PrepWall (fixed_t *swall, fixed_t *lwall, fixed_t walxrepeat, int x1, int x2); +void PrepLWall (fixed_t *lwall, fixed_t walxrepeat, int x1, int x2); ptrdiff_t R_NewOpening (ptrdiff_t len); @@ -40,4 +42,11 @@ void R_CheckDrawSegs (); void R_RenderSegLoop (); +extern fixed_t swall[MAXWIDTH]; +extern fixed_t lwall[MAXWIDTH]; +extern fixed_t rw_light; // [RH] Scale lights with viewsize adjustments +extern fixed_t rw_lightstep; +extern fixed_t rw_lightleft; +extern fixed_t rw_offset; + #endif diff --git a/src/r_things.cpp b/src/r_things.cpp index 7243ac6f9..1d2c07a2a 100644 --- a/src/r_things.cpp +++ b/src/r_things.cpp @@ -114,6 +114,8 @@ FDynamicColormap *VisPSpritesBaseColormap[NUMPSPRITES]; static int spriteshade; +FTexture *WallSpriteTile; + // constant arrays // used for psprite clipping and initializing clipping short zeroarray[MAXWIDTH]; @@ -145,6 +147,8 @@ static vissprite_t **spritesorter; static int spritesortersize = 0; static int vsprcount; +static void R_ProjectWallSprite(AActor *thing, fixed_t fx, fixed_t fy, fixed_t fz, FTextureID picnum, fixed_t xscale, fixed_t yscale, INTBOOL flip); + void R_DeinitSprites() { @@ -401,6 +405,151 @@ void R_DrawVisSprite (vissprite_t *vis) NetUpdate (); } +void R_DrawWallSprite(vissprite_t *spr) +{ + int x1, x2; + fixed_t yscale; + int shade = LIGHT2SHADE(140); + + x1 = MAX(spr->x1, spr->wallc.SX1); + x2 = MIN(spr->x2, spr->wallc.SX2 + 1); + if (x1 >= x2) + return; + WallT.InitFromWallCoords(&spr->wallc); + PrepWall(swall, lwall, spr->pic->GetWidth() << FRACBITS, x1, x2); + dc_texturemid = spr->gzt - viewz; + yscale = FRACUNIT; + if (spr->renderflags & RF_XFLIP) + { + int right = (spr->pic->GetWidth() << FRACBITS) - 1; + + for (int i = x1; i < x2; i++) + { + lwall[i] = right - lwall[i]; + } + } + // Prepare lighting + bool calclighting = false; + FDynamicColormap *usecolormap = basecolormap; + bool rereadcolormap = true; + + // Decals that are added to the scene must fade to black. + if (spr->Style.RenderStyle == LegacyRenderStyles[STYLE_Add] && usecolormap->Fade != 0) + { + usecolormap = GetSpecialLights(usecolormap->Color, 0, usecolormap->Desaturate); + rereadcolormap = false; + } + + rw_light = rw_lightleft + (x1 - spr->wallc.SX1) * rw_lightstep; + if (fixedlightlev >= 0) + dc_colormap = usecolormap->Maps + fixedlightlev; + else if (fixedcolormap != NULL) + dc_colormap = fixedcolormap; + else if (!foggy && (spr->renderflags & RF_FULLBRIGHT)) + dc_colormap = usecolormap->Maps; + else + calclighting = true; + + // Draw it + WallSpriteTile = spr->pic; + if (spr->renderflags & RF_YFLIP) + { + sprflipvert = true; + yscale = -yscale; + dc_texturemid = dc_texturemid - (spr->pic->GetHeight() << FRACBITS); + } + else + { + sprflipvert = false; + } + + // rw_offset is used as the texture's vertical scale + rw_offset = SafeDivScale30(1, yscale); + + dc_x = x1; + ESPSResult mode; + + mode = R_SetPatchStyle (spr->Style.RenderStyle, spr->Style.alpha, spr->Translation, spr->FillColor); + + // R_SetPatchStyle can modify basecolormap. + if (rereadcolormap) + { + usecolormap = basecolormap; + } + + if (mode == DontDraw) + { + return; + } + else + { + int stop4; + + if (mode == DoDraw0) + { // 1 column at a time + stop4 = dc_x; + } + else // DoDraw1 + { // up to 4 columns at a time + stop4 = x2 & ~3; + } + + while ((dc_x < stop4) && (dc_x & 3)) + { + if (calclighting) + { // calculate lighting + dc_colormap = usecolormap->Maps + (GETPALOOKUP (rw_light, shade) << COLORMAPSHIFT); + } + R_WallSpriteColumn(R_DrawMaskedColumn); + dc_x++; + } + + while (dc_x < stop4) + { + if (calclighting) + { // calculate lighting + dc_colormap = usecolormap->Maps + (GETPALOOKUP (rw_light, shade) << COLORMAPSHIFT); + } + rt_initcols(); + for (int zz = 4; zz; --zz) + { + R_WallSpriteColumn(R_DrawMaskedColumnHoriz); + dc_x++; + } + rt_draw4cols(dc_x - 4); + } + + while (dc_x < x2) + { + if (calclighting) + { // calculate lighting + dc_colormap = usecolormap->Maps + (GETPALOOKUP (rw_light, shade) << COLORMAPSHIFT); + } + R_WallSpriteColumn(R_DrawMaskedColumn); + dc_x++; + } + } + R_FinishSetPatchStyle(); +} + +void R_WallSpriteColumn (void (*drawfunc)(const BYTE *column, const FTexture::Span *spans)) +{ + unsigned int texturecolumn = lwall[dc_x] >> FRACBITS; + dc_iscale = MulScale16 (swall[dc_x], rw_offset); + spryscale = SafeDivScale32 (1, dc_iscale); + if (sprflipvert) + sprtopscreen = centeryfrac + FixedMul (dc_texturemid, spryscale); + else + sprtopscreen = centeryfrac - FixedMul (dc_texturemid, spryscale); + + const BYTE *column; + const FTexture::Span *spans; + column = WallSpriteTile->GetColumn (texturecolumn, &spans); + dc_texturefrac = 0; + drawfunc (column, spans); + rw_light += rw_lightstep; +} + void R_DrawVisVoxel(vissprite_t *spr, int minslabz, int maxslabz, short *cliptop, short *clipbot) { ESPSResult mode; @@ -521,12 +670,6 @@ void R_ProjectSprite (AActor *thing, int fakeside, F3DFloor *fakefloor, F3DFloor fy = thing->PrevY + FixedMul (r_TicFrac, thing->y - thing->PrevY); fz = thing->PrevZ + FixedMul (r_TicFrac, thing->z - thing->PrevZ) + thing->GetBobOffset(r_TicFrac); - // transform the origin point - tr_x = fx - viewx; - tr_y = fy - viewy; - - tz = DMulScale20 (tr_x, viewtancos, tr_y, viewtansin); - tex = NULL; voxel = NULL; @@ -618,6 +761,18 @@ void R_ProjectSprite (AActor *thing, int fakeside, F3DFloor *fakefloor, F3DFloor return; } + if ((thing->renderflags & RF_SPRITETYPEMASK) == RF_WALLSPRITE) + { + R_ProjectWallSprite(thing, fx, fy, fz, picnum, spritescaleX, spritescaleY, flip); + return; + } + + // transform the origin point + tr_x = fx - viewx; + tr_y = fy - viewy; + + tz = DMulScale20 (tr_x, viewtancos, tr_y, viewtansin); + // thing is behind view plane? if (voxel == NULL && tz < MINZ) return; @@ -782,7 +937,6 @@ void R_ProjectSprite (AActor *thing, int fakeside, F3DFloor *fakefloor, F3DFloor vis->heightsec = heightsec; vis->sector = thing->Sector; - vis->cx = tx2; vis->depth = tz; vis->gx = fx; vis->gy = fy; @@ -807,12 +961,14 @@ void R_ProjectSprite (AActor *thing, int fakeside, F3DFloor *fakefloor, F3DFloor { vis->voxel = voxel->Voxel; vis->bIsVoxel = true; + vis->bWallSprite = false; DrewAVoxel = true; } else { vis->pic = tex; vis->bIsVoxel = false; + vis->bWallSprite = false; } // The software renderer cannot invert the source without inverting the overlay @@ -874,6 +1030,78 @@ void R_ProjectSprite (AActor *thing, int fakeside, F3DFloor *fakefloor, F3DFloor } } +static void R_ProjectWallSprite(AActor *thing, fixed_t fx, fixed_t fy, fixed_t fz, FTextureID picnum, fixed_t xscale, fixed_t yscale, INTBOOL flip) +{ + FWallCoords wallc; + int x1, x2; + fixed_t lx1, lx2, ly1, ly2; + fixed_t gzb, gzt, tz; + FTexture *pic = TexMan(picnum, true); + angle_t ang = (thing->angle + ANGLE_90) >> ANGLETOFINESHIFT; + vissprite_t *vis; + + // Determine left and right edges of sprite. The sprite's angle is its normal, + // so the edges are 90 degrees each side of it. + x2 = pic->GetScaledWidth(); + x1 = pic->GetScaledLeftOffset(); + + x1 *= xscale; + x2 *= xscale; + + lx1 = fx - FixedMul(x1, finecosine[ang]) - viewx; + ly1 = fy - FixedMul(x1, finesine[ang]) - viewy; + lx2 = lx1 + FixedMul(x2, finecosine[ang]); + ly2 = ly1 + FixedMul(x2, finesine[ang]); + + // Is it off-screen? + if (wallc.Init(lx1, ly1, lx2, ly2, TOO_CLOSE_Z)) + return; + + if (wallc.SX1 > WindowRight || wallc.SX2 <= WindowLeft) + return; + + // Sprite sorting should probably treat these as walls, not sprites, + // but right now, I just want to get them drawing. + tz = DMulScale20(fx - viewx, viewtancos, fy - viewy, viewtansin); + + int scaled_to = pic->GetScaledTopOffset(); + int scaled_bo = scaled_to - pic->GetScaledHeight(); + gzt = fz + yscale * scaled_to; + gzb = fz + yscale * scaled_bo; + + vis = R_NewVisSprite(); + vis->x1 = wallc.SX1 < WindowLeft ? WindowLeft : wallc.SX1; + vis->x2 = wallc.SX2 >= WindowRight ? WindowRight-1 : wallc.SX2-1; + vis->idepth = (unsigned)DivScale32(1, tz) >> 1; + vis->depth = tz; + vis->sector = thing->Sector; + vis->heightsec = NULL; + vis->gx = fx; + vis->gy = fy; + vis->gz = fz; + vis->gzb = gzb; + vis->gzt = gzt; + vis->deltax = fx - viewx; + vis->deltay = fy - viewy; + vis->renderflags = thing->renderflags; + if(thing->flags5 & MF5_BRIGHT) vis->renderflags |= RF_FULLBRIGHT; // kg3D + vis->Style.RenderStyle = thing->RenderStyle; + vis->FillColor = thing->fillcolor; + vis->Translation = thing->Translation; + vis->FakeFlatStat = 0; + vis->Style.alpha = thing->alpha; + vis->fakefloor = NULL; + vis->fakeceiling = NULL; + vis->ColormapNum = 0; + vis->bInMirror = MirrorFlags & RF_XFLIP; + vis->pic = pic; + vis->bIsVoxel = false; + vis->bWallSprite = true; + vis->ColormapNum = GETPALOOKUP( + (fixed_t)DivScale12 (r_SpriteVisibility, MAX(tz, MINZ)), spriteshade); + vis->Style.colormap = basecolormap->Maps + (vis->ColormapNum << COLORMAPSHIFT); + vis->wallc = wallc; +} // // R_AddSprites @@ -1904,7 +2132,14 @@ void R_DrawSprite (vissprite_t *spr) { mfloorclip = clipbot; mceilingclip = cliptop; - R_DrawVisSprite (spr); + if (!spr->bWallSprite) + { + R_DrawVisSprite(spr); + } + else + { + R_DrawWallSprite(spr); + } } else { @@ -2161,7 +2396,6 @@ void R_ProjectParticle (particle_t *particle, const sector_t *sector, int shade, vis->yscale = xscale; vis->depth = tz; vis->idepth = (DWORD)DivScale32 (1, tz) >> 1; - vis->cx = tx; vis->gx = particle->x; vis->gy = particle->y; vis->gz = particle->z; // kg3D diff --git a/src/r_things.h b/src/r_things.h index 2219eee20..3ce1a4d4d 100644 --- a/src/r_things.h +++ b/src/r_things.h @@ -23,6 +23,7 @@ #ifndef __R_THINGS__ #define __R_THINGS__ +#include "r_bsp.h" // A vissprite_t is a thing // that will be drawn during a refresh. @@ -31,7 +32,6 @@ struct vissprite_t { short x1, x2; - fixed_t cx; // for line side calculation fixed_t gx, gy, gz; // origin in world coordinates angle_t angle; fixed_t gzb, gzt; // global bottom / top for silhouette clipping @@ -43,18 +43,26 @@ struct vissprite_t fixed_t floorclip; union { - // Used by regular sprites + FTexture *pic; + struct FVoxel *voxel; + }; + union + { + // Used by face sprites struct { - FTexture *pic; fixed_t texturemid; fixed_t startfrac; // horizontal position of x1 fixed_t xiscale; // negative if flipped }; + // Used by wall sprites + struct + { + FWallCoords wallc; + }; // Used by voxels struct { - struct FVoxel *voxel; fixed_t vx, vy, vz; // view origin angle_t vang; // view angle }; @@ -64,6 +72,7 @@ struct vissprite_t F3DFloor *fakefloor; F3DFloor *fakeceiling; BYTE bIsVoxel:1; // [RH] Use voxel instead of pic + BYTE bWallSprite:1; // [RH] This is a wall sprite BYTE bSplitSprite:1; // [RH] Sprite was split by a drawseg BYTE bInMirror:1; // [RH] Sprite is "inside" a mirror BYTE FakeFlatStat; // [RH] which side of fake/floor ceiling sprite is on @@ -99,9 +108,11 @@ extern fixed_t pspritexscale; extern fixed_t pspriteyscale; extern fixed_t pspritexiscale; +extern FTexture *WallSpriteTile; + void R_DrawMaskedColumn (const BYTE *column, const FTexture::Span *spans); - +void R_WallSpriteColumn (void (*drawfunc)(const BYTE *column, const FTexture::Span *spans)); void R_CacheSprite (spritedef_t *sprite); void R_SortVisSprites (int (STACK_ARGS *compare)(const void *, const void *), size_t first); From 398d902e7e527f78d109ff70eed53676ce63e9aa Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Sun, 3 Aug 2014 10:22:12 +0200 Subject: [PATCH 13/14] - split off sprite clipping adjustment code into its own function. --- src/gl/scene/gl_sprite.cpp | 187 ++++++++++++++++++++----------------- src/gl/scene/gl_wall.h | 1 + src/p_setup.cpp | 1 + 3 files changed, 101 insertions(+), 88 deletions(-) diff --git a/src/gl/scene/gl_sprite.cpp b/src/gl/scene/gl_sprite.cpp index 0ba386b1a..f420256f3 100644 --- a/src/gl/scene/gl_sprite.cpp +++ b/src/gl/scene/gl_sprite.cpp @@ -489,6 +489,103 @@ void GLSprite::SetSpriteColor(sector_t *sector, fixed_t center_y) // //========================================================================== +void GLSprite::PerformSpriteClipAdjustment(AActor *thing, fixed_t thingx, fixed_t thingy, float spriteheight) +{ + bool smarterclip = false; // Set to true if one condition triggers the test below + if (((thing->player || thing->flags3&MF3_ISMONSTER || + thing->IsKindOf(RUNTIME_CLASS(AInventory))) && (thing->flags&MF_ICECORPSE || + !(thing->flags&MF_CORPSE))) || (gl_spriteclip == 3 && (smarterclip = true)) || gl_spriteclip > 1) + { + float btm = 1000000.0f; + float top = -1000000.0f; + extsector_t::xfloor &x = thing->Sector->e->XFloor; + + if (x.ffloors.Size()) + { + for (unsigned int i = 0; i < x.ffloors.Size(); i++) + { + F3DFloor * ff = x.ffloors[i]; + fixed_t floorh = ff->top.plane->ZatPoint(thingx, thingy); + fixed_t ceilingh = ff->bottom.plane->ZatPoint(thingx, thingy); + if (floorh == thing->floorz) + { + btm = FIXED2FLOAT(floorh); + } + if (ceilingh == thing->ceilingz) + { + top = FIXED2FLOAT(ceilingh); + } + if (btm != 1000000.0f && top != -1000000.0f) + { + break; + } + } + } + else if (thing->Sector->heightsec && !(thing->Sector->heightsec->MoreFlags & SECF_IGNOREHEIGHTSEC)) + { + if (thing->flags2&MF2_ONMOBJ && thing->floorz == + thing->Sector->heightsec->floorplane.ZatPoint(thingx, thingy)) + { + btm = FIXED2FLOAT(thing->floorz); + top = FIXED2FLOAT(thing->ceilingz); + } + } + if (btm == 1000000.0f) + btm = FIXED2FLOAT(thing->Sector->floorplane.ZatPoint(thingx, thingy) - thing->floorclip); + if (top == -1000000.0f) + top = FIXED2FLOAT(thing->Sector->ceilingplane.ZatPoint(thingx, thingy)); + + float diffb = z2 - btm; + float difft = z1 - top; + if (diffb >= 0 /*|| !gl_sprite_clip_to_floor*/) diffb = 0; + // Adjust sprites clipping into ceiling and adjust clipping adjustment for tall graphics + if (smarterclip) + { + // Reduce slightly clipping adjustment of corpses + if (thing->flags & MF_CORPSE || spriteheight > fabs(diffb)) + { + float ratio = clamp((fabs(diffb) * (float)gl_sclipfactor / (spriteheight + 1)), 0.5, 1.0); + diffb *= ratio; + } + if (!diffb) + { + if (difft <= 0) difft = 0; + if (difft >= (float)gl_sclipthreshold) + { + // dumb copy of the above. + if (!(thing->flags3&MF3_ISMONSTER) || (thing->flags&MF_NOGRAVITY) || (thing->flags&MF_CORPSE) || difft > (float)gl_sclipthreshold) + { + difft = 0; + } + } + if (spriteheight > fabs(difft)) + { + float ratio = clamp((fabs(difft) * (float)gl_sclipfactor / (spriteheight + 1)), 0.5, 1.0); + difft *= ratio; + } + z2 -= difft; + z1 -= difft; + } + } + if (diffb <= (0 - (float)gl_sclipthreshold)) // such a large displacement can't be correct! + { + // for living monsters standing on the floor allow a little more. + if (!(thing->flags3&MF3_ISMONSTER) || (thing->flags&MF_NOGRAVITY) || (thing->flags&MF_CORPSE) || diffb < (-1.8*(float)gl_sclipthreshold)) + { + diffb = 0; + } + } + z2 -= diffb; + z1 -= diffb; + } +} + +//========================================================================== +// +// +// +//========================================================================== + void GLSprite::Process(AActor* thing,sector_t * sector) { sector_t rs; @@ -610,95 +707,9 @@ void GLSprite::Process(AActor* thing,sector_t * sector) float spriteheight = FIXED2FLOAT(spritescaleY) * gltexture->GetScaledHeightFloat(GLUSE_SPRITE); // Tests show that this doesn't look good for many decorations and corpses - if (spriteheight>0 && gl_spriteclip>0) + if (spriteheight > 0 && gl_spriteclip > 0 && (thing->renderflags & RF_SPRITETYPEMASK) == RF_FACESPRITE) { - bool smarterclip = false; // Set to true if one condition triggers the test below - if (((thing->player || thing->flags3&MF3_ISMONSTER || - thing->IsKindOf(RUNTIME_CLASS(AInventory))) && (thing->flags&MF_ICECORPSE || - !(thing->flags&MF_CORPSE))) || (gl_spriteclip==3 && (smarterclip = true)) || gl_spriteclip > 1) - { - float btm= 1000000.0f; - float top=-1000000.0f; - extsector_t::xfloor &x = thing->Sector->e->XFloor; - - if (x.ffloors.Size()) - { - for(unsigned int i=0;itop.plane->ZatPoint(thingx, thingy); - fixed_t ceilingh=ff->bottom.plane->ZatPoint(thingx, thingy); - if (floorh==thing->floorz) - { - btm=FIXED2FLOAT(floorh); - } - if (ceilingh==thing->ceilingz) - { - top=FIXED2FLOAT(ceilingh); - } - if (btm != 1000000.0f && top != -1000000.0f) - { - break; - } - } - } - else if (thing->Sector->heightsec && !(thing->Sector->heightsec->MoreFlags & SECF_IGNOREHEIGHTSEC)) - { - if (thing->flags2&MF2_ONMOBJ && thing->floorz== - thing->Sector->heightsec->floorplane.ZatPoint(thingx, thingy)) - { - btm=FIXED2FLOAT(thing->floorz); - top=FIXED2FLOAT(thing->ceilingz); - } - } - if (btm==1000000.0f) - btm= FIXED2FLOAT(thing->Sector->floorplane.ZatPoint(thingx, thingy)-thing->floorclip); - if (top==-1000000.0f) - top= FIXED2FLOAT(thing->Sector->ceilingplane.ZatPoint(thingx, thingy)); - - float diffb = z2 - btm; - float difft = z1 - top; - if (diffb >= 0 /*|| !gl_sprite_clip_to_floor*/) diffb = 0; - // Adjust sprites clipping into ceiling and adjust clipping adjustment for tall graphics - if (smarterclip) - { - // Reduce slightly clipping adjustment of corpses - if (thing->flags & MF_CORPSE || spriteheight > fabs(diffb)) - { - float ratio = clamp((fabs(diffb) * (float)gl_sclipfactor/(spriteheight+1)), 0.5, 1.0); - diffb*=ratio; - } - if (!diffb) - { - if (difft <= 0) difft = 0; - if (difft >= (float)gl_sclipthreshold) - { - // dumb copy of the above. - if (!(thing->flags3&MF3_ISMONSTER) || (thing->flags&MF_NOGRAVITY) || (thing->flags&MF_CORPSE) || difft > (float)gl_sclipthreshold) - { - difft=0; - } - } - if (spriteheight > fabs(difft)) - { - float ratio = clamp((fabs(difft) * (float)gl_sclipfactor/(spriteheight+1)), 0.5, 1.0); - difft*=ratio; - } - z2-=difft; - z1-=difft; - } - } - if (diffb <= (0 - (float)gl_sclipthreshold)) // such a large displacement can't be correct! - { - // for living monsters standing on the floor allow a little more. - if (!(thing->flags3&MF3_ISMONSTER) || (thing->flags&MF_NOGRAVITY) || (thing->flags&MF_CORPSE) || diffb<(-1.8*(float)gl_sclipthreshold)) - { - diffb=0; - } - } - z2-=diffb; - z1-=diffb; - } + PerformSpriteClipAdjustment(thing, thingx, thingy, spriteheight); } float viewvecX = GLRenderer->mViewVector.X; float viewvecY = GLRenderer->mViewVector.Y; diff --git a/src/gl/scene/gl_wall.h b/src/gl/scene/gl_wall.h index e53513167..2fecf1d60 100644 --- a/src/gl/scene/gl_wall.h +++ b/src/gl/scene/gl_wall.h @@ -324,6 +324,7 @@ public: void SplitSprite(sector_t * frontsector, bool translucent); void SetLowerParam(); + void PerformSpriteClipAdjustment(AActor *thing, fixed_t thingx, fixed_t thingy, float spriteheight); public: diff --git a/src/p_setup.cpp b/src/p_setup.cpp index a6dbca868..0312feba5 100644 --- a/src/p_setup.cpp +++ b/src/p_setup.cpp @@ -1858,6 +1858,7 @@ void P_SpawnThings (int position) { SetMapThingUserData(actor, *udi); } + if (actor != NULL) actor->renderflags |= RF_WALLSPRITE; } for(int i=0; i Date: Sun, 3 Aug 2014 10:57:58 +0200 Subject: [PATCH 14/14] - implemented rendering of wall sprites. --- src/gl/scene/gl_sprite.cpp | 47 ++++++++++++++++++++++++++------------ src/p_setup.cpp | 1 - 2 files changed, 33 insertions(+), 15 deletions(-) diff --git a/src/gl/scene/gl_sprite.cpp b/src/gl/scene/gl_sprite.cpp index f420256f3..a600ef5a2 100644 --- a/src/gl/scene/gl_sprite.cpp +++ b/src/gl/scene/gl_sprite.cpp @@ -678,7 +678,7 @@ void GLSprite::Process(AActor* thing,sector_t * sector) bool mirror; FTextureID patch = gl_GetSpriteFrame(spritenum, thing->frame, -1, ang - thing->angle, &mirror); if (!patch.isValid()) return; - gltexture=FMaterial::ValidateTexture(patch, false); + gltexture = FMaterial::ValidateTexture(patch, false); if (!gltexture) return; vt = gltexture->GetSpriteVT(); @@ -686,7 +686,7 @@ void GLSprite::Process(AActor* thing,sector_t * sector) gltexture->GetRect(&r, GLUSE_SPRITE); if (mirror) { - r.left=-r.width-r.left; // mirror the sprite's x-offset + r.left = -r.width - r.left; // mirror the sprite's x-offset ul = gltexture->GetSpriteUL(); ur = gltexture->GetSpriteUR(); } @@ -696,28 +696,46 @@ void GLSprite::Process(AActor* thing,sector_t * sector) ur = gltexture->GetSpriteUL(); } - r.Scale(FIXED2FLOAT(spritescaleX),FIXED2FLOAT(spritescaleY)); + r.Scale(FIXED2FLOAT(spritescaleX), FIXED2FLOAT(spritescaleY)); - float rightfac=-r.left; - float leftfac=rightfac-r.width; + float rightfac = -r.left; + float leftfac = rightfac - r.width; - z1=z-r.top; - z2=z1-r.height; + z1 = z - r.top; + z2 = z1 - r.height; float spriteheight = FIXED2FLOAT(spritescaleY) * gltexture->GetScaledHeightFloat(GLUSE_SPRITE); - + // Tests show that this doesn't look good for many decorations and corpses if (spriteheight > 0 && gl_spriteclip > 0 && (thing->renderflags & RF_SPRITETYPEMASK) == RF_FACESPRITE) { PerformSpriteClipAdjustment(thing, thingx, thingy, spriteheight); } - float viewvecX = GLRenderer->mViewVector.X; - float viewvecY = GLRenderer->mViewVector.Y; - x1=x-viewvecY*leftfac; - x2=x-viewvecY*rightfac; - y1=y+viewvecX*leftfac; - y2=y+viewvecX*rightfac; + float viewvecX; + float viewvecY; + switch (thing->renderflags & RF_SPRITETYPEMASK) + { + case RF_FACESPRITE: + viewvecX = GLRenderer->mViewVector.X; + viewvecY = GLRenderer->mViewVector.Y; + + x1 = x - viewvecY*leftfac; + x2 = x - viewvecY*rightfac; + y1 = y + viewvecX*leftfac; + y2 = y + viewvecX*rightfac; + break; + + case RF_WALLSPRITE: + viewvecX = FIXED2FLOAT(finecosine[thing->angle >> ANGLETOFINESHIFT]); + viewvecY = FIXED2FLOAT(finesine[thing->angle >> ANGLETOFINESHIFT]); + + x1 = x + viewvecY*leftfac; + x2 = x + viewvecY*rightfac; + y1 = y - viewvecX*leftfac; + y2 = y - viewvecX*rightfac; + break; + } } else { @@ -887,6 +905,7 @@ void GLSprite::Process(AActor* thing,sector_t * sector) particle=NULL; const bool drawWithXYBillboard = ( !(actor->renderflags & RF_FORCEYBILLBOARD) + && (actor->renderflags & RF_SPRITETYPEMASK) == RF_FACESPRITE && players[consoleplayer].camera && (gl_billboard_mode == 1 || actor->renderflags & RF_FORCEXYBILLBOARD ) ); diff --git a/src/p_setup.cpp b/src/p_setup.cpp index 0312feba5..a6dbca868 100644 --- a/src/p_setup.cpp +++ b/src/p_setup.cpp @@ -1858,7 +1858,6 @@ void P_SpawnThings (int position) { SetMapThingUserData(actor, *udi); } - if (actor != NULL) actor->renderflags |= RF_WALLSPRITE; } for(int i=0; i