Screen size-related limit removals

This commit is contained in:
Lactozilla 2023-07-25 01:06:55 -03:00
parent 0d943e31b1
commit c162216db9
19 changed files with 258 additions and 871 deletions

View file

@ -498,14 +498,14 @@ static void D_Display(void)
if (rendermode != render_none) if (rendermode != render_none)
{ {
viewwindowy = vid.height / 2; viewwindowy = vid.height / 2;
M_Memcpy(ylookup, ylookup2, viewheight*sizeof (ylookup[0])); ylookup = ylookup2;
topleft = screens[0] + viewwindowy*vid.width + viewwindowx; topleft = screens[0] + viewwindowy*vid.width + viewwindowx;
R_RenderPlayerView(&players[secondarydisplayplayer]); R_RenderPlayerView(&players[secondarydisplayplayer]);
viewwindowy = 0; viewwindowy = 0;
M_Memcpy(ylookup, ylookup1, viewheight*sizeof (ylookup[0])); ylookup = ylookup1;
} }
} }

View file

@ -677,13 +677,6 @@ extern const char *compdate, *comptime, *comprevision, *compbranch;
/// Experimental attempts at preventing MF_PAPERCOLLISION objects from getting stuck in walls. /// Experimental attempts at preventing MF_PAPERCOLLISION objects from getting stuck in walls.
//#define PAPER_COLLISIONCORRECTION //#define PAPER_COLLISIONCORRECTION
/// FINALLY some real clipping that doesn't make walls dissappear AND speeds the game up
/// (that was the original comment from SRB2CB, sadly it is a lie and actually slows game down)
/// on the bright side it fixes some weird issues with translucent walls
/// \note SRB2CB port.
/// SRB2CB itself ported this from PrBoom+
#define NEWCLIP
/// OpenGL shaders /// OpenGL shaders
#define GL_SHADERS #define GL_SHADERS

View file

@ -130,7 +130,7 @@ extern postimg_t postimgtype2;
extern INT32 postimgparam2; extern INT32 postimgparam2;
extern INT32 viewwindowx, viewwindowy; extern INT32 viewwindowx, viewwindowy;
extern INT32 viewwidth, scaledviewwidth; extern INT32 viewwidth;
// Player taking events, and displaying. // Player taking events, and displaying.
extern INT32 consoleplayer; extern INT32 consoleplayer;

View file

