From 2863ede7bf06ed032e12825a07616d1f1b5be9b5 Mon Sep 17 00:00:00 2001 From: Jaime Passos Date: Sun, 8 Sep 2019 18:27:35 -0300 Subject: [PATCH 01/79] initial stuff --- src/android/i_video.c | 5 + src/console.c | 10 +- src/d_main.c | 19 +++- src/d_netcmd.c | 1 + src/djgppdos/vid_vesa.c | 5 + src/dummy/i_video.c | 5 + src/f_finale.c | 138 +++++++++++++------------ src/hardware/hw_cache.c | 32 ++++-- src/hardware/hw_draw.c | 16 +-- src/hardware/hw_main.c | 8 +- src/hardware/hw_md2.c | 2 +- src/hu_stuff.c | 3 + src/i_video.h | 1 + src/lua_hudlib.c | 4 +- src/m_menu.c | 120 ++++++++++++---------- src/p_setup.c | 29 +++--- src/p_setup.h | 3 + src/r_data.c | 6 +- src/r_data.h | 2 + src/r_main.c | 21 ++++ src/r_main.h | 4 + src/r_segs.c | 2 +- src/r_splats.c | 2 +- src/screen.c | 65 +++++++++--- src/screen.h | 4 +- src/sdl/i_video.c | 219 ++++++++++++++++++++++++---------------- src/st_stuff.c | 3 + src/v_video.c | 2 +- src/w_wad.c | 20 +++- src/w_wad.h | 1 + src/win32/win_vid.c | 5 + src/y_inter.c | 36 +++---- src/z_zone.h | 1 + 33 files changed, 507 insertions(+), 287 deletions(-) diff --git a/src/android/i_video.c b/src/android/i_video.c index 2d0151f5e..44e1cbac0 100644 --- a/src/android/i_video.c +++ b/src/android/i_video.c @@ -51,6 +51,11 @@ INT32 VID_SetMode(INT32 modenum) return 0; } +void VID_CheckRenderer(void) +{ + // .............. +} + const char *VID_GetModeName(INT32 modenum) { return "A320x240"; diff --git a/src/console.c b/src/console.c index 09a6cab45..f34958835 100644 --- a/src/console.c +++ b/src/console.c @@ -1288,7 +1288,7 @@ void CONS_Printf(const char *fmt, ...) if (con_startup) { #ifdef _WINDOWS - patch_t *con_backpic = W_CachePatchName("CONSBACK", PU_CACHE); + patch_t *con_backpic = W_CachePatchName("CONSBACK", PU_PATCH); // Jimita: CON_DrawBackpic just called V_DrawScaledPatch V_DrawScaledPatch(0, 0, 0, con_backpic); @@ -1545,7 +1545,7 @@ static void CON_DrawConsole(void) // draw console background if (cons_backpic.value || con_forcepic) { - patch_t *con_backpic = W_CachePatchName("CONSBACK", PU_CACHE); + patch_t *con_backpic = W_CachePatchName("CONSBACK", PU_PATCH); // Jimita: CON_DrawBackpic just called V_DrawScaledPatch V_DrawScaledPatch(0, 0, 0, con_backpic); @@ -1602,6 +1602,12 @@ void CON_Drawer(void) if (!con_started || !graphics_started) return; + if (needpatchrecache) + { + W_FlushCachedPatches(); + HU_LoadGraphics(); + } + if (con_recalc) CON_RecalcSize(); diff --git a/src/d_main.c b/src/d_main.c index eaeae4b10..a51ce0098 100644 --- a/src/d_main.c +++ b/src/d_main.c @@ -211,6 +211,7 @@ INT16 wipetypepost = -1; static void D_Display(void) { + INT32 setrenderstillneeded = setrenderneeded; boolean forcerefresh = false; static boolean wipe = false; INT32 wipedefindex = 0; @@ -221,15 +222,19 @@ static void D_Display(void) if (nodrawers) return; // for comparative timing/profiling + // stop movie if needs to change renderer + if (setrenderneeded && (moviemode != MM_OFF)) + M_StopMovie(); + // check for change of screen size (video mode) - if (setmodeneeded && !wipe) + if ((setmodeneeded || setrenderneeded) && !wipe) SCR_SetMode(); // change video mode - if (vid.recalc) + if (vid.recalc || setrenderstillneeded) SCR_Recalc(); // NOTE! setsizeneeded is set by SCR_Recalc() // change the view size if needed - if (setsizeneeded) + if (setsizeneeded || setrenderstillneeded) { R_ExecuteSetViewSize(); forcerefresh = true; // force background redraw @@ -445,7 +450,7 @@ static void D_Display(void) py = 4; else py = viewwindowy + 4; - patch = W_CachePatchName("M_PAUSE", PU_CACHE); + patch = W_CachePatchName("M_PAUSE", PU_PATCH); V_DrawScaledPatch(viewwindowx + (BASEVIDWIDTH - SHORT(patch->width))/2, py, 0, patch); #else INT32 y = ((automapactive) ? (32) : (BASEVIDHEIGHT/2)); @@ -520,6 +525,12 @@ static void D_Display(void) I_FinishUpdate(); // page flip or blit buffer } + + if (needpatchrecache) + R_ReloadHUDGraphics(); + + needpatchflush = false; + needpatchrecache = false; } // ========================================================================= diff --git a/src/d_netcmd.c b/src/d_netcmd.c index 590543f00..c277e23fb 100644 --- a/src/d_netcmd.c +++ b/src/d_netcmd.c @@ -812,6 +812,7 @@ void D_RegisterClientCommands(void) // screen.c CV_RegisterVar(&cv_fullscreen); CV_RegisterVar(&cv_renderview); + CV_RegisterVar(&cv_renderer); CV_RegisterVar(&cv_scr_depth); CV_RegisterVar(&cv_scr_width); CV_RegisterVar(&cv_scr_height); diff --git a/src/djgppdos/vid_vesa.c b/src/djgppdos/vid_vesa.c index ec7b8b886..c8ce7dae5 100644 --- a/src/djgppdos/vid_vesa.c +++ b/src/djgppdos/vid_vesa.c @@ -378,6 +378,11 @@ INT32 VID_SetMode (INT32 modenum) //, UINT8 *palette) return 1; } +void VID_CheckRenderer(void) +{ + // .............. +} + // converts a segm:offs 32bit pair to a 32bit flat ptr diff --git a/src/dummy/i_video.c b/src/dummy/i_video.c index e167e833f..b8f40bed3 100644 --- a/src/dummy/i_video.c +++ b/src/dummy/i_video.c @@ -39,6 +39,11 @@ INT32 VID_SetMode(INT32 modenum) return 0; } +void VID_CheckRenderer(void) +{ + // .............. +} + const char *VID_GetModeName(INT32 modenum) { (void)modenum; diff --git a/src/f_finale.c b/src/f_finale.c index da042abeb..e302d24ba 100644 --- a/src/f_finale.c +++ b/src/f_finale.c @@ -424,16 +424,16 @@ static void F_IntroDrawScene(void) // DRAW A FULL PIC INSTEAD OF FLAT! if (intro_scenenum == 0); else if (intro_scenenum == 1) - background = W_CachePatchName("INTRO1", PU_CACHE); + background = W_CachePatchName("INTRO1", PU_PATCH); else if (intro_scenenum == 2) { - background = W_CachePatchName("INTRO2", PU_CACHE); + background = W_CachePatchName("INTRO2", PU_PATCH); highres = true; } else if (intro_scenenum == 3) - background = W_CachePatchName("INTRO3", PU_CACHE); + background = W_CachePatchName("INTRO3", PU_PATCH); else if (intro_scenenum == 4) - background = W_CachePatchName("INTRO4", PU_CACHE); + background = W_CachePatchName("INTRO4", PU_PATCH); else if (intro_scenenum == 5) { if (intro_curtime >= 5*TICRATE) @@ -708,8 +708,8 @@ static void F_IntroDrawScene(void) y += (30*(FRACUNIT-scale)); } - rockpat = W_CachePatchName(va("ROID00%.2d", 34 - (worktics % 35)), PU_LEVEL); - glow = W_CachePatchName(va("ENDGLOW%.1d", 2+(worktics & 1)), PU_LEVEL); + rockpat = W_CachePatchName(va("ROID00%.2d", 34 - (worktics % 35)), PU_PATCH); + glow = W_CachePatchName(va("ENDGLOW%.1d", 2+(worktics & 1)), PU_PATCH); if (worktics >= 5) trans = (worktics-5)>>1; @@ -1350,14 +1350,14 @@ void F_GameEvaluationDrawer(void) if (goodending) { - rockpat = W_CachePatchName(va("ROID00%.2d", 34 - (finalecount % 35)), PU_LEVEL); - glow = W_CachePatchName(va("ENDGLOW%.1d", 2+(finalecount & 1)), PU_LEVEL); + rockpat = W_CachePatchName(va("ROID00%.2d", 34 - (finalecount % 35)), PU_PATCH); + glow = W_CachePatchName(va("ENDGLOW%.1d", 2+(finalecount & 1)), PU_PATCH); x -= FRACUNIT; } else { rockpat = W_CachePatchName("ROID0000", PU_LEVEL); - glow = W_CachePatchName(va("ENDGLOW%.1d", (finalecount & 1)), PU_LEVEL); + glow = W_CachePatchName(va("ENDGLOW%.1d", (finalecount & 1)), PU_PATCH); } if (finalecount >= 5) @@ -1389,20 +1389,20 @@ void F_GameEvaluationDrawer(void) // if j == 0 - alternate between 0 and 1 // 1 - 1 and 2 // 2 - 2 and not rendered - V_DrawFixedPatch(x+sparkloffs[j-1][0], y+sparkloffs[j-1][1], FRACUNIT, 0, W_CachePatchName(va("ENDSPKL%.1d", (j - ((sparklloop & 1) ? 0 : 1))), PU_LEVEL), R_GetTranslationColormap(TC_DEFAULT, SKINCOLOR_AQUA, GTC_CACHE)); + V_DrawFixedPatch(x+sparkloffs[j-1][0], y+sparkloffs[j-1][1], FRACUNIT, 0, W_CachePatchName(va("ENDSPKL%.1d", (j - ((sparklloop & 1) ? 0 : 1))), PU_PATCH), R_GetTranslationColormap(TC_DEFAULT, SKINCOLOR_AQUA, GTC_CACHE)); } j--; } } else { - patch_t *eggrock = W_CachePatchName("ENDEGRK5", PU_LEVEL); + patch_t *eggrock = W_CachePatchName("ENDEGRK5", PU_PATCH); V_DrawFixedPatch(x, y, scale, 0, eggrock, colormap[0]); if (trans < 10) V_DrawFixedPatch(x, y, scale, trans<spriteframes[2]; - endfwrk[0] = W_CachePatchNum(sprframe->lumppat[0], PU_LEVEL); + endfwrk[0] = W_CachePatchNum(sprframe->lumppat[0], PU_PATCH); sprframe = &sprdef->spriteframes[3]; - endfwrk[1] = W_CachePatchNum(sprframe->lumppat[0], PU_LEVEL); + endfwrk[1] = W_CachePatchNum(sprframe->lumppat[0], PU_PATCH); sprframe = &sprdef->spriteframes[4]; - endfwrk[2] = W_CachePatchNum(sprframe->lumppat[0], PU_LEVEL); + endfwrk[2] = W_CachePatchNum(sprframe->lumppat[0], PU_PATCH); } else // eh, yknow what? too lazy to put MISSINGs here. eggman wins if you don't give your character an ending firework display. { - endfwrk[0] = W_CachePatchName("ENDFWRK0", PU_LEVEL); - endfwrk[1] = W_CachePatchName("ENDFWRK1", PU_LEVEL); - endfwrk[2] = W_CachePatchName("ENDFWRK2", PU_LEVEL); + endfwrk[0] = W_CachePatchName("ENDFWRK0", PU_PATCH); + endfwrk[1] = W_CachePatchName("ENDFWRK1", PU_PATCH); + endfwrk[2] = W_CachePatchName("ENDFWRK2", PU_PATCH); } - endbrdr[0] = W_CachePatchName("ENDBRDR2", PU_LEVEL); + endbrdr[0] = W_CachePatchName("ENDBRDR2", PU_PATCH); } else { // eggman, skin nonspecific - endfwrk[0] = W_CachePatchName("ENDFWRK0", PU_LEVEL); - endfwrk[1] = W_CachePatchName("ENDFWRK1", PU_LEVEL); - endfwrk[2] = W_CachePatchName("ENDFWRK2", PU_LEVEL); + endfwrk[0] = W_CachePatchName("ENDFWRK0", PU_PATCH); + endfwrk[1] = W_CachePatchName("ENDFWRK1", PU_PATCH); + endfwrk[2] = W_CachePatchName("ENDFWRK2", PU_PATCH); endbrdr[0] = W_CachePatchName("ENDBRDR0", PU_LEVEL); } @@ -1626,13 +1626,13 @@ void F_EndingTicker(void) if (goodending && finalecount == INFLECTIONPOINT) // time to swap some assets { - endegrk[0] = W_CachePatchName("ENDEGRK2", PU_LEVEL); - endegrk[1] = W_CachePatchName("ENDEGRK3", PU_LEVEL); + endegrk[0] = W_CachePatchName("ENDEGRK2", PU_PATCH); + endegrk[1] = W_CachePatchName("ENDEGRK3", PU_PATCH); - endglow[0] = W_CachePatchName("ENDGLOW2", PU_LEVEL); - endglow[1] = W_CachePatchName("ENDGLOW3", PU_LEVEL); + endglow[0] = W_CachePatchName("ENDGLOW2", PU_PATCH); + endglow[1] = W_CachePatchName("ENDGLOW3", PU_PATCH); - endxpld[0] = W_CachePatchName("ENDEGRK4", PU_LEVEL); + endxpld[0] = W_CachePatchName("ENDEGRK4", PU_PATCH); } if (++sparklloop == SPARKLLOOPTIME) // time to roll the randomisation again @@ -1653,9 +1653,9 @@ void F_EndingDrawer(void) patch_t *rockpat; if (!goodending || finalecount < INFLECTIONPOINT) - rockpat = W_CachePatchName("ROID0000", PU_LEVEL); + rockpat = W_CachePatchName("ROID0000", PU_PATCH); else - rockpat = W_CachePatchName(va("ROID00%.2d", 34 - ((finalecount - INFLECTIONPOINT) % 35)), PU_LEVEL); + rockpat = W_CachePatchName(va("ROID00%.2d", 34 - ((finalecount - INFLECTIONPOINT) % 35)), PU_PATCH); V_DrawFill(0, 0, BASEVIDWIDTH, BASEVIDHEIGHT, 31); @@ -2171,6 +2171,25 @@ void F_SkyScroll(INT32 scrollxspeed, INT32 scrollyspeed, const char *patchname) W_UnlockCachedPatch(pat); } +static void F_CacheTitleScreen(void) +{ + ttbanner = W_CachePatchName("TTBANNER", PU_PATCH); + ttwing = W_CachePatchName("TTWING", PU_PATCH); + ttsonic = W_CachePatchName("TTSONIC", PU_PATCH); + ttswave1 = W_CachePatchName("TTSWAVE1", PU_PATCH); + ttswave2 = W_CachePatchName("TTSWAVE2", PU_PATCH); + ttswip1 = W_CachePatchName("TTSWIP1", PU_PATCH); + ttsprep1 = W_CachePatchName("TTSPREP1", PU_PATCH); + ttsprep2 = W_CachePatchName("TTSPREP2", PU_PATCH); + ttspop1 = W_CachePatchName("TTSPOP1", PU_PATCH); + ttspop2 = W_CachePatchName("TTSPOP2", PU_PATCH); + ttspop3 = W_CachePatchName("TTSPOP3", PU_PATCH); + ttspop4 = W_CachePatchName("TTSPOP4", PU_PATCH); + ttspop5 = W_CachePatchName("TTSPOP5", PU_PATCH); + ttspop6 = W_CachePatchName("TTSPOP6", PU_PATCH); + ttspop7 = W_CachePatchName("TTSPOP7", PU_PATCH); +} + void F_StartTitleScreen(void) { if (menupres[MN_MAIN].musname[0]) @@ -2255,21 +2274,7 @@ void F_StartTitleScreen(void) demoDelayLeft = demoDelayTime; demoIdleLeft = demoIdleTime; - ttbanner = W_CachePatchName("TTBANNER", PU_LEVEL); - ttwing = W_CachePatchName("TTWING", PU_LEVEL); - ttsonic = W_CachePatchName("TTSONIC", PU_LEVEL); - ttswave1 = W_CachePatchName("TTSWAVE1", PU_LEVEL); - ttswave2 = W_CachePatchName("TTSWAVE2", PU_LEVEL); - ttswip1 = W_CachePatchName("TTSWIP1", PU_LEVEL); - ttsprep1 = W_CachePatchName("TTSPREP1", PU_LEVEL); - ttsprep2 = W_CachePatchName("TTSPREP2", PU_LEVEL); - ttspop1 = W_CachePatchName("TTSPOP1", PU_LEVEL); - ttspop2 = W_CachePatchName("TTSPOP2", PU_LEVEL); - ttspop3 = W_CachePatchName("TTSPOP3", PU_LEVEL); - ttspop4 = W_CachePatchName("TTSPOP4", PU_LEVEL); - ttspop5 = W_CachePatchName("TTSPOP5", PU_LEVEL); - ttspop6 = W_CachePatchName("TTSPOP6", PU_LEVEL); - ttspop7 = W_CachePatchName("TTSPOP7", PU_LEVEL); + F_CacheTitleScreen(); } // (no longer) De-Demo'd Title Screen @@ -2280,6 +2285,9 @@ void F_TitleScreenDrawer(void) if (modeattacking) return; // We likely came here from retrying. Don't do a damn thing. + if (needpatchrecache) + F_CacheTitleScreen(); + // Draw that sky! if (curbgcolor >= 0) V_DrawFill(0, 0, BASEVIDWIDTH, BASEVIDHEIGHT, curbgcolor); diff --git a/src/hardware/hw_cache.c b/src/hardware/hw_cache.c index 6bc2c712e..258e3bb0d 100644 --- a/src/hardware/hw_cache.c +++ b/src/hardware/hw_cache.c @@ -754,16 +754,14 @@ void HWR_MakePatch (const patch_t *patch, GLPatch_t *grPatch, GLMipmap_t *grMipm // CACHING HANDLING // ================================================= -static size_t gr_numtextures; +static size_t gr_numtextures = 0; static GLTexture_t *gr_textures; // for ALL Doom textures void HWR_InitTextureCache(void) { - gr_numtextures = 0; gr_textures = NULL; } - // Callback function for HWR_FreeTextureCache. static void FreeMipmapColormap(INT32 patchnum, void *patch) { @@ -792,15 +790,17 @@ void HWR_FreeTextureCache(void) // Alam: free the Z_Blocks before freeing it's users // free all skin after each level: must be done after pfnClearMipMapCache! - for (i = 0; i < numwadfiles; i++) - M_AATreeIterate(wadfiles[i]->hwrcache, FreeMipmapColormap); + // temp fix, idk why this crashes + // is it because the colormaps were already freed anyway? + if (!needpatchrecache) + for (i = 0; i < numwadfiles; i++) + M_AATreeIterate(wadfiles[i]->hwrcache, FreeMipmapColormap); // now the heap don't have any 'user' pointing to our // texturecache info, we can free it if (gr_textures) free(gr_textures); gr_textures = NULL; - gr_numtextures = 0; } void HWR_PrepLevelCache(size_t pnumtextures) @@ -847,8 +847,11 @@ GLTexture_t *HWR_GetTexture(INT32 tex) GLTexture_t *grtex; #ifdef PARANOIA if ((unsigned)tex >= gr_numtextures) - I_Error(" HWR_GetTexture: tex >= numtextures\n"); + I_Error("HWR_GetTexture: tex >= numtextures\n"); #endif + if (needpatchrecache && (!gr_textures)) + HWR_PrepLevelCache(gr_numtextures); + grtex = &gr_textures[tex]; if (!grtex->mipmap.grInfo.data && !grtex->mipmap.downloaded) @@ -914,6 +917,9 @@ void HWR_GetFlat(lumpnum_t flatlumpnum) { GLMipmap_t *grmip; + if (needpatchflush) + W_FlushCachedPatches(); + grmip = &HWR_GetCachedGLPatch(flatlumpnum)->mipmap; if (!grmip->downloaded && !grmip->grInfo.data) @@ -950,6 +956,9 @@ static void HWR_LoadMappedPatch(GLMipmap_t *grmip, GLPatch_t *gpatch) // -----------------+ void HWR_GetPatch(GLPatch_t *gpatch) { + if (needpatchflush) + W_FlushCachedPatches(); + // is it in hardware cache if (!gpatch->mipmap.downloaded && !gpatch->mipmap.grInfo.data) { @@ -977,6 +986,9 @@ void HWR_GetMappedPatch(GLPatch_t *gpatch, const UINT8 *colormap) { GLMipmap_t *grmip, *newmip; + if (needpatchflush) + W_FlushCachedPatches(); + if (colormap == colormaps || colormap == NULL) { // Load the default (green) color in doom cache (temporary?) AND hardware cache @@ -1102,6 +1114,9 @@ GLPatch_t *HWR_GetPic(lumpnum_t lumpnum) { GLPatch_t *grpatch; + if (needpatchflush) + W_FlushCachedPatches(); + grpatch = HWR_GetCachedGLPatch(lumpnum); if (!grpatch->mipmap.downloaded && !grpatch->mipmap.grInfo.data) @@ -1299,6 +1314,9 @@ void HWR_GetFadeMask(lumpnum_t fademasklumpnum) { GLMipmap_t *grmip; + if (needpatchflush) + W_FlushCachedPatches(); + grmip = &HWR_GetCachedGLPatch(fademasklumpnum)->mipmap; if (!grmip->downloaded && !grmip->grInfo.data) diff --git a/src/hardware/hw_draw.c b/src/hardware/hw_draw.c index d9e688c0a..ea3183aa1 100644 --- a/src/hardware/hw_draw.c +++ b/src/hardware/hw_draw.c @@ -990,7 +990,7 @@ void HWR_DrawViewBorder(INT32 clearlines) // top edge if (clearlines > basewindowy - 8) { - patch = W_CachePatchNum(viewborderlump[BRDR_T], PU_CACHE); + patch = W_CachePatchNum(viewborderlump[BRDR_T], PU_PATCH); for (x = 0; x < baseviewwidth; x += 8) HWR_DrawPatch(patch, basewindowx + x, basewindowy - 8, 0); @@ -999,7 +999,7 @@ void HWR_DrawViewBorder(INT32 clearlines) // bottom edge if (clearlines > basewindowy + baseviewheight) { - patch = W_CachePatchNum(viewborderlump[BRDR_B], PU_CACHE); + patch = W_CachePatchNum(viewborderlump[BRDR_B], PU_PATCH); for (x = 0; x < baseviewwidth; x += 8) HWR_DrawPatch(patch, basewindowx + x, basewindowy + baseviewheight, 0); @@ -1008,7 +1008,7 @@ void HWR_DrawViewBorder(INT32 clearlines) // left edge if (clearlines > basewindowy) { - patch = W_CachePatchNum(viewborderlump[BRDR_L], PU_CACHE); + patch = W_CachePatchNum(viewborderlump[BRDR_L], PU_PATCH); for (y = 0; y < baseviewheight && basewindowy + y < clearlines; y += 8) { @@ -1020,7 +1020,7 @@ void HWR_DrawViewBorder(INT32 clearlines) // right edge if (clearlines > basewindowy) { - patch = W_CachePatchNum(viewborderlump[BRDR_R], PU_CACHE); + patch = W_CachePatchNum(viewborderlump[BRDR_R], PU_PATCH); for (y = 0; y < baseviewheight && basewindowy+y < clearlines; y += 8) { @@ -1032,22 +1032,22 @@ void HWR_DrawViewBorder(INT32 clearlines) // Draw beveled corners. if (clearlines > basewindowy - 8) HWR_DrawPatch(W_CachePatchNum(viewborderlump[BRDR_TL], - PU_CACHE), + PU_PATCH), basewindowx - 8, basewindowy - 8, 0); if (clearlines > basewindowy - 8) HWR_DrawPatch(W_CachePatchNum(viewborderlump[BRDR_TR], - PU_CACHE), + PU_PATCH), basewindowx + baseviewwidth, basewindowy - 8, 0); if (clearlines > basewindowy+baseviewheight) HWR_DrawPatch(W_CachePatchNum(viewborderlump[BRDR_BL], - PU_CACHE), + PU_PATCH), basewindowx - 8, basewindowy + baseviewheight, 0); if (clearlines > basewindowy + baseviewheight) HWR_DrawPatch(W_CachePatchNum(viewborderlump[BRDR_BR], - PU_CACHE), + PU_PATCH), basewindowx + baseviewwidth, basewindowy + baseviewheight, 0); } diff --git a/src/hardware/hw_main.c b/src/hardware/hw_main.c index c600800fd..ae20ee3ec 100644 --- a/src/hardware/hw_main.c +++ b/src/hardware/hw_main.c @@ -866,7 +866,7 @@ static void HWR_DrawSegsSplats(FSurfaceInfo * pSurf) if (!M_PointInBox(segbbox,splat->v1.x,splat->v1.y) && !M_PointInBox(segbbox,splat->v2.x,splat->v2.y)) continue; - gpatch = W_CachePatchNum(splat->patch, PU_CACHE); + gpatch = W_CachePatchNum(splat->patch, PU_PATCH); HWR_GetPatch(gpatch); wallVerts[0].x = wallVerts[3].x = FIXED_TO_FLOAT(splat->v1.x); @@ -4332,7 +4332,7 @@ static void HWR_SplitSprite(gr_vissprite_t *spr) if (hires) this_scale = this_scale * FIXED_TO_FLOAT(((skin_t *)spr->mobj->skin)->highresscale); - gpatch = W_CachePatchNum(spr->patchlumpnum, PU_CACHE); + gpatch = W_CachePatchNum(spr->patchlumpnum, PU_PATCH); // cache the patch in the graphics card memory //12/12/99: Hurdler: same comment as above (for md2) @@ -4688,7 +4688,7 @@ static void HWR_DrawSprite(gr_vissprite_t *spr) // sure to do it the right way. So actually, we keep normal sprite // in memory and we add the md2 model if it exists for that sprite - gpatch = W_CachePatchNum(spr->patchlumpnum, PU_CACHE); + gpatch = W_CachePatchNum(spr->patchlumpnum, PU_PATCH); #ifdef ALAM_LIGHTING if (!(spr->mobj->flags2 & MF2_DEBRIS) && (spr->mobj->sprite != SPR_PLAY || @@ -4833,7 +4833,7 @@ static inline void HWR_DrawPrecipitationSprite(gr_vissprite_t *spr) return; // cache sprite graphics - gpatch = W_CachePatchNum(spr->patchlumpnum, PU_CACHE); + gpatch = W_CachePatchNum(spr->patchlumpnum, PU_PATCH); // create the sprite billboard // diff --git a/src/hardware/hw_md2.c b/src/hardware/hw_md2.c index d4728315a..7f43f858a 100644 --- a/src/hardware/hw_md2.c +++ b/src/hardware/hw_md2.c @@ -1401,7 +1401,7 @@ void HWR_DrawMD2(gr_vissprite_t *spr) else { // Sprite - gpatch = W_CachePatchNum(spr->patchlumpnum, PU_CACHE); + gpatch = W_CachePatchNum(spr->patchlumpnum, PU_PATCH); HWR_GetMappedPatch(gpatch, spr->colormap); } diff --git a/src/hu_stuff.c b/src/hu_stuff.c index 3bc643c3c..7270cb986 100644 --- a/src/hu_stuff.c +++ b/src/hu_stuff.c @@ -2087,6 +2087,9 @@ static void HU_DrawDemoInfo(void) // void HU_Drawer(void) { + if (needpatchrecache) + R_ReloadHUDGraphics(); + #ifndef NONET // draw chat string plus cursor if (chat_on) diff --git a/src/i_video.h b/src/i_video.h index 4bb2c5829..a62f3ff64 100644 --- a/src/i_video.h +++ b/src/i_video.h @@ -84,6 +84,7 @@ INT32 VID_GetModeForSize(INT32 w, INT32 h); \return currect video mode */ INT32 VID_SetMode(INT32 modenum); +void VID_CheckRenderer(void); /** \brief The VID_GetModeName function diff --git a/src/lua_hudlib.c b/src/lua_hudlib.c index 8c1134bca..560b73819 100644 --- a/src/lua_hudlib.c +++ b/src/lua_hudlib.c @@ -407,7 +407,7 @@ static int libd_getSpritePatch(lua_State *L) return 0; // push both the patch and it's "flip" value - LUA_PushUserdata(L, W_CachePatchNum(sprframe->lumppat[angle], PU_STATIC), META_PATCH); + LUA_PushUserdata(L, W_CachePatchNum(sprframe->lumppat[angle], PU_PATCH), META_PATCH); lua_pushboolean(L, (sprframe->flip & (1<lumppat[angle], PU_STATIC), META_PATCH); + LUA_PushUserdata(L, W_CachePatchNum(sprframe->lumppat[angle], PU_PATCH), META_PATCH); lua_pushboolean(L, (sprframe->flip & (1<width) - SHORT(p->leftoffset); for (i = 0; i < 16; i++) { - V_DrawScaledPatch(xx, y, V_WRAPX, W_CachePatchNum(centerlump[i & 1], PU_CACHE)); + V_DrawScaledPatch(xx, y, V_WRAPX, W_CachePatchNum(centerlump[i & 1], PU_PATCH)); xx += 8; } - V_DrawScaledPatch(xx, y, 0, W_CachePatchNum(rightlump, PU_CACHE)); + V_DrawScaledPatch(xx, y, 0, W_CachePatchNum(rightlump, PU_PATCH)); xx = (cv->value - cv->PossibleValue[0].value) * (15*8) / (cv->PossibleValue[1].value - cv->PossibleValue[0].value); - V_DrawScaledPatch((x + 8) + xx, y, 0, W_CachePatchNum(cursorlump, PU_CACHE)); + V_DrawScaledPatch((x + 8) + xx, y, 0, W_CachePatchNum(cursorlump, PU_PATCH)); } // A smaller 'Thermo', with range given as percents (0-100) @@ -3678,15 +3680,15 @@ void M_DrawTextBox(INT32 x, INT32 y, INT32 width, INT32 boxlines) // draw left side cx = x; cy = y; - V_DrawScaledPatch(cx, cy, 0, W_CachePatchNum(viewborderlump[BRDR_TL], PU_CACHE)); + V_DrawScaledPatch(cx, cy, 0, W_CachePatchNum(viewborderlump[BRDR_TL], PU_PATCH)); cy += boff; - p = W_CachePatchNum(viewborderlump[BRDR_L], PU_CACHE); + p = W_CachePatchNum(viewborderlump[BRDR_L], PU_PATCH); for (n = 0; n < boxlines; n++) { V_DrawScaledPatch(cx, cy, V_WRAPY, p); cy += step; } - V_DrawScaledPatch(cx, cy, 0, W_CachePatchNum(viewborderlump[BRDR_BL], PU_CACHE)); + V_DrawScaledPatch(cx, cy, 0, W_CachePatchNum(viewborderlump[BRDR_BL], PU_PATCH)); // draw middle V_DrawFlatFill(x + boff, y + boff, width*step, boxlines*step, st_borderpatchnum); @@ -3695,23 +3697,23 @@ void M_DrawTextBox(INT32 x, INT32 y, INT32 width, INT32 boxlines) cy = y; while (width > 0) { - V_DrawScaledPatch(cx, cy, V_WRAPX, W_CachePatchNum(viewborderlump[BRDR_T], PU_CACHE)); - V_DrawScaledPatch(cx, y + boff + boxlines*step, V_WRAPX, W_CachePatchNum(viewborderlump[BRDR_B], PU_CACHE)); + V_DrawScaledPatch(cx, cy, V_WRAPX, W_CachePatchNum(viewborderlump[BRDR_T], PU_PATCH)); + V_DrawScaledPatch(cx, y + boff + boxlines*step, V_WRAPX, W_CachePatchNum(viewborderlump[BRDR_B], PU_PATCH)); width--; cx += step; } // draw right side cy = y; - V_DrawScaledPatch(cx, cy, 0, W_CachePatchNum(viewborderlump[BRDR_TR], PU_CACHE)); + V_DrawScaledPatch(cx, cy, 0, W_CachePatchNum(viewborderlump[BRDR_TR], PU_PATCH)); cy += boff; - p = W_CachePatchNum(viewborderlump[BRDR_R], PU_CACHE); + p = W_CachePatchNum(viewborderlump[BRDR_R], PU_PATCH); for (n = 0; n < boxlines; n++) { V_DrawScaledPatch(cx, cy, V_WRAPY, p); cy += step; } - V_DrawScaledPatch(cx, cy, 0, W_CachePatchNum(viewborderlump[BRDR_BR], PU_CACHE)); + V_DrawScaledPatch(cx, cy, 0, W_CachePatchNum(viewborderlump[BRDR_BR], PU_PATCH)); */ } @@ -4781,13 +4783,13 @@ static boolean M_PrepareLevelPlatter(INT32 gt, boolean nextmappick) W_UnlockCachedPatch(levselp[1][2]); } - levselp[0][0] = W_CachePatchName("SLCT1LVL", PU_STATIC); - levselp[0][1] = W_CachePatchName("SLCT2LVL", PU_STATIC); - levselp[0][2] = W_CachePatchName("BLANKLVL", PU_STATIC); + levselp[0][0] = W_CachePatchName("SLCT1LVL", PU_PATCH); + levselp[0][1] = W_CachePatchName("SLCT2LVL", PU_PATCH); + levselp[0][2] = W_CachePatchName("BLANKLVL", PU_PATCH); - levselp[1][0] = W_CachePatchName("SLCT1LVW", PU_STATIC); - levselp[1][1] = W_CachePatchName("SLCT2LVW", PU_STATIC); - levselp[1][2] = W_CachePatchName("BLANKLVW", PU_STATIC); + levselp[1][0] = W_CachePatchName("SLCT1LVW", PU_PATCH); + levselp[1][1] = W_CachePatchName("SLCT2LVW", PU_PATCH); + levselp[1][2] = W_CachePatchName("BLANKLVW", PU_PATCH); return true; } @@ -5435,6 +5437,27 @@ static void M_AddonsOptions(INT32 choice) #define LOCATIONSTRING1 "Visit \x83SRB2.ORG/MODS\x80 to get & make add-ons!" //#define LOCATIONSTRING2 "Visit \x88SRB2.ORG/MODS\x80 to get & make add-ons!" +static void M_LoadAddonsPatches(void) +{ + addonsp[EXT_FOLDER] = W_CachePatchName("M_FFLDR", PU_PATCH); + addonsp[EXT_UP] = W_CachePatchName("M_FBACK", PU_PATCH); + addonsp[EXT_NORESULTS] = W_CachePatchName("M_FNOPE", PU_PATCH); + addonsp[EXT_TXT] = W_CachePatchName("M_FTXT", PU_PATCH); + addonsp[EXT_CFG] = W_CachePatchName("M_FCFG", PU_PATCH); + addonsp[EXT_WAD] = W_CachePatchName("M_FWAD", PU_PATCH); +#ifdef USE_KART + addonsp[EXT_KART] = W_CachePatchName("M_FKART", PU_PATCH); +#endif + addonsp[EXT_PK3] = W_CachePatchName("M_FPK3", PU_PATCH); + addonsp[EXT_SOC] = W_CachePatchName("M_FSOC", PU_PATCH); + addonsp[EXT_LUA] = W_CachePatchName("M_FLUA", PU_PATCH); + addonsp[NUM_EXT] = W_CachePatchName("M_FUNKN", PU_PATCH); + addonsp[NUM_EXT+1] = W_CachePatchName("M_FSEL", PU_PATCH); + addonsp[NUM_EXT+2] = W_CachePatchName("M_FLOAD", PU_PATCH); + addonsp[NUM_EXT+3] = W_CachePatchName("M_FSRCH", PU_PATCH); + addonsp[NUM_EXT+4] = W_CachePatchName("M_FSAVE", PU_PATCH); +} + static void M_Addons(INT32 choice) { const char *pathname = "."; @@ -5485,23 +5508,7 @@ static void M_Addons(INT32 choice) W_UnlockCachedPatch(addonsp[i]); } - addonsp[EXT_FOLDER] = W_CachePatchName("M_FFLDR", PU_STATIC); - addonsp[EXT_UP] = W_CachePatchName("M_FBACK", PU_STATIC); - addonsp[EXT_NORESULTS] = W_CachePatchName("M_FNOPE", PU_STATIC); - addonsp[EXT_TXT] = W_CachePatchName("M_FTXT", PU_STATIC); - addonsp[EXT_CFG] = W_CachePatchName("M_FCFG", PU_STATIC); - addonsp[EXT_WAD] = W_CachePatchName("M_FWAD", PU_STATIC); -#ifdef USE_KART - addonsp[EXT_KART] = W_CachePatchName("M_FKART", PU_STATIC); -#endif - addonsp[EXT_PK3] = W_CachePatchName("M_FPK3", PU_STATIC); - addonsp[EXT_SOC] = W_CachePatchName("M_FSOC", PU_STATIC); - addonsp[EXT_LUA] = W_CachePatchName("M_FLUA", PU_STATIC); - addonsp[NUM_EXT] = W_CachePatchName("M_FUNKN", PU_STATIC); - addonsp[NUM_EXT+1] = W_CachePatchName("M_FSEL", PU_STATIC); - addonsp[NUM_EXT+2] = W_CachePatchName("M_FLOAD", PU_STATIC); - addonsp[NUM_EXT+3] = W_CachePatchName("M_FSRCH", PU_STATIC); - addonsp[NUM_EXT+4] = W_CachePatchName("M_FSAVE", PU_STATIC); + M_LoadAddonsPatches(); MISC_AddonsDef.prevMenu = currentMenu; M_SetupNextMenu(&MISC_AddonsDef); @@ -5640,6 +5647,9 @@ static void M_DrawAddons(void) return; } + if (needpatchrecache) + M_LoadAddonsPatches(); + if (Playing()) V_DrawCenteredString(BASEVIDWIDTH/2, 5, warningflags, "Adding files mid-game may cause problems."); else @@ -7015,7 +7025,7 @@ static void M_DrawLoadGameData(void) { lumpnum_t lumpnum = W_CheckNumForName(va("%sP", G_BuildMapName((savegameinfo[savetodraw].gamemap) & 8191))); if (lumpnum != LUMPERROR) - patch = W_CachePatchNum(lumpnum, PU_CACHE); + patch = W_CachePatchNum(lumpnum, PU_PATCH); else patch = savselp[5]; } @@ -7071,7 +7081,7 @@ static void M_DrawLoadGameData(void) goto skipbot; colormap = R_GetTranslationColormap(savegameinfo[savetodraw].botskin, charbotskin->prefcolor, 0); sprframe = &sprdef->spriteframes[0]; - patch = W_CachePatchNum(sprframe->lumppat[0], PU_CACHE); + patch = W_CachePatchNum(sprframe->lumppat[0], PU_PATCH); V_DrawFixedPatch( tempx + (18<numframes) goto skipsign; sprframe = &sprdef->spriteframes[0]; - patch = W_CachePatchNum(sprframe->lumppat[0], PU_CACHE); + patch = W_CachePatchNum(sprframe->lumppat[0], PU_PATCH); if ((calc = SHORT(patch->topoffset) - 42) > 0) tempy += ((4+calc)<numframes) goto skiplife; sprframe = &sprdef->spriteframes[0]; - patch = W_CachePatchNum(sprframe->lumppat[0], PU_CACHE); + patch = W_CachePatchNum(sprframe->lumppat[0], PU_PATCH); V_DrawFixedPatch( (tempx + 4)<spriteframes[1]; - description[i].pic = W_CachePatchNum(sprframe->lumppat[0], PU_CACHE); + description[i].pic = W_CachePatchNum(sprframe->lumppat[0], PU_PATCH); } else - description[i].pic = W_CachePatchName("MISSING", PU_CACHE); + description[i].pic = W_CachePatchName("MISSING", PU_PATCH); } else - description[i].pic = W_CachePatchName(description[i].picname, PU_CACHE); + description[i].pic = W_CachePatchName(description[i].picname, PU_PATCH); } // else -- Technically, character select icons without corresponding skins get bundled away behind this too. Sucks to be them. Z_Free(name); @@ -8044,7 +8054,7 @@ static void M_DrawLevelStats(void) V_DrawString(20, 56, V_GREENMAP, "(complete)"); V_DrawString(36, 64, 0, va("x %d/%d", M_CountEmblems(), numemblems+numextraemblems)); - V_DrawSmallScaledPatch(20, 64, 0, W_CachePatchName("EMBLICON", PU_STATIC)); + V_DrawSmallScaledPatch(20, 64, 0, W_CachePatchName("EMBLICON", PU_PATCH)); sprintf(beststr, "%u", bestscore); V_DrawString(BASEVIDWIDTH/2, 48, V_YELLOWMAP, "SCORE:"); @@ -9481,7 +9491,7 @@ static void M_DrawSetupMultiPlayerMenu(void) multi_frame = 0; sprframe = &sprdef->spriteframes[multi_frame]; - patch = W_CachePatchNum(sprframe->lumppat[0], PU_CACHE); + patch = W_CachePatchNum(sprframe->lumppat[0], PU_PATCH); if (sprframe->flip & 1) // Only for first sprite flags |= V_FLIP; // This sprite is left/right flipped! @@ -9502,7 +9512,7 @@ faildraw: return; // Can't render! sprframe = &sprdef->spriteframes[0]; - patch = W_CachePatchNum(sprframe->lumppat[0], PU_CACHE); + patch = W_CachePatchNum(sprframe->lumppat[0], PU_PATCH); if (sprframe->flip & 1) // Only for first sprite flags |= V_FLIP; // This sprite is left/right flipped! diff --git a/src/p_setup.c b/src/p_setup.c index d0cd14b22..592ce4d8c 100644 --- a/src/p_setup.c +++ b/src/p_setup.c @@ -2955,16 +2955,8 @@ boolean P_SetupLevel(boolean skipprecip) P_SpawnPrecipitation(); #ifdef HWRENDER // not win32 only 19990829 by Kin - if (rendermode != render_soft && rendermode != render_none) - { -#ifdef ALAM_LIGHTING - // BP: reset light between levels (we draw preview frame lights on current frame) - HWR_ResetLights(); -#endif - // Correct missing sidedefs & deep water trick - HWR_CorrectSWTricks(); - HWR_CreatePlanePolygons((INT32)numnodes - 1); - } + if (rendermode == render_opengl) + HWR_SetupLevel(); #endif // oh god I hope this helps @@ -3119,10 +3111,8 @@ boolean P_SetupLevel(boolean skipprecip) // preload graphics #ifdef HWRENDER // not win32 only 19990829 by Kin - if (rendermode != render_soft && rendermode != render_none) - { + if (rendermode == render_opengl) HWR_PrepLevelCache(numtextures); - } #endif P_MapEnd(); @@ -3220,6 +3210,19 @@ boolean P_SetupLevel(boolean skipprecip) return true; } +#ifdef HWRENDER +void HWR_SetupLevel(void) +{ +#ifdef ALAM_LIGHTING + // BP: reset light between levels (we draw preview frame lights on current frame) + HWR_ResetLights(); +#endif + // Correct missing sidedefs & deep water trick + HWR_CorrectSWTricks(); + HWR_CreatePlanePolygons((INT32)numnodes - 1); +} +#endif + // // P_RunSOC // diff --git a/src/p_setup.h b/src/p_setup.h index 7e8a5d7e6..27ea62778 100644 --- a/src/p_setup.h +++ b/src/p_setup.h @@ -60,6 +60,9 @@ void P_ScanThings(INT16 mapnum, INT16 wadnum, INT16 lumpnum); #endif void P_LoadThingsOnly(void); boolean P_SetupLevel(boolean skipprecip); +#ifdef HWRENDER +void HWR_SetupLevel(void); +#endif boolean P_AddWadFile(const char *wadfilename); boolean P_RunSOC(const char *socfilename); void P_LoadSoundsRange(UINT16 wadnum, UINT16 first, UINT16 num); diff --git a/src/r_data.c b/src/r_data.c index 6889bddde..d829700b4 100644 --- a/src/r_data.c +++ b/src/r_data.c @@ -95,6 +95,8 @@ size_t numspritelumps, max_spritelumps; // textures INT32 numtextures = 0; // total number of textures found, +boolean needpatchflush = false; +boolean needpatchrecache = false; // size of following tables texture_t **textures = NULL; @@ -1672,7 +1674,7 @@ lighttable_t *R_CreateLightTable(extracolormap_t *extra_colormap) ///////////////////// // This code creates the colormap array used by software renderer ///////////////////// - if (rendermode == render_soft) + //if (rendermode == render_soft) { double r, g, b, cbrightness; int p; @@ -2294,7 +2296,7 @@ void R_PrecacheLevel(void) lump = sf->lumppat[k]; if (devparm) spritememory += W_LumpLength(lump); - W_CachePatchNum(lump, PU_CACHE); + W_CachePatchNum(lump, PU_PATCH); } } } diff --git a/src/r_data.h b/src/r_data.h index b6b0a16a1..a077c1fdc 100644 --- a/src/r_data.h +++ b/src/r_data.h @@ -149,5 +149,7 @@ const char *R_NameForColormap(extracolormap_t *extra_colormap); #define R_PutRgbaRGBA(r, g, b, a) (R_PutRgbaRGB(r, g, b) + R_PutRgbaA(a)) extern INT32 numtextures; +extern boolean needpatchflush; +extern boolean needpatchrecache; #endif diff --git a/src/r_main.c b/src/r_main.c index db351e991..20e074b82 100644 --- a/src/r_main.c +++ b/src/r_main.c @@ -19,6 +19,7 @@ #include "r_local.h" #include "r_splats.h" // faB(21jan): testing #include "r_sky.h" +#include "hu_stuff.h" #include "st_stuff.h" #include "p_local.h" #include "keys.h" @@ -28,6 +29,7 @@ #include "d_main.h" #include "v_video.h" #include "p_spec.h" // skyboxmo +#include "p_setup.h" #include "z_zone.h" #include "m_random.h" // quake camera shake #include "r_portal.h" @@ -1148,6 +1150,25 @@ void R_RenderPlayerView(player_t *player) free(masks); } +#ifdef HWRENDER +void R_InitHardwareMode(void) +{ + if (gamestate == GS_LEVEL) + { + HWR_SetupLevel(); + HWR_PrepLevelCache(numtextures); + } +} +#endif + +void R_ReloadHUDGraphics(void) +{ + W_FlushCachedPatches(); + ST_LoadGraphics(); + HU_LoadGraphics(); + ST_ReloadSkinFaceGraphics(); +} + // ========================================================================= // ENGINE COMMANDS & VARS // ========================================================================= diff --git a/src/r_main.h b/src/r_main.h index 2c9b5cc3d..5a2ec9fec 100644 --- a/src/r_main.h +++ b/src/r_main.h @@ -84,6 +84,10 @@ extern consvar_t cv_tailspickup; // Called by startup code. void R_Init(void); +#ifdef HWRENDER +void R_InitHardwareMode(void); +#endif +void R_ReloadHUDGraphics(void); // just sets setsizeneeded true extern boolean setsizeneeded; diff --git a/src/r_segs.c b/src/r_segs.c index 6eb81ce7a..a36250d24 100644 --- a/src/r_segs.c +++ b/src/r_segs.c @@ -165,7 +165,7 @@ static void R_DrawWallSplats(void) mfloorclip = floorclip; mceilingclip = ceilingclip; - patch = W_CachePatchNum(splat->patch, PU_CACHE); + patch = W_CachePatchNum(splat->patch, PU_PATCH); dc_texturemid = splat->top + (SHORT(patch->height)<<(FRACBITS-1)) - viewz; if (splat->yoffset) diff --git a/src/r_splats.c b/src/r_splats.c index 9ab671274..e09e68aa1 100644 --- a/src/r_splats.c +++ b/src/r_splats.c @@ -147,7 +147,7 @@ void R_AddWallSplat(line_t *wallline, INT16 sectorside, const char *patchname, f splat->flags = flags; // bad.. but will be needed for drawing anyway.. - patch = W_CachePatchNum(splat->patch, PU_CACHE); + patch = W_CachePatchNum(splat->patch, PU_PATCH); // offset needed by draw code for texture mapping linelength = P_SegLength((seg_t *)wallline); diff --git a/src/screen.c b/src/screen.c index fc3f5b8e8..33e4dc897 100644 --- a/src/screen.c +++ b/src/screen.c @@ -60,6 +60,7 @@ void (*twosmultipatchtransfunc)(void); // for cols with transparent pixels AND t // ------------------ viddef_t vid; INT32 setmodeneeded; //video mode change needed if > 0 (the mode number to set + 1) +INT32 setrenderneeded = 0; static CV_PossibleValue_t scr_depth_cons_t[] = {{8, "8 bits"}, {16, "16 bits"}, {24, "24 bits"}, {32, "32 bits"}, {0, NULL}}; @@ -69,6 +70,10 @@ consvar_t cv_scr_height = {"scr_height", "800", CV_SAVE, CV_Unsigned, NULL, 0, N consvar_t cv_scr_depth = {"scr_depth", "16 bits", CV_SAVE, scr_depth_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL}; consvar_t cv_renderview = {"renderview", "On", 0, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL}; +static void SCR_ChangeRenderer (void); +static CV_PossibleValue_t cv_renderer_t[] = {{1, "Software"}, {2, "OpenGL"}, {0, NULL}}; +consvar_t cv_renderer = {"renderer", "Software", CV_CALL, cv_renderer_t, SCR_ChangeRenderer, 0, NULL, NULL, 0, 0, NULL}; + static void SCR_ChangeFullscreen (void); consvar_t cv_fullscreen = {"fullscreen", "Yes", CV_SAVE|CV_CALL, CV_YesNo, SCR_ChangeFullscreen, 0, NULL, NULL, 0, 0, NULL}; @@ -94,19 +99,8 @@ boolean R_3DNow = false; boolean R_MMXExt = false; boolean R_SSE2 = false; - -void SCR_SetMode(void) +void SCR_SetDrawFuncs(void) { - if (dedicated) - return; - - if (!setmodeneeded || WipeInAction) - return; // should never happen and don't change it during a wipe, BAD! - - VID_SetMode(--setmodeneeded); - - V_SetPalette(0); - // // setup the right draw routines for either 8bpp or 16bpp // @@ -166,9 +160,33 @@ void SCR_SetMode(void) */ wallcolfunc = walldrawerfunc; +} + +void SCR_SetMode(void) +{ + if (dedicated) + return; + + if (!(setmodeneeded || setrenderneeded) || WipeInAction) + return; // should never happen and don't change it during a wipe, BAD! + + if (setrenderneeded) + { + needpatchflush = true; + needpatchrecache = true; + VID_CheckRenderer(); + } + + if (setmodeneeded) + VID_SetMode(--setmodeneeded); + + V_SetPalette(0); + + SCR_SetDrawFuncs(); // set the apprpriate drawer for the sky (tall or INT16) setmodeneeded = 0; + setrenderneeded = 0; } // do some initial settings for the game loading screen @@ -385,6 +403,29 @@ void SCR_ChangeFullscreen(void) #endif } +void SCR_ChangeRenderer(void) +{ + setrenderneeded = 0; + + if (con_startup) + { + if (rendermode == render_soft) + CV_StealthSetValue(&cv_renderer, 1); + else if (rendermode == render_opengl) + CV_StealthSetValue(&cv_renderer, 2); + return; + } + + if (cv_renderer.value == 1) + setrenderneeded = render_soft; + else if (cv_renderer.value == 2) + setrenderneeded = render_opengl; + + // setting the same renderer twice WILL crash your game, so let's not, please + if (rendermode == setrenderneeded) + setrenderneeded = 0; +} + boolean SCR_IsAspectCorrect(INT32 width, INT32 height) { return diff --git a/src/screen.h b/src/screen.h index 7aa6fdb63..6f8b02bae 100644 --- a/src/screen.h +++ b/src/screen.h @@ -144,11 +144,12 @@ extern boolean R_SSE2; // ---------------- extern viddef_t vid; extern INT32 setmodeneeded; // mode number to set if needed, or 0 +extern INT32 setrenderneeded; extern INT32 scr_bpp; extern UINT8 *scr_borderpatch; // patch used to fill the view borders -extern consvar_t cv_scr_width, cv_scr_height, cv_scr_depth, cv_renderview, cv_fullscreen; +extern consvar_t cv_scr_width, cv_scr_height, cv_scr_depth, cv_renderview, cv_renderer, cv_fullscreen; // wait for page flipping to end or not extern consvar_t cv_vidwait; @@ -157,6 +158,7 @@ extern void (*walldrawerfunc)(void); // Change video mode, only at the start of a refresh. void SCR_SetMode(void); +void SCR_SetDrawFuncs(void); // Recalc screen size dependent stuff void SCR_Recalc(void); // Check parms once at startup diff --git a/src/sdl/i_video.c b/src/sdl/i_video.c index 5a4fd7a02..c8f4fdc31 100644 --- a/src/sdl/i_video.c +++ b/src/sdl/i_video.c @@ -70,6 +70,7 @@ #include "../i_video.h" #include "../console.h" #include "../command.h" +#include "../r_main.h" #include "sdlmain.h" #ifdef HWRENDER #include "../hardware/hw_main.h" @@ -169,6 +170,7 @@ static void Impl_VideoSetupBuffer(void); static SDL_bool Impl_CreateWindow(SDL_bool fullscreen); //static void Impl_SetWindowName(const char *title); static void Impl_SetWindowIcon(void); +static void I_StartupGraphicsGL(void); static void SDLSetMode(INT32 width, INT32 height, SDL_bool fullscreen) { @@ -1062,7 +1064,6 @@ void I_FinishUpdate(void) SDL_RenderCopy(renderer, texture, NULL, NULL); SDL_RenderPresent(renderer); } - #ifdef HWRENDER else if (rendermode == render_opengl) { @@ -1262,6 +1263,81 @@ void VID_PrepareModeList(void) #endif } +// SOMETIME IN +// THE FUTURE +// WHEN I ACTUALLY RENDER +// THIS FRAME +static int renderflags; +static SDL_bool Impl_CreateContext(int flags) +{ + // Renderer-specific stuff +#ifdef HWRENDER + if (rendermode == render_opengl) + { + if (!sdlglcontext) + sdlglcontext = SDL_GL_CreateContext(window); + if (sdlglcontext == NULL) + { + SDL_DestroyWindow(window); + I_Error("Failed to create a GL context: %s\n", SDL_GetError()); + } + SDL_GL_MakeCurrent(window, sdlglcontext); + } + else +#endif + if (rendermode == render_soft) + { + flags = 0; // Use this to set SDL_RENDERER_* flags now + if (usesdl2soft) + flags |= SDL_RENDERER_SOFTWARE; + else if (cv_vidwait.value) + flags |= SDL_RENDERER_PRESENTVSYNC; + + if (!renderer) + renderer = SDL_CreateRenderer(window, -1, flags); + if (renderer == NULL) + { + CONS_Printf(M_GetText("Couldn't create rendering context: %s\n"), SDL_GetError()); + return SDL_FALSE; + } + SDL_RenderSetLogicalSize(renderer, BASEVIDWIDTH, BASEVIDHEIGHT); + } + return SDL_TRUE; +} + +void VID_CheckRenderer(void) +{ + if (setrenderneeded) + { + rendermode = setrenderneeded; + Impl_CreateContext(renderflags); + if (rendermode == render_soft) + { +#ifdef HWRENDER + HWR_FreeTextureCache(); +#endif + SCR_SetDrawFuncs(); + } + } + + SDLSetMode(vid.width, vid.height, USE_FULLSCREEN); + + if (rendermode == render_soft) + { + if (bufSurface) + { + SDL_FreeSurface(bufSurface); + bufSurface = NULL; + } + Impl_VideoSetupBuffer(); + } + else if (rendermode == render_opengl) + { + I_StartupGraphicsGL(); + R_InitHardwareMode(); + } +} + INT32 VID_SetMode(INT32 modeNum) { SDLdoUngrabMouse(); @@ -1293,20 +1369,7 @@ INT32 VID_SetMode(INT32 modeNum) vid.modenum = -1; } //Impl_SetWindowName("SRB2 "VERSIONSTRING); - - SDLSetMode(vid.width, vid.height, USE_FULLSCREEN); - - if (rendermode == render_soft) - { - if (bufSurface) - { - SDL_FreeSurface(bufSurface); - bufSurface = NULL; - } - - Impl_VideoSetupBuffer(); - } - + VID_CheckRenderer(); return SDL_TRUE; } @@ -1341,38 +1404,8 @@ static SDL_bool Impl_CreateWindow(SDL_bool fullscreen) return SDL_FALSE; } - // Renderer-specific stuff -#ifdef HWRENDER - if (rendermode == render_opengl) - { - sdlglcontext = SDL_GL_CreateContext(window); - if (sdlglcontext == NULL) - { - SDL_DestroyWindow(window); - I_Error("Failed to create a GL context: %s\n", SDL_GetError()); - } - SDL_GL_MakeCurrent(window, sdlglcontext); - } - else -#endif - if (rendermode == render_soft) - { - flags = 0; // Use this to set SDL_RENDERER_* flags now - if (usesdl2soft) - flags |= SDL_RENDERER_SOFTWARE; - else if (cv_vidwait.value) - flags |= SDL_RENDERER_PRESENTVSYNC; - - renderer = SDL_CreateRenderer(window, -1, flags); - if (renderer == NULL) - { - CONS_Printf(M_GetText("Couldn't create rendering context: %s\n"), SDL_GetError()); - return SDL_FALSE; - } - SDL_RenderSetLogicalSize(renderer, BASEVIDWIDTH, BASEVIDHEIGHT); - } - - return SDL_TRUE; + renderflags = flags; + return Impl_CreateContext(flags); } /* @@ -1441,6 +1474,51 @@ static void Impl_VideoSetupBuffer(void) } } +static void I_StartupGraphicsGL(void) +{ +#ifdef HWRENDER + static boolean glstartup = false; + if (!glstartup) + { + HWD.pfnInit = hwSym("Init",NULL); + HWD.pfnFinishUpdate = NULL; + HWD.pfnDraw2DLine = hwSym("Draw2DLine",NULL); + HWD.pfnDrawPolygon = hwSym("DrawPolygon",NULL); + HWD.pfnSetBlend = hwSym("SetBlend",NULL); + HWD.pfnClearBuffer = hwSym("ClearBuffer",NULL); + HWD.pfnSetTexture = hwSym("SetTexture",NULL); + HWD.pfnReadRect = hwSym("ReadRect",NULL); + HWD.pfnGClipRect = hwSym("GClipRect",NULL); + HWD.pfnClearMipMapCache = hwSym("ClearMipMapCache",NULL); + HWD.pfnSetSpecialState = hwSym("SetSpecialState",NULL); + HWD.pfnSetPalette = hwSym("SetPalette",NULL); + HWD.pfnGetTextureUsed = hwSym("GetTextureUsed",NULL); + HWD.pfnDrawMD2 = hwSym("DrawMD2",NULL); + HWD.pfnDrawMD2i = hwSym("DrawMD2i",NULL); + HWD.pfnSetTransform = hwSym("SetTransform",NULL); + HWD.pfnGetRenderVersion = hwSym("GetRenderVersion",NULL); +#ifdef SHUFFLE + HWD.pfnPostImgRedraw = hwSym("PostImgRedraw",NULL); +#endif + HWD.pfnFlushScreenTextures=hwSym("FlushScreenTextures",NULL); + HWD.pfnStartScreenWipe = hwSym("StartScreenWipe",NULL); + HWD.pfnEndScreenWipe = hwSym("EndScreenWipe",NULL); + HWD.pfnDoScreenWipe = hwSym("DoScreenWipe",NULL); + HWD.pfnDrawIntermissionBG=hwSym("DrawIntermissionBG",NULL); + HWD.pfnMakeScreenTexture= hwSym("MakeScreenTexture",NULL); + HWD.pfnMakeScreenFinalTexture=hwSym("MakeScreenFinalTexture",NULL); + HWD.pfnDrawScreenFinalTexture=hwSym("DrawScreenFinalTexture",NULL); + // check gl renderer lib + if (HWD.pfnGetRenderVersion() != VERSION) + I_Error("%s", M_GetText("The version of the renderer doesn't match the version of the executable\nBe sure you have installed SRB2 properly.\n")); + if (!HWD.pfnInit(I_Error)) // let load the OpenGL library + rendermode = render_soft; + else + glstartup = true; + } +#endif +} + void I_StartupGraphics(void) { if (dedicated) @@ -1481,10 +1559,11 @@ void I_StartupGraphics(void) )) framebuffer = SDL_TRUE; } - if (M_CheckParm("-software")) - { + + if (M_CheckParm("-opengl")) + rendermode = render_opengl; + else if (M_CheckParm("software")) rendermode = render_soft; - } usesdl2soft = M_CheckParm("-softblit"); borderlesswindow = M_CheckParm("-borderless"); @@ -1492,45 +1571,7 @@ void I_StartupGraphics(void) //SDL_EnableKeyRepeat(SDL_DEFAULT_REPEAT_DELAY>>1,SDL_DEFAULT_REPEAT_INTERVAL<<2); VID_Command_ModeList_f(); #ifdef HWRENDER - if (M_CheckParm("-opengl") || rendermode == render_opengl) - { - rendermode = render_opengl; - HWD.pfnInit = hwSym("Init",NULL); - HWD.pfnFinishUpdate = NULL; - HWD.pfnDraw2DLine = hwSym("Draw2DLine",NULL); - HWD.pfnDrawPolygon = hwSym("DrawPolygon",NULL); - HWD.pfnSetBlend = hwSym("SetBlend",NULL); - HWD.pfnClearBuffer = hwSym("ClearBuffer",NULL); - HWD.pfnSetTexture = hwSym("SetTexture",NULL); - HWD.pfnReadRect = hwSym("ReadRect",NULL); - HWD.pfnGClipRect = hwSym("GClipRect",NULL); - HWD.pfnClearMipMapCache = hwSym("ClearMipMapCache",NULL); - HWD.pfnSetSpecialState = hwSym("SetSpecialState",NULL); - HWD.pfnSetPalette = hwSym("SetPalette",NULL); - HWD.pfnGetTextureUsed = hwSym("GetTextureUsed",NULL); - HWD.pfnDrawMD2 = hwSym("DrawMD2",NULL); - HWD.pfnDrawMD2i = hwSym("DrawMD2i",NULL); - HWD.pfnSetTransform = hwSym("SetTransform",NULL); - HWD.pfnGetRenderVersion = hwSym("GetRenderVersion",NULL); -#ifdef SHUFFLE - HWD.pfnPostImgRedraw = hwSym("PostImgRedraw",NULL); -#endif - HWD.pfnFlushScreenTextures=hwSym("FlushScreenTextures",NULL); - HWD.pfnStartScreenWipe = hwSym("StartScreenWipe",NULL); - HWD.pfnEndScreenWipe = hwSym("EndScreenWipe",NULL); - HWD.pfnDoScreenWipe = hwSym("DoScreenWipe",NULL); - HWD.pfnDrawIntermissionBG=hwSym("DrawIntermissionBG",NULL); - HWD.pfnMakeScreenTexture= hwSym("MakeScreenTexture",NULL); - HWD.pfnMakeScreenFinalTexture=hwSym("MakeScreenFinalTexture",NULL); - HWD.pfnDrawScreenFinalTexture=hwSym("DrawScreenFinalTexture",NULL); - // check gl renderer lib - if (HWD.pfnGetRenderVersion() != VERSION) - I_Error("%s", M_GetText("The version of the renderer doesn't match the version of the executable\nBe sure you have installed SRB2 properly.\n")); - if (!HWD.pfnInit(I_Error)) // let load the OpenGL library - { - rendermode = render_soft; - } - } + I_StartupGraphicsGL(); #endif // Fury: we do window initialization after GL setup to allow diff --git a/src/st_stuff.c b/src/st_stuff.c index a90661ef3..1afe9f4cc 100644 --- a/src/st_stuff.c +++ b/src/st_stuff.c @@ -2554,6 +2554,9 @@ static void ST_overlayDrawer(void) void ST_Drawer(void) { + if (needpatchrecache) + R_ReloadHUDGraphics(); + #ifdef SEENAMES if (cv_seenames.value && cv_allowseenames.value && displayplayer == consoleplayer && seenplayer && seenplayer->mo) { diff --git a/src/v_video.c b/src/v_video.c index 082d84915..a1ba5406f 100644 --- a/src/v_video.c +++ b/src/v_video.c @@ -1069,7 +1069,7 @@ void V_DrawContinueIcon(INT32 x, INT32 y, INT32 flags, INT32 skinnum, UINT8 skin else { spriteframe_t *sprframe = &skins[skinnum].sprites[SPR2_WAIT].spriteframes[0]; - patch_t *patch = W_CachePatchNum(sprframe->lumppat[0], PU_CACHE); + patch_t *patch = W_CachePatchNum(sprframe->lumppat[0], PU_PATCH); const UINT8 *colormap = R_GetTranslationColormap(skinnum, skincolor, GTC_CACHE); // No variant for translucency diff --git a/src/w_wad.c b/src/w_wad.c index d02ce9ce6..01910ba44 100644 --- a/src/w_wad.c +++ b/src/w_wad.c @@ -53,6 +53,7 @@ #include "dehacked.h" #include "d_clisrv.h" #include "r_defs.h" +#include "r_data.h" #include "i_system.h" #include "md5.h" #include "lua_script.h" @@ -1401,7 +1402,6 @@ void *W_CacheLumpNumPwad(UINT16 wad, UINT16 lump, INT32 tag) void *W_CacheLumpNum(lumpnum_t lumpnum, INT32 tag) { - return W_CacheLumpNumPwad(WADFILENUM(lumpnum),LUMPNUM(lumpnum),tag); } @@ -1482,12 +1482,30 @@ void *W_CacheLumpName(const char *name, INT32 tag) // Cache a patch into heap memory, convert the patch format as necessary // +void W_FlushCachedPatches(void) +{ + if (needpatchflush) + { + Z_FreeTag(PU_CACHE); + Z_FreeTag(PU_PATCH); + Z_FreeTag(PU_HUDGFX); + Z_FreeTag(PU_HWRPATCHINFO); + Z_FreeTag(PU_HWRPATCHCOLMIPMAP); + Z_FreeTag(PU_HWRCACHE); + Z_FreeTags(PU_HWRCACHE_UNLOCKED, PU_HWRPATCHINFO_UNLOCKED); + } + needpatchflush = false; +} + // Software-only compile cache the data without conversion #ifdef HWRENDER static inline void *W_CachePatchNumPwad(UINT16 wad, UINT16 lump, INT32 tag) { GLPatch_t *grPatch; + if (needpatchflush) + W_FlushCachedPatches(); + if (rendermode == render_soft || rendermode == render_none) return W_CacheLumpNumPwad(wad, lump, tag); diff --git a/src/w_wad.h b/src/w_wad.h index 651738850..965a0d697 100644 --- a/src/w_wad.h +++ b/src/w_wad.h @@ -180,6 +180,7 @@ void *W_CachePatchNum(lumpnum_t lumpnum, INT32 tag); // return a patch_t #endif void W_UnlockCachedPatch(void *patch); +void W_FlushCachedPatches(void); void W_VerifyFileMD5(UINT16 wadfilenum, const char *matchmd5); diff --git a/src/win32/win_vid.c b/src/win32/win_vid.c index e2f32fa61..38be7a6b8 100644 --- a/src/win32/win_vid.c +++ b/src/win32/win_vid.c @@ -943,6 +943,11 @@ INT32 VID_SetMode(INT32 modenum) return 1; } +void VID_CheckRenderer(void) +{ + // .............. +} + // ======================================================================== // Free the video buffer of the last video mode, // allocate a new buffer for the video mode to set. diff --git a/src/y_inter.c b/src/y_inter.c index 975902ab0..632cf8795 100644 --- a/src/y_inter.c +++ b/src/y_inter.c @@ -1221,20 +1221,20 @@ void Y_StartIntermission(void) } for (i = 0; i < 4; ++i) - data.coop.bonuspatches[i] = W_CachePatchName(data.coop.bonuses[i].patch, PU_STATIC); - data.coop.ptotal = W_CachePatchName("YB_TOTAL", PU_STATIC); + data.coop.bonuspatches[i] = W_CachePatchName(data.coop.bonuses[i].patch, PU_PATCH); + data.coop.ptotal = W_CachePatchName("YB_TOTAL", PU_PATCH); // get act number data.coop.actnum = mapheaderinfo[gamemap-1]->actnum; // get background patches - widebgpatch = W_CachePatchName("INTERSCW", PU_STATIC); - bgpatch = W_CachePatchName("INTERSCR", PU_STATIC); + widebgpatch = W_CachePatchName("INTERSCW", PU_PATCH); + bgpatch = W_CachePatchName("INTERSCR", PU_PATCH); // grab an interscreen if appropriate if (mapheaderinfo[gamemap-1]->interscreen[0] != '#') { - interpic = W_CachePatchName(mapheaderinfo[gamemap-1]->interscreen, PU_STATIC); + interpic = W_CachePatchName(mapheaderinfo[gamemap-1]->interscreen, PU_PATCH); useinterpic = true; usebuffer = false; } @@ -1324,18 +1324,18 @@ void Y_StartIntermission(void) Y_AwardSpecialStageBonus(); for (i = 0; i < 2; ++i) - data.spec.bonuspatches[i] = W_CachePatchName(data.spec.bonuses[i].patch, PU_STATIC); + data.spec.bonuspatches[i] = W_CachePatchName(data.spec.bonuses[i].patch, PU_PATCH); - data.spec.pscore = W_CachePatchName("YB_SCORE", PU_STATIC); - data.spec.pcontinues = W_CachePatchName("YB_CONTI", PU_STATIC); + data.spec.pscore = W_CachePatchName("YB_SCORE", PU_PATCH); + data.spec.pcontinues = W_CachePatchName("YB_CONTI", PU_PATCH); // get background tile - bgtile = W_CachePatchName("SPECTILE", PU_STATIC); + bgtile = W_CachePatchName("SPECTILE", PU_PATCH); // grab an interscreen if appropriate if (mapheaderinfo[gamemap-1]->interscreen[0] != '#') { - interpic = W_CachePatchName(mapheaderinfo[gamemap-1]->interscreen, PU_STATIC); + interpic = W_CachePatchName(mapheaderinfo[gamemap-1]->interscreen, PU_PATCH); useinterpic = true; } else @@ -1347,14 +1347,14 @@ void Y_StartIntermission(void) // get special stage specific patches /* if (!stagefailed && ALL7EMERALDS(emeralds)) { - data.spec.cemerald = W_CachePatchName("GOTEMALL", PU_STATIC); + data.spec.cemerald = W_CachePatchName("GOTEMALL", PU_PATCH); data.spec.headx = 70; data.spec.nowsuper = players[consoleplayer].skin ? NULL : W_CachePatchName("NOWSUPER", PU_STATIC); } else { - data.spec.cemerald = W_CachePatchName("CEMERALD", PU_STATIC); + data.spec.cemerald = W_CachePatchName("CEMERALD", PU_PATCH); data.spec.headx = 48; data.spec.nowsuper = NULL; } */ @@ -1432,9 +1432,9 @@ void Y_StartIntermission(void) // get RESULT header data.match.result = - W_CachePatchName("RESULT", PU_STATIC); + W_CachePatchName("RESULT", PU_PATCH); - bgtile = W_CachePatchName("SRB2BACK", PU_STATIC); + bgtile = W_CachePatchName("SRB2BACK", PU_PATCH); usetile = true; useinterpic = false; break; @@ -1460,9 +1460,9 @@ void Y_StartIntermission(void) data.match.levelstring[sizeof data.match.levelstring - 1] = '\0'; // get RESULT header - data.match.result = W_CachePatchName("RESULT", PU_STATIC); + data.match.result = W_CachePatchName("RESULT", PU_PATCH); - bgtile = W_CachePatchName("SRB2BACK", PU_STATIC); + bgtile = W_CachePatchName("SRB2BACK", PU_PATCH); usetile = true; useinterpic = false; break; @@ -1499,7 +1499,7 @@ void Y_StartIntermission(void) data.match.blueflag = bmatcico; } - bgtile = W_CachePatchName("SRB2BACK", PU_STATIC); + bgtile = W_CachePatchName("SRB2BACK", PU_PATCH); usetile = true; useinterpic = false; break; @@ -1525,7 +1525,7 @@ void Y_StartIntermission(void) data.competition.levelstring[sizeof data.competition.levelstring - 1] = '\0'; // get background tile - bgtile = W_CachePatchName("SRB2BACK", PU_STATIC); + bgtile = W_CachePatchName("SRB2BACK", PU_PATCH); usetile = true; useinterpic = false; break; diff --git a/src/z_zone.h b/src/z_zone.h index 8d32e74f1..af8ca1241 100644 --- a/src/z_zone.h +++ b/src/z_zone.h @@ -43,6 +43,7 @@ enum PU_SOUND = 11, // static while playing PU_MUSIC = 12, // static while playing PU_HUDGFX = 13, // static until WAD added + PU_PATCH = 14, // static until renderer change PU_HWRPATCHINFO = 21, // Hardware GLPatch_t struct for OpenGL texture cache PU_HWRPATCHCOLMIPMAP = 22, // Hardware GLMipmap_t struct colormap variation of patch From c7e01a558e829ec0595a7df378f6197ea5a87014 Mon Sep 17 00:00:00 2001 From: Jaime Passos Date: Sun, 8 Sep 2019 18:27:35 -0300 Subject: [PATCH 02/79] initial stuff --- src/android/i_video.c | 5 + src/console.c | 10 +- src/d_main.c | 19 +++- src/d_netcmd.c | 1 + src/djgppdos/vid_vesa.c | 5 + src/dummy/i_video.c | 5 + src/f_finale.c | 50 +++++---- src/hardware/hw_cache.c | 32 ++++-- src/hardware/hw_draw.c | 16 +-- src/hardware/hw_main.c | 8 +- src/hardware/hw_md2.c | 2 +- src/hu_stuff.c | 3 + src/i_video.h | 1 + src/m_menu.c | 66 ++++++------ src/p_setup.c | 29 +++--- src/p_setup.h | 3 + src/r_data.c | 5 +- src/r_data.h | 2 + src/r_main.c | 21 ++++ src/r_main.h | 4 + src/r_segs.c | 2 +- src/r_splats.c | 2 +- src/screen.c | 68 ++++++++++--- src/screen.h | 4 +- src/sdl/i_video.c | 219 ++++++++++++++++++++++++---------------- src/st_stuff.c | 3 + src/w_wad.c | 20 +++- src/w_wad.h | 1 + src/win32/win_vid.c | 5 + src/y_inter.c | 36 +++---- src/z_zone.h | 1 + 31 files changed, 433 insertions(+), 215 deletions(-) diff --git a/src/android/i_video.c b/src/android/i_video.c index 2d0151f5e..44e1cbac0 100644 --- a/src/android/i_video.c +++ b/src/android/i_video.c @@ -51,6 +51,11 @@ INT32 VID_SetMode(INT32 modenum) return 0; } +void VID_CheckRenderer(void) +{ + // .............. +} + const char *VID_GetModeName(INT32 modenum) { return "A320x240"; diff --git a/src/console.c b/src/console.c index 91baf25fc..826153ff0 100644 --- a/src/console.c +++ b/src/console.c @@ -1269,7 +1269,7 @@ void CONS_Printf(const char *fmt, ...) if (con_startup) { #if (defined (_WINDOWS)) || (defined (__OS2__) && !defined (HAVE_SDL)) - patch_t *con_backpic = W_CachePatchName("CONSBACK", PU_CACHE); + patch_t *con_backpic = W_CachePatchName("CONSBACK", PU_PATCH); // Jimita: CON_DrawBackpic just called V_DrawScaledPatch V_DrawScaledPatch(0, 0, 0, con_backpic); @@ -1526,7 +1526,7 @@ static void CON_DrawConsole(void) // draw console background if (cons_backpic.value || con_forcepic) { - patch_t *con_backpic = W_CachePatchName("CONSBACK", PU_CACHE); + patch_t *con_backpic = W_CachePatchName("CONSBACK", PU_PATCH); // Jimita: CON_DrawBackpic just called V_DrawScaledPatch V_DrawScaledPatch(0, 0, 0, con_backpic); @@ -1583,6 +1583,12 @@ void CON_Drawer(void) if (!con_started || !graphics_started) return; + if (needpatchrecache) + { + W_FlushCachedPatches(); + HU_LoadGraphics(); + } + if (con_recalc) CON_RecalcSize(); diff --git a/src/d_main.c b/src/d_main.c index 3344732e5..06489ac7c 100644 --- a/src/d_main.c +++ b/src/d_main.c @@ -227,6 +227,7 @@ gamestate_t wipegamestate = GS_LEVEL; static void D_Display(void) { + INT32 setrenderstillneeded = setrenderneeded; boolean forcerefresh = false; static boolean wipe = false; INT32 wipedefindex = 0; @@ -237,15 +238,19 @@ static void D_Display(void) if (nodrawers) return; // for comparative timing/profiling + // stop movie if needs to change renderer + if (setrenderneeded && (moviemode != MM_OFF)) + M_StopMovie(); + // check for change of screen size (video mode) - if (setmodeneeded && !wipe) + if ((setmodeneeded || setrenderneeded) && !wipe) SCR_SetMode(); // change video mode - if (vid.recalc) + if (vid.recalc || setrenderstillneeded) SCR_Recalc(); // NOTE! setsizeneeded is set by SCR_Recalc() // change the view size if needed - if (setsizeneeded) + if (setsizeneeded || setrenderstillneeded) { R_ExecuteSetViewSize(); forcerefresh = true; // force background redraw @@ -426,7 +431,7 @@ static void D_Display(void) py = 4; else py = viewwindowy + 4; - patch = W_CachePatchName("M_PAUSE", PU_CACHE); + patch = W_CachePatchName("M_PAUSE", PU_PATCH); V_DrawScaledPatch(viewwindowx + (BASEVIDWIDTH - SHORT(patch->width))/2, py, 0, patch); } @@ -489,6 +494,12 @@ static void D_Display(void) I_FinishUpdate(); // page flip or blit buffer } + + if (needpatchrecache) + R_ReloadHUDGraphics(); + + needpatchflush = false; + needpatchrecache = false; } // ========================================================================= diff --git a/src/d_netcmd.c b/src/d_netcmd.c index cc9127af0..1e9915e1d 100644 --- a/src/d_netcmd.c +++ b/src/d_netcmd.c @@ -771,6 +771,7 @@ void D_RegisterClientCommands(void) // screen.c CV_RegisterVar(&cv_fullscreen); CV_RegisterVar(&cv_renderview); + CV_RegisterVar(&cv_renderer); CV_RegisterVar(&cv_scr_depth); CV_RegisterVar(&cv_scr_width); CV_RegisterVar(&cv_scr_height); diff --git a/src/djgppdos/vid_vesa.c b/src/djgppdos/vid_vesa.c index ec7b8b886..c8ce7dae5 100644 --- a/src/djgppdos/vid_vesa.c +++ b/src/djgppdos/vid_vesa.c @@ -378,6 +378,11 @@ INT32 VID_SetMode (INT32 modenum) //, UINT8 *palette) return 1; } +void VID_CheckRenderer(void) +{ + // .............. +} + // converts a segm:offs 32bit pair to a 32bit flat ptr diff --git a/src/dummy/i_video.c b/src/dummy/i_video.c index e167e833f..b8f40bed3 100644 --- a/src/dummy/i_video.c +++ b/src/dummy/i_video.c @@ -39,6 +39,11 @@ INT32 VID_SetMode(INT32 modenum) return 0; } +void VID_CheckRenderer(void) +{ + // .............. +} + const char *VID_GetModeName(INT32 modenum) { (void)modenum; diff --git a/src/f_finale.c b/src/f_finale.c index 63221fc23..58d57948b 100644 --- a/src/f_finale.c +++ b/src/f_finale.c @@ -466,16 +466,16 @@ static void F_IntroDrawScene(void) // DRAW A FULL PIC INSTEAD OF FLAT! if (intro_scenenum == 0); else if (intro_scenenum == 1) - background = W_CachePatchName("INTRO1", PU_CACHE); + background = W_CachePatchName("INTRO1", PU_PATCH); else if (intro_scenenum == 2) { - background = W_CachePatchName("INTRO2", PU_CACHE); + background = W_CachePatchName("INTRO2", PU_PATCH); highres = true; } else if (intro_scenenum == 3) - background = W_CachePatchName("INTRO3", PU_CACHE); + background = W_CachePatchName("INTRO3", PU_PATCH); else if (intro_scenenum == 4) - background = W_CachePatchName("INTRO4", PU_CACHE); + background = W_CachePatchName("INTRO4", PU_PATCH); else if (intro_scenenum == 5) { if (intro_curtime >= 5*TICRATE) @@ -734,7 +734,7 @@ static void F_IntroDrawScene(void) if (roidtics >= 0) { V_DrawScaledPatch(roidtics, 24, 0, - (patch = W_CachePatchName(va("ROID00%.2d", intro_curtime%35), PU_CACHE))); + (patch = W_CachePatchName(va("ROID00%.2d", intro_curtime%35), PU_PATCH))); W_UnlockCachedPatch(patch); } } @@ -1359,7 +1359,6 @@ void F_GameEvaluationDrawer(void) if (ALL7EMERALDS(emeralds)) ++timesBeatenWithEmeralds; - if (ultimatemode) ++timesBeatenUltimate; @@ -1447,10 +1446,28 @@ void F_GameEndTicker(void) D_StartTitle(); } - // ============== // TITLE SCREEN // ============== +static void F_CacheTitleScreen(void) +{ + ttbanner = W_CachePatchName("TTBANNER", PU_LEVEL); + ttwing = W_CachePatchName("TTWING", PU_LEVEL); + ttsonic = W_CachePatchName("TTSONIC", PU_LEVEL); + ttswave1 = W_CachePatchName("TTSWAVE1", PU_LEVEL); + ttswave2 = W_CachePatchName("TTSWAVE2", PU_LEVEL); + ttswip1 = W_CachePatchName("TTSWIP1", PU_LEVEL); + ttsprep1 = W_CachePatchName("TTSPREP1", PU_LEVEL); + ttsprep2 = W_CachePatchName("TTSPREP2", PU_LEVEL); + ttspop1 = W_CachePatchName("TTSPOP1", PU_LEVEL); + ttspop2 = W_CachePatchName("TTSPOP2", PU_LEVEL); + ttspop3 = W_CachePatchName("TTSPOP3", PU_LEVEL); + ttspop4 = W_CachePatchName("TTSPOP4", PU_LEVEL); + ttspop5 = W_CachePatchName("TTSPOP5", PU_LEVEL); + ttspop6 = W_CachePatchName("TTSPOP6", PU_LEVEL); + ttspop7 = W_CachePatchName("TTSPOP7", PU_LEVEL); +} + void F_StartTitleScreen(void) { if (gamestate != GS_TITLESCREEN && gamestate != GS_WAITINGPLAYERS) @@ -1469,21 +1486,7 @@ void F_StartTitleScreen(void) demoDelayLeft = demoDelayTime; demoIdleLeft = demoIdleTime; - ttbanner = W_CachePatchName("TTBANNER", PU_LEVEL); - ttwing = W_CachePatchName("TTWING", PU_LEVEL); - ttsonic = W_CachePatchName("TTSONIC", PU_LEVEL); - ttswave1 = W_CachePatchName("TTSWAVE1", PU_LEVEL); - ttswave2 = W_CachePatchName("TTSWAVE2", PU_LEVEL); - ttswip1 = W_CachePatchName("TTSWIP1", PU_LEVEL); - ttsprep1 = W_CachePatchName("TTSPREP1", PU_LEVEL); - ttsprep2 = W_CachePatchName("TTSPREP2", PU_LEVEL); - ttspop1 = W_CachePatchName("TTSPOP1", PU_LEVEL); - ttspop2 = W_CachePatchName("TTSPOP2", PU_LEVEL); - ttspop3 = W_CachePatchName("TTSPOP3", PU_LEVEL); - ttspop4 = W_CachePatchName("TTSPOP4", PU_LEVEL); - ttspop5 = W_CachePatchName("TTSPOP5", PU_LEVEL); - ttspop6 = W_CachePatchName("TTSPOP6", PU_LEVEL); - ttspop7 = W_CachePatchName("TTSPOP7", PU_LEVEL); + F_CacheTitleScreen(); } // (no longer) De-Demo'd Title Screen @@ -1492,6 +1495,9 @@ void F_TitleScreenDrawer(void) if (modeattacking) return; // We likely came here from retrying. Don't do a damn thing. + if (needpatchrecache) + F_CacheTitleScreen(); + // Draw that sky! F_SkyScroll(titlescrollspeed); diff --git a/src/hardware/hw_cache.c b/src/hardware/hw_cache.c index 78fc31afc..3857ad5d7 100644 --- a/src/hardware/hw_cache.c +++ b/src/hardware/hw_cache.c @@ -549,16 +549,14 @@ void HWR_MakePatch (const patch_t *patch, GLPatch_t *grPatch, GLMipmap_t *grMipm // CACHING HANDLING // ================================================= -static size_t gr_numtextures; +static size_t gr_numtextures = 0; static GLTexture_t *gr_textures; // for ALL Doom textures void HWR_InitTextureCache(void) { - gr_numtextures = 0; gr_textures = NULL; } - // Callback function for HWR_FreeTextureCache. static void FreeMipmapColormap(INT32 patchnum, void *patch) { @@ -587,15 +585,17 @@ void HWR_FreeTextureCache(void) // Alam: free the Z_Blocks before freeing it's users // free all skin after each level: must be done after pfnClearMipMapCache! - for (i = 0; i < numwadfiles; i++) - M_AATreeIterate(wadfiles[i]->hwrcache, FreeMipmapColormap); + // temp fix, idk why this crashes + // is it because the colormaps were already freed anyway? + if (!needpatchrecache) + for (i = 0; i < numwadfiles; i++) + M_AATreeIterate(wadfiles[i]->hwrcache, FreeMipmapColormap); // now the heap don't have any 'user' pointing to our // texturecache info, we can free it if (gr_textures) free(gr_textures); gr_textures = NULL; - gr_numtextures = 0; } void HWR_PrepLevelCache(size_t pnumtextures) @@ -642,8 +642,11 @@ GLTexture_t *HWR_GetTexture(INT32 tex) GLTexture_t *grtex; #ifdef PARANOIA if ((unsigned)tex >= gr_numtextures) - I_Error(" HWR_GetTexture: tex >= numtextures\n"); + I_Error("HWR_GetTexture: tex >= numtextures\n"); #endif + if (needpatchrecache && (!gr_textures)) + HWR_PrepLevelCache(gr_numtextures); + grtex = &gr_textures[tex]; if (!grtex->mipmap.grInfo.data && !grtex->mipmap.downloaded) @@ -709,6 +712,9 @@ void HWR_GetFlat(lumpnum_t flatlumpnum) { GLMipmap_t *grmip; + if (needpatchflush) + W_FlushCachedPatches(); + grmip = &HWR_GetCachedGLPatch(flatlumpnum)->mipmap; if (!grmip->downloaded && !grmip->grInfo.data) @@ -745,6 +751,9 @@ static void HWR_LoadMappedPatch(GLMipmap_t *grmip, GLPatch_t *gpatch) // -----------------+ void HWR_GetPatch(GLPatch_t *gpatch) { + if (needpatchflush) + W_FlushCachedPatches(); + // is it in hardware cache if (!gpatch->mipmap.downloaded && !gpatch->mipmap.grInfo.data) { @@ -772,6 +781,9 @@ void HWR_GetMappedPatch(GLPatch_t *gpatch, const UINT8 *colormap) { GLMipmap_t *grmip, *newmip; + if (needpatchflush) + W_FlushCachedPatches(); + if (colormap == colormaps || colormap == NULL) { // Load the default (green) color in doom cache (temporary?) AND hardware cache @@ -897,6 +909,9 @@ GLPatch_t *HWR_GetPic(lumpnum_t lumpnum) { GLPatch_t *grpatch; + if (needpatchflush) + W_FlushCachedPatches(); + grpatch = HWR_GetCachedGLPatch(lumpnum); if (!grpatch->mipmap.downloaded && !grpatch->mipmap.grInfo.data) @@ -1094,6 +1109,9 @@ void HWR_GetFadeMask(lumpnum_t fademasklumpnum) { GLMipmap_t *grmip; + if (needpatchflush) + W_FlushCachedPatches(); + grmip = &HWR_GetCachedGLPatch(fademasklumpnum)->mipmap; if (!grmip->downloaded && !grmip->grInfo.data) diff --git a/src/hardware/hw_draw.c b/src/hardware/hw_draw.c index cd2c95237..2dc18aee1 100644 --- a/src/hardware/hw_draw.c +++ b/src/hardware/hw_draw.c @@ -703,7 +703,7 @@ void HWR_DrawViewBorder(INT32 clearlines) // top edge if (clearlines > basewindowy - 8) { - patch = W_CachePatchNum(viewborderlump[BRDR_T], PU_CACHE); + patch = W_CachePatchNum(viewborderlump[BRDR_T], PU_PATCH); for (x = 0; x < baseviewwidth; x += 8) HWR_DrawPatch(patch, basewindowx + x, basewindowy - 8, 0); @@ -712,7 +712,7 @@ void HWR_DrawViewBorder(INT32 clearlines) // bottom edge if (clearlines > basewindowy + baseviewheight) { - patch = W_CachePatchNum(viewborderlump[BRDR_B], PU_CACHE); + patch = W_CachePatchNum(viewborderlump[BRDR_B], PU_PATCH); for (x = 0; x < baseviewwidth; x += 8) HWR_DrawPatch(patch, basewindowx + x, basewindowy + baseviewheight, 0); @@ -721,7 +721,7 @@ void HWR_DrawViewBorder(INT32 clearlines) // left edge if (clearlines > basewindowy) { - patch = W_CachePatchNum(viewborderlump[BRDR_L], PU_CACHE); + patch = W_CachePatchNum(viewborderlump[BRDR_L], PU_PATCH); for (y = 0; y < baseviewheight && basewindowy + y < clearlines; y += 8) { @@ -733,7 +733,7 @@ void HWR_DrawViewBorder(INT32 clearlines) // right edge if (clearlines > basewindowy) { - patch = W_CachePatchNum(viewborderlump[BRDR_R], PU_CACHE); + patch = W_CachePatchNum(viewborderlump[BRDR_R], PU_PATCH); for (y = 0; y < baseviewheight && basewindowy+y < clearlines; y += 8) { @@ -745,22 +745,22 @@ void HWR_DrawViewBorder(INT32 clearlines) // Draw beveled corners. if (clearlines > basewindowy - 8) HWR_DrawPatch(W_CachePatchNum(viewborderlump[BRDR_TL], - PU_CACHE), + PU_PATCH), basewindowx - 8, basewindowy - 8, 0); if (clearlines > basewindowy - 8) HWR_DrawPatch(W_CachePatchNum(viewborderlump[BRDR_TR], - PU_CACHE), + PU_PATCH), basewindowx + baseviewwidth, basewindowy - 8, 0); if (clearlines > basewindowy+baseviewheight) HWR_DrawPatch(W_CachePatchNum(viewborderlump[BRDR_BL], - PU_CACHE), + PU_PATCH), basewindowx - 8, basewindowy + baseviewheight, 0); if (clearlines > basewindowy + baseviewheight) HWR_DrawPatch(W_CachePatchNum(viewborderlump[BRDR_BR], - PU_CACHE), + PU_PATCH), basewindowx + baseviewwidth, basewindowy + baseviewheight, 0); } diff --git a/src/hardware/hw_main.c b/src/hardware/hw_main.c index 7e0b369eb..399a7bfd2 100644 --- a/src/hardware/hw_main.c +++ b/src/hardware/hw_main.c @@ -872,7 +872,7 @@ static void HWR_DrawSegsSplats(FSurfaceInfo * pSurf) if (!M_PointInBox(segbbox,splat->v1.x,splat->v1.y) && !M_PointInBox(segbbox,splat->v2.x,splat->v2.y)) continue; - gpatch = W_CachePatchNum(splat->patch, PU_CACHE); + gpatch = W_CachePatchNum(splat->patch, PU_PATCH); HWR_GetPatch(gpatch); wallVerts[0].x = wallVerts[3].x = FIXED_TO_FLOAT(splat->v1.x); @@ -4311,7 +4311,7 @@ static void HWR_SplitSprite(gr_vissprite_t *spr) if (hires) this_scale = this_scale * FIXED_TO_FLOAT(((skin_t *)spr->mobj->skin)->highresscale); - gpatch = W_CachePatchNum(spr->patchlumpnum, PU_CACHE); + gpatch = W_CachePatchNum(spr->patchlumpnum, PU_PATCH); // cache the patch in the graphics card memory //12/12/99: Hurdler: same comment as above (for md2) @@ -4664,7 +4664,7 @@ static void HWR_DrawSprite(gr_vissprite_t *spr) // sure to do it the right way. So actually, we keep normal sprite // in memory and we add the md2 model if it exists for that sprite - gpatch = W_CachePatchNum(spr->patchlumpnum, PU_CACHE); + gpatch = W_CachePatchNum(spr->patchlumpnum, PU_PATCH); #ifdef ALAM_LIGHTING if (!(spr->mobj->flags2 & MF2_DEBRIS) && (spr->mobj->sprite != SPR_PLAY || @@ -4809,7 +4809,7 @@ static inline void HWR_DrawPrecipitationSprite(gr_vissprite_t *spr) return; // cache sprite graphics - gpatch = W_CachePatchNum(spr->patchlumpnum, PU_CACHE); + gpatch = W_CachePatchNum(spr->patchlumpnum, PU_PATCH); // create the sprite billboard // diff --git a/src/hardware/hw_md2.c b/src/hardware/hw_md2.c index cb33562d8..353e49f81 100644 --- a/src/hardware/hw_md2.c +++ b/src/hardware/hw_md2.c @@ -1350,7 +1350,7 @@ void HWR_DrawMD2(gr_vissprite_t *spr) else { // Sprite - gpatch = W_CachePatchNum(spr->patchlumpnum, PU_CACHE); + gpatch = W_CachePatchNum(spr->patchlumpnum, PU_PATCH); HWR_GetMappedPatch(gpatch, spr->colormap); } diff --git a/src/hu_stuff.c b/src/hu_stuff.c index a9a2b7504..2451f5c4d 100644 --- a/src/hu_stuff.c +++ b/src/hu_stuff.c @@ -1993,6 +1993,9 @@ static void HU_DrawDemoInfo(void) // void HU_Drawer(void) { + if (needpatchrecache) + R_ReloadHUDGraphics(); + #ifndef NONET // draw chat string plus cursor if (chat_on) diff --git a/src/i_video.h b/src/i_video.h index 4bb2c5829..a62f3ff64 100644 --- a/src/i_video.h +++ b/src/i_video.h @@ -84,6 +84,7 @@ INT32 VID_GetModeForSize(INT32 w, INT32 h); \return currect video mode */ INT32 VID_SetMode(INT32 modenum); +void VID_CheckRenderer(void); /** \brief The VID_GetModeName function diff --git a/src/m_menu.c b/src/m_menu.c index a833ace21..f6c47077e 100644 --- a/src/m_menu.c +++ b/src/m_menu.c @@ -2872,19 +2872,19 @@ static void M_DrawThermo(INT32 x, INT32 y, consvar_t *cv) centerlump[1] = W_GetNumForName("M_THERMM"); cursorlump = W_GetNumForName("M_THERMO"); - V_DrawScaledPatch(xx, y, 0, p = W_CachePatchNum(leftlump,PU_CACHE)); + V_DrawScaledPatch(xx, y, 0, p = W_CachePatchNum(leftlump,PU_PATCH)); xx += SHORT(p->width) - SHORT(p->leftoffset); for (i = 0; i < 16; i++) { - V_DrawScaledPatch(xx, y, V_WRAPX, W_CachePatchNum(centerlump[i & 1], PU_CACHE)); + V_DrawScaledPatch(xx, y, V_WRAPX, W_CachePatchNum(centerlump[i & 1], PU_PATCH)); xx += 8; } - V_DrawScaledPatch(xx, y, 0, W_CachePatchNum(rightlump, PU_CACHE)); + V_DrawScaledPatch(xx, y, 0, W_CachePatchNum(rightlump, PU_PATCH)); xx = (cv->value - cv->PossibleValue[0].value) * (15*8) / (cv->PossibleValue[1].value - cv->PossibleValue[0].value); - V_DrawScaledPatch((x + 8) + xx, y, 0, W_CachePatchNum(cursorlump, PU_CACHE)); + V_DrawScaledPatch((x + 8) + xx, y, 0, W_CachePatchNum(cursorlump, PU_PATCH)); } // A smaller 'Thermo', with range given as percents (0-100) @@ -2940,15 +2940,15 @@ void M_DrawTextBox(INT32 x, INT32 y, INT32 width, INT32 boxlines) // draw left side cx = x; cy = y; - V_DrawScaledPatch(cx, cy, 0, W_CachePatchNum(viewborderlump[BRDR_TL], PU_CACHE)); + V_DrawScaledPatch(cx, cy, 0, W_CachePatchNum(viewborderlump[BRDR_TL], PU_PATCH)); cy += boff; - p = W_CachePatchNum(viewborderlump[BRDR_L], PU_CACHE); + p = W_CachePatchNum(viewborderlump[BRDR_L], PU_PATCH); for (n = 0; n < boxlines; n++) { V_DrawScaledPatch(cx, cy, V_WRAPY, p); cy += step; } - V_DrawScaledPatch(cx, cy, 0, W_CachePatchNum(viewborderlump[BRDR_BL], PU_CACHE)); + V_DrawScaledPatch(cx, cy, 0, W_CachePatchNum(viewborderlump[BRDR_BL], PU_PATCH)); // draw middle V_DrawFlatFill(x + boff, y + boff, width*step, boxlines*step, st_borderpatchnum); @@ -2957,23 +2957,23 @@ void M_DrawTextBox(INT32 x, INT32 y, INT32 width, INT32 boxlines) cy = y; while (width > 0) { - V_DrawScaledPatch(cx, cy, V_WRAPX, W_CachePatchNum(viewborderlump[BRDR_T], PU_CACHE)); - V_DrawScaledPatch(cx, y + boff + boxlines*step, V_WRAPX, W_CachePatchNum(viewborderlump[BRDR_B], PU_CACHE)); + V_DrawScaledPatch(cx, cy, V_WRAPX, W_CachePatchNum(viewborderlump[BRDR_T], PU_PATCH)); + V_DrawScaledPatch(cx, y + boff + boxlines*step, V_WRAPX, W_CachePatchNum(viewborderlump[BRDR_B], PU_PATCH)); width--; cx += step; } // draw right side cy = y; - V_DrawScaledPatch(cx, cy, 0, W_CachePatchNum(viewborderlump[BRDR_TR], PU_CACHE)); + V_DrawScaledPatch(cx, cy, 0, W_CachePatchNum(viewborderlump[BRDR_TR], PU_PATCH)); cy += boff; - p = W_CachePatchNum(viewborderlump[BRDR_R], PU_CACHE); + p = W_CachePatchNum(viewborderlump[BRDR_R], PU_PATCH); for (n = 0; n < boxlines; n++) { V_DrawScaledPatch(cx, cy, V_WRAPY, p); cy += step; } - V_DrawScaledPatch(cx, cy, 0, W_CachePatchNum(viewborderlump[BRDR_BR], PU_CACHE)); + V_DrawScaledPatch(cx, cy, 0, W_CachePatchNum(viewborderlump[BRDR_BR], PU_PATCH)); */ } @@ -3914,6 +3914,27 @@ static void M_AddonsOptions(INT32 choice) #define LOCATIONSTRING1 "Visit \x83SRB2.ORG/MODS\x80 to get & make add-ons!" //#define LOCATIONSTRING2 "Visit \x88SRB2.ORG/MODS\x80 to get & make add-ons!" +static void M_LoadAddonsPatches(void) +{ + addonsp[EXT_FOLDER] = W_CachePatchName("M_FFLDR", PU_PATCH); + addonsp[EXT_UP] = W_CachePatchName("M_FBACK", PU_PATCH); + addonsp[EXT_NORESULTS] = W_CachePatchName("M_FNOPE", PU_PATCH); + addonsp[EXT_TXT] = W_CachePatchName("M_FTXT", PU_PATCH); + addonsp[EXT_CFG] = W_CachePatchName("M_FCFG", PU_PATCH); + addonsp[EXT_WAD] = W_CachePatchName("M_FWAD", PU_PATCH); +#ifdef USE_KART + addonsp[EXT_KART] = W_CachePatchName("M_FKART", PU_PATCH); +#endif + addonsp[EXT_PK3] = W_CachePatchName("M_FPK3", PU_PATCH); + addonsp[EXT_SOC] = W_CachePatchName("M_FSOC", PU_PATCH); + addonsp[EXT_LUA] = W_CachePatchName("M_FLUA", PU_PATCH); + addonsp[NUM_EXT] = W_CachePatchName("M_FUNKN", PU_PATCH); + addonsp[NUM_EXT+1] = W_CachePatchName("M_FSEL", PU_PATCH); + addonsp[NUM_EXT+2] = W_CachePatchName("M_FLOAD", PU_PATCH); + addonsp[NUM_EXT+3] = W_CachePatchName("M_FSRCH", PU_PATCH); + addonsp[NUM_EXT+4] = W_CachePatchName("M_FSAVE", PU_PATCH); +} + static void M_Addons(INT32 choice) { const char *pathname = "."; @@ -3964,23 +3985,7 @@ static void M_Addons(INT32 choice) W_UnlockCachedPatch(addonsp[i]); } - addonsp[EXT_FOLDER] = W_CachePatchName("M_FFLDR", PU_STATIC); - addonsp[EXT_UP] = W_CachePatchName("M_FBACK", PU_STATIC); - addonsp[EXT_NORESULTS] = W_CachePatchName("M_FNOPE", PU_STATIC); - addonsp[EXT_TXT] = W_CachePatchName("M_FTXT", PU_STATIC); - addonsp[EXT_CFG] = W_CachePatchName("M_FCFG", PU_STATIC); - addonsp[EXT_WAD] = W_CachePatchName("M_FWAD", PU_STATIC); -#ifdef USE_KART - addonsp[EXT_KART] = W_CachePatchName("M_FKART", PU_STATIC); -#endif - addonsp[EXT_PK3] = W_CachePatchName("M_FPK3", PU_STATIC); - addonsp[EXT_SOC] = W_CachePatchName("M_FSOC", PU_STATIC); - addonsp[EXT_LUA] = W_CachePatchName("M_FLUA", PU_STATIC); - addonsp[NUM_EXT] = W_CachePatchName("M_FUNKN", PU_STATIC); - addonsp[NUM_EXT+1] = W_CachePatchName("M_FSEL", PU_STATIC); - addonsp[NUM_EXT+2] = W_CachePatchName("M_FLOAD", PU_STATIC); - addonsp[NUM_EXT+3] = W_CachePatchName("M_FSRCH", PU_STATIC); - addonsp[NUM_EXT+4] = W_CachePatchName("M_FSAVE", PU_STATIC); + M_LoadAddonsPatches(); MISC_AddonsDef.prevMenu = currentMenu; M_SetupNextMenu(&MISC_AddonsDef); @@ -4119,6 +4124,9 @@ static void M_DrawAddons(void) return; } + if (needpatchrecache) + M_LoadAddonsPatches(); + if (Playing()) V_DrawCenteredString(BASEVIDWIDTH/2, 5, warningflags, "Adding files mid-game may cause problems."); else diff --git a/src/p_setup.c b/src/p_setup.c index b2636c350..0058f7def 100644 --- a/src/p_setup.c +++ b/src/p_setup.c @@ -2967,16 +2967,8 @@ boolean P_SetupLevel(boolean skipprecip) globalweather = mapheaderinfo[gamemap-1]->weather; #ifdef HWRENDER // not win32 only 19990829 by Kin - if (rendermode != render_soft && rendermode != render_none) - { -#ifdef ALAM_LIGHTING - // BP: reset light between levels (we draw preview frame lights on current frame) - HWR_ResetLights(); -#endif - // Correct missing sidedefs & deep water trick - HWR_CorrectSWTricks(); - HWR_CreatePlanePolygons((INT32)numnodes - 1); - } + if (rendermode == render_opengl) + HWR_SetupLevel(); #endif // oh god I hope this helps @@ -3123,10 +3115,8 @@ boolean P_SetupLevel(boolean skipprecip) // preload graphics #ifdef HWRENDER // not win32 only 19990829 by Kin - if (rendermode != render_soft && rendermode != render_none) - { + if (rendermode == render_opengl) HWR_PrepLevelCache(numtextures); - } #endif P_MapEnd(); @@ -3181,6 +3171,19 @@ boolean P_SetupLevel(boolean skipprecip) return true; } +#ifdef HWRENDER +void HWR_SetupLevel(void) +{ +#ifdef ALAM_LIGHTING + // BP: reset light between levels (we draw preview frame lights on current frame) + HWR_ResetLights(); +#endif + // Correct missing sidedefs & deep water trick + HWR_CorrectSWTricks(); + HWR_CreatePlanePolygons((INT32)numnodes - 1); +} +#endif + // // P_RunSOC // diff --git a/src/p_setup.h b/src/p_setup.h index 41c2bf133..622e1edbc 100644 --- a/src/p_setup.h +++ b/src/p_setup.h @@ -59,6 +59,9 @@ void P_ScanThings(INT16 mapnum, INT16 wadnum, INT16 lumpnum); #endif void P_LoadThingsOnly(void); boolean P_SetupLevel(boolean skipprecip); +#ifdef HWRENDER +void HWR_SetupLevel(void); +#endif boolean P_AddWadFile(const char *wadfilename); #ifdef DELFILE boolean P_DelWadFile(void); diff --git a/src/r_data.c b/src/r_data.c index bd12eb248..cd50272b0 100644 --- a/src/r_data.c +++ b/src/r_data.c @@ -95,6 +95,8 @@ size_t numspritelumps, max_spritelumps; // textures INT32 numtextures = 0; // total number of textures found, +boolean needpatchflush = false; +boolean needpatchrecache = false; // size of following tables texture_t **textures = NULL; @@ -1266,7 +1268,6 @@ INT32 R_CreateColormap(char *p1, char *p2, char *p3) extra_colormaps[mapnum].fog = fog; // This code creates the colormap array used by software renderer - if (rendermode == render_soft) { double r, g, b, cbrightness; int p; @@ -1611,7 +1612,7 @@ void R_PrecacheLevel(void) lump = sf->lumppat[k]; if (devparm) spritememory += W_LumpLength(lump); - W_CachePatchNum(lump, PU_CACHE); + W_CachePatchNum(lump, PU_PATCH); } } } diff --git a/src/r_data.h b/src/r_data.h index 5de51ccd4..e6229d6c8 100644 --- a/src/r_data.h +++ b/src/r_data.h @@ -96,5 +96,7 @@ INT32 R_CreateColormap(char *p1, char *p2, char *p3); const char *R_ColormapNameForNum(INT32 num); extern INT32 numtextures; +extern boolean needpatchflush; +extern boolean needpatchrecache; #endif diff --git a/src/r_main.c b/src/r_main.c index 08b1ab2f0..f12fe23fe 100644 --- a/src/r_main.c +++ b/src/r_main.c @@ -19,6 +19,7 @@ #include "r_local.h" #include "r_splats.h" // faB(21jan): testing #include "r_sky.h" +#include "hu_stuff.h" #include "st_stuff.h" #include "p_local.h" #include "keys.h" @@ -28,6 +29,7 @@ #include "d_main.h" #include "v_video.h" #include "p_spec.h" // skyboxmo +#include "p_setup.h" #include "z_zone.h" #include "m_random.h" // quake camera shake @@ -1337,6 +1339,25 @@ void R_RenderPlayerView(player_t *player) skyVisible1 = skyVisible; } +#ifdef HWRENDER +void R_InitHardwareMode(void) +{ + if (gamestate == GS_LEVEL) + { + HWR_SetupLevel(); + HWR_PrepLevelCache(numtextures); + } +} +#endif + +void R_ReloadHUDGraphics(void) +{ + W_FlushCachedPatches(); + ST_LoadGraphics(); + HU_LoadGraphics(); + ST_ReloadSkinFaceGraphics(); +} + // ========================================================================= // ENGINE COMMANDS & VARS // ========================================================================= diff --git a/src/r_main.h b/src/r_main.h index 6ae5aa221..6b521e43a 100644 --- a/src/r_main.h +++ b/src/r_main.h @@ -84,6 +84,10 @@ extern consvar_t cv_tailspickup; // Called by startup code. void R_Init(void); +#ifdef HWRENDER +void R_InitHardwareMode(void); +#endif +void R_ReloadHUDGraphics(void); // just sets setsizeneeded true extern boolean setsizeneeded; diff --git a/src/r_segs.c b/src/r_segs.c index c82554ac8..d5f651fc5 100644 --- a/src/r_segs.c +++ b/src/r_segs.c @@ -164,7 +164,7 @@ static void R_DrawWallSplats(void) mfloorclip = floorclip; mceilingclip = ceilingclip; - patch = W_CachePatchNum(splat->patch, PU_CACHE); + patch = W_CachePatchNum(splat->patch, PU_PATCH); dc_texturemid = splat->top + (SHORT(patch->height)<<(FRACBITS-1)) - viewz; if (splat->yoffset) diff --git a/src/r_splats.c b/src/r_splats.c index 9ab671274..e09e68aa1 100644 --- a/src/r_splats.c +++ b/src/r_splats.c @@ -147,7 +147,7 @@ void R_AddWallSplat(line_t *wallline, INT16 sectorside, const char *patchname, f splat->flags = flags; // bad.. but will be needed for drawing anyway.. - patch = W_CachePatchNum(splat->patch, PU_CACHE); + patch = W_CachePatchNum(splat->patch, PU_PATCH); // offset needed by draw code for texture mapping linelength = P_SegLength((seg_t *)wallline); diff --git a/src/screen.c b/src/screen.c index af6aed03c..d485a6367 100644 --- a/src/screen.c +++ b/src/screen.c @@ -56,6 +56,7 @@ void (*twosmultipatchtransfunc)(void); // for cols with transparent pixels AND t // ------------------ viddef_t vid; INT32 setmodeneeded; //video mode change needed if > 0 (the mode number to set + 1) +INT32 setrenderneeded = 0; static CV_PossibleValue_t scr_depth_cons_t[] = {{8, "8 bits"}, {16, "16 bits"}, {24, "24 bits"}, {32, "32 bits"}, {0, NULL}}; @@ -71,6 +72,10 @@ consvar_t cv_scr_depth = {"scr_depth", "16 bits", CV_SAVE, scr_depth_cons_t, NUL #endif consvar_t cv_renderview = {"renderview", "On", 0, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL}; +static void SCR_ChangeRenderer (void); +static CV_PossibleValue_t cv_renderer_t[] = {{1, "Software"}, {2, "OpenGL"}, {0, NULL}}; +consvar_t cv_renderer = {"renderer", "Software", CV_CALL, cv_renderer_t, SCR_ChangeRenderer, 0, NULL, NULL, 0, 0, NULL}; + static void SCR_ChangeFullscreen (void); consvar_t cv_fullscreen = {"fullscreen", "Yes", CV_SAVE|CV_CALL, CV_YesNo, SCR_ChangeFullscreen, 0, NULL, NULL, 0, 0, NULL}; @@ -96,19 +101,8 @@ boolean R_3DNow = false; boolean R_MMXExt = false; boolean R_SSE2 = false; - -void SCR_SetMode(void) +void SCR_SetDrawFuncs(void) { - if (dedicated) - return; - - if (!setmodeneeded || WipeInAction) - return; // should never happen and don't change it during a wipe, BAD! - - VID_SetMode(--setmodeneeded); - - V_SetPalette(0); - // // setup the right draw routines for either 8bpp or 16bpp // @@ -166,8 +160,35 @@ void SCR_SetMode(void) if (SCR_IsAspectCorrect(vid.width, vid.height)) CONS_Alert(CONS_WARNING, M_GetText("Resolution is not aspect-correct!\nUse a multiple of %dx%d\n"), BASEVIDWIDTH, BASEVIDHEIGHT); #endif*/ + + wallcolfunc = walldrawerfunc; +} + +void SCR_SetMode(void) +{ + if (dedicated) + return; + + if (!(setmodeneeded || setrenderneeded) || WipeInAction) + return; // should never happen and don't change it during a wipe, BAD! + + if (setrenderneeded) + { + needpatchflush = true; + needpatchrecache = true; + VID_CheckRenderer(); + } + + if (setmodeneeded) + VID_SetMode(--setmodeneeded); + + V_SetPalette(0); + + SCR_SetDrawFuncs(); + // set the apprpriate drawer for the sky (tall or INT16) setmodeneeded = 0; + setrenderneeded = 0; } // do some initial settings for the game loading screen @@ -384,6 +405,29 @@ void SCR_ChangeFullscreen(void) #endif } +void SCR_ChangeRenderer(void) +{ + setrenderneeded = 0; + + if (con_startup) + { + if (rendermode == render_soft) + CV_StealthSetValue(&cv_renderer, 1); + else if (rendermode == render_opengl) + CV_StealthSetValue(&cv_renderer, 2); + return; + } + + if (cv_renderer.value == 1) + setrenderneeded = render_soft; + else if (cv_renderer.value == 2) + setrenderneeded = render_opengl; + + // setting the same renderer twice WILL crash your game, so let's not, please + if (rendermode == setrenderneeded) + setrenderneeded = 0; +} + boolean SCR_IsAspectCorrect(INT32 width, INT32 height) { return diff --git a/src/screen.h b/src/screen.h index 9ad254d3f..df0518421 100644 --- a/src/screen.h +++ b/src/screen.h @@ -154,11 +154,12 @@ extern boolean R_SSE2; // ---------------- extern viddef_t vid; extern INT32 setmodeneeded; // mode number to set if needed, or 0 +extern INT32 setrenderneeded; extern INT32 scr_bpp; extern UINT8 *scr_borderpatch; // patch used to fill the view borders -extern consvar_t cv_scr_width, cv_scr_height, cv_scr_depth, cv_renderview, cv_fullscreen; +extern consvar_t cv_scr_width, cv_scr_height, cv_scr_depth, cv_renderview, cv_renderer, cv_fullscreen; // wait for page flipping to end or not extern consvar_t cv_vidwait; @@ -167,6 +168,7 @@ extern void (*walldrawerfunc)(void); // Change video mode, only at the start of a refresh. void SCR_SetMode(void); +void SCR_SetDrawFuncs(void); // Recalc screen size dependent stuff void SCR_Recalc(void); // Check parms once at startup diff --git a/src/sdl/i_video.c b/src/sdl/i_video.c index 77bf414cc..45d9e3ed9 100644 --- a/src/sdl/i_video.c +++ b/src/sdl/i_video.c @@ -71,6 +71,7 @@ #include "../i_video.h" #include "../console.h" #include "../command.h" +#include "../r_main.h" #include "sdlmain.h" #ifdef HWRENDER #include "../hardware/hw_main.h" @@ -170,6 +171,7 @@ static void Impl_VideoSetupBuffer(void); static SDL_bool Impl_CreateWindow(SDL_bool fullscreen); //static void Impl_SetWindowName(const char *title); static void Impl_SetWindowIcon(void); +static void I_StartupGraphicsGL(void); static void SDLSetMode(INT32 width, INT32 height, SDL_bool fullscreen) { @@ -1059,7 +1061,6 @@ void I_FinishUpdate(void) SDL_RenderCopy(renderer, texture, NULL, NULL); SDL_RenderPresent(renderer); } - #ifdef HWRENDER else if (rendermode == render_opengl) { @@ -1259,6 +1260,81 @@ void VID_PrepareModeList(void) #endif } +// SOMETIME IN +// THE FUTURE +// WHEN I ACTUALLY RENDER +// THIS FRAME +static int renderflags; +static SDL_bool Impl_CreateContext(int flags) +{ + // Renderer-specific stuff +#ifdef HWRENDER + if (rendermode == render_opengl) + { + if (!sdlglcontext) + sdlglcontext = SDL_GL_CreateContext(window); + if (sdlglcontext == NULL) + { + SDL_DestroyWindow(window); + I_Error("Failed to create a GL context: %s\n", SDL_GetError()); + } + SDL_GL_MakeCurrent(window, sdlglcontext); + } + else +#endif + if (rendermode == render_soft) + { + flags = 0; // Use this to set SDL_RENDERER_* flags now + if (usesdl2soft) + flags |= SDL_RENDERER_SOFTWARE; + else if (cv_vidwait.value) + flags |= SDL_RENDERER_PRESENTVSYNC; + + if (!renderer) + renderer = SDL_CreateRenderer(window, -1, flags); + if (renderer == NULL) + { + CONS_Printf(M_GetText("Couldn't create rendering context: %s\n"), SDL_GetError()); + return SDL_FALSE; + } + SDL_RenderSetLogicalSize(renderer, BASEVIDWIDTH, BASEVIDHEIGHT); + } + return SDL_TRUE; +} + +void VID_CheckRenderer(void) +{ + if (setrenderneeded) + { + rendermode = setrenderneeded; + Impl_CreateContext(renderflags); + if (rendermode == render_soft) + { +#ifdef HWRENDER + HWR_FreeTextureCache(); +#endif + SCR_SetDrawFuncs(); + } + } + + SDLSetMode(vid.width, vid.height, USE_FULLSCREEN); + + if (rendermode == render_soft) + { + if (bufSurface) + { + SDL_FreeSurface(bufSurface); + bufSurface = NULL; + } + Impl_VideoSetupBuffer(); + } + else if (rendermode == render_opengl) + { + I_StartupGraphicsGL(); + R_InitHardwareMode(); + } +} + INT32 VID_SetMode(INT32 modeNum) { SDLdoUngrabMouse(); @@ -1290,20 +1366,7 @@ INT32 VID_SetMode(INT32 modeNum) vid.modenum = -1; } //Impl_SetWindowName("SRB2 "VERSIONSTRING); - - SDLSetMode(vid.width, vid.height, USE_FULLSCREEN); - - if (rendermode == render_soft) - { - if (bufSurface) - { - SDL_FreeSurface(bufSurface); - bufSurface = NULL; - } - - Impl_VideoSetupBuffer(); - } - + VID_CheckRenderer(); return SDL_TRUE; } @@ -1338,38 +1401,8 @@ static SDL_bool Impl_CreateWindow(SDL_bool fullscreen) return SDL_FALSE; } - // Renderer-specific stuff -#ifdef HWRENDER - if (rendermode == render_opengl) - { - sdlglcontext = SDL_GL_CreateContext(window); - if (sdlglcontext == NULL) - { - SDL_DestroyWindow(window); - I_Error("Failed to create a GL context: %s\n", SDL_GetError()); - } - SDL_GL_MakeCurrent(window, sdlglcontext); - } - else -#endif - if (rendermode == render_soft) - { - flags = 0; // Use this to set SDL_RENDERER_* flags now - if (usesdl2soft) - flags |= SDL_RENDERER_SOFTWARE; - else if (cv_vidwait.value) - flags |= SDL_RENDERER_PRESENTVSYNC; - - renderer = SDL_CreateRenderer(window, -1, flags); - if (renderer == NULL) - { - CONS_Printf(M_GetText("Couldn't create rendering context: %s\n"), SDL_GetError()); - return SDL_FALSE; - } - SDL_RenderSetLogicalSize(renderer, BASEVIDWIDTH, BASEVIDHEIGHT); - } - - return SDL_TRUE; + renderflags = flags; + return Impl_CreateContext(flags); } /* @@ -1438,6 +1471,51 @@ static void Impl_VideoSetupBuffer(void) } } +static void I_StartupGraphicsGL(void) +{ +#ifdef HWRENDER + static boolean glstartup = false; + if (!glstartup) + { + HWD.pfnInit = hwSym("Init",NULL); + HWD.pfnFinishUpdate = NULL; + HWD.pfnDraw2DLine = hwSym("Draw2DLine",NULL); + HWD.pfnDrawPolygon = hwSym("DrawPolygon",NULL); + HWD.pfnSetBlend = hwSym("SetBlend",NULL); + HWD.pfnClearBuffer = hwSym("ClearBuffer",NULL); + HWD.pfnSetTexture = hwSym("SetTexture",NULL); + HWD.pfnReadRect = hwSym("ReadRect",NULL); + HWD.pfnGClipRect = hwSym("GClipRect",NULL); + HWD.pfnClearMipMapCache = hwSym("ClearMipMapCache",NULL); + HWD.pfnSetSpecialState = hwSym("SetSpecialState",NULL); + HWD.pfnSetPalette = hwSym("SetPalette",NULL); + HWD.pfnGetTextureUsed = hwSym("GetTextureUsed",NULL); + HWD.pfnDrawMD2 = hwSym("DrawMD2",NULL); + HWD.pfnDrawMD2i = hwSym("DrawMD2i",NULL); + HWD.pfnSetTransform = hwSym("SetTransform",NULL); + HWD.pfnGetRenderVersion = hwSym("GetRenderVersion",NULL); +#ifdef SHUFFLE + HWD.pfnPostImgRedraw = hwSym("PostImgRedraw",NULL); +#endif + HWD.pfnFlushScreenTextures=hwSym("FlushScreenTextures",NULL); + HWD.pfnStartScreenWipe = hwSym("StartScreenWipe",NULL); + HWD.pfnEndScreenWipe = hwSym("EndScreenWipe",NULL); + HWD.pfnDoScreenWipe = hwSym("DoScreenWipe",NULL); + HWD.pfnDrawIntermissionBG=hwSym("DrawIntermissionBG",NULL); + HWD.pfnMakeScreenTexture= hwSym("MakeScreenTexture",NULL); + HWD.pfnMakeScreenFinalTexture=hwSym("MakeScreenFinalTexture",NULL); + HWD.pfnDrawScreenFinalTexture=hwSym("DrawScreenFinalTexture",NULL); + // check gl renderer lib + if (HWD.pfnGetRenderVersion() != VERSION) + I_Error("%s", M_GetText("The version of the renderer doesn't match the version of the executable\nBe sure you have installed SRB2 properly.\n")); + if (!HWD.pfnInit(I_Error)) // let load the OpenGL library + rendermode = render_soft; + else + glstartup = true; + } +#endif +} + void I_StartupGraphics(void) { if (dedicated) @@ -1478,10 +1556,11 @@ void I_StartupGraphics(void) )) framebuffer = SDL_TRUE; } - if (M_CheckParm("-software")) - { + + if (M_CheckParm("-opengl")) + rendermode = render_opengl; + else if (M_CheckParm("software")) rendermode = render_soft; - } usesdl2soft = M_CheckParm("-softblit"); borderlesswindow = M_CheckParm("-borderless"); @@ -1489,45 +1568,7 @@ void I_StartupGraphics(void) //SDL_EnableKeyRepeat(SDL_DEFAULT_REPEAT_DELAY>>1,SDL_DEFAULT_REPEAT_INTERVAL<<2); VID_Command_ModeList_f(); #ifdef HWRENDER - if (M_CheckParm("-opengl") || rendermode == render_opengl) - { - rendermode = render_opengl; - HWD.pfnInit = hwSym("Init",NULL); - HWD.pfnFinishUpdate = NULL; - HWD.pfnDraw2DLine = hwSym("Draw2DLine",NULL); - HWD.pfnDrawPolygon = hwSym("DrawPolygon",NULL); - HWD.pfnSetBlend = hwSym("SetBlend",NULL); - HWD.pfnClearBuffer = hwSym("ClearBuffer",NULL); - HWD.pfnSetTexture = hwSym("SetTexture",NULL); - HWD.pfnReadRect = hwSym("ReadRect",NULL); - HWD.pfnGClipRect = hwSym("GClipRect",NULL); - HWD.pfnClearMipMapCache = hwSym("ClearMipMapCache",NULL); - HWD.pfnSetSpecialState = hwSym("SetSpecialState",NULL); - HWD.pfnSetPalette = hwSym("SetPalette",NULL); - HWD.pfnGetTextureUsed = hwSym("GetTextureUsed",NULL); - HWD.pfnDrawMD2 = hwSym("DrawMD2",NULL); - HWD.pfnDrawMD2i = hwSym("DrawMD2i",NULL); - HWD.pfnSetTransform = hwSym("SetTransform",NULL); - HWD.pfnGetRenderVersion = hwSym("GetRenderVersion",NULL); -#ifdef SHUFFLE - HWD.pfnPostImgRedraw = hwSym("PostImgRedraw",NULL); -#endif - HWD.pfnFlushScreenTextures=hwSym("FlushScreenTextures",NULL); - HWD.pfnStartScreenWipe = hwSym("StartScreenWipe",NULL); - HWD.pfnEndScreenWipe = hwSym("EndScreenWipe",NULL); - HWD.pfnDoScreenWipe = hwSym("DoScreenWipe",NULL); - HWD.pfnDrawIntermissionBG=hwSym("DrawIntermissionBG",NULL); - HWD.pfnMakeScreenTexture= hwSym("MakeScreenTexture",NULL); - HWD.pfnMakeScreenFinalTexture=hwSym("MakeScreenFinalTexture",NULL); - HWD.pfnDrawScreenFinalTexture=hwSym("DrawScreenFinalTexture",NULL); - // check gl renderer lib - if (HWD.pfnGetRenderVersion() != VERSION) - I_Error("%s", M_GetText("The version of the renderer doesn't match the version of the executable\nBe sure you have installed SRB2 properly.\n")); - if (!HWD.pfnInit(I_Error)) // let load the OpenGL library - { - rendermode = render_soft; - } - } + I_StartupGraphicsGL(); #endif // Fury: we do window initialization after GL setup to allow diff --git a/src/st_stuff.c b/src/st_stuff.c index 287aea134..11bb9875d 100644 --- a/src/st_stuff.c +++ b/src/st_stuff.c @@ -1909,6 +1909,9 @@ static void ST_overlayDrawer(void) void ST_Drawer(void) { + if (needpatchrecache) + R_ReloadHUDGraphics(); + #ifdef SEENAMES if (cv_seenames.value && cv_allowseenames.value && displayplayer == consoleplayer && seenplayer && seenplayer->mo) { diff --git a/src/w_wad.c b/src/w_wad.c index 7de64f9ad..00797b87d 100644 --- a/src/w_wad.c +++ b/src/w_wad.c @@ -41,6 +41,7 @@ #include "dehacked.h" #include "d_clisrv.h" #include "r_defs.h" +#include "r_data.h" #include "i_system.h" #include "md5.h" #include "lua_script.h" @@ -1422,7 +1423,6 @@ void *W_CacheLumpNumPwad(UINT16 wad, UINT16 lump, INT32 tag) void *W_CacheLumpNum(lumpnum_t lumpnum, INT32 tag) { - return W_CacheLumpNumPwad(WADFILENUM(lumpnum),LUMPNUM(lumpnum),tag); } @@ -1503,12 +1503,30 @@ void *W_CacheLumpName(const char *name, INT32 tag) // Cache a patch into heap memory, convert the patch format as necessary // +void W_FlushCachedPatches(void) +{ + if (needpatchflush) + { + Z_FreeTag(PU_CACHE); + Z_FreeTag(PU_PATCH); + Z_FreeTag(PU_HUDGFX); + Z_FreeTag(PU_HWRPATCHINFO); + Z_FreeTag(PU_HWRPATCHCOLMIPMAP); + Z_FreeTag(PU_HWRCACHE); + Z_FreeTags(PU_HWRCACHE_UNLOCKED, PU_HWRPATCHINFO_UNLOCKED); + } + needpatchflush = false; +} + // Software-only compile cache the data without conversion #ifdef HWRENDER static inline void *W_CachePatchNumPwad(UINT16 wad, UINT16 lump, INT32 tag) { GLPatch_t *grPatch; + if (needpatchflush) + W_FlushCachedPatches(); + if (rendermode == render_soft || rendermode == render_none) return W_CacheLumpNumPwad(wad, lump, tag); diff --git a/src/w_wad.h b/src/w_wad.h index 87566c3ee..84e921e75 100644 --- a/src/w_wad.h +++ b/src/w_wad.h @@ -183,6 +183,7 @@ void *W_CachePatchNum(lumpnum_t lumpnum, INT32 tag); // return a patch_t #endif void W_UnlockCachedPatch(void *patch); +void W_FlushCachedPatches(void); void W_VerifyFileMD5(UINT16 wadfilenum, const char *matchmd5); diff --git a/src/win32/win_vid.c b/src/win32/win_vid.c index cca7810b3..a6d9cdfc1 100644 --- a/src/win32/win_vid.c +++ b/src/win32/win_vid.c @@ -939,6 +939,11 @@ INT32 VID_SetMode(INT32 modenum) return 1; } +void VID_CheckRenderer(void) +{ + // .............. +} + // ======================================================================== // Free the video buffer of the last video mode, // allocate a new buffer for the video mode to set. diff --git a/src/y_inter.c b/src/y_inter.c index ed4972d2e..ab0af490d 100644 --- a/src/y_inter.c +++ b/src/y_inter.c @@ -1051,8 +1051,8 @@ void Y_StartIntermission(void) } for (i = 0; i < 4; ++i) - data.coop.bonuspatches[i] = W_CachePatchName(data.coop.bonuses[i].patch, PU_STATIC); - data.coop.ptotal = W_CachePatchName("YB_TOTAL", PU_STATIC); + data.coop.bonuspatches[i] = W_CachePatchName(data.coop.bonuses[i].patch, PU_PATCH); + data.coop.ptotal = W_CachePatchName("YB_TOTAL", PU_PATCH); // get act number if (mapheaderinfo[prevmap]->actnum) @@ -1062,13 +1062,13 @@ void Y_StartIntermission(void) data.coop.ttlnum = W_CachePatchName("TTL01", PU_STATIC); // get background patches - widebgpatch = W_CachePatchName("INTERSCW", PU_STATIC); - bgpatch = W_CachePatchName("INTERSCR", PU_STATIC); + widebgpatch = W_CachePatchName("INTERSCW", PU_PATCH); + bgpatch = W_CachePatchName("INTERSCR", PU_PATCH); // grab an interscreen if appropriate if (mapheaderinfo[gamemap-1]->interscreen[0] != '#') { - interpic = W_CachePatchName(mapheaderinfo[gamemap-1]->interscreen, PU_STATIC); + interpic = W_CachePatchName(mapheaderinfo[gamemap-1]->interscreen, PU_PATCH); useinterpic = true; usebuffer = false; } @@ -1153,17 +1153,17 @@ void Y_StartIntermission(void) // give out ring bonuses Y_AwardSpecialStageBonus(); - data.spec.bonuspatch = W_CachePatchName(data.spec.bonus.patch, PU_STATIC); - data.spec.pscore = W_CachePatchName("YB_SCORE", PU_STATIC); - data.spec.pcontinues = W_CachePatchName("YB_CONTI", PU_STATIC); + data.spec.bonuspatch = W_CachePatchName(data.spec.bonus.patch, PU_PATCH); + data.spec.pscore = W_CachePatchName("YB_SCORE", PU_PATCH); + data.spec.pcontinues = W_CachePatchName("YB_CONTI", PU_PATCH); // get background tile - bgtile = W_CachePatchName("SPECTILE", PU_STATIC); + bgtile = W_CachePatchName("SPECTILE", PU_PATCH); // grab an interscreen if appropriate if (mapheaderinfo[gamemap-1]->interscreen[0] != '#') { - interpic = W_CachePatchName(mapheaderinfo[gamemap-1]->interscreen, PU_STATIC); + interpic = W_CachePatchName(mapheaderinfo[gamemap-1]->interscreen, PU_PATCH); useinterpic = true; } else @@ -1175,14 +1175,14 @@ void Y_StartIntermission(void) // get special stage specific patches /* if (!stagefailed && ALL7EMERALDS(emeralds)) { - data.spec.cemerald = W_CachePatchName("GOTEMALL", PU_STATIC); + data.spec.cemerald = W_CachePatchName("GOTEMALL", PU_PATCH); data.spec.headx = 70; data.spec.nowsuper = players[consoleplayer].skin ? NULL : W_CachePatchName("NOWSUPER", PU_STATIC); } else { - data.spec.cemerald = W_CachePatchName("CEMERALD", PU_STATIC); + data.spec.cemerald = W_CachePatchName("CEMERALD", PU_PATCH); data.spec.headx = 48; data.spec.nowsuper = NULL; } */ @@ -1255,9 +1255,9 @@ void Y_StartIntermission(void) // get RESULT header data.match.result = - W_CachePatchName("RESULT", PU_STATIC); + W_CachePatchName("RESULT", PU_PATCH); - bgtile = W_CachePatchName("SRB2BACK", PU_STATIC); + bgtile = W_CachePatchName("SRB2BACK", PU_PATCH); usetile = true; useinterpic = false; break; @@ -1283,9 +1283,9 @@ void Y_StartIntermission(void) data.match.levelstring[sizeof data.match.levelstring - 1] = '\0'; // get RESULT header - data.match.result = W_CachePatchName("RESULT", PU_STATIC); + data.match.result = W_CachePatchName("RESULT", PU_PATCH); - bgtile = W_CachePatchName("SRB2BACK", PU_STATIC); + bgtile = W_CachePatchName("SRB2BACK", PU_PATCH); usetile = true; useinterpic = false; break; @@ -1322,7 +1322,7 @@ void Y_StartIntermission(void) data.match.blueflag = bmatcico; } - bgtile = W_CachePatchName("SRB2BACK", PU_STATIC); + bgtile = W_CachePatchName("SRB2BACK", PU_PATCH); usetile = true; useinterpic = false; break; @@ -1348,7 +1348,7 @@ void Y_StartIntermission(void) data.competition.levelstring[sizeof data.competition.levelstring - 1] = '\0'; // get background tile - bgtile = W_CachePatchName("SRB2BACK", PU_STATIC); + bgtile = W_CachePatchName("SRB2BACK", PU_PATCH); usetile = true; useinterpic = false; break; diff --git a/src/z_zone.h b/src/z_zone.h index 1424a3782..a62555243 100644 --- a/src/z_zone.h +++ b/src/z_zone.h @@ -39,6 +39,7 @@ #define PU_SOUND 11 // static while playing #define PU_MUSIC 12 // static while playing #define PU_HUDGFX 13 // static until WAD added +#define PU_PATCH 14 // static until renderer change #define PU_HWRPATCHINFO 21 // Hardware GLPatch_t struct for OpenGL texture cache #define PU_HWRPATCHCOLMIPMAP 22 // Hardware GLMipmap_t struct colromap variation of patch From 19e50062cc41aeb0efda24e2478ec98a645f6a97 Mon Sep 17 00:00:00 2001 From: Jaime Passos Date: Sun, 8 Sep 2019 18:59:49 -0300 Subject: [PATCH 03/79] more stuff. i hope i didnt mess this up. --- src/hardware/hw_main.c | 19 ++++++++++++------- src/m_menu.c | 7 ++++--- src/r_main.c | 3 ++- src/sdl/i_video.c | 23 ++++++++--------------- src/z_zone.h | 1 + 5 files changed, 27 insertions(+), 26 deletions(-) diff --git a/src/hardware/hw_main.c b/src/hardware/hw_main.c index 399a7bfd2..4f31b262a 100644 --- a/src/hardware/hw_main.c +++ b/src/hardware/hw_main.c @@ -6378,13 +6378,18 @@ static void Command_GrStats_f(void) //added by Hurdler: console varibale that are saved void HWR_AddCommands(void) { - CV_RegisterVar(&cv_grrounddown); - CV_RegisterVar(&cv_grfov); - CV_RegisterVar(&cv_grfogdensity); - CV_RegisterVar(&cv_grfiltermode); - CV_RegisterVar(&cv_granisotropicmode); - CV_RegisterVar(&cv_grcorrecttricks); - CV_RegisterVar(&cv_grsolvetjoin); + static boolean alreadycalled = false; + if (!alreadycalled) + { + CV_RegisterVar(&cv_grrounddown); + CV_RegisterVar(&cv_grfov); + CV_RegisterVar(&cv_grfogdensity); + CV_RegisterVar(&cv_grfiltermode); + CV_RegisterVar(&cv_granisotropicmode); + CV_RegisterVar(&cv_grcorrecttricks); + CV_RegisterVar(&cv_grsolvetjoin); + } + alreadycalled = true; } static inline void HWR_AddEngineCommands(void) diff --git a/src/m_menu.c b/src/m_menu.c index f6c47077e..8ae341e31 100644 --- a/src/m_menu.c +++ b/src/m_menu.c @@ -1101,7 +1101,8 @@ static menuitem_t OP_VideoOptionsMenu[] = {IT_STRING | IT_CALL, NULL, "Video Modes...", M_VideoModeMenu, 10}, #ifdef HWRENDER - {IT_SUBMENU|IT_STRING, NULL, "3D Card Options...", &OP_OpenGLOptionsDef, 20}, + {IT_STRING|IT_CVAR, NULL, "Renderer", &cv_renderer, 20}, + //{IT_SUBMENU|IT_STRING, NULL, "3D Card Options...", &OP_OpenGLOptionsDef, 20}, #endif #if (defined (__unix__) && !defined (MSDOS)) || defined (UNIXCOMMON) || defined (HAVE_SDL) @@ -2769,11 +2770,11 @@ void M_Init(void) quitmsg[QUIT3MSG5] = M_GetText("You'll be back to play soon, though...\n......right?\n\n(Press 'Y' to quit)"); quitmsg[QUIT3MSG6] = M_GetText("Aww, is Egg Rock Zone too\ndifficult for you?\n\n(Press 'Y' to quit)"); -#ifdef HWRENDER +/*#ifdef HWRENDER // Permanently hide some options based on render mode if (rendermode == render_soft) OP_VideoOptionsMenu[1].status = IT_DISABLED; -#endif +#endif*/ #ifndef NONET CV_RegisterVar(&cv_serversort); diff --git a/src/r_main.c b/src/r_main.c index f12fe23fe..f7678b928 100644 --- a/src/r_main.c +++ b/src/r_main.c @@ -1342,6 +1342,7 @@ void R_RenderPlayerView(player_t *player) #ifdef HWRENDER void R_InitHardwareMode(void) { + HWR_AddCommands(); if (gamestate == GS_LEVEL) { HWR_SetupLevel(); @@ -1432,7 +1433,7 @@ void R_RegisterEngineStuff(void) #endif #ifdef HWRENDER - if (rendermode != render_soft && rendermode != render_none) + if (rendermode == render_opengl) HWR_AddCommands(); #endif } diff --git a/src/sdl/i_video.c b/src/sdl/i_video.c index 45d9e3ed9..163e650b9 100644 --- a/src/sdl/i_video.c +++ b/src/sdl/i_video.c @@ -139,6 +139,7 @@ static SDL_bool borderlesswindow = SDL_FALSE; // SDL2 vars SDL_Window *window; SDL_Renderer *renderer; +static int renderflags; static SDL_Texture *texture; static SDL_bool havefocus = SDL_TRUE; static const char *fallback_resolution_name = "Fallback"; @@ -1260,11 +1261,6 @@ void VID_PrepareModeList(void) #endif } -// SOMETIME IN -// THE FUTURE -// WHEN I ACTUALLY RENDER -// THIS FRAME -static int renderflags; static SDL_bool Impl_CreateContext(int flags) { // Renderer-specific stuff @@ -1308,13 +1304,6 @@ void VID_CheckRenderer(void) { rendermode = setrenderneeded; Impl_CreateContext(renderflags); - if (rendermode == render_soft) - { -#ifdef HWRENDER - HWR_FreeTextureCache(); -#endif - SCR_SetDrawFuncs(); - } } SDLSetMode(vid.width, vid.height, USE_FULLSCREEN); @@ -1327,6 +1316,10 @@ void VID_CheckRenderer(void) bufSurface = NULL; } Impl_VideoSetupBuffer(); +#ifdef HWRENDER + HWR_FreeTextureCache(); +#endif + SCR_SetDrawFuncs(); } else if (rendermode == render_opengl) { @@ -1386,10 +1379,10 @@ static SDL_bool Impl_CreateWindow(SDL_bool fullscreen) if (borderlesswindow) flags |= SDL_WINDOW_BORDERLESS; -#ifdef HWRENDER - if (rendermode == render_opengl) +//#ifdef HWRENDER + //if (rendermode == render_opengl) flags |= SDL_WINDOW_OPENGL; -#endif +//#endif // Create a window window = SDL_CreateWindow("SRB2 "VERSIONSTRING, SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED, diff --git a/src/z_zone.h b/src/z_zone.h index a62555243..edf4c79ba 100644 --- a/src/z_zone.h +++ b/src/z_zone.h @@ -60,6 +60,7 @@ #define PU_HWRPATCHINFO_UNLOCKED 103 void Z_Init(void); +#define Z_FreeTag(tag) Z_FreeTags(tag, tag) void Z_FreeTags(INT32 lowtag, INT32 hightag); void Z_CheckMemCleanup(void); void Z_CheckHeap(INT32 i); From 725d0b4c44fbe88c566220603c56c66dcc787748 Mon Sep 17 00:00:00 2001 From: Jaime Passos Date: Sun, 8 Sep 2019 21:37:24 -0300 Subject: [PATCH 04/79] still making things better --- src/console.c | 5 +- src/f_finale.c | 30 +++++----- src/hardware/hw_bsp.c | 4 +- src/hardware/hw_cache.c | 30 +++++----- src/hardware/hw_glob.h | 1 + src/hardware/hw_main.c | 1 + src/hardware/hw_md2.c | 2 +- src/lua_hudlib.c | 2 +- src/m_menu.c | 5 +- src/p_setup.c | 37 ++++-------- src/r_data.c | 2 - src/r_data.h | 2 - src/r_main.c | 2 +- src/screen.c | 34 ++++++++--- src/sdl/i_video.c | 45 +++++--------- src/w_wad.c | 20 ++----- src/w_wad.h | 1 - src/y_inter.c | 128 ++++++++++++++++++++++++++++++---------- src/z_zone.c | 20 +++++++ src/z_zone.h | 5 ++ 20 files changed, 224 insertions(+), 152 deletions(-) diff --git a/src/console.c b/src/console.c index 826153ff0..6dd3fadff 100644 --- a/src/console.c +++ b/src/console.c @@ -1585,12 +1585,15 @@ void CON_Drawer(void) if (needpatchrecache) { - W_FlushCachedPatches(); + Z_FlushCachedPatches(); HU_LoadGraphics(); } if (con_recalc) + { CON_RecalcSize(); + CON_ClearHUD(); + } if (con_curlines > 0) CON_DrawConsole(); diff --git a/src/f_finale.c b/src/f_finale.c index 58d57948b..b97a6206e 100644 --- a/src/f_finale.c +++ b/src/f_finale.c @@ -1451,21 +1451,21 @@ void F_GameEndTicker(void) // ============== static void F_CacheTitleScreen(void) { - ttbanner = W_CachePatchName("TTBANNER", PU_LEVEL); - ttwing = W_CachePatchName("TTWING", PU_LEVEL); - ttsonic = W_CachePatchName("TTSONIC", PU_LEVEL); - ttswave1 = W_CachePatchName("TTSWAVE1", PU_LEVEL); - ttswave2 = W_CachePatchName("TTSWAVE2", PU_LEVEL); - ttswip1 = W_CachePatchName("TTSWIP1", PU_LEVEL); - ttsprep1 = W_CachePatchName("TTSPREP1", PU_LEVEL); - ttsprep2 = W_CachePatchName("TTSPREP2", PU_LEVEL); - ttspop1 = W_CachePatchName("TTSPOP1", PU_LEVEL); - ttspop2 = W_CachePatchName("TTSPOP2", PU_LEVEL); - ttspop3 = W_CachePatchName("TTSPOP3", PU_LEVEL); - ttspop4 = W_CachePatchName("TTSPOP4", PU_LEVEL); - ttspop5 = W_CachePatchName("TTSPOP5", PU_LEVEL); - ttspop6 = W_CachePatchName("TTSPOP6", PU_LEVEL); - ttspop7 = W_CachePatchName("TTSPOP7", PU_LEVEL); + ttbanner = W_CachePatchName("TTBANNER", PU_PATCH); + ttwing = W_CachePatchName("TTWING", PU_PATCH); + ttsonic = W_CachePatchName("TTSONIC", PU_PATCH); + ttswave1 = W_CachePatchName("TTSWAVE1", PU_PATCH); + ttswave2 = W_CachePatchName("TTSWAVE2", PU_PATCH); + ttswip1 = W_CachePatchName("TTSWIP1", PU_PATCH); + ttsprep1 = W_CachePatchName("TTSPREP1", PU_PATCH); + ttsprep2 = W_CachePatchName("TTSPREP2", PU_PATCH); + ttspop1 = W_CachePatchName("TTSPOP1", PU_PATCH); + ttspop2 = W_CachePatchName("TTSPOP2", PU_PATCH); + ttspop3 = W_CachePatchName("TTSPOP3", PU_PATCH); + ttspop4 = W_CachePatchName("TTSPOP4", PU_PATCH); + ttspop5 = W_CachePatchName("TTSPOP5", PU_PATCH); + ttspop6 = W_CachePatchName("TTSPOP6", PU_PATCH); + ttspop7 = W_CachePatchName("TTSPOP7", PU_PATCH); } void F_StartTitleScreen(void) diff --git a/src/hardware/hw_bsp.c b/src/hardware/hw_bsp.c index 21fd85a33..f8bf84c9a 100644 --- a/src/hardware/hw_bsp.c +++ b/src/hardware/hw_bsp.c @@ -835,8 +835,10 @@ static INT32 SolveTProblem(void) return 0; CONS_Debug(DBG_RENDER, "Solving T-joins. This may take a while. Please wait...\n"); +#ifdef HWR_LOADING_SCREEN CON_Drawer(); //let the user know what we are doing I_FinishUpdate(); // page flip or blit buffer +#endif numsplitpoly = 0; @@ -963,9 +965,9 @@ void HWR_CreatePlanePolygons(INT32 bspnum) CONS_Debug(DBG_RENDER, "Creating polygons, please wait...\n"); #ifdef HWR_LOADING_SCREEN ls_count = ls_percent = 0; // reset the loading status -#endif CON_Drawer(); //let the user know what we are doing I_FinishUpdate(); // page flip or blit buffer +#endif HWR_ClearPolys(); diff --git a/src/hardware/hw_cache.c b/src/hardware/hw_cache.c index 3857ad5d7..0716a130f 100644 --- a/src/hardware/hw_cache.c +++ b/src/hardware/hw_cache.c @@ -571,9 +571,18 @@ static void FreeMipmapColormap(INT32 patchnum, void *patch) } } -void HWR_FreeTextureCache(void) +void HWR_FreeColormaps(void) { INT32 i; + + // Alam: free the Z_Blocks before freeing it's users + // free all skin after each level: must be done after pfnClearMipMapCache! + for (i = 0; i < numwadfiles; i++) + M_AATreeIterate(wadfiles[i]->hwrcache, FreeMipmapColormap); +} + +void HWR_FreeTextureCache(void) +{ // free references to the textures HWD.pfnClearMipMapCache(); @@ -582,15 +591,6 @@ void HWR_FreeTextureCache(void) Z_FreeTags(PU_HWRCACHE, PU_HWRCACHE); Z_FreeTags(PU_HWRCACHE_UNLOCKED, PU_HWRCACHE_UNLOCKED); - // Alam: free the Z_Blocks before freeing it's users - - // free all skin after each level: must be done after pfnClearMipMapCache! - // temp fix, idk why this crashes - // is it because the colormaps were already freed anyway? - if (!needpatchrecache) - for (i = 0; i < numwadfiles; i++) - M_AATreeIterate(wadfiles[i]->hwrcache, FreeMipmapColormap); - // now the heap don't have any 'user' pointing to our // texturecache info, we can free it if (gr_textures) @@ -713,7 +713,7 @@ void HWR_GetFlat(lumpnum_t flatlumpnum) GLMipmap_t *grmip; if (needpatchflush) - W_FlushCachedPatches(); + Z_FlushCachedPatches(); grmip = &HWR_GetCachedGLPatch(flatlumpnum)->mipmap; @@ -752,7 +752,7 @@ static void HWR_LoadMappedPatch(GLMipmap_t *grmip, GLPatch_t *gpatch) void HWR_GetPatch(GLPatch_t *gpatch) { if (needpatchflush) - W_FlushCachedPatches(); + Z_FlushCachedPatches(); // is it in hardware cache if (!gpatch->mipmap.downloaded && !gpatch->mipmap.grInfo.data) @@ -782,7 +782,7 @@ void HWR_GetMappedPatch(GLPatch_t *gpatch, const UINT8 *colormap) GLMipmap_t *grmip, *newmip; if (needpatchflush) - W_FlushCachedPatches(); + Z_FlushCachedPatches(); if (colormap == colormaps || colormap == NULL) { @@ -910,7 +910,7 @@ GLPatch_t *HWR_GetPic(lumpnum_t lumpnum) GLPatch_t *grpatch; if (needpatchflush) - W_FlushCachedPatches(); + Z_FlushCachedPatches(); grpatch = HWR_GetCachedGLPatch(lumpnum); @@ -1110,7 +1110,7 @@ void HWR_GetFadeMask(lumpnum_t fademasklumpnum) GLMipmap_t *grmip; if (needpatchflush) - W_FlushCachedPatches(); + Z_FlushCachedPatches(); grmip = &HWR_GetCachedGLPatch(fademasklumpnum)->mipmap; diff --git a/src/hardware/hw_glob.h b/src/hardware/hw_glob.h index bdf219464..eb00802a3 100644 --- a/src/hardware/hw_glob.h +++ b/src/hardware/hw_glob.h @@ -98,6 +98,7 @@ void HWR_FreePolyPool(void); // -------- void HWR_InitTextureCache(void); void HWR_FreeTextureCache(void); +void HWR_FreeColormaps(void); void HWR_FreeExtraSubsectors(void); void HWR_GetFlat(lumpnum_t flatlumpnum); diff --git a/src/hardware/hw_main.c b/src/hardware/hw_main.c index 4f31b262a..bcda8361e 100644 --- a/src/hardware/hw_main.c +++ b/src/hardware/hw_main.c @@ -6461,6 +6461,7 @@ void HWR_Shutdown(void) HWR_FreeExtraSubsectors(); HWR_FreePolyPool(); HWR_FreeTextureCache(); + HWR_FreeColormaps(); HWD.pfnFlushScreenTextures(); } diff --git a/src/hardware/hw_md2.c b/src/hardware/hw_md2.c index 353e49f81..72ea8a4cf 100644 --- a/src/hardware/hw_md2.c +++ b/src/hardware/hw_md2.c @@ -857,7 +857,7 @@ void HWR_InitMD2(void) } } // no sprite/player skin name found?!? - CONS_Printf("Unknown sprite/player skin %s detected in md2.dat\n", name); + //CONS_Printf("Unknown sprite/player skin %s detected in md2.dat\n", name); md2found: // move on to next line... continue; diff --git a/src/lua_hudlib.c b/src/lua_hudlib.c index b16125395..ba8b3a6d9 100644 --- a/src/lua_hudlib.c +++ b/src/lua_hudlib.c @@ -334,7 +334,7 @@ static int libd_patchExists(lua_State *L) static int libd_cachePatch(lua_State *L) { HUDONLY - LUA_PushUserdata(L, W_CachePatchName(luaL_checkstring(L, 1), PU_STATIC), META_PATCH); + LUA_PushUserdata(L, W_CachePatchName(luaL_checkstring(L, 1), PU_PATCH), META_PATCH); return 1; } diff --git a/src/m_menu.c b/src/m_menu.c index 8ae341e31..9a55ced4b 100644 --- a/src/m_menu.c +++ b/src/m_menu.c @@ -2481,6 +2481,9 @@ void M_Drawer(void) if (currentMenu == &MessageDef) menuactive = true; + if (needpatchrecache) + R_ReloadHUDGraphics(); + if (menuactive) { // now that's more readable with a faded background (yeah like Quake...) @@ -5709,7 +5712,7 @@ static void M_DrawLevelStats(void) V_DrawCenteredString(BASEVIDWIDTH/2, 24, V_YELLOWMAP, "PAGE 2 OF 2"); V_DrawString(72, 48, 0, va("x %d/%d", M_CountEmblems(), numemblems+numextraemblems)); - V_DrawScaledPatch(40, 48-4, 0, W_CachePatchName("EMBLICON", PU_STATIC)); + V_DrawScaledPatch(40, 48-4, 0, W_CachePatchName("EMBLICON", PU_PATCH)); M_DrawStatsMaps(statsLocation); } diff --git a/src/p_setup.c b/src/p_setup.c index 0058f7def..82b9eb691 100644 --- a/src/p_setup.c +++ b/src/p_setup.c @@ -1424,7 +1424,6 @@ static void P_LoadRawSideDefs2(void *data) case 606: //SoM: 4/4/2000: Just colormap transfer // SoM: R_CreateColormap will only create a colormap in software mode... // Perhaps we should just call it instead of doing the calculations here. - if (rendermode == render_soft || rendermode == render_none) { if (msd->toptexture[0] == '#' || msd->bottomtexture[0] == '#') { @@ -1447,11 +1446,6 @@ static void P_LoadRawSideDefs2(void *data) else sd->bottomtexture = num; } - break; - } -#ifdef HWRENDER - else - { // for now, full support of toptexture only if ((msd->toptexture[0] == '#' && msd->toptexture[1] && msd->toptexture[2] && msd->toptexture[3] && msd->toptexture[4] && msd->toptexture[5] && msd->toptexture[6]) || (msd->bottomtexture[0] == '#' && msd->bottomtexture[1] && msd->bottomtexture[2] && msd->bottomtexture[3] && msd->bottomtexture[4] && msd->bottomtexture[5] && msd->bottomtexture[6])) @@ -1503,26 +1497,8 @@ static void P_LoadRawSideDefs2(void *data) #undef ALPHA2INT #undef HEX2INT } - else - { - if ((num = R_CheckTextureNumForName(msd->toptexture)) == -1) - sd->toptexture = 0; - else - sd->toptexture = num; - - if ((num = R_CheckTextureNumForName(msd->midtexture)) == -1) - sd->midtexture = 0; - else - sd->midtexture = num; - - if ((num = R_CheckTextureNumForName(msd->bottomtexture)) == -1) - sd->bottomtexture = 0; - else - sd->bottomtexture = num; - } break; } -#endif case 413: // Change music { @@ -2967,6 +2943,12 @@ boolean P_SetupLevel(boolean skipprecip) globalweather = mapheaderinfo[gamemap-1]->weather; #ifdef HWRENDER // not win32 only 19990829 by Kin + // gotta free this regardless of rendermode. + // maybe we're not in opengl anymore....... + if (extrasubsectors) + free(extrasubsectors); + extrasubsectors = NULL; + // stuff like HWR_CreatePlanePolygons is called there if (rendermode == render_opengl) HWR_SetupLevel(); #endif @@ -3116,7 +3098,10 @@ boolean P_SetupLevel(boolean skipprecip) // preload graphics #ifdef HWRENDER // not win32 only 19990829 by Kin if (rendermode == render_opengl) + { HWR_PrepLevelCache(numtextures); + //HWR_FreeColormaps(); + } #endif P_MapEnd(); @@ -3180,7 +3165,9 @@ void HWR_SetupLevel(void) #endif // Correct missing sidedefs & deep water trick HWR_CorrectSWTricks(); - HWR_CreatePlanePolygons((INT32)numnodes - 1); + // don't do it twice... + if (!extrasubsectors) + HWR_CreatePlanePolygons((INT32)numnodes - 1); } #endif diff --git a/src/r_data.c b/src/r_data.c index cd50272b0..a487601a3 100644 --- a/src/r_data.c +++ b/src/r_data.c @@ -95,8 +95,6 @@ size_t numspritelumps, max_spritelumps; // textures INT32 numtextures = 0; // total number of textures found, -boolean needpatchflush = false; -boolean needpatchrecache = false; // size of following tables texture_t **textures = NULL; diff --git a/src/r_data.h b/src/r_data.h index e6229d6c8..5de51ccd4 100644 --- a/src/r_data.h +++ b/src/r_data.h @@ -96,7 +96,5 @@ INT32 R_CreateColormap(char *p1, char *p2, char *p3); const char *R_ColormapNameForNum(INT32 num); extern INT32 numtextures; -extern boolean needpatchflush; -extern boolean needpatchrecache; #endif diff --git a/src/r_main.c b/src/r_main.c index f7678b928..d7196427c 100644 --- a/src/r_main.c +++ b/src/r_main.c @@ -1353,7 +1353,7 @@ void R_InitHardwareMode(void) void R_ReloadHUDGraphics(void) { - W_FlushCachedPatches(); + Z_FlushCachedPatches(); ST_LoadGraphics(); HU_LoadGraphics(); ST_ReloadSkinFaceGraphics(); diff --git a/src/screen.c b/src/screen.c index d485a6367..7c8bfb14a 100644 --- a/src/screen.c +++ b/src/screen.c @@ -72,11 +72,12 @@ consvar_t cv_scr_depth = {"scr_depth", "16 bits", CV_SAVE, scr_depth_cons_t, NUL #endif consvar_t cv_renderview = {"renderview", "On", 0, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL}; -static void SCR_ChangeRenderer (void); +static void SCR_ChangeRenderer(void); +static void SCR_ActuallyChangeRenderer(void); static CV_PossibleValue_t cv_renderer_t[] = {{1, "Software"}, {2, "OpenGL"}, {0, NULL}}; -consvar_t cv_renderer = {"renderer", "Software", CV_CALL, cv_renderer_t, SCR_ChangeRenderer, 0, NULL, NULL, 0, 0, NULL}; +consvar_t cv_renderer = {"renderer", "Software", CV_SAVE|CV_CALL, cv_renderer_t, SCR_ChangeRenderer, 0, NULL, NULL, 0, 0, NULL}; -static void SCR_ChangeFullscreen (void); +static void SCR_ChangeFullscreen(void); consvar_t cv_fullscreen = {"fullscreen", "Yes", CV_SAVE|CV_CALL, CV_YesNo, SCR_ChangeFullscreen, 0, NULL, NULL, 0, 0, NULL}; @@ -376,6 +377,8 @@ void SCR_CheckDefaultMode(void) // see note above setmodeneeded = VID_GetModeForSize(cv_scr_width.value, cv_scr_height.value) + 1; } + + SCR_ActuallyChangeRenderer(); } // sets the modenum as the new default video mode to be saved in the config file @@ -405,12 +408,28 @@ void SCR_ChangeFullscreen(void) #endif } +static int target_renderer = 0; + +void SCR_ActuallyChangeRenderer(void) +{ + setrenderneeded = target_renderer; + // setting the same renderer twice WILL crash your game, so let's not, please + if (rendermode == setrenderneeded) + setrenderneeded = 0; +} + void SCR_ChangeRenderer(void) { setrenderneeded = 0; if (con_startup) { + target_renderer = cv_renderer.value; + if (M_CheckParm("-opengl")) + target_renderer = rendermode = render_opengl; + else if (M_CheckParm("-software")) + target_renderer = rendermode = render_soft; + // set cv_renderer back if (rendermode == render_soft) CV_StealthSetValue(&cv_renderer, 1); else if (rendermode == render_opengl) @@ -419,13 +438,10 @@ void SCR_ChangeRenderer(void) } if (cv_renderer.value == 1) - setrenderneeded = render_soft; + target_renderer = render_soft; else if (cv_renderer.value == 2) - setrenderneeded = render_opengl; - - // setting the same renderer twice WILL crash your game, so let's not, please - if (rendermode == setrenderneeded) - setrenderneeded = 0; + target_renderer = render_opengl; + SCR_ActuallyChangeRenderer(); } boolean SCR_IsAspectCorrect(INT32 width, INT32 height) diff --git a/src/sdl/i_video.c b/src/sdl/i_video.c index 163e650b9..7c068205d 100644 --- a/src/sdl/i_video.c +++ b/src/sdl/i_video.c @@ -139,7 +139,6 @@ static SDL_bool borderlesswindow = SDL_FALSE; // SDL2 vars SDL_Window *window; SDL_Renderer *renderer; -static int renderflags; static SDL_Texture *texture; static SDL_bool havefocus = SDL_TRUE; static const char *fallback_resolution_name = "Fallback"; @@ -1261,7 +1260,7 @@ void VID_PrepareModeList(void) #endif } -static SDL_bool Impl_CreateContext(int flags) +static SDL_bool Impl_CreateContext(void) { // Renderer-specific stuff #ifdef HWRENDER @@ -1280,7 +1279,7 @@ static SDL_bool Impl_CreateContext(int flags) #endif if (rendermode == render_soft) { - flags = 0; // Use this to set SDL_RENDERER_* flags now + int flags = 0; // Use this to set SDL_RENDERER_* flags now if (usesdl2soft) flags |= SDL_RENDERER_SOFTWARE; else if (cv_vidwait.value) @@ -1300,10 +1299,13 @@ static SDL_bool Impl_CreateContext(int flags) void VID_CheckRenderer(void) { + if (dedicated) + return; + if (setrenderneeded) { rendermode = setrenderneeded; - Impl_CreateContext(renderflags); + Impl_CreateContext(); } SDLSetMode(vid.width, vid.height, USE_FULLSCREEN); @@ -1335,29 +1337,15 @@ INT32 VID_SetMode(INT32 modeNum) vid.recalc = 1; vid.bpp = 1; - if (modeNum >= 0 && modeNum < MAXWINMODES) - { - vid.width = windowedModes[modeNum][0]; - vid.height = windowedModes[modeNum][1]; - vid.modenum = modeNum; - } - else - { - // just set the desktop resolution as a fallback - SDL_DisplayMode mode; - SDL_GetWindowDisplayMode(window, &mode); - if (mode.w >= 2048) - { - vid.width = 1920; - vid.height = 1200; - } - else - { - vid.width = mode.w; - vid.height = mode.h; - } - vid.modenum = -1; - } + if (modeNum < 0) + modeNum = 0; + if (modeNum >= MAXWINMODES) + modeNum = MAXWINMODES-1; + + vid.width = windowedModes[modeNum][0]; + vid.height = windowedModes[modeNum][1]; + vid.modenum = modeNum; + //Impl_SetWindowName("SRB2 "VERSIONSTRING); VID_CheckRenderer(); return SDL_TRUE; @@ -1394,8 +1382,7 @@ static SDL_bool Impl_CreateWindow(SDL_bool fullscreen) return SDL_FALSE; } - renderflags = flags; - return Impl_CreateContext(flags); + return Impl_CreateContext(); } /* diff --git a/src/w_wad.c b/src/w_wad.c index 00797b87d..96381635a 100644 --- a/src/w_wad.c +++ b/src/w_wad.c @@ -831,7 +831,10 @@ void W_UnloadWadFile(UINT16 num) numwadfiles--; #ifdef HWRENDER if (rendermode != render_soft && rendermode != render_none) + { HWR_FreeTextureCache(); + HWR_FreeColormaps(); + } M_AATreeFree(delwad->hwrcache); #endif if (*lumpcache) @@ -1503,21 +1506,6 @@ void *W_CacheLumpName(const char *name, INT32 tag) // Cache a patch into heap memory, convert the patch format as necessary // -void W_FlushCachedPatches(void) -{ - if (needpatchflush) - { - Z_FreeTag(PU_CACHE); - Z_FreeTag(PU_PATCH); - Z_FreeTag(PU_HUDGFX); - Z_FreeTag(PU_HWRPATCHINFO); - Z_FreeTag(PU_HWRPATCHCOLMIPMAP); - Z_FreeTag(PU_HWRCACHE); - Z_FreeTags(PU_HWRCACHE_UNLOCKED, PU_HWRPATCHINFO_UNLOCKED); - } - needpatchflush = false; -} - // Software-only compile cache the data without conversion #ifdef HWRENDER static inline void *W_CachePatchNumPwad(UINT16 wad, UINT16 lump, INT32 tag) @@ -1525,7 +1513,7 @@ static inline void *W_CachePatchNumPwad(UINT16 wad, UINT16 lump, INT32 tag) GLPatch_t *grPatch; if (needpatchflush) - W_FlushCachedPatches(); + Z_FlushCachedPatches(); if (rendermode == render_soft || rendermode == render_none) return W_CacheLumpNumPwad(wad, lump, tag); diff --git a/src/w_wad.h b/src/w_wad.h index 84e921e75..87566c3ee 100644 --- a/src/w_wad.h +++ b/src/w_wad.h @@ -183,7 +183,6 @@ void *W_CachePatchNum(lumpnum_t lumpnum, INT32 tag); // return a patch_t #endif void W_UnlockCachedPatch(void *patch); -void W_FlushCachedPatches(void); void W_VerifyFileMD5(UINT16 wadfilenum, const char *matchmd5); diff --git a/src/y_inter.c b/src/y_inter.c index ab0af490d..ab27a00fe 100644 --- a/src/y_inter.c +++ b/src/y_inter.c @@ -144,6 +144,7 @@ static patch_t *interpic = NULL; // custom picture defined in map header static boolean usetile; boolean usebuffer = false; static boolean useinterpic; +static boolean safetorender = true; static INT32 timer; static INT32 intertic; @@ -158,6 +159,7 @@ static void Y_CalculateTimeRaceWinners(void); static void Y_CalculateMatchWinners(void); static void Y_FollowIntermission(void); static void Y_UnloadData(void); +static void Y_CleanupData(void); // Stuff copy+pasted from st_stuff.c static INT32 SCX(INT32 x) @@ -187,31 +189,41 @@ void Y_IntermissionDrawer(void) if (intertype == int_none || rendermode == render_none) return; - if (!usebuffer) + if (needpatchrecache) + { + Y_CleanupData(); + R_ReloadHUDGraphics(); + safetorender = false; + } + + if (!usebuffer || !safetorender) V_DrawFill(0, 0, BASEVIDWIDTH, BASEVIDHEIGHT, 31); - if (useinterpic) - V_DrawScaledPatch(0, 0, 0, interpic); - else if (!usetile) + if (safetorender) { - if (rendermode == render_soft && usebuffer) - VID_BlitLinearScreen(screens[1], screens[0], vid.width*vid.bpp, vid.height, vid.width*vid.bpp, vid.rowbytes); + if (useinterpic) + V_DrawScaledPatch(0, 0, 0, interpic); + else if (!usetile) + { + if (rendermode == render_soft && usebuffer) + VID_BlitLinearScreen(screens[1], screens[0], vid.width*vid.bpp, vid.height, vid.width*vid.bpp, vid.rowbytes); #ifdef HWRENDER - else if(rendermode != render_soft && usebuffer) - { - HWR_DrawIntermissionBG(); - } + else if(rendermode != render_soft && usebuffer) + { + HWR_DrawIntermissionBG(); + } #endif - else - { - if (widebgpatch && rendermode == render_soft && vid.width / vid.dupx == 400) - V_DrawScaledPatch(0, 0, V_SNAPTOLEFT, widebgpatch); else - V_DrawScaledPatch(0, 0, 0, bgpatch); + { + if (widebgpatch && rendermode == render_soft && vid.width / vid.dupx == 400) + V_DrawScaledPatch(0, 0, V_SNAPTOLEFT, widebgpatch); + else + V_DrawScaledPatch(0, 0, 0, bgpatch); + } } + else + V_DrawPatchFill(bgtile); } - else - V_DrawPatchFill(bgtile); if (intertype == int_coop) { @@ -249,19 +261,22 @@ void Y_IntermissionDrawer(void) V_DrawLevelTitle(data.coop.passedx1, 49, 0, data.coop.passed1); V_DrawLevelTitle(data.coop.passedx2, 49+V_LevelNameHeight(data.coop.passed2)+2, 0, data.coop.passed2); - if (mapheaderinfo[gamemap-1]->actnum) + if (mapheaderinfo[gamemap-1]->actnum && safetorender) V_DrawScaledPatch(244, 57, 0, data.coop.ttlnum); bonusy = 150; // Total - V_DrawScaledPatch(152, bonusy, 0, data.coop.ptotal); - V_DrawTallNum(BASEVIDWIDTH - 68, bonusy + 1, 0, data.coop.total); + if (safetorender) + { + V_DrawScaledPatch(152, bonusy, 0, data.coop.ptotal); + V_DrawTallNum(BASEVIDWIDTH - 68, bonusy + 1, 0, data.coop.total); + } bonusy -= (3*SHORT(tallnum[0]->height)/2) + 1; // Draw bonuses for (i = 3; i >= 0; --i) { - if (data.coop.bonuses[i].display) + if (data.coop.bonuses[i].display && safetorender) { V_DrawScaledPatch(152, bonusy, 0, data.coop.bonuspatches[i]); V_DrawTallNum(BASEVIDWIDTH - 68, bonusy + 1, 0, data.coop.bonuses[i].points); @@ -340,13 +355,16 @@ void Y_IntermissionDrawer(void) } } - V_DrawScaledPatch(152, 108, 0, data.spec.bonuspatch); - V_DrawTallNum(BASEVIDWIDTH - 68, 109, 0, data.spec.bonus.points); - V_DrawScaledPatch(152, 124, 0, data.spec.pscore); - V_DrawTallNum(BASEVIDWIDTH - 68, 125, 0, data.spec.score); + if (safetorender) + { + V_DrawScaledPatch(152, 108, 0, data.spec.bonuspatch); + V_DrawTallNum(BASEVIDWIDTH - 68, 109, 0, data.spec.bonus.points); + V_DrawScaledPatch(152, 124, 0, data.spec.pscore); + V_DrawTallNum(BASEVIDWIDTH - 68, 125, 0, data.spec.score); + } // Draw continues! - if (!multiplayer /* && (data.spec.continues & 0x80) */) // Always draw outside of netplay + if (!multiplayer && safetorender /* && (data.spec.continues & 0x80) */) // Always draw outside of netplay { UINT8 continues = data.spec.continues & 0x7F; @@ -368,7 +386,8 @@ void Y_IntermissionDrawer(void) char strtime[10]; // draw the header - V_DrawScaledPatch(112, 2, 0, data.match.result); + if (safetorender) + V_DrawScaledPatch(112, 2, 0, data.match.result); // draw the level name V_DrawCenteredString(BASEVIDWIDTH/2, 20, 0, data.match.levelstring); @@ -959,6 +978,8 @@ void Y_StartIntermission(void) I_Error("endtic is dirty"); #endif + safetorender = true; + if (!multiplayer) { timer = 0; @@ -1057,9 +1078,9 @@ void Y_StartIntermission(void) // get act number if (mapheaderinfo[prevmap]->actnum) data.coop.ttlnum = W_CachePatchName(va("TTL%.2d", mapheaderinfo[prevmap]->actnum), - PU_STATIC); + PU_PATCH); else - data.coop.ttlnum = W_CachePatchName("TTL01", PU_STATIC); + data.coop.ttlnum = W_CachePatchName("TTL01", PU_PATCH); // get background patches widebgpatch = W_CachePatchName("INTERSCW", PU_PATCH); @@ -1178,7 +1199,7 @@ void Y_StartIntermission(void) data.spec.cemerald = W_CachePatchName("GOTEMALL", PU_PATCH); data.spec.headx = 70; data.spec.nowsuper = players[consoleplayer].skin - ? NULL : W_CachePatchName("NOWSUPER", PU_STATIC); + ? NULL : W_CachePatchName("NOWSUPER", PU_PATCH); } else { @@ -1835,7 +1856,8 @@ static void Y_FollowIntermission(void) G_AfterIntermission(); } -#define UNLOAD(x) Z_ChangeTag(x, PU_CACHE); x = NULL +#define UNLOAD(x) if (x) {Z_ChangeTag(x, PU_CACHE);} x = NULL; +#define CLEANUP(x) x = NULL; // // Y_UnloadData @@ -1886,5 +1908,47 @@ static void Y_UnloadData(void) //are not handled break; } - +} + +static void Y_CleanupData(void) +{ + // unload the background patches + CLEANUP(bgpatch); + CLEANUP(widebgpatch); + CLEANUP(bgtile); + CLEANUP(interpic); + + switch (intertype) + { + case int_coop: + // unload the coop and single player patches + CLEANUP(data.coop.ttlnum); + CLEANUP(data.coop.bonuspatches[3]); + CLEANUP(data.coop.bonuspatches[2]); + CLEANUP(data.coop.bonuspatches[1]); + CLEANUP(data.coop.bonuspatches[0]); + CLEANUP(data.coop.ptotal); + break; + case int_spec: + // unload the special stage patches + //CLEANUP(data.spec.cemerald); + //CLEANUP(data.spec.nowsuper); + CLEANUP(data.spec.bonuspatch); + CLEANUP(data.spec.pscore); + CLEANUP(data.spec.pcontinues); + break; + case int_match: + case int_race: + CLEANUP(data.match.result); + break; + case int_ctf: + CLEANUP(data.match.blueflag); + CLEANUP(data.match.redflag); + break; + default: + //without this default, + //int_none, int_tag, int_chaos, and int_classicrace + //are not handled + break; + } } diff --git a/src/z_zone.c b/src/z_zone.c index a3e13422f..add18b568 100644 --- a/src/z_zone.c +++ b/src/z_zone.c @@ -411,6 +411,26 @@ void Z_FreeTags(INT32 lowtag, INT32 hightag) } } +// for renderer switching, free a bunch of stuff +boolean needpatchflush = false; +boolean needpatchrecache = false; + +void Z_FlushCachedPatches(void) +{ + if (needpatchflush) + { + Z_FreeTag(PU_CACHE); + Z_FreeTag(PU_PATCH); + Z_FreeTag(PU_HUDGFX); + Z_FreeTag(PU_HWRPATCHINFO); + Z_FreeTag(PU_HWRPATCHCOLMIPMAP); + Z_FreeTag(PU_HWRCACHE); + Z_FreeTag(PU_HWRCACHE_UNLOCKED); + Z_FreeTag(PU_HWRPATCHINFO_UNLOCKED); + } + needpatchflush = false; +} + // // Z_CheckMemCleanup // diff --git a/src/z_zone.h b/src/z_zone.h index edf4c79ba..700e3a1d5 100644 --- a/src/z_zone.h +++ b/src/z_zone.h @@ -70,6 +70,11 @@ void Z_ChangeTag2(void *ptr, INT32 tag, const char *file, INT32 line); void Z_ChangeTag2(void *ptr, INT32 tag); #endif +// for renderer switching, free a bunch of stuff +extern boolean needpatchflush; +extern boolean needpatchrecache; +void Z_FlushCachedPatches(void); + #ifdef PARANOIA void Z_SetUser2(void *ptr, void **newuser, const char *file, INT32 line); #else From dc93cafda9a0b3e5221e2041d2d668eebc550701 Mon Sep 17 00:00:00 2001 From: Jaime Passos Date: Sun, 8 Sep 2019 22:25:18 -0300 Subject: [PATCH 05/79] can i push this already? --- src/android/i_video.c | 1 + src/console.c | 6 +- src/d_main.c | 3 + src/djgppdos/i_video.c | 5 ++ src/dummy/i_video.c | 1 + src/i_video.h | 1 + src/nds/i_video.c | 41 ++++++++------ src/sdl/i_video.c | 106 ++++++++++++++++++------------------ src/sdl12/i_video.c | 121 ++++++++++++++++++++++------------------- src/win32/win_vid.c | 5 ++ src/win32ce/win_vid.c | 5 ++ 11 files changed, 164 insertions(+), 131 deletions(-) diff --git a/src/android/i_video.c b/src/android/i_video.c index 44e1cbac0..b8bb4fefb 100644 --- a/src/android/i_video.c +++ b/src/android/i_video.c @@ -19,6 +19,7 @@ boolean allow_fullscreen = false; consvar_t cv_vidwait = {"vid_wait", "On", CV_SAVE, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL}; void I_StartupGraphics(void){} +void I_StartupHardwareGraphics(void){} void I_ShutdownGraphics(void){} diff --git a/src/console.c b/src/console.c index 6dd3fadff..1ac181086 100644 --- a/src/console.c +++ b/src/console.c @@ -23,6 +23,7 @@ #include "g_input.h" #include "hu_stuff.h" #include "keys.h" +#include "r_main.h" #include "r_defs.h" #include "sounds.h" #include "st_stuff.h" @@ -1584,10 +1585,7 @@ void CON_Drawer(void) return; if (needpatchrecache) - { - Z_FlushCachedPatches(); - HU_LoadGraphics(); - } + R_ReloadHUDGraphics(); if (con_recalc) { diff --git a/src/d_main.c b/src/d_main.c index 06489ac7c..c84d6e7a2 100644 --- a/src/d_main.c +++ b/src/d_main.c @@ -495,6 +495,9 @@ static void D_Display(void) I_FinishUpdate(); // page flip or blit buffer } + // in the occasion no functions + // that require patches to be cached + // have been called. if (needpatchrecache) R_ReloadHUDGraphics(); diff --git a/src/djgppdos/i_video.c b/src/djgppdos/i_video.c index 612c72215..1658fa52b 100644 --- a/src/djgppdos/i_video.c +++ b/src/djgppdos/i_video.c @@ -331,3 +331,8 @@ void I_StartupGraphics(void) graphics_started = true; } + +void I_StartupHardwareGraphics(void) +{ + // oh yeah woo yeah oh yeah woo yeah oh yeah woo yeah oh yeah woo yeah oh yeah woo yeah oh yeah woo yeah oh yeah woo y +} diff --git a/src/dummy/i_video.c b/src/dummy/i_video.c index b8f40bed3..fafeee000 100644 --- a/src/dummy/i_video.c +++ b/src/dummy/i_video.c @@ -11,6 +11,7 @@ boolean allow_fullscreen = false; consvar_t cv_vidwait = {"vid_wait", "On", CV_SAVE, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL}; void I_StartupGraphics(void){} +void I_StartupHardwareGraphics(void){} void I_ShutdownGraphics(void){} diff --git a/src/i_video.h b/src/i_video.h index a62f3ff64..c57977306 100644 --- a/src/i_video.h +++ b/src/i_video.h @@ -44,6 +44,7 @@ extern boolean highcolor; /** \brief setup video mode */ void I_StartupGraphics(void); +void I_StartupHardwareGraphics(void); /** \brief restore old video mode */ diff --git a/src/nds/i_video.c b/src/nds/i_video.c index 3dfb99557..8ec1997fa 100644 --- a/src/nds/i_video.c +++ b/src/nds/i_video.c @@ -42,24 +42,7 @@ void I_StartupGraphics(void) vid.rowbytes = vid.width * vid.bpp; vid.recalc = true; - HWD.pfnInit = NDS3D_Init; - HWD.pfnShutdown = NDS3D_Shutdown; - HWD.pfnFinishUpdate = NDS3D_FinishUpdate; - HWD.pfnDraw2DLine = NDS3D_Draw2DLine; - HWD.pfnDrawPolygon = NDS3D_DrawPolygon; - HWD.pfnSetBlend = NDS3D_SetBlend; - HWD.pfnClearBuffer = NDS3D_ClearBuffer; - HWD.pfnSetTexture = NDS3D_SetTexture; - HWD.pfnReadRect = NDS3D_ReadRect; - HWD.pfnGClipRect = NDS3D_GClipRect; - HWD.pfnClearMipMapCache = NDS3D_ClearMipMapCache; - HWD.pfnSetSpecialState = NDS3D_SetSpecialState; - HWD.pfnSetPalette = NDS3D_SetPalette; - HWD.pfnGetTextureUsed = NDS3D_GetTextureUsed; - HWD.pfnDrawMD2 = NDS3D_DrawMD2; - HWD.pfnDrawMD2i = NDS3D_DrawMD2i; - HWD.pfnSetTransform = NDS3D_SetTransform; - HWD.pfnGetRenderVersion = NDS3D_GetRenderVersion; + I_StartupGraphicsHardware(); videoSetMode(MODE_0_3D); vramSetBankA(VRAM_A_TEXTURE); @@ -91,6 +74,28 @@ void I_StartupGraphics(void) HWR_Startup(); } +void I_StartupHardwareGraphics(void) +{ + HWD.pfnInit = NDS3D_Init; + HWD.pfnShutdown = NDS3D_Shutdown; + HWD.pfnFinishUpdate = NDS3D_FinishUpdate; + HWD.pfnDraw2DLine = NDS3D_Draw2DLine; + HWD.pfnDrawPolygon = NDS3D_DrawPolygon; + HWD.pfnSetBlend = NDS3D_SetBlend; + HWD.pfnClearBuffer = NDS3D_ClearBuffer; + HWD.pfnSetTexture = NDS3D_SetTexture; + HWD.pfnReadRect = NDS3D_ReadRect; + HWD.pfnGClipRect = NDS3D_GClipRect; + HWD.pfnClearMipMapCache = NDS3D_ClearMipMapCache; + HWD.pfnSetSpecialState = NDS3D_SetSpecialState; + HWD.pfnSetPalette = NDS3D_SetPalette; + HWD.pfnGetTextureUsed = NDS3D_GetTextureUsed; + HWD.pfnDrawMD2 = NDS3D_DrawMD2; + HWD.pfnDrawMD2i = NDS3D_DrawMD2i; + HWD.pfnSetTransform = NDS3D_SetTransform; + HWD.pfnGetRenderVersion = NDS3D_GetRenderVersion; +} + void I_ShutdownGraphics(void){} void I_SetPalette(RGBA_t *palette) diff --git a/src/sdl/i_video.c b/src/sdl/i_video.c index 7c068205d..4c2078b38 100644 --- a/src/sdl/i_video.c +++ b/src/sdl/i_video.c @@ -171,7 +171,6 @@ static void Impl_VideoSetupBuffer(void); static SDL_bool Impl_CreateWindow(SDL_bool fullscreen); //static void Impl_SetWindowName(const char *title); static void Impl_SetWindowIcon(void); -static void I_StartupGraphicsGL(void); static void SDLSetMode(INT32 width, INT32 height, SDL_bool fullscreen) { @@ -1323,11 +1322,13 @@ void VID_CheckRenderer(void) #endif SCR_SetDrawFuncs(); } +#ifdef HWRENDER else if (rendermode == render_opengl) { - I_StartupGraphicsGL(); + I_StartupHardwareGraphics(); R_InitHardwareMode(); } +#endif } INT32 VID_SetMode(INT32 modeNum) @@ -1367,10 +1368,9 @@ static SDL_bool Impl_CreateWindow(SDL_bool fullscreen) if (borderlesswindow) flags |= SDL_WINDOW_BORDERLESS; -//#ifdef HWRENDER - //if (rendermode == render_opengl) - flags |= SDL_WINDOW_OPENGL; -//#endif +#ifdef HWRENDER + flags |= SDL_WINDOW_OPENGL; +#endif // Create a window window = SDL_CreateWindow("SRB2 "VERSIONSTRING, SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED, @@ -1451,51 +1451,6 @@ static void Impl_VideoSetupBuffer(void) } } -static void I_StartupGraphicsGL(void) -{ -#ifdef HWRENDER - static boolean glstartup = false; - if (!glstartup) - { - HWD.pfnInit = hwSym("Init",NULL); - HWD.pfnFinishUpdate = NULL; - HWD.pfnDraw2DLine = hwSym("Draw2DLine",NULL); - HWD.pfnDrawPolygon = hwSym("DrawPolygon",NULL); - HWD.pfnSetBlend = hwSym("SetBlend",NULL); - HWD.pfnClearBuffer = hwSym("ClearBuffer",NULL); - HWD.pfnSetTexture = hwSym("SetTexture",NULL); - HWD.pfnReadRect = hwSym("ReadRect",NULL); - HWD.pfnGClipRect = hwSym("GClipRect",NULL); - HWD.pfnClearMipMapCache = hwSym("ClearMipMapCache",NULL); - HWD.pfnSetSpecialState = hwSym("SetSpecialState",NULL); - HWD.pfnSetPalette = hwSym("SetPalette",NULL); - HWD.pfnGetTextureUsed = hwSym("GetTextureUsed",NULL); - HWD.pfnDrawMD2 = hwSym("DrawMD2",NULL); - HWD.pfnDrawMD2i = hwSym("DrawMD2i",NULL); - HWD.pfnSetTransform = hwSym("SetTransform",NULL); - HWD.pfnGetRenderVersion = hwSym("GetRenderVersion",NULL); -#ifdef SHUFFLE - HWD.pfnPostImgRedraw = hwSym("PostImgRedraw",NULL); -#endif - HWD.pfnFlushScreenTextures=hwSym("FlushScreenTextures",NULL); - HWD.pfnStartScreenWipe = hwSym("StartScreenWipe",NULL); - HWD.pfnEndScreenWipe = hwSym("EndScreenWipe",NULL); - HWD.pfnDoScreenWipe = hwSym("DoScreenWipe",NULL); - HWD.pfnDrawIntermissionBG=hwSym("DrawIntermissionBG",NULL); - HWD.pfnMakeScreenTexture= hwSym("MakeScreenTexture",NULL); - HWD.pfnMakeScreenFinalTexture=hwSym("MakeScreenFinalTexture",NULL); - HWD.pfnDrawScreenFinalTexture=hwSym("DrawScreenFinalTexture",NULL); - // check gl renderer lib - if (HWD.pfnGetRenderVersion() != VERSION) - I_Error("%s", M_GetText("The version of the renderer doesn't match the version of the executable\nBe sure you have installed SRB2 properly.\n")); - if (!HWD.pfnInit(I_Error)) // let load the OpenGL library - rendermode = render_soft; - else - glstartup = true; - } -#endif -} - void I_StartupGraphics(void) { if (dedicated) @@ -1537,9 +1492,11 @@ void I_StartupGraphics(void) framebuffer = SDL_TRUE; } +#ifdef HWRENDER if (M_CheckParm("-opengl")) rendermode = render_opengl; else if (M_CheckParm("software")) +#endif rendermode = render_soft; usesdl2soft = M_CheckParm("-softblit"); @@ -1548,7 +1505,7 @@ void I_StartupGraphics(void) //SDL_EnableKeyRepeat(SDL_DEFAULT_REPEAT_DELAY>>1,SDL_DEFAULT_REPEAT_INTERVAL<<2); VID_Command_ModeList_f(); #ifdef HWRENDER - I_StartupGraphicsGL(); + I_StartupHardwareGraphics(); #endif // Fury: we do window initialization after GL setup to allow @@ -1608,6 +1565,51 @@ void I_StartupGraphics(void) graphics_started = true; } +void I_StartupHardwareGraphics(void) +{ +#ifdef HWRENDER + static boolean glstartup = false; + if (!glstartup) + { + HWD.pfnInit = hwSym("Init",NULL); + HWD.pfnFinishUpdate = NULL; + HWD.pfnDraw2DLine = hwSym("Draw2DLine",NULL); + HWD.pfnDrawPolygon = hwSym("DrawPolygon",NULL); + HWD.pfnSetBlend = hwSym("SetBlend",NULL); + HWD.pfnClearBuffer = hwSym("ClearBuffer",NULL); + HWD.pfnSetTexture = hwSym("SetTexture",NULL); + HWD.pfnReadRect = hwSym("ReadRect",NULL); + HWD.pfnGClipRect = hwSym("GClipRect",NULL); + HWD.pfnClearMipMapCache = hwSym("ClearMipMapCache",NULL); + HWD.pfnSetSpecialState = hwSym("SetSpecialState",NULL); + HWD.pfnSetPalette = hwSym("SetPalette",NULL); + HWD.pfnGetTextureUsed = hwSym("GetTextureUsed",NULL); + HWD.pfnDrawMD2 = hwSym("DrawMD2",NULL); + HWD.pfnDrawMD2i = hwSym("DrawMD2i",NULL); + HWD.pfnSetTransform = hwSym("SetTransform",NULL); + HWD.pfnGetRenderVersion = hwSym("GetRenderVersion",NULL); +#ifdef SHUFFLE + HWD.pfnPostImgRedraw = hwSym("PostImgRedraw",NULL); +#endif + HWD.pfnFlushScreenTextures=hwSym("FlushScreenTextures",NULL); + HWD.pfnStartScreenWipe = hwSym("StartScreenWipe",NULL); + HWD.pfnEndScreenWipe = hwSym("EndScreenWipe",NULL); + HWD.pfnDoScreenWipe = hwSym("DoScreenWipe",NULL); + HWD.pfnDrawIntermissionBG=hwSym("DrawIntermissionBG",NULL); + HWD.pfnMakeScreenTexture= hwSym("MakeScreenTexture",NULL); + HWD.pfnMakeScreenFinalTexture=hwSym("MakeScreenFinalTexture",NULL); + HWD.pfnDrawScreenFinalTexture=hwSym("DrawScreenFinalTexture",NULL); + // check gl renderer lib + if (HWD.pfnGetRenderVersion() != VERSION) + I_Error("%s", M_GetText("The version of the renderer doesn't match the version of the executable\nBe sure you have installed SRB2 properly.\n")); + if (!HWD.pfnInit(I_Error)) // let load the OpenGL library + rendermode = render_soft; + else + glstartup = true; + } +#endif +} + void I_ShutdownGraphics(void) { const rendermode_t oldrendermode = rendermode; diff --git a/src/sdl12/i_video.c b/src/sdl12/i_video.c index 349e06cba..b95a6a48d 100644 --- a/src/sdl12/i_video.c +++ b/src/sdl12/i_video.c @@ -1914,8 +1914,12 @@ void I_StartupGraphics(void) if (strncasecmp(vd, "gcvideo", 8) == 0 || strncasecmp(vd, "fbcon", 6) == 0 || strncasecmp(vd, "wii", 4) == 0 || strncasecmp(vd, "psl1ght", 8) == 0) framebuffer = SDL_TRUE; } - if (M_CheckParm("-software")) +#ifdef HWRENDER + if (M_CheckParm("-opengl")) + rendermode = render_opengl; + else if (M_CheckParm("-software")) rendermode = render_soft; +#endif SDL_EnableKeyRepeat(SDL_DEFAULT_REPEAT_DELAY>>1,SDL_DEFAULT_REPEAT_INTERVAL<<2); SDLESSet(); VID_Command_ModeList_f(); @@ -1949,62 +1953,9 @@ void I_StartupGraphics(void) #endif #ifdef HWRENDER - if (M_CheckParm("-opengl") || rendermode == render_opengl) - { - rendermode = render_opengl; - HWD.pfnInit = hwSym("Init",NULL); - HWD.pfnFinishUpdate = NULL; - HWD.pfnDraw2DLine = hwSym("Draw2DLine",NULL); - HWD.pfnDrawPolygon = hwSym("DrawPolygon",NULL); - HWD.pfnSetBlend = hwSym("SetBlend",NULL); - HWD.pfnClearBuffer = hwSym("ClearBuffer",NULL); - HWD.pfnSetTexture = hwSym("SetTexture",NULL); - HWD.pfnReadRect = hwSym("ReadRect",NULL); - HWD.pfnGClipRect = hwSym("GClipRect",NULL); - HWD.pfnClearMipMapCache = hwSym("ClearMipMapCache",NULL); - HWD.pfnSetSpecialState = hwSym("SetSpecialState",NULL); - HWD.pfnSetPalette = hwSym("SetPalette",NULL); - HWD.pfnGetTextureUsed = hwSym("GetTextureUsed",NULL); - HWD.pfnDrawMD2 = hwSym("DrawMD2",NULL); - HWD.pfnDrawMD2i = hwSym("DrawMD2i",NULL); - HWD.pfnSetTransform = hwSym("SetTransform",NULL); - HWD.pfnGetRenderVersion = hwSym("GetRenderVersion",NULL); -#ifdef SHUFFLE - HWD.pfnPostImgRedraw = hwSym("PostImgRedraw",NULL); -#endif - HWD.pfnFlushScreenTextures=hwSym("FlushScreenTextures",NULL); - HWD.pfnStartScreenWipe = hwSym("StartScreenWipe",NULL); - HWD.pfnEndScreenWipe = hwSym("EndScreenWipe",NULL); - HWD.pfnDoScreenWipe = hwSym("DoScreenWipe",NULL); - HWD.pfnDrawIntermissionBG=hwSym("DrawIntermissionBG",NULL); - HWD.pfnMakeScreenTexture= hwSym("MakeScreenTexture",NULL); - // check gl renderer lib - if (HWD.pfnGetRenderVersion() != VERSION) - I_Error("%s", M_GetText("The version of the renderer doesn't match the version of the executable\nBe sure you have installed SRB2 properly.\n")); -#if 1 //#ifdef _WIN32_WCE - vid.width = BASEVIDWIDTH; - vid.height = BASEVIDHEIGHT; -#else - vid.width = 640; // hack to make voodoo cards work in 640x480 - vid.height = 480; -#endif - if (HWD.pfnInit(I_Error)) // let load the OpenGL library - { - /* - * We want at least 1 bit R, G, and B, - * and at least 16 bpp. Why 1 bit? May be more? - */ - SDL_GL_SetAttribute(SDL_GL_RED_SIZE, 1); - SDL_GL_SetAttribute(SDL_GL_GREEN_SIZE, 1); - SDL_GL_SetAttribute(SDL_GL_BLUE_SIZE, 1); - SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1); - if (!OglSdlSurface(vid.width, vid.height, (USE_FULLSCREEN))) - if (!OglSdlSurface(vid.width, vid.height, !(USE_FULLSCREEN))) - rendermode = render_soft; - } - else - rendermode = render_soft; - } + I_StartupHardwareGraphics(); + if (rendermode == render_opengl) + I_StartupHardwareGraphics(); #else rendermode = render_soft; //force software mode when there no HWRENDER code #endif @@ -2058,6 +2009,62 @@ void I_StartupGraphics(void) graphics_started = true; } +void I_StartupHardwareGraphics(void) +{ + HWD.pfnInit = hwSym("Init",NULL); + HWD.pfnFinishUpdate = NULL; + HWD.pfnDraw2DLine = hwSym("Draw2DLine",NULL); + HWD.pfnDrawPolygon = hwSym("DrawPolygon",NULL); + HWD.pfnSetBlend = hwSym("SetBlend",NULL); + HWD.pfnClearBuffer = hwSym("ClearBuffer",NULL); + HWD.pfnSetTexture = hwSym("SetTexture",NULL); + HWD.pfnReadRect = hwSym("ReadRect",NULL); + HWD.pfnGClipRect = hwSym("GClipRect",NULL); + HWD.pfnClearMipMapCache = hwSym("ClearMipMapCache",NULL); + HWD.pfnSetSpecialState = hwSym("SetSpecialState",NULL); + HWD.pfnSetPalette = hwSym("SetPalette",NULL); + HWD.pfnGetTextureUsed = hwSym("GetTextureUsed",NULL); + HWD.pfnDrawMD2 = hwSym("DrawMD2",NULL); + HWD.pfnDrawMD2i = hwSym("DrawMD2i",NULL); + HWD.pfnSetTransform = hwSym("SetTransform",NULL); + HWD.pfnGetRenderVersion = hwSym("GetRenderVersion",NULL); +#ifdef SHUFFLE + HWD.pfnPostImgRedraw = hwSym("PostImgRedraw",NULL); +#endif + HWD.pfnFlushScreenTextures=hwSym("FlushScreenTextures",NULL); + HWD.pfnStartScreenWipe = hwSym("StartScreenWipe",NULL); + HWD.pfnEndScreenWipe = hwSym("EndScreenWipe",NULL); + HWD.pfnDoScreenWipe = hwSym("DoScreenWipe",NULL); + HWD.pfnDrawIntermissionBG=hwSym("DrawIntermissionBG",NULL); + HWD.pfnMakeScreenTexture= hwSym("MakeScreenTexture",NULL); + // check gl renderer lib + if (HWD.pfnGetRenderVersion() != VERSION) + I_Error("%s", M_GetText("The version of the renderer doesn't match the version of the executable\nBe sure you have installed SRB2 properly.\n")); +#if 1 //#ifdef _WIN32_WCE + vid.width = BASEVIDWIDTH; + vid.height = BASEVIDHEIGHT; +#else + vid.width = 640; // hack to make voodoo cards work in 640x480 + vid.height = 480; +#endif + if (HWD.pfnInit(I_Error)) // let load the OpenGL library + { + /* + * We want at least 1 bit R, G, and B, + * and at least 16 bpp. Why 1 bit? May be more? + */ + SDL_GL_SetAttribute(SDL_GL_RED_SIZE, 1); + SDL_GL_SetAttribute(SDL_GL_GREEN_SIZE, 1); + SDL_GL_SetAttribute(SDL_GL_BLUE_SIZE, 1); + SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1); + if (!OglSdlSurface(vid.width, vid.height, (USE_FULLSCREEN))) + if (!OglSdlSurface(vid.width, vid.height, !(USE_FULLSCREEN))) + rendermode = render_soft; + } + else + rendermode = render_soft; +} + void I_ShutdownGraphics(void) { const rendermode_t oldrendermode = rendermode; diff --git a/src/win32/win_vid.c b/src/win32/win_vid.c index a6d9cdfc1..54f8e110e 100644 --- a/src/win32/win_vid.c +++ b/src/win32/win_vid.c @@ -239,6 +239,11 @@ void I_StartupGraphics(void) if (!dedicated) graphics_started = true; } +void I_StartupHardwareGraphics(void) +{ + // oh yeah woo yeah oh yeah woo yeah oh yeah woo yeah oh yeah woo yeah oh yeah woo yeah oh yeah woo yeah oh yeah woo y +} + // ------------------ // I_ShutdownGraphics // Close the screen, restore previous video mode. diff --git a/src/win32ce/win_vid.c b/src/win32ce/win_vid.c index b9c2e131f..3b1c3fcfa 100644 --- a/src/win32ce/win_vid.c +++ b/src/win32ce/win_vid.c @@ -127,6 +127,11 @@ void I_StartupGraphics(void) if (!dedicated) graphics_started = true; } +void I_StartupHardwareGraphics(void) +{ + // oh yeah woo yeah oh yeah woo yeah oh yeah woo yeah oh yeah woo yeah oh yeah woo yeah oh yeah woo yeah oh yeah woo y +} + // ------------------ // I_ShutdownGraphics // Close the screen, restore previous video mode. From da93e0f1f55e69c9baa7ff7a4093bd40b2964f88 Mon Sep 17 00:00:00 2001 From: Jaime Passos Date: Mon, 9 Sep 2019 16:20:17 -0300 Subject: [PATCH 06/79] I am the CEO of renderers --- src/console.c | 8 +++---- src/d_main.c | 52 ++++++++++++++++++++++++++++++++++------- src/hardware/hw_cache.c | 15 ------------ src/hu_stuff.c | 3 --- src/m_menu.c | 3 --- src/p_setup.c | 3 --- src/r_main.c | 2 +- src/st_stuff.c | 3 --- src/w_wad.c | 7 ++---- src/y_inter.c | 1 - src/z_zone.c | 24 +++++++++---------- 11 files changed, 61 insertions(+), 60 deletions(-) diff --git a/src/console.c b/src/console.c index 1ac181086..10b569daa 100644 --- a/src/console.c +++ b/src/console.c @@ -1267,7 +1267,7 @@ void CONS_Printf(const char *fmt, ...) con_scrollup = 0; // if not in display loop, force screen update - if (con_startup) + if (con_startup && (!setrenderneeded)) { #if (defined (_WINDOWS)) || (defined (__OS2__) && !defined (HAVE_SDL)) patch_t *con_backpic = W_CachePatchName("CONSBACK", PU_PATCH); @@ -1584,13 +1584,11 @@ void CON_Drawer(void) if (!con_started || !graphics_started) return; - if (needpatchrecache) - R_ReloadHUDGraphics(); - if (con_recalc) { CON_RecalcSize(); - CON_ClearHUD(); + if (con_curlines <= 0) + CON_ClearHUD(); } if (con_curlines > 0) diff --git a/src/d_main.c b/src/d_main.c index c84d6e7a2..4b68f73ba 100644 --- a/src/d_main.c +++ b/src/d_main.c @@ -117,6 +117,8 @@ boolean devparm = false; // started game with -devparm boolean singletics = false; // timedemo boolean lastdraw = false; +static void D_CheckRendererState(void); + postimg_t postimgtype = postimg_none; INT32 postimgparam; postimg_t postimgtype2 = postimg_none; @@ -227,7 +229,7 @@ gamestate_t wipegamestate = GS_LEVEL; static void D_Display(void) { - INT32 setrenderstillneeded = setrenderneeded; + INT32 setrenderstillneeded = 0; boolean forcerefresh = false; static boolean wipe = false; INT32 wipedefindex = 0; @@ -242,9 +244,16 @@ static void D_Display(void) if (setrenderneeded && (moviemode != MM_OFF)) M_StopMovie(); - // check for change of screen size (video mode) - if ((setmodeneeded || setrenderneeded) && !wipe) + // check for change of renderer or screen size (video mode) + if ((setrenderneeded || setmodeneeded) && !wipe) + { + if (setrenderneeded) + { + CONS_Debug(DBG_RENDER, "setrenderneeded set (%d)\n", setrenderneeded); + setrenderstillneeded = setrenderneeded; + } SCR_SetMode(); // change video mode + } if (vid.recalc || setrenderstillneeded) SCR_Recalc(); // NOTE! setsizeneeded is set by SCR_Recalc() @@ -256,6 +265,8 @@ static void D_Display(void) forcerefresh = true; // force background redraw } + D_CheckRendererState(); + // draw buffered stuff to screen // Used only by linux GGI version I_UpdateNoBlit(); @@ -495,16 +506,24 @@ static void D_Display(void) I_FinishUpdate(); // page flip or blit buffer } - // in the occasion no functions - // that require patches to be cached - // have been called. - if (needpatchrecache) - R_ReloadHUDGraphics(); - needpatchflush = false; needpatchrecache = false; } +void D_CheckRendererState(void) +{ + // flush all patches from memory + // (also frees memory tagged with PU_CACHE) + // (which are not necessarily patches but I don't care) + if (needpatchflush) + Z_FlushCachedPatches(); + + // some patches have been freed, + // so cache them again + if (needpatchrecache) + R_ReloadHUDGraphics(); +} + // ========================================================================= // D_SRB2Loop // ========================================================================= @@ -1201,6 +1220,21 @@ void D_SRB2Main(void) // set user default mode or mode set at cmdline SCR_CheckDefaultMode(); + // renderer needs to change? + // ok cool please just change it + // exactly right now please. + if ((setrenderneeded != 0) && (setrenderneeded != rendermode)) + { + needpatchflush = true; + needpatchrecache = true; + VID_CheckRenderer(); + // set cv_renderer back + if (setrenderneeded == render_soft) + CV_StealthSetValue(&cv_renderer, 1); + else if (setrenderneeded == render_opengl) + CV_StealthSetValue(&cv_renderer, 2); + } + D_CheckRendererState(); wipegamestate = gamestate; diff --git a/src/hardware/hw_cache.c b/src/hardware/hw_cache.c index 0716a130f..7e9efd38b 100644 --- a/src/hardware/hw_cache.c +++ b/src/hardware/hw_cache.c @@ -712,9 +712,6 @@ void HWR_GetFlat(lumpnum_t flatlumpnum) { GLMipmap_t *grmip; - if (needpatchflush) - Z_FlushCachedPatches(); - grmip = &HWR_GetCachedGLPatch(flatlumpnum)->mipmap; if (!grmip->downloaded && !grmip->grInfo.data) @@ -751,9 +748,6 @@ static void HWR_LoadMappedPatch(GLMipmap_t *grmip, GLPatch_t *gpatch) // -----------------+ void HWR_GetPatch(GLPatch_t *gpatch) { - if (needpatchflush) - Z_FlushCachedPatches(); - // is it in hardware cache if (!gpatch->mipmap.downloaded && !gpatch->mipmap.grInfo.data) { @@ -781,9 +775,6 @@ void HWR_GetMappedPatch(GLPatch_t *gpatch, const UINT8 *colormap) { GLMipmap_t *grmip, *newmip; - if (needpatchflush) - Z_FlushCachedPatches(); - if (colormap == colormaps || colormap == NULL) { // Load the default (green) color in doom cache (temporary?) AND hardware cache @@ -909,9 +900,6 @@ GLPatch_t *HWR_GetPic(lumpnum_t lumpnum) { GLPatch_t *grpatch; - if (needpatchflush) - Z_FlushCachedPatches(); - grpatch = HWR_GetCachedGLPatch(lumpnum); if (!grpatch->mipmap.downloaded && !grpatch->mipmap.grInfo.data) @@ -1109,9 +1097,6 @@ void HWR_GetFadeMask(lumpnum_t fademasklumpnum) { GLMipmap_t *grmip; - if (needpatchflush) - Z_FlushCachedPatches(); - grmip = &HWR_GetCachedGLPatch(fademasklumpnum)->mipmap; if (!grmip->downloaded && !grmip->grInfo.data) diff --git a/src/hu_stuff.c b/src/hu_stuff.c index 2451f5c4d..a9a2b7504 100644 --- a/src/hu_stuff.c +++ b/src/hu_stuff.c @@ -1993,9 +1993,6 @@ static void HU_DrawDemoInfo(void) // void HU_Drawer(void) { - if (needpatchrecache) - R_ReloadHUDGraphics(); - #ifndef NONET // draw chat string plus cursor if (chat_on) diff --git a/src/m_menu.c b/src/m_menu.c index 9a55ced4b..ba3fb4c2d 100644 --- a/src/m_menu.c +++ b/src/m_menu.c @@ -2481,9 +2481,6 @@ void M_Drawer(void) if (currentMenu == &MessageDef) menuactive = true; - if (needpatchrecache) - R_ReloadHUDGraphics(); - if (menuactive) { // now that's more readable with a faded background (yeah like Quake...) diff --git a/src/p_setup.c b/src/p_setup.c index 82b9eb691..afd5ac06a 100644 --- a/src/p_setup.c +++ b/src/p_setup.c @@ -3098,10 +3098,7 @@ boolean P_SetupLevel(boolean skipprecip) // preload graphics #ifdef HWRENDER // not win32 only 19990829 by Kin if (rendermode == render_opengl) - { HWR_PrepLevelCache(numtextures); - //HWR_FreeColormaps(); - } #endif P_MapEnd(); diff --git a/src/r_main.c b/src/r_main.c index d7196427c..2cca68ff0 100644 --- a/src/r_main.c +++ b/src/r_main.c @@ -1353,7 +1353,7 @@ void R_InitHardwareMode(void) void R_ReloadHUDGraphics(void) { - Z_FlushCachedPatches(); + CONS_Debug(DBG_RENDER, "R_ReloadHUDGraphics()...\n"); ST_LoadGraphics(); HU_LoadGraphics(); ST_ReloadSkinFaceGraphics(); diff --git a/src/st_stuff.c b/src/st_stuff.c index 11bb9875d..287aea134 100644 --- a/src/st_stuff.c +++ b/src/st_stuff.c @@ -1909,9 +1909,6 @@ static void ST_overlayDrawer(void) void ST_Drawer(void) { - if (needpatchrecache) - R_ReloadHUDGraphics(); - #ifdef SEENAMES if (cv_seenames.value && cv_allowseenames.value && displayplayer == consoleplayer && seenplayer && seenplayer->mo) { diff --git a/src/w_wad.c b/src/w_wad.c index 96381635a..2a98ba0a7 100644 --- a/src/w_wad.c +++ b/src/w_wad.c @@ -830,10 +830,10 @@ void W_UnloadWadFile(UINT16 num) lumpcache = delwad->lumpcache; numwadfiles--; #ifdef HWRENDER - if (rendermode != render_soft && rendermode != render_none) + if (rendermode == render_opengl) { - HWR_FreeTextureCache(); HWR_FreeColormaps(); + HWR_FreeTextureCache(); } M_AATreeFree(delwad->hwrcache); #endif @@ -1512,9 +1512,6 @@ static inline void *W_CachePatchNumPwad(UINT16 wad, UINT16 lump, INT32 tag) { GLPatch_t *grPatch; - if (needpatchflush) - Z_FlushCachedPatches(); - if (rendermode == render_soft || rendermode == render_none) return W_CacheLumpNumPwad(wad, lump, tag); diff --git a/src/y_inter.c b/src/y_inter.c index ab27a00fe..080e380d1 100644 --- a/src/y_inter.c +++ b/src/y_inter.c @@ -192,7 +192,6 @@ void Y_IntermissionDrawer(void) if (needpatchrecache) { Y_CleanupData(); - R_ReloadHUDGraphics(); safetorender = false; } diff --git a/src/z_zone.c b/src/z_zone.c index add18b568..a0e34ec35 100644 --- a/src/z_zone.c +++ b/src/z_zone.c @@ -415,20 +415,20 @@ void Z_FreeTags(INT32 lowtag, INT32 hightag) boolean needpatchflush = false; boolean needpatchrecache = false; +// flush all patches from memory +// (also frees memory tagged with PU_CACHE) +// (which are not necessarily patches but I don't care) void Z_FlushCachedPatches(void) { - if (needpatchflush) - { - Z_FreeTag(PU_CACHE); - Z_FreeTag(PU_PATCH); - Z_FreeTag(PU_HUDGFX); - Z_FreeTag(PU_HWRPATCHINFO); - Z_FreeTag(PU_HWRPATCHCOLMIPMAP); - Z_FreeTag(PU_HWRCACHE); - Z_FreeTag(PU_HWRCACHE_UNLOCKED); - Z_FreeTag(PU_HWRPATCHINFO_UNLOCKED); - } - needpatchflush = false; + CONS_Debug(DBG_RENDER, "Z_FlushCachedPatches()...\n"); + Z_FreeTag(PU_CACHE); + Z_FreeTag(PU_PATCH); + Z_FreeTag(PU_HUDGFX); + Z_FreeTag(PU_HWRPATCHINFO); + Z_FreeTag(PU_HWRPATCHCOLMIPMAP); + Z_FreeTag(PU_HWRCACHE); + Z_FreeTag(PU_HWRCACHE_UNLOCKED); + Z_FreeTag(PU_HWRPATCHINFO_UNLOCKED); } // From ebc22b9df80e0e3a52977e3326bb8152e69e738e Mon Sep 17 00:00:00 2001 From: Jaime Passos Date: Mon, 9 Sep 2019 16:31:30 -0300 Subject: [PATCH 07/79] yet even more cleanup here --- src/d_main.c | 6 +----- src/screen.c | 15 ++++++++++----- src/screen.h | 3 +++ 3 files changed, 14 insertions(+), 10 deletions(-) diff --git a/src/d_main.c b/src/d_main.c index 4b68f73ba..34dc5ab65 100644 --- a/src/d_main.c +++ b/src/d_main.c @@ -1228,11 +1228,7 @@ void D_SRB2Main(void) needpatchflush = true; needpatchrecache = true; VID_CheckRenderer(); - // set cv_renderer back - if (setrenderneeded == render_soft) - CV_StealthSetValue(&cv_renderer, 1); - else if (setrenderneeded == render_opengl) - CV_StealthSetValue(&cv_renderer, 2); + SCR_ChangeRendererCVars(setrenderneeded); } D_CheckRendererState(); diff --git a/src/screen.c b/src/screen.c index 7c8bfb14a..26d8c7a9d 100644 --- a/src/screen.c +++ b/src/screen.c @@ -72,7 +72,6 @@ consvar_t cv_scr_depth = {"scr_depth", "16 bits", CV_SAVE, scr_depth_cons_t, NUL #endif consvar_t cv_renderview = {"renderview", "On", 0, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL}; -static void SCR_ChangeRenderer(void); static void SCR_ActuallyChangeRenderer(void); static CV_PossibleValue_t cv_renderer_t[] = {{1, "Software"}, {2, "OpenGL"}, {0, NULL}}; consvar_t cv_renderer = {"renderer", "Software", CV_SAVE|CV_CALL, cv_renderer_t, SCR_ChangeRenderer, 0, NULL, NULL, 0, 0, NULL}; @@ -430,10 +429,7 @@ void SCR_ChangeRenderer(void) else if (M_CheckParm("-software")) target_renderer = rendermode = render_soft; // set cv_renderer back - if (rendermode == render_soft) - CV_StealthSetValue(&cv_renderer, 1); - else if (rendermode == render_opengl) - CV_StealthSetValue(&cv_renderer, 2); + SCR_ChangeRendererCVars(rendermode); return; } @@ -444,6 +440,15 @@ void SCR_ChangeRenderer(void) SCR_ActuallyChangeRenderer(); } +void SCR_ChangeRendererCVars(INT32 mode) +{ + // set cv_renderer back + if (mode == render_soft) + CV_StealthSetValue(&cv_renderer, 1); + else if (mode == render_opengl) + CV_StealthSetValue(&cv_renderer, 2); +} + boolean SCR_IsAspectCorrect(INT32 width, INT32 height) { return diff --git a/src/screen.h b/src/screen.h index df0518421..cc45de3d6 100644 --- a/src/screen.h +++ b/src/screen.h @@ -154,6 +154,9 @@ extern boolean R_SSE2; // ---------------- extern viddef_t vid; extern INT32 setmodeneeded; // mode number to set if needed, or 0 + +void SCR_ChangeRenderer(void); +void SCR_ChangeRendererCVars(INT32 mode); extern INT32 setrenderneeded; extern INT32 scr_bpp; From 26569f494be6240cbbe31d838248adafc2b35650 Mon Sep 17 00:00:00 2001 From: Jaime Passos Date: Mon, 9 Sep 2019 17:24:13 -0300 Subject: [PATCH 08/79] lua stuff --- src/doomdef.h | 3 ++ src/lua_hudlib.c | 87 +++++++++++++++++++++++++++++++++++++++++++++++- src/r_defs.h | 18 ++++++++++ 3 files changed, 107 insertions(+), 1 deletion(-) diff --git a/src/doomdef.h b/src/doomdef.h index 1c034f5f7..593ad0358 100644 --- a/src/doomdef.h +++ b/src/doomdef.h @@ -538,4 +538,7 @@ extern const char *compdate, *comptime, *comprevision, *compbranch; /// SRB2CB itself ported this from PrBoom+ #define NEWCLIP +/// Cache patches in Lua more safely, so that renderer switching can work. +#define LUA_PATCH_SAFETY + #endif // __DOOMDEF__ diff --git a/src/lua_hudlib.c b/src/lua_hudlib.c index ba8b3a6d9..5e104c77a 100644 --- a/src/lua_hudlib.c +++ b/src/lua_hudlib.c @@ -34,6 +34,11 @@ static UINT8 hud_enabled[(hud_MAX/8)+1]; static UINT8 hudAvailable; // hud hooks field +#ifdef LUA_PATCH_SAFETY +static patchinfo_t *patchinfo, *patchinfohead; +static int numluapatches; +#endif + // must match enum hud in lua_hud.h static const char *const hud_disable_options[] = { "stagetitle", @@ -231,12 +236,17 @@ static int colormap_get(lua_State *L) static int patch_get(lua_State *L) { +#ifdef LUA_PATCH_SAFETY patch_t *patch = *((patch_t **)luaL_checkudata(L, 1, META_PATCH)); +#else + patchinfo_t *patch = *((patchinfo_t **)luaL_checkudata(L, 1, META_PATCH)); +#endif enum patch field = luaL_checkoption(L, 2, NULL, patch_opt); // patches are CURRENTLY always valid, expected to be cached with PU_STATIC // this may change in the future, so patch.valid still exists - I_Assert(patch != NULL); + if (!patch) + return LUA_ErrInvalid(L, "patch_t"); switch (field) { @@ -333,8 +343,59 @@ static int libd_patchExists(lua_State *L) static int libd_cachePatch(lua_State *L) { +#ifdef LUA_PATCH_SAFETY + int i; + lumpnum_t lumpnum; + patchinfo_t *luapat; + patch_t *realpatch; + + HUDONLY + + luapat = patchinfohead; + lumpnum = W_CheckNumForName(luaL_checkstring(L, 1)); + if (lumpnum == LUMPERROR) + lumpnum = W_GetNumForName("MISSING"); + + for (i = 0; i < numluapatches; i++) + { + // check if already cached + if (luapat->wadnum == WADFILENUM(lumpnum) && luapat->lumpnum == LUMPNUM(lumpnum)) + { + LUA_PushUserdata(L, luapat, META_PATCH); + return 1; + } + luapat = luapat->next; + if (!luapat) + break; + } + + if (numluapatches > 0) + { + patchinfo->next = Z_Malloc(sizeof(patchinfo_t), PU_STATIC, NULL); + patchinfo = patchinfo->next; + } + else + { + patchinfo = Z_Malloc(sizeof(patchinfo_t), PU_STATIC, NULL); + patchinfohead = patchinfo; + } + + realpatch = W_CachePatchNum(lumpnum, PU_PATCH); + + patchinfo->width = realpatch->width; + patchinfo->height = realpatch->height; + patchinfo->leftoffset = realpatch->leftoffset; + patchinfo->topoffset = realpatch->topoffset; + + patchinfo->wadnum = WADFILENUM(lumpnum); + patchinfo->lumpnum = LUMPNUM(lumpnum); + + LUA_PushUserdata(L, patchinfo, META_PATCH); + numluapatches++; +#else HUDONLY LUA_PushUserdata(L, W_CachePatchName(luaL_checkstring(L, 1), PU_PATCH), META_PATCH); +#endif return 1; } @@ -342,12 +403,22 @@ static int libd_draw(lua_State *L) { INT32 x, y, flags; patch_t *patch; +#ifdef LUA_PATCH_SAFETY + patchinfo_t *luapat; +#endif const UINT8 *colormap = NULL; HUDONLY x = luaL_checkinteger(L, 1); y = luaL_checkinteger(L, 2); +#ifdef LUA_PATCH_SAFETY + luapat = *((patchinfo_t **)luaL_checkudata(L, 3, META_PATCH)); + patch = W_CachePatchNum((luapat->wadnum<<16)+luapat->lumpnum, PU_PATCH); +#else patch = *((patch_t **)luaL_checkudata(L, 3, META_PATCH)); + if (!patch) + return LUA_ErrInvalid(L, "patch_t"); +#endif flags = luaL_optinteger(L, 4, 0); if (!lua_isnoneornil(L, 5)) colormap = *((UINT8 **)luaL_checkudata(L, 5, META_COLORMAP)); @@ -363,6 +434,9 @@ static int libd_drawScaled(lua_State *L) fixed_t x, y, scale; INT32 flags; patch_t *patch; +#ifdef LUA_PATCH_SAFETY + patchinfo_t *luapat; +#endif const UINT8 *colormap = NULL; HUDONLY @@ -371,7 +445,14 @@ static int libd_drawScaled(lua_State *L) scale = luaL_checkinteger(L, 3); if (scale < 0) return luaL_error(L, "negative scale"); +#ifdef LUA_PATCH_SAFETY + luapat = *((patchinfo_t **)luaL_checkudata(L, 4, META_PATCH)); + patch = W_CachePatchNum((luapat->wadnum<<16)+luapat->lumpnum, PU_PATCH); +#else patch = *((patch_t **)luaL_checkudata(L, 4, META_PATCH)); + if (!patch) + return LUA_ErrInvalid(L, "patch_t"); +#endif flags = luaL_optinteger(L, 5, 0); if (!lua_isnoneornil(L, 6)) colormap = *((UINT8 **)luaL_checkudata(L, 6, META_COLORMAP)); @@ -659,6 +740,10 @@ int LUA_HudLib(lua_State *L) { memset(hud_enabled, 0xff, (hud_MAX/8)+1); +#ifdef LUA_PATCH_SAFETY + numluapatches = 0; +#endif + lua_newtable(L); // HUD registry table lua_newtable(L); luaL_register(L, NULL, lib_draw); diff --git a/src/r_defs.h b/src/r_defs.h index 1cb4e0815..c09635bd5 100644 --- a/src/r_defs.h +++ b/src/r_defs.h @@ -726,6 +726,24 @@ typedef struct #pragma pack() #endif +// Same as a patch_t, except just the header +// and the wadnum/lumpnum combination that points +// to wherever the patch is in memory. +struct patchinfo_s +{ + INT16 width; // bounding box size + INT16 height; + INT16 leftoffset; // pixels to the left of origin + INT16 topoffset; // pixels below the origin + + UINT16 wadnum; // the software patch lump num for when the patch + UINT16 lumpnum; // was flushed, and we need to re-create it + + // next patchinfo_t in memory + struct patchinfo_s *next; +}; +typedef struct patchinfo_s patchinfo_t; + // // Sprites are patches with a special naming convention so they can be // recognized by R_InitSprites. From 02e327a4e463f202ed83afa30bab14d93dbfead5 Mon Sep 17 00:00:00 2001 From: Jaime Passos Date: Mon, 9 Sep 2019 17:35:38 -0300 Subject: [PATCH 09/79] D_SRB2Loop: Draw CONSBACK even in OpenGL --- src/d_main.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/d_main.c b/src/d_main.c index 34dc5ab65..4c9f78c02 100644 --- a/src/d_main.c +++ b/src/d_main.c @@ -571,8 +571,7 @@ void D_SRB2Loop(void) // hack to start on a nice clear console screen. COM_ImmedExecute("cls;version"); - if (rendermode == render_soft) - V_DrawScaledPatch(0, 0, 0, (patch_t *)W_CacheLumpNum(W_GetNumForName("CONSBACK"), PU_CACHE)); + V_DrawScaledPatch(0, 0, 0, W_CachePatchNum(W_GetNumForName("CONSBACK"), PU_CACHE)); I_FinishUpdate(); // page flip or blit buffer for (;;) From 6f4dadaa128f8190ab0ba8c17cdc5af5c451c0b6 Mon Sep 17 00:00:00 2001 From: Jaime Passos Date: Mon, 9 Sep 2019 17:53:34 -0300 Subject: [PATCH 10/79] menu changes --- src/m_menu.c | 16 +++++++++++++--- 1 file changed, 13 insertions(+), 3 deletions(-) diff --git a/src/m_menu.c b/src/m_menu.c index ba3fb4c2d..74d685fd5 100644 --- a/src/m_menu.c +++ b/src/m_menu.c @@ -257,6 +257,7 @@ static void M_ChangeControl(INT32 choice); // Video & Sound menu_t OP_VideoOptionsDef, OP_VideoModeDef; #ifdef HWRENDER +static void M_OpenGLOptionsMenu(void); menu_t OP_OpenGLOptionsDef, OP_OpenGLFogDef, OP_OpenGLColorDef; #endif menu_t OP_SoundOptionsDef; @@ -1100,10 +1101,7 @@ static menuitem_t OP_VideoOptionsMenu[] = { {IT_STRING | IT_CALL, NULL, "Video Modes...", M_VideoModeMenu, 10}, -#ifdef HWRENDER {IT_STRING|IT_CVAR, NULL, "Renderer", &cv_renderer, 20}, - //{IT_SUBMENU|IT_STRING, NULL, "3D Card Options...", &OP_OpenGLOptionsDef, 20}, -#endif #if (defined (__unix__) && !defined (MSDOS)) || defined (UNIXCOMMON) || defined (HAVE_SDL) {IT_STRING|IT_CVAR, NULL, "Fullscreen", &cv_fullscreen, 30}, @@ -1119,6 +1117,10 @@ static menuitem_t OP_VideoOptionsMenu[] = {IT_STRING | IT_CVAR, NULL, "Show FPS", &cv_ticrate, 110}, {IT_STRING | IT_CVAR, NULL, "Clear Before Redraw", &cv_homremoval, 120}, {IT_STRING | IT_CVAR, NULL, "Vertical Sync", &cv_vidwait, 130}, + +#ifdef HWRENDER + {IT_STRING | IT_CALL, NULL, "3D Card Options...", M_OpenGLOptionsMenu, 150}, +#endif }; static menuitem_t OP_VideoModeMenu[] = @@ -1712,6 +1714,14 @@ menu_t OP_MonitorToggleDef = }; #ifdef HWRENDER +static void M_OpenGLOptionsMenu(void) +{ + if (rendermode == render_opengl) + M_SetupNextMenu(&OP_OpenGLOptionsDef); + else + M_StartMessage(M_GetText("You must be in OpenGL mode\nto access this menu.\n\n(Press a key)\n"), NULL, MM_NOTHING); +} + menu_t OP_OpenGLOptionsDef = DEFAULTMENUSTYLE("M_VIDEO", OP_OpenGLOptionsMenu, &OP_VideoOptionsDef, 30, 30); #ifdef ALAM_LIGHTING menu_t OP_OpenGLLightingDef = DEFAULTMENUSTYLE("M_VIDEO", OP_OpenGLLightingMenu, &OP_OpenGLOptionsDef, 60, 40); From 0a973af5b8c1df0ab577e77198056ca9ba2296bf Mon Sep 17 00:00:00 2001 From: Jaime Passos Date: Mon, 9 Sep 2019 19:27:08 -0300 Subject: [PATCH 11/79] Comments --- src/d_main.c | 24 +++++++++++++++++++++--- src/f_finale.c | 1 + src/hardware/hw_cache.c | 1 + src/m_menu.c | 1 + src/p_setup.c | 6 +++--- src/r_main.c | 1 + src/screen.c | 2 ++ src/y_inter.c | 1 + 8 files changed, 31 insertions(+), 6 deletions(-) diff --git a/src/d_main.c b/src/d_main.c index 4c9f78c02..f42fc535e 100644 --- a/src/d_main.c +++ b/src/d_main.c @@ -240,6 +240,22 @@ static void D_Display(void) if (nodrawers) return; // for comparative timing/profiling + // Jimita: Switching renderers works by checking + // if the game has to do it right when the frame + // needs to render. If so, five things will happen: + // 1. Interface functions will be called so + // that switching to OpenGL creates a + // GL context, and switching to Software + // allocates screen buffers. + // 2. Software will set drawer functions, + // and OpenGL will load textures and + // create plane polygons, if necessary. + // 3. Functions related to switching video + // modes (resolution) are called. + // 4. Patch data is freed from memory, + // and recached if necessary. + // 5. The frame is ready to be drawn! + // stop movie if needs to change renderer if (setrenderneeded && (moviemode != MM_OFF)) M_StopMovie(); @@ -265,6 +281,7 @@ static void D_Display(void) forcerefresh = true; // force background redraw } + // Jimita D_CheckRendererState(); // draw buffered stuff to screen @@ -510,6 +527,8 @@ static void D_Display(void) needpatchrecache = false; } +// Jimita: Check the renderer's state +// after a possible renderer switch. void D_CheckRendererState(void) { // flush all patches from memory @@ -1219,9 +1238,8 @@ void D_SRB2Main(void) // set user default mode or mode set at cmdline SCR_CheckDefaultMode(); - // renderer needs to change? - // ok cool please just change it - // exactly right now please. + + // Jimita: Does the render mode need to change? if ((setrenderneeded != 0) && (setrenderneeded != rendermode)) { needpatchflush = true; diff --git a/src/f_finale.c b/src/f_finale.c index b97a6206e..637d4bd29 100644 --- a/src/f_finale.c +++ b/src/f_finale.c @@ -1495,6 +1495,7 @@ void F_TitleScreenDrawer(void) if (modeattacking) return; // We likely came here from retrying. Don't do a damn thing. + // Jimita: Load title screen patches. if (needpatchrecache) F_CacheTitleScreen(); diff --git a/src/hardware/hw_cache.c b/src/hardware/hw_cache.c index 7e9efd38b..a5e6d0eca 100644 --- a/src/hardware/hw_cache.c +++ b/src/hardware/hw_cache.c @@ -644,6 +644,7 @@ GLTexture_t *HWR_GetTexture(INT32 tex) if ((unsigned)tex >= gr_numtextures) I_Error("HWR_GetTexture: tex >= numtextures\n"); #endif + // Jimita if (needpatchrecache && (!gr_textures)) HWR_PrepLevelCache(gr_numtextures); diff --git a/src/m_menu.c b/src/m_menu.c index 74d685fd5..9bd8c0a7f 100644 --- a/src/m_menu.c +++ b/src/m_menu.c @@ -4135,6 +4135,7 @@ static void M_DrawAddons(void) return; } + // Jimita: Load addons menu patches. if (needpatchrecache) M_LoadAddonsPatches(); diff --git a/src/p_setup.c b/src/p_setup.c index afd5ac06a..7e600d66f 100644 --- a/src/p_setup.c +++ b/src/p_setup.c @@ -2943,8 +2943,8 @@ boolean P_SetupLevel(boolean skipprecip) globalweather = mapheaderinfo[gamemap-1]->weather; #ifdef HWRENDER // not win32 only 19990829 by Kin - // gotta free this regardless of rendermode. - // maybe we're not in opengl anymore....... + // Jimita: Free extrasubsectors regardless of renderer. + // Maybe we're not in OpenGL anymore. if (extrasubsectors) free(extrasubsectors); extrasubsectors = NULL; @@ -3162,7 +3162,7 @@ void HWR_SetupLevel(void) #endif // Correct missing sidedefs & deep water trick HWR_CorrectSWTricks(); - // don't do it twice... + // Jimita: Don't call this more than once! if (!extrasubsectors) HWR_CreatePlanePolygons((INT32)numnodes - 1); } diff --git a/src/r_main.c b/src/r_main.c index 2cca68ff0..766c548a2 100644 --- a/src/r_main.c +++ b/src/r_main.c @@ -1339,6 +1339,7 @@ void R_RenderPlayerView(player_t *player) skyVisible1 = skyVisible; } +// Jimita #ifdef HWRENDER void R_InitHardwareMode(void) { diff --git a/src/screen.c b/src/screen.c index 26d8c7a9d..c14beb6eb 100644 --- a/src/screen.c +++ b/src/screen.c @@ -172,6 +172,7 @@ void SCR_SetMode(void) if (!(setmodeneeded || setrenderneeded) || WipeInAction) return; // should never happen and don't change it during a wipe, BAD! + // Jimita if (setrenderneeded) { needpatchflush = true; @@ -417,6 +418,7 @@ void SCR_ActuallyChangeRenderer(void) setrenderneeded = 0; } +// Jimita void SCR_ChangeRenderer(void) { setrenderneeded = 0; diff --git a/src/y_inter.c b/src/y_inter.c index 080e380d1..d55046fff 100644 --- a/src/y_inter.c +++ b/src/y_inter.c @@ -189,6 +189,7 @@ void Y_IntermissionDrawer(void) if (intertype == int_none || rendermode == render_none) return; + // Jimita if (needpatchrecache) { Y_CleanupData(); From 1a9191dcd74b45a03c99d4100ae125d9e52b50b7 Mon Sep 17 00:00:00 2001 From: Jaime Passos Date: Mon, 9 Sep 2019 19:34:51 -0300 Subject: [PATCH 12/79] Attempt to fix warnings --- src/screen.c | 2 +- src/screen.h | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/screen.c b/src/screen.c index c14beb6eb..6f77631c2 100644 --- a/src/screen.c +++ b/src/screen.c @@ -56,7 +56,7 @@ void (*twosmultipatchtransfunc)(void); // for cols with transparent pixels AND t // ------------------ viddef_t vid; INT32 setmodeneeded; //video mode change needed if > 0 (the mode number to set + 1) -INT32 setrenderneeded = 0; +UINT8 setrenderneeded = 0; static CV_PossibleValue_t scr_depth_cons_t[] = {{8, "8 bits"}, {16, "16 bits"}, {24, "24 bits"}, {32, "32 bits"}, {0, NULL}}; diff --git a/src/screen.h b/src/screen.h index cc45de3d6..8792f7912 100644 --- a/src/screen.h +++ b/src/screen.h @@ -157,7 +157,7 @@ extern INT32 setmodeneeded; // mode number to set if needed, or 0 void SCR_ChangeRenderer(void); void SCR_ChangeRendererCVars(INT32 mode); -extern INT32 setrenderneeded; +extern UINT8 setrenderneeded; extern INT32 scr_bpp; extern UINT8 *scr_borderpatch; // patch used to fill the view borders From 6ab20060a7e356fe2cd614d4251eba85a849ceaf Mon Sep 17 00:00:00 2001 From: Jaime Passos Date: Tue, 10 Sep 2019 16:59:37 -0300 Subject: [PATCH 13/79] Disable LUA_PATCH_SAFETY because I trust Lua scripters enough haha........ha................. --- src/doomdef.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/doomdef.h b/src/doomdef.h index 593ad0358..0fb5d3b03 100644 --- a/src/doomdef.h +++ b/src/doomdef.h @@ -538,7 +538,7 @@ extern const char *compdate, *comptime, *comprevision, *compbranch; /// SRB2CB itself ported this from PrBoom+ #define NEWCLIP -/// Cache patches in Lua more safely, so that renderer switching can work. -#define LUA_PATCH_SAFETY +/// Cache patches in Lua in a way that renderer switching will work flawlessly. +//#define LUA_PATCH_SAFETY #endif // __DOOMDEF__ From f0019f2b2acc057f0af29ff63aa69de65ad95124 Mon Sep 17 00:00:00 2001 From: Jaime Passos Date: Tue, 10 Sep 2019 18:17:02 -0300 Subject: [PATCH 14/79] Oops. --- src/z_zone.c | 12 ------------ 1 file changed, 12 deletions(-) diff --git a/src/z_zone.c b/src/z_zone.c index e0ed1b296..ce38947cb 100644 --- a/src/z_zone.c +++ b/src/z_zone.c @@ -510,18 +510,6 @@ void Z_FlushCachedPatches(void) Z_FreeTag(PU_HWRPATCHINFO_UNLOCKED); } -// -// Z_CheckMemCleanup -// -// TODO: Currently blocks >= PU_PURGELEVEL are freed every -// CLEANUPCOUNT. It might be better to keep track of -// the total size of all purgable memory and free it when the -// size exceeds some value. -// -// This was in Z_Malloc, but was freeing data at -// unsafe times. Now it is only called when it is safe -// to cleanup memory. - // starting value of nextcleanup #define CLEANUPCOUNT 2000 From 347f9cda8b375f1019ec62f51d0dd9948f79a3a7 Mon Sep 17 00:00:00 2001 From: Jaime Passos Date: Tue, 10 Sep 2019 18:33:06 -0300 Subject: [PATCH 15/79] Fix title screen crash --- src/r_main.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/r_main.c b/src/r_main.c index d1952994c..63641a25a 100644 --- a/src/r_main.c +++ b/src/r_main.c @@ -1155,7 +1155,7 @@ void R_RenderPlayerView(player_t *player) void R_InitHardwareMode(void) { HWR_AddCommands(); - if (gamestate == GS_LEVEL) + if (gamestate == GS_LEVEL || gamestate == GS_TITLESCREEN) { HWR_SetupLevel(); HWR_PrepLevelCache(numtextures); From 00f5cbb1856eb355933c186b55955c8cd8dd9bd4 Mon Sep 17 00:00:00 2001 From: Jaime Passos Date: Tue, 10 Sep 2019 18:34:29 -0300 Subject: [PATCH 16/79] Fix titlemap* crash --- src/r_main.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/r_main.c b/src/r_main.c index 63641a25a..a7592b554 100644 --- a/src/r_main.c +++ b/src/r_main.c @@ -1155,7 +1155,7 @@ void R_RenderPlayerView(player_t *player) void R_InitHardwareMode(void) { HWR_AddCommands(); - if (gamestate == GS_LEVEL || gamestate == GS_TITLESCREEN) + if (gamestate == GS_LEVEL || (gamestate == GS_TITLESCREEN && titlemapinaction)) { HWR_SetupLevel(); HWR_PrepLevelCache(numtextures); From 362be6f9da4fa31221a921c597059afb97308384 Mon Sep 17 00:00:00 2001 From: Jaime Passos Date: Tue, 12 Nov 2019 21:44:43 -0300 Subject: [PATCH 17/79] Make cv_renderer a hidden command Finally! Renderer switching IS SAVED!! :tada: :tada: :tada: :tada: :tada: :tada: --- src/screen.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/screen.c b/src/screen.c index dc25b2acf..6f6ebfbd6 100644 --- a/src/screen.c +++ b/src/screen.c @@ -73,7 +73,7 @@ consvar_t cv_renderview = {"renderview", "On", 0, CV_OnOff, NULL, 0, NULL, NULL, static void SCR_ActuallyChangeRenderer(void); static CV_PossibleValue_t cv_renderer_t[] = {{1, "Software"}, {2, "OpenGL"}, {0, NULL}}; -consvar_t cv_renderer = {"renderer", "Software", CV_SAVE|CV_CALL, cv_renderer_t, SCR_ChangeRenderer, 0, NULL, NULL, 0, 0, NULL}; +consvar_t cv_renderer = {"renderer", "Software", CV_HIDEN|CV_CALL, cv_renderer_t, SCR_ChangeRenderer, 0, NULL, NULL, 0, 0, NULL}; static void SCR_ChangeFullscreen(void); From 90d385b402ac10d4602fba2e051b568b224630eb Mon Sep 17 00:00:00 2001 From: Jaime Passos Date: Tue, 12 Nov 2019 22:03:40 -0300 Subject: [PATCH 18/79] fix crash --- src/f_finale.c | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/src/f_finale.c b/src/f_finale.c index aa3b96754..7d2631a79 100644 --- a/src/f_finale.c +++ b/src/f_finale.c @@ -2597,7 +2597,7 @@ void F_TitleScreenDrawer(void) if (modeattacking) return; // We likely came here from retrying. Don't do a damn thing. - if (needpatchrecache) + if (needpatchrecache && (curttmode != TTMODE_ALACROIX)) F_CacheTitleScreen(); // Draw that sky! @@ -2621,6 +2621,12 @@ void F_TitleScreenDrawer(void) return; #endif + if (needpatchrecache && (curttmode == TTMODE_ALACROIX)) + { + ttloaded[0] = ttloaded[1] = ttloaded[2] = ttloaded[3] = ttloaded[4] = ttloaded[5] = 0; + F_LoadAlacroixGraphics(activettscale); + } + switch(curttmode) { case TTMODE_OLD: From f531a8971f8f8b266b167a3db0c25cdeb9f33f8d Mon Sep 17 00:00:00 2001 From: Jaime Passos Date: Tue, 10 Dec 2019 23:40:15 -0300 Subject: [PATCH 19/79] Update m_menu.c --- src/m_menu.c | 31 ++++++++++++------------------- 1 file changed, 12 insertions(+), 19 deletions(-) diff --git a/src/m_menu.c b/src/m_menu.c index 3d202e4d1..d5fc5f357 100644 --- a/src/m_menu.c +++ b/src/m_menu.c @@ -7675,6 +7675,18 @@ static void M_DrawLoadGameData(void) INT32 i, savetodraw, x, y, hsep = 90; skin_t *charskin = NULL; + // Lactozilla: Intentional, because there is + // no way to know if those patches were ever + // flushed from memory, other than pointers + // to nowhere. + savselp[0] = W_CachePatchName("SAVEBACK", PU_PATCH); + savselp[1] = W_CachePatchName("SAVENONE", PU_PATCH); + savselp[2] = W_CachePatchName("ULTIMATE", PU_PATCH); + + savselp[3] = W_CachePatchName("GAMEDONE", PU_PATCH); + savselp[4] = W_CachePatchName("BLACXLVL", PU_PATCH); + savselp[5] = W_CachePatchName("BLANKLVL", PU_PATCH); + if (vid.width != BASEVIDWIDTH*vid.dupx) hsep = (hsep*vid.width)/(BASEVIDWIDTH*vid.dupx); @@ -8153,25 +8165,6 @@ static void M_ReadSaveStrings(void) } M_ReadSavegameInfo(i); } - - if (savselp[0]) // never going to have some provided but not all, saves individually checking - { - W_UnlockCachedPatch(savselp[0]); - W_UnlockCachedPatch(savselp[1]); - W_UnlockCachedPatch(savselp[2]); - - W_UnlockCachedPatch(savselp[3]); - W_UnlockCachedPatch(savselp[4]); - W_UnlockCachedPatch(savselp[5]); - } - - savselp[0] = W_CachePatchName("SAVEBACK", PU_PATCH); - savselp[1] = W_CachePatchName("SAVENONE", PU_PATCH); - savselp[2] = W_CachePatchName("ULTIMATE", PU_PATCH); - - savselp[3] = W_CachePatchName("GAMEDONE", PU_PATCH); - savselp[4] = W_CachePatchName("BLACXLVL", PU_PATCH); - savselp[5] = W_CachePatchName("BLANKLVL", PU_PATCH); } // From 3ca0fbf5c30fa871f647bcdc98be118d842e81f3 Mon Sep 17 00:00:00 2001 From: Jaime Passos Date: Thu, 12 Dec 2019 01:29:59 -0300 Subject: [PATCH 20/79] da ba dee da ba die --- src/m_menu.c | 16 ---------------- 1 file changed, 16 deletions(-) diff --git a/src/m_menu.c b/src/m_menu.c index d5fc5f357..9ddaf27d7 100644 --- a/src/m_menu.c +++ b/src/m_menu.c @@ -3675,12 +3675,6 @@ void M_Init(void) quitmsg[QUIT3MSG5] = M_GetText("You'll be back to play soon, though...\n......right?\n\n(Press 'Y' to quit)"); quitmsg[QUIT3MSG6] = M_GetText("Aww, is Egg Rock Zone too\ndifficult for you?\n\n(Press 'Y' to quit)"); -#ifdef HWRENDER - // Permanently hide some options based on render mode - if (rendermode == render_opengl) - OP_ScreenshotOptionsMenu[op_screenshot_colorprofile].status = IT_GRAYEDOUT; -#endif - /* Well the menu sucks for forcing us to have an item set at all if every item just calls the same function, and @@ -11807,17 +11801,7 @@ static void M_HandleVideoMode(INT32 ch) static void M_DrawScreenshotMenu(void) { - M_DrawGenericScrollMenu(); -#ifdef HWRENDER - if ((rendermode == render_opengl) && (itemOn < 7)) // where it starts to go offscreen; change this number if you change the layout of the screenshot menu - { - INT32 y = currentMenu->y+currentMenu->menuitems[op_screenshot_colorprofile].alphaKey*2; - if (itemOn == 6) - y -= 10; - V_DrawRightAlignedString(BASEVIDWIDTH - currentMenu->x, y, V_REDMAP, "ON"); - } -#endif } // =============== From a0971d0756e1edd08a46695e8cf1c1bfee687fe7 Mon Sep 17 00:00:00 2001 From: Jaime Passos Date: Tue, 17 Dec 2019 15:56:56 -0300 Subject: [PATCH 21/79] Put loadgame patch loading back in M_ReadSaveStrings --- src/m_menu.c | 20 ++++++++------------ 1 file changed, 8 insertions(+), 12 deletions(-) diff --git a/src/m_menu.c b/src/m_menu.c index 9ddaf27d7..6107a3f8f 100644 --- a/src/m_menu.c +++ b/src/m_menu.c @@ -7669,18 +7669,6 @@ static void M_DrawLoadGameData(void) INT32 i, savetodraw, x, y, hsep = 90; skin_t *charskin = NULL; - // Lactozilla: Intentional, because there is - // no way to know if those patches were ever - // flushed from memory, other than pointers - // to nowhere. - savselp[0] = W_CachePatchName("SAVEBACK", PU_PATCH); - savselp[1] = W_CachePatchName("SAVENONE", PU_PATCH); - savselp[2] = W_CachePatchName("ULTIMATE", PU_PATCH); - - savselp[3] = W_CachePatchName("GAMEDONE", PU_PATCH); - savselp[4] = W_CachePatchName("BLACXLVL", PU_PATCH); - savselp[5] = W_CachePatchName("BLANKLVL", PU_PATCH); - if (vid.width != BASEVIDWIDTH*vid.dupx) hsep = (hsep*vid.width)/(BASEVIDWIDTH*vid.dupx); @@ -8159,6 +8147,14 @@ static void M_ReadSaveStrings(void) } M_ReadSavegameInfo(i); } + + savselp[0] = W_CachePatchName("SAVEBACK", PU_PATCH); + savselp[1] = W_CachePatchName("SAVENONE", PU_PATCH); + savselp[2] = W_CachePatchName("ULTIMATE", PU_PATCH); + + savselp[3] = W_CachePatchName("GAMEDONE", PU_PATCH); + savselp[4] = W_CachePatchName("BLACXLVL", PU_PATCH); + savselp[5] = W_CachePatchName("BLANKLVL", PU_PATCH); } // From e359f802fd7370d5462a594b6f4b60675a58503c Mon Sep 17 00:00:00 2001 From: Jaime Passos Date: Tue, 17 Dec 2019 16:14:26 -0300 Subject: [PATCH 22/79] Update comments --- src/d_main.c | 8 ++++---- src/hardware/hw_cache.c | 2 +- src/m_menu.c | 2 +- src/p_setup.c | 2 +- src/r_main.c | 2 +- src/screen.c | 4 ++-- src/y_inter.c | 2 +- 7 files changed, 11 insertions(+), 11 deletions(-) diff --git a/src/d_main.c b/src/d_main.c index 45cac3cf7..9d420dd22 100644 --- a/src/d_main.c +++ b/src/d_main.c @@ -225,7 +225,7 @@ static void D_Display(void) if (nodrawers) return; // for comparative timing/profiling - // Jimita: Switching renderers works by checking + // Lactozilla: Switching renderers works by checking // if the game has to do it right when the frame // needs to render. If so, five things will happen: // 1. Interface functions will be called so @@ -273,7 +273,7 @@ static void D_Display(void) forcerefresh = true; // force background redraw } - // Jimita + // Lactozilla: Renderer switching D_CheckRendererState(); // draw buffered stuff to screen @@ -583,7 +583,7 @@ static void D_Display(void) needpatchrecache = false; } -// Jimita: Check the renderer's state +// Lactozilla: Check the renderer's state // after a possible renderer switch. void D_CheckRendererState(void) { @@ -1281,7 +1281,7 @@ void D_SRB2Main(void) // set user default mode or mode set at cmdline SCR_CheckDefaultMode(); - // Jimita: Does the render mode need to change? + // Lactozilla: Does the render mode need to change? if ((setrenderneeded != 0) && (setrenderneeded != rendermode)) { needpatchflush = true; diff --git a/src/hardware/hw_cache.c b/src/hardware/hw_cache.c index e7a4637c9..2c7539f2c 100644 --- a/src/hardware/hw_cache.c +++ b/src/hardware/hw_cache.c @@ -884,7 +884,7 @@ GLTexture_t *HWR_GetTexture(INT32 tex) I_Error("HWR_GetTexture: tex >= numtextures\n"); #endif - // Jimita + // Lactozilla: Renderer switching if (needpatchrecache && (!gr_textures)) HWR_LoadTextures(gr_numtextures); diff --git a/src/m_menu.c b/src/m_menu.c index 4cac6dada..e108c421c 100644 --- a/src/m_menu.c +++ b/src/m_menu.c @@ -6022,7 +6022,7 @@ static void M_DrawAddons(void) return; } - // Jimita: Load addons menu patches. + // Lactozilla: Load addons menu patches. if (needpatchrecache) M_LoadAddonsPatches(); diff --git a/src/p_setup.c b/src/p_setup.c index dd9a6d5fe..42a6438a0 100644 --- a/src/p_setup.c +++ b/src/p_setup.c @@ -3019,7 +3019,7 @@ boolean P_SetupLevel(boolean skipprecip) P_SpawnPrecipitation(); #ifdef HWRENDER // not win32 only 19990829 by Kin - // Jimita: Free extrasubsectors regardless of renderer. + // Lactozilla: Free extrasubsectors regardless of renderer. // Maybe we're not in OpenGL anymore. if (extrasubsectors) free(extrasubsectors); diff --git a/src/r_main.c b/src/r_main.c index 06556e342..713480397 100644 --- a/src/r_main.c +++ b/src/r_main.c @@ -1156,7 +1156,7 @@ void R_RenderPlayerView(player_t *player) free(masks); } -// Jimita +// Lactozilla: Renderer switching #ifdef HWRENDER void R_InitHardwareMode(void) { diff --git a/src/screen.c b/src/screen.c index 56cdfba3c..f739a5177 100644 --- a/src/screen.c +++ b/src/screen.c @@ -197,7 +197,7 @@ void SCR_SetMode(void) if (!(setmodeneeded || setrenderneeded) || WipeInAction) return; // should never happen and don't change it during a wipe, BAD! - // Jimita + // Lactozilla: Renderer switching if (setrenderneeded) { needpatchflush = true; @@ -443,7 +443,7 @@ void SCR_ActuallyChangeRenderer(void) setrenderneeded = 0; } -// Jimita +// Lactozilla: Renderer switching void SCR_ChangeRenderer(void) { setrenderneeded = 0; diff --git a/src/y_inter.c b/src/y_inter.c index 51d267bd4..5123f2f97 100644 --- a/src/y_inter.c +++ b/src/y_inter.c @@ -323,7 +323,7 @@ void Y_IntermissionDrawer(void) if (intertype == int_none || rendermode == render_none) return; - // Jimita + // Lactozilla: Renderer switching if (needpatchrecache) { Y_CleanupData(); From 53885e5ac0c30cbd9dd8a704b297eaebfb747ec4 Mon Sep 17 00:00:00 2001 From: Jaime Passos Date: Tue, 17 Dec 2019 16:28:32 -0300 Subject: [PATCH 23/79] Free PU_HWRMODELTEXTURE tag --- src/w_wad.c | 2 +- src/z_zone.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/w_wad.c b/src/w_wad.c index 1d4b160a7..f889d2659 100644 --- a/src/w_wad.c +++ b/src/w_wad.c @@ -1512,7 +1512,7 @@ void W_FlushCachedPatches(void) Z_FreeTag(PU_PATCH); Z_FreeTag(PU_HUDGFX); Z_FreeTag(PU_HWRPATCHINFO); - Z_FreeTag(PU_HWRPATCHCOLMIPMAP); + Z_FreeTag(PU_HWRMODELTEXTURE); Z_FreeTag(PU_HWRCACHE); Z_FreeTags(PU_HWRCACHE_UNLOCKED, PU_HWRPATCHINFO_UNLOCKED); } diff --git a/src/z_zone.c b/src/z_zone.c index c1056b163..e0c56ced6 100644 --- a/src/z_zone.c +++ b/src/z_zone.c @@ -511,7 +511,7 @@ void Z_FlushCachedPatches(void) Z_FreeTag(PU_PATCH); Z_FreeTag(PU_HUDGFX); Z_FreeTag(PU_HWRPATCHINFO); - Z_FreeTag(PU_HWRPATCHCOLMIPMAP); + Z_FreeTag(PU_HWRMODELTEXTURE); Z_FreeTag(PU_HWRCACHE); Z_FreeTag(PU_HWRCACHE_UNLOCKED); Z_FreeTag(PU_HWRPATCHINFO_UNLOCKED); From 79daafd893d776d9b0b56ac31fd2ce3c0fc22626 Mon Sep 17 00:00:00 2001 From: Jaime Passos Date: Tue, 17 Dec 2019 18:04:05 -0300 Subject: [PATCH 24/79] Fix missing "-" prefix on "-software" cmdline parm --- src/sdl/i_video.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/sdl/i_video.c b/src/sdl/i_video.c index d63aa8ad1..376d865db 100644 --- a/src/sdl/i_video.c +++ b/src/sdl/i_video.c @@ -1645,7 +1645,7 @@ void I_StartupGraphics(void) #ifdef HWRENDER if (M_CheckParm("-opengl")) rendermode = render_opengl; - else if (M_CheckParm("software")) + else if (M_CheckParm("-software")) #endif rendermode = render_soft; From 77747c66df62e4c110c899f3b8be252a0c0db0aa Mon Sep 17 00:00:00 2001 From: James R Date: Tue, 1 Oct 2019 23:52:08 -0700 Subject: [PATCH 25/79] Fix switching to software Would show a black screen for me on Linux. My suspsicion is that some things are not initialized with just VID_CheckRenderer. --- src/screen.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/screen.c b/src/screen.c index f739a5177..b21b6815a 100644 --- a/src/screen.c +++ b/src/screen.c @@ -203,6 +203,8 @@ void SCR_SetMode(void) needpatchflush = true; needpatchrecache = true; VID_CheckRenderer(); + if (!setmodeneeded) + VID_SetMode(vid.modenum); } if (setmodeneeded) From 4e349cbd0f527a3c2d7247d4517a12ab8fcfa3ad Mon Sep 17 00:00:00 2001 From: Jaime Passos Date: Thu, 19 Dec 2019 17:14:56 -0300 Subject: [PATCH 26/79] Remove W_UnlockCachedPatch calls to avoid crashing --- src/m_menu.c | 22 ---------------------- 1 file changed, 22 deletions(-) diff --git a/src/m_menu.c b/src/m_menu.c index e108c421c..d9caf28cb 100644 --- a/src/m_menu.c +++ b/src/m_menu.c @@ -4929,17 +4929,6 @@ static boolean M_PrepareLevelPlatter(INT32 gt, boolean nextmappick) } #endif - if (levselp[0][0]) // never going to have some provided but not all, saves individually checking - { - W_UnlockCachedPatch(levselp[0][0]); - W_UnlockCachedPatch(levselp[0][1]); - W_UnlockCachedPatch(levselp[0][2]); - - W_UnlockCachedPatch(levselp[1][0]); - W_UnlockCachedPatch(levselp[1][1]); - W_UnlockCachedPatch(levselp[1][2]); - } - levselp[0][0] = W_CachePatchName("SLCT1LVL", PU_PATCH); levselp[0][1] = W_CachePatchName("SLCT2LVL", PU_PATCH); levselp[0][2] = W_CachePatchName("BLANKLVL", PU_PATCH); @@ -5875,13 +5864,6 @@ static void M_Addons(INT32 choice) else dir_on[menudepthleft] = 0; - if (addonsp[0]) // never going to have some provided but not all, saves individually checking - { - size_t i; - for (i = 0; i < NUM_EXT+5; i++) - W_UnlockCachedPatch(addonsp[i]); - } - M_LoadAddonsPatches(); MISC_AddonsDef.prevMenu = currentMenu; @@ -7040,8 +7022,6 @@ static void M_SoundTest(INT32 choice) STRBUFCPY(buf, "M_RADIOn"); for (i = 0; i < 9; i++) { - if (st_radio[i]) - W_UnlockCachedPatch(st_radio[i]); buf[7] = (char)('0'+i); st_radio[i] = W_CachePatchName(buf, PU_STATIC); } @@ -7049,8 +7029,6 @@ static void M_SoundTest(INT32 choice) STRBUFCPY(buf, "M_LPADn"); for (i = 0; i < 4; i++) { - if (st_launchpad[i]) - W_UnlockCachedPatch(st_launchpad[i]); buf[6] = (char)('0'+i); st_launchpad[i] = W_CachePatchName(buf, PU_STATIC); } From 6f5a259983d9d8e97769cec83ac4a54ac518342c Mon Sep 17 00:00:00 2001 From: Jaime Passos Date: Thu, 26 Dec 2019 00:07:04 -0300 Subject: [PATCH 27/79] Tame R_StoreWallRange --- src/r_segs.c | 1933 +++++++++++++++++++++++++++----------------------- 1 file changed, 1040 insertions(+), 893 deletions(-) diff --git a/src/r_segs.c b/src/r_segs.c index 29120ebb8..c131af9ed 100644 --- a/src/r_segs.c +++ b/src/r_segs.c @@ -37,6 +37,14 @@ static boolean maskedtexture; static INT32 toptexture, bottomtexture, midtexture; static INT32 numthicksides, numbackffloors; +static boolean bothceilingssky; +static boolean bothfloorssky; + +#ifdef ESLOPE +static vertex_t segleft, segright; +static fixed_t ceilingfrontslide, floorfrontslide, ceilingbackslide, floorbackslide; +#endif + angle_t rw_normalangle; // angle to line origin angle_t rw_angle1; @@ -1687,8 +1695,20 @@ static void R_RenderSegLoop (void) } } -// Uses precalculated seg->length -static INT64 R_CalcSegDist(seg_t* seg, INT64 x2, INT64 y2) +// Macro for slope bullshit +#define SLOPEPARAMS(slope, end1, end2, normalheight) \ + if (slope) { \ + end1 = P_GetZAt(slope, segleft.x, segleft.y); \ + end2 = P_GetZAt(slope, segright.x, segright.y); \ + } else \ + end1 = end2 = normalheight; + +// +// R_CalculateSegDistance +// Calculate the distance from a seg. +// Uses precalculated seg->length. +// +static INT64 R_CalculateSegDistance(seg_t* seg, INT64 x2, INT64 y2) { if (!seg->linedef->dy) return llabs(y2 - seg->v1->y); @@ -1705,112 +1725,13 @@ static INT64 R_CalcSegDist(seg_t* seg, INT64 x2, INT64 y2) } // -// R_StoreWallRange -// A wall segment will be drawn -// between start and stop pixels (inclusive). +// R_CalculateWallScale +// Calculate scale at both ends and step. // -void R_StoreWallRange(INT32 start, INT32 stop) +static INT32 R_CalculateWallScale(INT32 start, INT32 stop) { - fixed_t hyp; - fixed_t sineval; - angle_t distangle, offsetangle; - boolean longboi; -#ifndef ESLOPE - fixed_t vtop; -#endif - INT32 lightnum; - INT32 i, p; - lightlist_t *light; - r_lightlist_t *rlight; - INT32 range; -#ifdef ESLOPE - vertex_t segleft, segright; - fixed_t ceilingfrontslide, floorfrontslide, ceilingbackslide, floorbackslide; -#endif - static size_t maxdrawsegs = 0; + INT32 range = 1; -#ifdef ESLOPE - maskedtextureheight = NULL; - //initialize segleft and segright - memset(&segleft, 0x00, sizeof(segleft)); - memset(&segright, 0x00, sizeof(segright)); -#endif - - colfunc = colfuncs[BASEDRAWFUNC]; - - if (ds_p == drawsegs+maxdrawsegs) - { - size_t curpos = curdrawsegs - drawsegs; - size_t pos = ds_p - drawsegs; - size_t newmax = maxdrawsegs ? maxdrawsegs*2 : 128; - if (firstseg) - firstseg = (drawseg_t *)(firstseg - drawsegs); - drawsegs = Z_Realloc(drawsegs, newmax*sizeof (*drawsegs), PU_STATIC, NULL); - ds_p = drawsegs + pos; - maxdrawsegs = newmax; - curdrawsegs = drawsegs + curpos; - if (firstseg) - firstseg = drawsegs + (size_t)firstseg; - } - - sidedef = curline->sidedef; - linedef = curline->linedef; - - // calculate rw_distance for scale calculation - rw_normalangle = curline->angle + ANGLE_90; - offsetangle = abs((INT32)(rw_normalangle-rw_angle1)); - - if (offsetangle > ANGLE_90) - offsetangle = ANGLE_90; - - distangle = ANGLE_90 - offsetangle; - sineval = FINESINE(distangle>>ANGLETOFINESHIFT); - - hyp = R_PointToDist(curline->v1->x, curline->v1->y); - rw_distance = FixedMul(hyp, sineval); - longboi = (hyp >= INT32_MAX); - - // big room fix - if (longboi) - rw_distance = (fixed_t)R_CalcSegDist(curline,viewx,viewy); - - ds_p->x1 = rw_x = start; - ds_p->x2 = stop; - ds_p->curline = curline; - rw_stopx = stop+1; - - //SoM: Code to remove limits on openings. - { - size_t pos = lastopening - openings; - size_t need = (rw_stopx - start)*4 + pos; - if (need > maxopenings) - { - drawseg_t *ds; //needed for fix from *cough* zdoom *cough* - INT16 *oldopenings = openings; - INT16 *oldlast = lastopening; - - do - maxopenings = maxopenings ? maxopenings*2 : 16384; - while (need > maxopenings); - openings = Z_Realloc(openings, maxopenings * sizeof (*openings), PU_STATIC, NULL); - lastopening = openings + pos; - - // borrowed fix from *cough* zdoom *cough* - // [RH] We also need to adjust the openings pointers that - // were already stored in drawsegs. - for (ds = drawsegs; ds < ds_p; ds++) - { -#define ADJUST(p) if (ds->p + ds->x1 >= oldopenings && ds->p + ds->x1 <= oldlast) ds->p = ds->p - oldopenings + openings; - ADJUST(maskedtexturecol); - ADJUST(sprtopclip); - ADJUST(sprbottomclip); - ADJUST(thicksidecol); -#undef ADJUST - } - } - } // end of code to remove limits on openings - - // calculate scale at both ends and step ds_p->scale1 = rw_scale = R_ScaleFromGlobalAngle(viewangle + xtoviewangle[start]); if (stop > start) @@ -1837,13 +1758,20 @@ void R_StoreWallRange(INT32 start, INT32 stop) } #endif ds_p->scale2 = ds_p->scale1; - range = 1; } ds_p->scalestep = rw_scalestep = (ds_p->scale2 - rw_scale) / (range); - // calculate texture boundaries - // and decide if floor / ceiling marks are needed + return range; +} + +// +// R_WorldTopAndBottom +// Calculate texture boundaries +// and decide if floor or ceiling marks are needed. +// +static void R_WorldTopAndBottom(INT32 start, INT32 stop) +{ #ifdef ESLOPE // Figure out map coordinates of where start and end are mapping to on seg, so we can clip right for slope bullshit if (frontsector->hasslope || (backsector && backsector->hasslope)) // Commenting this out for FOFslop. -Red @@ -1895,14 +1823,6 @@ void R_StoreWallRange(INT32 start, INT32 stop) } } - -#define SLOPEPARAMS(slope, end1, end2, normalheight) \ - if (slope) { \ - end1 = P_GetZAt(slope, segleft.x, segleft.y); \ - end2 = P_GetZAt(slope, segright.x, segright.y); \ - } else \ - end1 = end2 = normalheight; - SLOPEPARAMS(frontsector->c_slope, worldtop, worldtopslope, frontsector->ceilingheight) SLOPEPARAMS(frontsector->f_slope, worldbottom, worldbottomslope, frontsector->floorheight) // subtract viewz from these to turn them into @@ -1915,60 +1835,350 @@ void R_StoreWallRange(INT32 start, INT32 stop) worldtop = frontsector->ceilingheight - viewz; worldbottom = frontsector->floorheight - viewz; #endif +} - midtexture = toptexture = bottomtexture = maskedtexture = 0; - ds_p->maskedtexturecol = NULL; - ds_p->numthicksides = numthicksides = 0; - ds_p->thicksidecol = NULL; - ds_p->tsilheight = 0; +// +// R_WorldSegTextured +// Calculate rw_offset. +// Only needed for textured lines. +// +static void R_WorldSegTextured(fixed_t hyp, boolean longboi) +{ + INT32 lightnum; + fixed_t sineval; + angle_t offsetangle = rw_normalangle-rw_angle1; - numbackffloors = 0; + if (offsetangle > ANGLE_180) + offsetangle = -(signed)offsetangle; + if (offsetangle > ANGLE_90) + offsetangle = ANGLE_90; - for (i = 0; i < MAXFFLOORS; i++) - ds_p->thicksides[i] = NULL; + sineval = FINESINE(offsetangle>>ANGLETOFINESHIFT); + rw_offset = FixedMul(hyp, sineval); - if (numffloors) + // big room fix + if (longboi) { - for (i = 0; i < numffloors; i++) + INT64 dx = (curline->v2->x)-(curline->v1->x); + INT64 dy = (curline->v2->y)-(curline->v1->y); + INT64 vdx = viewx-(curline->v1->x); + INT64 vdy = viewy-(curline->v1->y); + rw_offset = ((dx*vdx-dy*vdy))/(curline->length); + } + + if (rw_normalangle-rw_angle1 < ANGLE_180) + rw_offset = -rw_offset; + + /// don't use texture offset for splats + rw_offset2 = rw_offset + curline->offset; + rw_offset += sidedef->textureoffset + curline->offset; + rw_centerangle = ANGLE_90 + viewangle - rw_normalangle; + + // calculate light table + // use different light tables + // for horizontal / vertical / diagonal + // OPTIMIZE: get rid of LIGHTSEGSHIFT globally + lightnum = (frontsector->lightlevel >> LIGHTSEGSHIFT); + + if (curline->v1->y == curline->v2->y) + lightnum--; + else if (curline->v1->x == curline->v2->x) + lightnum++; + + if (lightnum < 0) + walllights = scalelight[0]; + else if (lightnum >= LIGHTLEVELS) + walllights = scalelight[LIGHTLEVELS - 1]; + else + walllights = scalelight[lightnum]; +} + +// +// R_CheckMaskedTextures +// Midtexture stuff, presumably. +// +static void R_CheckMaskedTextures(void) +{ + INT32 i = 0; + // allocate space for masked texture tables + if (frontsector && backsector && frontsector->tag != backsector->tag && (backsector->ffloors || frontsector->ffloors)) + { + ffloor_t *rover; + ffloor_t *r2; + fixed_t lowcut, highcut; +#ifdef ESLOPE + fixed_t lowcutslope, highcutslope; + + // Used for height comparisons and etc across FOFs and slopes + fixed_t high1, highslope1, low1, lowslope1, high2, highslope2, low2, lowslope2; +#endif + + //markceiling = markfloor = true; + maskedtexture = true; + + ds_p->thicksidecol = maskedtexturecol = lastopening - rw_x; + lastopening += rw_stopx - rw_x; + + lowcut = max(worldbottom, worldlow) + viewz; + highcut = min(worldtop, worldhigh) + viewz; +#ifdef ESLOPE + lowcutslope = max(worldbottomslope, worldlowslope) + viewz; + highcutslope = min(worldtopslope, worldhighslope) + viewz; +#endif + + if (frontsector->ffloors && backsector->ffloors) { -#ifdef POLYOBJECTS_PLANES - if (ffloor[i].polyobj && (!ds_p->curline->polyseg || ffloor[i].polyobj != ds_p->curline->polyseg)) - continue; -#endif + i = 0; + for (rover = backsector->ffloors; rover && i < MAXFFLOORS; rover = rover->next) + { + if (!(rover->flags & FF_RENDERSIDES) || !(rover->flags & FF_EXISTS)) + continue; + if (rover->flags & FF_INVERTSIDES) + continue; + + if (rover->norender == leveltime) + continue; #ifdef ESLOPE - if (ffloor[i].slope) { - ffloor[i].f_pos = P_GetZAt(ffloor[i].slope, segleft.x, segleft.y) - viewz; - ffloor[i].f_pos_slope = P_GetZAt(ffloor[i].slope, segright.x, segright.y) - viewz; - } else - ffloor[i].f_pos_slope = + SLOPEPARAMS(*rover->t_slope, high1, highslope1, *rover->topheight) + SLOPEPARAMS(*rover->b_slope, low1, lowslope1, *rover->bottomheight) + + if ((high1 < lowcut && highslope1 < lowcutslope) || (low1 > highcut && lowslope1 > highcutslope)) + continue; +#else + if (*rover->topheight < lowcut || *rover->bottomheight > highcut) + continue; #endif - ffloor[i].f_pos = ffloor[i].height - viewz; + + for (r2 = frontsector->ffloors; r2; r2 = r2->next) + { + if (!(r2->flags & FF_EXISTS) || !(r2->flags & FF_RENDERSIDES)) + continue; + + if (r2->norender == leveltime) + continue; + + if (rover->flags & FF_EXTRA) + { + if (!(r2->flags & FF_CUTEXTRA)) + continue; + + if (r2->flags & FF_EXTRA && (r2->flags & (FF_TRANSLUCENT|FF_FOG)) != (rover->flags & (FF_TRANSLUCENT|FF_FOG))) + continue; + } + else + { + if (!(r2->flags & FF_CUTSOLIDS)) + continue; + } + +#ifdef ESLOPE + SLOPEPARAMS(*r2->t_slope, high2, highslope2, *r2->topheight) + SLOPEPARAMS(*r2->b_slope, low2, lowslope2, *r2->bottomheight) + + if ((high2 < lowcut || highslope2 < lowcutslope) || (low2 > highcut || lowslope2 > highcutslope)) + continue; + if ((high1 > high2 || highslope1 > highslope2) || (low1 < low2 || lowslope1 < lowslope2)) + continue; +#else + if (*r2->topheight < lowcut || *r2->bottomheight > highcut) + continue; + if (*rover->topheight > *r2->topheight || *rover->bottomheight < *r2->bottomheight) + continue; +#endif + + break; + } + if (r2) + continue; + + ds_p->thicksides[i] = rover; + i++; + } + + for (rover = frontsector->ffloors; rover && i < MAXFFLOORS; rover = rover->next) + { + if (!(rover->flags & FF_RENDERSIDES) || !(rover->flags & FF_EXISTS)) + continue; + if (!(rover->flags & FF_ALLSIDES)) + continue; + + if (rover->norender == leveltime) + continue; + +#ifdef ESLOPE + SLOPEPARAMS(*rover->t_slope, high1, highslope1, *rover->topheight) + SLOPEPARAMS(*rover->b_slope, low1, lowslope1, *rover->bottomheight) + + if ((high1 < lowcut && highslope1 < lowcutslope) || (low1 > highcut && lowslope1 > highcutslope)) + continue; +#else + if (*rover->topheight < lowcut || *rover->bottomheight > highcut) + continue; +#endif + + for (r2 = backsector->ffloors; r2; r2 = r2->next) + { + if (!(r2->flags & FF_EXISTS) || !(r2->flags & FF_RENDERSIDES)) + continue; + + if (r2->norender == leveltime) + continue; + + if (rover->flags & FF_EXTRA) + { + if (!(r2->flags & FF_CUTEXTRA)) + continue; + + if (r2->flags & FF_EXTRA && (r2->flags & (FF_TRANSLUCENT|FF_FOG)) != (rover->flags & (FF_TRANSLUCENT|FF_FOG))) + continue; + } + else + { + if (!(r2->flags & FF_CUTSOLIDS)) + continue; + } + +#ifdef ESLOPE + SLOPEPARAMS(*r2->t_slope, high2, highslope2, *r2->topheight) + SLOPEPARAMS(*r2->b_slope, low2, lowslope2, *r2->bottomheight) + if ((high2 < lowcut || highslope2 < lowcutslope) || (low2 > highcut || lowslope2 > highcutslope)) + continue; + if ((high1 > high2 || highslope1 > highslope2) || (low1 < low2 || lowslope1 < lowslope2)) + continue; +#else + if (*r2->topheight < lowcut || *r2->bottomheight > highcut) + continue; + if (*rover->topheight > *r2->topheight || *rover->bottomheight < *r2->bottomheight) + continue; +#endif + + break; + } + if (r2) + continue; + + ds_p->thicksides[i] = rover; + i++; + } } - } + else if (backsector->ffloors) + { + for (rover = backsector->ffloors, i = 0; rover && i < MAXFFLOORS; rover = rover->next) + { + if (!(rover->flags & FF_RENDERSIDES) || !(rover->flags & FF_EXISTS) || rover->flags & FF_INVERTSIDES) + continue; + if (rover->norender == leveltime) + continue; #ifdef ESLOPE - // Set up texture Y offset slides for sloped walls - rw_toptextureslide = rw_midtextureslide = rw_bottomtextureslide = 0; - ceilingfrontslide = floorfrontslide = ceilingbackslide = floorbackslide = 0; - - { - angle_t lineangle = R_PointToAngle2(curline->v1->x, curline->v1->y, curline->v2->x, curline->v2->y); - - if (frontsector->f_slope) - floorfrontslide = FixedMul(frontsector->f_slope->zdelta, FINECOSINE((lineangle-frontsector->f_slope->xydirection)>>ANGLETOFINESHIFT)); - - if (frontsector->c_slope) - ceilingfrontslide = FixedMul(frontsector->c_slope->zdelta, FINECOSINE((lineangle-frontsector->c_slope->xydirection)>>ANGLETOFINESHIFT)); - - if (backsector && backsector->f_slope) - floorbackslide = FixedMul(backsector->f_slope->zdelta, FINECOSINE((lineangle-backsector->f_slope->xydirection)>>ANGLETOFINESHIFT)); - - if (backsector && backsector->c_slope) - ceilingbackslide = FixedMul(backsector->c_slope->zdelta, FINECOSINE((lineangle-backsector->c_slope->xydirection)>>ANGLETOFINESHIFT)); - } + // Oy vey. + if (( (*rover->t_slope ? P_GetZAt(*rover->t_slope, segleft.x, segleft.y) : *rover->topheight) <= worldbottom+viewz + && (*rover->t_slope ? P_GetZAt(*rover->t_slope, segright.x, segright.y) : *rover->topheight) <= worldbottomslope+viewz) + ||((*rover->b_slope ? P_GetZAt(*rover->b_slope, segleft.x, segleft.y) : *rover->bottomheight) >= worldtop+viewz + && (*rover->b_slope ? P_GetZAt(*rover->b_slope, segright.x, segright.y) : *rover->bottomheight) >= worldtopslope+viewz)) + continue; +#else + if (*rover->topheight <= frontsector->floorheight || *rover->bottomheight >= frontsector->ceilingheight) + continue; #endif + ds_p->thicksides[i] = rover; + i++; + } + } + else if (frontsector->ffloors) + { + for (rover = frontsector->ffloors, i = 0; rover && i < MAXFFLOORS; rover = rover->next) + { + if (!(rover->flags & FF_RENDERSIDES) || !(rover->flags & FF_EXISTS) || !(rover->flags & FF_ALLSIDES)) + continue; + if (rover->norender == leveltime) + continue; +#ifdef ESLOPE + // Oy vey. + if (( (*rover->t_slope ? P_GetZAt(*rover->t_slope, segleft.x, segleft.y) : *rover->topheight) <= worldbottom+viewz + && (*rover->t_slope ? P_GetZAt(*rover->t_slope, segright.x, segright.y) : *rover->topheight) <= worldbottomslope+viewz) + ||((*rover->b_slope ? P_GetZAt(*rover->b_slope, segleft.x, segleft.y) : *rover->bottomheight) >= worldtop+viewz + && (*rover->b_slope ? P_GetZAt(*rover->b_slope, segright.x, segright.y) : *rover->bottomheight) >= worldtopslope+viewz)) + continue; + + if (( (*rover->t_slope ? P_GetZAt(*rover->t_slope, segleft.x, segleft.y) : *rover->topheight) <= worldlow+viewz + && (*rover->t_slope ? P_GetZAt(*rover->t_slope, segright.x, segright.y) : *rover->topheight) <= worldlowslope+viewz) + ||((*rover->b_slope ? P_GetZAt(*rover->b_slope, segleft.x, segleft.y) : *rover->bottomheight) >= worldhigh+viewz + && (*rover->b_slope ? P_GetZAt(*rover->b_slope, segright.x, segright.y) : *rover->bottomheight) >= worldhighslope+viewz)) + continue; +#else + if (*rover->topheight <= frontsector->floorheight || *rover->bottomheight >= frontsector->ceilingheight) + continue; + if (*rover->topheight <= backsector->floorheight || *rover->bottomheight >= backsector->ceilingheight) + continue; +#endif + + ds_p->thicksides[i] = rover; + i++; + } + } + + ds_p->numthicksides = numthicksides = i; + } + + if (sidedef->midtexture > 0 && sidedef->midtexture < numtextures) + { + // masked midtexture + if (!ds_p->thicksidecol) + { + ds_p->maskedtexturecol = maskedtexturecol = lastopening - rw_x; + lastopening += rw_stopx - rw_x; + } + else + ds_p->maskedtexturecol = ds_p->thicksidecol; + +#ifdef ESLOPE + maskedtextureheight = ds_p->maskedtextureheight; // note to red, this == &(ds_p->maskedtextureheight[0]) + +#ifdef POLYOBJECTS + if (curline->polyseg) { // use REAL front and back floors please, so midtexture rendering isn't mucked up + rw_midtextureslide = rw_midtexturebackslide = 0; + if (!!(linedef->flags & ML_DONTPEGBOTTOM) ^ !!(linedef->flags & ML_EFFECT3)) + rw_midtexturemid = rw_midtextureback = max(curline->frontsector->floorheight, curline->backsector->floorheight) - viewz; + else + rw_midtexturemid = rw_midtextureback = min(curline->frontsector->ceilingheight, curline->backsector->ceilingheight) - viewz; + } else +#endif + // Set midtexture starting height + if (linedef->flags & ML_EFFECT2) { // Ignore slopes when texturing + rw_midtextureslide = rw_midtexturebackslide = 0; + if (!!(linedef->flags & ML_DONTPEGBOTTOM) ^ !!(linedef->flags & ML_EFFECT3)) + rw_midtexturemid = rw_midtextureback = max(frontsector->floorheight, backsector->floorheight) - viewz; + else + rw_midtexturemid = rw_midtextureback = min(frontsector->ceilingheight, backsector->ceilingheight) - viewz; + + } else if (!!(linedef->flags & ML_DONTPEGBOTTOM) ^ !!(linedef->flags & ML_EFFECT3)) { + rw_midtexturemid = worldbottom; + rw_midtextureslide = floorfrontslide; + rw_midtextureback = worldlow; + rw_midtexturebackslide = floorbackslide; + } else { + rw_midtexturemid = worldtop; + rw_midtextureslide = ceilingfrontslide; + rw_midtextureback = worldhigh; + rw_midtexturebackslide = ceilingbackslide; + } + rw_midtexturemid += sidedef->rowoffset; + rw_midtextureback += sidedef->rowoffset; +#endif + + maskedtexture = true; + } +} + +// +// R_CheckWallTextures +// Self-explanatory, I hope?! +// +static void R_CheckWallTextures(void) +{ if (!backsector) { fixed_t texheight; @@ -2006,7 +2216,113 @@ void R_StoreWallRange(INT32 start, INT32 stop) #endif } rw_midtexturemid += sidedef->rowoffset; + } + else + { + // check TOP TEXTURE + if (!bothceilingssky // never draw the top texture if on + && (worldhigh < worldtop +#ifdef ESLOPE + || worldhighslope < worldtopslope +#endif + )) + { + fixed_t texheight; + // top texture + if ((linedef->flags & (ML_DONTPEGTOP) && (linedef->flags & ML_DONTPEGBOTTOM)) + && linedef->sidenum[1] != 0xffff) + { + // Special case... use offsets from 2nd side but only if it has a texture. + side_t *def = &sides[linedef->sidenum[1]]; + toptexture = R_GetTextureNum(def->toptexture); + if (!toptexture) //Second side has no texture, use the first side's instead. + toptexture = R_GetTextureNum(sidedef->toptexture); + texheight = textureheight[toptexture]; + } + else + { + toptexture = R_GetTextureNum(sidedef->toptexture); + texheight = textureheight[toptexture]; + } +#ifdef ESLOPE + if (!(linedef->flags & ML_EFFECT1)) { // Ignore slopes for lower/upper textures unless flag is checked + if (linedef->flags & ML_DONTPEGTOP) + rw_toptexturemid = frontsector->ceilingheight - viewz; + else + rw_toptexturemid = backsector->ceilingheight - viewz; + } else +#endif + if (linedef->flags & ML_DONTPEGTOP) + { + // top of texture at top + rw_toptexturemid = worldtop; +#ifdef ESLOPE + rw_toptextureslide = ceilingfrontslide; +#endif + } + else + { +#ifdef ESLOPE + rw_toptexturemid = worldhigh + texheight; + rw_toptextureslide = ceilingbackslide; +#else + vtop = backsector->ceilingheight + texheight; + // bottom of texture + rw_toptexturemid = vtop - viewz; +#endif + } + } + // check BOTTOM TEXTURE + if (!bothfloorssky // never draw the bottom texture if on + && (worldlow > worldbottom +#ifdef ESLOPE + || worldlowslope > worldbottomslope +#endif + )) //seulement si VISIBLE!!! + { + // bottom texture + bottomtexture = R_GetTextureNum(sidedef->bottomtexture); + +#ifdef ESLOPE + if (!(linedef->flags & ML_EFFECT1)) { // Ignore slopes for lower/upper textures unless flag is checked + if (linedef->flags & ML_DONTPEGBOTTOM) + rw_bottomtexturemid = frontsector->floorheight - viewz; + else + rw_bottomtexturemid = backsector->floorheight - viewz; + } else +#endif + if (linedef->flags & ML_DONTPEGBOTTOM) + { + // bottom of texture at bottom + // top of texture at top + rw_bottomtexturemid = worldbottom; +#ifdef ESLOPE + rw_bottomtextureslide = floorfrontslide; +#endif + } + else { // top of texture at top + rw_bottomtexturemid = worldlow; +#ifdef ESLOPE + rw_bottomtextureslide = floorbackslide; +#endif + } + } + + rw_toptexturemid += sidedef->rowoffset; + rw_bottomtexturemid += sidedef->rowoffset; + } +} + +// +// R_StoreWallSilhouette +// Sets the silhouette for the current seg. +// Also checks if any floors or ceilings have to be marked. +// +static void R_StoreWallSilhouette(void) +{ + if (!backsector) + { ds_p->silhouette = SIL_BOTH; ds_p->sprtopclip = screenheightarray; ds_p->sprbottomclip = negonearray; @@ -2016,8 +2332,8 @@ void R_StoreWallRange(INT32 start, INT32 stop) else { // two sided line - boolean bothceilingssky = false; // turned on if both back and front ceilings are sky - boolean bothfloorssky = false; // likewise, but for floors + bothceilingssky = false; // turned on if both back and front ceilings are sky + bothfloorssky = false; // likewise, but for floors #ifdef ESLOPE SLOPEPARAMS(backsector->c_slope, worldhigh, worldhighslope, backsector->ceilingheight) @@ -2240,460 +2556,22 @@ void R_StoreWallRange(INT32 start, INT32 stop) markceiling = markfloor = true; } } - - // check TOP TEXTURE - if (!bothceilingssky // never draw the top texture if on - && (worldhigh < worldtop -#ifdef ESLOPE - || worldhighslope < worldtopslope -#endif - )) - { - fixed_t texheight; - // top texture - if ((linedef->flags & (ML_DONTPEGTOP) && (linedef->flags & ML_DONTPEGBOTTOM)) - && linedef->sidenum[1] != 0xffff) - { - // Special case... use offsets from 2nd side but only if it has a texture. - side_t *def = &sides[linedef->sidenum[1]]; - toptexture = R_GetTextureNum(def->toptexture); - - if (!toptexture) //Second side has no texture, use the first side's instead. - toptexture = R_GetTextureNum(sidedef->toptexture); - texheight = textureheight[toptexture]; - } - else - { - toptexture = R_GetTextureNum(sidedef->toptexture); - texheight = textureheight[toptexture]; - } -#ifdef ESLOPE - if (!(linedef->flags & ML_EFFECT1)) { // Ignore slopes for lower/upper textures unless flag is checked - if (linedef->flags & ML_DONTPEGTOP) - rw_toptexturemid = frontsector->ceilingheight - viewz; - else - rw_toptexturemid = backsector->ceilingheight - viewz; - } else -#endif - if (linedef->flags & ML_DONTPEGTOP) - { - // top of texture at top - rw_toptexturemid = worldtop; -#ifdef ESLOPE - rw_toptextureslide = ceilingfrontslide; -#endif - } - else - { -#ifdef ESLOPE - rw_toptexturemid = worldhigh + texheight; - rw_toptextureslide = ceilingbackslide; -#else - vtop = backsector->ceilingheight + texheight; - // bottom of texture - rw_toptexturemid = vtop - viewz; -#endif - } - } - // check BOTTOM TEXTURE - if (!bothfloorssky // never draw the bottom texture if on - && (worldlow > worldbottom -#ifdef ESLOPE - || worldlowslope > worldbottomslope -#endif - )) //seulement si VISIBLE!!! - { - // bottom texture - bottomtexture = R_GetTextureNum(sidedef->bottomtexture); - -#ifdef ESLOPE - if (!(linedef->flags & ML_EFFECT1)) { // Ignore slopes for lower/upper textures unless flag is checked - if (linedef->flags & ML_DONTPEGBOTTOM) - rw_bottomtexturemid = frontsector->floorheight - viewz; - else - rw_bottomtexturemid = backsector->floorheight - viewz; - } else -#endif - if (linedef->flags & ML_DONTPEGBOTTOM) - { - // bottom of texture at bottom - // top of texture at top - rw_bottomtexturemid = worldbottom; -#ifdef ESLOPE - rw_bottomtextureslide = floorfrontslide; -#endif - } - else { // top of texture at top - rw_bottomtexturemid = worldlow; -#ifdef ESLOPE - rw_bottomtextureslide = floorbackslide; -#endif - } - } - - rw_toptexturemid += sidedef->rowoffset; - rw_bottomtexturemid += sidedef->rowoffset; - - // allocate space for masked texture tables - if (frontsector && backsector && frontsector->tag != backsector->tag && (backsector->ffloors || frontsector->ffloors)) - { - ffloor_t *rover; - ffloor_t *r2; - fixed_t lowcut, highcut; -#ifdef ESLOPE - fixed_t lowcutslope, highcutslope; - - // Used for height comparisons and etc across FOFs and slopes - fixed_t high1, highslope1, low1, lowslope1, high2, highslope2, low2, lowslope2; -#endif - - //markceiling = markfloor = true; - maskedtexture = true; - - ds_p->thicksidecol = maskedtexturecol = lastopening - rw_x; - lastopening += rw_stopx - rw_x; - - lowcut = max(worldbottom, worldlow) + viewz; - highcut = min(worldtop, worldhigh) + viewz; -#ifdef ESLOPE - lowcutslope = max(worldbottomslope, worldlowslope) + viewz; - highcutslope = min(worldtopslope, worldhighslope) + viewz; -#endif - - if (frontsector->ffloors && backsector->ffloors) - { - i = 0; - for (rover = backsector->ffloors; rover && i < MAXFFLOORS; rover = rover->next) - { - if (!(rover->flags & FF_RENDERSIDES) || !(rover->flags & FF_EXISTS)) - continue; - if (rover->flags & FF_INVERTSIDES) - continue; - - if (rover->norender == leveltime) - continue; - -#ifdef ESLOPE - SLOPEPARAMS(*rover->t_slope, high1, highslope1, *rover->topheight) - SLOPEPARAMS(*rover->b_slope, low1, lowslope1, *rover->bottomheight) - - if ((high1 < lowcut && highslope1 < lowcutslope) || (low1 > highcut && lowslope1 > highcutslope)) - continue; -#else - if (*rover->topheight < lowcut || *rover->bottomheight > highcut) - continue; -#endif - - for (r2 = frontsector->ffloors; r2; r2 = r2->next) - { - if (!(r2->flags & FF_EXISTS) || !(r2->flags & FF_RENDERSIDES)) - continue; - - if (r2->norender == leveltime) - continue; - - if (rover->flags & FF_EXTRA) - { - if (!(r2->flags & FF_CUTEXTRA)) - continue; - - if (r2->flags & FF_EXTRA && (r2->flags & (FF_TRANSLUCENT|FF_FOG)) != (rover->flags & (FF_TRANSLUCENT|FF_FOG))) - continue; - } - else - { - if (!(r2->flags & FF_CUTSOLIDS)) - continue; - } - -#ifdef ESLOPE - SLOPEPARAMS(*r2->t_slope, high2, highslope2, *r2->topheight) - SLOPEPARAMS(*r2->b_slope, low2, lowslope2, *r2->bottomheight) - - if ((high2 < lowcut || highslope2 < lowcutslope) || (low2 > highcut || lowslope2 > highcutslope)) - continue; - if ((high1 > high2 || highslope1 > highslope2) || (low1 < low2 || lowslope1 < lowslope2)) - continue; -#else - if (*r2->topheight < lowcut || *r2->bottomheight > highcut) - continue; - if (*rover->topheight > *r2->topheight || *rover->bottomheight < *r2->bottomheight) - continue; -#endif - - break; - } - if (r2) - continue; - - ds_p->thicksides[i] = rover; - i++; - } - - for (rover = frontsector->ffloors; rover && i < MAXFFLOORS; rover = rover->next) - { - if (!(rover->flags & FF_RENDERSIDES) || !(rover->flags & FF_EXISTS)) - continue; - if (!(rover->flags & FF_ALLSIDES)) - continue; - - if (rover->norender == leveltime) - continue; - -#ifdef ESLOPE - SLOPEPARAMS(*rover->t_slope, high1, highslope1, *rover->topheight) - SLOPEPARAMS(*rover->b_slope, low1, lowslope1, *rover->bottomheight) - - if ((high1 < lowcut && highslope1 < lowcutslope) || (low1 > highcut && lowslope1 > highcutslope)) - continue; -#else - if (*rover->topheight < lowcut || *rover->bottomheight > highcut) - continue; -#endif - - for (r2 = backsector->ffloors; r2; r2 = r2->next) - { - if (!(r2->flags & FF_EXISTS) || !(r2->flags & FF_RENDERSIDES)) - continue; - - if (r2->norender == leveltime) - continue; - - if (rover->flags & FF_EXTRA) - { - if (!(r2->flags & FF_CUTEXTRA)) - continue; - - if (r2->flags & FF_EXTRA && (r2->flags & (FF_TRANSLUCENT|FF_FOG)) != (rover->flags & (FF_TRANSLUCENT|FF_FOG))) - continue; - } - else - { - if (!(r2->flags & FF_CUTSOLIDS)) - continue; - } - -#ifdef ESLOPE - SLOPEPARAMS(*r2->t_slope, high2, highslope2, *r2->topheight) - SLOPEPARAMS(*r2->b_slope, low2, lowslope2, *r2->bottomheight) -#undef SLOPEPARAMS - if ((high2 < lowcut || highslope2 < lowcutslope) || (low2 > highcut || lowslope2 > highcutslope)) - continue; - if ((high1 > high2 || highslope1 > highslope2) || (low1 < low2 || lowslope1 < lowslope2)) - continue; -#else - if (*r2->topheight < lowcut || *r2->bottomheight > highcut) - continue; - if (*rover->topheight > *r2->topheight || *rover->bottomheight < *r2->bottomheight) - continue; -#endif - - break; - } - if (r2) - continue; - - ds_p->thicksides[i] = rover; - i++; - } - } - else if (backsector->ffloors) - { - for (rover = backsector->ffloors, i = 0; rover && i < MAXFFLOORS; rover = rover->next) - { - if (!(rover->flags & FF_RENDERSIDES) || !(rover->flags & FF_EXISTS) || rover->flags & FF_INVERTSIDES) - continue; - if (rover->norender == leveltime) - continue; - -#ifdef ESLOPE - // Oy vey. - if (( (*rover->t_slope ? P_GetZAt(*rover->t_slope, segleft.x, segleft.y) : *rover->topheight) <= worldbottom+viewz - && (*rover->t_slope ? P_GetZAt(*rover->t_slope, segright.x, segright.y) : *rover->topheight) <= worldbottomslope+viewz) - ||((*rover->b_slope ? P_GetZAt(*rover->b_slope, segleft.x, segleft.y) : *rover->bottomheight) >= worldtop+viewz - && (*rover->b_slope ? P_GetZAt(*rover->b_slope, segright.x, segright.y) : *rover->bottomheight) >= worldtopslope+viewz)) - continue; -#else - if (*rover->topheight <= frontsector->floorheight || *rover->bottomheight >= frontsector->ceilingheight) - continue; -#endif - - ds_p->thicksides[i] = rover; - i++; - } - } - else if (frontsector->ffloors) - { - for (rover = frontsector->ffloors, i = 0; rover && i < MAXFFLOORS; rover = rover->next) - { - if (!(rover->flags & FF_RENDERSIDES) || !(rover->flags & FF_EXISTS) || !(rover->flags & FF_ALLSIDES)) - continue; - if (rover->norender == leveltime) - continue; -#ifdef ESLOPE - // Oy vey. - if (( (*rover->t_slope ? P_GetZAt(*rover->t_slope, segleft.x, segleft.y) : *rover->topheight) <= worldbottom+viewz - && (*rover->t_slope ? P_GetZAt(*rover->t_slope, segright.x, segright.y) : *rover->topheight) <= worldbottomslope+viewz) - ||((*rover->b_slope ? P_GetZAt(*rover->b_slope, segleft.x, segleft.y) : *rover->bottomheight) >= worldtop+viewz - && (*rover->b_slope ? P_GetZAt(*rover->b_slope, segright.x, segright.y) : *rover->bottomheight) >= worldtopslope+viewz)) - continue; - - if (( (*rover->t_slope ? P_GetZAt(*rover->t_slope, segleft.x, segleft.y) : *rover->topheight) <= worldlow+viewz - && (*rover->t_slope ? P_GetZAt(*rover->t_slope, segright.x, segright.y) : *rover->topheight) <= worldlowslope+viewz) - ||((*rover->b_slope ? P_GetZAt(*rover->b_slope, segleft.x, segleft.y) : *rover->bottomheight) >= worldhigh+viewz - && (*rover->b_slope ? P_GetZAt(*rover->b_slope, segright.x, segright.y) : *rover->bottomheight) >= worldhighslope+viewz)) - continue; -#else - if (*rover->topheight <= frontsector->floorheight || *rover->bottomheight >= frontsector->ceilingheight) - continue; - if (*rover->topheight <= backsector->floorheight || *rover->bottomheight >= backsector->ceilingheight) - continue; -#endif - - ds_p->thicksides[i] = rover; - i++; - } - } - - ds_p->numthicksides = numthicksides = i; - } - if (sidedef->midtexture > 0 && sidedef->midtexture < numtextures) - { - // masked midtexture - if (!ds_p->thicksidecol) - { - ds_p->maskedtexturecol = maskedtexturecol = lastopening - rw_x; - lastopening += rw_stopx - rw_x; - } - else - ds_p->maskedtexturecol = ds_p->thicksidecol; - -#ifdef ESLOPE - maskedtextureheight = ds_p->maskedtextureheight; // note to red, this == &(ds_p->maskedtextureheight[0]) - -#ifdef POLYOBJECTS - if (curline->polyseg) { // use REAL front and back floors please, so midtexture rendering isn't mucked up - rw_midtextureslide = rw_midtexturebackslide = 0; - if (!!(linedef->flags & ML_DONTPEGBOTTOM) ^ !!(linedef->flags & ML_EFFECT3)) - rw_midtexturemid = rw_midtextureback = max(curline->frontsector->floorheight, curline->backsector->floorheight) - viewz; - else - rw_midtexturemid = rw_midtextureback = min(curline->frontsector->ceilingheight, curline->backsector->ceilingheight) - viewz; - } else -#endif - // Set midtexture starting height - if (linedef->flags & ML_EFFECT2) { // Ignore slopes when texturing - rw_midtextureslide = rw_midtexturebackslide = 0; - if (!!(linedef->flags & ML_DONTPEGBOTTOM) ^ !!(linedef->flags & ML_EFFECT3)) - rw_midtexturemid = rw_midtextureback = max(frontsector->floorheight, backsector->floorheight) - viewz; - else - rw_midtexturemid = rw_midtextureback = min(frontsector->ceilingheight, backsector->ceilingheight) - viewz; - - } else if (!!(linedef->flags & ML_DONTPEGBOTTOM) ^ !!(linedef->flags & ML_EFFECT3)) { - rw_midtexturemid = worldbottom; - rw_midtextureslide = floorfrontslide; - rw_midtextureback = worldlow; - rw_midtexturebackslide = floorbackslide; - } else { - rw_midtexturemid = worldtop; - rw_midtextureslide = ceilingfrontslide; - rw_midtextureback = worldhigh; - rw_midtexturebackslide = ceilingbackslide; - } - rw_midtexturemid += sidedef->rowoffset; - rw_midtextureback += sidedef->rowoffset; -#endif - - maskedtexture = true; - } } +} - // calculate rw_offset (only needed for textured lines) - segtextured = midtexture || toptexture || bottomtexture || maskedtexture || (numthicksides > 0); - - if (segtextured) - { - offsetangle = rw_normalangle-rw_angle1; - - if (offsetangle > ANGLE_180) - offsetangle = -(signed)offsetangle; - - if (offsetangle > ANGLE_90) - offsetangle = ANGLE_90; - - sineval = FINESINE(offsetangle>>ANGLETOFINESHIFT); - rw_offset = FixedMul(hyp, sineval); - - // big room fix - if (longboi) - { - INT64 dx = (curline->v2->x)-(curline->v1->x); - INT64 dy = (curline->v2->y)-(curline->v1->y); - INT64 vdx = viewx-(curline->v1->x); - INT64 vdy = viewy-(curline->v1->y); - rw_offset = ((dx*vdx-dy*vdy))/(curline->length); - } - - if (rw_normalangle-rw_angle1 < ANGLE_180) - rw_offset = -rw_offset; - - /// don't use texture offset for splats - rw_offset2 = rw_offset + curline->offset; - rw_offset += sidedef->textureoffset + curline->offset; - rw_centerangle = ANGLE_90 + viewangle - rw_normalangle; - - // calculate light table - // use different light tables - // for horizontal / vertical / diagonal - // OPTIMIZE: get rid of LIGHTSEGSHIFT globally - lightnum = (frontsector->lightlevel >> LIGHTSEGSHIFT); - - if (curline->v1->y == curline->v2->y) - lightnum--; - else if (curline->v1->x == curline->v2->x) - lightnum++; - - if (lightnum < 0) - walllights = scalelight[0]; - else if (lightnum >= LIGHTLEVELS) - walllights = scalelight[LIGHTLEVELS - 1]; - else - walllights = scalelight[lightnum]; - } - - // if a floor / ceiling plane is on the wrong side - // of the view plane, it is definitely invisible - // and doesn't need to be marked. - if (frontsector->heightsec == -1) - { - if (frontsector->floorpic != skyflatnum - && ( -#ifdef ESLOPE - frontsector->f_slope ? P_GetZAt(frontsector->f_slope, viewx, viewy) : -#endif - frontsector->floorheight) >= viewz) - { - // above view plane - markfloor = false; - } - - if (frontsector->ceilingpic != skyflatnum - && ( -#ifdef ESLOPE - frontsector->c_slope ? P_GetZAt(frontsector->c_slope, viewx, viewy) : -#endif - frontsector->ceilingheight) <= viewz) - { - // below view plane - markceiling = false; - } - } - - // calculate incremental stepping values for texture edges +// +// R_WorldStep +// Does... stepping... stuff? +// +static void R_WorldStep(INT32 range) +{ worldtop >>= 4; worldbottom >>= 4; #ifdef ESLOPE worldtopslope >>= 4; worldbottomslope >>= 4; +#else + (void)range; #endif if (linedef->special == HORIZONSPECIAL) { // HORIZON LINES @@ -2718,6 +2596,329 @@ void R_StoreWallRange(INT32 start, INT32 stop) } #endif } +} + +// +// R_WorldBackStep +// Does... stepping... stuff? For backsides?!?!?!?!?!?! +// +static void R_WorldBackStep(INT32 range) +{ + INT32 i; + + worldhigh >>= 4; + worldlow >>= 4; +#ifdef ESLOPE + worldhighslope >>= 4; + worldlowslope >>= 4; +#else + (void)range; +#endif + + if (toptexture) + { + pixhigh = (centeryfrac>>4) - FixedMul (worldhigh, rw_scale); + pixhighstep = -FixedMul (rw_scalestep,worldhigh); + +#ifdef ESLOPE + if (backsector->c_slope) { + fixed_t topfracend = (centeryfrac>>4) - FixedMul (worldhighslope, ds_p->scale2); + pixhighstep = (topfracend-pixhigh)/(range); + } +#endif + } + + if (bottomtexture) + { + pixlow = (centeryfrac>>4) - FixedMul (worldlow, rw_scale); + pixlowstep = -FixedMul (rw_scalestep,worldlow); +#ifdef ESLOPE + if (backsector->f_slope) { + fixed_t bottomfracend = (centeryfrac>>4) - FixedMul (worldlowslope, ds_p->scale2); + pixlowstep = (bottomfracend-pixlow)/(range); + } +#endif + } + + { + ffloor_t * rover; +#ifdef ESLOPE + fixed_t roverleft, roverright; + fixed_t planevistest; +#endif + i = 0; + + if (backsector->ffloors) + { + for (rover = backsector->ffloors; rover && i < MAXFFLOORS; rover = rover->next) + { + if (!(rover->flags & FF_EXISTS) || !(rover->flags & FF_RENDERPLANES)) + continue; + if (rover->norender == leveltime) + continue; + +#ifdef ESLOPE + // Let the renderer know this sector is sloped. + if (*rover->b_slope || *rover->t_slope) + backsector->hasslope = true; + + roverleft = (*rover->b_slope ? P_GetZAt(*rover->b_slope, segleft.x, segleft.y) : *rover->bottomheight) - viewz; + roverright = (*rover->b_slope ? P_GetZAt(*rover->b_slope, segright.x, segright.y) : *rover->bottomheight) - viewz; + planevistest = (*rover->b_slope ? P_GetZAt(*rover->b_slope, viewx, viewy) : *rover->bottomheight); + + if ((roverleft>>4 <= worldhigh || roverright>>4 <= worldhighslope) && + (roverleft>>4 >= worldlow || roverright>>4 >= worldlowslope) && + ((viewz < planevistest && !(rover->flags & FF_INVERTPLANES)) || + (viewz > planevistest && (rover->flags & FF_BOTHPLANES)))) + { + //ffloor[i].slope = *rover->b_slope; + ffloor[i].b_pos = roverleft; + ffloor[i].b_pos_slope = roverright; + ffloor[i].b_pos >>= 4; + ffloor[i].b_pos_slope >>= 4; + ffloor[i].b_frac = (centeryfrac >> 4) - FixedMul(ffloor[i].b_pos, rw_scale); + ffloor[i].b_step = (centeryfrac >> 4) - FixedMul(ffloor[i].b_pos_slope, ds_p->scale2); + ffloor[i].b_step = (ffloor[i].b_step-ffloor[i].b_frac)/(range); + i++; + } + + if (i >= MAXFFLOORS) + break; + + roverleft = (*rover->t_slope ? P_GetZAt(*rover->t_slope, segleft.x, segleft.y) : *rover->topheight) - viewz; + roverright = (*rover->t_slope ? P_GetZAt(*rover->t_slope, segright.x, segright.y) : *rover->topheight) - viewz; + planevistest = (*rover->t_slope ? P_GetZAt(*rover->t_slope, viewx, viewy) : *rover->topheight); + + if ((roverleft>>4 <= worldhigh || roverright>>4 <= worldhighslope) && + (roverleft>>4 >= worldlow || roverright>>4 >= worldlowslope) && + ((viewz > planevistest && !(rover->flags & FF_INVERTPLANES)) || + (viewz < planevistest && (rover->flags & FF_BOTHPLANES)))) + { + //ffloor[i].slope = *rover->t_slope; + ffloor[i].b_pos = roverleft; + ffloor[i].b_pos_slope = roverright; + ffloor[i].b_pos >>= 4; + ffloor[i].b_pos_slope >>= 4; + ffloor[i].b_frac = (centeryfrac >> 4) - FixedMul(ffloor[i].b_pos, rw_scale); + ffloor[i].b_step = (centeryfrac >> 4) - FixedMul(ffloor[i].b_pos_slope, ds_p->scale2); + ffloor[i].b_step = (ffloor[i].b_step-ffloor[i].b_frac)/(range); + i++; + } +#else + if (*rover->bottomheight <= backsector->ceilingheight && + *rover->bottomheight >= backsector->floorheight && + ((viewz < *rover->bottomheight && !(rover->flags & FF_INVERTPLANES)) || + (viewz > *rover->bottomheight && (rover->flags & FF_BOTHPLANES)))) + { + ffloor[i].b_pos = *rover->bottomheight; + ffloor[i].b_pos = (ffloor[i].b_pos - viewz) >> 4; + ffloor[i].b_step = FixedMul(-rw_scalestep, ffloor[i].b_pos); + ffloor[i].b_frac = (centeryfrac >> 4) - FixedMul(ffloor[i].b_pos, rw_scale); + i++; + } + + if (i >= MAXFFLOORS) + break; + + if (*rover->topheight >= backsector->floorheight && + *rover->topheight <= backsector->ceilingheight && + ((viewz > *rover->topheight && !(rover->flags & FF_INVERTPLANES)) || + (viewz < *rover->topheight && (rover->flags & FF_BOTHPLANES)))) + { + ffloor[i].b_pos = *rover->topheight; + ffloor[i].b_pos = (ffloor[i].b_pos - viewz) >> 4; + ffloor[i].b_step = FixedMul(-rw_scalestep, ffloor[i].b_pos); + ffloor[i].b_frac = (centeryfrac >> 4) - FixedMul(ffloor[i].b_pos, rw_scale); + i++; + } +#endif + } + } + else if (frontsector && frontsector->ffloors) + { + for (rover = frontsector->ffloors; rover && i < MAXFFLOORS; rover = rover->next) + { + if (!(rover->flags & FF_EXISTS) || !(rover->flags & FF_RENDERPLANES)) + continue; + if (rover->norender == leveltime) + continue; + + +#ifdef ESLOPE + // Let the renderer know this sector is sloped. + if (*rover->b_slope || *rover->t_slope) + frontsector->hasslope = true; + + roverleft = (*rover->b_slope ? P_GetZAt(*rover->b_slope, segleft.x, segleft.y) : *rover->bottomheight) - viewz; + roverright = (*rover->b_slope ? P_GetZAt(*rover->b_slope, segright.x, segright.y) : *rover->bottomheight) - viewz; + planevistest = (*rover->b_slope ? P_GetZAt(*rover->b_slope, viewx, viewy) : *rover->bottomheight); + + if ((roverleft>>4 <= worldhigh || roverright>>4 <= worldhighslope) && + (roverleft>>4 >= worldlow || roverright>>4 >= worldlowslope) && + ((viewz < planevistest && !(rover->flags & FF_INVERTPLANES)) || + (viewz > planevistest && (rover->flags & FF_BOTHPLANES)))) + { + //ffloor[i].slope = *rover->b_slope; + ffloor[i].b_pos = roverleft; + ffloor[i].b_pos_slope = roverright; + ffloor[i].b_pos >>= 4; + ffloor[i].b_pos_slope >>= 4; + ffloor[i].b_frac = (centeryfrac >> 4) - FixedMul(ffloor[i].b_pos, rw_scale); + ffloor[i].b_step = (centeryfrac >> 4) - FixedMul(ffloor[i].b_pos_slope, ds_p->scale2); + ffloor[i].b_step = (ffloor[i].b_step-ffloor[i].b_frac)/(range); + i++; + } + + if (i >= MAXFFLOORS) + break; + + roverleft = (*rover->t_slope ? P_GetZAt(*rover->t_slope, segleft.x, segleft.y) : *rover->topheight) - viewz; + roverright = (*rover->t_slope ? P_GetZAt(*rover->t_slope, segright.x, segright.y) : *rover->topheight) - viewz; + planevistest = (*rover->t_slope ? P_GetZAt(*rover->t_slope, viewx, viewy) : *rover->topheight); + + if ((roverleft>>4 <= worldhigh || roverright>>4 <= worldhighslope) && + (roverleft>>4 >= worldlow || roverright>>4 >= worldlowslope) && + ((viewz > planevistest && !(rover->flags & FF_INVERTPLANES)) || + (viewz < planevistest && (rover->flags & FF_BOTHPLANES)))) + { + //ffloor[i].slope = *rover->t_slope; + ffloor[i].b_pos = roverleft; + ffloor[i].b_pos_slope = roverright; + ffloor[i].b_pos >>= 4; + ffloor[i].b_pos_slope >>= 4; + ffloor[i].b_frac = (centeryfrac >> 4) - FixedMul(ffloor[i].b_pos, rw_scale); + ffloor[i].b_step = (centeryfrac >> 4) - FixedMul(ffloor[i].b_pos_slope, ds_p->scale2); + ffloor[i].b_step = (ffloor[i].b_step-ffloor[i].b_frac)/(range); + i++; + } +#else + if (*rover->bottomheight <= frontsector->ceilingheight && + *rover->bottomheight >= frontsector->floorheight && + ((viewz < *rover->bottomheight && !(rover->flags & FF_INVERTPLANES)) || + (viewz > *rover->bottomheight && (rover->flags & FF_BOTHPLANES)))) + { + ffloor[i].b_pos = *rover->bottomheight; + ffloor[i].b_pos = (ffloor[i].b_pos - viewz) >> 4; + ffloor[i].b_step = FixedMul(-rw_scalestep, ffloor[i].b_pos); + ffloor[i].b_frac = (centeryfrac >> 4) - FixedMul(ffloor[i].b_pos, rw_scale); + i++; + } + if (i >= MAXFFLOORS) + break; + if (*rover->topheight >= frontsector->floorheight && + *rover->topheight <= frontsector->ceilingheight && + ((viewz > *rover->topheight && !(rover->flags & FF_INVERTPLANES)) || + (viewz < *rover->topheight && (rover->flags & FF_BOTHPLANES)))) + { + ffloor[i].b_pos = *rover->topheight; + ffloor[i].b_pos = (ffloor[i].b_pos - viewz) >> 4; + ffloor[i].b_step = FixedMul(-rw_scalestep, ffloor[i].b_pos); + ffloor[i].b_frac = (centeryfrac >> 4) - FixedMul(ffloor[i].b_pos, rw_scale); + i++; + } +#endif + } + } + +#ifdef POLYOBJECTS_PLANES + if (curline->polyseg && frontsector && (curline->polyseg->flags & POF_RENDERPLANES)) + { + while (i < numffloors && ffloor[i].polyobj != curline->polyseg) i++; + if (i < numffloors && backsector->floorheight <= frontsector->ceilingheight && + backsector->floorheight >= frontsector->floorheight && + (viewz < backsector->floorheight)) + { + if (ffloor[i].plane->minx > ds_p->x1) + ffloor[i].plane->minx = ds_p->x1; + + if (ffloor[i].plane->maxx < ds_p->x2) + ffloor[i].plane->maxx = ds_p->x2; + +#ifdef ESLOPE + ffloor[i].slope = NULL; +#endif + ffloor[i].b_pos = backsector->floorheight; + ffloor[i].b_pos = (ffloor[i].b_pos - viewz) >> 4; + ffloor[i].b_step = FixedMul(-rw_scalestep, ffloor[i].b_pos); + ffloor[i].b_frac = (centeryfrac >> 4) - FixedMul(ffloor[i].b_pos, rw_scale); + i++; + } + if (i < numffloors && backsector->ceilingheight >= frontsector->floorheight && + backsector->ceilingheight <= frontsector->ceilingheight && + (viewz > backsector->ceilingheight)) + { + if (ffloor[i].plane->minx > ds_p->x1) + ffloor[i].plane->minx = ds_p->x1; + + if (ffloor[i].plane->maxx < ds_p->x2) + ffloor[i].plane->maxx = ds_p->x2; + +#ifdef ESLOPE + ffloor[i].slope = NULL; +#endif + ffloor[i].b_pos = backsector->ceilingheight; + ffloor[i].b_pos = (ffloor[i].b_pos - viewz) >> 4; + ffloor[i].b_step = FixedMul(-rw_scalestep, ffloor[i].b_pos); + ffloor[i].b_frac = (centeryfrac >> 4) - FixedMul(ffloor[i].b_pos, rw_scale); + i++; + } + } +#endif + + numbackffloors = i; + } +} + +// +// R_WorldFFloorStep +// Does... stepping... stuff? For FOFs?! +// +static void R_WorldFFloorStep(INT32 range) +{ + INT32 i; + +#ifndef ESLOPE + (void)range; // Not needed! +#endif + + for (i = 0; i < numffloors; i++) + { + ffloor[i].f_pos >>= 4; +#ifdef ESLOPE + ffloor[i].f_pos_slope >>= 4; +#endif + if (linedef->special == HORIZONSPECIAL) // Horizon lines extend FOFs in contact with them too. + { + ffloor[i].f_step = 0; + ffloor[i].f_frac = (centeryfrac>>4); + topfrac++; // Prevent 1px HOM + } + else + { +#ifdef ESLOPE + ffloor[i].f_frac = (centeryfrac>>4) - FixedMul(ffloor[i].f_pos, rw_scale); + ffloor[i].f_step = ((centeryfrac>>4) - FixedMul(ffloor[i].f_pos_slope, ds_p->scale2) - ffloor[i].f_frac)/(range); +#else + ffloor[i].f_step = FixedMul(-rw_scalestep, ffloor[i].f_pos); + ffloor[i].f_frac = (centeryfrac>>4) - FixedMul(ffloor[i].f_pos, rw_scale); +#endif + } + } +} + +// +// R_WorldLightLists +// Creates light lists. +// +static void R_WorldLightLists(INT32 range) +{ + INT32 i, p; + lightlist_t *light; + r_lightlist_t *rlight; + +#ifndef ESLOPE + (void)range; // Not needed! +#endif dc_numlights = 0; @@ -2818,295 +3019,15 @@ void R_StoreWallRange(INT32 start, INT32 stop) dc_numlights = p; } +} - if (numffloors) - { - for (i = 0; i < numffloors; i++) - { - ffloor[i].f_pos >>= 4; -#ifdef ESLOPE - ffloor[i].f_pos_slope >>= 4; -#endif - if (linedef->special == HORIZONSPECIAL) // Horizon lines extend FOFs in contact with them too. - { - ffloor[i].f_step = 0; - ffloor[i].f_frac = (centeryfrac>>4); - topfrac++; // Prevent 1px HOM - } - else - { -#ifdef ESLOPE - ffloor[i].f_frac = (centeryfrac>>4) - FixedMul(ffloor[i].f_pos, rw_scale); - ffloor[i].f_step = ((centeryfrac>>4) - FixedMul(ffloor[i].f_pos_slope, ds_p->scale2) - ffloor[i].f_frac)/(range); -#else - ffloor[i].f_step = FixedMul(-rw_scalestep, ffloor[i].f_pos); - ffloor[i].f_frac = (centeryfrac>>4) - FixedMul(ffloor[i].f_pos, rw_scale); -#endif - } - } - } - - if (backsector) - { - worldhigh >>= 4; - worldlow >>= 4; -#ifdef ESLOPE - worldhighslope >>= 4; - worldlowslope >>= 4; -#endif - - if (toptexture) - { - pixhigh = (centeryfrac>>4) - FixedMul (worldhigh, rw_scale); - pixhighstep = -FixedMul (rw_scalestep,worldhigh); - -#ifdef ESLOPE - if (backsector->c_slope) { - fixed_t topfracend = (centeryfrac>>4) - FixedMul (worldhighslope, ds_p->scale2); - pixhighstep = (topfracend-pixhigh)/(range); - } -#endif - } - - if (bottomtexture) - { - pixlow = (centeryfrac>>4) - FixedMul (worldlow, rw_scale); - pixlowstep = -FixedMul (rw_scalestep,worldlow); -#ifdef ESLOPE - if (backsector->f_slope) { - fixed_t bottomfracend = (centeryfrac>>4) - FixedMul (worldlowslope, ds_p->scale2); - pixlowstep = (bottomfracend-pixlow)/(range); - } -#endif - } - - { - ffloor_t * rover; -#ifdef ESLOPE - fixed_t roverleft, roverright; - fixed_t planevistest; -#endif - i = 0; - - if (backsector->ffloors) - { - for (rover = backsector->ffloors; rover && i < MAXFFLOORS; rover = rover->next) - { - if (!(rover->flags & FF_EXISTS) || !(rover->flags & FF_RENDERPLANES)) - continue; - if (rover->norender == leveltime) - continue; - -#ifdef ESLOPE - // Let the renderer know this sector is sloped. - if (*rover->b_slope || *rover->t_slope) - backsector->hasslope = true; - - roverleft = (*rover->b_slope ? P_GetZAt(*rover->b_slope, segleft.x, segleft.y) : *rover->bottomheight) - viewz; - roverright = (*rover->b_slope ? P_GetZAt(*rover->b_slope, segright.x, segright.y) : *rover->bottomheight) - viewz; - planevistest = (*rover->b_slope ? P_GetZAt(*rover->b_slope, viewx, viewy) : *rover->bottomheight); - - if ((roverleft>>4 <= worldhigh || roverright>>4 <= worldhighslope) && - (roverleft>>4 >= worldlow || roverright>>4 >= worldlowslope) && - ((viewz < planevistest && !(rover->flags & FF_INVERTPLANES)) || - (viewz > planevistest && (rover->flags & FF_BOTHPLANES)))) - { - //ffloor[i].slope = *rover->b_slope; - ffloor[i].b_pos = roverleft; - ffloor[i].b_pos_slope = roverright; - ffloor[i].b_pos >>= 4; - ffloor[i].b_pos_slope >>= 4; - ffloor[i].b_frac = (centeryfrac >> 4) - FixedMul(ffloor[i].b_pos, rw_scale); - ffloor[i].b_step = (centeryfrac >> 4) - FixedMul(ffloor[i].b_pos_slope, ds_p->scale2); - ffloor[i].b_step = (ffloor[i].b_step-ffloor[i].b_frac)/(range); - i++; - } - - if (i >= MAXFFLOORS) - break; - - roverleft = (*rover->t_slope ? P_GetZAt(*rover->t_slope, segleft.x, segleft.y) : *rover->topheight) - viewz; - roverright = (*rover->t_slope ? P_GetZAt(*rover->t_slope, segright.x, segright.y) : *rover->topheight) - viewz; - planevistest = (*rover->t_slope ? P_GetZAt(*rover->t_slope, viewx, viewy) : *rover->topheight); - - if ((roverleft>>4 <= worldhigh || roverright>>4 <= worldhighslope) && - (roverleft>>4 >= worldlow || roverright>>4 >= worldlowslope) && - ((viewz > planevistest && !(rover->flags & FF_INVERTPLANES)) || - (viewz < planevistest && (rover->flags & FF_BOTHPLANES)))) - { - //ffloor[i].slope = *rover->t_slope; - ffloor[i].b_pos = roverleft; - ffloor[i].b_pos_slope = roverright; - ffloor[i].b_pos >>= 4; - ffloor[i].b_pos_slope >>= 4; - ffloor[i].b_frac = (centeryfrac >> 4) - FixedMul(ffloor[i].b_pos, rw_scale); - ffloor[i].b_step = (centeryfrac >> 4) - FixedMul(ffloor[i].b_pos_slope, ds_p->scale2); - ffloor[i].b_step = (ffloor[i].b_step-ffloor[i].b_frac)/(range); - i++; - } -#else - if (*rover->bottomheight <= backsector->ceilingheight && - *rover->bottomheight >= backsector->floorheight && - ((viewz < *rover->bottomheight && !(rover->flags & FF_INVERTPLANES)) || - (viewz > *rover->bottomheight && (rover->flags & FF_BOTHPLANES)))) - { - ffloor[i].b_pos = *rover->bottomheight; - ffloor[i].b_pos = (ffloor[i].b_pos - viewz) >> 4; - ffloor[i].b_step = FixedMul(-rw_scalestep, ffloor[i].b_pos); - ffloor[i].b_frac = (centeryfrac >> 4) - FixedMul(ffloor[i].b_pos, rw_scale); - i++; - } - - if (i >= MAXFFLOORS) - break; - - if (*rover->topheight >= backsector->floorheight && - *rover->topheight <= backsector->ceilingheight && - ((viewz > *rover->topheight && !(rover->flags & FF_INVERTPLANES)) || - (viewz < *rover->topheight && (rover->flags & FF_BOTHPLANES)))) - { - ffloor[i].b_pos = *rover->topheight; - ffloor[i].b_pos = (ffloor[i].b_pos - viewz) >> 4; - ffloor[i].b_step = FixedMul(-rw_scalestep, ffloor[i].b_pos); - ffloor[i].b_frac = (centeryfrac >> 4) - FixedMul(ffloor[i].b_pos, rw_scale); - i++; - } -#endif - } - } - else if (frontsector && frontsector->ffloors) - { - for (rover = frontsector->ffloors; rover && i < MAXFFLOORS; rover = rover->next) - { - if (!(rover->flags & FF_EXISTS) || !(rover->flags & FF_RENDERPLANES)) - continue; - if (rover->norender == leveltime) - continue; - - -#ifdef ESLOPE - // Let the renderer know this sector is sloped. - if (*rover->b_slope || *rover->t_slope) - frontsector->hasslope = true; - - roverleft = (*rover->b_slope ? P_GetZAt(*rover->b_slope, segleft.x, segleft.y) : *rover->bottomheight) - viewz; - roverright = (*rover->b_slope ? P_GetZAt(*rover->b_slope, segright.x, segright.y) : *rover->bottomheight) - viewz; - planevistest = (*rover->b_slope ? P_GetZAt(*rover->b_slope, viewx, viewy) : *rover->bottomheight); - - if ((roverleft>>4 <= worldhigh || roverright>>4 <= worldhighslope) && - (roverleft>>4 >= worldlow || roverright>>4 >= worldlowslope) && - ((viewz < planevistest && !(rover->flags & FF_INVERTPLANES)) || - (viewz > planevistest && (rover->flags & FF_BOTHPLANES)))) - { - //ffloor[i].slope = *rover->b_slope; - ffloor[i].b_pos = roverleft; - ffloor[i].b_pos_slope = roverright; - ffloor[i].b_pos >>= 4; - ffloor[i].b_pos_slope >>= 4; - ffloor[i].b_frac = (centeryfrac >> 4) - FixedMul(ffloor[i].b_pos, rw_scale); - ffloor[i].b_step = (centeryfrac >> 4) - FixedMul(ffloor[i].b_pos_slope, ds_p->scale2); - ffloor[i].b_step = (ffloor[i].b_step-ffloor[i].b_frac)/(range); - i++; - } - - if (i >= MAXFFLOORS) - break; - - roverleft = (*rover->t_slope ? P_GetZAt(*rover->t_slope, segleft.x, segleft.y) : *rover->topheight) - viewz; - roverright = (*rover->t_slope ? P_GetZAt(*rover->t_slope, segright.x, segright.y) : *rover->topheight) - viewz; - planevistest = (*rover->t_slope ? P_GetZAt(*rover->t_slope, viewx, viewy) : *rover->topheight); - - if ((roverleft>>4 <= worldhigh || roverright>>4 <= worldhighslope) && - (roverleft>>4 >= worldlow || roverright>>4 >= worldlowslope) && - ((viewz > planevistest && !(rover->flags & FF_INVERTPLANES)) || - (viewz < planevistest && (rover->flags & FF_BOTHPLANES)))) - { - //ffloor[i].slope = *rover->t_slope; - ffloor[i].b_pos = roverleft; - ffloor[i].b_pos_slope = roverright; - ffloor[i].b_pos >>= 4; - ffloor[i].b_pos_slope >>= 4; - ffloor[i].b_frac = (centeryfrac >> 4) - FixedMul(ffloor[i].b_pos, rw_scale); - ffloor[i].b_step = (centeryfrac >> 4) - FixedMul(ffloor[i].b_pos_slope, ds_p->scale2); - ffloor[i].b_step = (ffloor[i].b_step-ffloor[i].b_frac)/(range); - i++; - } -#else - if (*rover->bottomheight <= frontsector->ceilingheight && - *rover->bottomheight >= frontsector->floorheight && - ((viewz < *rover->bottomheight && !(rover->flags & FF_INVERTPLANES)) || - (viewz > *rover->bottomheight && (rover->flags & FF_BOTHPLANES)))) - { - ffloor[i].b_pos = *rover->bottomheight; - ffloor[i].b_pos = (ffloor[i].b_pos - viewz) >> 4; - ffloor[i].b_step = FixedMul(-rw_scalestep, ffloor[i].b_pos); - ffloor[i].b_frac = (centeryfrac >> 4) - FixedMul(ffloor[i].b_pos, rw_scale); - i++; - } - if (i >= MAXFFLOORS) - break; - if (*rover->topheight >= frontsector->floorheight && - *rover->topheight <= frontsector->ceilingheight && - ((viewz > *rover->topheight && !(rover->flags & FF_INVERTPLANES)) || - (viewz < *rover->topheight && (rover->flags & FF_BOTHPLANES)))) - { - ffloor[i].b_pos = *rover->topheight; - ffloor[i].b_pos = (ffloor[i].b_pos - viewz) >> 4; - ffloor[i].b_step = FixedMul(-rw_scalestep, ffloor[i].b_pos); - ffloor[i].b_frac = (centeryfrac >> 4) - FixedMul(ffloor[i].b_pos, rw_scale); - i++; - } -#endif - } - } -#ifdef POLYOBJECTS_PLANES - if (curline->polyseg && frontsector && (curline->polyseg->flags & POF_RENDERPLANES)) - { - while (i < numffloors && ffloor[i].polyobj != curline->polyseg) i++; - if (i < numffloors && backsector->floorheight <= frontsector->ceilingheight && - backsector->floorheight >= frontsector->floorheight && - (viewz < backsector->floorheight)) - { - if (ffloor[i].plane->minx > ds_p->x1) - ffloor[i].plane->minx = ds_p->x1; - - if (ffloor[i].plane->maxx < ds_p->x2) - ffloor[i].plane->maxx = ds_p->x2; - -#ifdef ESLOPE - ffloor[i].slope = NULL; -#endif - ffloor[i].b_pos = backsector->floorheight; - ffloor[i].b_pos = (ffloor[i].b_pos - viewz) >> 4; - ffloor[i].b_step = FixedMul(-rw_scalestep, ffloor[i].b_pos); - ffloor[i].b_frac = (centeryfrac >> 4) - FixedMul(ffloor[i].b_pos, rw_scale); - i++; - } - if (i < numffloors && backsector->ceilingheight >= frontsector->floorheight && - backsector->ceilingheight <= frontsector->ceilingheight && - (viewz > backsector->ceilingheight)) - { - if (ffloor[i].plane->minx > ds_p->x1) - ffloor[i].plane->minx = ds_p->x1; - - if (ffloor[i].plane->maxx < ds_p->x2) - ffloor[i].plane->maxx = ds_p->x2; - -#ifdef ESLOPE - ffloor[i].slope = NULL; -#endif - ffloor[i].b_pos = backsector->ceilingheight; - ffloor[i].b_pos = (ffloor[i].b_pos - viewz) >> 4; - ffloor[i].b_step = FixedMul(-rw_scalestep, ffloor[i].b_pos); - ffloor[i].b_frac = (centeryfrac >> 4) - FixedMul(ffloor[i].b_pos, rw_scale); - i++; - } - } -#endif - - numbackffloors = i; - } - } +// +// R_MarkPlanes +// Creates visplanes. +// +static void R_MarkPlanes(void) +{ + INT32 i; // get a new or use the same visplane if (markceiling) @@ -3173,6 +3094,231 @@ void R_StoreWallRange(INT32 start, INT32 stop) } #endif } +} + +// +// R_RemoveOpeningLimits +// Code to remove limits on openings. +// +static void R_RemoveOpeningLimits(INT32 start) +{ + size_t pos = lastopening - openings; + size_t need = (rw_stopx - start)*4 + pos; + if (need > maxopenings) + { + drawseg_t *ds; //needed for fix from *cough* zdoom *cough* + INT16 *oldopenings = openings; + INT16 *oldlast = lastopening; + + do + maxopenings = maxopenings ? maxopenings*2 : 16384; + while (need > maxopenings); + openings = Z_Realloc(openings, maxopenings * sizeof (*openings), PU_STATIC, NULL); + lastopening = openings + pos; + + // borrowed fix from *cough* zdoom *cough* + // [RH] We also need to adjust the openings pointers that + // were already stored in drawsegs. + for (ds = drawsegs; ds < ds_p; ds++) + { +#define ADJUST(p) if (ds->p + ds->x1 >= oldopenings && ds->p + ds->x1 <= oldlast) ds->p = ds->p - oldopenings + openings; + ADJUST(maskedtexturecol); + ADJUST(sprtopclip); + ADJUST(sprbottomclip); + ADJUST(thicksidecol); +#undef ADJUST + } + } +} + +// +// R_StoreWallRange +// A wall segment will be drawn +// between start and stop pixels (inclusive). +// +void R_StoreWallRange(INT32 start, INT32 stop) +{ + fixed_t hyp; + fixed_t sineval; + angle_t distangle, offsetangle; + boolean longboi; +#ifndef ESLOPE + fixed_t vtop; +#endif + INT32 i; + INT32 range; + static size_t maxdrawsegs = 0; + +#ifdef ESLOPE + maskedtextureheight = NULL; + //initialize segleft and segright + memset(&segleft, 0x00, sizeof(segleft)); + memset(&segright, 0x00, sizeof(segright)); +#endif + + colfunc = colfuncs[BASEDRAWFUNC]; + + if (ds_p == drawsegs+maxdrawsegs) + { + size_t curpos = curdrawsegs - drawsegs; + size_t pos = ds_p - drawsegs; + size_t newmax = maxdrawsegs ? maxdrawsegs*2 : 128; + if (firstseg) + firstseg = (drawseg_t *)(firstseg - drawsegs); + drawsegs = Z_Realloc(drawsegs, newmax*sizeof (*drawsegs), PU_STATIC, NULL); + ds_p = drawsegs + pos; + maxdrawsegs = newmax; + curdrawsegs = drawsegs + curpos; + if (firstseg) + firstseg = drawsegs + (size_t)firstseg; + } + + sidedef = curline->sidedef; + linedef = curline->linedef; + + // calculate rw_distance for scale calculation + rw_normalangle = curline->angle + ANGLE_90; + offsetangle = abs((INT32)(rw_normalangle-rw_angle1)); + + if (offsetangle > ANGLE_90) + offsetangle = ANGLE_90; + + distangle = ANGLE_90 - offsetangle; + sineval = FINESINE(distangle>>ANGLETOFINESHIFT); + + hyp = R_PointToDist(curline->v1->x, curline->v1->y); + rw_distance = FixedMul(hyp, sineval); + longboi = (hyp >= INT32_MAX); + + // big room fix + if (longboi) + rw_distance = (fixed_t)R_CalculateSegDistance(curline,viewx,viewy); + + ds_p->x1 = rw_x = start; + ds_p->x2 = stop; + ds_p->curline = curline; + rw_stopx = stop+1; + + //SoM: Code to remove limits on openings. + R_RemoveOpeningLimits(start); + + // calculate scale at both ends and step + range = R_CalculateWallScale(start, stop); + + // calculate texture boundaries + // and decide if floor / ceiling marks are needed + R_WorldTopAndBottom(start, stop); + + midtexture = toptexture = bottomtexture = maskedtexture = 0; + ds_p->maskedtexturecol = NULL; + ds_p->numthicksides = numthicksides = 0; + ds_p->thicksidecol = NULL; + ds_p->tsilheight = 0; + + numbackffloors = 0; + + for (i = 0; i < MAXFFLOORS; i++) + ds_p->thicksides[i] = NULL; + + if (numffloors) + { + for (i = 0; i < numffloors; i++) + { +#ifdef POLYOBJECTS_PLANES + if (ffloor[i].polyobj && (!ds_p->curline->polyseg || ffloor[i].polyobj != ds_p->curline->polyseg)) + continue; +#endif + +#ifdef ESLOPE + if (ffloor[i].slope) { + ffloor[i].f_pos = P_GetZAt(ffloor[i].slope, segleft.x, segleft.y) - viewz; + ffloor[i].f_pos_slope = P_GetZAt(ffloor[i].slope, segright.x, segright.y) - viewz; + } else + ffloor[i].f_pos_slope = +#endif + ffloor[i].f_pos = ffloor[i].height - viewz; + } + } + +#ifdef ESLOPE + // Set up texture Y offset slides for sloped walls + rw_toptextureslide = rw_midtextureslide = rw_bottomtextureslide = 0; + ceilingfrontslide = floorfrontslide = ceilingbackslide = floorbackslide = 0; + + { + angle_t lineangle = R_PointToAngle2(curline->v1->x, curline->v1->y, curline->v2->x, curline->v2->y); + + if (frontsector->f_slope) + floorfrontslide = FixedMul(frontsector->f_slope->zdelta, FINECOSINE((lineangle-frontsector->f_slope->xydirection)>>ANGLETOFINESHIFT)); + + if (frontsector->c_slope) + ceilingfrontslide = FixedMul(frontsector->c_slope->zdelta, FINECOSINE((lineangle-frontsector->c_slope->xydirection)>>ANGLETOFINESHIFT)); + + if (backsector && backsector->f_slope) + floorbackslide = FixedMul(backsector->f_slope->zdelta, FINECOSINE((lineangle-backsector->f_slope->xydirection)>>ANGLETOFINESHIFT)); + + if (backsector && backsector->c_slope) + ceilingbackslide = FixedMul(backsector->c_slope->zdelta, FINECOSINE((lineangle-backsector->c_slope->xydirection)>>ANGLETOFINESHIFT)); + } +#endif + + // Check for textures + R_StoreWallSilhouette(); + R_CheckWallTextures(); + if (backsector) + R_CheckMaskedTextures(); + +#undef SLOPEPARAMS + + // Calculate rw_offset (only needed for textured lines) + segtextured = midtexture || toptexture || bottomtexture || maskedtexture || (numthicksides > 0); + if (segtextured) + R_WorldSegTextured(hyp, longboi); + + // if a floor / ceiling plane is on the wrong side + // of the view plane, it is definitely invisible + // and doesn't need to be marked. + if (frontsector->heightsec == -1) + { + if (frontsector->floorpic != skyflatnum + && ( +#ifdef ESLOPE + frontsector->f_slope ? P_GetZAt(frontsector->f_slope, viewx, viewy) : +#endif + frontsector->floorheight) >= viewz) + { + // above view plane + markfloor = false; + } + + if (frontsector->ceilingpic != skyflatnum + && ( +#ifdef ESLOPE + frontsector->c_slope ? P_GetZAt(frontsector->c_slope, viewx, viewy) : +#endif + frontsector->ceilingheight) <= viewz) + { + // below view plane + markceiling = false; + } + } + + // Calculate incremental stepping values for texture edges + R_WorldStep(range); + + // Create light lists + R_WorldLightLists(range); + + // Step FOFs + if (numffloors) + R_WorldFFloorStep(range); + + // Step world back + if (backsector) + R_WorldBackStep(range); + + // Mark floor and or ceiling visplanes + R_MarkPlanes(); #ifdef WALLSPLATS if (linedef->splats && cv_splats.value) @@ -3220,5 +3366,6 @@ void R_StoreWallRange(INT32 start, INT32 stop) ds_p->silhouette |= SIL_BOTTOM; ds_p->bsilheight = (sidedef->midtexture > 0 && sidedef->midtexture < numtextures) ? INT32_MAX: INT32_MIN; } + ds_p++; } From 69e97840856423abfc25f0636e1649f11dd75be1 Mon Sep 17 00:00:00 2001 From: Jaime Passos Date: Thu, 26 Dec 2019 00:55:34 -0300 Subject: [PATCH 28/79] Something in R_RenderSegLoop I thought looked off... --- src/r_segs.c | 28 ++++++++++++++-------------- 1 file changed, 14 insertions(+), 14 deletions(-) diff --git a/src/r_segs.c b/src/r_segs.c index c131af9ed..bc2996011 100644 --- a/src/r_segs.c +++ b/src/r_segs.c @@ -1349,7 +1349,7 @@ UINT32 nombre = 100000; static void R_RenderSegLoop (void) { angle_t angle; - size_t pindex; + size_t pindex = 0; INT32 yl; INT32 yh; @@ -1362,6 +1362,10 @@ static void R_RenderSegLoop (void) INT32 bottom; INT32 i; + // Set the shadowed column drawer for light lists. + if (dc_numlights) + colfunc = colfuncs[COLDRAWFUNC_SHADOWED]; + for (; rw_x < rw_stopx; rw_x++) { // mark floor / ceiling areas @@ -1472,6 +1476,15 @@ static void R_RenderSegLoop (void) } } + // Calculate lighting. + // Done for light lists anyway to avoid doing it for every light. + if (segtextured || dc_numlights) + { + pindex = FixedMul(rw_scale, FixedDiv(640, vid.width))>>LIGHTSCALESHIFT; + if (pindex >= MAXLIGHTSCALE) + pindex = MAXLIGHTSCALE-1; + } + //SoM: Calculate offsets for Thick fake floors. // calculate texture offset angle = (rw_centerangle + xtoviewangle[rw_x])>>ANGLETOFINESHIFT; @@ -1492,12 +1505,6 @@ static void R_RenderSegLoop (void) // texturecolumn and lighting are independent of wall tiers if (segtextured) { - // calculate lighting - pindex = FixedMul(rw_scale, FixedDiv(640, vid.width))>>LIGHTSCALESHIFT; - - if (pindex >= MAXLIGHTSCALE) - pindex = MAXLIGHTSCALE-1; - dc_colormap = walllights[pindex]; dc_x = rw_x; dc_iscale = 0xffffffffu / (unsigned)rw_scale; @@ -1528,17 +1535,10 @@ static void R_RenderSegLoop (void) else xwalllights = scalelight[lightnum]; - pindex = FixedMul(rw_scale, FixedDiv(640, vid.width))>>LIGHTSCALESHIFT; - - if (pindex >= MAXLIGHTSCALE) - pindex = MAXLIGHTSCALE-1; - if (dc_lightlist[i].extra_colormap) dc_lightlist[i].rcolormap = dc_lightlist[i].extra_colormap->colormap + (xwalllights[pindex] - colormaps); else dc_lightlist[i].rcolormap = xwalllights[pindex]; - - colfunc = colfuncs[COLDRAWFUNC_SHADOWED]; } } From 649455c2d0890770e02922776368749c70e18063 Mon Sep 17 00:00:00 2001 From: Jaime Passos Date: Thu, 26 Dec 2019 01:58:38 -0300 Subject: [PATCH 29/79] R_CalculateSegDistance stuff... --- src/p_setup.c | 5 +--- src/r_defs.h | 3 +- src/r_segs.c | 77 +++++++++++++++++++++++++++++++++++++++++++++------ 3 files changed, 72 insertions(+), 13 deletions(-) diff --git a/src/p_setup.c b/src/p_setup.c index bf3493d8c..06344a0e3 100644 --- a/src/p_setup.c +++ b/src/p_setup.c @@ -416,9 +416,7 @@ fixed_t P_SegLength(seg_t *seg) return FixedHypot(dx, dy)<<1; } -#ifdef HWRENDER /** Computes the length of a seg as a float. - * This is needed for OpenGL. * * \param seg Seg to compute length for. * \return Length as a float. @@ -433,7 +431,6 @@ static inline float P_SegLengthFloat(seg_t *seg) return (float)hypot(dx, dy); } -#endif /** Loads the SEGS resource from a level. * @@ -460,10 +457,10 @@ static void P_LoadRawSegs(UINT8 *data, size_t i) li->v2 = &vertexes[SHORT(ml->v2)]; li->length = P_SegLength(li); + li->flength = P_SegLengthFloat(li); #ifdef HWRENDER if (rendermode == render_opengl) { - li->flength = P_SegLengthFloat(li); //Hurdler: 04/12/2000: for now, only used in hardware mode li->lightmaps = NULL; // list of static lightmap for this seg } diff --git a/src/r_defs.h b/src/r_defs.h index 3cc780545..bc0343730 100644 --- a/src/r_defs.h +++ b/src/r_defs.h @@ -582,11 +582,12 @@ typedef struct seg_s sector_t *backsector; fixed_t length; // precalculated seg length + float flength; // ditto but float + #ifdef HWRENDER // new pointers so that AdjustSegs doesn't mess with v1/v2 void *pv1; // polyvertex_t void *pv2; // polyvertex_t - float flength; // length of the seg, used by hardware renderer lightmap_t *lightmaps; // for static lightmap #endif diff --git a/src/r_segs.c b/src/r_segs.c index bc2996011..241402d44 100644 --- a/src/r_segs.c +++ b/src/r_segs.c @@ -50,6 +50,9 @@ angle_t rw_normalangle; angle_t rw_angle1; fixed_t rw_distance; +// for R_CalculateSegDistance +#define SOFTWARE_USE_FLOATS + // // regular wall // @@ -1706,22 +1709,73 @@ static void R_RenderSegLoop (void) // // R_CalculateSegDistance // Calculate the distance from a seg. -// Uses precalculated seg->length. +// Uses precalculated seg length. // -static INT64 R_CalculateSegDistance(seg_t* seg, INT64 x2, INT64 y2) +static void R_CalculateSegDistance(seg_t *seg, INT64 x2, INT64 y2, boolean longboi) { +#ifdef SOFTWARE_USE_FLOATS + float v1x = FIXED_TO_FLOAT(seg->v1->x); + float v1y = FIXED_TO_FLOAT(seg->v1->y); + float v2x = FIXED_TO_FLOAT(seg->v2->x); + float v2y = FIXED_TO_FLOAT(seg->v2->y); + float dx, dy, vdx, vdy; + float distance = 0.0f; + + // The seg is vertical. if (!seg->linedef->dy) - return llabs(y2 - seg->v1->y); + distance = fabsf(y2 - v1y); + // The seg is horizontal. else if (!seg->linedef->dx) - return llabs(x2 - seg->v1->x); + distance = fabsf(x2 - v1x); + // Uses precalculated seg->flength + else if (longboi) + { + dx = v2x-v1x; + dy = v2y-v1y; + vdx = x2-v1x; + vdy = y2-v1y; + distance = ((dy*vdx)-(dx*vdy))/(seg->flength); + } + // Linguica's fix converted to floating-point math + else + { + fixed_t x, y; + float a, c, ac; + + v1x -= FIXED_TO_FLOAT(viewx); + v1y -= FIXED_TO_FLOAT(viewy); + v2x -= FIXED_TO_FLOAT(viewx); + v2y -= FIXED_TO_FLOAT(viewy); + dx = v2x - v1x; + dy = v2y - v1y; + + a = (v1x*v2y) - (v1y*v2x); + c = (dx*dx) + (dy*dy); + ac = (a/c); + + x = FLOAT_TO_FIXED(ac*(-dy)); + y = FLOAT_TO_FIXED(ac*dx); + + rw_distance = R_PointToDist(viewx + x, viewy + y); + return; + } + + rw_distance = FLOAT_TO_FIXED(distance); +#else + (void)longboi; + if (!seg->linedef->dy) + rw_distance = (fixed_t)(llabs(y2 - seg->v1->y)); + else if (!seg->linedef->dx) + rw_distance = (fixed_t)(llabs(x2 - seg->v1->x)); else { INT64 dx = (seg->v2->x)-(seg->v1->x); INT64 dy = (seg->v2->y)-(seg->v1->y); INT64 vdx = x2-(seg->v1->x); INT64 vdy = y2-(seg->v1->y); - return ((dy*vdx)-(dx*vdy))/(seg->length); + rw_distance = (fixed_t)(((dy*vdx)-(dx*vdy))/(seg->length)); } +#endif } // @@ -3187,12 +3241,19 @@ void R_StoreWallRange(INT32 start, INT32 stop) sineval = FINESINE(distangle>>ANGLETOFINESHIFT); hyp = R_PointToDist(curline->v1->x, curline->v1->y); - rw_distance = FixedMul(hyp, sineval); longboi = (hyp >= INT32_MAX); + // The seg is vertical. + if (curline->v1->y == curline->v2->y) + rw_distance = (fixed_t)(llabs(viewy - curline->v1->y)); + // The seg is horizontal. + else if (curline->v1->x == curline->v2->x) + rw_distance = (fixed_t)(llabs(viewx - curline->v1->x)); // big room fix - if (longboi) - rw_distance = (fixed_t)R_CalculateSegDistance(curline,viewx,viewy); + else if ((curline->length >= 1024<x1 = rw_x = start; ds_p->x2 = stop; From e09838224e6ff998327a8d6de9e5a6eb791e54d5 Mon Sep 17 00:00:00 2001 From: Jaime Passos Date: Thu, 26 Dec 2019 15:27:16 -0300 Subject: [PATCH 30/79] ifdef this right so it works like before without the define --- src/r_segs.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/r_segs.c b/src/r_segs.c index 241402d44..0066579ac 100644 --- a/src/r_segs.c +++ b/src/r_segs.c @@ -3250,7 +3250,11 @@ void R_StoreWallRange(INT32 start, INT32 stop) else if (curline->v1->x == curline->v2->x) rw_distance = (fixed_t)(llabs(viewx - curline->v1->x)); // big room fix +#ifdef SOFTWARE_USE_FLOATS else if ((curline->length >= 1024< Date: Thu, 26 Dec 2019 15:34:33 -0300 Subject: [PATCH 31/79] Move all the thick/masked/splat stuff to the end of the file --- src/r_segs.c | 2472 +++++++++++++++++++++++++------------------------- 1 file changed, 1236 insertions(+), 1236 deletions(-) diff --git a/src/r_segs.c b/src/r_segs.c index 0066579ac..b132ca976 100644 --- a/src/r_segs.c +++ b/src/r_segs.c @@ -78,1242 +78,6 @@ static INT16 *maskedtexturecol; static fixed_t *maskedtextureheight = NULL; #endif -// ========================================================================== -// R_Splats Wall Splats Drawer -// ========================================================================== - -#ifdef WALLSPLATS -static INT16 last_ceilingclip[MAXVIDWIDTH]; -static INT16 last_floorclip[MAXVIDWIDTH]; - -static void R_DrawSplatColumn(column_t *column) -{ - INT32 topscreen, bottomscreen; - fixed_t basetexturemid; - INT32 topdelta, prevdelta = -1; - - basetexturemid = dc_texturemid; - - for (; column->topdelta != 0xff ;) - { - // calculate unclipped screen coordinates for post - topdelta = column->topdelta; - if (topdelta <= prevdelta) - topdelta += prevdelta; - prevdelta = topdelta; - topscreen = sprtopscreen + spryscale*topdelta; - bottomscreen = topscreen + spryscale*column->length; - - dc_yl = (topscreen+FRACUNIT-1)>>FRACBITS; - dc_yh = (bottomscreen-1)>>FRACBITS; - - if (dc_yh >= last_floorclip[dc_x]) - dc_yh = last_floorclip[dc_x] - 1; - if (dc_yl <= last_ceilingclip[dc_x]) - dc_yl = last_ceilingclip[dc_x] + 1; - if (dc_yl <= dc_yh && dl_yh < vid.height && yh > 0) - { - dc_source = (UINT8 *)column + 3; - dc_texturemid = basetexturemid - (topdelta<length + 4); - } - - dc_texturemid = basetexturemid; -} - -static void R_DrawWallSplats(void) -{ - wallsplat_t *splat; - seg_t *seg; - angle_t angle, angle1, angle2; - INT32 x1, x2; - size_t pindex; - column_t *col; - patch_t *patch; - fixed_t texturecolumn; - - splat = (wallsplat_t *)linedef->splats; - - I_Assert(splat != NULL); - - seg = ds_p->curline; - - // draw all splats from the line that touches the range of the seg - for (; splat; splat = splat->next) - { - angle1 = R_PointToAngle(splat->v1.x, splat->v1.y); - angle2 = R_PointToAngle(splat->v2.x, splat->v2.y); - angle1 = (angle1 - viewangle + ANGLE_90)>>ANGLETOFINESHIFT; - angle2 = (angle2 - viewangle + ANGLE_90)>>ANGLETOFINESHIFT; - // out of the viewangletox lut - /// \todo clip it to the screen - if (angle1 > FINEANGLES/2 || angle2 > FINEANGLES/2) - continue; - x1 = viewangletox[angle1]; - x2 = viewangletox[angle2]; - - if (x1 >= x2) - continue; // does not cross a pixel - - // splat is not in this seg range - if (x2 < ds_p->x1 || x1 > ds_p->x2) - continue; - - if (x1 < ds_p->x1) - x1 = ds_p->x1; - if (x2 > ds_p->x2) - x2 = ds_p->x2; - if (x2 <= x1) - continue; - - // calculate incremental stepping values for texture edges - rw_scalestep = ds_p->scalestep; - spryscale = ds_p->scale1 + (x1 - ds_p->x1)*rw_scalestep; - mfloorclip = floorclip; - mceilingclip = ceilingclip; - - patch = W_CachePatchNum(splat->patch, PU_CACHE); - - dc_texturemid = splat->top + (SHORT(patch->height)<<(FRACBITS-1)) - viewz; - if (splat->yoffset) - dc_texturemid += *splat->yoffset; - - sprtopscreen = centeryfrac - FixedMul(dc_texturemid, spryscale); - - // set drawing mode - switch (splat->flags & SPLATDRAWMODE_MASK) - { - case SPLATDRAWMODE_OPAQUE: - colfunc = colfuncs[BASEDRAWFUNC]; - break; - case SPLATDRAWMODE_TRANS: - if (!cv_translucency.value) - colfunc = colfuncs[BASEDRAWFUNC]; - else - { - dc_transmap = transtables + ((tr_trans50 - 1)<>LIGHTSCALESHIFT; - if (pindex >= MAXLIGHTSCALE) - pindex = MAXLIGHTSCALE - 1; - dc_colormap = walllights[pindex]; - - if (frontsector->extra_colormap) - dc_colormap = frontsector->extra_colormap->colormap + (dc_colormap - colormaps); - - sprtopscreen = centeryfrac - FixedMul(dc_texturemid, spryscale); - dc_iscale = 0xffffffffu / (unsigned)spryscale; - - // find column of patch, from perspective - angle = (rw_centerangle + xtoviewangle[dc_x])>>ANGLETOFINESHIFT; - texturecolumn = rw_offset2 - splat->offset - - FixedMul(FINETANGENT(angle), rw_distance); - - // FIXME! - texturecolumn >>= FRACBITS; - if (texturecolumn < 0 || texturecolumn >= SHORT(patch->width)) - continue; - - // draw the texture - col = (column_t *)((UINT8 *)patch + LONG(patch->columnofs[texturecolumn])); - R_DrawSplatColumn(col); - } - } // next splat - - colfunc = colfuncs[BASEDRAWFUNC]; -} - -#endif //WALLSPLATS - -// ========================================================================== -// R_RenderMaskedSegRange -// ========================================================================== - -// If we have a multi-patch texture on a 2sided wall (rare) then we draw -// it using R_DrawColumn, else we draw it using R_DrawMaskedColumn, this -// way we don't have to store extra post_t info with each column for -// multi-patch textures. They are not normally needed as multi-patch -// textures don't have holes in it. At least not for now. -static INT32 column2s_length; // column->length : for multi-patch on 2sided wall = texture->height - -static void R_Render2sidedMultiPatchColumn(column_t *column) -{ - INT32 topscreen, bottomscreen; - - topscreen = sprtopscreen; // + spryscale*column->topdelta; topdelta is 0 for the wall - bottomscreen = topscreen + spryscale * column2s_length; - - dc_yl = (sprtopscreen+FRACUNIT-1)>>FRACBITS; - dc_yh = (bottomscreen-1)>>FRACBITS; - - if (windowtop != INT32_MAX && windowbottom != INT32_MAX) - { - dc_yl = ((windowtop + FRACUNIT)>>FRACBITS); - dc_yh = (windowbottom - 1)>>FRACBITS; - } - - if (dc_yh >= mfloorclip[dc_x]) - dc_yh = mfloorclip[dc_x] - 1; - if (dc_yl <= mceilingclip[dc_x]) - dc_yl = mceilingclip[dc_x] + 1; - - if (dc_yl >= vid.height || dc_yh < 0) - return; - - if (dc_yl <= dc_yh && dc_yh < vid.height && dc_yh > 0) - { - dc_source = (UINT8 *)column + 3; - - if (colfunc == colfuncs[BASEDRAWFUNC]) - (colfuncs[COLDRAWFUNC_TWOSMULTIPATCH])(); - else if (colfunc == colfuncs[COLDRAWFUNC_FUZZY]) - (colfuncs[COLDRAWFUNC_TWOSMULTIPATCHTRANS])(); - else - colfunc(); - } -} - -// quick wrapper for R_DrawFlippedMaskedColumn so it can be set as a colfunc_2s value -// uses column2s_length for texture->height as above -static void R_DrawFlippedMaskedSegColumn(column_t *column) -{ - R_DrawFlippedMaskedColumn(column, column2s_length); -} - -void R_RenderMaskedSegRange(drawseg_t *ds, INT32 x1, INT32 x2) -{ - size_t pindex; - column_t *col; - INT32 lightnum, texnum, i; - fixed_t height, realbot; - lightlist_t *light; - r_lightlist_t *rlight; - void (*colfunc_2s)(column_t *); - line_t *ldef; - sector_t *front, *back; - INT32 times, repeats; - INT64 overflow_test; -#ifdef ESLOPE - INT32 range; -#endif - - // Calculate light table. - // Use different light tables - // for horizontal / vertical / diagonal. Diagonal? - // OPTIMIZE: get rid of LIGHTSEGSHIFT globally - curline = ds->curline; - frontsector = curline->frontsector; - backsector = curline->backsector; - texnum = R_GetTextureNum(curline->sidedef->midtexture); - windowbottom = windowtop = sprbotscreen = INT32_MAX; - - // hack translucent linedef types (900-909 for transtables 1-9) - ldef = curline->linedef; - switch (ldef->special) - { - case 900: - case 901: - case 902: - case 903: - case 904: - case 905: - case 906: - case 907: - case 908: - dc_transmap = transtables + ((ldef->special-900)<ceilingheight; - windowbottom = frontsector->floorheight; - break; - default: - colfunc = colfuncs[BASEDRAWFUNC]; - break; - } - - if (curline->polyseg && curline->polyseg->translucency > 0) - { - if (curline->polyseg->translucency >= NUMTRANSMAPS) - return; - - dc_transmap = transtables + ((curline->polyseg->translucency-1)<x2-ds->x1, 1); -#endif - rw_scalestep = ds->scalestep; - spryscale = ds->scale1 + (x1 - ds->x1)*rw_scalestep; - - // Texture must be cached before setting colfunc_2s, - // otherwise texture[texnum]->holes may be false when it shouldn't be - R_CheckTextureCache(texnum); - // handle case where multipatch texture is drawn on a 2sided wall, multi-patch textures - // are not stored per-column with post info in SRB2 - if (textures[texnum]->holes) - { - if (textures[texnum]->flip & 2) // vertically flipped? - { - colfunc_2s = R_DrawFlippedMaskedSegColumn; - column2s_length = textures[texnum]->height; - } - else - colfunc_2s = R_DrawMaskedColumn; // render the usual 2sided single-patch packed texture - } - else - { - colfunc_2s = R_Render2sidedMultiPatchColumn; // render multipatch with no holes (no post_t info) - column2s_length = textures[texnum]->height; - } - - // Setup lighting based on the presence/lack-of 3D floors. - dc_numlights = 0; - if (frontsector->numlights) - { - dc_numlights = frontsector->numlights; - if (dc_numlights >= dc_maxlights) - { - dc_maxlights = dc_numlights; - dc_lightlist = Z_Realloc(dc_lightlist, sizeof (*dc_lightlist) * dc_maxlights, PU_STATIC, NULL); - } - - for (i = 0; i < dc_numlights; i++) - { -#ifdef ESLOPE - fixed_t leftheight, rightheight; -#endif - light = &frontsector->lightlist[i]; - rlight = &dc_lightlist[i]; -#ifdef ESLOPE - if (light->slope) { - leftheight = P_GetZAt(light->slope, ds->leftpos.x, ds->leftpos.y); - rightheight = P_GetZAt(light->slope, ds->rightpos.x, ds->rightpos.y); - } else - leftheight = rightheight = light->height; - - leftheight -= viewz; - rightheight -= viewz; - - rlight->height = (centeryfrac) - FixedMul(leftheight, ds->scale1); - rlight->heightstep = (centeryfrac) - FixedMul(rightheight, ds->scale2); - rlight->heightstep = (rlight->heightstep-rlight->height)/(range); - //if (x1 > ds->x1) - //rlight->height -= (x1 - ds->x1)*rlight->heightstep; -#else - rlight->height = (centeryfrac) - FixedMul((light->height - viewz), spryscale); - rlight->heightstep = -FixedMul(rw_scalestep, (light->height - viewz)); -#endif - rlight->startheight = rlight->height; // keep starting value here to reset for each repeat - rlight->lightlevel = *light->lightlevel; - rlight->extra_colormap = *light->extra_colormap; - rlight->flags = light->flags; - - if (rlight->flags & FF_FOG || (rlight->extra_colormap && rlight->extra_colormap->fog)) - lightnum = (rlight->lightlevel >> LIGHTSEGSHIFT); - else if (colfunc == colfuncs[COLDRAWFUNC_FUZZY]) - lightnum = LIGHTLEVELS - 1; - else - lightnum = (rlight->lightlevel >> LIGHTSEGSHIFT); - - if (rlight->extra_colormap && rlight->extra_colormap->fog) - ; - else if (curline->v1->y == curline->v2->y) - lightnum--; - else if (curline->v1->x == curline->v2->x) - lightnum++; - - rlight->lightnum = lightnum; - } - } - else - { - if (colfunc == colfuncs[COLDRAWFUNC_FUZZY]) - { - if (frontsector->extra_colormap && frontsector->extra_colormap->fog) - lightnum = (frontsector->lightlevel >> LIGHTSEGSHIFT); - else - lightnum = LIGHTLEVELS - 1; - } - else - lightnum = (frontsector->lightlevel >> LIGHTSEGSHIFT); - - if (colfunc == colfuncs[COLDRAWFUNC_FOG] - || (frontsector->extra_colormap && frontsector->extra_colormap->fog)) - ; - else if (curline->v1->y == curline->v2->y) - lightnum--; - else if (curline->v1->x == curline->v2->x) - lightnum++; - - if (lightnum < 0) - walllights = scalelight[0]; - else if (lightnum >= LIGHTLEVELS) - walllights = scalelight[LIGHTLEVELS - 1]; - else - walllights = scalelight[lightnum]; - } - - maskedtexturecol = ds->maskedtexturecol; - - mfloorclip = ds->sprbottomclip; - mceilingclip = ds->sprtopclip; - - if (frontsector->heightsec != -1) - front = §ors[frontsector->heightsec]; - else - front = frontsector; - - if (backsector->heightsec != -1) - back = §ors[backsector->heightsec]; - else - back = backsector; - - if (ds->curline->sidedef->repeatcnt) - repeats = 1 + ds->curline->sidedef->repeatcnt; - else if (ldef->flags & ML_EFFECT5) - { - fixed_t high, low; - - if (front->ceilingheight > back->ceilingheight) - high = back->ceilingheight; - else - high = front->ceilingheight; - - if (front->floorheight > back->floorheight) - low = front->floorheight; - else - low = back->floorheight; - - repeats = (high - low)/textureheight[texnum]; - if ((high-low)%textureheight[texnum]) - repeats++; // tile an extra time to fill the gap -- Monster Iestyn - } - else - repeats = 1; - - for (times = 0; times < repeats; times++) - { - if (times > 0) - { - rw_scalestep = ds->scalestep; - spryscale = ds->scale1 + (x1 - ds->x1)*rw_scalestep; - if (dc_numlights) - { // reset all lights to their starting heights - for (i = 0; i < dc_numlights; i++) - { - rlight = &dc_lightlist[i]; - rlight->height = rlight->startheight; - } - } - } - -#ifndef ESLOPE - if (curline->linedef->flags & ML_DONTPEGBOTTOM) - { - dc_texturemid = front->floorheight > back->floorheight - ? front->floorheight : back->floorheight; - dc_texturemid = dc_texturemid + textureheight[texnum] - viewz; - } - else - { - dc_texturemid = front->ceilingheight < back->ceilingheight - ? front->ceilingheight : back->ceilingheight; - dc_texturemid = dc_texturemid - viewz; - } - dc_texturemid += curline->sidedef->rowoffset; - - if (curline->linedef->flags & ML_DONTPEGBOTTOM) - dc_texturemid += (textureheight[texnum])*times; - else - dc_texturemid -= (textureheight[texnum])*times; -#endif - - dc_texheight = textureheight[texnum]>>FRACBITS; - - // draw the columns - for (dc_x = x1; dc_x <= x2; dc_x++) - { -#ifdef ESLOPE - dc_texturemid = ds->maskedtextureheight[dc_x]; - - if (!!(curline->linedef->flags & ML_DONTPEGBOTTOM) ^ !!(curline->linedef->flags & ML_EFFECT3)) - dc_texturemid += (textureheight[texnum])*times + textureheight[texnum]; - else - dc_texturemid -= (textureheight[texnum])*times; -#endif - // calculate lighting - if (maskedtexturecol[dc_x] != INT16_MAX) - { - // Check for overflows first - overflow_test = (INT64)centeryfrac - (((INT64)dc_texturemid*spryscale)>>FRACBITS); - if (overflow_test < 0) overflow_test = -overflow_test; - if ((UINT64)overflow_test&0xFFFFFFFF80000000ULL) - { - // Eh, no, go away, don't waste our time - if (dc_numlights) - { - for (i = 0; i < dc_numlights; i++) - { - rlight = &dc_lightlist[i]; - rlight->height += rlight->heightstep; - } - } - spryscale += rw_scalestep; - continue; - } - - if (dc_numlights) - { - lighttable_t **xwalllights; - - sprbotscreen = INT32_MAX; - sprtopscreen = windowtop = (centeryfrac - FixedMul(dc_texturemid, spryscale)); - - realbot = windowbottom = FixedMul(textureheight[texnum], spryscale) + sprtopscreen; - dc_iscale = 0xffffffffu / (unsigned)spryscale; - - // draw the texture - col = (column_t *)((UINT8 *)R_GetColumn(texnum, maskedtexturecol[dc_x]) - 3); - - for (i = 0; i < dc_numlights; i++) - { - rlight = &dc_lightlist[i]; - - if ((rlight->flags & FF_NOSHADE)) - continue; - - if (rlight->lightnum < 0) - xwalllights = scalelight[0]; - else if (rlight->lightnum >= LIGHTLEVELS) - xwalllights = scalelight[LIGHTLEVELS-1]; - else - xwalllights = scalelight[rlight->lightnum]; - - pindex = FixedMul(spryscale, FixedDiv(640, vid.width))>>LIGHTSCALESHIFT; - - if (pindex >= MAXLIGHTSCALE) - pindex = MAXLIGHTSCALE - 1; - - if (rlight->extra_colormap) - rlight->rcolormap = rlight->extra_colormap->colormap + (xwalllights[pindex] - colormaps); - else - rlight->rcolormap = xwalllights[pindex]; - - height = rlight->height; - rlight->height += rlight->heightstep; - - if (height <= windowtop) - { - dc_colormap = rlight->rcolormap; - continue; - } - - windowbottom = height; - if (windowbottom >= realbot) - { - windowbottom = realbot; - colfunc_2s(col); - for (i++; i < dc_numlights; i++) - { - rlight = &dc_lightlist[i]; - rlight->height += rlight->heightstep; - } - - continue; - } - colfunc_2s(col); - windowtop = windowbottom + 1; - dc_colormap = rlight->rcolormap; - } - windowbottom = realbot; - if (windowtop < windowbottom) - colfunc_2s(col); - - spryscale += rw_scalestep; - continue; - } - - // calculate lighting - pindex = FixedMul(spryscale, FixedDiv(640, vid.width))>>LIGHTSCALESHIFT; - - if (pindex >= MAXLIGHTSCALE) - pindex = MAXLIGHTSCALE - 1; - - dc_colormap = walllights[pindex]; - - if (frontsector->extra_colormap) - dc_colormap = frontsector->extra_colormap->colormap + (dc_colormap - colormaps); - - sprtopscreen = centeryfrac - FixedMul(dc_texturemid, spryscale); - dc_iscale = 0xffffffffu / (unsigned)spryscale; - - // draw the texture - col = (column_t *)((UINT8 *)R_GetColumn(texnum, maskedtexturecol[dc_x]) - 3); - -//#ifdef POLYOBJECTS_PLANES -#if 0 // Disabling this allows inside edges to render below the planes, for until the clipping is fixed to work right when POs are near the camera. -Red - if (curline->dontrenderme && curline->polyseg && (curline->polyseg->flags & POF_RENDERPLANES)) - { - fixed_t my_topscreen; - fixed_t my_bottomscreen; - fixed_t my_yl, my_yh; - - my_topscreen = sprtopscreen + spryscale*col->topdelta; - my_bottomscreen = sprbotscreen == INT32_MAX ? my_topscreen + spryscale*col->length - : sprbotscreen + spryscale*col->length; - - my_yl = (my_topscreen+FRACUNIT-1)>>FRACBITS; - my_yh = (my_bottomscreen-1)>>FRACBITS; - // CONS_Debug(DBG_RENDER, "my_topscreen: %d\nmy_bottomscreen: %d\nmy_yl: %d\nmy_yh: %d\n", my_topscreen, my_bottomscreen, my_yl, my_yh); - - if (numffloors) - { - INT32 top = my_yl; - INT32 bottom = my_yh; - - for (i = 0; i < numffloors; i++) - { - if (!ffloor[i].polyobj || ffloor[i].polyobj != curline->polyseg) - continue; - - if (ffloor[i].height < viewz) - { - INT32 top_w = ffloor[i].plane->top[dc_x]; - - // CONS_Debug(DBG_RENDER, "Leveltime : %d\n", leveltime); - // CONS_Debug(DBG_RENDER, "Top is %d, top_w is %d\n", top, top_w); - if (top_w < top) - { - ffloor[i].plane->top[dc_x] = (INT16)top; - ffloor[i].plane->picnum = 0; - } - // CONS_Debug(DBG_RENDER, "top_w is now %d\n", ffloor[i].plane->top[dc_x]); - } - else if (ffloor[i].height > viewz) - { - INT32 bottom_w = ffloor[i].plane->bottom[dc_x]; - - if (bottom_w > bottom) - { - ffloor[i].plane->bottom[dc_x] = (INT16)bottom; - ffloor[i].plane->picnum = 0; - } - } - } - } - } - else -#endif - colfunc_2s(col); - } - spryscale += rw_scalestep; - } - } - colfunc = colfuncs[BASEDRAWFUNC]; -} - -// Loop through R_DrawMaskedColumn calls -static void R_DrawRepeatMaskedColumn(column_t *col) -{ - while (sprtopscreen < sprbotscreen) { - R_DrawMaskedColumn(col); - if ((INT64)sprtopscreen + dc_texheight*spryscale > (INT64)INT32_MAX) // prevent overflow - sprtopscreen = INT32_MAX; - else - sprtopscreen += dc_texheight*spryscale; - } -} - -static void R_DrawRepeatFlippedMaskedColumn(column_t *col) -{ - do { - R_DrawFlippedMaskedColumn(col, column2s_length); - sprtopscreen += dc_texheight*spryscale; - } while (sprtopscreen < sprbotscreen); -} - -// -// R_RenderThickSideRange -// Renders all the thick sides in the given range. -void R_RenderThickSideRange(drawseg_t *ds, INT32 x1, INT32 x2, ffloor_t *pfloor) -{ - size_t pindex; - column_t * col; - INT32 lightnum; - INT32 texnum; - sector_t tempsec; - INT32 templight; - INT32 i, p; - fixed_t bottombounds = viewheight << FRACBITS; - fixed_t topbounds = (con_clipviewtop - 1) << FRACBITS; - fixed_t offsetvalue = 0; - lightlist_t *light; - r_lightlist_t *rlight; -#ifdef ESLOPE - INT32 range; -#endif -#ifndef ESLOPE - fixed_t lheight; -#endif - line_t *newline = NULL; -#ifdef ESLOPE - // Render FOF sides kinda like normal sides, with the frac and step and everything - // NOTE: INT64 instead of fixed_t because overflow concerns - INT64 top_frac, top_step, bottom_frac, bottom_step; - // skew FOF walls with slopes? - boolean slopeskew = false; - fixed_t ffloortextureslide = 0; - INT32 oldx = -1; - fixed_t left_top, left_bottom; // needed here for slope skewing - pslope_t *skewslope = NULL; -#endif - - void (*colfunc_2s) (column_t *); - - // Calculate light table. - // Use different light tables - // for horizontal / vertical / diagonal. Diagonal? - // OPTIMIZE: get rid of LIGHTSEGSHIFT globally - - curline = ds->curline; - backsector = pfloor->target; - frontsector = curline->frontsector == pfloor->target ? curline->backsector : curline->frontsector; - texnum = R_GetTextureNum(sides[pfloor->master->sidenum[0]].midtexture); - - colfunc = colfuncs[BASEDRAWFUNC]; - - if (pfloor->master->flags & ML_TFERLINE) - { - size_t linenum = curline->linedef-backsector->lines[0]; - newline = pfloor->master->frontsector->lines[0] + linenum; - texnum = R_GetTextureNum(sides[newline->sidenum[0]].midtexture); - } - - if (pfloor->flags & FF_TRANSLUCENT) - { - boolean fuzzy = true; - - // Hacked up support for alpha value in software mode Tails 09-24-2002 - if (pfloor->alpha < 12) - return; // Don't even draw it - else if (pfloor->alpha < 38) - dc_transmap = transtables + ((tr_trans90-1)<alpha < 64) - dc_transmap = transtables + ((tr_trans80-1)<alpha < 89) - dc_transmap = transtables + ((tr_trans70-1)<alpha < 115) - dc_transmap = transtables + ((tr_trans60-1)<alpha < 140) - dc_transmap = transtables + ((tr_trans50-1)<alpha < 166) - dc_transmap = transtables + ((tr_trans40-1)<alpha < 192) - dc_transmap = transtables + ((tr_trans30-1)<alpha < 217) - dc_transmap = transtables + ((tr_trans20-1)<alpha < 243) - dc_transmap = transtables + ((tr_trans10-1)<flags & FF_FOG) - colfunc = colfuncs[COLDRAWFUNC_FOG]; - -#ifdef ESLOPE - range = max(ds->x2-ds->x1, 1); -#endif - //SoM: Moved these up here so they are available for my lightlist calculations - rw_scalestep = ds->scalestep; - spryscale = ds->scale1 + (x1 - ds->x1)*rw_scalestep; - - dc_numlights = 0; - if (frontsector->numlights) - { - dc_numlights = frontsector->numlights; - if (dc_numlights > dc_maxlights) - { - dc_maxlights = dc_numlights; - dc_lightlist = Z_Realloc(dc_lightlist, sizeof (*dc_lightlist) * dc_maxlights, PU_STATIC, NULL); - } - - for (i = p = 0; i < dc_numlights; i++) - { -#ifdef ESLOPE - fixed_t leftheight, rightheight; - fixed_t pfloorleft, pfloorright; - INT64 overflow_test; -#endif - light = &frontsector->lightlist[i]; - rlight = &dc_lightlist[p]; -#ifdef ESLOPE - -#define SLOPEPARAMS(slope, end1, end2, normalheight) \ - if (slope) { \ - end1 = P_GetZAt(slope, ds->leftpos.x, ds->leftpos.y); \ - end2 = P_GetZAt(slope, ds->rightpos.x, ds->rightpos.y); \ - } else \ - end1 = end2 = normalheight; - - SLOPEPARAMS(light->slope, leftheight, rightheight, light->height) - SLOPEPARAMS(*pfloor->b_slope, pfloorleft, pfloorright, *pfloor->bottomheight) - - if (leftheight < pfloorleft && rightheight < pfloorright) - continue; - - SLOPEPARAMS(*pfloor->t_slope, pfloorleft, pfloorright, *pfloor->topheight) - - if (leftheight > pfloorleft && rightheight > pfloorright && i+1 < dc_numlights) - { - lightlist_t *nextlight = &frontsector->lightlist[i+1]; - if ((nextlight->slope ? P_GetZAt(nextlight->slope, ds->leftpos.x, ds->leftpos.y) : nextlight->height) > pfloorleft - && (nextlight->slope ? P_GetZAt(nextlight->slope, ds->rightpos.x, ds->rightpos.y) : nextlight->height) > pfloorright) - continue; - } - - leftheight -= viewz; - rightheight -= viewz; - -#define CLAMPMAX INT32_MAX -#define CLAMPMIN (-INT32_MAX) // This is not INT32_MIN on purpose! INT32_MIN makes the drawers freak out. - // Monster Iestyn (25/03/18): do not skip these lights if they fail overflow test, just clamp them instead so they behave. - overflow_test = (INT64)centeryfrac - (((INT64)leftheight*ds->scale1)>>FRACBITS); - if (overflow_test > (INT64)CLAMPMAX) rlight->height = CLAMPMAX; - else if (overflow_test > (INT64)CLAMPMIN) rlight->height = (fixed_t)overflow_test; - else rlight->height = CLAMPMIN; - - overflow_test = (INT64)centeryfrac - (((INT64)rightheight*ds->scale2)>>FRACBITS); - if (overflow_test > (INT64)CLAMPMAX) rlight->heightstep = CLAMPMAX; - else if (overflow_test > (INT64)CLAMPMIN) rlight->heightstep = (fixed_t)overflow_test; - else rlight->heightstep = CLAMPMIN; - rlight->heightstep = (rlight->heightstep-rlight->height)/(range); -#else - if (light->height < *pfloor->bottomheight) - continue; - - if (light->height > *pfloor->topheight && i+1 < dc_numlights && frontsector->lightlist[i+1].height > *pfloor->topheight) - continue; - - lheight = light->height;// > *pfloor->topheight ? *pfloor->topheight + FRACUNIT : light->height; - rlight->heightstep = -FixedMul (rw_scalestep, (lheight - viewz)); - rlight->height = (centeryfrac) - FixedMul((lheight - viewz), spryscale); -#endif - rlight->flags = light->flags; - if (light->flags & FF_CUTLEVEL) - { -#ifdef ESLOPE - SLOPEPARAMS(*light->caster->b_slope, leftheight, rightheight, *light->caster->bottomheight) -#undef SLOPEPARAMS - leftheight -= viewz; - rightheight -= viewz; - - // Monster Iestyn (25/03/18): do not skip these lights if they fail overflow test, just clamp them instead so they behave. - overflow_test = (INT64)centeryfrac - (((INT64)leftheight*ds->scale1)>>FRACBITS); - if (overflow_test > (INT64)CLAMPMAX) rlight->botheight = CLAMPMAX; - else if (overflow_test > (INT64)CLAMPMIN) rlight->botheight = (fixed_t)overflow_test; - else rlight->botheight = CLAMPMIN; - - overflow_test = (INT64)centeryfrac - (((INT64)rightheight*ds->scale2)>>FRACBITS); - if (overflow_test > (INT64)CLAMPMAX) rlight->botheightstep = CLAMPMAX; - else if (overflow_test > (INT64)CLAMPMIN) rlight->botheightstep = (fixed_t)overflow_test; - else rlight->botheightstep = CLAMPMIN; - rlight->botheightstep = (rlight->botheightstep-rlight->botheight)/(range); -#else - lheight = *light->caster->bottomheight;// > *pfloor->topheight ? *pfloor->topheight + FRACUNIT : *light->caster->bottomheight; - rlight->botheightstep = -FixedMul (rw_scalestep, (lheight - viewz)); - rlight->botheight = (centeryfrac) - FixedMul((lheight - viewz), spryscale); -#endif - } - - rlight->lightlevel = *light->lightlevel; - rlight->extra_colormap = *light->extra_colormap; - - // Check if the current light effects the colormap/lightlevel - if (pfloor->flags & FF_FOG) - rlight->lightnum = (pfloor->master->frontsector->lightlevel >> LIGHTSEGSHIFT); - else - rlight->lightnum = (rlight->lightlevel >> LIGHTSEGSHIFT); - - if (pfloor->flags & FF_FOG || rlight->flags & FF_FOG || (rlight->extra_colormap && rlight->extra_colormap->fog)) - ; - else if (curline->v1->y == curline->v2->y) - rlight->lightnum--; - else if (curline->v1->x == curline->v2->x) - rlight->lightnum++; - - p++; - } - - dc_numlights = p; - } - else - { - // Get correct light level! - if ((frontsector->extra_colormap && frontsector->extra_colormap->fog)) - lightnum = (frontsector->lightlevel >> LIGHTSEGSHIFT); - else if (pfloor->flags & FF_FOG) - lightnum = (pfloor->master->frontsector->lightlevel >> LIGHTSEGSHIFT); - else if (colfunc == colfuncs[COLDRAWFUNC_FUZZY]) - lightnum = LIGHTLEVELS-1; - else - lightnum = R_FakeFlat(frontsector, &tempsec, &templight, &templight, false) - ->lightlevel >> LIGHTSEGSHIFT; - - if (pfloor->flags & FF_FOG || (frontsector->extra_colormap && frontsector->extra_colormap->fog)); - else if (curline->v1->y == curline->v2->y) - lightnum--; - else if (curline->v1->x == curline->v2->x) - lightnum++; - - if (lightnum < 0) - walllights = scalelight[0]; - else if (lightnum >= LIGHTLEVELS) - walllights = scalelight[LIGHTLEVELS-1]; - else - walllights = scalelight[lightnum]; - } - - maskedtexturecol = ds->thicksidecol; - - mfloorclip = ds->sprbottomclip; - mceilingclip = ds->sprtopclip; - dc_texheight = textureheight[texnum]>>FRACBITS; - -#ifdef ESLOPE - // calculate both left ends - if (*pfloor->t_slope) - left_top = P_GetZAt(*pfloor->t_slope, ds->leftpos.x, ds->leftpos.y) - viewz; - else - left_top = *pfloor->topheight - viewz; - - if (*pfloor->b_slope) - left_bottom = P_GetZAt(*pfloor->b_slope, ds->leftpos.x, ds->leftpos.y) - viewz; - else - left_bottom = *pfloor->bottomheight - viewz; - skewslope = *pfloor->t_slope; // skew using top slope by default - if (newline) - { - if (newline->flags & ML_DONTPEGTOP) - slopeskew = true; - } - else if (pfloor->master->flags & ML_DONTPEGTOP) - slopeskew = true; - - if (slopeskew) - dc_texturemid = left_top; - else -#endif - dc_texturemid = *pfloor->topheight - viewz; - - if (newline) - { - offsetvalue = sides[newline->sidenum[0]].rowoffset; - if (newline->flags & ML_DONTPEGBOTTOM) - { -#ifdef ESLOPE - skewslope = *pfloor->b_slope; // skew using bottom slope - if (slopeskew) - dc_texturemid = left_bottom; - else -#endif - offsetvalue -= *pfloor->topheight - *pfloor->bottomheight; - } - } - else - { - offsetvalue = sides[pfloor->master->sidenum[0]].rowoffset; - if (curline->linedef->flags & ML_DONTPEGBOTTOM) - { -#ifdef ESLOPE - skewslope = *pfloor->b_slope; // skew using bottom slope - if (slopeskew) - dc_texturemid = left_bottom; - else -#endif - offsetvalue -= *pfloor->topheight - *pfloor->bottomheight; - } - } - -#ifdef ESLOPE - if (slopeskew) - { - angle_t lineangle = R_PointToAngle2(curline->v1->x, curline->v1->y, curline->v2->x, curline->v2->y); - - if (skewslope) - ffloortextureslide = FixedMul(skewslope->zdelta, FINECOSINE((lineangle-skewslope->xydirection)>>ANGLETOFINESHIFT)); - } -#endif - - dc_texturemid += offsetvalue; - - // Texture must be cached before setting colfunc_2s, - // otherwise texture[texnum]->holes may be false when it shouldn't be - R_CheckTextureCache(texnum); - //faB: handle case where multipatch texture is drawn on a 2sided wall, multi-patch textures - // are not stored per-column with post info anymore in Doom Legacy - if (textures[texnum]->holes) - { - if (textures[texnum]->flip & 2) // vertically flipped? - { - colfunc_2s = R_DrawRepeatFlippedMaskedColumn; - column2s_length = textures[texnum]->height; - } - else - colfunc_2s = R_DrawRepeatMaskedColumn; // render the usual 2sided single-patch packed texture - } - else - { - colfunc_2s = R_Render2sidedMultiPatchColumn; //render multipatch with no holes (no post_t info) - column2s_length = textures[texnum]->height; - } - -#ifdef ESLOPE - // Set heights according to plane, or slope, whichever - { - fixed_t right_top, right_bottom; - - // calculate right ends now - if (*pfloor->t_slope) - right_top = P_GetZAt(*pfloor->t_slope, ds->rightpos.x, ds->rightpos.y) - viewz; - else - right_top = *pfloor->topheight - viewz; - - if (*pfloor->b_slope) - right_bottom = P_GetZAt(*pfloor->b_slope, ds->rightpos.x, ds->rightpos.y) - viewz; - else - right_bottom = *pfloor->bottomheight - viewz; - - // using INT64 to avoid 32bit overflow - top_frac = (INT64)centeryfrac - (((INT64)left_top * ds->scale1) >> FRACBITS); - bottom_frac = (INT64)centeryfrac - (((INT64)left_bottom * ds->scale1) >> FRACBITS); - top_step = (INT64)centeryfrac - (((INT64)right_top * ds->scale2) >> FRACBITS); - bottom_step = (INT64)centeryfrac - (((INT64)right_bottom * ds->scale2) >> FRACBITS); - - top_step = (top_step-top_frac)/(range); - bottom_step = (bottom_step-bottom_frac)/(range); - - top_frac += top_step * (x1 - ds->x1); - bottom_frac += bottom_step * (x1 - ds->x1); - } -#endif - - // draw the columns - for (dc_x = x1; dc_x <= x2; dc_x++) - { - if (maskedtexturecol[dc_x] != INT16_MAX) - { -#ifdef ESLOPE - if (ffloortextureslide) { // skew FOF walls - if (oldx != -1) - dc_texturemid += FixedMul(ffloortextureslide, (maskedtexturecol[oldx]-maskedtexturecol[dc_x])< (INT64)CLAMPMAX) sprtopscreen = windowtop = CLAMPMAX; - else if (top_frac > (INT64)CLAMPMIN) sprtopscreen = windowtop = (fixed_t)top_frac; - else sprtopscreen = windowtop = CLAMPMIN; - if (bottom_frac > (INT64)CLAMPMAX) sprbotscreen = windowbottom = CLAMPMAX; - else if (bottom_frac > (INT64)CLAMPMIN) sprbotscreen = windowbottom = (fixed_t)bottom_frac; - else sprbotscreen = windowbottom = CLAMPMIN; - - top_frac += top_step; - bottom_frac += bottom_step; -#else - sprtopscreen = windowtop = (centeryfrac - FixedMul((dc_texturemid - offsetvalue), spryscale)); - sprbotscreen = windowbottom = FixedMul(*pfloor->topheight - *pfloor->bottomheight, spryscale) + sprtopscreen; -#endif - - // SoM: If column is out of range, why bother with it?? - if (windowbottom < topbounds || windowtop > bottombounds) - { - if (dc_numlights) - { - for (i = 0; i < dc_numlights; i++) - { - rlight = &dc_lightlist[i]; - rlight->height += rlight->heightstep; - if (rlight->flags & FF_CUTLEVEL) - rlight->botheight += rlight->botheightstep; - } - } - spryscale += rw_scalestep; - continue; - } - - dc_iscale = 0xffffffffu / (unsigned)spryscale; - - // Get data for the column - col = (column_t *)((UINT8 *)R_GetColumn(texnum,maskedtexturecol[dc_x]) - 3); - - // SoM: New code does not rely on R_DrawColumnShadowed_8 which - // will (hopefully) put less strain on the stack. - if (dc_numlights) - { - lighttable_t **xwalllights; - fixed_t height; - fixed_t bheight = 0; - INT32 solid = 0; - INT32 lighteffect = 0; - - for (i = 0; i < dc_numlights; i++) - { - // Check if the current light effects the colormap/lightlevel - rlight = &dc_lightlist[i]; - lighteffect = !(dc_lightlist[i].flags & FF_NOSHADE); - if (lighteffect) - { - lightnum = rlight->lightnum; - - if (lightnum < 0) - xwalllights = scalelight[0]; - else if (lightnum >= LIGHTLEVELS) - xwalllights = scalelight[LIGHTLEVELS-1]; - else - xwalllights = scalelight[lightnum]; - - pindex = FixedMul(spryscale, FixedDiv(640, vid.width))>>LIGHTSCALESHIFT; - - if (pindex >= MAXLIGHTSCALE) - pindex = MAXLIGHTSCALE-1; - - if (pfloor->flags & FF_FOG) - { - if (pfloor->master->frontsector->extra_colormap) - rlight->rcolormap = pfloor->master->frontsector->extra_colormap->colormap + (xwalllights[pindex] - colormaps); - else - rlight->rcolormap = xwalllights[pindex]; - } - else - { - if (rlight->extra_colormap) - rlight->rcolormap = rlight->extra_colormap->colormap + (xwalllights[pindex] - colormaps); - else - rlight->rcolormap = xwalllights[pindex]; - } - } - - solid = 0; // don't carry over solid-cutting flag from the previous light - - // Check if the current light can cut the current 3D floor. - if (rlight->flags & FF_CUTSOLIDS && !(pfloor->flags & FF_EXTRA)) - solid = 1; - else if (rlight->flags & FF_CUTEXTRA && pfloor->flags & FF_EXTRA) - { - if (rlight->flags & FF_EXTRA) - { - // The light is from an extra 3D floor... Check the flags so - // there are no undesired cuts. - if ((rlight->flags & (FF_FOG|FF_SWIMMABLE)) == (pfloor->flags & (FF_FOG|FF_SWIMMABLE))) - solid = 1; - } - else - solid = 1; - } - else - solid = 0; - - height = rlight->height; - rlight->height += rlight->heightstep; - - if (solid) - { - bheight = rlight->botheight - (FRACUNIT >> 1); - rlight->botheight += rlight->botheightstep; - } - - if (height <= windowtop) - { - if (lighteffect) - dc_colormap = rlight->rcolormap; - if (solid && windowtop < bheight) - windowtop = bheight; - continue; - } - - windowbottom = height; - if (windowbottom >= sprbotscreen) - { - windowbottom = sprbotscreen; - // draw the texture - colfunc_2s (col); - for (i++; i < dc_numlights; i++) - { - rlight = &dc_lightlist[i]; - rlight->height += rlight->heightstep; - if (rlight->flags & FF_CUTLEVEL) - rlight->botheight += rlight->botheightstep; - } - continue; - } - // draw the texture - colfunc_2s (col); - if (solid) - windowtop = bheight; - else - windowtop = windowbottom + 1; - if (lighteffect) - dc_colormap = rlight->rcolormap; - } - windowbottom = sprbotscreen; - // draw the texture, if there is any space left - if (windowtop < windowbottom) - colfunc_2s (col); - - spryscale += rw_scalestep; - continue; - } - - // calculate lighting - pindex = FixedMul(spryscale, FixedDiv(640, vid.width))>>LIGHTSCALESHIFT; - - if (pindex >= MAXLIGHTSCALE) - pindex = MAXLIGHTSCALE - 1; - - dc_colormap = walllights[pindex]; - - if (pfloor->flags & FF_FOG && pfloor->master->frontsector->extra_colormap) - dc_colormap = pfloor->master->frontsector->extra_colormap->colormap + (dc_colormap - colormaps); - else if (frontsector->extra_colormap) - dc_colormap = frontsector->extra_colormap->colormap + (dc_colormap - colormaps); - - // draw the texture - colfunc_2s (col); - spryscale += rw_scalestep; - } - } - colfunc = colfuncs[BASEDRAWFUNC]; - -#undef CLAMPMAX -#undef CLAMPMIN -} - // R_ExpandPlaneY // // A simple function to modify a vsplane's top and bottom for a particular column @@ -3434,3 +2198,1239 @@ void R_StoreWallRange(INT32 start, INT32 stop) ds_p++; } + +// ========================================================================== +// R_Splats Wall Splats Drawer +// ========================================================================== + +#ifdef WALLSPLATS +static INT16 last_ceilingclip[MAXVIDWIDTH]; +static INT16 last_floorclip[MAXVIDWIDTH]; + +static void R_DrawSplatColumn(column_t *column) +{ + INT32 topscreen, bottomscreen; + fixed_t basetexturemid; + INT32 topdelta, prevdelta = -1; + + basetexturemid = dc_texturemid; + + for (; column->topdelta != 0xff ;) + { + // calculate unclipped screen coordinates for post + topdelta = column->topdelta; + if (topdelta <= prevdelta) + topdelta += prevdelta; + prevdelta = topdelta; + topscreen = sprtopscreen + spryscale*topdelta; + bottomscreen = topscreen + spryscale*column->length; + + dc_yl = (topscreen+FRACUNIT-1)>>FRACBITS; + dc_yh = (bottomscreen-1)>>FRACBITS; + + if (dc_yh >= last_floorclip[dc_x]) + dc_yh = last_floorclip[dc_x] - 1; + if (dc_yl <= last_ceilingclip[dc_x]) + dc_yl = last_ceilingclip[dc_x] + 1; + if (dc_yl <= dc_yh && dl_yh < vid.height && yh > 0) + { + dc_source = (UINT8 *)column + 3; + dc_texturemid = basetexturemid - (topdelta<length + 4); + } + + dc_texturemid = basetexturemid; +} + +static void R_DrawWallSplats(void) +{ + wallsplat_t *splat; + seg_t *seg; + angle_t angle, angle1, angle2; + INT32 x1, x2; + size_t pindex; + column_t *col; + patch_t *patch; + fixed_t texturecolumn; + + splat = (wallsplat_t *)linedef->splats; + + I_Assert(splat != NULL); + + seg = ds_p->curline; + + // draw all splats from the line that touches the range of the seg + for (; splat; splat = splat->next) + { + angle1 = R_PointToAngle(splat->v1.x, splat->v1.y); + angle2 = R_PointToAngle(splat->v2.x, splat->v2.y); + angle1 = (angle1 - viewangle + ANGLE_90)>>ANGLETOFINESHIFT; + angle2 = (angle2 - viewangle + ANGLE_90)>>ANGLETOFINESHIFT; + // out of the viewangletox lut + /// \todo clip it to the screen + if (angle1 > FINEANGLES/2 || angle2 > FINEANGLES/2) + continue; + x1 = viewangletox[angle1]; + x2 = viewangletox[angle2]; + + if (x1 >= x2) + continue; // does not cross a pixel + + // splat is not in this seg range + if (x2 < ds_p->x1 || x1 > ds_p->x2) + continue; + + if (x1 < ds_p->x1) + x1 = ds_p->x1; + if (x2 > ds_p->x2) + x2 = ds_p->x2; + if (x2 <= x1) + continue; + + // calculate incremental stepping values for texture edges + rw_scalestep = ds_p->scalestep; + spryscale = ds_p->scale1 + (x1 - ds_p->x1)*rw_scalestep; + mfloorclip = floorclip; + mceilingclip = ceilingclip; + + patch = W_CachePatchNum(splat->patch, PU_CACHE); + + dc_texturemid = splat->top + (SHORT(patch->height)<<(FRACBITS-1)) - viewz; + if (splat->yoffset) + dc_texturemid += *splat->yoffset; + + sprtopscreen = centeryfrac - FixedMul(dc_texturemid, spryscale); + + // set drawing mode + switch (splat->flags & SPLATDRAWMODE_MASK) + { + case SPLATDRAWMODE_OPAQUE: + colfunc = colfuncs[BASEDRAWFUNC]; + break; + case SPLATDRAWMODE_TRANS: + if (!cv_translucency.value) + colfunc = colfuncs[BASEDRAWFUNC]; + else + { + dc_transmap = transtables + ((tr_trans50 - 1)<>LIGHTSCALESHIFT; + if (pindex >= MAXLIGHTSCALE) + pindex = MAXLIGHTSCALE - 1; + dc_colormap = walllights[pindex]; + + if (frontsector->extra_colormap) + dc_colormap = frontsector->extra_colormap->colormap + (dc_colormap - colormaps); + + sprtopscreen = centeryfrac - FixedMul(dc_texturemid, spryscale); + dc_iscale = 0xffffffffu / (unsigned)spryscale; + + // find column of patch, from perspective + angle = (rw_centerangle + xtoviewangle[dc_x])>>ANGLETOFINESHIFT; + texturecolumn = rw_offset2 - splat->offset + - FixedMul(FINETANGENT(angle), rw_distance); + + // FIXME! + texturecolumn >>= FRACBITS; + if (texturecolumn < 0 || texturecolumn >= SHORT(patch->width)) + continue; + + // draw the texture + col = (column_t *)((UINT8 *)patch + LONG(patch->columnofs[texturecolumn])); + R_DrawSplatColumn(col); + } + } // next splat + + colfunc = colfuncs[BASEDRAWFUNC]; +} + +#endif //WALLSPLATS + +// ========================================================================== +// R_RenderMaskedSegRange +// ========================================================================== + +// If we have a multi-patch texture on a 2sided wall (rare) then we draw +// it using R_DrawColumn, else we draw it using R_DrawMaskedColumn, this +// way we don't have to store extra post_t info with each column for +// multi-patch textures. They are not normally needed as multi-patch +// textures don't have holes in it. At least not for now. +static INT32 column2s_length; // column->length : for multi-patch on 2sided wall = texture->height + +static void R_Render2sidedMultiPatchColumn(column_t *column) +{ + INT32 topscreen, bottomscreen; + + topscreen = sprtopscreen; // + spryscale*column->topdelta; topdelta is 0 for the wall + bottomscreen = topscreen + spryscale * column2s_length; + + dc_yl = (sprtopscreen+FRACUNIT-1)>>FRACBITS; + dc_yh = (bottomscreen-1)>>FRACBITS; + + if (windowtop != INT32_MAX && windowbottom != INT32_MAX) + { + dc_yl = ((windowtop + FRACUNIT)>>FRACBITS); + dc_yh = (windowbottom - 1)>>FRACBITS; + } + + if (dc_yh >= mfloorclip[dc_x]) + dc_yh = mfloorclip[dc_x] - 1; + if (dc_yl <= mceilingclip[dc_x]) + dc_yl = mceilingclip[dc_x] + 1; + + if (dc_yl >= vid.height || dc_yh < 0) + return; + + if (dc_yl <= dc_yh && dc_yh < vid.height && dc_yh > 0) + { + dc_source = (UINT8 *)column + 3; + + if (colfunc == colfuncs[BASEDRAWFUNC]) + (colfuncs[COLDRAWFUNC_TWOSMULTIPATCH])(); + else if (colfunc == colfuncs[COLDRAWFUNC_FUZZY]) + (colfuncs[COLDRAWFUNC_TWOSMULTIPATCHTRANS])(); + else + colfunc(); + } +} + +// quick wrapper for R_DrawFlippedMaskedColumn so it can be set as a colfunc_2s value +// uses column2s_length for texture->height as above +static void R_DrawFlippedMaskedSegColumn(column_t *column) +{ + R_DrawFlippedMaskedColumn(column, column2s_length); +} + +void R_RenderMaskedSegRange(drawseg_t *ds, INT32 x1, INT32 x2) +{ + size_t pindex; + column_t *col; + INT32 lightnum, texnum, i; + fixed_t height, realbot; + lightlist_t *light; + r_lightlist_t *rlight; + void (*colfunc_2s)(column_t *); + line_t *ldef; + sector_t *front, *back; + INT32 times, repeats; + INT64 overflow_test; +#ifdef ESLOPE + INT32 range; +#endif + + // Calculate light table. + // Use different light tables + // for horizontal / vertical / diagonal. Diagonal? + // OPTIMIZE: get rid of LIGHTSEGSHIFT globally + curline = ds->curline; + frontsector = curline->frontsector; + backsector = curline->backsector; + texnum = R_GetTextureNum(curline->sidedef->midtexture); + windowbottom = windowtop = sprbotscreen = INT32_MAX; + + // hack translucent linedef types (900-909 for transtables 1-9) + ldef = curline->linedef; + switch (ldef->special) + { + case 900: + case 901: + case 902: + case 903: + case 904: + case 905: + case 906: + case 907: + case 908: + dc_transmap = transtables + ((ldef->special-900)<ceilingheight; + windowbottom = frontsector->floorheight; + break; + default: + colfunc = colfuncs[BASEDRAWFUNC]; + break; + } + + if (curline->polyseg && curline->polyseg->translucency > 0) + { + if (curline->polyseg->translucency >= NUMTRANSMAPS) + return; + + dc_transmap = transtables + ((curline->polyseg->translucency-1)<x2-ds->x1, 1); +#endif + rw_scalestep = ds->scalestep; + spryscale = ds->scale1 + (x1 - ds->x1)*rw_scalestep; + + // Texture must be cached before setting colfunc_2s, + // otherwise texture[texnum]->holes may be false when it shouldn't be + R_CheckTextureCache(texnum); + // handle case where multipatch texture is drawn on a 2sided wall, multi-patch textures + // are not stored per-column with post info in SRB2 + if (textures[texnum]->holes) + { + if (textures[texnum]->flip & 2) // vertically flipped? + { + colfunc_2s = R_DrawFlippedMaskedSegColumn; + column2s_length = textures[texnum]->height; + } + else + colfunc_2s = R_DrawMaskedColumn; // render the usual 2sided single-patch packed texture + } + else + { + colfunc_2s = R_Render2sidedMultiPatchColumn; // render multipatch with no holes (no post_t info) + column2s_length = textures[texnum]->height; + } + + // Setup lighting based on the presence/lack-of 3D floors. + dc_numlights = 0; + if (frontsector->numlights) + { + dc_numlights = frontsector->numlights; + if (dc_numlights >= dc_maxlights) + { + dc_maxlights = dc_numlights; + dc_lightlist = Z_Realloc(dc_lightlist, sizeof (*dc_lightlist) * dc_maxlights, PU_STATIC, NULL); + } + + for (i = 0; i < dc_numlights; i++) + { +#ifdef ESLOPE + fixed_t leftheight, rightheight; +#endif + light = &frontsector->lightlist[i]; + rlight = &dc_lightlist[i]; +#ifdef ESLOPE + if (light->slope) { + leftheight = P_GetZAt(light->slope, ds->leftpos.x, ds->leftpos.y); + rightheight = P_GetZAt(light->slope, ds->rightpos.x, ds->rightpos.y); + } else + leftheight = rightheight = light->height; + + leftheight -= viewz; + rightheight -= viewz; + + rlight->height = (centeryfrac) - FixedMul(leftheight, ds->scale1); + rlight->heightstep = (centeryfrac) - FixedMul(rightheight, ds->scale2); + rlight->heightstep = (rlight->heightstep-rlight->height)/(range); + //if (x1 > ds->x1) + //rlight->height -= (x1 - ds->x1)*rlight->heightstep; +#else + rlight->height = (centeryfrac) - FixedMul((light->height - viewz), spryscale); + rlight->heightstep = -FixedMul(rw_scalestep, (light->height - viewz)); +#endif + rlight->startheight = rlight->height; // keep starting value here to reset for each repeat + rlight->lightlevel = *light->lightlevel; + rlight->extra_colormap = *light->extra_colormap; + rlight->flags = light->flags; + + if (rlight->flags & FF_FOG || (rlight->extra_colormap && rlight->extra_colormap->fog)) + lightnum = (rlight->lightlevel >> LIGHTSEGSHIFT); + else if (colfunc == colfuncs[COLDRAWFUNC_FUZZY]) + lightnum = LIGHTLEVELS - 1; + else + lightnum = (rlight->lightlevel >> LIGHTSEGSHIFT); + + if (rlight->extra_colormap && rlight->extra_colormap->fog) + ; + else if (curline->v1->y == curline->v2->y) + lightnum--; + else if (curline->v1->x == curline->v2->x) + lightnum++; + + rlight->lightnum = lightnum; + } + } + else + { + if (colfunc == colfuncs[COLDRAWFUNC_FUZZY]) + { + if (frontsector->extra_colormap && frontsector->extra_colormap->fog) + lightnum = (frontsector->lightlevel >> LIGHTSEGSHIFT); + else + lightnum = LIGHTLEVELS - 1; + } + else + lightnum = (frontsector->lightlevel >> LIGHTSEGSHIFT); + + if (colfunc == colfuncs[COLDRAWFUNC_FOG] + || (frontsector->extra_colormap && frontsector->extra_colormap->fog)) + ; + else if (curline->v1->y == curline->v2->y) + lightnum--; + else if (curline->v1->x == curline->v2->x) + lightnum++; + + if (lightnum < 0) + walllights = scalelight[0]; + else if (lightnum >= LIGHTLEVELS) + walllights = scalelight[LIGHTLEVELS - 1]; + else + walllights = scalelight[lightnum]; + } + + maskedtexturecol = ds->maskedtexturecol; + + mfloorclip = ds->sprbottomclip; + mceilingclip = ds->sprtopclip; + + if (frontsector->heightsec != -1) + front = §ors[frontsector->heightsec]; + else + front = frontsector; + + if (backsector->heightsec != -1) + back = §ors[backsector->heightsec]; + else + back = backsector; + + if (ds->curline->sidedef->repeatcnt) + repeats = 1 + ds->curline->sidedef->repeatcnt; + else if (ldef->flags & ML_EFFECT5) + { + fixed_t high, low; + + if (front->ceilingheight > back->ceilingheight) + high = back->ceilingheight; + else + high = front->ceilingheight; + + if (front->floorheight > back->floorheight) + low = front->floorheight; + else + low = back->floorheight; + + repeats = (high - low)/textureheight[texnum]; + if ((high-low)%textureheight[texnum]) + repeats++; // tile an extra time to fill the gap -- Monster Iestyn + } + else + repeats = 1; + + for (times = 0; times < repeats; times++) + { + if (times > 0) + { + rw_scalestep = ds->scalestep; + spryscale = ds->scale1 + (x1 - ds->x1)*rw_scalestep; + if (dc_numlights) + { // reset all lights to their starting heights + for (i = 0; i < dc_numlights; i++) + { + rlight = &dc_lightlist[i]; + rlight->height = rlight->startheight; + } + } + } + +#ifndef ESLOPE + if (curline->linedef->flags & ML_DONTPEGBOTTOM) + { + dc_texturemid = front->floorheight > back->floorheight + ? front->floorheight : back->floorheight; + dc_texturemid = dc_texturemid + textureheight[texnum] - viewz; + } + else + { + dc_texturemid = front->ceilingheight < back->ceilingheight + ? front->ceilingheight : back->ceilingheight; + dc_texturemid = dc_texturemid - viewz; + } + dc_texturemid += curline->sidedef->rowoffset; + + if (curline->linedef->flags & ML_DONTPEGBOTTOM) + dc_texturemid += (textureheight[texnum])*times; + else + dc_texturemid -= (textureheight[texnum])*times; +#endif + + dc_texheight = textureheight[texnum]>>FRACBITS; + + // draw the columns + for (dc_x = x1; dc_x <= x2; dc_x++) + { +#ifdef ESLOPE + dc_texturemid = ds->maskedtextureheight[dc_x]; + + if (!!(curline->linedef->flags & ML_DONTPEGBOTTOM) ^ !!(curline->linedef->flags & ML_EFFECT3)) + dc_texturemid += (textureheight[texnum])*times + textureheight[texnum]; + else + dc_texturemid -= (textureheight[texnum])*times; +#endif + // calculate lighting + if (maskedtexturecol[dc_x] != INT16_MAX) + { + // Check for overflows first + overflow_test = (INT64)centeryfrac - (((INT64)dc_texturemid*spryscale)>>FRACBITS); + if (overflow_test < 0) overflow_test = -overflow_test; + if ((UINT64)overflow_test&0xFFFFFFFF80000000ULL) + { + // Eh, no, go away, don't waste our time + if (dc_numlights) + { + for (i = 0; i < dc_numlights; i++) + { + rlight = &dc_lightlist[i]; + rlight->height += rlight->heightstep; + } + } + spryscale += rw_scalestep; + continue; + } + + if (dc_numlights) + { + lighttable_t **xwalllights; + + sprbotscreen = INT32_MAX; + sprtopscreen = windowtop = (centeryfrac - FixedMul(dc_texturemid, spryscale)); + + realbot = windowbottom = FixedMul(textureheight[texnum], spryscale) + sprtopscreen; + dc_iscale = 0xffffffffu / (unsigned)spryscale; + + // draw the texture + col = (column_t *)((UINT8 *)R_GetColumn(texnum, maskedtexturecol[dc_x]) - 3); + + for (i = 0; i < dc_numlights; i++) + { + rlight = &dc_lightlist[i]; + + if ((rlight->flags & FF_NOSHADE)) + continue; + + if (rlight->lightnum < 0) + xwalllights = scalelight[0]; + else if (rlight->lightnum >= LIGHTLEVELS) + xwalllights = scalelight[LIGHTLEVELS-1]; + else + xwalllights = scalelight[rlight->lightnum]; + + pindex = FixedMul(spryscale, FixedDiv(640, vid.width))>>LIGHTSCALESHIFT; + + if (pindex >= MAXLIGHTSCALE) + pindex = MAXLIGHTSCALE - 1; + + if (rlight->extra_colormap) + rlight->rcolormap = rlight->extra_colormap->colormap + (xwalllights[pindex] - colormaps); + else + rlight->rcolormap = xwalllights[pindex]; + + height = rlight->height; + rlight->height += rlight->heightstep; + + if (height <= windowtop) + { + dc_colormap = rlight->rcolormap; + continue; + } + + windowbottom = height; + if (windowbottom >= realbot) + { + windowbottom = realbot; + colfunc_2s(col); + for (i++; i < dc_numlights; i++) + { + rlight = &dc_lightlist[i]; + rlight->height += rlight->heightstep; + } + + continue; + } + colfunc_2s(col); + windowtop = windowbottom + 1; + dc_colormap = rlight->rcolormap; + } + windowbottom = realbot; + if (windowtop < windowbottom) + colfunc_2s(col); + + spryscale += rw_scalestep; + continue; + } + + // calculate lighting + pindex = FixedMul(spryscale, FixedDiv(640, vid.width))>>LIGHTSCALESHIFT; + + if (pindex >= MAXLIGHTSCALE) + pindex = MAXLIGHTSCALE - 1; + + dc_colormap = walllights[pindex]; + + if (frontsector->extra_colormap) + dc_colormap = frontsector->extra_colormap->colormap + (dc_colormap - colormaps); + + sprtopscreen = centeryfrac - FixedMul(dc_texturemid, spryscale); + dc_iscale = 0xffffffffu / (unsigned)spryscale; + + // draw the texture + col = (column_t *)((UINT8 *)R_GetColumn(texnum, maskedtexturecol[dc_x]) - 3); + +//#ifdef POLYOBJECTS_PLANES +#if 0 // Disabling this allows inside edges to render below the planes, for until the clipping is fixed to work right when POs are near the camera. -Red + if (curline->dontrenderme && curline->polyseg && (curline->polyseg->flags & POF_RENDERPLANES)) + { + fixed_t my_topscreen; + fixed_t my_bottomscreen; + fixed_t my_yl, my_yh; + + my_topscreen = sprtopscreen + spryscale*col->topdelta; + my_bottomscreen = sprbotscreen == INT32_MAX ? my_topscreen + spryscale*col->length + : sprbotscreen + spryscale*col->length; + + my_yl = (my_topscreen+FRACUNIT-1)>>FRACBITS; + my_yh = (my_bottomscreen-1)>>FRACBITS; + // CONS_Debug(DBG_RENDER, "my_topscreen: %d\nmy_bottomscreen: %d\nmy_yl: %d\nmy_yh: %d\n", my_topscreen, my_bottomscreen, my_yl, my_yh); + + if (numffloors) + { + INT32 top = my_yl; + INT32 bottom = my_yh; + + for (i = 0; i < numffloors; i++) + { + if (!ffloor[i].polyobj || ffloor[i].polyobj != curline->polyseg) + continue; + + if (ffloor[i].height < viewz) + { + INT32 top_w = ffloor[i].plane->top[dc_x]; + + // CONS_Debug(DBG_RENDER, "Leveltime : %d\n", leveltime); + // CONS_Debug(DBG_RENDER, "Top is %d, top_w is %d\n", top, top_w); + if (top_w < top) + { + ffloor[i].plane->top[dc_x] = (INT16)top; + ffloor[i].plane->picnum = 0; + } + // CONS_Debug(DBG_RENDER, "top_w is now %d\n", ffloor[i].plane->top[dc_x]); + } + else if (ffloor[i].height > viewz) + { + INT32 bottom_w = ffloor[i].plane->bottom[dc_x]; + + if (bottom_w > bottom) + { + ffloor[i].plane->bottom[dc_x] = (INT16)bottom; + ffloor[i].plane->picnum = 0; + } + } + } + } + } + else +#endif + colfunc_2s(col); + } + spryscale += rw_scalestep; + } + } + colfunc = colfuncs[BASEDRAWFUNC]; +} + +// Loop through R_DrawMaskedColumn calls +static void R_DrawRepeatMaskedColumn(column_t *col) +{ + while (sprtopscreen < sprbotscreen) { + R_DrawMaskedColumn(col); + if ((INT64)sprtopscreen + dc_texheight*spryscale > (INT64)INT32_MAX) // prevent overflow + sprtopscreen = INT32_MAX; + else + sprtopscreen += dc_texheight*spryscale; + } +} + +static void R_DrawRepeatFlippedMaskedColumn(column_t *col) +{ + do { + R_DrawFlippedMaskedColumn(col, column2s_length); + sprtopscreen += dc_texheight*spryscale; + } while (sprtopscreen < sprbotscreen); +} + +// +// R_RenderThickSideRange +// Renders all the thick sides in the given range. +void R_RenderThickSideRange(drawseg_t *ds, INT32 x1, INT32 x2, ffloor_t *pfloor) +{ + size_t pindex; + column_t * col; + INT32 lightnum; + INT32 texnum; + sector_t tempsec; + INT32 templight; + INT32 i, p; + fixed_t bottombounds = viewheight << FRACBITS; + fixed_t topbounds = (con_clipviewtop - 1) << FRACBITS; + fixed_t offsetvalue = 0; + lightlist_t *light; + r_lightlist_t *rlight; +#ifdef ESLOPE + INT32 range; +#endif +#ifndef ESLOPE + fixed_t lheight; +#endif + line_t *newline = NULL; +#ifdef ESLOPE + // Render FOF sides kinda like normal sides, with the frac and step and everything + // NOTE: INT64 instead of fixed_t because overflow concerns + INT64 top_frac, top_step, bottom_frac, bottom_step; + // skew FOF walls with slopes? + boolean slopeskew = false; + fixed_t ffloortextureslide = 0; + INT32 oldx = -1; + fixed_t left_top, left_bottom; // needed here for slope skewing + pslope_t *skewslope = NULL; +#endif + + void (*colfunc_2s) (column_t *); + + // Calculate light table. + // Use different light tables + // for horizontal / vertical / diagonal. Diagonal? + // OPTIMIZE: get rid of LIGHTSEGSHIFT globally + + curline = ds->curline; + backsector = pfloor->target; + frontsector = curline->frontsector == pfloor->target ? curline->backsector : curline->frontsector; + texnum = R_GetTextureNum(sides[pfloor->master->sidenum[0]].midtexture); + + colfunc = colfuncs[BASEDRAWFUNC]; + + if (pfloor->master->flags & ML_TFERLINE) + { + size_t linenum = curline->linedef-backsector->lines[0]; + newline = pfloor->master->frontsector->lines[0] + linenum; + texnum = R_GetTextureNum(sides[newline->sidenum[0]].midtexture); + } + + if (pfloor->flags & FF_TRANSLUCENT) + { + boolean fuzzy = true; + + // Hacked up support for alpha value in software mode Tails 09-24-2002 + if (pfloor->alpha < 12) + return; // Don't even draw it + else if (pfloor->alpha < 38) + dc_transmap = transtables + ((tr_trans90-1)<alpha < 64) + dc_transmap = transtables + ((tr_trans80-1)<alpha < 89) + dc_transmap = transtables + ((tr_trans70-1)<alpha < 115) + dc_transmap = transtables + ((tr_trans60-1)<alpha < 140) + dc_transmap = transtables + ((tr_trans50-1)<alpha < 166) + dc_transmap = transtables + ((tr_trans40-1)<alpha < 192) + dc_transmap = transtables + ((tr_trans30-1)<alpha < 217) + dc_transmap = transtables + ((tr_trans20-1)<alpha < 243) + dc_transmap = transtables + ((tr_trans10-1)<flags & FF_FOG) + colfunc = colfuncs[COLDRAWFUNC_FOG]; + +#ifdef ESLOPE + range = max(ds->x2-ds->x1, 1); +#endif + //SoM: Moved these up here so they are available for my lightlist calculations + rw_scalestep = ds->scalestep; + spryscale = ds->scale1 + (x1 - ds->x1)*rw_scalestep; + + dc_numlights = 0; + if (frontsector->numlights) + { + dc_numlights = frontsector->numlights; + if (dc_numlights > dc_maxlights) + { + dc_maxlights = dc_numlights; + dc_lightlist = Z_Realloc(dc_lightlist, sizeof (*dc_lightlist) * dc_maxlights, PU_STATIC, NULL); + } + + for (i = p = 0; i < dc_numlights; i++) + { +#ifdef ESLOPE + fixed_t leftheight, rightheight; + fixed_t pfloorleft, pfloorright; + INT64 overflow_test; +#endif + light = &frontsector->lightlist[i]; + rlight = &dc_lightlist[p]; +#ifdef ESLOPE + +#define SLOPEPARAMS(slope, end1, end2, normalheight) \ + if (slope) { \ + end1 = P_GetZAt(slope, ds->leftpos.x, ds->leftpos.y); \ + end2 = P_GetZAt(slope, ds->rightpos.x, ds->rightpos.y); \ + } else \ + end1 = end2 = normalheight; + + SLOPEPARAMS(light->slope, leftheight, rightheight, light->height) + SLOPEPARAMS(*pfloor->b_slope, pfloorleft, pfloorright, *pfloor->bottomheight) + + if (leftheight < pfloorleft && rightheight < pfloorright) + continue; + + SLOPEPARAMS(*pfloor->t_slope, pfloorleft, pfloorright, *pfloor->topheight) + + if (leftheight > pfloorleft && rightheight > pfloorright && i+1 < dc_numlights) + { + lightlist_t *nextlight = &frontsector->lightlist[i+1]; + if ((nextlight->slope ? P_GetZAt(nextlight->slope, ds->leftpos.x, ds->leftpos.y) : nextlight->height) > pfloorleft + && (nextlight->slope ? P_GetZAt(nextlight->slope, ds->rightpos.x, ds->rightpos.y) : nextlight->height) > pfloorright) + continue; + } + + leftheight -= viewz; + rightheight -= viewz; + +#define CLAMPMAX INT32_MAX +#define CLAMPMIN (-INT32_MAX) // This is not INT32_MIN on purpose! INT32_MIN makes the drawers freak out. + // Monster Iestyn (25/03/18): do not skip these lights if they fail overflow test, just clamp them instead so they behave. + overflow_test = (INT64)centeryfrac - (((INT64)leftheight*ds->scale1)>>FRACBITS); + if (overflow_test > (INT64)CLAMPMAX) rlight->height = CLAMPMAX; + else if (overflow_test > (INT64)CLAMPMIN) rlight->height = (fixed_t)overflow_test; + else rlight->height = CLAMPMIN; + + overflow_test = (INT64)centeryfrac - (((INT64)rightheight*ds->scale2)>>FRACBITS); + if (overflow_test > (INT64)CLAMPMAX) rlight->heightstep = CLAMPMAX; + else if (overflow_test > (INT64)CLAMPMIN) rlight->heightstep = (fixed_t)overflow_test; + else rlight->heightstep = CLAMPMIN; + rlight->heightstep = (rlight->heightstep-rlight->height)/(range); +#else + if (light->height < *pfloor->bottomheight) + continue; + + if (light->height > *pfloor->topheight && i+1 < dc_numlights && frontsector->lightlist[i+1].height > *pfloor->topheight) + continue; + + lheight = light->height;// > *pfloor->topheight ? *pfloor->topheight + FRACUNIT : light->height; + rlight->heightstep = -FixedMul (rw_scalestep, (lheight - viewz)); + rlight->height = (centeryfrac) - FixedMul((lheight - viewz), spryscale); +#endif + rlight->flags = light->flags; + if (light->flags & FF_CUTLEVEL) + { +#ifdef ESLOPE + SLOPEPARAMS(*light->caster->b_slope, leftheight, rightheight, *light->caster->bottomheight) +#undef SLOPEPARAMS + leftheight -= viewz; + rightheight -= viewz; + + // Monster Iestyn (25/03/18): do not skip these lights if they fail overflow test, just clamp them instead so they behave. + overflow_test = (INT64)centeryfrac - (((INT64)leftheight*ds->scale1)>>FRACBITS); + if (overflow_test > (INT64)CLAMPMAX) rlight->botheight = CLAMPMAX; + else if (overflow_test > (INT64)CLAMPMIN) rlight->botheight = (fixed_t)overflow_test; + else rlight->botheight = CLAMPMIN; + + overflow_test = (INT64)centeryfrac - (((INT64)rightheight*ds->scale2)>>FRACBITS); + if (overflow_test > (INT64)CLAMPMAX) rlight->botheightstep = CLAMPMAX; + else if (overflow_test > (INT64)CLAMPMIN) rlight->botheightstep = (fixed_t)overflow_test; + else rlight->botheightstep = CLAMPMIN; + rlight->botheightstep = (rlight->botheightstep-rlight->botheight)/(range); +#else + lheight = *light->caster->bottomheight;// > *pfloor->topheight ? *pfloor->topheight + FRACUNIT : *light->caster->bottomheight; + rlight->botheightstep = -FixedMul (rw_scalestep, (lheight - viewz)); + rlight->botheight = (centeryfrac) - FixedMul((lheight - viewz), spryscale); +#endif + } + + rlight->lightlevel = *light->lightlevel; + rlight->extra_colormap = *light->extra_colormap; + + // Check if the current light effects the colormap/lightlevel + if (pfloor->flags & FF_FOG) + rlight->lightnum = (pfloor->master->frontsector->lightlevel >> LIGHTSEGSHIFT); + else + rlight->lightnum = (rlight->lightlevel >> LIGHTSEGSHIFT); + + if (pfloor->flags & FF_FOG || rlight->flags & FF_FOG || (rlight->extra_colormap && rlight->extra_colormap->fog)) + ; + else if (curline->v1->y == curline->v2->y) + rlight->lightnum--; + else if (curline->v1->x == curline->v2->x) + rlight->lightnum++; + + p++; + } + + dc_numlights = p; + } + else + { + // Get correct light level! + if ((frontsector->extra_colormap && frontsector->extra_colormap->fog)) + lightnum = (frontsector->lightlevel >> LIGHTSEGSHIFT); + else if (pfloor->flags & FF_FOG) + lightnum = (pfloor->master->frontsector->lightlevel >> LIGHTSEGSHIFT); + else if (colfunc == colfuncs[COLDRAWFUNC_FUZZY]) + lightnum = LIGHTLEVELS-1; + else + lightnum = R_FakeFlat(frontsector, &tempsec, &templight, &templight, false) + ->lightlevel >> LIGHTSEGSHIFT; + + if (pfloor->flags & FF_FOG || (frontsector->extra_colormap && frontsector->extra_colormap->fog)); + else if (curline->v1->y == curline->v2->y) + lightnum--; + else if (curline->v1->x == curline->v2->x) + lightnum++; + + if (lightnum < 0) + walllights = scalelight[0]; + else if (lightnum >= LIGHTLEVELS) + walllights = scalelight[LIGHTLEVELS-1]; + else + walllights = scalelight[lightnum]; + } + + maskedtexturecol = ds->thicksidecol; + + mfloorclip = ds->sprbottomclip; + mceilingclip = ds->sprtopclip; + dc_texheight = textureheight[texnum]>>FRACBITS; + +#ifdef ESLOPE + // calculate both left ends + if (*pfloor->t_slope) + left_top = P_GetZAt(*pfloor->t_slope, ds->leftpos.x, ds->leftpos.y) - viewz; + else + left_top = *pfloor->topheight - viewz; + + if (*pfloor->b_slope) + left_bottom = P_GetZAt(*pfloor->b_slope, ds->leftpos.x, ds->leftpos.y) - viewz; + else + left_bottom = *pfloor->bottomheight - viewz; + skewslope = *pfloor->t_slope; // skew using top slope by default + if (newline) + { + if (newline->flags & ML_DONTPEGTOP) + slopeskew = true; + } + else if (pfloor->master->flags & ML_DONTPEGTOP) + slopeskew = true; + + if (slopeskew) + dc_texturemid = left_top; + else +#endif + dc_texturemid = *pfloor->topheight - viewz; + + if (newline) + { + offsetvalue = sides[newline->sidenum[0]].rowoffset; + if (newline->flags & ML_DONTPEGBOTTOM) + { +#ifdef ESLOPE + skewslope = *pfloor->b_slope; // skew using bottom slope + if (slopeskew) + dc_texturemid = left_bottom; + else +#endif + offsetvalue -= *pfloor->topheight - *pfloor->bottomheight; + } + } + else + { + offsetvalue = sides[pfloor->master->sidenum[0]].rowoffset; + if (curline->linedef->flags & ML_DONTPEGBOTTOM) + { +#ifdef ESLOPE + skewslope = *pfloor->b_slope; // skew using bottom slope + if (slopeskew) + dc_texturemid = left_bottom; + else +#endif + offsetvalue -= *pfloor->topheight - *pfloor->bottomheight; + } + } + +#ifdef ESLOPE + if (slopeskew) + { + angle_t lineangle = R_PointToAngle2(curline->v1->x, curline->v1->y, curline->v2->x, curline->v2->y); + + if (skewslope) + ffloortextureslide = FixedMul(skewslope->zdelta, FINECOSINE((lineangle-skewslope->xydirection)>>ANGLETOFINESHIFT)); + } +#endif + + dc_texturemid += offsetvalue; + + // Texture must be cached before setting colfunc_2s, + // otherwise texture[texnum]->holes may be false when it shouldn't be + R_CheckTextureCache(texnum); + //faB: handle case where multipatch texture is drawn on a 2sided wall, multi-patch textures + // are not stored per-column with post info anymore in Doom Legacy + if (textures[texnum]->holes) + { + if (textures[texnum]->flip & 2) // vertically flipped? + { + colfunc_2s = R_DrawRepeatFlippedMaskedColumn; + column2s_length = textures[texnum]->height; + } + else + colfunc_2s = R_DrawRepeatMaskedColumn; // render the usual 2sided single-patch packed texture + } + else + { + colfunc_2s = R_Render2sidedMultiPatchColumn; //render multipatch with no holes (no post_t info) + column2s_length = textures[texnum]->height; + } + +#ifdef ESLOPE + // Set heights according to plane, or slope, whichever + { + fixed_t right_top, right_bottom; + + // calculate right ends now + if (*pfloor->t_slope) + right_top = P_GetZAt(*pfloor->t_slope, ds->rightpos.x, ds->rightpos.y) - viewz; + else + right_top = *pfloor->topheight - viewz; + + if (*pfloor->b_slope) + right_bottom = P_GetZAt(*pfloor->b_slope, ds->rightpos.x, ds->rightpos.y) - viewz; + else + right_bottom = *pfloor->bottomheight - viewz; + + // using INT64 to avoid 32bit overflow + top_frac = (INT64)centeryfrac - (((INT64)left_top * ds->scale1) >> FRACBITS); + bottom_frac = (INT64)centeryfrac - (((INT64)left_bottom * ds->scale1) >> FRACBITS); + top_step = (INT64)centeryfrac - (((INT64)right_top * ds->scale2) >> FRACBITS); + bottom_step = (INT64)centeryfrac - (((INT64)right_bottom * ds->scale2) >> FRACBITS); + + top_step = (top_step-top_frac)/(range); + bottom_step = (bottom_step-bottom_frac)/(range); + + top_frac += top_step * (x1 - ds->x1); + bottom_frac += bottom_step * (x1 - ds->x1); + } +#endif + + // draw the columns + for (dc_x = x1; dc_x <= x2; dc_x++) + { + if (maskedtexturecol[dc_x] != INT16_MAX) + { +#ifdef ESLOPE + if (ffloortextureslide) { // skew FOF walls + if (oldx != -1) + dc_texturemid += FixedMul(ffloortextureslide, (maskedtexturecol[oldx]-maskedtexturecol[dc_x])< (INT64)CLAMPMAX) sprtopscreen = windowtop = CLAMPMAX; + else if (top_frac > (INT64)CLAMPMIN) sprtopscreen = windowtop = (fixed_t)top_frac; + else sprtopscreen = windowtop = CLAMPMIN; + if (bottom_frac > (INT64)CLAMPMAX) sprbotscreen = windowbottom = CLAMPMAX; + else if (bottom_frac > (INT64)CLAMPMIN) sprbotscreen = windowbottom = (fixed_t)bottom_frac; + else sprbotscreen = windowbottom = CLAMPMIN; + + top_frac += top_step; + bottom_frac += bottom_step; +#else + sprtopscreen = windowtop = (centeryfrac - FixedMul((dc_texturemid - offsetvalue), spryscale)); + sprbotscreen = windowbottom = FixedMul(*pfloor->topheight - *pfloor->bottomheight, spryscale) + sprtopscreen; +#endif + + // SoM: If column is out of range, why bother with it?? + if (windowbottom < topbounds || windowtop > bottombounds) + { + if (dc_numlights) + { + for (i = 0; i < dc_numlights; i++) + { + rlight = &dc_lightlist[i]; + rlight->height += rlight->heightstep; + if (rlight->flags & FF_CUTLEVEL) + rlight->botheight += rlight->botheightstep; + } + } + spryscale += rw_scalestep; + continue; + } + + dc_iscale = 0xffffffffu / (unsigned)spryscale; + + // Get data for the column + col = (column_t *)((UINT8 *)R_GetColumn(texnum,maskedtexturecol[dc_x]) - 3); + + // SoM: New code does not rely on R_DrawColumnShadowed_8 which + // will (hopefully) put less strain on the stack. + if (dc_numlights) + { + lighttable_t **xwalllights; + fixed_t height; + fixed_t bheight = 0; + INT32 solid = 0; + INT32 lighteffect = 0; + + for (i = 0; i < dc_numlights; i++) + { + // Check if the current light effects the colormap/lightlevel + rlight = &dc_lightlist[i]; + lighteffect = !(dc_lightlist[i].flags & FF_NOSHADE); + if (lighteffect) + { + lightnum = rlight->lightnum; + + if (lightnum < 0) + xwalllights = scalelight[0]; + else if (lightnum >= LIGHTLEVELS) + xwalllights = scalelight[LIGHTLEVELS-1]; + else + xwalllights = scalelight[lightnum]; + + pindex = FixedMul(spryscale, FixedDiv(640, vid.width))>>LIGHTSCALESHIFT; + + if (pindex >= MAXLIGHTSCALE) + pindex = MAXLIGHTSCALE-1; + + if (pfloor->flags & FF_FOG) + { + if (pfloor->master->frontsector->extra_colormap) + rlight->rcolormap = pfloor->master->frontsector->extra_colormap->colormap + (xwalllights[pindex] - colormaps); + else + rlight->rcolormap = xwalllights[pindex]; + } + else + { + if (rlight->extra_colormap) + rlight->rcolormap = rlight->extra_colormap->colormap + (xwalllights[pindex] - colormaps); + else + rlight->rcolormap = xwalllights[pindex]; + } + } + + solid = 0; // don't carry over solid-cutting flag from the previous light + + // Check if the current light can cut the current 3D floor. + if (rlight->flags & FF_CUTSOLIDS && !(pfloor->flags & FF_EXTRA)) + solid = 1; + else if (rlight->flags & FF_CUTEXTRA && pfloor->flags & FF_EXTRA) + { + if (rlight->flags & FF_EXTRA) + { + // The light is from an extra 3D floor... Check the flags so + // there are no undesired cuts. + if ((rlight->flags & (FF_FOG|FF_SWIMMABLE)) == (pfloor->flags & (FF_FOG|FF_SWIMMABLE))) + solid = 1; + } + else + solid = 1; + } + else + solid = 0; + + height = rlight->height; + rlight->height += rlight->heightstep; + + if (solid) + { + bheight = rlight->botheight - (FRACUNIT >> 1); + rlight->botheight += rlight->botheightstep; + } + + if (height <= windowtop) + { + if (lighteffect) + dc_colormap = rlight->rcolormap; + if (solid && windowtop < bheight) + windowtop = bheight; + continue; + } + + windowbottom = height; + if (windowbottom >= sprbotscreen) + { + windowbottom = sprbotscreen; + // draw the texture + colfunc_2s (col); + for (i++; i < dc_numlights; i++) + { + rlight = &dc_lightlist[i]; + rlight->height += rlight->heightstep; + if (rlight->flags & FF_CUTLEVEL) + rlight->botheight += rlight->botheightstep; + } + continue; + } + // draw the texture + colfunc_2s (col); + if (solid) + windowtop = bheight; + else + windowtop = windowbottom + 1; + if (lighteffect) + dc_colormap = rlight->rcolormap; + } + windowbottom = sprbotscreen; + // draw the texture, if there is any space left + if (windowtop < windowbottom) + colfunc_2s (col); + + spryscale += rw_scalestep; + continue; + } + + // calculate lighting + pindex = FixedMul(spryscale, FixedDiv(640, vid.width))>>LIGHTSCALESHIFT; + + if (pindex >= MAXLIGHTSCALE) + pindex = MAXLIGHTSCALE - 1; + + dc_colormap = walllights[pindex]; + + if (pfloor->flags & FF_FOG && pfloor->master->frontsector->extra_colormap) + dc_colormap = pfloor->master->frontsector->extra_colormap->colormap + (dc_colormap - colormaps); + else if (frontsector->extra_colormap) + dc_colormap = frontsector->extra_colormap->colormap + (dc_colormap - colormaps); + + // draw the texture + colfunc_2s (col); + spryscale += rw_scalestep; + } + } + colfunc = colfuncs[BASEDRAWFUNC]; + +#undef CLAMPMAX +#undef CLAMPMIN +} From 5f1e3bab718f2c278c00ef0da39bc62ea1a66dae Mon Sep 17 00:00:00 2001 From: Jaime Passos Date: Thu, 26 Dec 2019 16:25:04 -0300 Subject: [PATCH 32/79] struct time --- src/r_bsp.c | 2 +- src/r_main.c | 6 +- src/r_segs.c | 406 ++++++++++++++++++++++++-------------------------- src/r_state.h | 23 ++- 4 files changed, 219 insertions(+), 218 deletions(-) diff --git a/src/r_bsp.c b/src/r_bsp.c index 51d9bd3fd..b6dbfd76a 100644 --- a/src/r_bsp.c +++ b/src/r_bsp.c @@ -410,7 +410,7 @@ static void R_AddLine(seg_t *line) return; // Global angle needed by segcalc. - rw_angle1 = angle1; + rw.angle1 = angle1; angle1 -= viewangle; angle2 -= viewangle; diff --git a/src/r_main.c b/src/r_main.c index 0ef0a3d88..8c3fa8857 100644 --- a/src/r_main.c +++ b/src/r_main.c @@ -364,7 +364,7 @@ angle_t R_PointToAngleEx(INT32 x2, INT32 y2, INT32 x1, INT32 y1) // R_ScaleFromGlobalAngle // Returns the texture mapping scale for the current line (horizontal span) // at the given angle. -// rw_distance must be calculated first. +// rw.distance must be calculated first. // // killough 5/2/98: reformatted, cleaned up // @@ -372,8 +372,8 @@ angle_t R_PointToAngleEx(INT32 x2, INT32 y2, INT32 x1, INT32 y1) fixed_t R_ScaleFromGlobalAngle(angle_t visangle) { angle_t anglea = ANGLE_90 + (visangle-viewangle); - angle_t angleb = ANGLE_90 + (visangle-rw_normalangle); - fixed_t den = FixedMul(rw_distance, FINESINE(anglea>>ANGLETOFINESHIFT)); + angle_t angleb = ANGLE_90 + (visangle-rw.normalangle); + fixed_t den = FixedMul(rw.distance, FINESINE(anglea>>ANGLETOFINESHIFT)); // proff 11/06/98: Changed for high-res fixed_t num = FixedMul(projectiony, FINESINE(angleb>>ANGLETOFINESHIFT)); diff --git a/src/r_segs.c b/src/r_segs.c index b132ca976..63c9799e0 100644 --- a/src/r_segs.c +++ b/src/r_segs.c @@ -45,28 +45,16 @@ static vertex_t segleft, segright; static fixed_t ceilingfrontslide, floorfrontslide, ceilingbackslide, floorbackslide; #endif -angle_t rw_normalangle; -// angle to line origin -angle_t rw_angle1; -fixed_t rw_distance; - // for R_CalculateSegDistance #define SOFTWARE_USE_FLOATS // // regular wall // -static INT32 rw_x, rw_stopx; -static angle_t rw_centerangle; -static fixed_t rw_offset; -static fixed_t rw_offset2; // for splats -static fixed_t rw_scale, rw_scalestep; -static fixed_t rw_midtexturemid, rw_toptexturemid, rw_bottomtexturemid; +renderwall_t rw; static INT32 worldtop, worldbottom, worldhigh, worldlow; #ifdef ESLOPE static INT32 worldtopslope, worldbottomslope, worldhighslope, worldlowslope; // worldtop/bottom at end of slope -static fixed_t rw_toptextureslide, rw_midtextureslide, rw_bottomtextureslide; // Defines how to adjust Y offsets along the wall for slopes -static fixed_t rw_midtextureback, rw_midtexturebackslide; // Values for masked midtexture height calculation #endif static fixed_t pixhigh, pixlow, pixhighstep, pixlowstep; static fixed_t topfrac, topstep; @@ -133,12 +121,12 @@ static void R_RenderSegLoop (void) if (dc_numlights) colfunc = colfuncs[COLDRAWFUNC_SHADOWED]; - for (; rw_x < rw_stopx; rw_x++) + for (; rw.x < rw.stopx; rw.x++) { // mark floor / ceiling areas yl = (topfrac+HEIGHTUNIT-1)>>HEIGHTBITS; - top = ceilingclip[rw_x]+1; + top = ceilingclip[rw.x]+1; // no space above wall? if (yl < top) @@ -149,39 +137,39 @@ static void R_RenderSegLoop (void) #if 0 bottom = yl-1; - if (bottom >= floorclip[rw_x]) - bottom = floorclip[rw_x]-1; + if (bottom >= floorclip[rw.x]) + bottom = floorclip[rw.x]-1; if (top <= bottom) #else - bottom = yl > floorclip[rw_x] ? floorclip[rw_x] : yl; + bottom = yl > floorclip[rw.x] ? floorclip[rw.x] : yl; if (top <= --bottom && ceilingplane) #endif - R_ExpandPlaneY(ceilingplane, rw_x, top, bottom); + R_ExpandPlaneY(ceilingplane, rw.x, top, bottom); } yh = bottomfrac>>HEIGHTBITS; - bottom = floorclip[rw_x]-1; + bottom = floorclip[rw.x]-1; if (yh > bottom) yh = bottom; if (markfloor) { - top = yh < ceilingclip[rw_x] ? ceilingclip[rw_x] : yh; + top = yh < ceilingclip[rw.x] ? ceilingclip[rw.x] : yh; if (++top <= bottom && floorplane) - R_ExpandPlaneY(floorplane, rw_x, top, bottom); + R_ExpandPlaneY(floorplane, rw.x, top, bottom); } if (numffloors) { - firstseg->frontscale[rw_x] = frontscale[rw_x]; - top = ceilingclip[rw_x]+1; // PRBoom - bottom = floorclip[rw_x]-1; // PRBoom + firstseg->frontscale[rw.x] = frontscale[rw.x]; + top = ceilingclip[rw.x]+1; // PRBoom + bottom = floorclip[rw.x]-1; // PRBoom for (i = 0; i < numffloors; i++) { @@ -193,7 +181,7 @@ static void R_RenderSegLoop (void) if (ffloor[i].height < viewz) { INT32 top_w = (ffloor[i].f_frac >> HEIGHTBITS) + 1; - INT32 bottom_w = ffloor[i].f_clip[rw_x]; + INT32 bottom_w = ffloor[i].f_clip[rw.x]; if (top_w < top) top_w = top; @@ -204,20 +192,20 @@ static void R_RenderSegLoop (void) #ifdef POLYOBJECTS_PLANES // Polyobject-specific hack to fix plane leaking -Red if (ffloor[i].polyobj && top_w >= bottom_w) { - ffloor[i].plane->top[rw_x] = 0xFFFF; - ffloor[i].plane->bottom[rw_x] = 0x0000; // fix for sky plane drawing crashes - Monster Iestyn 25/05/18 + ffloor[i].plane->top[rw.x] = 0xFFFF; + ffloor[i].plane->bottom[rw.x] = 0x0000; // fix for sky plane drawing crashes - Monster Iestyn 25/05/18 } else #endif if (top_w <= bottom_w) { - ffloor[i].plane->top[rw_x] = (INT16)top_w; - ffloor[i].plane->bottom[rw_x] = (INT16)bottom_w; + ffloor[i].plane->top[rw.x] = (INT16)top_w; + ffloor[i].plane->bottom[rw.x] = (INT16)bottom_w; } } else if (ffloor[i].height > viewz) { - INT32 top_w = ffloor[i].c_clip[rw_x] + 1; + INT32 top_w = ffloor[i].c_clip[rw.x] + 1; INT32 bottom_w = (ffloor[i].f_frac >> HEIGHTBITS); if (top_w < top) @@ -229,15 +217,15 @@ static void R_RenderSegLoop (void) #ifdef POLYOBJECTS_PLANES // Polyobject-specific hack to fix plane leaking -Red if (ffloor[i].polyobj && top_w >= bottom_w) { - ffloor[i].plane->top[rw_x] = 0xFFFF; - ffloor[i].plane->bottom[rw_x] = 0x0000; // fix for sky plane drawing crashes - Monster Iestyn 25/05/18 + ffloor[i].plane->top[rw.x] = 0xFFFF; + ffloor[i].plane->bottom[rw.x] = 0x0000; // fix for sky plane drawing crashes - Monster Iestyn 25/05/18 } else #endif if (top_w <= bottom_w) { - ffloor[i].plane->top[rw_x] = (INT16)top_w; - ffloor[i].plane->bottom[rw_x] = (INT16)bottom_w; + ffloor[i].plane->top[rw.x] = (INT16)top_w; + ffloor[i].plane->bottom[rw.x] = (INT16)bottom_w; } } } @@ -247,22 +235,22 @@ static void R_RenderSegLoop (void) // Done for light lists anyway to avoid doing it for every light. if (segtextured || dc_numlights) { - pindex = FixedMul(rw_scale, FixedDiv(640, vid.width))>>LIGHTSCALESHIFT; + pindex = FixedMul(rw.scale, FixedDiv(640, vid.width))>>LIGHTSCALESHIFT; if (pindex >= MAXLIGHTSCALE) pindex = MAXLIGHTSCALE-1; } //SoM: Calculate offsets for Thick fake floors. // calculate texture offset - angle = (rw_centerangle + xtoviewangle[rw_x])>>ANGLETOFINESHIFT; - texturecolumn = rw_offset-FixedMul(FINETANGENT(angle),rw_distance); + angle = (rw.centerangle + xtoviewangle[rw.x])>>ANGLETOFINESHIFT; + texturecolumn = rw.offset-FixedMul(FINETANGENT(angle),rw.distance); #ifdef ESLOPE if (oldtexturecolumn != -1) { - rw_bottomtexturemid += FixedMul(rw_bottomtextureslide, oldtexturecolumn-texturecolumn); - rw_midtexturemid += FixedMul(rw_midtextureslide, oldtexturecolumn-texturecolumn); - rw_toptexturemid += FixedMul(rw_toptextureslide, oldtexturecolumn-texturecolumn); - rw_midtextureback += FixedMul(rw_midtexturebackslide, oldtexturecolumn-texturecolumn); + rw.bottomtexturemid += FixedMul(rw.bottomtextureslide, oldtexturecolumn-texturecolumn); + rw.midtexturemid += FixedMul(rw.midtextureslide, oldtexturecolumn-texturecolumn); + rw.toptexturemid += FixedMul(rw.toptextureslide, oldtexturecolumn-texturecolumn); + rw.midtextureback += FixedMul(rw.midtexturebackslide, oldtexturecolumn-texturecolumn); } oldtexturecolumn = texturecolumn; #endif @@ -273,8 +261,8 @@ static void R_RenderSegLoop (void) if (segtextured) { dc_colormap = walllights[pindex]; - dc_x = rw_x; - dc_iscale = 0xffffffffu / (unsigned)rw_scale; + dc_x = rw.x; + dc_iscale = 0xffffffffu / (unsigned)rw.scale; if (frontsector->extra_colormap) dc_colormap = frontsector->extra_colormap->colormap + (dc_colormap - colormaps); @@ -309,7 +297,7 @@ static void R_RenderSegLoop (void) } } - frontscale[rw_x] = rw_scale; + frontscale[rw.x] = rw.scale; // draw the wall tiers if (midtexture) @@ -319,7 +307,7 @@ static void R_RenderSegLoop (void) { dc_yl = yl; dc_yh = yh; - dc_texturemid = rw_midtexturemid; + dc_texturemid = rw.midtexturemid; dc_source = R_GetColumn(midtexture,texturecolumn); dc_texheight = textureheight[midtexture]>>FRACBITS; @@ -340,16 +328,16 @@ static void R_RenderSegLoop (void) // dont draw anything more for this column, since // a midtexture blocks the view - ceilingclip[rw_x] = (INT16)viewheight; - floorclip[rw_x] = -1; + ceilingclip[rw.x] = (INT16)viewheight; + floorclip[rw.x] = -1; } else { // note: don't use min/max macros, since casting from INT32 to INT16 is involved here if (markceiling) - ceilingclip[rw_x] = (yl >= 0) ? ((yl > viewheight) ? (INT16)viewheight : (INT16)((INT16)yl - 1)) : -1; + ceilingclip[rw.x] = (yl >= 0) ? ((yl > viewheight) ? (INT16)viewheight : (INT16)((INT16)yl - 1)) : -1; if (markfloor) - floorclip[rw_x] = (yh < viewheight) ? ((yh < -1) ? -1 : (INT16)((INT16)yh + 1)) : (INT16)viewheight; + floorclip[rw.x] = (yh < viewheight) ? ((yh < -1) ? -1 : (INT16)((INT16)yh + 1)) : (INT16)viewheight; } } else @@ -361,31 +349,31 @@ static void R_RenderSegLoop (void) mid = pixhigh>>HEIGHTBITS; pixhigh += pixhighstep; - if (mid >= floorclip[rw_x]) - mid = floorclip[rw_x]-1; + if (mid >= floorclip[rw.x]) + mid = floorclip[rw.x]-1; if (mid >= yl) // back ceiling lower than front ceiling ? { if (yl >= viewheight) // entirely off bottom of screen - ceilingclip[rw_x] = (INT16)viewheight; + ceilingclip[rw.x] = (INT16)viewheight; else if (mid >= 0) // safe to draw top texture { dc_yl = yl; dc_yh = mid; - dc_texturemid = rw_toptexturemid; + dc_texturemid = rw.toptexturemid; dc_source = R_GetColumn(toptexture,texturecolumn); dc_texheight = textureheight[toptexture]>>FRACBITS; colfunc(); - ceilingclip[rw_x] = (INT16)mid; + ceilingclip[rw.x] = (INT16)mid; } else // entirely off top of screen - ceilingclip[rw_x] = -1; + ceilingclip[rw.x] = -1; } else - ceilingclip[rw_x] = (yl >= 0) ? ((yl > viewheight) ? (INT16)viewheight : (INT16)((INT16)yl - 1)) : -1; + ceilingclip[rw.x] = (yl >= 0) ? ((yl > viewheight) ? (INT16)viewheight : (INT16)((INT16)yl - 1)) : -1; } else if (markceiling) // no top wall - ceilingclip[rw_x] = (yl >= 0) ? ((yl > viewheight) ? (INT16)viewheight : (INT16)((INT16)yl - 1)) : -1; + ceilingclip[rw.x] = (yl >= 0) ? ((yl > viewheight) ? (INT16)viewheight : (INT16)((INT16)yl - 1)) : -1; if (bottomtexture) { @@ -394,45 +382,45 @@ static void R_RenderSegLoop (void) pixlow += pixlowstep; // no space above wall? - if (mid <= ceilingclip[rw_x]) - mid = ceilingclip[rw_x]+1; + if (mid <= ceilingclip[rw.x]) + mid = ceilingclip[rw.x]+1; if (mid <= yh) // back floor higher than front floor ? { if (yh < 0) // entirely off top of screen - floorclip[rw_x] = -1; + floorclip[rw.x] = -1; else if (mid < viewheight) // safe to draw bottom texture { dc_yl = mid; dc_yh = yh; - dc_texturemid = rw_bottomtexturemid; + dc_texturemid = rw.bottomtexturemid; dc_source = R_GetColumn(bottomtexture, texturecolumn); dc_texheight = textureheight[bottomtexture]>>FRACBITS; colfunc(); - floorclip[rw_x] = (INT16)mid; + floorclip[rw.x] = (INT16)mid; } else // entirely off bottom of screen - floorclip[rw_x] = (INT16)viewheight; + floorclip[rw.x] = (INT16)viewheight; } else - floorclip[rw_x] = (yh < viewheight) ? ((yh < -1) ? -1 : (INT16)((INT16)yh + 1)) : (INT16)viewheight; + floorclip[rw.x] = (yh < viewheight) ? ((yh < -1) ? -1 : (INT16)((INT16)yh + 1)) : (INT16)viewheight; } else if (markfloor) // no bottom wall - floorclip[rw_x] = (yh < viewheight) ? ((yh < -1) ? -1 : (INT16)((INT16)yh + 1)) : (INT16)viewheight; + floorclip[rw.x] = (yh < viewheight) ? ((yh < -1) ? -1 : (INT16)((INT16)yh + 1)) : (INT16)viewheight; } if (maskedtexture || numthicksides) { // save texturecol // for backdrawing of masked mid texture - maskedtexturecol[rw_x] = (INT16)texturecolumn; + maskedtexturecol[rw.x] = (INT16)texturecolumn; #ifdef ESLOPE if (maskedtextureheight != NULL) { - maskedtextureheight[rw_x] = (!!(curline->linedef->flags & ML_DONTPEGBOTTOM) ^ !!(curline->linedef->flags & ML_EFFECT3) ? - max(rw_midtexturemid, rw_midtextureback) : - min(rw_midtexturemid, rw_midtextureback)); + maskedtextureheight[rw.x] = (!!(curline->linedef->flags & ML_DONTPEGBOTTOM) ^ !!(curline->linedef->flags & ML_EFFECT3) ? + max(rw.midtexturemid, rw.midtextureback) : + min(rw.midtexturemid, rw.midtextureback)); } #endif } @@ -452,11 +440,11 @@ static void R_RenderSegLoop (void) for (i = 0; i < numbackffloors; i++) { - ffloor[i].f_clip[rw_x] = ffloor[i].c_clip[rw_x] = (INT16)((ffloor[i].b_frac >> HEIGHTBITS) & 0xFFFF); + ffloor[i].f_clip[rw.x] = ffloor[i].c_clip[rw.x] = (INT16)((ffloor[i].b_frac >> HEIGHTBITS) & 0xFFFF); ffloor[i].b_frac += ffloor[i].b_step; } - rw_scale += rw_scalestep; + rw.scale += rw.scalestep; topfrac += topstep; bottomfrac += bottomstep; } @@ -520,24 +508,24 @@ static void R_CalculateSegDistance(seg_t *seg, INT64 x2, INT64 y2, boolean longb x = FLOAT_TO_FIXED(ac*(-dy)); y = FLOAT_TO_FIXED(ac*dx); - rw_distance = R_PointToDist(viewx + x, viewy + y); + rw.distance = R_PointToDist(viewx + x, viewy + y); return; } - rw_distance = FLOAT_TO_FIXED(distance); + rw.distance = FLOAT_TO_FIXED(distance); #else (void)longboi; if (!seg->linedef->dy) - rw_distance = (fixed_t)(llabs(y2 - seg->v1->y)); + rw.distance = (fixed_t)(llabs(y2 - seg->v1->y)); else if (!seg->linedef->dx) - rw_distance = (fixed_t)(llabs(x2 - seg->v1->x)); + rw.distance = (fixed_t)(llabs(x2 - seg->v1->x)); else { INT64 dx = (seg->v2->x)-(seg->v1->x); INT64 dy = (seg->v2->y)-(seg->v1->y); INT64 vdx = x2-(seg->v1->x); INT64 vdy = y2-(seg->v1->y); - rw_distance = (fixed_t)(((dy*vdx)-(dx*vdy))/(seg->length)); + rw.distance = (fixed_t)(((dy*vdx)-(dx*vdy))/(seg->length)); } #endif } @@ -550,7 +538,7 @@ static INT32 R_CalculateWallScale(INT32 start, INT32 stop) { INT32 range = 1; - ds_p->scale1 = rw_scale = R_ScaleFromGlobalAngle(viewangle + xtoviewangle[start]); + ds_p->scale1 = rw.scale = R_ScaleFromGlobalAngle(viewangle + xtoviewangle[start]); if (stop > start) { @@ -561,7 +549,7 @@ static INT32 R_CalculateWallScale(INT32 start, INT32 stop) { // UNUSED: try to fix the stretched line bug #if 0 - if (rw_distance < FRACUNIT/2) + if (rw.distance < FRACUNIT/2) { fixed_t tr_x,tr_y; fixed_t gxt,gyt; @@ -578,7 +566,7 @@ static INT32 R_CalculateWallScale(INT32 start, INT32 stop) ds_p->scale2 = ds_p->scale1; } - ds_p->scalestep = rw_scalestep = (ds_p->scale2 - rw_scale) / (range); + ds_p->scalestep = rw.scalestep = (ds_p->scale2 - rw.scale) / (range); return range; } @@ -657,14 +645,14 @@ static void R_WorldTopAndBottom(INT32 start, INT32 stop) // // R_WorldSegTextured -// Calculate rw_offset. +// Calculate rw.offset. // Only needed for textured lines. // static void R_WorldSegTextured(fixed_t hyp, boolean longboi) { INT32 lightnum; fixed_t sineval; - angle_t offsetangle = rw_normalangle-rw_angle1; + angle_t offsetangle = rw.normalangle-rw.angle1; if (offsetangle > ANGLE_180) offsetangle = -(signed)offsetangle; @@ -672,7 +660,7 @@ static void R_WorldSegTextured(fixed_t hyp, boolean longboi) offsetangle = ANGLE_90; sineval = FINESINE(offsetangle>>ANGLETOFINESHIFT); - rw_offset = FixedMul(hyp, sineval); + rw.offset = FixedMul(hyp, sineval); // big room fix if (longboi) @@ -681,16 +669,16 @@ static void R_WorldSegTextured(fixed_t hyp, boolean longboi) INT64 dy = (curline->v2->y)-(curline->v1->y); INT64 vdx = viewx-(curline->v1->x); INT64 vdy = viewy-(curline->v1->y); - rw_offset = ((dx*vdx-dy*vdy))/(curline->length); + rw.offset = ((dx*vdx-dy*vdy))/(curline->length); } - if (rw_normalangle-rw_angle1 < ANGLE_180) - rw_offset = -rw_offset; + if (rw.normalangle-rw.angle1 < ANGLE_180) + rw.offset = -rw.offset; /// don't use texture offset for splats - rw_offset2 = rw_offset + curline->offset; - rw_offset += sidedef->textureoffset + curline->offset; - rw_centerangle = ANGLE_90 + viewangle - rw_normalangle; + rw.offset2 = rw.offset + curline->offset; + rw.offset += sidedef->textureoffset + curline->offset; + rw.centerangle = ANGLE_90 + viewangle - rw.normalangle; // calculate light table // use different light tables @@ -734,8 +722,8 @@ static void R_CheckMaskedTextures(void) //markceiling = markfloor = true; maskedtexture = true; - ds_p->thicksidecol = maskedtexturecol = lastopening - rw_x; - lastopening += rw_stopx - rw_x; + ds_p->thicksidecol = maskedtexturecol = lastopening - rw.x; + lastopening += rw.stopx - rw.x; lowcut = max(worldbottom, worldlow) + viewz; highcut = min(worldtop, worldhigh) + viewz; @@ -946,8 +934,8 @@ static void R_CheckMaskedTextures(void) // masked midtexture if (!ds_p->thicksidecol) { - ds_p->maskedtexturecol = maskedtexturecol = lastopening - rw_x; - lastopening += rw_stopx - rw_x; + ds_p->maskedtexturecol = maskedtexturecol = lastopening - rw.x; + lastopening += rw.stopx - rw.x; } else ds_p->maskedtexturecol = ds_p->thicksidecol; @@ -957,34 +945,34 @@ static void R_CheckMaskedTextures(void) #ifdef POLYOBJECTS if (curline->polyseg) { // use REAL front and back floors please, so midtexture rendering isn't mucked up - rw_midtextureslide = rw_midtexturebackslide = 0; + rw.midtextureslide = rw.midtexturebackslide = 0; if (!!(linedef->flags & ML_DONTPEGBOTTOM) ^ !!(linedef->flags & ML_EFFECT3)) - rw_midtexturemid = rw_midtextureback = max(curline->frontsector->floorheight, curline->backsector->floorheight) - viewz; + rw.midtexturemid = rw.midtextureback = max(curline->frontsector->floorheight, curline->backsector->floorheight) - viewz; else - rw_midtexturemid = rw_midtextureback = min(curline->frontsector->ceilingheight, curline->backsector->ceilingheight) - viewz; + rw.midtexturemid = rw.midtextureback = min(curline->frontsector->ceilingheight, curline->backsector->ceilingheight) - viewz; } else #endif // Set midtexture starting height if (linedef->flags & ML_EFFECT2) { // Ignore slopes when texturing - rw_midtextureslide = rw_midtexturebackslide = 0; + rw.midtextureslide = rw.midtexturebackslide = 0; if (!!(linedef->flags & ML_DONTPEGBOTTOM) ^ !!(linedef->flags & ML_EFFECT3)) - rw_midtexturemid = rw_midtextureback = max(frontsector->floorheight, backsector->floorheight) - viewz; + rw.midtexturemid = rw.midtextureback = max(frontsector->floorheight, backsector->floorheight) - viewz; else - rw_midtexturemid = rw_midtextureback = min(frontsector->ceilingheight, backsector->ceilingheight) - viewz; + rw.midtexturemid = rw.midtextureback = min(frontsector->ceilingheight, backsector->ceilingheight) - viewz; } else if (!!(linedef->flags & ML_DONTPEGBOTTOM) ^ !!(linedef->flags & ML_EFFECT3)) { - rw_midtexturemid = worldbottom; - rw_midtextureslide = floorfrontslide; - rw_midtextureback = worldlow; - rw_midtexturebackslide = floorbackslide; + rw.midtexturemid = worldbottom; + rw.midtextureslide = floorfrontslide; + rw.midtextureback = worldlow; + rw.midtexturebackslide = floorbackslide; } else { - rw_midtexturemid = worldtop; - rw_midtextureslide = ceilingfrontslide; - rw_midtextureback = worldhigh; - rw_midtexturebackslide = ceilingbackslide; + rw.midtexturemid = worldtop; + rw.midtextureslide = ceilingfrontslide; + rw.midtextureback = worldhigh; + rw.midtexturebackslide = ceilingbackslide; } - rw_midtexturemid += sidedef->rowoffset; - rw_midtextureback += sidedef->rowoffset; + rw.midtexturemid += sidedef->rowoffset; + rw.midtextureback += sidedef->rowoffset; #endif maskedtexture = true; @@ -1008,32 +996,32 @@ static void R_CheckWallTextures(void) #ifdef ESLOPE if (linedef->flags & ML_EFFECT2) { if (linedef->flags & ML_DONTPEGBOTTOM) - rw_midtexturemid = frontsector->floorheight + texheight - viewz; + rw.midtexturemid = frontsector->floorheight + texheight - viewz; else - rw_midtexturemid = frontsector->ceilingheight - viewz; + rw.midtexturemid = frontsector->ceilingheight - viewz; } else #endif if (linedef->flags & ML_DONTPEGBOTTOM) { #ifdef ESLOPE - rw_midtexturemid = worldbottom + texheight; - rw_midtextureslide = floorfrontslide; + rw.midtexturemid = worldbottom + texheight; + rw.midtextureslide = floorfrontslide; #else vtop = frontsector->floorheight + texheight; // bottom of texture at bottom - rw_midtexturemid = vtop - viewz; + rw.midtexturemid = vtop - viewz; #endif } else { // top of texture at top - rw_midtexturemid = worldtop; + rw.midtexturemid = worldtop; #ifdef ESLOPE - rw_midtextureslide = ceilingfrontslide; + rw.midtextureslide = ceilingfrontslide; #endif } - rw_midtexturemid += sidedef->rowoffset; + rw.midtexturemid += sidedef->rowoffset; } else { @@ -1066,28 +1054,28 @@ static void R_CheckWallTextures(void) #ifdef ESLOPE if (!(linedef->flags & ML_EFFECT1)) { // Ignore slopes for lower/upper textures unless flag is checked if (linedef->flags & ML_DONTPEGTOP) - rw_toptexturemid = frontsector->ceilingheight - viewz; + rw.toptexturemid = frontsector->ceilingheight - viewz; else - rw_toptexturemid = backsector->ceilingheight - viewz; + rw.toptexturemid = backsector->ceilingheight - viewz; } else #endif if (linedef->flags & ML_DONTPEGTOP) { // top of texture at top - rw_toptexturemid = worldtop; + rw.toptexturemid = worldtop; #ifdef ESLOPE - rw_toptextureslide = ceilingfrontslide; + rw.toptextureslide = ceilingfrontslide; #endif } else { #ifdef ESLOPE - rw_toptexturemid = worldhigh + texheight; - rw_toptextureslide = ceilingbackslide; + rw.toptexturemid = worldhigh + texheight; + rw.toptextureslide = ceilingbackslide; #else vtop = backsector->ceilingheight + texheight; // bottom of texture - rw_toptexturemid = vtop - viewz; + rw.toptexturemid = vtop - viewz; #endif } } @@ -1105,30 +1093,30 @@ static void R_CheckWallTextures(void) #ifdef ESLOPE if (!(linedef->flags & ML_EFFECT1)) { // Ignore slopes for lower/upper textures unless flag is checked if (linedef->flags & ML_DONTPEGBOTTOM) - rw_bottomtexturemid = frontsector->floorheight - viewz; + rw.bottomtexturemid = frontsector->floorheight - viewz; else - rw_bottomtexturemid = backsector->floorheight - viewz; + rw.bottomtexturemid = backsector->floorheight - viewz; } else #endif if (linedef->flags & ML_DONTPEGBOTTOM) { // bottom of texture at bottom // top of texture at top - rw_bottomtexturemid = worldbottom; + rw.bottomtexturemid = worldbottom; #ifdef ESLOPE - rw_bottomtextureslide = floorfrontslide; + rw.bottomtextureslide = floorfrontslide; #endif } else { // top of texture at top - rw_bottomtexturemid = worldlow; + rw.bottomtexturemid = worldlow; #ifdef ESLOPE - rw_bottomtextureslide = floorbackslide; + rw.bottomtextureslide = floorbackslide; #endif } } - rw_toptexturemid += sidedef->rowoffset; - rw_bottomtexturemid += sidedef->rowoffset; + rw.toptexturemid += sidedef->rowoffset; + rw.bottomtexturemid += sidedef->rowoffset; } } @@ -1397,11 +1385,11 @@ static void R_WorldStep(INT32 range) topfrac = bottomfrac = (centeryfrac>>4); topfrac++; // Prevent 1px HOM } else { - topstep = -FixedMul (rw_scalestep, worldtop); - topfrac = (centeryfrac>>4) - FixedMul (worldtop, rw_scale); + topstep = -FixedMul (rw.scalestep, worldtop); + topfrac = (centeryfrac>>4) - FixedMul (worldtop, rw.scale); - bottomstep = -FixedMul (rw_scalestep,worldbottom); - bottomfrac = (centeryfrac>>4) - FixedMul (worldbottom, rw_scale); + bottomstep = -FixedMul (rw.scalestep,worldbottom); + bottomfrac = (centeryfrac>>4) - FixedMul (worldbottom, rw.scale); #ifdef ESLOPE if (frontsector->c_slope) { @@ -1435,8 +1423,8 @@ static void R_WorldBackStep(INT32 range) if (toptexture) { - pixhigh = (centeryfrac>>4) - FixedMul (worldhigh, rw_scale); - pixhighstep = -FixedMul (rw_scalestep,worldhigh); + pixhigh = (centeryfrac>>4) - FixedMul (worldhigh, rw.scale); + pixhighstep = -FixedMul (rw.scalestep,worldhigh); #ifdef ESLOPE if (backsector->c_slope) { @@ -1448,8 +1436,8 @@ static void R_WorldBackStep(INT32 range) if (bottomtexture) { - pixlow = (centeryfrac>>4) - FixedMul (worldlow, rw_scale); - pixlowstep = -FixedMul (rw_scalestep,worldlow); + pixlow = (centeryfrac>>4) - FixedMul (worldlow, rw.scale); + pixlowstep = -FixedMul (rw.scalestep,worldlow); #ifdef ESLOPE if (backsector->f_slope) { fixed_t bottomfracend = (centeryfrac>>4) - FixedMul (worldlowslope, ds_p->scale2); @@ -1494,7 +1482,7 @@ static void R_WorldBackStep(INT32 range) ffloor[i].b_pos_slope = roverright; ffloor[i].b_pos >>= 4; ffloor[i].b_pos_slope >>= 4; - ffloor[i].b_frac = (centeryfrac >> 4) - FixedMul(ffloor[i].b_pos, rw_scale); + ffloor[i].b_frac = (centeryfrac >> 4) - FixedMul(ffloor[i].b_pos, rw.scale); ffloor[i].b_step = (centeryfrac >> 4) - FixedMul(ffloor[i].b_pos_slope, ds_p->scale2); ffloor[i].b_step = (ffloor[i].b_step-ffloor[i].b_frac)/(range); i++; @@ -1517,7 +1505,7 @@ static void R_WorldBackStep(INT32 range) ffloor[i].b_pos_slope = roverright; ffloor[i].b_pos >>= 4; ffloor[i].b_pos_slope >>= 4; - ffloor[i].b_frac = (centeryfrac >> 4) - FixedMul(ffloor[i].b_pos, rw_scale); + ffloor[i].b_frac = (centeryfrac >> 4) - FixedMul(ffloor[i].b_pos, rw.scale); ffloor[i].b_step = (centeryfrac >> 4) - FixedMul(ffloor[i].b_pos_slope, ds_p->scale2); ffloor[i].b_step = (ffloor[i].b_step-ffloor[i].b_frac)/(range); i++; @@ -1530,8 +1518,8 @@ static void R_WorldBackStep(INT32 range) { ffloor[i].b_pos = *rover->bottomheight; ffloor[i].b_pos = (ffloor[i].b_pos - viewz) >> 4; - ffloor[i].b_step = FixedMul(-rw_scalestep, ffloor[i].b_pos); - ffloor[i].b_frac = (centeryfrac >> 4) - FixedMul(ffloor[i].b_pos, rw_scale); + ffloor[i].b_step = FixedMul(-rw.scalestep, ffloor[i].b_pos); + ffloor[i].b_frac = (centeryfrac >> 4) - FixedMul(ffloor[i].b_pos, rw.scale); i++; } @@ -1545,8 +1533,8 @@ static void R_WorldBackStep(INT32 range) { ffloor[i].b_pos = *rover->topheight; ffloor[i].b_pos = (ffloor[i].b_pos - viewz) >> 4; - ffloor[i].b_step = FixedMul(-rw_scalestep, ffloor[i].b_pos); - ffloor[i].b_frac = (centeryfrac >> 4) - FixedMul(ffloor[i].b_pos, rw_scale); + ffloor[i].b_step = FixedMul(-rw.scalestep, ffloor[i].b_pos); + ffloor[i].b_frac = (centeryfrac >> 4) - FixedMul(ffloor[i].b_pos, rw.scale); i++; } #endif @@ -1581,7 +1569,7 @@ static void R_WorldBackStep(INT32 range) ffloor[i].b_pos_slope = roverright; ffloor[i].b_pos >>= 4; ffloor[i].b_pos_slope >>= 4; - ffloor[i].b_frac = (centeryfrac >> 4) - FixedMul(ffloor[i].b_pos, rw_scale); + ffloor[i].b_frac = (centeryfrac >> 4) - FixedMul(ffloor[i].b_pos, rw.scale); ffloor[i].b_step = (centeryfrac >> 4) - FixedMul(ffloor[i].b_pos_slope, ds_p->scale2); ffloor[i].b_step = (ffloor[i].b_step-ffloor[i].b_frac)/(range); i++; @@ -1604,7 +1592,7 @@ static void R_WorldBackStep(INT32 range) ffloor[i].b_pos_slope = roverright; ffloor[i].b_pos >>= 4; ffloor[i].b_pos_slope >>= 4; - ffloor[i].b_frac = (centeryfrac >> 4) - FixedMul(ffloor[i].b_pos, rw_scale); + ffloor[i].b_frac = (centeryfrac >> 4) - FixedMul(ffloor[i].b_pos, rw.scale); ffloor[i].b_step = (centeryfrac >> 4) - FixedMul(ffloor[i].b_pos_slope, ds_p->scale2); ffloor[i].b_step = (ffloor[i].b_step-ffloor[i].b_frac)/(range); i++; @@ -1617,8 +1605,8 @@ static void R_WorldBackStep(INT32 range) { ffloor[i].b_pos = *rover->bottomheight; ffloor[i].b_pos = (ffloor[i].b_pos - viewz) >> 4; - ffloor[i].b_step = FixedMul(-rw_scalestep, ffloor[i].b_pos); - ffloor[i].b_frac = (centeryfrac >> 4) - FixedMul(ffloor[i].b_pos, rw_scale); + ffloor[i].b_step = FixedMul(-rw.scalestep, ffloor[i].b_pos); + ffloor[i].b_frac = (centeryfrac >> 4) - FixedMul(ffloor[i].b_pos, rw.scale); i++; } if (i >= MAXFFLOORS) @@ -1630,8 +1618,8 @@ static void R_WorldBackStep(INT32 range) { ffloor[i].b_pos = *rover->topheight; ffloor[i].b_pos = (ffloor[i].b_pos - viewz) >> 4; - ffloor[i].b_step = FixedMul(-rw_scalestep, ffloor[i].b_pos); - ffloor[i].b_frac = (centeryfrac >> 4) - FixedMul(ffloor[i].b_pos, rw_scale); + ffloor[i].b_step = FixedMul(-rw.scalestep, ffloor[i].b_pos); + ffloor[i].b_frac = (centeryfrac >> 4) - FixedMul(ffloor[i].b_pos, rw.scale); i++; } #endif @@ -1657,8 +1645,8 @@ static void R_WorldBackStep(INT32 range) #endif ffloor[i].b_pos = backsector->floorheight; ffloor[i].b_pos = (ffloor[i].b_pos - viewz) >> 4; - ffloor[i].b_step = FixedMul(-rw_scalestep, ffloor[i].b_pos); - ffloor[i].b_frac = (centeryfrac >> 4) - FixedMul(ffloor[i].b_pos, rw_scale); + ffloor[i].b_step = FixedMul(-rw.scalestep, ffloor[i].b_pos); + ffloor[i].b_frac = (centeryfrac >> 4) - FixedMul(ffloor[i].b_pos, rw.scale); i++; } if (i < numffloors && backsector->ceilingheight >= frontsector->floorheight && @@ -1676,8 +1664,8 @@ static void R_WorldBackStep(INT32 range) #endif ffloor[i].b_pos = backsector->ceilingheight; ffloor[i].b_pos = (ffloor[i].b_pos - viewz) >> 4; - ffloor[i].b_step = FixedMul(-rw_scalestep, ffloor[i].b_pos); - ffloor[i].b_frac = (centeryfrac >> 4) - FixedMul(ffloor[i].b_pos, rw_scale); + ffloor[i].b_step = FixedMul(-rw.scalestep, ffloor[i].b_pos); + ffloor[i].b_frac = (centeryfrac >> 4) - FixedMul(ffloor[i].b_pos, rw.scale); i++; } } @@ -1714,11 +1702,11 @@ static void R_WorldFFloorStep(INT32 range) else { #ifdef ESLOPE - ffloor[i].f_frac = (centeryfrac>>4) - FixedMul(ffloor[i].f_pos, rw_scale); + ffloor[i].f_frac = (centeryfrac>>4) - FixedMul(ffloor[i].f_pos, rw.scale); ffloor[i].f_step = ((centeryfrac>>4) - FixedMul(ffloor[i].f_pos_slope, ds_p->scale2) - ffloor[i].f_frac)/(range); #else - ffloor[i].f_step = FixedMul(-rw_scalestep, ffloor[i].f_pos); - ffloor[i].f_frac = (centeryfrac>>4) - FixedMul(ffloor[i].f_pos, rw_scale); + ffloor[i].f_step = FixedMul(-rw.scalestep, ffloor[i].f_pos); + ffloor[i].f_frac = (centeryfrac>>4) - FixedMul(ffloor[i].f_pos, rw.scale); #endif } } @@ -1793,12 +1781,12 @@ static void R_WorldLightLists(INT32 range) } #ifdef ESLOPE - rlight->height = (centeryfrac>>4) - FixedMul(leftheight, rw_scale); + rlight->height = (centeryfrac>>4) - FixedMul(leftheight, rw.scale); rlight->heightstep = (centeryfrac>>4) - FixedMul(rightheight, ds_p->scale2); rlight->heightstep = (rlight->heightstep-rlight->height)/(range); #else - rlight->height = (centeryfrac>>4) - FixedMul((light->height - viewz) >> 4, rw_scale); - rlight->heightstep = -FixedMul (rw_scalestep, (light->height - viewz) >> 4); + rlight->height = (centeryfrac>>4) - FixedMul((light->height - viewz) >> 4, rw.scale); + rlight->heightstep = -FixedMul (rw.scalestep, (light->height - viewz) >> 4); #endif rlight->flags = light->flags; @@ -1820,13 +1808,13 @@ static void R_WorldLightLists(INT32 range) leftheight >>= 4; rightheight >>= 4; - rlight->botheight = (centeryfrac>>4) - FixedMul(leftheight, rw_scale); + rlight->botheight = (centeryfrac>>4) - FixedMul(leftheight, rw.scale); rlight->botheightstep = (centeryfrac>>4) - FixedMul(rightheight, ds_p->scale2); rlight->botheightstep = (rlight->botheightstep-rlight->botheight)/(range); #else - rlight->botheight = (centeryfrac >> 4) - FixedMul((*light->caster->bottomheight - viewz) >> 4, rw_scale); - rlight->botheightstep = -FixedMul (rw_scalestep, (*light->caster->bottomheight - viewz) >> 4); + rlight->botheight = (centeryfrac >> 4) - FixedMul((*light->caster->bottomheight - viewz) >> 4, rw.scale); + rlight->botheightstep = -FixedMul (rw.scalestep, (*light->caster->bottomheight - viewz) >> 4); #endif } @@ -1851,7 +1839,7 @@ static void R_MarkPlanes(void) if (markceiling) { if (ceilingplane) //SoM: 3/29/2000: Check for null ceiling planes - ceilingplane = R_CheckPlane (ceilingplane, rw_x, rw_stopx-1); + ceilingplane = R_CheckPlane (ceilingplane, rw.x, rw.stopx-1); else markceiling = false; @@ -1865,7 +1853,7 @@ static void R_MarkPlanes(void) if (markfloor) { if (floorplane) //SoM: 3/29/2000: Check for null planes - floorplane = R_CheckPlane (floorplane, rw_x, rw_stopx-1); + floorplane = R_CheckPlane (floorplane, rw.x, rw.stopx-1); else markfloor = false; @@ -1885,7 +1873,7 @@ static void R_MarkPlanes(void) for (i = 0; i < numffloors; i++) { ds_p->ffloorplanes[i] = ffloor[i].plane = - R_CheckPlane(ffloor[i].plane, rw_x, rw_stopx - 1); + R_CheckPlane(ffloor[i].plane, rw.x, rw.stopx - 1); } firstseg = ds_p; @@ -1893,7 +1881,7 @@ static void R_MarkPlanes(void) else { for (i = 0; i < numffloors; i++) - R_ExpandPlane(ffloor[i].plane, rw_x, rw_stopx - 1); + R_ExpandPlane(ffloor[i].plane, rw.x, rw.stopx - 1); } #ifdef POLYOBJECTS_PLANES // FIXME hack to fix planes disappearing when a seg goes behind the camera. This NEEDS to be changed to be done properly. -Red @@ -1903,11 +1891,11 @@ static void R_MarkPlanes(void) { if (!ffloor[i].polyobj || ffloor[i].polyobj != curline->polyseg) continue; - if (ffloor[i].plane->minx > rw_x) - ffloor[i].plane->minx = rw_x; + if (ffloor[i].plane->minx > rw.x) + ffloor[i].plane->minx = rw.x; - if (ffloor[i].plane->maxx < rw_stopx - 1) - ffloor[i].plane->maxx = rw_stopx - 1; + if (ffloor[i].plane->maxx < rw.stopx - 1) + ffloor[i].plane->maxx = rw.stopx - 1; } } #endif @@ -1921,7 +1909,7 @@ static void R_MarkPlanes(void) static void R_RemoveOpeningLimits(INT32 start) { size_t pos = lastopening - openings; - size_t need = (rw_stopx - start)*4 + pos; + size_t need = (rw.stopx - start)*4 + pos; if (need > maxopenings) { drawseg_t *ds; //needed for fix from *cough* zdoom *cough* @@ -1994,9 +1982,9 @@ void R_StoreWallRange(INT32 start, INT32 stop) sidedef = curline->sidedef; linedef = curline->linedef; - // calculate rw_distance for scale calculation - rw_normalangle = curline->angle + ANGLE_90; - offsetangle = abs((INT32)(rw_normalangle-rw_angle1)); + // calculate rw.distance for scale calculation + rw.normalangle = curline->angle + ANGLE_90; + offsetangle = abs((INT32)(rw.normalangle-rw.angle1)); if (offsetangle > ANGLE_90) offsetangle = ANGLE_90; @@ -2009,10 +1997,10 @@ void R_StoreWallRange(INT32 start, INT32 stop) // The seg is vertical. if (curline->v1->y == curline->v2->y) - rw_distance = (fixed_t)(llabs(viewy - curline->v1->y)); + rw.distance = (fixed_t)(llabs(viewy - curline->v1->y)); // The seg is horizontal. else if (curline->v1->x == curline->v2->x) - rw_distance = (fixed_t)(llabs(viewx - curline->v1->x)); + rw.distance = (fixed_t)(llabs(viewx - curline->v1->x)); // big room fix #ifdef SOFTWARE_USE_FLOATS else if ((curline->length >= 1024<x1 = rw_x = start; + ds_p->x1 = rw.x = start; ds_p->x2 = stop; ds_p->curline = curline; - rw_stopx = stop+1; + rw.stopx = stop+1; //SoM: Code to remove limits on openings. R_RemoveOpeningLimits(start); @@ -2071,7 +2059,7 @@ void R_StoreWallRange(INT32 start, INT32 stop) #ifdef ESLOPE // Set up texture Y offset slides for sloped walls - rw_toptextureslide = rw_midtextureslide = rw_bottomtextureslide = 0; + rw.toptextureslide = rw.midtextureslide = rw.bottomtextureslide = 0; ceilingfrontslide = floorfrontslide = ceilingbackslide = floorbackslide = 0; { @@ -2099,7 +2087,7 @@ void R_StoreWallRange(INT32 start, INT32 stop) #undef SLOPEPARAMS - // 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) R_WorldSegTextured(hyp, longboi); @@ -2173,16 +2161,16 @@ void R_StoreWallRange(INT32 start, INT32 stop) // save sprite clipping info if (((ds_p->silhouette & SIL_TOP) || maskedtexture) && !ds_p->sprtopclip) { - M_Memcpy(lastopening, ceilingclip+start, 2*(rw_stopx - start)); + M_Memcpy(lastopening, ceilingclip+start, 2*(rw.stopx - start)); ds_p->sprtopclip = lastopening - start; - lastopening += rw_stopx - start; + lastopening += rw.stopx - start; } if (((ds_p->silhouette & SIL_BOTTOM) || maskedtexture) && !ds_p->sprbottomclip) { - M_Memcpy(lastopening, floorclip + start, 2*(rw_stopx-start)); + M_Memcpy(lastopening, floorclip + start, 2*(rw.stopx-start)); ds_p->sprbottomclip = lastopening - start; - lastopening += rw_stopx - start; + lastopening += rw.stopx - start; } if (maskedtexture && !(ds_p->silhouette & SIL_TOP)) @@ -2292,8 +2280,8 @@ static void R_DrawWallSplats(void) continue; // calculate incremental stepping values for texture edges - rw_scalestep = ds_p->scalestep; - spryscale = ds_p->scale1 + (x1 - ds_p->x1)*rw_scalestep; + rw.scalestep = ds_p->scalestep; + spryscale = ds_p->scale1 + (x1 - ds_p->x1)*rw.scalestep; mfloorclip = floorclip; mceilingclip = ceilingclip; @@ -2329,7 +2317,7 @@ static void R_DrawWallSplats(void) dc_texheight = 0; // draw the columns - for (dc_x = x1; dc_x <= x2; dc_x++, spryscale += rw_scalestep) + for (dc_x = x1; dc_x <= x2; dc_x++, spryscale += rw.scalestep) { pindex = FixedMul(spryscale, FixedDiv(640, vid.width))>>LIGHTSCALESHIFT; if (pindex >= MAXLIGHTSCALE) @@ -2343,9 +2331,9 @@ static void R_DrawWallSplats(void) dc_iscale = 0xffffffffu / (unsigned)spryscale; // find column of patch, from perspective - angle = (rw_centerangle + xtoviewangle[dc_x])>>ANGLETOFINESHIFT; - texturecolumn = rw_offset2 - splat->offset - - FixedMul(FINETANGENT(angle), rw_distance); + angle = (rw.centerangle + xtoviewangle[dc_x])>>ANGLETOFINESHIFT; + texturecolumn = rw.offset2 - splat->offset + - FixedMul(FINETANGENT(angle), rw.distance); // FIXME! texturecolumn >>= FRACBITS; @@ -2483,8 +2471,8 @@ void R_RenderMaskedSegRange(drawseg_t *ds, INT32 x1, INT32 x2) #ifdef ESLOPE range = max(ds->x2-ds->x1, 1); #endif - rw_scalestep = ds->scalestep; - spryscale = ds->scale1 + (x1 - ds->x1)*rw_scalestep; + rw.scalestep = ds->scalestep; + spryscale = ds->scale1 + (x1 - ds->x1)*rw.scalestep; // Texture must be cached before setting colfunc_2s, // otherwise texture[texnum]->holes may be false when it shouldn't be @@ -2542,7 +2530,7 @@ void R_RenderMaskedSegRange(drawseg_t *ds, INT32 x1, INT32 x2) //rlight->height -= (x1 - ds->x1)*rlight->heightstep; #else rlight->height = (centeryfrac) - FixedMul((light->height - viewz), spryscale); - rlight->heightstep = -FixedMul(rw_scalestep, (light->height - viewz)); + rlight->heightstep = -FixedMul(rw.scalestep, (light->height - viewz)); #endif rlight->startheight = rlight->height; // keep starting value here to reset for each repeat rlight->lightlevel = *light->lightlevel; @@ -2636,8 +2624,8 @@ void R_RenderMaskedSegRange(drawseg_t *ds, INT32 x1, INT32 x2) { if (times > 0) { - rw_scalestep = ds->scalestep; - spryscale = ds->scale1 + (x1 - ds->x1)*rw_scalestep; + rw.scalestep = ds->scalestep; + spryscale = ds->scale1 + (x1 - ds->x1)*rw.scalestep; if (dc_numlights) { // reset all lights to their starting heights for (i = 0; i < dc_numlights; i++) @@ -2699,7 +2687,7 @@ void R_RenderMaskedSegRange(drawseg_t *ds, INT32 x1, INT32 x2) rlight->height += rlight->heightstep; } } - spryscale += rw_scalestep; + spryscale += rw.scalestep; continue; } @@ -2770,7 +2758,7 @@ void R_RenderMaskedSegRange(drawseg_t *ds, INT32 x1, INT32 x2) if (windowtop < windowbottom) colfunc_2s(col); - spryscale += rw_scalestep; + spryscale += rw.scalestep; continue; } @@ -2847,7 +2835,7 @@ void R_RenderMaskedSegRange(drawseg_t *ds, INT32 x1, INT32 x2) #endif colfunc_2s(col); } - spryscale += rw_scalestep; + spryscale += rw.scalestep; } } colfunc = colfuncs[BASEDRAWFUNC]; @@ -2968,8 +2956,8 @@ void R_RenderThickSideRange(drawseg_t *ds, INT32 x1, INT32 x2, ffloor_t *pfloor) range = max(ds->x2-ds->x1, 1); #endif //SoM: Moved these up here so they are available for my lightlist calculations - rw_scalestep = ds->scalestep; - spryscale = ds->scale1 + (x1 - ds->x1)*rw_scalestep; + rw.scalestep = ds->scalestep; + spryscale = ds->scale1 + (x1 - ds->x1)*rw.scalestep; dc_numlights = 0; if (frontsector->numlights) @@ -3039,7 +3027,7 @@ void R_RenderThickSideRange(drawseg_t *ds, INT32 x1, INT32 x2, ffloor_t *pfloor) continue; lheight = light->height;// > *pfloor->topheight ? *pfloor->topheight + FRACUNIT : light->height; - rlight->heightstep = -FixedMul (rw_scalestep, (lheight - viewz)); + rlight->heightstep = -FixedMul (rw.scalestep, (lheight - viewz)); rlight->height = (centeryfrac) - FixedMul((lheight - viewz), spryscale); #endif rlight->flags = light->flags; @@ -3064,7 +3052,7 @@ void R_RenderThickSideRange(drawseg_t *ds, INT32 x1, INT32 x2, ffloor_t *pfloor) rlight->botheightstep = (rlight->botheightstep-rlight->botheight)/(range); #else lheight = *light->caster->bottomheight;// > *pfloor->topheight ? *pfloor->topheight + FRACUNIT : *light->caster->bottomheight; - rlight->botheightstep = -FixedMul (rw_scalestep, (lheight - viewz)); + rlight->botheightstep = -FixedMul (rw.scalestep, (lheight - viewz)); rlight->botheight = (centeryfrac) - FixedMul((lheight - viewz), spryscale); #endif } @@ -3284,7 +3272,7 @@ void R_RenderThickSideRange(drawseg_t *ds, INT32 x1, INT32 x2, ffloor_t *pfloor) rlight->botheight += rlight->botheightstep; } } - spryscale += rw_scalestep; + spryscale += rw.scalestep; continue; } @@ -3407,7 +3395,7 @@ void R_RenderThickSideRange(drawseg_t *ds, INT32 x1, INT32 x2, ffloor_t *pfloor) if (windowtop < windowbottom) colfunc_2s (col); - spryscale += rw_scalestep; + spryscale += rw.scalestep; continue; } @@ -3426,7 +3414,7 @@ void R_RenderThickSideRange(drawseg_t *ds, INT32 x1, INT32 x2, ffloor_t *pfloor) // draw the texture colfunc_2s (col); - spryscale += rw_scalestep; + spryscale += rw.scalestep; } } colfunc = colfuncs[BASEDRAWFUNC]; diff --git a/src/r_state.h b/src/r_state.h index 75566923b..8211ac75a 100644 --- a/src/r_state.h +++ b/src/r_state.h @@ -93,10 +93,23 @@ extern angle_t doubleclipangle; extern INT32 viewangletox[FINEANGLES/2]; extern angle_t xtoviewangle[MAXVIDWIDTH+1]; -extern fixed_t rw_distance; -extern angle_t rw_normalangle; - -// angle to line origin -extern angle_t rw_angle1; +// Wall rendering +typedef struct +{ + INT32 x, stopx; + angle_t centerangle; + fixed_t offset; + fixed_t offset2; // for splats + fixed_t scale, scalestep; + fixed_t midtexturemid, toptexturemid, bottomtexturemid; +#ifdef ESLOPE + fixed_t toptextureslide, midtextureslide, bottomtextureslide; // Defines how to adjust Y offsets along the wall for slopes + fixed_t midtextureback, midtexturebackslide; // Values for masked midtexture height calculation +#endif + fixed_t distance; + angle_t normalangle; + angle_t angle1; // angle to line origin +} renderwall_t; +extern renderwall_t rw; #endif From 919864d0f39688616d25cc3636d1ab48ae8334b3 Mon Sep 17 00:00:00 2001 From: Jaime Passos Date: Thu, 26 Dec 2019 17:15:30 -0300 Subject: [PATCH 33/79] Thick stuff. Hoping I didn't break anything. --- src/r_segs.c | 702 ++++++++++++++++++++++++++------------------------ src/r_state.h | 15 ++ 2 files changed, 386 insertions(+), 331 deletions(-) diff --git a/src/r_segs.c b/src/r_segs.c index 63c9799e0..1b78a22dd 100644 --- a/src/r_segs.c +++ b/src/r_segs.c @@ -2360,14 +2360,13 @@ static void R_DrawWallSplats(void) // way we don't have to store extra post_t info with each column for // multi-patch textures. They are not normally needed as multi-patch // textures don't have holes in it. At least not for now. -static INT32 column2s_length; // column->length : for multi-patch on 2sided wall = texture->height static void R_Render2sidedMultiPatchColumn(column_t *column) { INT32 topscreen, bottomscreen; topscreen = sprtopscreen; // + spryscale*column->topdelta; topdelta is 0 for the wall - bottomscreen = topscreen + spryscale * column2s_length; + bottomscreen = topscreen + spryscale * rw.column2s_length; dc_yl = (sprtopscreen+FRACUNIT-1)>>FRACBITS; dc_yh = (bottomscreen-1)>>FRACBITS; @@ -2403,7 +2402,7 @@ static void R_Render2sidedMultiPatchColumn(column_t *column) // uses column2s_length for texture->height as above static void R_DrawFlippedMaskedSegColumn(column_t *column) { - R_DrawFlippedMaskedColumn(column, column2s_length); + R_DrawFlippedMaskedColumn(column, rw.column2s_length); } void R_RenderMaskedSegRange(drawseg_t *ds, INT32 x1, INT32 x2) @@ -2414,7 +2413,6 @@ void R_RenderMaskedSegRange(drawseg_t *ds, INT32 x1, INT32 x2) fixed_t height, realbot; lightlist_t *light; r_lightlist_t *rlight; - void (*colfunc_2s)(column_t *); line_t *ldef; sector_t *front, *back; INT32 times, repeats; @@ -2483,16 +2481,16 @@ void R_RenderMaskedSegRange(drawseg_t *ds, INT32 x1, INT32 x2) { if (textures[texnum]->flip & 2) // vertically flipped? { - colfunc_2s = R_DrawFlippedMaskedSegColumn; - column2s_length = textures[texnum]->height; + rw.colfunc_2s = R_DrawFlippedMaskedSegColumn; + rw.column2s_length = textures[texnum]->height; } else - colfunc_2s = R_DrawMaskedColumn; // render the usual 2sided single-patch packed texture + rw.colfunc_2s = R_DrawMaskedColumn; // render the usual 2sided single-patch packed texture } else { - colfunc_2s = R_Render2sidedMultiPatchColumn; // render multipatch with no holes (no post_t info) - column2s_length = textures[texnum]->height; + rw.colfunc_2s = R_Render2sidedMultiPatchColumn; // render multipatch with no holes (no post_t info) + rw.column2s_length = textures[texnum]->height; } // Setup lighting based on the presence/lack-of 3D floors. @@ -2741,7 +2739,7 @@ void R_RenderMaskedSegRange(drawseg_t *ds, INT32 x1, INT32 x2) if (windowbottom >= realbot) { windowbottom = realbot; - colfunc_2s(col); + rw.colfunc_2s(col); for (i++; i < dc_numlights; i++) { rlight = &dc_lightlist[i]; @@ -2750,13 +2748,13 @@ void R_RenderMaskedSegRange(drawseg_t *ds, INT32 x1, INT32 x2) continue; } - colfunc_2s(col); + rw.colfunc_2s(col); windowtop = windowbottom + 1; dc_colormap = rlight->rcolormap; } windowbottom = realbot; if (windowtop < windowbottom) - colfunc_2s(col); + rw.colfunc_2s(col); spryscale += rw.scalestep; continue; @@ -2833,7 +2831,7 @@ void R_RenderMaskedSegRange(drawseg_t *ds, INT32 x1, INT32 x2) } else #endif - colfunc_2s(col); + rw.colfunc_2s(col); } spryscale += rw.scalestep; } @@ -2856,110 +2854,238 @@ static void R_DrawRepeatMaskedColumn(column_t *col) static void R_DrawRepeatFlippedMaskedColumn(column_t *col) { do { - R_DrawFlippedMaskedColumn(col, column2s_length); + R_DrawFlippedMaskedColumn(col, rw.column2s_length); sprtopscreen += dc_texheight*spryscale; } while (sprtopscreen < sprbotscreen); } // -// R_RenderThickSideRange -// Renders all the thick sides in the given range. -void R_RenderThickSideRange(drawseg_t *ds, INT32 x1, INT32 x2, ffloor_t *pfloor) +// R_RenderThickSegLoop +// Like R_RenderSegLoop, but for thick sides. +// +void R_RenderThickSegLoop(void) { - size_t pindex; - column_t * col; - INT32 lightnum; - INT32 texnum; - sector_t tempsec; - INT32 templight; - INT32 i, p; - fixed_t bottombounds = viewheight << FRACBITS; - fixed_t topbounds = (con_clipviewtop - 1) << FRACBITS; - fixed_t offsetvalue = 0; - lightlist_t *light; - r_lightlist_t *rlight; + column_t *col; + size_t pindex; + INT32 i; + INT32 lightnum; + r_lightlist_t *rlight; + + ffloor_t *pfloor = rw.pfloor; + fixed_t bottombounds = viewheight << FRACBITS; + fixed_t topbounds = (con_clipviewtop - 1) << FRACBITS; + #ifdef ESLOPE - INT32 range; -#endif -#ifndef ESLOPE - fixed_t lheight; -#endif - line_t *newline = NULL; -#ifdef ESLOPE - // Render FOF sides kinda like normal sides, with the frac and step and everything - // NOTE: INT64 instead of fixed_t because overflow concerns - INT64 top_frac, top_step, bottom_frac, bottom_step; - // skew FOF walls with slopes? - boolean slopeskew = false; - fixed_t ffloortextureslide = 0; - INT32 oldx = -1; - fixed_t left_top, left_bottom; // needed here for slope skewing - pslope_t *skewslope = NULL; + INT32 oldx = -1; #endif - void (*colfunc_2s) (column_t *); - - // Calculate light table. - // Use different light tables - // for horizontal / vertical / diagonal. Diagonal? - // OPTIMIZE: get rid of LIGHTSEGSHIFT globally - - curline = ds->curline; - backsector = pfloor->target; - frontsector = curline->frontsector == pfloor->target ? curline->backsector : curline->frontsector; - texnum = R_GetTextureNum(sides[pfloor->master->sidenum[0]].midtexture); - - colfunc = colfuncs[BASEDRAWFUNC]; - - if (pfloor->master->flags & ML_TFERLINE) + for (dc_x = rw.x; dc_x <= rw.stopx; dc_x++) { - size_t linenum = curline->linedef-backsector->lines[0]; - newline = pfloor->master->frontsector->lines[0] + linenum; - texnum = R_GetTextureNum(sides[newline->sidenum[0]].midtexture); - } - - if (pfloor->flags & FF_TRANSLUCENT) - { - boolean fuzzy = true; - - // Hacked up support for alpha value in software mode Tails 09-24-2002 - if (pfloor->alpha < 12) - return; // Don't even draw it - else if (pfloor->alpha < 38) - dc_transmap = transtables + ((tr_trans90-1)<alpha < 64) - dc_transmap = transtables + ((tr_trans80-1)<alpha < 89) - dc_transmap = transtables + ((tr_trans70-1)<alpha < 115) - dc_transmap = transtables + ((tr_trans60-1)<alpha < 140) - dc_transmap = transtables + ((tr_trans50-1)<alpha < 166) - dc_transmap = transtables + ((tr_trans40-1)<alpha < 192) - dc_transmap = transtables + ((tr_trans30-1)<alpha < 217) - dc_transmap = transtables + ((tr_trans20-1)<alpha < 243) - dc_transmap = transtables + ((tr_trans10-1)<flags & FF_FOG) - colfunc = colfuncs[COLDRAWFUNC_FOG]; - + if (maskedtexturecol[dc_x] != INT16_MAX) + { #ifdef ESLOPE - range = max(ds->x2-ds->x1, 1); + if (rw.ffloortextureslide) { // skew FOF walls + if (oldx != -1) + dc_texturemid += FixedMul(rw.ffloortextureslide, (maskedtexturecol[oldx]-maskedtexturecol[dc_x])<scalestep; - spryscale = ds->scale1 + (x1 - ds->x1)*rw.scalestep; + // Calculate bounds + // clamp the values if necessary to avoid overflows and rendering glitches caused by them +#ifdef ESLOPE + #define CLAMPMAX INT32_MAX + #define CLAMPMIN (-INT32_MAX) // This is not INT32_MIN on purpose! INT32_MIN makes the drawers freak out. + if (rw.top_frac > (INT64)CLAMPMAX) sprtopscreen = windowtop = CLAMPMAX; + else if (rw.top_frac > (INT64)CLAMPMIN) sprtopscreen = windowtop = (fixed_t)rw.top_frac; + else sprtopscreen = windowtop = CLAMPMIN; + if (rw.bottom_frac > (INT64)CLAMPMAX) sprbotscreen = windowbottom = CLAMPMAX; + else if (rw.bottom_frac > (INT64)CLAMPMIN) sprbotscreen = windowbottom = (fixed_t)rw.bottom_frac; + else sprbotscreen = windowbottom = CLAMPMIN; + + rw.top_frac += rw.top_step; + rw.bottom_frac += rw.bottom_step; +#else + sprtopscreen = windowtop = (centeryfrac - FixedMul((dc_texturemid - offsetvalue), spryscale)); + sprbotscreen = windowbottom = FixedMul(*pfloor->topheight - *pfloor->bottomheight, spryscale) + sprtopscreen; +#endif + + // SoM: If column is out of range, why bother with it?? + if (windowbottom < topbounds || windowtop > bottombounds) + { + if (dc_numlights) + { + for (i = 0; i < dc_numlights; i++) + { + rlight = &dc_lightlist[i]; + rlight->height += rlight->heightstep; + if (rlight->flags & FF_CUTLEVEL) + rlight->botheight += rlight->botheightstep; + } + } + spryscale += rw.scalestep; + continue; + } + + dc_iscale = 0xffffffffu / (unsigned)spryscale; + + // Get data for the column + col = (column_t *)((UINT8 *)R_GetColumn(rw.texnum,maskedtexturecol[dc_x]) - 3); + + // SoM: New code does not rely on R_DrawColumnShadowed_8 which + // will (hopefully) put less strain on the stack. + if (dc_numlights) + { + lighttable_t **xwalllights; + fixed_t height; + fixed_t bheight = 0; + INT32 solid = 0; + INT32 lighteffect = 0; + + for (i = 0; i < dc_numlights; i++) + { + // Check if the current light effects the colormap/lightlevel + rlight = &dc_lightlist[i]; + lighteffect = !(dc_lightlist[i].flags & FF_NOSHADE); + if (lighteffect) + { + lightnum = rlight->lightnum; + + if (lightnum < 0) + xwalllights = scalelight[0]; + else if (lightnum >= LIGHTLEVELS) + xwalllights = scalelight[LIGHTLEVELS-1]; + else + xwalllights = scalelight[lightnum]; + + pindex = FixedMul(spryscale, FixedDiv(640, vid.width))>>LIGHTSCALESHIFT; + + if (pindex >= MAXLIGHTSCALE) + pindex = MAXLIGHTSCALE-1; + + if (pfloor->flags & FF_FOG) + { + if (pfloor->master->frontsector->extra_colormap) + rlight->rcolormap = pfloor->master->frontsector->extra_colormap->colormap + (xwalllights[pindex] - colormaps); + else + rlight->rcolormap = xwalllights[pindex]; + } + else + { + if (rlight->extra_colormap) + rlight->rcolormap = rlight->extra_colormap->colormap + (xwalllights[pindex] - colormaps); + else + rlight->rcolormap = xwalllights[pindex]; + } + } + + solid = 0; // don't carry over solid-cutting flag from the previous light + + // Check if the current light can cut the current 3D floor. + if (rlight->flags & FF_CUTSOLIDS && !(pfloor->flags & FF_EXTRA)) + solid = 1; + else if (rlight->flags & FF_CUTEXTRA && pfloor->flags & FF_EXTRA) + { + if (rlight->flags & FF_EXTRA) + { + // The light is from an extra 3D floor... Check the flags so + // there are no undesired cuts. + if ((rlight->flags & (FF_FOG|FF_SWIMMABLE)) == (pfloor->flags & (FF_FOG|FF_SWIMMABLE))) + solid = 1; + } + else + solid = 1; + } + else + solid = 0; + + height = rlight->height; + rlight->height += rlight->heightstep; + + if (solid) + { + bheight = rlight->botheight - (FRACUNIT >> 1); + rlight->botheight += rlight->botheightstep; + } + + if (height <= windowtop) + { + if (lighteffect) + dc_colormap = rlight->rcolormap; + if (solid && windowtop < bheight) + windowtop = bheight; + continue; + } + + windowbottom = height; + if (windowbottom >= sprbotscreen) + { + windowbottom = sprbotscreen; + // draw the texture + rw.colfunc_2s (col); + for (i++; i < dc_numlights; i++) + { + rlight = &dc_lightlist[i]; + rlight->height += rlight->heightstep; + if (rlight->flags & FF_CUTLEVEL) + rlight->botheight += rlight->botheightstep; + } + continue; + } + // draw the texture + rw.colfunc_2s (col); + if (solid) + windowtop = bheight; + else + windowtop = windowbottom + 1; + if (lighteffect) + dc_colormap = rlight->rcolormap; + } + windowbottom = sprbotscreen; + // draw the texture, if there is any space left + if (windowtop < windowbottom) + rw.colfunc_2s (col); + + spryscale += rw.scalestep; + continue; + } + + // calculate lighting + pindex = FixedMul(spryscale, FixedDiv(640, vid.width))>>LIGHTSCALESHIFT; + + if (pindex >= MAXLIGHTSCALE) + pindex = MAXLIGHTSCALE - 1; + + dc_colormap = walllights[pindex]; + + if (pfloor->flags & FF_FOG && pfloor->master->frontsector->extra_colormap) + dc_colormap = pfloor->master->frontsector->extra_colormap->colormap + (dc_colormap - colormaps); + else if (frontsector->extra_colormap) + dc_colormap = frontsector->extra_colormap->colormap + (dc_colormap - colormaps); + + // draw the texture + rw.colfunc_2s (col); + spryscale += rw.scalestep; + } + } +} + +// +// R_ThickLightLists +// Creates light lists, but for thick sides. +// +static void R_ThickLightLists(drawseg_t *ds, INT32 range) +{ + INT32 lightnum; + sector_t tempsec; + INT32 templight; + INT32 i, p; + + lightlist_t *light; + r_lightlist_t *rlight; + ffloor_t *pfloor = rw.pfloor; dc_numlights = 0; + if (frontsector->numlights) { dc_numlights = frontsector->numlights; @@ -2975,6 +3101,8 @@ void R_RenderThickSideRange(drawseg_t *ds, INT32 x1, INT32 x2, ffloor_t *pfloor) fixed_t leftheight, rightheight; fixed_t pfloorleft, pfloorright; INT64 overflow_test; +#else + (void)range; #endif light = &frontsector->lightlist[i]; rlight = &dc_lightlist[p]; @@ -3006,8 +3134,6 @@ void R_RenderThickSideRange(drawseg_t *ds, INT32 x1, INT32 x2, ffloor_t *pfloor) leftheight -= viewz; rightheight -= viewz; -#define CLAMPMAX INT32_MAX -#define CLAMPMIN (-INT32_MAX) // This is not INT32_MIN on purpose! INT32_MIN makes the drawers freak out. // Monster Iestyn (25/03/18): do not skip these lights if they fail overflow test, just clamp them instead so they behave. overflow_test = (INT64)centeryfrac - (((INT64)leftheight*ds->scale1)>>FRACBITS); if (overflow_test > (INT64)CLAMPMAX) rlight->height = CLAMPMAX; @@ -3104,6 +3230,130 @@ void R_RenderThickSideRange(drawseg_t *ds, INT32 x1, INT32 x2, ffloor_t *pfloor) else walllights = scalelight[lightnum]; } +} + +// +// R_ThickStepping +// Set stepping values for thick sides. +// +#ifdef ESLOPE +static void R_ThickStepping(drawseg_t *ds, INT32 range) +{ + fixed_t right_top, right_bottom; + ffloor_t *pfloor = rw.pfloor; + + // calculate right ends now + if (*pfloor->t_slope) + right_top = P_GetZAt(*pfloor->t_slope, ds->rightpos.x, ds->rightpos.y) - viewz; + else + right_top = *pfloor->topheight - viewz; + + if (*pfloor->b_slope) + right_bottom = P_GetZAt(*pfloor->b_slope, ds->rightpos.x, ds->rightpos.y) - viewz; + else + right_bottom = *pfloor->bottomheight - viewz; + + // using INT64 to avoid 32bit overflow + rw.top_frac = (INT64)centeryfrac - (((INT64)rw.left_top * ds->scale1) >> FRACBITS); + rw.bottom_frac = (INT64)centeryfrac - (((INT64)rw.left_bottom * ds->scale1) >> FRACBITS); + rw.top_step = (INT64)centeryfrac - (((INT64)right_top * ds->scale2) >> FRACBITS); + rw.bottom_step = (INT64)centeryfrac - (((INT64)right_bottom * ds->scale2) >> FRACBITS); + + rw.top_step = (rw.top_step-rw.top_frac)/(range); + rw.bottom_step = (rw.bottom_step-rw.bottom_frac)/(range); + + rw.top_frac += rw.top_step * (rw.x - ds->x1); + rw.bottom_frac += rw.bottom_step * (rw.x - ds->x1); +} +#endif + +// +// R_RenderThickSideRange +// Renders all the thick sides in the given range. +// +void R_RenderThickSideRange(drawseg_t *ds, INT32 x1, INT32 x2, ffloor_t *pfloor) +{ + INT32 texnum; + + fixed_t offsetvalue = 0; +#ifdef ESLOPE + INT32 range; +#endif +#ifndef ESLOPE + fixed_t lheight; +#endif + line_t *newline = NULL; +#ifdef ESLOPE + // skew FOF walls with slopes? + boolean slopeskew = false; + pslope_t *skewslope = NULL; +#endif + + rw.x = x1; + rw.stopx = x2; + rw.pfloor = pfloor; + + // Calculate light table. + // Use different light tables + // for horizontal / vertical / diagonal. Diagonal? + // OPTIMIZE: get rid of LIGHTSEGSHIFT globally + + curline = ds->curline; + backsector = pfloor->target; + frontsector = curline->frontsector == pfloor->target ? curline->backsector : curline->frontsector; + texnum = R_GetTextureNum(sides[pfloor->master->sidenum[0]].midtexture); + + colfunc = colfuncs[BASEDRAWFUNC]; + + if (pfloor->master->flags & ML_TFERLINE) + { + size_t linenum = curline->linedef-backsector->lines[0]; + newline = pfloor->master->frontsector->lines[0] + linenum; + texnum = R_GetTextureNum(sides[newline->sidenum[0]].midtexture); + } + + if (pfloor->flags & FF_TRANSLUCENT) + { + boolean fuzzy = true; + + // Hacked up support for alpha value in software mode Tails 09-24-2002 + if (pfloor->alpha < 12) + return; // Don't even draw it + else if (pfloor->alpha < 38) + dc_transmap = transtables + ((tr_trans90-1)<alpha < 64) + dc_transmap = transtables + ((tr_trans80-1)<alpha < 89) + dc_transmap = transtables + ((tr_trans70-1)<alpha < 115) + dc_transmap = transtables + ((tr_trans60-1)<alpha < 140) + dc_transmap = transtables + ((tr_trans50-1)<alpha < 166) + dc_transmap = transtables + ((tr_trans40-1)<alpha < 192) + dc_transmap = transtables + ((tr_trans30-1)<alpha < 217) + dc_transmap = transtables + ((tr_trans20-1)<alpha < 243) + dc_transmap = transtables + ((tr_trans10-1)<flags & FF_FOG) + colfunc = colfuncs[COLDRAWFUNC_FOG]; + +#ifdef ESLOPE + range = max(ds->x2-ds->x1, 1); +#endif + //SoM: Moved these up here so they are available for my lightlist calculations + rw.scalestep = ds->scalestep; + spryscale = ds->scale1 + (x1 - ds->x1)*rw.scalestep; + + R_ThickLightLists(ds, range); maskedtexturecol = ds->thicksidecol; @@ -3114,14 +3364,14 @@ void R_RenderThickSideRange(drawseg_t *ds, INT32 x1, INT32 x2, ffloor_t *pfloor) #ifdef ESLOPE // calculate both left ends if (*pfloor->t_slope) - left_top = P_GetZAt(*pfloor->t_slope, ds->leftpos.x, ds->leftpos.y) - viewz; + rw.left_top = P_GetZAt(*pfloor->t_slope, ds->leftpos.x, ds->leftpos.y) - viewz; else - left_top = *pfloor->topheight - viewz; + rw.left_top = *pfloor->topheight - viewz; if (*pfloor->b_slope) - left_bottom = P_GetZAt(*pfloor->b_slope, ds->leftpos.x, ds->leftpos.y) - viewz; + rw.left_bottom = P_GetZAt(*pfloor->b_slope, ds->leftpos.x, ds->leftpos.y) - viewz; else - left_bottom = *pfloor->bottomheight - viewz; + rw.left_bottom = *pfloor->bottomheight - viewz; skewslope = *pfloor->t_slope; // skew using top slope by default if (newline) { @@ -3132,7 +3382,7 @@ void R_RenderThickSideRange(drawseg_t *ds, INT32 x1, INT32 x2, ffloor_t *pfloor) slopeskew = true; if (slopeskew) - dc_texturemid = left_top; + dc_texturemid = rw.left_top; else #endif dc_texturemid = *pfloor->topheight - viewz; @@ -3145,7 +3395,7 @@ void R_RenderThickSideRange(drawseg_t *ds, INT32 x1, INT32 x2, ffloor_t *pfloor) #ifdef ESLOPE skewslope = *pfloor->b_slope; // skew using bottom slope if (slopeskew) - dc_texturemid = left_bottom; + dc_texturemid = rw.left_bottom; else #endif offsetvalue -= *pfloor->topheight - *pfloor->bottomheight; @@ -3159,7 +3409,7 @@ void R_RenderThickSideRange(drawseg_t *ds, INT32 x1, INT32 x2, ffloor_t *pfloor) #ifdef ESLOPE skewslope = *pfloor->b_slope; // skew using bottom slope if (slopeskew) - dc_texturemid = left_bottom; + dc_texturemid = rw.left_bottom; else #endif offsetvalue -= *pfloor->topheight - *pfloor->bottomheight; @@ -3172,7 +3422,7 @@ void R_RenderThickSideRange(drawseg_t *ds, INT32 x1, INT32 x2, ffloor_t *pfloor) angle_t lineangle = R_PointToAngle2(curline->v1->x, curline->v1->y, curline->v2->x, curline->v2->y); if (skewslope) - ffloortextureslide = FixedMul(skewslope->zdelta, FINECOSINE((lineangle-skewslope->xydirection)>>ANGLETOFINESHIFT)); + rw.ffloortextureslide = FixedMul(skewslope->zdelta, FINECOSINE((lineangle-skewslope->xydirection)>>ANGLETOFINESHIFT)); } #endif @@ -3187,236 +3437,26 @@ void R_RenderThickSideRange(drawseg_t *ds, INT32 x1, INT32 x2, ffloor_t *pfloor) { if (textures[texnum]->flip & 2) // vertically flipped? { - colfunc_2s = R_DrawRepeatFlippedMaskedColumn; - column2s_length = textures[texnum]->height; + rw.colfunc_2s = R_DrawRepeatFlippedMaskedColumn; + rw.column2s_length = textures[texnum]->height; } else - colfunc_2s = R_DrawRepeatMaskedColumn; // render the usual 2sided single-patch packed texture + rw.colfunc_2s = R_DrawRepeatMaskedColumn; // render the usual 2sided single-patch packed texture } else { - colfunc_2s = R_Render2sidedMultiPatchColumn; //render multipatch with no holes (no post_t info) - column2s_length = textures[texnum]->height; + rw.colfunc_2s = R_Render2sidedMultiPatchColumn; //render multipatch with no holes (no post_t info) + rw.column2s_length = textures[texnum]->height; } #ifdef ESLOPE // Set heights according to plane, or slope, whichever - { - fixed_t right_top, right_bottom; - - // calculate right ends now - if (*pfloor->t_slope) - right_top = P_GetZAt(*pfloor->t_slope, ds->rightpos.x, ds->rightpos.y) - viewz; - else - right_top = *pfloor->topheight - viewz; - - if (*pfloor->b_slope) - right_bottom = P_GetZAt(*pfloor->b_slope, ds->rightpos.x, ds->rightpos.y) - viewz; - else - right_bottom = *pfloor->bottomheight - viewz; - - // using INT64 to avoid 32bit overflow - top_frac = (INT64)centeryfrac - (((INT64)left_top * ds->scale1) >> FRACBITS); - bottom_frac = (INT64)centeryfrac - (((INT64)left_bottom * ds->scale1) >> FRACBITS); - top_step = (INT64)centeryfrac - (((INT64)right_top * ds->scale2) >> FRACBITS); - bottom_step = (INT64)centeryfrac - (((INT64)right_bottom * ds->scale2) >> FRACBITS); - - top_step = (top_step-top_frac)/(range); - bottom_step = (bottom_step-bottom_frac)/(range); - - top_frac += top_step * (x1 - ds->x1); - bottom_frac += bottom_step * (x1 - ds->x1); - } + R_ThickStepping(ds, range); #endif // draw the columns - for (dc_x = x1; dc_x <= x2; dc_x++) - { - if (maskedtexturecol[dc_x] != INT16_MAX) - { -#ifdef ESLOPE - if (ffloortextureslide) { // skew FOF walls - if (oldx != -1) - dc_texturemid += FixedMul(ffloortextureslide, (maskedtexturecol[oldx]-maskedtexturecol[dc_x])< (INT64)CLAMPMAX) sprtopscreen = windowtop = CLAMPMAX; - else if (top_frac > (INT64)CLAMPMIN) sprtopscreen = windowtop = (fixed_t)top_frac; - else sprtopscreen = windowtop = CLAMPMIN; - if (bottom_frac > (INT64)CLAMPMAX) sprbotscreen = windowbottom = CLAMPMAX; - else if (bottom_frac > (INT64)CLAMPMIN) sprbotscreen = windowbottom = (fixed_t)bottom_frac; - else sprbotscreen = windowbottom = CLAMPMIN; - - top_frac += top_step; - bottom_frac += bottom_step; -#else - sprtopscreen = windowtop = (centeryfrac - FixedMul((dc_texturemid - offsetvalue), spryscale)); - sprbotscreen = windowbottom = FixedMul(*pfloor->topheight - *pfloor->bottomheight, spryscale) + sprtopscreen; -#endif - - // SoM: If column is out of range, why bother with it?? - if (windowbottom < topbounds || windowtop > bottombounds) - { - if (dc_numlights) - { - for (i = 0; i < dc_numlights; i++) - { - rlight = &dc_lightlist[i]; - rlight->height += rlight->heightstep; - if (rlight->flags & FF_CUTLEVEL) - rlight->botheight += rlight->botheightstep; - } - } - spryscale += rw.scalestep; - continue; - } - - dc_iscale = 0xffffffffu / (unsigned)spryscale; - - // Get data for the column - col = (column_t *)((UINT8 *)R_GetColumn(texnum,maskedtexturecol[dc_x]) - 3); - - // SoM: New code does not rely on R_DrawColumnShadowed_8 which - // will (hopefully) put less strain on the stack. - if (dc_numlights) - { - lighttable_t **xwalllights; - fixed_t height; - fixed_t bheight = 0; - INT32 solid = 0; - INT32 lighteffect = 0; - - for (i = 0; i < dc_numlights; i++) - { - // Check if the current light effects the colormap/lightlevel - rlight = &dc_lightlist[i]; - lighteffect = !(dc_lightlist[i].flags & FF_NOSHADE); - if (lighteffect) - { - lightnum = rlight->lightnum; - - if (lightnum < 0) - xwalllights = scalelight[0]; - else if (lightnum >= LIGHTLEVELS) - xwalllights = scalelight[LIGHTLEVELS-1]; - else - xwalllights = scalelight[lightnum]; - - pindex = FixedMul(spryscale, FixedDiv(640, vid.width))>>LIGHTSCALESHIFT; - - if (pindex >= MAXLIGHTSCALE) - pindex = MAXLIGHTSCALE-1; - - if (pfloor->flags & FF_FOG) - { - if (pfloor->master->frontsector->extra_colormap) - rlight->rcolormap = pfloor->master->frontsector->extra_colormap->colormap + (xwalllights[pindex] - colormaps); - else - rlight->rcolormap = xwalllights[pindex]; - } - else - { - if (rlight->extra_colormap) - rlight->rcolormap = rlight->extra_colormap->colormap + (xwalllights[pindex] - colormaps); - else - rlight->rcolormap = xwalllights[pindex]; - } - } - - solid = 0; // don't carry over solid-cutting flag from the previous light - - // Check if the current light can cut the current 3D floor. - if (rlight->flags & FF_CUTSOLIDS && !(pfloor->flags & FF_EXTRA)) - solid = 1; - else if (rlight->flags & FF_CUTEXTRA && pfloor->flags & FF_EXTRA) - { - if (rlight->flags & FF_EXTRA) - { - // The light is from an extra 3D floor... Check the flags so - // there are no undesired cuts. - if ((rlight->flags & (FF_FOG|FF_SWIMMABLE)) == (pfloor->flags & (FF_FOG|FF_SWIMMABLE))) - solid = 1; - } - else - solid = 1; - } - else - solid = 0; - - height = rlight->height; - rlight->height += rlight->heightstep; - - if (solid) - { - bheight = rlight->botheight - (FRACUNIT >> 1); - rlight->botheight += rlight->botheightstep; - } - - if (height <= windowtop) - { - if (lighteffect) - dc_colormap = rlight->rcolormap; - if (solid && windowtop < bheight) - windowtop = bheight; - continue; - } - - windowbottom = height; - if (windowbottom >= sprbotscreen) - { - windowbottom = sprbotscreen; - // draw the texture - colfunc_2s (col); - for (i++; i < dc_numlights; i++) - { - rlight = &dc_lightlist[i]; - rlight->height += rlight->heightstep; - if (rlight->flags & FF_CUTLEVEL) - rlight->botheight += rlight->botheightstep; - } - continue; - } - // draw the texture - colfunc_2s (col); - if (solid) - windowtop = bheight; - else - windowtop = windowbottom + 1; - if (lighteffect) - dc_colormap = rlight->rcolormap; - } - windowbottom = sprbotscreen; - // draw the texture, if there is any space left - if (windowtop < windowbottom) - colfunc_2s (col); - - spryscale += rw.scalestep; - continue; - } - - // calculate lighting - pindex = FixedMul(spryscale, FixedDiv(640, vid.width))>>LIGHTSCALESHIFT; - - if (pindex >= MAXLIGHTSCALE) - pindex = MAXLIGHTSCALE - 1; - - dc_colormap = walllights[pindex]; - - if (pfloor->flags & FF_FOG && pfloor->master->frontsector->extra_colormap) - dc_colormap = pfloor->master->frontsector->extra_colormap->colormap + (dc_colormap - colormaps); - else if (frontsector->extra_colormap) - dc_colormap = frontsector->extra_colormap->colormap + (dc_colormap - colormaps); - - // draw the texture - colfunc_2s (col); - spryscale += rw.scalestep; - } - } + rw.texnum = texnum; + R_RenderThickSegLoop(); colfunc = colfuncs[BASEDRAWFUNC]; #undef CLAMPMAX diff --git a/src/r_state.h b/src/r_state.h index 8211ac75a..cecdb8f4d 100644 --- a/src/r_state.h +++ b/src/r_state.h @@ -109,6 +109,21 @@ typedef struct fixed_t distance; angle_t normalangle; angle_t angle1; // angle to line origin + + // for masked segs and thick sides + INT32 texnum; + void (*colfunc_2s) (column_t *); + INT32 column2s_length; // column->length : for multi-patch on 2sided wall = texture->height + + // thick sides + ffloor_t *pfloor; +#ifdef ESLOPE + // Render FOF sides kinda like normal sides, with the frac and step and everything + // NOTE: INT64 instead of fixed_t because overflow concerns + INT64 top_frac, top_step, bottom_frac, bottom_step; + fixed_t ffloortextureslide; + fixed_t left_top, left_bottom; // needed here for slope skewing +#endif } renderwall_t; extern renderwall_t rw; From 0ec800b266bc22c06874789c02a7084bd9ec9938 Mon Sep 17 00:00:00 2001 From: Jaime Passos Date: Thu, 26 Dec 2019 17:20:17 -0300 Subject: [PATCH 34/79] I forgot a ``static`` --- src/r_segs.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/r_segs.c b/src/r_segs.c index 1b78a22dd..1d44d9f84 100644 --- a/src/r_segs.c +++ b/src/r_segs.c @@ -2863,7 +2863,7 @@ static void R_DrawRepeatFlippedMaskedColumn(column_t *col) // R_RenderThickSegLoop // Like R_RenderSegLoop, but for thick sides. // -void R_RenderThickSegLoop(void) +static void R_RenderThickSegLoop(void) { column_t *col; size_t pindex; From ad6cda7c53ec01748754b8fd883003017cce448f Mon Sep 17 00:00:00 2001 From: Jaime Passos Date: Thu, 26 Dec 2019 17:39:18 -0300 Subject: [PATCH 35/79] Masked stuff --- src/r_segs.c | 554 ++++++++++++++++++++++++++------------------------ src/r_state.h | 3 + 2 files changed, 296 insertions(+), 261 deletions(-) diff --git a/src/r_segs.c b/src/r_segs.c index 1d44d9f84..fa26420a8 100644 --- a/src/r_segs.c +++ b/src/r_segs.c @@ -2405,96 +2405,210 @@ static void R_DrawFlippedMaskedSegColumn(column_t *column) R_DrawFlippedMaskedColumn(column, rw.column2s_length); } -void R_RenderMaskedSegRange(drawseg_t *ds, INT32 x1, INT32 x2) +// +// R_RenderMaskedSegLoop +// Like R_RenderSegLoop, but for masked segs. +// +static void R_RenderMaskedSegLoop(drawseg_t *ds) { size_t pindex; column_t *col; - INT32 lightnum, texnum, i; + INT32 i; fixed_t height, realbot; + r_lightlist_t *rlight; + INT64 overflow_test; + + for (dc_x = rw.x; dc_x <= rw.stopx; dc_x++) + { +#ifdef ESLOPE + dc_texturemid = ds->maskedtextureheight[dc_x]; + + if (!!(curline->linedef->flags & ML_DONTPEGBOTTOM) ^ !!(curline->linedef->flags & ML_EFFECT3)) + dc_texturemid += (textureheight[rw.texnum])*rw.maskedrepeat + textureheight[rw.texnum]; + else + dc_texturemid -= (textureheight[rw.texnum])*rw.maskedrepeat; +#endif + // calculate lighting + if (maskedtexturecol[dc_x] != INT16_MAX) + { + // Check for overflows first + overflow_test = (INT64)centeryfrac - (((INT64)dc_texturemid*spryscale)>>FRACBITS); + if (overflow_test < 0) overflow_test = -overflow_test; + if ((UINT64)overflow_test&0xFFFFFFFF80000000ULL) + { + // Eh, no, go away, don't waste our time + if (dc_numlights) + { + for (i = 0; i < dc_numlights; i++) + { + rlight = &dc_lightlist[i]; + rlight->height += rlight->heightstep; + } + } + spryscale += rw.scalestep; + continue; + } + + if (dc_numlights) + { + lighttable_t **xwalllights; + + sprbotscreen = INT32_MAX; + sprtopscreen = windowtop = (centeryfrac - FixedMul(dc_texturemid, spryscale)); + + realbot = windowbottom = FixedMul(textureheight[rw.texnum], spryscale) + sprtopscreen; + dc_iscale = 0xffffffffu / (unsigned)spryscale; + + // draw the texture + col = (column_t *)((UINT8 *)R_GetColumn(rw.texnum, maskedtexturecol[dc_x]) - 3); + + for (i = 0; i < dc_numlights; i++) + { + rlight = &dc_lightlist[i]; + + if ((rlight->flags & FF_NOSHADE)) + continue; + + if (rlight->lightnum < 0) + xwalllights = scalelight[0]; + else if (rlight->lightnum >= LIGHTLEVELS) + xwalllights = scalelight[LIGHTLEVELS-1]; + else + xwalllights = scalelight[rlight->lightnum]; + + pindex = FixedMul(spryscale, FixedDiv(640, vid.width))>>LIGHTSCALESHIFT; + + if (pindex >= MAXLIGHTSCALE) + pindex = MAXLIGHTSCALE - 1; + + if (rlight->extra_colormap) + rlight->rcolormap = rlight->extra_colormap->colormap + (xwalllights[pindex] - colormaps); + else + rlight->rcolormap = xwalllights[pindex]; + + height = rlight->height; + rlight->height += rlight->heightstep; + + if (height <= windowtop) + { + dc_colormap = rlight->rcolormap; + continue; + } + + windowbottom = height; + if (windowbottom >= realbot) + { + windowbottom = realbot; + rw.colfunc_2s(col); + for (i++; i < dc_numlights; i++) + { + rlight = &dc_lightlist[i]; + rlight->height += rlight->heightstep; + } + + continue; + } + rw.colfunc_2s(col); + windowtop = windowbottom + 1; + dc_colormap = rlight->rcolormap; + } + windowbottom = realbot; + if (windowtop < windowbottom) + rw.colfunc_2s(col); + + spryscale += rw.scalestep; + continue; + } + + // calculate lighting + pindex = FixedMul(spryscale, FixedDiv(640, vid.width))>>LIGHTSCALESHIFT; + + if (pindex >= MAXLIGHTSCALE) + pindex = MAXLIGHTSCALE - 1; + + dc_colormap = walllights[pindex]; + + if (frontsector->extra_colormap) + dc_colormap = frontsector->extra_colormap->colormap + (dc_colormap - colormaps); + + sprtopscreen = centeryfrac - FixedMul(dc_texturemid, spryscale); + dc_iscale = 0xffffffffu / (unsigned)spryscale; + + // draw the texture + col = (column_t *)((UINT8 *)R_GetColumn(rw.texnum, maskedtexturecol[dc_x]) - 3); + +//#ifdef POLYOBJECTS_PLANES +#if 0 // Disabling this allows inside edges to render below the planes, for until the clipping is fixed to work right when POs are near the camera. -Red + if (curline->dontrenderme && curline->polyseg && (curline->polyseg->flags & POF_RENDERPLANES)) + { + fixed_t my_topscreen; + fixed_t my_bottomscreen; + fixed_t my_yl, my_yh; + + my_topscreen = sprtopscreen + spryscale*col->topdelta; + my_bottomscreen = sprbotscreen == INT32_MAX ? my_topscreen + spryscale*col->length + : sprbotscreen + spryscale*col->length; + + my_yl = (my_topscreen+FRACUNIT-1)>>FRACBITS; + my_yh = (my_bottomscreen-1)>>FRACBITS; +// CONS_Debug(DBG_RENDER, "my_topscreen: %d\nmy_bottomscreen: %d\nmy_yl: %d\nmy_yh: %d\n", my_topscreen, my_bottomscreen, my_yl, my_yh); + + if (numffloors) + { + INT32 top = my_yl; + INT32 bottom = my_yh; + + for (i = 0; i < numffloors; i++) + { + if (!ffloor[i].polyobj || ffloor[i].polyobj != curline->polyseg) + continue; + + if (ffloor[i].height < viewz) + { + INT32 top_w = ffloor[i].plane->top[dc_x]; + +// CONS_Debug(DBG_RENDER, "Leveltime : %d\n", leveltime); +// CONS_Debug(DBG_RENDER, "Top is %d, top_w is %d\n", top, top_w); + if (top_w < top) + { + ffloor[i].plane->top[dc_x] = (INT16)top; + ffloor[i].plane->picnum = 0; + } +// CONS_Debug(DBG_RENDER, "top_w is now %d\n", ffloor[i].plane->top[dc_x]); + } + else if (ffloor[i].height > viewz) + { + INT32 bottom_w = ffloor[i].plane->bottom[dc_x]; + + if (bottom_w > bottom) + { + ffloor[i].plane->bottom[dc_x] = (INT16)bottom; + ffloor[i].plane->picnum = 0; + } + } + } + } + } + else +#endif + rw.colfunc_2s(col); + } + spryscale += rw.scalestep; + } +} + +// +// R_MaskedLightLists +// Creates light lists, but for masked segs. +// +static void R_MaskedLightLists(drawseg_t *ds, INT32 range) +{ lightlist_t *light; r_lightlist_t *rlight; - line_t *ldef; - sector_t *front, *back; - INT32 times, repeats; - INT64 overflow_test; -#ifdef ESLOPE - INT32 range; -#endif + INT32 lightnum, i; - // Calculate light table. - // Use different light tables - // for horizontal / vertical / diagonal. Diagonal? - // OPTIMIZE: get rid of LIGHTSEGSHIFT globally - curline = ds->curline; - frontsector = curline->frontsector; - backsector = curline->backsector; - texnum = R_GetTextureNum(curline->sidedef->midtexture); - windowbottom = windowtop = sprbotscreen = INT32_MAX; - - // hack translucent linedef types (900-909 for transtables 1-9) - ldef = curline->linedef; - switch (ldef->special) - { - case 900: - case 901: - case 902: - case 903: - case 904: - case 905: - case 906: - case 907: - case 908: - dc_transmap = transtables + ((ldef->special-900)<ceilingheight; - windowbottom = frontsector->floorheight; - break; - default: - colfunc = colfuncs[BASEDRAWFUNC]; - break; - } - - if (curline->polyseg && curline->polyseg->translucency > 0) - { - if (curline->polyseg->translucency >= NUMTRANSMAPS) - return; - - dc_transmap = transtables + ((curline->polyseg->translucency-1)<x2-ds->x1, 1); -#endif - rw.scalestep = ds->scalestep; - spryscale = ds->scale1 + (x1 - ds->x1)*rw.scalestep; - - // Texture must be cached before setting colfunc_2s, - // otherwise texture[texnum]->holes may be false when it shouldn't be - R_CheckTextureCache(texnum); - // handle case where multipatch texture is drawn on a 2sided wall, multi-patch textures - // are not stored per-column with post info in SRB2 - if (textures[texnum]->holes) - { - if (textures[texnum]->flip & 2) // vertically flipped? - { - rw.colfunc_2s = R_DrawFlippedMaskedSegColumn; - rw.column2s_length = textures[texnum]->height; - } - else - rw.colfunc_2s = R_DrawMaskedColumn; // render the usual 2sided single-patch packed texture - } - else - { - rw.colfunc_2s = R_Render2sidedMultiPatchColumn; // render multipatch with no holes (no post_t info) - rw.column2s_length = textures[texnum]->height; - } - - // Setup lighting based on the presence/lack-of 3D floors. dc_numlights = 0; + if (frontsector->numlights) { dc_numlights = frontsector->numlights; @@ -2508,6 +2622,8 @@ void R_RenderMaskedSegRange(drawseg_t *ds, INT32 x1, INT32 x2) { #ifdef ESLOPE fixed_t leftheight, rightheight; +#else + (void)range; #endif light = &frontsector->lightlist[i]; rlight = &dc_lightlist[i]; @@ -2579,6 +2695,99 @@ void R_RenderMaskedSegRange(drawseg_t *ds, INT32 x1, INT32 x2) else walllights = scalelight[lightnum]; } +} + +// +// R_RenderMaskedSegRange +// Renders all the masked segs in the given range. +// +void R_RenderMaskedSegRange(drawseg_t *ds, INT32 x1, INT32 x2) +{ + INT32 texnum, i; + r_lightlist_t *rlight; + line_t *ldef; + sector_t *front, *back; + INT32 times, repeats; + INT32 range; + + // Calculate light table. + // Use different light tables + // for horizontal / vertical / diagonal. Diagonal? + // OPTIMIZE: get rid of LIGHTSEGSHIFT globally + curline = ds->curline; + frontsector = curline->frontsector; + backsector = curline->backsector; + texnum = R_GetTextureNum(curline->sidedef->midtexture); + windowbottom = windowtop = sprbotscreen = INT32_MAX; + + rw.x = x1; + rw.stopx = x2; + rw.texnum = texnum; + + // hack translucent linedef types (900-909 for transtables 1-9) + ldef = curline->linedef; + switch (ldef->special) + { + case 900: + case 901: + case 902: + case 903: + case 904: + case 905: + case 906: + case 907: + case 908: + dc_transmap = transtables + ((ldef->special-900)<ceilingheight; + windowbottom = frontsector->floorheight; + break; + default: + colfunc = colfuncs[BASEDRAWFUNC]; + break; + } + + if (curline->polyseg && curline->polyseg->translucency > 0) + { + if (curline->polyseg->translucency >= NUMTRANSMAPS) + return; + + dc_transmap = transtables + ((curline->polyseg->translucency-1)<x2-ds->x1, 1); +#endif + rw.scalestep = ds->scalestep; + spryscale = ds->scale1 + (x1 - ds->x1)*rw.scalestep; + + // Texture must be cached before setting colfunc_2s, + // otherwise texture[texnum]->holes may be false when it shouldn't be + R_CheckTextureCache(texnum); + // handle case where multipatch texture is drawn on a 2sided wall, multi-patch textures + // are not stored per-column with post info in SRB2 + if (textures[texnum]->holes) + { + if (textures[texnum]->flip & 2) // vertically flipped? + { + rw.colfunc_2s = R_DrawFlippedMaskedSegColumn; + rw.column2s_length = textures[texnum]->height; + } + else + rw.colfunc_2s = R_DrawMaskedColumn; // render the usual 2sided single-patch packed texture + } + else + { + rw.colfunc_2s = R_Render2sidedMultiPatchColumn; // render multipatch with no holes (no post_t info) + rw.column2s_length = textures[texnum]->height; + } + + // Setup lighting based on the presence/lack-of 3D floors. + R_MaskedLightLists(ds, range); maskedtexturecol = ds->maskedtexturecol; @@ -2658,183 +2867,8 @@ void R_RenderMaskedSegRange(drawseg_t *ds, INT32 x1, INT32 x2) dc_texheight = textureheight[texnum]>>FRACBITS; // draw the columns - for (dc_x = x1; dc_x <= x2; dc_x++) - { -#ifdef ESLOPE - dc_texturemid = ds->maskedtextureheight[dc_x]; - - if (!!(curline->linedef->flags & ML_DONTPEGBOTTOM) ^ !!(curline->linedef->flags & ML_EFFECT3)) - dc_texturemid += (textureheight[texnum])*times + textureheight[texnum]; - else - dc_texturemid -= (textureheight[texnum])*times; -#endif - // calculate lighting - if (maskedtexturecol[dc_x] != INT16_MAX) - { - // Check for overflows first - overflow_test = (INT64)centeryfrac - (((INT64)dc_texturemid*spryscale)>>FRACBITS); - if (overflow_test < 0) overflow_test = -overflow_test; - if ((UINT64)overflow_test&0xFFFFFFFF80000000ULL) - { - // Eh, no, go away, don't waste our time - if (dc_numlights) - { - for (i = 0; i < dc_numlights; i++) - { - rlight = &dc_lightlist[i]; - rlight->height += rlight->heightstep; - } - } - spryscale += rw.scalestep; - continue; - } - - if (dc_numlights) - { - lighttable_t **xwalllights; - - sprbotscreen = INT32_MAX; - sprtopscreen = windowtop = (centeryfrac - FixedMul(dc_texturemid, spryscale)); - - realbot = windowbottom = FixedMul(textureheight[texnum], spryscale) + sprtopscreen; - dc_iscale = 0xffffffffu / (unsigned)spryscale; - - // draw the texture - col = (column_t *)((UINT8 *)R_GetColumn(texnum, maskedtexturecol[dc_x]) - 3); - - for (i = 0; i < dc_numlights; i++) - { - rlight = &dc_lightlist[i]; - - if ((rlight->flags & FF_NOSHADE)) - continue; - - if (rlight->lightnum < 0) - xwalllights = scalelight[0]; - else if (rlight->lightnum >= LIGHTLEVELS) - xwalllights = scalelight[LIGHTLEVELS-1]; - else - xwalllights = scalelight[rlight->lightnum]; - - pindex = FixedMul(spryscale, FixedDiv(640, vid.width))>>LIGHTSCALESHIFT; - - if (pindex >= MAXLIGHTSCALE) - pindex = MAXLIGHTSCALE - 1; - - if (rlight->extra_colormap) - rlight->rcolormap = rlight->extra_colormap->colormap + (xwalllights[pindex] - colormaps); - else - rlight->rcolormap = xwalllights[pindex]; - - height = rlight->height; - rlight->height += rlight->heightstep; - - if (height <= windowtop) - { - dc_colormap = rlight->rcolormap; - continue; - } - - windowbottom = height; - if (windowbottom >= realbot) - { - windowbottom = realbot; - rw.colfunc_2s(col); - for (i++; i < dc_numlights; i++) - { - rlight = &dc_lightlist[i]; - rlight->height += rlight->heightstep; - } - - continue; - } - rw.colfunc_2s(col); - windowtop = windowbottom + 1; - dc_colormap = rlight->rcolormap; - } - windowbottom = realbot; - if (windowtop < windowbottom) - rw.colfunc_2s(col); - - spryscale += rw.scalestep; - continue; - } - - // calculate lighting - pindex = FixedMul(spryscale, FixedDiv(640, vid.width))>>LIGHTSCALESHIFT; - - if (pindex >= MAXLIGHTSCALE) - pindex = MAXLIGHTSCALE - 1; - - dc_colormap = walllights[pindex]; - - if (frontsector->extra_colormap) - dc_colormap = frontsector->extra_colormap->colormap + (dc_colormap - colormaps); - - sprtopscreen = centeryfrac - FixedMul(dc_texturemid, spryscale); - dc_iscale = 0xffffffffu / (unsigned)spryscale; - - // draw the texture - col = (column_t *)((UINT8 *)R_GetColumn(texnum, maskedtexturecol[dc_x]) - 3); - -//#ifdef POLYOBJECTS_PLANES -#if 0 // Disabling this allows inside edges to render below the planes, for until the clipping is fixed to work right when POs are near the camera. -Red - if (curline->dontrenderme && curline->polyseg && (curline->polyseg->flags & POF_RENDERPLANES)) - { - fixed_t my_topscreen; - fixed_t my_bottomscreen; - fixed_t my_yl, my_yh; - - my_topscreen = sprtopscreen + spryscale*col->topdelta; - my_bottomscreen = sprbotscreen == INT32_MAX ? my_topscreen + spryscale*col->length - : sprbotscreen + spryscale*col->length; - - my_yl = (my_topscreen+FRACUNIT-1)>>FRACBITS; - my_yh = (my_bottomscreen-1)>>FRACBITS; - // CONS_Debug(DBG_RENDER, "my_topscreen: %d\nmy_bottomscreen: %d\nmy_yl: %d\nmy_yh: %d\n", my_topscreen, my_bottomscreen, my_yl, my_yh); - - if (numffloors) - { - INT32 top = my_yl; - INT32 bottom = my_yh; - - for (i = 0; i < numffloors; i++) - { - if (!ffloor[i].polyobj || ffloor[i].polyobj != curline->polyseg) - continue; - - if (ffloor[i].height < viewz) - { - INT32 top_w = ffloor[i].plane->top[dc_x]; - - // CONS_Debug(DBG_RENDER, "Leveltime : %d\n", leveltime); - // CONS_Debug(DBG_RENDER, "Top is %d, top_w is %d\n", top, top_w); - if (top_w < top) - { - ffloor[i].plane->top[dc_x] = (INT16)top; - ffloor[i].plane->picnum = 0; - } - // CONS_Debug(DBG_RENDER, "top_w is now %d\n", ffloor[i].plane->top[dc_x]); - } - else if (ffloor[i].height > viewz) - { - INT32 bottom_w = ffloor[i].plane->bottom[dc_x]; - - if (bottom_w > bottom) - { - ffloor[i].plane->bottom[dc_x] = (INT16)bottom; - ffloor[i].plane->picnum = 0; - } - } - } - } - } - else -#endif - rw.colfunc_2s(col); - } - spryscale += rw.scalestep; - } + rw.maskedrepeat = times; + R_RenderMaskedSegLoop(ds); } colfunc = colfuncs[BASEDRAWFUNC]; } @@ -3276,9 +3310,7 @@ void R_RenderThickSideRange(drawseg_t *ds, INT32 x1, INT32 x2, ffloor_t *pfloor) INT32 texnum; fixed_t offsetvalue = 0; -#ifdef ESLOPE INT32 range; -#endif #ifndef ESLOPE fixed_t lheight; #endif diff --git a/src/r_state.h b/src/r_state.h index cecdb8f4d..2c5e5fcf7 100644 --- a/src/r_state.h +++ b/src/r_state.h @@ -115,6 +115,9 @@ typedef struct void (*colfunc_2s) (column_t *); INT32 column2s_length; // column->length : for multi-patch on 2sided wall = texture->height + // masked segs + INT32 maskedrepeat; + // thick sides ffloor_t *pfloor; #ifdef ESLOPE From 69b4efb57966eacd62da24e43fedbaf99d29fd46 Mon Sep 17 00:00:00 2001 From: Jaime Passos Date: Thu, 26 Dec 2019 18:13:03 -0300 Subject: [PATCH 36/79] Rename R_WorldSegTextured --- src/r_segs.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/r_segs.c b/src/r_segs.c index fa26420a8..665176f85 100644 --- a/src/r_segs.c +++ b/src/r_segs.c @@ -644,11 +644,11 @@ static void R_WorldTopAndBottom(INT32 start, INT32 stop) } // -// R_WorldSegTextured +// R_SegTextured // Calculate rw.offset. // Only needed for textured lines. // -static void R_WorldSegTextured(fixed_t hyp, boolean longboi) +static void R_SegTextured(fixed_t hyp, boolean longboi) { INT32 lightnum; fixed_t sineval; @@ -2090,7 +2090,7 @@ void R_StoreWallRange(INT32 start, INT32 stop) // Calculate rw.offset (only needed for textured lines) segtextured = midtexture || toptexture || bottomtexture || maskedtexture || (numthicksides > 0); if (segtextured) - R_WorldSegTextured(hyp, longboi); + R_SegTextured(hyp, longboi); // if a floor / ceiling plane is on the wrong side // of the view plane, it is definitely invisible From f26bdf00fe6d02ea092554bc72135d015a752a4c Mon Sep 17 00:00:00 2001 From: James R Date: Thu, 26 Dec 2019 18:12:10 -0800 Subject: [PATCH 37/79] A system to encode flags in the command buffer --- src/command.c | 67 ++++++++++++++++++++++++++++++++++++++++++++------- src/command.h | 7 ++++-- 2 files changed, 63 insertions(+), 11 deletions(-) diff --git a/src/command.c b/src/command.c index 33d8ead96..3aa22b62f 100644 --- a/src/command.c +++ b/src/command.c @@ -61,6 +61,8 @@ static consvar_t *consvar_vars; // list of registered console variables static char com_token[1024]; static char *COM_Parse(char *data); +static char * COM_Purge (char *text, int *lenp); + CV_PossibleValue_t CV_OnOff[] = {{0, "Off"}, {1, "On"}, {0, NULL}}; CV_PossibleValue_t CV_YesNo[] = {{0, "No"}, {1, "Yes"}, {0, NULL}}; CV_PossibleValue_t CV_Unsigned[] = {{0, "MIN"}, {999999999, "MAX"}, {0, NULL}}; @@ -100,31 +102,61 @@ static cmdalias_t *com_alias; // aliases list static vsbuf_t com_text; // variable sized buffer +/** Purges control characters out of some text. + * + * \param s The text. + * \param np Optionally a pointer to fill with the new string length. + * \return The new length. + * \sa COM_ExecuteString + */ +static char * +COM_Purge (char *s, int *np) +{ + char *t; + char *p; + int n; + n = strlen(s); + t = s + n + 1; + p = s; + while (( p = strchr(p, '\033') )) + { + memmove(p, &p[1], t - p - 1); + n--; + } + if (np) + (*np) = n; + return s; +} + /** Adds text into the command buffer for later execution. * * \param ptext The text to add. - * \sa COM_BufInsertText + * \sa COM_BufInsertTextEx */ -void COM_BufAddText(const char *ptext) +void COM_BufAddTextEx(const char *ptext, int flags) { - size_t l; + int l; + char *text; - l = strlen(ptext); + text = COM_Purge(Z_StrDup(ptext), &l); - if (com_text.cursize + l >= com_text.maxsize) + if (com_text.cursize + 2 + l >= com_text.maxsize) { CONS_Alert(CONS_WARNING, M_GetText("Command buffer full!\n")); return; } - VS_Write(&com_text, ptext, l); + + VS_WriteEx(&com_text, text, l, flags); + + Z_Free(text); } /** Adds command text and executes it immediately. * * \param ptext The text to execute. A newline is automatically added. - * \sa COM_BufAddText + * \sa COM_BufAddTextEx */ -void COM_BufInsertText(const char *ptext) +void COM_BufInsertTextEx(const char *ptext, int flags) { char *temp = NULL; size_t templen; @@ -138,7 +170,7 @@ void COM_BufInsertText(const char *ptext) } // add the entire text of the file (or alias) - COM_BufAddText(ptext); + COM_BufAddTextEx(ptext, flags); COM_BufExecute(); // do it right away // add the copied off data @@ -272,6 +304,7 @@ static size_t com_argc; static char *com_argv[MAX_ARGS]; static const char *com_null_string = ""; static char *com_args = NULL; // current command args or NULL +static int com_flags; static void Got_NetVar(UINT8 **p, INT32 playernum); @@ -394,9 +427,16 @@ static void COM_TokenizeString(char *ptext) com_argc = 0; com_args = NULL; + com_flags = 0; while (com_argc < MAX_ARGS) { + if (ptext[0] == '\033') + { + com_flags = (unsigned)ptext[1]; + ptext += 2; + } + // Skip whitespace up to a newline. while (*ptext != '\0' && *ptext <= ' ' && *ptext != '\n') ptext++; @@ -1016,6 +1056,15 @@ void VS_Write(vsbuf_t *buf, const void *data, size_t length) M_Memcpy(VS_GetSpace(buf, length), data, length); } +void VS_WriteEx(vsbuf_t *buf, const void *data, size_t length, int flags) +{ + char *p; + p = VS_GetSpace(buf, 2 + length); + p[0] = '\033'; + p[1] = flags; + M_Memcpy(&p[2], data, length); +} + /** Prints text in a variable buffer. Like VS_Write() plus a * trailing NUL. * diff --git a/src/command.h b/src/command.h index 51e161cd0..af9d08ae1 100644 --- a/src/command.h +++ b/src/command.h @@ -36,10 +36,12 @@ size_t COM_FirstOption(void); const char *COM_CompleteCommand(const char *partial, INT32 skips); // insert at queu (at end of other command) -void COM_BufAddText(const char *btext); +#define COM_BufAddText(s) COM_BufAddTextEx(s, 0) +void COM_BufAddTextEx(const char *btext, int flags); // insert in head (before other command) -void COM_BufInsertText(const char *btext); +#define COM_BufInsertText(s) COM_BufInsertTextEx(s, 0) +void COM_BufInsertTextEx(const char *btext, int flags); // don't bother inserting, just do immediately void COM_ImmedExecute(const char *ptext); @@ -71,6 +73,7 @@ void VS_Free(vsbuf_t *buf); void VS_Clear(vsbuf_t *buf); void *VS_GetSpace(vsbuf_t *buf, size_t length); void VS_Write(vsbuf_t *buf, const void *data, size_t length); +void VS_WriteEx(vsbuf_t *buf, const void *data, size_t length, int flags); void VS_Print(vsbuf_t *buf, const char *data); // strcats onto the sizebuf //================== From cb29a9dd0aeb28f3293f03f9810b46b70027545d Mon Sep 17 00:00:00 2001 From: James R Date: Thu, 26 Dec 2019 18:15:19 -0800 Subject: [PATCH 38/79] CV_NOLUA for when a cvar should not be changed via Lua --- src/command.c | 3 +++ src/command.h | 8 +++++++- src/dehacked.c | 1 + src/lua_consolelib.c | 4 ++-- 4 files changed, 13 insertions(+), 3 deletions(-) diff --git a/src/command.c b/src/command.c index 3aa22b62f..861a1f828 100644 --- a/src/command.c +++ b/src/command.c @@ -2064,6 +2064,9 @@ static boolean CV_Command(void) if (!v) return false; + if (( com_flags & COM_SAFE ) && ( v->flags & CV_NOLUA )) + return false; + // perform a variable print or set if (COM_Argc() == 1) { diff --git a/src/command.h b/src/command.h index af9d08ae1..b1026437f 100644 --- a/src/command.h +++ b/src/command.h @@ -20,6 +20,11 @@ // Command buffer & command execution //=================================== +enum +{ + COM_SAFE = 1, +}; + typedef void (*com_func_t)(void); void COM_AddCommand(const char *name, com_func_t func); @@ -103,7 +108,8 @@ typedef enum CV_HIDEN = 1024, // variable is not part of the cvar list so cannot be accessed by the console // can only be set when we have the pointer to it // used on menus - CV_CHEAT = 2048 // Don't let this be used in multiplayer unless cheats are on. + CV_CHEAT = 2048, // Don't let this be used in multiplayer unless cheats are on. + CV_NOLUA = 4096,/* don't let this be called from Lua */ } cvflags_t; typedef struct CV_PossibleValue_s diff --git a/src/dehacked.c b/src/dehacked.c index 9abb708a9..c9e10c064 100644 --- a/src/dehacked.c +++ b/src/dehacked.c @@ -9462,6 +9462,7 @@ struct { {"CV_HIDEN",CV_HIDEN}, {"CV_HIDDEN",CV_HIDEN}, {"CV_CHEAT",CV_CHEAT}, + {"CV_NOLUA",CV_NOLUA}, // v_video flags {"V_NOSCALEPATCH",V_NOSCALEPATCH}, diff --git a/src/lua_consolelib.c b/src/lua_consolelib.c index 58e720c85..837612e52 100644 --- a/src/lua_consolelib.c +++ b/src/lua_consolelib.c @@ -245,7 +245,7 @@ static int lib_comBufAddText(lua_State *L) return LUA_ErrInvalid(L, "player_t"); if (plr != &players[consoleplayer]) return 0; - COM_BufAddText(va("%s\n", luaL_checkstring(L, 2))); + COM_BufAddTextEx(va("%s\n", luaL_checkstring(L, 2)), COM_SAFE); return 0; } @@ -262,7 +262,7 @@ static int lib_comBufInsertText(lua_State *L) return LUA_ErrInvalid(L, "player_t"); if (plr != &players[consoleplayer]) return 0; - COM_BufInsertText(va("%s\n", luaL_checkstring(L, 2))); + COM_BufInsertTextEx(va("%s\n", luaL_checkstring(L, 2)), COM_SAFE); return 0; } From 4959d52ae0b33e7db90afb7db2cedd4a42108079 Mon Sep 17 00:00:00 2001 From: James R Date: Thu, 26 Dec 2019 18:15:52 -0800 Subject: [PATCH 39/79] Make cv_renderer CV_NOLUA instead of hidden!!! --- src/screen.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/screen.c b/src/screen.c index b21b6815a..4aac27c01 100644 --- a/src/screen.c +++ b/src/screen.c @@ -65,7 +65,7 @@ consvar_t cv_renderview = {"renderview", "On", 0, CV_OnOff, NULL, 0, NULL, NULL, static void SCR_ActuallyChangeRenderer(void); static CV_PossibleValue_t cv_renderer_t[] = {{1, "Software"}, {2, "OpenGL"}, {0, NULL}}; -consvar_t cv_renderer = {"renderer", "Software", CV_HIDEN|CV_CALL, cv_renderer_t, SCR_ChangeRenderer, 0, NULL, NULL, 0, 0, NULL}; +consvar_t cv_renderer = {"renderer", "Software", CV_NOLUA|CV_CALL, cv_renderer_t, SCR_ChangeRenderer, 0, NULL, NULL, 0, 0, NULL}; static void SCR_ChangeFullscreen(void); From 967343962869852bc626e26a278cce1640253a09 Mon Sep 17 00:00:00 2001 From: James R Date: Thu, 26 Dec 2019 18:20:48 -0800 Subject: [PATCH 40/79] e --- src/command.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/command.c b/src/command.c index 861a1f828..5e9453b16 100644 --- a/src/command.c +++ b/src/command.c @@ -106,7 +106,7 @@ static vsbuf_t com_text; // variable sized buffer * * \param s The text. * \param np Optionally a pointer to fill with the new string length. - * \return The new length. + * \return The text. * \sa COM_ExecuteString */ static char * From 4865a190578b900b48571e74e0bd97bef88ea71b Mon Sep 17 00:00:00 2001 From: James R Date: Thu, 26 Dec 2019 18:23:01 -0800 Subject: [PATCH 41/79] One more optimization --- src/command.c | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/src/command.c b/src/command.c index 5e9453b16..40efa1eee 100644 --- a/src/command.c +++ b/src/command.c @@ -427,16 +427,17 @@ static void COM_TokenizeString(char *ptext) com_argc = 0; com_args = NULL; - com_flags = 0; + + if (ptext[0] == '\033') + { + com_flags = (unsigned)ptext[1]; + ptext += 2; + } + else + com_flags = 0; while (com_argc < MAX_ARGS) { - if (ptext[0] == '\033') - { - com_flags = (unsigned)ptext[1]; - ptext += 2; - } - // Skip whitespace up to a newline. while (*ptext != '\0' && *ptext <= ' ' && *ptext != '\n') ptext++; From e617f3518241621719780e97eb2248671b81ca35 Mon Sep 17 00:00:00 2001 From: Jaime Passos Date: Thu, 26 Dec 2019 23:26:43 -0300 Subject: [PATCH 42/79] PU_PATCH funny --- src/m_menu.c | 140 +++++++++++++++++++++++++-------------------------- 1 file changed, 70 insertions(+), 70 deletions(-) diff --git a/src/m_menu.c b/src/m_menu.c index 7de755783..7049b00c4 100644 --- a/src/m_menu.c +++ b/src/m_menu.c @@ -3763,9 +3763,9 @@ static void M_DrawSlider(INT32 x, INT32 y, const consvar_t *cv, boolean ontop) x = BASEVIDWIDTH - x - SLIDER_WIDTH; - V_DrawScaledPatch(x, y, 0, W_CachePatchName("M_SLIDEL", PU_CACHE)); + V_DrawScaledPatch(x, y, 0, W_CachePatchName("M_SLIDEL", PU_PATCH)); - p = W_CachePatchName("M_SLIDEM", PU_CACHE); + p = W_CachePatchName("M_SLIDEM", PU_PATCH); for (i = 1; i < SLIDER_RANGE; i++) V_DrawScaledPatch (x+i*8, y, 0,p); @@ -3777,11 +3777,11 @@ static void M_DrawSlider(INT32 x, INT32 y, const consvar_t *cv, boolean ontop) '\x1D' | V_YELLOWMAP, false); } - p = W_CachePatchName("M_SLIDER", PU_CACHE); + p = W_CachePatchName("M_SLIDER", PU_PATCH); V_DrawScaledPatch(x+i*8, y, 0, p); // draw the slider cursor - p = W_CachePatchName("M_SLIDEC", PU_CACHE); + p = W_CachePatchName("M_SLIDEC", PU_PATCH); for (i = 0; cv->PossibleValue[i+1].strvalue; i++); @@ -3878,7 +3878,7 @@ static void M_DrawStaticBox(fixed_t x, fixed_t y, INT32 flags, fixed_t w, fixed_ patch_t *patch; fixed_t sw, pw; - patch = W_CachePatchName("LSSTATIC", PU_CACHE); + patch = W_CachePatchName("LSSTATIC", PU_PATCH); pw = SHORT(patch->width) - (sw = w*2); //FixedDiv(w, scale); -- for scale FRACUNIT/2 /*if (pw > 0) -- model code for modders providing weird LSSTATIC @@ -3907,15 +3907,15 @@ static void M_DrawSaveLoadBorder(INT32 x,INT32 y) { INT32 i; - V_DrawScaledPatch (x-8,y+7,0,W_CachePatchName("M_LSLEFT",PU_CACHE)); + V_DrawScaledPatch (x-8,y+7,0,W_CachePatchName("M_LSLEFT",PU_PATCH)); for (i = 0;i < 24;i++) { - V_DrawScaledPatch (x,y+7,0,W_CachePatchName("M_LSCNTR",PU_CACHE)); + V_DrawScaledPatch (x,y+7,0,W_CachePatchName("M_LSCNTR",PU_PATCH)); x += 8; } - V_DrawScaledPatch (x,y+7,0,W_CachePatchName("M_LSRGHT",PU_CACHE)); + V_DrawScaledPatch (x,y+7,0,W_CachePatchName("M_LSRGHT",PU_PATCH)); } #endif @@ -3958,10 +3958,10 @@ static void M_DrawMapEmblems(INT32 mapnum, INT32 x, INT32 y) lasttype = curtype; if (emblem->collected) - V_DrawSmallMappedPatch(x, y, 0, W_CachePatchName(M_GetEmblemPatch(emblem, false), PU_CACHE), + V_DrawSmallMappedPatch(x, y, 0, W_CachePatchName(M_GetEmblemPatch(emblem, false), PU_PATCH), R_GetTranslationColormap(TC_DEFAULT, M_GetEmblemColor(emblem), GTC_CACHE)); else - V_DrawSmallScaledPatch(x, y, 0, W_CachePatchName("NEEDIT", PU_CACHE)); + V_DrawSmallScaledPatch(x, y, 0, W_CachePatchName("NEEDIT", PU_PATCH)); emblem = M_GetLevelEmblems(-1); x -= 12; @@ -3972,7 +3972,7 @@ static void M_DrawMenuTitle(void) { if (currentMenu->menutitlepic) { - patch_t *p = W_CachePatchName(currentMenu->menutitlepic, PU_CACHE); + patch_t *p = W_CachePatchName(currentMenu->menutitlepic, PU_PATCH); if (p->height > 24) // title is larger than normal { @@ -4024,13 +4024,13 @@ static void M_DrawGenericMenu(void) if (currentMenu->menuitems[i].status & IT_CENTER) { patch_t *p; - p = W_CachePatchName(currentMenu->menuitems[i].patch, PU_CACHE); + p = W_CachePatchName(currentMenu->menuitems[i].patch, PU_PATCH); V_DrawScaledPatch((BASEVIDWIDTH - SHORT(p->width))/2, y, 0, p); } else { V_DrawScaledPatch(x, y, 0, - W_CachePatchName(currentMenu->menuitems[i].patch, PU_CACHE)); + W_CachePatchName(currentMenu->menuitems[i].patch, PU_PATCH)); } } /* FALLTHRU */ @@ -4099,7 +4099,7 @@ static void M_DrawGenericMenu(void) case IT_GRAYPATCH: if (currentMenu->menuitems[i].patch && currentMenu->menuitems[i].patch[0]) V_DrawMappedPatch(x, y, 0, - W_CachePatchName(currentMenu->menuitems[i].patch,PU_CACHE), graymap); + W_CachePatchName(currentMenu->menuitems[i].patch,PU_PATCH), graymap); y += LINEHEIGHT; break; case IT_TRANSTEXT: @@ -4133,12 +4133,12 @@ static void M_DrawGenericMenu(void) || ((currentMenu->menuitems[itemOn].status & IT_DISPLAY) == IT_NOTHING)) { V_DrawScaledPatch(currentMenu->x + SKULLXOFF, cursory - 5, 0, - W_CachePatchName("M_CURSOR", PU_CACHE)); + W_CachePatchName("M_CURSOR", PU_PATCH)); } else { V_DrawScaledPatch(currentMenu->x - 24, cursory, 0, - W_CachePatchName("M_CURSOR", PU_CACHE)); + W_CachePatchName("M_CURSOR", PU_PATCH)); V_DrawString(currentMenu->x, cursory, V_YELLOWMAP, currentMenu->menuitems[itemOn].text); } } @@ -4276,7 +4276,7 @@ static void M_DrawGenericScrollMenu(void) // DRAW THE SKULL CURSOR V_DrawScaledPatch(currentMenu->x - 24, cursory, 0, - W_CachePatchName("M_CURSOR", PU_CACHE)); + W_CachePatchName("M_CURSOR", PU_PATCH)); } static void M_DrawPauseMenu(void) @@ -4397,10 +4397,10 @@ static void M_DrawPauseMenu(void) continue; if (emblem->collected) - V_DrawSmallMappedPatch(40, 44 + (i*8), 0, W_CachePatchName(M_GetEmblemPatch(emblem, false), PU_CACHE), + V_DrawSmallMappedPatch(40, 44 + (i*8), 0, W_CachePatchName(M_GetEmblemPatch(emblem, false), PU_PATCH), R_GetTranslationColormap(TC_DEFAULT, M_GetEmblemColor(emblem), GTC_CACHE)); else - V_DrawSmallScaledPatch(40, 44 + (i*8), 0, W_CachePatchName("NEEDIT", PU_CACHE)); + V_DrawSmallScaledPatch(40, 44 + (i*8), 0, W_CachePatchName("NEEDIT", PU_PATCH)); switch (emblem->type) { @@ -4446,13 +4446,13 @@ static void M_DrawCenteredMenu(void) if (currentMenu->menuitems[i].status & IT_CENTER) { patch_t *p; - p = W_CachePatchName(currentMenu->menuitems[i].patch, PU_CACHE); + p = W_CachePatchName(currentMenu->menuitems[i].patch, PU_PATCH); V_DrawScaledPatch((BASEVIDWIDTH - SHORT(p->width))/2, y, 0, p); } else { V_DrawScaledPatch(x, y, 0, - W_CachePatchName(currentMenu->menuitems[i].patch, PU_CACHE)); + W_CachePatchName(currentMenu->menuitems[i].patch, PU_PATCH)); } } /* FALLTHRU */ @@ -4527,7 +4527,7 @@ static void M_DrawCenteredMenu(void) case IT_GRAYPATCH: if (currentMenu->menuitems[i].patch && currentMenu->menuitems[i].patch[0]) V_DrawMappedPatch(x, y, 0, - W_CachePatchName(currentMenu->menuitems[i].patch,PU_CACHE), graymap); + W_CachePatchName(currentMenu->menuitems[i].patch,PU_PATCH), graymap); y += LINEHEIGHT; break; } @@ -4538,12 +4538,12 @@ static void M_DrawCenteredMenu(void) || ((currentMenu->menuitems[itemOn].status & IT_DISPLAY) == IT_NOTHING)) { V_DrawScaledPatch(x + SKULLXOFF, cursory - 5, 0, - W_CachePatchName("M_CURSOR", PU_CACHE)); + W_CachePatchName("M_CURSOR", PU_PATCH)); } else { V_DrawScaledPatch(x - V_StringWidth(currentMenu->menuitems[itemOn].text, 0)/2 - 24, cursory, 0, - W_CachePatchName("M_CURSOR", PU_CACHE)); + W_CachePatchName("M_CURSOR", PU_PATCH)); V_DrawCenteredString(x, cursory, V_YELLOWMAP, currentMenu->menuitems[itemOn].text); } } @@ -5169,7 +5169,7 @@ static void M_DrawLevelPlatterWideMap(UINT8 row, UINT8 col, INT32 x, INT32 y, bo else { if (W_CheckNumForName(va("%sW", G_BuildMapName(map))) != LUMPERROR) - patch = W_CachePatchName(va("%sW", G_BuildMapName(map)), PU_CACHE); + patch = W_CachePatchName(va("%sW", G_BuildMapName(map)), PU_PATCH); else patch = levselp[1][2]; // don't static to indicate that it's just a normal level @@ -5200,7 +5200,7 @@ static void M_DrawLevelPlatterMap(UINT8 row, UINT8 col, INT32 x, INT32 y, boolea else { if (W_CheckNumForName(va("%sP", G_BuildMapName(map))) != LUMPERROR) - patch = W_CachePatchName(va("%sP", G_BuildMapName(map)), PU_CACHE); + patch = W_CachePatchName(va("%sP", G_BuildMapName(map)), PU_PATCH); else patch = levselp[0][2]; // don't static to indicate that it's just a normal level @@ -5260,8 +5260,8 @@ static void M_DrawLevelPlatterRow(UINT8 row, INT32 y) // new menus static void M_DrawRecordAttackForeground(void) { - patch_t *fg = W_CachePatchName("RECATKFG", PU_CACHE); - patch_t *clock = W_CachePatchName("RECCLOCK", PU_CACHE); + patch_t *fg = W_CachePatchName("RECATKFG", PU_PATCH); + patch_t *clock = W_CachePatchName("RECCLOCK", PU_PATCH); angle_t fa; INT32 i; @@ -5299,7 +5299,7 @@ static void M_DrawNightsAttackMountains(void) { static INT32 bgscrollx; INT32 dupz = (vid.dupx < vid.dupy ? vid.dupx : vid.dupy); - patch_t *background = W_CachePatchName(curbgname, PU_CACHE); + patch_t *background = W_CachePatchName(curbgname, PU_PATCH); INT32 x = FixedInt(bgscrollx) % SHORT(background->width); INT32 y = BASEVIDHEIGHT - SHORT(background->height)*2; @@ -5322,16 +5322,16 @@ static void M_DrawNightsAttackBackground(void) INT32 i; // top - patch_t *backtopfg = W_CachePatchName("NTSATKT1", PU_CACHE); - patch_t *fronttopfg = W_CachePatchName("NTSATKT2", PU_CACHE); + patch_t *backtopfg = W_CachePatchName("NTSATKT1", PU_PATCH); + patch_t *fronttopfg = W_CachePatchName("NTSATKT2", PU_PATCH); INT32 backtopwidth = SHORT(backtopfg->width); //INT32 backtopheight = SHORT(backtopfg->height); INT32 fronttopwidth = SHORT(fronttopfg->width); //INT32 fronttopheight = SHORT(fronttopfg->height); // bottom - patch_t *backbottomfg = W_CachePatchName("NTSATKB1", PU_CACHE); - patch_t *frontbottomfg = W_CachePatchName("NTSATKB2", PU_CACHE); + patch_t *backbottomfg = W_CachePatchName("NTSATKB1", PU_PATCH); + patch_t *frontbottomfg = W_CachePatchName("NTSATKB2", PU_PATCH); INT32 backbottomwidth = SHORT(backbottomfg->width); INT32 backbottomheight = SHORT(backbottomfg->height); INT32 frontbottomwidth = SHORT(frontbottomfg->width); @@ -5475,7 +5475,7 @@ static void M_DrawLevelPlatterMenu(void) #if 0 if (levelselect.rows[lsrow].maplist[lscol] > 0) - V_DrawScaledPatch(lsbasex + cursorx-17, lsbasey+50+lsoffs[0], 0, W_CachePatchName("M_CURSOR", PU_CACHE)); + V_DrawScaledPatch(lsbasex + cursorx-17, lsbasey+50+lsoffs[0], 0, W_CachePatchName("M_CURSOR", PU_PATCH)); #endif // handle movement of cursor box @@ -5745,7 +5745,7 @@ static void M_DrawImageDef(void) V_DrawScaledPic(0,0,0,W_GetNumForName(currentMenu->menuitems[itemOn].text)); else { - patch_t *patch = W_CachePatchName(currentMenu->menuitems[itemOn].text,PU_CACHE); + patch_t *patch = W_CachePatchName(currentMenu->menuitems[itemOn].text,PU_PATCH); if (patch->width <= BASEVIDWIDTH) V_DrawScaledPatch(0,0,0,patch); else @@ -6947,13 +6947,13 @@ static void M_DrawEmblemHints(void) if (emblem->collected) { collected = V_GREENMAP; - V_DrawMappedPatch(12, 12+(28*j), 0, W_CachePatchName(M_GetEmblemPatch(emblem, false), PU_CACHE), + V_DrawMappedPatch(12, 12+(28*j), 0, W_CachePatchName(M_GetEmblemPatch(emblem, false), PU_PATCH), R_GetTranslationColormap(TC_DEFAULT, M_GetEmblemColor(emblem), GTC_CACHE)); } else { collected = 0; - V_DrawScaledPatch(12, 12+(28*j), 0, W_CachePatchName("NEEDIT", PU_CACHE)); + V_DrawScaledPatch(12, 12+(28*j), 0, W_CachePatchName("NEEDIT", PU_PATCH)); } if (emblem->hint[0]) @@ -7855,7 +7855,7 @@ skiplife: if (colormap) Z_Free(colormap); - patch = W_CachePatchName("STLIVEX", PU_CACHE); + patch = W_CachePatchName("STLIVEX", PU_PATCH); V_DrawScaledPatch(tempx + 9, y + 2, 0, patch); tempx += 16; @@ -7871,14 +7871,14 @@ skiplife: // continues if (savegameinfo[savetodraw].continues > 0) { - V_DrawSmallScaledPatch(tempx, y, 0, W_CachePatchName("CONTSAVE", PU_CACHE)); + V_DrawSmallScaledPatch(tempx, y, 0, W_CachePatchName("CONTSAVE", PU_PATCH)); V_DrawScaledPatch(tempx + 9, y + 2, 0, patch); V_DrawString(tempx + 16, y, 0, va("%d", savegameinfo[savetodraw].continues)); } else { - V_DrawSmallScaledPatch(tempx, y, 0, W_CachePatchName("CONTNONE", PU_CACHE)); - V_DrawScaledPatch(tempx + 9, y + 2, 0, W_CachePatchName("STNONEX", PU_CACHE)); + V_DrawSmallScaledPatch(tempx, y, 0, W_CachePatchName("CONTNONE", PU_PATCH)); + V_DrawScaledPatch(tempx + 9, y + 2, 0, W_CachePatchName("STNONEX", PU_PATCH)); V_DrawString(tempx + 16, y, V_GRAYMAP, "0"); } } @@ -8352,7 +8352,7 @@ static void M_SetupChoosePlayer(INT32 choice) description[i].charpic = W_CachePatchNum(sprframe->lumppat[0], PU_PATCH); } else - description[i].charpic = W_CachePatchName("MISSING", PU_CACHE); + description[i].charpic = W_CachePatchName("MISSING", PU_PATCH); } else description[i].charpic = W_CachePatchName(description[i].picname, PU_PATCH); @@ -8362,7 +8362,7 @@ static void M_SetupChoosePlayer(INT32 choice) const char *nametag = description[i].nametag; description[i].namepic = NULL; if (W_LumpExists(nametag)) - description[i].namepic = W_CachePatchName(nametag, PU_CACHE); + description[i].namepic = W_CachePatchName(nametag, PU_PATCH); } } // else -- Technically, character select icons without corresponding skins get bundled away behind this too. Sucks to be them. @@ -8502,8 +8502,8 @@ static void M_DrawSetupChoosePlayerMenu(void) UINT8 *colormap = NULL; INT32 prev = -1, next = -1; - patch_t *charbg = W_CachePatchName("CHARBG", PU_CACHE); - patch_t *charfg = W_CachePatchName("CHARFG", PU_CACHE); + patch_t *charbg = W_CachePatchName("CHARBG", PU_PATCH); + patch_t *charfg = W_CachePatchName("CHARFG", PU_PATCH); INT16 bgheight = SHORT(charbg->height); INT16 fgheight = SHORT(charfg->height); INT16 bgwidth = SHORT(charbg->width); @@ -8689,7 +8689,7 @@ static void M_DrawSetupChoosePlayerMenu(void) // Alternative menu header #ifdef CHOOSEPLAYER_DRAWHEADER { - patch_t *header = W_CachePatchName("M_PICKP", PU_CACHE); + patch_t *header = W_CachePatchName("M_PICKP", PU_PATCH); INT32 xtitle = 146; INT32 ytitle = (35 - SHORT(header->height))/2; V_DrawFixedPatch(xtitle<collected) - V_DrawSmallMappedPatch(292, y, 0, W_CachePatchName(M_GetExtraEmblemPatch(exemblem, false), PU_CACHE), + V_DrawSmallMappedPatch(292, y, 0, W_CachePatchName(M_GetExtraEmblemPatch(exemblem, false), PU_PATCH), R_GetTranslationColormap(TC_DEFAULT, M_GetExtraEmblemColor(exemblem), GTC_CACHE)); else - V_DrawSmallScaledPatch(292, y, 0, W_CachePatchName("NEEDIT", PU_CACHE)); + V_DrawSmallScaledPatch(292, y, 0, W_CachePatchName("NEEDIT", PU_PATCH)); V_DrawString(20, y, V_YELLOWMAP|V_ALLOWLOWERCASE, va("%s", exemblem->description)); } @@ -9070,7 +9070,7 @@ void M_DrawTimeAttackMenu(void) } // DRAW THE SKULL CURSOR - V_DrawScaledPatch(currentMenu->x - 24, cursory, 0, W_CachePatchName("M_CURSOR", PU_CACHE)); + V_DrawScaledPatch(currentMenu->x - 24, cursory, 0, W_CachePatchName("M_CURSOR", PU_PATCH)); V_DrawString(currentMenu->x, cursory, V_YELLOWMAP, currentMenu->menuitems[itemOn].text); // Character face! @@ -9079,10 +9079,10 @@ void M_DrawTimeAttackMenu(void) { spritedef_t *sprdef = &skins[cv_chooseskin.value-1].sprites[SPR2_XTRA]; spriteframe_t *sprframe = &sprdef->spriteframes[XTRA_CHARSEL]; - PictureOfUrFace = W_CachePatchNum(sprframe->lumppat[0], PU_CACHE); + PictureOfUrFace = W_CachePatchNum(sprframe->lumppat[0], PU_PATCH); } else - PictureOfUrFace = W_CachePatchName("MISSING", PU_CACHE); + PictureOfUrFace = W_CachePatchName("MISSING", PU_PATCH); if (PictureOfUrFace->width >= 256) V_DrawTinyScaledPatch(224, 120, 0, PictureOfUrFace); @@ -9110,9 +9110,9 @@ void M_DrawTimeAttackMenu(void) lumpnum = W_CheckNumForName(va("%sP", G_BuildMapName(cv_nextmap.value))); if (lumpnum != LUMPERROR) - PictureOfLevel = W_CachePatchName(va("%sP", G_BuildMapName(cv_nextmap.value)), PU_CACHE); + PictureOfLevel = W_CachePatchName(va("%sP", G_BuildMapName(cv_nextmap.value)), PU_PATCH); else - PictureOfLevel = W_CachePatchName("BLANKLVL", PU_CACHE); + PictureOfLevel = W_CachePatchName("BLANKLVL", PU_PATCH); y = 32+lsheadingheight; V_DrawSmallScaledPatch(216, y, 0, PictureOfLevel); @@ -9157,7 +9157,7 @@ void M_DrawTimeAttackMenu(void) goto skipThisOne; } - empatch = W_CachePatchName(M_GetEmblemPatch(em, true), PU_CACHE); + empatch = W_CachePatchName(M_GetEmblemPatch(em, true), PU_PATCH); empatx = SHORT(empatch->leftoffset)/2; empaty = SHORT(empatch->topoffset)/2; @@ -9166,7 +9166,7 @@ void M_DrawTimeAttackMenu(void) V_DrawSmallMappedPatch(104+76+empatx, yHeight+lsheadingheight/2+empaty, 0, empatch, R_GetTranslationColormap(TC_DEFAULT, M_GetEmblemColor(em), GTC_CACHE)); else - V_DrawSmallScaledPatch(104+76, yHeight+lsheadingheight/2, 0, W_CachePatchName("NEEDITL", PU_CACHE)); + V_DrawSmallScaledPatch(104+76, yHeight+lsheadingheight/2, 0, W_CachePatchName("NEEDITL", PU_PATCH)); skipThisOne: em = M_GetLevelEmblems(-1); @@ -9346,7 +9346,7 @@ void M_DrawNightsAttackMenu(void) } // DRAW THE SKULL CURSOR - V_DrawScaledPatch(currentMenu->x - 24, cursory, 0, W_CachePatchName("M_CURSOR", PU_CACHE)); + V_DrawScaledPatch(currentMenu->x - 24, cursory, 0, W_CachePatchName("M_CURSOR", PU_PATCH)); V_DrawString(currentMenu->x, cursory, V_YELLOWMAP, currentMenu->menuitems[itemOn].text); // Level record list @@ -9370,9 +9370,9 @@ void M_DrawNightsAttackMenu(void) lumpnum = W_CheckNumForName(va("%sP", G_BuildMapName(cv_nextmap.value))); if (lumpnum != LUMPERROR) - PictureOfLevel = W_CachePatchName(va("%sP", G_BuildMapName(cv_nextmap.value)), PU_CACHE); + PictureOfLevel = W_CachePatchName(va("%sP", G_BuildMapName(cv_nextmap.value)), PU_PATCH); else - PictureOfLevel = W_CachePatchName("BLANKLVL", PU_CACHE); + PictureOfLevel = W_CachePatchName("BLANKLVL", PU_PATCH); y = 32+lsheadingheight; V_DrawSmallScaledPatch(208, y, 0, PictureOfLevel); @@ -9444,10 +9444,10 @@ void M_DrawNightsAttackMenu(void) } if (em->collected) - V_DrawSmallMappedPatch(xpos, yHeight+lsheadingheight/2, 0, W_CachePatchName(M_GetEmblemPatch(em, false), PU_CACHE), + V_DrawSmallMappedPatch(xpos, yHeight+lsheadingheight/2, 0, W_CachePatchName(M_GetEmblemPatch(em, false), PU_PATCH), R_GetTranslationColormap(TC_DEFAULT, M_GetEmblemColor(em), GTC_CACHE)); else - V_DrawSmallScaledPatch(xpos, yHeight+lsheadingheight/2, 0, W_CachePatchName("NEEDIT", PU_CACHE)); + V_DrawSmallScaledPatch(xpos, yHeight+lsheadingheight/2, 0, W_CachePatchName("NEEDIT", PU_PATCH)); skipThisOne: em = M_GetLevelEmblems(-1); @@ -9483,8 +9483,8 @@ static void M_NightsAttack(INT32 choice) // This is really just to make sure Sonic is the played character, just in case M_PatchSkinNameTable(); - ntssupersonic[0] = W_CachePatchName("NTSSONC1", PU_CACHE); - ntssupersonic[1] = W_CachePatchName("NTSSONC2", PU_CACHE); + ntssupersonic[0] = W_CachePatchName("NTSSONC1", PU_PATCH); + ntssupersonic[1] = W_CachePatchName("NTSSONC2", PU_PATCH); G_SetGamestate(GS_TIMEATTACK); // do this before M_SetupNextMenu so that menu meta state knows that we're switching titlemapinaction = TITLEMAP_OFF; // Nope don't give us HOMs please @@ -10206,9 +10206,9 @@ static void M_DrawServerMenu(void) lumpnum = W_CheckNumForName(va("%sP", G_BuildMapName(cv_nextmap.value))); if (lumpnum != LUMPERROR) - PictureOfLevel = W_CachePatchName(va("%sP", G_BuildMapName(cv_nextmap.value)), PU_CACHE); + PictureOfLevel = W_CachePatchName(va("%sP", G_BuildMapName(cv_nextmap.value)), PU_PATCH); else - PictureOfLevel = W_CachePatchName("BLANKLVL", PU_CACHE); + PictureOfLevel = W_CachePatchName("BLANKLVL", PU_PATCH); V_DrawSmallScaledPatch(319 - (currentMenu->x + (SHORT(PictureOfLevel->width)/2)), currentMenu->y + imgheight, 0, PictureOfLevel); } @@ -10617,7 +10617,7 @@ colordraw: cursory = y; V_DrawScaledPatch(x - 17, cursory, 0, - W_CachePatchName("M_CURSOR", PU_CACHE)); + W_CachePatchName("M_CURSOR", PU_PATCH)); } // Handle 1P/2P MP Setup @@ -10943,7 +10943,7 @@ static void M_DrawJoystick(void) if (i == itemOn) { V_DrawScaledPatch(currentMenu->x - 24, OP_JoystickSetDef.y+LINEHEIGHT*i-4, 0, - W_CachePatchName("M_CURSOR", PU_CACHE)); + W_CachePatchName("M_CURSOR", PU_PATCH)); } } } @@ -11261,7 +11261,7 @@ static void M_DrawControl(void) } V_DrawScaledPatch(currentMenu->x - 20, cursory, 0, - W_CachePatchName("M_CURSOR", PU_CACHE)); + W_CachePatchName("M_CURSOR", PU_PATCH)); } #undef controlbuffer @@ -11553,7 +11553,7 @@ static void M_DrawVideoMode(void) j = OP_VideoModeDef.y + 14 + ((vidm_selected % vidm_column_size)*8); V_DrawScaledPatch(i - 8, j, 0, - W_CachePatchName("M_CURSOR", PU_CACHE)); + W_CachePatchName("M_CURSOR", PU_PATCH)); } // Just M_DrawGenericScrollMenu but showing a backing behind the headers. @@ -11681,7 +11681,7 @@ static void M_DrawColorMenu(void) // DRAW THE SKULL CURSOR V_DrawScaledPatch(currentMenu->x - 24, cursory, 0, - W_CachePatchName("M_CURSOR", PU_CACHE)); + W_CachePatchName("M_CURSOR", PU_PATCH)); } // special menuitem key handler for video mode list @@ -11844,7 +11844,7 @@ void M_QuitResponse(INT32 ch) ptime = I_GetTime() + NEWTICRATE*2; // Shortened the quit time, used to be 2 seconds Tails 03-26-2001 while (ptime > I_GetTime()) { - V_DrawScaledPatch(0, 0, 0, W_CachePatchName("GAMEQUIT", PU_CACHE)); // Demo 3 Quit Screen Tails 06-16-2001 + V_DrawScaledPatch(0, 0, 0, W_CachePatchName("GAMEQUIT", PU_PATCH)); // Demo 3 Quit Screen Tails 06-16-2001 I_FinishUpdate(); // Update the screen with the image Tails 06-19-2001 I_Sleep(); } From 644e41d90cffb211e80c3bf38b0f22bb2619989d Mon Sep 17 00:00:00 2001 From: Jaime Passos Date: Thu, 26 Dec 2019 23:39:40 -0300 Subject: [PATCH 43/79] Handle character select screen correctly after a renderer switch --- src/m_menu.c | 63 ++++++++++++++++++++++++++++++++++------------------ 1 file changed, 42 insertions(+), 21 deletions(-) diff --git a/src/m_menu.c b/src/m_menu.c index 7049b00c4..fccffed8e 100644 --- a/src/m_menu.c +++ b/src/m_menu.c @@ -8296,6 +8296,43 @@ void M_ForceSaveSlotSelected(INT32 sslot) // CHARACTER SELECT // ================ +// lactozilla: sometimes the renderer changes and these patches don't exist anymore +static void M_CacheCharacterSelectEntry(INT32 i, INT32 skinnum) +{ + if (!(description[i].picname[0])) + { + if (skins[skinnum].sprites[SPR2_XTRA].numframes > XTRA_CHARSEL) + { + spritedef_t *sprdef = &skins[skinnum].sprites[SPR2_XTRA]; + spriteframe_t *sprframe = &sprdef->spriteframes[XTRA_CHARSEL]; + description[i].charpic = W_CachePatchNum(sprframe->lumppat[0], PU_PATCH); + } + else + description[i].charpic = W_CachePatchName("MISSING", PU_PATCH); + } + else + description[i].charpic = W_CachePatchName(description[i].picname, PU_PATCH); + + if (description[i].nametag[0]) + description[i].namepic = W_CachePatchName(description[i].nametag, PU_PATCH); +} + +static void M_CacheCharacterSelect(void) +{ + INT32 i, skinnum; + + for (i = 0; i < 32; i++) + { + if (!description[i].used) + continue; + + // Already set in M_SetupChoosePlayer + skinnum = description[i].skinnum[0]; + if ((skinnum != -1) && (R_SkinUsable(-1, skinnum))) + M_CacheCharacterSelectEntry(i, skinnum); + } +} + static void M_SetupChoosePlayer(INT32 choice) { INT32 skinnum; @@ -8343,27 +8380,7 @@ static void M_SetupChoosePlayer(INT32 choice) if (i == char_on) allowed = true; - if (!(description[i].picname[0])) - { - if (skins[skinnum].sprites[SPR2_XTRA].numframes > XTRA_CHARSEL) - { - spritedef_t *sprdef = &skins[skinnum].sprites[SPR2_XTRA]; - spriteframe_t *sprframe = &sprdef->spriteframes[XTRA_CHARSEL]; - description[i].charpic = W_CachePatchNum(sprframe->lumppat[0], PU_PATCH); - } - else - description[i].charpic = W_CachePatchName("MISSING", PU_PATCH); - } - else - description[i].charpic = W_CachePatchName(description[i].picname, PU_PATCH); - - if (description[i].nametag[0]) - { - const char *nametag = description[i].nametag; - description[i].namepic = NULL; - if (W_LumpExists(nametag)) - description[i].namepic = W_CachePatchName(nametag, PU_PATCH); - } + M_CacheCharacterSelectEntry(i, skinnum); } // else -- Technically, character select icons without corresponding skins get bundled away behind this too. Sucks to be them. } @@ -8511,6 +8528,10 @@ static void M_DrawSetupChoosePlayerMenu(void) INT32 x, y; INT32 w = (vid.width/vid.dupx); + // lactozilla: the renderer changed so recache patches + if (needpatchrecache) + M_CacheCharacterSelect(); + if (abs(char_scroll) > FRACUNIT) char_scroll -= (char_scroll>>2); else // close enough. From 76a1a80d711c1a4e393e3dfdd3ed8c09b50e89db Mon Sep 17 00:00:00 2001 From: James R Date: Thu, 26 Dec 2019 18:44:02 -0800 Subject: [PATCH 44/79] Save the renderer --- src/screen.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/screen.c b/src/screen.c index 4aac27c01..94b6c2454 100644 --- a/src/screen.c +++ b/src/screen.c @@ -65,7 +65,7 @@ consvar_t cv_renderview = {"renderview", "On", 0, CV_OnOff, NULL, 0, NULL, NULL, static void SCR_ActuallyChangeRenderer(void); static CV_PossibleValue_t cv_renderer_t[] = {{1, "Software"}, {2, "OpenGL"}, {0, NULL}}; -consvar_t cv_renderer = {"renderer", "Software", CV_NOLUA|CV_CALL, cv_renderer_t, SCR_ChangeRenderer, 0, NULL, NULL, 0, 0, NULL}; +consvar_t cv_renderer = {"renderer", "Software", CV_SAVE|CV_NOLUA|CV_CALL, cv_renderer_t, SCR_ChangeRenderer, 0, NULL, NULL, 0, 0, NULL}; static void SCR_ChangeFullscreen(void); From 956905c8f4395c196068a3e83f65feb09f4a9833 Mon Sep 17 00:00:00 2001 From: Jaime Passos Date: Thu, 26 Dec 2019 23:49:31 -0300 Subject: [PATCH 45/79] Same deal, but for the level platter and save select screen --- src/m_menu.c | 52 ++++++++++++++++++++++++++++++++++++++-------------- 1 file changed, 38 insertions(+), 14 deletions(-) diff --git a/src/m_menu.c b/src/m_menu.c index fccffed8e..9fbcd55d7 100644 --- a/src/m_menu.c +++ b/src/m_menu.c @@ -4784,6 +4784,22 @@ static INT32 M_CountRowsToShowOnPlatter(INT32 gt) return rows; } +// +// M_CacheLevelPlatter +// +// Cache every patch used by the level platter. +// +static void M_CacheLevelPlatter(void) +{ + levselp[0][0] = W_CachePatchName("SLCT1LVL", PU_PATCH); + levselp[0][1] = W_CachePatchName("SLCT2LVL", PU_PATCH); + levselp[0][2] = W_CachePatchName("BLANKLVL", PU_PATCH); + + levselp[1][0] = W_CachePatchName("SLCT1LVW", PU_PATCH); + levselp[1][1] = W_CachePatchName("SLCT2LVW", PU_PATCH); + levselp[1][2] = W_CachePatchName("BLANKLVW", PU_PATCH); +} + // // M_PrepareLevelPlatter // @@ -4933,13 +4949,7 @@ static boolean M_PrepareLevelPlatter(INT32 gt, boolean nextmappick) } #endif - levselp[0][0] = W_CachePatchName("SLCT1LVL", PU_PATCH); - levselp[0][1] = W_CachePatchName("SLCT2LVL", PU_PATCH); - levselp[0][2] = W_CachePatchName("BLANKLVL", PU_PATCH); - - levselp[1][0] = W_CachePatchName("SLCT1LVW", PU_PATCH); - levselp[1][1] = W_CachePatchName("SLCT2LVW", PU_PATCH); - levselp[1][2] = W_CachePatchName("BLANKLVW", PU_PATCH); + M_CacheLevelPlatter(); return true; } @@ -5160,6 +5170,9 @@ static void M_DrawLevelPlatterWideMap(UINT8 row, UINT8 col, INT32 x, INT32 y, bo if (map <= 0) return; + if (needpatchrecache) + M_CacheLevelPlatter(); + // A 564x100 image of the level as entry MAPxxW if (!(levelselect.rows[row].mapavailable[col])) { @@ -5191,6 +5204,9 @@ static void M_DrawLevelPlatterMap(UINT8 row, UINT8 col, INT32 x, INT32 y, boolea if (map <= 0) return; + if (needpatchrecache) + M_CacheLevelPlatter(); + // A 160x100 image of the level as entry MAPxxP if (!(levelselect.rows[row].mapavailable[col])) { @@ -7626,6 +7642,17 @@ static INT32 saveSlotSelected = 1; static INT32 loadgamescroll = 0; static UINT8 loadgameoffset = 0; +static void M_CacheLoadGameData(void) +{ + savselp[0] = W_CachePatchName("SAVEBACK", PU_PATCH); + savselp[1] = W_CachePatchName("SAVENONE", PU_PATCH); + savselp[2] = W_CachePatchName("ULTIMATE", PU_PATCH); + + savselp[3] = W_CachePatchName("GAMEDONE", PU_PATCH); + savselp[4] = W_CachePatchName("BLACXLVL", PU_PATCH); + savselp[5] = W_CachePatchName("BLANKLVL", PU_PATCH); +} + static void M_DrawLoadGameData(void) { INT32 i, savetodraw, x, y, hsep = 90; @@ -7634,6 +7661,9 @@ static void M_DrawLoadGameData(void) if (vid.width != BASEVIDWIDTH*vid.dupx) hsep = (hsep*vid.width)/(BASEVIDWIDTH*vid.dupx); + if (needpatchrecache) + M_CacheLoadGameData(); + for (i = -2; i <= 2; i++) { savetodraw = (saveSlotSelected + i + numsaves)%numsaves; @@ -8110,13 +8140,7 @@ static void M_ReadSaveStrings(void) M_ReadSavegameInfo(i); } - savselp[0] = W_CachePatchName("SAVEBACK", PU_PATCH); - savselp[1] = W_CachePatchName("SAVENONE", PU_PATCH); - savselp[2] = W_CachePatchName("ULTIMATE", PU_PATCH); - - savselp[3] = W_CachePatchName("GAMEDONE", PU_PATCH); - savselp[4] = W_CachePatchName("BLACXLVL", PU_PATCH); - savselp[5] = W_CachePatchName("BLANKLVL", PU_PATCH); + M_CacheLoadGameData(); } // From eca5be52b28613319173241b04b22191736fa561 Mon Sep 17 00:00:00 2001 From: Jaime Passos Date: Thu, 26 Dec 2019 23:52:42 -0300 Subject: [PATCH 46/79] And the sound test --- src/m_menu.c | 39 ++++++++++++++++++++++++--------------- 1 file changed, 24 insertions(+), 15 deletions(-) diff --git a/src/m_menu.c b/src/m_menu.c index 9fbcd55d7..e2451de6a 100644 --- a/src/m_menu.c +++ b/src/m_menu.c @@ -7023,11 +7023,29 @@ static tic_t st_time = 0; static patch_t* st_radio[9]; static patch_t* st_launchpad[4]; +static void M_CacheSoundTest(void) +{ + UINT8 i; + char buf[8]; + + STRBUFCPY(buf, "M_RADIOn"); + for (i = 0; i < 9; i++) + { + buf[7] = (char)('0'+i); + st_radio[i] = W_CachePatchName(buf, PU_PATCH); + } + + STRBUFCPY(buf, "M_LPADn"); + for (i = 0; i < 4; i++) + { + buf[6] = (char)('0'+i); + st_launchpad[i] = W_CachePatchName(buf, PU_PATCH); + } +} + static void M_SoundTest(INT32 choice) { INT32 ul = skyRoomMenuTranslations[choice-1]; - UINT8 i; - char buf[8]; soundtestpage = (UINT8)(unlockables[ul].variable); if (!soundtestpage) @@ -7039,19 +7057,7 @@ static void M_SoundTest(INT32 choice) return; } - STRBUFCPY(buf, "M_RADIOn"); - for (i = 0; i < 9; i++) - { - buf[7] = (char)('0'+i); - st_radio[i] = W_CachePatchName(buf, PU_STATIC); - } - - STRBUFCPY(buf, "M_LPADn"); - for (i = 0; i < 4; i++) - { - buf[6] = (char)('0'+i); - st_launchpad[i] = W_CachePatchName(buf, PU_STATIC); - } + M_CacheSoundTest(); curplaying = NULL; st_time = 0; @@ -7070,6 +7076,9 @@ static void M_DrawSoundTest(void) fixed_t hscale = FRACUNIT/2, vscale = FRACUNIT/2, bounce = 0; UINT8 frame[4] = {0, 0, -1, SKINCOLOR_RUBY}; + if (needpatchrecache) + M_CacheSoundTest(); + // let's handle the ticker first. ideally we'd tick this somewhere else, BUT... if (curplaying) { From 96609e45aeaf7baf05c6ad5bab665cd3f66a0ec9 Mon Sep 17 00:00:00 2001 From: Jaime Passos Date: Fri, 27 Dec 2019 00:02:30 -0300 Subject: [PATCH 47/79] OpenGL funny --- src/hardware/hw_cache.c | 4 ---- src/r_main.c | 4 +--- 2 files changed, 1 insertion(+), 7 deletions(-) diff --git a/src/hardware/hw_cache.c b/src/hardware/hw_cache.c index 6f375bdab..c47833187 100644 --- a/src/hardware/hw_cache.c +++ b/src/hardware/hw_cache.c @@ -888,10 +888,6 @@ GLTexture_t *HWR_GetTexture(INT32 tex) I_Error("HWR_GetTexture: tex >= numtextures\n"); #endif - // Lactozilla: Renderer switching - if (needpatchrecache && (!gr_textures)) - HWR_LoadTextures(gr_numtextures); - // Every texture in memory, stored in the // hardware renderer's bit depth format. Wow! grtex = &gr_textures[tex]; diff --git a/src/r_main.c b/src/r_main.c index 713480397..38777a521 100644 --- a/src/r_main.c +++ b/src/r_main.c @@ -1162,11 +1162,9 @@ void R_InitHardwareMode(void) { HWR_AddSessionCommands(); HWR_Switch(); + HWR_LoadTextures(numtextures); if (gamestate == GS_LEVEL || (gamestate == GS_TITLESCREEN && titlemapinaction)) - { HWR_SetupLevel(); - HWR_LoadTextures(numtextures); - } } #endif From 5ea43aa023aaf35c0ba39e483823f59f03a501dc Mon Sep 17 00:00:00 2001 From: Jaime Passos Date: Fri, 27 Dec 2019 00:37:40 -0300 Subject: [PATCH 48/79] Fix sprite rotation crashes. --- src/r_defs.h | 2 -- src/r_patch.c | 14 ++++++++++++++ src/r_patch.h | 1 + src/r_things.c | 5 +---- src/screen.c | 1 + src/z_zone.c | 10 ++++++++++ src/z_zone.h | 1 + 7 files changed, 28 insertions(+), 6 deletions(-) diff --git a/src/r_defs.h b/src/r_defs.h index 9e32777df..964956503 100644 --- a/src/r_defs.h +++ b/src/r_defs.h @@ -740,9 +740,7 @@ typedef struct { patch_t *patch[8][ROTANGLES]; boolean cached[8]; -#ifdef HWRENDER aatree_t *hardware_patch[8]; -#endif } rotsprite_t; #endif diff --git a/src/r_patch.c b/src/r_patch.c index d4bfa9cbd..ec394e731 100644 --- a/src/r_patch.c +++ b/src/r_patch.c @@ -1374,4 +1374,18 @@ void R_FreeSkinRotSprite(size_t skinnum) skinsprites++; } } + +// +// R_FreeAllRotSprite +// +// Free ALL sprite rotation data from memory. +// +void R_FreeAllRotSprite(void) +{ + INT32 i; + for (i = 0; i < numsprites; i++) + R_FreeSingleRotSprite(&sprites[i]); + for (i = 0; i < numskins; ++i) + R_FreeSkinRotSprite(i); +} #endif diff --git a/src/r_patch.h b/src/r_patch.h index 8a8ab5602..53d306b88 100644 --- a/src/r_patch.h +++ b/src/r_patch.h @@ -69,6 +69,7 @@ void R_ParseSPRTINFOLump(UINT16 wadNum, UINT16 lumpNum); void R_CacheRotSprite(spritenum_t sprnum, UINT8 frame, spriteinfo_t *sprinfo, spriteframe_t *sprframe, INT32 rot, UINT8 flip); void R_FreeSingleRotSprite(spritedef_t *spritedef); void R_FreeSkinRotSprite(size_t skinnum); +void R_FreeAllRotSprite(void); extern fixed_t cosang2rad[ROTANGLES]; extern fixed_t sinang2rad[ROTANGLES]; #endif diff --git a/src/r_things.c b/src/r_things.c index aa2a73515..bbe62d88a 100644 --- a/src/r_things.c +++ b/src/r_things.c @@ -125,10 +125,7 @@ static void R_InstallSpriteLump(UINT16 wad, // graphics patch sprtemp[frame].rotsprite.cached[r] = false; for (ang = 0; ang < ROTANGLES; ang++) sprtemp[frame].rotsprite.patch[r][ang] = NULL; -#ifdef HWRENDER - if (rendermode == render_opengl) - sprtemp[frame].rotsprite.hardware_patch[r] = M_AATreeAlloc(AATREE_ZUSER); -#endif // HWRENDER + sprtemp[frame].rotsprite.hardware_patch[r] = M_AATreeAlloc(AATREE_ZUSER); } #endif diff --git a/src/screen.c b/src/screen.c index 94b6c2454..16ba13087 100644 --- a/src/screen.c +++ b/src/screen.c @@ -200,6 +200,7 @@ void SCR_SetMode(void) // Lactozilla: Renderer switching if (setrenderneeded) { + Z_PreparePatchFlush(); needpatchflush = true; needpatchrecache = true; VID_CheckRenderer(); diff --git a/src/z_zone.c b/src/z_zone.c index e0c56ced6..5a0ff638b 100644 --- a/src/z_zone.c +++ b/src/z_zone.c @@ -27,6 +27,7 @@ #include "doomdef.h" #include "doomstat.h" +#include "r_patch.h" #include "i_system.h" // I_GetFreeMem #include "i_video.h" // rendermode #include "z_zone.h" @@ -517,6 +518,15 @@ void Z_FlushCachedPatches(void) Z_FreeTag(PU_HWRPATCHINFO_UNLOCKED); } +// happens before a renderer switch +void Z_PreparePatchFlush(void) +{ + CONS_Debug(DBG_RENDER, "Z_PreparePatchFlush()...\n"); +#ifdef ROTSPRITE + R_FreeAllRotSprite(); +#endif +} + // starting value of nextcleanup #define CLEANUPCOUNT 2000 diff --git a/src/z_zone.h b/src/z_zone.h index d70e9285b..9e5f74343 100644 --- a/src/z_zone.h +++ b/src/z_zone.h @@ -147,5 +147,6 @@ char *Z_StrDup(const char *in); extern boolean needpatchflush; extern boolean needpatchrecache; void Z_FlushCachedPatches(void); +void Z_PreparePatchFlush(void); #endif From c394ad056c9756c7f8fc96e5a248188c183fa6d4 Mon Sep 17 00:00:00 2001 From: Alam Ed Arias Date: Fri, 27 Dec 2019 13:20:58 -0500 Subject: [PATCH 49/79] use size_t to count the sprites --- src/r_patch.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/r_patch.c b/src/r_patch.c index ec394e731..18dfe523a 100644 --- a/src/r_patch.c +++ b/src/r_patch.c @@ -1383,8 +1383,9 @@ void R_FreeSkinRotSprite(size_t skinnum) void R_FreeAllRotSprite(void) { INT32 i; - for (i = 0; i < numsprites; i++) - R_FreeSingleRotSprite(&sprites[i]); + size_t s; + for (s = 0; s < numsprites; s++) + R_FreeSingleRotSprite(&sprites[s]); for (i = 0; i < numskins; ++i) R_FreeSkinRotSprite(i); } From f997866b4d3f9d2f4c6177e708529657359520d2 Mon Sep 17 00:00:00 2001 From: Jaime Passos Date: Sat, 28 Dec 2019 22:57:37 -0300 Subject: [PATCH 50/79] Fix broken dynlight list because of a SPR_NON2 that doesn't exist --- src/hardware/hw_light.c | 1 - 1 file changed, 1 deletion(-) diff --git a/src/hardware/hw_light.c b/src/hardware/hw_light.c index 4df71d145..8545a88b3 100644 --- a/src/hardware/hw_light.c +++ b/src/hardware/hw_light.c @@ -374,7 +374,6 @@ light_t *t_lspr[NUMSPRITES] = &lspr[NOLIGHT], // SPR_ADST &lspr[NOLIGHT], // SPR_MCRT &lspr[NOLIGHT], // SPR_MCSP - &lspr[NOLIGHT], // SPR_NON2 &lspr[NOLIGHT], // SPR_SALD &lspr[NOLIGHT], // SPR_TRAE &lspr[NOLIGHT], // SPR_TRAI From 19aafbfd0b9bde40809ca91195d4636899504708 Mon Sep 17 00:00:00 2001 From: James R Date: Sun, 29 Dec 2019 02:14:02 -0800 Subject: [PATCH 51/79] Split map code checking from Command_Map_f --- src/d_netcmd.c | 45 +---------------------------------------- src/g_game.c | 54 ++++++++++++++++++++++++++++++++++++++++++++++++++ src/g_game.h | 3 +++ 3 files changed, 58 insertions(+), 44 deletions(-) diff --git a/src/d_netcmd.c b/src/d_netcmd.c index 262d0d1bc..80359db54 100644 --- a/src/d_netcmd.c +++ b/src/d_netcmd.c @@ -1802,18 +1802,15 @@ static void Command_Map_f(void) boolean newresetplayers; boolean mustmodifygame; - boolean usemapcode = false; INT32 newmapnum; char * mapname; - size_t mapnamelen; char *realmapname = NULL; INT32 newgametype = gametype; INT32 d; - char *p; if (client && !IsPlayerAdmin(consoleplayer)) { @@ -1873,43 +1870,8 @@ static void Command_Map_f(void) } mapname = ConcatCommandArgv(1, first_option); - mapnamelen = strlen(mapname); - if (mapnamelen == 2)/* maybe two digit code */ - { - if (( newmapnum = M_MapNumber(mapname[0], mapname[1]) )) - usemapcode = true; - } - else if (mapnamelen == 5 && strnicmp(mapname, "MAP", 3) == 0) - { - if (( newmapnum = M_MapNumber(mapname[3], mapname[4]) ) == 0) - { - CONS_Alert(CONS_ERROR, M_GetText("Invalid map code '%s'.\n"), mapname); - Z_Free(mapname); - return; - } - usemapcode = true; - } - - if (!usemapcode) - { - /* Now detect map number in base 10, which no one asked for. */ - newmapnum = strtol(mapname, &p, 10); - if (*p == '\0')/* we got it */ - { - if (newmapnum < 1 || newmapnum > NUMMAPS) - { - CONS_Alert(CONS_ERROR, M_GetText("Invalid map number %d.\n"), newmapnum); - Z_Free(mapname); - return; - } - usemapcode = true; - } - else - { - newmapnum = G_FindMap(mapname, &realmapname, NULL, NULL); - } - } + newmapnum = G_FindMapByNameOrCode(mapname, &realmapname); if (newmapnum == 0) { @@ -1918,11 +1880,6 @@ static void Command_Map_f(void) return; } - if (usemapcode) - { - realmapname = G_BuildMapTitle(newmapnum); - } - if (mustmodifygame && option_force) { G_SetGameModified(false); diff --git a/src/g_game.c b/src/g_game.c index e4caa3a36..e1a90eb71 100644 --- a/src/g_game.c +++ b/src/g_game.c @@ -4536,6 +4536,60 @@ void G_FreeMapSearch(mapsearchfreq_t *freq, INT32 freqc) Z_Free(freq); } +INT32 G_FindMapByNameOrCode(const char *mapname, char **realmapnamep) +{ + boolean usemapcode = false; + + INT32 newmapnum; + + size_t mapnamelen; + + char *p; + + mapnamelen = strlen(mapname); + + if (mapnamelen == 2)/* maybe two digit code */ + { + if (( newmapnum = M_MapNumber(mapname[0], mapname[1]) )) + usemapcode = true; + } + else if (mapnamelen == 5 && strnicmp(mapname, "MAP", 3) == 0) + { + if (( newmapnum = M_MapNumber(mapname[3], mapname[4]) ) == 0) + { + CONS_Alert(CONS_ERROR, M_GetText("Invalid map code '%s'.\n"), mapname); + return 0; + } + usemapcode = true; + } + + if (!usemapcode) + { + /* Now detect map number in base 10, which no one asked for. */ + newmapnum = strtol(mapname, &p, 10); + if (*p == '\0')/* we got it */ + { + if (newmapnum < 1 || newmapnum > NUMMAPS) + { + CONS_Alert(CONS_ERROR, M_GetText("Invalid map number %d.\n"), newmapnum); + return 0; + } + usemapcode = true; + } + else + { + newmapnum = G_FindMap(mapname, realmapnamep, NULL, NULL); + } + } + + if (usemapcode) + { + (*realmapnamep) = G_BuildMapTitle(newmapnum); + } + + return newmapnum; +} + // // DEMO RECORDING // diff --git a/src/g_game.h b/src/g_game.h index c19faebe4..596555071 100644 --- a/src/g_game.h +++ b/src/g_game.h @@ -130,6 +130,9 @@ INT32 G_FindMap(const char *query, char **foundmapnamep, mapsearchfreq_t **freqp, INT32 *freqc); void G_FreeMapSearch(mapsearchfreq_t *freq, INT32 freqc); +/* Match map name by search + 2 digit map code or map number. */ +INT32 G_FindMapByNameOrCode(const char *query, char **foundmapnamep); + // XMOD spawning mapthing_t *G_FindCTFStart(INT32 playernum); mapthing_t *G_FindMatchStart(INT32 playernum); From 2ffff56b391235257c65eb23e539926c4da6ac62 Mon Sep 17 00:00:00 2001 From: James R Date: Sun, 29 Dec 2019 02:15:48 -0800 Subject: [PATCH 52/79] Who cares? --- src/g_game.c | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/src/g_game.c b/src/g_game.c index e1a90eb71..0adedf3dc 100644 --- a/src/g_game.c +++ b/src/g_game.c @@ -4555,12 +4555,8 @@ INT32 G_FindMapByNameOrCode(const char *mapname, char **realmapnamep) } else if (mapnamelen == 5 && strnicmp(mapname, "MAP", 3) == 0) { - if (( newmapnum = M_MapNumber(mapname[3], mapname[4]) ) == 0) - { - CONS_Alert(CONS_ERROR, M_GetText("Invalid map code '%s'.\n"), mapname); - return 0; - } - usemapcode = true; + if (( newmapnum = M_MapNumber(mapname[3], mapname[4]) )) + usemapcode = true; } if (!usemapcode) From 0a014755b98fb909aed4a12feba00744bc2af225 Mon Sep 17 00:00:00 2001 From: James R Date: Sun, 29 Dec 2019 02:16:37 -0800 Subject: [PATCH 53/79] I'm still an idiot --- src/g_game.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/g_game.c b/src/g_game.c index 0adedf3dc..e5bbf9d5d 100644 --- a/src/g_game.c +++ b/src/g_game.c @@ -4580,7 +4580,8 @@ INT32 G_FindMapByNameOrCode(const char *mapname, char **realmapnamep) if (usemapcode) { - (*realmapnamep) = G_BuildMapTitle(newmapnum); + if (realmapnamep) + (*realmapnamep) = G_BuildMapTitle(newmapnum); } return newmapnum; From 404f3c13e4ed1d9e1a375bba1c2ae59b4f694e0e Mon Sep 17 00:00:00 2001 From: James R Date: Sun, 29 Dec 2019 02:31:14 -0800 Subject: [PATCH 54/79] If we move the -warp code down, map searching can be used --- src/d_main.c | 34 ++++++++++++++-------------------- 1 file changed, 14 insertions(+), 20 deletions(-) diff --git a/src/d_main.c b/src/d_main.c index c4b0d7117..c83c4ccc8 100644 --- a/src/d_main.c +++ b/src/d_main.c @@ -1118,26 +1118,6 @@ void D_SRB2Main(void) if (M_CheckParm("-server") || dedicated) netgame = server = true; - if (M_CheckParm("-warp") && M_IsNextParm()) - { - const char *word = M_GetNextParm(); - char ch; // use this with sscanf to catch non-digits with - if (fastncmp(word, "MAP", 3)) // MAPxx name - pstartmap = M_MapNumber(word[3], word[4]); - else if (sscanf(word, "%d%c", &pstartmap, &ch) != 1) // a plain number - I_Error("Cannot warp to map %s (invalid map name)\n", word); - // Don't check if lump exists just yet because the wads haven't been loaded! - // Just do a basic range check here. - if (pstartmap < 1 || pstartmap > NUMMAPS) - I_Error("Cannot warp to map %d (out of range)\n", pstartmap); - else - { - if (!M_CheckParm("-server")) - G_SetGameModified(true); - autostart = true; - } - } - CONS_Printf("Z_Init(): Init zone memory allocation daemon. \n"); Z_Init(); @@ -1194,6 +1174,20 @@ void D_SRB2Main(void) mainwadstally = packetsizetally; // technically not accurate atm, remember to port the two-stage -file process from kart in 2.2.x + if (M_CheckParm("-warp") && M_IsNextParm()) + { + const char *word = M_GetNextParm(); + pstartmap = G_FindMapByNameOrCode(word, 0); + if (! pstartmap) + I_Error("Cannot find a map remotely named '%s'\n", word); + else + { + if (!M_CheckParm("-server")) + G_SetGameModified(true); + autostart = true; + } + } + cht_Init(); //---------------------------------------------------- READY SCREEN From 566b4a1626399b1c1621bf8b4ab1f8426c789c36 Mon Sep 17 00:00:00 2001 From: James R Date: Sun, 29 Dec 2019 02:44:27 -0800 Subject: [PATCH 55/79] Don't let us warp to a map that doesn't exist (really!) Okay so 6464df9876e472d1210aabce4237d02af38377e1, I WAS mistaken! Except that's not how you check for a map's existence, at least not how the old map command did it. --- src/g_game.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/g_game.c b/src/g_game.c index e5bbf9d5d..95aa1ae00 100644 --- a/src/g_game.c +++ b/src/g_game.c @@ -4580,6 +4580,10 @@ INT32 G_FindMapByNameOrCode(const char *mapname, char **realmapnamep) if (usemapcode) { + /* we can't check mapheaderinfo for this hahahaha */ + if (W_CheckNumForName(G_BuildMapName(newmapnum)) == LUMPERROR) + return 0; + if (realmapnamep) (*realmapnamep) = G_BuildMapTitle(newmapnum); } From 2f4c270a7bd322e7c67f8d2cf64f9022dce2e879 Mon Sep 17 00:00:00 2001 From: Jaime Passos Date: Sun, 29 Dec 2019 19:43:38 -0300 Subject: [PATCH 56/79] Update r_segs.c --- src/r_segs.c | 3 --- 1 file changed, 3 deletions(-) diff --git a/src/r_segs.c b/src/r_segs.c index 665176f85..dd7d5e991 100644 --- a/src/r_segs.c +++ b/src/r_segs.c @@ -45,9 +45,6 @@ static vertex_t segleft, segright; static fixed_t ceilingfrontslide, floorfrontslide, ceilingbackslide, floorbackslide; #endif -// for R_CalculateSegDistance -#define SOFTWARE_USE_FLOATS - // // regular wall // From 569453ee93d26fa3840915ac0307c2ba3d1a02c6 Mon Sep 17 00:00:00 2001 From: James R Date: Sun, 29 Dec 2019 18:37:22 -0800 Subject: [PATCH 57/79] Warn when going to OpenGL from the menu --- src/d_netcmd.c | 1 + src/m_menu.c | 43 ++++++++++++++++++++++++++++++++++++++++++- src/screen.c | 3 ++- src/screen.h | 4 ++++ 4 files changed, 49 insertions(+), 2 deletions(-) diff --git a/src/d_netcmd.c b/src/d_netcmd.c index f619f666a..28843c0d7 100644 --- a/src/d_netcmd.c +++ b/src/d_netcmd.c @@ -842,6 +842,7 @@ void D_RegisterClientCommands(void) CV_RegisterVar(&cv_fullscreen); CV_RegisterVar(&cv_renderview); CV_RegisterVar(&cv_renderer); + CV_RegisterVar(&cv_newrenderer); CV_RegisterVar(&cv_scr_depth); CV_RegisterVar(&cv_scr_width); CV_RegisterVar(&cv_scr_height); diff --git a/src/m_menu.c b/src/m_menu.c index e2451de6a..cbc65f86f 100644 --- a/src/m_menu.c +++ b/src/m_menu.c @@ -389,6 +389,7 @@ static void M_ResetCvars(void); // Consvar onchange functions static void Newgametype_OnChange(void); +static void Newrenderer_OnChange(void); static void Dummymares_OnChange(void); // ========================================================================== @@ -413,6 +414,9 @@ CV_PossibleValue_t gametype_cons_t[NUMGAMETYPES+1]; consvar_t cv_newgametype = {"newgametype", "Co-op", CV_HIDEN|CV_CALL, gametype_cons_t, Newgametype_OnChange, 0, NULL, NULL, 0, 0, NULL}; +consvar_t cv_newrenderer = {"newrenderer", "Software", CV_HIDEN|CV_CALL, cv_renderer_t, Newrenderer_OnChange, 0, NULL, NULL, 0, 0, NULL}; +static int newrenderer_set = 1;/* Software doesn't need confirmation! */ + static CV_PossibleValue_t serversort_cons_t[] = { {0,"Ping"}, {1,"Modified State"}, @@ -1210,7 +1214,7 @@ static menuitem_t OP_VideoOptionsMenu[] = {IT_STRING|IT_CVAR, NULL, "Fullscreen", &cv_fullscreen, 11}, #endif {IT_STRING | IT_CVAR, NULL, "Vertical Sync", &cv_vidwait, 16}, - {IT_STRING | IT_CVAR, NULL, "Renderer", &cv_renderer, 21}, + {IT_STRING | IT_CVAR, NULL, "Renderer", &cv_newrenderer, 21}, {IT_HEADER, NULL, "Color Profile", NULL, 30}, {IT_STRING | IT_CVAR | IT_CV_SLIDER, NULL, "Brightness (F11)", &cv_globalgamma,36}, @@ -2223,6 +2227,43 @@ static void Newgametype_OnChange(void) } } +static void Newrenderer_AREYOUSURE(INT32 c) +{ + int n; + switch (c) + { + case 'y': + case KEY_ENTER: + n = cv_newrenderer.value; + newrenderer_set |= n; + CV_SetValue(&cv_renderer, n); + break; + default: + CV_StealthSetValue(&cv_newrenderer, cv_renderer.value); + } +} + +static void Newrenderer_OnChange(void) +{ + /* Well this works for now because there's only two options. */ + int n; + n = cv_newrenderer.value; + if (( newrenderer_set & n )) + CV_SetValue(&cv_renderer, n); + else + { + M_StartMessage( + "The OpenGL renderer is incomplete.\n" + "Some visuals may fail to appear, or\n" + "appear incorrectly.\n" + "Do you still want to switch to it?\n" + "\n" + "(Press 'y' or 'n')", + Newrenderer_AREYOUSURE, MM_YESNO + ); + } +} + void Screenshot_option_Onchange(void) { OP_ScreenshotOptionsMenu[op_screenshot_folder].status = diff --git a/src/screen.c b/src/screen.c index 16ba13087..f9d81f8af 100644 --- a/src/screen.c +++ b/src/screen.c @@ -64,7 +64,7 @@ consvar_t cv_scr_depth = {"scr_depth", "16 bits", CV_SAVE, scr_depth_cons_t, NUL consvar_t cv_renderview = {"renderview", "On", 0, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL}; static void SCR_ActuallyChangeRenderer(void); -static CV_PossibleValue_t cv_renderer_t[] = {{1, "Software"}, {2, "OpenGL"}, {0, NULL}}; +CV_PossibleValue_t cv_renderer_t[] = {{1, "Software"}, {2, "OpenGL"}, {0, NULL}}; consvar_t cv_renderer = {"renderer", "Software", CV_SAVE|CV_NOLUA|CV_CALL, cv_renderer_t, SCR_ChangeRenderer, 0, NULL, NULL, 0, 0, NULL}; static void SCR_ChangeFullscreen(void); @@ -477,6 +477,7 @@ void SCR_ChangeRendererCVars(INT32 mode) CV_StealthSetValue(&cv_renderer, 1); else if (mode == render_opengl) CV_StealthSetValue(&cv_renderer, 2); + CV_StealthSetValue(&cv_newrenderer, cv_renderer.value); } boolean SCR_IsAspectCorrect(INT32 width, INT32 height) diff --git a/src/screen.h b/src/screen.h index 884ee303b..d47cdff9a 100644 --- a/src/screen.h +++ b/src/screen.h @@ -170,6 +170,7 @@ extern boolean R_SSE2; // ---------------- // screen variables // ---------------- + extern viddef_t vid; extern INT32 setmodeneeded; // mode number to set if needed, or 0 @@ -180,7 +181,10 @@ extern UINT8 setrenderneeded; extern INT32 scr_bpp; extern UINT8 *scr_borderpatch; // patch used to fill the view borders +extern CV_PossibleValue_t cv_renderer_t[]; + extern consvar_t cv_scr_width, cv_scr_height, cv_scr_depth, cv_renderview, cv_renderer, cv_fullscreen; +extern consvar_t cv_newrenderer; // wait for page flipping to end or not extern consvar_t cv_vidwait; From 7886a4bbee28c61dc6f877f5c6af8474a1453ac2 Mon Sep 17 00:00:00 2001 From: James R Date: Sun, 29 Dec 2019 18:37:44 -0800 Subject: [PATCH 58/79] Don't warn if we start in OpenGL --- src/m_menu.c | 1 + 1 file changed, 1 insertion(+) diff --git a/src/m_menu.c b/src/m_menu.c index cbc65f86f..ef49f2a95 100644 --- a/src/m_menu.c +++ b/src/m_menu.c @@ -2248,6 +2248,7 @@ static void Newrenderer_OnChange(void) /* Well this works for now because there's only two options. */ int n; n = cv_newrenderer.value; + newrenderer_set |= cv_renderer.value; if (( newrenderer_set & n )) CV_SetValue(&cv_renderer, n); else From a04834d1aa1dc361b2fbed81ad7cd81e005a1bdb Mon Sep 17 00:00:00 2001 From: Jaime Passos Date: Mon, 30 Dec 2019 12:02:09 -0300 Subject: [PATCH 59/79] Fix alignment in R_ThickStepping --- src/r_segs.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/r_segs.c b/src/r_segs.c index dd7d5e991..e873d1a1b 100644 --- a/src/r_segs.c +++ b/src/r_segs.c @@ -3287,8 +3287,8 @@ static void R_ThickStepping(drawseg_t *ds, INT32 range) // using INT64 to avoid 32bit overflow rw.top_frac = (INT64)centeryfrac - (((INT64)rw.left_top * ds->scale1) >> FRACBITS); rw.bottom_frac = (INT64)centeryfrac - (((INT64)rw.left_bottom * ds->scale1) >> FRACBITS); - rw.top_step = (INT64)centeryfrac - (((INT64)right_top * ds->scale2) >> FRACBITS); - rw.bottom_step = (INT64)centeryfrac - (((INT64)right_bottom * ds->scale2) >> FRACBITS); + rw.top_step = (INT64)centeryfrac - (((INT64)right_top * ds->scale2) >> FRACBITS); + rw.bottom_step = (INT64)centeryfrac - (((INT64)right_bottom * ds->scale2) >> FRACBITS); rw.top_step = (rw.top_step-rw.top_frac)/(range); rw.bottom_step = (rw.bottom_step-rw.bottom_frac)/(range); From ab410652aeeb79b0ff6fc655db938bd406006ad4 Mon Sep 17 00:00:00 2001 From: James R Date: Mon, 30 Dec 2019 18:44:13 -0800 Subject: [PATCH 60/79] Fix unclosed quotes leaving the escape character in --- src/command.c | 29 +++++++++++++++++++++++------ 1 file changed, 23 insertions(+), 6 deletions(-) diff --git a/src/command.c b/src/command.c index 40efa1eee..efa56a825 100644 --- a/src/command.c +++ b/src/command.c @@ -2169,8 +2169,13 @@ skipwhite: com_token[len] = 0; return data; } - com_token[len] = c; - len++; + if (c == '\033') + data += 2; + else + { + com_token[len] = c; + len++; + } } } @@ -2186,10 +2191,22 @@ skipwhite: // parse a regular word do { - com_token[len] = c; - data++; - len++; - c = *data; + if (c == '\033') + { + do + { + data += 2; + c = *data; + } + while (c == '\033') ; + } + else + { + com_token[len] = c; + data++; + len++; + c = *data; + } if (c == '{' || c == '}' || c == ')'|| c == '(' || c == '\'') break; } while (c > 32); From ff47f911dc8e4a53d81328670de557ff264f1b1f Mon Sep 17 00:00:00 2001 From: James R Date: Mon, 30 Dec 2019 18:46:38 -0800 Subject: [PATCH 61/79] Fix command not running if it was split by COM_BufAddText (Looks at 4865a190578b900b48571e74e0bd97bef88ea71b...) --- src/command.c | 19 ++++++++++--------- 1 file changed, 10 insertions(+), 9 deletions(-) diff --git a/src/command.c b/src/command.c index efa56a825..0a6b34fc8 100644 --- a/src/command.c +++ b/src/command.c @@ -427,20 +427,21 @@ static void COM_TokenizeString(char *ptext) com_argc = 0; com_args = NULL; - - if (ptext[0] == '\033') - { - com_flags = (unsigned)ptext[1]; - ptext += 2; - } - else - com_flags = 0; + com_flags = 0; while (com_argc < MAX_ARGS) { // Skip whitespace up to a newline. while (*ptext != '\0' && *ptext <= ' ' && *ptext != '\n') - ptext++; + { + if (ptext[0] == '\033') + { + com_flags = (unsigned)ptext[1]; + ptext += 2; + } + else + ptext++; + } // A newline means end of command in buffer, // thus end of this command's args too. From 4bf35971168a5fa2b5759dc0c3d05a3767f30f95 Mon Sep 17 00:00:00 2001 From: James R Date: Mon, 30 Dec 2019 19:19:17 -0800 Subject: [PATCH 62/79] Fix NOOPENMPT compiling --- src/s_sound.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/s_sound.c b/src/s_sound.c index a49499040..0235d8376 100644 --- a/src/s_sound.c +++ b/src/s_sound.c @@ -61,7 +61,9 @@ static void GameMIDIMusic_OnChange(void); static void GameSounds_OnChange(void); static void GameDigiMusic_OnChange(void); +#ifdef HAVE_OPENMPT static void ModFilter_OnChange(void); +#endif static lumpnum_t S_GetMusicLumpNum(const char *mname); From 782bf8d31ed486679011a1c4b57f823e3e53c5d2 Mon Sep 17 00:00:00 2001 From: James R Date: Mon, 30 Dec 2019 20:08:29 -0800 Subject: [PATCH 63/79] Fix NOMIXER compiling --- src/sdl/sdl_sound.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/sdl/sdl_sound.c b/src/sdl/sdl_sound.c index 33b366bf6..b8991293c 100644 --- a/src/sdl/sdl_sound.c +++ b/src/sdl/sdl_sound.c @@ -1432,6 +1432,8 @@ static void I_ResumeGME(void) boolean I_LoadSong(char *data, size_t len) { + (void)data; + (void)len; return false; } @@ -1493,6 +1495,7 @@ boolean I_FadeSongFromVolume(UINT8 target_volume, UINT8 source_volume, UINT32 ms (void)target_volume; (void)source_volume; (void)ms; + (void)callback; return false; } @@ -1500,6 +1503,7 @@ boolean I_FadeSong(UINT8 target_volume, UINT32 ms, void (*callback)(void)) { (void)target_volume; (void)ms; + (void)callback; return false; } From 36c5bb7b0d32cd14c7b6ddc17f64c62c65965eb9 Mon Sep 17 00:00:00 2001 From: James R Date: Mon, 30 Dec 2019 20:18:08 -0800 Subject: [PATCH 64/79] Fix NOHW compiling --- src/r_defs.h | 4 +++- src/r_things.c | 4 +++- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/src/r_defs.h b/src/r_defs.h index 964956503..2791ac8b0 100644 --- a/src/r_defs.h +++ b/src/r_defs.h @@ -740,9 +740,11 @@ typedef struct { patch_t *patch[8][ROTANGLES]; boolean cached[8]; +#ifdef HWRENDER aatree_t *hardware_patch[8]; +#endif/*HWRENDER*/ } rotsprite_t; -#endif +#endif/*ROTSPRITE*/ typedef enum { diff --git a/src/r_things.c b/src/r_things.c index bbe62d88a..a328da03a 100644 --- a/src/r_things.c +++ b/src/r_things.c @@ -125,9 +125,11 @@ static void R_InstallSpriteLump(UINT16 wad, // graphics patch sprtemp[frame].rotsprite.cached[r] = false; for (ang = 0; ang < ROTANGLES; ang++) sprtemp[frame].rotsprite.patch[r][ang] = NULL; +#ifdef HWRENDER sprtemp[frame].rotsprite.hardware_patch[r] = M_AATreeAlloc(AATREE_ZUSER); +#endif/*HWRENDER*/ } -#endif +#endif/*ROTSPRITE*/ if (rotation == 0) { From e8db39229c0afe967e571340362412853ee4749c Mon Sep 17 00:00:00 2001 From: James R Date: Mon, 30 Dec 2019 20:29:41 -0800 Subject: [PATCH 65/79] Don't let the user switch to OpenGL if NOHW --- src/screen.c | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/src/screen.c b/src/screen.c index f9d81f8af..6a60c53da 100644 --- a/src/screen.c +++ b/src/screen.c @@ -64,7 +64,13 @@ consvar_t cv_scr_depth = {"scr_depth", "16 bits", CV_SAVE, scr_depth_cons_t, NUL consvar_t cv_renderview = {"renderview", "On", 0, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL}; static void SCR_ActuallyChangeRenderer(void); -CV_PossibleValue_t cv_renderer_t[] = {{1, "Software"}, {2, "OpenGL"}, {0, NULL}}; +CV_PossibleValue_t cv_renderer_t[] = { + {1, "Software"}, +#ifdef HWRENDER + {2, "OpenGL"}, +#endif + {0, NULL} +}; consvar_t cv_renderer = {"renderer", "Software", CV_SAVE|CV_NOLUA|CV_CALL, cv_renderer_t, SCR_ChangeRenderer, 0, NULL, NULL, 0, 0, NULL}; static void SCR_ChangeFullscreen(void); @@ -454,9 +460,12 @@ void SCR_ChangeRenderer(void) if (con_startup) { target_renderer = cv_renderer.value; +#ifdef HWRENDER if (M_CheckParm("-opengl")) target_renderer = rendermode = render_opengl; - else if (M_CheckParm("-software")) + else +#endif + if (M_CheckParm("-software")) target_renderer = rendermode = render_soft; // set cv_renderer back SCR_ChangeRendererCVars(rendermode); From 38492073fa9a240fe90606c3e79fd42a6a14bff5 Mon Sep 17 00:00:00 2001 From: James R Date: Mon, 30 Dec 2019 21:40:13 -0800 Subject: [PATCH 66/79] IT_PAIR for when you want to define both sides of a menu item --- src/m_menu.c | 21 ++++++++++++++++----- src/m_menu.h | 5 +++-- 2 files changed, 19 insertions(+), 7 deletions(-) diff --git a/src/m_menu.c b/src/m_menu.c index ae00c8062..c6206a572 100644 --- a/src/m_menu.c +++ b/src/m_menu.c @@ -2973,7 +2973,7 @@ static void M_NextOpt(void) itemOn = 0; else itemOn++; - } while (oldItemOn != itemOn && (currentMenu->menuitems[itemOn].status & IT_TYPE) == IT_SPACE); + } while (oldItemOn != itemOn && ( (currentMenu->menuitems[itemOn].status & IT_TYPE) & IT_SPACE )); } static void M_PrevOpt(void) @@ -2985,7 +2985,7 @@ static void M_PrevOpt(void) itemOn = currentMenu->numitems - 1; else itemOn--; - } while (oldItemOn != itemOn && (currentMenu->menuitems[itemOn].status & IT_TYPE) == IT_SPACE); + } while (oldItemOn != itemOn && ( (currentMenu->menuitems[itemOn].status & IT_TYPE) & IT_SPACE )); } // lock out further input in a tic when important buttons are pressed @@ -3619,11 +3619,11 @@ void M_SetupNextMenu(menu_t *menudef) // the curent item can be disabled, // this code go up until an enabled item found - if ((currentMenu->menuitems[itemOn].status & IT_TYPE) == IT_SPACE) + if (( (currentMenu->menuitems[itemOn].status & IT_TYPE) & IT_SPACE )) { for (i = 0; i < currentMenu->numitems; i++) { - if ((currentMenu->menuitems[i].status & IT_TYPE) != IT_SPACE) + if (!( (currentMenu->menuitems[i].status & IT_TYPE) & IT_SPACE )) { itemOn = i; break; @@ -4306,7 +4306,18 @@ static void M_DrawGenericScrollMenu(void) } break; case IT_TRANSTEXT: - V_DrawString(x, y, V_TRANSLUCENT, currentMenu->menuitems[i].text); + switch (currentMenu->menuitems[i].status & IT_TYPE) + { + case IT_PAIR: + V_DrawString(x, y, + V_TRANSLUCENT, currentMenu->menuitems[i].patch); + V_DrawRightAlignedString(BASEVIDWIDTH - x, y, + V_TRANSLUCENT, currentMenu->menuitems[i].text); + break; + default: + V_DrawString(x, y, + V_TRANSLUCENT, currentMenu->menuitems[i].text); + } break; case IT_QUESTIONMARKS: V_DrawString(x, y, V_TRANSLUCENT|V_OLDSPACING, M_CreateSecretMenuOption(currentMenu->menuitems[i].text)); diff --git a/src/m_menu.h b/src/m_menu.h index ce9b422dc..00c258fe8 100644 --- a/src/m_menu.h +++ b/src/m_menu.h @@ -222,13 +222,14 @@ boolean M_CanShowLevelInList(INT32 mapnum, INT32 gt); // flags for items in the menu // menu handle (what we do when key is pressed -#define IT_TYPE 14 // (2+4+8) +#define IT_TYPE 15 // (1+2+4+8) #define IT_CALL 0 // call the function +#define IT_SPACE 1 // no handling #define IT_ARROWS 2 // call function with 0 for left arrow and 1 for right arrow in param #define IT_KEYHANDLER 4 // call with the key in param #define IT_SUBMENU 6 // go to sub menu #define IT_CVAR 8 // handle as a cvar -#define IT_SPACE 10 // no handling +#define IT_PAIR 11 // no handling, define both sides of text #define IT_MSGHANDLER 12 // same as key but with event and sometime can handle y/n key (special for message) #define IT_DISPLAY (48+64+128) // 16+32+64+128 From 7af2533d237831ec0ffac516d2b4c358f564d73c Mon Sep 17 00:00:00 2001 From: James R Date: Mon, 30 Dec 2019 21:45:19 -0800 Subject: [PATCH 67/79] Make the menu option for renderer switching transparent under NOHW --- src/d_netcmd.c | 2 ++ src/m_menu.c | 10 ++++++++++ src/screen.c | 2 ++ src/screen.h | 2 ++ 4 files changed, 16 insertions(+) diff --git a/src/d_netcmd.c b/src/d_netcmd.c index 28843c0d7..316182453 100644 --- a/src/d_netcmd.c +++ b/src/d_netcmd.c @@ -842,7 +842,9 @@ void D_RegisterClientCommands(void) CV_RegisterVar(&cv_fullscreen); CV_RegisterVar(&cv_renderview); CV_RegisterVar(&cv_renderer); +#ifdef HWRENDER CV_RegisterVar(&cv_newrenderer); +#endif CV_RegisterVar(&cv_scr_depth); CV_RegisterVar(&cv_scr_width); CV_RegisterVar(&cv_scr_height); diff --git a/src/m_menu.c b/src/m_menu.c index c6206a572..439d651c0 100644 --- a/src/m_menu.c +++ b/src/m_menu.c @@ -389,7 +389,9 @@ static void M_ResetCvars(void); // Consvar onchange functions static void Newgametype_OnChange(void); +#ifdef HWRENDER static void Newrenderer_OnChange(void); +#endif static void Dummymares_OnChange(void); // ========================================================================== @@ -414,8 +416,10 @@ CV_PossibleValue_t gametype_cons_t[NUMGAMETYPES+1]; consvar_t cv_newgametype = {"newgametype", "Co-op", CV_HIDEN|CV_CALL, gametype_cons_t, Newgametype_OnChange, 0, NULL, NULL, 0, 0, NULL}; +#ifdef HWRENDER consvar_t cv_newrenderer = {"newrenderer", "Software", CV_HIDEN|CV_CALL, cv_renderer_t, Newrenderer_OnChange, 0, NULL, NULL, 0, 0, NULL}; static int newrenderer_set = 1;/* Software doesn't need confirmation! */ +#endif static CV_PossibleValue_t serversort_cons_t[] = { {0,"Ping"}, @@ -1216,7 +1220,11 @@ static menuitem_t OP_VideoOptionsMenu[] = {IT_STRING|IT_CVAR, NULL, "Fullscreen", &cv_fullscreen, 11}, #endif {IT_STRING | IT_CVAR, NULL, "Vertical Sync", &cv_vidwait, 16}, +#ifdef HWRENDER {IT_STRING | IT_CVAR, NULL, "Renderer", &cv_newrenderer, 21}, +#else + {IT_TRANSTEXT | IT_PAIR, "Renderer", "Software", &cv_renderer, 21}, +#endif {IT_HEADER, NULL, "Color Profile", NULL, 30}, {IT_STRING | IT_CVAR | IT_CV_SLIDER, NULL, "Brightness (F11)", &cv_globalgamma,36}, @@ -2229,6 +2237,7 @@ static void Newgametype_OnChange(void) } } +#ifdef HWRENDER static void Newrenderer_AREYOUSURE(INT32 c) { int n; @@ -2266,6 +2275,7 @@ static void Newrenderer_OnChange(void) ); } } +#endif/*HWRENDER*/ void Screenshot_option_Onchange(void) { diff --git a/src/screen.c b/src/screen.c index 6a60c53da..5bb304c08 100644 --- a/src/screen.c +++ b/src/screen.c @@ -486,7 +486,9 @@ void SCR_ChangeRendererCVars(INT32 mode) CV_StealthSetValue(&cv_renderer, 1); else if (mode == render_opengl) CV_StealthSetValue(&cv_renderer, 2); +#ifdef HWRENDER CV_StealthSetValue(&cv_newrenderer, cv_renderer.value); +#endif } boolean SCR_IsAspectCorrect(INT32 width, INT32 height) diff --git a/src/screen.h b/src/screen.h index d47cdff9a..02b336f75 100644 --- a/src/screen.h +++ b/src/screen.h @@ -184,7 +184,9 @@ extern UINT8 *scr_borderpatch; // patch used to fill the view borders extern CV_PossibleValue_t cv_renderer_t[]; extern consvar_t cv_scr_width, cv_scr_height, cv_scr_depth, cv_renderview, cv_renderer, cv_fullscreen; +#ifdef HWRENDER extern consvar_t cv_newrenderer; +#endif // wait for page flipping to end or not extern consvar_t cv_vidwait; From b41cd59e5198415d71b03b794b73b1c9ea9ffcc7 Mon Sep 17 00:00:00 2001 From: Jaime Passos Date: Tue, 31 Dec 2019 23:40:17 +0000 Subject: [PATCH 68/79] Revert "Merge branch 'software-clownery' into 'master'" This reverts merge request !578 --- src/p_setup.c | 5 +- src/r_bsp.c | 2 +- src/r_defs.h | 3 +- src/r_main.c | 6 +- src/r_segs.c | 4765 +++++++++++++++++++++++-------------------------- src/r_state.h | 39 +- 6 files changed, 2261 insertions(+), 2559 deletions(-) diff --git a/src/p_setup.c b/src/p_setup.c index c29cc907e..42a6438a0 100644 --- a/src/p_setup.c +++ b/src/p_setup.c @@ -416,7 +416,9 @@ fixed_t P_SegLength(seg_t *seg) return FixedHypot(dx, dy)<<1; } +#ifdef HWRENDER /** Computes the length of a seg as a float. + * This is needed for OpenGL. * * \param seg Seg to compute length for. * \return Length as a float. @@ -431,6 +433,7 @@ static inline float P_SegLengthFloat(seg_t *seg) return (float)hypot(dx, dy); } +#endif /** Loads the SEGS resource from a level. * @@ -457,10 +460,10 @@ static void P_LoadRawSegs(UINT8 *data, size_t i) li->v2 = &vertexes[SHORT(ml->v2)]; li->length = P_SegLength(li); - li->flength = P_SegLengthFloat(li); #ifdef HWRENDER if (rendermode == render_opengl) { + li->flength = P_SegLengthFloat(li); //Hurdler: 04/12/2000: for now, only used in hardware mode li->lightmaps = NULL; // list of static lightmap for this seg } diff --git a/src/r_bsp.c b/src/r_bsp.c index b6dbfd76a..51d9bd3fd 100644 --- a/src/r_bsp.c +++ b/src/r_bsp.c @@ -410,7 +410,7 @@ static void R_AddLine(seg_t *line) return; // Global angle needed by segcalc. - rw.angle1 = angle1; + rw_angle1 = angle1; angle1 -= viewangle; angle2 -= viewangle; diff --git a/src/r_defs.h b/src/r_defs.h index cfc55ef18..2791ac8b0 100644 --- a/src/r_defs.h +++ b/src/r_defs.h @@ -582,12 +582,11 @@ typedef struct seg_s sector_t *backsector; fixed_t length; // precalculated seg length - float flength; // ditto but float - #ifdef HWRENDER // new pointers so that AdjustSegs doesn't mess with v1/v2 void *pv1; // polyvertex_t void *pv2; // polyvertex_t + float flength; // length of the seg, used by hardware renderer lightmap_t *lightmaps; // for static lightmap #endif diff --git a/src/r_main.c b/src/r_main.c index 8ef47d21d..a5f4bc118 100644 --- a/src/r_main.c +++ b/src/r_main.c @@ -366,7 +366,7 @@ angle_t R_PointToAngleEx(INT32 x2, INT32 y2, INT32 x1, INT32 y1) // R_ScaleFromGlobalAngle // Returns the texture mapping scale for the current line (horizontal span) // at the given angle. -// rw.distance must be calculated first. +// rw_distance must be calculated first. // // killough 5/2/98: reformatted, cleaned up // @@ -374,8 +374,8 @@ angle_t R_PointToAngleEx(INT32 x2, INT32 y2, INT32 x1, INT32 y1) fixed_t R_ScaleFromGlobalAngle(angle_t visangle) { angle_t anglea = ANGLE_90 + (visangle-viewangle); - angle_t angleb = ANGLE_90 + (visangle-rw.normalangle); - fixed_t den = FixedMul(rw.distance, FINESINE(anglea>>ANGLETOFINESHIFT)); + angle_t angleb = ANGLE_90 + (visangle-rw_normalangle); + fixed_t den = FixedMul(rw_distance, FINESINE(anglea>>ANGLETOFINESHIFT)); // proff 11/06/98: Changed for high-res fixed_t num = FixedMul(projectiony, FINESINE(angleb>>ANGLETOFINESHIFT)); diff --git a/src/r_segs.c b/src/r_segs.c index 750b32522..2c8aadec8 100644 --- a/src/r_segs.c +++ b/src/r_segs.c @@ -37,21 +37,25 @@ static boolean maskedtexture; static INT32 toptexture, bottomtexture, midtexture; static INT32 numthicksides, numbackffloors; -static boolean bothceilingssky; -static boolean bothfloorssky; - -#ifdef ESLOPE -static vertex_t segleft, segright; -static fixed_t ceilingfrontslide, floorfrontslide, ceilingbackslide, floorbackslide; -#endif +angle_t rw_normalangle; +// angle to line origin +angle_t rw_angle1; +fixed_t rw_distance; // // regular wall // -renderwall_t rw; +static INT32 rw_x, rw_stopx; +static angle_t rw_centerangle; +static fixed_t rw_offset; +static fixed_t rw_offset2; // for splats +static fixed_t rw_scale, rw_scalestep; +static fixed_t rw_midtexturemid, rw_toptexturemid, rw_bottomtexturemid; static INT32 worldtop, worldbottom, worldhigh, worldlow; #ifdef ESLOPE static INT32 worldtopslope, worldbottomslope, worldhighslope, worldlowslope; // worldtop/bottom at end of slope +static fixed_t rw_toptextureslide, rw_midtextureslide, rw_bottomtextureslide; // Defines how to adjust Y offsets along the wall for slopes +static fixed_t rw_midtextureback, rw_midtexturebackslide; // Values for masked midtexture height calculation #endif static fixed_t pixhigh, pixlow, pixhighstep, pixlowstep; static fixed_t topfrac, topstep; @@ -63,6 +67,1242 @@ static INT16 *maskedtexturecol; static fixed_t *maskedtextureheight = NULL; #endif +// ========================================================================== +// R_Splats Wall Splats Drawer +// ========================================================================== + +#ifdef WALLSPLATS +static INT16 last_ceilingclip[MAXVIDWIDTH]; +static INT16 last_floorclip[MAXVIDWIDTH]; + +static void R_DrawSplatColumn(column_t *column) +{ + INT32 topscreen, bottomscreen; + fixed_t basetexturemid; + INT32 topdelta, prevdelta = -1; + + basetexturemid = dc_texturemid; + + for (; column->topdelta != 0xff ;) + { + // calculate unclipped screen coordinates for post + topdelta = column->topdelta; + if (topdelta <= prevdelta) + topdelta += prevdelta; + prevdelta = topdelta; + topscreen = sprtopscreen + spryscale*topdelta; + bottomscreen = topscreen + spryscale*column->length; + + dc_yl = (topscreen+FRACUNIT-1)>>FRACBITS; + dc_yh = (bottomscreen-1)>>FRACBITS; + + if (dc_yh >= last_floorclip[dc_x]) + dc_yh = last_floorclip[dc_x] - 1; + if (dc_yl <= last_ceilingclip[dc_x]) + dc_yl = last_ceilingclip[dc_x] + 1; + if (dc_yl <= dc_yh && dl_yh < vid.height && yh > 0) + { + dc_source = (UINT8 *)column + 3; + dc_texturemid = basetexturemid - (topdelta<length + 4); + } + + dc_texturemid = basetexturemid; +} + +static void R_DrawWallSplats(void) +{ + wallsplat_t *splat; + seg_t *seg; + angle_t angle, angle1, angle2; + INT32 x1, x2; + size_t pindex; + column_t *col; + patch_t *patch; + fixed_t texturecolumn; + + splat = (wallsplat_t *)linedef->splats; + + I_Assert(splat != NULL); + + seg = ds_p->curline; + + // draw all splats from the line that touches the range of the seg + for (; splat; splat = splat->next) + { + angle1 = R_PointToAngle(splat->v1.x, splat->v1.y); + angle2 = R_PointToAngle(splat->v2.x, splat->v2.y); + angle1 = (angle1 - viewangle + ANGLE_90)>>ANGLETOFINESHIFT; + angle2 = (angle2 - viewangle + ANGLE_90)>>ANGLETOFINESHIFT; + // out of the viewangletox lut + /// \todo clip it to the screen + if (angle1 > FINEANGLES/2 || angle2 > FINEANGLES/2) + continue; + x1 = viewangletox[angle1]; + x2 = viewangletox[angle2]; + + if (x1 >= x2) + continue; // does not cross a pixel + + // splat is not in this seg range + if (x2 < ds_p->x1 || x1 > ds_p->x2) + continue; + + if (x1 < ds_p->x1) + x1 = ds_p->x1; + if (x2 > ds_p->x2) + x2 = ds_p->x2; + if (x2 <= x1) + continue; + + // calculate incremental stepping values for texture edges + rw_scalestep = ds_p->scalestep; + spryscale = ds_p->scale1 + (x1 - ds_p->x1)*rw_scalestep; + mfloorclip = floorclip; + mceilingclip = ceilingclip; + + patch = W_CachePatchNum(splat->patch, PU_PATCH); + + dc_texturemid = splat->top + (SHORT(patch->height)<<(FRACBITS-1)) - viewz; + if (splat->yoffset) + dc_texturemid += *splat->yoffset; + + sprtopscreen = centeryfrac - FixedMul(dc_texturemid, spryscale); + + // set drawing mode + switch (splat->flags & SPLATDRAWMODE_MASK) + { + case SPLATDRAWMODE_OPAQUE: + colfunc = colfuncs[BASEDRAWFUNC]; + break; + case SPLATDRAWMODE_TRANS: + if (!cv_translucency.value) + colfunc = colfuncs[BASEDRAWFUNC]; + else + { + dc_transmap = transtables + ((tr_trans50 - 1)<>LIGHTSCALESHIFT; + if (pindex >= MAXLIGHTSCALE) + pindex = MAXLIGHTSCALE - 1; + dc_colormap = walllights[pindex]; + + if (frontsector->extra_colormap) + dc_colormap = frontsector->extra_colormap->colormap + (dc_colormap - colormaps); + + sprtopscreen = centeryfrac - FixedMul(dc_texturemid, spryscale); + dc_iscale = 0xffffffffu / (unsigned)spryscale; + + // find column of patch, from perspective + angle = (rw_centerangle + xtoviewangle[dc_x])>>ANGLETOFINESHIFT; + texturecolumn = rw_offset2 - splat->offset + - FixedMul(FINETANGENT(angle), rw_distance); + + // FIXME! + texturecolumn >>= FRACBITS; + if (texturecolumn < 0 || texturecolumn >= SHORT(patch->width)) + continue; + + // draw the texture + col = (column_t *)((UINT8 *)patch + LONG(patch->columnofs[texturecolumn])); + R_DrawSplatColumn(col); + } + } // next splat + + colfunc = colfuncs[BASEDRAWFUNC]; +} + +#endif //WALLSPLATS + +// ========================================================================== +// R_RenderMaskedSegRange +// ========================================================================== + +// If we have a multi-patch texture on a 2sided wall (rare) then we draw +// it using R_DrawColumn, else we draw it using R_DrawMaskedColumn, this +// way we don't have to store extra post_t info with each column for +// multi-patch textures. They are not normally needed as multi-patch +// textures don't have holes in it. At least not for now. +static INT32 column2s_length; // column->length : for multi-patch on 2sided wall = texture->height + +static void R_Render2sidedMultiPatchColumn(column_t *column) +{ + INT32 topscreen, bottomscreen; + + topscreen = sprtopscreen; // + spryscale*column->topdelta; topdelta is 0 for the wall + bottomscreen = topscreen + spryscale * column2s_length; + + dc_yl = (sprtopscreen+FRACUNIT-1)>>FRACBITS; + dc_yh = (bottomscreen-1)>>FRACBITS; + + if (windowtop != INT32_MAX && windowbottom != INT32_MAX) + { + dc_yl = ((windowtop + FRACUNIT)>>FRACBITS); + dc_yh = (windowbottom - 1)>>FRACBITS; + } + + if (dc_yh >= mfloorclip[dc_x]) + dc_yh = mfloorclip[dc_x] - 1; + if (dc_yl <= mceilingclip[dc_x]) + dc_yl = mceilingclip[dc_x] + 1; + + if (dc_yl >= vid.height || dc_yh < 0) + return; + + if (dc_yl <= dc_yh && dc_yh < vid.height && dc_yh > 0) + { + dc_source = (UINT8 *)column + 3; + + if (colfunc == colfuncs[BASEDRAWFUNC]) + (colfuncs[COLDRAWFUNC_TWOSMULTIPATCH])(); + else if (colfunc == colfuncs[COLDRAWFUNC_FUZZY]) + (colfuncs[COLDRAWFUNC_TWOSMULTIPATCHTRANS])(); + else + colfunc(); + } +} + +// quick wrapper for R_DrawFlippedMaskedColumn so it can be set as a colfunc_2s value +// uses column2s_length for texture->height as above +static void R_DrawFlippedMaskedSegColumn(column_t *column) +{ + R_DrawFlippedMaskedColumn(column, column2s_length); +} + +void R_RenderMaskedSegRange(drawseg_t *ds, INT32 x1, INT32 x2) +{ + size_t pindex; + column_t *col; + INT32 lightnum, texnum, i; + fixed_t height, realbot; + lightlist_t *light; + r_lightlist_t *rlight; + void (*colfunc_2s)(column_t *); + line_t *ldef; + sector_t *front, *back; + INT32 times, repeats; + INT64 overflow_test; +#ifdef ESLOPE + INT32 range; +#endif + + // Calculate light table. + // Use different light tables + // for horizontal / vertical / diagonal. Diagonal? + // OPTIMIZE: get rid of LIGHTSEGSHIFT globally + curline = ds->curline; + frontsector = curline->frontsector; + backsector = curline->backsector; + texnum = R_GetTextureNum(curline->sidedef->midtexture); + windowbottom = windowtop = sprbotscreen = INT32_MAX; + + // hack translucent linedef types (900-909 for transtables 1-9) + ldef = curline->linedef; + switch (ldef->special) + { + case 900: + case 901: + case 902: + case 903: + case 904: + case 905: + case 906: + case 907: + case 908: + dc_transmap = transtables + ((ldef->special-900)<ceilingheight; + windowbottom = frontsector->floorheight; + break; + default: + colfunc = colfuncs[BASEDRAWFUNC]; + break; + } + + if (curline->polyseg && curline->polyseg->translucency > 0) + { + if (curline->polyseg->translucency >= NUMTRANSMAPS) + return; + + dc_transmap = transtables + ((curline->polyseg->translucency-1)<x2-ds->x1, 1); +#endif + rw_scalestep = ds->scalestep; + spryscale = ds->scale1 + (x1 - ds->x1)*rw_scalestep; + + // Texture must be cached before setting colfunc_2s, + // otherwise texture[texnum]->holes may be false when it shouldn't be + R_CheckTextureCache(texnum); + // handle case where multipatch texture is drawn on a 2sided wall, multi-patch textures + // are not stored per-column with post info in SRB2 + if (textures[texnum]->holes) + { + if (textures[texnum]->flip & 2) // vertically flipped? + { + colfunc_2s = R_DrawFlippedMaskedSegColumn; + column2s_length = textures[texnum]->height; + } + else + colfunc_2s = R_DrawMaskedColumn; // render the usual 2sided single-patch packed texture + } + else + { + colfunc_2s = R_Render2sidedMultiPatchColumn; // render multipatch with no holes (no post_t info) + column2s_length = textures[texnum]->height; + } + + // Setup lighting based on the presence/lack-of 3D floors. + dc_numlights = 0; + if (frontsector->numlights) + { + dc_numlights = frontsector->numlights; + if (dc_numlights >= dc_maxlights) + { + dc_maxlights = dc_numlights; + dc_lightlist = Z_Realloc(dc_lightlist, sizeof (*dc_lightlist) * dc_maxlights, PU_STATIC, NULL); + } + + for (i = 0; i < dc_numlights; i++) + { +#ifdef ESLOPE + fixed_t leftheight, rightheight; +#endif + light = &frontsector->lightlist[i]; + rlight = &dc_lightlist[i]; +#ifdef ESLOPE + if (light->slope) { + leftheight = P_GetZAt(light->slope, ds->leftpos.x, ds->leftpos.y); + rightheight = P_GetZAt(light->slope, ds->rightpos.x, ds->rightpos.y); + } else + leftheight = rightheight = light->height; + + leftheight -= viewz; + rightheight -= viewz; + + rlight->height = (centeryfrac) - FixedMul(leftheight, ds->scale1); + rlight->heightstep = (centeryfrac) - FixedMul(rightheight, ds->scale2); + rlight->heightstep = (rlight->heightstep-rlight->height)/(range); + //if (x1 > ds->x1) + //rlight->height -= (x1 - ds->x1)*rlight->heightstep; +#else + rlight->height = (centeryfrac) - FixedMul((light->height - viewz), spryscale); + rlight->heightstep = -FixedMul(rw_scalestep, (light->height - viewz)); +#endif + rlight->startheight = rlight->height; // keep starting value here to reset for each repeat + rlight->lightlevel = *light->lightlevel; + rlight->extra_colormap = *light->extra_colormap; + rlight->flags = light->flags; + + if (rlight->flags & FF_FOG || (rlight->extra_colormap && rlight->extra_colormap->fog)) + lightnum = (rlight->lightlevel >> LIGHTSEGSHIFT); + else if (colfunc == colfuncs[COLDRAWFUNC_FUZZY]) + lightnum = LIGHTLEVELS - 1; + else + lightnum = (rlight->lightlevel >> LIGHTSEGSHIFT); + + if (rlight->extra_colormap && rlight->extra_colormap->fog) + ; + else if (curline->v1->y == curline->v2->y) + lightnum--; + else if (curline->v1->x == curline->v2->x) + lightnum++; + + rlight->lightnum = lightnum; + } + } + else + { + if (colfunc == colfuncs[COLDRAWFUNC_FUZZY]) + { + if (frontsector->extra_colormap && frontsector->extra_colormap->fog) + lightnum = (frontsector->lightlevel >> LIGHTSEGSHIFT); + else + lightnum = LIGHTLEVELS - 1; + } + else + lightnum = (frontsector->lightlevel >> LIGHTSEGSHIFT); + + if (colfunc == colfuncs[COLDRAWFUNC_FOG] + || (frontsector->extra_colormap && frontsector->extra_colormap->fog)) + ; + else if (curline->v1->y == curline->v2->y) + lightnum--; + else if (curline->v1->x == curline->v2->x) + lightnum++; + + if (lightnum < 0) + walllights = scalelight[0]; + else if (lightnum >= LIGHTLEVELS) + walllights = scalelight[LIGHTLEVELS - 1]; + else + walllights = scalelight[lightnum]; + } + + maskedtexturecol = ds->maskedtexturecol; + + mfloorclip = ds->sprbottomclip; + mceilingclip = ds->sprtopclip; + + if (frontsector->heightsec != -1) + front = §ors[frontsector->heightsec]; + else + front = frontsector; + + if (backsector->heightsec != -1) + back = §ors[backsector->heightsec]; + else + back = backsector; + + if (ds->curline->sidedef->repeatcnt) + repeats = 1 + ds->curline->sidedef->repeatcnt; + else if (ldef->flags & ML_EFFECT5) + { + fixed_t high, low; + + if (front->ceilingheight > back->ceilingheight) + high = back->ceilingheight; + else + high = front->ceilingheight; + + if (front->floorheight > back->floorheight) + low = front->floorheight; + else + low = back->floorheight; + + repeats = (high - low)/textureheight[texnum]; + if ((high-low)%textureheight[texnum]) + repeats++; // tile an extra time to fill the gap -- Monster Iestyn + } + else + repeats = 1; + + for (times = 0; times < repeats; times++) + { + if (times > 0) + { + rw_scalestep = ds->scalestep; + spryscale = ds->scale1 + (x1 - ds->x1)*rw_scalestep; + if (dc_numlights) + { // reset all lights to their starting heights + for (i = 0; i < dc_numlights; i++) + { + rlight = &dc_lightlist[i]; + rlight->height = rlight->startheight; + } + } + } + +#ifndef ESLOPE + if (curline->linedef->flags & ML_DONTPEGBOTTOM) + { + dc_texturemid = front->floorheight > back->floorheight + ? front->floorheight : back->floorheight; + dc_texturemid = dc_texturemid + textureheight[texnum] - viewz; + } + else + { + dc_texturemid = front->ceilingheight < back->ceilingheight + ? front->ceilingheight : back->ceilingheight; + dc_texturemid = dc_texturemid - viewz; + } + dc_texturemid += curline->sidedef->rowoffset; + + if (curline->linedef->flags & ML_DONTPEGBOTTOM) + dc_texturemid += (textureheight[texnum])*times; + else + dc_texturemid -= (textureheight[texnum])*times; +#endif + + dc_texheight = textureheight[texnum]>>FRACBITS; + + // draw the columns + for (dc_x = x1; dc_x <= x2; dc_x++) + { +#ifdef ESLOPE + dc_texturemid = ds->maskedtextureheight[dc_x]; + + if (!!(curline->linedef->flags & ML_DONTPEGBOTTOM) ^ !!(curline->linedef->flags & ML_EFFECT3)) + dc_texturemid += (textureheight[texnum])*times + textureheight[texnum]; + else + dc_texturemid -= (textureheight[texnum])*times; +#endif + // calculate lighting + if (maskedtexturecol[dc_x] != INT16_MAX) + { + // Check for overflows first + overflow_test = (INT64)centeryfrac - (((INT64)dc_texturemid*spryscale)>>FRACBITS); + if (overflow_test < 0) overflow_test = -overflow_test; + if ((UINT64)overflow_test&0xFFFFFFFF80000000ULL) + { + // Eh, no, go away, don't waste our time + if (dc_numlights) + { + for (i = 0; i < dc_numlights; i++) + { + rlight = &dc_lightlist[i]; + rlight->height += rlight->heightstep; + } + } + spryscale += rw_scalestep; + continue; + } + + if (dc_numlights) + { + lighttable_t **xwalllights; + + sprbotscreen = INT32_MAX; + sprtopscreen = windowtop = (centeryfrac - FixedMul(dc_texturemid, spryscale)); + + realbot = windowbottom = FixedMul(textureheight[texnum], spryscale) + sprtopscreen; + dc_iscale = 0xffffffffu / (unsigned)spryscale; + + // draw the texture + col = (column_t *)((UINT8 *)R_GetColumn(texnum, maskedtexturecol[dc_x]) - 3); + + for (i = 0; i < dc_numlights; i++) + { + rlight = &dc_lightlist[i]; + + if ((rlight->flags & FF_NOSHADE)) + continue; + + if (rlight->lightnum < 0) + xwalllights = scalelight[0]; + else if (rlight->lightnum >= LIGHTLEVELS) + xwalllights = scalelight[LIGHTLEVELS-1]; + else + xwalllights = scalelight[rlight->lightnum]; + + pindex = FixedMul(spryscale, FixedDiv(640, vid.width))>>LIGHTSCALESHIFT; + + if (pindex >= MAXLIGHTSCALE) + pindex = MAXLIGHTSCALE - 1; + + if (rlight->extra_colormap) + rlight->rcolormap = rlight->extra_colormap->colormap + (xwalllights[pindex] - colormaps); + else + rlight->rcolormap = xwalllights[pindex]; + + height = rlight->height; + rlight->height += rlight->heightstep; + + if (height <= windowtop) + { + dc_colormap = rlight->rcolormap; + continue; + } + + windowbottom = height; + if (windowbottom >= realbot) + { + windowbottom = realbot; + colfunc_2s(col); + for (i++; i < dc_numlights; i++) + { + rlight = &dc_lightlist[i]; + rlight->height += rlight->heightstep; + } + + continue; + } + colfunc_2s(col); + windowtop = windowbottom + 1; + dc_colormap = rlight->rcolormap; + } + windowbottom = realbot; + if (windowtop < windowbottom) + colfunc_2s(col); + + spryscale += rw_scalestep; + continue; + } + + // calculate lighting + pindex = FixedMul(spryscale, FixedDiv(640, vid.width))>>LIGHTSCALESHIFT; + + if (pindex >= MAXLIGHTSCALE) + pindex = MAXLIGHTSCALE - 1; + + dc_colormap = walllights[pindex]; + + if (frontsector->extra_colormap) + dc_colormap = frontsector->extra_colormap->colormap + (dc_colormap - colormaps); + + sprtopscreen = centeryfrac - FixedMul(dc_texturemid, spryscale); + dc_iscale = 0xffffffffu / (unsigned)spryscale; + + // draw the texture + col = (column_t *)((UINT8 *)R_GetColumn(texnum, maskedtexturecol[dc_x]) - 3); + +//#ifdef POLYOBJECTS_PLANES +#if 0 // Disabling this allows inside edges to render below the planes, for until the clipping is fixed to work right when POs are near the camera. -Red + if (curline->dontrenderme && curline->polyseg && (curline->polyseg->flags & POF_RENDERPLANES)) + { + fixed_t my_topscreen; + fixed_t my_bottomscreen; + fixed_t my_yl, my_yh; + + my_topscreen = sprtopscreen + spryscale*col->topdelta; + my_bottomscreen = sprbotscreen == INT32_MAX ? my_topscreen + spryscale*col->length + : sprbotscreen + spryscale*col->length; + + my_yl = (my_topscreen+FRACUNIT-1)>>FRACBITS; + my_yh = (my_bottomscreen-1)>>FRACBITS; + // CONS_Debug(DBG_RENDER, "my_topscreen: %d\nmy_bottomscreen: %d\nmy_yl: %d\nmy_yh: %d\n", my_topscreen, my_bottomscreen, my_yl, my_yh); + + if (numffloors) + { + INT32 top = my_yl; + INT32 bottom = my_yh; + + for (i = 0; i < numffloors; i++) + { + if (!ffloor[i].polyobj || ffloor[i].polyobj != curline->polyseg) + continue; + + if (ffloor[i].height < viewz) + { + INT32 top_w = ffloor[i].plane->top[dc_x]; + + // CONS_Debug(DBG_RENDER, "Leveltime : %d\n", leveltime); + // CONS_Debug(DBG_RENDER, "Top is %d, top_w is %d\n", top, top_w); + if (top_w < top) + { + ffloor[i].plane->top[dc_x] = (INT16)top; + ffloor[i].plane->picnum = 0; + } + // CONS_Debug(DBG_RENDER, "top_w is now %d\n", ffloor[i].plane->top[dc_x]); + } + else if (ffloor[i].height > viewz) + { + INT32 bottom_w = ffloor[i].plane->bottom[dc_x]; + + if (bottom_w > bottom) + { + ffloor[i].plane->bottom[dc_x] = (INT16)bottom; + ffloor[i].plane->picnum = 0; + } + } + } + } + } + else +#endif + colfunc_2s(col); + } + spryscale += rw_scalestep; + } + } + colfunc = colfuncs[BASEDRAWFUNC]; +} + +// Loop through R_DrawMaskedColumn calls +static void R_DrawRepeatMaskedColumn(column_t *col) +{ + while (sprtopscreen < sprbotscreen) { + R_DrawMaskedColumn(col); + if ((INT64)sprtopscreen + dc_texheight*spryscale > (INT64)INT32_MAX) // prevent overflow + sprtopscreen = INT32_MAX; + else + sprtopscreen += dc_texheight*spryscale; + } +} + +static void R_DrawRepeatFlippedMaskedColumn(column_t *col) +{ + do { + R_DrawFlippedMaskedColumn(col, column2s_length); + sprtopscreen += dc_texheight*spryscale; + } while (sprtopscreen < sprbotscreen); +} + +// +// R_RenderThickSideRange +// Renders all the thick sides in the given range. +void R_RenderThickSideRange(drawseg_t *ds, INT32 x1, INT32 x2, ffloor_t *pfloor) +{ + size_t pindex; + column_t * col; + INT32 lightnum; + INT32 texnum; + sector_t tempsec; + INT32 templight; + INT32 i, p; + fixed_t bottombounds = viewheight << FRACBITS; + fixed_t topbounds = (con_clipviewtop - 1) << FRACBITS; + fixed_t offsetvalue = 0; + lightlist_t *light; + r_lightlist_t *rlight; +#ifdef ESLOPE + INT32 range; +#endif +#ifndef ESLOPE + fixed_t lheight; +#endif + line_t *newline = NULL; +#ifdef ESLOPE + // Render FOF sides kinda like normal sides, with the frac and step and everything + // NOTE: INT64 instead of fixed_t because overflow concerns + INT64 top_frac, top_step, bottom_frac, bottom_step; + // skew FOF walls with slopes? + boolean slopeskew = false; + fixed_t ffloortextureslide = 0; + INT32 oldx = -1; + fixed_t left_top, left_bottom; // needed here for slope skewing + pslope_t *skewslope = NULL; +#endif + + void (*colfunc_2s) (column_t *); + + // Calculate light table. + // Use different light tables + // for horizontal / vertical / diagonal. Diagonal? + // OPTIMIZE: get rid of LIGHTSEGSHIFT globally + + curline = ds->curline; + backsector = pfloor->target; + frontsector = curline->frontsector == pfloor->target ? curline->backsector : curline->frontsector; + texnum = R_GetTextureNum(sides[pfloor->master->sidenum[0]].midtexture); + + colfunc = colfuncs[BASEDRAWFUNC]; + + if (pfloor->master->flags & ML_TFERLINE) + { + size_t linenum = curline->linedef-backsector->lines[0]; + newline = pfloor->master->frontsector->lines[0] + linenum; + texnum = R_GetTextureNum(sides[newline->sidenum[0]].midtexture); + } + + if (pfloor->flags & FF_TRANSLUCENT) + { + boolean fuzzy = true; + + // Hacked up support for alpha value in software mode Tails 09-24-2002 + if (pfloor->alpha < 12) + return; // Don't even draw it + else if (pfloor->alpha < 38) + dc_transmap = transtables + ((tr_trans90-1)<alpha < 64) + dc_transmap = transtables + ((tr_trans80-1)<alpha < 89) + dc_transmap = transtables + ((tr_trans70-1)<alpha < 115) + dc_transmap = transtables + ((tr_trans60-1)<alpha < 140) + dc_transmap = transtables + ((tr_trans50-1)<alpha < 166) + dc_transmap = transtables + ((tr_trans40-1)<alpha < 192) + dc_transmap = transtables + ((tr_trans30-1)<alpha < 217) + dc_transmap = transtables + ((tr_trans20-1)<alpha < 243) + dc_transmap = transtables + ((tr_trans10-1)<flags & FF_FOG) + colfunc = colfuncs[COLDRAWFUNC_FOG]; + +#ifdef ESLOPE + range = max(ds->x2-ds->x1, 1); +#endif + //SoM: Moved these up here so they are available for my lightlist calculations + rw_scalestep = ds->scalestep; + spryscale = ds->scale1 + (x1 - ds->x1)*rw_scalestep; + + dc_numlights = 0; + if (frontsector->numlights) + { + dc_numlights = frontsector->numlights; + if (dc_numlights > dc_maxlights) + { + dc_maxlights = dc_numlights; + dc_lightlist = Z_Realloc(dc_lightlist, sizeof (*dc_lightlist) * dc_maxlights, PU_STATIC, NULL); + } + + for (i = p = 0; i < dc_numlights; i++) + { +#ifdef ESLOPE + fixed_t leftheight, rightheight; + fixed_t pfloorleft, pfloorright; + INT64 overflow_test; +#endif + light = &frontsector->lightlist[i]; + rlight = &dc_lightlist[p]; +#ifdef ESLOPE + +#define SLOPEPARAMS(slope, end1, end2, normalheight) \ + if (slope) { \ + end1 = P_GetZAt(slope, ds->leftpos.x, ds->leftpos.y); \ + end2 = P_GetZAt(slope, ds->rightpos.x, ds->rightpos.y); \ + } else \ + end1 = end2 = normalheight; + + SLOPEPARAMS(light->slope, leftheight, rightheight, light->height) + SLOPEPARAMS(*pfloor->b_slope, pfloorleft, pfloorright, *pfloor->bottomheight) + + if (leftheight < pfloorleft && rightheight < pfloorright) + continue; + + SLOPEPARAMS(*pfloor->t_slope, pfloorleft, pfloorright, *pfloor->topheight) + + if (leftheight > pfloorleft && rightheight > pfloorright && i+1 < dc_numlights) + { + lightlist_t *nextlight = &frontsector->lightlist[i+1]; + if ((nextlight->slope ? P_GetZAt(nextlight->slope, ds->leftpos.x, ds->leftpos.y) : nextlight->height) > pfloorleft + && (nextlight->slope ? P_GetZAt(nextlight->slope, ds->rightpos.x, ds->rightpos.y) : nextlight->height) > pfloorright) + continue; + } + + leftheight -= viewz; + rightheight -= viewz; + +#define CLAMPMAX INT32_MAX +#define CLAMPMIN (-INT32_MAX) // This is not INT32_MIN on purpose! INT32_MIN makes the drawers freak out. + // Monster Iestyn (25/03/18): do not skip these lights if they fail overflow test, just clamp them instead so they behave. + overflow_test = (INT64)centeryfrac - (((INT64)leftheight*ds->scale1)>>FRACBITS); + if (overflow_test > (INT64)CLAMPMAX) rlight->height = CLAMPMAX; + else if (overflow_test > (INT64)CLAMPMIN) rlight->height = (fixed_t)overflow_test; + else rlight->height = CLAMPMIN; + + overflow_test = (INT64)centeryfrac - (((INT64)rightheight*ds->scale2)>>FRACBITS); + if (overflow_test > (INT64)CLAMPMAX) rlight->heightstep = CLAMPMAX; + else if (overflow_test > (INT64)CLAMPMIN) rlight->heightstep = (fixed_t)overflow_test; + else rlight->heightstep = CLAMPMIN; + rlight->heightstep = (rlight->heightstep-rlight->height)/(range); +#else + if (light->height < *pfloor->bottomheight) + continue; + + if (light->height > *pfloor->topheight && i+1 < dc_numlights && frontsector->lightlist[i+1].height > *pfloor->topheight) + continue; + + lheight = light->height;// > *pfloor->topheight ? *pfloor->topheight + FRACUNIT : light->height; + rlight->heightstep = -FixedMul (rw_scalestep, (lheight - viewz)); + rlight->height = (centeryfrac) - FixedMul((lheight - viewz), spryscale); +#endif + rlight->flags = light->flags; + if (light->flags & FF_CUTLEVEL) + { +#ifdef ESLOPE + SLOPEPARAMS(*light->caster->b_slope, leftheight, rightheight, *light->caster->bottomheight) +#undef SLOPEPARAMS + leftheight -= viewz; + rightheight -= viewz; + + // Monster Iestyn (25/03/18): do not skip these lights if they fail overflow test, just clamp them instead so they behave. + overflow_test = (INT64)centeryfrac - (((INT64)leftheight*ds->scale1)>>FRACBITS); + if (overflow_test > (INT64)CLAMPMAX) rlight->botheight = CLAMPMAX; + else if (overflow_test > (INT64)CLAMPMIN) rlight->botheight = (fixed_t)overflow_test; + else rlight->botheight = CLAMPMIN; + + overflow_test = (INT64)centeryfrac - (((INT64)rightheight*ds->scale2)>>FRACBITS); + if (overflow_test > (INT64)CLAMPMAX) rlight->botheightstep = CLAMPMAX; + else if (overflow_test > (INT64)CLAMPMIN) rlight->botheightstep = (fixed_t)overflow_test; + else rlight->botheightstep = CLAMPMIN; + rlight->botheightstep = (rlight->botheightstep-rlight->botheight)/(range); +#else + lheight = *light->caster->bottomheight;// > *pfloor->topheight ? *pfloor->topheight + FRACUNIT : *light->caster->bottomheight; + rlight->botheightstep = -FixedMul (rw_scalestep, (lheight - viewz)); + rlight->botheight = (centeryfrac) - FixedMul((lheight - viewz), spryscale); +#endif + } + + rlight->lightlevel = *light->lightlevel; + rlight->extra_colormap = *light->extra_colormap; + + // Check if the current light effects the colormap/lightlevel + if (pfloor->flags & FF_FOG) + rlight->lightnum = (pfloor->master->frontsector->lightlevel >> LIGHTSEGSHIFT); + else + rlight->lightnum = (rlight->lightlevel >> LIGHTSEGSHIFT); + + if (pfloor->flags & FF_FOG || rlight->flags & FF_FOG || (rlight->extra_colormap && rlight->extra_colormap->fog)) + ; + else if (curline->v1->y == curline->v2->y) + rlight->lightnum--; + else if (curline->v1->x == curline->v2->x) + rlight->lightnum++; + + p++; + } + + dc_numlights = p; + } + else + { + // Get correct light level! + if ((frontsector->extra_colormap && frontsector->extra_colormap->fog)) + lightnum = (frontsector->lightlevel >> LIGHTSEGSHIFT); + else if (pfloor->flags & FF_FOG) + lightnum = (pfloor->master->frontsector->lightlevel >> LIGHTSEGSHIFT); + else if (colfunc == colfuncs[COLDRAWFUNC_FUZZY]) + lightnum = LIGHTLEVELS-1; + else + lightnum = R_FakeFlat(frontsector, &tempsec, &templight, &templight, false) + ->lightlevel >> LIGHTSEGSHIFT; + + if (pfloor->flags & FF_FOG || (frontsector->extra_colormap && frontsector->extra_colormap->fog)); + else if (curline->v1->y == curline->v2->y) + lightnum--; + else if (curline->v1->x == curline->v2->x) + lightnum++; + + if (lightnum < 0) + walllights = scalelight[0]; + else if (lightnum >= LIGHTLEVELS) + walllights = scalelight[LIGHTLEVELS-1]; + else + walllights = scalelight[lightnum]; + } + + maskedtexturecol = ds->thicksidecol; + + mfloorclip = ds->sprbottomclip; + mceilingclip = ds->sprtopclip; + dc_texheight = textureheight[texnum]>>FRACBITS; + +#ifdef ESLOPE + // calculate both left ends + if (*pfloor->t_slope) + left_top = P_GetZAt(*pfloor->t_slope, ds->leftpos.x, ds->leftpos.y) - viewz; + else + left_top = *pfloor->topheight - viewz; + + if (*pfloor->b_slope) + left_bottom = P_GetZAt(*pfloor->b_slope, ds->leftpos.x, ds->leftpos.y) - viewz; + else + left_bottom = *pfloor->bottomheight - viewz; + skewslope = *pfloor->t_slope; // skew using top slope by default + if (newline) + { + if (newline->flags & ML_DONTPEGTOP) + slopeskew = true; + } + else if (pfloor->master->flags & ML_DONTPEGTOP) + slopeskew = true; + + if (slopeskew) + dc_texturemid = left_top; + else +#endif + dc_texturemid = *pfloor->topheight - viewz; + + if (newline) + { + offsetvalue = sides[newline->sidenum[0]].rowoffset; + if (newline->flags & ML_DONTPEGBOTTOM) + { +#ifdef ESLOPE + skewslope = *pfloor->b_slope; // skew using bottom slope + if (slopeskew) + dc_texturemid = left_bottom; + else +#endif + offsetvalue -= *pfloor->topheight - *pfloor->bottomheight; + } + } + else + { + offsetvalue = sides[pfloor->master->sidenum[0]].rowoffset; + if (curline->linedef->flags & ML_DONTPEGBOTTOM) + { +#ifdef ESLOPE + skewslope = *pfloor->b_slope; // skew using bottom slope + if (slopeskew) + dc_texturemid = left_bottom; + else +#endif + offsetvalue -= *pfloor->topheight - *pfloor->bottomheight; + } + } + +#ifdef ESLOPE + if (slopeskew) + { + angle_t lineangle = R_PointToAngle2(curline->v1->x, curline->v1->y, curline->v2->x, curline->v2->y); + + if (skewslope) + ffloortextureslide = FixedMul(skewslope->zdelta, FINECOSINE((lineangle-skewslope->xydirection)>>ANGLETOFINESHIFT)); + } +#endif + + dc_texturemid += offsetvalue; + + // Texture must be cached before setting colfunc_2s, + // otherwise texture[texnum]->holes may be false when it shouldn't be + R_CheckTextureCache(texnum); + //faB: handle case where multipatch texture is drawn on a 2sided wall, multi-patch textures + // are not stored per-column with post info anymore in Doom Legacy + if (textures[texnum]->holes) + { + if (textures[texnum]->flip & 2) // vertically flipped? + { + colfunc_2s = R_DrawRepeatFlippedMaskedColumn; + column2s_length = textures[texnum]->height; + } + else + colfunc_2s = R_DrawRepeatMaskedColumn; // render the usual 2sided single-patch packed texture + } + else + { + colfunc_2s = R_Render2sidedMultiPatchColumn; //render multipatch with no holes (no post_t info) + column2s_length = textures[texnum]->height; + } + +#ifdef ESLOPE + // Set heights according to plane, or slope, whichever + { + fixed_t right_top, right_bottom; + + // calculate right ends now + if (*pfloor->t_slope) + right_top = P_GetZAt(*pfloor->t_slope, ds->rightpos.x, ds->rightpos.y) - viewz; + else + right_top = *pfloor->topheight - viewz; + + if (*pfloor->b_slope) + right_bottom = P_GetZAt(*pfloor->b_slope, ds->rightpos.x, ds->rightpos.y) - viewz; + else + right_bottom = *pfloor->bottomheight - viewz; + + // using INT64 to avoid 32bit overflow + top_frac = (INT64)centeryfrac - (((INT64)left_top * ds->scale1) >> FRACBITS); + bottom_frac = (INT64)centeryfrac - (((INT64)left_bottom * ds->scale1) >> FRACBITS); + top_step = (INT64)centeryfrac - (((INT64)right_top * ds->scale2) >> FRACBITS); + bottom_step = (INT64)centeryfrac - (((INT64)right_bottom * ds->scale2) >> FRACBITS); + + top_step = (top_step-top_frac)/(range); + bottom_step = (bottom_step-bottom_frac)/(range); + + top_frac += top_step * (x1 - ds->x1); + bottom_frac += bottom_step * (x1 - ds->x1); + } +#endif + + // draw the columns + for (dc_x = x1; dc_x <= x2; dc_x++) + { + if (maskedtexturecol[dc_x] != INT16_MAX) + { +#ifdef ESLOPE + if (ffloortextureslide) { // skew FOF walls + if (oldx != -1) + dc_texturemid += FixedMul(ffloortextureslide, (maskedtexturecol[oldx]-maskedtexturecol[dc_x])< (INT64)CLAMPMAX) sprtopscreen = windowtop = CLAMPMAX; + else if (top_frac > (INT64)CLAMPMIN) sprtopscreen = windowtop = (fixed_t)top_frac; + else sprtopscreen = windowtop = CLAMPMIN; + if (bottom_frac > (INT64)CLAMPMAX) sprbotscreen = windowbottom = CLAMPMAX; + else if (bottom_frac > (INT64)CLAMPMIN) sprbotscreen = windowbottom = (fixed_t)bottom_frac; + else sprbotscreen = windowbottom = CLAMPMIN; + + top_frac += top_step; + bottom_frac += bottom_step; +#else + sprtopscreen = windowtop = (centeryfrac - FixedMul((dc_texturemid - offsetvalue), spryscale)); + sprbotscreen = windowbottom = FixedMul(*pfloor->topheight - *pfloor->bottomheight, spryscale) + sprtopscreen; +#endif + + // SoM: If column is out of range, why bother with it?? + if (windowbottom < topbounds || windowtop > bottombounds) + { + if (dc_numlights) + { + for (i = 0; i < dc_numlights; i++) + { + rlight = &dc_lightlist[i]; + rlight->height += rlight->heightstep; + if (rlight->flags & FF_CUTLEVEL) + rlight->botheight += rlight->botheightstep; + } + } + spryscale += rw_scalestep; + continue; + } + + dc_iscale = 0xffffffffu / (unsigned)spryscale; + + // Get data for the column + col = (column_t *)((UINT8 *)R_GetColumn(texnum,maskedtexturecol[dc_x]) - 3); + + // SoM: New code does not rely on R_DrawColumnShadowed_8 which + // will (hopefully) put less strain on the stack. + if (dc_numlights) + { + lighttable_t **xwalllights; + fixed_t height; + fixed_t bheight = 0; + INT32 solid = 0; + INT32 lighteffect = 0; + + for (i = 0; i < dc_numlights; i++) + { + // Check if the current light effects the colormap/lightlevel + rlight = &dc_lightlist[i]; + lighteffect = !(dc_lightlist[i].flags & FF_NOSHADE); + if (lighteffect) + { + lightnum = rlight->lightnum; + + if (lightnum < 0) + xwalllights = scalelight[0]; + else if (lightnum >= LIGHTLEVELS) + xwalllights = scalelight[LIGHTLEVELS-1]; + else + xwalllights = scalelight[lightnum]; + + pindex = FixedMul(spryscale, FixedDiv(640, vid.width))>>LIGHTSCALESHIFT; + + if (pindex >= MAXLIGHTSCALE) + pindex = MAXLIGHTSCALE-1; + + if (pfloor->flags & FF_FOG) + { + if (pfloor->master->frontsector->extra_colormap) + rlight->rcolormap = pfloor->master->frontsector->extra_colormap->colormap + (xwalllights[pindex] - colormaps); + else + rlight->rcolormap = xwalllights[pindex]; + } + else + { + if (rlight->extra_colormap) + rlight->rcolormap = rlight->extra_colormap->colormap + (xwalllights[pindex] - colormaps); + else + rlight->rcolormap = xwalllights[pindex]; + } + } + + solid = 0; // don't carry over solid-cutting flag from the previous light + + // Check if the current light can cut the current 3D floor. + if (rlight->flags & FF_CUTSOLIDS && !(pfloor->flags & FF_EXTRA)) + solid = 1; + else if (rlight->flags & FF_CUTEXTRA && pfloor->flags & FF_EXTRA) + { + if (rlight->flags & FF_EXTRA) + { + // The light is from an extra 3D floor... Check the flags so + // there are no undesired cuts. + if ((rlight->flags & (FF_FOG|FF_SWIMMABLE)) == (pfloor->flags & (FF_FOG|FF_SWIMMABLE))) + solid = 1; + } + else + solid = 1; + } + else + solid = 0; + + height = rlight->height; + rlight->height += rlight->heightstep; + + if (solid) + { + bheight = rlight->botheight - (FRACUNIT >> 1); + rlight->botheight += rlight->botheightstep; + } + + if (height <= windowtop) + { + if (lighteffect) + dc_colormap = rlight->rcolormap; + if (solid && windowtop < bheight) + windowtop = bheight; + continue; + } + + windowbottom = height; + if (windowbottom >= sprbotscreen) + { + windowbottom = sprbotscreen; + // draw the texture + colfunc_2s (col); + for (i++; i < dc_numlights; i++) + { + rlight = &dc_lightlist[i]; + rlight->height += rlight->heightstep; + if (rlight->flags & FF_CUTLEVEL) + rlight->botheight += rlight->botheightstep; + } + continue; + } + // draw the texture + colfunc_2s (col); + if (solid) + windowtop = bheight; + else + windowtop = windowbottom + 1; + if (lighteffect) + dc_colormap = rlight->rcolormap; + } + windowbottom = sprbotscreen; + // draw the texture, if there is any space left + if (windowtop < windowbottom) + colfunc_2s (col); + + spryscale += rw_scalestep; + continue; + } + + // calculate lighting + pindex = FixedMul(spryscale, FixedDiv(640, vid.width))>>LIGHTSCALESHIFT; + + if (pindex >= MAXLIGHTSCALE) + pindex = MAXLIGHTSCALE - 1; + + dc_colormap = walllights[pindex]; + + if (pfloor->flags & FF_FOG && pfloor->master->frontsector->extra_colormap) + dc_colormap = pfloor->master->frontsector->extra_colormap->colormap + (dc_colormap - colormaps); + else if (frontsector->extra_colormap) + dc_colormap = frontsector->extra_colormap->colormap + (dc_colormap - colormaps); + + // draw the texture + colfunc_2s (col); + spryscale += rw_scalestep; + } + } + colfunc = colfuncs[BASEDRAWFUNC]; + +#undef CLAMPMAX +#undef CLAMPMIN +} + // R_ExpandPlaneY // // A simple function to modify a vsplane's top and bottom for a particular column @@ -101,7 +1341,7 @@ UINT32 nombre = 100000; static void R_RenderSegLoop (void) { angle_t angle; - size_t pindex = 0; + size_t pindex; INT32 yl; INT32 yh; @@ -114,16 +1354,12 @@ static void R_RenderSegLoop (void) INT32 bottom; INT32 i; - // Set the shadowed column drawer for light lists. - if (dc_numlights) - colfunc = colfuncs[COLDRAWFUNC_SHADOWED]; - - for (; rw.x < rw.stopx; rw.x++) + for (; rw_x < rw_stopx; rw_x++) { // mark floor / ceiling areas yl = (topfrac+HEIGHTUNIT-1)>>HEIGHTBITS; - top = ceilingclip[rw.x]+1; + top = ceilingclip[rw_x]+1; // no space above wall? if (yl < top) @@ -134,39 +1370,39 @@ static void R_RenderSegLoop (void) #if 0 bottom = yl-1; - if (bottom >= floorclip[rw.x]) - bottom = floorclip[rw.x]-1; + if (bottom >= floorclip[rw_x]) + bottom = floorclip[rw_x]-1; if (top <= bottom) #else - bottom = yl > floorclip[rw.x] ? floorclip[rw.x] : yl; + bottom = yl > floorclip[rw_x] ? floorclip[rw_x] : yl; if (top <= --bottom && ceilingplane) #endif - R_ExpandPlaneY(ceilingplane, rw.x, top, bottom); + R_ExpandPlaneY(ceilingplane, rw_x, top, bottom); } yh = bottomfrac>>HEIGHTBITS; - bottom = floorclip[rw.x]-1; + bottom = floorclip[rw_x]-1; if (yh > bottom) yh = bottom; if (markfloor) { - top = yh < ceilingclip[rw.x] ? ceilingclip[rw.x] : yh; + top = yh < ceilingclip[rw_x] ? ceilingclip[rw_x] : yh; if (++top <= bottom && floorplane) - R_ExpandPlaneY(floorplane, rw.x, top, bottom); + R_ExpandPlaneY(floorplane, rw_x, top, bottom); } if (numffloors) { - firstseg->frontscale[rw.x] = frontscale[rw.x]; - top = ceilingclip[rw.x]+1; // PRBoom - bottom = floorclip[rw.x]-1; // PRBoom + firstseg->frontscale[rw_x] = frontscale[rw_x]; + top = ceilingclip[rw_x]+1; // PRBoom + bottom = floorclip[rw_x]-1; // PRBoom for (i = 0; i < numffloors; i++) { @@ -178,7 +1414,7 @@ static void R_RenderSegLoop (void) if (ffloor[i].height < viewz) { INT32 top_w = (ffloor[i].f_frac >> HEIGHTBITS) + 1; - INT32 bottom_w = ffloor[i].f_clip[rw.x]; + INT32 bottom_w = ffloor[i].f_clip[rw_x]; if (top_w < top) top_w = top; @@ -189,20 +1425,20 @@ static void R_RenderSegLoop (void) #ifdef POLYOBJECTS_PLANES // Polyobject-specific hack to fix plane leaking -Red if (ffloor[i].polyobj && top_w >= bottom_w) { - ffloor[i].plane->top[rw.x] = 0xFFFF; - ffloor[i].plane->bottom[rw.x] = 0x0000; // fix for sky plane drawing crashes - Monster Iestyn 25/05/18 + ffloor[i].plane->top[rw_x] = 0xFFFF; + ffloor[i].plane->bottom[rw_x] = 0x0000; // fix for sky plane drawing crashes - Monster Iestyn 25/05/18 } else #endif if (top_w <= bottom_w) { - ffloor[i].plane->top[rw.x] = (INT16)top_w; - ffloor[i].plane->bottom[rw.x] = (INT16)bottom_w; + ffloor[i].plane->top[rw_x] = (INT16)top_w; + ffloor[i].plane->bottom[rw_x] = (INT16)bottom_w; } } else if (ffloor[i].height > viewz) { - INT32 top_w = ffloor[i].c_clip[rw.x] + 1; + INT32 top_w = ffloor[i].c_clip[rw_x] + 1; INT32 bottom_w = (ffloor[i].f_frac >> HEIGHTBITS); if (top_w < top) @@ -214,40 +1450,31 @@ static void R_RenderSegLoop (void) #ifdef POLYOBJECTS_PLANES // Polyobject-specific hack to fix plane leaking -Red if (ffloor[i].polyobj && top_w >= bottom_w) { - ffloor[i].plane->top[rw.x] = 0xFFFF; - ffloor[i].plane->bottom[rw.x] = 0x0000; // fix for sky plane drawing crashes - Monster Iestyn 25/05/18 + ffloor[i].plane->top[rw_x] = 0xFFFF; + ffloor[i].plane->bottom[rw_x] = 0x0000; // fix for sky plane drawing crashes - Monster Iestyn 25/05/18 } else #endif if (top_w <= bottom_w) { - ffloor[i].plane->top[rw.x] = (INT16)top_w; - ffloor[i].plane->bottom[rw.x] = (INT16)bottom_w; + ffloor[i].plane->top[rw_x] = (INT16)top_w; + ffloor[i].plane->bottom[rw_x] = (INT16)bottom_w; } } } } - // Calculate lighting. - // Done for light lists anyway to avoid doing it for every light. - if (segtextured || dc_numlights) - { - pindex = FixedMul(rw.scale, FixedDiv(640, vid.width))>>LIGHTSCALESHIFT; - if (pindex >= MAXLIGHTSCALE) - pindex = MAXLIGHTSCALE-1; - } - //SoM: Calculate offsets for Thick fake floors. // calculate texture offset - angle = (rw.centerangle + xtoviewangle[rw.x])>>ANGLETOFINESHIFT; - texturecolumn = rw.offset-FixedMul(FINETANGENT(angle),rw.distance); + angle = (rw_centerangle + xtoviewangle[rw_x])>>ANGLETOFINESHIFT; + texturecolumn = rw_offset-FixedMul(FINETANGENT(angle),rw_distance); #ifdef ESLOPE if (oldtexturecolumn != -1) { - rw.bottomtexturemid += FixedMul(rw.bottomtextureslide, oldtexturecolumn-texturecolumn); - rw.midtexturemid += FixedMul(rw.midtextureslide, oldtexturecolumn-texturecolumn); - rw.toptexturemid += FixedMul(rw.toptextureslide, oldtexturecolumn-texturecolumn); - rw.midtextureback += FixedMul(rw.midtexturebackslide, oldtexturecolumn-texturecolumn); + rw_bottomtexturemid += FixedMul(rw_bottomtextureslide, oldtexturecolumn-texturecolumn); + rw_midtexturemid += FixedMul(rw_midtextureslide, oldtexturecolumn-texturecolumn); + rw_toptexturemid += FixedMul(rw_toptextureslide, oldtexturecolumn-texturecolumn); + rw_midtextureback += FixedMul(rw_midtexturebackslide, oldtexturecolumn-texturecolumn); } oldtexturecolumn = texturecolumn; #endif @@ -257,9 +1484,15 @@ static void R_RenderSegLoop (void) // texturecolumn and lighting are independent of wall tiers if (segtextured) { + // calculate lighting + pindex = FixedMul(rw_scale, FixedDiv(640, vid.width))>>LIGHTSCALESHIFT; + + if (pindex >= MAXLIGHTSCALE) + pindex = MAXLIGHTSCALE-1; + dc_colormap = walllights[pindex]; - dc_x = rw.x; - dc_iscale = 0xffffffffu / (unsigned)rw.scale; + dc_x = rw_x; + dc_iscale = 0xffffffffu / (unsigned)rw_scale; if (frontsector->extra_colormap) dc_colormap = frontsector->extra_colormap->colormap + (dc_colormap - colormaps); @@ -287,14 +1520,21 @@ static void R_RenderSegLoop (void) else xwalllights = scalelight[lightnum]; + pindex = FixedMul(rw_scale, FixedDiv(640, vid.width))>>LIGHTSCALESHIFT; + + if (pindex >= MAXLIGHTSCALE) + pindex = MAXLIGHTSCALE-1; + if (dc_lightlist[i].extra_colormap) dc_lightlist[i].rcolormap = dc_lightlist[i].extra_colormap->colormap + (xwalllights[pindex] - colormaps); else dc_lightlist[i].rcolormap = xwalllights[pindex]; + + colfunc = colfuncs[COLDRAWFUNC_SHADOWED]; } } - frontscale[rw.x] = rw.scale; + frontscale[rw_x] = rw_scale; // draw the wall tiers if (midtexture) @@ -304,7 +1544,7 @@ static void R_RenderSegLoop (void) { dc_yl = yl; dc_yh = yh; - dc_texturemid = rw.midtexturemid; + dc_texturemid = rw_midtexturemid; dc_source = R_GetColumn(midtexture,texturecolumn); dc_texheight = textureheight[midtexture]>>FRACBITS; @@ -325,16 +1565,16 @@ static void R_RenderSegLoop (void) // dont draw anything more for this column, since // a midtexture blocks the view - ceilingclip[rw.x] = (INT16)viewheight; - floorclip[rw.x] = -1; + ceilingclip[rw_x] = (INT16)viewheight; + floorclip[rw_x] = -1; } else { // note: don't use min/max macros, since casting from INT32 to INT16 is involved here if (markceiling) - ceilingclip[rw.x] = (yl >= 0) ? ((yl > viewheight) ? (INT16)viewheight : (INT16)((INT16)yl - 1)) : -1; + ceilingclip[rw_x] = (yl >= 0) ? ((yl > viewheight) ? (INT16)viewheight : (INT16)((INT16)yl - 1)) : -1; if (markfloor) - floorclip[rw.x] = (yh < viewheight) ? ((yh < -1) ? -1 : (INT16)((INT16)yh + 1)) : (INT16)viewheight; + floorclip[rw_x] = (yh < viewheight) ? ((yh < -1) ? -1 : (INT16)((INT16)yh + 1)) : (INT16)viewheight; } } else @@ -346,31 +1586,31 @@ static void R_RenderSegLoop (void) mid = pixhigh>>HEIGHTBITS; pixhigh += pixhighstep; - if (mid >= floorclip[rw.x]) - mid = floorclip[rw.x]-1; + if (mid >= floorclip[rw_x]) + mid = floorclip[rw_x]-1; if (mid >= yl) // back ceiling lower than front ceiling ? { if (yl >= viewheight) // entirely off bottom of screen - ceilingclip[rw.x] = (INT16)viewheight; + ceilingclip[rw_x] = (INT16)viewheight; else if (mid >= 0) // safe to draw top texture { dc_yl = yl; dc_yh = mid; - dc_texturemid = rw.toptexturemid; + dc_texturemid = rw_toptexturemid; dc_source = R_GetColumn(toptexture,texturecolumn); dc_texheight = textureheight[toptexture]>>FRACBITS; colfunc(); - ceilingclip[rw.x] = (INT16)mid; + ceilingclip[rw_x] = (INT16)mid; } else // entirely off top of screen - ceilingclip[rw.x] = -1; + ceilingclip[rw_x] = -1; } else - ceilingclip[rw.x] = (yl >= 0) ? ((yl > viewheight) ? (INT16)viewheight : (INT16)((INT16)yl - 1)) : -1; + ceilingclip[rw_x] = (yl >= 0) ? ((yl > viewheight) ? (INT16)viewheight : (INT16)((INT16)yl - 1)) : -1; } else if (markceiling) // no top wall - ceilingclip[rw.x] = (yl >= 0) ? ((yl > viewheight) ? (INT16)viewheight : (INT16)((INT16)yl - 1)) : -1; + ceilingclip[rw_x] = (yl >= 0) ? ((yl > viewheight) ? (INT16)viewheight : (INT16)((INT16)yl - 1)) : -1; if (bottomtexture) { @@ -379,45 +1619,45 @@ static void R_RenderSegLoop (void) pixlow += pixlowstep; // no space above wall? - if (mid <= ceilingclip[rw.x]) - mid = ceilingclip[rw.x]+1; + if (mid <= ceilingclip[rw_x]) + mid = ceilingclip[rw_x]+1; if (mid <= yh) // back floor higher than front floor ? { if (yh < 0) // entirely off top of screen - floorclip[rw.x] = -1; + floorclip[rw_x] = -1; else if (mid < viewheight) // safe to draw bottom texture { dc_yl = mid; dc_yh = yh; - dc_texturemid = rw.bottomtexturemid; + dc_texturemid = rw_bottomtexturemid; dc_source = R_GetColumn(bottomtexture, texturecolumn); dc_texheight = textureheight[bottomtexture]>>FRACBITS; colfunc(); - floorclip[rw.x] = (INT16)mid; + floorclip[rw_x] = (INT16)mid; } else // entirely off bottom of screen - floorclip[rw.x] = (INT16)viewheight; + floorclip[rw_x] = (INT16)viewheight; } else - floorclip[rw.x] = (yh < viewheight) ? ((yh < -1) ? -1 : (INT16)((INT16)yh + 1)) : (INT16)viewheight; + floorclip[rw_x] = (yh < viewheight) ? ((yh < -1) ? -1 : (INT16)((INT16)yh + 1)) : (INT16)viewheight; } else if (markfloor) // no bottom wall - floorclip[rw.x] = (yh < viewheight) ? ((yh < -1) ? -1 : (INT16)((INT16)yh + 1)) : (INT16)viewheight; + floorclip[rw_x] = (yh < viewheight) ? ((yh < -1) ? -1 : (INT16)((INT16)yh + 1)) : (INT16)viewheight; } if (maskedtexture || numthicksides) { // save texturecol // for backdrawing of masked mid texture - maskedtexturecol[rw.x] = (INT16)texturecolumn; + maskedtexturecol[rw_x] = (INT16)texturecolumn; #ifdef ESLOPE if (maskedtextureheight != NULL) { - maskedtextureheight[rw.x] = (!!(curline->linedef->flags & ML_DONTPEGBOTTOM) ^ !!(curline->linedef->flags & ML_EFFECT3) ? - max(rw.midtexturemid, rw.midtextureback) : - min(rw.midtexturemid, rw.midtextureback)); + maskedtextureheight[rw_x] = (!!(curline->linedef->flags & ML_DONTPEGBOTTOM) ^ !!(curline->linedef->flags & ML_EFFECT3) ? + max(rw_midtexturemid, rw_midtextureback) : + min(rw_midtexturemid, rw_midtextureback)); } #endif } @@ -437,105 +1677,141 @@ static void R_RenderSegLoop (void) for (i = 0; i < numbackffloors; i++) { - ffloor[i].f_clip[rw.x] = ffloor[i].c_clip[rw.x] = (INT16)((ffloor[i].b_frac >> HEIGHTBITS) & 0xFFFF); + ffloor[i].f_clip[rw_x] = ffloor[i].c_clip[rw_x] = (INT16)((ffloor[i].b_frac >> HEIGHTBITS) & 0xFFFF); ffloor[i].b_frac += ffloor[i].b_step; } - rw.scale += rw.scalestep; + rw_scale += rw_scalestep; topfrac += topstep; bottomfrac += bottomstep; } } -// Macro for slope bullshit -#define SLOPEPARAMS(slope, end1, end2, normalheight) \ - if (slope) { \ - end1 = P_GetZAt(slope, segleft.x, segleft.y); \ - end2 = P_GetZAt(slope, segright.x, segright.y); \ - } else \ - end1 = end2 = normalheight; - -// -// R_CalculateSegDistance -// Calculate the distance from a seg. -// Uses precalculated seg length. -// -static void R_CalculateSegDistance(seg_t *seg, INT64 x2, INT64 y2, boolean longboi) +// Uses precalculated seg->length +static INT64 R_CalcSegDist(seg_t* seg, INT64 x2, INT64 y2) { -#ifdef SOFTWARE_USE_FLOATS - float v1x = FIXED_TO_FLOAT(seg->v1->x); - float v1y = FIXED_TO_FLOAT(seg->v1->y); - float v2x = FIXED_TO_FLOAT(seg->v2->x); - float v2y = FIXED_TO_FLOAT(seg->v2->y); - float dx, dy, vdx, vdy; - float distance = 0.0f; - - // The seg is vertical. if (!seg->linedef->dy) - distance = fabsf(y2 - v1y); - // The seg is horizontal. + return llabs(y2 - seg->v1->y); else if (!seg->linedef->dx) - distance = fabsf(x2 - v1x); - // Uses precalculated seg->flength - else if (longboi) - { - dx = v2x-v1x; - dy = v2y-v1y; - vdx = x2-v1x; - vdy = y2-v1y; - distance = ((dy*vdx)-(dx*vdy))/(seg->flength); - } - // Linguica's fix converted to floating-point math - else - { - fixed_t x, y; - float a, c, ac; - - v1x -= FIXED_TO_FLOAT(viewx); - v1y -= FIXED_TO_FLOAT(viewy); - v2x -= FIXED_TO_FLOAT(viewx); - v2y -= FIXED_TO_FLOAT(viewy); - dx = v2x - v1x; - dy = v2y - v1y; - - a = (v1x*v2y) - (v1y*v2x); - c = (dx*dx) + (dy*dy); - ac = (a/c); - - x = FLOAT_TO_FIXED(ac*(-dy)); - y = FLOAT_TO_FIXED(ac*dx); - - rw.distance = R_PointToDist(viewx + x, viewy + y); - return; - } - - rw.distance = FLOAT_TO_FIXED(distance); -#else - (void)longboi; - if (!seg->linedef->dy) - rw.distance = (fixed_t)(llabs(y2 - seg->v1->y)); - else if (!seg->linedef->dx) - rw.distance = (fixed_t)(llabs(x2 - seg->v1->x)); + return llabs(x2 - seg->v1->x); else { INT64 dx = (seg->v2->x)-(seg->v1->x); INT64 dy = (seg->v2->y)-(seg->v1->y); INT64 vdx = x2-(seg->v1->x); INT64 vdy = y2-(seg->v1->y); - rw.distance = (fixed_t)(((dy*vdx)-(dx*vdy))/(seg->length)); + return ((dy*vdx)-(dx*vdy))/(seg->length); } -#endif } // -// R_CalculateWallScale -// Calculate scale at both ends and step. +// R_StoreWallRange +// A wall segment will be drawn +// between start and stop pixels (inclusive). // -static INT32 R_CalculateWallScale(INT32 start, INT32 stop) +void R_StoreWallRange(INT32 start, INT32 stop) { - INT32 range = 1; + fixed_t hyp; + fixed_t sineval; + angle_t distangle, offsetangle; + boolean longboi; +#ifndef ESLOPE + fixed_t vtop; +#endif + INT32 lightnum; + INT32 i, p; + lightlist_t *light; + r_lightlist_t *rlight; + INT32 range; +#ifdef ESLOPE + vertex_t segleft, segright; + fixed_t ceilingfrontslide, floorfrontslide, ceilingbackslide, floorbackslide; +#endif + static size_t maxdrawsegs = 0; - ds_p->scale1 = rw.scale = R_ScaleFromGlobalAngle(viewangle + xtoviewangle[start]); +#ifdef ESLOPE + maskedtextureheight = NULL; + //initialize segleft and segright + memset(&segleft, 0x00, sizeof(segleft)); + memset(&segright, 0x00, sizeof(segright)); +#endif + + colfunc = colfuncs[BASEDRAWFUNC]; + + if (ds_p == drawsegs+maxdrawsegs) + { + size_t curpos = curdrawsegs - drawsegs; + size_t pos = ds_p - drawsegs; + size_t newmax = maxdrawsegs ? maxdrawsegs*2 : 128; + if (firstseg) + firstseg = (drawseg_t *)(firstseg - drawsegs); + drawsegs = Z_Realloc(drawsegs, newmax*sizeof (*drawsegs), PU_STATIC, NULL); + ds_p = drawsegs + pos; + maxdrawsegs = newmax; + curdrawsegs = drawsegs + curpos; + if (firstseg) + firstseg = drawsegs + (size_t)firstseg; + } + + sidedef = curline->sidedef; + linedef = curline->linedef; + + // calculate rw_distance for scale calculation + rw_normalangle = curline->angle + ANGLE_90; + offsetangle = abs((INT32)(rw_normalangle-rw_angle1)); + + if (offsetangle > ANGLE_90) + offsetangle = ANGLE_90; + + distangle = ANGLE_90 - offsetangle; + sineval = FINESINE(distangle>>ANGLETOFINESHIFT); + + hyp = R_PointToDist(curline->v1->x, curline->v1->y); + rw_distance = FixedMul(hyp, sineval); + longboi = (hyp >= INT32_MAX); + + // big room fix + if (longboi) + rw_distance = (fixed_t)R_CalcSegDist(curline,viewx,viewy); + + ds_p->x1 = rw_x = start; + ds_p->x2 = stop; + ds_p->curline = curline; + rw_stopx = stop+1; + + //SoM: Code to remove limits on openings. + { + size_t pos = lastopening - openings; + size_t need = (rw_stopx - start)*4 + pos; + if (need > maxopenings) + { + drawseg_t *ds; //needed for fix from *cough* zdoom *cough* + INT16 *oldopenings = openings; + INT16 *oldlast = lastopening; + + do + maxopenings = maxopenings ? maxopenings*2 : 16384; + while (need > maxopenings); + openings = Z_Realloc(openings, maxopenings * sizeof (*openings), PU_STATIC, NULL); + lastopening = openings + pos; + + // borrowed fix from *cough* zdoom *cough* + // [RH] We also need to adjust the openings pointers that + // were already stored in drawsegs. + for (ds = drawsegs; ds < ds_p; ds++) + { +#define ADJUST(p) if (ds->p + ds->x1 >= oldopenings && ds->p + ds->x1 <= oldlast) ds->p = ds->p - oldopenings + openings; + ADJUST(maskedtexturecol); + ADJUST(sprtopclip); + ADJUST(sprbottomclip); + ADJUST(thicksidecol); +#undef ADJUST + } + } + } // end of code to remove limits on openings + + // calculate scale at both ends and step + ds_p->scale1 = rw_scale = R_ScaleFromGlobalAngle(viewangle + xtoviewangle[start]); if (stop > start) { @@ -546,7 +1822,7 @@ static INT32 R_CalculateWallScale(INT32 start, INT32 stop) { // UNUSED: try to fix the stretched line bug #if 0 - if (rw.distance < FRACUNIT/2) + if (rw_distance < FRACUNIT/2) { fixed_t tr_x,tr_y; fixed_t gxt,gyt; @@ -561,20 +1837,13 @@ static INT32 R_CalculateWallScale(INT32 start, INT32 stop) } #endif ds_p->scale2 = ds_p->scale1; + range = 1; } - ds_p->scalestep = rw.scalestep = (ds_p->scale2 - rw.scale) / (range); + ds_p->scalestep = rw_scalestep = (ds_p->scale2 - rw_scale) / (range); - return range; -} - -// -// R_WorldTopAndBottom -// Calculate texture boundaries -// and decide if floor or ceiling marks are needed. -// -static void R_WorldTopAndBottom(INT32 start, INT32 stop) -{ + // calculate texture boundaries + // and decide if floor / ceiling marks are needed #ifdef ESLOPE // Figure out map coordinates of where start and end are mapping to on seg, so we can clip right for slope bullshit if (frontsector->hasslope || (backsector && backsector->hasslope)) // Commenting this out for FOFslop. -Red @@ -626,6 +1895,14 @@ static void R_WorldTopAndBottom(INT32 start, INT32 stop) } } + +#define SLOPEPARAMS(slope, end1, end2, normalheight) \ + if (slope) { \ + end1 = P_GetZAt(slope, segleft.x, segleft.y); \ + end2 = P_GetZAt(slope, segright.x, segright.y); \ + } else \ + end1 = end2 = normalheight; + SLOPEPARAMS(frontsector->c_slope, worldtop, worldtopslope, frontsector->ceilingheight) SLOPEPARAMS(frontsector->f_slope, worldbottom, worldbottomslope, frontsector->floorheight) // subtract viewz from these to turn them into @@ -638,350 +1915,60 @@ static void R_WorldTopAndBottom(INT32 start, INT32 stop) worldtop = frontsector->ceilingheight - viewz; worldbottom = frontsector->floorheight - viewz; #endif -} -// -// R_SegTextured -// Calculate rw.offset. -// Only needed for textured lines. -// -static void R_SegTextured(fixed_t hyp, boolean longboi) -{ - INT32 lightnum; - fixed_t sineval; - angle_t offsetangle = rw.normalangle-rw.angle1; + midtexture = toptexture = bottomtexture = maskedtexture = 0; + ds_p->maskedtexturecol = NULL; + ds_p->numthicksides = numthicksides = 0; + ds_p->thicksidecol = NULL; + ds_p->tsilheight = 0; - if (offsetangle > ANGLE_180) - offsetangle = -(signed)offsetangle; - if (offsetangle > ANGLE_90) - offsetangle = ANGLE_90; + numbackffloors = 0; - sineval = FINESINE(offsetangle>>ANGLETOFINESHIFT); - rw.offset = FixedMul(hyp, sineval); + for (i = 0; i < MAXFFLOORS; i++) + ds_p->thicksides[i] = NULL; - // big room fix - if (longboi) + if (numffloors) { - INT64 dx = (curline->v2->x)-(curline->v1->x); - INT64 dy = (curline->v2->y)-(curline->v1->y); - INT64 vdx = viewx-(curline->v1->x); - INT64 vdy = viewy-(curline->v1->y); - rw.offset = ((dx*vdx-dy*vdy))/(curline->length); + for (i = 0; i < numffloors; i++) + { +#ifdef POLYOBJECTS_PLANES + if (ffloor[i].polyobj && (!ds_p->curline->polyseg || ffloor[i].polyobj != ds_p->curline->polyseg)) + continue; +#endif + +#ifdef ESLOPE + if (ffloor[i].slope) { + ffloor[i].f_pos = P_GetZAt(ffloor[i].slope, segleft.x, segleft.y) - viewz; + ffloor[i].f_pos_slope = P_GetZAt(ffloor[i].slope, segright.x, segright.y) - viewz; + } else + ffloor[i].f_pos_slope = +#endif + ffloor[i].f_pos = ffloor[i].height - viewz; + } } - if (rw.normalangle-rw.angle1 < ANGLE_180) - rw.offset = -rw.offset; +#ifdef ESLOPE + // Set up texture Y offset slides for sloped walls + rw_toptextureslide = rw_midtextureslide = rw_bottomtextureslide = 0; + ceilingfrontslide = floorfrontslide = ceilingbackslide = floorbackslide = 0; - /// don't use texture offset for splats - rw.offset2 = rw.offset + curline->offset; - rw.offset += sidedef->textureoffset + curline->offset; - rw.centerangle = ANGLE_90 + viewangle - rw.normalangle; - - // calculate light table - // use different light tables - // for horizontal / vertical / diagonal - // OPTIMIZE: get rid of LIGHTSEGSHIFT globally - lightnum = (frontsector->lightlevel >> LIGHTSEGSHIFT); - - if (curline->v1->y == curline->v2->y) - lightnum--; - else if (curline->v1->x == curline->v2->x) - lightnum++; - - if (lightnum < 0) - walllights = scalelight[0]; - else if (lightnum >= LIGHTLEVELS) - walllights = scalelight[LIGHTLEVELS - 1]; - else - walllights = scalelight[lightnum]; -} - -// -// R_CheckMaskedTextures -// Midtexture stuff, presumably. -// -static void R_CheckMaskedTextures(void) -{ - INT32 i = 0; - // allocate space for masked texture tables - if (frontsector && backsector && frontsector->tag != backsector->tag && (backsector->ffloors || frontsector->ffloors)) { - ffloor_t *rover; - ffloor_t *r2; - fixed_t lowcut, highcut; -#ifdef ESLOPE - fixed_t lowcutslope, highcutslope; + angle_t lineangle = R_PointToAngle2(curline->v1->x, curline->v1->y, curline->v2->x, curline->v2->y); - // Used for height comparisons and etc across FOFs and slopes - fixed_t high1, highslope1, low1, lowslope1, high2, highslope2, low2, lowslope2; -#endif + if (frontsector->f_slope) + floorfrontslide = FixedMul(frontsector->f_slope->zdelta, FINECOSINE((lineangle-frontsector->f_slope->xydirection)>>ANGLETOFINESHIFT)); - //markceiling = markfloor = true; - maskedtexture = true; + if (frontsector->c_slope) + ceilingfrontslide = FixedMul(frontsector->c_slope->zdelta, FINECOSINE((lineangle-frontsector->c_slope->xydirection)>>ANGLETOFINESHIFT)); - ds_p->thicksidecol = maskedtexturecol = lastopening - rw.x; - lastopening += rw.stopx - rw.x; + if (backsector && backsector->f_slope) + floorbackslide = FixedMul(backsector->f_slope->zdelta, FINECOSINE((lineangle-backsector->f_slope->xydirection)>>ANGLETOFINESHIFT)); - lowcut = max(worldbottom, worldlow) + viewz; - highcut = min(worldtop, worldhigh) + viewz; -#ifdef ESLOPE - lowcutslope = max(worldbottomslope, worldlowslope) + viewz; - highcutslope = min(worldtopslope, worldhighslope) + viewz; -#endif - - if (frontsector->ffloors && backsector->ffloors) - { - i = 0; - for (rover = backsector->ffloors; rover && i < MAXFFLOORS; rover = rover->next) - { - if (!(rover->flags & FF_RENDERSIDES) || !(rover->flags & FF_EXISTS)) - continue; - if (rover->flags & FF_INVERTSIDES) - continue; - - if (rover->norender == leveltime) - continue; - -#ifdef ESLOPE - SLOPEPARAMS(*rover->t_slope, high1, highslope1, *rover->topheight) - SLOPEPARAMS(*rover->b_slope, low1, lowslope1, *rover->bottomheight) - - if ((high1 < lowcut && highslope1 < lowcutslope) || (low1 > highcut && lowslope1 > highcutslope)) - continue; -#else - if (*rover->topheight < lowcut || *rover->bottomheight > highcut) - continue; -#endif - - for (r2 = frontsector->ffloors; r2; r2 = r2->next) - { - if (!(r2->flags & FF_EXISTS) || !(r2->flags & FF_RENDERSIDES)) - continue; - - if (r2->norender == leveltime) - continue; - - if (rover->flags & FF_EXTRA) - { - if (!(r2->flags & FF_CUTEXTRA)) - continue; - - if (r2->flags & FF_EXTRA && (r2->flags & (FF_TRANSLUCENT|FF_FOG)) != (rover->flags & (FF_TRANSLUCENT|FF_FOG))) - continue; - } - else - { - if (!(r2->flags & FF_CUTSOLIDS)) - continue; - } - -#ifdef ESLOPE - SLOPEPARAMS(*r2->t_slope, high2, highslope2, *r2->topheight) - SLOPEPARAMS(*r2->b_slope, low2, lowslope2, *r2->bottomheight) - - if ((high2 < lowcut || highslope2 < lowcutslope) || (low2 > highcut || lowslope2 > highcutslope)) - continue; - if ((high1 > high2 || highslope1 > highslope2) || (low1 < low2 || lowslope1 < lowslope2)) - continue; -#else - if (*r2->topheight < lowcut || *r2->bottomheight > highcut) - continue; - if (*rover->topheight > *r2->topheight || *rover->bottomheight < *r2->bottomheight) - continue; -#endif - - break; - } - if (r2) - continue; - - ds_p->thicksides[i] = rover; - i++; - } - - for (rover = frontsector->ffloors; rover && i < MAXFFLOORS; rover = rover->next) - { - if (!(rover->flags & FF_RENDERSIDES) || !(rover->flags & FF_EXISTS)) - continue; - if (!(rover->flags & FF_ALLSIDES)) - continue; - - if (rover->norender == leveltime) - continue; - -#ifdef ESLOPE - SLOPEPARAMS(*rover->t_slope, high1, highslope1, *rover->topheight) - SLOPEPARAMS(*rover->b_slope, low1, lowslope1, *rover->bottomheight) - - if ((high1 < lowcut && highslope1 < lowcutslope) || (low1 > highcut && lowslope1 > highcutslope)) - continue; -#else - if (*rover->topheight < lowcut || *rover->bottomheight > highcut) - continue; -#endif - - for (r2 = backsector->ffloors; r2; r2 = r2->next) - { - if (!(r2->flags & FF_EXISTS) || !(r2->flags & FF_RENDERSIDES)) - continue; - - if (r2->norender == leveltime) - continue; - - if (rover->flags & FF_EXTRA) - { - if (!(r2->flags & FF_CUTEXTRA)) - continue; - - if (r2->flags & FF_EXTRA && (r2->flags & (FF_TRANSLUCENT|FF_FOG)) != (rover->flags & (FF_TRANSLUCENT|FF_FOG))) - continue; - } - else - { - if (!(r2->flags & FF_CUTSOLIDS)) - continue; - } - -#ifdef ESLOPE - SLOPEPARAMS(*r2->t_slope, high2, highslope2, *r2->topheight) - SLOPEPARAMS(*r2->b_slope, low2, lowslope2, *r2->bottomheight) - if ((high2 < lowcut || highslope2 < lowcutslope) || (low2 > highcut || lowslope2 > highcutslope)) - continue; - if ((high1 > high2 || highslope1 > highslope2) || (low1 < low2 || lowslope1 < lowslope2)) - continue; -#else - if (*r2->topheight < lowcut || *r2->bottomheight > highcut) - continue; - if (*rover->topheight > *r2->topheight || *rover->bottomheight < *r2->bottomheight) - continue; -#endif - - break; - } - if (r2) - continue; - - ds_p->thicksides[i] = rover; - i++; - } - } - else if (backsector->ffloors) - { - for (rover = backsector->ffloors, i = 0; rover && i < MAXFFLOORS; rover = rover->next) - { - if (!(rover->flags & FF_RENDERSIDES) || !(rover->flags & FF_EXISTS) || rover->flags & FF_INVERTSIDES) - continue; - if (rover->norender == leveltime) - continue; - -#ifdef ESLOPE - // Oy vey. - if (( (*rover->t_slope ? P_GetZAt(*rover->t_slope, segleft.x, segleft.y) : *rover->topheight) <= worldbottom+viewz - && (*rover->t_slope ? P_GetZAt(*rover->t_slope, segright.x, segright.y) : *rover->topheight) <= worldbottomslope+viewz) - ||((*rover->b_slope ? P_GetZAt(*rover->b_slope, segleft.x, segleft.y) : *rover->bottomheight) >= worldtop+viewz - && (*rover->b_slope ? P_GetZAt(*rover->b_slope, segright.x, segright.y) : *rover->bottomheight) >= worldtopslope+viewz)) - continue; -#else - if (*rover->topheight <= frontsector->floorheight || *rover->bottomheight >= frontsector->ceilingheight) - continue; -#endif - - ds_p->thicksides[i] = rover; - i++; - } - } - else if (frontsector->ffloors) - { - for (rover = frontsector->ffloors, i = 0; rover && i < MAXFFLOORS; rover = rover->next) - { - if (!(rover->flags & FF_RENDERSIDES) || !(rover->flags & FF_EXISTS) || !(rover->flags & FF_ALLSIDES)) - continue; - if (rover->norender == leveltime) - continue; -#ifdef ESLOPE - // Oy vey. - if (( (*rover->t_slope ? P_GetZAt(*rover->t_slope, segleft.x, segleft.y) : *rover->topheight) <= worldbottom+viewz - && (*rover->t_slope ? P_GetZAt(*rover->t_slope, segright.x, segright.y) : *rover->topheight) <= worldbottomslope+viewz) - ||((*rover->b_slope ? P_GetZAt(*rover->b_slope, segleft.x, segleft.y) : *rover->bottomheight) >= worldtop+viewz - && (*rover->b_slope ? P_GetZAt(*rover->b_slope, segright.x, segright.y) : *rover->bottomheight) >= worldtopslope+viewz)) - continue; - - if (( (*rover->t_slope ? P_GetZAt(*rover->t_slope, segleft.x, segleft.y) : *rover->topheight) <= worldlow+viewz - && (*rover->t_slope ? P_GetZAt(*rover->t_slope, segright.x, segright.y) : *rover->topheight) <= worldlowslope+viewz) - ||((*rover->b_slope ? P_GetZAt(*rover->b_slope, segleft.x, segleft.y) : *rover->bottomheight) >= worldhigh+viewz - && (*rover->b_slope ? P_GetZAt(*rover->b_slope, segright.x, segright.y) : *rover->bottomheight) >= worldhighslope+viewz)) - continue; -#else - if (*rover->topheight <= frontsector->floorheight || *rover->bottomheight >= frontsector->ceilingheight) - continue; - if (*rover->topheight <= backsector->floorheight || *rover->bottomheight >= backsector->ceilingheight) - continue; -#endif - - ds_p->thicksides[i] = rover; - i++; - } - } - - ds_p->numthicksides = numthicksides = i; + if (backsector && backsector->c_slope) + ceilingbackslide = FixedMul(backsector->c_slope->zdelta, FINECOSINE((lineangle-backsector->c_slope->xydirection)>>ANGLETOFINESHIFT)); } - - if (sidedef->midtexture > 0 && sidedef->midtexture < numtextures) - { - // masked midtexture - if (!ds_p->thicksidecol) - { - ds_p->maskedtexturecol = maskedtexturecol = lastopening - rw.x; - lastopening += rw.stopx - rw.x; - } - else - ds_p->maskedtexturecol = ds_p->thicksidecol; - -#ifdef ESLOPE - maskedtextureheight = ds_p->maskedtextureheight; // note to red, this == &(ds_p->maskedtextureheight[0]) - -#ifdef POLYOBJECTS - if (curline->polyseg) { // use REAL front and back floors please, so midtexture rendering isn't mucked up - rw.midtextureslide = rw.midtexturebackslide = 0; - if (!!(linedef->flags & ML_DONTPEGBOTTOM) ^ !!(linedef->flags & ML_EFFECT3)) - rw.midtexturemid = rw.midtextureback = max(curline->frontsector->floorheight, curline->backsector->floorheight) - viewz; - else - rw.midtexturemid = rw.midtextureback = min(curline->frontsector->ceilingheight, curline->backsector->ceilingheight) - viewz; - } else -#endif - // Set midtexture starting height - if (linedef->flags & ML_EFFECT2) { // Ignore slopes when texturing - rw.midtextureslide = rw.midtexturebackslide = 0; - if (!!(linedef->flags & ML_DONTPEGBOTTOM) ^ !!(linedef->flags & ML_EFFECT3)) - rw.midtexturemid = rw.midtextureback = max(frontsector->floorheight, backsector->floorheight) - viewz; - else - rw.midtexturemid = rw.midtextureback = min(frontsector->ceilingheight, backsector->ceilingheight) - viewz; - - } else if (!!(linedef->flags & ML_DONTPEGBOTTOM) ^ !!(linedef->flags & ML_EFFECT3)) { - rw.midtexturemid = worldbottom; - rw.midtextureslide = floorfrontslide; - rw.midtextureback = worldlow; - rw.midtexturebackslide = floorbackslide; - } else { - rw.midtexturemid = worldtop; - rw.midtextureslide = ceilingfrontslide; - rw.midtextureback = worldhigh; - rw.midtexturebackslide = ceilingbackslide; - } - rw.midtexturemid += sidedef->rowoffset; - rw.midtextureback += sidedef->rowoffset; #endif - maskedtexture = true; - } -} - -// -// R_CheckWallTextures -// Self-explanatory, I hope?! -// -static void R_CheckWallTextures(void) -{ if (!backsector) { fixed_t texheight; @@ -993,139 +1980,33 @@ static void R_CheckWallTextures(void) #ifdef ESLOPE if (linedef->flags & ML_EFFECT2) { if (linedef->flags & ML_DONTPEGBOTTOM) - rw.midtexturemid = frontsector->floorheight + texheight - viewz; + rw_midtexturemid = frontsector->floorheight + texheight - viewz; else - rw.midtexturemid = frontsector->ceilingheight - viewz; + rw_midtexturemid = frontsector->ceilingheight - viewz; } else #endif if (linedef->flags & ML_DONTPEGBOTTOM) { #ifdef ESLOPE - rw.midtexturemid = worldbottom + texheight; - rw.midtextureslide = floorfrontslide; + rw_midtexturemid = worldbottom + texheight; + rw_midtextureslide = floorfrontslide; #else vtop = frontsector->floorheight + texheight; // bottom of texture at bottom - rw.midtexturemid = vtop - viewz; + rw_midtexturemid = vtop - viewz; #endif } else { // top of texture at top - rw.midtexturemid = worldtop; + rw_midtexturemid = worldtop; #ifdef ESLOPE - rw.midtextureslide = ceilingfrontslide; + rw_midtextureslide = ceilingfrontslide; #endif } - rw.midtexturemid += sidedef->rowoffset; - } - else - { - // check TOP TEXTURE - if (!bothceilingssky // never draw the top texture if on - && (worldhigh < worldtop -#ifdef ESLOPE - || worldhighslope < worldtopslope -#endif - )) - { - fixed_t texheight; - // top texture - if ((linedef->flags & (ML_DONTPEGTOP) && (linedef->flags & ML_DONTPEGBOTTOM)) - && linedef->sidenum[1] != 0xffff) - { - // Special case... use offsets from 2nd side but only if it has a texture. - side_t *def = &sides[linedef->sidenum[1]]; - toptexture = R_GetTextureNum(def->toptexture); + rw_midtexturemid += sidedef->rowoffset; - if (!toptexture) //Second side has no texture, use the first side's instead. - toptexture = R_GetTextureNum(sidedef->toptexture); - texheight = textureheight[toptexture]; - } - else - { - toptexture = R_GetTextureNum(sidedef->toptexture); - texheight = textureheight[toptexture]; - } -#ifdef ESLOPE - if (!(linedef->flags & ML_EFFECT1)) { // Ignore slopes for lower/upper textures unless flag is checked - if (linedef->flags & ML_DONTPEGTOP) - rw.toptexturemid = frontsector->ceilingheight - viewz; - else - rw.toptexturemid = backsector->ceilingheight - viewz; - } else -#endif - if (linedef->flags & ML_DONTPEGTOP) - { - // top of texture at top - rw.toptexturemid = worldtop; -#ifdef ESLOPE - rw.toptextureslide = ceilingfrontslide; -#endif - } - else - { -#ifdef ESLOPE - rw.toptexturemid = worldhigh + texheight; - rw.toptextureslide = ceilingbackslide; -#else - vtop = backsector->ceilingheight + texheight; - // bottom of texture - rw.toptexturemid = vtop - viewz; -#endif - } - } - // check BOTTOM TEXTURE - if (!bothfloorssky // never draw the bottom texture if on - && (worldlow > worldbottom -#ifdef ESLOPE - || worldlowslope > worldbottomslope -#endif - )) //seulement si VISIBLE!!! - { - // bottom texture - bottomtexture = R_GetTextureNum(sidedef->bottomtexture); - -#ifdef ESLOPE - if (!(linedef->flags & ML_EFFECT1)) { // Ignore slopes for lower/upper textures unless flag is checked - if (linedef->flags & ML_DONTPEGBOTTOM) - rw.bottomtexturemid = frontsector->floorheight - viewz; - else - rw.bottomtexturemid = backsector->floorheight - viewz; - } else -#endif - if (linedef->flags & ML_DONTPEGBOTTOM) - { - // bottom of texture at bottom - // top of texture at top - rw.bottomtexturemid = worldbottom; -#ifdef ESLOPE - rw.bottomtextureslide = floorfrontslide; -#endif - } - else { // top of texture at top - rw.bottomtexturemid = worldlow; -#ifdef ESLOPE - rw.bottomtextureslide = floorbackslide; -#endif - } - } - - rw.toptexturemid += sidedef->rowoffset; - rw.bottomtexturemid += sidedef->rowoffset; - } -} - -// -// R_StoreWallSilhouette -// Sets the silhouette for the current seg. -// Also checks if any floors or ceilings have to be marked. -// -static void R_StoreWallSilhouette(void) -{ - if (!backsector) - { ds_p->silhouette = SIL_BOTH; ds_p->sprtopclip = screenheightarray; ds_p->sprbottomclip = negonearray; @@ -1135,8 +2016,8 @@ static void R_StoreWallSilhouette(void) else { // two sided line - bothceilingssky = false; // turned on if both back and front ceilings are sky - bothfloorssky = false; // likewise, but for floors + boolean bothceilingssky = false; // turned on if both back and front ceilings are sky + boolean bothfloorssky = false; // likewise, but for floors #ifdef ESLOPE SLOPEPARAMS(backsector->c_slope, worldhigh, worldhighslope, backsector->ceilingheight) @@ -1359,22 +2240,460 @@ static void R_StoreWallSilhouette(void) markceiling = markfloor = true; } } - } -} -// -// R_WorldStep -// Does... stepping... stuff? -// -static void R_WorldStep(INT32 range) -{ + // check TOP TEXTURE + if (!bothceilingssky // never draw the top texture if on + && (worldhigh < worldtop +#ifdef ESLOPE + || worldhighslope < worldtopslope +#endif + )) + { + fixed_t texheight; + // top texture + if ((linedef->flags & (ML_DONTPEGTOP) && (linedef->flags & ML_DONTPEGBOTTOM)) + && linedef->sidenum[1] != 0xffff) + { + // Special case... use offsets from 2nd side but only if it has a texture. + side_t *def = &sides[linedef->sidenum[1]]; + toptexture = R_GetTextureNum(def->toptexture); + + if (!toptexture) //Second side has no texture, use the first side's instead. + toptexture = R_GetTextureNum(sidedef->toptexture); + texheight = textureheight[toptexture]; + } + else + { + toptexture = R_GetTextureNum(sidedef->toptexture); + texheight = textureheight[toptexture]; + } +#ifdef ESLOPE + if (!(linedef->flags & ML_EFFECT1)) { // Ignore slopes for lower/upper textures unless flag is checked + if (linedef->flags & ML_DONTPEGTOP) + rw_toptexturemid = frontsector->ceilingheight - viewz; + else + rw_toptexturemid = backsector->ceilingheight - viewz; + } else +#endif + if (linedef->flags & ML_DONTPEGTOP) + { + // top of texture at top + rw_toptexturemid = worldtop; +#ifdef ESLOPE + rw_toptextureslide = ceilingfrontslide; +#endif + } + else + { +#ifdef ESLOPE + rw_toptexturemid = worldhigh + texheight; + rw_toptextureslide = ceilingbackslide; +#else + vtop = backsector->ceilingheight + texheight; + // bottom of texture + rw_toptexturemid = vtop - viewz; +#endif + } + } + // check BOTTOM TEXTURE + if (!bothfloorssky // never draw the bottom texture if on + && (worldlow > worldbottom +#ifdef ESLOPE + || worldlowslope > worldbottomslope +#endif + )) //seulement si VISIBLE!!! + { + // bottom texture + bottomtexture = R_GetTextureNum(sidedef->bottomtexture); + +#ifdef ESLOPE + if (!(linedef->flags & ML_EFFECT1)) { // Ignore slopes for lower/upper textures unless flag is checked + if (linedef->flags & ML_DONTPEGBOTTOM) + rw_bottomtexturemid = frontsector->floorheight - viewz; + else + rw_bottomtexturemid = backsector->floorheight - viewz; + } else +#endif + if (linedef->flags & ML_DONTPEGBOTTOM) + { + // bottom of texture at bottom + // top of texture at top + rw_bottomtexturemid = worldbottom; +#ifdef ESLOPE + rw_bottomtextureslide = floorfrontslide; +#endif + } + else { // top of texture at top + rw_bottomtexturemid = worldlow; +#ifdef ESLOPE + rw_bottomtextureslide = floorbackslide; +#endif + } + } + + rw_toptexturemid += sidedef->rowoffset; + rw_bottomtexturemid += sidedef->rowoffset; + + // allocate space for masked texture tables + if (frontsector && backsector && frontsector->tag != backsector->tag && (backsector->ffloors || frontsector->ffloors)) + { + ffloor_t *rover; + ffloor_t *r2; + fixed_t lowcut, highcut; +#ifdef ESLOPE + fixed_t lowcutslope, highcutslope; + + // Used for height comparisons and etc across FOFs and slopes + fixed_t high1, highslope1, low1, lowslope1, high2, highslope2, low2, lowslope2; +#endif + + //markceiling = markfloor = true; + maskedtexture = true; + + ds_p->thicksidecol = maskedtexturecol = lastopening - rw_x; + lastopening += rw_stopx - rw_x; + + lowcut = max(worldbottom, worldlow) + viewz; + highcut = min(worldtop, worldhigh) + viewz; +#ifdef ESLOPE + lowcutslope = max(worldbottomslope, worldlowslope) + viewz; + highcutslope = min(worldtopslope, worldhighslope) + viewz; +#endif + + if (frontsector->ffloors && backsector->ffloors) + { + i = 0; + for (rover = backsector->ffloors; rover && i < MAXFFLOORS; rover = rover->next) + { + if (!(rover->flags & FF_RENDERSIDES) || !(rover->flags & FF_EXISTS)) + continue; + if (rover->flags & FF_INVERTSIDES) + continue; + + if (rover->norender == leveltime) + continue; + +#ifdef ESLOPE + SLOPEPARAMS(*rover->t_slope, high1, highslope1, *rover->topheight) + SLOPEPARAMS(*rover->b_slope, low1, lowslope1, *rover->bottomheight) + + if ((high1 < lowcut && highslope1 < lowcutslope) || (low1 > highcut && lowslope1 > highcutslope)) + continue; +#else + if (*rover->topheight < lowcut || *rover->bottomheight > highcut) + continue; +#endif + + for (r2 = frontsector->ffloors; r2; r2 = r2->next) + { + if (!(r2->flags & FF_EXISTS) || !(r2->flags & FF_RENDERSIDES)) + continue; + + if (r2->norender == leveltime) + continue; + + if (rover->flags & FF_EXTRA) + { + if (!(r2->flags & FF_CUTEXTRA)) + continue; + + if (r2->flags & FF_EXTRA && (r2->flags & (FF_TRANSLUCENT|FF_FOG)) != (rover->flags & (FF_TRANSLUCENT|FF_FOG))) + continue; + } + else + { + if (!(r2->flags & FF_CUTSOLIDS)) + continue; + } + +#ifdef ESLOPE + SLOPEPARAMS(*r2->t_slope, high2, highslope2, *r2->topheight) + SLOPEPARAMS(*r2->b_slope, low2, lowslope2, *r2->bottomheight) + + if ((high2 < lowcut || highslope2 < lowcutslope) || (low2 > highcut || lowslope2 > highcutslope)) + continue; + if ((high1 > high2 || highslope1 > highslope2) || (low1 < low2 || lowslope1 < lowslope2)) + continue; +#else + if (*r2->topheight < lowcut || *r2->bottomheight > highcut) + continue; + if (*rover->topheight > *r2->topheight || *rover->bottomheight < *r2->bottomheight) + continue; +#endif + + break; + } + if (r2) + continue; + + ds_p->thicksides[i] = rover; + i++; + } + + for (rover = frontsector->ffloors; rover && i < MAXFFLOORS; rover = rover->next) + { + if (!(rover->flags & FF_RENDERSIDES) || !(rover->flags & FF_EXISTS)) + continue; + if (!(rover->flags & FF_ALLSIDES)) + continue; + + if (rover->norender == leveltime) + continue; + +#ifdef ESLOPE + SLOPEPARAMS(*rover->t_slope, high1, highslope1, *rover->topheight) + SLOPEPARAMS(*rover->b_slope, low1, lowslope1, *rover->bottomheight) + + if ((high1 < lowcut && highslope1 < lowcutslope) || (low1 > highcut && lowslope1 > highcutslope)) + continue; +#else + if (*rover->topheight < lowcut || *rover->bottomheight > highcut) + continue; +#endif + + for (r2 = backsector->ffloors; r2; r2 = r2->next) + { + if (!(r2->flags & FF_EXISTS) || !(r2->flags & FF_RENDERSIDES)) + continue; + + if (r2->norender == leveltime) + continue; + + if (rover->flags & FF_EXTRA) + { + if (!(r2->flags & FF_CUTEXTRA)) + continue; + + if (r2->flags & FF_EXTRA && (r2->flags & (FF_TRANSLUCENT|FF_FOG)) != (rover->flags & (FF_TRANSLUCENT|FF_FOG))) + continue; + } + else + { + if (!(r2->flags & FF_CUTSOLIDS)) + continue; + } + +#ifdef ESLOPE + SLOPEPARAMS(*r2->t_slope, high2, highslope2, *r2->topheight) + SLOPEPARAMS(*r2->b_slope, low2, lowslope2, *r2->bottomheight) +#undef SLOPEPARAMS + if ((high2 < lowcut || highslope2 < lowcutslope) || (low2 > highcut || lowslope2 > highcutslope)) + continue; + if ((high1 > high2 || highslope1 > highslope2) || (low1 < low2 || lowslope1 < lowslope2)) + continue; +#else + if (*r2->topheight < lowcut || *r2->bottomheight > highcut) + continue; + if (*rover->topheight > *r2->topheight || *rover->bottomheight < *r2->bottomheight) + continue; +#endif + + break; + } + if (r2) + continue; + + ds_p->thicksides[i] = rover; + i++; + } + } + else if (backsector->ffloors) + { + for (rover = backsector->ffloors, i = 0; rover && i < MAXFFLOORS; rover = rover->next) + { + if (!(rover->flags & FF_RENDERSIDES) || !(rover->flags & FF_EXISTS) || rover->flags & FF_INVERTSIDES) + continue; + if (rover->norender == leveltime) + continue; + +#ifdef ESLOPE + // Oy vey. + if (( (*rover->t_slope ? P_GetZAt(*rover->t_slope, segleft.x, segleft.y) : *rover->topheight) <= worldbottom+viewz + && (*rover->t_slope ? P_GetZAt(*rover->t_slope, segright.x, segright.y) : *rover->topheight) <= worldbottomslope+viewz) + ||((*rover->b_slope ? P_GetZAt(*rover->b_slope, segleft.x, segleft.y) : *rover->bottomheight) >= worldtop+viewz + && (*rover->b_slope ? P_GetZAt(*rover->b_slope, segright.x, segright.y) : *rover->bottomheight) >= worldtopslope+viewz)) + continue; +#else + if (*rover->topheight <= frontsector->floorheight || *rover->bottomheight >= frontsector->ceilingheight) + continue; +#endif + + ds_p->thicksides[i] = rover; + i++; + } + } + else if (frontsector->ffloors) + { + for (rover = frontsector->ffloors, i = 0; rover && i < MAXFFLOORS; rover = rover->next) + { + if (!(rover->flags & FF_RENDERSIDES) || !(rover->flags & FF_EXISTS) || !(rover->flags & FF_ALLSIDES)) + continue; + if (rover->norender == leveltime) + continue; +#ifdef ESLOPE + // Oy vey. + if (( (*rover->t_slope ? P_GetZAt(*rover->t_slope, segleft.x, segleft.y) : *rover->topheight) <= worldbottom+viewz + && (*rover->t_slope ? P_GetZAt(*rover->t_slope, segright.x, segright.y) : *rover->topheight) <= worldbottomslope+viewz) + ||((*rover->b_slope ? P_GetZAt(*rover->b_slope, segleft.x, segleft.y) : *rover->bottomheight) >= worldtop+viewz + && (*rover->b_slope ? P_GetZAt(*rover->b_slope, segright.x, segright.y) : *rover->bottomheight) >= worldtopslope+viewz)) + continue; + + if (( (*rover->t_slope ? P_GetZAt(*rover->t_slope, segleft.x, segleft.y) : *rover->topheight) <= worldlow+viewz + && (*rover->t_slope ? P_GetZAt(*rover->t_slope, segright.x, segright.y) : *rover->topheight) <= worldlowslope+viewz) + ||((*rover->b_slope ? P_GetZAt(*rover->b_slope, segleft.x, segleft.y) : *rover->bottomheight) >= worldhigh+viewz + && (*rover->b_slope ? P_GetZAt(*rover->b_slope, segright.x, segright.y) : *rover->bottomheight) >= worldhighslope+viewz)) + continue; +#else + if (*rover->topheight <= frontsector->floorheight || *rover->bottomheight >= frontsector->ceilingheight) + continue; + if (*rover->topheight <= backsector->floorheight || *rover->bottomheight >= backsector->ceilingheight) + continue; +#endif + + ds_p->thicksides[i] = rover; + i++; + } + } + + ds_p->numthicksides = numthicksides = i; + } + if (sidedef->midtexture > 0 && sidedef->midtexture < numtextures) + { + // masked midtexture + if (!ds_p->thicksidecol) + { + ds_p->maskedtexturecol = maskedtexturecol = lastopening - rw_x; + lastopening += rw_stopx - rw_x; + } + else + ds_p->maskedtexturecol = ds_p->thicksidecol; + +#ifdef ESLOPE + maskedtextureheight = ds_p->maskedtextureheight; // note to red, this == &(ds_p->maskedtextureheight[0]) + +#ifdef POLYOBJECTS + if (curline->polyseg) { // use REAL front and back floors please, so midtexture rendering isn't mucked up + rw_midtextureslide = rw_midtexturebackslide = 0; + if (!!(linedef->flags & ML_DONTPEGBOTTOM) ^ !!(linedef->flags & ML_EFFECT3)) + rw_midtexturemid = rw_midtextureback = max(curline->frontsector->floorheight, curline->backsector->floorheight) - viewz; + else + rw_midtexturemid = rw_midtextureback = min(curline->frontsector->ceilingheight, curline->backsector->ceilingheight) - viewz; + } else +#endif + // Set midtexture starting height + if (linedef->flags & ML_EFFECT2) { // Ignore slopes when texturing + rw_midtextureslide = rw_midtexturebackslide = 0; + if (!!(linedef->flags & ML_DONTPEGBOTTOM) ^ !!(linedef->flags & ML_EFFECT3)) + rw_midtexturemid = rw_midtextureback = max(frontsector->floorheight, backsector->floorheight) - viewz; + else + rw_midtexturemid = rw_midtextureback = min(frontsector->ceilingheight, backsector->ceilingheight) - viewz; + + } else if (!!(linedef->flags & ML_DONTPEGBOTTOM) ^ !!(linedef->flags & ML_EFFECT3)) { + rw_midtexturemid = worldbottom; + rw_midtextureslide = floorfrontslide; + rw_midtextureback = worldlow; + rw_midtexturebackslide = floorbackslide; + } else { + rw_midtexturemid = worldtop; + rw_midtextureslide = ceilingfrontslide; + rw_midtextureback = worldhigh; + rw_midtexturebackslide = ceilingbackslide; + } + rw_midtexturemid += sidedef->rowoffset; + rw_midtextureback += sidedef->rowoffset; +#endif + + maskedtexture = true; + } + } + + // calculate rw_offset (only needed for textured lines) + segtextured = midtexture || toptexture || bottomtexture || maskedtexture || (numthicksides > 0); + + if (segtextured) + { + offsetangle = rw_normalangle-rw_angle1; + + if (offsetangle > ANGLE_180) + offsetangle = -(signed)offsetangle; + + if (offsetangle > ANGLE_90) + offsetangle = ANGLE_90; + + sineval = FINESINE(offsetangle>>ANGLETOFINESHIFT); + rw_offset = FixedMul(hyp, sineval); + + // big room fix + if (longboi) + { + INT64 dx = (curline->v2->x)-(curline->v1->x); + INT64 dy = (curline->v2->y)-(curline->v1->y); + INT64 vdx = viewx-(curline->v1->x); + INT64 vdy = viewy-(curline->v1->y); + rw_offset = ((dx*vdx-dy*vdy))/(curline->length); + } + + if (rw_normalangle-rw_angle1 < ANGLE_180) + rw_offset = -rw_offset; + + /// don't use texture offset for splats + rw_offset2 = rw_offset + curline->offset; + rw_offset += sidedef->textureoffset + curline->offset; + rw_centerangle = ANGLE_90 + viewangle - rw_normalangle; + + // calculate light table + // use different light tables + // for horizontal / vertical / diagonal + // OPTIMIZE: get rid of LIGHTSEGSHIFT globally + lightnum = (frontsector->lightlevel >> LIGHTSEGSHIFT); + + if (curline->v1->y == curline->v2->y) + lightnum--; + else if (curline->v1->x == curline->v2->x) + lightnum++; + + if (lightnum < 0) + walllights = scalelight[0]; + else if (lightnum >= LIGHTLEVELS) + walllights = scalelight[LIGHTLEVELS - 1]; + else + walllights = scalelight[lightnum]; + } + + // if a floor / ceiling plane is on the wrong side + // of the view plane, it is definitely invisible + // and doesn't need to be marked. + if (frontsector->heightsec == -1) + { + if (frontsector->floorpic != skyflatnum + && ( +#ifdef ESLOPE + frontsector->f_slope ? P_GetZAt(frontsector->f_slope, viewx, viewy) : +#endif + frontsector->floorheight) >= viewz) + { + // above view plane + markfloor = false; + } + + if (frontsector->ceilingpic != skyflatnum + && ( +#ifdef ESLOPE + frontsector->c_slope ? P_GetZAt(frontsector->c_slope, viewx, viewy) : +#endif + frontsector->ceilingheight) <= viewz) + { + // below view plane + markceiling = false; + } + } + + // calculate incremental stepping values for texture edges worldtop >>= 4; worldbottom >>= 4; #ifdef ESLOPE worldtopslope >>= 4; worldbottomslope >>= 4; -#else - (void)range; #endif if (linedef->special == HORIZONSPECIAL) { // HORIZON LINES @@ -1382,11 +2701,11 @@ static void R_WorldStep(INT32 range) topfrac = bottomfrac = (centeryfrac>>4); topfrac++; // Prevent 1px HOM } else { - topstep = -FixedMul (rw.scalestep, worldtop); - topfrac = (centeryfrac>>4) - FixedMul (worldtop, rw.scale); + topstep = -FixedMul (rw_scalestep, worldtop); + topfrac = (centeryfrac>>4) - FixedMul (worldtop, rw_scale); - bottomstep = -FixedMul (rw.scalestep,worldbottom); - bottomfrac = (centeryfrac>>4) - FixedMul (worldbottom, rw.scale); + bottomstep = -FixedMul (rw_scalestep,worldbottom); + bottomfrac = (centeryfrac>>4) - FixedMul (worldbottom, rw_scale); #ifdef ESLOPE if (frontsector->c_slope) { @@ -1399,329 +2718,6 @@ static void R_WorldStep(INT32 range) } #endif } -} - -// -// R_WorldBackStep -// Does... stepping... stuff? For backsides?!?!?!?!?!?! -// -static void R_WorldBackStep(INT32 range) -{ - INT32 i; - - worldhigh >>= 4; - worldlow >>= 4; -#ifdef ESLOPE - worldhighslope >>= 4; - worldlowslope >>= 4; -#else - (void)range; -#endif - - if (toptexture) - { - pixhigh = (centeryfrac>>4) - FixedMul (worldhigh, rw.scale); - pixhighstep = -FixedMul (rw.scalestep,worldhigh); - -#ifdef ESLOPE - if (backsector->c_slope) { - fixed_t topfracend = (centeryfrac>>4) - FixedMul (worldhighslope, ds_p->scale2); - pixhighstep = (topfracend-pixhigh)/(range); - } -#endif - } - - if (bottomtexture) - { - pixlow = (centeryfrac>>4) - FixedMul (worldlow, rw.scale); - pixlowstep = -FixedMul (rw.scalestep,worldlow); -#ifdef ESLOPE - if (backsector->f_slope) { - fixed_t bottomfracend = (centeryfrac>>4) - FixedMul (worldlowslope, ds_p->scale2); - pixlowstep = (bottomfracend-pixlow)/(range); - } -#endif - } - - { - ffloor_t * rover; -#ifdef ESLOPE - fixed_t roverleft, roverright; - fixed_t planevistest; -#endif - i = 0; - - if (backsector->ffloors) - { - for (rover = backsector->ffloors; rover && i < MAXFFLOORS; rover = rover->next) - { - if (!(rover->flags & FF_EXISTS) || !(rover->flags & FF_RENDERPLANES)) - continue; - if (rover->norender == leveltime) - continue; - -#ifdef ESLOPE - // Let the renderer know this sector is sloped. - if (*rover->b_slope || *rover->t_slope) - backsector->hasslope = true; - - roverleft = (*rover->b_slope ? P_GetZAt(*rover->b_slope, segleft.x, segleft.y) : *rover->bottomheight) - viewz; - roverright = (*rover->b_slope ? P_GetZAt(*rover->b_slope, segright.x, segright.y) : *rover->bottomheight) - viewz; - planevistest = (*rover->b_slope ? P_GetZAt(*rover->b_slope, viewx, viewy) : *rover->bottomheight); - - if ((roverleft>>4 <= worldhigh || roverright>>4 <= worldhighslope) && - (roverleft>>4 >= worldlow || roverright>>4 >= worldlowslope) && - ((viewz < planevistest && !(rover->flags & FF_INVERTPLANES)) || - (viewz > planevistest && (rover->flags & FF_BOTHPLANES)))) - { - //ffloor[i].slope = *rover->b_slope; - ffloor[i].b_pos = roverleft; - ffloor[i].b_pos_slope = roverright; - ffloor[i].b_pos >>= 4; - ffloor[i].b_pos_slope >>= 4; - ffloor[i].b_frac = (centeryfrac >> 4) - FixedMul(ffloor[i].b_pos, rw.scale); - ffloor[i].b_step = (centeryfrac >> 4) - FixedMul(ffloor[i].b_pos_slope, ds_p->scale2); - ffloor[i].b_step = (ffloor[i].b_step-ffloor[i].b_frac)/(range); - i++; - } - - if (i >= MAXFFLOORS) - break; - - roverleft = (*rover->t_slope ? P_GetZAt(*rover->t_slope, segleft.x, segleft.y) : *rover->topheight) - viewz; - roverright = (*rover->t_slope ? P_GetZAt(*rover->t_slope, segright.x, segright.y) : *rover->topheight) - viewz; - planevistest = (*rover->t_slope ? P_GetZAt(*rover->t_slope, viewx, viewy) : *rover->topheight); - - if ((roverleft>>4 <= worldhigh || roverright>>4 <= worldhighslope) && - (roverleft>>4 >= worldlow || roverright>>4 >= worldlowslope) && - ((viewz > planevistest && !(rover->flags & FF_INVERTPLANES)) || - (viewz < planevistest && (rover->flags & FF_BOTHPLANES)))) - { - //ffloor[i].slope = *rover->t_slope; - ffloor[i].b_pos = roverleft; - ffloor[i].b_pos_slope = roverright; - ffloor[i].b_pos >>= 4; - ffloor[i].b_pos_slope >>= 4; - ffloor[i].b_frac = (centeryfrac >> 4) - FixedMul(ffloor[i].b_pos, rw.scale); - ffloor[i].b_step = (centeryfrac >> 4) - FixedMul(ffloor[i].b_pos_slope, ds_p->scale2); - ffloor[i].b_step = (ffloor[i].b_step-ffloor[i].b_frac)/(range); - i++; - } -#else - if (*rover->bottomheight <= backsector->ceilingheight && - *rover->bottomheight >= backsector->floorheight && - ((viewz < *rover->bottomheight && !(rover->flags & FF_INVERTPLANES)) || - (viewz > *rover->bottomheight && (rover->flags & FF_BOTHPLANES)))) - { - ffloor[i].b_pos = *rover->bottomheight; - ffloor[i].b_pos = (ffloor[i].b_pos - viewz) >> 4; - ffloor[i].b_step = FixedMul(-rw.scalestep, ffloor[i].b_pos); - ffloor[i].b_frac = (centeryfrac >> 4) - FixedMul(ffloor[i].b_pos, rw.scale); - i++; - } - - if (i >= MAXFFLOORS) - break; - - if (*rover->topheight >= backsector->floorheight && - *rover->topheight <= backsector->ceilingheight && - ((viewz > *rover->topheight && !(rover->flags & FF_INVERTPLANES)) || - (viewz < *rover->topheight && (rover->flags & FF_BOTHPLANES)))) - { - ffloor[i].b_pos = *rover->topheight; - ffloor[i].b_pos = (ffloor[i].b_pos - viewz) >> 4; - ffloor[i].b_step = FixedMul(-rw.scalestep, ffloor[i].b_pos); - ffloor[i].b_frac = (centeryfrac >> 4) - FixedMul(ffloor[i].b_pos, rw.scale); - i++; - } -#endif - } - } - else if (frontsector && frontsector->ffloors) - { - for (rover = frontsector->ffloors; rover && i < MAXFFLOORS; rover = rover->next) - { - if (!(rover->flags & FF_EXISTS) || !(rover->flags & FF_RENDERPLANES)) - continue; - if (rover->norender == leveltime) - continue; - - -#ifdef ESLOPE - // Let the renderer know this sector is sloped. - if (*rover->b_slope || *rover->t_slope) - frontsector->hasslope = true; - - roverleft = (*rover->b_slope ? P_GetZAt(*rover->b_slope, segleft.x, segleft.y) : *rover->bottomheight) - viewz; - roverright = (*rover->b_slope ? P_GetZAt(*rover->b_slope, segright.x, segright.y) : *rover->bottomheight) - viewz; - planevistest = (*rover->b_slope ? P_GetZAt(*rover->b_slope, viewx, viewy) : *rover->bottomheight); - - if ((roverleft>>4 <= worldhigh || roverright>>4 <= worldhighslope) && - (roverleft>>4 >= worldlow || roverright>>4 >= worldlowslope) && - ((viewz < planevistest && !(rover->flags & FF_INVERTPLANES)) || - (viewz > planevistest && (rover->flags & FF_BOTHPLANES)))) - { - //ffloor[i].slope = *rover->b_slope; - ffloor[i].b_pos = roverleft; - ffloor[i].b_pos_slope = roverright; - ffloor[i].b_pos >>= 4; - ffloor[i].b_pos_slope >>= 4; - ffloor[i].b_frac = (centeryfrac >> 4) - FixedMul(ffloor[i].b_pos, rw.scale); - ffloor[i].b_step = (centeryfrac >> 4) - FixedMul(ffloor[i].b_pos_slope, ds_p->scale2); - ffloor[i].b_step = (ffloor[i].b_step-ffloor[i].b_frac)/(range); - i++; - } - - if (i >= MAXFFLOORS) - break; - - roverleft = (*rover->t_slope ? P_GetZAt(*rover->t_slope, segleft.x, segleft.y) : *rover->topheight) - viewz; - roverright = (*rover->t_slope ? P_GetZAt(*rover->t_slope, segright.x, segright.y) : *rover->topheight) - viewz; - planevistest = (*rover->t_slope ? P_GetZAt(*rover->t_slope, viewx, viewy) : *rover->topheight); - - if ((roverleft>>4 <= worldhigh || roverright>>4 <= worldhighslope) && - (roverleft>>4 >= worldlow || roverright>>4 >= worldlowslope) && - ((viewz > planevistest && !(rover->flags & FF_INVERTPLANES)) || - (viewz < planevistest && (rover->flags & FF_BOTHPLANES)))) - { - //ffloor[i].slope = *rover->t_slope; - ffloor[i].b_pos = roverleft; - ffloor[i].b_pos_slope = roverright; - ffloor[i].b_pos >>= 4; - ffloor[i].b_pos_slope >>= 4; - ffloor[i].b_frac = (centeryfrac >> 4) - FixedMul(ffloor[i].b_pos, rw.scale); - ffloor[i].b_step = (centeryfrac >> 4) - FixedMul(ffloor[i].b_pos_slope, ds_p->scale2); - ffloor[i].b_step = (ffloor[i].b_step-ffloor[i].b_frac)/(range); - i++; - } -#else - if (*rover->bottomheight <= frontsector->ceilingheight && - *rover->bottomheight >= frontsector->floorheight && - ((viewz < *rover->bottomheight && !(rover->flags & FF_INVERTPLANES)) || - (viewz > *rover->bottomheight && (rover->flags & FF_BOTHPLANES)))) - { - ffloor[i].b_pos = *rover->bottomheight; - ffloor[i].b_pos = (ffloor[i].b_pos - viewz) >> 4; - ffloor[i].b_step = FixedMul(-rw.scalestep, ffloor[i].b_pos); - ffloor[i].b_frac = (centeryfrac >> 4) - FixedMul(ffloor[i].b_pos, rw.scale); - i++; - } - if (i >= MAXFFLOORS) - break; - if (*rover->topheight >= frontsector->floorheight && - *rover->topheight <= frontsector->ceilingheight && - ((viewz > *rover->topheight && !(rover->flags & FF_INVERTPLANES)) || - (viewz < *rover->topheight && (rover->flags & FF_BOTHPLANES)))) - { - ffloor[i].b_pos = *rover->topheight; - ffloor[i].b_pos = (ffloor[i].b_pos - viewz) >> 4; - ffloor[i].b_step = FixedMul(-rw.scalestep, ffloor[i].b_pos); - ffloor[i].b_frac = (centeryfrac >> 4) - FixedMul(ffloor[i].b_pos, rw.scale); - i++; - } -#endif - } - } - -#ifdef POLYOBJECTS_PLANES - if (curline->polyseg && frontsector && (curline->polyseg->flags & POF_RENDERPLANES)) - { - while (i < numffloors && ffloor[i].polyobj != curline->polyseg) i++; - if (i < numffloors && backsector->floorheight <= frontsector->ceilingheight && - backsector->floorheight >= frontsector->floorheight && - (viewz < backsector->floorheight)) - { - if (ffloor[i].plane->minx > ds_p->x1) - ffloor[i].plane->minx = ds_p->x1; - - if (ffloor[i].plane->maxx < ds_p->x2) - ffloor[i].plane->maxx = ds_p->x2; - -#ifdef ESLOPE - ffloor[i].slope = NULL; -#endif - ffloor[i].b_pos = backsector->floorheight; - ffloor[i].b_pos = (ffloor[i].b_pos - viewz) >> 4; - ffloor[i].b_step = FixedMul(-rw.scalestep, ffloor[i].b_pos); - ffloor[i].b_frac = (centeryfrac >> 4) - FixedMul(ffloor[i].b_pos, rw.scale); - i++; - } - if (i < numffloors && backsector->ceilingheight >= frontsector->floorheight && - backsector->ceilingheight <= frontsector->ceilingheight && - (viewz > backsector->ceilingheight)) - { - if (ffloor[i].plane->minx > ds_p->x1) - ffloor[i].plane->minx = ds_p->x1; - - if (ffloor[i].plane->maxx < ds_p->x2) - ffloor[i].plane->maxx = ds_p->x2; - -#ifdef ESLOPE - ffloor[i].slope = NULL; -#endif - ffloor[i].b_pos = backsector->ceilingheight; - ffloor[i].b_pos = (ffloor[i].b_pos - viewz) >> 4; - ffloor[i].b_step = FixedMul(-rw.scalestep, ffloor[i].b_pos); - ffloor[i].b_frac = (centeryfrac >> 4) - FixedMul(ffloor[i].b_pos, rw.scale); - i++; - } - } -#endif - - numbackffloors = i; - } -} - -// -// R_WorldFFloorStep -// Does... stepping... stuff? For FOFs?! -// -static void R_WorldFFloorStep(INT32 range) -{ - INT32 i; - -#ifndef ESLOPE - (void)range; // Not needed! -#endif - - for (i = 0; i < numffloors; i++) - { - ffloor[i].f_pos >>= 4; -#ifdef ESLOPE - ffloor[i].f_pos_slope >>= 4; -#endif - if (linedef->special == HORIZONSPECIAL) // Horizon lines extend FOFs in contact with them too. - { - ffloor[i].f_step = 0; - ffloor[i].f_frac = (centeryfrac>>4); - topfrac++; // Prevent 1px HOM - } - else - { -#ifdef ESLOPE - ffloor[i].f_frac = (centeryfrac>>4) - FixedMul(ffloor[i].f_pos, rw.scale); - ffloor[i].f_step = ((centeryfrac>>4) - FixedMul(ffloor[i].f_pos_slope, ds_p->scale2) - ffloor[i].f_frac)/(range); -#else - ffloor[i].f_step = FixedMul(-rw.scalestep, ffloor[i].f_pos); - ffloor[i].f_frac = (centeryfrac>>4) - FixedMul(ffloor[i].f_pos, rw.scale); -#endif - } - } -} - -// -// R_WorldLightLists -// Creates light lists. -// -static void R_WorldLightLists(INT32 range) -{ - INT32 i, p; - lightlist_t *light; - r_lightlist_t *rlight; - -#ifndef ESLOPE - (void)range; // Not needed! -#endif dc_numlights = 0; @@ -1778,12 +2774,12 @@ static void R_WorldLightLists(INT32 range) } #ifdef ESLOPE - rlight->height = (centeryfrac>>4) - FixedMul(leftheight, rw.scale); + rlight->height = (centeryfrac>>4) - FixedMul(leftheight, rw_scale); rlight->heightstep = (centeryfrac>>4) - FixedMul(rightheight, ds_p->scale2); rlight->heightstep = (rlight->heightstep-rlight->height)/(range); #else - rlight->height = (centeryfrac>>4) - FixedMul((light->height - viewz) >> 4, rw.scale); - rlight->heightstep = -FixedMul (rw.scalestep, (light->height - viewz) >> 4); + rlight->height = (centeryfrac>>4) - FixedMul((light->height - viewz) >> 4, rw_scale); + rlight->heightstep = -FixedMul (rw_scalestep, (light->height - viewz) >> 4); #endif rlight->flags = light->flags; @@ -1805,13 +2801,13 @@ static void R_WorldLightLists(INT32 range) leftheight >>= 4; rightheight >>= 4; - rlight->botheight = (centeryfrac>>4) - FixedMul(leftheight, rw.scale); + rlight->botheight = (centeryfrac>>4) - FixedMul(leftheight, rw_scale); rlight->botheightstep = (centeryfrac>>4) - FixedMul(rightheight, ds_p->scale2); rlight->botheightstep = (rlight->botheightstep-rlight->botheight)/(range); #else - rlight->botheight = (centeryfrac >> 4) - FixedMul((*light->caster->bottomheight - viewz) >> 4, rw.scale); - rlight->botheightstep = -FixedMul (rw.scalestep, (*light->caster->bottomheight - viewz) >> 4); + rlight->botheight = (centeryfrac >> 4) - FixedMul((*light->caster->bottomheight - viewz) >> 4, rw_scale); + rlight->botheightstep = -FixedMul (rw_scalestep, (*light->caster->bottomheight - viewz) >> 4); #endif } @@ -1822,21 +2818,301 @@ static void R_WorldLightLists(INT32 range) dc_numlights = p; } -} -// -// R_MarkPlanes -// Creates visplanes. -// -static void R_MarkPlanes(void) -{ - INT32 i; + if (numffloors) + { + for (i = 0; i < numffloors; i++) + { + ffloor[i].f_pos >>= 4; +#ifdef ESLOPE + ffloor[i].f_pos_slope >>= 4; +#endif + if (linedef->special == HORIZONSPECIAL) // Horizon lines extend FOFs in contact with them too. + { + ffloor[i].f_step = 0; + ffloor[i].f_frac = (centeryfrac>>4); + topfrac++; // Prevent 1px HOM + } + else + { +#ifdef ESLOPE + ffloor[i].f_frac = (centeryfrac>>4) - FixedMul(ffloor[i].f_pos, rw_scale); + ffloor[i].f_step = ((centeryfrac>>4) - FixedMul(ffloor[i].f_pos_slope, ds_p->scale2) - ffloor[i].f_frac)/(range); +#else + ffloor[i].f_step = FixedMul(-rw_scalestep, ffloor[i].f_pos); + ffloor[i].f_frac = (centeryfrac>>4) - FixedMul(ffloor[i].f_pos, rw_scale); +#endif + } + } + } + + if (backsector) + { + worldhigh >>= 4; + worldlow >>= 4; +#ifdef ESLOPE + worldhighslope >>= 4; + worldlowslope >>= 4; +#endif + + if (toptexture) + { + pixhigh = (centeryfrac>>4) - FixedMul (worldhigh, rw_scale); + pixhighstep = -FixedMul (rw_scalestep,worldhigh); + +#ifdef ESLOPE + if (backsector->c_slope) { + fixed_t topfracend = (centeryfrac>>4) - FixedMul (worldhighslope, ds_p->scale2); + pixhighstep = (topfracend-pixhigh)/(range); + } +#endif + } + + if (bottomtexture) + { + pixlow = (centeryfrac>>4) - FixedMul (worldlow, rw_scale); + pixlowstep = -FixedMul (rw_scalestep,worldlow); +#ifdef ESLOPE + if (backsector->f_slope) { + fixed_t bottomfracend = (centeryfrac>>4) - FixedMul (worldlowslope, ds_p->scale2); + pixlowstep = (bottomfracend-pixlow)/(range); + } +#endif + } + + { + ffloor_t * rover; +#ifdef ESLOPE + fixed_t roverleft, roverright; + fixed_t planevistest; +#endif + i = 0; + + if (backsector->ffloors) + { + for (rover = backsector->ffloors; rover && i < MAXFFLOORS; rover = rover->next) + { + if (!(rover->flags & FF_EXISTS) || !(rover->flags & FF_RENDERPLANES)) + continue; + if (rover->norender == leveltime) + continue; + +#ifdef ESLOPE + // Let the renderer know this sector is sloped. + if (*rover->b_slope || *rover->t_slope) + backsector->hasslope = true; + + roverleft = (*rover->b_slope ? P_GetZAt(*rover->b_slope, segleft.x, segleft.y) : *rover->bottomheight) - viewz; + roverright = (*rover->b_slope ? P_GetZAt(*rover->b_slope, segright.x, segright.y) : *rover->bottomheight) - viewz; + planevistest = (*rover->b_slope ? P_GetZAt(*rover->b_slope, viewx, viewy) : *rover->bottomheight); + + if ((roverleft>>4 <= worldhigh || roverright>>4 <= worldhighslope) && + (roverleft>>4 >= worldlow || roverright>>4 >= worldlowslope) && + ((viewz < planevistest && !(rover->flags & FF_INVERTPLANES)) || + (viewz > planevistest && (rover->flags & FF_BOTHPLANES)))) + { + //ffloor[i].slope = *rover->b_slope; + ffloor[i].b_pos = roverleft; + ffloor[i].b_pos_slope = roverright; + ffloor[i].b_pos >>= 4; + ffloor[i].b_pos_slope >>= 4; + ffloor[i].b_frac = (centeryfrac >> 4) - FixedMul(ffloor[i].b_pos, rw_scale); + ffloor[i].b_step = (centeryfrac >> 4) - FixedMul(ffloor[i].b_pos_slope, ds_p->scale2); + ffloor[i].b_step = (ffloor[i].b_step-ffloor[i].b_frac)/(range); + i++; + } + + if (i >= MAXFFLOORS) + break; + + roverleft = (*rover->t_slope ? P_GetZAt(*rover->t_slope, segleft.x, segleft.y) : *rover->topheight) - viewz; + roverright = (*rover->t_slope ? P_GetZAt(*rover->t_slope, segright.x, segright.y) : *rover->topheight) - viewz; + planevistest = (*rover->t_slope ? P_GetZAt(*rover->t_slope, viewx, viewy) : *rover->topheight); + + if ((roverleft>>4 <= worldhigh || roverright>>4 <= worldhighslope) && + (roverleft>>4 >= worldlow || roverright>>4 >= worldlowslope) && + ((viewz > planevistest && !(rover->flags & FF_INVERTPLANES)) || + (viewz < planevistest && (rover->flags & FF_BOTHPLANES)))) + { + //ffloor[i].slope = *rover->t_slope; + ffloor[i].b_pos = roverleft; + ffloor[i].b_pos_slope = roverright; + ffloor[i].b_pos >>= 4; + ffloor[i].b_pos_slope >>= 4; + ffloor[i].b_frac = (centeryfrac >> 4) - FixedMul(ffloor[i].b_pos, rw_scale); + ffloor[i].b_step = (centeryfrac >> 4) - FixedMul(ffloor[i].b_pos_slope, ds_p->scale2); + ffloor[i].b_step = (ffloor[i].b_step-ffloor[i].b_frac)/(range); + i++; + } +#else + if (*rover->bottomheight <= backsector->ceilingheight && + *rover->bottomheight >= backsector->floorheight && + ((viewz < *rover->bottomheight && !(rover->flags & FF_INVERTPLANES)) || + (viewz > *rover->bottomheight && (rover->flags & FF_BOTHPLANES)))) + { + ffloor[i].b_pos = *rover->bottomheight; + ffloor[i].b_pos = (ffloor[i].b_pos - viewz) >> 4; + ffloor[i].b_step = FixedMul(-rw_scalestep, ffloor[i].b_pos); + ffloor[i].b_frac = (centeryfrac >> 4) - FixedMul(ffloor[i].b_pos, rw_scale); + i++; + } + + if (i >= MAXFFLOORS) + break; + + if (*rover->topheight >= backsector->floorheight && + *rover->topheight <= backsector->ceilingheight && + ((viewz > *rover->topheight && !(rover->flags & FF_INVERTPLANES)) || + (viewz < *rover->topheight && (rover->flags & FF_BOTHPLANES)))) + { + ffloor[i].b_pos = *rover->topheight; + ffloor[i].b_pos = (ffloor[i].b_pos - viewz) >> 4; + ffloor[i].b_step = FixedMul(-rw_scalestep, ffloor[i].b_pos); + ffloor[i].b_frac = (centeryfrac >> 4) - FixedMul(ffloor[i].b_pos, rw_scale); + i++; + } +#endif + } + } + else if (frontsector && frontsector->ffloors) + { + for (rover = frontsector->ffloors; rover && i < MAXFFLOORS; rover = rover->next) + { + if (!(rover->flags & FF_EXISTS) || !(rover->flags & FF_RENDERPLANES)) + continue; + if (rover->norender == leveltime) + continue; + + +#ifdef ESLOPE + // Let the renderer know this sector is sloped. + if (*rover->b_slope || *rover->t_slope) + frontsector->hasslope = true; + + roverleft = (*rover->b_slope ? P_GetZAt(*rover->b_slope, segleft.x, segleft.y) : *rover->bottomheight) - viewz; + roverright = (*rover->b_slope ? P_GetZAt(*rover->b_slope, segright.x, segright.y) : *rover->bottomheight) - viewz; + planevistest = (*rover->b_slope ? P_GetZAt(*rover->b_slope, viewx, viewy) : *rover->bottomheight); + + if ((roverleft>>4 <= worldhigh || roverright>>4 <= worldhighslope) && + (roverleft>>4 >= worldlow || roverright>>4 >= worldlowslope) && + ((viewz < planevistest && !(rover->flags & FF_INVERTPLANES)) || + (viewz > planevistest && (rover->flags & FF_BOTHPLANES)))) + { + //ffloor[i].slope = *rover->b_slope; + ffloor[i].b_pos = roverleft; + ffloor[i].b_pos_slope = roverright; + ffloor[i].b_pos >>= 4; + ffloor[i].b_pos_slope >>= 4; + ffloor[i].b_frac = (centeryfrac >> 4) - FixedMul(ffloor[i].b_pos, rw_scale); + ffloor[i].b_step = (centeryfrac >> 4) - FixedMul(ffloor[i].b_pos_slope, ds_p->scale2); + ffloor[i].b_step = (ffloor[i].b_step-ffloor[i].b_frac)/(range); + i++; + } + + if (i >= MAXFFLOORS) + break; + + roverleft = (*rover->t_slope ? P_GetZAt(*rover->t_slope, segleft.x, segleft.y) : *rover->topheight) - viewz; + roverright = (*rover->t_slope ? P_GetZAt(*rover->t_slope, segright.x, segright.y) : *rover->topheight) - viewz; + planevistest = (*rover->t_slope ? P_GetZAt(*rover->t_slope, viewx, viewy) : *rover->topheight); + + if ((roverleft>>4 <= worldhigh || roverright>>4 <= worldhighslope) && + (roverleft>>4 >= worldlow || roverright>>4 >= worldlowslope) && + ((viewz > planevistest && !(rover->flags & FF_INVERTPLANES)) || + (viewz < planevistest && (rover->flags & FF_BOTHPLANES)))) + { + //ffloor[i].slope = *rover->t_slope; + ffloor[i].b_pos = roverleft; + ffloor[i].b_pos_slope = roverright; + ffloor[i].b_pos >>= 4; + ffloor[i].b_pos_slope >>= 4; + ffloor[i].b_frac = (centeryfrac >> 4) - FixedMul(ffloor[i].b_pos, rw_scale); + ffloor[i].b_step = (centeryfrac >> 4) - FixedMul(ffloor[i].b_pos_slope, ds_p->scale2); + ffloor[i].b_step = (ffloor[i].b_step-ffloor[i].b_frac)/(range); + i++; + } +#else + if (*rover->bottomheight <= frontsector->ceilingheight && + *rover->bottomheight >= frontsector->floorheight && + ((viewz < *rover->bottomheight && !(rover->flags & FF_INVERTPLANES)) || + (viewz > *rover->bottomheight && (rover->flags & FF_BOTHPLANES)))) + { + ffloor[i].b_pos = *rover->bottomheight; + ffloor[i].b_pos = (ffloor[i].b_pos - viewz) >> 4; + ffloor[i].b_step = FixedMul(-rw_scalestep, ffloor[i].b_pos); + ffloor[i].b_frac = (centeryfrac >> 4) - FixedMul(ffloor[i].b_pos, rw_scale); + i++; + } + if (i >= MAXFFLOORS) + break; + if (*rover->topheight >= frontsector->floorheight && + *rover->topheight <= frontsector->ceilingheight && + ((viewz > *rover->topheight && !(rover->flags & FF_INVERTPLANES)) || + (viewz < *rover->topheight && (rover->flags & FF_BOTHPLANES)))) + { + ffloor[i].b_pos = *rover->topheight; + ffloor[i].b_pos = (ffloor[i].b_pos - viewz) >> 4; + ffloor[i].b_step = FixedMul(-rw_scalestep, ffloor[i].b_pos); + ffloor[i].b_frac = (centeryfrac >> 4) - FixedMul(ffloor[i].b_pos, rw_scale); + i++; + } +#endif + } + } +#ifdef POLYOBJECTS_PLANES + if (curline->polyseg && frontsector && (curline->polyseg->flags & POF_RENDERPLANES)) + { + while (i < numffloors && ffloor[i].polyobj != curline->polyseg) i++; + if (i < numffloors && backsector->floorheight <= frontsector->ceilingheight && + backsector->floorheight >= frontsector->floorheight && + (viewz < backsector->floorheight)) + { + if (ffloor[i].plane->minx > ds_p->x1) + ffloor[i].plane->minx = ds_p->x1; + + if (ffloor[i].plane->maxx < ds_p->x2) + ffloor[i].plane->maxx = ds_p->x2; + +#ifdef ESLOPE + ffloor[i].slope = NULL; +#endif + ffloor[i].b_pos = backsector->floorheight; + ffloor[i].b_pos = (ffloor[i].b_pos - viewz) >> 4; + ffloor[i].b_step = FixedMul(-rw_scalestep, ffloor[i].b_pos); + ffloor[i].b_frac = (centeryfrac >> 4) - FixedMul(ffloor[i].b_pos, rw_scale); + i++; + } + if (i < numffloors && backsector->ceilingheight >= frontsector->floorheight && + backsector->ceilingheight <= frontsector->ceilingheight && + (viewz > backsector->ceilingheight)) + { + if (ffloor[i].plane->minx > ds_p->x1) + ffloor[i].plane->minx = ds_p->x1; + + if (ffloor[i].plane->maxx < ds_p->x2) + ffloor[i].plane->maxx = ds_p->x2; + +#ifdef ESLOPE + ffloor[i].slope = NULL; +#endif + ffloor[i].b_pos = backsector->ceilingheight; + ffloor[i].b_pos = (ffloor[i].b_pos - viewz) >> 4; + ffloor[i].b_step = FixedMul(-rw_scalestep, ffloor[i].b_pos); + ffloor[i].b_frac = (centeryfrac >> 4) - FixedMul(ffloor[i].b_pos, rw_scale); + i++; + } + } +#endif + + numbackffloors = i; + } + } // get a new or use the same visplane if (markceiling) { if (ceilingplane) //SoM: 3/29/2000: Check for null ceiling planes - ceilingplane = R_CheckPlane (ceilingplane, rw.x, rw.stopx-1); + ceilingplane = R_CheckPlane (ceilingplane, rw_x, rw_stopx-1); else markceiling = false; @@ -1850,7 +3126,7 @@ static void R_MarkPlanes(void) if (markfloor) { if (floorplane) //SoM: 3/29/2000: Check for null planes - floorplane = R_CheckPlane (floorplane, rw.x, rw.stopx-1); + floorplane = R_CheckPlane (floorplane, rw_x, rw_stopx-1); else markfloor = false; @@ -1870,7 +3146,7 @@ static void R_MarkPlanes(void) for (i = 0; i < numffloors; i++) { ds_p->ffloorplanes[i] = ffloor[i].plane = - R_CheckPlane(ffloor[i].plane, rw.x, rw.stopx - 1); + R_CheckPlane(ffloor[i].plane, rw_x, rw_stopx - 1); } firstseg = ds_p; @@ -1878,7 +3154,7 @@ static void R_MarkPlanes(void) else { for (i = 0; i < numffloors; i++) - R_ExpandPlane(ffloor[i].plane, rw.x, rw.stopx - 1); + R_ExpandPlane(ffloor[i].plane, rw_x, rw_stopx - 1); } #ifdef POLYOBJECTS_PLANES // FIXME hack to fix planes disappearing when a seg goes behind the camera. This NEEDS to be changed to be done properly. -Red @@ -1888,251 +3164,15 @@ static void R_MarkPlanes(void) { if (!ffloor[i].polyobj || ffloor[i].polyobj != curline->polyseg) continue; - if (ffloor[i].plane->minx > rw.x) - ffloor[i].plane->minx = rw.x; + if (ffloor[i].plane->minx > rw_x) + ffloor[i].plane->minx = rw_x; - if (ffloor[i].plane->maxx < rw.stopx - 1) - ffloor[i].plane->maxx = rw.stopx - 1; + if (ffloor[i].plane->maxx < rw_stopx - 1) + ffloor[i].plane->maxx = rw_stopx - 1; } } #endif } -} - -// -// R_RemoveOpeningLimits -// Code to remove limits on openings. -// -static void R_RemoveOpeningLimits(INT32 start) -{ - size_t pos = lastopening - openings; - size_t need = (rw.stopx - start)*4 + pos; - if (need > maxopenings) - { - drawseg_t *ds; //needed for fix from *cough* zdoom *cough* - INT16 *oldopenings = openings; - INT16 *oldlast = lastopening; - - do - maxopenings = maxopenings ? maxopenings*2 : 16384; - while (need > maxopenings); - openings = Z_Realloc(openings, maxopenings * sizeof (*openings), PU_STATIC, NULL); - lastopening = openings + pos; - - // borrowed fix from *cough* zdoom *cough* - // [RH] We also need to adjust the openings pointers that - // were already stored in drawsegs. - for (ds = drawsegs; ds < ds_p; ds++) - { -#define ADJUST(p) if (ds->p + ds->x1 >= oldopenings && ds->p + ds->x1 <= oldlast) ds->p = ds->p - oldopenings + openings; - ADJUST(maskedtexturecol); - ADJUST(sprtopclip); - ADJUST(sprbottomclip); - ADJUST(thicksidecol); -#undef ADJUST - } - } -} - -// -// R_StoreWallRange -// A wall segment will be drawn -// between start and stop pixels (inclusive). -// -void R_StoreWallRange(INT32 start, INT32 stop) -{ - fixed_t hyp; - fixed_t sineval; - angle_t distangle, offsetangle; - boolean longboi; -#ifndef ESLOPE - fixed_t vtop; -#endif - INT32 i; - INT32 range; - static size_t maxdrawsegs = 0; - -#ifdef ESLOPE - maskedtextureheight = NULL; - //initialize segleft and segright - memset(&segleft, 0x00, sizeof(segleft)); - memset(&segright, 0x00, sizeof(segright)); -#endif - - colfunc = colfuncs[BASEDRAWFUNC]; - - if (ds_p == drawsegs+maxdrawsegs) - { - size_t curpos = curdrawsegs - drawsegs; - size_t pos = ds_p - drawsegs; - size_t newmax = maxdrawsegs ? maxdrawsegs*2 : 128; - if (firstseg) - firstseg = (drawseg_t *)(firstseg - drawsegs); - drawsegs = Z_Realloc(drawsegs, newmax*sizeof (*drawsegs), PU_STATIC, NULL); - ds_p = drawsegs + pos; - maxdrawsegs = newmax; - curdrawsegs = drawsegs + curpos; - if (firstseg) - firstseg = drawsegs + (size_t)firstseg; - } - - sidedef = curline->sidedef; - linedef = curline->linedef; - - // calculate rw.distance for scale calculation - rw.normalangle = curline->angle + ANGLE_90; - offsetangle = abs((INT32)(rw.normalangle-rw.angle1)); - - if (offsetangle > ANGLE_90) - offsetangle = ANGLE_90; - - distangle = ANGLE_90 - offsetangle; - sineval = FINESINE(distangle>>ANGLETOFINESHIFT); - - hyp = R_PointToDist(curline->v1->x, curline->v1->y); - longboi = (hyp >= INT32_MAX); - - // The seg is vertical. - if (curline->v1->y == curline->v2->y) - rw.distance = (fixed_t)(llabs(viewy - curline->v1->y)); - // The seg is horizontal. - else if (curline->v1->x == curline->v2->x) - rw.distance = (fixed_t)(llabs(viewx - curline->v1->x)); - // big room fix -#ifdef SOFTWARE_USE_FLOATS - else if ((curline->length >= 1024<x1 = rw.x = start; - ds_p->x2 = stop; - ds_p->curline = curline; - rw.stopx = stop+1; - - //SoM: Code to remove limits on openings. - R_RemoveOpeningLimits(start); - - // calculate scale at both ends and step - range = R_CalculateWallScale(start, stop); - - // calculate texture boundaries - // and decide if floor / ceiling marks are needed - R_WorldTopAndBottom(start, stop); - - midtexture = toptexture = bottomtexture = maskedtexture = 0; - ds_p->maskedtexturecol = NULL; - ds_p->numthicksides = numthicksides = 0; - ds_p->thicksidecol = NULL; - ds_p->tsilheight = 0; - - numbackffloors = 0; - - for (i = 0; i < MAXFFLOORS; i++) - ds_p->thicksides[i] = NULL; - - if (numffloors) - { - for (i = 0; i < numffloors; i++) - { -#ifdef POLYOBJECTS_PLANES - if (ffloor[i].polyobj && (!ds_p->curline->polyseg || ffloor[i].polyobj != ds_p->curline->polyseg)) - continue; -#endif - -#ifdef ESLOPE - if (ffloor[i].slope) { - ffloor[i].f_pos = P_GetZAt(ffloor[i].slope, segleft.x, segleft.y) - viewz; - ffloor[i].f_pos_slope = P_GetZAt(ffloor[i].slope, segright.x, segright.y) - viewz; - } else - ffloor[i].f_pos_slope = -#endif - ffloor[i].f_pos = ffloor[i].height - viewz; - } - } - -#ifdef ESLOPE - // Set up texture Y offset slides for sloped walls - rw.toptextureslide = rw.midtextureslide = rw.bottomtextureslide = 0; - ceilingfrontslide = floorfrontslide = ceilingbackslide = floorbackslide = 0; - - { - angle_t lineangle = R_PointToAngle2(curline->v1->x, curline->v1->y, curline->v2->x, curline->v2->y); - - if (frontsector->f_slope) - floorfrontslide = FixedMul(frontsector->f_slope->zdelta, FINECOSINE((lineangle-frontsector->f_slope->xydirection)>>ANGLETOFINESHIFT)); - - if (frontsector->c_slope) - ceilingfrontslide = FixedMul(frontsector->c_slope->zdelta, FINECOSINE((lineangle-frontsector->c_slope->xydirection)>>ANGLETOFINESHIFT)); - - if (backsector && backsector->f_slope) - floorbackslide = FixedMul(backsector->f_slope->zdelta, FINECOSINE((lineangle-backsector->f_slope->xydirection)>>ANGLETOFINESHIFT)); - - if (backsector && backsector->c_slope) - ceilingbackslide = FixedMul(backsector->c_slope->zdelta, FINECOSINE((lineangle-backsector->c_slope->xydirection)>>ANGLETOFINESHIFT)); - } -#endif - - // Check for textures - R_StoreWallSilhouette(); - R_CheckWallTextures(); - if (backsector) - R_CheckMaskedTextures(); - -#undef SLOPEPARAMS - - // Calculate rw.offset (only needed for textured lines) - segtextured = midtexture || toptexture || bottomtexture || maskedtexture || (numthicksides > 0); - if (segtextured) - R_SegTextured(hyp, longboi); - - // if a floor / ceiling plane is on the wrong side - // of the view plane, it is definitely invisible - // and doesn't need to be marked. - if (frontsector->heightsec == -1) - { - if (frontsector->floorpic != skyflatnum - && ( -#ifdef ESLOPE - frontsector->f_slope ? P_GetZAt(frontsector->f_slope, viewx, viewy) : -#endif - frontsector->floorheight) >= viewz) - { - // above view plane - markfloor = false; - } - - if (frontsector->ceilingpic != skyflatnum - && ( -#ifdef ESLOPE - frontsector->c_slope ? P_GetZAt(frontsector->c_slope, viewx, viewy) : -#endif - frontsector->ceilingheight) <= viewz) - { - // below view plane - markceiling = false; - } - } - - // Calculate incremental stepping values for texture edges - R_WorldStep(range); - - // Create light lists - R_WorldLightLists(range); - - // Step FOFs - if (numffloors) - R_WorldFFloorStep(range); - - // Step world back - if (backsector) - R_WorldBackStep(range); - - // Mark floor and or ceiling visplanes - R_MarkPlanes(); #ifdef WALLSPLATS if (linedef->splats && cv_splats.value) @@ -2158,16 +3198,16 @@ void R_StoreWallRange(INT32 start, INT32 stop) // save sprite clipping info if (((ds_p->silhouette & SIL_TOP) || maskedtexture) && !ds_p->sprtopclip) { - M_Memcpy(lastopening, ceilingclip+start, 2*(rw.stopx - start)); + M_Memcpy(lastopening, ceilingclip+start, 2*(rw_stopx - start)); ds_p->sprtopclip = lastopening - start; - lastopening += rw.stopx - start; + lastopening += rw_stopx - start; } if (((ds_p->silhouette & SIL_BOTTOM) || maskedtexture) && !ds_p->sprbottomclip) { - M_Memcpy(lastopening, floorclip + start, 2*(rw.stopx-start)); + M_Memcpy(lastopening, floorclip + start, 2*(rw_stopx-start)); ds_p->sprbottomclip = lastopening - start; - lastopening += rw.stopx - start; + lastopening += rw_stopx - start; } if (maskedtexture && !(ds_p->silhouette & SIL_TOP)) @@ -2180,1314 +3220,5 @@ void R_StoreWallRange(INT32 start, INT32 stop) ds_p->silhouette |= SIL_BOTTOM; ds_p->bsilheight = (sidedef->midtexture > 0 && sidedef->midtexture < numtextures) ? INT32_MAX: INT32_MIN; } - ds_p++; } - -// ========================================================================== -// R_Splats Wall Splats Drawer -// ========================================================================== - -#ifdef WALLSPLATS -static INT16 last_ceilingclip[MAXVIDWIDTH]; -static INT16 last_floorclip[MAXVIDWIDTH]; - -static void R_DrawSplatColumn(column_t *column) -{ - INT32 topscreen, bottomscreen; - fixed_t basetexturemid; - INT32 topdelta, prevdelta = -1; - - basetexturemid = dc_texturemid; - - for (; column->topdelta != 0xff ;) - { - // calculate unclipped screen coordinates for post - topdelta = column->topdelta; - if (topdelta <= prevdelta) - topdelta += prevdelta; - prevdelta = topdelta; - topscreen = sprtopscreen + spryscale*topdelta; - bottomscreen = topscreen + spryscale*column->length; - - dc_yl = (topscreen+FRACUNIT-1)>>FRACBITS; - dc_yh = (bottomscreen-1)>>FRACBITS; - - if (dc_yh >= last_floorclip[dc_x]) - dc_yh = last_floorclip[dc_x] - 1; - if (dc_yl <= last_ceilingclip[dc_x]) - dc_yl = last_ceilingclip[dc_x] + 1; - if (dc_yl <= dc_yh && dl_yh < vid.height && yh > 0) - { - dc_source = (UINT8 *)column + 3; - dc_texturemid = basetexturemid - (topdelta<length + 4); - } - - dc_texturemid = basetexturemid; -} - -static void R_DrawWallSplats(void) -{ - wallsplat_t *splat; - seg_t *seg; - angle_t angle, angle1, angle2; - INT32 x1, x2; - size_t pindex; - column_t *col; - patch_t *patch; - fixed_t texturecolumn; - - splat = (wallsplat_t *)linedef->splats; - - I_Assert(splat != NULL); - - seg = ds_p->curline; - - // draw all splats from the line that touches the range of the seg - for (; splat; splat = splat->next) - { - angle1 = R_PointToAngle(splat->v1.x, splat->v1.y); - angle2 = R_PointToAngle(splat->v2.x, splat->v2.y); - angle1 = (angle1 - viewangle + ANGLE_90)>>ANGLETOFINESHIFT; - angle2 = (angle2 - viewangle + ANGLE_90)>>ANGLETOFINESHIFT; - // out of the viewangletox lut - /// \todo clip it to the screen - if (angle1 > FINEANGLES/2 || angle2 > FINEANGLES/2) - continue; - x1 = viewangletox[angle1]; - x2 = viewangletox[angle2]; - - if (x1 >= x2) - continue; // does not cross a pixel - - // splat is not in this seg range - if (x2 < ds_p->x1 || x1 > ds_p->x2) - continue; - - if (x1 < ds_p->x1) - x1 = ds_p->x1; - if (x2 > ds_p->x2) - x2 = ds_p->x2; - if (x2 <= x1) - continue; - - // calculate incremental stepping values for texture edges - rw.scalestep = ds_p->scalestep; - spryscale = ds_p->scale1 + (x1 - ds_p->x1)*rw.scalestep; - mfloorclip = floorclip; - mceilingclip = ceilingclip; - - patch = W_CachePatchNum(splat->patch, PU_PATCH); - - dc_texturemid = splat->top + (SHORT(patch->height)<<(FRACBITS-1)) - viewz; - if (splat->yoffset) - dc_texturemid += *splat->yoffset; - - sprtopscreen = centeryfrac - FixedMul(dc_texturemid, spryscale); - - // set drawing mode - switch (splat->flags & SPLATDRAWMODE_MASK) - { - case SPLATDRAWMODE_OPAQUE: - colfunc = colfuncs[BASEDRAWFUNC]; - break; - case SPLATDRAWMODE_TRANS: - if (!cv_translucency.value) - colfunc = colfuncs[BASEDRAWFUNC]; - else - { - dc_transmap = transtables + ((tr_trans50 - 1)<>LIGHTSCALESHIFT; - if (pindex >= MAXLIGHTSCALE) - pindex = MAXLIGHTSCALE - 1; - dc_colormap = walllights[pindex]; - - if (frontsector->extra_colormap) - dc_colormap = frontsector->extra_colormap->colormap + (dc_colormap - colormaps); - - sprtopscreen = centeryfrac - FixedMul(dc_texturemid, spryscale); - dc_iscale = 0xffffffffu / (unsigned)spryscale; - - // find column of patch, from perspective - angle = (rw.centerangle + xtoviewangle[dc_x])>>ANGLETOFINESHIFT; - texturecolumn = rw.offset2 - splat->offset - - FixedMul(FINETANGENT(angle), rw.distance); - - // FIXME! - texturecolumn >>= FRACBITS; - if (texturecolumn < 0 || texturecolumn >= SHORT(patch->width)) - continue; - - // draw the texture - col = (column_t *)((UINT8 *)patch + LONG(patch->columnofs[texturecolumn])); - R_DrawSplatColumn(col); - } - } // next splat - - colfunc = colfuncs[BASEDRAWFUNC]; -} - -#endif //WALLSPLATS - -// ========================================================================== -// R_RenderMaskedSegRange -// ========================================================================== - -// If we have a multi-patch texture on a 2sided wall (rare) then we draw -// it using R_DrawColumn, else we draw it using R_DrawMaskedColumn, this -// way we don't have to store extra post_t info with each column for -// multi-patch textures. They are not normally needed as multi-patch -// textures don't have holes in it. At least not for now. - -static void R_Render2sidedMultiPatchColumn(column_t *column) -{ - INT32 topscreen, bottomscreen; - - topscreen = sprtopscreen; // + spryscale*column->topdelta; topdelta is 0 for the wall - bottomscreen = topscreen + spryscale * rw.column2s_length; - - dc_yl = (sprtopscreen+FRACUNIT-1)>>FRACBITS; - dc_yh = (bottomscreen-1)>>FRACBITS; - - if (windowtop != INT32_MAX && windowbottom != INT32_MAX) - { - dc_yl = ((windowtop + FRACUNIT)>>FRACBITS); - dc_yh = (windowbottom - 1)>>FRACBITS; - } - - if (dc_yh >= mfloorclip[dc_x]) - dc_yh = mfloorclip[dc_x] - 1; - if (dc_yl <= mceilingclip[dc_x]) - dc_yl = mceilingclip[dc_x] + 1; - - if (dc_yl >= vid.height || dc_yh < 0) - return; - - if (dc_yl <= dc_yh && dc_yh < vid.height && dc_yh > 0) - { - dc_source = (UINT8 *)column + 3; - - if (colfunc == colfuncs[BASEDRAWFUNC]) - (colfuncs[COLDRAWFUNC_TWOSMULTIPATCH])(); - else if (colfunc == colfuncs[COLDRAWFUNC_FUZZY]) - (colfuncs[COLDRAWFUNC_TWOSMULTIPATCHTRANS])(); - else - colfunc(); - } -} - -// quick wrapper for R_DrawFlippedMaskedColumn so it can be set as a colfunc_2s value -// uses column2s_length for texture->height as above -static void R_DrawFlippedMaskedSegColumn(column_t *column) -{ - R_DrawFlippedMaskedColumn(column, rw.column2s_length); -} - -// -// R_RenderMaskedSegLoop -// Like R_RenderSegLoop, but for masked segs. -// -static void R_RenderMaskedSegLoop(drawseg_t *ds) -{ - size_t pindex; - column_t *col; - INT32 i; - fixed_t height, realbot; - r_lightlist_t *rlight; - INT64 overflow_test; - - for (dc_x = rw.x; dc_x <= rw.stopx; dc_x++) - { -#ifdef ESLOPE - dc_texturemid = ds->maskedtextureheight[dc_x]; - - if (!!(curline->linedef->flags & ML_DONTPEGBOTTOM) ^ !!(curline->linedef->flags & ML_EFFECT3)) - dc_texturemid += (textureheight[rw.texnum])*rw.maskedrepeat + textureheight[rw.texnum]; - else - dc_texturemid -= (textureheight[rw.texnum])*rw.maskedrepeat; -#endif - // calculate lighting - if (maskedtexturecol[dc_x] != INT16_MAX) - { - // Check for overflows first - overflow_test = (INT64)centeryfrac - (((INT64)dc_texturemid*spryscale)>>FRACBITS); - if (overflow_test < 0) overflow_test = -overflow_test; - if ((UINT64)overflow_test&0xFFFFFFFF80000000ULL) - { - // Eh, no, go away, don't waste our time - if (dc_numlights) - { - for (i = 0; i < dc_numlights; i++) - { - rlight = &dc_lightlist[i]; - rlight->height += rlight->heightstep; - } - } - spryscale += rw.scalestep; - continue; - } - - if (dc_numlights) - { - lighttable_t **xwalllights; - - sprbotscreen = INT32_MAX; - sprtopscreen = windowtop = (centeryfrac - FixedMul(dc_texturemid, spryscale)); - - realbot = windowbottom = FixedMul(textureheight[rw.texnum], spryscale) + sprtopscreen; - dc_iscale = 0xffffffffu / (unsigned)spryscale; - - // draw the texture - col = (column_t *)((UINT8 *)R_GetColumn(rw.texnum, maskedtexturecol[dc_x]) - 3); - - for (i = 0; i < dc_numlights; i++) - { - rlight = &dc_lightlist[i]; - - if ((rlight->flags & FF_NOSHADE)) - continue; - - if (rlight->lightnum < 0) - xwalllights = scalelight[0]; - else if (rlight->lightnum >= LIGHTLEVELS) - xwalllights = scalelight[LIGHTLEVELS-1]; - else - xwalllights = scalelight[rlight->lightnum]; - - pindex = FixedMul(spryscale, FixedDiv(640, vid.width))>>LIGHTSCALESHIFT; - - if (pindex >= MAXLIGHTSCALE) - pindex = MAXLIGHTSCALE - 1; - - if (rlight->extra_colormap) - rlight->rcolormap = rlight->extra_colormap->colormap + (xwalllights[pindex] - colormaps); - else - rlight->rcolormap = xwalllights[pindex]; - - height = rlight->height; - rlight->height += rlight->heightstep; - - if (height <= windowtop) - { - dc_colormap = rlight->rcolormap; - continue; - } - - windowbottom = height; - if (windowbottom >= realbot) - { - windowbottom = realbot; - rw.colfunc_2s(col); - for (i++; i < dc_numlights; i++) - { - rlight = &dc_lightlist[i]; - rlight->height += rlight->heightstep; - } - - continue; - } - rw.colfunc_2s(col); - windowtop = windowbottom + 1; - dc_colormap = rlight->rcolormap; - } - windowbottom = realbot; - if (windowtop < windowbottom) - rw.colfunc_2s(col); - - spryscale += rw.scalestep; - continue; - } - - // calculate lighting - pindex = FixedMul(spryscale, FixedDiv(640, vid.width))>>LIGHTSCALESHIFT; - - if (pindex >= MAXLIGHTSCALE) - pindex = MAXLIGHTSCALE - 1; - - dc_colormap = walllights[pindex]; - - if (frontsector->extra_colormap) - dc_colormap = frontsector->extra_colormap->colormap + (dc_colormap - colormaps); - - sprtopscreen = centeryfrac - FixedMul(dc_texturemid, spryscale); - dc_iscale = 0xffffffffu / (unsigned)spryscale; - - // draw the texture - col = (column_t *)((UINT8 *)R_GetColumn(rw.texnum, maskedtexturecol[dc_x]) - 3); - -//#ifdef POLYOBJECTS_PLANES -#if 0 // Disabling this allows inside edges to render below the planes, for until the clipping is fixed to work right when POs are near the camera. -Red - if (curline->dontrenderme && curline->polyseg && (curline->polyseg->flags & POF_RENDERPLANES)) - { - fixed_t my_topscreen; - fixed_t my_bottomscreen; - fixed_t my_yl, my_yh; - - my_topscreen = sprtopscreen + spryscale*col->topdelta; - my_bottomscreen = sprbotscreen == INT32_MAX ? my_topscreen + spryscale*col->length - : sprbotscreen + spryscale*col->length; - - my_yl = (my_topscreen+FRACUNIT-1)>>FRACBITS; - my_yh = (my_bottomscreen-1)>>FRACBITS; -// CONS_Debug(DBG_RENDER, "my_topscreen: %d\nmy_bottomscreen: %d\nmy_yl: %d\nmy_yh: %d\n", my_topscreen, my_bottomscreen, my_yl, my_yh); - - if (numffloors) - { - INT32 top = my_yl; - INT32 bottom = my_yh; - - for (i = 0; i < numffloors; i++) - { - if (!ffloor[i].polyobj || ffloor[i].polyobj != curline->polyseg) - continue; - - if (ffloor[i].height < viewz) - { - INT32 top_w = ffloor[i].plane->top[dc_x]; - -// CONS_Debug(DBG_RENDER, "Leveltime : %d\n", leveltime); -// CONS_Debug(DBG_RENDER, "Top is %d, top_w is %d\n", top, top_w); - if (top_w < top) - { - ffloor[i].plane->top[dc_x] = (INT16)top; - ffloor[i].plane->picnum = 0; - } -// CONS_Debug(DBG_RENDER, "top_w is now %d\n", ffloor[i].plane->top[dc_x]); - } - else if (ffloor[i].height > viewz) - { - INT32 bottom_w = ffloor[i].plane->bottom[dc_x]; - - if (bottom_w > bottom) - { - ffloor[i].plane->bottom[dc_x] = (INT16)bottom; - ffloor[i].plane->picnum = 0; - } - } - } - } - } - else -#endif - rw.colfunc_2s(col); - } - spryscale += rw.scalestep; - } -} - -// -// R_MaskedLightLists -// Creates light lists, but for masked segs. -// -static void R_MaskedLightLists(drawseg_t *ds, INT32 range) -{ - lightlist_t *light; - r_lightlist_t *rlight; - INT32 lightnum, i; - - dc_numlights = 0; - - if (frontsector->numlights) - { - dc_numlights = frontsector->numlights; - if (dc_numlights >= dc_maxlights) - { - dc_maxlights = dc_numlights; - dc_lightlist = Z_Realloc(dc_lightlist, sizeof (*dc_lightlist) * dc_maxlights, PU_STATIC, NULL); - } - - for (i = 0; i < dc_numlights; i++) - { -#ifdef ESLOPE - fixed_t leftheight, rightheight; -#else - (void)range; -#endif - light = &frontsector->lightlist[i]; - rlight = &dc_lightlist[i]; -#ifdef ESLOPE - if (light->slope) { - leftheight = P_GetZAt(light->slope, ds->leftpos.x, ds->leftpos.y); - rightheight = P_GetZAt(light->slope, ds->rightpos.x, ds->rightpos.y); - } else - leftheight = rightheight = light->height; - - leftheight -= viewz; - rightheight -= viewz; - - rlight->height = (centeryfrac) - FixedMul(leftheight, ds->scale1); - rlight->heightstep = (centeryfrac) - FixedMul(rightheight, ds->scale2); - rlight->heightstep = (rlight->heightstep-rlight->height)/(range); - //if (x1 > ds->x1) - //rlight->height -= (x1 - ds->x1)*rlight->heightstep; -#else - rlight->height = (centeryfrac) - FixedMul((light->height - viewz), spryscale); - rlight->heightstep = -FixedMul(rw.scalestep, (light->height - viewz)); -#endif - rlight->startheight = rlight->height; // keep starting value here to reset for each repeat - rlight->lightlevel = *light->lightlevel; - rlight->extra_colormap = *light->extra_colormap; - rlight->flags = light->flags; - - if (rlight->flags & FF_FOG || (rlight->extra_colormap && rlight->extra_colormap->fog)) - lightnum = (rlight->lightlevel >> LIGHTSEGSHIFT); - else if (colfunc == colfuncs[COLDRAWFUNC_FUZZY]) - lightnum = LIGHTLEVELS - 1; - else - lightnum = (rlight->lightlevel >> LIGHTSEGSHIFT); - - if (rlight->extra_colormap && rlight->extra_colormap->fog) - ; - else if (curline->v1->y == curline->v2->y) - lightnum--; - else if (curline->v1->x == curline->v2->x) - lightnum++; - - rlight->lightnum = lightnum; - } - } - else - { - if (colfunc == colfuncs[COLDRAWFUNC_FUZZY]) - { - if (frontsector->extra_colormap && frontsector->extra_colormap->fog) - lightnum = (frontsector->lightlevel >> LIGHTSEGSHIFT); - else - lightnum = LIGHTLEVELS - 1; - } - else - lightnum = (frontsector->lightlevel >> LIGHTSEGSHIFT); - - if (colfunc == colfuncs[COLDRAWFUNC_FOG] - || (frontsector->extra_colormap && frontsector->extra_colormap->fog)) - ; - else if (curline->v1->y == curline->v2->y) - lightnum--; - else if (curline->v1->x == curline->v2->x) - lightnum++; - - if (lightnum < 0) - walllights = scalelight[0]; - else if (lightnum >= LIGHTLEVELS) - walllights = scalelight[LIGHTLEVELS - 1]; - else - walllights = scalelight[lightnum]; - } -} - -// -// R_RenderMaskedSegRange -// Renders all the masked segs in the given range. -// -void R_RenderMaskedSegRange(drawseg_t *ds, INT32 x1, INT32 x2) -{ - INT32 texnum, i; - r_lightlist_t *rlight; - line_t *ldef; - sector_t *front, *back; - INT32 times, repeats; - INT32 range; - - // Calculate light table. - // Use different light tables - // for horizontal / vertical / diagonal. Diagonal? - // OPTIMIZE: get rid of LIGHTSEGSHIFT globally - curline = ds->curline; - frontsector = curline->frontsector; - backsector = curline->backsector; - texnum = R_GetTextureNum(curline->sidedef->midtexture); - windowbottom = windowtop = sprbotscreen = INT32_MAX; - - rw.x = x1; - rw.stopx = x2; - rw.texnum = texnum; - - // hack translucent linedef types (900-909 for transtables 1-9) - ldef = curline->linedef; - switch (ldef->special) - { - case 900: - case 901: - case 902: - case 903: - case 904: - case 905: - case 906: - case 907: - case 908: - dc_transmap = transtables + ((ldef->special-900)<ceilingheight; - windowbottom = frontsector->floorheight; - break; - default: - colfunc = colfuncs[BASEDRAWFUNC]; - break; - } - - if (curline->polyseg && curline->polyseg->translucency > 0) - { - if (curline->polyseg->translucency >= NUMTRANSMAPS) - return; - - dc_transmap = transtables + ((curline->polyseg->translucency-1)<x2-ds->x1, 1); -#endif - rw.scalestep = ds->scalestep; - spryscale = ds->scale1 + (x1 - ds->x1)*rw.scalestep; - - // Texture must be cached before setting colfunc_2s, - // otherwise texture[texnum]->holes may be false when it shouldn't be - R_CheckTextureCache(texnum); - // handle case where multipatch texture is drawn on a 2sided wall, multi-patch textures - // are not stored per-column with post info in SRB2 - if (textures[texnum]->holes) - { - if (textures[texnum]->flip & 2) // vertically flipped? - { - rw.colfunc_2s = R_DrawFlippedMaskedSegColumn; - rw.column2s_length = textures[texnum]->height; - } - else - rw.colfunc_2s = R_DrawMaskedColumn; // render the usual 2sided single-patch packed texture - } - else - { - rw.colfunc_2s = R_Render2sidedMultiPatchColumn; // render multipatch with no holes (no post_t info) - rw.column2s_length = textures[texnum]->height; - } - - // Setup lighting based on the presence/lack-of 3D floors. - R_MaskedLightLists(ds, range); - - maskedtexturecol = ds->maskedtexturecol; - - mfloorclip = ds->sprbottomclip; - mceilingclip = ds->sprtopclip; - - if (frontsector->heightsec != -1) - front = §ors[frontsector->heightsec]; - else - front = frontsector; - - if (backsector->heightsec != -1) - back = §ors[backsector->heightsec]; - else - back = backsector; - - if (ds->curline->sidedef->repeatcnt) - repeats = 1 + ds->curline->sidedef->repeatcnt; - else if (ldef->flags & ML_EFFECT5) - { - fixed_t high, low; - - if (front->ceilingheight > back->ceilingheight) - high = back->ceilingheight; - else - high = front->ceilingheight; - - if (front->floorheight > back->floorheight) - low = front->floorheight; - else - low = back->floorheight; - - repeats = (high - low)/textureheight[texnum]; - if ((high-low)%textureheight[texnum]) - repeats++; // tile an extra time to fill the gap -- Monster Iestyn - } - else - repeats = 1; - - for (times = 0; times < repeats; times++) - { - if (times > 0) - { - rw.scalestep = ds->scalestep; - spryscale = ds->scale1 + (x1 - ds->x1)*rw.scalestep; - if (dc_numlights) - { // reset all lights to their starting heights - for (i = 0; i < dc_numlights; i++) - { - rlight = &dc_lightlist[i]; - rlight->height = rlight->startheight; - } - } - } - -#ifndef ESLOPE - if (curline->linedef->flags & ML_DONTPEGBOTTOM) - { - dc_texturemid = front->floorheight > back->floorheight - ? front->floorheight : back->floorheight; - dc_texturemid = dc_texturemid + textureheight[texnum] - viewz; - } - else - { - dc_texturemid = front->ceilingheight < back->ceilingheight - ? front->ceilingheight : back->ceilingheight; - dc_texturemid = dc_texturemid - viewz; - } - dc_texturemid += curline->sidedef->rowoffset; - - if (curline->linedef->flags & ML_DONTPEGBOTTOM) - dc_texturemid += (textureheight[texnum])*times; - else - dc_texturemid -= (textureheight[texnum])*times; -#endif - - dc_texheight = textureheight[texnum]>>FRACBITS; - - // draw the columns - rw.maskedrepeat = times; - R_RenderMaskedSegLoop(ds); - } - colfunc = colfuncs[BASEDRAWFUNC]; -} - -// Loop through R_DrawMaskedColumn calls -static void R_DrawRepeatMaskedColumn(column_t *col) -{ - while (sprtopscreen < sprbotscreen) { - R_DrawMaskedColumn(col); - if ((INT64)sprtopscreen + dc_texheight*spryscale > (INT64)INT32_MAX) // prevent overflow - sprtopscreen = INT32_MAX; - else - sprtopscreen += dc_texheight*spryscale; - } -} - -static void R_DrawRepeatFlippedMaskedColumn(column_t *col) -{ - do { - R_DrawFlippedMaskedColumn(col, rw.column2s_length); - sprtopscreen += dc_texheight*spryscale; - } while (sprtopscreen < sprbotscreen); -} - -// -// R_RenderThickSegLoop -// Like R_RenderSegLoop, but for thick sides. -// -static void R_RenderThickSegLoop(void) -{ - column_t *col; - size_t pindex; - INT32 i; - INT32 lightnum; - r_lightlist_t *rlight; - - ffloor_t *pfloor = rw.pfloor; - fixed_t bottombounds = viewheight << FRACBITS; - fixed_t topbounds = (con_clipviewtop - 1) << FRACBITS; - -#ifdef ESLOPE - INT32 oldx = -1; -#endif - - for (dc_x = rw.x; dc_x <= rw.stopx; dc_x++) - { - if (maskedtexturecol[dc_x] != INT16_MAX) - { -#ifdef ESLOPE - if (rw.ffloortextureslide) { // skew FOF walls - if (oldx != -1) - dc_texturemid += FixedMul(rw.ffloortextureslide, (maskedtexturecol[oldx]-maskedtexturecol[dc_x])< (INT64)CLAMPMAX) sprtopscreen = windowtop = CLAMPMAX; - else if (rw.top_frac > (INT64)CLAMPMIN) sprtopscreen = windowtop = (fixed_t)rw.top_frac; - else sprtopscreen = windowtop = CLAMPMIN; - if (rw.bottom_frac > (INT64)CLAMPMAX) sprbotscreen = windowbottom = CLAMPMAX; - else if (rw.bottom_frac > (INT64)CLAMPMIN) sprbotscreen = windowbottom = (fixed_t)rw.bottom_frac; - else sprbotscreen = windowbottom = CLAMPMIN; - - rw.top_frac += rw.top_step; - rw.bottom_frac += rw.bottom_step; -#else - sprtopscreen = windowtop = (centeryfrac - FixedMul((dc_texturemid - offsetvalue), spryscale)); - sprbotscreen = windowbottom = FixedMul(*pfloor->topheight - *pfloor->bottomheight, spryscale) + sprtopscreen; -#endif - - // SoM: If column is out of range, why bother with it?? - if (windowbottom < topbounds || windowtop > bottombounds) - { - if (dc_numlights) - { - for (i = 0; i < dc_numlights; i++) - { - rlight = &dc_lightlist[i]; - rlight->height += rlight->heightstep; - if (rlight->flags & FF_CUTLEVEL) - rlight->botheight += rlight->botheightstep; - } - } - spryscale += rw.scalestep; - continue; - } - - dc_iscale = 0xffffffffu / (unsigned)spryscale; - - // Get data for the column - col = (column_t *)((UINT8 *)R_GetColumn(rw.texnum,maskedtexturecol[dc_x]) - 3); - - // SoM: New code does not rely on R_DrawColumnShadowed_8 which - // will (hopefully) put less strain on the stack. - if (dc_numlights) - { - lighttable_t **xwalllights; - fixed_t height; - fixed_t bheight = 0; - INT32 solid = 0; - INT32 lighteffect = 0; - - for (i = 0; i < dc_numlights; i++) - { - // Check if the current light effects the colormap/lightlevel - rlight = &dc_lightlist[i]; - lighteffect = !(dc_lightlist[i].flags & FF_NOSHADE); - if (lighteffect) - { - lightnum = rlight->lightnum; - - if (lightnum < 0) - xwalllights = scalelight[0]; - else if (lightnum >= LIGHTLEVELS) - xwalllights = scalelight[LIGHTLEVELS-1]; - else - xwalllights = scalelight[lightnum]; - - pindex = FixedMul(spryscale, FixedDiv(640, vid.width))>>LIGHTSCALESHIFT; - - if (pindex >= MAXLIGHTSCALE) - pindex = MAXLIGHTSCALE-1; - - if (pfloor->flags & FF_FOG) - { - if (pfloor->master->frontsector->extra_colormap) - rlight->rcolormap = pfloor->master->frontsector->extra_colormap->colormap + (xwalllights[pindex] - colormaps); - else - rlight->rcolormap = xwalllights[pindex]; - } - else - { - if (rlight->extra_colormap) - rlight->rcolormap = rlight->extra_colormap->colormap + (xwalllights[pindex] - colormaps); - else - rlight->rcolormap = xwalllights[pindex]; - } - } - - solid = 0; // don't carry over solid-cutting flag from the previous light - - // Check if the current light can cut the current 3D floor. - if (rlight->flags & FF_CUTSOLIDS && !(pfloor->flags & FF_EXTRA)) - solid = 1; - else if (rlight->flags & FF_CUTEXTRA && pfloor->flags & FF_EXTRA) - { - if (rlight->flags & FF_EXTRA) - { - // The light is from an extra 3D floor... Check the flags so - // there are no undesired cuts. - if ((rlight->flags & (FF_FOG|FF_SWIMMABLE)) == (pfloor->flags & (FF_FOG|FF_SWIMMABLE))) - solid = 1; - } - else - solid = 1; - } - else - solid = 0; - - height = rlight->height; - rlight->height += rlight->heightstep; - - if (solid) - { - bheight = rlight->botheight - (FRACUNIT >> 1); - rlight->botheight += rlight->botheightstep; - } - - if (height <= windowtop) - { - if (lighteffect) - dc_colormap = rlight->rcolormap; - if (solid && windowtop < bheight) - windowtop = bheight; - continue; - } - - windowbottom = height; - if (windowbottom >= sprbotscreen) - { - windowbottom = sprbotscreen; - // draw the texture - rw.colfunc_2s (col); - for (i++; i < dc_numlights; i++) - { - rlight = &dc_lightlist[i]; - rlight->height += rlight->heightstep; - if (rlight->flags & FF_CUTLEVEL) - rlight->botheight += rlight->botheightstep; - } - continue; - } - // draw the texture - rw.colfunc_2s (col); - if (solid) - windowtop = bheight; - else - windowtop = windowbottom + 1; - if (lighteffect) - dc_colormap = rlight->rcolormap; - } - windowbottom = sprbotscreen; - // draw the texture, if there is any space left - if (windowtop < windowbottom) - rw.colfunc_2s (col); - - spryscale += rw.scalestep; - continue; - } - - // calculate lighting - pindex = FixedMul(spryscale, FixedDiv(640, vid.width))>>LIGHTSCALESHIFT; - - if (pindex >= MAXLIGHTSCALE) - pindex = MAXLIGHTSCALE - 1; - - dc_colormap = walllights[pindex]; - - if (pfloor->flags & FF_FOG && pfloor->master->frontsector->extra_colormap) - dc_colormap = pfloor->master->frontsector->extra_colormap->colormap + (dc_colormap - colormaps); - else if (frontsector->extra_colormap) - dc_colormap = frontsector->extra_colormap->colormap + (dc_colormap - colormaps); - - // draw the texture - rw.colfunc_2s (col); - spryscale += rw.scalestep; - } - } -} - -// -// R_ThickLightLists -// Creates light lists, but for thick sides. -// -static void R_ThickLightLists(drawseg_t *ds, INT32 range) -{ - INT32 lightnum; - sector_t tempsec; - INT32 templight; - INT32 i, p; - - lightlist_t *light; - r_lightlist_t *rlight; - ffloor_t *pfloor = rw.pfloor; - - dc_numlights = 0; - - if (frontsector->numlights) - { - dc_numlights = frontsector->numlights; - if (dc_numlights > dc_maxlights) - { - dc_maxlights = dc_numlights; - dc_lightlist = Z_Realloc(dc_lightlist, sizeof (*dc_lightlist) * dc_maxlights, PU_STATIC, NULL); - } - - for (i = p = 0; i < dc_numlights; i++) - { -#ifdef ESLOPE - fixed_t leftheight, rightheight; - fixed_t pfloorleft, pfloorright; - INT64 overflow_test; -#else - (void)range; -#endif - light = &frontsector->lightlist[i]; - rlight = &dc_lightlist[p]; -#ifdef ESLOPE - -#define SLOPEPARAMS(slope, end1, end2, normalheight) \ - if (slope) { \ - end1 = P_GetZAt(slope, ds->leftpos.x, ds->leftpos.y); \ - end2 = P_GetZAt(slope, ds->rightpos.x, ds->rightpos.y); \ - } else \ - end1 = end2 = normalheight; - - SLOPEPARAMS(light->slope, leftheight, rightheight, light->height) - SLOPEPARAMS(*pfloor->b_slope, pfloorleft, pfloorright, *pfloor->bottomheight) - - if (leftheight < pfloorleft && rightheight < pfloorright) - continue; - - SLOPEPARAMS(*pfloor->t_slope, pfloorleft, pfloorright, *pfloor->topheight) - - if (leftheight > pfloorleft && rightheight > pfloorright && i+1 < dc_numlights) - { - lightlist_t *nextlight = &frontsector->lightlist[i+1]; - if ((nextlight->slope ? P_GetZAt(nextlight->slope, ds->leftpos.x, ds->leftpos.y) : nextlight->height) > pfloorleft - && (nextlight->slope ? P_GetZAt(nextlight->slope, ds->rightpos.x, ds->rightpos.y) : nextlight->height) > pfloorright) - continue; - } - - leftheight -= viewz; - rightheight -= viewz; - - // Monster Iestyn (25/03/18): do not skip these lights if they fail overflow test, just clamp them instead so they behave. - overflow_test = (INT64)centeryfrac - (((INT64)leftheight*ds->scale1)>>FRACBITS); - if (overflow_test > (INT64)CLAMPMAX) rlight->height = CLAMPMAX; - else if (overflow_test > (INT64)CLAMPMIN) rlight->height = (fixed_t)overflow_test; - else rlight->height = CLAMPMIN; - - overflow_test = (INT64)centeryfrac - (((INT64)rightheight*ds->scale2)>>FRACBITS); - if (overflow_test > (INT64)CLAMPMAX) rlight->heightstep = CLAMPMAX; - else if (overflow_test > (INT64)CLAMPMIN) rlight->heightstep = (fixed_t)overflow_test; - else rlight->heightstep = CLAMPMIN; - rlight->heightstep = (rlight->heightstep-rlight->height)/(range); -#else - if (light->height < *pfloor->bottomheight) - continue; - - if (light->height > *pfloor->topheight && i+1 < dc_numlights && frontsector->lightlist[i+1].height > *pfloor->topheight) - continue; - - lheight = light->height;// > *pfloor->topheight ? *pfloor->topheight + FRACUNIT : light->height; - rlight->heightstep = -FixedMul (rw.scalestep, (lheight - viewz)); - rlight->height = (centeryfrac) - FixedMul((lheight - viewz), spryscale); -#endif - rlight->flags = light->flags; - if (light->flags & FF_CUTLEVEL) - { -#ifdef ESLOPE - SLOPEPARAMS(*light->caster->b_slope, leftheight, rightheight, *light->caster->bottomheight) -#undef SLOPEPARAMS - leftheight -= viewz; - rightheight -= viewz; - - // Monster Iestyn (25/03/18): do not skip these lights if they fail overflow test, just clamp them instead so they behave. - overflow_test = (INT64)centeryfrac - (((INT64)leftheight*ds->scale1)>>FRACBITS); - if (overflow_test > (INT64)CLAMPMAX) rlight->botheight = CLAMPMAX; - else if (overflow_test > (INT64)CLAMPMIN) rlight->botheight = (fixed_t)overflow_test; - else rlight->botheight = CLAMPMIN; - - overflow_test = (INT64)centeryfrac - (((INT64)rightheight*ds->scale2)>>FRACBITS); - if (overflow_test > (INT64)CLAMPMAX) rlight->botheightstep = CLAMPMAX; - else if (overflow_test > (INT64)CLAMPMIN) rlight->botheightstep = (fixed_t)overflow_test; - else rlight->botheightstep = CLAMPMIN; - rlight->botheightstep = (rlight->botheightstep-rlight->botheight)/(range); -#else - lheight = *light->caster->bottomheight;// > *pfloor->topheight ? *pfloor->topheight + FRACUNIT : *light->caster->bottomheight; - rlight->botheightstep = -FixedMul (rw.scalestep, (lheight - viewz)); - rlight->botheight = (centeryfrac) - FixedMul((lheight - viewz), spryscale); -#endif - } - - rlight->lightlevel = *light->lightlevel; - rlight->extra_colormap = *light->extra_colormap; - - // Check if the current light effects the colormap/lightlevel - if (pfloor->flags & FF_FOG) - rlight->lightnum = (pfloor->master->frontsector->lightlevel >> LIGHTSEGSHIFT); - else - rlight->lightnum = (rlight->lightlevel >> LIGHTSEGSHIFT); - - if (pfloor->flags & FF_FOG || rlight->flags & FF_FOG || (rlight->extra_colormap && rlight->extra_colormap->fog)) - ; - else if (curline->v1->y == curline->v2->y) - rlight->lightnum--; - else if (curline->v1->x == curline->v2->x) - rlight->lightnum++; - - p++; - } - - dc_numlights = p; - } - else - { - // Get correct light level! - if ((frontsector->extra_colormap && frontsector->extra_colormap->fog)) - lightnum = (frontsector->lightlevel >> LIGHTSEGSHIFT); - else if (pfloor->flags & FF_FOG) - lightnum = (pfloor->master->frontsector->lightlevel >> LIGHTSEGSHIFT); - else if (colfunc == colfuncs[COLDRAWFUNC_FUZZY]) - lightnum = LIGHTLEVELS-1; - else - lightnum = R_FakeFlat(frontsector, &tempsec, &templight, &templight, false) - ->lightlevel >> LIGHTSEGSHIFT; - - if (pfloor->flags & FF_FOG || (frontsector->extra_colormap && frontsector->extra_colormap->fog)); - else if (curline->v1->y == curline->v2->y) - lightnum--; - else if (curline->v1->x == curline->v2->x) - lightnum++; - - if (lightnum < 0) - walllights = scalelight[0]; - else if (lightnum >= LIGHTLEVELS) - walllights = scalelight[LIGHTLEVELS-1]; - else - walllights = scalelight[lightnum]; - } -} - -// -// R_ThickStepping -// Set stepping values for thick sides. -// -#ifdef ESLOPE -static void R_ThickStepping(drawseg_t *ds, INT32 range) -{ - fixed_t right_top, right_bottom; - ffloor_t *pfloor = rw.pfloor; - - // calculate right ends now - if (*pfloor->t_slope) - right_top = P_GetZAt(*pfloor->t_slope, ds->rightpos.x, ds->rightpos.y) - viewz; - else - right_top = *pfloor->topheight - viewz; - - if (*pfloor->b_slope) - right_bottom = P_GetZAt(*pfloor->b_slope, ds->rightpos.x, ds->rightpos.y) - viewz; - else - right_bottom = *pfloor->bottomheight - viewz; - - // using INT64 to avoid 32bit overflow - rw.top_frac = (INT64)centeryfrac - (((INT64)rw.left_top * ds->scale1) >> FRACBITS); - rw.bottom_frac = (INT64)centeryfrac - (((INT64)rw.left_bottom * ds->scale1) >> FRACBITS); - rw.top_step = (INT64)centeryfrac - (((INT64)right_top * ds->scale2) >> FRACBITS); - rw.bottom_step = (INT64)centeryfrac - (((INT64)right_bottom * ds->scale2) >> FRACBITS); - - rw.top_step = (rw.top_step-rw.top_frac)/(range); - rw.bottom_step = (rw.bottom_step-rw.bottom_frac)/(range); - - rw.top_frac += rw.top_step * (rw.x - ds->x1); - rw.bottom_frac += rw.bottom_step * (rw.x - ds->x1); -} -#endif - -// -// R_RenderThickSideRange -// Renders all the thick sides in the given range. -// -void R_RenderThickSideRange(drawseg_t *ds, INT32 x1, INT32 x2, ffloor_t *pfloor) -{ - INT32 texnum; - - fixed_t offsetvalue = 0; - INT32 range; -#ifndef ESLOPE - fixed_t lheight; -#endif - line_t *newline = NULL; -#ifdef ESLOPE - // skew FOF walls with slopes? - boolean slopeskew = false; - pslope_t *skewslope = NULL; -#endif - - rw.x = x1; - rw.stopx = x2; - rw.pfloor = pfloor; - - // Calculate light table. - // Use different light tables - // for horizontal / vertical / diagonal. Diagonal? - // OPTIMIZE: get rid of LIGHTSEGSHIFT globally - - curline = ds->curline; - backsector = pfloor->target; - frontsector = curline->frontsector == pfloor->target ? curline->backsector : curline->frontsector; - texnum = R_GetTextureNum(sides[pfloor->master->sidenum[0]].midtexture); - - colfunc = colfuncs[BASEDRAWFUNC]; - - if (pfloor->master->flags & ML_TFERLINE) - { - size_t linenum = curline->linedef-backsector->lines[0]; - newline = pfloor->master->frontsector->lines[0] + linenum; - texnum = R_GetTextureNum(sides[newline->sidenum[0]].midtexture); - } - - if (pfloor->flags & FF_TRANSLUCENT) - { - boolean fuzzy = true; - - // Hacked up support for alpha value in software mode Tails 09-24-2002 - if (pfloor->alpha < 12) - return; // Don't even draw it - else if (pfloor->alpha < 38) - dc_transmap = transtables + ((tr_trans90-1)<alpha < 64) - dc_transmap = transtables + ((tr_trans80-1)<alpha < 89) - dc_transmap = transtables + ((tr_trans70-1)<alpha < 115) - dc_transmap = transtables + ((tr_trans60-1)<alpha < 140) - dc_transmap = transtables + ((tr_trans50-1)<alpha < 166) - dc_transmap = transtables + ((tr_trans40-1)<alpha < 192) - dc_transmap = transtables + ((tr_trans30-1)<alpha < 217) - dc_transmap = transtables + ((tr_trans20-1)<alpha < 243) - dc_transmap = transtables + ((tr_trans10-1)<flags & FF_FOG) - colfunc = colfuncs[COLDRAWFUNC_FOG]; - -#ifdef ESLOPE - range = max(ds->x2-ds->x1, 1); -#endif - //SoM: Moved these up here so they are available for my lightlist calculations - rw.scalestep = ds->scalestep; - spryscale = ds->scale1 + (x1 - ds->x1)*rw.scalestep; - - R_ThickLightLists(ds, range); - - maskedtexturecol = ds->thicksidecol; - - mfloorclip = ds->sprbottomclip; - mceilingclip = ds->sprtopclip; - dc_texheight = textureheight[texnum]>>FRACBITS; - -#ifdef ESLOPE - // calculate both left ends - if (*pfloor->t_slope) - rw.left_top = P_GetZAt(*pfloor->t_slope, ds->leftpos.x, ds->leftpos.y) - viewz; - else - rw.left_top = *pfloor->topheight - viewz; - - if (*pfloor->b_slope) - rw.left_bottom = P_GetZAt(*pfloor->b_slope, ds->leftpos.x, ds->leftpos.y) - viewz; - else - rw.left_bottom = *pfloor->bottomheight - viewz; - skewslope = *pfloor->t_slope; // skew using top slope by default - if (newline) - { - if (newline->flags & ML_DONTPEGTOP) - slopeskew = true; - } - else if (pfloor->master->flags & ML_DONTPEGTOP) - slopeskew = true; - - if (slopeskew) - dc_texturemid = rw.left_top; - else -#endif - dc_texturemid = *pfloor->topheight - viewz; - - if (newline) - { - offsetvalue = sides[newline->sidenum[0]].rowoffset; - if (newline->flags & ML_DONTPEGBOTTOM) - { -#ifdef ESLOPE - skewslope = *pfloor->b_slope; // skew using bottom slope - if (slopeskew) - dc_texturemid = rw.left_bottom; - else -#endif - offsetvalue -= *pfloor->topheight - *pfloor->bottomheight; - } - } - else - { - offsetvalue = sides[pfloor->master->sidenum[0]].rowoffset; - if (curline->linedef->flags & ML_DONTPEGBOTTOM) - { -#ifdef ESLOPE - skewslope = *pfloor->b_slope; // skew using bottom slope - if (slopeskew) - dc_texturemid = rw.left_bottom; - else -#endif - offsetvalue -= *pfloor->topheight - *pfloor->bottomheight; - } - } - -#ifdef ESLOPE - if (slopeskew) - { - angle_t lineangle = R_PointToAngle2(curline->v1->x, curline->v1->y, curline->v2->x, curline->v2->y); - - if (skewslope) - rw.ffloortextureslide = FixedMul(skewslope->zdelta, FINECOSINE((lineangle-skewslope->xydirection)>>ANGLETOFINESHIFT)); - } -#endif - - dc_texturemid += offsetvalue; - - // Texture must be cached before setting colfunc_2s, - // otherwise texture[texnum]->holes may be false when it shouldn't be - R_CheckTextureCache(texnum); - //faB: handle case where multipatch texture is drawn on a 2sided wall, multi-patch textures - // are not stored per-column with post info anymore in Doom Legacy - if (textures[texnum]->holes) - { - if (textures[texnum]->flip & 2) // vertically flipped? - { - rw.colfunc_2s = R_DrawRepeatFlippedMaskedColumn; - rw.column2s_length = textures[texnum]->height; - } - else - rw.colfunc_2s = R_DrawRepeatMaskedColumn; // render the usual 2sided single-patch packed texture - } - else - { - rw.colfunc_2s = R_Render2sidedMultiPatchColumn; //render multipatch with no holes (no post_t info) - rw.column2s_length = textures[texnum]->height; - } - -#ifdef ESLOPE - // Set heights according to plane, or slope, whichever - R_ThickStepping(ds, range); -#endif - - // draw the columns - rw.texnum = texnum; - R_RenderThickSegLoop(); - colfunc = colfuncs[BASEDRAWFUNC]; - -#undef CLAMPMAX -#undef CLAMPMIN -} diff --git a/src/r_state.h b/src/r_state.h index 2c5e5fcf7..75566923b 100644 --- a/src/r_state.h +++ b/src/r_state.h @@ -93,41 +93,10 @@ extern angle_t doubleclipangle; extern INT32 viewangletox[FINEANGLES/2]; extern angle_t xtoviewangle[MAXVIDWIDTH+1]; -// Wall rendering -typedef struct -{ - INT32 x, stopx; - angle_t centerangle; - fixed_t offset; - fixed_t offset2; // for splats - fixed_t scale, scalestep; - fixed_t midtexturemid, toptexturemid, bottomtexturemid; -#ifdef ESLOPE - fixed_t toptextureslide, midtextureslide, bottomtextureslide; // Defines how to adjust Y offsets along the wall for slopes - fixed_t midtextureback, midtexturebackslide; // Values for masked midtexture height calculation -#endif - fixed_t distance; - angle_t normalangle; - angle_t angle1; // angle to line origin +extern fixed_t rw_distance; +extern angle_t rw_normalangle; - // for masked segs and thick sides - INT32 texnum; - void (*colfunc_2s) (column_t *); - INT32 column2s_length; // column->length : for multi-patch on 2sided wall = texture->height - - // masked segs - INT32 maskedrepeat; - - // thick sides - ffloor_t *pfloor; -#ifdef ESLOPE - // Render FOF sides kinda like normal sides, with the frac and step and everything - // NOTE: INT64 instead of fixed_t because overflow concerns - INT64 top_frac, top_step, bottom_frac, bottom_step; - fixed_t ffloortextureslide; - fixed_t left_top, left_bottom; // needed here for slope skewing -#endif -} renderwall_t; -extern renderwall_t rw; +// angle to line origin +extern angle_t rw_angle1; #endif From caadf6aa6128c417496aefc358b973c2a49c1361 Mon Sep 17 00:00:00 2001 From: Louis-Antoine Date: Wed, 1 Jan 2020 13:29:07 +0100 Subject: [PATCH 69/79] Let the mouse move freely when a menu is open or game is paused That means you can now easily move your mouse out of SRB2's window and switch between several windows easily by just pressing escape! Any phase of the game that isn't actual gameplay counts as a menu, which means you can also move the mouse in cutscenes, at the title screen, server connection screen, and even when the chat or console are open. --- src/sdl/i_video.c | 17 +++++++---------- 1 file changed, 7 insertions(+), 10 deletions(-) diff --git a/src/sdl/i_video.c b/src/sdl/i_video.c index 806516292..d21edb1c6 100644 --- a/src/sdl/i_video.c +++ b/src/sdl/i_video.c @@ -67,6 +67,7 @@ #include "../s_sound.h" #include "../i_joy.h" #include "../st_stuff.h" +#include "../hu_stuff.h" #include "../g_game.h" #include "../i_video.h" #include "../console.h" @@ -108,6 +109,7 @@ static SDL_bool disable_fullscreen = SDL_FALSE; #define USE_FULLSCREEN (disable_fullscreen||!allow_fullscreen)?0:cv_fullscreen.value static SDL_bool disable_mouse = SDL_FALSE; #define USE_MOUSEINPUT (!disable_mouse && cv_usemouse.value && havefocus) +#define IGNORE_MOUSE (menuactive || paused || con_destlines || chat_on || gamestate != GS_LEVEL) #define MOUSE_MENU false //(!disable_mouse && cv_usemouse.value && menuactive && !USE_FULLSCREEN) #define MOUSEBUTTONS_MAX MOUSEBUTTONS @@ -590,7 +592,7 @@ static void Impl_HandleWindowEvent(SDL_WindowEvent evt) } //else firsttimeonmouse = SDL_FALSE; - if (USE_MOUSEINPUT) + if (USE_MOUSEINPUT && !IGNORE_MOUSE) SDLdoGrabMouse(); } else if (!mousefocus && !kbfocus) @@ -639,7 +641,7 @@ static void Impl_HandleMouseMotionEvent(SDL_MouseMotionEvent evt) { if (USE_MOUSEINPUT) { - if ((SDL_GetMouseFocus() != window && SDL_GetKeyboardFocus() != window)) + if ((SDL_GetMouseFocus() != window && SDL_GetKeyboardFocus() != window) || IGNORE_MOUSE) { SDLdoUngrabMouse(); return; @@ -687,7 +689,7 @@ static void Impl_HandleMouseButtonEvent(SDL_MouseButtonEvent evt, Uint32 type) // this apparently makes a mouse button down event but not a mouse button up event, // resulting in whatever key was pressed down getting "stuck" if we don't ignore it. // -- Monster Iestyn (28/05/18) - if (SDL_GetMouseFocus() != window) + if (SDL_GetMouseFocus() != window || IGNORE_MOUSE) return; /// \todo inputEvent.button.which @@ -1069,7 +1071,7 @@ void I_StartupMouse(void) } else firsttimeonmouse = SDL_FALSE; - if (cv_usemouse.value) + if (cv_usemouse.value && !IGNORE_MOUSE) SDLdoGrabMouse(); else SDLdoUngrabMouse(); @@ -1702,12 +1704,7 @@ void I_StartupGraphics(void) SDL_RaiseWindow(window); if (mousegrabok && !disable_mouse) - { - SDL_ShowCursor(SDL_DISABLE); - SDL_SetRelativeMouseMode(SDL_TRUE); - wrapmouseok = SDL_TRUE; - SDL_SetWindowGrab(window, SDL_TRUE); - } + SDLdoGrabMouse(); graphics_started = true; } From 62397a36ec7a618588a8e23dbb94c733ec7f77e4 Mon Sep 17 00:00:00 2001 From: Louis-Antoine Date: Thu, 2 Jan 2020 00:38:43 +0100 Subject: [PATCH 70/79] Grab mouse on game startup --- src/sdl/i_video.c | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/src/sdl/i_video.c b/src/sdl/i_video.c index d21edb1c6..645b65e84 100644 --- a/src/sdl/i_video.c +++ b/src/sdl/i_video.c @@ -639,11 +639,14 @@ static void Impl_HandleKeyboardEvent(SDL_KeyboardEvent evt, Uint32 type) static void Impl_HandleMouseMotionEvent(SDL_MouseMotionEvent evt) { + static boolean firstmove = true; + if (USE_MOUSEINPUT) { - if ((SDL_GetMouseFocus() != window && SDL_GetKeyboardFocus() != window) || IGNORE_MOUSE) + if ((SDL_GetMouseFocus() != window && SDL_GetKeyboardFocus() != window) || (IGNORE_MOUSE && !firstmove)) { SDLdoUngrabMouse(); + firstmove = false; return; } @@ -657,6 +660,7 @@ static void Impl_HandleMouseMotionEvent(SDL_MouseMotionEvent evt) mousemovey += -evt.yrel; SDL_SetWindowGrab(window, SDL_TRUE); } + firstmove = false; return; } @@ -664,6 +668,7 @@ static void Impl_HandleMouseMotionEvent(SDL_MouseMotionEvent evt) // of the screen then ignore it. if ((evt.x == realwidth/2) && (evt.y == realheight/2)) { + firstmove = false; return; } @@ -676,6 +681,8 @@ static void Impl_HandleMouseMotionEvent(SDL_MouseMotionEvent evt) SDLdoGrabMouse(); } } + + firstmove = false; } static void Impl_HandleMouseButtonEvent(SDL_MouseButtonEvent evt, Uint32 type) From 5bde4df4393cd586410ad8d08f405dc6459b2776 Mon Sep 17 00:00:00 2001 From: Louis-Antoine Date: Thu, 2 Jan 2020 00:45:28 +0100 Subject: [PATCH 71/79] Grab mouse again when closing menu, unpausing, etc --- src/android/i_system.c | 2 ++ src/console.c | 4 ++++ src/d_netcmd.c | 2 ++ src/dehacked.c | 2 ++ src/dummy/i_system.c | 2 ++ src/g_game.c | 1 + src/hu_stuff.c | 4 ++++ src/i_system.h | 4 ++++ src/m_menu.c | 3 +++ src/sdl/i_video.c | 8 ++++++++ src/win32/win_sys.c | 2 ++ 11 files changed, 34 insertions(+) diff --git a/src/android/i_system.c b/src/android/i_system.c index 58fca7c19..752e9f6c6 100644 --- a/src/android/i_system.c +++ b/src/android/i_system.c @@ -245,6 +245,8 @@ void I_GetJoystick2Events(void){} void I_GetMouseEvents(void){} +void I_UpdateMouseGrab(void){} + char *I_GetEnv(const char *name) { LOGW("I_GetEnv() called?!"); diff --git a/src/console.c b/src/console.c index 6549370ee..01d1ddaa2 100644 --- a/src/console.c +++ b/src/console.c @@ -592,6 +592,8 @@ void CON_ToggleOff(void) CON_ClearHUD(); con_forcepic = 0; con_clipviewtop = -1; // remove console clipping of view + + I_UpdateMouseGrab(); } boolean CON_Ready(void) @@ -616,6 +618,7 @@ void CON_Ticker(void) consoletoggle = false; con_destlines = 0; CON_ClearHUD(); + I_UpdateMouseGrab(); } // console key was pushed @@ -628,6 +631,7 @@ void CON_Ticker(void) { con_destlines = 0; CON_ClearHUD(); + I_UpdateMouseGrab(); } else CON_ChangeHeight(); diff --git a/src/d_netcmd.c b/src/d_netcmd.c index 28843c0d7..0cd0ae20a 100644 --- a/src/d_netcmd.c +++ b/src/d_netcmd.c @@ -2203,6 +2203,8 @@ static void Got_Pause(UINT8 **cp, INT32 playernum) else S_ResumeAudio(); } + + I_UpdateMouseGrab(); } // Command for stuck characters in netgames, griefing, etc. diff --git a/src/dehacked.c b/src/dehacked.c index c9e10c064..78be8b0b3 100644 --- a/src/dehacked.c +++ b/src/dehacked.c @@ -4539,11 +4539,13 @@ static void DEH_LoadDehackedFile(MYFILE *f, boolean mainfile) if (introchanged) { menuactive = false; + I_UpdateMouseGrab(); COM_BufAddText("playintro"); } else if (titlechanged) { menuactive = false; + I_UpdateMouseGrab(); COM_BufAddText("exitgame"); // Command_ExitGame_f() but delayed } } diff --git a/src/dummy/i_system.c b/src/dummy/i_system.c index a3fe3077c..5c0f7eb99 100644 --- a/src/dummy/i_system.c +++ b/src/dummy/i_system.c @@ -150,6 +150,8 @@ void I_GetJoystick2Events(void){} void I_GetMouseEvents(void){} +void I_UpdateMouseGrab(void){} + char *I_GetEnv(const char *name) { (void)name; diff --git a/src/g_game.c b/src/g_game.c index e4caa3a36..354d75e82 100644 --- a/src/g_game.c +++ b/src/g_game.c @@ -1832,6 +1832,7 @@ void G_DoLoadLevel(boolean resetplayer) titlemapinaction = TITLEMAP_OFF; G_SetGamestate(GS_LEVEL); + I_UpdateMouseGrab(); for (i = 0; i < MAXPLAYERS; i++) { diff --git a/src/hu_stuff.c b/src/hu_stuff.c index 07eb5d24e..772d1cd58 100644 --- a/src/hu_stuff.c +++ b/src/hu_stuff.c @@ -1173,6 +1173,8 @@ void HU_clearChatChars(void) w_chat[i] = 0; // reset this. chat_on = false; c_input = 0; + + I_UpdateMouseGrab(); } #ifndef NONET @@ -1323,6 +1325,7 @@ boolean HU_Responder(event_t *ev) chat_on = false; c_input = 0; // reset input cursor chat_scrollmedown = true; // you hit enter, so you might wanna autoscroll to see what you just sent. :) + I_UpdateMouseGrab(); } else if (c == KEY_ESCAPE || ((c == gamecontrol[gc_talkkey][0] || c == gamecontrol[gc_talkkey][1] @@ -1331,6 +1334,7 @@ boolean HU_Responder(event_t *ev) { chat_on = false; c_input = 0; // reset input cursor + I_UpdateMouseGrab(); } else if ((c == KEY_UPARROW || c == KEY_MOUSEWHEELUP) && chat_scroll > 0 && !OLDCHAT) // CHAT SCROLLING YAYS! { diff --git a/src/i_system.h b/src/i_system.h index 2532ba0ee..a60b56310 100644 --- a/src/i_system.h +++ b/src/i_system.h @@ -288,6 +288,10 @@ void I_GetJoystick2Events(void); */ void I_GetMouseEvents(void); +/** \brief Checks if the mouse needs to be grabbed +*/ +void I_UpdateMouseGrab(void); + char *I_GetEnv(const char *name); INT32 I_PutEnv(char *variable); diff --git a/src/m_menu.c b/src/m_menu.c index ae00c8062..1a3c43b75 100644 --- a/src/m_menu.c +++ b/src/m_menu.c @@ -2867,6 +2867,7 @@ static void M_GoBack(INT32 choice) menuactive = false; wipetypepre = menupres[M_GetYoungestChildMenu()].exitwipe; + I_UpdateMouseGrab(); D_StartTitle(); } else @@ -3592,6 +3593,8 @@ void M_ClearMenus(boolean callexitmenufunc) currentMenu = &MainDef; // Not like it matters menuactive = false; hidetitlemap = false; + + I_UpdateMouseGrab(); } // diff --git a/src/sdl/i_video.c b/src/sdl/i_video.c index 645b65e84..553ce3676 100644 --- a/src/sdl/i_video.c +++ b/src/sdl/i_video.c @@ -388,6 +388,14 @@ void SDLforceUngrabMouse(void) } } +void I_UpdateMouseGrab(void) +{ + if (SDL_WasInit(SDL_INIT_VIDEO) == SDL_INIT_VIDEO && window != NULL + && SDL_GetMouseFocus() == window && SDL_GetKeyboardFocus() == window + && !IGNORE_MOUSE) + SDLdoGrabMouse(); +} + static void VID_Command_NumModes_f (void) { CONS_Printf(M_GetText("%d video mode(s) available(s)\n"), VID_NumModes()); diff --git a/src/win32/win_sys.c b/src/win32/win_sys.c index c9fdb1c97..42733c309 100644 --- a/src/win32/win_sys.c +++ b/src/win32/win_sys.c @@ -1354,6 +1354,8 @@ getBufferedData: } } +void I_UpdateMouseGrab(void) {} + // =========================================================================================== // DIRECT INPUT JOYSTICK // =========================================================================================== From 17636ccc01b82cd4d85dee35a00a474c211b8bde Mon Sep 17 00:00:00 2001 From: Louis-Antoine Date: Thu, 2 Jan 2020 00:46:50 +0100 Subject: [PATCH 72/79] Ungrab mouse when watching a record --- src/sdl/i_video.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/sdl/i_video.c b/src/sdl/i_video.c index 553ce3676..d6b36d0ed 100644 --- a/src/sdl/i_video.c +++ b/src/sdl/i_video.c @@ -109,7 +109,7 @@ static SDL_bool disable_fullscreen = SDL_FALSE; #define USE_FULLSCREEN (disable_fullscreen||!allow_fullscreen)?0:cv_fullscreen.value static SDL_bool disable_mouse = SDL_FALSE; #define USE_MOUSEINPUT (!disable_mouse && cv_usemouse.value && havefocus) -#define IGNORE_MOUSE (menuactive || paused || con_destlines || chat_on || gamestate != GS_LEVEL) +#define IGNORE_MOUSE (menuactive || paused || con_destlines || chat_on || demoplayback || gamestate != GS_LEVEL) #define MOUSE_MENU false //(!disable_mouse && cv_usemouse.value && menuactive && !USE_FULLSCREEN) #define MOUSEBUTTONS_MAX MOUSEBUTTONS From 3af00ac93e215af45c4a67dbf29b8161f425261b Mon Sep 17 00:00:00 2001 From: Louis-Antoine Date: Thu, 2 Jan 2020 00:47:20 +0100 Subject: [PATCH 73/79] Minor code refactoring --- src/m_menu.c | 3 --- src/sdl/i_video.c | 7 +------ 2 files changed, 1 insertion(+), 9 deletions(-) diff --git a/src/m_menu.c b/src/m_menu.c index 1a3c43b75..5d1bbd07d 100644 --- a/src/m_menu.c +++ b/src/m_menu.c @@ -3212,10 +3212,7 @@ boolean M_Responder(event_t *ev) case KEY_ESCAPE: // Pop up menu if (chat_on) - { HU_clearChatChars(); - chat_on = false; - } else M_StartControlPanel(); return true; diff --git a/src/sdl/i_video.c b/src/sdl/i_video.c index d6b36d0ed..e1b3781d9 100644 --- a/src/sdl/i_video.c +++ b/src/sdl/i_video.c @@ -380,12 +380,7 @@ static void SDLdoUngrabMouse(void) void SDLforceUngrabMouse(void) { if (SDL_WasInit(SDL_INIT_VIDEO)==SDL_INIT_VIDEO && window != NULL) - { - SDL_ShowCursor(SDL_ENABLE); - SDL_SetWindowGrab(window, SDL_FALSE); - wrapmouseok = SDL_FALSE; - SDL_SetRelativeMouseMode(SDL_FALSE); - } + SDLdoUngrabMouse(); } void I_UpdateMouseGrab(void) From b9cecea25c2efd62dd241aa1fd3a92191dbe69b0 Mon Sep 17 00:00:00 2001 From: James R Date: Wed, 1 Jan 2020 15:52:23 -0800 Subject: [PATCH 74/79] Hahahahahahahahahahahahaha --- src/command.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/command.c b/src/command.c index 0a6b34fc8..7cacc6d7b 100644 --- a/src/command.c +++ b/src/command.c @@ -2171,7 +2171,7 @@ skipwhite: return data; } if (c == '\033') - data += 2; + data++; else { com_token[len] = c; From e0e5e83869e22beeb1dc6abc373d166dc2c1af99 Mon Sep 17 00:00:00 2001 From: Louis-Antoine Date: Thu, 2 Jan 2020 20:29:51 +0100 Subject: [PATCH 75/79] Revert "Ungrab mouse when watching a record" This reverts commit 17636ccc01b82cd4d85dee35a00a474c211b8bde. --- src/sdl/i_video.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/sdl/i_video.c b/src/sdl/i_video.c index e1b3781d9..7123a2d20 100644 --- a/src/sdl/i_video.c +++ b/src/sdl/i_video.c @@ -109,7 +109,7 @@ static SDL_bool disable_fullscreen = SDL_FALSE; #define USE_FULLSCREEN (disable_fullscreen||!allow_fullscreen)?0:cv_fullscreen.value static SDL_bool disable_mouse = SDL_FALSE; #define USE_MOUSEINPUT (!disable_mouse && cv_usemouse.value && havefocus) -#define IGNORE_MOUSE (menuactive || paused || con_destlines || chat_on || demoplayback || gamestate != GS_LEVEL) +#define IGNORE_MOUSE (menuactive || paused || con_destlines || chat_on || gamestate != GS_LEVEL) #define MOUSE_MENU false //(!disable_mouse && cv_usemouse.value && menuactive && !USE_FULLSCREEN) #define MOUSEBUTTONS_MAX MOUSEBUTTONS From 945f50c2736ee64734dcc94f36ff7dff4085c8e2 Mon Sep 17 00:00:00 2001 From: James R Date: Thu, 2 Jan 2020 14:58:09 -0800 Subject: [PATCH 76/79] Remove Direct Draw from AppVeyor config --- appveyor.yml | 9 --------- 1 file changed, 9 deletions(-) diff --git a/appveyor.yml b/appveyor.yml index 0edc7ce28..c64e69665 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -55,8 +55,6 @@ cache: install: - if [%CONFIGURATION%] == [SDL64] ( set "X86_64=1" ) - if [%CONFIGURATION%] == [SDL64] ( set "CONFIGURATION=SDL" ) -- if [%CONFIGURATION%] == [DD64] ( set "X86_64=1" ) -- if [%CONFIGURATION%] == [DD64] ( set "CONFIGURATION=DD" ) - if [%X86_64%] == [1] ( set "MINGW_SDK=%MINGW_SDK_64%" ) - if [%X86_64%] == [1] ( set "CCACHE_CC=%CCACHE_CC_64%" ) @@ -75,13 +73,6 @@ install: configuration: - SDL - SDL64 -- DD -- DD64 - -matrix: - allow_failures: - - configuration: DD - - configuration: DD64 before_build: - set "Path=%MINGW_SDK%\bin;%Path%" From 49934007d7e904e78a2038d1dc0715f36fffa66b Mon Sep 17 00:00:00 2001 From: Louis-Antoine Date: Fri, 3 Jan 2020 00:25:58 +0100 Subject: [PATCH 77/79] Add a "alwaysgrabmouse" console variable --- src/sdl/i_video.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/sdl/i_video.c b/src/sdl/i_video.c index 7123a2d20..e6a40327b 100644 --- a/src/sdl/i_video.c +++ b/src/sdl/i_video.c @@ -100,6 +100,7 @@ boolean highcolor = false; // synchronize page flipping with screen refresh consvar_t cv_vidwait = {"vid_wait", "On", CV_SAVE, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL}; static consvar_t cv_stretch = {"stretch", "Off", CV_SAVE|CV_NOSHOWHELP, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL}; +static consvar_t cv_alwaysgrabmouse = {"alwaysgrabmouse", "Off", CV_SAVE, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL}; UINT8 graphics_started = 0; // Is used in console.c and screen.c @@ -109,7 +110,7 @@ static SDL_bool disable_fullscreen = SDL_FALSE; #define USE_FULLSCREEN (disable_fullscreen||!allow_fullscreen)?0:cv_fullscreen.value static SDL_bool disable_mouse = SDL_FALSE; #define USE_MOUSEINPUT (!disable_mouse && cv_usemouse.value && havefocus) -#define IGNORE_MOUSE (menuactive || paused || con_destlines || chat_on || gamestate != GS_LEVEL) +#define IGNORE_MOUSE (!cv_alwaysgrabmouse.value && (menuactive || paused || con_destlines || chat_on || gamestate != GS_LEVEL)) #define MOUSE_MENU false //(!disable_mouse && cv_usemouse.value && menuactive && !USE_FULLSCREEN) #define MOUSEBUTTONS_MAX MOUSEBUTTONS @@ -1626,6 +1627,7 @@ void I_StartupGraphics(void) COM_AddCommand ("vid_mode", VID_Command_Mode_f); CV_RegisterVar (&cv_vidwait); CV_RegisterVar (&cv_stretch); + CV_RegisterVar (&cv_alwaysgrabmouse); disable_mouse = M_CheckParm("-nomouse"); disable_fullscreen = M_CheckParm("-win") ? 1 : 0; From 1845266bc835f6d9b82f6ada75a50d4d1c1ad579 Mon Sep 17 00:00:00 2001 From: Louis-Antoine Date: Fri, 3 Jan 2020 00:40:49 +0100 Subject: [PATCH 78/79] Do not save netgame-synced console variables This is a bad thing to do, because if you join a server, your game will save the host's settings. --- src/d_clisrv.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/d_clisrv.c b/src/d_clisrv.c index 6520a1aa1..586e3077c 100644 --- a/src/d_clisrv.c +++ b/src/d_clisrv.c @@ -2985,8 +2985,8 @@ static void Got_KickCmd(UINT8 **p, INT32 playernum) CL_RemovePlayer(pnum, kickreason); } -consvar_t cv_allownewplayer = {"allowjoin", "On", CV_SAVE|CV_NETVAR, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL }; -consvar_t cv_joinnextround = {"joinnextround", "Off", CV_SAVE|CV_NETVAR, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL}; /// \todo not done +consvar_t cv_allownewplayer = {"allowjoin", "On", CV_NETVAR, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL }; +consvar_t cv_joinnextround = {"joinnextround", "Off", CV_NETVAR, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL}; /// \todo not done static CV_PossibleValue_t maxplayers_cons_t[] = {{2, "MIN"}, {32, "MAX"}, {0, NULL}}; consvar_t cv_maxplayers = {"maxplayers", "8", CV_SAVE, maxplayers_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL}; static CV_PossibleValue_t resynchattempts_cons_t[] = {{1, "MIN"}, {20, "MAX"}, {0, "No"}, {0, NULL}}; From b45ee059e31f01ba20ea2cec89f4a6c41746fab5 Mon Sep 17 00:00:00 2001 From: Louis-Antoine Date: Fri, 3 Jan 2020 02:58:23 +0100 Subject: [PATCH 79/79] Fix major issue --- src/r_things.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/r_things.c b/src/r_things.c index a328da03a..2f01ac7f6 100644 --- a/src/r_things.c +++ b/src/r_things.c @@ -988,7 +988,7 @@ static void R_DrawPrecipitationVisSprite(vissprite_t *vis) // // R_SplitSprite -// runs through a sector's lightlist and +// runs through a sector's lightlist and Knuckles static void R_SplitSprite(vissprite_t *sprite) { INT32 i, lightnum, lindex;