diff --git a/src/r_bsp.c b/src/r_bsp.c index e79a1cee3..f71dea646 100644 --- a/src/r_bsp.c +++ b/src/r_bsp.c @@ -425,11 +425,13 @@ boolean R_IsEmptyLine(seg_t *line, sector_t *front, sector_t *back) boolean R_IsDebugLine(seg_t *line) { - if (line->linedef->special == 2001) // Ring Racers: Finish Line + if (cv_debugfinishline.value) { - if (cv_debugfinishline.value) + switch (line->linedef->special) { - return true; + case 2001: // Ring Racers: Finish Line + case 2003: // Ring Racers: Respawn Line + return true; } } diff --git a/src/r_debug.cpp b/src/r_debug.cpp index 8fbe9390d..bb7590a5c 100644 --- a/src/r_debug.cpp +++ b/src/r_debug.cpp @@ -15,6 +15,7 @@ #include "r_debug_detail.hpp" #include "command.h" +#include "i_time.h" #include "m_fixed.h" #include "r_draw.h" #include "r_main.h" @@ -72,6 +73,22 @@ INT32 R_AdjustLightLevel(INT32 light) return light / FRACUNIT; } +UINT8 R_DebugLineColor(const line_t *ld) +{ + const bool alt = (I_GetTime() % 70 < 35); + + switch (ld->special) + { + case 2001: // Ring Racers: Finish Line + return alt ? 0x1F : 0x49; // black, yellow + + case 2003: // Ring Racers: Respawn Line + return alt ? 0x23 : 0x00; // red, white + } + + return 0x00; +} + void Command_Debugrender_highlight(void) { const bool changes = COM_Argc() > 1; diff --git a/src/r_main.h b/src/r_main.h index 40103561a..62d6cd1d3 100644 --- a/src/r_main.h +++ b/src/r_main.h @@ -142,6 +142,7 @@ extern UINT32 debugrender_highlight; void R_CheckDebugHighlight(debugrender_highlight_t type); INT32 R_AdjustLightLevel(INT32 light); +UINT8 R_DebugLineColor(const line_t *ld); void Command_Debugrender_highlight(void); diff --git a/src/r_segs.c b/src/r_segs.c index 00ab6348b..f671241cf 100644 --- a/src/r_segs.c +++ b/src/r_segs.c @@ -500,6 +500,52 @@ static void R_RenderMaskedSegLoop(drawseg_t *ds, INT32 x1, INT32 x2, INT32 texnu } } +static void R_RenderMaskedSegLoopDebug(drawseg_t *ds, INT32 x1, INT32 x2, void (*colfunc_2s)(column_t *, column_t *, INT32)) +{ + column_t *col; + + dc_lightmap = scalelight[LIGHTLEVELS - 1][0]; // max brightness + + // draw the columns + for (dc_x = x1; dc_x <= x2; dc_x++) + { + if (maskedtexturecol[dc_x] != INT16_MAX) + { + dc_texturemid = ds->maskedtextureheight[dc_x]; + + if (R_OverflowTest()) + { + spryscale += rw_scalestep; + continue; + } + + sprtopscreen = centeryfrac - FixedMul(dc_texturemid, spryscale); + dc_iscale = 0xffffffffu / (unsigned)spryscale; + + col = (column_t *)((UINT8 *)R_GetColumn(g_texturenum_dbgline, maskedtexturecol[dc_x]) - 3); + colfunc_2s(col, NULL, -1); + } + + spryscale += rw_scalestep; + } +} + +static INT32 R_GetTwoSidedMidTexture(seg_t *line) +{ + INT32 texture; + + if (R_IsDebugLine(line)) + { + texture = g_texturenum_dbgline; + } + else + { + texture = line->sidedef->midtexture; + } + + return R_GetTextureNum(texture); +} + static boolean R_CheckBlendMode(const line_t *ldef, INT32 bmnum) { transnum_t transtable = NUMTRANSMAPS; @@ -549,10 +595,10 @@ static boolean R_CheckBlendMode(const line_t *ldef, INT32 bmnum) void R_RenderMaskedSegRange(drawseg_t *ds, INT32 x1, INT32 x2) { - INT32 texnum, bmnum, i; + INT32 texnum, bmnum; void (*colfunc_2s)(column_t *, column_t *, INT32); line_t *ldef; - INT32 range; + const boolean debug = R_IsDebugLine(ds->curline); // Calculate light table. // Use different light tables @@ -560,35 +606,9 @@ void R_RenderMaskedSegRange(drawseg_t *ds, INT32 x1, INT32 x2) // OPTIMIZE: get rid of LIGHTSEGSHIFT globally curline = ds->curline; - if (R_IsDebugLine(curline)) - { - const UINT8 thickness = 4; - const UINT8 pal = (leveltime % 70 < 35) ? 0x23 : 0x00; - - const INT32 horizon = ((centeryfrac>>4) + 1 + HEIGHTUNIT - 1) >> HEIGHTBITS; - const INT32 y = max(0, min(horizon, vid.height - thickness)); - - UINT8 *p = &topleft[x1 + (y * vid.width)]; - - range = max(x2 - x1, 0) + 1; - - for (i = 0; i < thickness; ++i) - { - memset(p, pal, range); - p += vid.width; - } - - return; - } - - if (ds->maskedtexturecol == NULL) - { - return; - } - frontsector = curline->frontsector; backsector = curline->backsector; - texnum = R_GetTextureNum(curline->sidedef->midtexture); + texnum = R_GetTwoSidedMidTexture(curline); bmnum = R_GetTextureBrightmap(texnum); windowbottom = windowtop = sprbotscreen = INT32_MAX; @@ -596,7 +616,7 @@ void R_RenderMaskedSegRange(drawseg_t *ds, INT32 x1, INT32 x2) R_CheckDebugHighlight(SW_HI_MIDTEXTURES); - if (R_CheckBlendMode(ldef, bmnum) == false) + if (debug == false && R_CheckBlendMode(ldef, bmnum) == false) { return; // does not render } @@ -632,7 +652,16 @@ void R_RenderMaskedSegRange(drawseg_t *ds, INT32 x1, INT32 x2) mfloorclip = ds->sprbottomclip; mceilingclip = ds->sprtopclip; - R_RenderMaskedSegLoop(ds, x1, x2, texnum, bmnum, colfunc_2s); + if (debug) + { + colfunc = R_DrawColumn_Flat_8; + r8_flatcolor = R_DebugLineColor(ldef); + R_RenderMaskedSegLoopDebug(ds, x1, x2, colfunc_2s); + } + else + { + R_RenderMaskedSegLoop(ds, x1, x2, texnum, bmnum, colfunc_2s); + } R_SetColumnFunc(BASEDRAWFUNC, false); } @@ -1694,6 +1723,7 @@ void R_StoreWallRange(INT32 start, INT32 stop) vertex_t segleft, segright; fixed_t ceilingfrontslide, floorfrontslide, ceilingbackslide, floorbackslide; static size_t maxdrawsegs = 0; + const INT32 twosidedmidtexture = R_GetTwoSidedMidTexture(curline); maskedtextureheight = NULL; //initialize segleft and segright @@ -2411,7 +2441,7 @@ void R_StoreWallRange(INT32 start, INT32 stop) ds_p->numthicksides = numthicksides = i; } - if (sidedef->midtexture > 0 && sidedef->midtexture < numtextures) + if (twosidedmidtexture) { // masked midtexture if (!ds_p->thicksidecol) @@ -2462,6 +2492,17 @@ void R_StoreWallRange(INT32 start, INT32 stop) rw_midtexturemid += sidedef->rowoffset; rw_midtextureback += sidedef->rowoffset; + if (R_IsDebugLine(curline)) + { + // Line draws at horizon + rw_midtexturemid = 0; + rw_midtextureback = 0; + + // Ignore slopes + rw_midtextureslide = 0; + rw_midtexturebackslide = 0; + } + maskedtexture = true; } } @@ -2943,12 +2984,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 = twosidedmidtexture ? 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 = twosidedmidtexture ? INT32_MAX: INT32_MIN; } ds_p++; } diff --git a/src/r_textures.c b/src/r_textures.c index 2f36fca08..5d3669b11 100644 --- a/src/r_textures.c +++ b/src/r_textures.c @@ -57,6 +57,8 @@ fixed_t *textureheight; // needed for texture pegging INT32 *texturetranslation; INT32 *texturebrightmaps; +INT32 g_texturenum_dbgline; + // Painfully simple texture id cacheing to make maps load faster. :3 static struct { char name[9]; @@ -1126,6 +1128,8 @@ static void R_FinishLoadingTextures(INT32 add) if (rendermode == render_opengl) HWR_LoadMapTextures(numtextures); #endif + + g_texturenum_dbgline = R_CheckTextureNumForName("DBGLINE"); } // diff --git a/src/r_textures.h b/src/r_textures.h index 066b10fbd..084447faa 100644 --- a/src/r_textures.h +++ b/src/r_textures.h @@ -114,6 +114,8 @@ void R_PrintTextureDuplicates(void); extern INT32 numtextures; +extern INT32 g_texturenum_dbgline; + #ifdef __cplusplus } // extern "C" #endif diff --git a/src/r_things.c b/src/r_things.c index c8ef9b557..70fc44923 100644 --- a/src/r_things.c +++ b/src/r_things.c @@ -2899,7 +2899,7 @@ static void R_CreateDrawNodes(maskcount_t* mask, drawnode_t* head, boolean temps } ds->curline->polyseg->visplane = NULL; } - if (ds->maskedtexturecol || R_IsDebugLine(ds->curline)) + if (ds->maskedtexturecol) { entry = R_CreateDrawNode(head); entry->seg = ds; @@ -3698,10 +3698,11 @@ static void R_DrawMaskedList (drawnode_t* head) R_DoneWithNode(r2); r2 = next; } - else if (r2->seg) + else if (r2->seg && r2->seg->maskedtexturecol != NULL) { next = r2->prev; R_RenderMaskedSegRange(r2->seg, r2->seg->x1, r2->seg->x2); + r2->seg->maskedtexturecol = NULL; R_DoneWithNode(r2); r2 = next; }