@ -41,11 +41,9 @@
#include "../r_things.h" // R_GetShadowZ #include "../r_things.h" // R_GetShadowZ
#include "../d_main.h" #include "../d_main.h"
#include "../p_slopes.h" #include "../p_slopes.h"
#include "hw_md2.h"
#ifdef NEWCLIP #include "hw_md2.h"
#include "hw_clip.h" #include "hw_clip.h"
#endif
#define R_FAKEFLOORS #define R_FAKEFLOORS
#define HWPRECIP #define HWPRECIP
@ -81,19 +79,6 @@ boolean drawsky = true;
#define FIELDOFVIEW ANGLE_90 #define FIELDOFVIEW ANGLE_90
#define ABS(x) ((x) < 0 ? -(x) : (x)) #define ABS(x) ((x) < 0 ? -(x) : (x))
static angle_t gl_clipangle;
// The viewangletox[viewangle + FINEANGLES/4] lookup
// maps the visible view angles to screen X coordinates,
// flattening the arc to a flat projection plane.
// There will be many angles mapped to the same X.
static INT32 gl_viewangletox[FINEANGLES/2];
// The xtoviewangleangle[] table maps a screen pixel
// to the lowest viewangle that maps back to x ranges
// from clipangle to -clipangle.
static angle_t gl_xtoviewangle[MAXVIDWIDTH+1];
// ========================================================================== // ==========================================================================
// GLOBALS // GLOBALS
// ========================================================================== // ==========================================================================
@ -786,41 +771,6 @@ static void HWR_ProjectWall(FOutVector *wallVerts, FSurfaceInfo *pSurf, FBITFIEL
// BSP, CULL, ETC.. // BSP, CULL, ETC..
// ========================================================================== // ==========================================================================
// return the frac from the interception of the clipping line
// (in fact a clipping plane that has a constant, so can clip with simple 2d)
// with the wall segment
//
#ifndef NEWCLIP
static float HWR_ClipViewSegment(INT32 x, polyvertex_t *v1, polyvertex_t *v2)
{
float num, den;
float v1x, v1y, v1dx, v1dy, v2dx, v2dy;
angle_t pclipangle = gl_xtoviewangle[x];
// a segment of a polygon
v1x = v1->x;
v1y = v1->y;
v1dx = (v2->x - v1->x);
v1dy = (v2->y - v1->y);
// the clipping line
pclipangle = pclipangle + dup_viewangle; //back to normal angle (non-relative)
v2dx = FIXED_TO_FLOAT(FINECOSINE(pclipangle>>ANGLETOFINESHIFT));
v2dy = FIXED_TO_FLOAT(FINESINE(pclipangle>>ANGLETOFINESHIFT));
den = v2dy*v1dx - v2dx*v1dy;
if (den == 0)
return -1; // parallel
// calc the frac along the polygon segment,
//num = (v2x - v1x)*v2dy + (v1y - v2y)*v2dx;
//num = -v1x * v2dy + v1y * v2dx;
num = (gl_viewx - v1x)*v2dy + (v1y - gl_viewy)*v2dx;
return num / den;
}
#endif
// SoM: split up and light walls according to the lightlist. // SoM: split up and light walls according to the lightlist.
// This may also include leaving out parts of the wall that can't be seen // This may also include leaving out parts of the wall that can't be seen
static void HWR_SplitWall(sector_t *sector, FOutVector *wallVerts, INT32 texnum, FSurfaceInfo* Surf, INT32 cutflag, ffloor_t *pfloor, FBITFIELD polyflags) static void HWR_SplitWall(sector_t *sector, FOutVector *wallVerts, INT32 texnum, FSurfaceInfo* Surf, INT32 cutflag, ffloor_t *pfloor, FBITFIELD polyflags)
@ -1846,7 +1796,6 @@ static void HWR_ProcessSeg(void) // Sort of like GLWall::Process in GZDoom
// //
// e6y: Check whether the player can look beyond this line // e6y: Check whether the player can look beyond this line
// //
#ifdef NEWCLIP
boolean checkforemptylines = true; boolean checkforemptylines = true;
// Don't modify anything here, just check // Don't modify anything here, just check
// Kalaron: Modified for sloped linedefs // Kalaron: Modified for sloped linedefs
@ -1929,295 +1878,6 @@ static boolean CheckClip(seg_t * seg, sector_t * afrontsector, sector_t * abacks
return false; return false;
} }
#else
//Hurdler: just like in r_bsp.c
#if 1
#define MAXSEGS MAXVIDWIDTH/2+1
#else
//Alam_GBC: Or not (may cause overflow)
#define MAXSEGS 128
#endif
// hw_newend is one past the last valid seg
static cliprange_t * hw_newend;
static cliprange_t gl_solidsegs[MAXSEGS];
// needs fix: walls are incorrectly clipped one column less
static consvar_t cv_glclipwalls = CVAR_INIT ("gr_clipwalls", "Off", 0, CV_OnOff, NULL);
static void printsolidsegs(void)
{
cliprange_t * start;
if (!hw_newend)
return;
for (start = gl_solidsegs;start != hw_newend;start++)
{
CONS_Debug(DBG_RENDER, "%d-%d|",start->first,start->last);
}
CONS_Debug(DBG_RENDER, "\n\n");
}
//
//
//
static void HWR_ClipSolidWallSegment(INT32 first, INT32 last)
{
cliprange_t *next, *start;
float lowfrac, highfrac;
boolean poorhack = false;
// Find the first range that touches the range
// (adjacent pixels are touching).
start = gl_solidsegs;
while (start->last < first-1)
start++;
if (first < start->first)
{
if (last < start->first-1)
{
// Post is entirely visible (above start),
// so insert a new clippost.
HWR_StoreWallRange(first, last);
next = hw_newend;
hw_newend++;
while (next != start)
{
*next = *(next-1);
next--;
}
next->first = first;
next->last = last;
printsolidsegs();
return;
}
// There is a fragment above *start.
if (!cv_glclipwalls.value)
{
if (!poorhack) HWR_StoreWallRange(first, last);
poorhack = true;
}
else
{
highfrac = HWR_ClipViewSegment(start->first+1, (polyvertex_t *)gl_curline->pv1, (polyvertex_t *)gl_curline->pv2);
HWR_StoreWallRange(0, highfrac);
}
// Now adjust the clip size.
start->first = first;
}
// Bottom contained in start?
if (last <= start->last)
{
printsolidsegs();
return;
}
next = start;
while (last >= (next+1)->first-1)
{
// There is a fragment between two posts.
if (!cv_glclipwalls.value)
{
if (!poorhack) HWR_StoreWallRange(first,last);
poorhack = true;
}
else
{
lowfrac = HWR_ClipViewSegment(next->last-1, (polyvertex_t *)gl_curline->pv1, (polyvertex_t *)gl_curline->pv2);
highfrac = HWR_ClipViewSegment((next+1)->first+1, (polyvertex_t *)gl_curline->pv1, (polyvertex_t *)gl_curline->pv2);
HWR_StoreWallRange(lowfrac, highfrac);
}
next++;
if (last <= next->last)
{
// Bottom is contained in next.
// Adjust the clip size.
start->last = next->last;
goto crunch;
}
}
if (first == next->first+1) // 1 line texture
{
if (!cv_glclipwalls.value)
{
if (!poorhack) HWR_StoreWallRange(first,last);
poorhack = true;
}
else
HWR_StoreWallRange(0, 1);
}
else
{
// There is a fragment after *next.
if (!cv_glclipwalls.value)
{
if (!poorhack) HWR_StoreWallRange(first,last);
poorhack = true;
}
else
{
lowfrac = HWR_ClipViewSegment(next->last-1, (polyvertex_t *)gl_curline->pv1, (polyvertex_t *)gl_curline->pv2);
HWR_StoreWallRange(lowfrac, 1);
}
}
// Adjust the clip size.
start->last = last;
// Remove start+1 to next from the clip list,
// because start now covers their area.
crunch:
if (next == start)
{
printsolidsegs();
// Post just extended past the bottom of one post.
return;
}
while (next++ != hw_newend)
{
// Remove a post.
*++start = *next;
}
hw_newend = start;
printsolidsegs();
}
//
// handle LineDefs with upper and lower texture (windows)
//
static void HWR_ClipPassWallSegment(INT32 first, INT32 last)
{
cliprange_t *start;
float lowfrac, highfrac;
//to allow noclipwalls but still solidseg reject of non-visible walls
boolean poorhack = false;
// Find the first range that touches the range
// (adjacent pixels are touching).
start = gl_solidsegs;
while (start->last < first - 1)
start++;
if (first < start->first)
{
if (last < start->first-1)
{
// Post is entirely visible (above start).
HWR_StoreWallRange(0, 1);
return;
}
// There is a fragment above *start.
if (!cv_glclipwalls.value)
{ //20/08/99: Changed by Hurdler (taken from faB's code)
if (!poorhack) HWR_StoreWallRange(0, 1);
poorhack = true;
}
else
{
highfrac = HWR_ClipViewSegment(min(start->first + 1,
start->last), (polyvertex_t *)gl_curline->pv1,
(polyvertex_t *)gl_curline->pv2);
HWR_StoreWallRange(0, highfrac);
}
}
// Bottom contained in start?
if (last <= start->last)
return;
while (last >= (start+1)->first-1)
{
// There is a fragment between two posts.
if (!cv_glclipwalls.value)
{
if (!poorhack) HWR_StoreWallRange(0, 1);
poorhack = true;
}
else
{
lowfrac = HWR_ClipViewSegment(max(start->last-1,start->first), (polyvertex_t *)gl_curline->pv1, (polyvertex_t *)gl_curline->pv2);
highfrac = HWR_ClipViewSegment(min((start+1)->first+1,(start+1)->last), (polyvertex_t *)gl_curline->pv1, (polyvertex_t *)gl_curline->pv2);
HWR_StoreWallRange(lowfrac, highfrac);
}
start++;
if (last <= start->last)
return;
}
if (first == start->first+1) // 1 line texture
{
if (!cv_glclipwalls.value)
{
if (!poorhack) HWR_StoreWallRange(0, 1);
poorhack = true;
}
else
HWR_StoreWallRange(0, 1);
}
else
{
// There is a fragment after *next.
if (!cv_glclipwalls.value)
{
if (!poorhack) HWR_StoreWallRange(0,1);
poorhack = true;
}
else
{
lowfrac = HWR_ClipViewSegment(max(start->last - 1,
start->first), (polyvertex_t *)gl_curline->pv1,
(polyvertex_t *)gl_curline->pv2);
HWR_StoreWallRange(lowfrac, 1);
}
}
}
// --------------------------------------------------------------------------
// HWR_ClipToSolidSegs check if it is hide by wall (solidsegs)
// --------------------------------------------------------------------------
static boolean HWR_ClipToSolidSegs(INT32 first, INT32 last)
{
cliprange_t * start;
// Find the first range that touches the range
// (adjacent pixels are touching).
start = gl_solidsegs;
while (start->last < first-1)
start++;
if (first < start->first)
return true;
// Bottom contained in start?
if (last <= start->last)
return false;
return true;
}
//
// HWR_ClearClipSegs
//
static void HWR_ClearClipSegs(void)
{
gl_solidsegs[0].first = -0x7fffffff;
gl_solidsegs[0].last = -1;
gl_solidsegs[1].first = vid.width; //viewwidth;
gl_solidsegs[1].last = 0x7fffffff;
hw_newend = gl_solidsegs+2;
}
#endif // NEWCLIP
// -----------------+ // -----------------+
// HWR_AddLine : Clips the given segment and adds any visible pieces to the line list. // HWR_AddLine : Clips the given segment and adds any visible pieces to the line list.
@ -2227,11 +1887,6 @@ static void HWR_ClearClipSegs(void)
static void HWR_AddLine(seg_t * line) static void HWR_AddLine(seg_t * line)
{ {
angle_t angle1, angle2; angle_t angle1, angle2;
#ifndef NEWCLIP
INT32 x1, x2;
angle_t span, tspan;
boolean bothceilingssky = false, bothfloorssky = false;
#endif
// SoM: Backsector needs to be run through R_FakeFlat // SoM: Backsector needs to be run through R_FakeFlat
static sector_t tempsec; static sector_t tempsec;
@ -2251,7 +1906,6 @@ static void HWR_AddLine(seg_t * line)
angle1 = R_PointToAngle64(v1x, v1y); angle1 = R_PointToAngle64(v1x, v1y);
angle2 = R_PointToAngle64(v2x, v2y); angle2 = R_PointToAngle64(v2x, v2y);
#ifdef NEWCLIP
// PrBoom: Back side, i.e. backface culling - read: endAngle >= startAngle! // PrBoom: Back side, i.e. backface culling - read: endAngle >= startAngle!
if (angle2 - angle1 < ANGLE_180) if (angle2 - angle1 < ANGLE_180)
return; return;
@ -2264,90 +1918,9 @@ static void HWR_AddLine(seg_t * line)
} }
checkforemptylines = true; checkforemptylines = true;
#else
// Clip to view edges.
span = angle1 - angle2;
// backface culling : span is < ANGLE_180 if ang1 > ang2 : the seg is facing
if (span >= ANGLE_180)
return;
// Global angle needed by segcalc.
//rw_angle1 = angle1;
angle1 -= dup_viewangle;
angle2 -= dup_viewangle;
tspan = angle1 + gl_clipangle;
if (tspan > 2*gl_clipangle)
{
tspan -= 2*gl_clipangle;
// Totally off the left edge?
if (tspan >= span)
return;
angle1 = gl_clipangle;
}
tspan = gl_clipangle - angle2;
if (tspan > 2*gl_clipangle)
{
tspan -= 2*gl_clipangle;
// Totally off the left edge?
if (tspan >= span)
return;
angle2 = (angle_t)-(signed)gl_clipangle;
}
#if 0
{
float fx1,fx2,fy1,fy2;
//BP: test with a better projection than viewangletox[R_PointToAngle(angle)]
// do not enable this at release 4 mul and 2 div
fx1 = ((polyvertex_t *)(line->pv1))->x-gl_viewx;
fy1 = ((polyvertex_t *)(line->pv1))->y-gl_viewy;
fy2 = (fx1 * gl_viewcos + fy1 * gl_viewsin);
if (fy2 < 0)
// the point is back
fx1 = 0;
else
fx1 = gl_windowcenterx + (fx1 * gl_viewsin - fy1 * gl_viewcos) * gl_centerx / fy2;
fx2 = ((polyvertex_t *)(line->pv2))->x-gl_viewx;
fy2 = ((polyvertex_t *)(line->pv2))->y-gl_viewy;
fy1 = (fx2 * gl_viewcos + fy2 * gl_viewsin);
if (fy1 < 0)
// the point is back
fx2 = vid.width;
else
fx2 = gl_windowcenterx + (fx2 * gl_viewsin - fy2 * gl_viewcos) * gl_centerx / fy1;
x1 = fx1+0.5f;
x2 = fx2+0.5f;
}
#else
// The seg is in the view range,
// but not necessarily visible.
angle1 = (angle1+ANGLE_90)>>ANGLETOFINESHIFT;
angle2 = (angle2+ANGLE_90)>>ANGLETOFINESHIFT;
x1 = gl_viewangletox[angle1];
x2 = gl_viewangletox[angle2];
#endif
// Does not cross a pixel?
// if (x1 == x2)
/* {
// BP: HERE IS THE MAIN PROBLEM !
//CONS_Debug(DBG_RENDER, "tineline\n");
return;
}
*/
#endif
gl_backsector = line->backsector; gl_backsector = line->backsector;
#ifdef NEWCLIP
if (!line->backsector) if (!line->backsector)
{ {
gld_clipper_SafeAddClipRange(angle2, angle1); gld_clipper_SafeAddClipRange(angle2, angle1);
@ -2389,115 +1962,6 @@ static void HWR_AddLine(seg_t * line)
} }
HWR_ProcessSeg(); // Doesn't need arguments because they're defined globally :D HWR_ProcessSeg(); // Doesn't need arguments because they're defined globally :D
return;
#else
// Single sided line?
if (!gl_backsector)
goto clipsolid;
gl_backsector = R_FakeFlat(gl_backsector, &tempsec, NULL, NULL, true);
if (gl_backsector->ceilingpic == skyflatnum && gl_frontsector->ceilingpic == skyflatnum)
bothceilingssky = true;
if (gl_backsector->floorpic == skyflatnum && gl_frontsector->floorpic == skyflatnum)
bothfloorssky = true;
if (bothceilingssky && bothfloorssky) // everything's sky? let's save us a bit of time then
{
if (!line->polyseg &&
!line->sidedef->midtexture
&& ((!gl_frontsector->ffloors && !gl_backsector->ffloors)
|| Tag_Compare(&gl_frontsector->tags, &gl_backsector->tags)))
return; // line is empty, don't even bother
goto clippass; // treat like wide open window instead
}
if (gl_frontsector->f_slope || gl_frontsector->c_slope || gl_backsector->f_slope || gl_backsector->c_slope)
{
fixed_t frontf1,frontf2, frontc1, frontc2; // front floor/ceiling ends
fixed_t backf1, backf2, backc1, backc2; // back floor ceiling ends
#define SLOPEPARAMS(slope, end1, end2, normalheight) \
end1 = P_GetZAt(slope, v1x, v1y, normalheight); \
end2 = P_GetZAt(slope, v2x, v2y, normalheight);
SLOPEPARAMS(gl_frontsector->f_slope, frontf1, frontf2, gl_frontsector-> floorheight)
SLOPEPARAMS(gl_frontsector->c_slope, frontc1, frontc2, gl_frontsector->ceilingheight)
SLOPEPARAMS( gl_backsector->f_slope, backf1, backf2, gl_backsector-> floorheight)
SLOPEPARAMS( gl_backsector->c_slope, backc1, backc2, gl_backsector->ceilingheight)
#undef SLOPEPARAMS
// if both ceilings are skies, consider it always "open"
// same for floors
if (!bothceilingssky && !bothfloorssky)
{
// Closed door.
if ((backc1 <= frontf1 && backc2 <= frontf2)
|| (backf1 >= frontc1 && backf2 >= frontc2))
{
goto clipsolid;
}
// Check for automap fix.
if (backc1 <= backf1 && backc2 <= backf2
&& ((backc1 >= frontc1 && backc2 >= frontc2) || gl_curline->sidedef->toptexture)
&& ((backf1 <= frontf1 && backf2 >= frontf2) || gl_curline->sidedef->bottomtexture))
goto clipsolid;
}
// Window.
if (!bothceilingssky) // ceilings are always the "same" when sky
if (backc1 != frontc1 || backc2 != frontc2)
goto clippass;
if (!bothfloorssky) // floors are always the "same" when sky
if (backf1 != frontf1 || backf2 != frontf2)
goto clippass;
}
else
{
// if both ceilings are skies, consider it always "open"
// same for floors
if (!bothceilingssky && !bothfloorssky)
{
// Closed door.
if (gl_backsector->ceilingheight <= gl_frontsector->floorheight ||
gl_backsector->floorheight >= gl_frontsector->ceilingheight)
goto clipsolid;
// Check for automap fix.
if (gl_backsector->ceilingheight <= gl_backsector->floorheight
&& ((gl_backsector->ceilingheight >= gl_frontsector->ceilingheight) || gl_curline->sidedef->toptexture)
&& ((gl_backsector->floorheight <= gl_backsector->floorheight) || gl_curline->sidedef->bottomtexture))
goto clipsolid;
}
// Window.
if (!bothceilingssky) // ceilings are always the "same" when sky
if (gl_backsector->ceilingheight != gl_frontsector->ceilingheight)
goto clippass;
if (!bothfloorssky) // floors are always the "same" when sky
if (gl_backsector->floorheight != gl_frontsector->floorheight)
goto clippass;
}
// 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.
if (R_IsEmptyLine(gl_curline, gl_frontsector, gl_backsector))
return;
clippass:
if (x1 == x2)
{ x2++;x1 -= 2; }
HWR_ClipPassWallSegment(x1, x2-1);
return;
clipsolid:
if (x1 == x2)
goto clippass;
HWR_ClipSolidWallSegment(x1, x2-1);
#endif
} }
// HWR_CheckBBox // HWR_CheckBBox
@ -2512,10 +1976,6 @@ static boolean HWR_CheckBBox(fixed_t *bspcoord)
INT32 boxpos; INT32 boxpos;
fixed_t px1, py1, px2, py2; fixed_t px1, py1, px2, py2;
angle_t angle1, angle2; angle_t angle1, angle2;
#ifndef NEWCLIP
INT32 sx1, sx2;
angle_t span, tspan;
#endif
// Find the corners of the box // Find the corners of the box
// that define the edges from current viewpoint. // that define the edges from current viewpoint.
@ -2541,59 +2001,9 @@ static boolean HWR_CheckBBox(fixed_t *bspcoord)
px2 = bspcoord[checkcoord[boxpos][2]]; px2 = bspcoord[checkcoord[boxpos][2]];
py2 = bspcoord[checkcoord[boxpos][3]]; py2 = bspcoord[checkcoord[boxpos][3]];
#ifdef NEWCLIP
angle1 = R_PointToAngle64(px1, py1); angle1 = R_PointToAngle64(px1, py1);
angle2 = R_PointToAngle64(px2, py2); angle2 = R_PointToAngle64(px2, py2);
return gld_clipper_SafeCheckRange(angle2, angle1); return gld_clipper_SafeCheckRange(angle2, angle1);
#else
// check clip list for an open space
angle1 = R_PointToAngle2(dup_viewx>>1, dup_viewy>>1, px1>>1, py1>>1) - dup_viewangle;
angle2 = R_PointToAngle2(dup_viewx>>1, dup_viewy>>1, px2>>1, py2>>1) - dup_viewangle;
span = angle1 - angle2;
// Sitting on a line?
if (span >= ANGLE_180)
return true;
tspan = angle1 + gl_clipangle;
if (tspan > 2*gl_clipangle)
{
tspan -= 2*gl_clipangle;
// Totally off the left edge?
if (tspan >= span)
return false;
angle1 = gl_clipangle;
}
tspan = gl_clipangle - angle2;
if (tspan > 2*gl_clipangle)
{
tspan -= 2*gl_clipangle;
// Totally off the left edge?
if (tspan >= span)
return false;
angle2 = (angle_t)-(signed)gl_clipangle;
}
// Find the first clippost
// that touches the source post
// (adjacent pixels are touching).
angle1 = (angle1+ANGLE_90)>>ANGLETOFINESHIFT;
angle2 = (angle2+ANGLE_90)>>ANGLETOFINESHIFT;
sx1 = gl_viewangletox[angle1];
sx2 = gl_viewangletox[angle2];
// Does not cross a pixel.
if (sx1 == sx2)
return false;
return HWR_ClipToSolidSegs(sx1, sx2 - 1);
#endif
} }
// //
@ -3317,100 +2727,6 @@ static void HWR_RenderBSPNode(INT32 bspnum)
} }
} }
/*
//
// Clear 'stack' of subsectors to draw
//
static void HWR_ClearDrawSubsectors(void)
{
gl_drawsubsector_p = gl_drawsubsectors;
}
//
// Draw subsectors pushed on the drawsubsectors 'stack', back to front
//
static void HWR_RenderSubsectors(void)
{
while (gl_drawsubsector_p > gl_drawsubsectors)
{
HWR_RenderBSPNode(
lastsubsec->nextsubsec = bspnum & (~NF_SUBSECTOR);
}
}
*/
// ==========================================================================
// FROM R_MAIN.C
// ==========================================================================
//BP : exactely the same as R_InitTextureMapping
void HWR_InitTextureMapping(void)
{
angle_t i;
INT32 x;
INT32 t;
fixed_t focallength;
fixed_t grcenterx;
fixed_t grcenterxfrac;
INT32 grviewwidth;
#define clipanglefov (FIELDOFVIEW>>ANGLETOFINESHIFT)
grviewwidth = vid.width;
grcenterx = grviewwidth/2;
grcenterxfrac = grcenterx<<FRACBITS;
// Use tangent table to generate viewangletox:
// viewangletox will give the next greatest x
// after the view angle.
//
// Calc focallength
// so FIELDOFVIEW angles covers SCREENWIDTH.
focallength = FixedDiv(grcenterxfrac,
FINETANGENT(FINEANGLES/4+clipanglefov/2));
for (i = 0; i < FINEANGLES/2; i++)
{
if (FINETANGENT(i) > FRACUNIT*2)
t = -1;
else if (FINETANGENT(i) < -FRACUNIT*2)
t = grviewwidth+1;
else
{
t = FixedMul(FINETANGENT(i), focallength);
t = (grcenterxfrac - t+FRACUNIT-1)>>FRACBITS;
if (t < -1)
t = -1;
else if (t > grviewwidth+1)
t = grviewwidth+1;
}
gl_viewangletox[i] = t;
}
// Scan viewangletox[] to generate xtoviewangle[]:
// xtoviewangle will give the smallest view angle
// that maps to x.
for (x = 0; x <= grviewwidth; x++)
{
i = 0;
while (gl_viewangletox[i]>x)
i++;
gl_xtoviewangle[x] = (i<<ANGLETOFINESHIFT) - ANGLE_90;
}
// Take out the fencepost cases from viewangletox.
for (i = 0; i < FINEANGLES/2; i++)
{
if (gl_viewangletox[i] == -1)
gl_viewangletox[i] = 0;
else if (gl_viewangletox[i] == grviewwidth+1)
gl_viewangletox[i] = grviewwidth;
}
gl_clipangle = gl_xtoviewangle[0];
}
// ========================================================================== // ==========================================================================
// gl_things.c // gl_things.c
// ========================================================================== // ==========================================================================
@ -5967,7 +5283,7 @@ static void HWR_DrawSkyBackground(player_t *player)
// software doesn't draw any further than 1024 for skies anyway, but this doesn't overlap properly // software doesn't draw any further than 1024 for skies anyway, but this doesn't overlap properly
// The only time this will probably be an issue is when a sky wider than 1024 is used as a sky AND a regular wall texture // The only time this will probably be an issue is when a sky wider than 1024 is used as a sky AND a regular wall texture
angle = (dup_viewangle + gl_xtoviewangle[0]); angle = (dup_viewangle + xtoviewangle[0]);
dimensionmultiply = ((float)textures[texturetranslation[skytexture]]->width/256.0f); dimensionmultiply = ((float)textures[texturetranslation[skytexture]]->width/256.0f);
@ -6217,19 +5533,12 @@ void HWR_RenderSkyboxView(INT32 viewnumber, player_t *player)
drawcount = 0; drawcount = 0;
#ifdef NEWCLIP
if (rendermode == render_opengl)
{
angle_t a1 = gld_FrustumAngle(gl_aimingangle); angle_t a1 = gld_FrustumAngle(gl_aimingangle);
gld_clipper_Clear(); gld_clipper_Clear();
gld_clipper_SafeAddClipRange(viewangle + a1, viewangle - a1); gld_clipper_SafeAddClipRange(viewangle + a1, viewangle - a1);
#ifdef HAVE_SPHEREFRUSTRUM #ifdef HAVE_SPHEREFRUSTRUM
gld_FrustrumSetup(); gld_FrustrumSetup();
#endif #endif
}
#else
HWR_ClearClipSegs();
#endif
//04/01/2000: Hurdler: added for T&L //04/01/2000: Hurdler: added for T&L
// Actually it only works on Walls and Planes // Actually it only works on Walls and Planes
@ -6245,35 +5554,6 @@ void HWR_RenderSkyboxView(INT32 viewnumber, player_t *player)
HWR_RenderBSPNode((INT32)numnodes-1); HWR_RenderBSPNode((INT32)numnodes-1);
#ifndef NEWCLIP
// Make a viewangle int so we can render things based on mouselook
if (player == &players[consoleplayer])
viewangle = localaiming;
else if (splitscreen && player == &players[secondarydisplayplayer])
viewangle = localaiming2;
// Handle stuff when you are looking farther up or down.
if ((gl_aimingangle || cv_fov.value+player->fovadd > 90*FRACUNIT))
{
dup_viewangle += ANGLE_90;
HWR_ClearClipSegs();
HWR_RenderBSPNode((INT32)numnodes-1); //left
dup_viewangle += ANGLE_90;
if (((INT32)gl_aimingangle > ANGLE_45 || (INT32)gl_aimingangle<-ANGLE_45))
{
HWR_ClearClipSegs();
HWR_RenderBSPNode((INT32)numnodes-1); //back
}
dup_viewangle += ANGLE_90;
HWR_ClearClipSegs();
HWR_RenderBSPNode((INT32)numnodes-1); //right
dup_viewangle += ANGLE_90;
}
#endif
if (cv_glbatching.value) if (cv_glbatching.value)
HWR_RenderBatches(); HWR_RenderBatches();
@ -6433,19 +5713,12 @@ void HWR_RenderPlayerView(INT32 viewnumber, player_t *player)
drawcount = 0; drawcount = 0;
#ifdef NEWCLIP
if (rendermode == render_opengl)
{
angle_t a1 = gld_FrustumAngle(gl_aimingangle); angle_t a1 = gld_FrustumAngle(gl_aimingangle);
gld_clipper_Clear(); gld_clipper_Clear();
gld_clipper_SafeAddClipRange(viewangle + a1, viewangle - a1); gld_clipper_SafeAddClipRange(viewangle + a1, viewangle - a1);
#ifdef HAVE_SPHEREFRUSTRUM #ifdef HAVE_SPHEREFRUSTRUM
gld_FrustrumSetup(); gld_FrustrumSetup();
#endif #endif
}
#else
HWR_ClearClipSegs();
#endif
//04/01/2000: Hurdler: added for T&L //04/01/2000: Hurdler: added for T&L
// Actually it only works on Walls and Planes // Actually it only works on Walls and Planes
@ -6465,35 +5738,6 @@ void HWR_RenderPlayerView(INT32 viewnumber, player_t *player)
HWR_RenderBSPNode((INT32)numnodes-1); HWR_RenderBSPNode((INT32)numnodes-1);
#ifndef NEWCLIP
// Make a viewangle int so we can render things based on mouselook
if (player == &players[consoleplayer])
viewangle = localaiming;
else if (splitscreen && player == &players[secondarydisplayplayer])
viewangle = localaiming2;
// Handle stuff when you are looking farther up or down.
if ((gl_aimingangle || cv_fov.value+player->fovadd > 90*FRACUNIT))
{
dup_viewangle += ANGLE_90;
HWR_ClearClipSegs();
HWR_RenderBSPNode((INT32)numnodes-1); //left
dup_viewangle += ANGLE_90;
if (((INT32)gl_aimingangle > ANGLE_45 || (INT32)gl_aimingangle<-ANGLE_45))
{
HWR_ClearClipSegs();
HWR_RenderBSPNode((INT32)numnodes-1); //back
}
dup_viewangle += ANGLE_90;
HWR_ClearClipSegs();
HWR_RenderBSPNode((INT32)numnodes-1); //right
dup_viewangle += ANGLE_90;
}
#endif
PS_STOP_TIMING(ps_bsptime); PS_STOP_TIMING(ps_bsptime);
if (cv_glbatching.value) if (cv_glbatching.value)
@ -6646,10 +5890,6 @@ void HWR_AddCommands(void)
CV_RegisterVar(&cv_glsolvetjoin); CV_RegisterVar(&cv_glsolvetjoin);
CV_RegisterVar(&cv_glbatching); CV_RegisterVar(&cv_glbatching);
#ifndef NEWCLIP
CV_RegisterVar(&cv_glclipwalls);
#endif
} }
void HWR_AddSessionCommands(void) void HWR_AddSessionCommands(void)

