From d93a19bddbc710469bd537966d84c92a9fb4103b Mon Sep 17 00:00:00 2001 From: Lactozilla Date: Sat, 17 Feb 2024 00:15:10 -0300 Subject: [PATCH] Fix #167 --- src/doomdef.h | 7 - src/hardware/hw_cache.c | 5 +- src/hardware/hw_clip.c | 6 +- src/hardware/hw_clip.h | 2 +- src/hardware/hw_light.c | 2 +- src/hardware/hw_main.c | 655 +++------------------------------------- src/p_maputl.c | 2 +- src/p_setup.c | 22 +- src/p_spec.c | 16 +- src/r_bsp.c | 12 +- src/r_defs.h | 2 + src/r_picformats.c | 4 +- src/r_picformats.h | 2 +- src/r_plane.c | 6 +- src/r_segs.c | 158 ++++++---- src/r_textures.c | 57 ++-- src/r_textures.h | 2 +- 17 files changed, 204 insertions(+), 756 deletions(-) diff --git a/src/doomdef.h b/src/doomdef.h index 4c843f9e2..e682ca179 100644 --- a/src/doomdef.h +++ b/src/doomdef.h @@ -709,13 +709,6 @@ extern int /// Experimental attempts at preventing MF_PAPERCOLLISION objects from getting stuck in walls. //#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 #define GL_SHADERS diff --git a/src/hardware/hw_cache.c b/src/hardware/hw_cache.c index 58e16d623..a5f8bb5bc 100644 --- a/src/hardware/hw_cache.c +++ b/src/hardware/hw_cache.c @@ -829,13 +829,14 @@ void HWR_GetLevelFlat(levelflat_t *levelflat) return; } - INT32 texturenum = texturetranslation[levelflat->texture_id]; - if (texturenum <= 0) + if (levelflat->texture_id == NO_TEXTURE_NUM) { HWR_SetCurrentTexture(NULL); return; } + INT32 texturenum = texturetranslation[levelflat->texture_id]; + GLMapTexture_t *grtex = &gl_flats[texturenum]; GLMipmap_t *grMipmap = &grtex->mipmap; diff --git a/src/hardware/hw_clip.c b/src/hardware/hw_clip.c index 86e0c58d2..499e35af4 100644 --- a/src/hardware/hw_clip.c +++ b/src/hardware/hw_clip.c @@ -320,16 +320,12 @@ void gld_clipper_Clear(void) #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; angle_t a1; 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_multiplier = 64.0f / render_fovratio / RMUL; diff --git a/src/hardware/hw_clip.h b/src/hardware/hw_clip.h index 27a2ed1ef..e3bb4c319 100644 --- a/src/hardware/hw_clip.h +++ b/src/hardware/hw_clip.h @@ -17,7 +17,7 @@ boolean gld_clipper_SafeCheckRange(angle_t startAngle, angle_t endAngle); void gld_clipper_SafeAddClipRange(angle_t startangle, angle_t endangle); 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 void gld_FrustrumSetup(void); boolean gld_SphereInFrustum(float x, float y, float z, float radius); diff --git a/src/hardware/hw_light.c b/src/hardware/hw_light.c index bcfdfa960..cda6cee4b 100644 --- a/src/hardware/hw_light.c +++ b/src/hardware/hw_light.c @@ -1316,7 +1316,7 @@ static void HWR_AddLightMapForLine(int lightnum, seg_t *line) if ( lgl_backsector->ceilingpic == gl_frontsector->ceilingpic && lgl_backsector->floorpic == gl_frontsector->floorpic && lgl_backsector->lightlevel == gl_frontsector->lightlevel - && lgl_curline->sidedef->midtexture == 0) + && lgl_curline->sidedef->midtexture == NO_TEXTURE_NUM) { return; } diff --git a/src/hardware/hw_main.c b/src/hardware/hw_main.c index 9c1a95c93..59e18ed21 100644 --- a/src/hardware/hw_main.c +++ b/src/hardware/hw_main.c @@ -19,8 +19,10 @@ #include "hw_light.h" #include "hw_drv.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 "../p_local.h" #include "../p_setup.h" @@ -42,11 +44,6 @@ #include "../r_translation.h" #include "../d_main.h" #include "../p_slopes.h" -#include "hw_md2.h" - -#ifdef NEWCLIP -#include "hw_clip.h" -#endif #define R_FAKEFLOORS #define HWPRECIP @@ -428,7 +425,11 @@ static void HWR_RenderPlane(subsector_t *subsector, extrasubsector_t *xsub, bool // set texture for polygon 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; fflatheight = texture->height; } @@ -776,41 +777,6 @@ static void HWR_ProjectWall(FOutVector *wallVerts, FSurfaceInfo *pSurf, FBITFIEL // 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. // 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) @@ -1121,7 +1087,7 @@ static void HWR_ProcessSeg(void) // Sort of like GLWall::Process in GZDoom // two sided line if (gl_backsector) { - INT32 gl_toptexture = 0, gl_bottomtexture = 0; + INT32 gl_toptexture = NO_TEXTURE_NUM, gl_bottomtexture = NO_TEXTURE_NUM; fixed_t texturevpeg; 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); // 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); 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 - if ((worldlowslope > worldbottomslope || worldlow > worldbottom) && gl_bottomtexture) + if ((worldlowslope > worldbottomslope || worldlow > worldbottom) && gl_bottomtexture != NO_TEXTURE_NUM) { grTex = HWR_GetTexture(gl_bottomtexture); 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 - if (gl_midtexture && HWR_BlendMidtextureSurface(&Surf)) + if (gl_midtexture != NO_TEXTURE_NUM && HWR_BlendMidtextureSurface(&Surf)) { sector_t *front, *back; 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 { // 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); 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); + if (texnum == NO_TEXTURE_NUM) + continue; h = P_GetFFloorTopZAt (rover, v1x, v1y); 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); + if (texnum == NO_TEXTURE_NUM) + continue; h = P_GetFFloorTopZAt (rover, v1x, v1y); 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 // -#ifdef NEWCLIP -boolean checkforemptylines = true; +static boolean checkforemptylines = true; + // Don't modify anything here, just check // Kalaron: Modified for sloped linedefs 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) { // preserve a kind of transparent door/lift special effect: - if (((backc1 >= frontc1 && backc2 >= frontc2) || seg->sidedef->toptexture) - && ((backf1 <= frontf1 && backf2 <= frontf2) || seg->sidedef->bottomtexture)) + if (((backc1 >= frontc1 && backc2 >= frontc2) || (seg->sidedef->toptexture != NO_TEXTURE_NUM)) + && ((backf1 <= frontf1 && backf2 <= frontf2) || (seg->sidedef->bottomtexture != NO_TEXTURE_NUM))) { checkforemptylines = false; return true; @@ -1961,295 +1931,6 @@ static boolean CheckClip(seg_t * seg, sector_t * afrontsector, sector_t * abacks 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. @@ -2259,11 +1940,6 @@ static void HWR_ClearClipSegs(void) static void HWR_AddLine(seg_t * line) { 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 static sector_t tempsec; @@ -2299,8 +1975,7 @@ static void HWR_AddLine(seg_t * line) angle1 = R_PointToAngle64(v1x, v1y); 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) return; @@ -2312,91 +1987,10 @@ static void HWR_AddLine(seg_t * line) } 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; bothceilingssky = bothfloorssky = false; -#ifdef NEWCLIP if (!line->backsector) { gld_clipper_SafeAddClipRange(angle2, angle1); @@ -2438,116 +2032,7 @@ static void HWR_AddLine(seg_t * line) return; } - 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_ProcessSeg(); } // HWR_CheckBBox @@ -2562,10 +2047,6 @@ static boolean HWR_CheckBBox(fixed_t *bspcoord) INT32 boxpos; fixed_t px1, py1, px2, py2; angle_t angle1, angle2; -#ifndef NEWCLIP - INT32 sx1, sx2; - angle_t span, tspan; -#endif // Find the corners of the box // that define the edges from current viewpoint. @@ -2591,59 +2072,9 @@ static boolean HWR_CheckBBox(fixed_t *bspcoord) px2 = bspcoord[checkcoord[boxpos][2]]; py2 = bspcoord[checkcoord[boxpos][3]]; -#ifdef NEWCLIP angle1 = R_PointToAngle64(px1, py1); angle2 = R_PointToAngle64(px2, py2); 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 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; fflatheight = texture->height; } @@ -6171,18 +5606,11 @@ void HWR_RenderSkyboxView(INT32 viewnumber, player_t *player) drawcount = 0; -#ifdef NEWCLIP - if (rendermode == render_opengl) - { - angle_t a1 = gld_FrustumAngle(gl_aimingangle); - gld_clipper_Clear(); - gld_clipper_SafeAddClipRange(viewangle + a1, viewangle - a1); + angle_t a1 = gld_FrustumAngle(fpov, gl_aimingangle); + gld_clipper_Clear(); + gld_clipper_SafeAddClipRange(viewangle + a1, viewangle - a1); #ifdef HAVE_SPHEREFRUSTRUM - gld_FrustrumSetup(); -#endif - } -#else - HWR_ClearClipSegs(); + gld_FrustrumSetup(); #endif //04/01/2000: Hurdler: added for T&L @@ -6364,18 +5792,11 @@ void HWR_RenderPlayerView(INT32 viewnumber, player_t *player) drawcount = 0; -#ifdef NEWCLIP - if (rendermode == render_opengl) - { - angle_t a1 = gld_FrustumAngle(gl_aimingangle); - gld_clipper_Clear(); - gld_clipper_SafeAddClipRange(viewangle + a1, viewangle - a1); + angle_t a1 = gld_FrustumAngle(fpov, gl_aimingangle); + gld_clipper_Clear(); + gld_clipper_SafeAddClipRange(viewangle + a1, viewangle - a1); #ifdef HAVE_SPHEREFRUSTRUM - gld_FrustrumSetup(); -#endif - } -#else - HWR_ClearClipSegs(); + gld_FrustrumSetup(); #endif //04/01/2000: Hurdler: added for T&L @@ -6554,10 +5975,6 @@ void HWR_AddCommands(void) CV_RegisterVar(&cv_glbatching); CV_RegisterVar(&cv_glwireframe); - -#ifndef NEWCLIP - CV_RegisterVar(&cv_glclipwalls); -#endif } // -------------------------------------------------------------------------- diff --git a/src/p_maputl.c b/src/p_maputl.c index 82b864715..bde156181 100644 --- a/src/p_maputl.c +++ b/src/p_maputl.c @@ -499,7 +499,7 @@ void P_LineOpening(line_t *linedef, mobj_t *mobj) fixed_t texmid, delta1, delta2; 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 texheight = textures[texnum]->height << FRACBITS; diff --git a/src/p_setup.c b/src/p_setup.c index 1d985beb4..41dd53d36 100644 --- a/src/p_setup.c +++ b/src/p_setup.c @@ -585,20 +585,20 @@ Ploadflat (levelflat_t *levelflat, const char *flatname, boolean resize) // Look for a flat 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! texturenum = R_CheckTextureNumForName(levelflat->name); - if (texturenum <= 0) + if (texturenum == NO_TEXTURE_NUM) { // Use "not found" texture texturenum = R_CheckTextureNumForName("REDWALL"); // Give up? - if (texturenum <= 0) + if (texturenum == NO_TEXTURE_NUM) { 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... // Perhaps we should just call it instead of doing the calculations here. 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; case 413: // Change music { - sd->toptexture = sd->midtexture = sd->bottomtexture = 0; + sd->toptexture = sd->midtexture = sd->bottomtexture = NO_TEXTURE_NUM; if (!isfrontside) break; @@ -1379,7 +1379,7 @@ static void P_LoadSidedefs(UINT8 *data) case 4: // Speed pad parameters case 414: // Play SFX { - sd->toptexture = sd->midtexture = sd->bottomtexture = 0; + sd->toptexture = sd->midtexture = sd->bottomtexture = NO_TEXTURE_NUM; if (!isfrontside) break; @@ -1421,7 +1421,7 @@ static void P_LoadSidedefs(UINT8 *data) { char process[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') break; else @@ -2600,11 +2600,11 @@ static void P_WriteTextmap(void) fprintf(f, "scalex_bottom = %f;\n", FIXED_TO_FLOAT(wsides[i].scalex_bottom)); if (wsides[i].scaley_bottom != FRACUNIT) 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); - 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); - 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); if (wsides[i].repeatcnt != 0) fprintf(f, "repeatcnt = %d;\n", wsides[i].repeatcnt); diff --git a/src/p_spec.c b/src/p_spec.c index 572258165..bcb1c665b 100644 --- a/src/p_spec.c +++ b/src/p_spec.c @@ -847,11 +847,11 @@ static fixed_t P_FindShortestUpperAround(INT32 secnum) if (twoSided(secnum, i)) { side = getSide(secnum,i,0); - if (side->toptexture > 0) + if (side->toptexture != NO_TEXTURE_NUM) if (textureheight[side->toptexture] < minsize) minsize = textureheight[side->toptexture]; side = getSide(secnum,i,1); - if (side->toptexture > 0) + if (side->toptexture != NO_TEXTURE_NUM) if (textureheight[side->toptexture] < minsize) 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) { this = &sides[lines[linenum].sidenum[0]]; - if (always || this->toptexture) this->toptexture = setfront->toptexture; - if (always || this->midtexture) this->midtexture = setfront->midtexture; - if (always || this->bottomtexture) this->bottomtexture = setfront->bottomtexture; + if (always || this->toptexture != NO_TEXTURE_NUM) this->toptexture = setfront->toptexture; + if (always || this->midtexture != NO_TEXTURE_NUM) this->midtexture = setfront->midtexture; + if (always || this->bottomtexture != NO_TEXTURE_NUM) this->bottomtexture = setfront->bottomtexture; } // Back side if (line->args[1] != TMSD_FRONT && lines[linenum].sidenum[1] != NO_SIDEDEF) { this = &sides[lines[linenum].sidenum[1]]; - if (always || this->toptexture) this->toptexture = setback->toptexture; - if (always || this->midtexture) this->midtexture = setback->midtexture; - if (always || this->bottomtexture) this->bottomtexture = setback->bottomtexture; + if (always || this->toptexture != NO_TEXTURE_NUM) this->toptexture = setback->toptexture; + if (always || this->midtexture != NO_TEXTURE_NUM) this->midtexture = setback->midtexture; + if (always || this->bottomtexture != NO_TEXTURE_NUM) this->bottomtexture = setback->bottomtexture; } } } diff --git a/src/r_bsp.c b/src/r_bsp.c index 918dc40b0..41a02461c 100644 --- a/src/r_bsp.c +++ b/src/r_bsp.c @@ -225,9 +225,9 @@ static INT32 R_DoorClosed(void) backsector->ceilingheight <= backsector->floorheight // 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->c_slope == front->c_slope && back->lightlevel == front->lightlevel - && !line->sidedef->midtexture + && line->sidedef->midtexture == NO_TEXTURE_NUM // Check offsets and scale too! && back->floorxoffset == front->floorxoffset && 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 (!line->polyseg && - !line->sidedef->midtexture + line->sidedef->midtexture == NO_TEXTURE_NUM && ((!frontsector->ffloors && !backsector->ffloors) || Tag_Compare(&frontsector->tags, &backsector->tags))) 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 doorclosed = (backc1 <= backf1 && backc2 <= backf2 - && ((backc1 >= frontc1 && backc2 >= frontc2) || curline->sidedef->toptexture) - && ((backf1 <= frontf1 && backf2 >= frontf2) || curline->sidedef->bottomtexture)); + && ((backc1 >= frontc1 && backc2 >= frontc2) || (curline->sidedef->toptexture != NO_TEXTURE_NUM)) + && ((backf1 <= frontf1 && backf2 >= frontf2) || (curline->sidedef->bottomtexture != NO_TEXTURE_NUM))); if (doorclosed) goto clipsolid; diff --git a/src/r_defs.h b/src/r_defs.h index d556b540f..7f06385d6 100644 --- a/src/r_defs.h +++ b/src/r_defs.h @@ -27,6 +27,8 @@ #include "taglist.h" +#define NO_TEXTURE_NUM -1 + // // ClipWallSegment // Clips the given range of columns diff --git a/src/r_picformats.c b/src/r_picformats.c index e4a59f211..102e7ecab 100644 --- a/src/r_picformats.c +++ b/src/r_picformats.c @@ -847,7 +847,7 @@ boolean Picture_CheckIfDoomPatch(softwarepatch_t *patch, size_t size) * \param texnum The texture number. * \return The converted flat. */ -void *Picture_TextureToFlat(size_t texnum) +void *Picture_TextureToFlat(INT32 texnum) { texture_t *texture; @@ -856,7 +856,7 @@ void *Picture_TextureToFlat(size_t texnum) UINT8 *desttop, *dest, *deststop; UINT8 *source; - if (texnum >= (unsigned)numtextures) + if (texnum < 0 || texnum >= numtextures) I_Error("Picture_TextureToFlat: invalid texture number!"); // Check the texture cache diff --git a/src/r_picformats.h b/src/r_picformats.h index 3ee9805d8..c40988571 100644 --- a/src/r_picformats.h +++ b/src/r_picformats.h @@ -76,7 +76,7 @@ void *Picture_GetPatchPixel( INT32 x, INT32 y, pictureflags_t flags); -void *Picture_TextureToFlat(size_t texnum); +void *Picture_TextureToFlat(INT32 texnum); INT32 Picture_FormatBPP(pictureformat_t format); boolean Picture_IsPatchFormat(pictureformat_t format); diff --git a/src/r_plane.c b/src/r_plane.c index 4f9ce9ec8..d8b47e124 100644 --- a/src/r_plane.c +++ b/src/r_plane.c @@ -1003,7 +1003,11 @@ void R_DrawSinglePlane(visplane_t *pl) if (ds_source == NULL) 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_flatheight = texture->height; diff --git a/src/r_segs.c b/src/r_segs.c index 267c1d47d..7b3a02634 100644 --- a/src/r_segs.c +++ b/src/r_segs.c @@ -123,10 +123,13 @@ void R_RenderMaskedSegRange(drawseg_t *ds, INT32 x1, INT32 x2) // OPTIMIZE: get rid of LIGHTSEGSHIFT globally curline = ds->curline; - frontsector = curline->frontsector; - backsector = curline->backsector; sidedef = curline->sidedef; texnum = R_GetTextureNum(sidedef->midtexture); + if (texnum == NO_TEXTURE_NUM) + return; + + frontsector = curline->frontsector; + backsector = curline->backsector; windowbottom = windowtop = sprbotscreen = INT32_MAX; 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); + if (texnum == NO_TEXTURE_NUM) + return; if (pfloor->fofflags & FOF_TRANSLUCENT) { @@ -1015,11 +1020,11 @@ static void R_RenderSegLoop (void) INT32 bottom; INT32 i; - if (midtexture) + if (midtexture != NO_TEXTURE_NUM) R_CheckTextureCache(midtexture); - if (toptexture) + if (toptexture != NO_TEXTURE_NUM) R_CheckTextureCache(toptexture); - if (bottomtexture) + if (bottomtexture != NO_TEXTURE_NUM) R_CheckTextureCache(bottomtexture); for (; rw_x < rw_stopx; rw_x++) @@ -1242,7 +1247,7 @@ static void R_RenderSegLoop (void) frontscale[rw_x] = rw_scale; // draw the wall tiers - if (midtexture) + if (midtexture != NO_TEXTURE_NUM) { // single sided line 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; // two sided line - if (toptexture) + if (toptexture != NO_TEXTURE_NUM) { // top wall mid = pixhigh>>HEIGHTBITS; @@ -1340,7 +1345,7 @@ static void R_RenderSegLoop (void) else if (markceiling && (!rw_ceilingmarked)) // no top wall ceilingclip[rw_x] = topclip; - if (bottomtexture) + if (bottomtexture != NO_TEXTURE_NUM) { // bottom wall mid = (pixlow+HEIGHTUNIT-1)>>HEIGHTBITS; @@ -1403,7 +1408,7 @@ static void R_RenderSegLoop (void) maskedtextureheight[rw_x] = min(rw_midtexturemid, rw_midtextureback); } - if (midtexture || maskedtextureheight) + if (midtexture != NO_TEXTURE_NUM || maskedtextureheight) { if (oldtexturecolumn != -1) { @@ -1704,7 +1709,8 @@ void R_StoreWallRange(INT32 start, INT32 stop) worldbottom -= viewz; worldbottomslope -= viewz; - midtexture = toptexture = bottomtexture = maskedtexture = 0; + midtexture = toptexture = bottomtexture = NO_TEXTURE_NUM; + maskedtexture = false; ds_p->maskedtexturecol = NULL; ds_p->numthicksides = numthicksides = 0; ds_p->thicksidecol = NULL; @@ -1752,6 +1758,8 @@ void R_StoreWallRange(INT32 start, INT32 stop) rw_midtexturescaley = sidedef->scaley_mid; rw_invmidtexturescalex = FixedDiv(FRACUNIT, rw_midtexturescalex); + segtextured = false; + if (!backsector) { 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 markfloor = markceiling = true; - fixed_t rowoffset = sidedef->rowoffset + sidedef->offsety_mid; - fixed_t texheight = textureheight[midtexture]; - - if (rw_midtexturescaley > 0) + if (midtexture != NO_TEXTURE_NUM) // tsk tsk { - 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) - rw_midtexturemid = FixedMul(frontsector->floorheight - viewz, rw_midtexturescaley) + texheight; + if (linedef->flags & ML_NOSKEW) + { + 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 - rw_midtexturemid = FixedMul(frontsector->ceilingheight - viewz, rw_midtexturescaley); - } - else if (linedef->flags & ML_DONTPEGBOTTOM) - { - rw_midtexturemid = FixedMul(worldbottom, rw_midtexturescaley) + texheight; - rw_midtextureslide = floorfrontslide; + { + // top of texture at top + rw_midtexturemid = FixedMul(worldtop, rw_midtexturescaley); + rw_midtextureslide = ceilingfrontslide; + } } else { - // top of texture at top - rw_midtexturemid = FixedMul(worldtop, rw_midtexturescaley); - rw_midtextureslide = ceilingfrontslide; - } - } - else - { - // Upside down - rowoffset = -rowoffset; + // Upside down + rowoffset = -rowoffset; - if (linedef->flags & ML_NOSKEW) - { - if (linedef->flags & ML_DONTPEGBOTTOM) - rw_midtexturemid = FixedMul(frontsector->floorheight - viewz, rw_midtexturescaley); + if (linedef->flags & ML_NOSKEW) + { + if (linedef->flags & ML_DONTPEGBOTTOM) + 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 - 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->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 if (!bothceilingssky // never draw the top texture if on && (worldhigh < worldtop || worldhighslope < worldtopslope)) { toptexture = R_GetTextureNum(sidedef->toptexture); + } + + if (toptexture != NO_TEXTURE_NUM) + { + fixed_t toprowoffset = sidedef->rowoffset + sidedef->offsety_top; rw_toptexturescalex = sidedef->scalex_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 += toprowoffset; + + segtextured = true; } // check BOTTOM TEXTURE 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); + } + + if (bottomtexture != NO_TEXTURE_NUM) + { + fixed_t botrowoffset = sidedef->rowoffset + sidedef->offsety_bottom; rw_bottomtexturescalex = sidedef->scalex_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 += botrowoffset; - rw_toptexturemid += toprowoffset; - rw_bottomtexturemid += botrowoffset; + segtextured = true; + } // allocate space for masked texture tables R_AllocTextureColumnTables(rw_stopx - start); @@ -2260,10 +2282,13 @@ void R_StoreWallRange(INT32 start, INT32 stop) } ds_p->numthicksides = numthicksides = i; + + if (numthicksides > 0) + segtextured = true; } // masked midtexture - if (sidedef->midtexture > 0 && sidedef->midtexture < numtextures) + if (sidedef->midtexture >= 0 && sidedef->midtexture < numtextures) { ds_p->maskedtexturecol = maskedtexturecol = curtexturecolumntable - 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]) maskedtexture = true; + segtextured = true; if (curline->polyseg) { @@ -2321,8 +2347,6 @@ void R_StoreWallRange(INT32 start, INT32 stop) } // calculate rw_offset (only needed for textured lines) - segtextured = midtexture || toptexture || bottomtexture || maskedtexture || (numthicksides > 0); - if (segtextured) { fixed_t sideoffset = sidedef->textureoffset; @@ -2536,7 +2560,7 @@ void R_StoreWallRange(INT32 start, INT32 stop) worldhighslope >>= 4; worldlowslope >>= 4; - if (toptexture) + if (toptexture != NO_TEXTURE_NUM) { pixhigh = (centeryfrac>>4) - FixedMul (worldhigh, rw_scale); 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); 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 // (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; } @@ -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 // (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; } @@ -2819,12 +2843,12 @@ void R_StoreWallRange(INT32 start, INT32 stop) if (maskedtexture && !(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)) { 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++; } diff --git a/src/r_textures.c b/src/r_textures.c index 0175a080e..807f66aac 100644 --- a/src/r_textures.c +++ b/src/r_textures.c @@ -540,9 +540,9 @@ done: return blocktex; } -UINT8 *R_GetFlatForTexture(size_t texnum) +UINT8 *R_GetFlatForTexture(INT32 texnum) { - if (texnum >= (unsigned)numtextures) + if (texnum < 0 || texnum >= numtextures) return NULL; texture_t *texture = textures[texnum]; @@ -585,12 +585,13 @@ UINT8 *R_GetFlatForTexture(size_t texnum) // // Returns the actual texture id that we should use. // 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) { if (texnum < 0 || texnum >= numtextures) - return 0; + return NO_TEXTURE_NUM; + return texturetranslation[texnum]; } @@ -619,6 +620,9 @@ column_t *R_GetColumn(fixed_t tex, INT32 col) INT32 R_GetTextureNumForFlat(levelflat_t *levelflat) { + if (levelflat->texture_id == NO_TEXTURE_NUM) + return NO_TEXTURE_NUM; + return texturetranslation[levelflat->texture_id]; } @@ -1566,7 +1570,7 @@ INT32 R_CheckTextureNumForName(const char *name) // "NoTexture" marker. if (name[0] == '-') - return 0; + return NO_TEXTURE_NUM; hash = quickncasehash(name, 8); @@ -1582,7 +1586,7 @@ INT32 R_CheckTextureNumForName(const char *name) return i; } - return -1; + return NO_TEXTURE_NUM; } // @@ -1593,9 +1597,9 @@ INT32 R_CheckTextureNumForName(const char *name) // const char *R_CheckTextureNameForNum(INT32 num) { - if (num > 0 && num < numtextures) + if (num >= 0 && num < numtextures) return textures[num]->name; - + return "-"; } @@ -1608,8 +1612,11 @@ const char *R_TextureNameForNum(INT32 num) { const char *result = R_CheckTextureNameForNum(num); +#if 0 + // No, why??? if (strcmp(result, "-") == 0) return "REDWALL"; +#endif return result; } @@ -1617,23 +1624,27 @@ const char *R_TextureNameForNum(INT32 num) // // R_TextureNumForName // -// Calls R_CheckTextureNumForName, aborts with error message. +// Calls R_CheckTextureNumForName, returns REDWALL if not found. // INT32 R_TextureNumForName(const char *name) { - const INT32 i = R_CheckTextureNumForName(name); + // "NoTexture" marker. + if (name[0] == '-') + return NO_TEXTURE_NUM; - if (i == -1) - { - static INT32 redwall = -2; - CONS_Debug(DBG_SETUP, "WARNING: R_TextureNumForName: %.8s not found\n", name); - if (redwall == -2) - redwall = R_CheckTextureNumForName("REDWALL"); - if (redwall != -1) - return redwall; - return 1; - } - return i; + // If R_CheckTextureNumForName returns NO_TEXTURE_NUM we use a fallback texture + INT32 i = R_CheckTextureNumForName(name); + if (i != NO_TEXTURE_NUM) + return i; + + // Texture wasn't found, use REDWALL + CONS_Debug(DBG_SETUP, "WARNING: R_TextureNumForName: %.8s not found\n", name); + + i = R_CheckTextureNumForName("REDWALL"); + if (i != NO_TEXTURE_NUM) + return i; + + return 0; // Give up and return texture #1 } // Like R_CheckTextureNumForName, but only looks in the flat namespace specifically. @@ -1644,7 +1655,7 @@ INT32 R_CheckFlatNumForName(const char *name) // "NoTexture" marker. if (name[0] == '-') - return 0; + return NO_TEXTURE_NUM; hash = quickncasehash(name, 8); @@ -1659,5 +1670,5 @@ INT32 R_CheckFlatNumForName(const char *name) return i; } - return -1; + return NO_TEXTURE_NUM; } diff --git a/src/r_textures.h b/src/r_textures.h index eb68ec09f..b690687a1 100644 --- a/src/r_textures.h +++ b/src/r_textures.h @@ -79,7 +79,7 @@ void R_FlushTextureCache(void); // Texture generation UINT8 *R_GenerateTexture(size_t texnum); -UINT8 *R_GetFlatForTexture(size_t texnum); +UINT8 *R_GetFlatForTexture(INT32 texnum); INT32 R_GetTextureNum(INT32 texnum); void R_CheckTextureCache(INT32 tex); void R_ClearTextureNumCache(boolean btell);