This commit is contained in:
Lactozilla 2024-02-17 00:15:10 -03:00
parent 2747e30f8c
commit d93a19bddb
17 changed files with 204 additions and 756 deletions

View file

@ -709,13 +709,6 @@ extern int
/// 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

@ -829,13 +829,14 @@ void HWR_GetLevelFlat(levelflat_t *levelflat)
return; return;
} }
INT32 texturenum = texturetranslation[levelflat->texture_id]; if (levelflat->texture_id == NO_TEXTURE_NUM)
if (texturenum <= 0)
{ {
HWR_SetCurrentTexture(NULL); HWR_SetCurrentTexture(NULL);
return; return;
} }
INT32 texturenum = texturetranslation[levelflat->texture_id];
GLMapTexture_t *grtex = &gl_flats[texturenum]; GLMapTexture_t *grtex = &gl_flats[texturenum];
GLMipmap_t *grMipmap = &grtex->mipmap; GLMipmap_t *grMipmap = &grtex->mipmap;

View file

@ -320,16 +320,12 @@ void gld_clipper_Clear(void)
#define RMUL (1.6f/1.333333f) #define RMUL (1.6f/1.333333f)
angle_t gld_FrustumAngle(angle_t tiltangle) angle_t gld_FrustumAngle(float render_fov, angle_t tiltangle)
{ {
double floatangle; double floatangle;
angle_t a1; angle_t a1;
float tilt = (float)fabs(((double)(int)tiltangle) / ANG1); float tilt = (float)fabs(((double)(int)tiltangle) / ANG1);
// NEWCLIP TODO: SRB2CBTODO: make a global render_fov for this function
float render_fov = FIXED_TO_FLOAT(cv_fov.value);
float render_fovratio = (float)BASEVIDWIDTH / (float)BASEVIDHEIGHT; // SRB2CBTODO: NEWCLIPTODO: Is this right? float render_fovratio = (float)BASEVIDWIDTH / (float)BASEVIDHEIGHT; // SRB2CBTODO: NEWCLIPTODO: Is this right?
float render_multiplier = 64.0f / render_fovratio / RMUL; float render_multiplier = 64.0f / render_fovratio / RMUL;

View file

@ -17,7 +17,7 @@
boolean gld_clipper_SafeCheckRange(angle_t startAngle, angle_t endAngle); boolean gld_clipper_SafeCheckRange(angle_t startAngle, angle_t endAngle);
void gld_clipper_SafeAddClipRange(angle_t startangle, angle_t endangle); void gld_clipper_SafeAddClipRange(angle_t startangle, angle_t endangle);
void gld_clipper_Clear(void); void gld_clipper_Clear(void);
angle_t gld_FrustumAngle(angle_t tiltangle); angle_t gld_FrustumAngle(float render_fov, angle_t tiltangle);
#ifdef HAVE_SPHEREFRUSTRUM #ifdef HAVE_SPHEREFRUSTRUM
void gld_FrustrumSetup(void); void gld_FrustrumSetup(void);
boolean gld_SphereInFrustum(float x, float y, float z, float radius); boolean gld_SphereInFrustum(float x, float y, float z, float radius);

View file

@ -1316,7 +1316,7 @@ static void HWR_AddLightMapForLine(int lightnum, seg_t *line)
if ( lgl_backsector->ceilingpic == gl_frontsector->ceilingpic if ( lgl_backsector->ceilingpic == gl_frontsector->ceilingpic
&& lgl_backsector->floorpic == gl_frontsector->floorpic && lgl_backsector->floorpic == gl_frontsector->floorpic
&& lgl_backsector->lightlevel == gl_frontsector->lightlevel && lgl_backsector->lightlevel == gl_frontsector->lightlevel
&& lgl_curline->sidedef->midtexture == 0) && lgl_curline->sidedef->midtexture == NO_TEXTURE_NUM)
{ {
return; return;
} }

View file

@ -19,8 +19,10 @@
#include "hw_light.h" #include "hw_light.h"
#include "hw_drv.h" #include "hw_drv.h"
#include "hw_batching.h" #include "hw_batching.h"
#include "hw_md2.h"
#include "hw_clip.h"
#include "../i_video.h" // for rendermode == render_glide #include "../i_video.h"
#include "../v_video.h" #include "../v_video.h"
#include "../p_local.h" #include "../p_local.h"
#include "../p_setup.h" #include "../p_setup.h"
@ -42,11 +44,6 @@
#include "../r_translation.h" #include "../r_translation.h"
#include "../d_main.h" #include "../d_main.h"
#include "../p_slopes.h" #include "../p_slopes.h"
#include "hw_md2.h"
#ifdef NEWCLIP
#include "hw_clip.h"
#endif
#define R_FAKEFLOORS #define R_FAKEFLOORS
#define HWPRECIP #define HWPRECIP
@ -428,7 +425,11 @@ static void HWR_RenderPlane(subsector_t *subsector, extrasubsector_t *xsub, bool
// set texture for polygon // set texture for polygon
if (levelflat != NULL) if (levelflat != NULL)
{ {
texture_t *texture = textures[R_GetTextureNumForFlat(levelflat)]; INT32 texnum = R_GetTextureNumForFlat(levelflat);
if (texnum == NO_TEXTURE_NUM)
return;
texture_t *texture = textures[texnum];
fflatwidth = texture->width; fflatwidth = texture->width;
fflatheight = texture->height; fflatheight = texture->height;
} }
@ -776,41 +777,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)
@ -1121,7 +1087,7 @@ static void HWR_ProcessSeg(void) // Sort of like GLWall::Process in GZDoom
// two sided line // two sided line
if (gl_backsector) if (gl_backsector)
{ {
INT32 gl_toptexture = 0, gl_bottomtexture = 0; INT32 gl_toptexture = NO_TEXTURE_NUM, gl_bottomtexture = NO_TEXTURE_NUM;
fixed_t texturevpeg; fixed_t texturevpeg;
SLOPEPARAMS(gl_backsector->c_slope, worldhigh, worldhighslope, gl_backsector->ceilingheight) SLOPEPARAMS(gl_backsector->c_slope, worldhigh, worldhighslope, gl_backsector->ceilingheight)
@ -1148,7 +1114,7 @@ static void HWR_ProcessSeg(void) // Sort of like GLWall::Process in GZDoom
gl_bottomtexture = R_GetTextureNum(gl_sidedef->bottomtexture); gl_bottomtexture = R_GetTextureNum(gl_sidedef->bottomtexture);
// check TOP TEXTURE // check TOP TEXTURE
if ((worldhighslope < worldtopslope || worldhigh < worldtop) && gl_toptexture) if ((worldhighslope < worldtopslope || worldhigh < worldtop) && gl_toptexture != NO_TEXTURE_NUM)
{ {
grTex = HWR_GetTexture(gl_toptexture); grTex = HWR_GetTexture(gl_toptexture);
xscale = FixedToFloat(gl_sidedef->scalex_top); xscale = FixedToFloat(gl_sidedef->scalex_top);
@ -1214,7 +1180,7 @@ static void HWR_ProcessSeg(void) // Sort of like GLWall::Process in GZDoom
} }
// check BOTTOM TEXTURE // check BOTTOM TEXTURE
if ((worldlowslope > worldbottomslope || worldlow > worldbottom) && gl_bottomtexture) if ((worldlowslope > worldbottomslope || worldlow > worldbottom) && gl_bottomtexture != NO_TEXTURE_NUM)
{ {
grTex = HWR_GetTexture(gl_bottomtexture); grTex = HWR_GetTexture(gl_bottomtexture);
xscale = FixedToFloat(gl_sidedef->scalex_bottom); xscale = FixedToFloat(gl_sidedef->scalex_bottom);
@ -1277,7 +1243,7 @@ static void HWR_ProcessSeg(void) // Sort of like GLWall::Process in GZDoom
} }
// Render midtexture if there's one. Determine if it's visible first, though // Render midtexture if there's one. Determine if it's visible first, though
if (gl_midtexture && HWR_BlendMidtextureSurface(&Surf)) if (gl_midtexture != NO_TEXTURE_NUM && HWR_BlendMidtextureSurface(&Surf))
{ {
sector_t *front, *back; sector_t *front, *back;
fixed_t texheight = FixedDiv(textureheight[gl_midtexture], gl_sidedef->scaley_mid); fixed_t texheight = FixedDiv(textureheight[gl_midtexture], gl_sidedef->scaley_mid);
@ -1488,7 +1454,7 @@ static void HWR_ProcessSeg(void) // Sort of like GLWall::Process in GZDoom
else else
{ {
// Single sided line... Deal only with the middletexture (if one exists) // Single sided line... Deal only with the middletexture (if one exists)
if (gl_midtexture && gl_linedef->special != SPECIAL_HORIZON_LINE) // (Ignore horizon line for OGL) if (gl_midtexture != NO_TEXTURE_NUM && gl_linedef->special != SPECIAL_HORIZON_LINE) // (Ignore horizon line for OGL)
{ {
grTex = HWR_GetTexture(gl_midtexture); grTex = HWR_GetTexture(gl_midtexture);
xscale = FixedToFloat(gl_sidedef->scalex_mid); xscale = FixedToFloat(gl_sidedef->scalex_mid);
@ -1628,6 +1594,8 @@ static void HWR_ProcessSeg(void) // Sort of like GLWall::Process in GZDoom
} }
texnum = R_GetTextureNum(side->midtexture); texnum = R_GetTextureNum(side->midtexture);
if (texnum == NO_TEXTURE_NUM)
continue;
h = P_GetFFloorTopZAt (rover, v1x, v1y); h = P_GetFFloorTopZAt (rover, v1x, v1y);
hS = P_GetFFloorTopZAt (rover, v2x, v2y); hS = P_GetFFloorTopZAt (rover, v2x, v2y);
@ -1775,6 +1743,8 @@ static void HWR_ProcessSeg(void) // Sort of like GLWall::Process in GZDoom
} }
texnum = R_GetTextureNum(side->midtexture); texnum = R_GetTextureNum(side->midtexture);
if (texnum == NO_TEXTURE_NUM)
continue;
h = P_GetFFloorTopZAt (rover, v1x, v1y); h = P_GetFFloorTopZAt (rover, v1x, v1y);
hS = P_GetFFloorTopZAt (rover, v2x, v2y); hS = P_GetFFloorTopZAt (rover, v2x, v2y);
@ -1868,8 +1838,8 @@ 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 static 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
static boolean CheckClip(seg_t * seg, sector_t * afrontsector, sector_t * abacksector) static boolean CheckClip(seg_t * seg, sector_t * afrontsector, sector_t * abacksector)
@ -1934,8 +1904,8 @@ static boolean CheckClip(seg_t * seg, sector_t * afrontsector, sector_t * abacks
if (backc1 <= backf1 && backc2 <= backf2) if (backc1 <= backf1 && backc2 <= backf2)
{ {
// preserve a kind of transparent door/lift special effect: // preserve a kind of transparent door/lift special effect:
if (((backc1 >= frontc1 && backc2 >= frontc2) || seg->sidedef->toptexture) if (((backc1 >= frontc1 && backc2 >= frontc2) || (seg->sidedef->toptexture != NO_TEXTURE_NUM))
&& ((backf1 <= frontf1 && backf2 <= frontf2) || seg->sidedef->bottomtexture)) && ((backf1 <= frontf1 && backf2 <= frontf2) || (seg->sidedef->bottomtexture != NO_TEXTURE_NUM)))
{ {
checkforemptylines = false; checkforemptylines = false;
return true; return true;
@ -1961,295 +1931,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.
@ -2259,11 +1940,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;
@ -2299,8 +1975,7 @@ 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;
@ -2312,91 +1987,10 @@ 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;
bothceilingssky = bothfloorssky = false; bothceilingssky = bothfloorssky = false;
#ifdef NEWCLIP
if (!line->backsector) if (!line->backsector)
{ {
gld_clipper_SafeAddClipRange(angle2, angle1); gld_clipper_SafeAddClipRange(angle2, angle1);
@ -2438,116 +2032,7 @@ static void HWR_AddLine(seg_t * line)
return; return;
} }
HWR_ProcessSeg(); // Doesn't need arguments because they're defined globally :D HWR_ProcessSeg();
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
@ -2562,10 +2047,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.
@ -2591,59 +2072,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
} }
// //
@ -2729,7 +2160,11 @@ static void HWR_RenderPolyObjectPlane(polyobj_t *polysector, boolean isceiling,
// set texture for polygon // set texture for polygon
if (levelflat != NULL) if (levelflat != NULL)
{ {
texture_t *texture = textures[R_GetTextureNumForFlat(levelflat)]; INT32 texnum = R_GetTextureNumForFlat(levelflat);
if (texnum == NO_TEXTURE_NUM)
return;
texture_t *texture = textures[texnum];
fflatwidth = texture->width; fflatwidth = texture->width;
fflatheight = texture->height; fflatheight = texture->height;
} }
@ -6171,18 +5606,11 @@ void HWR_RenderSkyboxView(INT32 viewnumber, player_t *player)
drawcount = 0; drawcount = 0;
#ifdef NEWCLIP angle_t a1 = gld_FrustumAngle(fpov, gl_aimingangle);
if (rendermode == render_opengl) gld_clipper_Clear();
{ gld_clipper_SafeAddClipRange(viewangle + a1, viewangle - a1);
angle_t a1 = gld_FrustumAngle(gl_aimingangle);
gld_clipper_Clear();
gld_clipper_SafeAddClipRange(viewangle + a1, viewangle - a1);
#ifdef HAVE_SPHEREFRUSTRUM #ifdef HAVE_SPHEREFRUSTRUM
gld_FrustrumSetup(); gld_FrustrumSetup();
#endif
}
#else
HWR_ClearClipSegs();
#endif #endif
//04/01/2000: Hurdler: added for T&L //04/01/2000: Hurdler: added for T&L
@ -6364,18 +5792,11 @@ void HWR_RenderPlayerView(INT32 viewnumber, player_t *player)
drawcount = 0; drawcount = 0;
#ifdef NEWCLIP angle_t a1 = gld_FrustumAngle(fpov, gl_aimingangle);
if (rendermode == render_opengl) gld_clipper_Clear();
{ gld_clipper_SafeAddClipRange(viewangle + a1, viewangle - a1);
angle_t a1 = gld_FrustumAngle(gl_aimingangle);
gld_clipper_Clear();
gld_clipper_SafeAddClipRange(viewangle + a1, viewangle - a1);
#ifdef HAVE_SPHEREFRUSTRUM #ifdef HAVE_SPHEREFRUSTRUM
gld_FrustrumSetup(); gld_FrustrumSetup();
#endif
}
#else
HWR_ClearClipSegs();
#endif #endif
//04/01/2000: Hurdler: added for T&L //04/01/2000: Hurdler: added for T&L
@ -6554,10 +5975,6 @@ void HWR_AddCommands(void)
CV_RegisterVar(&cv_glbatching); CV_RegisterVar(&cv_glbatching);
CV_RegisterVar(&cv_glwireframe); CV_RegisterVar(&cv_glwireframe);
#ifndef NEWCLIP
CV_RegisterVar(&cv_glclipwalls);
#endif
} }
// -------------------------------------------------------------------------- // --------------------------------------------------------------------------

View file

@ -499,7 +499,7 @@ void P_LineOpening(line_t *linedef, mobj_t *mobj)
fixed_t texmid, delta1, delta2; fixed_t texmid, delta1, delta2;
INT32 texnum = R_GetTextureNum(side->midtexture); // make sure the texture is actually valid INT32 texnum = R_GetTextureNum(side->midtexture); // make sure the texture is actually valid
if (texnum) { if (texnum != NO_TEXTURE_NUM) {
// Get the midtexture's height // Get the midtexture's height
texheight = textures[texnum]->height << FRACBITS; texheight = textures[texnum]->height << FRACBITS;

View file

@ -585,20 +585,20 @@ Ploadflat (levelflat_t *levelflat, const char *flatname, boolean resize)
// Look for a flat // Look for a flat
int texturenum = R_CheckFlatNumForName(levelflat->name); int texturenum = R_CheckFlatNumForName(levelflat->name);
if (texturenum <= 0) if (texturenum == NO_TEXTURE_NUM)
{ {
// If we can't find a flat, try looking for a texture! // If we can't find a flat, try looking for a texture!
texturenum = R_CheckTextureNumForName(levelflat->name); texturenum = R_CheckTextureNumForName(levelflat->name);
if (texturenum <= 0) if (texturenum == NO_TEXTURE_NUM)
{ {
// Use "not found" texture // Use "not found" texture
texturenum = R_CheckTextureNumForName("REDWALL"); texturenum = R_CheckTextureNumForName("REDWALL");
// Give up? // Give up?
if (texturenum <= 0) if (texturenum == NO_TEXTURE_NUM)
{ {
levelflat->type = LEVELFLAT_NONE; levelflat->type = LEVELFLAT_NONE;
texturenum = -1; texturenum = NO_TEXTURE_NUM;
} }
} }
} }
@ -1331,12 +1331,12 @@ static void P_LoadSidedefs(UINT8 *data)
// SoM: R_CreateColormap will only create a colormap in software mode... // SoM: R_CreateColormap will only create a colormap in software mode...
// Perhaps we should just call it instead of doing the calculations here. // Perhaps we should just call it instead of doing the calculations here.
sd->colormap_data = R_CreateColormapFromLinedef(msd->toptexture, msd->midtexture, msd->bottomtexture); sd->colormap_data = R_CreateColormapFromLinedef(msd->toptexture, msd->midtexture, msd->bottomtexture);
sd->toptexture = sd->midtexture = sd->bottomtexture = 0; sd->toptexture = sd->midtexture = sd->bottomtexture = NO_TEXTURE_NUM;
break; break;
case 413: // Change music case 413: // Change music
{ {
sd->toptexture = sd->midtexture = sd->bottomtexture = 0; sd->toptexture = sd->midtexture = sd->bottomtexture = NO_TEXTURE_NUM;
if (!isfrontside) if (!isfrontside)
break; break;
@ -1379,7 +1379,7 @@ static void P_LoadSidedefs(UINT8 *data)
case 4: // Speed pad parameters case 4: // Speed pad parameters
case 414: // Play SFX case 414: // Play SFX
{ {
sd->toptexture = sd->midtexture = sd->bottomtexture = 0; sd->toptexture = sd->midtexture = sd->bottomtexture = NO_TEXTURE_NUM;
if (!isfrontside) if (!isfrontside)
break; break;
@ -1421,7 +1421,7 @@ static void P_LoadSidedefs(UINT8 *data)
{ {
char process[8*3+1]; char process[8*3+1];
memset(process,0,8*3+1); memset(process,0,8*3+1);
sd->toptexture = sd->midtexture = sd->bottomtexture = 0; sd->toptexture = sd->midtexture = sd->bottomtexture = NO_TEXTURE_NUM;
if (msd->toptexture[0] == '-' && msd->toptexture[1] == '\0') if (msd->toptexture[0] == '-' && msd->toptexture[1] == '\0')
break; break;
else else
@ -2600,11 +2600,11 @@ static void P_WriteTextmap(void)
fprintf(f, "scalex_bottom = %f;\n", FIXED_TO_FLOAT(wsides[i].scalex_bottom)); fprintf(f, "scalex_bottom = %f;\n", FIXED_TO_FLOAT(wsides[i].scalex_bottom));
if (wsides[i].scaley_bottom != FRACUNIT) if (wsides[i].scaley_bottom != FRACUNIT)
fprintf(f, "scaley_bottom = %f;\n", FIXED_TO_FLOAT(wsides[i].scaley_bottom)); fprintf(f, "scaley_bottom = %f;\n", FIXED_TO_FLOAT(wsides[i].scaley_bottom));
if (wsides[i].toptexture > 0 && wsides[i].toptexture < numtextures) if (wsides[i].toptexture >= 0 && wsides[i].toptexture < numtextures)
fprintf(f, "texturetop = \"%.*s\";\n", 8, textures[wsides[i].toptexture]->name); fprintf(f, "texturetop = \"%.*s\";\n", 8, textures[wsides[i].toptexture]->name);
if (wsides[i].bottomtexture > 0 && wsides[i].bottomtexture < numtextures) if (wsides[i].bottomtexture >= 0 && wsides[i].bottomtexture < numtextures)
fprintf(f, "texturebottom = \"%.*s\";\n", 8, textures[wsides[i].bottomtexture]->name); fprintf(f, "texturebottom = \"%.*s\";\n", 8, textures[wsides[i].bottomtexture]->name);
if (wsides[i].midtexture > 0 && wsides[i].midtexture < numtextures) if (wsides[i].midtexture >= 0 && wsides[i].midtexture < numtextures)
fprintf(f, "texturemiddle = \"%.*s\";\n", 8, textures[wsides[i].midtexture]->name); fprintf(f, "texturemiddle = \"%.*s\";\n", 8, textures[wsides[i].midtexture]->name);
if (wsides[i].repeatcnt != 0) if (wsides[i].repeatcnt != 0)
fprintf(f, "repeatcnt = %d;\n", wsides[i].repeatcnt); fprintf(f, "repeatcnt = %d;\n", wsides[i].repeatcnt);

View file

@ -847,11 +847,11 @@ static fixed_t P_FindShortestUpperAround(INT32 secnum)
if (twoSided(secnum, i)) if (twoSided(secnum, i))
{ {
side = getSide(secnum,i,0); side = getSide(secnum,i,0);
if (side->toptexture > 0) if (side->toptexture != NO_TEXTURE_NUM)
if (textureheight[side->toptexture] < minsize) if (textureheight[side->toptexture] < minsize)
minsize = textureheight[side->toptexture]; minsize = textureheight[side->toptexture];
side = getSide(secnum,i,1); side = getSide(secnum,i,1);
if (side->toptexture > 0) if (side->toptexture != NO_TEXTURE_NUM)
if (textureheight[side->toptexture] < minsize) if (textureheight[side->toptexture] < minsize)
minsize = textureheight[side->toptexture]; minsize = textureheight[side->toptexture];
} }
@ -2856,18 +2856,18 @@ static void P_ProcessLineSpecial(line_t *line, mobj_t *mo, sector_t *callsec)
if (line->args[1] != TMSD_BACK) if (line->args[1] != TMSD_BACK)
{ {
this = &sides[lines[linenum].sidenum[0]]; this = &sides[lines[linenum].sidenum[0]];
if (always || this->toptexture) this->toptexture = setfront->toptexture; if (always || this->toptexture != NO_TEXTURE_NUM) this->toptexture = setfront->toptexture;
if (always || this->midtexture) this->midtexture = setfront->midtexture; if (always || this->midtexture != NO_TEXTURE_NUM) this->midtexture = setfront->midtexture;
if (always || this->bottomtexture) this->bottomtexture = setfront->bottomtexture; if (always || this->bottomtexture != NO_TEXTURE_NUM) this->bottomtexture = setfront->bottomtexture;
} }
// Back side // Back side
if (line->args[1] != TMSD_FRONT && lines[linenum].sidenum[1] != NO_SIDEDEF) if (line->args[1] != TMSD_FRONT && lines[linenum].sidenum[1] != NO_SIDEDEF)
{ {
this = &sides[lines[linenum].sidenum[1]]; this = &sides[lines[linenum].sidenum[1]];
if (always || this->toptexture) this->toptexture = setback->toptexture; if (always || this->toptexture != NO_TEXTURE_NUM) this->toptexture = setback->toptexture;
if (always || this->midtexture) this->midtexture = setback->midtexture; if (always || this->midtexture != NO_TEXTURE_NUM) this->midtexture = setback->midtexture;
if (always || this->bottomtexture) this->bottomtexture = setback->bottomtexture; if (always || this->bottomtexture != NO_TEXTURE_NUM) this->bottomtexture = setback->bottomtexture;
} }
} }
} }

View file

@ -225,9 +225,9 @@ static INT32 R_DoorClosed(void)
backsector->ceilingheight <= backsector->floorheight backsector->ceilingheight <= backsector->floorheight
// preserve a kind of transparent door/lift special effect: // preserve a kind of transparent door/lift special effect:
&& (backsector->ceilingheight >= frontsector->ceilingheight || curline->sidedef->toptexture) && (backsector->ceilingheight >= frontsector->ceilingheight || (curline->sidedef->toptexture != NO_TEXTURE_NUM))
&& (backsector->floorheight <= frontsector->floorheight || curline->sidedef->bottomtexture); && (backsector->floorheight <= frontsector->floorheight || (curline->sidedef->bottomtexture != NO_TEXTURE_NUM));
} }
// //
@ -383,7 +383,7 @@ boolean R_IsEmptyLine(seg_t *line, sector_t *front, sector_t *back)
&& back->f_slope == front->f_slope && back->f_slope == front->f_slope
&& back->c_slope == front->c_slope && back->c_slope == front->c_slope
&& back->lightlevel == front->lightlevel && back->lightlevel == front->lightlevel
&& !line->sidedef->midtexture && line->sidedef->midtexture == NO_TEXTURE_NUM
// Check offsets and scale too! // Check offsets and scale too!
&& back->floorxoffset == front->floorxoffset && back->floorxoffset == front->floorxoffset
&& back->flooryoffset == front->flooryoffset && back->flooryoffset == front->flooryoffset
@ -532,7 +532,7 @@ static void R_AddLine(seg_t *line)
if (bothceilingssky && bothfloorssky) // everything's sky? let's save us a bit of time then if (bothceilingssky && bothfloorssky) // everything's sky? let's save us a bit of time then
{ {
if (!line->polyseg && if (!line->polyseg &&
!line->sidedef->midtexture line->sidedef->midtexture == NO_TEXTURE_NUM
&& ((!frontsector->ffloors && !backsector->ffloors) && ((!frontsector->ffloors && !backsector->ffloors)
|| Tag_Compare(&frontsector->tags, &backsector->tags))) || Tag_Compare(&frontsector->tags, &backsector->tags)))
return; // line is empty, don't even bother return; // line is empty, don't even bother
@ -566,8 +566,8 @@ static void R_AddLine(seg_t *line)
// Check for automap fix. Store in doorclosed for r_segs.c // Check for automap fix. Store in doorclosed for r_segs.c
doorclosed = (backc1 <= backf1 && backc2 <= backf2 doorclosed = (backc1 <= backf1 && backc2 <= backf2
&& ((backc1 >= frontc1 && backc2 >= frontc2) || curline->sidedef->toptexture) && ((backc1 >= frontc1 && backc2 >= frontc2) || (curline->sidedef->toptexture != NO_TEXTURE_NUM))
&& ((backf1 <= frontf1 && backf2 >= frontf2) || curline->sidedef->bottomtexture)); && ((backf1 <= frontf1 && backf2 >= frontf2) || (curline->sidedef->bottomtexture != NO_TEXTURE_NUM)));
if (doorclosed) if (doorclosed)
goto clipsolid; goto clipsolid;

View file

@ -27,6 +27,8 @@
#include "taglist.h" #include "taglist.h"
#define NO_TEXTURE_NUM -1
// //
// ClipWallSegment // ClipWallSegment
// Clips the given range of columns // Clips the given range of columns

View file

@ -847,7 +847,7 @@ boolean Picture_CheckIfDoomPatch(softwarepatch_t *patch, size_t size)
* \param texnum The texture number. * \param texnum The texture number.
* \return The converted flat. * \return The converted flat.
*/ */
void *Picture_TextureToFlat(size_t texnum) void *Picture_TextureToFlat(INT32 texnum)
{ {
texture_t *texture; texture_t *texture;
@ -856,7 +856,7 @@ void *Picture_TextureToFlat(size_t texnum)
UINT8 *desttop, *dest, *deststop; UINT8 *desttop, *dest, *deststop;
UINT8 *source; UINT8 *source;
if (texnum >= (unsigned)numtextures) if (texnum < 0 || texnum >= numtextures)
I_Error("Picture_TextureToFlat: invalid texture number!"); I_Error("Picture_TextureToFlat: invalid texture number!");
// Check the texture cache // Check the texture cache

View file

@ -76,7 +76,7 @@ void *Picture_GetPatchPixel(
INT32 x, INT32 y, INT32 x, INT32 y,
pictureflags_t flags); pictureflags_t flags);
void *Picture_TextureToFlat(size_t texnum); void *Picture_TextureToFlat(INT32 texnum);
INT32 Picture_FormatBPP(pictureformat_t format); INT32 Picture_FormatBPP(pictureformat_t format);
boolean Picture_IsPatchFormat(pictureformat_t format); boolean Picture_IsPatchFormat(pictureformat_t format);

View file

@ -1003,7 +1003,11 @@ void R_DrawSinglePlane(visplane_t *pl)
if (ds_source == NULL) if (ds_source == NULL)
return; return;
texture_t *texture = textures[R_GetTextureNumForFlat(levelflat)]; INT32 texnum = R_GetTextureNumForFlat(levelflat);
if (texnum == NO_TEXTURE_NUM)
return;
texture_t *texture = textures[texnum];
ds_flatwidth = texture->width; ds_flatwidth = texture->width;
ds_flatheight = texture->height; ds_flatheight = texture->height;

View file

@ -123,10 +123,13 @@ void R_RenderMaskedSegRange(drawseg_t *ds, INT32 x1, INT32 x2)
// OPTIMIZE: get rid of LIGHTSEGSHIFT globally // OPTIMIZE: get rid of LIGHTSEGSHIFT globally
curline = ds->curline; curline = ds->curline;
frontsector = curline->frontsector;
backsector = curline->backsector;
sidedef = curline->sidedef; sidedef = curline->sidedef;
texnum = R_GetTextureNum(sidedef->midtexture); texnum = R_GetTextureNum(sidedef->midtexture);
if (texnum == NO_TEXTURE_NUM)
return;
frontsector = curline->frontsector;
backsector = curline->backsector;
windowbottom = windowtop = sprbotscreen = INT32_MAX; windowbottom = windowtop = sprbotscreen = INT32_MAX;
ldef = curline->linedef; ldef = curline->linedef;
@ -532,6 +535,8 @@ void R_RenderThickSideRange(drawseg_t *ds, INT32 x1, INT32 x2, ffloor_t *pfloor)
} }
texnum = R_GetTextureNum(sidedef->midtexture); texnum = R_GetTextureNum(sidedef->midtexture);
if (texnum == NO_TEXTURE_NUM)
return;
if (pfloor->fofflags & FOF_TRANSLUCENT) if (pfloor->fofflags & FOF_TRANSLUCENT)
{ {
@ -1015,11 +1020,11 @@ static void R_RenderSegLoop (void)
INT32 bottom; INT32 bottom;
INT32 i; INT32 i;
if (midtexture) if (midtexture != NO_TEXTURE_NUM)
R_CheckTextureCache(midtexture); R_CheckTextureCache(midtexture);
if (toptexture) if (toptexture != NO_TEXTURE_NUM)
R_CheckTextureCache(toptexture); R_CheckTextureCache(toptexture);
if (bottomtexture) if (bottomtexture != NO_TEXTURE_NUM)
R_CheckTextureCache(bottomtexture); R_CheckTextureCache(bottomtexture);
for (; rw_x < rw_stopx; rw_x++) for (; rw_x < rw_stopx; rw_x++)
@ -1242,7 +1247,7 @@ static void R_RenderSegLoop (void)
frontscale[rw_x] = rw_scale; frontscale[rw_x] = rw_scale;
// draw the wall tiers // draw the wall tiers
if (midtexture) if (midtexture != NO_TEXTURE_NUM)
{ {
// single sided line // single sided line
if (yl <= yh && yh >= 0 && yl < viewheight) if (yl <= yh && yh >= 0 && yl < viewheight)
@ -1293,7 +1298,7 @@ static void R_RenderSegLoop (void)
INT16 bottomclip = (yh < viewheight) ? ((yh < -1) ? -1 : (INT16)((INT16)yh + 1)) : (INT16)viewheight; INT16 bottomclip = (yh < viewheight) ? ((yh < -1) ? -1 : (INT16)((INT16)yh + 1)) : (INT16)viewheight;
// two sided line // two sided line
if (toptexture) if (toptexture != NO_TEXTURE_NUM)
{ {
// top wall // top wall
mid = pixhigh>>HEIGHTBITS; mid = pixhigh>>HEIGHTBITS;
@ -1340,7 +1345,7 @@ static void R_RenderSegLoop (void)
else if (markceiling && (!rw_ceilingmarked)) // no top wall else if (markceiling && (!rw_ceilingmarked)) // no top wall
ceilingclip[rw_x] = topclip; ceilingclip[rw_x] = topclip;
if (bottomtexture) if (bottomtexture != NO_TEXTURE_NUM)
{ {
// bottom wall // bottom wall
mid = (pixlow+HEIGHTUNIT-1)>>HEIGHTBITS; mid = (pixlow+HEIGHTUNIT-1)>>HEIGHTBITS;
@ -1403,7 +1408,7 @@ static void R_RenderSegLoop (void)
maskedtextureheight[rw_x] = min(rw_midtexturemid, rw_midtextureback); maskedtextureheight[rw_x] = min(rw_midtexturemid, rw_midtextureback);
} }
if (midtexture || maskedtextureheight) if (midtexture != NO_TEXTURE_NUM || maskedtextureheight)
{ {
if (oldtexturecolumn != -1) if (oldtexturecolumn != -1)
{ {
@ -1704,7 +1709,8 @@ void R_StoreWallRange(INT32 start, INT32 stop)
worldbottom -= viewz; worldbottom -= viewz;
worldbottomslope -= viewz; worldbottomslope -= viewz;
midtexture = toptexture = bottomtexture = maskedtexture = 0; midtexture = toptexture = bottomtexture = NO_TEXTURE_NUM;
maskedtexture = false;
ds_p->maskedtexturecol = NULL; ds_p->maskedtexturecol = NULL;
ds_p->numthicksides = numthicksides = 0; ds_p->numthicksides = numthicksides = 0;
ds_p->thicksidecol = NULL; ds_p->thicksidecol = NULL;
@ -1752,6 +1758,8 @@ void R_StoreWallRange(INT32 start, INT32 stop)
rw_midtexturescaley = sidedef->scaley_mid; rw_midtexturescaley = sidedef->scaley_mid;
rw_invmidtexturescalex = FixedDiv(FRACUNIT, rw_midtexturescalex); rw_invmidtexturescalex = FixedDiv(FRACUNIT, rw_midtexturescalex);
segtextured = false;
if (!backsector) if (!backsector)
{ {
midtexture = R_GetTextureNum(sidedef->midtexture); midtexture = R_GetTextureNum(sidedef->midtexture);
@ -1759,56 +1767,61 @@ void R_StoreWallRange(INT32 start, INT32 stop)
// a single sided line is terminal, so it must mark ends // a single sided line is terminal, so it must mark ends
markfloor = markceiling = true; markfloor = markceiling = true;
fixed_t rowoffset = sidedef->rowoffset + sidedef->offsety_mid; if (midtexture != NO_TEXTURE_NUM) // tsk tsk
fixed_t texheight = textureheight[midtexture];
if (rw_midtexturescaley > 0)
{ {
if (linedef->flags & ML_NOSKEW) fixed_t rowoffset = sidedef->rowoffset + sidedef->offsety_mid;
fixed_t texheight = textureheight[midtexture];
if (rw_midtexturescaley > 0)
{ {
if (linedef->flags & ML_DONTPEGBOTTOM) if (linedef->flags & ML_NOSKEW)
rw_midtexturemid = FixedMul(frontsector->floorheight - viewz, rw_midtexturescaley) + texheight; {
if (linedef->flags & ML_DONTPEGBOTTOM)
rw_midtexturemid = FixedMul(frontsector->floorheight - viewz, rw_midtexturescaley) + texheight;
else
rw_midtexturemid = FixedMul(frontsector->ceilingheight - viewz, rw_midtexturescaley);
}
else if (linedef->flags & ML_DONTPEGBOTTOM)
{
rw_midtexturemid = FixedMul(worldbottom, rw_midtexturescaley) + texheight;
rw_midtextureslide = floorfrontslide;
}
else else
rw_midtexturemid = FixedMul(frontsector->ceilingheight - viewz, rw_midtexturescaley); {
} // top of texture at top
else if (linedef->flags & ML_DONTPEGBOTTOM) rw_midtexturemid = FixedMul(worldtop, rw_midtexturescaley);
{ rw_midtextureslide = ceilingfrontslide;
rw_midtexturemid = FixedMul(worldbottom, rw_midtexturescaley) + texheight; }
rw_midtextureslide = floorfrontslide;
} }
else else
{ {
// top of texture at top // Upside down
rw_midtexturemid = FixedMul(worldtop, rw_midtexturescaley); rowoffset = -rowoffset;
rw_midtextureslide = ceilingfrontslide;
}
}
else
{
// Upside down
rowoffset = -rowoffset;
if (linedef->flags & ML_NOSKEW) if (linedef->flags & ML_NOSKEW)
{ {
if (linedef->flags & ML_DONTPEGBOTTOM) if (linedef->flags & ML_DONTPEGBOTTOM)
rw_midtexturemid = FixedMul(frontsector->floorheight - viewz, rw_midtexturescaley); rw_midtexturemid = FixedMul(frontsector->floorheight - viewz, rw_midtexturescaley);
else
rw_midtexturemid = FixedMul(frontsector->ceilingheight - viewz, rw_midtexturescaley) + texheight;
}
else if (linedef->flags & ML_DONTPEGBOTTOM)
{
rw_midtexturemid = FixedMul(worldbottom, rw_midtexturescaley);
rw_midtextureslide = floorfrontslide;
}
else else
rw_midtexturemid = FixedMul(frontsector->ceilingheight - viewz, rw_midtexturescaley) + texheight; {
// top of texture at top
rw_midtexturemid = FixedMul(worldtop, rw_midtexturescaley) + texheight;
rw_midtextureslide = ceilingfrontslide;
}
} }
else if (linedef->flags & ML_DONTPEGBOTTOM)
{
rw_midtexturemid = FixedMul(worldbottom, rw_midtexturescaley);
rw_midtextureslide = floorfrontslide;
}
else
{
// top of texture at top
rw_midtexturemid = FixedMul(worldtop, rw_midtexturescaley) + texheight;
rw_midtextureslide = ceilingfrontslide;
}
}
rw_midtexturemid += rowoffset; rw_midtexturemid += rowoffset;
segtextured = true;
}
ds_p->silhouette = SIL_BOTH; ds_p->silhouette = SIL_BOTH;
ds_p->sprtopclip = screenheightarray; ds_p->sprtopclip = screenheightarray;
@ -1982,14 +1995,16 @@ void R_StoreWallRange(INT32 start, INT32 stop)
} }
} }
fixed_t toprowoffset = sidedef->rowoffset + sidedef->offsety_top;
fixed_t botrowoffset = sidedef->rowoffset + sidedef->offsety_bottom;
// check TOP TEXTURE // check TOP TEXTURE
if (!bothceilingssky // never draw the top texture if on if (!bothceilingssky // never draw the top texture if on
&& (worldhigh < worldtop || worldhighslope < worldtopslope)) && (worldhigh < worldtop || worldhighslope < worldtopslope))
{ {
toptexture = R_GetTextureNum(sidedef->toptexture); toptexture = R_GetTextureNum(sidedef->toptexture);
}
if (toptexture != NO_TEXTURE_NUM)
{
fixed_t toprowoffset = sidedef->rowoffset + sidedef->offsety_top;
rw_toptexturescalex = sidedef->scalex_top; rw_toptexturescalex = sidedef->scalex_top;
rw_toptexturescaley = sidedef->scaley_top; rw_toptexturescaley = sidedef->scaley_top;
@ -2022,14 +2037,21 @@ void R_StoreWallRange(INT32 start, INT32 stop)
} }
rw_toptexturemid = FixedMul(rw_toptexturemid, rw_toptexturescaley); rw_toptexturemid = FixedMul(rw_toptexturemid, rw_toptexturescaley);
rw_toptexturemid += toprowoffset;
segtextured = true;
} }
// check BOTTOM TEXTURE // check BOTTOM TEXTURE
if (!bothfloorssky // never draw the bottom texture if on if (!bothfloorssky // never draw the bottom texture if on
&& (worldlow > worldbottom || worldlowslope > worldbottomslope)) // Only if VISIBLE!!! && (worldlow > worldbottom || worldlowslope > worldbottomslope))
{ {
// bottom texture
bottomtexture = R_GetTextureNum(sidedef->bottomtexture); bottomtexture = R_GetTextureNum(sidedef->bottomtexture);
}
if (bottomtexture != NO_TEXTURE_NUM)
{
fixed_t botrowoffset = sidedef->rowoffset + sidedef->offsety_bottom;
rw_bottomtexturescalex = sidedef->scalex_bottom; rw_bottomtexturescalex = sidedef->scalex_bottom;
rw_bottomtexturescaley = sidedef->scaley_bottom; rw_bottomtexturescaley = sidedef->scaley_bottom;
@ -2062,10 +2084,10 @@ void R_StoreWallRange(INT32 start, INT32 stop)
} }
rw_bottomtexturemid = FixedMul(rw_bottomtexturemid, rw_bottomtexturescaley); rw_bottomtexturemid = FixedMul(rw_bottomtexturemid, rw_bottomtexturescaley);
} rw_bottomtexturemid += botrowoffset;
rw_toptexturemid += toprowoffset; segtextured = true;
rw_bottomtexturemid += botrowoffset; }
// allocate space for masked texture tables // allocate space for masked texture tables
R_AllocTextureColumnTables(rw_stopx - start); R_AllocTextureColumnTables(rw_stopx - start);
@ -2260,10 +2282,13 @@ void R_StoreWallRange(INT32 start, INT32 stop)
} }
ds_p->numthicksides = numthicksides = i; ds_p->numthicksides = numthicksides = i;
if (numthicksides > 0)
segtextured = true;
} }
// masked midtexture // masked midtexture
if (sidedef->midtexture > 0 && sidedef->midtexture < numtextures) if (sidedef->midtexture >= 0 && sidedef->midtexture < numtextures)
{ {
ds_p->maskedtexturecol = maskedtexturecol = curtexturecolumntable - rw_x; ds_p->maskedtexturecol = maskedtexturecol = curtexturecolumntable - rw_x;
curtexturecolumntable += rw_stopx - rw_x; curtexturecolumntable += rw_stopx - rw_x;
@ -2271,6 +2296,7 @@ void R_StoreWallRange(INT32 start, INT32 stop)
maskedtextureheight = ds_p->maskedtextureheight; // note to red, this == &(ds_p->maskedtextureheight[0]) maskedtextureheight = ds_p->maskedtextureheight; // note to red, this == &(ds_p->maskedtextureheight[0])
maskedtexture = true; maskedtexture = true;
segtextured = true;
if (curline->polyseg) if (curline->polyseg)
{ {
@ -2321,8 +2347,6 @@ void R_StoreWallRange(INT32 start, INT32 stop)
} }
// calculate rw_offset (only needed for textured lines) // calculate rw_offset (only needed for textured lines)
segtextured = midtexture || toptexture || bottomtexture || maskedtexture || (numthicksides > 0);
if (segtextured) if (segtextured)
{ {
fixed_t sideoffset = sidedef->textureoffset; fixed_t sideoffset = sidedef->textureoffset;
@ -2536,7 +2560,7 @@ void R_StoreWallRange(INT32 start, INT32 stop)
worldhighslope >>= 4; worldhighslope >>= 4;
worldlowslope >>= 4; worldlowslope >>= 4;
if (toptexture) if (toptexture != NO_TEXTURE_NUM)
{ {
pixhigh = (centeryfrac>>4) - FixedMul (worldhigh, rw_scale); pixhigh = (centeryfrac>>4) - FixedMul (worldhigh, rw_scale);
pixhighstep = -FixedMul (rw_scalestep,worldhigh); pixhighstep = -FixedMul (rw_scalestep,worldhigh);
@ -2547,7 +2571,7 @@ void R_StoreWallRange(INT32 start, INT32 stop)
} }
} }
if (bottomtexture) if (bottomtexture != NO_TEXTURE_NUM)
{ {
pixlow = (centeryfrac>>4) - FixedMul (worldlow, rw_scale); pixlow = (centeryfrac>>4) - FixedMul (worldlow, rw_scale);
pixlowstep = -FixedMul (rw_scalestep,worldlow); pixlowstep = -FixedMul (rw_scalestep,worldlow);
@ -2730,7 +2754,7 @@ void R_StoreWallRange(INT32 start, INT32 stop)
// Don't mark ceiling flat lines for polys unless this line has an upper texture, otherwise we get flat leakage pulling downward // Don't mark ceiling flat lines for polys unless this line has an upper texture, otherwise we get flat leakage pulling downward
// (If it DOES have an upper texture and we do this, the ceiling won't render at all) // (If it DOES have an upper texture and we do this, the ceiling won't render at all)
if (curline->polyseg && !curline->sidedef->toptexture) if (curline->polyseg && curline->sidedef->toptexture == NO_TEXTURE_NUM)
markceiling = false; markceiling = false;
} }
@ -2744,7 +2768,7 @@ void R_StoreWallRange(INT32 start, INT32 stop)
// Don't mark floor flat lines for polys unless this line has a lower texture, otherwise we get flat leakage pulling upward // Don't mark floor flat lines for polys unless this line has a lower texture, otherwise we get flat leakage pulling upward
// (If it DOES have a lower texture and we do this, the floor won't render at all) // (If it DOES have a lower texture and we do this, the floor won't render at all)
if (curline->polyseg && !curline->sidedef->bottomtexture) if (curline->polyseg && curline->sidedef->bottomtexture == NO_TEXTURE_NUM)
markfloor = false; markfloor = false;
} }
@ -2819,12 +2843,12 @@ void R_StoreWallRange(INT32 start, INT32 stop)
if (maskedtexture && !(ds_p->silhouette & SIL_TOP)) if (maskedtexture && !(ds_p->silhouette & SIL_TOP))
{ {
ds_p->silhouette |= SIL_TOP; ds_p->silhouette |= SIL_TOP;
ds_p->tsilheight = (sidedef->midtexture > 0 && sidedef->midtexture < numtextures) ? INT32_MIN : INT32_MAX; ds_p->tsilheight = (sidedef->midtexture >= 0 && sidedef->midtexture < numtextures) ? INT32_MIN : INT32_MAX;
} }
if (maskedtexture && !(ds_p->silhouette & SIL_BOTTOM)) if (maskedtexture && !(ds_p->silhouette & SIL_BOTTOM))
{ {
ds_p->silhouette |= SIL_BOTTOM; ds_p->silhouette |= SIL_BOTTOM;
ds_p->bsilheight = (sidedef->midtexture > 0 && sidedef->midtexture < numtextures) ? INT32_MAX : INT32_MIN; ds_p->bsilheight = (sidedef->midtexture >= 0 && sidedef->midtexture < numtextures) ? INT32_MAX : INT32_MIN;
} }
ds_p++; ds_p++;
} }

View file

@ -540,9 +540,9 @@ done:
return blocktex; return blocktex;
} }
UINT8 *R_GetFlatForTexture(size_t texnum) UINT8 *R_GetFlatForTexture(INT32 texnum)
{ {
if (texnum >= (unsigned)numtextures) if (texnum < 0 || texnum >= numtextures)
return NULL; return NULL;
texture_t *texture = textures[texnum]; texture_t *texture = textures[texnum];
@ -585,12 +585,13 @@ UINT8 *R_GetFlatForTexture(size_t texnum)
// //
// Returns the actual texture id that we should use. // Returns the actual texture id that we should use.
// This can either be texnum, the current frame for texnum's anim (if animated), // This can either be texnum, the current frame for texnum's anim (if animated),
// or 0 if not valid. // or NO_TEXTURE_NUM if not valid.
// //
INT32 R_GetTextureNum(INT32 texnum) INT32 R_GetTextureNum(INT32 texnum)
{ {
if (texnum < 0 || texnum >= numtextures) if (texnum < 0 || texnum >= numtextures)
return 0; return NO_TEXTURE_NUM;
return texturetranslation[texnum]; return texturetranslation[texnum];
} }
@ -619,6 +620,9 @@ column_t *R_GetColumn(fixed_t tex, INT32 col)
INT32 R_GetTextureNumForFlat(levelflat_t *levelflat) INT32 R_GetTextureNumForFlat(levelflat_t *levelflat)
{ {
if (levelflat->texture_id == NO_TEXTURE_NUM)
return NO_TEXTURE_NUM;
return texturetranslation[levelflat->texture_id]; return texturetranslation[levelflat->texture_id];
} }
@ -1566,7 +1570,7 @@ INT32 R_CheckTextureNumForName(const char *name)
// "NoTexture" marker. // "NoTexture" marker.
if (name[0] == '-') if (name[0] == '-')
return 0; return NO_TEXTURE_NUM;
hash = quickncasehash(name, 8); hash = quickncasehash(name, 8);
@ -1582,7 +1586,7 @@ INT32 R_CheckTextureNumForName(const char *name)
return i; return i;
} }
return -1; return NO_TEXTURE_NUM;
} }
// //
@ -1593,7 +1597,7 @@ INT32 R_CheckTextureNumForName(const char *name)
// //
const char *R_CheckTextureNameForNum(INT32 num) const char *R_CheckTextureNameForNum(INT32 num)
{ {
if (num > 0 && num < numtextures) if (num >= 0 && num < numtextures)
return textures[num]->name; return textures[num]->name;
return "-"; return "-";
@ -1608,8 +1612,11 @@ const char *R_TextureNameForNum(INT32 num)
{ {
const char *result = R_CheckTextureNameForNum(num); const char *result = R_CheckTextureNameForNum(num);
#if 0
// No, why???
if (strcmp(result, "-") == 0) if (strcmp(result, "-") == 0)
return "REDWALL"; return "REDWALL";
#endif
return result; return result;
} }
@ -1617,23 +1624,27 @@ const char *R_TextureNameForNum(INT32 num)
// //
// R_TextureNumForName // R_TextureNumForName
// //
// Calls R_CheckTextureNumForName, aborts with error message. // Calls R_CheckTextureNumForName, returns REDWALL if not found.
// //
INT32 R_TextureNumForName(const char *name) INT32 R_TextureNumForName(const char *name)
{ {
const INT32 i = R_CheckTextureNumForName(name); // "NoTexture" marker.
if (name[0] == '-')
return NO_TEXTURE_NUM;
if (i == -1) // If R_CheckTextureNumForName returns NO_TEXTURE_NUM we use a fallback texture
{ INT32 i = R_CheckTextureNumForName(name);
static INT32 redwall = -2; if (i != NO_TEXTURE_NUM)
CONS_Debug(DBG_SETUP, "WARNING: R_TextureNumForName: %.8s not found\n", name); return i;
if (redwall == -2)
redwall = R_CheckTextureNumForName("REDWALL"); // Texture wasn't found, use REDWALL
if (redwall != -1) CONS_Debug(DBG_SETUP, "WARNING: R_TextureNumForName: %.8s not found\n", name);
return redwall;
return 1; i = R_CheckTextureNumForName("REDWALL");
} if (i != NO_TEXTURE_NUM)
return i; return i;
return 0; // Give up and return texture #1
} }
// Like R_CheckTextureNumForName, but only looks in the flat namespace specifically. // Like R_CheckTextureNumForName, but only looks in the flat namespace specifically.
@ -1644,7 +1655,7 @@ INT32 R_CheckFlatNumForName(const char *name)
// "NoTexture" marker. // "NoTexture" marker.
if (name[0] == '-') if (name[0] == '-')
return 0; return NO_TEXTURE_NUM;
hash = quickncasehash(name, 8); hash = quickncasehash(name, 8);
@ -1659,5 +1670,5 @@ INT32 R_CheckFlatNumForName(const char *name)
return i; return i;
} }
return -1; return NO_TEXTURE_NUM;
} }

View file

@ -79,7 +79,7 @@ void R_FlushTextureCache(void);
// Texture generation // Texture generation
UINT8 *R_GenerateTexture(size_t texnum); UINT8 *R_GenerateTexture(size_t texnum);
UINT8 *R_GetFlatForTexture(size_t texnum); UINT8 *R_GetFlatForTexture(INT32 texnum);
INT32 R_GetTextureNum(INT32 texnum); INT32 R_GetTextureNum(INT32 texnum);
void R_CheckTextureCache(INT32 tex); void R_CheckTextureCache(INT32 tex);
void R_ClearTextureNumCache(boolean btell); void R_ClearTextureNumCache(boolean btell);