View file

@ -37,7 +37,6 @@ void HWR_ClearSkyDome(void);
void HWR_BuildSkyDome(void); void HWR_BuildSkyDome(void);
void HWR_DrawViewBorder(INT32 clearlines); void HWR_DrawViewBorder(INT32 clearlines);
void HWR_DrawFlatFill(INT32 x, INT32 y, INT32 w, INT32 h, lumpnum_t flatlumpnum); void HWR_DrawFlatFill(INT32 x, INT32 y, INT32 w, INT32 h, lumpnum_t flatlumpnum);
void HWR_InitTextureMapping(void);
void HWR_SetViewSize(void); void HWR_SetViewSize(void);
void HWR_DrawPatch(patch_t *gpatch, INT32 x, INT32 y, INT32 option); void HWR_DrawPatch(patch_t *gpatch, INT32 x, INT32 y, INT32 option);
void HWR_DrawStretchyFixedPatch(patch_t *gpatch, fixed_t x, fixed_t y, fixed_t pscale, fixed_t vscale, INT32 option, const UINT8 *colormap); void HWR_DrawStretchyFixedPatch(patch_t *gpatch, fixed_t x, fixed_t y, fixed_t pscale, fixed_t vscale, INT32 option, const UINT8 *colormap);

View file

@ -764,11 +764,11 @@ typedef struct drawseg_s
struct ffloor_s *thicksides[MAXFFLOORS]; struct ffloor_s *thicksides[MAXFFLOORS];
INT16 *thicksidecol; INT16 *thicksidecol;
INT32 numthicksides; INT32 numthicksides;
fixed_t frontscale[MAXVIDWIDTH]; fixed_t *frontscale;
UINT8 portalpass; // if > 0 and <= portalrender, do not affect sprite clipping UINT8 portalpass; // if > 0 and <= portalrender, do not affect sprite clipping
fixed_t maskedtextureheight[MAXVIDWIDTH]; // For handling sloped midtextures fixed_t *maskedtextureheight; // For handling sloped midtextures
vertex_t leftpos, rightpos; // Used for rendering FOF walls with slopes vertex_t leftpos, rightpos; // Used for rendering FOF walls with slopes
} drawseg_t; } drawseg_t;

