From 398b320aec8e4c7701d021d7763bd8e680cbe4cc Mon Sep 17 00:00:00 2001 From: Jaime Passos Date: Sun, 8 Sep 2019 18:27:35 -0300 Subject: [PATCH 001/136] 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 1cb22d5e6bc98264ab172518337ea2eb50d44555 Mon Sep 17 00:00:00 2001 From: Jaime Passos Date: Sun, 8 Sep 2019 18:27:35 -0300 Subject: [PATCH 002/136] 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 61a16d43f55a315eea91c3fb3ab35e8197937112 Mon Sep 17 00:00:00 2001 From: Jaime Passos Date: Sun, 8 Sep 2019 18:59:49 -0300 Subject: [PATCH 003/136] 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 11077c2bacda45bbb2c8dd7987147e6c2d39c6a7 Mon Sep 17 00:00:00 2001 From: Jaime Passos Date: Sun, 8 Sep 2019 21:37:24 -0300 Subject: [PATCH 004/136] 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 93ea8c4019643b2ac93fec6d388546c8f5e6f756 Mon Sep 17 00:00:00 2001 From: Jaime Passos Date: Sun, 8 Sep 2019 22:25:18 -0300 Subject: [PATCH 005/136] 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 371e16094001afba2b1153a85b33b5c8a7e4c2e4 Mon Sep 17 00:00:00 2001 From: Jaime Passos Date: Mon, 9 Sep 2019 16:20:17 -0300 Subject: [PATCH 006/136] 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 073e33de212e4eb64db8fb4685181ca5a50f00d6 Mon Sep 17 00:00:00 2001 From: Jaime Passos Date: Mon, 9 Sep 2019 16:31:30 -0300 Subject: [PATCH 007/136] 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 59f403d67b0d640c48c2ce89a60d244f82ccc917 Mon Sep 17 00:00:00 2001 From: Jaime Passos Date: Mon, 9 Sep 2019 17:24:13 -0300 Subject: [PATCH 008/136] 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 d534b0f1f48b4acc7304d17f050153562a14450f Mon Sep 17 00:00:00 2001 From: Jaime Passos Date: Mon, 9 Sep 2019 17:35:38 -0300 Subject: [PATCH 009/136] 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 36e305735f6277c38a9860c79233c6c0ff078384 Mon Sep 17 00:00:00 2001 From: Jaime Passos Date: Mon, 9 Sep 2019 17:53:34 -0300 Subject: [PATCH 010/136] 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 fe737c33f644a6a3bddc9963ec82cec8c2615aaa Mon Sep 17 00:00:00 2001 From: Jaime Passos Date: Mon, 9 Sep 2019 19:27:08 -0300 Subject: [PATCH 011/136] 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 2b6ae5081aa26479aa2e01f8fcee4fbf3c785bae Mon Sep 17 00:00:00 2001 From: Jaime Passos Date: Mon, 9 Sep 2019 19:34:51 -0300 Subject: [PATCH 012/136] 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 356e3c274d71a75ba5d1ba5070cfe39821527a8e Mon Sep 17 00:00:00 2001 From: Jaime Passos Date: Tue, 10 Sep 2019 16:59:37 -0300 Subject: [PATCH 013/136] 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 b36418882f60b6156193902ce86246f8a9dccbb2 Mon Sep 17 00:00:00 2001 From: Jaime Passos Date: Tue, 10 Sep 2019 18:17:02 -0300 Subject: [PATCH 014/136] 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 2e930686183e6ee8de1bec7b1807ceb554f00f26 Mon Sep 17 00:00:00 2001 From: Jaime Passos Date: Tue, 10 Sep 2019 18:33:06 -0300 Subject: [PATCH 015/136] 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 db1e38451e5776e1c3e36802c0099d8c2b91dc5f Mon Sep 17 00:00:00 2001 From: Jaime Passos Date: Tue, 10 Sep 2019 18:34:29 -0300 Subject: [PATCH 016/136] 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 d3fb98dfe47cac3bd8cd71bd8c1fc77989c5e91c Mon Sep 17 00:00:00 2001 From: Jaime Passos Date: Tue, 12 Nov 2019 21:44:43 -0300 Subject: [PATCH 017/136] 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 8f2a34f58c251d09d1c83089b929a4220186ee17 Mon Sep 17 00:00:00 2001 From: Jaime Passos Date: Tue, 12 Nov 2019 22:03:40 -0300 Subject: [PATCH 018/136] 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 b28e4d95520b483ecd3ac3ccf270b35721112338 Mon Sep 17 00:00:00 2001 From: Jaime Passos Date: Tue, 10 Dec 2019 23:40:15 -0300 Subject: [PATCH 019/136] 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 24688649346ff97431d63fa2bce4e1e4114135d2 Mon Sep 17 00:00:00 2001 From: Jaime Passos Date: Thu, 12 Dec 2019 01:29:59 -0300 Subject: [PATCH 020/136] 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 26e67702bff0b083b953e9653d5f49895270a2d7 Mon Sep 17 00:00:00 2001 From: Jaime Passos Date: Tue, 17 Dec 2019 15:56:56 -0300 Subject: [PATCH 021/136] 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 11dc6801dce0cf74544df794f6e291e188cfab3b Mon Sep 17 00:00:00 2001 From: Jaime Passos Date: Tue, 17 Dec 2019 16:14:26 -0300 Subject: [PATCH 022/136] 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 ed6d6e3bd77db65feeaa050cffc26c213742788d Mon Sep 17 00:00:00 2001 From: Jaime Passos Date: Tue, 17 Dec 2019 16:28:32 -0300 Subject: [PATCH 023/136] 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 81ed4b38fceb10d2e3586df70382f1bf73e6304e Mon Sep 17 00:00:00 2001 From: Jaime Passos Date: Tue, 17 Dec 2019 18:04:05 -0300 Subject: [PATCH 024/136] 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 0b87dd355410ed9036d8efa7aee60f9941492e86 Mon Sep 17 00:00:00 2001 From: James R Date: Tue, 1 Oct 2019 23:52:08 -0700 Subject: [PATCH 025/136] 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 c40cf626bf12cc84741605722d46a0c0be6c36d8 Mon Sep 17 00:00:00 2001 From: Jaime Passos Date: Thu, 19 Dec 2019 17:14:56 -0300 Subject: [PATCH 026/136] 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 39321e8637b7a971f4de416791b756f553b2acf1 Mon Sep 17 00:00:00 2001 From: GoldenTails Date: Mon, 23 Dec 2019 14:01:37 -0600 Subject: [PATCH 027/136] Cap dashspeed to at least mindash before revving. --- src/p_user.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/p_user.c b/src/p_user.c index 2b82ae697..003135a90 100644 --- a/src/p_user.c +++ b/src/p_user.c @@ -4635,6 +4635,8 @@ static void P_DoSpinAbility(player_t *player, ticcmd_t *cmd) S_StartSound(player->mo, sfx_spin); break; } + if (player->dashspeed < player->mindash) + player->dashspeed = player->mindash; if (player->dashspeed < player->maxdash && player->mindash != player->maxdash) { #define chargecalculation (6*(player->dashspeed - player->mindash))/(player->maxdash - player->mindash) From edd6f743ec0886abf46014a42f6847e80f009fa1 Mon Sep 17 00:00:00 2001 From: GoldenTails Date: Tue, 24 Dec 2019 13:55:19 -0600 Subject: [PATCH 028/136] Also cap dashspeed to at most maxdash. --- src/p_user.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/p_user.c b/src/p_user.c index 003135a90..10d55ae0e 100644 --- a/src/p_user.c +++ b/src/p_user.c @@ -4637,6 +4637,10 @@ static void P_DoSpinAbility(player_t *player, ticcmd_t *cmd) } if (player->dashspeed < player->mindash) player->dashspeed = player->mindash; + + if (player->dashspeed < player->maxdash) + player->dashspeed = player->maxdash; + if (player->dashspeed < player->maxdash && player->mindash != player->maxdash) { #define chargecalculation (6*(player->dashspeed - player->mindash))/(player->maxdash - player->mindash) From 4652d6444acae3721dfb90b789ebcdb6b9517c6b Mon Sep 17 00:00:00 2001 From: Jaime Passos Date: Thu, 26 Dec 2019 00:07:04 -0300 Subject: [PATCH 029/136] 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 f1eb51d2479098d0b66ec2d610278ff057cb67d0 Mon Sep 17 00:00:00 2001 From: Jaime Passos Date: Thu, 26 Dec 2019 00:55:34 -0300 Subject: [PATCH 030/136] 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 14fed1f64476ff99938252d427cd247de3e0f12a Mon Sep 17 00:00:00 2001 From: James R Date: Wed, 25 Dec 2019 20:44:25 -0800 Subject: [PATCH 031/136] More fine tuned versioning You get a PACKETVERSION, for when some packets change format. You get SRB2APPLICATION, for when you have big fucking mod. --- src/d_clisrv.c | 25 +++++++++++++++++++++++++ src/d_clisrv.h | 23 +++++++++++++++++++++++ src/doomdef.h | 3 +++ 3 files changed, 51 insertions(+) diff --git a/src/d_clisrv.c b/src/d_clisrv.c index 6520a1aa1..5dd879b61 100644 --- a/src/d_clisrv.c +++ b/src/d_clisrv.c @@ -1271,8 +1271,12 @@ static boolean CL_SendJoin(void) if (splitscreen || botingame) localplayers++; netbuffer->u.clientcfg.localplayers = localplayers; + netbuffer->u.clientcfg._255 = 255; + netbuffer->u.clientcfg.packetversion = PACKETVERSION; netbuffer->u.clientcfg.version = VERSION; netbuffer->u.clientcfg.subversion = SUBVERSION; + strncpy(netbuffer->u.clientcfg.application, SRB2APPLICATION, + sizeof netbuffer->u.clientcfg.application); strncpy(netbuffer->u.clientcfg.names[0], cv_playername.zstring, MAXPLAYERNAME); strncpy(netbuffer->u.clientcfg.names[1], cv_playername2.zstring, MAXPLAYERNAME); return HSendPacket(servernode, true, 0, sizeof (clientconfig_pak)); @@ -1283,8 +1287,12 @@ static void SV_SendServerInfo(INT32 node, tic_t servertime) UINT8 *p; netbuffer->packettype = PT_SERVERINFO; + netbuffer->u.serverinfo._255 = 255; + netbuffer->u.serverinfo.packetversion = PACKETVERSION; netbuffer->u.serverinfo.version = VERSION; netbuffer->u.serverinfo.subversion = SUBVERSION; + strncpy(netbuffer->u.serverinfo.application, SRB2APPLICATION, + sizeof netbuffer->u.serverinfo.application); // return back the time value so client can compute their ping netbuffer->u.serverinfo.time = (tic_t)LONG(servertime); netbuffer->u.serverinfo.leveltime = (tic_t)LONG(leveltime); @@ -1718,12 +1726,21 @@ static void SL_InsertServer(serverinfo_pak* info, SINT8 node) if (serverlistcount >= MAXSERVERLIST) return; // list full + if (info->_255 != 255) + return;/* old packet format */ + + if (info->packetversion != PACKETVERSION) + return;/* old new packet format */ + if (info->version != VERSION) return; // Not same version. if (info->subversion != SUBVERSION) return; // Close, but no cigar. + if (strcmp(info->application, SRB2APPLICATION)) + return;/* that's a different mod */ + i = serverlistcount++; } @@ -3507,6 +3524,12 @@ static void HandleConnect(SINT8 node) if (bannednode && bannednode[node]) SV_SendRefuse(node, M_GetText("You have been banned\nfrom the server")); + else if (netbuffer->u.clientcfg._255 != 255 || + netbuffer->u.clientcfg.packetversion != PACKETVERSION) + SV_SendRefuse(node, "Incompatible packet formats."); + else if (strncmp(netbuffer->u.clientcfg.application, SRB2APPLICATION, + sizeof netbuffer->u.clientcfg.application)) + SV_SendRefuse(node, "Different SRB2 modifications\nare not compatible."); else if (netbuffer->u.clientcfg.version != VERSION || netbuffer->u.clientcfg.subversion != SUBVERSION) SV_SendRefuse(node, va(M_GetText("Different SRB2 versions cannot\nplay a netgame!\n(server version %d.%d.%d)"), VERSION/100, VERSION%100, SUBVERSION)); @@ -3629,6 +3652,8 @@ static void HandleServerInfo(SINT8 node) const tic_t ticdiff = (ticnow - ticthen)*1000/NEWTICRATE; netbuffer->u.serverinfo.time = (tic_t)LONG(ticdiff); netbuffer->u.serverinfo.servername[MAXSERVERNAME-1] = 0; + netbuffer->u.serverinfo.application + [sizeof netbuffer->u.serverinfo.application - 1] = '\0'; SL_InsertServer(&netbuffer->u.serverinfo, node); } diff --git a/src/d_clisrv.h b/src/d_clisrv.h index 4ba4ee0eb..49f8afc76 100644 --- a/src/d_clisrv.h +++ b/src/d_clisrv.h @@ -19,6 +19,16 @@ #include "tables.h" #include "d_player.h" +/* +The 'packet version' may be used with packets whose +format is expected to change between versions. + +This version is independent of the mod name, and standard +version and subversion. It should only account for the +basic fields of the packet, and change infrequently. +*/ +#define PACKETVERSION 0 + // Network play related stuff. // There is a data struct that stores network // communication related stuff, and another @@ -320,8 +330,13 @@ typedef struct { #pragma warning(default : 4200) #endif +#define MAXAPPLICATION 16 + typedef struct { + UINT8 _255;/* see serverinfo_pak */ + UINT8 packetversion; + char application[MAXAPPLICATION]; UINT8 version; // Different versions don't work UINT8 subversion; // Contains build version UINT8 localplayers; @@ -334,6 +349,14 @@ typedef struct // This packet is too large typedef struct { + /* + In the old packet, 'version' is the first field. Now that field is set + to 255 always, so older versions won't be confused with the new + versions or vice-versa. + */ + UINT8 _255; + UINT8 packetversion; + char application[MAXAPPLICATION]; UINT8 version; UINT8 subversion; UINT8 numberofplayer; diff --git a/src/doomdef.h b/src/doomdef.h index 0da1a1fed..a8b927a73 100644 --- a/src/doomdef.h +++ b/src/doomdef.h @@ -130,6 +130,9 @@ extern FILE *logstream; extern char logfilename[1024]; #endif +/* A mod name to further distinguish versions. */ +#define SRB2APPLICATION "SRB2" + //#define DEVELOP // Disable this for release builds to remove excessive cheat commands and enable MD5 checking and stuff, all in one go. :3 #ifdef DEVELOP #define VERSION 0 // Game version From 016cced4a1841a1dcea85812af3c7dec21a310cd Mon Sep 17 00:00:00 2001 From: Jaime Passos Date: Thu, 26 Dec 2019 01:58:38 -0300 Subject: [PATCH 032/136] 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 08ab0664f5b9a7004af2c99218bbefd2f54a1777 Mon Sep 17 00:00:00 2001 From: Jaime Passos Date: Thu, 26 Dec 2019 15:27:16 -0300 Subject: [PATCH 033/136] 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 034/136] 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 176b853b017728142581babe3c71719c37723607 Mon Sep 17 00:00:00 2001 From: Sally Cochenour Date: Thu, 26 Dec 2019 14:02:02 -0500 Subject: [PATCH 035/136] Fix scoreadd not doing anything when modified by Lua This does not change any vanilla behavior, as scoreadd is reset constantly on the ground anyway -- this simply makes the behavior modifiable for Lua scripts. --- src/p_inter.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/src/p_inter.c b/src/p_inter.c index 70fb01fd0..c82e36c31 100644 --- a/src/p_inter.c +++ b/src/p_inter.c @@ -2481,9 +2481,7 @@ void P_KillMobj(mobj_t *target, mobj_t *inflictor, mobj_t *source, UINT8 damaget P_SetMobjState(scoremobj, scorestate); - // On ground? No chain starts. - if (source->player->powers[pw_invulnerability] || !P_IsObjectOnGround(source)) - source->player->scoreadd = locscoreadd; + source->player->scoreadd = locscoreadd; } } From c8f9896e2df0fca9c046ca57682a01967b3480ac Mon Sep 17 00:00:00 2001 From: Jaime Passos Date: Thu, 26 Dec 2019 16:25:04 -0300 Subject: [PATCH 036/136] 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 1ac4b608dc589ea69b39ed2476b3bdb30c8a884b Mon Sep 17 00:00:00 2001 From: Jaime Passos Date: Thu, 26 Dec 2019 17:15:30 -0300 Subject: [PATCH 037/136] 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 51e51dfa4c9e4ae740e05b1e5f02bb6afd490ab2 Mon Sep 17 00:00:00 2001 From: Jaime Passos Date: Thu, 26 Dec 2019 17:20:17 -0300 Subject: [PATCH 038/136] 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 96980749ac7661e9068be7cdb86031c27af36659 Mon Sep 17 00:00:00 2001 From: Jaime Passos Date: Thu, 26 Dec 2019 17:39:18 -0300 Subject: [PATCH 039/136] 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 b90236281c5170b843e5a1135a45699239c37434 Mon Sep 17 00:00:00 2001 From: Jaime Passos Date: Thu, 26 Dec 2019 18:13:03 -0300 Subject: [PATCH 040/136] 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 43dab49e7487b25928550a68c2b0918824bf5a70 Mon Sep 17 00:00:00 2001 From: James R Date: Thu, 26 Dec 2019 18:12:10 -0800 Subject: [PATCH 041/136] 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 4100e43a9d44bb55103951c392db0aee7c8415dd Mon Sep 17 00:00:00 2001 From: James R Date: Thu, 26 Dec 2019 18:15:19 -0800 Subject: [PATCH 042/136] 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 e3d08831f2db54cfd6f970182d99e2b2777ac86b Mon Sep 17 00:00:00 2001 From: James R Date: Thu, 26 Dec 2019 18:15:52 -0800 Subject: [PATCH 043/136] 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 bbed1a16bae5025af4f6a27a5a2e2db1c7df4b5c Mon Sep 17 00:00:00 2001 From: James R Date: Thu, 26 Dec 2019 18:20:48 -0800 Subject: [PATCH 044/136] 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 d57083264e93f1020c2730e072c7a7b5417e08b3 Mon Sep 17 00:00:00 2001 From: James R Date: Thu, 26 Dec 2019 18:23:01 -0800 Subject: [PATCH 045/136] 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 a5ef201e3fd2b620271c8990d477cfff77a70bc2 Mon Sep 17 00:00:00 2001 From: Jaime Passos Date: Thu, 26 Dec 2019 23:26:43 -0300 Subject: [PATCH 046/136] 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 c8e08ec617c462e3e50e510c2421b23a48bac113 Mon Sep 17 00:00:00 2001 From: James R Date: Mon, 5 Aug 2019 15:00:09 -0700 Subject: [PATCH 047/136] Expose CV_FindVar (cherry picked from commit 0e9d69d6a3759686ca8bb567817be650291ea0e1) --- src/command.c | 4 ++-- src/command.h | 3 +++ 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/src/command.c b/src/command.c index 33d8ead96..309881382 100644 --- a/src/command.c +++ b/src/command.c @@ -54,7 +54,7 @@ static void COM_Add_f(void); static void CV_EnforceExecVersion(void); static boolean CV_FilterVarByVersion(consvar_t *v, const char *valstr); static boolean CV_Command(void); -static consvar_t *CV_FindVar(const char *name); +consvar_t *CV_FindVar(const char *name); static const char *CV_StringValue(const char *var_name); static consvar_t *consvar_vars; // list of registered console variables @@ -1055,7 +1055,7 @@ static const char *cv_null_string = ""; * \return Pointer to the variable if found, or NULL. * \sa CV_FindNetVar */ -static consvar_t *CV_FindVar(const char *name) +consvar_t *CV_FindVar(const char *name) { consvar_t *cvar; diff --git a/src/command.h b/src/command.h index 51e161cd0..54584bb2d 100644 --- a/src/command.h +++ b/src/command.h @@ -140,6 +140,9 @@ void CV_ToggleExecVersion(boolean enable); // register a variable for use at the console void CV_RegisterVar(consvar_t *variable); +// returns a console variable by name +consvar_t *CV_FindVar(const char *name); + // sets changed to 0 for every console variable void CV_ClearChangedFlags(void); From c92378fab71e51d5369844c247c7b33112b828c0 Mon Sep 17 00:00:00 2001 From: James R Date: Mon, 5 Aug 2019 15:00:21 -0700 Subject: [PATCH 048/136] Lua CV_FindVar function (cherry picked from commit b5746c231d17cd7b58c6b633e242d5ad26ad7017) --- src/lua_consolelib.c | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/src/lua_consolelib.c b/src/lua_consolelib.c index 58e720c85..65dd553cd 100644 --- a/src/lua_consolelib.c +++ b/src/lua_consolelib.c @@ -427,6 +427,26 @@ static int lib_cvRegisterVar(lua_State *L) return 1; } +static int lib_cvFindVar(lua_State *L) +{ + consvar_t *cv; + if (( cv = CV_FindVar(luaL_checkstring(L,1)) )) + { + lua_settop(L,1);/* We only want one argument in the stack. */ + lua_pushlightuserdata(L, cv);/* Now the second value on stack. */ + luaL_getmetatable(L, META_CVAR); + /* + The metatable is the last value on the stack, so this + applies it to the second value, which is the cvar. + */ + lua_setmetatable(L,2); + lua_pushvalue(L,2); + return 1; + } + else + return 0; +} + // CONS_Printf for a single player // Use 'print' in baselib for a global message. static int lib_consPrintf(lua_State *L) @@ -466,6 +486,7 @@ static luaL_Reg lib[] = { {"COM_BufAddText", lib_comBufAddText}, {"COM_BufInsertText", lib_comBufInsertText}, {"CV_RegisterVar", lib_cvRegisterVar}, + {"CV_FindVar", lib_cvFindVar}, {"CONS_Printf", lib_consPrintf}, {NULL, NULL} }; From 6de7b7eb99f4ccd12c2d93e1d735814b35eb265f Mon Sep 17 00:00:00 2001 From: Jaime Passos Date: Thu, 26 Dec 2019 23:39:40 -0300 Subject: [PATCH 049/136] 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 02104402ed402dda2f67b9c52c891a475be93df5 Mon Sep 17 00:00:00 2001 From: James R Date: Thu, 26 Dec 2019 18:44:02 -0800 Subject: [PATCH 050/136] 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 ed11e89fdc542bbc800b461152cfb7068add5e2b Mon Sep 17 00:00:00 2001 From: Jaime Passos Date: Thu, 26 Dec 2019 23:49:31 -0300 Subject: [PATCH 051/136] 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 543f80510b6af4d21de837d6042febf5b129eb82 Mon Sep 17 00:00:00 2001 From: Jaime Passos Date: Thu, 26 Dec 2019 23:52:42 -0300 Subject: [PATCH 052/136] 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 b8e91a50a55de98e09e18a36ba8527157d3be190 Mon Sep 17 00:00:00 2001 From: Jaime Passos Date: Fri, 27 Dec 2019 00:02:30 -0300 Subject: [PATCH 053/136] 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 5b715fa11a9ce32457d3fadd7de8f9366d3b7eff Mon Sep 17 00:00:00 2001 From: James R Date: Thu, 26 Dec 2019 19:27:25 -0800 Subject: [PATCH 054/136] Pop monitors properly so Metal doesn't destroy enemy team's monitors --- src/p_map.c | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/src/p_map.c b/src/p_map.c index 1b6f23cde..96fb8ee07 100644 --- a/src/p_map.c +++ b/src/p_map.c @@ -829,13 +829,10 @@ static boolean PIT_CheckThing(mobj_t *thing) for (iter = thing->subsector->sector->thinglist; iter; iter = iter->snext) if (iter->type == thing->type && iter->health > 0 && iter->flags & MF_SOLID && (iter == thing || P_AproxDistance(P_AproxDistance(thing->x - iter->x, thing->y - iter->y), thing->z - iter->z) < 56*thing->scale))//FixedMul(56*FRACUNIT, thing->scale)) P_KillMobj(iter, tmthing, tmthing, 0); + return true; } else - { - thing->health = 0; - P_KillMobj(thing, tmthing, tmthing, 0); - } - return true; + return P_DamageMobj(thing, tmthing, tmthing, 1, 0); } // vectorise metal - done in a special case as at this point neither has the right flags for touching From 518714a51a2929d1e6aa96c072e57391590d8c6d Mon Sep 17 00:00:00 2001 From: Jaime Passos Date: Fri, 27 Dec 2019 00:37:40 -0300 Subject: [PATCH 055/136] 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 be323975629af6e08be003febacfd3ce3dc49bc4 Mon Sep 17 00:00:00 2001 From: Jaime Passos Date: Fri, 27 Dec 2019 01:44:27 -0300 Subject: [PATCH 056/136] Respawn delay gametype rule --- src/dehacked.c | 1 + src/doomstat.h | 1 + src/g_game.c | 10 +++++----- src/p_user.c | 25 ++++++++++++++----------- src/st_stuff.c | 2 +- 5 files changed, 22 insertions(+), 17 deletions(-) diff --git a/src/dehacked.c b/src/dehacked.c index b77939c2a..939e8c8cf 100644 --- a/src/dehacked.c +++ b/src/dehacked.c @@ -8928,6 +8928,7 @@ static const char *const GAMETYPERULE_LIST[] = { "OVERTIME", "HURTMESSAGES", "SPAWNINVUL", + "RESPAWNDELAY", NULL }; diff --git a/src/doomstat.h b/src/doomstat.h index b7bb7a362..5dc3a6eb9 100644 --- a/src/doomstat.h +++ b/src/doomstat.h @@ -423,6 +423,7 @@ enum GameTypeRules GTR_OVERTIME = 1<<26, // Allow overtime GTR_HURTMESSAGES = 1<<27, // Hit and death messages GTR_SPAWNINVUL = 1<<28, // Babysitting deterrent + GTR_RESPAWNDELAY = 1<<29, // Respawn delay }; // String names for gametypes diff --git a/src/g_game.c b/src/g_game.c index 19b18ef8c..3f1441922 100644 --- a/src/g_game.c +++ b/src/g_game.c @@ -3201,17 +3201,17 @@ UINT32 gametypedefaultrules[NUMGAMETYPES] = GTR_RACE|GTR_SPAWNENEMIES|GTR_SPAWNINVUL|GTR_ALLOWEXIT, // Match - GTR_RINGSLINGER|GTR_FIRSTPERSON|GTR_SPECTATORS|GTR_POINTLIMIT|GTR_TIMELIMIT|GTR_MATCHEMERALDS|GTR_SPAWNINVUL|GTR_PITYSHIELD|GTR_DEATHPENALTY, + GTR_RINGSLINGER|GTR_FIRSTPERSON|GTR_SPECTATORS|GTR_POINTLIMIT|GTR_TIMELIMIT|GTR_MATCHEMERALDS|GTR_SPAWNINVUL|GTR_RESPAWNDELAY|GTR_PITYSHIELD|GTR_DEATHPENALTY, // Team Match - GTR_RINGSLINGER|GTR_FIRSTPERSON|GTR_SPECTATORS|GTR_TEAMS|GTR_POINTLIMIT|GTR_TIMELIMIT|GTR_SPAWNINVUL|GTR_PITYSHIELD, + GTR_RINGSLINGER|GTR_FIRSTPERSON|GTR_SPECTATORS|GTR_TEAMS|GTR_POINTLIMIT|GTR_TIMELIMIT|GTR_SPAWNINVUL|GTR_RESPAWNDELAY|GTR_PITYSHIELD, // Tag - GTR_RINGSLINGER|GTR_FIRSTPERSON|GTR_TAG|GTR_SPECTATORS|GTR_POINTLIMIT|GTR_TIMELIMIT|GTR_HIDETIME|GTR_BLINDFOLDED|GTR_SPAWNINVUL, + GTR_RINGSLINGER|GTR_FIRSTPERSON|GTR_TAG|GTR_SPECTATORS|GTR_POINTLIMIT|GTR_TIMELIMIT|GTR_HIDETIME|GTR_BLINDFOLDED|GTR_SPAWNINVUL|GTR_RESPAWNDELAY, // Hide and Seek - GTR_RINGSLINGER|GTR_FIRSTPERSON|GTR_TAG|GTR_SPECTATORS|GTR_POINTLIMIT|GTR_TIMELIMIT|GTR_HIDETIME|GTR_BLINDFOLDED|GTR_SPAWNINVUL, + GTR_RINGSLINGER|GTR_FIRSTPERSON|GTR_TAG|GTR_SPECTATORS|GTR_POINTLIMIT|GTR_TIMELIMIT|GTR_HIDETIME|GTR_BLINDFOLDED|GTR_SPAWNINVUL|GTR_RESPAWNDELAY, // CTF - GTR_RINGSLINGER|GTR_FIRSTPERSON|GTR_SPECTATORS|GTR_TEAMS|GTR_TEAMFLAGS|GTR_POINTLIMIT|GTR_TIMELIMIT|GTR_MATCHEMERALDS|GTR_SPAWNINVUL|GTR_PITYSHIELD, + GTR_RINGSLINGER|GTR_FIRSTPERSON|GTR_SPECTATORS|GTR_TEAMS|GTR_TEAMFLAGS|GTR_POINTLIMIT|GTR_TIMELIMIT|GTR_MATCHEMERALDS|GTR_SPAWNINVUL|GTR_RESPAWNDELAY|GTR_PITYSHIELD, }; // diff --git a/src/p_user.c b/src/p_user.c index fbcc17d24..a85457ad4 100644 --- a/src/p_user.c +++ b/src/p_user.c @@ -9462,19 +9462,22 @@ static void P_DeathThink(player_t *player) // Respawn with jump button, force respawn time (3 second default, cheat protected) in shooter modes. if (cmd->buttons & BT_JUMP) { + // You're a spectator, so respawn right away. if (gametype != GT_COOP && player->spectator) player->playerstate = PST_REBORN; - else switch(gametype) { - case GT_COOP: - case GT_COMPETITION: - case GT_RACE: - if (player->deadtimer > TICRATE) - player->playerstate = PST_REBORN; - break; - default: - if (player->deadtimer > cv_respawntime.value*TICRATE) - player->playerstate = PST_REBORN; - break; + else + { + // Give me one second. + INT32 respawndelay = TICRATE; + + // Non-platform gametypes + if (gametyperules & GTR_RESPAWNDELAY) + respawndelay = (cv_respawntime.value*TICRATE); + + // You've been dead for enough time. + // You may now respawn. + if (player->deadtimer > respawndelay) + player->playerstate = PST_REBORN; } } diff --git a/src/st_stuff.c b/src/st_stuff.c index 5e05030c3..d8b9a8059 100644 --- a/src/st_stuff.c +++ b/src/st_stuff.c @@ -2202,7 +2202,7 @@ static void ST_drawTextHUD(void) donef12 = true; } } - else if (!G_PlatformGametype() && stplyr->playerstate == PST_DEAD && stplyr->lives) // Death overrides spectator text. + else if ((gametyperules & GTR_RESPAWNDELAY) && stplyr->playerstate == PST_DEAD && stplyr->lives) // Death overrides spectator text. { INT32 respawntime = cv_respawntime.value - stplyr->deadtimer/TICRATE; From adb34258f1863d2e84b0078241de1f41f37d4957 Mon Sep 17 00:00:00 2001 From: Jaime Passos Date: Fri, 27 Dec 2019 02:07:13 -0300 Subject: [PATCH 057/136] P_SetupCamera funny --- src/p_setup.c | 11 ++--------- 1 file changed, 2 insertions(+), 9 deletions(-) diff --git a/src/p_setup.c b/src/p_setup.c index 9acc4adb3..39f2ef545 100644 --- a/src/p_setup.c +++ b/src/p_setup.c @@ -2447,17 +2447,10 @@ static void P_SetupCamera(void) { mapthing_t *thing; - switch (gametype) - { - case GT_MATCH: - case GT_TAG: + if ((gametyperules & GTR_DEATHMATCHSTARTS) || (gametype == GT_MATCH || gametype == GT_TAG)) thing = deathmatchstarts[0]; - break; - - default: + else thing = playerstarts[0]; - break; - } if (thing) { From ca3941f5b87331c0902480c220f264f38ea299fd Mon Sep 17 00:00:00 2001 From: Jaime Passos Date: Fri, 27 Dec 2019 12:14:33 -0300 Subject: [PATCH 058/136] use GTR_DEATHMATCHSTARTS --- src/g_game.c | 13 ++++++------- src/p_setup.c | 2 +- 2 files changed, 7 insertions(+), 8 deletions(-) diff --git a/src/g_game.c b/src/g_game.c index 3f1441922..3ba3ab40f 100644 --- a/src/g_game.c +++ b/src/g_game.c @@ -2689,8 +2689,7 @@ void G_SpawnPlayer(INT32 playernum, boolean starpost) // -- DM/Tag/CTF-spectator/etc -- // Order: DM->CTF->Coop - else if ((gametyperules & GTR_DEATHMATCHSTARTS) || gametype == GT_MATCH || gametype == GT_TEAMMATCH || gametype == GT_CTF - || ((gametype == GT_TAG || gametype == GT_HIDEANDSEEK) && !(players[playernum].pflags & PF_TAGIT))) + else if ((gametyperules & GTR_DEATHMATCHSTARTS) && !(players[playernum].pflags & PF_TAGIT)) { if (!(spawnpoint = G_FindMatchStart(playernum)) // find a DM start && !(spawnpoint = G_FindCTFStart(playernum))) // find a CTF start @@ -3201,17 +3200,17 @@ UINT32 gametypedefaultrules[NUMGAMETYPES] = GTR_RACE|GTR_SPAWNENEMIES|GTR_SPAWNINVUL|GTR_ALLOWEXIT, // Match - GTR_RINGSLINGER|GTR_FIRSTPERSON|GTR_SPECTATORS|GTR_POINTLIMIT|GTR_TIMELIMIT|GTR_MATCHEMERALDS|GTR_SPAWNINVUL|GTR_RESPAWNDELAY|GTR_PITYSHIELD|GTR_DEATHPENALTY, + GTR_RINGSLINGER|GTR_FIRSTPERSON|GTR_SPECTATORS|GTR_POINTLIMIT|GTR_TIMELIMIT|GTR_MATCHEMERALDS|GTR_DEATHMATCHSTARTS|GTR_SPAWNINVUL|GTR_RESPAWNDELAY|GTR_PITYSHIELD|GTR_DEATHPENALTY, // Team Match - GTR_RINGSLINGER|GTR_FIRSTPERSON|GTR_SPECTATORS|GTR_TEAMS|GTR_POINTLIMIT|GTR_TIMELIMIT|GTR_SPAWNINVUL|GTR_RESPAWNDELAY|GTR_PITYSHIELD, + GTR_RINGSLINGER|GTR_FIRSTPERSON|GTR_SPECTATORS|GTR_TEAMS|GTR_POINTLIMIT|GTR_TIMELIMIT|GTR_DEATHMATCHSTARTS|GTR_SPAWNINVUL|GTR_RESPAWNDELAY|GTR_PITYSHIELD, // Tag - GTR_RINGSLINGER|GTR_FIRSTPERSON|GTR_TAG|GTR_SPECTATORS|GTR_POINTLIMIT|GTR_TIMELIMIT|GTR_HIDETIME|GTR_BLINDFOLDED|GTR_SPAWNINVUL|GTR_RESPAWNDELAY, + GTR_RINGSLINGER|GTR_FIRSTPERSON|GTR_TAG|GTR_SPECTATORS|GTR_POINTLIMIT|GTR_TIMELIMIT|GTR_HIDETIME|GTR_BLINDFOLDED|GTR_DEATHMATCHSTARTS|GTR_SPAWNINVUL|GTR_RESPAWNDELAY, // Hide and Seek - GTR_RINGSLINGER|GTR_FIRSTPERSON|GTR_TAG|GTR_SPECTATORS|GTR_POINTLIMIT|GTR_TIMELIMIT|GTR_HIDETIME|GTR_BLINDFOLDED|GTR_SPAWNINVUL|GTR_RESPAWNDELAY, + GTR_RINGSLINGER|GTR_FIRSTPERSON|GTR_TAG|GTR_SPECTATORS|GTR_POINTLIMIT|GTR_TIMELIMIT|GTR_HIDETIME|GTR_BLINDFOLDED|GTR_DEATHMATCHSTARTS|GTR_SPAWNINVUL|GTR_RESPAWNDELAY, // CTF - GTR_RINGSLINGER|GTR_FIRSTPERSON|GTR_SPECTATORS|GTR_TEAMS|GTR_TEAMFLAGS|GTR_POINTLIMIT|GTR_TIMELIMIT|GTR_MATCHEMERALDS|GTR_SPAWNINVUL|GTR_RESPAWNDELAY|GTR_PITYSHIELD, + GTR_RINGSLINGER|GTR_FIRSTPERSON|GTR_SPECTATORS|GTR_TEAMS|GTR_TEAMFLAGS|GTR_POINTLIMIT|GTR_TIMELIMIT|GTR_MATCHEMERALDS|GTR_DEATHMATCHSTARTS|GTR_SPAWNINVUL|GTR_RESPAWNDELAY|GTR_PITYSHIELD, }; // diff --git a/src/p_setup.c b/src/p_setup.c index 39f2ef545..5fc740191 100644 --- a/src/p_setup.c +++ b/src/p_setup.c @@ -2447,7 +2447,7 @@ static void P_SetupCamera(void) { mapthing_t *thing; - if ((gametyperules & GTR_DEATHMATCHSTARTS) || (gametype == GT_MATCH || gametype == GT_TAG)) + if (gametyperules & GTR_DEATHMATCHSTARTS) thing = deathmatchstarts[0]; else thing = playerstarts[0]; From 5e328d6d332980376dae47e1f69c6f932f1aac0b Mon Sep 17 00:00:00 2001 From: Jaime Passos Date: Fri, 27 Dec 2019 12:17:38 -0300 Subject: [PATCH 059/136] check if the gametype allows spectators to allow jump key respawn --- src/p_user.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/p_user.c b/src/p_user.c index a85457ad4..e9c32813a 100644 --- a/src/p_user.c +++ b/src/p_user.c @@ -9463,7 +9463,7 @@ static void P_DeathThink(player_t *player) if (cmd->buttons & BT_JUMP) { // You're a spectator, so respawn right away. - if (gametype != GT_COOP && player->spectator) + if ((gametyperules & GTR_SPECTATORS) && player->spectator) player->playerstate = PST_REBORN; else { From 964125c8cfc49d55453199aa1f688a71d159864e Mon Sep 17 00:00:00 2001 From: Jaime Passos Date: Fri, 27 Dec 2019 12:23:50 -0300 Subject: [PATCH 060/136] change this > to >= --- src/m_menu.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/m_menu.c b/src/m_menu.c index b3ff8ce71..5e405156c 100644 --- a/src/m_menu.c +++ b/src/m_menu.c @@ -4690,7 +4690,7 @@ static boolean M_CanShowLevelOnPlatter(INT32 mapnum, INT32 gt) if (gt == GT_RACE && (mapheaderinfo[mapnum]->typeoflevel & TOL_RACE)) return true; - if (gt > 0 && gt < gametypecount && (mapheaderinfo[mapnum]->typeoflevel & gametypetol[gt])) + if (gt >= 0 && gt < gametypecount && (mapheaderinfo[mapnum]->typeoflevel & gametypetol[gt])) return true; return false; From 203f4c50a0516f26f2eac8e61be9340558c31c6e Mon Sep 17 00:00:00 2001 From: Jaime Passos Date: Fri, 27 Dec 2019 12:28:00 -0300 Subject: [PATCH 061/136] add G_CompetitionGametype(void) --- src/g_game.c | 10 ++++++++++ src/g_game.h | 1 + src/p_setup.c | 2 +- src/p_user.c | 2 +- 4 files changed, 13 insertions(+), 2 deletions(-) diff --git a/src/g_game.c b/src/g_game.c index 3ba3ab40f..28de6693f 100644 --- a/src/g_game.c +++ b/src/g_game.c @@ -3492,6 +3492,16 @@ boolean G_TagGametype(void) return (gametyperules & GTR_TAG); } +// +// G_CompetitionGametype +// +// For gametypes that are race gametypes, and have lives. +// +boolean G_CompetitionGametype(void) +{ + return ((gametyperules & GTR_RACE) && (gametyperules & GTR_LIVES)); +} + /** Get the typeoflevel flag needed to indicate support of a gametype. * In single-player, this always returns TOL_SP. * \param gametype The gametype for which support is desired. diff --git a/src/g_game.h b/src/g_game.h index 238dd1964..6916bba6e 100644 --- a/src/g_game.h +++ b/src/g_game.h @@ -223,6 +223,7 @@ boolean G_GametypeHasSpectators(void); boolean G_RingSlingerGametype(void); boolean G_PlatformGametype(void); boolean G_TagGametype(void); +boolean G_CompetitionGametype(void); boolean G_EnoughPlayersFinished(void); void G_ExitLevel(void); void G_NextLevel(void); diff --git a/src/p_setup.c b/src/p_setup.c index 5fc740191..3f49a1680 100644 --- a/src/p_setup.c +++ b/src/p_setup.c @@ -2159,7 +2159,7 @@ static void P_LevelInitStuff(void) { G_PlayerReborn(i, true); - if (canresetlives && (netgame || multiplayer) && playeringame[i] && (gametype == GT_COMPETITION || players[i].lives <= 0)) + if (canresetlives && (netgame || multiplayer) && playeringame[i] && (G_CompetitionGametype() || players[i].lives <= 0)) { // In Co-Op, replenish a user's lives if they are depleted. players[i].lives = cv_startinglives.value; diff --git a/src/p_user.c b/src/p_user.c index e9c32813a..ff6ffc677 100644 --- a/src/p_user.c +++ b/src/p_user.c @@ -9491,7 +9491,7 @@ static void P_DeathThink(player_t *player) INT32 i, deadtimercheck = INT32_MAX; // In a net/multiplayer game, and out of lives - if (gametype == GT_COMPETITION) + if (G_CompetitionGametype()) { for (i = 0; i < MAXPLAYERS; i++) { From 8a3b47e1a9519cfb46340631e7c59538a5655263 Mon Sep 17 00:00:00 2001 From: Jaime Passos Date: Fri, 27 Dec 2019 12:29:21 -0300 Subject: [PATCH 062/136] look for GTR_LIVES rule instead of coop/competition gametype --- src/p_user.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/p_user.c b/src/p_user.c index ff6ffc677..3f407d6a9 100644 --- a/src/p_user.c +++ b/src/p_user.c @@ -1230,7 +1230,7 @@ void P_GivePlayerLives(player_t *player, INT32 numlives) if (gamestate == GS_LEVEL) { - if (player->lives == INFLIVES || (gametype != GT_COOP && gametype != GT_COMPETITION)) + if (player->lives == INFLIVES || !(gametyperules & GTR_LIVES)) { P_GivePlayerRings(player, 100*numlives); return; @@ -1395,7 +1395,7 @@ void P_AddPlayerScore(player_t *player, UINT32 amount) player->score = MAXSCORE; // check for extra lives every 50000 pts - if (!ultimatemode && !modeattacking && player->score > oldscore && player->score % 50000 < amount && (gametype == GT_COMPETITION || gametype == GT_COOP)) + if (!ultimatemode && !modeattacking && player->score > oldscore && player->score % 50000 < amount && (gametyperules & GTR_LIVES)) { P_GivePlayerLives(player, (player->score/50000) - (oldscore/50000)); P_PlayLivesJingle(player); From 3ce02b813557f7b5214229a2c8efb18c023f18be Mon Sep 17 00:00:00 2001 From: Jaime Passos Date: Fri, 27 Dec 2019 12:34:35 -0300 Subject: [PATCH 063/136] burst emeralds with GTR_MATCHEMERALDS --- src/p_inter.c | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/src/p_inter.c b/src/p_inter.c index 56a76b15c..a8b169db5 100644 --- a/src/p_inter.c +++ b/src/p_inter.c @@ -3201,10 +3201,12 @@ static void P_KillPlayer(player_t *player, mobj_t *source, INT32 damage) player->powers[pw_carry] = CR_NONE; // Burst weapons and emeralds in Match/CTF only - if (source && (gametype == GT_MATCH || gametype == GT_TEAMMATCH || gametype == GT_CTF)) + if (source) { - P_PlayerRingBurst(player, player->rings); - P_PlayerEmeraldBurst(player, false); + if (gametype == GT_MATCH || gametype == GT_TEAMMATCH || gametype == GT_CTF) + P_PlayerRingBurst(player, player->rings); + if (gametyperules & GTR_MATCHEMERALDS) + P_PlayerEmeraldBurst(player, false); } // Get rid of shield From 1f143ca9d65354ff8a065f2dd001b39f96734c0f Mon Sep 17 00:00:00 2001 From: Alam Ed Arias Date: Fri, 27 Dec 2019 13:20:58 -0500 Subject: [PATCH 064/136] 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 ad56f5e36278894ec05c6c6f530375e2a5649842 Mon Sep 17 00:00:00 2001 From: Monster Iestyn Date: Fri, 27 Dec 2019 19:10:14 +0000 Subject: [PATCH 065/136] added a "target" pointer to polywaypoint_t, so the polyobj waypoint thinker doesn't have to re-find the next waypoint every tic --- src/p_polyobj.c | 8 ++++++++ src/p_polyobj.h | 2 ++ src/p_saveg.c | 16 ++++++++++++++-- 3 files changed, 24 insertions(+), 2 deletions(-) diff --git a/src/p_polyobj.c b/src/p_polyobj.c index c37926adf..d7105ee5a 100644 --- a/src/p_polyobj.c +++ b/src/p_polyobj.c @@ -1815,6 +1815,7 @@ void T_PolyObjWaypoint(polywaypoint_t *th) if (po->thinker == NULL) po->thinker = &th->thinker; +/* // Find out target first. // We redo this each tic to make savegame compatibility easier. for (wp = thlist[THINK_MOBJ].next; wp != &thlist[THINK_MOBJ]; wp = wp->next) @@ -1833,6 +1834,9 @@ void T_PolyObjWaypoint(polywaypoint_t *th) break; } } +*/ + + target = th->target; if (!target) { @@ -2015,6 +2019,8 @@ void T_PolyObjWaypoint(polywaypoint_t *th) target = waypoint; th->pointnum = target->health; + // Set the mobj as your target! -- Monster Iestyn 27/12/19 + th->target = target; // calculate MOMX/MOMY/MOMZ for next waypoint // change slope @@ -2641,6 +2647,8 @@ INT32 EV_DoPolyObjWaypoint(polywaypointdata_t *pwdata) // Set pointnum th->pointnum = target->health; + // Set the mobj as your target! -- Monster Iestyn 27/12/19 + th->target = target; // We don't deal with the mirror crap here, we'll // handle that in the T_Thinker function. diff --git a/src/p_polyobj.h b/src/p_polyobj.h index ffacf628b..339390c0a 100644 --- a/src/p_polyobj.h +++ b/src/p_polyobj.h @@ -161,6 +161,8 @@ typedef struct polywaypoint_s fixed_t diffx; fixed_t diffy; fixed_t diffz; + + mobj_t *target; // next waypoint mobj } polywaypoint_t; typedef struct polyslidedoor_s diff --git a/src/p_saveg.c b/src/p_saveg.c index 85efacf88..092eca8a4 100644 --- a/src/p_saveg.c +++ b/src/p_saveg.c @@ -2055,6 +2055,7 @@ static void SavePolywaypointThinker(const thinker_t *th, UINT8 type) WRITEFIXED(save_p, ht->diffx); WRITEFIXED(save_p, ht->diffy); WRITEFIXED(save_p, ht->diffz); + WRITEUINT32(save_p, SaveMobjnum(ht->target)); } // @@ -3244,6 +3245,7 @@ static inline thinker_t* LoadPolywaypointThinker(actionf_p1 thinker) ht->diffx = READFIXED(save_p); ht->diffy = READFIXED(save_p); ht->diffz = READFIXED(save_p); + ht->target = LoadMobj(READUINT32(save_p)); return &ht->thinker; } @@ -3538,6 +3540,7 @@ static void P_NetUnArchiveThinkers(void) case tc_polywaypoint: th = LoadPolywaypointThinker((actionf_p1)T_PolyObjWaypoint); + restoreNum = true; break; case tc_polyslidedoor: @@ -3599,9 +3602,9 @@ static void P_NetUnArchiveThinkers(void) if (restoreNum) { executor_t *delay = NULL; + polywaypoint_t *polywp = NULL; UINT32 mobjnum; - for (currentthinker = thlist[THINK_MAIN].next; currentthinker != &thlist[THINK_MAIN]; - currentthinker = currentthinker->next) + for (currentthinker = thlist[THINK_MAIN].next; currentthinker != &thlist[THINK_MAIN]; currentthinker = currentthinker->next) { if (currentthinker->function.acp1 != (actionf_p1)T_ExecutorDelay) continue; @@ -3610,6 +3613,15 @@ static void P_NetUnArchiveThinkers(void) continue; delay->caller = P_FindNewPosition(mobjnum); } + for (currentthinker = thlist[THINK_POLYOBJ].next; currentthinker != &thlist[THINK_POLYOBJ]; currentthinker = currentthinker->next) + { + if (currentthinker->function.acp1 != (actionf_p1)T_PolyObjWaypoint) + continue; + polywp = (void *)currentthinker; + if (!(mobjnum = (UINT32)(size_t)polywp->target)) + continue; + polywp->target = P_FindNewPosition(mobjnum); + } } } From 6092c5774e9e15d6d209cf232c89cce8d21596c3 Mon Sep 17 00:00:00 2001 From: Monster Iestyn Date: Fri, 27 Dec 2019 19:24:00 +0000 Subject: [PATCH 066/136] use P_SetTarget to assign a value to th->target --- src/p_polyobj.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/p_polyobj.c b/src/p_polyobj.c index d7105ee5a..be5673093 100644 --- a/src/p_polyobj.c +++ b/src/p_polyobj.c @@ -2020,7 +2020,7 @@ void T_PolyObjWaypoint(polywaypoint_t *th) target = waypoint; th->pointnum = target->health; // Set the mobj as your target! -- Monster Iestyn 27/12/19 - th->target = target; + P_SetTarget(&th->target, target); // calculate MOMX/MOMY/MOMZ for next waypoint // change slope @@ -2648,7 +2648,7 @@ INT32 EV_DoPolyObjWaypoint(polywaypointdata_t *pwdata) // Set pointnum th->pointnum = target->health; // Set the mobj as your target! -- Monster Iestyn 27/12/19 - th->target = target; + P_SetTarget(&th->target, target); // We don't deal with the mirror crap here, we'll // handle that in the T_Thinker function. From 58c1adf3ef0cd585a7f23c493b08c13cbd75d3c8 Mon Sep 17 00:00:00 2001 From: Jaime Passos Date: Fri, 27 Dec 2019 16:58:55 -0300 Subject: [PATCH 067/136] ST_drawLivesArea stuff. --- src/st_stuff.c | 134 ++++++++++++++++++++++++++++--------------------- 1 file changed, 77 insertions(+), 57 deletions(-) diff --git a/src/st_stuff.c b/src/st_stuff.c index d8b9a8059..02b559cbf 100644 --- a/src/st_stuff.c +++ b/src/st_stuff.c @@ -845,69 +845,13 @@ static void ST_drawLivesArea(void) hudinfo[HUD_LIVES].f|V_PERPLAYER|V_HUDTRANS, faceprefix[stplyr->skin], colormap); } - // Lives number + // Metal Sonic recording if (metalrecording) { if (((2*leveltime)/TICRATE) & 1) V_DrawRightAlignedString(hudinfo[HUD_LIVES].x+58, hudinfo[HUD_LIVES].y+8, hudinfo[HUD_LIVES].f|V_PERPLAYER|V_REDMAP|V_HUDTRANS, "REC"); } - else if (G_GametypeUsesLives() || gametype == GT_RACE) - { - // x - V_DrawScaledPatch(hudinfo[HUD_LIVES].x+22, hudinfo[HUD_LIVES].y+10, - hudinfo[HUD_LIVES].f|V_PERPLAYER|V_HUDTRANS, stlivex); - - // lives number - if (gametype == GT_RACE) - { - livescount = INFLIVES; - notgreyedout = true; - } - else if ((netgame || multiplayer) && gametype == GT_COOP && cv_cooplives.value == 3) - { - INT32 i; - livescount = 0; - notgreyedout = (stplyr->lives > 0); - for (i = 0; i < MAXPLAYERS; i++) - { - if (!playeringame[i]) - continue; - - if (players[i].lives < 1) - continue; - - if (players[i].lives > 1) - notgreyedout = true; - - if (players[i].lives == INFLIVES) - { - livescount = INFLIVES; - break; - } - else if (livescount < 99) - livescount += (players[i].lives); - } - } - else - { - livescount = (((netgame || multiplayer) && gametype == GT_COOP && cv_cooplives.value == 0) ? INFLIVES : stplyr->lives); - notgreyedout = true; - } - - if (livescount == INFLIVES) - V_DrawCharacter(hudinfo[HUD_LIVES].x+50, hudinfo[HUD_LIVES].y+8, - '\x16' | 0x80 | hudinfo[HUD_LIVES].f|V_PERPLAYER|V_HUDTRANS, false); - else - { - if (stplyr->playerstate == PST_DEAD && !(stplyr->spectator) && (livescount || stplyr->deadtimer < (TICRATE<<1))) - livescount++; - if (livescount > 99) - livescount = 99; - V_DrawRightAlignedString(hudinfo[HUD_LIVES].x+58, hudinfo[HUD_LIVES].y+8, - hudinfo[HUD_LIVES].f|V_PERPLAYER|(notgreyedout ? V_HUDTRANS : V_HUDTRANSHALF), va("%d",livescount)); - } - } // Spectator else if (stplyr->spectator) v_colmap = V_GRAYMAP; @@ -934,6 +878,82 @@ static void ST_drawLivesArea(void) v_colmap = V_BLUEMAP; } } + // Lives number + else + { + boolean candrawlives = true; + + // Co-op and Competition, normal life counter + if (G_GametypeUsesLives()) + { + // Handle cooplives here + if ((netgame || multiplayer) && gametype == GT_COOP && cv_cooplives.value == 3) + { + INT32 i; + livescount = 0; + notgreyedout = (stplyr->lives > 0); + for (i = 0; i < MAXPLAYERS; i++) + { + if (!playeringame[i]) + continue; + + if (players[i].lives < 1) + continue; + + if (players[i].lives > 1) + notgreyedout = true; + + if (players[i].lives == INFLIVES) + { + livescount = INFLIVES; + break; + } + else if (livescount < 99) + livescount += (players[i].lives); + } + } + else + { + livescount = (((netgame || multiplayer) && gametype == GT_COOP && cv_cooplives.value == 0) ? INFLIVES : stplyr->lives); + notgreyedout = true; + } + } + // Infinity symbol (Race) + else if (G_PlatformGametype() && !(gametyperules & GTR_LIVES)) + { + livescount = INFLIVES; + notgreyedout = true; + } + // Otherwise nothing, sorry. + // Special Stages keep not showing lives, + // as G_GametypeUsesLives() returns false in + // Special Stages, and the infinity symbol + // cannot show up because Special Stages + // still have the GTR_LIVES gametype rule + // by default. + else + candrawlives = false; + + // Draw the lives counter here. + if (candrawlives) + { + // x + V_DrawScaledPatch(hudinfo[HUD_LIVES].x+22, hudinfo[HUD_LIVES].y+10, hudinfo[HUD_LIVES].f|V_PERPLAYER|V_HUDTRANS, stlivex); + if (livescount == INFLIVES) + V_DrawCharacter(hudinfo[HUD_LIVES].x+50, hudinfo[HUD_LIVES].y+8, + '\x16' | 0x80 | hudinfo[HUD_LIVES].f|V_PERPLAYER|V_HUDTRANS, false); + else + { + if (stplyr->playerstate == PST_DEAD && !(stplyr->spectator) && (livescount || stplyr->deadtimer < (TICRATE<<1))) + livescount++; + if (livescount > 99) + livescount = 99; + V_DrawRightAlignedString(hudinfo[HUD_LIVES].x+58, hudinfo[HUD_LIVES].y+8, + hudinfo[HUD_LIVES].f|V_PERPLAYER|(notgreyedout ? V_HUDTRANS : V_HUDTRANSHALF), va("%d",livescount)); + } + } +#undef ST_drawLivesX + } // name v_colmap |= (V_HUDTRANS|hudinfo[HUD_LIVES].f|V_PERPLAYER); From ff80c4ef4dc4316fda0e62b8a86af65027224c82 Mon Sep 17 00:00:00 2001 From: Jaime Passos Date: Fri, 27 Dec 2019 17:08:20 -0300 Subject: [PATCH 068/136] Preparing for the inevitable gametype rule that will handle cooplives... --- src/d_netcmd.c | 2 +- src/g_game.c | 14 ++++++++++++++ src/g_game.h | 1 + src/hu_stuff.c | 4 ++-- src/lua_baselib.c | 18 ++++++++++++++++++ src/p_inter.c | 4 ++-- src/p_user.c | 6 +++--- src/st_stuff.c | 8 ++++---- src/y_inter.c | 4 ++-- 9 files changed, 47 insertions(+), 14 deletions(-) diff --git a/src/d_netcmd.c b/src/d_netcmd.c index 4e14ca25f..77cb3bcd0 100644 --- a/src/d_netcmd.c +++ b/src/d_netcmd.c @@ -3800,7 +3800,7 @@ static void CoopLives_OnChange(void) { INT32 i; - if (!(netgame || multiplayer) || gametype != GT_COOP) + if (!(netgame || multiplayer) || !G_GametypeUsesCoopLives()) return; switch (cv_cooplives.value) diff --git a/src/g_game.c b/src/g_game.c index 28de6693f..08422ee58 100644 --- a/src/g_game.c +++ b/src/g_game.c @@ -3439,6 +3439,20 @@ boolean G_GametypeUsesLives(void) return false; } +// +// G_GametypeUsesCoopLives +// +// Returns true if the current gametype uses +// the cooplives CVAR. False otherwise. +// +boolean G_GametypeUsesCoopLives(void) +{ + // Preparing for the inevitable + // gametype rule that will + // handle cooplives... + return (gametype == GT_COOP); +} + // // G_GametypeHasTeams // diff --git a/src/g_game.h b/src/g_game.h index 6916bba6e..8e25554ab 100644 --- a/src/g_game.h +++ b/src/g_game.h @@ -218,6 +218,7 @@ void G_SetGametypeDescription(INT16 gtype, char *descriptiontext, UINT8 leftcolo INT32 G_GetGametypeByName(const char *gametypestr); boolean G_IsSpecialStage(INT32 mapnum); boolean G_GametypeUsesLives(void); +boolean G_GametypeUsesCoopLives(void); boolean G_GametypeHasTeams(void); boolean G_GametypeHasSpectators(void); boolean G_RingSlingerGametype(void); diff --git a/src/hu_stuff.c b/src/hu_stuff.c index d9801793b..3844cf903 100644 --- a/src/hu_stuff.c +++ b/src/hu_stuff.c @@ -2434,7 +2434,7 @@ void HU_DrawTabRankings(INT32 x, INT32 y, playersort_t *tab, INT32 scorelines, I } } - if (G_GametypeUsesLives() && !(gametyperankings[gametype] == GT_COOP && (cv_cooplives.value == 0 || cv_cooplives.value == 3)) && (players[tab[i].num].lives != INFLIVES)) //show lives + if (G_GametypeUsesLives() && !(G_GametypeUsesCoopLives() && (cv_cooplives.value == 0 || cv_cooplives.value == 3)) && (players[tab[i].num].lives != INFLIVES)) //show lives V_DrawRightAlignedString(x, y+4, V_ALLOWLOWERCASE|(greycheck ? V_60TRANS : 0), va("%dx", players[tab[i].num].lives)); else if (G_TagGametype() && players[tab[i].num].pflags & PF_TAGIT) { @@ -2743,7 +2743,7 @@ void HU_DrawDualTabRankings(INT32 x, INT32 y, playersort_t *tab, INT32 scoreline | (greycheck ? V_TRANSLUCENT : 0) | V_ALLOWLOWERCASE, name); - if (G_GametypeUsesLives() && !(gametyperankings[gametype] == GT_COOP && (cv_cooplives.value == 0 || cv_cooplives.value == 3)) && (players[tab[i].num].lives != INFLIVES)) //show lives + if (G_GametypeUsesLives() && !(G_GametypeUsesCoopLives() && (cv_cooplives.value == 0 || cv_cooplives.value == 3)) && (players[tab[i].num].lives != INFLIVES)) //show lives V_DrawRightAlignedString(x, y+4, V_ALLOWLOWERCASE, va("%dx", players[tab[i].num].lives)); else if (G_TagGametype() && players[tab[i].num].pflags & PF_TAGIT) V_DrawSmallScaledPatch(x-28, y-4, 0, tagico); diff --git a/src/lua_baselib.c b/src/lua_baselib.c index 695e9367e..e3ded8256 100644 --- a/src/lua_baselib.c +++ b/src/lua_baselib.c @@ -2854,6 +2854,14 @@ static int lib_gGametypeUsesLives(lua_State *L) return 1; } +static int lib_gGametypeUsesCoopLives(lua_State *L) +{ + //HUDSAFE + INLEVEL + lua_pushboolean(L, G_GametypeUsesCoopLives()); + return 1; +} + static int lib_gGametypeHasTeams(lua_State *L) { //HUDSAFE @@ -2894,6 +2902,14 @@ static int lib_gTagGametype(lua_State *L) return 1; } +static int lib_gCompetitionGametype(lua_State *L) +{ + //HUDSAFE + INLEVEL + lua_pushboolean(L, G_CompetitionGametype()); + return 1; +} + static int lib_gTicsToHours(lua_State *L) { tic_t rtic = luaL_checkinteger(L, 1); @@ -3139,11 +3155,13 @@ static luaL_Reg lib[] = { {"G_ExitLevel",lib_gExitLevel}, {"G_IsSpecialStage",lib_gIsSpecialStage}, {"G_GametypeUsesLives",lib_gGametypeUsesLives}, + {"G_GametypeUsesCoopLives",lib_gGametypeUsesCoopLives}, {"G_GametypeHasTeams",lib_gGametypeHasTeams}, {"G_GametypeHasSpectators",lib_gGametypeHasSpectators}, {"G_RingSlingerGametype",lib_gRingSlingerGametype}, {"G_PlatformGametype",lib_gPlatformGametype}, {"G_TagGametype",lib_gTagGametype}, + {"G_CompetitionGametype",lib_gCompetitionGametype}, {"G_TicsToHours",lib_gTicsToHours}, {"G_TicsToMinutes",lib_gTicsToMinutes}, {"G_TicsToSeconds",lib_gTicsToSeconds}, diff --git a/src/p_inter.c b/src/p_inter.c index a8b169db5..6fd0c91d1 100644 --- a/src/p_inter.c +++ b/src/p_inter.c @@ -2523,7 +2523,7 @@ void P_KillMobj(mobj_t *target, mobj_t *inflictor, mobj_t *source, UINT8 damaget target->colorized = false; G_GhostAddColor(GHC_NORMAL); - if ((target->player->lives <= 1) && (netgame || multiplayer) && (gametype == GT_COOP) && (cv_cooplives.value == 0)) + if ((target->player->lives <= 1) && (netgame || multiplayer) && G_GametypeUsesCoopLives() && (cv_cooplives.value == 0)) ; else if (!target->player->bot && !target->player->spectator && (target->player->lives != INFLIVES) && G_GametypeUsesLives()) @@ -2533,7 +2533,7 @@ void P_KillMobj(mobj_t *target, mobj_t *inflictor, mobj_t *source, UINT8 damaget if (target->player->lives <= 0) // Tails 03-14-2000 { boolean gameovermus = false; - if ((netgame || multiplayer) && (gametype == GT_COOP) && (cv_cooplives.value != 1)) + if ((netgame || multiplayer) && G_GametypeUsesCoopLives() && (cv_cooplives.value != 1)) { INT32 i; for (i = 0; i < MAXPLAYERS; i++) diff --git a/src/p_user.c b/src/p_user.c index 3f407d6a9..38560fe97 100644 --- a/src/p_user.c +++ b/src/p_user.c @@ -1236,7 +1236,7 @@ void P_GivePlayerLives(player_t *player, INT32 numlives) return; } - if ((netgame || multiplayer) && gametype == GT_COOP && cv_cooplives.value == 0) + if ((netgame || multiplayer) && G_GametypeUsesCoopLives() && cv_cooplives.value == 0) { P_GivePlayerRings(player, 100*numlives); if (player->lives - prevlives >= numlives) @@ -1267,7 +1267,7 @@ docooprespawn: void P_GiveCoopLives(player_t *player, INT32 numlives, boolean sound) { - if (!((netgame || multiplayer) && gametype == GT_COOP)) + if (!((netgame || multiplayer) && G_GametypeUsesCoopLives())) { P_GivePlayerLives(player, numlives); if (sound) @@ -9298,7 +9298,7 @@ boolean P_GetLives(player_t *player) { INT32 i, maxlivesplayer = -1, livescheck = 1; if (!(netgame || multiplayer) - || (gametype != GT_COOP) + || !G_GametypeUsesCoopLives() || (player->lives == INFLIVES)) return true; diff --git a/src/st_stuff.c b/src/st_stuff.c index 02b559cbf..9e761b1ab 100644 --- a/src/st_stuff.c +++ b/src/st_stuff.c @@ -887,7 +887,7 @@ static void ST_drawLivesArea(void) if (G_GametypeUsesLives()) { // Handle cooplives here - if ((netgame || multiplayer) && gametype == GT_COOP && cv_cooplives.value == 3) + if ((netgame || multiplayer) && G_GametypeUsesCoopLives() && cv_cooplives.value == 3) { INT32 i; livescount = 0; @@ -914,7 +914,7 @@ static void ST_drawLivesArea(void) } else { - livescount = (((netgame || multiplayer) && gametype == GT_COOP && cv_cooplives.value == 0) ? INFLIVES : stplyr->lives); + livescount = (((netgame || multiplayer) && G_GametypeUsesCoopLives() && cv_cooplives.value == 0) ? INFLIVES : stplyr->lives); notgreyedout = true; } } @@ -2246,7 +2246,7 @@ static void ST_drawTextHUD(void) textHUDdraw(M_GetText("\x82""Wait for the stage to end...")) else if (G_PlatformGametype()) { - if (gametype == GT_COOP) + if (G_GametypeUsesCoopLives()) { if (stplyr->lives <= 0 && cv_cooplives.value == 2 @@ -2657,7 +2657,7 @@ static void ST_overlayDrawer(void) INT32 i = MAXPLAYERS; INT32 deadtimer = stplyr->spectator ? TICRATE : (stplyr->deadtimer-(TICRATE<<1)); - if ((gametype == GT_COOP) + if (G_GametypeUsesCoopLives() && (netgame || multiplayer) && (cv_cooplives.value != 1)) { diff --git a/src/y_inter.c b/src/y_inter.c index b26c0797e..62b3d553d 100644 --- a/src/y_inter.c +++ b/src/y_inter.c @@ -1977,7 +1977,7 @@ static void Y_AwardCoopBonuses(void) if (i == consoleplayer) { - data.coop.gotlife = (((netgame || multiplayer) && gametype == GT_COOP && cv_cooplives.value == 0) ? 0 : ptlives); + data.coop.gotlife = (((netgame || multiplayer) && G_GametypeUsesCoopLives() && cv_cooplives.value == 0) ? 0 : ptlives); M_Memcpy(&data.coop.bonuses, &localbonuses, sizeof(data.coop.bonuses)); } } @@ -2032,7 +2032,7 @@ static void Y_AwardSpecialStageBonus(void) if (i == consoleplayer) { - data.spec.gotlife = (((netgame || multiplayer) && gametype == GT_COOP && cv_cooplives.value == 0) ? 0 : ptlives); + data.spec.gotlife = (((netgame || multiplayer) && G_GametypeUsesCoopLives() && cv_cooplives.value == 0) ? 0 : ptlives); M_Memcpy(&data.spec.bonuses, &localbonuses, sizeof(data.spec.bonuses)); // Continues related From 62d79eef2a3e6ffc0c042ab9c2ebc1fa048349de Mon Sep 17 00:00:00 2001 From: Jaime Passos Date: Fri, 27 Dec 2019 17:14:56 -0300 Subject: [PATCH 069/136] Same deal, but for starposts. --- src/g_game.c | 24 +++++++++++++++++++----- src/g_game.h | 1 + src/lua_baselib.c | 9 +++++++++ src/p_inter.c | 2 +- src/p_setup.c | 4 ++-- src/p_user.c | 4 ++-- 6 files changed, 34 insertions(+), 10 deletions(-) diff --git a/src/g_game.c b/src/g_game.c index 08422ee58..2d9f2663e 100644 --- a/src/g_game.c +++ b/src/g_game.c @@ -2890,11 +2890,11 @@ void G_DoReborn(INT32 playernum) if (countdowntimeup || (!(netgame || multiplayer) && gametype == GT_COOP)) resetlevel = true; - else if (gametype == GT_COOP && (netgame || multiplayer) && !G_IsSpecialStage(gamemap)) + else if ((G_GametypeUsesCoopLives() || G_GametypeUsesCoopStarposts()) && (netgame || multiplayer) && !G_IsSpecialStage(gamemap)) { boolean notgameover = true; - if (cv_cooplives.value != 0 && player->lives <= 0) // consider game over first + if (G_GametypeUsesCoopLives() && (cv_cooplives.value != 0 && player->lives <= 0)) // consider game over first { for (i = 0; i < MAXPLAYERS; i++) { @@ -2929,7 +2929,7 @@ void G_DoReborn(INT32 playernum) } } - if (notgameover && cv_coopstarposts.value == 2) + if (G_GametypeUsesCoopStarposts() && (notgameover && cv_coopstarposts.value == 2)) { for (i = 0; i < MAXPLAYERS; i++) { @@ -3005,7 +3005,7 @@ void G_DoReborn(INT32 playernum) } // restore time in netgame (see also p_setup.c) - if ((netgame || multiplayer) && gametype == GT_COOP && cv_coopstarposts.value == 2) + if ((netgame || multiplayer) && G_GametypeUsesCoopStarposts() && cv_coopstarposts.value == 2) { // is this a hack? maybe tic_t maxstarposttime = 0; @@ -3076,7 +3076,7 @@ void G_AddPlayer(INT32 playernum) if (!players[i].exiting) notexiting++; - if (!(cv_coopstarposts.value && (gametype == GT_COOP) && (p->starpostnum < players[i].starpostnum))) + if (!(cv_coopstarposts.value && G_GametypeUsesCoopStarposts() && (p->starpostnum < players[i].starpostnum))) continue; p->starpostscale = players[i].starpostscale; @@ -3453,6 +3453,20 @@ boolean G_GametypeUsesCoopLives(void) return (gametype == GT_COOP); } +// +// G_GametypeUsesCoopStarposts +// +// Returns true if the current gametype uses +// the coopstarposts CVAR. False otherwise. +// +boolean G_GametypeUsesCoopStarposts(void) +{ + // Preparing for the inevitable + // gametype rule that will + // handle coopstarposts... + return (gametype == GT_COOP); +} + // // G_GametypeHasTeams // diff --git a/src/g_game.h b/src/g_game.h index 8e25554ab..68e78789f 100644 --- a/src/g_game.h +++ b/src/g_game.h @@ -219,6 +219,7 @@ INT32 G_GetGametypeByName(const char *gametypestr); boolean G_IsSpecialStage(INT32 mapnum); boolean G_GametypeUsesLives(void); boolean G_GametypeUsesCoopLives(void); +boolean G_GametypeUsesCoopStarposts(void); boolean G_GametypeHasTeams(void); boolean G_GametypeHasSpectators(void); boolean G_RingSlingerGametype(void); diff --git a/src/lua_baselib.c b/src/lua_baselib.c index e3ded8256..2a82ec512 100644 --- a/src/lua_baselib.c +++ b/src/lua_baselib.c @@ -2862,6 +2862,14 @@ static int lib_gGametypeUsesCoopLives(lua_State *L) return 1; } +static int lib_gGametypeUsesCoopStarposts(lua_State *L) +{ + //HUDSAFE + INLEVEL + lua_pushboolean(L, G_GametypeUsesCoopStarposts()); + return 1; +} + static int lib_gGametypeHasTeams(lua_State *L) { //HUDSAFE @@ -3156,6 +3164,7 @@ static luaL_Reg lib[] = { {"G_IsSpecialStage",lib_gIsSpecialStage}, {"G_GametypeUsesLives",lib_gGametypeUsesLives}, {"G_GametypeUsesCoopLives",lib_gGametypeUsesCoopLives}, + {"G_GametypeUsesCoopStarposts",lib_gGametypeUsesCoopStarposts}, {"G_GametypeHasTeams",lib_gGametypeHasTeams}, {"G_GametypeHasSpectators",lib_gGametypeHasSpectators}, {"G_RingSlingerGametype",lib_gRingSlingerGametype}, diff --git a/src/p_inter.c b/src/p_inter.c index 6fd0c91d1..f2d34bd7d 100644 --- a/src/p_inter.c +++ b/src/p_inter.c @@ -1451,7 +1451,7 @@ void P_TouchSpecialThing(mobj_t *special, mobj_t *toucher, boolean heightcheck) if (player->starpostnum >= special->health) return; // Already hit this post - if (cv_coopstarposts.value && gametype == GT_COOP && (netgame || multiplayer)) + if (cv_coopstarposts.value && G_GametypeUsesCoopStarposts() && (netgame || multiplayer)) { for (i = 0; i < MAXPLAYERS; i++) { diff --git a/src/p_setup.c b/src/p_setup.c index 3f49a1680..e09ecf6c3 100644 --- a/src/p_setup.c +++ b/src/p_setup.c @@ -2141,7 +2141,7 @@ static void P_LevelInitStuff(void) // earthquake camera memset(&quake,0,sizeof(struct quake)); - if ((netgame || multiplayer) && gametype == GT_COOP && cv_coopstarposts.value == 2) + if ((netgame || multiplayer) && G_GametypeUsesCoopStarposts() && cv_coopstarposts.value == 2) { for (i = 0; i < MAXPLAYERS; i++) { @@ -2848,7 +2848,7 @@ boolean P_SetupLevel(boolean skipprecip) } // restore time in netgame (see also g_game.c) - if ((netgame || multiplayer) && gametype == GT_COOP && cv_coopstarposts.value == 2) + if ((netgame || multiplayer) && G_GametypeUsesCoopStarposts() && cv_coopstarposts.value == 2) { // is this a hack? maybe tic_t maxstarposttime = 0; diff --git a/src/p_user.c b/src/p_user.c index 38560fe97..9ad85cac1 100644 --- a/src/p_user.c +++ b/src/p_user.c @@ -9447,7 +9447,7 @@ static void P_DeathThink(player_t *player) player->playerstate = PST_REBORN; else if ((player->lives > 0 || j != MAXPLAYERS) && !(!(netgame || multiplayer) && G_IsSpecialStage(gamemap))) // Don't allow "click to respawn" in special stages! { - if (gametype == GT_COOP && (netgame || multiplayer) && cv_coopstarposts.value == 2) + if (G_GametypeUsesCoopStarposts() && (netgame || multiplayer) && cv_coopstarposts.value == 2) { P_ConsiderAllGone(); if ((player->deadtimer > TICRATE<<1) || ((cmd->buttons & BT_JUMP) && (player->deadtimer > TICRATE))) @@ -11537,7 +11537,7 @@ void P_PlayerThink(player_t *player) #else if (player->spectator && #endif - gametype == GT_COOP && (netgame || multiplayer) && cv_coopstarposts.value == 2) + G_GametypeUsesCoopStarposts() && (netgame || multiplayer) && cv_coopstarposts.value == 2) P_ConsiderAllGone(); if (player->playerstate == PST_DEAD) From 142875cf3df93ec49503d05049fb0adb1c1c39a4 Mon Sep 17 00:00:00 2001 From: Jaime Passos Date: Fri, 27 Dec 2019 17:15:23 -0300 Subject: [PATCH 070/136] Fix CoopLives_OnChange. --- src/d_netcmd.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/d_netcmd.c b/src/d_netcmd.c index 77cb3bcd0..154bcb625 100644 --- a/src/d_netcmd.c +++ b/src/d_netcmd.c @@ -3745,7 +3745,7 @@ static void CoopStarposts_OnChange(void) { INT32 i; - if (!(netgame || multiplayer) || gametype != GT_COOP) + if (!(netgame || multiplayer) || !G_GametypeUsesCoopStarposts()) return; switch (cv_coopstarposts.value) From 9ede8f7c2edba4d5d6f47138de4537af97a2cc7d Mon Sep 17 00:00:00 2001 From: Jaime Passos Date: Fri, 27 Dec 2019 17:22:55 -0300 Subject: [PATCH 071/136] In P_KillPlayer, check for the gametype's rules, instead of the gametype itself, before bursting rings. --- src/p_inter.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/p_inter.c b/src/p_inter.c index f2d34bd7d..87b0c0a43 100644 --- a/src/p_inter.c +++ b/src/p_inter.c @@ -3203,7 +3203,7 @@ static void P_KillPlayer(player_t *player, mobj_t *source, INT32 damage) // Burst weapons and emeralds in Match/CTF only if (source) { - if (gametype == GT_MATCH || gametype == GT_TEAMMATCH || gametype == GT_CTF) + if ((gametyperules & GTR_RINGSLINGER) && !(gametyperules & GTR_TAG)) P_PlayerRingBurst(player, player->rings); if (gametyperules & GTR_MATCHEMERALDS) P_PlayerEmeraldBurst(player, false); From 7d4c00affbc8fb17a47d78065789da04547e2f0a Mon Sep 17 00:00:00 2001 From: Jaime Passos Date: Fri, 27 Dec 2019 18:24:08 -0300 Subject: [PATCH 072/136] GTR_HIDETIME, not GTR_TAG --- src/st_stuff.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/st_stuff.c b/src/st_stuff.c index 9e761b1ab..35dd861c5 100644 --- a/src/st_stuff.c +++ b/src/st_stuff.c @@ -723,7 +723,7 @@ static void ST_drawTime(void) downwards = true; } // Post-hidetime normal. - else if (gametyperules & GTR_TAG) + else if (gametyperules & GTR_HIDETIME) tics = stplyr->realtime - hidetime*TICRATE; // "Shadow! What are you doing? Hurry and get back here // right now before the island blows up with you on it!" From 821e1cf618c18b6c50d5cf0e7d38cb85b2dd29af Mon Sep 17 00:00:00 2001 From: James R Date: Fri, 27 Dec 2019 14:48:55 -0800 Subject: [PATCH 073/136] Only return if we damaged the monitor --- src/p_map.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/p_map.c b/src/p_map.c index 96fb8ee07..f859c8c77 100644 --- a/src/p_map.c +++ b/src/p_map.c @@ -832,7 +832,10 @@ static boolean PIT_CheckThing(mobj_t *thing) return true; } else - return P_DamageMobj(thing, tmthing, tmthing, 1, 0); + { + if (P_DamageMobj(thing, tmthing, tmthing, 1, 0)) + return true; + } } // vectorise metal - done in a special case as at this point neither has the right flags for touching From 655de1aca8d43cec9fe172a3996ed8a039d04320 Mon Sep 17 00:00:00 2001 From: GoldenTails Date: Fri, 27 Dec 2019 23:51:13 -0600 Subject: [PATCH 074/136] Fixed messed up comparison. --- src/p_user.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/p_user.c b/src/p_user.c index 10d55ae0e..a9e6cd1a1 100644 --- a/src/p_user.c +++ b/src/p_user.c @@ -4638,7 +4638,7 @@ static void P_DoSpinAbility(player_t *player, ticcmd_t *cmd) if (player->dashspeed < player->mindash) player->dashspeed = player->mindash; - if (player->dashspeed < player->maxdash) + if (player->dashspeed > player->maxdash) player->dashspeed = player->maxdash; if (player->dashspeed < player->maxdash && player->mindash != player->maxdash) From a7fa90d11d5d4cc67e24f75b4b3cf9c25e15ed02 Mon Sep 17 00:00:00 2001 From: Jaime Passos Date: Sat, 28 Dec 2019 19:47:03 -0300 Subject: [PATCH 075/136] Rename GTR_HIDETIME to GTR_STARTCOUNTDOWN. --- src/dehacked.c | 2 +- src/doomstat.h | 2 +- src/g_game.c | 4 ++-- src/st_stuff.c | 6 +++--- 4 files changed, 7 insertions(+), 7 deletions(-) diff --git a/src/dehacked.c b/src/dehacked.c index 939e8c8cf..5023f55ee 100644 --- a/src/dehacked.c +++ b/src/dehacked.c @@ -8909,7 +8909,7 @@ static const char *const GAMETYPERULE_LIST[] = { "TAG", "POINTLIMIT", "TIMELIMIT", - "HIDETIME", + "STARTCOUNTDOWN", "HIDEFROZEN", "BLINDFOLDED", "FIRSTPERSON", diff --git a/src/doomstat.h b/src/doomstat.h index 5dc3a6eb9..faedf48d5 100644 --- a/src/doomstat.h +++ b/src/doomstat.h @@ -404,7 +404,7 @@ enum GameTypeRules GTR_TAG = 1<<7, // Tag and Hide and Seek GTR_POINTLIMIT = 1<<8, // Ringslinger point limit GTR_TIMELIMIT = 1<<9, // Ringslinger time limit - GTR_HIDETIME = 1<<10, // Hide time (Tag and Hide and Seek) + GTR_STARTCOUNTDOWN = 1<<10, // Hide time countdown (Tag and Hide and Seek) GTR_HIDEFROZEN = 1<<11, // Frozen after hide time (Hide and Seek, but not Tag) GTR_BLINDFOLDED = 1<<12, // Blindfolded view (Tag and Hide and Seek) GTR_FIRSTPERSON = 1<<13, // First person camera diff --git a/src/g_game.c b/src/g_game.c index 2d9f2663e..4adc0d604 100644 --- a/src/g_game.c +++ b/src/g_game.c @@ -3205,9 +3205,9 @@ UINT32 gametypedefaultrules[NUMGAMETYPES] = GTR_RINGSLINGER|GTR_FIRSTPERSON|GTR_SPECTATORS|GTR_TEAMS|GTR_POINTLIMIT|GTR_TIMELIMIT|GTR_DEATHMATCHSTARTS|GTR_SPAWNINVUL|GTR_RESPAWNDELAY|GTR_PITYSHIELD, // Tag - GTR_RINGSLINGER|GTR_FIRSTPERSON|GTR_TAG|GTR_SPECTATORS|GTR_POINTLIMIT|GTR_TIMELIMIT|GTR_HIDETIME|GTR_BLINDFOLDED|GTR_DEATHMATCHSTARTS|GTR_SPAWNINVUL|GTR_RESPAWNDELAY, + GTR_RINGSLINGER|GTR_FIRSTPERSON|GTR_TAG|GTR_SPECTATORS|GTR_POINTLIMIT|GTR_TIMELIMIT|GTR_STARTCOUNTDOWN|GTR_BLINDFOLDED|GTR_DEATHMATCHSTARTS|GTR_SPAWNINVUL|GTR_RESPAWNDELAY, // Hide and Seek - GTR_RINGSLINGER|GTR_FIRSTPERSON|GTR_TAG|GTR_SPECTATORS|GTR_POINTLIMIT|GTR_TIMELIMIT|GTR_HIDETIME|GTR_BLINDFOLDED|GTR_DEATHMATCHSTARTS|GTR_SPAWNINVUL|GTR_RESPAWNDELAY, + GTR_RINGSLINGER|GTR_FIRSTPERSON|GTR_TAG|GTR_SPECTATORS|GTR_POINTLIMIT|GTR_TIMELIMIT|GTR_STARTCOUNTDOWN|GTR_BLINDFOLDED|GTR_DEATHMATCHSTARTS|GTR_SPAWNINVUL|GTR_RESPAWNDELAY, // CTF GTR_RINGSLINGER|GTR_FIRSTPERSON|GTR_SPECTATORS|GTR_TEAMS|GTR_TEAMFLAGS|GTR_POINTLIMIT|GTR_TIMELIMIT|GTR_MATCHEMERALDS|GTR_DEATHMATCHSTARTS|GTR_SPAWNINVUL|GTR_RESPAWNDELAY|GTR_PITYSHIELD, diff --git a/src/st_stuff.c b/src/st_stuff.c index 35dd861c5..960953b1b 100644 --- a/src/st_stuff.c +++ b/src/st_stuff.c @@ -694,7 +694,7 @@ static void ST_drawTime(void) else { // Counting down the hidetime? - if ((gametyperules & GTR_HIDETIME) && (stplyr->realtime <= (hidetime*TICRATE))) + if ((gametyperules & GTR_STARTCOUNTDOWN) && (stplyr->realtime <= (hidetime*TICRATE))) { tics = (hidetime*TICRATE - stplyr->realtime); if (tics < 3*TICRATE) @@ -705,7 +705,7 @@ static void ST_drawTime(void) else { // Hidetime finish! - if ((gametyperules & GTR_HIDETIME) && (stplyr->realtime < ((hidetime+1)*TICRATE))) + if ((gametyperules & GTR_STARTCOUNTDOWN) && (stplyr->realtime < ((hidetime+1)*TICRATE))) ST_drawRaceNum(hidetime*TICRATE - stplyr->realtime); // Time limit? @@ -723,7 +723,7 @@ static void ST_drawTime(void) downwards = true; } // Post-hidetime normal. - else if (gametyperules & GTR_HIDETIME) + else if (gametyperules & GTR_STARTCOUNTDOWN) tics = stplyr->realtime - hidetime*TICRATE; // "Shadow! What are you doing? Hurry and get back here // right now before the island blows up with you on it!" From 63132da7e0a8f5800cec911b10b30dd82137030f Mon Sep 17 00:00:00 2001 From: Jaime Passos Date: Sat, 28 Dec 2019 19:49:34 -0300 Subject: [PATCH 076/136] Rename GTR_MATCHEMERALDS to GTR_POWERSTONES. --- src/dehacked.c | 2 +- src/doomstat.h | 2 +- src/g_game.c | 4 ++-- src/p_inter.c | 2 +- src/p_mobj.c | 2 +- 5 files changed, 6 insertions(+), 6 deletions(-) diff --git a/src/dehacked.c b/src/dehacked.c index 5023f55ee..3c7fe25aa 100644 --- a/src/dehacked.c +++ b/src/dehacked.c @@ -8913,7 +8913,7 @@ static const char *const GAMETYPERULE_LIST[] = { "HIDEFROZEN", "BLINDFOLDED", "FIRSTPERSON", - "MATCHEMERALDS", + "POWERSTONES", "TEAMFLAGS", "PITYSHIELD", "DEATHPENALTY", diff --git a/src/doomstat.h b/src/doomstat.h index faedf48d5..8046b5ed9 100644 --- a/src/doomstat.h +++ b/src/doomstat.h @@ -408,7 +408,7 @@ enum GameTypeRules GTR_HIDEFROZEN = 1<<11, // Frozen after hide time (Hide and Seek, but not Tag) GTR_BLINDFOLDED = 1<<12, // Blindfolded view (Tag and Hide and Seek) GTR_FIRSTPERSON = 1<<13, // First person camera - GTR_MATCHEMERALDS = 1<<14, // Ringslinger emeralds (Match and CTF) + GTR_POWERSTONES = 1<<14, // Power stones (Match and CTF) GTR_TEAMFLAGS = 1<<15, // Gametype has team flags (CTF) GTR_PITYSHIELD = 1<<16, // Award pity shield GTR_DEATHPENALTY = 1<<17, // Death score penalty diff --git a/src/g_game.c b/src/g_game.c index 4adc0d604..c8e185f56 100644 --- a/src/g_game.c +++ b/src/g_game.c @@ -3200,7 +3200,7 @@ UINT32 gametypedefaultrules[NUMGAMETYPES] = GTR_RACE|GTR_SPAWNENEMIES|GTR_SPAWNINVUL|GTR_ALLOWEXIT, // Match - GTR_RINGSLINGER|GTR_FIRSTPERSON|GTR_SPECTATORS|GTR_POINTLIMIT|GTR_TIMELIMIT|GTR_MATCHEMERALDS|GTR_DEATHMATCHSTARTS|GTR_SPAWNINVUL|GTR_RESPAWNDELAY|GTR_PITYSHIELD|GTR_DEATHPENALTY, + GTR_RINGSLINGER|GTR_FIRSTPERSON|GTR_SPECTATORS|GTR_POINTLIMIT|GTR_TIMELIMIT|GTR_POWERSTONES|GTR_DEATHMATCHSTARTS|GTR_SPAWNINVUL|GTR_RESPAWNDELAY|GTR_PITYSHIELD|GTR_DEATHPENALTY, // Team Match GTR_RINGSLINGER|GTR_FIRSTPERSON|GTR_SPECTATORS|GTR_TEAMS|GTR_POINTLIMIT|GTR_TIMELIMIT|GTR_DEATHMATCHSTARTS|GTR_SPAWNINVUL|GTR_RESPAWNDELAY|GTR_PITYSHIELD, @@ -3210,7 +3210,7 @@ UINT32 gametypedefaultrules[NUMGAMETYPES] = GTR_RINGSLINGER|GTR_FIRSTPERSON|GTR_TAG|GTR_SPECTATORS|GTR_POINTLIMIT|GTR_TIMELIMIT|GTR_STARTCOUNTDOWN|GTR_BLINDFOLDED|GTR_DEATHMATCHSTARTS|GTR_SPAWNINVUL|GTR_RESPAWNDELAY, // CTF - GTR_RINGSLINGER|GTR_FIRSTPERSON|GTR_SPECTATORS|GTR_TEAMS|GTR_TEAMFLAGS|GTR_POINTLIMIT|GTR_TIMELIMIT|GTR_MATCHEMERALDS|GTR_DEATHMATCHSTARTS|GTR_SPAWNINVUL|GTR_RESPAWNDELAY|GTR_PITYSHIELD, + GTR_RINGSLINGER|GTR_FIRSTPERSON|GTR_SPECTATORS|GTR_TEAMS|GTR_TEAMFLAGS|GTR_POINTLIMIT|GTR_TIMELIMIT|GTR_POWERSTONES|GTR_DEATHMATCHSTARTS|GTR_SPAWNINVUL|GTR_RESPAWNDELAY|GTR_PITYSHIELD, }; // diff --git a/src/p_inter.c b/src/p_inter.c index 87b0c0a43..2bbfafdb7 100644 --- a/src/p_inter.c +++ b/src/p_inter.c @@ -3205,7 +3205,7 @@ static void P_KillPlayer(player_t *player, mobj_t *source, INT32 damage) { if ((gametyperules & GTR_RINGSLINGER) && !(gametyperules & GTR_TAG)) P_PlayerRingBurst(player, player->rings); - if (gametyperules & GTR_MATCHEMERALDS) + if (gametyperules & GTR_POWERSTONES) P_PlayerEmeraldBurst(player, false); } diff --git a/src/p_mobj.c b/src/p_mobj.c index 75bc174a5..b6ec5df83 100644 --- a/src/p_mobj.c +++ b/src/p_mobj.c @@ -11893,7 +11893,7 @@ static boolean P_AllowMobjSpawn(mapthing_t* mthing, mobjtype_t i) if (!cv_powerstones.value) return false; - if (!(gametyperules & GTR_MATCHEMERALDS)) + if (!(gametyperules & GTR_POWERSTONES)) return false; runemeraldmanager = true; From 41e5789e04827598ca4656838572ddcec0f08ecc Mon Sep 17 00:00:00 2001 From: Jaime Passos Date: Sat, 28 Dec 2019 19:50:14 -0300 Subject: [PATCH 077/136] Remove debugging stuff. --- src/lua_script.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/src/lua_script.c b/src/lua_script.c index 18d9a87c2..eb1afaf09 100644 --- a/src/lua_script.c +++ b/src/lua_script.c @@ -299,9 +299,7 @@ int LUA_PushGlobals(lua_State *L, const char *word) // See the above. int LUA_CheckGlobals(lua_State *L, const char *word) { - if (fastcmp(word, "gametyperules")) - gametyperules = (UINT32)luaL_checkinteger(L, 2); - else if (fastcmp(word, "redscore")) + if (fastcmp(word, "redscore")) redscore = (UINT32)luaL_checkinteger(L, 2); else if (fastcmp(word, "bluescore")) bluescore = (UINT32)luaL_checkinteger(L, 2); From d16563487096127106b0fdb48e98c09188f522ae Mon Sep 17 00:00:00 2001 From: Jaime Passos Date: Sat, 28 Dec 2019 19:56:18 -0300 Subject: [PATCH 078/136] Add GTR_FRIENDLY. --- src/dehacked.c | 1 + src/doomstat.h | 49 +++++++++++++++++++++++++------------------------ src/g_game.c | 12 +++--------- 3 files changed, 29 insertions(+), 33 deletions(-) diff --git a/src/dehacked.c b/src/dehacked.c index 3c7fe25aa..799428455 100644 --- a/src/dehacked.c +++ b/src/dehacked.c @@ -8905,6 +8905,7 @@ static const char *const GAMETYPERULE_LIST[] = { "FRIENDLYFIRE", "LIVES", "TEAMS", + "FRIENDLY", "RACE", "TAG", "POINTLIMIT", diff --git a/src/doomstat.h b/src/doomstat.h index 8046b5ed9..42c05ba63 100644 --- a/src/doomstat.h +++ b/src/doomstat.h @@ -400,30 +400,31 @@ enum GameTypeRules GTR_FRIENDLYFIRE = 1<<3, // Always allow friendly fire GTR_LIVES = 1<<4, // Co-op and Competition GTR_TEAMS = 1<<5, // Team Match, CTF - GTR_RACE = 1<<6, // Race and Competition - GTR_TAG = 1<<7, // Tag and Hide and Seek - GTR_POINTLIMIT = 1<<8, // Ringslinger point limit - GTR_TIMELIMIT = 1<<9, // Ringslinger time limit - GTR_STARTCOUNTDOWN = 1<<10, // Hide time countdown (Tag and Hide and Seek) - GTR_HIDEFROZEN = 1<<11, // Frozen after hide time (Hide and Seek, but not Tag) - GTR_BLINDFOLDED = 1<<12, // Blindfolded view (Tag and Hide and Seek) - GTR_FIRSTPERSON = 1<<13, // First person camera - GTR_POWERSTONES = 1<<14, // Power stones (Match and CTF) - GTR_TEAMFLAGS = 1<<15, // Gametype has team flags (CTF) - GTR_PITYSHIELD = 1<<16, // Award pity shield - GTR_DEATHPENALTY = 1<<17, // Death score penalty - GTR_NOSPECTATORSPAWN = 1<<18, // Use with GTR_SPECTATORS, spawn in the map instead of with the spectators - GTR_DEATHMATCHSTARTS = 1<<19, // Use deathmatch starts - GTR_SPECIALSTAGES = 1<<20, // Allow special stages - GTR_EMERALDTOKENS = 1<<21, // Spawn emerald tokens - GTR_EMERALDHUNT = 1<<22, // Emerald Hunt - GTR_SPAWNENEMIES = 1<<23, // Spawn enemies - GTR_ALLOWEXIT = 1<<24, // Allow exit sectors - GTR_NOTITLECARD = 1<<25, // Don't show the title card - GTR_OVERTIME = 1<<26, // Allow overtime - GTR_HURTMESSAGES = 1<<27, // Hit and death messages - GTR_SPAWNINVUL = 1<<28, // Babysitting deterrent - GTR_RESPAWNDELAY = 1<<29, // Respawn delay + GTR_FRIENDLY = 1<<6, // Co-op + GTR_RACE = 1<<7, // Race and Competition + GTR_TAG = 1<<8, // Tag and Hide and Seek + GTR_POINTLIMIT = 1<<9, // Ringslinger point limit + GTR_TIMELIMIT = 1<<10, // Ringslinger time limit + GTR_STARTCOUNTDOWN = 1<<11, // Hide time countdown (Tag and Hide and Seek) + GTR_HIDEFROZEN = 1<<12, // Frozen after hide time (Hide and Seek, but not Tag) + GTR_BLINDFOLDED = 1<<13, // Blindfolded view (Tag and Hide and Seek) + GTR_FIRSTPERSON = 1<<14, // First person camera + GTR_POWERSTONES = 1<<15, // Power stones (Match and CTF) + GTR_TEAMFLAGS = 1<<16, // Gametype has team flags (CTF) + GTR_PITYSHIELD = 1<<17, // Award pity shield + GTR_DEATHPENALTY = 1<<18, // Death score penalty + GTR_NOSPECTATORSPAWN = 1<<19, // Use with GTR_SPECTATORS, spawn in the map instead of with the spectators + GTR_DEATHMATCHSTARTS = 1<<20, // Use deathmatch starts + GTR_SPECIALSTAGES = 1<<21, // Allow special stages + GTR_EMERALDTOKENS = 1<<22, // Spawn emerald tokens + GTR_EMERALDHUNT = 1<<23, // Emerald Hunt + GTR_SPAWNENEMIES = 1<<24, // Spawn enemies + GTR_ALLOWEXIT = 1<<25, // Allow exit sectors + GTR_NOTITLECARD = 1<<26, // Don't show the title card + GTR_OVERTIME = 1<<27, // Allow overtime + GTR_HURTMESSAGES = 1<<28, // Hit and death messages + GTR_SPAWNINVUL = 1<<29, // Babysitting deterrent + GTR_RESPAWNDELAY = 1<<30, // Respawn delay }; // String names for gametypes diff --git a/src/g_game.c b/src/g_game.c index c8e185f56..67b6c2098 100644 --- a/src/g_game.c +++ b/src/g_game.c @@ -3193,7 +3193,7 @@ const char *Gametype_ConstantNames[NUMGAMETYPES] = UINT32 gametypedefaultrules[NUMGAMETYPES] = { // Co-op - GTR_CAMPAIGN|GTR_LIVES|GTR_SPAWNENEMIES|GTR_ALLOWEXIT|GTR_EMERALDHUNT|GTR_EMERALDTOKENS|GTR_SPECIALSTAGES, + GTR_CAMPAIGN|GTR_LIVES|GTR_FRIENDLY|GTR_SPAWNENEMIES|GTR_ALLOWEXIT|GTR_EMERALDHUNT|GTR_EMERALDTOKENS|GTR_SPECIALSTAGES, // Competition GTR_RACE|GTR_LIVES|GTR_SPAWNENEMIES|GTR_EMERALDTOKENS|GTR_SPAWNINVUL|GTR_ALLOWEXIT, // Race @@ -3447,10 +3447,7 @@ boolean G_GametypeUsesLives(void) // boolean G_GametypeUsesCoopLives(void) { - // Preparing for the inevitable - // gametype rule that will - // handle cooplives... - return (gametype == GT_COOP); + return (gametyperules & (GTR_LIVES|GTR_FRIENDLY)) == (GTR_LIVES|GTR_FRIENDLY); } // @@ -3461,10 +3458,7 @@ boolean G_GametypeUsesCoopLives(void) // boolean G_GametypeUsesCoopStarposts(void) { - // Preparing for the inevitable - // gametype rule that will - // handle coopstarposts... - return (gametype == GT_COOP); + return (gametyperules & GTR_FRIENDLY); } // From 8f0d5bf46872c3b041cb4ad5eeff382c30b57906 Mon Sep 17 00:00:00 2001 From: Jaime Passos Date: Sat, 28 Dec 2019 20:18:21 -0300 Subject: [PATCH 079/136] Organise gametype ruleset again. --- src/dehacked.c | 22 ++++++++++---------- src/doomstat.h | 56 +++++++++++++++++++++++++------------------------- 2 files changed, 39 insertions(+), 39 deletions(-) diff --git a/src/dehacked.c b/src/dehacked.c index 799428455..d71ed854c 100644 --- a/src/dehacked.c +++ b/src/dehacked.c @@ -8902,34 +8902,34 @@ static const char *const GAMETYPERULE_LIST[] = { "CAMPAIGN", "RINGSLINGER", "SPECTATORS", - "FRIENDLYFIRE", "LIVES", "TEAMS", + "FIRSTPERSON", + "POWERSTONES", + "TEAMFLAGS", "FRIENDLY", + "SPECIALSTAGES", + "EMERALDTOKENS", + "EMERALDHUNT", "RACE", "TAG", "POINTLIMIT", "TIMELIMIT", + "OVERTIME", + "HURTMESSAGES", + "FRIENDLYFIRE", "STARTCOUNTDOWN", "HIDEFROZEN", "BLINDFOLDED", - "FIRSTPERSON", - "POWERSTONES", - "TEAMFLAGS", + "RESPAWNDELAY", "PITYSHIELD", "DEATHPENALTY", "NOSPECTATORSPAWN", "DEATHMATCHSTARTS", - "SPECIALSTAGES", - "EMERALDTOKENS", - "EMERALDHUNT", + "SPAWNINVUL", "SPAWNENEMIES", "ALLOWEXIT", "NOTITLECARD", - "OVERTIME", - "HURTMESSAGES", - "SPAWNINVUL", - "RESPAWNDELAY", NULL }; diff --git a/src/doomstat.h b/src/doomstat.h index 42c05ba63..1e0eb4815 100644 --- a/src/doomstat.h +++ b/src/doomstat.h @@ -397,34 +397,34 @@ enum GameTypeRules GTR_CAMPAIGN = 1, // Linear Co-op map progression, don't allow random maps GTR_RINGSLINGER = 1<<1, // Outside of Co-op, Competition, and Race (overriden by cv_ringslinger) GTR_SPECTATORS = 1<<2, // Outside of Co-op, Competition, and Race - GTR_FRIENDLYFIRE = 1<<3, // Always allow friendly fire - GTR_LIVES = 1<<4, // Co-op and Competition - GTR_TEAMS = 1<<5, // Team Match, CTF - GTR_FRIENDLY = 1<<6, // Co-op - GTR_RACE = 1<<7, // Race and Competition - GTR_TAG = 1<<8, // Tag and Hide and Seek - GTR_POINTLIMIT = 1<<9, // Ringslinger point limit - GTR_TIMELIMIT = 1<<10, // Ringslinger time limit - GTR_STARTCOUNTDOWN = 1<<11, // Hide time countdown (Tag and Hide and Seek) - GTR_HIDEFROZEN = 1<<12, // Frozen after hide time (Hide and Seek, but not Tag) - GTR_BLINDFOLDED = 1<<13, // Blindfolded view (Tag and Hide and Seek) - GTR_FIRSTPERSON = 1<<14, // First person camera - GTR_POWERSTONES = 1<<15, // Power stones (Match and CTF) - GTR_TEAMFLAGS = 1<<16, // Gametype has team flags (CTF) - GTR_PITYSHIELD = 1<<17, // Award pity shield - GTR_DEATHPENALTY = 1<<18, // Death score penalty - GTR_NOSPECTATORSPAWN = 1<<19, // Use with GTR_SPECTATORS, spawn in the map instead of with the spectators - GTR_DEATHMATCHSTARTS = 1<<20, // Use deathmatch starts - GTR_SPECIALSTAGES = 1<<21, // Allow special stages - GTR_EMERALDTOKENS = 1<<22, // Spawn emerald tokens - GTR_EMERALDHUNT = 1<<23, // Emerald Hunt - GTR_SPAWNENEMIES = 1<<24, // Spawn enemies - GTR_ALLOWEXIT = 1<<25, // Allow exit sectors - GTR_NOTITLECARD = 1<<26, // Don't show the title card - GTR_OVERTIME = 1<<27, // Allow overtime - GTR_HURTMESSAGES = 1<<28, // Hit and death messages - GTR_SPAWNINVUL = 1<<29, // Babysitting deterrent - GTR_RESPAWNDELAY = 1<<30, // Respawn delay + GTR_LIVES = 1<<3, // Co-op and Competition + GTR_TEAMS = 1<<4, // Team Match, CTF + GTR_FIRSTPERSON = 1<<5, // First person camera + GTR_POWERSTONES = 1<<6, // Power stones (Match and CTF) + GTR_TEAMFLAGS = 1<<7, // Gametype has team flags (CTF) + GTR_FRIENDLY = 1<<8, // Co-op + GTR_SPECIALSTAGES = 1<<9, // Allow special stages + GTR_EMERALDTOKENS = 1<<10, // Spawn emerald tokens + GTR_EMERALDHUNT = 1<<11, // Emerald Hunt + GTR_RACE = 1<<12, // Race and Competition + GTR_TAG = 1<<13, // Tag and Hide and Seek + GTR_POINTLIMIT = 1<<14, // Ringslinger point limit + GTR_TIMELIMIT = 1<<15, // Ringslinger time limit + GTR_OVERTIME = 1<<16, // Allow overtime + GTR_HURTMESSAGES = 1<<17, // Hit and death messages + GTR_FRIENDLYFIRE = 1<<18, // Always allow friendly fire + GTR_STARTCOUNTDOWN = 1<<19, // Hide time countdown (Tag and Hide and Seek) + GTR_HIDEFROZEN = 1<<20, // Frozen after hide time (Hide and Seek, but not Tag) + GTR_BLINDFOLDED = 1<<21, // Blindfolded view (Tag and Hide and Seek) + GTR_RESPAWNDELAY = 1<<22, // Respawn delay + GTR_PITYSHIELD = 1<<23, // Award pity shield + GTR_DEATHPENALTY = 1<<24, // Death score penalty + GTR_NOSPECTATORSPAWN = 1<<25, // Use with GTR_SPECTATORS, spawn in the map instead of with the spectators + GTR_DEATHMATCHSTARTS = 1<<26, // Use deathmatch starts + GTR_SPAWNINVUL = 1<<27, // Babysitting deterrent + GTR_SPAWNENEMIES = 1<<28, // Spawn enemies + GTR_ALLOWEXIT = 1<<29, // Allow exit sectors + GTR_NOTITLECARD = 1<<30, // Don't show the title card }; // String names for gametypes From e5e4b4891a1d90b1a225896c0ab73965d94bd8ed Mon Sep 17 00:00:00 2001 From: Jaime Passos Date: Sat, 28 Dec 2019 20:33:28 -0300 Subject: [PATCH 080/136] Add GTR_CUTSCENES. And I ran out of rule slots. Cool. --- src/d_main.c | 2 +- src/dehacked.c | 1 + src/doomstat.h | 1 + src/g_game.c | 8 ++++---- 4 files changed, 7 insertions(+), 5 deletions(-) diff --git a/src/d_main.c b/src/d_main.c index e25ef998e..e79234730 100644 --- a/src/d_main.c +++ b/src/d_main.c @@ -715,7 +715,7 @@ void D_StartTitle(void) if (netgame) { - if (gametype == GT_COOP) + if (gametyperules & GTR_CAMPAIGN) { G_SetGamestate(GS_WAITINGPLAYERS); // hack to prevent a command repeat diff --git a/src/dehacked.c b/src/dehacked.c index d71ed854c..9a4e0d499 100644 --- a/src/dehacked.c +++ b/src/dehacked.c @@ -8930,6 +8930,7 @@ static const char *const GAMETYPERULE_LIST[] = { "SPAWNENEMIES", "ALLOWEXIT", "NOTITLECARD", + "CUTSCENES", NULL }; diff --git a/src/doomstat.h b/src/doomstat.h index 1e0eb4815..6d1d6eb36 100644 --- a/src/doomstat.h +++ b/src/doomstat.h @@ -425,6 +425,7 @@ enum GameTypeRules GTR_SPAWNENEMIES = 1<<28, // Spawn enemies GTR_ALLOWEXIT = 1<<29, // Allow exit sectors GTR_NOTITLECARD = 1<<30, // Don't show the title card + GTR_CUTSCENES = 1<<31, // Play cutscenes, ending, credits, and evaluation }; // String names for gametypes diff --git a/src/g_game.c b/src/g_game.c index 67b6c2098..e201faf6a 100644 --- a/src/g_game.c +++ b/src/g_game.c @@ -3193,7 +3193,7 @@ const char *Gametype_ConstantNames[NUMGAMETYPES] = UINT32 gametypedefaultrules[NUMGAMETYPES] = { // Co-op - GTR_CAMPAIGN|GTR_LIVES|GTR_FRIENDLY|GTR_SPAWNENEMIES|GTR_ALLOWEXIT|GTR_EMERALDHUNT|GTR_EMERALDTOKENS|GTR_SPECIALSTAGES, + GTR_CAMPAIGN|GTR_LIVES|GTR_FRIENDLY|GTR_SPAWNENEMIES|GTR_ALLOWEXIT|GTR_EMERALDHUNT|GTR_EMERALDTOKENS|GTR_SPECIALSTAGES|GTR_CUTSCENES, // Competition GTR_RACE|GTR_LIVES|GTR_SPAWNENEMIES|GTR_EMERALDTOKENS|GTR_SPAWNINVUL|GTR_ALLOWEXIT, // Race @@ -3765,7 +3765,7 @@ void G_AfterIntermission(void) HU_ClearCEcho(); - if (mapheaderinfo[gamemap-1]->cutscenenum && !modeattacking && skipstats <= 1) // Start a custom cutscene. + if ((gametyperules & GTR_CUTSCENES) && mapheaderinfo[gamemap-1]->cutscenenum && !modeattacking && skipstats <= 1) // Start a custom cutscene. F_StartCustomCutscene(mapheaderinfo[gamemap-1]->cutscenenum-1, false, false); else { @@ -3875,7 +3875,7 @@ static void G_DoContinued(void) void G_EndGame(void) { // Only do evaluation and credits in coop games. - if (gametype == GT_COOP) + if (gametyperules & GTR_CUTSCENES) { if (nextmap == 1103-1) // end game with ending { @@ -4578,7 +4578,7 @@ void G_InitNew(UINT8 pultmode, const char *mapname, boolean resetplayer, boolean automapactive = false; imcontinuing = false; - if (!skipprecutscene && mapheaderinfo[gamemap-1]->precutscenenum && !modeattacking) // Start a custom cutscene. + if ((gametyperules & GTR_CUTSCENES) && !skipprecutscene && mapheaderinfo[gamemap-1]->precutscenenum && !modeattacking) // Start a custom cutscene. F_StartCustomCutscene(mapheaderinfo[gamemap-1]->precutscenenum-1, true, resetplayer); else G_DoLoadLevel(resetplayer); From 4dafc59133d315c7425b5aef50bcdf1d837437b0 Mon Sep 17 00:00:00 2001 From: Jaime Passos Date: Sat, 28 Dec 2019 20:54:22 -0300 Subject: [PATCH 081/136] Remove characters that will not be allowed in the constant string. --- src/g_game.c | 96 ++++++++++++++++++++++++++++++---------------------- 1 file changed, 55 insertions(+), 41 deletions(-) diff --git a/src/g_game.c b/src/g_game.c index e201faf6a..37dd292f9 100644 --- a/src/g_game.c +++ b/src/g_game.c @@ -3251,50 +3251,64 @@ INT16 G_AddGametype(UINT32 rules) // void G_AddGametypeConstant(INT16 gtype, const char *newgtconst) { - char *gtconst = Z_Malloc(strlen(newgtconst) + 3, PU_STATIC, NULL); - // Copy GT_ and the gametype name. - strcpy(gtconst, "GT_"); - strcat(gtconst, newgtconst); + size_t r = 0; // read + size_t w = 0; // write + char *gtconst = Z_Calloc(strlen(newgtconst) + 3, PU_STATIC, NULL); + char *tmpconst = Z_Calloc(strlen(newgtconst), PU_STATIC, NULL); + + // Copy the gametype name. + strcpy(tmpconst, newgtconst); + // Make uppercase. - strupr(gtconst); - // Remove characters. -#define REMOVECHAR(chr) \ - { \ - char *chrfind = strchr(gtconst, chr); \ - while (chrfind) \ - { \ - *chrfind = '_'; \ - chrfind = strchr(chrfind, chr); \ - } \ + strupr(tmpconst); + + // Prepare to write the new constant string now. + strcpy(gtconst, "GT_"); + + // Remove characters that will not be allowed in the constant string. + for (; r < strlen(tmpconst); r++) + { + boolean writechar = true; + char rc = tmpconst[r]; + switch (rc) + { + // Space + case ' ': + // Used for operations + case '+': + case '-': + case '*': + case '/': + case '%': + case '^': + // Part of Lua's syntax + case '#': + case '=': + case '~': + case '<': + case '>': + case '(': + case ')': + case '{': + case '}': + case '[': + case ']': + case ':': + case ';': + case ',': + case '.': + writechar = false; + break; + } + if (writechar) + { + gtconst[3 + w] = rc; + w++; + } } - // Space - REMOVECHAR(' ') - // Used for operations - REMOVECHAR('+') - REMOVECHAR('-') - REMOVECHAR('*') - REMOVECHAR('/') - REMOVECHAR('%') - REMOVECHAR('^') - // Part of Lua's syntax - REMOVECHAR('#') - REMOVECHAR('=') - REMOVECHAR('~') - REMOVECHAR('<') - REMOVECHAR('>') - REMOVECHAR('(') - REMOVECHAR(')') - REMOVECHAR('{') - REMOVECHAR('}') - REMOVECHAR('[') - REMOVECHAR(']') - REMOVECHAR(':') - REMOVECHAR(';') - REMOVECHAR(',') - REMOVECHAR('.') - -#undef REMOVECHAR + // Free the temporary string. + Z_Free(tmpconst); // Finally, set the constant string. Gametype_ConstantNames[gtype] = gtconst; From 37b1953a143fbc843339adc5db670e46aa010d85 Mon Sep 17 00:00:00 2001 From: Jaime Passos Date: Sat, 28 Dec 2019 21:05:42 -0300 Subject: [PATCH 082/136] Disallow few more characters. --- src/g_game.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/g_game.c b/src/g_game.c index 37dd292f9..779592713 100644 --- a/src/g_game.c +++ b/src/g_game.c @@ -3272,8 +3272,10 @@ void G_AddGametypeConstant(INT16 gtype, const char *newgtconst) char rc = tmpconst[r]; switch (rc) { - // Space + // Space, at sign and question mark case ' ': + case '@': + case '?': // Used for operations case '+': case '-': @@ -3281,6 +3283,8 @@ void G_AddGametypeConstant(INT16 gtype, const char *newgtconst) case '/': case '%': case '^': + case '&': + case '!': // Part of Lua's syntax case '#': case '=': From ba40acf626e24002590334f05862e83c056b5dcb Mon Sep 17 00:00:00 2001 From: Jaime Passos Date: Sat, 28 Dec 2019 22:57:37 -0300 Subject: [PATCH 083/136] 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 0ecbd0baec329796cd008ee96b023b0bdeff2492 Mon Sep 17 00:00:00 2001 From: Steel Titanium Date: Sat, 28 Dec 2019 21:57:29 -0500 Subject: [PATCH 084/136] Fix emerald hunt not working properly --- src/g_game.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/g_game.c b/src/g_game.c index 19b18ef8c..518b5564e 100644 --- a/src/g_game.c +++ b/src/g_game.c @@ -1854,8 +1854,7 @@ void G_DoLoadLevel(boolean resetplayer) return; } - if (!resetplayer) - P_FindEmerald(); + P_FindEmerald(); displayplayer = consoleplayer; // view the guy you are playing if (!splitscreen && !botingame) From 08016fbdca2057e59db5ab9644d8b6a98f6d8801 Mon Sep 17 00:00:00 2001 From: James R Date: Sun, 29 Dec 2019 02:14:02 -0800 Subject: [PATCH 085/136] 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 0004f47f94b70f9561a075b2b8fa8616aa14e9aa Mon Sep 17 00:00:00 2001 From: James R Date: Sun, 29 Dec 2019 02:15:48 -0800 Subject: [PATCH 086/136] 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 69535cf20226a438c714e27d2a523b787b0e95f1 Mon Sep 17 00:00:00 2001 From: James R Date: Sun, 29 Dec 2019 02:16:37 -0800 Subject: [PATCH 087/136] 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 d9e9a2e1cec48425df71c0cfc21b13a6dbaef78c Mon Sep 17 00:00:00 2001 From: James R Date: Sun, 29 Dec 2019 02:31:14 -0800 Subject: [PATCH 088/136] 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 909a9dccc7f4335c7c00a707273a00c12b69fc55 Mon Sep 17 00:00:00 2001 From: James R Date: Sun, 29 Dec 2019 02:44:27 -0800 Subject: [PATCH 089/136] Don't let us warp to a map that doesn't exist (really!) Okay so 66524a1e3f1f85cd61821d271971e4edea9a5058, 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 ee94af04d526c3cb782e8dee6aa1d1e5e634f6d7 Mon Sep 17 00:00:00 2001 From: Jaime Passos Date: Sun, 29 Dec 2019 19:43:38 -0300 Subject: [PATCH 090/136] 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 3883d44bb57d8a68dd1c15fad69a631463a5de52 Mon Sep 17 00:00:00 2001 From: James R Date: Sun, 29 Dec 2019 18:37:22 -0800 Subject: [PATCH 091/136] 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 a330a7ee40b9570746aef917f59414e3080ec3aa Mon Sep 17 00:00:00 2001 From: James R Date: Sun, 29 Dec 2019 18:37:44 -0800 Subject: [PATCH 092/136] 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 69663fe87257d69c1871cbeb91017a564543c97b Mon Sep 17 00:00:00 2001 From: lachwright Date: Mon, 30 Dec 2019 19:00:45 +0800 Subject: [PATCH 093/136] Add unused sounds and remove unused sound slots --- src/sounds.c | 42 +++++++++++++++++++++++++----------------- src/sounds.h | 42 +++++++++++++++++++++++++----------------- 2 files changed, 50 insertions(+), 34 deletions(-) diff --git a/src/sounds.c b/src/sounds.c index 175bd8960..720ba851e 100644 --- a/src/sounds.c +++ b/src/sounds.c @@ -187,6 +187,7 @@ sfxinfo_t S_sfx[NUMSFX] = {"shield", false, 60, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Pity Shield"}, // generic GET! {"wirlsg", false, 60, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Whirlwind Shield"}, // Whirlwind GET! {"forcsg", false, 60, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Force Shield"}, // Force GET! + {"frcssg", false, 60, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Weak Force Shield"}, // Force GET...? (consider making a custom shield with this instead of a single-hit force shield!) {"elemsg", false, 60, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Elemental Shield"}, // Elemental GET! {"armasg", false, 60, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Armageddon Shield"}, // Armaggeddon GET! {"attrsg", false, 60, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Attraction Shield"}, // Attract GET! @@ -220,6 +221,9 @@ sfxinfo_t S_sfx[NUMSFX] = {"sprong", false, 112, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Power spring"}, {"lvfal1", true, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Rumble"}, {"pscree", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, "SCREE!"}, + {"iceb", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Ice crack"}, + {"shattr", true, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Shattering"}, + {"antiri", true, 255, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Depletion"}, // Menu, interface {"chchng", false, 120, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Score"}, @@ -233,6 +237,9 @@ sfxinfo_t S_sfx[NUMSFX] = {"wepchg", true, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Weapon change"}, // Weapon switch is identical to menu for now {"wtrdng", true, 212, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Aquaphobia"}, // make sure you can hear the DING DING! Tails 03-08-2000 {"zelda", false, 120, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Discovery"}, + {"adderr", true, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Error"}, + {"notadd", true, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Reject"}, + {"addfil", true, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Accept"}, // NiGHTS {"ideya", false, 127, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Success"}, @@ -427,24 +434,9 @@ sfxinfo_t S_sfx[NUMSFX] = {"s25e", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""}, {"s25f", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""}, {"s260", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""}, - {"s261", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""}, - {"s262", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""}, - {"s263", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""}, - {"s264", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""}, - {"s265", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""}, - {"s266", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""}, - {"s267", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""}, - {"s268", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""}, - {"s269", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""}, - {"s26a", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""}, - {"s26b", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""}, - {"s26c", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""}, - {"s26d", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""}, - {"s26e", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""}, - {"s26f", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""}, - {"s270", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""}, // S3&K sounds + {"s3k2b", true, 120, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Got Emerald"}, // Got Emerald! {"s3k33", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Sparkle"}, // stereo in original game, identical to latter {"s3k34", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Sparkle"}, // mono in original game, identical to previous {"s3k35", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Hurt"}, @@ -566,6 +558,21 @@ sfxinfo_t S_sfx[NUMSFX] = {"s3ka9", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Aquaphobia"}, {"s3kaa", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Bumper"}, {"s3kab", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Spindash"}, + {"s3kab1", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Spindash"}, + {"s3kab2", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Spindash"}, + {"s3kab3", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Spindash"}, + {"s3kab4", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Spindash"}, + {"s3kab5", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Spindash"}, + {"s3kab6", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Spindash"}, + {"s3kab7", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Spindash"}, + {"s3kab8", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Spindash"}, + {"s3kab9", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Spindash"}, + {"s3kaba", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Spindash"}, + {"s3kabb", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Spindash"}, + {"s3kabc", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Spindash"}, + {"s3kabd", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Spindash"}, + {"s3kabe", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Spindash"}, + {"s3kabf", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Spindash"}, {"s3kac", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Got Continue"}, {"s3kad", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, "GO!"}, {"s3kae", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Pinball flipper"}, @@ -604,7 +611,8 @@ sfxinfo_t S_sfx[NUMSFX] = {"s3kc5l", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Revving up"}, // ditto {"s3kc6s", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Orbiting"}, {"s3kc6l", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Orbiting"}, // ditto - {"s3kc7", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Aiming"}, + {"s3kc7s", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Aiming"}, + {"s3kc7l", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Aiming"}, // ditto {"s3kc8s", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Sliding"}, {"s3kc8l", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Sliding"}, // ditto {"s3kc9s", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Swinging"}, diff --git a/src/sounds.h b/src/sounds.h index e520c6243..039349d4f 100644 --- a/src/sounds.h +++ b/src/sounds.h @@ -236,6 +236,7 @@ typedef enum sfx_shield, sfx_wirlsg, sfx_forcsg, + sfx_frcssg, sfx_elemsg, sfx_armasg, sfx_attrsg, @@ -269,6 +270,9 @@ typedef enum sfx_sprong, sfx_lvfal1, sfx_pscree, + sfx_iceb, + sfx_shattr, + sfx_antiri, // Menu, interface sfx_chchng, @@ -282,6 +286,9 @@ typedef enum sfx_wepchg, sfx_wtrdng, sfx_zelda, + sfx_adderr, + sfx_notadd, + sfx_addfil, // NiGHTS sfx_ideya, @@ -476,24 +483,9 @@ typedef enum sfx_s25e, sfx_s25f, sfx_s260, - sfx_s261, - sfx_s262, - sfx_s263, - sfx_s264, - sfx_s265, - sfx_s266, - sfx_s267, - sfx_s268, - sfx_s269, - sfx_s26a, - sfx_s26b, - sfx_s26c, - sfx_s26d, - sfx_s26e, - sfx_s26f, - sfx_s270, // S3&K sounds + sfx_s3k2b, sfx_s3k33, sfx_s3k34, sfx_s3k35, @@ -615,6 +607,21 @@ typedef enum sfx_s3ka9, sfx_s3kaa, sfx_s3kab, + sfx_s3kab1, + sfx_s3kab2, + sfx_s3kab3, + sfx_s3kab4, + sfx_s3kab5, + sfx_s3kab6, + sfx_s3kab7, + sfx_s3kab8, + sfx_s3kab9, + sfx_s3kaba, + sfx_s3kabb, + sfx_s3kabc, + sfx_s3kabd, + sfx_s3kabe, + sfx_s3kabf, sfx_s3kac, sfx_s3kad, sfx_s3kae, @@ -653,7 +660,8 @@ typedef enum sfx_s3kc5l, sfx_s3kc6s, sfx_s3kc6l, - sfx_s3kc7, + sfx_s3kc7s, + sfx_s3kc7l, sfx_s3kc8s, sfx_s3kc8l, sfx_s3kc9s, From 014d2f63582f89549ee58805723392ffd766f874 Mon Sep 17 00:00:00 2001 From: Monster Iestyn Date: Mon, 30 Dec 2019 11:49:01 +0000 Subject: [PATCH 094/136] Fix P_SetTarget crash by setting th->target to NULL first --- src/p_polyobj.c | 1 + 1 file changed, 1 insertion(+) diff --git a/src/p_polyobj.c b/src/p_polyobj.c index be5673093..f6f666061 100644 --- a/src/p_polyobj.c +++ b/src/p_polyobj.c @@ -2647,6 +2647,7 @@ INT32 EV_DoPolyObjWaypoint(polywaypointdata_t *pwdata) // Set pointnum th->pointnum = target->health; + th->target = NULL; // set to NULL first so the below doesn't go wrong // Set the mobj as your target! -- Monster Iestyn 27/12/19 P_SetTarget(&th->target, target); From 8d1ad4dc2e62b5287d441afa14956249cda645b5 Mon Sep 17 00:00:00 2001 From: Jaime Passos Date: Mon, 30 Dec 2019 12:02:09 -0300 Subject: [PATCH 095/136] 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 2e8f83b79c476d8ec69bc8ab0b9da3ecf3fbab9f Mon Sep 17 00:00:00 2001 From: James R Date: Mon, 30 Dec 2019 17:57:18 -0800 Subject: [PATCH 096/136] Use gametypecount in G_GetGametypeByName --- src/g_game.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/g_game.c b/src/g_game.c index efb580f21..96e7559ee 100644 --- a/src/g_game.c +++ b/src/g_game.c @@ -3398,7 +3398,7 @@ INT32 G_GetGametypeByName(const char *gametypestr) { INT32 i; - for (i = 0; i < NUMGAMETYPES; i++) + for (i = 0; i < gametypecount; i++) if (!stricmp(gametypestr, Gametype_Names[i])) return i; From 46c0d62a0696d4a7a853a4147354b65ac4563b27 Mon Sep 17 00:00:00 2001 From: James R Date: Mon, 30 Dec 2019 18:44:13 -0800 Subject: [PATCH 097/136] 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 7d6d8b3b6e8be83db6e778a6f322874dbd410a82 Mon Sep 17 00:00:00 2001 From: James R Date: Mon, 30 Dec 2019 18:46:38 -0800 Subject: [PATCH 098/136] Fix command not running if it was split by COM_BufAddText (Looks at d57083264e93f1020c2730e072c7a7b5417e08b3...) --- 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 cdadd86780a1877ba9b4d59a991ecf9f319bc8eb Mon Sep 17 00:00:00 2001 From: James R Date: Mon, 30 Dec 2019 19:19:17 -0800 Subject: [PATCH 099/136] 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 5cf362dd87794e1f7e1647c641f4ab63048bd417 Mon Sep 17 00:00:00 2001 From: Tatsuru <44866610+Ikkarin@users.noreply.github.com> Date: Tue, 31 Dec 2019 00:38:09 -0300 Subject: [PATCH 100/136] Disable Minecart Spawners for players already riding a minecart --- src/p_inter.c | 34 +++++++++++++++++++--------------- 1 file changed, 19 insertions(+), 15 deletions(-) diff --git a/src/p_inter.c b/src/p_inter.c index 70fb01fd0..4804905f5 100644 --- a/src/p_inter.c +++ b/src/p_inter.c @@ -1807,23 +1807,27 @@ void P_TouchSpecialThing(mobj_t *special, mobj_t *toucher, boolean heightcheck) return; case MT_MINECARTSPAWNER: - if (!player->bot && (special->fuse < TICRATE || player->powers[pw_carry] != CR_MINECART)) - { - mobj_t *mcart = P_SpawnMobj(special->x, special->y, special->z, MT_MINECART); - P_SetTarget(&mcart->target, toucher); - mcart->angle = toucher->angle = player->drawangle = special->angle; - mcart->friction = FRACUNIT; + if (player->bot) + return; + if (special->fuse > TICRATE) + return; + if (player->powers[pw_carry] == CR_MINECART) + return; + + mobj_t *mcart = P_SpawnMobj(special->x, special->y, special->z, MT_MINECART); + P_SetTarget(&mcart->target, toucher); + mcart->angle = toucher->angle = player->drawangle = special->angle; + mcart->friction = FRACUNIT; - P_ResetPlayer(player); - player->pflags |= PF_JUMPDOWN; - player->powers[pw_carry] = CR_MINECART; - player->pflags &= ~PF_APPLYAUTOBRAKE; - P_SetTarget(&toucher->tracer, mcart); - toucher->momx = toucher->momy = toucher->momz = 0; + P_ResetPlayer(player); + player->pflags |= PF_JUMPDOWN; + player->powers[pw_carry] = CR_MINECART; + player->pflags &= ~PF_APPLYAUTOBRAKE; + P_SetTarget(&toucher->tracer, mcart); + toucher->momx = toucher->momy = toucher->momz = 0; - special->fuse = 3*TICRATE; - special->flags2 |= MF2_DONTDRAW; - } + special->fuse = 3*TICRATE; + special->flags2 |= MF2_DONTDRAW; return; case MT_MINECARTEND: From 4f8775d560eeb2add99bf1fa20f942657be3f304 Mon Sep 17 00:00:00 2001 From: James R Date: Mon, 30 Dec 2019 20:08:29 -0800 Subject: [PATCH 101/136] 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 73643dafaf9fe931f4327c04f3af5f9514cdf779 Mon Sep 17 00:00:00 2001 From: James R Date: Mon, 30 Dec 2019 20:18:08 -0800 Subject: [PATCH 102/136] 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 15d4829e19c48ed5b70af5067b91dc644bf50fb6 Mon Sep 17 00:00:00 2001 From: Tatsuru <44866610+Ikkarin@users.noreply.github.com> Date: Tue, 31 Dec 2019 01:20:11 -0300 Subject: [PATCH 103/136] Appease the C90 entity --- src/p_inter.c | 28 +++++++++++++++------------- 1 file changed, 15 insertions(+), 13 deletions(-) diff --git a/src/p_inter.c b/src/p_inter.c index 4804905f5..b28b98758 100644 --- a/src/p_inter.c +++ b/src/p_inter.c @@ -1813,21 +1813,23 @@ void P_TouchSpecialThing(mobj_t *special, mobj_t *toucher, boolean heightcheck) return; if (player->powers[pw_carry] == CR_MINECART) return; - - mobj_t *mcart = P_SpawnMobj(special->x, special->y, special->z, MT_MINECART); - P_SetTarget(&mcart->target, toucher); - mcart->angle = toucher->angle = player->drawangle = special->angle; - mcart->friction = FRACUNIT; + else + { + mobj_t *mcart = P_SpawnMobj(special->x, special->y, special->z, MT_MINECART); + P_SetTarget(&mcart->target, toucher); + mcart->angle = toucher->angle = player->drawangle = special->angle; + mcart->friction = FRACUNIT; - P_ResetPlayer(player); - player->pflags |= PF_JUMPDOWN; - player->powers[pw_carry] = CR_MINECART; - player->pflags &= ~PF_APPLYAUTOBRAKE; - P_SetTarget(&toucher->tracer, mcart); - toucher->momx = toucher->momy = toucher->momz = 0; + P_ResetPlayer(player); + player->pflags |= PF_JUMPDOWN; + player->powers[pw_carry] = CR_MINECART; + player->pflags &= ~PF_APPLYAUTOBRAKE; + P_SetTarget(&toucher->tracer, mcart); + toucher->momx = toucher->momy = toucher->momz = 0; - special->fuse = 3*TICRATE; - special->flags2 |= MF2_DONTDRAW; + special->fuse = 3*TICRATE; + special->flags2 |= MF2_DONTDRAW; + } return; case MT_MINECARTEND: From 3b30fcc5fade69aa06386b8de0e576b629c320e5 Mon Sep 17 00:00:00 2001 From: James R Date: Mon, 30 Dec 2019 20:29:41 -0800 Subject: [PATCH 104/136] 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 50ffcba552abdc825c88fdeaf6cda28b64fa5817 Mon Sep 17 00:00:00 2001 From: Tatsuru <44866610+Ikkarin@users.noreply.github.com> Date: Tue, 31 Dec 2019 01:48:50 -0300 Subject: [PATCH 105/136] Small --- src/p_inter.c | 8 +------- 1 file changed, 1 insertion(+), 7 deletions(-) diff --git a/src/p_inter.c b/src/p_inter.c index b28b98758..67d5a8a3f 100644 --- a/src/p_inter.c +++ b/src/p_inter.c @@ -1807,13 +1807,7 @@ void P_TouchSpecialThing(mobj_t *special, mobj_t *toucher, boolean heightcheck) return; case MT_MINECARTSPAWNER: - if (player->bot) - return; - if (special->fuse > TICRATE) - return; - if (player->powers[pw_carry] == CR_MINECART) - return; - else + if (!player->bot && special->fuse <= TICRATE && player->powers[pw_carry] != CR_MINECART) { mobj_t *mcart = P_SpawnMobj(special->x, special->y, special->z, MT_MINECART); P_SetTarget(&mcart->target, toucher); From 7616bf573449812085ca17ad3985e6759c9e5515 Mon Sep 17 00:00:00 2001 From: James R Date: Mon, 30 Dec 2019 21:40:13 -0800 Subject: [PATCH 106/136] 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 ec72c69614df54eed1f72f8c0c9a620038687311 Mon Sep 17 00:00:00 2001 From: James R Date: Mon, 30 Dec 2019 21:45:19 -0800 Subject: [PATCH 107/136] 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 6d042c4d3f4e986df6329bc2cc123cf9d3658c79 Mon Sep 17 00:00:00 2001 From: James R Date: Mon, 30 Dec 2019 22:18:55 -0800 Subject: [PATCH 108/136] Replace gametype with gametypename in SERVERINFO PACKETVERSION 1 --- src/d_clisrv.c | 14 +++++++------- src/d_clisrv.h | 4 ++-- src/m_menu.c | 18 ++++++++++++------ 3 files changed, 21 insertions(+), 15 deletions(-) diff --git a/src/d_clisrv.c b/src/d_clisrv.c index af2be129f..302294557 100644 --- a/src/d_clisrv.c +++ b/src/d_clisrv.c @@ -1293,7 +1293,8 @@ static void SV_SendServerInfo(INT32 node, tic_t servertime) netbuffer->u.serverinfo.numberofplayer = (UINT8)D_NumPlayers(); netbuffer->u.serverinfo.maxplayer = (UINT8)cv_maxplayers.value; - netbuffer->u.serverinfo.gametype = (UINT8)gametype; + strncpy(netbuffer->u.serverinfo.gametypename, Gametype_Names[gametype], + sizeof netbuffer->u.serverinfo.gametypename); netbuffer->u.serverinfo.modifiedgame = (UINT8)modifiedgame; netbuffer->u.serverinfo.cheatsenabled = CV_CheatsEnabled(); netbuffer->u.serverinfo.isdedicated = (UINT8)dedicated; @@ -2122,13 +2123,10 @@ static void CL_ConnectToServer(boolean viams) if (i != -1) { - UINT16 num = serverlist[i].info.gametype; - const char *gametypestr = NULL; + char *gametypestr = serverlist[i].info.gametypename; CONS_Printf(M_GetText("Connecting to: %s\n"), serverlist[i].info.servername); - if (num < gametypecount) - gametypestr = Gametype_Names[num]; - if (gametypestr) - CONS_Printf(M_GetText("Gametype: %s\n"), gametypestr); + gametypestr[sizeof serverlist[i].info.gametypename - 1] = '\0'; + CONS_Printf(M_GetText("Gametype: %s\n"), gametypestr); CONS_Printf(M_GetText("Version: %d.%d.%u\n"), serverlist[i].info.version/100, serverlist[i].info.version%100, serverlist[i].info.subversion); } @@ -3656,6 +3654,8 @@ static void HandleServerInfo(SINT8 node) netbuffer->u.serverinfo.servername[MAXSERVERNAME-1] = 0; netbuffer->u.serverinfo.application [sizeof netbuffer->u.serverinfo.application - 1] = '\0'; + netbuffer->u.serverinfo.gametypename + [sizeof netbuffer->u.serverinfo.gametypename - 1] = '\0'; SL_InsertServer(&netbuffer->u.serverinfo, node); } diff --git a/src/d_clisrv.h b/src/d_clisrv.h index 49f8afc76..c797e5ca8 100644 --- a/src/d_clisrv.h +++ b/src/d_clisrv.h @@ -27,7 +27,7 @@ This version is independent of the mod name, and standard version and subversion. It should only account for the basic fields of the packet, and change infrequently. */ -#define PACKETVERSION 0 +#define PACKETVERSION 1 // Network play related stuff. // There is a data struct that stores network @@ -361,7 +361,7 @@ typedef struct UINT8 subversion; UINT8 numberofplayer; UINT8 maxplayer; - UINT8 gametype; + char gametypename[24]; UINT8 modifiedgame; UINT8 cheatsenabled; UINT8 isdedicated; diff --git a/src/m_menu.c b/src/m_menu.c index 6ef9a5e19..a199b0ae3 100644 --- a/src/m_menu.c +++ b/src/m_menu.c @@ -9971,7 +9971,7 @@ static void M_DrawRoomMenu(void) static void M_DrawConnectMenu(void) { UINT16 i; - const char *gt = "Unknown"; + char *gt; INT32 numPages = (serverlistcount+(SERVERS_PER_PAGE-1))/SERVERS_PER_PAGE; for (i = FIRSTSERVERLINE; i < min(localservercount, SERVERS_PER_PAGE)+FIRSTSERVERLINE; i++) @@ -10015,9 +10015,7 @@ static void M_DrawConnectMenu(void) V_DrawSmallString(currentMenu->x, S_LINEY(i)+8, globalflags, va("Ping: %u", (UINT32)LONG(serverlist[slindex].info.time))); - gt = "Unknown"; - if (serverlist[slindex].info.gametype < gametypecount) - gt = Gametype_Names[serverlist[slindex].info.gametype]; + gt = serverlist[slindex].info.gametypename; V_DrawSmallString(currentMenu->x+46,S_LINEY(i)+8, globalflags, va("Players: %02d/%02d", serverlist[slindex].info.numberofplayer, serverlist[slindex].info.maxplayer)); @@ -10063,7 +10061,15 @@ SERVER_LIST_ENTRY_COMPARATOR(time) SERVER_LIST_ENTRY_COMPARATOR(numberofplayer) SERVER_LIST_ENTRY_COMPARATOR_REVERSE(numberofplayer) SERVER_LIST_ENTRY_COMPARATOR_REVERSE(maxplayer) -SERVER_LIST_ENTRY_COMPARATOR(gametype) + +static int ServerListEntryComparator_gametypename(const void *entry1, const void *entry2) +{ + const serverelem_t *sa = (const serverelem_t*)entry1, *sb = (const serverelem_t*)entry2; + int c; + if (( c = strcasecmp(sa->info.gametypename, sb->info.gametypename) )) + return c; + return strcmp(sa->info.servername, sb->info.servername); \ +} // Special one for modified state. static int ServerListEntryComparator_modified(const void *entry1, const void *entry2) @@ -10103,7 +10109,7 @@ void M_SortServerList(void) qsort(serverlist, serverlistcount, sizeof(serverelem_t), ServerListEntryComparator_maxplayer_reverse); break; case 5: // Gametype. - qsort(serverlist, serverlistcount, sizeof(serverelem_t), ServerListEntryComparator_gametype); + qsort(serverlist, serverlistcount, sizeof(serverelem_t), ServerListEntryComparator_gametypename); break; } #endif From 93d5a9a17485a592ad7f5e975873627ea84fe2bd Mon Sep 17 00:00:00 2001 From: James R Date: Mon, 30 Dec 2019 22:23:19 -0800 Subject: [PATCH 109/136] Truncate gametype name in server list if it's too long --- src/m_menu.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/src/m_menu.c b/src/m_menu.c index a199b0ae3..282e2fe1b 100644 --- a/src/m_menu.c +++ b/src/m_menu.c @@ -10020,7 +10020,12 @@ static void M_DrawConnectMenu(void) V_DrawSmallString(currentMenu->x+46,S_LINEY(i)+8, globalflags, va("Players: %02d/%02d", serverlist[slindex].info.numberofplayer, serverlist[slindex].info.maxplayer)); - V_DrawSmallString(currentMenu->x+112, S_LINEY(i)+8, globalflags, va("Gametype: %s", gt)); + if (strlen(gt) > 11) + gt = va("Gametype: %.11s...", gt); + else + gt = va("Gametype: %s", gt); + + V_DrawSmallString(currentMenu->x+112, S_LINEY(i)+8, globalflags, gt); MP_ConnectMenu[i+FIRSTSERVERLINE].status = IT_STRING | IT_CALL; } From aaa18750401d2ff27412f43df92433a4ba849c81 Mon Sep 17 00:00:00 2001 From: lachwright Date: Tue, 31 Dec 2019 16:48:29 +0800 Subject: [PATCH 110/136] Remove flight indicator when AI Tails is taken over by second player --- src/b_bot.c | 48 +++++++++++++++++++++++++++--------------------- src/b_bot.h | 1 + src/g_game.c | 1 + 3 files changed, 29 insertions(+), 21 deletions(-) diff --git a/src/b_bot.c b/src/b_bot.c index dfb5ee1cf..dba156b27 100644 --- a/src/b_bot.c +++ b/src/b_bot.c @@ -335,27 +335,6 @@ static void B_BuildTailsTiccmd(mobj_t *sonic, mobj_t *tails, ticcmd_t *cmd) jump_last = jump; spin_last = spin; - // ******** - // Thinkfly overlay - if (thinkfly) - { - if (!tails->hnext) - { - P_SetTarget(&tails->hnext, P_SpawnMobjFromMobj(tails, 0, 0, 0, MT_OVERLAY)); - if (tails->hnext) - { - P_SetTarget(&tails->hnext->target, tails); - P_SetTarget(&tails->hnext->hprev, tails); - P_SetMobjState(tails->hnext, S_FLIGHTINDICATOR); - } - } - } - else if (tails->hnext && tails->hnext->type == MT_OVERLAY && tails->hnext->state == states+S_FLIGHTINDICATOR) - { - P_RemoveMobj(tails->hnext); - P_SetTarget(&tails->hnext, NULL); - } - // Turn the virtual keypresses into ticcmd_t. B_KeysToTiccmd(tails, cmd, forward, backward, left, right, false, false, jump, spin); @@ -565,3 +544,30 @@ void B_RespawnBot(INT32 playernum) P_SetScale(tails, sonic->scale); tails->destscale = sonic->destscale; } + +void B_HandleFlightIndicator(player_t *player) +{ + mobj_t *tails = player->mo + + if (!tails) + return; + + if (thinkfly && player->bot == 1) + { + if (!tails->hnext) + { + P_SetTarget(&tails->hnext, P_SpawnMobjFromMobj(tails, 0, 0, 0, MT_OVERLAY)); + if (tails->hnext) + { + P_SetTarget(&tails->hnext->target, tails); + P_SetTarget(&tails->hnext->hprev, tails); + P_SetMobjState(tails->hnext, S_FLIGHTINDICATOR); + } + } + } + else if (tails->hnext && tails->hnext->type == MT_OVERLAY && tails->hnext->state == states+S_FLIGHTINDICATOR) + { + P_RemoveMobj(tails->hnext); + P_SetTarget(&tails->hnext, NULL); + } +} diff --git a/src/b_bot.h b/src/b_bot.h index b42577c5c..54ef300a3 100644 --- a/src/b_bot.h +++ b/src/b_bot.h @@ -15,3 +15,4 @@ void B_KeysToTiccmd(mobj_t *mo, ticcmd_t *cmd, boolean forward, boolean backward boolean B_CheckRespawn(player_t *player); void B_MoveBlocked(player_t *player); void B_RespawnBot(INT32 playernum); +void B_HandleFlightIndicator(player_t *player); diff --git a/src/g_game.c b/src/g_game.c index 144975177..79ea2c70b 100644 --- a/src/g_game.c +++ b/src/g_game.c @@ -1718,6 +1718,7 @@ void G_BuildTiccmd2(ticcmd_t *cmd, INT32 realtics) G_CopyTiccmd(cmd, I_BaseTiccmd2(), 1); // empty, or external driver B_BuildTiccmd(player, cmd); } + B_HandleFlightIndicator(player); } if (cv_analog2.value) { From 9f5283f84154fbc28ff8286d811ebb71b9fd4945 Mon Sep 17 00:00:00 2001 From: lachwright Date: Tue, 31 Dec 2019 16:54:52 +0800 Subject: [PATCH 111/136] Remove flight indicator on death as well --- src/b_bot.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/b_bot.c b/src/b_bot.c index dba156b27..64cb00e7e 100644 --- a/src/b_bot.c +++ b/src/b_bot.c @@ -552,7 +552,7 @@ void B_HandleFlightIndicator(player_t *player) if (!tails) return; - if (thinkfly && player->bot == 1) + if (thinkfly && player->bot == 1 && tails->health) { if (!tails->hnext) { From 2f8033c42621206a3e24a682d1e9cdb9130427c5 Mon Sep 17 00:00:00 2001 From: lachwright Date: Tue, 31 Dec 2019 16:55:36 +0800 Subject: [PATCH 112/136] Add missed semicolon, oops --- src/b_bot.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/b_bot.c b/src/b_bot.c index 64cb00e7e..51dc4d2f2 100644 --- a/src/b_bot.c +++ b/src/b_bot.c @@ -547,7 +547,7 @@ void B_RespawnBot(INT32 playernum) void B_HandleFlightIndicator(player_t *player) { - mobj_t *tails = player->mo + mobj_t *tails = player->mo; if (!tails) return; From 8132905436933172b655d3c9c2481ed4648ec11d Mon Sep 17 00:00:00 2001 From: lachwright Date: Tue, 31 Dec 2019 17:26:35 +0800 Subject: [PATCH 113/136] Make Metal Sonic's jet fume opaque when re-emerging from water --- src/p_user.c | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/src/p_user.c b/src/p_user.c index 02dd77668..bc4589751 100644 --- a/src/p_user.c +++ b/src/p_user.c @@ -11250,7 +11250,10 @@ static void P_DoMetalJetFume(player_t *player, mobj_t *fume) if (panim == PA_WALK) { if (stat != fume->info->spawnstate) + { + fume->threshold = 0; P_SetMobjState(fume, fume->info->spawnstate); + } return; } } @@ -11281,6 +11284,12 @@ static void P_DoMetalJetFume(player_t *player, mobj_t *fume) if (underwater) { fume->frame = (fume->frame & FF_FRAMEMASK) | FF_ANIMATE | (P_RandomRange(0, 9) * FF_TRANS10); + fume->threshold = 1; + } + else if (fume->threshold) + { + fume->frame = (fume->frame & FF_FRAMEMASK) | fume->state->frame; + fume->threshold = 0; } } From b575e7ab471840747e1aaeaba7298eb7d4e7fee1 Mon Sep 17 00:00:00 2001 From: lachwright Date: Tue, 31 Dec 2019 18:06:40 +0800 Subject: [PATCH 114/136] Make elemental crop circle flames obey player gravity --- src/p_user.c | 1 + 1 file changed, 1 insertion(+) diff --git a/src/p_user.c b/src/p_user.c index 02dd77668..36bc0a2fc 100644 --- a/src/p_user.c +++ b/src/p_user.c @@ -7786,6 +7786,7 @@ void P_ElementalFire(player_t *player, boolean cropcircle) flame->fuse = TICRATE*7; // takes about an extra second to hit the ground flame->destscale = player->mo->scale; P_SetScale(flame, player->mo->scale); + flame->flags2 = (flame->flags2 & ~MF2_OBJECTFLIP)|(player->mo->flags2 & MF2_OBJECTFLIP); flame->eflags = (flame->eflags & ~MFE_VERTICALFLIP)|(player->mo->eflags & MFE_VERTICALFLIP); P_InstaThrust(flame, flame->angle, FixedMul(3*FRACUNIT, flame->scale)); P_SetObjectMomZ(flame, 3*FRACUNIT, false); From 24e4552d5b0c64e3645258202902c95327a9e8ba Mon Sep 17 00:00:00 2001 From: Tatsuru <44866610+Ikkarin@users.noreply.github.com> Date: Tue, 31 Dec 2019 11:19:54 -0300 Subject: [PATCH 115/136] Got rid of the uhh --- src/p_inter.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/p_inter.c b/src/p_inter.c index 67d5a8a3f..ff68cdf69 100644 --- a/src/p_inter.c +++ b/src/p_inter.c @@ -1808,7 +1808,7 @@ void P_TouchSpecialThing(mobj_t *special, mobj_t *toucher, boolean heightcheck) case MT_MINECARTSPAWNER: if (!player->bot && special->fuse <= TICRATE && player->powers[pw_carry] != CR_MINECART) - { + { mobj_t *mcart = P_SpawnMobj(special->x, special->y, special->z, MT_MINECART); P_SetTarget(&mcart->target, toucher); mcart->angle = toucher->angle = player->drawangle = special->angle; From 77d6601e8b3f65a296acee2e87f1a7639728f410 Mon Sep 17 00:00:00 2001 From: Jaime Passos Date: Tue, 31 Dec 2019 14:00:25 -0300 Subject: [PATCH 116/136] Fix desynch --- src/p_setup.c | 1 + 1 file changed, 1 insertion(+) diff --git a/src/p_setup.c b/src/p_setup.c index 5a7a5cb93..366fc5372 100644 --- a/src/p_setup.c +++ b/src/p_setup.c @@ -3016,6 +3016,7 @@ boolean P_LoadLevel(boolean fromnetsave) // This is needed. Don't touch. maptol = mapheaderinfo[gamemap-1]->typeoflevel; + gametyperules = gametypedefaultrules[gametype]; CON_Drawer(); // let the user know what we are going to do I_FinishUpdate(); // page flip or blit buffer From a8110211127dfe03513fe5533ad3c2c4b9ea284a Mon Sep 17 00:00:00 2001 From: Jaime Passos Date: Tue, 31 Dec 2019 14:37:45 -0300 Subject: [PATCH 117/136] **NEW!** hook_SeenPlayer --- src/lua_hook.h | 4 ++++ src/lua_hooklib.c | 49 ++++++++++++++++++++++++++++++++++++++++++++++- src/p_map.c | 11 ++++++++--- 3 files changed, 60 insertions(+), 4 deletions(-) diff --git a/src/lua_hook.h b/src/lua_hook.h index 68efbce93..24e61c20c 100644 --- a/src/lua_hook.h +++ b/src/lua_hook.h @@ -53,6 +53,7 @@ enum hook { hook_IntermissionThinker, hook_TeamSwitch, hook_ViewpointSwitch, + hook_SeenPlayer, hook_MAX // last hook }; @@ -97,5 +98,8 @@ void LUAh_PlayerQuit(player_t *plr, int reason); // Hook for player quitting void LUAh_IntermissionThinker(void); // Hook for Y_Ticker boolean LUAh_TeamSwitch(player_t *player, int newteam, boolean fromspectators, boolean tryingautobalance, boolean tryingscramble); // Hook for team switching in... uh.... UINT8 LUAh_ViewpointSwitch(player_t *player, player_t *newdisplayplayer, boolean forced); // Hook for spy mode +#ifdef SEENAMES +boolean LUAh_SeenPlayer(player_t *player, player_t *seenplayer); // Hook for MT_NAMECHECK +#endif #endif diff --git a/src/lua_hooklib.c b/src/lua_hooklib.c index 91b4c6992..fc9d74f08 100644 --- a/src/lua_hooklib.c +++ b/src/lua_hooklib.c @@ -64,6 +64,7 @@ const char *const hookNames[hook_MAX+1] = { "IntermissionThinker", "TeamSwitch", "ViewpointSwitch", + "SeenPlayer", NULL }; @@ -207,6 +208,7 @@ static int lib_addHook(lua_State *L) case hook_PlayerCanDamage: case hook_TeamSwitch: case hook_ViewpointSwitch: + case hook_SeenPlayer: case hook_ShieldSpawn: case hook_ShieldSpecial: lastp = &playerhooks; @@ -1412,7 +1414,7 @@ UINT8 LUAh_ViewpointSwitch(player_t *player, player_t *newdisplayplayer, boolean return 0; lua_settop(gL, 0); - hud_running = true; + hud_running = true; // local hook for (hookp = playerhooks; hookp; hookp = hookp->next) { @@ -1453,4 +1455,49 @@ UINT8 LUAh_ViewpointSwitch(player_t *player, player_t *newdisplayplayer, boolean return canSwitchView; } +// Hook for MT_NAMECHECK +#ifdef SEENAMES +boolean LUAh_SeenPlayer(player_t *player, player_t *seenplayer) +{ + hook_p hookp; + boolean hasSeenPlayer = true; + if (!gL || !(hooksAvailable[hook_SeenPlayer/8] & (1<<(hook_SeenPlayer%8)))) + return 0; + + lua_settop(gL, 0); + hud_running = true; // local hook + + for (hookp = playerhooks; hookp; hookp = hookp->next) + { + if (hookp->type != hook_SeenPlayer) + continue; + + if (lua_gettop(gL) == 0) + { + LUA_PushUserdata(gL, player, META_PLAYER); + LUA_PushUserdata(gL, seenplayer, META_PLAYER); + } + lua_pushfstring(gL, FMT_HOOKID, hookp->id); + lua_gettable(gL, LUA_REGISTRYINDEX); + lua_pushvalue(gL, -3); + lua_pushvalue(gL, -3); + if (lua_pcall(gL, 2, 1, 0)) { + if (!hookp->error || cv_debug & DBG_LUA) + CONS_Alert(CONS_WARNING,"%s\n",lua_tostring(gL, -1)); + lua_pop(gL, 1); + hookp->error = true; + continue; + } + if (!lua_isnil(gL, -1) && !lua_toboolean(gL, -1)) + hasSeenPlayer = false; // Hasn't seen player + lua_pop(gL, 1); + } + + lua_settop(gL, 0); + hud_running = false; + + return hasSeenPlayer; +} +#endif // SEENAMES + #endif diff --git a/src/p_map.c b/src/p_map.c index 25da9c58d..4a965998e 100644 --- a/src/p_map.c +++ b/src/p_map.c @@ -745,9 +745,8 @@ static boolean PIT_CheckThing(mobj_t *thing) // So that NOTHING ELSE can see MT_NAMECHECK because it is client-side. if (tmthing->type == MT_NAMECHECK) { - // Ignore things that aren't players, ignore spectators, ignore yourself. - // (also don't bother to check that tmthing->target->player is non-NULL because we're not actually using it here.) - if (!thing->player || thing->player->spectator || (tmthing->target && thing->player == tmthing->target->player)) + // Ignore things that aren't players, ignore spectators, ignore yourself. + if (!thing->player || !(tmthing->target && tmthing->target->player) || thing->player->spectator || (tmthing->target && thing->player == tmthing->target->player)) return true; // Now check that you actually hit them. @@ -760,6 +759,12 @@ static boolean PIT_CheckThing(mobj_t *thing) if (tmthing->z + tmthing->height < thing->z) return true; // underneath +#ifdef HAVE_BLUA + // REX HAS SEEN YOU + if (!LUAh_SeenPlayer(tmthing->target->player, thing->player)) + return false; +#endif + seenplayer = thing->player; return false; } From 402b58ce4287ebc9d6f99882ef824156f0bd1555 Mon Sep 17 00:00:00 2001 From: Tatsuru <44866610+Ikkarin@users.noreply.github.com> Date: Tue, 31 Dec 2019 19:38:11 -0300 Subject: [PATCH 118/136] Fix MP Special Stages crashing if a player is being carried when it ends --- src/p_user.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/p_user.c b/src/p_user.c index ea42a2c36..292bad2af 100644 --- a/src/p_user.c +++ b/src/p_user.c @@ -347,6 +347,11 @@ void P_GiveEmerald(boolean spawnObj) continue; P_SetTarget(&emmo->target, players[i].mo); P_SetMobjState(emmo, mobjinfo[MT_GOTEMERALD].meleestate + em); + + // Make sure we're not being carried before our tracer is changed + if (players[i].powers[pw_carry] != CR_NONE) + players[i].powers[pw_carry] = CR_NONE; + P_SetTarget(&players[i].mo->tracer, emmo); if (pnum == 255) From df9809f3d71f964dd9358c67061111610886fd96 Mon Sep 17 00:00:00 2001 From: Tatsuru <44866610+Ikkarin@users.noreply.github.com> Date: Tue, 31 Dec 2019 20:13:16 -0300 Subject: [PATCH 119/136] The dumbass forgot NiGHTS mode is also a carry power --- src/p_user.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/p_user.c b/src/p_user.c index 292bad2af..f8d1dbbc1 100644 --- a/src/p_user.c +++ b/src/p_user.c @@ -349,7 +349,7 @@ void P_GiveEmerald(boolean spawnObj) P_SetMobjState(emmo, mobjinfo[MT_GOTEMERALD].meleestate + em); // Make sure we're not being carried before our tracer is changed - if (players[i].powers[pw_carry] != CR_NONE) + if (players[i].powers[pw_carry] == CR_PLAYER) players[i].powers[pw_carry] = CR_NONE; P_SetTarget(&players[i].mo->tracer, emmo); From dda18dd0803b6fa43d8797ba2337b5ba2cd0165c Mon Sep 17 00:00:00 2001 From: Tatsuru <44866610+Ikkarin@users.noreply.github.com> Date: Tue, 31 Dec 2019 20:20:30 -0300 Subject: [PATCH 120/136] Or is it better like this? --- src/p_user.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/p_user.c b/src/p_user.c index f8d1dbbc1..586c8b022 100644 --- a/src/p_user.c +++ b/src/p_user.c @@ -349,7 +349,7 @@ void P_GiveEmerald(boolean spawnObj) P_SetMobjState(emmo, mobjinfo[MT_GOTEMERALD].meleestate + em); // Make sure we're not being carried before our tracer is changed - if (players[i].powers[pw_carry] == CR_PLAYER) + if (players[i].powers[pw_carry] != CR_NIGHTSMODE) players[i].powers[pw_carry] = CR_NONE; P_SetTarget(&players[i].mo->tracer, emmo); From 285a2ec05dc0b65936373bc7eb65ecd14c310e35 Mon Sep 17 00:00:00 2001 From: Jaime Passos Date: Tue, 31 Dec 2019 23:40:17 +0000 Subject: [PATCH 121/136] 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 30bc8af7e87772857a70f47ff86094c4b9f793ee Mon Sep 17 00:00:00 2001 From: Louis-Antoine Date: Wed, 1 Jan 2020 13:29:07 +0100 Subject: [PATCH 122/136] 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 5df1de42b52bbb6145025ae3bdb2ba6c9638275e Mon Sep 17 00:00:00 2001 From: lachwright Date: Wed, 1 Jan 2020 23:49:29 +0800 Subject: [PATCH 123/136] Allow 6-letter character names to be drawn with the thick font --- src/st_stuff.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/st_stuff.c b/src/st_stuff.c index 9c4f0abd5..ea868b5a5 100644 --- a/src/st_stuff.c +++ b/src/st_stuff.c @@ -939,6 +939,8 @@ static void ST_drawLivesArea(void) v_colmap |= (V_HUDTRANS|hudinfo[HUD_LIVES].f|V_PERPLAYER); if (strlen(skins[stplyr->skin].hudname) <= 5) V_DrawRightAlignedString(hudinfo[HUD_LIVES].x+58, hudinfo[HUD_LIVES].y, v_colmap, skins[stplyr->skin].hudname); + else if (V_StringWidth(skins[stplyr->skin].hudname, v_colmap) <= 48) + V_DrawString(hudinfo[HUD_LIVES].x+18, hudinfo[HUD_LIVES].y, v_colmap, skins[stplyr->skin].hudname); else if (V_ThinStringWidth(skins[stplyr->skin].hudname, v_colmap) <= 40) V_DrawRightAlignedThinString(hudinfo[HUD_LIVES].x+58, hudinfo[HUD_LIVES].y, v_colmap, skins[stplyr->skin].hudname); else From 0ab6fe1fd84101ba55d90020da81e14fc9e7627d Mon Sep 17 00:00:00 2001 From: Jaime Passos Date: Wed, 1 Jan 2020 15:17:29 -0300 Subject: [PATCH 124/136] Rename ``seenplayer`` to ``seenfriend`` --- src/lua_hook.h | 2 +- src/lua_hooklib.c | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/lua_hook.h b/src/lua_hook.h index 24e61c20c..023090897 100644 --- a/src/lua_hook.h +++ b/src/lua_hook.h @@ -99,7 +99,7 @@ void LUAh_IntermissionThinker(void); // Hook for Y_Ticker boolean LUAh_TeamSwitch(player_t *player, int newteam, boolean fromspectators, boolean tryingautobalance, boolean tryingscramble); // Hook for team switching in... uh.... UINT8 LUAh_ViewpointSwitch(player_t *player, player_t *newdisplayplayer, boolean forced); // Hook for spy mode #ifdef SEENAMES -boolean LUAh_SeenPlayer(player_t *player, player_t *seenplayer); // Hook for MT_NAMECHECK +boolean LUAh_SeenPlayer(player_t *player, player_t *seenfriend); // Hook for MT_NAMECHECK #endif #endif diff --git a/src/lua_hooklib.c b/src/lua_hooklib.c index fc9d74f08..5faa625b3 100644 --- a/src/lua_hooklib.c +++ b/src/lua_hooklib.c @@ -1457,7 +1457,7 @@ UINT8 LUAh_ViewpointSwitch(player_t *player, player_t *newdisplayplayer, boolean // Hook for MT_NAMECHECK #ifdef SEENAMES -boolean LUAh_SeenPlayer(player_t *player, player_t *seenplayer) +boolean LUAh_SeenPlayer(player_t *player, player_t *seenfriend) { hook_p hookp; boolean hasSeenPlayer = true; @@ -1475,7 +1475,7 @@ boolean LUAh_SeenPlayer(player_t *player, player_t *seenplayer) if (lua_gettop(gL) == 0) { LUA_PushUserdata(gL, player, META_PLAYER); - LUA_PushUserdata(gL, seenplayer, META_PLAYER); + LUA_PushUserdata(gL, seenfriend, META_PLAYER); } lua_pushfstring(gL, FMT_HOOKID, hookp->id); lua_gettable(gL, LUA_REGISTRYINDEX); From d4a2483c3e646c1e7d5db178e22446ed3fd6db70 Mon Sep 17 00:00:00 2001 From: Louis-Antoine Date: Thu, 2 Jan 2020 00:38:43 +0100 Subject: [PATCH 125/136] 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 61a681ed0251b08c6f6b860fcf6dc9d664bc988a Mon Sep 17 00:00:00 2001 From: Louis-Antoine Date: Thu, 2 Jan 2020 00:45:28 +0100 Subject: [PATCH 126/136] 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 bd25e7b4acd8a4989c758f0dc85f0009692805ee Mon Sep 17 00:00:00 2001 From: Louis-Antoine Date: Thu, 2 Jan 2020 00:46:50 +0100 Subject: [PATCH 127/136] 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 f750144c8842c84d930ad98229b07c14ca140ef7 Mon Sep 17 00:00:00 2001 From: Louis-Antoine Date: Thu, 2 Jan 2020 00:47:20 +0100 Subject: [PATCH 128/136] 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 8720bbe04451547f58e158938e72ace3d2dc89a1 Mon Sep 17 00:00:00 2001 From: James R Date: Wed, 1 Jan 2020 15:52:23 -0800 Subject: [PATCH 129/136] 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 1864526f727104c972d1d4d26ff74e9f2940cd97 Mon Sep 17 00:00:00 2001 From: Louis-Antoine Date: Thu, 2 Jan 2020 20:29:51 +0100 Subject: [PATCH 130/136] Revert "Ungrab mouse when watching a record" This reverts commit bd25e7b4acd8a4989c758f0dc85f0009692805ee. --- 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 3762b638c750a81af75129d4e3e60b04fd587462 Mon Sep 17 00:00:00 2001 From: James R Date: Thu, 2 Jan 2020 14:58:09 -0800 Subject: [PATCH 131/136] 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 54b4a53f923a634ebf5e7ce7bce2ea2f68e3644f Mon Sep 17 00:00:00 2001 From: Louis-Antoine Date: Fri, 3 Jan 2020 00:25:58 +0100 Subject: [PATCH 132/136] 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 ff47e36b439389da34d0639e8c3e7e9b850ca2d8 Mon Sep 17 00:00:00 2001 From: Louis-Antoine Date: Fri, 3 Jan 2020 00:40:49 +0100 Subject: [PATCH 133/136] 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 8d328d16c7f690142516f06aeee73d11dd7dddce Mon Sep 17 00:00:00 2001 From: Louis-Antoine Date: Fri, 3 Jan 2020 02:58:23 +0100 Subject: [PATCH 134/136] 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; From 6bca318fa8f5fcd5fef24ef64ba8d03e26603e4a Mon Sep 17 00:00:00 2001 From: MascaraSnake Date: Fri, 3 Jan 2020 21:50:27 +0100 Subject: [PATCH 135/136] Compressing sidedefs can break both special effects and netgame syncing, so let's get rid of it --- src/p_setup.c | 65 --------------------------------------------------- 1 file changed, 65 deletions(-) diff --git a/src/p_setup.c b/src/p_setup.c index dcb2a0ae4..bd1c53104 100644 --- a/src/p_setup.c +++ b/src/p_setup.c @@ -2548,69 +2548,6 @@ static void P_ProcessLinedefsWithSidedefs(void) } } -static void P_CompressSidedefs(void) -{ - side_t *newsides; - size_t numnewsides = 0; - size_t z; - size_t i; - - for (i = 0; i < numsides; i++) - { - size_t j, k; - line_t *ld; - - if (!sides[i].sector) - continue; - - for (k = numlines, ld = lines; k--; ld++) - { - if (ld->sidenum[0] == i) - ld->sidenum[0] = (UINT16)numnewsides; - - if (ld->sidenum[1] == i) - ld->sidenum[1] = (UINT16)numnewsides; - } - - for (j = i + 1; j < numsides; j++) - { - if (!sides[j].sector) - continue; - - if (!memcmp(&sides[i], &sides[j], sizeof(side_t))) - { - // Find the linedefs that belong to this one - for (k = numlines, ld = lines; k--; ld++) - { - if (ld->sidenum[0] == j) - ld->sidenum[0] = (UINT16)numnewsides; - - if (ld->sidenum[1] == j) - ld->sidenum[1] = (UINT16)numnewsides; - } - sides[j].sector = NULL; // Flag for deletion - } - } - numnewsides++; - } - - // We're loading crap into this block anyhow, so no point in zeroing it out. - newsides = Z_Malloc(numnewsides*sizeof(*newsides), PU_LEVEL, NULL); - - // Copy the sides to their new block of memory. - for (i = 0, z = 0; i < numsides; i++) - { - if (sides[i].sector) - M_Memcpy(&newsides[z++], &sides[i], sizeof(side_t)); - } - - CONS_Debug(DBG_SETUP, "P_CompressSidedefs: Old sides is %s, new sides is %s\n", sizeu1(numsides), sizeu1(numnewsides)); - - Z_Free(sides); - sides = newsides; - numsides = numnewsides; -} - // // P_LinkMapData // Builds sector line lists and subsector sector numbers. @@ -2777,8 +2714,6 @@ static boolean P_LoadMapFromFile(void) P_LoadMapLUT(virt); P_ProcessLinedefsWithSidedefs(); - if (M_CheckParm("-compress")) - P_CompressSidedefs(); P_LinkMapData(); P_MakeMapMD5(virt, &mapmd5); From 275f07e05fe53976d45a381453be54e48dfd30fe Mon Sep 17 00:00:00 2001 From: Nev3r Date: Sat, 4 Jan 2020 11:17:54 +0100 Subject: [PATCH 136/136] Provide a fix for "non-sloped" slopes launch/land behavior by checking the normal's components. --- src/p_slopes.c | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/src/p_slopes.c b/src/p_slopes.c index e66d7ed21..2cf2c74ba 100644 --- a/src/p_slopes.c +++ b/src/p_slopes.c @@ -50,10 +50,10 @@ static void ReconfigureViaVertexes (pslope_t *slope, const vector3_t v1, const v // Set some defaults for a non-sloped "slope" if (vec1.z == 0 && vec2.z == 0) { - /// \todo Fix fully flat cases. - slope->zangle = slope->xydirection = 0; slope->zdelta = slope->d.x = slope->d.y = 0; + slope->normal.x = slope->normal.y = 0; + slope->normal.z = FRACUNIT; } else { @@ -653,7 +653,9 @@ void P_ReverseQuantizeMomentumToSlope(vector3_t *momentum, pslope_t *slope) // Handles slope ejection for objects void P_SlopeLaunch(mobj_t *mo) { - if (!(mo->standingslope->flags & SL_NOPHYSICS)) // If there's physics, time for launching. + if (!(mo->standingslope->flags & SL_NOPHYSICS) // If there's physics, time for launching. + && (mo->standingslope->normal.x != 0 + || mo->standingslope->normal.y != 0)) { // Double the pre-rotation Z, then halve the post-rotation Z. This reduces the // vertical launch given from slopes while increasing the horizontal launch @@ -710,8 +712,7 @@ fixed_t P_GetWallTransferMomZ(mobj_t *mo, pslope_t *slope) void P_HandleSlopeLanding(mobj_t *thing, pslope_t *slope) { vector3_t mom; // Ditto. - - if (slope->flags & SL_NOPHYSICS) { // No physics, no need to make anything complicated. + if (slope->flags & SL_NOPHYSICS || (slope->normal.x == 0 && slope->normal.y == 0)) { // No physics, no need to make anything complicated. if (P_MobjFlip(thing)*(thing->momz) < 0) // falling, land on slope { thing->standingslope = slope;