View file

@ -18,6 +18,7 @@
#include "doomdef.h" #include "doomdef.h"
#include "doomstat.h" #include "doomstat.h"
#include "r_local.h" #include "r_local.h"
#include "r_splats.h"
#include "st_stuff.h" // need ST_HEIGHT #include "st_stuff.h" // need ST_HEIGHT
#include "i_video.h" #include "i_video.h"
#include "v_video.h" #include "v_video.h"
@ -37,24 +38,24 @@
/** \brief view info /** \brief view info
*/ */
INT32 viewwidth, scaledviewwidth, viewheight, viewwindowx, viewwindowy; INT32 viewwidth, viewheight, viewwindowx, viewwindowy;
/** \brief pointer to the start of each line of the screen, /** \brief pointer to the start of each line of the screen,
*/ */
UINT8 *ylookup[MAXVIDHEIGHT*4]; UINT8 **ylookup;
/** \brief pointer to the start of each line of the screen, for view1 (splitscreen) /** \brief pointer to the start of each line of the screen, for view1 (splitscreen)
*/ */
UINT8 *ylookup1[MAXVIDHEIGHT*4]; UINT8 **ylookup1;
/** \brief pointer to the start of each line of the screen, for view2 (splitscreen) /** \brief pointer to the start of each line of the screen, for view2 (splitscreen)
*/ */
UINT8 *ylookup2[MAXVIDHEIGHT*4]; UINT8 **ylookup2;
/** \brief x byte offset for columns inside the viewwindow, /** \brief x byte offset for columns inside the viewwindow,
so the first column starts at (SCRWIDTH - VIEWWIDTH)/2 so the first column starts at (SCRWIDTH - VIEWWIDTH)/2
*/ */
INT32 columnofs[MAXVIDWIDTH*4]; INT32 *columnofs;
UINT8 *topleft; UINT8 *topleft;
@ -121,6 +122,9 @@ float focallengthf, zeroheight;
UINT32 nflatxshift, nflatyshift, nflatshiftup, nflatmask; UINT32 nflatxshift, nflatyshift, nflatshiftup, nflatmask;
// For, uh, tilted lighting, duh.
static INT32 *tiltlighting;
// ========================================================================= // =========================================================================
// TRANSLATION COLORMAP CODE // TRANSLATION COLORMAP CODE
// ========================================================================= // =========================================================================
@ -701,6 +705,29 @@ void R_InitViewBuffer(INT32 width, INT32 height)
if (bytesperpixel < 1 || bytesperpixel > 4) if (bytesperpixel < 1 || bytesperpixel > 4)
I_Error("R_InitViewBuffer: wrong bytesperpixel value %d\n", bytesperpixel); I_Error("R_InitViewBuffer: wrong bytesperpixel value %d\n", bytesperpixel);
negonearray = Z_Realloc(negonearray, sizeof(*negonearray) * viewwidth, PU_STATIC, NULL);
screenheightarray = Z_Realloc(screenheightarray, sizeof(*screenheightarray) * viewwidth, PU_STATIC, NULL);
floorclip = Z_Realloc(floorclip, sizeof(*floorclip) * viewwidth, PU_STATIC, NULL);
ceilingclip = Z_Realloc(ceilingclip, sizeof(*ceilingclip) * viewwidth, PU_STATIC, NULL);
frontscale = Z_Realloc(frontscale, sizeof(*frontscale) * viewwidth, PU_STATIC, NULL);
ylookup1 = Z_Realloc(ylookup1, sizeof(*ylookup1) * (viewheight * 4), PU_STATIC, NULL);
ylookup2 = Z_Realloc(ylookup2, sizeof(*ylookup2) * (viewheight * 4), PU_STATIC, NULL);
ylookup = ylookup1;
columnofs = Z_Realloc(columnofs, sizeof(*columnofs) * (viewwidth * 4), PU_STATIC, NULL);
xtoviewangle = Z_Realloc(xtoviewangle, sizeof(*xtoviewangle) * (viewwidth + 1), PU_STATIC, NULL);
tiltlighting = Z_Realloc(tiltlighting, sizeof(*tiltlighting) * viewwidth, PU_STATIC, NULL);
R_AllocSegMemory();
R_AllocPlaneMemory();
R_AllocFloorSpriteTables();
R_AllocVisSpriteMemory();
// Handle resize, e.g. smaller view windows with border and/or status bar. // Handle resize, e.g. smaller view windows with border and/or status bar.
viewwindowx = (vid.width - width) >> 1; viewwindowx = (vid.width - width) >> 1;
@ -717,7 +744,7 @@ void R_InitViewBuffer(INT32 width, INT32 height)
// Precalculate all row offsets. // Precalculate all row offsets.
for (i = 0; i < height; i++) for (i = 0; i < height; i++)
{ {
ylookup[i] = ylookup1[i] = screens[0] + (i+viewwindowy)*vid.width*bytesperpixel; ylookup1[i] = screens[0] + (i+viewwindowy)*vid.width*bytesperpixel;
ylookup2[i] = screens[0] + (i+(vid.height>>1))*vid.width*bytesperpixel; // for splitscreen ylookup2[i] = screens[0] + (i+(vid.height>>1))*vid.width*bytesperpixel; // for splitscreen
} }
} }
@ -745,8 +772,6 @@ void R_VideoErase(size_t ofs, INT32 count)
// R_CalcTiltedLighting // R_CalcTiltedLighting
// Exactly what it says on the tin. I wish I wasn't too lazy to explain things properly. // Exactly what it says on the tin. I wish I wasn't too lazy to explain things properly.
static INT32 tiltlighting[MAXVIDWIDTH];
static void R_CalcTiltedLighting(fixed_t start, fixed_t end) static void R_CalcTiltedLighting(fixed_t start, fixed_t end)
{ {
// ZDoom uses a different lighting setup to us, and I couldn't figure out how to adapt their version // ZDoom uses a different lighting setup to us, and I couldn't figure out how to adapt their version

View file

@ -19,10 +19,10 @@
// ------------------------------- // -------------------------------
// COMMON STUFF FOR 8bpp AND 16bpp // COMMON STUFF FOR 8bpp AND 16bpp
// ------------------------------- // -------------------------------
extern UINT8 *ylookup[MAXVIDHEIGHT*4]; extern UINT8 **ylookup;
extern UINT8 *ylookup1[MAXVIDHEIGHT*4]; extern UINT8 **ylookup1;
extern UINT8 *ylookup2[MAXVIDHEIGHT*4]; extern UINT8 **ylookup2;
extern INT32 columnofs[MAXVIDWIDTH*4]; extern INT32 *columnofs;
extern UINT8 *topleft; extern UINT8 *topleft;
// ------------------------- // -------------------------

View file

@ -122,7 +122,7 @@ static vector3_t *R_LerpVector3(const vector3_t *from, const vector3_t *to, fixe
// recalc necessary stuff for mouseaiming // recalc necessary stuff for mouseaiming
// slopes are already calculated for the full possible view (which is 4*viewheight). // slopes are already calculated for the full possible view (which is 4*viewheight).
// 18/08/18: (No it's actually 16*viewheight, thanks Jimita for finding this out) // 18/08/18: (No it's actually 16*viewheight, thanks Lactozilla for finding this out)
static void R_SetupFreelook(player_t *player, boolean skybox) static void R_SetupFreelook(player_t *player, boolean skybox)
{ {
#ifndef HWRENDER #ifndef HWRENDER

View file

@ -95,7 +95,7 @@ INT32 viewangletox[FINEANGLES/2];
// The xtoviewangleangle[] table maps a screen pixel // The xtoviewangleangle[] table maps a screen pixel
// to the lowest viewangle that maps back to x ranges // to the lowest viewangle that maps back to x ranges
// from clipangle to -clipangle. // from clipangle to -clipangle.
angle_t xtoviewangle[MAXVIDWIDTH+1]; angle_t *xtoviewangle;
lighttable_t *scalelight[LIGHTLEVELS][MAXLIGHTSCALE]; lighttable_t *scalelight[LIGHTLEVELS][MAXLIGHTSCALE];
lighttable_t *scalelightfixed[MAXLIGHTSCALE]; lighttable_t *scalelightfixed[MAXLIGHTSCALE];
@ -606,7 +606,10 @@ static struct {
INT32 scrmapsize; INT32 scrmapsize;
INT32 x1; // clip rendering horizontally for efficiency INT32 x1; // clip rendering horizontally for efficiency
INT16 ceilingclip[MAXVIDWIDTH], floorclip[MAXVIDWIDTH]; INT16 *ceilingclip, *floorclip;
#ifdef WOUGHMP_WOUGHMP
float *fisheyemap;
#endif
boolean use; boolean use;
} viewmorph = { } viewmorph = {
@ -620,7 +623,10 @@ static struct {
0, 0,
0, 0,
{0}, {0}, NULL, NULL,
#ifdef WOUGHMP_WOUGHMP
NULL,
#endif
false false
}; };
@ -632,9 +638,6 @@ void R_CheckViewMorph(void)
fixed_t temp; fixed_t temp;
INT32 end, vx, vy, pos, usedpos; INT32 end, vx, vy, pos, usedpos;
INT32 usedx, usedy, halfwidth = vid.width/2, halfheight = vid.height/2; INT32 usedx, usedy, halfwidth = vid.width/2, halfheight = vid.height/2;
#ifdef WOUGHMP_WOUGHMP
float fisheyemap[MAXVIDWIDTH/2 + 1];
#endif
angle_t rollangle = players[displayplayer].viewrollangle; angle_t rollangle = players[displayplayer].viewrollangle;
#ifdef WOUGHMP_WOUGHMP #ifdef WOUGHMP_WOUGHMP
@ -677,10 +680,13 @@ void R_CheckViewMorph(void)
if (viewmorph.scrmapsize != vid.width*vid.height) if (viewmorph.scrmapsize != vid.width*vid.height)
{ {
if (viewmorph.scrmap)
free(viewmorph.scrmap);
viewmorph.scrmap = malloc(vid.width*vid.height * sizeof(INT32));
viewmorph.scrmapsize = vid.width*vid.height; viewmorph.scrmapsize = vid.width*vid.height;
viewmorph.scrmap = realloc(viewmorph.scrmap, vid.width*vid.height * sizeof(INT32));
viewmorph.ceilingclip = realloc(viewmorph.ceilingclip, vid.width * sizeof(INT16));
viewmorph.floorclip = realloc(viewmorph.floorclip, vid.width * sizeof(INT16));
#ifdef WOUGHMP_WOUGHMP
viewmorph.fisheyemap = realloc(viewmorph.fisheyemap, (vid.width/2 + 1) * sizeof(float));
#endif
} }
temp = FINECOSINE(rollangle); temp = FINECOSINE(rollangle);
@ -923,14 +929,12 @@ void R_ExecuteSetViewSize(void)
// status bar overlay // status bar overlay
st_overlay = cv_showhud.value; st_overlay = cv_showhud.value;
scaledviewwidth = vid.width; viewwidth = vid.width;
viewheight = vid.height; viewheight = vid.height;
if (splitscreen) if (splitscreen)
viewheight >>= 1; viewheight >>= 1;
viewwidth = scaledviewwidth;
centerx = viewwidth/2; centerx = viewwidth/2;
centery = viewheight/2; centery = viewheight/2;
centerxfrac = centerx<<FRACBITS; centerxfrac = centerx<<FRACBITS;
@ -948,13 +952,16 @@ void R_ExecuteSetViewSize(void)
projection = projectiony = FixedDiv(centerxfrac, fovtan); projection = projectiony = FixedDiv(centerxfrac, fovtan);
R_InitViewBuffer(scaledviewwidth, viewheight); R_InitViewBuffer(viewwidth, viewheight);
R_InitTextureMapping(); R_InitTextureMapping();
// thing clipping // thing clipping
for (i = 0; i < viewwidth; i++) for (i = 0; i < viewwidth; i++)
{
negonearray[i] = -1;
screenheightarray[i] = (INT16)viewheight; screenheightarray[i] = (INT16)viewheight;
}
// setup sky scaling // setup sky scaling
R_SetSkyScale(); R_SetSkyScale();
@ -1023,9 +1030,6 @@ void R_Init(void)
R_SetViewSize(); // setsizeneeded is set true R_SetViewSize(); // setsizeneeded is set true
//I_OutputMsg("\nR_InitPlanes");
R_InitPlanes();
// this is now done by SCR_Recalc() at the first mode set // this is now done by SCR_Recalc() at the first mode set
//I_OutputMsg("\nR_InitLightTables"); //I_OutputMsg("\nR_InitLightTables");
R_InitLightTables(); R_InitLightTables();

View file

@ -39,6 +39,7 @@
//SoM: 3/23/2000: Use Boom visplane hashing. //SoM: 3/23/2000: Use Boom visplane hashing.
visplane_t *visplanes[MAXVISPLANES]; visplane_t *visplanes[MAXVISPLANES];
static UINT16 numvisplanes;
static visplane_t *freetail; static visplane_t *freetail;
static visplane_t **freehead = &freetail; static visplane_t **freehead = &freetail;
@ -62,14 +63,14 @@ INT16 *openings, *lastopening; /// \todo free leak
// floorclip starts out SCREENHEIGHT // floorclip starts out SCREENHEIGHT
// ceilingclip starts out -1 // ceilingclip starts out -1
// //
INT16 floorclip[MAXVIDWIDTH], ceilingclip[MAXVIDWIDTH]; INT16 *floorclip, *ceilingclip;
fixed_t frontscale[MAXVIDWIDTH]; fixed_t *frontscale;
// //
// spanstart holds the start of a plane span // spanstart holds the start of a plane span
// initialized to 0 at start // initialized to 0 at start
// //
static INT32 spanstart[MAXVIDHEIGHT]; static INT32 *spanstart;
// //
// texture mapping // texture mapping
@ -84,24 +85,75 @@ static fixed_t planeheight;
// (this is to calculate yslopes only when really needed) // (this is to calculate yslopes only when really needed)
// (when mouselookin', yslope is moving into yslopetab) // (when mouselookin', yslope is moving into yslopetab)
// Check R_SetupFrame, R_SetViewSize for more... // Check R_SetupFrame, R_SetViewSize for more...
fixed_t yslopetab[MAXVIDHEIGHT*16]; fixed_t *yslopetab;
fixed_t *yslope; fixed_t *yslope;
fixed_t cachedheight[MAXVIDHEIGHT]; fixed_t *cachedheight;
fixed_t cacheddistance[MAXVIDHEIGHT]; fixed_t *cacheddistance;
fixed_t cachedxstep[MAXVIDHEIGHT]; fixed_t *cachedxstep;
fixed_t cachedystep[MAXVIDHEIGHT]; fixed_t *cachedystep;
static fixed_t xoffs, yoffs; static fixed_t xoffs, yoffs;
static floatv3_t ds_slope_origin, ds_slope_u, ds_slope_v; static floatv3_t ds_slope_origin, ds_slope_u, ds_slope_v;
// static INT16 *ffloor_f_clip;
// R_InitPlanes static INT16 *ffloor_c_clip;
// Only at game startup.
// UINT16 *visplanes_top[MAXVISPLANES];
void R_InitPlanes(void) UINT16 *visplanes_bottom[MAXVISPLANES];
static void R_AllocVisplaneTables(unsigned i)
{ {
// FIXME: unused // leave pads for [minx-1]/[maxx+1]
visplanes_top[i] = Z_Realloc(visplanes_top[i], sizeof(UINT16) * (viewwidth + 2), PU_STATIC, NULL);
visplanes_bottom[i] = Z_Realloc(visplanes_bottom[i], sizeof(UINT16) * (viewwidth + 2), PU_STATIC, NULL);
}
void R_AllocPlaneMemory(void)
{
// Alloc visplane top/bottom bounds
visplane_t *check;
for (unsigned i = 0; i < MAXVISPLANES; i++)
{
if (visplanes_top[i] || visplanes_bottom[i])
R_AllocVisplaneTables(i);
if ((check = visplanes[i]))
{
check->top = visplanes_top[check->id] + 1;
check->bottom = visplanes_bottom[check->id] + 1;
}
}
// Need to do it for "freed" visplanes too
check = freetail;
while (check)
{
check->top = visplanes_top[check->id] + 1;
check->bottom = visplanes_bottom[check->id] + 1;
check = check->next;
}
// Alloc ffloor clip tables
ffloor_f_clip = Z_Realloc(ffloor_f_clip, sizeof(*ffloor_f_clip) * (viewwidth * MAXFFLOORS), PU_STATIC, NULL);
ffloor_c_clip = Z_Realloc(ffloor_c_clip, sizeof(*ffloor_c_clip) * (viewwidth * MAXFFLOORS), PU_STATIC, NULL);
for (unsigned i = 0; i < MAXFFLOORS; i++)
{
ffloor[i].f_clip = ffloor_f_clip + (i * viewwidth);
ffloor[i].c_clip = ffloor_c_clip + (i * viewwidth);
}
yslopetab = Z_Realloc(yslopetab, sizeof(*yslopetab) * (viewheight * 16), PU_STATIC, NULL);
cachedheight = Z_Realloc(cachedheight, sizeof(*cachedheight) * viewheight, PU_STATIC, NULL);
cacheddistance = Z_Realloc(cacheddistance, sizeof(*cacheddistance) * viewheight, PU_STATIC, NULL);
cachedxstep = Z_Realloc(cachedxstep, sizeof(*cachedxstep) * viewheight, PU_STATIC, NULL);
cachedystep = Z_Realloc(cachedystep, sizeof(*cachedystep) * viewheight, PU_STATIC, NULL);
spanstart = Z_Realloc(spanstart, sizeof(*spanstart) * viewheight, PU_STATIC, NULL);
} }
// //
@ -369,7 +421,7 @@ void R_ClearPlanes(void)
lastopening = openings; lastopening = openings;
// texture calculation // texture calculation
memset(cachedheight, 0, sizeof (cachedheight)); memset(cachedheight, 0, sizeof(*cachedheight) * viewheight);
} }
static visplane_t *new_visplane(unsigned hash) static visplane_t *new_visplane(unsigned hash)
@ -377,8 +429,10 @@ static visplane_t *new_visplane(unsigned hash)
visplane_t *check = freetail; visplane_t *check = freetail;
if (!check) if (!check)
{ {
check = malloc(sizeof (*check)); check = calloc(1, sizeof (*check));
if (check == NULL) I_Error("%s: Out of memory", "new_visplane"); // FIXME: ugly if (check == NULL) I_Error("%s: Out of memory", "new_visplane"); // FIXME: ugly
check->id = numvisplanes++;
R_AllocVisplaneTables(check->id);
} }
else else
{ {
@ -486,8 +540,11 @@ visplane_t *R_FindPlane(fixed_t height, INT32 picnum, INT32 lightlevel,
check->polyobj = polyobj; check->polyobj = polyobj;
check->slope = slope; check->slope = slope;
memset(check->top, 0xff, sizeof (check->top)); check->top = visplanes_top[check->id] + 1;
memset(check->bottom, 0x00, sizeof (check->bottom)); check->bottom = visplanes_bottom[check->id] + 1;
memset(check->top, 0xff, sizeof(*check->top) * viewwidth);
memset(check->bottom, 0x00, sizeof(*check->bottom) * viewwidth);
return check; return check;
} }
@ -542,8 +599,7 @@ visplane_t *R_CheckPlane(visplane_t *pl, INT32 start, INT32 stop)
} }
else else
{ {
unsigned hash = unsigned hash = visplane_hash(pl->picnum, pl->lightlevel, pl->height);
visplane_hash(pl->picnum, pl->lightlevel, pl->height);
new_pl = new_visplane(hash); new_pl = new_visplane(hash);
} }
@ -564,8 +620,10 @@ visplane_t *R_CheckPlane(visplane_t *pl, INT32 start, INT32 stop)
pl = new_pl; pl = new_pl;
pl->minx = start; pl->minx = start;
pl->maxx = stop; pl->maxx = stop;
memset(pl->top, 0xff, sizeof pl->top); pl->top = visplanes_top[pl->id] + 1;
memset(pl->bottom, 0x00, sizeof pl->bottom); pl->bottom = visplanes_bottom[pl->id] + 1;
memset(pl->top, 0xff, sizeof(*pl->top) * viewwidth);
memset(pl->bottom, 0x00, sizeof(*pl->bottom) * viewwidth);
} }
return pl; return pl;
} }
@ -1009,7 +1067,7 @@ void R_DrawSinglePlane(visplane_t *pl)
// Don't mess with angle on slopes! We'll handle this ourselves later // Don't mess with angle on slopes! We'll handle this ourselves later
if (!pl->slope && viewangle != pl->viewangle+pl->plangle) if (!pl->slope && viewangle != pl->viewangle+pl->plangle)
{ {
memset(cachedheight, 0, sizeof (cachedheight)); memset(cachedheight, 0, sizeof(*cachedheight) * viewheight);
viewangle = pl->viewangle+pl->plangle; viewangle = pl->viewangle+pl->plangle;
} }

View file

@ -31,6 +31,7 @@
typedef struct visplane_s typedef struct visplane_s
{ {
struct visplane_s *next; struct visplane_s *next;
UINT16 id;
fixed_t height; fixed_t height;
fixed_t viewx, viewy, viewz; fixed_t viewx, viewy, viewz;
@ -43,9 +44,8 @@ typedef struct visplane_s
// colormaps per sector // colormaps per sector
extracolormap_t *extra_colormap; extracolormap_t *extra_colormap;
// leave pads for [minx-1]/[maxx+1] UINT16 *top;
UINT16 padtopstart, top[MAXVIDWIDTH], padtopend; UINT16 *bottom;
UINT16 padbottomstart, bottom[MAXVIDWIDTH], padbottomend;
INT32 high, low; // R_PlaneBounds should set these. INT32 high, low; // R_PlaneBounds should set these.
fixed_t xoffs, yoffs; // Scrolling flats. fixed_t xoffs, yoffs; // Scrolling flats.
@ -63,17 +63,17 @@ extern visplane_t *ceilingplane;
extern INT16 *lastopening, *openings; extern INT16 *lastopening, *openings;
extern size_t maxopenings; extern size_t maxopenings;
extern INT16 floorclip[MAXVIDWIDTH], ceilingclip[MAXVIDWIDTH]; extern INT16 *floorclip, *ceilingclip;
extern fixed_t frontscale[MAXVIDWIDTH], yslopetab[MAXVIDHEIGHT*16]; extern fixed_t *frontscale, *yslopetab;
extern fixed_t cachedheight[MAXVIDHEIGHT]; extern fixed_t *cachedheight;
extern fixed_t cacheddistance[MAXVIDHEIGHT]; extern fixed_t *cacheddistance;
extern fixed_t cachedxstep[MAXVIDHEIGHT]; extern fixed_t *cachedxstep;
extern fixed_t cachedystep[MAXVIDHEIGHT]; extern fixed_t *cachedystep;
extern fixed_t *yslope; extern fixed_t *yslope;
extern lighttable_t **planezlight; extern lighttable_t **planezlight;
void R_InitPlanes(void); void R_AllocPlaneMemory(void);
void R_ClearPlanes(void); void R_ClearPlanes(void);
void R_ClearFFloorClips (void); void R_ClearFFloorClips (void);
@ -103,8 +103,8 @@ typedef struct planemgr_s
fixed_t b_pos; // B for Back sector fixed_t b_pos; // B for Back sector
fixed_t f_frac, f_step; fixed_t f_frac, f_step;
fixed_t b_frac, b_step; fixed_t b_frac, b_step;
INT16 f_clip[MAXVIDWIDTH]; INT16 *f_clip;
INT16 c_clip[MAXVIDWIDTH]; INT16 *c_clip;
// For slope rendering; the height at the other end // For slope rendering; the height at the other end
fixed_t f_pos_slope; fixed_t f_pos_slope;

View file

@ -1512,6 +1512,33 @@ static INT64 R_CalcSegDist(seg_t* seg, INT64 x2, INT64 y2)
} }
} }
static size_t maxdrawsegs = 0;
static fixed_t *frontscaletable = NULL;
static fixed_t *maskedheighttable = NULL;
void R_AllocSegMemory(void)
{
if (!maxdrawsegs)
return;
frontscaletable = Z_Realloc(frontscaletable, sizeof(*frontscaletable) * (maxdrawsegs * viewwidth), PU_STATIC, NULL);
maskedheighttable = Z_Realloc(maskedheighttable, sizeof(*maskedheighttable) * (maxdrawsegs * viewwidth), PU_STATIC, NULL);
drawseg_t *lastseg = drawsegs + maxdrawsegs;
fixed_t *frontscale_p = frontscaletable;
fixed_t *maskedheight_p = maskedheighttable;
for (drawseg_t *ds = drawsegs; ds < lastseg; ds++)
{
ds->frontscale = frontscale_p;
ds->maskedtextureheight = maskedheight_p;
frontscale_p += viewwidth;
maskedheight_p += viewwidth;
}
}
// //
// R_StoreWallRange // R_StoreWallRange
// A wall segment will be drawn // A wall segment will be drawn
@ -1530,7 +1557,6 @@ void R_StoreWallRange(INT32 start, INT32 stop)
INT32 range; INT32 range;
vertex_t segleft, segright; vertex_t segleft, segright;
fixed_t ceilingfrontslide, floorfrontslide, ceilingbackslide, floorbackslide; fixed_t ceilingfrontslide, floorfrontslide, ceilingbackslide, floorbackslide;
static size_t maxdrawsegs = 0;
maskedtextureheight = NULL; maskedtextureheight = NULL;
//initialize segleft and segright //initialize segleft and segright
@ -1552,6 +1578,7 @@ void R_StoreWallRange(INT32 start, INT32 stop)
curdrawsegs = drawsegs + curpos; curdrawsegs = drawsegs + curpos;
if (firstseg) if (firstseg)
firstseg = drawsegs + (size_t)firstseg; firstseg = drawsegs + (size_t)firstseg;
R_AllocSegMemory();
} }
sidedef = curline->sidedef; sidedef = curline->sidedef;

View file

@ -18,9 +18,12 @@
#pragma interface #pragma interface
#endif #endif
transnum_t R_GetLinedefTransTable(fixed_t alpha);
void R_RenderMaskedSegRange(drawseg_t *ds, INT32 x1, INT32 x2); void R_RenderMaskedSegRange(drawseg_t *ds, INT32 x1, INT32 x2);
void R_RenderThickSideRange(drawseg_t *ds, INT32 x1, INT32 x2, ffloor_t *pffloor); void R_RenderThickSideRange(drawseg_t *ds, INT32 x1, INT32 x2, ffloor_t *pffloor);
void R_StoreWallRange(INT32 start, INT32 stop); void R_StoreWallRange(INT32 start, INT32 stop);
void R_AllocSegMemory(void);
transnum_t R_GetLinedefTransTable(fixed_t alpha);
#endif #endif

View file

@ -22,9 +22,17 @@
struct rastery_s *prastertab; // for ASM code struct rastery_s *prastertab; // for ASM code
static struct rastery_s rastertab[MAXVIDHEIGHT]; static struct rastery_s *rastertab;
static void prepare_rastertab(void); static void prepare_rastertab(void);
static boolean *cliptable;
void R_AllocFloorSpriteTables(void)
{
cliptable = Z_Realloc(cliptable, sizeof(*cliptable) * (viewwidth + 1), PU_STATIC, NULL);
rastertab = Z_Realloc(rastertab, sizeof(*rastertab) * viewheight, PU_STATIC, NULL);
}
// ========================================================================== // ==========================================================================
// FLOOR SPLATS // FLOOR SPLATS
// ========================================================================== // ==========================================================================
@ -412,7 +420,7 @@ static void R_RasterizeFloorSplat(floorsplat_t *pSplat, vector2_t *verts, visspr
if (pSplat->angle) if (pSplat->angle)
{ {
memset(cachedheight, 0, sizeof(cachedheight)); memset(cachedheight, 0, sizeof(*cachedheight) * viewheight);
// Add the view offset, rotated by the plane angle. // Add the view offset, rotated by the plane angle.
fixed_t a = -pSplat->verts[0].x + vis->viewpoint.x; fixed_t a = -pSplat->verts[0].x + vis->viewpoint.x;
@ -463,8 +471,6 @@ static void R_RasterizeFloorSplat(floorsplat_t *pSplat, vector2_t *verts, visspr
for (y = miny; y <= maxy; y++) for (y = miny; y <= maxy; y++)
{ {
boolean cliptab[MAXVIDWIDTH+1];
x1 = rastertab[y].minx>>FRACBITS; x1 = rastertab[y].minx>>FRACBITS;
x2 = rastertab[y].maxx>>FRACBITS; x2 = rastertab[y].maxx>>FRACBITS;
@ -487,10 +493,10 @@ static void R_RasterizeFloorSplat(floorsplat_t *pSplat, vector2_t *verts, visspr
continue; continue;
for (i = x1; i <= x2; i++) for (i = x1; i <= x2; i++)
cliptab[i] = (y >= mfloorclip[i] || y <= mceilingclip[i]); cliptable[i] = (y >= mfloorclip[i] || y <= mceilingclip[i]);
// clip left // clip left
while (cliptab[x1]) while (cliptable[x1])
{ {
x1++; x1++;
if (x1 >= viewwidth) if (x1 >= viewwidth)
@ -502,7 +508,7 @@ static void R_RasterizeFloorSplat(floorsplat_t *pSplat, vector2_t *verts, visspr
while (i > x1) while (i > x1)
{ {
if (cliptab[i]) if (cliptable[i])
x2 = i-1; x2 = i-1;
i--; i--;
if (i < 0) if (i < 0)
@ -562,7 +568,7 @@ static void R_RasterizeFloorSplat(floorsplat_t *pSplat, vector2_t *verts, visspr
} }
if (pSplat->angle && !pSplat->slope) if (pSplat->angle && !pSplat->slope)
memset(cachedheight, 0, sizeof(cachedheight)); memset(cachedheight, 0, sizeof(*cachedheight) * viewheight);
} }
static void prepare_rastertab(void) static void prepare_rastertab(void)

View file

@ -43,4 +43,6 @@ typedef struct floorsplat_s
void R_DrawFloorSplat(vissprite_t *spr); void R_DrawFloorSplat(vissprite_t *spr);
void R_AllocFloorSpriteTables(void);
#endif /*__R_SPLATS_H__*/ #endif /*__R_SPLATS_H__*/

View file

@ -97,7 +97,7 @@ extern angle_t clipangle;
extern angle_t doubleclipangle; extern angle_t doubleclipangle;
extern INT32 viewangletox[FINEANGLES/2]; extern INT32 viewangletox[FINEANGLES/2];
extern angle_t xtoviewangle[MAXVIDWIDTH+1]; extern angle_t *xtoviewangle;
extern fixed_t rw_distance; extern fixed_t rw_distance;
extern angle_t rw_normalangle; extern angle_t rw_normalangle;

View file

@ -63,8 +63,8 @@ typedef struct
static lighttable_t **spritelights; static lighttable_t **spritelights;
// constant arrays used for psprite clipping and initializing clipping // constant arrays used for psprite clipping and initializing clipping
INT16 negonearray[MAXVIDWIDTH]; INT16 *negonearray;
INT16 screenheightarray[MAXVIDWIDTH]; INT16 *screenheightarray;
spriteinfo_t spriteinfo[NUMSPRITES]; spriteinfo_t spriteinfo[NUMSPRITES];
@ -513,9 +513,6 @@ void R_InitSprites(void)
float fa; float fa;
#endif #endif
for (i = 0; i < MAXVIDWIDTH; i++)
negonearray[i] = -1;
#ifdef ROTSPRITE #ifdef ROTSPRITE
for (angle = 1; angle < ROTANGLES; angle++) for (angle = 1; angle < ROTANGLES; angle++)
{ {
@ -574,6 +571,34 @@ void R_ClearSprites(void)
visspritecount = clippedvissprites = 0; visspritecount = clippedvissprites = 0;
} }
static INT16 *vissprite_clipbot[MAXVISSPRITES >> VISSPRITECHUNKBITS];
static INT16 *vissprite_cliptop[MAXVISSPRITES >> VISSPRITECHUNKBITS];
static void R_AllocVisSpriteChunkMemory(UINT32 chunk)
{
vissprite_clipbot[chunk] = Z_Realloc(vissprite_clipbot[chunk], sizeof(INT16) * (VISSPRITESPERCHUNK * viewwidth), PU_STATIC, NULL);
vissprite_cliptop[chunk] = Z_Realloc(vissprite_cliptop[chunk], sizeof(INT16) * (VISSPRITESPERCHUNK * viewwidth), PU_STATIC, NULL);
for (unsigned i = 0; i < VISSPRITESPERCHUNK; i++)
{
vissprite_t *sprite = visspritechunks[chunk] + i;
sprite->clipbot = vissprite_clipbot[chunk] + (viewwidth * i);
sprite->cliptop = vissprite_cliptop[chunk] + (viewwidth * i);
}
}
void R_AllocVisSpriteMemory(void)
{
unsigned numchunks = MAXVISSPRITES >> VISSPRITECHUNKBITS;
for (unsigned i = 0; i < numchunks; i++)
{
if (visspritechunks[i])
R_AllocVisSpriteChunkMemory(i);
}
}
// //
// R_NewVisSprite // R_NewVisSprite
// //
@ -585,7 +610,10 @@ static vissprite_t *R_GetVisSprite(UINT32 num)
// Allocate chunk if necessary // Allocate chunk if necessary
if (!visspritechunks[chunk]) if (!visspritechunks[chunk])
{
Z_Malloc(sizeof(vissprite_t) * VISSPRITESPERCHUNK, PU_LEVEL, &visspritechunks[chunk]); Z_Malloc(sizeof(vissprite_t) * VISSPRITESPERCHUNK, PU_LEVEL, &visspritechunks[chunk]);
R_AllocVisSpriteChunkMemory(chunk);
}
return visspritechunks[chunk] + (num & VISSPRITEINDEXMASK); return visspritechunks[chunk] + (num & VISSPRITEINDEXMASK);
} }

View file

@ -56,8 +56,8 @@ void R_DrawFlippedMaskedColumn(column_t *column);
// Constant arrays used for psprite clipping // Constant arrays used for psprite clipping
// and initializing clipping. // and initializing clipping.
extern INT16 negonearray[MAXVIDWIDTH]; extern INT16 *negonearray;
extern INT16 screenheightarray[MAXVIDWIDTH]; extern INT16 *screenheightarray;
fixed_t R_GetShadowZ(mobj_t *thing, pslope_t **shadowslope); fixed_t R_GetShadowZ(mobj_t *thing, pslope_t **shadowslope);
@ -214,7 +214,7 @@ typedef struct vissprite_s
skincolornum_t color; skincolornum_t color;
INT16 clipbot[MAXVIDWIDTH], cliptop[MAXVIDWIDTH]; INT16 *clipbot, *cliptop;
INT32 dispoffset; // copy of mobj->dispoffset, affects ordering but not drawing INT32 dispoffset; // copy of mobj->dispoffset, affects ordering but not drawing
} vissprite_t; } vissprite_t;
@ -224,6 +224,8 @@ extern UINT32 visspritecount;
void R_ClipSprites(drawseg_t* dsstart, portal_t* portal); void R_ClipSprites(drawseg_t* dsstart, portal_t* portal);
void R_ClipVisSprite(vissprite_t *spr, INT32 x1, INT32 x2, drawseg_t* dsstart, portal_t* portal); void R_ClipVisSprite(vissprite_t *spr, INT32 x1, INT32 x2, drawseg_t* dsstart, portal_t* portal);
void R_AllocVisSpriteMemory(void);
boolean R_SpriteIsFlashing(vissprite_t *vis); boolean R_SpriteIsFlashing(vissprite_t *vis);
void R_DrawThingBoundingBox(vissprite_t *spr); void R_DrawThingBoundingBox(vissprite_t *spr);