From 2863ede7bf06ed032e12825a07616d1f1b5be9b5 Mon Sep 17 00:00:00 2001 From: Jaime Passos Date: Sun, 8 Sep 2019 18:27:35 -0300 Subject: [PATCH 001/746] initial stuff --- src/android/i_video.c | 5 + src/console.c | 10 +- src/d_main.c | 19 +++- src/d_netcmd.c | 1 + src/djgppdos/vid_vesa.c | 5 + src/dummy/i_video.c | 5 + src/f_finale.c | 138 +++++++++++++------------ src/hardware/hw_cache.c | 32 ++++-- src/hardware/hw_draw.c | 16 +-- src/hardware/hw_main.c | 8 +- src/hardware/hw_md2.c | 2 +- src/hu_stuff.c | 3 + src/i_video.h | 1 + src/lua_hudlib.c | 4 +- src/m_menu.c | 120 ++++++++++++---------- src/p_setup.c | 29 +++--- src/p_setup.h | 3 + src/r_data.c | 6 +- src/r_data.h | 2 + src/r_main.c | 21 ++++ src/r_main.h | 4 + src/r_segs.c | 2 +- src/r_splats.c | 2 +- src/screen.c | 65 +++++++++--- src/screen.h | 4 +- src/sdl/i_video.c | 219 ++++++++++++++++++++++++---------------- src/st_stuff.c | 3 + src/v_video.c | 2 +- src/w_wad.c | 20 +++- src/w_wad.h | 1 + src/win32/win_vid.c | 5 + src/y_inter.c | 36 +++---- src/z_zone.h | 1 + 33 files changed, 507 insertions(+), 287 deletions(-) diff --git a/src/android/i_video.c b/src/android/i_video.c index 2d0151f5e..44e1cbac0 100644 --- a/src/android/i_video.c +++ b/src/android/i_video.c @@ -51,6 +51,11 @@ INT32 VID_SetMode(INT32 modenum) return 0; } +void VID_CheckRenderer(void) +{ + // .............. +} + const char *VID_GetModeName(INT32 modenum) { return "A320x240"; diff --git a/src/console.c b/src/console.c index 09a6cab45..f34958835 100644 --- a/src/console.c +++ b/src/console.c @@ -1288,7 +1288,7 @@ void CONS_Printf(const char *fmt, ...) if (con_startup) { #ifdef _WINDOWS - patch_t *con_backpic = W_CachePatchName("CONSBACK", PU_CACHE); + patch_t *con_backpic = W_CachePatchName("CONSBACK", PU_PATCH); // Jimita: CON_DrawBackpic just called V_DrawScaledPatch V_DrawScaledPatch(0, 0, 0, con_backpic); @@ -1545,7 +1545,7 @@ static void CON_DrawConsole(void) // draw console background if (cons_backpic.value || con_forcepic) { - patch_t *con_backpic = W_CachePatchName("CONSBACK", PU_CACHE); + patch_t *con_backpic = W_CachePatchName("CONSBACK", PU_PATCH); // Jimita: CON_DrawBackpic just called V_DrawScaledPatch V_DrawScaledPatch(0, 0, 0, con_backpic); @@ -1602,6 +1602,12 @@ void CON_Drawer(void) if (!con_started || !graphics_started) return; + if (needpatchrecache) + { + W_FlushCachedPatches(); + HU_LoadGraphics(); + } + if (con_recalc) CON_RecalcSize(); diff --git a/src/d_main.c b/src/d_main.c index eaeae4b10..a51ce0098 100644 --- a/src/d_main.c +++ b/src/d_main.c @@ -211,6 +211,7 @@ INT16 wipetypepost = -1; static void D_Display(void) { + INT32 setrenderstillneeded = setrenderneeded; boolean forcerefresh = false; static boolean wipe = false; INT32 wipedefindex = 0; @@ -221,15 +222,19 @@ static void D_Display(void) if (nodrawers) return; // for comparative timing/profiling + // stop movie if needs to change renderer + if (setrenderneeded && (moviemode != MM_OFF)) + M_StopMovie(); + // check for change of screen size (video mode) - if (setmodeneeded && !wipe) + if ((setmodeneeded || setrenderneeded) && !wipe) SCR_SetMode(); // change video mode - if (vid.recalc) + if (vid.recalc || setrenderstillneeded) SCR_Recalc(); // NOTE! setsizeneeded is set by SCR_Recalc() // change the view size if needed - if (setsizeneeded) + if (setsizeneeded || setrenderstillneeded) { R_ExecuteSetViewSize(); forcerefresh = true; // force background redraw @@ -445,7 +450,7 @@ static void D_Display(void) py = 4; else py = viewwindowy + 4; - patch = W_CachePatchName("M_PAUSE", PU_CACHE); + patch = W_CachePatchName("M_PAUSE", PU_PATCH); V_DrawScaledPatch(viewwindowx + (BASEVIDWIDTH - SHORT(patch->width))/2, py, 0, patch); #else INT32 y = ((automapactive) ? (32) : (BASEVIDHEIGHT/2)); @@ -520,6 +525,12 @@ static void D_Display(void) I_FinishUpdate(); // page flip or blit buffer } + + if (needpatchrecache) + R_ReloadHUDGraphics(); + + needpatchflush = false; + needpatchrecache = false; } // ========================================================================= diff --git a/src/d_netcmd.c b/src/d_netcmd.c index 590543f00..c277e23fb 100644 --- a/src/d_netcmd.c +++ b/src/d_netcmd.c @@ -812,6 +812,7 @@ void D_RegisterClientCommands(void) // screen.c CV_RegisterVar(&cv_fullscreen); CV_RegisterVar(&cv_renderview); + CV_RegisterVar(&cv_renderer); CV_RegisterVar(&cv_scr_depth); CV_RegisterVar(&cv_scr_width); CV_RegisterVar(&cv_scr_height); diff --git a/src/djgppdos/vid_vesa.c b/src/djgppdos/vid_vesa.c index ec7b8b886..c8ce7dae5 100644 --- a/src/djgppdos/vid_vesa.c +++ b/src/djgppdos/vid_vesa.c @@ -378,6 +378,11 @@ INT32 VID_SetMode (INT32 modenum) //, UINT8 *palette) return 1; } +void VID_CheckRenderer(void) +{ + // .............. +} + // converts a segm:offs 32bit pair to a 32bit flat ptr diff --git a/src/dummy/i_video.c b/src/dummy/i_video.c index e167e833f..b8f40bed3 100644 --- a/src/dummy/i_video.c +++ b/src/dummy/i_video.c @@ -39,6 +39,11 @@ INT32 VID_SetMode(INT32 modenum) return 0; } +void VID_CheckRenderer(void) +{ + // .............. +} + const char *VID_GetModeName(INT32 modenum) { (void)modenum; diff --git a/src/f_finale.c b/src/f_finale.c index da042abeb..e302d24ba 100644 --- a/src/f_finale.c +++ b/src/f_finale.c @@ -424,16 +424,16 @@ static void F_IntroDrawScene(void) // DRAW A FULL PIC INSTEAD OF FLAT! if (intro_scenenum == 0); else if (intro_scenenum == 1) - background = W_CachePatchName("INTRO1", PU_CACHE); + background = W_CachePatchName("INTRO1", PU_PATCH); else if (intro_scenenum == 2) { - background = W_CachePatchName("INTRO2", PU_CACHE); + background = W_CachePatchName("INTRO2", PU_PATCH); highres = true; } else if (intro_scenenum == 3) - background = W_CachePatchName("INTRO3", PU_CACHE); + background = W_CachePatchName("INTRO3", PU_PATCH); else if (intro_scenenum == 4) - background = W_CachePatchName("INTRO4", PU_CACHE); + background = W_CachePatchName("INTRO4", PU_PATCH); else if (intro_scenenum == 5) { if (intro_curtime >= 5*TICRATE) @@ -708,8 +708,8 @@ static void F_IntroDrawScene(void) y += (30*(FRACUNIT-scale)); } - rockpat = W_CachePatchName(va("ROID00%.2d", 34 - (worktics % 35)), PU_LEVEL); - glow = W_CachePatchName(va("ENDGLOW%.1d", 2+(worktics & 1)), PU_LEVEL); + rockpat = W_CachePatchName(va("ROID00%.2d", 34 - (worktics % 35)), PU_PATCH); + glow = W_CachePatchName(va("ENDGLOW%.1d", 2+(worktics & 1)), PU_PATCH); if (worktics >= 5) trans = (worktics-5)>>1; @@ -1350,14 +1350,14 @@ void F_GameEvaluationDrawer(void) if (goodending) { - rockpat = W_CachePatchName(va("ROID00%.2d", 34 - (finalecount % 35)), PU_LEVEL); - glow = W_CachePatchName(va("ENDGLOW%.1d", 2+(finalecount & 1)), PU_LEVEL); + rockpat = W_CachePatchName(va("ROID00%.2d", 34 - (finalecount % 35)), PU_PATCH); + glow = W_CachePatchName(va("ENDGLOW%.1d", 2+(finalecount & 1)), PU_PATCH); x -= FRACUNIT; } else { rockpat = W_CachePatchName("ROID0000", PU_LEVEL); - glow = W_CachePatchName(va("ENDGLOW%.1d", (finalecount & 1)), PU_LEVEL); + glow = W_CachePatchName(va("ENDGLOW%.1d", (finalecount & 1)), PU_PATCH); } if (finalecount >= 5) @@ -1389,20 +1389,20 @@ void F_GameEvaluationDrawer(void) // if j == 0 - alternate between 0 and 1 // 1 - 1 and 2 // 2 - 2 and not rendered - V_DrawFixedPatch(x+sparkloffs[j-1][0], y+sparkloffs[j-1][1], FRACUNIT, 0, W_CachePatchName(va("ENDSPKL%.1d", (j - ((sparklloop & 1) ? 0 : 1))), PU_LEVEL), R_GetTranslationColormap(TC_DEFAULT, SKINCOLOR_AQUA, GTC_CACHE)); + V_DrawFixedPatch(x+sparkloffs[j-1][0], y+sparkloffs[j-1][1], FRACUNIT, 0, W_CachePatchName(va("ENDSPKL%.1d", (j - ((sparklloop & 1) ? 0 : 1))), PU_PATCH), R_GetTranslationColormap(TC_DEFAULT, SKINCOLOR_AQUA, GTC_CACHE)); } j--; } } else { - patch_t *eggrock = W_CachePatchName("ENDEGRK5", PU_LEVEL); + patch_t *eggrock = W_CachePatchName("ENDEGRK5", PU_PATCH); V_DrawFixedPatch(x, y, scale, 0, eggrock, colormap[0]); if (trans < 10) V_DrawFixedPatch(x, y, scale, trans<spriteframes[2]; - endfwrk[0] = W_CachePatchNum(sprframe->lumppat[0], PU_LEVEL); + endfwrk[0] = W_CachePatchNum(sprframe->lumppat[0], PU_PATCH); sprframe = &sprdef->spriteframes[3]; - endfwrk[1] = W_CachePatchNum(sprframe->lumppat[0], PU_LEVEL); + endfwrk[1] = W_CachePatchNum(sprframe->lumppat[0], PU_PATCH); sprframe = &sprdef->spriteframes[4]; - endfwrk[2] = W_CachePatchNum(sprframe->lumppat[0], PU_LEVEL); + endfwrk[2] = W_CachePatchNum(sprframe->lumppat[0], PU_PATCH); } else // eh, yknow what? too lazy to put MISSINGs here. eggman wins if you don't give your character an ending firework display. { - endfwrk[0] = W_CachePatchName("ENDFWRK0", PU_LEVEL); - endfwrk[1] = W_CachePatchName("ENDFWRK1", PU_LEVEL); - endfwrk[2] = W_CachePatchName("ENDFWRK2", PU_LEVEL); + endfwrk[0] = W_CachePatchName("ENDFWRK0", PU_PATCH); + endfwrk[1] = W_CachePatchName("ENDFWRK1", PU_PATCH); + endfwrk[2] = W_CachePatchName("ENDFWRK2", PU_PATCH); } - endbrdr[0] = W_CachePatchName("ENDBRDR2", PU_LEVEL); + endbrdr[0] = W_CachePatchName("ENDBRDR2", PU_PATCH); } else { // eggman, skin nonspecific - endfwrk[0] = W_CachePatchName("ENDFWRK0", PU_LEVEL); - endfwrk[1] = W_CachePatchName("ENDFWRK1", PU_LEVEL); - endfwrk[2] = W_CachePatchName("ENDFWRK2", PU_LEVEL); + endfwrk[0] = W_CachePatchName("ENDFWRK0", PU_PATCH); + endfwrk[1] = W_CachePatchName("ENDFWRK1", PU_PATCH); + endfwrk[2] = W_CachePatchName("ENDFWRK2", PU_PATCH); endbrdr[0] = W_CachePatchName("ENDBRDR0", PU_LEVEL); } @@ -1626,13 +1626,13 @@ void F_EndingTicker(void) if (goodending && finalecount == INFLECTIONPOINT) // time to swap some assets { - endegrk[0] = W_CachePatchName("ENDEGRK2", PU_LEVEL); - endegrk[1] = W_CachePatchName("ENDEGRK3", PU_LEVEL); + endegrk[0] = W_CachePatchName("ENDEGRK2", PU_PATCH); + endegrk[1] = W_CachePatchName("ENDEGRK3", PU_PATCH); - endglow[0] = W_CachePatchName("ENDGLOW2", PU_LEVEL); - endglow[1] = W_CachePatchName("ENDGLOW3", PU_LEVEL); + endglow[0] = W_CachePatchName("ENDGLOW2", PU_PATCH); + endglow[1] = W_CachePatchName("ENDGLOW3", PU_PATCH); - endxpld[0] = W_CachePatchName("ENDEGRK4", PU_LEVEL); + endxpld[0] = W_CachePatchName("ENDEGRK4", PU_PATCH); } if (++sparklloop == SPARKLLOOPTIME) // time to roll the randomisation again @@ -1653,9 +1653,9 @@ void F_EndingDrawer(void) patch_t *rockpat; if (!goodending || finalecount < INFLECTIONPOINT) - rockpat = W_CachePatchName("ROID0000", PU_LEVEL); + rockpat = W_CachePatchName("ROID0000", PU_PATCH); else - rockpat = W_CachePatchName(va("ROID00%.2d", 34 - ((finalecount - INFLECTIONPOINT) % 35)), PU_LEVEL); + rockpat = W_CachePatchName(va("ROID00%.2d", 34 - ((finalecount - INFLECTIONPOINT) % 35)), PU_PATCH); V_DrawFill(0, 0, BASEVIDWIDTH, BASEVIDHEIGHT, 31); @@ -2171,6 +2171,25 @@ void F_SkyScroll(INT32 scrollxspeed, INT32 scrollyspeed, const char *patchname) W_UnlockCachedPatch(pat); } +static void F_CacheTitleScreen(void) +{ + ttbanner = W_CachePatchName("TTBANNER", PU_PATCH); + ttwing = W_CachePatchName("TTWING", PU_PATCH); + ttsonic = W_CachePatchName("TTSONIC", PU_PATCH); + ttswave1 = W_CachePatchName("TTSWAVE1", PU_PATCH); + ttswave2 = W_CachePatchName("TTSWAVE2", PU_PATCH); + ttswip1 = W_CachePatchName("TTSWIP1", PU_PATCH); + ttsprep1 = W_CachePatchName("TTSPREP1", PU_PATCH); + ttsprep2 = W_CachePatchName("TTSPREP2", PU_PATCH); + ttspop1 = W_CachePatchName("TTSPOP1", PU_PATCH); + ttspop2 = W_CachePatchName("TTSPOP2", PU_PATCH); + ttspop3 = W_CachePatchName("TTSPOP3", PU_PATCH); + ttspop4 = W_CachePatchName("TTSPOP4", PU_PATCH); + ttspop5 = W_CachePatchName("TTSPOP5", PU_PATCH); + ttspop6 = W_CachePatchName("TTSPOP6", PU_PATCH); + ttspop7 = W_CachePatchName("TTSPOP7", PU_PATCH); +} + void F_StartTitleScreen(void) { if (menupres[MN_MAIN].musname[0]) @@ -2255,21 +2274,7 @@ void F_StartTitleScreen(void) demoDelayLeft = demoDelayTime; demoIdleLeft = demoIdleTime; - ttbanner = W_CachePatchName("TTBANNER", PU_LEVEL); - ttwing = W_CachePatchName("TTWING", PU_LEVEL); - ttsonic = W_CachePatchName("TTSONIC", PU_LEVEL); - ttswave1 = W_CachePatchName("TTSWAVE1", PU_LEVEL); - ttswave2 = W_CachePatchName("TTSWAVE2", PU_LEVEL); - ttswip1 = W_CachePatchName("TTSWIP1", PU_LEVEL); - ttsprep1 = W_CachePatchName("TTSPREP1", PU_LEVEL); - ttsprep2 = W_CachePatchName("TTSPREP2", PU_LEVEL); - ttspop1 = W_CachePatchName("TTSPOP1", PU_LEVEL); - ttspop2 = W_CachePatchName("TTSPOP2", PU_LEVEL); - ttspop3 = W_CachePatchName("TTSPOP3", PU_LEVEL); - ttspop4 = W_CachePatchName("TTSPOP4", PU_LEVEL); - ttspop5 = W_CachePatchName("TTSPOP5", PU_LEVEL); - ttspop6 = W_CachePatchName("TTSPOP6", PU_LEVEL); - ttspop7 = W_CachePatchName("TTSPOP7", PU_LEVEL); + F_CacheTitleScreen(); } // (no longer) De-Demo'd Title Screen @@ -2280,6 +2285,9 @@ void F_TitleScreenDrawer(void) if (modeattacking) return; // We likely came here from retrying. Don't do a damn thing. + if (needpatchrecache) + F_CacheTitleScreen(); + // Draw that sky! if (curbgcolor >= 0) V_DrawFill(0, 0, BASEVIDWIDTH, BASEVIDHEIGHT, curbgcolor); diff --git a/src/hardware/hw_cache.c b/src/hardware/hw_cache.c index 6bc2c712e..258e3bb0d 100644 --- a/src/hardware/hw_cache.c +++ b/src/hardware/hw_cache.c @@ -754,16 +754,14 @@ void HWR_MakePatch (const patch_t *patch, GLPatch_t *grPatch, GLMipmap_t *grMipm // CACHING HANDLING // ================================================= -static size_t gr_numtextures; +static size_t gr_numtextures = 0; static GLTexture_t *gr_textures; // for ALL Doom textures void HWR_InitTextureCache(void) { - gr_numtextures = 0; gr_textures = NULL; } - // Callback function for HWR_FreeTextureCache. static void FreeMipmapColormap(INT32 patchnum, void *patch) { @@ -792,15 +790,17 @@ void HWR_FreeTextureCache(void) // Alam: free the Z_Blocks before freeing it's users // free all skin after each level: must be done after pfnClearMipMapCache! - for (i = 0; i < numwadfiles; i++) - M_AATreeIterate(wadfiles[i]->hwrcache, FreeMipmapColormap); + // temp fix, idk why this crashes + // is it because the colormaps were already freed anyway? + if (!needpatchrecache) + for (i = 0; i < numwadfiles; i++) + M_AATreeIterate(wadfiles[i]->hwrcache, FreeMipmapColormap); // now the heap don't have any 'user' pointing to our // texturecache info, we can free it if (gr_textures) free(gr_textures); gr_textures = NULL; - gr_numtextures = 0; } void HWR_PrepLevelCache(size_t pnumtextures) @@ -847,8 +847,11 @@ GLTexture_t *HWR_GetTexture(INT32 tex) GLTexture_t *grtex; #ifdef PARANOIA if ((unsigned)tex >= gr_numtextures) - I_Error(" HWR_GetTexture: tex >= numtextures\n"); + I_Error("HWR_GetTexture: tex >= numtextures\n"); #endif + if (needpatchrecache && (!gr_textures)) + HWR_PrepLevelCache(gr_numtextures); + grtex = &gr_textures[tex]; if (!grtex->mipmap.grInfo.data && !grtex->mipmap.downloaded) @@ -914,6 +917,9 @@ void HWR_GetFlat(lumpnum_t flatlumpnum) { GLMipmap_t *grmip; + if (needpatchflush) + W_FlushCachedPatches(); + grmip = &HWR_GetCachedGLPatch(flatlumpnum)->mipmap; if (!grmip->downloaded && !grmip->grInfo.data) @@ -950,6 +956,9 @@ static void HWR_LoadMappedPatch(GLMipmap_t *grmip, GLPatch_t *gpatch) // -----------------+ void HWR_GetPatch(GLPatch_t *gpatch) { + if (needpatchflush) + W_FlushCachedPatches(); + // is it in hardware cache if (!gpatch->mipmap.downloaded && !gpatch->mipmap.grInfo.data) { @@ -977,6 +986,9 @@ void HWR_GetMappedPatch(GLPatch_t *gpatch, const UINT8 *colormap) { GLMipmap_t *grmip, *newmip; + if (needpatchflush) + W_FlushCachedPatches(); + if (colormap == colormaps || colormap == NULL) { // Load the default (green) color in doom cache (temporary?) AND hardware cache @@ -1102,6 +1114,9 @@ GLPatch_t *HWR_GetPic(lumpnum_t lumpnum) { GLPatch_t *grpatch; + if (needpatchflush) + W_FlushCachedPatches(); + grpatch = HWR_GetCachedGLPatch(lumpnum); if (!grpatch->mipmap.downloaded && !grpatch->mipmap.grInfo.data) @@ -1299,6 +1314,9 @@ void HWR_GetFadeMask(lumpnum_t fademasklumpnum) { GLMipmap_t *grmip; + if (needpatchflush) + W_FlushCachedPatches(); + grmip = &HWR_GetCachedGLPatch(fademasklumpnum)->mipmap; if (!grmip->downloaded && !grmip->grInfo.data) diff --git a/src/hardware/hw_draw.c b/src/hardware/hw_draw.c index d9e688c0a..ea3183aa1 100644 --- a/src/hardware/hw_draw.c +++ b/src/hardware/hw_draw.c @@ -990,7 +990,7 @@ void HWR_DrawViewBorder(INT32 clearlines) // top edge if (clearlines > basewindowy - 8) { - patch = W_CachePatchNum(viewborderlump[BRDR_T], PU_CACHE); + patch = W_CachePatchNum(viewborderlump[BRDR_T], PU_PATCH); for (x = 0; x < baseviewwidth; x += 8) HWR_DrawPatch(patch, basewindowx + x, basewindowy - 8, 0); @@ -999,7 +999,7 @@ void HWR_DrawViewBorder(INT32 clearlines) // bottom edge if (clearlines > basewindowy + baseviewheight) { - patch = W_CachePatchNum(viewborderlump[BRDR_B], PU_CACHE); + patch = W_CachePatchNum(viewborderlump[BRDR_B], PU_PATCH); for (x = 0; x < baseviewwidth; x += 8) HWR_DrawPatch(patch, basewindowx + x, basewindowy + baseviewheight, 0); @@ -1008,7 +1008,7 @@ void HWR_DrawViewBorder(INT32 clearlines) // left edge if (clearlines > basewindowy) { - patch = W_CachePatchNum(viewborderlump[BRDR_L], PU_CACHE); + patch = W_CachePatchNum(viewborderlump[BRDR_L], PU_PATCH); for (y = 0; y < baseviewheight && basewindowy + y < clearlines; y += 8) { @@ -1020,7 +1020,7 @@ void HWR_DrawViewBorder(INT32 clearlines) // right edge if (clearlines > basewindowy) { - patch = W_CachePatchNum(viewborderlump[BRDR_R], PU_CACHE); + patch = W_CachePatchNum(viewborderlump[BRDR_R], PU_PATCH); for (y = 0; y < baseviewheight && basewindowy+y < clearlines; y += 8) { @@ -1032,22 +1032,22 @@ void HWR_DrawViewBorder(INT32 clearlines) // Draw beveled corners. if (clearlines > basewindowy - 8) HWR_DrawPatch(W_CachePatchNum(viewborderlump[BRDR_TL], - PU_CACHE), + PU_PATCH), basewindowx - 8, basewindowy - 8, 0); if (clearlines > basewindowy - 8) HWR_DrawPatch(W_CachePatchNum(viewborderlump[BRDR_TR], - PU_CACHE), + PU_PATCH), basewindowx + baseviewwidth, basewindowy - 8, 0); if (clearlines > basewindowy+baseviewheight) HWR_DrawPatch(W_CachePatchNum(viewborderlump[BRDR_BL], - PU_CACHE), + PU_PATCH), basewindowx - 8, basewindowy + baseviewheight, 0); if (clearlines > basewindowy + baseviewheight) HWR_DrawPatch(W_CachePatchNum(viewborderlump[BRDR_BR], - PU_CACHE), + PU_PATCH), basewindowx + baseviewwidth, basewindowy + baseviewheight, 0); } diff --git a/src/hardware/hw_main.c b/src/hardware/hw_main.c index c600800fd..ae20ee3ec 100644 --- a/src/hardware/hw_main.c +++ b/src/hardware/hw_main.c @@ -866,7 +866,7 @@ static void HWR_DrawSegsSplats(FSurfaceInfo * pSurf) if (!M_PointInBox(segbbox,splat->v1.x,splat->v1.y) && !M_PointInBox(segbbox,splat->v2.x,splat->v2.y)) continue; - gpatch = W_CachePatchNum(splat->patch, PU_CACHE); + gpatch = W_CachePatchNum(splat->patch, PU_PATCH); HWR_GetPatch(gpatch); wallVerts[0].x = wallVerts[3].x = FIXED_TO_FLOAT(splat->v1.x); @@ -4332,7 +4332,7 @@ static void HWR_SplitSprite(gr_vissprite_t *spr) if (hires) this_scale = this_scale * FIXED_TO_FLOAT(((skin_t *)spr->mobj->skin)->highresscale); - gpatch = W_CachePatchNum(spr->patchlumpnum, PU_CACHE); + gpatch = W_CachePatchNum(spr->patchlumpnum, PU_PATCH); // cache the patch in the graphics card memory //12/12/99: Hurdler: same comment as above (for md2) @@ -4688,7 +4688,7 @@ static void HWR_DrawSprite(gr_vissprite_t *spr) // sure to do it the right way. So actually, we keep normal sprite // in memory and we add the md2 model if it exists for that sprite - gpatch = W_CachePatchNum(spr->patchlumpnum, PU_CACHE); + gpatch = W_CachePatchNum(spr->patchlumpnum, PU_PATCH); #ifdef ALAM_LIGHTING if (!(spr->mobj->flags2 & MF2_DEBRIS) && (spr->mobj->sprite != SPR_PLAY || @@ -4833,7 +4833,7 @@ static inline void HWR_DrawPrecipitationSprite(gr_vissprite_t *spr) return; // cache sprite graphics - gpatch = W_CachePatchNum(spr->patchlumpnum, PU_CACHE); + gpatch = W_CachePatchNum(spr->patchlumpnum, PU_PATCH); // create the sprite billboard // diff --git a/src/hardware/hw_md2.c b/src/hardware/hw_md2.c index d4728315a..7f43f858a 100644 --- a/src/hardware/hw_md2.c +++ b/src/hardware/hw_md2.c @@ -1401,7 +1401,7 @@ void HWR_DrawMD2(gr_vissprite_t *spr) else { // Sprite - gpatch = W_CachePatchNum(spr->patchlumpnum, PU_CACHE); + gpatch = W_CachePatchNum(spr->patchlumpnum, PU_PATCH); HWR_GetMappedPatch(gpatch, spr->colormap); } diff --git a/src/hu_stuff.c b/src/hu_stuff.c index 3bc643c3c..7270cb986 100644 --- a/src/hu_stuff.c +++ b/src/hu_stuff.c @@ -2087,6 +2087,9 @@ static void HU_DrawDemoInfo(void) // void HU_Drawer(void) { + if (needpatchrecache) + R_ReloadHUDGraphics(); + #ifndef NONET // draw chat string plus cursor if (chat_on) diff --git a/src/i_video.h b/src/i_video.h index 4bb2c5829..a62f3ff64 100644 --- a/src/i_video.h +++ b/src/i_video.h @@ -84,6 +84,7 @@ INT32 VID_GetModeForSize(INT32 w, INT32 h); \return currect video mode */ INT32 VID_SetMode(INT32 modenum); +void VID_CheckRenderer(void); /** \brief The VID_GetModeName function diff --git a/src/lua_hudlib.c b/src/lua_hudlib.c index 8c1134bca..560b73819 100644 --- a/src/lua_hudlib.c +++ b/src/lua_hudlib.c @@ -407,7 +407,7 @@ static int libd_getSpritePatch(lua_State *L) return 0; // push both the patch and it's "flip" value - LUA_PushUserdata(L, W_CachePatchNum(sprframe->lumppat[angle], PU_STATIC), META_PATCH); + LUA_PushUserdata(L, W_CachePatchNum(sprframe->lumppat[angle], PU_PATCH), META_PATCH); lua_pushboolean(L, (sprframe->flip & (1<lumppat[angle], PU_STATIC), META_PATCH); + LUA_PushUserdata(L, W_CachePatchNum(sprframe->lumppat[angle], PU_PATCH), META_PATCH); lua_pushboolean(L, (sprframe->flip & (1<width) - SHORT(p->leftoffset); for (i = 0; i < 16; i++) { - V_DrawScaledPatch(xx, y, V_WRAPX, W_CachePatchNum(centerlump[i & 1], PU_CACHE)); + V_DrawScaledPatch(xx, y, V_WRAPX, W_CachePatchNum(centerlump[i & 1], PU_PATCH)); xx += 8; } - V_DrawScaledPatch(xx, y, 0, W_CachePatchNum(rightlump, PU_CACHE)); + V_DrawScaledPatch(xx, y, 0, W_CachePatchNum(rightlump, PU_PATCH)); xx = (cv->value - cv->PossibleValue[0].value) * (15*8) / (cv->PossibleValue[1].value - cv->PossibleValue[0].value); - V_DrawScaledPatch((x + 8) + xx, y, 0, W_CachePatchNum(cursorlump, PU_CACHE)); + V_DrawScaledPatch((x + 8) + xx, y, 0, W_CachePatchNum(cursorlump, PU_PATCH)); } // A smaller 'Thermo', with range given as percents (0-100) @@ -3678,15 +3680,15 @@ void M_DrawTextBox(INT32 x, INT32 y, INT32 width, INT32 boxlines) // draw left side cx = x; cy = y; - V_DrawScaledPatch(cx, cy, 0, W_CachePatchNum(viewborderlump[BRDR_TL], PU_CACHE)); + V_DrawScaledPatch(cx, cy, 0, W_CachePatchNum(viewborderlump[BRDR_TL], PU_PATCH)); cy += boff; - p = W_CachePatchNum(viewborderlump[BRDR_L], PU_CACHE); + p = W_CachePatchNum(viewborderlump[BRDR_L], PU_PATCH); for (n = 0; n < boxlines; n++) { V_DrawScaledPatch(cx, cy, V_WRAPY, p); cy += step; } - V_DrawScaledPatch(cx, cy, 0, W_CachePatchNum(viewborderlump[BRDR_BL], PU_CACHE)); + V_DrawScaledPatch(cx, cy, 0, W_CachePatchNum(viewborderlump[BRDR_BL], PU_PATCH)); // draw middle V_DrawFlatFill(x + boff, y + boff, width*step, boxlines*step, st_borderpatchnum); @@ -3695,23 +3697,23 @@ void M_DrawTextBox(INT32 x, INT32 y, INT32 width, INT32 boxlines) cy = y; while (width > 0) { - V_DrawScaledPatch(cx, cy, V_WRAPX, W_CachePatchNum(viewborderlump[BRDR_T], PU_CACHE)); - V_DrawScaledPatch(cx, y + boff + boxlines*step, V_WRAPX, W_CachePatchNum(viewborderlump[BRDR_B], PU_CACHE)); + V_DrawScaledPatch(cx, cy, V_WRAPX, W_CachePatchNum(viewborderlump[BRDR_T], PU_PATCH)); + V_DrawScaledPatch(cx, y + boff + boxlines*step, V_WRAPX, W_CachePatchNum(viewborderlump[BRDR_B], PU_PATCH)); width--; cx += step; } // draw right side cy = y; - V_DrawScaledPatch(cx, cy, 0, W_CachePatchNum(viewborderlump[BRDR_TR], PU_CACHE)); + V_DrawScaledPatch(cx, cy, 0, W_CachePatchNum(viewborderlump[BRDR_TR], PU_PATCH)); cy += boff; - p = W_CachePatchNum(viewborderlump[BRDR_R], PU_CACHE); + p = W_CachePatchNum(viewborderlump[BRDR_R], PU_PATCH); for (n = 0; n < boxlines; n++) { V_DrawScaledPatch(cx, cy, V_WRAPY, p); cy += step; } - V_DrawScaledPatch(cx, cy, 0, W_CachePatchNum(viewborderlump[BRDR_BR], PU_CACHE)); + V_DrawScaledPatch(cx, cy, 0, W_CachePatchNum(viewborderlump[BRDR_BR], PU_PATCH)); */ } @@ -4781,13 +4783,13 @@ static boolean M_PrepareLevelPlatter(INT32 gt, boolean nextmappick) W_UnlockCachedPatch(levselp[1][2]); } - levselp[0][0] = W_CachePatchName("SLCT1LVL", PU_STATIC); - levselp[0][1] = W_CachePatchName("SLCT2LVL", PU_STATIC); - levselp[0][2] = W_CachePatchName("BLANKLVL", PU_STATIC); + levselp[0][0] = W_CachePatchName("SLCT1LVL", PU_PATCH); + levselp[0][1] = W_CachePatchName("SLCT2LVL", PU_PATCH); + levselp[0][2] = W_CachePatchName("BLANKLVL", PU_PATCH); - levselp[1][0] = W_CachePatchName("SLCT1LVW", PU_STATIC); - levselp[1][1] = W_CachePatchName("SLCT2LVW", PU_STATIC); - levselp[1][2] = W_CachePatchName("BLANKLVW", PU_STATIC); + levselp[1][0] = W_CachePatchName("SLCT1LVW", PU_PATCH); + levselp[1][1] = W_CachePatchName("SLCT2LVW", PU_PATCH); + levselp[1][2] = W_CachePatchName("BLANKLVW", PU_PATCH); return true; } @@ -5435,6 +5437,27 @@ static void M_AddonsOptions(INT32 choice) #define LOCATIONSTRING1 "Visit \x83SRB2.ORG/MODS\x80 to get & make add-ons!" //#define LOCATIONSTRING2 "Visit \x88SRB2.ORG/MODS\x80 to get & make add-ons!" +static void M_LoadAddonsPatches(void) +{ + addonsp[EXT_FOLDER] = W_CachePatchName("M_FFLDR", PU_PATCH); + addonsp[EXT_UP] = W_CachePatchName("M_FBACK", PU_PATCH); + addonsp[EXT_NORESULTS] = W_CachePatchName("M_FNOPE", PU_PATCH); + addonsp[EXT_TXT] = W_CachePatchName("M_FTXT", PU_PATCH); + addonsp[EXT_CFG] = W_CachePatchName("M_FCFG", PU_PATCH); + addonsp[EXT_WAD] = W_CachePatchName("M_FWAD", PU_PATCH); +#ifdef USE_KART + addonsp[EXT_KART] = W_CachePatchName("M_FKART", PU_PATCH); +#endif + addonsp[EXT_PK3] = W_CachePatchName("M_FPK3", PU_PATCH); + addonsp[EXT_SOC] = W_CachePatchName("M_FSOC", PU_PATCH); + addonsp[EXT_LUA] = W_CachePatchName("M_FLUA", PU_PATCH); + addonsp[NUM_EXT] = W_CachePatchName("M_FUNKN", PU_PATCH); + addonsp[NUM_EXT+1] = W_CachePatchName("M_FSEL", PU_PATCH); + addonsp[NUM_EXT+2] = W_CachePatchName("M_FLOAD", PU_PATCH); + addonsp[NUM_EXT+3] = W_CachePatchName("M_FSRCH", PU_PATCH); + addonsp[NUM_EXT+4] = W_CachePatchName("M_FSAVE", PU_PATCH); +} + static void M_Addons(INT32 choice) { const char *pathname = "."; @@ -5485,23 +5508,7 @@ static void M_Addons(INT32 choice) W_UnlockCachedPatch(addonsp[i]); } - addonsp[EXT_FOLDER] = W_CachePatchName("M_FFLDR", PU_STATIC); - addonsp[EXT_UP] = W_CachePatchName("M_FBACK", PU_STATIC); - addonsp[EXT_NORESULTS] = W_CachePatchName("M_FNOPE", PU_STATIC); - addonsp[EXT_TXT] = W_CachePatchName("M_FTXT", PU_STATIC); - addonsp[EXT_CFG] = W_CachePatchName("M_FCFG", PU_STATIC); - addonsp[EXT_WAD] = W_CachePatchName("M_FWAD", PU_STATIC); -#ifdef USE_KART - addonsp[EXT_KART] = W_CachePatchName("M_FKART", PU_STATIC); -#endif - addonsp[EXT_PK3] = W_CachePatchName("M_FPK3", PU_STATIC); - addonsp[EXT_SOC] = W_CachePatchName("M_FSOC", PU_STATIC); - addonsp[EXT_LUA] = W_CachePatchName("M_FLUA", PU_STATIC); - addonsp[NUM_EXT] = W_CachePatchName("M_FUNKN", PU_STATIC); - addonsp[NUM_EXT+1] = W_CachePatchName("M_FSEL", PU_STATIC); - addonsp[NUM_EXT+2] = W_CachePatchName("M_FLOAD", PU_STATIC); - addonsp[NUM_EXT+3] = W_CachePatchName("M_FSRCH", PU_STATIC); - addonsp[NUM_EXT+4] = W_CachePatchName("M_FSAVE", PU_STATIC); + M_LoadAddonsPatches(); MISC_AddonsDef.prevMenu = currentMenu; M_SetupNextMenu(&MISC_AddonsDef); @@ -5640,6 +5647,9 @@ static void M_DrawAddons(void) return; } + if (needpatchrecache) + M_LoadAddonsPatches(); + if (Playing()) V_DrawCenteredString(BASEVIDWIDTH/2, 5, warningflags, "Adding files mid-game may cause problems."); else @@ -7015,7 +7025,7 @@ static void M_DrawLoadGameData(void) { lumpnum_t lumpnum = W_CheckNumForName(va("%sP", G_BuildMapName((savegameinfo[savetodraw].gamemap) & 8191))); if (lumpnum != LUMPERROR) - patch = W_CachePatchNum(lumpnum, PU_CACHE); + patch = W_CachePatchNum(lumpnum, PU_PATCH); else patch = savselp[5]; } @@ -7071,7 +7081,7 @@ static void M_DrawLoadGameData(void) goto skipbot; colormap = R_GetTranslationColormap(savegameinfo[savetodraw].botskin, charbotskin->prefcolor, 0); sprframe = &sprdef->spriteframes[0]; - patch = W_CachePatchNum(sprframe->lumppat[0], PU_CACHE); + patch = W_CachePatchNum(sprframe->lumppat[0], PU_PATCH); V_DrawFixedPatch( tempx + (18<numframes) goto skipsign; sprframe = &sprdef->spriteframes[0]; - patch = W_CachePatchNum(sprframe->lumppat[0], PU_CACHE); + patch = W_CachePatchNum(sprframe->lumppat[0], PU_PATCH); if ((calc = SHORT(patch->topoffset) - 42) > 0) tempy += ((4+calc)<numframes) goto skiplife; sprframe = &sprdef->spriteframes[0]; - patch = W_CachePatchNum(sprframe->lumppat[0], PU_CACHE); + patch = W_CachePatchNum(sprframe->lumppat[0], PU_PATCH); V_DrawFixedPatch( (tempx + 4)<spriteframes[1]; - description[i].pic = W_CachePatchNum(sprframe->lumppat[0], PU_CACHE); + description[i].pic = W_CachePatchNum(sprframe->lumppat[0], PU_PATCH); } else - description[i].pic = W_CachePatchName("MISSING", PU_CACHE); + description[i].pic = W_CachePatchName("MISSING", PU_PATCH); } else - description[i].pic = W_CachePatchName(description[i].picname, PU_CACHE); + description[i].pic = W_CachePatchName(description[i].picname, PU_PATCH); } // else -- Technically, character select icons without corresponding skins get bundled away behind this too. Sucks to be them. Z_Free(name); @@ -8044,7 +8054,7 @@ static void M_DrawLevelStats(void) V_DrawString(20, 56, V_GREENMAP, "(complete)"); V_DrawString(36, 64, 0, va("x %d/%d", M_CountEmblems(), numemblems+numextraemblems)); - V_DrawSmallScaledPatch(20, 64, 0, W_CachePatchName("EMBLICON", PU_STATIC)); + V_DrawSmallScaledPatch(20, 64, 0, W_CachePatchName("EMBLICON", PU_PATCH)); sprintf(beststr, "%u", bestscore); V_DrawString(BASEVIDWIDTH/2, 48, V_YELLOWMAP, "SCORE:"); @@ -9481,7 +9491,7 @@ static void M_DrawSetupMultiPlayerMenu(void) multi_frame = 0; sprframe = &sprdef->spriteframes[multi_frame]; - patch = W_CachePatchNum(sprframe->lumppat[0], PU_CACHE); + patch = W_CachePatchNum(sprframe->lumppat[0], PU_PATCH); if (sprframe->flip & 1) // Only for first sprite flags |= V_FLIP; // This sprite is left/right flipped! @@ -9502,7 +9512,7 @@ faildraw: return; // Can't render! sprframe = &sprdef->spriteframes[0]; - patch = W_CachePatchNum(sprframe->lumppat[0], PU_CACHE); + patch = W_CachePatchNum(sprframe->lumppat[0], PU_PATCH); if (sprframe->flip & 1) // Only for first sprite flags |= V_FLIP; // This sprite is left/right flipped! diff --git a/src/p_setup.c b/src/p_setup.c index d0cd14b22..592ce4d8c 100644 --- a/src/p_setup.c +++ b/src/p_setup.c @@ -2955,16 +2955,8 @@ boolean P_SetupLevel(boolean skipprecip) P_SpawnPrecipitation(); #ifdef HWRENDER // not win32 only 19990829 by Kin - if (rendermode != render_soft && rendermode != render_none) - { -#ifdef ALAM_LIGHTING - // BP: reset light between levels (we draw preview frame lights on current frame) - HWR_ResetLights(); -#endif - // Correct missing sidedefs & deep water trick - HWR_CorrectSWTricks(); - HWR_CreatePlanePolygons((INT32)numnodes - 1); - } + if (rendermode == render_opengl) + HWR_SetupLevel(); #endif // oh god I hope this helps @@ -3119,10 +3111,8 @@ boolean P_SetupLevel(boolean skipprecip) // preload graphics #ifdef HWRENDER // not win32 only 19990829 by Kin - if (rendermode != render_soft && rendermode != render_none) - { + if (rendermode == render_opengl) HWR_PrepLevelCache(numtextures); - } #endif P_MapEnd(); @@ -3220,6 +3210,19 @@ boolean P_SetupLevel(boolean skipprecip) return true; } +#ifdef HWRENDER +void HWR_SetupLevel(void) +{ +#ifdef ALAM_LIGHTING + // BP: reset light between levels (we draw preview frame lights on current frame) + HWR_ResetLights(); +#endif + // Correct missing sidedefs & deep water trick + HWR_CorrectSWTricks(); + HWR_CreatePlanePolygons((INT32)numnodes - 1); +} +#endif + // // P_RunSOC // diff --git a/src/p_setup.h b/src/p_setup.h index 7e8a5d7e6..27ea62778 100644 --- a/src/p_setup.h +++ b/src/p_setup.h @@ -60,6 +60,9 @@ void P_ScanThings(INT16 mapnum, INT16 wadnum, INT16 lumpnum); #endif void P_LoadThingsOnly(void); boolean P_SetupLevel(boolean skipprecip); +#ifdef HWRENDER +void HWR_SetupLevel(void); +#endif boolean P_AddWadFile(const char *wadfilename); boolean P_RunSOC(const char *socfilename); void P_LoadSoundsRange(UINT16 wadnum, UINT16 first, UINT16 num); diff --git a/src/r_data.c b/src/r_data.c index 6889bddde..d829700b4 100644 --- a/src/r_data.c +++ b/src/r_data.c @@ -95,6 +95,8 @@ size_t numspritelumps, max_spritelumps; // textures INT32 numtextures = 0; // total number of textures found, +boolean needpatchflush = false; +boolean needpatchrecache = false; // size of following tables texture_t **textures = NULL; @@ -1672,7 +1674,7 @@ lighttable_t *R_CreateLightTable(extracolormap_t *extra_colormap) ///////////////////// // This code creates the colormap array used by software renderer ///////////////////// - if (rendermode == render_soft) + //if (rendermode == render_soft) { double r, g, b, cbrightness; int p; @@ -2294,7 +2296,7 @@ void R_PrecacheLevel(void) lump = sf->lumppat[k]; if (devparm) spritememory += W_LumpLength(lump); - W_CachePatchNum(lump, PU_CACHE); + W_CachePatchNum(lump, PU_PATCH); } } } diff --git a/src/r_data.h b/src/r_data.h index b6b0a16a1..a077c1fdc 100644 --- a/src/r_data.h +++ b/src/r_data.h @@ -149,5 +149,7 @@ const char *R_NameForColormap(extracolormap_t *extra_colormap); #define R_PutRgbaRGBA(r, g, b, a) (R_PutRgbaRGB(r, g, b) + R_PutRgbaA(a)) extern INT32 numtextures; +extern boolean needpatchflush; +extern boolean needpatchrecache; #endif diff --git a/src/r_main.c b/src/r_main.c index db351e991..20e074b82 100644 --- a/src/r_main.c +++ b/src/r_main.c @@ -19,6 +19,7 @@ #include "r_local.h" #include "r_splats.h" // faB(21jan): testing #include "r_sky.h" +#include "hu_stuff.h" #include "st_stuff.h" #include "p_local.h" #include "keys.h" @@ -28,6 +29,7 @@ #include "d_main.h" #include "v_video.h" #include "p_spec.h" // skyboxmo +#include "p_setup.h" #include "z_zone.h" #include "m_random.h" // quake camera shake #include "r_portal.h" @@ -1148,6 +1150,25 @@ void R_RenderPlayerView(player_t *player) free(masks); } +#ifdef HWRENDER +void R_InitHardwareMode(void) +{ + if (gamestate == GS_LEVEL) + { + HWR_SetupLevel(); + HWR_PrepLevelCache(numtextures); + } +} +#endif + +void R_ReloadHUDGraphics(void) +{ + W_FlushCachedPatches(); + ST_LoadGraphics(); + HU_LoadGraphics(); + ST_ReloadSkinFaceGraphics(); +} + // ========================================================================= // ENGINE COMMANDS & VARS // ========================================================================= diff --git a/src/r_main.h b/src/r_main.h index 2c9b5cc3d..5a2ec9fec 100644 --- a/src/r_main.h +++ b/src/r_main.h @@ -84,6 +84,10 @@ extern consvar_t cv_tailspickup; // Called by startup code. void R_Init(void); +#ifdef HWRENDER +void R_InitHardwareMode(void); +#endif +void R_ReloadHUDGraphics(void); // just sets setsizeneeded true extern boolean setsizeneeded; diff --git a/src/r_segs.c b/src/r_segs.c index 6eb81ce7a..a36250d24 100644 --- a/src/r_segs.c +++ b/src/r_segs.c @@ -165,7 +165,7 @@ static void R_DrawWallSplats(void) mfloorclip = floorclip; mceilingclip = ceilingclip; - patch = W_CachePatchNum(splat->patch, PU_CACHE); + patch = W_CachePatchNum(splat->patch, PU_PATCH); dc_texturemid = splat->top + (SHORT(patch->height)<<(FRACBITS-1)) - viewz; if (splat->yoffset) diff --git a/src/r_splats.c b/src/r_splats.c index 9ab671274..e09e68aa1 100644 --- a/src/r_splats.c +++ b/src/r_splats.c @@ -147,7 +147,7 @@ void R_AddWallSplat(line_t *wallline, INT16 sectorside, const char *patchname, f splat->flags = flags; // bad.. but will be needed for drawing anyway.. - patch = W_CachePatchNum(splat->patch, PU_CACHE); + patch = W_CachePatchNum(splat->patch, PU_PATCH); // offset needed by draw code for texture mapping linelength = P_SegLength((seg_t *)wallline); diff --git a/src/screen.c b/src/screen.c index fc3f5b8e8..33e4dc897 100644 --- a/src/screen.c +++ b/src/screen.c @@ -60,6 +60,7 @@ void (*twosmultipatchtransfunc)(void); // for cols with transparent pixels AND t // ------------------ viddef_t vid; INT32 setmodeneeded; //video mode change needed if > 0 (the mode number to set + 1) +INT32 setrenderneeded = 0; static CV_PossibleValue_t scr_depth_cons_t[] = {{8, "8 bits"}, {16, "16 bits"}, {24, "24 bits"}, {32, "32 bits"}, {0, NULL}}; @@ -69,6 +70,10 @@ consvar_t cv_scr_height = {"scr_height", "800", CV_SAVE, CV_Unsigned, NULL, 0, N consvar_t cv_scr_depth = {"scr_depth", "16 bits", CV_SAVE, scr_depth_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL}; consvar_t cv_renderview = {"renderview", "On", 0, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL}; +static void SCR_ChangeRenderer (void); +static CV_PossibleValue_t cv_renderer_t[] = {{1, "Software"}, {2, "OpenGL"}, {0, NULL}}; +consvar_t cv_renderer = {"renderer", "Software", CV_CALL, cv_renderer_t, SCR_ChangeRenderer, 0, NULL, NULL, 0, 0, NULL}; + static void SCR_ChangeFullscreen (void); consvar_t cv_fullscreen = {"fullscreen", "Yes", CV_SAVE|CV_CALL, CV_YesNo, SCR_ChangeFullscreen, 0, NULL, NULL, 0, 0, NULL}; @@ -94,19 +99,8 @@ boolean R_3DNow = false; boolean R_MMXExt = false; boolean R_SSE2 = false; - -void SCR_SetMode(void) +void SCR_SetDrawFuncs(void) { - if (dedicated) - return; - - if (!setmodeneeded || WipeInAction) - return; // should never happen and don't change it during a wipe, BAD! - - VID_SetMode(--setmodeneeded); - - V_SetPalette(0); - // // setup the right draw routines for either 8bpp or 16bpp // @@ -166,9 +160,33 @@ void SCR_SetMode(void) */ wallcolfunc = walldrawerfunc; +} + +void SCR_SetMode(void) +{ + if (dedicated) + return; + + if (!(setmodeneeded || setrenderneeded) || WipeInAction) + return; // should never happen and don't change it during a wipe, BAD! + + if (setrenderneeded) + { + needpatchflush = true; + needpatchrecache = true; + VID_CheckRenderer(); + } + + if (setmodeneeded) + VID_SetMode(--setmodeneeded); + + V_SetPalette(0); + + SCR_SetDrawFuncs(); // set the apprpriate drawer for the sky (tall or INT16) setmodeneeded = 0; + setrenderneeded = 0; } // do some initial settings for the game loading screen @@ -385,6 +403,29 @@ void SCR_ChangeFullscreen(void) #endif } +void SCR_ChangeRenderer(void) +{ + setrenderneeded = 0; + + if (con_startup) + { + if (rendermode == render_soft) + CV_StealthSetValue(&cv_renderer, 1); + else if (rendermode == render_opengl) + CV_StealthSetValue(&cv_renderer, 2); + return; + } + + if (cv_renderer.value == 1) + setrenderneeded = render_soft; + else if (cv_renderer.value == 2) + setrenderneeded = render_opengl; + + // setting the same renderer twice WILL crash your game, so let's not, please + if (rendermode == setrenderneeded) + setrenderneeded = 0; +} + boolean SCR_IsAspectCorrect(INT32 width, INT32 height) { return diff --git a/src/screen.h b/src/screen.h index 7aa6fdb63..6f8b02bae 100644 --- a/src/screen.h +++ b/src/screen.h @@ -144,11 +144,12 @@ extern boolean R_SSE2; // ---------------- extern viddef_t vid; extern INT32 setmodeneeded; // mode number to set if needed, or 0 +extern INT32 setrenderneeded; extern INT32 scr_bpp; extern UINT8 *scr_borderpatch; // patch used to fill the view borders -extern consvar_t cv_scr_width, cv_scr_height, cv_scr_depth, cv_renderview, cv_fullscreen; +extern consvar_t cv_scr_width, cv_scr_height, cv_scr_depth, cv_renderview, cv_renderer, cv_fullscreen; // wait for page flipping to end or not extern consvar_t cv_vidwait; @@ -157,6 +158,7 @@ extern void (*walldrawerfunc)(void); // Change video mode, only at the start of a refresh. void SCR_SetMode(void); +void SCR_SetDrawFuncs(void); // Recalc screen size dependent stuff void SCR_Recalc(void); // Check parms once at startup diff --git a/src/sdl/i_video.c b/src/sdl/i_video.c index 5a4fd7a02..c8f4fdc31 100644 --- a/src/sdl/i_video.c +++ b/src/sdl/i_video.c @@ -70,6 +70,7 @@ #include "../i_video.h" #include "../console.h" #include "../command.h" +#include "../r_main.h" #include "sdlmain.h" #ifdef HWRENDER #include "../hardware/hw_main.h" @@ -169,6 +170,7 @@ static void Impl_VideoSetupBuffer(void); static SDL_bool Impl_CreateWindow(SDL_bool fullscreen); //static void Impl_SetWindowName(const char *title); static void Impl_SetWindowIcon(void); +static void I_StartupGraphicsGL(void); static void SDLSetMode(INT32 width, INT32 height, SDL_bool fullscreen) { @@ -1062,7 +1064,6 @@ void I_FinishUpdate(void) SDL_RenderCopy(renderer, texture, NULL, NULL); SDL_RenderPresent(renderer); } - #ifdef HWRENDER else if (rendermode == render_opengl) { @@ -1262,6 +1263,81 @@ void VID_PrepareModeList(void) #endif } +// SOMETIME IN +// THE FUTURE +// WHEN I ACTUALLY RENDER +// THIS FRAME +static int renderflags; +static SDL_bool Impl_CreateContext(int flags) +{ + // Renderer-specific stuff +#ifdef HWRENDER + if (rendermode == render_opengl) + { + if (!sdlglcontext) + sdlglcontext = SDL_GL_CreateContext(window); + if (sdlglcontext == NULL) + { + SDL_DestroyWindow(window); + I_Error("Failed to create a GL context: %s\n", SDL_GetError()); + } + SDL_GL_MakeCurrent(window, sdlglcontext); + } + else +#endif + if (rendermode == render_soft) + { + flags = 0; // Use this to set SDL_RENDERER_* flags now + if (usesdl2soft) + flags |= SDL_RENDERER_SOFTWARE; + else if (cv_vidwait.value) + flags |= SDL_RENDERER_PRESENTVSYNC; + + if (!renderer) + renderer = SDL_CreateRenderer(window, -1, flags); + if (renderer == NULL) + { + CONS_Printf(M_GetText("Couldn't create rendering context: %s\n"), SDL_GetError()); + return SDL_FALSE; + } + SDL_RenderSetLogicalSize(renderer, BASEVIDWIDTH, BASEVIDHEIGHT); + } + return SDL_TRUE; +} + +void VID_CheckRenderer(void) +{ + if (setrenderneeded) + { + rendermode = setrenderneeded; + Impl_CreateContext(renderflags); + if (rendermode == render_soft) + { +#ifdef HWRENDER + HWR_FreeTextureCache(); +#endif + SCR_SetDrawFuncs(); + } + } + + SDLSetMode(vid.width, vid.height, USE_FULLSCREEN); + + if (rendermode == render_soft) + { + if (bufSurface) + { + SDL_FreeSurface(bufSurface); + bufSurface = NULL; + } + Impl_VideoSetupBuffer(); + } + else if (rendermode == render_opengl) + { + I_StartupGraphicsGL(); + R_InitHardwareMode(); + } +} + INT32 VID_SetMode(INT32 modeNum) { SDLdoUngrabMouse(); @@ -1293,20 +1369,7 @@ INT32 VID_SetMode(INT32 modeNum) vid.modenum = -1; } //Impl_SetWindowName("SRB2 "VERSIONSTRING); - - SDLSetMode(vid.width, vid.height, USE_FULLSCREEN); - - if (rendermode == render_soft) - { - if (bufSurface) - { - SDL_FreeSurface(bufSurface); - bufSurface = NULL; - } - - Impl_VideoSetupBuffer(); - } - + VID_CheckRenderer(); return SDL_TRUE; } @@ -1341,38 +1404,8 @@ static SDL_bool Impl_CreateWindow(SDL_bool fullscreen) return SDL_FALSE; } - // Renderer-specific stuff -#ifdef HWRENDER - if (rendermode == render_opengl) - { - sdlglcontext = SDL_GL_CreateContext(window); - if (sdlglcontext == NULL) - { - SDL_DestroyWindow(window); - I_Error("Failed to create a GL context: %s\n", SDL_GetError()); - } - SDL_GL_MakeCurrent(window, sdlglcontext); - } - else -#endif - if (rendermode == render_soft) - { - flags = 0; // Use this to set SDL_RENDERER_* flags now - if (usesdl2soft) - flags |= SDL_RENDERER_SOFTWARE; - else if (cv_vidwait.value) - flags |= SDL_RENDERER_PRESENTVSYNC; - - renderer = SDL_CreateRenderer(window, -1, flags); - if (renderer == NULL) - { - CONS_Printf(M_GetText("Couldn't create rendering context: %s\n"), SDL_GetError()); - return SDL_FALSE; - } - SDL_RenderSetLogicalSize(renderer, BASEVIDWIDTH, BASEVIDHEIGHT); - } - - return SDL_TRUE; + renderflags = flags; + return Impl_CreateContext(flags); } /* @@ -1441,6 +1474,51 @@ static void Impl_VideoSetupBuffer(void) } } +static void I_StartupGraphicsGL(void) +{ +#ifdef HWRENDER + static boolean glstartup = false; + if (!glstartup) + { + HWD.pfnInit = hwSym("Init",NULL); + HWD.pfnFinishUpdate = NULL; + HWD.pfnDraw2DLine = hwSym("Draw2DLine",NULL); + HWD.pfnDrawPolygon = hwSym("DrawPolygon",NULL); + HWD.pfnSetBlend = hwSym("SetBlend",NULL); + HWD.pfnClearBuffer = hwSym("ClearBuffer",NULL); + HWD.pfnSetTexture = hwSym("SetTexture",NULL); + HWD.pfnReadRect = hwSym("ReadRect",NULL); + HWD.pfnGClipRect = hwSym("GClipRect",NULL); + HWD.pfnClearMipMapCache = hwSym("ClearMipMapCache",NULL); + HWD.pfnSetSpecialState = hwSym("SetSpecialState",NULL); + HWD.pfnSetPalette = hwSym("SetPalette",NULL); + HWD.pfnGetTextureUsed = hwSym("GetTextureUsed",NULL); + HWD.pfnDrawMD2 = hwSym("DrawMD2",NULL); + HWD.pfnDrawMD2i = hwSym("DrawMD2i",NULL); + HWD.pfnSetTransform = hwSym("SetTransform",NULL); + HWD.pfnGetRenderVersion = hwSym("GetRenderVersion",NULL); +#ifdef SHUFFLE + HWD.pfnPostImgRedraw = hwSym("PostImgRedraw",NULL); +#endif + HWD.pfnFlushScreenTextures=hwSym("FlushScreenTextures",NULL); + HWD.pfnStartScreenWipe = hwSym("StartScreenWipe",NULL); + HWD.pfnEndScreenWipe = hwSym("EndScreenWipe",NULL); + HWD.pfnDoScreenWipe = hwSym("DoScreenWipe",NULL); + HWD.pfnDrawIntermissionBG=hwSym("DrawIntermissionBG",NULL); + HWD.pfnMakeScreenTexture= hwSym("MakeScreenTexture",NULL); + HWD.pfnMakeScreenFinalTexture=hwSym("MakeScreenFinalTexture",NULL); + HWD.pfnDrawScreenFinalTexture=hwSym("DrawScreenFinalTexture",NULL); + // check gl renderer lib + if (HWD.pfnGetRenderVersion() != VERSION) + I_Error("%s", M_GetText("The version of the renderer doesn't match the version of the executable\nBe sure you have installed SRB2 properly.\n")); + if (!HWD.pfnInit(I_Error)) // let load the OpenGL library + rendermode = render_soft; + else + glstartup = true; + } +#endif +} + void I_StartupGraphics(void) { if (dedicated) @@ -1481,10 +1559,11 @@ void I_StartupGraphics(void) )) framebuffer = SDL_TRUE; } - if (M_CheckParm("-software")) - { + + if (M_CheckParm("-opengl")) + rendermode = render_opengl; + else if (M_CheckParm("software")) rendermode = render_soft; - } usesdl2soft = M_CheckParm("-softblit"); borderlesswindow = M_CheckParm("-borderless"); @@ -1492,45 +1571,7 @@ void I_StartupGraphics(void) //SDL_EnableKeyRepeat(SDL_DEFAULT_REPEAT_DELAY>>1,SDL_DEFAULT_REPEAT_INTERVAL<<2); VID_Command_ModeList_f(); #ifdef HWRENDER - if (M_CheckParm("-opengl") || rendermode == render_opengl) - { - rendermode = render_opengl; - HWD.pfnInit = hwSym("Init",NULL); - HWD.pfnFinishUpdate = NULL; - HWD.pfnDraw2DLine = hwSym("Draw2DLine",NULL); - HWD.pfnDrawPolygon = hwSym("DrawPolygon",NULL); - HWD.pfnSetBlend = hwSym("SetBlend",NULL); - HWD.pfnClearBuffer = hwSym("ClearBuffer",NULL); - HWD.pfnSetTexture = hwSym("SetTexture",NULL); - HWD.pfnReadRect = hwSym("ReadRect",NULL); - HWD.pfnGClipRect = hwSym("GClipRect",NULL); - HWD.pfnClearMipMapCache = hwSym("ClearMipMapCache",NULL); - HWD.pfnSetSpecialState = hwSym("SetSpecialState",NULL); - HWD.pfnSetPalette = hwSym("SetPalette",NULL); - HWD.pfnGetTextureUsed = hwSym("GetTextureUsed",NULL); - HWD.pfnDrawMD2 = hwSym("DrawMD2",NULL); - HWD.pfnDrawMD2i = hwSym("DrawMD2i",NULL); - HWD.pfnSetTransform = hwSym("SetTransform",NULL); - HWD.pfnGetRenderVersion = hwSym("GetRenderVersion",NULL); -#ifdef SHUFFLE - HWD.pfnPostImgRedraw = hwSym("PostImgRedraw",NULL); -#endif - HWD.pfnFlushScreenTextures=hwSym("FlushScreenTextures",NULL); - HWD.pfnStartScreenWipe = hwSym("StartScreenWipe",NULL); - HWD.pfnEndScreenWipe = hwSym("EndScreenWipe",NULL); - HWD.pfnDoScreenWipe = hwSym("DoScreenWipe",NULL); - HWD.pfnDrawIntermissionBG=hwSym("DrawIntermissionBG",NULL); - HWD.pfnMakeScreenTexture= hwSym("MakeScreenTexture",NULL); - HWD.pfnMakeScreenFinalTexture=hwSym("MakeScreenFinalTexture",NULL); - HWD.pfnDrawScreenFinalTexture=hwSym("DrawScreenFinalTexture",NULL); - // check gl renderer lib - if (HWD.pfnGetRenderVersion() != VERSION) - I_Error("%s", M_GetText("The version of the renderer doesn't match the version of the executable\nBe sure you have installed SRB2 properly.\n")); - if (!HWD.pfnInit(I_Error)) // let load the OpenGL library - { - rendermode = render_soft; - } - } + I_StartupGraphicsGL(); #endif // Fury: we do window initialization after GL setup to allow diff --git a/src/st_stuff.c b/src/st_stuff.c index a90661ef3..1afe9f4cc 100644 --- a/src/st_stuff.c +++ b/src/st_stuff.c @@ -2554,6 +2554,9 @@ static void ST_overlayDrawer(void) void ST_Drawer(void) { + if (needpatchrecache) + R_ReloadHUDGraphics(); + #ifdef SEENAMES if (cv_seenames.value && cv_allowseenames.value && displayplayer == consoleplayer && seenplayer && seenplayer->mo) { diff --git a/src/v_video.c b/src/v_video.c index 082d84915..a1ba5406f 100644 --- a/src/v_video.c +++ b/src/v_video.c @@ -1069,7 +1069,7 @@ void V_DrawContinueIcon(INT32 x, INT32 y, INT32 flags, INT32 skinnum, UINT8 skin else { spriteframe_t *sprframe = &skins[skinnum].sprites[SPR2_WAIT].spriteframes[0]; - patch_t *patch = W_CachePatchNum(sprframe->lumppat[0], PU_CACHE); + patch_t *patch = W_CachePatchNum(sprframe->lumppat[0], PU_PATCH); const UINT8 *colormap = R_GetTranslationColormap(skinnum, skincolor, GTC_CACHE); // No variant for translucency diff --git a/src/w_wad.c b/src/w_wad.c index d02ce9ce6..01910ba44 100644 --- a/src/w_wad.c +++ b/src/w_wad.c @@ -53,6 +53,7 @@ #include "dehacked.h" #include "d_clisrv.h" #include "r_defs.h" +#include "r_data.h" #include "i_system.h" #include "md5.h" #include "lua_script.h" @@ -1401,7 +1402,6 @@ void *W_CacheLumpNumPwad(UINT16 wad, UINT16 lump, INT32 tag) void *W_CacheLumpNum(lumpnum_t lumpnum, INT32 tag) { - return W_CacheLumpNumPwad(WADFILENUM(lumpnum),LUMPNUM(lumpnum),tag); } @@ -1482,12 +1482,30 @@ void *W_CacheLumpName(const char *name, INT32 tag) // Cache a patch into heap memory, convert the patch format as necessary // +void W_FlushCachedPatches(void) +{ + if (needpatchflush) + { + Z_FreeTag(PU_CACHE); + Z_FreeTag(PU_PATCH); + Z_FreeTag(PU_HUDGFX); + Z_FreeTag(PU_HWRPATCHINFO); + Z_FreeTag(PU_HWRPATCHCOLMIPMAP); + Z_FreeTag(PU_HWRCACHE); + Z_FreeTags(PU_HWRCACHE_UNLOCKED, PU_HWRPATCHINFO_UNLOCKED); + } + needpatchflush = false; +} + // Software-only compile cache the data without conversion #ifdef HWRENDER static inline void *W_CachePatchNumPwad(UINT16 wad, UINT16 lump, INT32 tag) { GLPatch_t *grPatch; + if (needpatchflush) + W_FlushCachedPatches(); + if (rendermode == render_soft || rendermode == render_none) return W_CacheLumpNumPwad(wad, lump, tag); diff --git a/src/w_wad.h b/src/w_wad.h index 651738850..965a0d697 100644 --- a/src/w_wad.h +++ b/src/w_wad.h @@ -180,6 +180,7 @@ void *W_CachePatchNum(lumpnum_t lumpnum, INT32 tag); // return a patch_t #endif void W_UnlockCachedPatch(void *patch); +void W_FlushCachedPatches(void); void W_VerifyFileMD5(UINT16 wadfilenum, const char *matchmd5); diff --git a/src/win32/win_vid.c b/src/win32/win_vid.c index e2f32fa61..38be7a6b8 100644 --- a/src/win32/win_vid.c +++ b/src/win32/win_vid.c @@ -943,6 +943,11 @@ INT32 VID_SetMode(INT32 modenum) return 1; } +void VID_CheckRenderer(void) +{ + // .............. +} + // ======================================================================== // Free the video buffer of the last video mode, // allocate a new buffer for the video mode to set. diff --git a/src/y_inter.c b/src/y_inter.c index 975902ab0..632cf8795 100644 --- a/src/y_inter.c +++ b/src/y_inter.c @@ -1221,20 +1221,20 @@ void Y_StartIntermission(void) } for (i = 0; i < 4; ++i) - data.coop.bonuspatches[i] = W_CachePatchName(data.coop.bonuses[i].patch, PU_STATIC); - data.coop.ptotal = W_CachePatchName("YB_TOTAL", PU_STATIC); + data.coop.bonuspatches[i] = W_CachePatchName(data.coop.bonuses[i].patch, PU_PATCH); + data.coop.ptotal = W_CachePatchName("YB_TOTAL", PU_PATCH); // get act number data.coop.actnum = mapheaderinfo[gamemap-1]->actnum; // get background patches - widebgpatch = W_CachePatchName("INTERSCW", PU_STATIC); - bgpatch = W_CachePatchName("INTERSCR", PU_STATIC); + widebgpatch = W_CachePatchName("INTERSCW", PU_PATCH); + bgpatch = W_CachePatchName("INTERSCR", PU_PATCH); // grab an interscreen if appropriate if (mapheaderinfo[gamemap-1]->interscreen[0] != '#') { - interpic = W_CachePatchName(mapheaderinfo[gamemap-1]->interscreen, PU_STATIC); + interpic = W_CachePatchName(mapheaderinfo[gamemap-1]->interscreen, PU_PATCH); useinterpic = true; usebuffer = false; } @@ -1324,18 +1324,18 @@ void Y_StartIntermission(void) Y_AwardSpecialStageBonus(); for (i = 0; i < 2; ++i) - data.spec.bonuspatches[i] = W_CachePatchName(data.spec.bonuses[i].patch, PU_STATIC); + data.spec.bonuspatches[i] = W_CachePatchName(data.spec.bonuses[i].patch, PU_PATCH); - data.spec.pscore = W_CachePatchName("YB_SCORE", PU_STATIC); - data.spec.pcontinues = W_CachePatchName("YB_CONTI", PU_STATIC); + data.spec.pscore = W_CachePatchName("YB_SCORE", PU_PATCH); + data.spec.pcontinues = W_CachePatchName("YB_CONTI", PU_PATCH); // get background tile - bgtile = W_CachePatchName("SPECTILE", PU_STATIC); + bgtile = W_CachePatchName("SPECTILE", PU_PATCH); // grab an interscreen if appropriate if (mapheaderinfo[gamemap-1]->interscreen[0] != '#') { - interpic = W_CachePatchName(mapheaderinfo[gamemap-1]->interscreen, PU_STATIC); + interpic = W_CachePatchName(mapheaderinfo[gamemap-1]->interscreen, PU_PATCH); useinterpic = true; } else @@ -1347,14 +1347,14 @@ void Y_StartIntermission(void) // get special stage specific patches /* if (!stagefailed && ALL7EMERALDS(emeralds)) { - data.spec.cemerald = W_CachePatchName("GOTEMALL", PU_STATIC); + data.spec.cemerald = W_CachePatchName("GOTEMALL", PU_PATCH); data.spec.headx = 70; data.spec.nowsuper = players[consoleplayer].skin ? NULL : W_CachePatchName("NOWSUPER", PU_STATIC); } else { - data.spec.cemerald = W_CachePatchName("CEMERALD", PU_STATIC); + data.spec.cemerald = W_CachePatchName("CEMERALD", PU_PATCH); data.spec.headx = 48; data.spec.nowsuper = NULL; } */ @@ -1432,9 +1432,9 @@ void Y_StartIntermission(void) // get RESULT header data.match.result = - W_CachePatchName("RESULT", PU_STATIC); + W_CachePatchName("RESULT", PU_PATCH); - bgtile = W_CachePatchName("SRB2BACK", PU_STATIC); + bgtile = W_CachePatchName("SRB2BACK", PU_PATCH); usetile = true; useinterpic = false; break; @@ -1460,9 +1460,9 @@ void Y_StartIntermission(void) data.match.levelstring[sizeof data.match.levelstring - 1] = '\0'; // get RESULT header - data.match.result = W_CachePatchName("RESULT", PU_STATIC); + data.match.result = W_CachePatchName("RESULT", PU_PATCH); - bgtile = W_CachePatchName("SRB2BACK", PU_STATIC); + bgtile = W_CachePatchName("SRB2BACK", PU_PATCH); usetile = true; useinterpic = false; break; @@ -1499,7 +1499,7 @@ void Y_StartIntermission(void) data.match.blueflag = bmatcico; } - bgtile = W_CachePatchName("SRB2BACK", PU_STATIC); + bgtile = W_CachePatchName("SRB2BACK", PU_PATCH); usetile = true; useinterpic = false; break; @@ -1525,7 +1525,7 @@ void Y_StartIntermission(void) data.competition.levelstring[sizeof data.competition.levelstring - 1] = '\0'; // get background tile - bgtile = W_CachePatchName("SRB2BACK", PU_STATIC); + bgtile = W_CachePatchName("SRB2BACK", PU_PATCH); usetile = true; useinterpic = false; break; diff --git a/src/z_zone.h b/src/z_zone.h index 8d32e74f1..af8ca1241 100644 --- a/src/z_zone.h +++ b/src/z_zone.h @@ -43,6 +43,7 @@ enum PU_SOUND = 11, // static while playing PU_MUSIC = 12, // static while playing PU_HUDGFX = 13, // static until WAD added + PU_PATCH = 14, // static until renderer change PU_HWRPATCHINFO = 21, // Hardware GLPatch_t struct for OpenGL texture cache PU_HWRPATCHCOLMIPMAP = 22, // Hardware GLMipmap_t struct colormap variation of patch From c7e01a558e829ec0595a7df378f6197ea5a87014 Mon Sep 17 00:00:00 2001 From: Jaime Passos Date: Sun, 8 Sep 2019 18:27:35 -0300 Subject: [PATCH 002/746] initial stuff --- src/android/i_video.c | 5 + src/console.c | 10 +- src/d_main.c | 19 +++- src/d_netcmd.c | 1 + src/djgppdos/vid_vesa.c | 5 + src/dummy/i_video.c | 5 + src/f_finale.c | 50 +++++---- src/hardware/hw_cache.c | 32 ++++-- src/hardware/hw_draw.c | 16 +-- src/hardware/hw_main.c | 8 +- src/hardware/hw_md2.c | 2 +- src/hu_stuff.c | 3 + src/i_video.h | 1 + src/m_menu.c | 66 ++++++------ src/p_setup.c | 29 +++--- src/p_setup.h | 3 + src/r_data.c | 5 +- src/r_data.h | 2 + src/r_main.c | 21 ++++ src/r_main.h | 4 + src/r_segs.c | 2 +- src/r_splats.c | 2 +- src/screen.c | 68 ++++++++++--- src/screen.h | 4 +- src/sdl/i_video.c | 219 ++++++++++++++++++++++++---------------- src/st_stuff.c | 3 + src/w_wad.c | 20 +++- src/w_wad.h | 1 + src/win32/win_vid.c | 5 + src/y_inter.c | 36 +++---- src/z_zone.h | 1 + 31 files changed, 433 insertions(+), 215 deletions(-) diff --git a/src/android/i_video.c b/src/android/i_video.c index 2d0151f5e..44e1cbac0 100644 --- a/src/android/i_video.c +++ b/src/android/i_video.c @@ -51,6 +51,11 @@ INT32 VID_SetMode(INT32 modenum) return 0; } +void VID_CheckRenderer(void) +{ + // .............. +} + const char *VID_GetModeName(INT32 modenum) { return "A320x240"; diff --git a/src/console.c b/src/console.c index 91baf25fc..826153ff0 100644 --- a/src/console.c +++ b/src/console.c @@ -1269,7 +1269,7 @@ void CONS_Printf(const char *fmt, ...) if (con_startup) { #if (defined (_WINDOWS)) || (defined (__OS2__) && !defined (HAVE_SDL)) - patch_t *con_backpic = W_CachePatchName("CONSBACK", PU_CACHE); + patch_t *con_backpic = W_CachePatchName("CONSBACK", PU_PATCH); // Jimita: CON_DrawBackpic just called V_DrawScaledPatch V_DrawScaledPatch(0, 0, 0, con_backpic); @@ -1526,7 +1526,7 @@ static void CON_DrawConsole(void) // draw console background if (cons_backpic.value || con_forcepic) { - patch_t *con_backpic = W_CachePatchName("CONSBACK", PU_CACHE); + patch_t *con_backpic = W_CachePatchName("CONSBACK", PU_PATCH); // Jimita: CON_DrawBackpic just called V_DrawScaledPatch V_DrawScaledPatch(0, 0, 0, con_backpic); @@ -1583,6 +1583,12 @@ void CON_Drawer(void) if (!con_started || !graphics_started) return; + if (needpatchrecache) + { + W_FlushCachedPatches(); + HU_LoadGraphics(); + } + if (con_recalc) CON_RecalcSize(); diff --git a/src/d_main.c b/src/d_main.c index 3344732e5..06489ac7c 100644 --- a/src/d_main.c +++ b/src/d_main.c @@ -227,6 +227,7 @@ gamestate_t wipegamestate = GS_LEVEL; static void D_Display(void) { + INT32 setrenderstillneeded = setrenderneeded; boolean forcerefresh = false; static boolean wipe = false; INT32 wipedefindex = 0; @@ -237,15 +238,19 @@ static void D_Display(void) if (nodrawers) return; // for comparative timing/profiling + // stop movie if needs to change renderer + if (setrenderneeded && (moviemode != MM_OFF)) + M_StopMovie(); + // check for change of screen size (video mode) - if (setmodeneeded && !wipe) + if ((setmodeneeded || setrenderneeded) && !wipe) SCR_SetMode(); // change video mode - if (vid.recalc) + if (vid.recalc || setrenderstillneeded) SCR_Recalc(); // NOTE! setsizeneeded is set by SCR_Recalc() // change the view size if needed - if (setsizeneeded) + if (setsizeneeded || setrenderstillneeded) { R_ExecuteSetViewSize(); forcerefresh = true; // force background redraw @@ -426,7 +431,7 @@ static void D_Display(void) py = 4; else py = viewwindowy + 4; - patch = W_CachePatchName("M_PAUSE", PU_CACHE); + patch = W_CachePatchName("M_PAUSE", PU_PATCH); V_DrawScaledPatch(viewwindowx + (BASEVIDWIDTH - SHORT(patch->width))/2, py, 0, patch); } @@ -489,6 +494,12 @@ static void D_Display(void) I_FinishUpdate(); // page flip or blit buffer } + + if (needpatchrecache) + R_ReloadHUDGraphics(); + + needpatchflush = false; + needpatchrecache = false; } // ========================================================================= diff --git a/src/d_netcmd.c b/src/d_netcmd.c index cc9127af0..1e9915e1d 100644 --- a/src/d_netcmd.c +++ b/src/d_netcmd.c @@ -771,6 +771,7 @@ void D_RegisterClientCommands(void) // screen.c CV_RegisterVar(&cv_fullscreen); CV_RegisterVar(&cv_renderview); + CV_RegisterVar(&cv_renderer); CV_RegisterVar(&cv_scr_depth); CV_RegisterVar(&cv_scr_width); CV_RegisterVar(&cv_scr_height); diff --git a/src/djgppdos/vid_vesa.c b/src/djgppdos/vid_vesa.c index ec7b8b886..c8ce7dae5 100644 --- a/src/djgppdos/vid_vesa.c +++ b/src/djgppdos/vid_vesa.c @@ -378,6 +378,11 @@ INT32 VID_SetMode (INT32 modenum) //, UINT8 *palette) return 1; } +void VID_CheckRenderer(void) +{ + // .............. +} + // converts a segm:offs 32bit pair to a 32bit flat ptr diff --git a/src/dummy/i_video.c b/src/dummy/i_video.c index e167e833f..b8f40bed3 100644 --- a/src/dummy/i_video.c +++ b/src/dummy/i_video.c @@ -39,6 +39,11 @@ INT32 VID_SetMode(INT32 modenum) return 0; } +void VID_CheckRenderer(void) +{ + // .............. +} + const char *VID_GetModeName(INT32 modenum) { (void)modenum; diff --git a/src/f_finale.c b/src/f_finale.c index 63221fc23..58d57948b 100644 --- a/src/f_finale.c +++ b/src/f_finale.c @@ -466,16 +466,16 @@ static void F_IntroDrawScene(void) // DRAW A FULL PIC INSTEAD OF FLAT! if (intro_scenenum == 0); else if (intro_scenenum == 1) - background = W_CachePatchName("INTRO1", PU_CACHE); + background = W_CachePatchName("INTRO1", PU_PATCH); else if (intro_scenenum == 2) { - background = W_CachePatchName("INTRO2", PU_CACHE); + background = W_CachePatchName("INTRO2", PU_PATCH); highres = true; } else if (intro_scenenum == 3) - background = W_CachePatchName("INTRO3", PU_CACHE); + background = W_CachePatchName("INTRO3", PU_PATCH); else if (intro_scenenum == 4) - background = W_CachePatchName("INTRO4", PU_CACHE); + background = W_CachePatchName("INTRO4", PU_PATCH); else if (intro_scenenum == 5) { if (intro_curtime >= 5*TICRATE) @@ -734,7 +734,7 @@ static void F_IntroDrawScene(void) if (roidtics >= 0) { V_DrawScaledPatch(roidtics, 24, 0, - (patch = W_CachePatchName(va("ROID00%.2d", intro_curtime%35), PU_CACHE))); + (patch = W_CachePatchName(va("ROID00%.2d", intro_curtime%35), PU_PATCH))); W_UnlockCachedPatch(patch); } } @@ -1359,7 +1359,6 @@ void F_GameEvaluationDrawer(void) if (ALL7EMERALDS(emeralds)) ++timesBeatenWithEmeralds; - if (ultimatemode) ++timesBeatenUltimate; @@ -1447,10 +1446,28 @@ void F_GameEndTicker(void) D_StartTitle(); } - // ============== // TITLE SCREEN // ============== +static void F_CacheTitleScreen(void) +{ + ttbanner = W_CachePatchName("TTBANNER", PU_LEVEL); + ttwing = W_CachePatchName("TTWING", PU_LEVEL); + ttsonic = W_CachePatchName("TTSONIC", PU_LEVEL); + ttswave1 = W_CachePatchName("TTSWAVE1", PU_LEVEL); + ttswave2 = W_CachePatchName("TTSWAVE2", PU_LEVEL); + ttswip1 = W_CachePatchName("TTSWIP1", PU_LEVEL); + ttsprep1 = W_CachePatchName("TTSPREP1", PU_LEVEL); + ttsprep2 = W_CachePatchName("TTSPREP2", PU_LEVEL); + ttspop1 = W_CachePatchName("TTSPOP1", PU_LEVEL); + ttspop2 = W_CachePatchName("TTSPOP2", PU_LEVEL); + ttspop3 = W_CachePatchName("TTSPOP3", PU_LEVEL); + ttspop4 = W_CachePatchName("TTSPOP4", PU_LEVEL); + ttspop5 = W_CachePatchName("TTSPOP5", PU_LEVEL); + ttspop6 = W_CachePatchName("TTSPOP6", PU_LEVEL); + ttspop7 = W_CachePatchName("TTSPOP7", PU_LEVEL); +} + void F_StartTitleScreen(void) { if (gamestate != GS_TITLESCREEN && gamestate != GS_WAITINGPLAYERS) @@ -1469,21 +1486,7 @@ void F_StartTitleScreen(void) demoDelayLeft = demoDelayTime; demoIdleLeft = demoIdleTime; - ttbanner = W_CachePatchName("TTBANNER", PU_LEVEL); - ttwing = W_CachePatchName("TTWING", PU_LEVEL); - ttsonic = W_CachePatchName("TTSONIC", PU_LEVEL); - ttswave1 = W_CachePatchName("TTSWAVE1", PU_LEVEL); - ttswave2 = W_CachePatchName("TTSWAVE2", PU_LEVEL); - ttswip1 = W_CachePatchName("TTSWIP1", PU_LEVEL); - ttsprep1 = W_CachePatchName("TTSPREP1", PU_LEVEL); - ttsprep2 = W_CachePatchName("TTSPREP2", PU_LEVEL); - ttspop1 = W_CachePatchName("TTSPOP1", PU_LEVEL); - ttspop2 = W_CachePatchName("TTSPOP2", PU_LEVEL); - ttspop3 = W_CachePatchName("TTSPOP3", PU_LEVEL); - ttspop4 = W_CachePatchName("TTSPOP4", PU_LEVEL); - ttspop5 = W_CachePatchName("TTSPOP5", PU_LEVEL); - ttspop6 = W_CachePatchName("TTSPOP6", PU_LEVEL); - ttspop7 = W_CachePatchName("TTSPOP7", PU_LEVEL); + F_CacheTitleScreen(); } // (no longer) De-Demo'd Title Screen @@ -1492,6 +1495,9 @@ void F_TitleScreenDrawer(void) if (modeattacking) return; // We likely came here from retrying. Don't do a damn thing. + if (needpatchrecache) + F_CacheTitleScreen(); + // Draw that sky! F_SkyScroll(titlescrollspeed); diff --git a/src/hardware/hw_cache.c b/src/hardware/hw_cache.c index 78fc31afc..3857ad5d7 100644 --- a/src/hardware/hw_cache.c +++ b/src/hardware/hw_cache.c @@ -549,16 +549,14 @@ void HWR_MakePatch (const patch_t *patch, GLPatch_t *grPatch, GLMipmap_t *grMipm // CACHING HANDLING // ================================================= -static size_t gr_numtextures; +static size_t gr_numtextures = 0; static GLTexture_t *gr_textures; // for ALL Doom textures void HWR_InitTextureCache(void) { - gr_numtextures = 0; gr_textures = NULL; } - // Callback function for HWR_FreeTextureCache. static void FreeMipmapColormap(INT32 patchnum, void *patch) { @@ -587,15 +585,17 @@ void HWR_FreeTextureCache(void) // Alam: free the Z_Blocks before freeing it's users // free all skin after each level: must be done after pfnClearMipMapCache! - for (i = 0; i < numwadfiles; i++) - M_AATreeIterate(wadfiles[i]->hwrcache, FreeMipmapColormap); + // temp fix, idk why this crashes + // is it because the colormaps were already freed anyway? + if (!needpatchrecache) + for (i = 0; i < numwadfiles; i++) + M_AATreeIterate(wadfiles[i]->hwrcache, FreeMipmapColormap); // now the heap don't have any 'user' pointing to our // texturecache info, we can free it if (gr_textures) free(gr_textures); gr_textures = NULL; - gr_numtextures = 0; } void HWR_PrepLevelCache(size_t pnumtextures) @@ -642,8 +642,11 @@ GLTexture_t *HWR_GetTexture(INT32 tex) GLTexture_t *grtex; #ifdef PARANOIA if ((unsigned)tex >= gr_numtextures) - I_Error(" HWR_GetTexture: tex >= numtextures\n"); + I_Error("HWR_GetTexture: tex >= numtextures\n"); #endif + if (needpatchrecache && (!gr_textures)) + HWR_PrepLevelCache(gr_numtextures); + grtex = &gr_textures[tex]; if (!grtex->mipmap.grInfo.data && !grtex->mipmap.downloaded) @@ -709,6 +712,9 @@ void HWR_GetFlat(lumpnum_t flatlumpnum) { GLMipmap_t *grmip; + if (needpatchflush) + W_FlushCachedPatches(); + grmip = &HWR_GetCachedGLPatch(flatlumpnum)->mipmap; if (!grmip->downloaded && !grmip->grInfo.data) @@ -745,6 +751,9 @@ static void HWR_LoadMappedPatch(GLMipmap_t *grmip, GLPatch_t *gpatch) // -----------------+ void HWR_GetPatch(GLPatch_t *gpatch) { + if (needpatchflush) + W_FlushCachedPatches(); + // is it in hardware cache if (!gpatch->mipmap.downloaded && !gpatch->mipmap.grInfo.data) { @@ -772,6 +781,9 @@ void HWR_GetMappedPatch(GLPatch_t *gpatch, const UINT8 *colormap) { GLMipmap_t *grmip, *newmip; + if (needpatchflush) + W_FlushCachedPatches(); + if (colormap == colormaps || colormap == NULL) { // Load the default (green) color in doom cache (temporary?) AND hardware cache @@ -897,6 +909,9 @@ GLPatch_t *HWR_GetPic(lumpnum_t lumpnum) { GLPatch_t *grpatch; + if (needpatchflush) + W_FlushCachedPatches(); + grpatch = HWR_GetCachedGLPatch(lumpnum); if (!grpatch->mipmap.downloaded && !grpatch->mipmap.grInfo.data) @@ -1094,6 +1109,9 @@ void HWR_GetFadeMask(lumpnum_t fademasklumpnum) { GLMipmap_t *grmip; + if (needpatchflush) + W_FlushCachedPatches(); + grmip = &HWR_GetCachedGLPatch(fademasklumpnum)->mipmap; if (!grmip->downloaded && !grmip->grInfo.data) diff --git a/src/hardware/hw_draw.c b/src/hardware/hw_draw.c index cd2c95237..2dc18aee1 100644 --- a/src/hardware/hw_draw.c +++ b/src/hardware/hw_draw.c @@ -703,7 +703,7 @@ void HWR_DrawViewBorder(INT32 clearlines) // top edge if (clearlines > basewindowy - 8) { - patch = W_CachePatchNum(viewborderlump[BRDR_T], PU_CACHE); + patch = W_CachePatchNum(viewborderlump[BRDR_T], PU_PATCH); for (x = 0; x < baseviewwidth; x += 8) HWR_DrawPatch(patch, basewindowx + x, basewindowy - 8, 0); @@ -712,7 +712,7 @@ void HWR_DrawViewBorder(INT32 clearlines) // bottom edge if (clearlines > basewindowy + baseviewheight) { - patch = W_CachePatchNum(viewborderlump[BRDR_B], PU_CACHE); + patch = W_CachePatchNum(viewborderlump[BRDR_B], PU_PATCH); for (x = 0; x < baseviewwidth; x += 8) HWR_DrawPatch(patch, basewindowx + x, basewindowy + baseviewheight, 0); @@ -721,7 +721,7 @@ void HWR_DrawViewBorder(INT32 clearlines) // left edge if (clearlines > basewindowy) { - patch = W_CachePatchNum(viewborderlump[BRDR_L], PU_CACHE); + patch = W_CachePatchNum(viewborderlump[BRDR_L], PU_PATCH); for (y = 0; y < baseviewheight && basewindowy + y < clearlines; y += 8) { @@ -733,7 +733,7 @@ void HWR_DrawViewBorder(INT32 clearlines) // right edge if (clearlines > basewindowy) { - patch = W_CachePatchNum(viewborderlump[BRDR_R], PU_CACHE); + patch = W_CachePatchNum(viewborderlump[BRDR_R], PU_PATCH); for (y = 0; y < baseviewheight && basewindowy+y < clearlines; y += 8) { @@ -745,22 +745,22 @@ void HWR_DrawViewBorder(INT32 clearlines) // Draw beveled corners. if (clearlines > basewindowy - 8) HWR_DrawPatch(W_CachePatchNum(viewborderlump[BRDR_TL], - PU_CACHE), + PU_PATCH), basewindowx - 8, basewindowy - 8, 0); if (clearlines > basewindowy - 8) HWR_DrawPatch(W_CachePatchNum(viewborderlump[BRDR_TR], - PU_CACHE), + PU_PATCH), basewindowx + baseviewwidth, basewindowy - 8, 0); if (clearlines > basewindowy+baseviewheight) HWR_DrawPatch(W_CachePatchNum(viewborderlump[BRDR_BL], - PU_CACHE), + PU_PATCH), basewindowx - 8, basewindowy + baseviewheight, 0); if (clearlines > basewindowy + baseviewheight) HWR_DrawPatch(W_CachePatchNum(viewborderlump[BRDR_BR], - PU_CACHE), + PU_PATCH), basewindowx + baseviewwidth, basewindowy + baseviewheight, 0); } diff --git a/src/hardware/hw_main.c b/src/hardware/hw_main.c index 7e0b369eb..399a7bfd2 100644 --- a/src/hardware/hw_main.c +++ b/src/hardware/hw_main.c @@ -872,7 +872,7 @@ static void HWR_DrawSegsSplats(FSurfaceInfo * pSurf) if (!M_PointInBox(segbbox,splat->v1.x,splat->v1.y) && !M_PointInBox(segbbox,splat->v2.x,splat->v2.y)) continue; - gpatch = W_CachePatchNum(splat->patch, PU_CACHE); + gpatch = W_CachePatchNum(splat->patch, PU_PATCH); HWR_GetPatch(gpatch); wallVerts[0].x = wallVerts[3].x = FIXED_TO_FLOAT(splat->v1.x); @@ -4311,7 +4311,7 @@ static void HWR_SplitSprite(gr_vissprite_t *spr) if (hires) this_scale = this_scale * FIXED_TO_FLOAT(((skin_t *)spr->mobj->skin)->highresscale); - gpatch = W_CachePatchNum(spr->patchlumpnum, PU_CACHE); + gpatch = W_CachePatchNum(spr->patchlumpnum, PU_PATCH); // cache the patch in the graphics card memory //12/12/99: Hurdler: same comment as above (for md2) @@ -4664,7 +4664,7 @@ static void HWR_DrawSprite(gr_vissprite_t *spr) // sure to do it the right way. So actually, we keep normal sprite // in memory and we add the md2 model if it exists for that sprite - gpatch = W_CachePatchNum(spr->patchlumpnum, PU_CACHE); + gpatch = W_CachePatchNum(spr->patchlumpnum, PU_PATCH); #ifdef ALAM_LIGHTING if (!(spr->mobj->flags2 & MF2_DEBRIS) && (spr->mobj->sprite != SPR_PLAY || @@ -4809,7 +4809,7 @@ static inline void HWR_DrawPrecipitationSprite(gr_vissprite_t *spr) return; // cache sprite graphics - gpatch = W_CachePatchNum(spr->patchlumpnum, PU_CACHE); + gpatch = W_CachePatchNum(spr->patchlumpnum, PU_PATCH); // create the sprite billboard // diff --git a/src/hardware/hw_md2.c b/src/hardware/hw_md2.c index cb33562d8..353e49f81 100644 --- a/src/hardware/hw_md2.c +++ b/src/hardware/hw_md2.c @@ -1350,7 +1350,7 @@ void HWR_DrawMD2(gr_vissprite_t *spr) else { // Sprite - gpatch = W_CachePatchNum(spr->patchlumpnum, PU_CACHE); + gpatch = W_CachePatchNum(spr->patchlumpnum, PU_PATCH); HWR_GetMappedPatch(gpatch, spr->colormap); } diff --git a/src/hu_stuff.c b/src/hu_stuff.c index a9a2b7504..2451f5c4d 100644 --- a/src/hu_stuff.c +++ b/src/hu_stuff.c @@ -1993,6 +1993,9 @@ static void HU_DrawDemoInfo(void) // void HU_Drawer(void) { + if (needpatchrecache) + R_ReloadHUDGraphics(); + #ifndef NONET // draw chat string plus cursor if (chat_on) diff --git a/src/i_video.h b/src/i_video.h index 4bb2c5829..a62f3ff64 100644 --- a/src/i_video.h +++ b/src/i_video.h @@ -84,6 +84,7 @@ INT32 VID_GetModeForSize(INT32 w, INT32 h); \return currect video mode */ INT32 VID_SetMode(INT32 modenum); +void VID_CheckRenderer(void); /** \brief The VID_GetModeName function diff --git a/src/m_menu.c b/src/m_menu.c index a833ace21..f6c47077e 100644 --- a/src/m_menu.c +++ b/src/m_menu.c @@ -2872,19 +2872,19 @@ static void M_DrawThermo(INT32 x, INT32 y, consvar_t *cv) centerlump[1] = W_GetNumForName("M_THERMM"); cursorlump = W_GetNumForName("M_THERMO"); - V_DrawScaledPatch(xx, y, 0, p = W_CachePatchNum(leftlump,PU_CACHE)); + V_DrawScaledPatch(xx, y, 0, p = W_CachePatchNum(leftlump,PU_PATCH)); xx += SHORT(p->width) - SHORT(p->leftoffset); for (i = 0; i < 16; i++) { - V_DrawScaledPatch(xx, y, V_WRAPX, W_CachePatchNum(centerlump[i & 1], PU_CACHE)); + V_DrawScaledPatch(xx, y, V_WRAPX, W_CachePatchNum(centerlump[i & 1], PU_PATCH)); xx += 8; } - V_DrawScaledPatch(xx, y, 0, W_CachePatchNum(rightlump, PU_CACHE)); + V_DrawScaledPatch(xx, y, 0, W_CachePatchNum(rightlump, PU_PATCH)); xx = (cv->value - cv->PossibleValue[0].value) * (15*8) / (cv->PossibleValue[1].value - cv->PossibleValue[0].value); - V_DrawScaledPatch((x + 8) + xx, y, 0, W_CachePatchNum(cursorlump, PU_CACHE)); + V_DrawScaledPatch((x + 8) + xx, y, 0, W_CachePatchNum(cursorlump, PU_PATCH)); } // A smaller 'Thermo', with range given as percents (0-100) @@ -2940,15 +2940,15 @@ void M_DrawTextBox(INT32 x, INT32 y, INT32 width, INT32 boxlines) // draw left side cx = x; cy = y; - V_DrawScaledPatch(cx, cy, 0, W_CachePatchNum(viewborderlump[BRDR_TL], PU_CACHE)); + V_DrawScaledPatch(cx, cy, 0, W_CachePatchNum(viewborderlump[BRDR_TL], PU_PATCH)); cy += boff; - p = W_CachePatchNum(viewborderlump[BRDR_L], PU_CACHE); + p = W_CachePatchNum(viewborderlump[BRDR_L], PU_PATCH); for (n = 0; n < boxlines; n++) { V_DrawScaledPatch(cx, cy, V_WRAPY, p); cy += step; } - V_DrawScaledPatch(cx, cy, 0, W_CachePatchNum(viewborderlump[BRDR_BL], PU_CACHE)); + V_DrawScaledPatch(cx, cy, 0, W_CachePatchNum(viewborderlump[BRDR_BL], PU_PATCH)); // draw middle V_DrawFlatFill(x + boff, y + boff, width*step, boxlines*step, st_borderpatchnum); @@ -2957,23 +2957,23 @@ void M_DrawTextBox(INT32 x, INT32 y, INT32 width, INT32 boxlines) cy = y; while (width > 0) { - V_DrawScaledPatch(cx, cy, V_WRAPX, W_CachePatchNum(viewborderlump[BRDR_T], PU_CACHE)); - V_DrawScaledPatch(cx, y + boff + boxlines*step, V_WRAPX, W_CachePatchNum(viewborderlump[BRDR_B], PU_CACHE)); + V_DrawScaledPatch(cx, cy, V_WRAPX, W_CachePatchNum(viewborderlump[BRDR_T], PU_PATCH)); + V_DrawScaledPatch(cx, y + boff + boxlines*step, V_WRAPX, W_CachePatchNum(viewborderlump[BRDR_B], PU_PATCH)); width--; cx += step; } // draw right side cy = y; - V_DrawScaledPatch(cx, cy, 0, W_CachePatchNum(viewborderlump[BRDR_TR], PU_CACHE)); + V_DrawScaledPatch(cx, cy, 0, W_CachePatchNum(viewborderlump[BRDR_TR], PU_PATCH)); cy += boff; - p = W_CachePatchNum(viewborderlump[BRDR_R], PU_CACHE); + p = W_CachePatchNum(viewborderlump[BRDR_R], PU_PATCH); for (n = 0; n < boxlines; n++) { V_DrawScaledPatch(cx, cy, V_WRAPY, p); cy += step; } - V_DrawScaledPatch(cx, cy, 0, W_CachePatchNum(viewborderlump[BRDR_BR], PU_CACHE)); + V_DrawScaledPatch(cx, cy, 0, W_CachePatchNum(viewborderlump[BRDR_BR], PU_PATCH)); */ } @@ -3914,6 +3914,27 @@ static void M_AddonsOptions(INT32 choice) #define LOCATIONSTRING1 "Visit \x83SRB2.ORG/MODS\x80 to get & make add-ons!" //#define LOCATIONSTRING2 "Visit \x88SRB2.ORG/MODS\x80 to get & make add-ons!" +static void M_LoadAddonsPatches(void) +{ + addonsp[EXT_FOLDER] = W_CachePatchName("M_FFLDR", PU_PATCH); + addonsp[EXT_UP] = W_CachePatchName("M_FBACK", PU_PATCH); + addonsp[EXT_NORESULTS] = W_CachePatchName("M_FNOPE", PU_PATCH); + addonsp[EXT_TXT] = W_CachePatchName("M_FTXT", PU_PATCH); + addonsp[EXT_CFG] = W_CachePatchName("M_FCFG", PU_PATCH); + addonsp[EXT_WAD] = W_CachePatchName("M_FWAD", PU_PATCH); +#ifdef USE_KART + addonsp[EXT_KART] = W_CachePatchName("M_FKART", PU_PATCH); +#endif + addonsp[EXT_PK3] = W_CachePatchName("M_FPK3", PU_PATCH); + addonsp[EXT_SOC] = W_CachePatchName("M_FSOC", PU_PATCH); + addonsp[EXT_LUA] = W_CachePatchName("M_FLUA", PU_PATCH); + addonsp[NUM_EXT] = W_CachePatchName("M_FUNKN", PU_PATCH); + addonsp[NUM_EXT+1] = W_CachePatchName("M_FSEL", PU_PATCH); + addonsp[NUM_EXT+2] = W_CachePatchName("M_FLOAD", PU_PATCH); + addonsp[NUM_EXT+3] = W_CachePatchName("M_FSRCH", PU_PATCH); + addonsp[NUM_EXT+4] = W_CachePatchName("M_FSAVE", PU_PATCH); +} + static void M_Addons(INT32 choice) { const char *pathname = "."; @@ -3964,23 +3985,7 @@ static void M_Addons(INT32 choice) W_UnlockCachedPatch(addonsp[i]); } - addonsp[EXT_FOLDER] = W_CachePatchName("M_FFLDR", PU_STATIC); - addonsp[EXT_UP] = W_CachePatchName("M_FBACK", PU_STATIC); - addonsp[EXT_NORESULTS] = W_CachePatchName("M_FNOPE", PU_STATIC); - addonsp[EXT_TXT] = W_CachePatchName("M_FTXT", PU_STATIC); - addonsp[EXT_CFG] = W_CachePatchName("M_FCFG", PU_STATIC); - addonsp[EXT_WAD] = W_CachePatchName("M_FWAD", PU_STATIC); -#ifdef USE_KART - addonsp[EXT_KART] = W_CachePatchName("M_FKART", PU_STATIC); -#endif - addonsp[EXT_PK3] = W_CachePatchName("M_FPK3", PU_STATIC); - addonsp[EXT_SOC] = W_CachePatchName("M_FSOC", PU_STATIC); - addonsp[EXT_LUA] = W_CachePatchName("M_FLUA", PU_STATIC); - addonsp[NUM_EXT] = W_CachePatchName("M_FUNKN", PU_STATIC); - addonsp[NUM_EXT+1] = W_CachePatchName("M_FSEL", PU_STATIC); - addonsp[NUM_EXT+2] = W_CachePatchName("M_FLOAD", PU_STATIC); - addonsp[NUM_EXT+3] = W_CachePatchName("M_FSRCH", PU_STATIC); - addonsp[NUM_EXT+4] = W_CachePatchName("M_FSAVE", PU_STATIC); + M_LoadAddonsPatches(); MISC_AddonsDef.prevMenu = currentMenu; M_SetupNextMenu(&MISC_AddonsDef); @@ -4119,6 +4124,9 @@ static void M_DrawAddons(void) return; } + if (needpatchrecache) + M_LoadAddonsPatches(); + if (Playing()) V_DrawCenteredString(BASEVIDWIDTH/2, 5, warningflags, "Adding files mid-game may cause problems."); else diff --git a/src/p_setup.c b/src/p_setup.c index b2636c350..0058f7def 100644 --- a/src/p_setup.c +++ b/src/p_setup.c @@ -2967,16 +2967,8 @@ boolean P_SetupLevel(boolean skipprecip) globalweather = mapheaderinfo[gamemap-1]->weather; #ifdef HWRENDER // not win32 only 19990829 by Kin - if (rendermode != render_soft && rendermode != render_none) - { -#ifdef ALAM_LIGHTING - // BP: reset light between levels (we draw preview frame lights on current frame) - HWR_ResetLights(); -#endif - // Correct missing sidedefs & deep water trick - HWR_CorrectSWTricks(); - HWR_CreatePlanePolygons((INT32)numnodes - 1); - } + if (rendermode == render_opengl) + HWR_SetupLevel(); #endif // oh god I hope this helps @@ -3123,10 +3115,8 @@ boolean P_SetupLevel(boolean skipprecip) // preload graphics #ifdef HWRENDER // not win32 only 19990829 by Kin - if (rendermode != render_soft && rendermode != render_none) - { + if (rendermode == render_opengl) HWR_PrepLevelCache(numtextures); - } #endif P_MapEnd(); @@ -3181,6 +3171,19 @@ boolean P_SetupLevel(boolean skipprecip) return true; } +#ifdef HWRENDER +void HWR_SetupLevel(void) +{ +#ifdef ALAM_LIGHTING + // BP: reset light between levels (we draw preview frame lights on current frame) + HWR_ResetLights(); +#endif + // Correct missing sidedefs & deep water trick + HWR_CorrectSWTricks(); + HWR_CreatePlanePolygons((INT32)numnodes - 1); +} +#endif + // // P_RunSOC // diff --git a/src/p_setup.h b/src/p_setup.h index 41c2bf133..622e1edbc 100644 --- a/src/p_setup.h +++ b/src/p_setup.h @@ -59,6 +59,9 @@ void P_ScanThings(INT16 mapnum, INT16 wadnum, INT16 lumpnum); #endif void P_LoadThingsOnly(void); boolean P_SetupLevel(boolean skipprecip); +#ifdef HWRENDER +void HWR_SetupLevel(void); +#endif boolean P_AddWadFile(const char *wadfilename); #ifdef DELFILE boolean P_DelWadFile(void); diff --git a/src/r_data.c b/src/r_data.c index bd12eb248..cd50272b0 100644 --- a/src/r_data.c +++ b/src/r_data.c @@ -95,6 +95,8 @@ size_t numspritelumps, max_spritelumps; // textures INT32 numtextures = 0; // total number of textures found, +boolean needpatchflush = false; +boolean needpatchrecache = false; // size of following tables texture_t **textures = NULL; @@ -1266,7 +1268,6 @@ INT32 R_CreateColormap(char *p1, char *p2, char *p3) extra_colormaps[mapnum].fog = fog; // This code creates the colormap array used by software renderer - if (rendermode == render_soft) { double r, g, b, cbrightness; int p; @@ -1611,7 +1612,7 @@ void R_PrecacheLevel(void) lump = sf->lumppat[k]; if (devparm) spritememory += W_LumpLength(lump); - W_CachePatchNum(lump, PU_CACHE); + W_CachePatchNum(lump, PU_PATCH); } } } diff --git a/src/r_data.h b/src/r_data.h index 5de51ccd4..e6229d6c8 100644 --- a/src/r_data.h +++ b/src/r_data.h @@ -96,5 +96,7 @@ INT32 R_CreateColormap(char *p1, char *p2, char *p3); const char *R_ColormapNameForNum(INT32 num); extern INT32 numtextures; +extern boolean needpatchflush; +extern boolean needpatchrecache; #endif diff --git a/src/r_main.c b/src/r_main.c index 08b1ab2f0..f12fe23fe 100644 --- a/src/r_main.c +++ b/src/r_main.c @@ -19,6 +19,7 @@ #include "r_local.h" #include "r_splats.h" // faB(21jan): testing #include "r_sky.h" +#include "hu_stuff.h" #include "st_stuff.h" #include "p_local.h" #include "keys.h" @@ -28,6 +29,7 @@ #include "d_main.h" #include "v_video.h" #include "p_spec.h" // skyboxmo +#include "p_setup.h" #include "z_zone.h" #include "m_random.h" // quake camera shake @@ -1337,6 +1339,25 @@ void R_RenderPlayerView(player_t *player) skyVisible1 = skyVisible; } +#ifdef HWRENDER +void R_InitHardwareMode(void) +{ + if (gamestate == GS_LEVEL) + { + HWR_SetupLevel(); + HWR_PrepLevelCache(numtextures); + } +} +#endif + +void R_ReloadHUDGraphics(void) +{ + W_FlushCachedPatches(); + ST_LoadGraphics(); + HU_LoadGraphics(); + ST_ReloadSkinFaceGraphics(); +} + // ========================================================================= // ENGINE COMMANDS & VARS // ========================================================================= diff --git a/src/r_main.h b/src/r_main.h index 6ae5aa221..6b521e43a 100644 --- a/src/r_main.h +++ b/src/r_main.h @@ -84,6 +84,10 @@ extern consvar_t cv_tailspickup; // Called by startup code. void R_Init(void); +#ifdef HWRENDER +void R_InitHardwareMode(void); +#endif +void R_ReloadHUDGraphics(void); // just sets setsizeneeded true extern boolean setsizeneeded; diff --git a/src/r_segs.c b/src/r_segs.c index c82554ac8..d5f651fc5 100644 --- a/src/r_segs.c +++ b/src/r_segs.c @@ -164,7 +164,7 @@ static void R_DrawWallSplats(void) mfloorclip = floorclip; mceilingclip = ceilingclip; - patch = W_CachePatchNum(splat->patch, PU_CACHE); + patch = W_CachePatchNum(splat->patch, PU_PATCH); dc_texturemid = splat->top + (SHORT(patch->height)<<(FRACBITS-1)) - viewz; if (splat->yoffset) diff --git a/src/r_splats.c b/src/r_splats.c index 9ab671274..e09e68aa1 100644 --- a/src/r_splats.c +++ b/src/r_splats.c @@ -147,7 +147,7 @@ void R_AddWallSplat(line_t *wallline, INT16 sectorside, const char *patchname, f splat->flags = flags; // bad.. but will be needed for drawing anyway.. - patch = W_CachePatchNum(splat->patch, PU_CACHE); + patch = W_CachePatchNum(splat->patch, PU_PATCH); // offset needed by draw code for texture mapping linelength = P_SegLength((seg_t *)wallline); diff --git a/src/screen.c b/src/screen.c index af6aed03c..d485a6367 100644 --- a/src/screen.c +++ b/src/screen.c @@ -56,6 +56,7 @@ void (*twosmultipatchtransfunc)(void); // for cols with transparent pixels AND t // ------------------ viddef_t vid; INT32 setmodeneeded; //video mode change needed if > 0 (the mode number to set + 1) +INT32 setrenderneeded = 0; static CV_PossibleValue_t scr_depth_cons_t[] = {{8, "8 bits"}, {16, "16 bits"}, {24, "24 bits"}, {32, "32 bits"}, {0, NULL}}; @@ -71,6 +72,10 @@ consvar_t cv_scr_depth = {"scr_depth", "16 bits", CV_SAVE, scr_depth_cons_t, NUL #endif consvar_t cv_renderview = {"renderview", "On", 0, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL}; +static void SCR_ChangeRenderer (void); +static CV_PossibleValue_t cv_renderer_t[] = {{1, "Software"}, {2, "OpenGL"}, {0, NULL}}; +consvar_t cv_renderer = {"renderer", "Software", CV_CALL, cv_renderer_t, SCR_ChangeRenderer, 0, NULL, NULL, 0, 0, NULL}; + static void SCR_ChangeFullscreen (void); consvar_t cv_fullscreen = {"fullscreen", "Yes", CV_SAVE|CV_CALL, CV_YesNo, SCR_ChangeFullscreen, 0, NULL, NULL, 0, 0, NULL}; @@ -96,19 +101,8 @@ boolean R_3DNow = false; boolean R_MMXExt = false; boolean R_SSE2 = false; - -void SCR_SetMode(void) +void SCR_SetDrawFuncs(void) { - if (dedicated) - return; - - if (!setmodeneeded || WipeInAction) - return; // should never happen and don't change it during a wipe, BAD! - - VID_SetMode(--setmodeneeded); - - V_SetPalette(0); - // // setup the right draw routines for either 8bpp or 16bpp // @@ -166,8 +160,35 @@ void SCR_SetMode(void) if (SCR_IsAspectCorrect(vid.width, vid.height)) CONS_Alert(CONS_WARNING, M_GetText("Resolution is not aspect-correct!\nUse a multiple of %dx%d\n"), BASEVIDWIDTH, BASEVIDHEIGHT); #endif*/ + + wallcolfunc = walldrawerfunc; +} + +void SCR_SetMode(void) +{ + if (dedicated) + return; + + if (!(setmodeneeded || setrenderneeded) || WipeInAction) + return; // should never happen and don't change it during a wipe, BAD! + + if (setrenderneeded) + { + needpatchflush = true; + needpatchrecache = true; + VID_CheckRenderer(); + } + + if (setmodeneeded) + VID_SetMode(--setmodeneeded); + + V_SetPalette(0); + + SCR_SetDrawFuncs(); + // set the apprpriate drawer for the sky (tall or INT16) setmodeneeded = 0; + setrenderneeded = 0; } // do some initial settings for the game loading screen @@ -384,6 +405,29 @@ void SCR_ChangeFullscreen(void) #endif } +void SCR_ChangeRenderer(void) +{ + setrenderneeded = 0; + + if (con_startup) + { + if (rendermode == render_soft) + CV_StealthSetValue(&cv_renderer, 1); + else if (rendermode == render_opengl) + CV_StealthSetValue(&cv_renderer, 2); + return; + } + + if (cv_renderer.value == 1) + setrenderneeded = render_soft; + else if (cv_renderer.value == 2) + setrenderneeded = render_opengl; + + // setting the same renderer twice WILL crash your game, so let's not, please + if (rendermode == setrenderneeded) + setrenderneeded = 0; +} + boolean SCR_IsAspectCorrect(INT32 width, INT32 height) { return diff --git a/src/screen.h b/src/screen.h index 9ad254d3f..df0518421 100644 --- a/src/screen.h +++ b/src/screen.h @@ -154,11 +154,12 @@ extern boolean R_SSE2; // ---------------- extern viddef_t vid; extern INT32 setmodeneeded; // mode number to set if needed, or 0 +extern INT32 setrenderneeded; extern INT32 scr_bpp; extern UINT8 *scr_borderpatch; // patch used to fill the view borders -extern consvar_t cv_scr_width, cv_scr_height, cv_scr_depth, cv_renderview, cv_fullscreen; +extern consvar_t cv_scr_width, cv_scr_height, cv_scr_depth, cv_renderview, cv_renderer, cv_fullscreen; // wait for page flipping to end or not extern consvar_t cv_vidwait; @@ -167,6 +168,7 @@ extern void (*walldrawerfunc)(void); // Change video mode, only at the start of a refresh. void SCR_SetMode(void); +void SCR_SetDrawFuncs(void); // Recalc screen size dependent stuff void SCR_Recalc(void); // Check parms once at startup diff --git a/src/sdl/i_video.c b/src/sdl/i_video.c index 77bf414cc..45d9e3ed9 100644 --- a/src/sdl/i_video.c +++ b/src/sdl/i_video.c @@ -71,6 +71,7 @@ #include "../i_video.h" #include "../console.h" #include "../command.h" +#include "../r_main.h" #include "sdlmain.h" #ifdef HWRENDER #include "../hardware/hw_main.h" @@ -170,6 +171,7 @@ static void Impl_VideoSetupBuffer(void); static SDL_bool Impl_CreateWindow(SDL_bool fullscreen); //static void Impl_SetWindowName(const char *title); static void Impl_SetWindowIcon(void); +static void I_StartupGraphicsGL(void); static void SDLSetMode(INT32 width, INT32 height, SDL_bool fullscreen) { @@ -1059,7 +1061,6 @@ void I_FinishUpdate(void) SDL_RenderCopy(renderer, texture, NULL, NULL); SDL_RenderPresent(renderer); } - #ifdef HWRENDER else if (rendermode == render_opengl) { @@ -1259,6 +1260,81 @@ void VID_PrepareModeList(void) #endif } +// SOMETIME IN +// THE FUTURE +// WHEN I ACTUALLY RENDER +// THIS FRAME +static int renderflags; +static SDL_bool Impl_CreateContext(int flags) +{ + // Renderer-specific stuff +#ifdef HWRENDER + if (rendermode == render_opengl) + { + if (!sdlglcontext) + sdlglcontext = SDL_GL_CreateContext(window); + if (sdlglcontext == NULL) + { + SDL_DestroyWindow(window); + I_Error("Failed to create a GL context: %s\n", SDL_GetError()); + } + SDL_GL_MakeCurrent(window, sdlglcontext); + } + else +#endif + if (rendermode == render_soft) + { + flags = 0; // Use this to set SDL_RENDERER_* flags now + if (usesdl2soft) + flags |= SDL_RENDERER_SOFTWARE; + else if (cv_vidwait.value) + flags |= SDL_RENDERER_PRESENTVSYNC; + + if (!renderer) + renderer = SDL_CreateRenderer(window, -1, flags); + if (renderer == NULL) + { + CONS_Printf(M_GetText("Couldn't create rendering context: %s\n"), SDL_GetError()); + return SDL_FALSE; + } + SDL_RenderSetLogicalSize(renderer, BASEVIDWIDTH, BASEVIDHEIGHT); + } + return SDL_TRUE; +} + +void VID_CheckRenderer(void) +{ + if (setrenderneeded) + { + rendermode = setrenderneeded; + Impl_CreateContext(renderflags); + if (rendermode == render_soft) + { +#ifdef HWRENDER + HWR_FreeTextureCache(); +#endif + SCR_SetDrawFuncs(); + } + } + + SDLSetMode(vid.width, vid.height, USE_FULLSCREEN); + + if (rendermode == render_soft) + { + if (bufSurface) + { + SDL_FreeSurface(bufSurface); + bufSurface = NULL; + } + Impl_VideoSetupBuffer(); + } + else if (rendermode == render_opengl) + { + I_StartupGraphicsGL(); + R_InitHardwareMode(); + } +} + INT32 VID_SetMode(INT32 modeNum) { SDLdoUngrabMouse(); @@ -1290,20 +1366,7 @@ INT32 VID_SetMode(INT32 modeNum) vid.modenum = -1; } //Impl_SetWindowName("SRB2 "VERSIONSTRING); - - SDLSetMode(vid.width, vid.height, USE_FULLSCREEN); - - if (rendermode == render_soft) - { - if (bufSurface) - { - SDL_FreeSurface(bufSurface); - bufSurface = NULL; - } - - Impl_VideoSetupBuffer(); - } - + VID_CheckRenderer(); return SDL_TRUE; } @@ -1338,38 +1401,8 @@ static SDL_bool Impl_CreateWindow(SDL_bool fullscreen) return SDL_FALSE; } - // Renderer-specific stuff -#ifdef HWRENDER - if (rendermode == render_opengl) - { - sdlglcontext = SDL_GL_CreateContext(window); - if (sdlglcontext == NULL) - { - SDL_DestroyWindow(window); - I_Error("Failed to create a GL context: %s\n", SDL_GetError()); - } - SDL_GL_MakeCurrent(window, sdlglcontext); - } - else -#endif - if (rendermode == render_soft) - { - flags = 0; // Use this to set SDL_RENDERER_* flags now - if (usesdl2soft) - flags |= SDL_RENDERER_SOFTWARE; - else if (cv_vidwait.value) - flags |= SDL_RENDERER_PRESENTVSYNC; - - renderer = SDL_CreateRenderer(window, -1, flags); - if (renderer == NULL) - { - CONS_Printf(M_GetText("Couldn't create rendering context: %s\n"), SDL_GetError()); - return SDL_FALSE; - } - SDL_RenderSetLogicalSize(renderer, BASEVIDWIDTH, BASEVIDHEIGHT); - } - - return SDL_TRUE; + renderflags = flags; + return Impl_CreateContext(flags); } /* @@ -1438,6 +1471,51 @@ static void Impl_VideoSetupBuffer(void) } } +static void I_StartupGraphicsGL(void) +{ +#ifdef HWRENDER + static boolean glstartup = false; + if (!glstartup) + { + HWD.pfnInit = hwSym("Init",NULL); + HWD.pfnFinishUpdate = NULL; + HWD.pfnDraw2DLine = hwSym("Draw2DLine",NULL); + HWD.pfnDrawPolygon = hwSym("DrawPolygon",NULL); + HWD.pfnSetBlend = hwSym("SetBlend",NULL); + HWD.pfnClearBuffer = hwSym("ClearBuffer",NULL); + HWD.pfnSetTexture = hwSym("SetTexture",NULL); + HWD.pfnReadRect = hwSym("ReadRect",NULL); + HWD.pfnGClipRect = hwSym("GClipRect",NULL); + HWD.pfnClearMipMapCache = hwSym("ClearMipMapCache",NULL); + HWD.pfnSetSpecialState = hwSym("SetSpecialState",NULL); + HWD.pfnSetPalette = hwSym("SetPalette",NULL); + HWD.pfnGetTextureUsed = hwSym("GetTextureUsed",NULL); + HWD.pfnDrawMD2 = hwSym("DrawMD2",NULL); + HWD.pfnDrawMD2i = hwSym("DrawMD2i",NULL); + HWD.pfnSetTransform = hwSym("SetTransform",NULL); + HWD.pfnGetRenderVersion = hwSym("GetRenderVersion",NULL); +#ifdef SHUFFLE + HWD.pfnPostImgRedraw = hwSym("PostImgRedraw",NULL); +#endif + HWD.pfnFlushScreenTextures=hwSym("FlushScreenTextures",NULL); + HWD.pfnStartScreenWipe = hwSym("StartScreenWipe",NULL); + HWD.pfnEndScreenWipe = hwSym("EndScreenWipe",NULL); + HWD.pfnDoScreenWipe = hwSym("DoScreenWipe",NULL); + HWD.pfnDrawIntermissionBG=hwSym("DrawIntermissionBG",NULL); + HWD.pfnMakeScreenTexture= hwSym("MakeScreenTexture",NULL); + HWD.pfnMakeScreenFinalTexture=hwSym("MakeScreenFinalTexture",NULL); + HWD.pfnDrawScreenFinalTexture=hwSym("DrawScreenFinalTexture",NULL); + // check gl renderer lib + if (HWD.pfnGetRenderVersion() != VERSION) + I_Error("%s", M_GetText("The version of the renderer doesn't match the version of the executable\nBe sure you have installed SRB2 properly.\n")); + if (!HWD.pfnInit(I_Error)) // let load the OpenGL library + rendermode = render_soft; + else + glstartup = true; + } +#endif +} + void I_StartupGraphics(void) { if (dedicated) @@ -1478,10 +1556,11 @@ void I_StartupGraphics(void) )) framebuffer = SDL_TRUE; } - if (M_CheckParm("-software")) - { + + if (M_CheckParm("-opengl")) + rendermode = render_opengl; + else if (M_CheckParm("software")) rendermode = render_soft; - } usesdl2soft = M_CheckParm("-softblit"); borderlesswindow = M_CheckParm("-borderless"); @@ -1489,45 +1568,7 @@ void I_StartupGraphics(void) //SDL_EnableKeyRepeat(SDL_DEFAULT_REPEAT_DELAY>>1,SDL_DEFAULT_REPEAT_INTERVAL<<2); VID_Command_ModeList_f(); #ifdef HWRENDER - if (M_CheckParm("-opengl") || rendermode == render_opengl) - { - rendermode = render_opengl; - HWD.pfnInit = hwSym("Init",NULL); - HWD.pfnFinishUpdate = NULL; - HWD.pfnDraw2DLine = hwSym("Draw2DLine",NULL); - HWD.pfnDrawPolygon = hwSym("DrawPolygon",NULL); - HWD.pfnSetBlend = hwSym("SetBlend",NULL); - HWD.pfnClearBuffer = hwSym("ClearBuffer",NULL); - HWD.pfnSetTexture = hwSym("SetTexture",NULL); - HWD.pfnReadRect = hwSym("ReadRect",NULL); - HWD.pfnGClipRect = hwSym("GClipRect",NULL); - HWD.pfnClearMipMapCache = hwSym("ClearMipMapCache",NULL); - HWD.pfnSetSpecialState = hwSym("SetSpecialState",NULL); - HWD.pfnSetPalette = hwSym("SetPalette",NULL); - HWD.pfnGetTextureUsed = hwSym("GetTextureUsed",NULL); - HWD.pfnDrawMD2 = hwSym("DrawMD2",NULL); - HWD.pfnDrawMD2i = hwSym("DrawMD2i",NULL); - HWD.pfnSetTransform = hwSym("SetTransform",NULL); - HWD.pfnGetRenderVersion = hwSym("GetRenderVersion",NULL); -#ifdef SHUFFLE - HWD.pfnPostImgRedraw = hwSym("PostImgRedraw",NULL); -#endif - HWD.pfnFlushScreenTextures=hwSym("FlushScreenTextures",NULL); - HWD.pfnStartScreenWipe = hwSym("StartScreenWipe",NULL); - HWD.pfnEndScreenWipe = hwSym("EndScreenWipe",NULL); - HWD.pfnDoScreenWipe = hwSym("DoScreenWipe",NULL); - HWD.pfnDrawIntermissionBG=hwSym("DrawIntermissionBG",NULL); - HWD.pfnMakeScreenTexture= hwSym("MakeScreenTexture",NULL); - HWD.pfnMakeScreenFinalTexture=hwSym("MakeScreenFinalTexture",NULL); - HWD.pfnDrawScreenFinalTexture=hwSym("DrawScreenFinalTexture",NULL); - // check gl renderer lib - if (HWD.pfnGetRenderVersion() != VERSION) - I_Error("%s", M_GetText("The version of the renderer doesn't match the version of the executable\nBe sure you have installed SRB2 properly.\n")); - if (!HWD.pfnInit(I_Error)) // let load the OpenGL library - { - rendermode = render_soft; - } - } + I_StartupGraphicsGL(); #endif // Fury: we do window initialization after GL setup to allow diff --git a/src/st_stuff.c b/src/st_stuff.c index 287aea134..11bb9875d 100644 --- a/src/st_stuff.c +++ b/src/st_stuff.c @@ -1909,6 +1909,9 @@ static void ST_overlayDrawer(void) void ST_Drawer(void) { + if (needpatchrecache) + R_ReloadHUDGraphics(); + #ifdef SEENAMES if (cv_seenames.value && cv_allowseenames.value && displayplayer == consoleplayer && seenplayer && seenplayer->mo) { diff --git a/src/w_wad.c b/src/w_wad.c index 7de64f9ad..00797b87d 100644 --- a/src/w_wad.c +++ b/src/w_wad.c @@ -41,6 +41,7 @@ #include "dehacked.h" #include "d_clisrv.h" #include "r_defs.h" +#include "r_data.h" #include "i_system.h" #include "md5.h" #include "lua_script.h" @@ -1422,7 +1423,6 @@ void *W_CacheLumpNumPwad(UINT16 wad, UINT16 lump, INT32 tag) void *W_CacheLumpNum(lumpnum_t lumpnum, INT32 tag) { - return W_CacheLumpNumPwad(WADFILENUM(lumpnum),LUMPNUM(lumpnum),tag); } @@ -1503,12 +1503,30 @@ void *W_CacheLumpName(const char *name, INT32 tag) // Cache a patch into heap memory, convert the patch format as necessary // +void W_FlushCachedPatches(void) +{ + if (needpatchflush) + { + Z_FreeTag(PU_CACHE); + Z_FreeTag(PU_PATCH); + Z_FreeTag(PU_HUDGFX); + Z_FreeTag(PU_HWRPATCHINFO); + Z_FreeTag(PU_HWRPATCHCOLMIPMAP); + Z_FreeTag(PU_HWRCACHE); + Z_FreeTags(PU_HWRCACHE_UNLOCKED, PU_HWRPATCHINFO_UNLOCKED); + } + needpatchflush = false; +} + // Software-only compile cache the data without conversion #ifdef HWRENDER static inline void *W_CachePatchNumPwad(UINT16 wad, UINT16 lump, INT32 tag) { GLPatch_t *grPatch; + if (needpatchflush) + W_FlushCachedPatches(); + if (rendermode == render_soft || rendermode == render_none) return W_CacheLumpNumPwad(wad, lump, tag); diff --git a/src/w_wad.h b/src/w_wad.h index 87566c3ee..84e921e75 100644 --- a/src/w_wad.h +++ b/src/w_wad.h @@ -183,6 +183,7 @@ void *W_CachePatchNum(lumpnum_t lumpnum, INT32 tag); // return a patch_t #endif void W_UnlockCachedPatch(void *patch); +void W_FlushCachedPatches(void); void W_VerifyFileMD5(UINT16 wadfilenum, const char *matchmd5); diff --git a/src/win32/win_vid.c b/src/win32/win_vid.c index cca7810b3..a6d9cdfc1 100644 --- a/src/win32/win_vid.c +++ b/src/win32/win_vid.c @@ -939,6 +939,11 @@ INT32 VID_SetMode(INT32 modenum) return 1; } +void VID_CheckRenderer(void) +{ + // .............. +} + // ======================================================================== // Free the video buffer of the last video mode, // allocate a new buffer for the video mode to set. diff --git a/src/y_inter.c b/src/y_inter.c index ed4972d2e..ab0af490d 100644 --- a/src/y_inter.c +++ b/src/y_inter.c @@ -1051,8 +1051,8 @@ void Y_StartIntermission(void) } for (i = 0; i < 4; ++i) - data.coop.bonuspatches[i] = W_CachePatchName(data.coop.bonuses[i].patch, PU_STATIC); - data.coop.ptotal = W_CachePatchName("YB_TOTAL", PU_STATIC); + data.coop.bonuspatches[i] = W_CachePatchName(data.coop.bonuses[i].patch, PU_PATCH); + data.coop.ptotal = W_CachePatchName("YB_TOTAL", PU_PATCH); // get act number if (mapheaderinfo[prevmap]->actnum) @@ -1062,13 +1062,13 @@ void Y_StartIntermission(void) data.coop.ttlnum = W_CachePatchName("TTL01", PU_STATIC); // get background patches - widebgpatch = W_CachePatchName("INTERSCW", PU_STATIC); - bgpatch = W_CachePatchName("INTERSCR", PU_STATIC); + widebgpatch = W_CachePatchName("INTERSCW", PU_PATCH); + bgpatch = W_CachePatchName("INTERSCR", PU_PATCH); // grab an interscreen if appropriate if (mapheaderinfo[gamemap-1]->interscreen[0] != '#') { - interpic = W_CachePatchName(mapheaderinfo[gamemap-1]->interscreen, PU_STATIC); + interpic = W_CachePatchName(mapheaderinfo[gamemap-1]->interscreen, PU_PATCH); useinterpic = true; usebuffer = false; } @@ -1153,17 +1153,17 @@ void Y_StartIntermission(void) // give out ring bonuses Y_AwardSpecialStageBonus(); - data.spec.bonuspatch = W_CachePatchName(data.spec.bonus.patch, PU_STATIC); - data.spec.pscore = W_CachePatchName("YB_SCORE", PU_STATIC); - data.spec.pcontinues = W_CachePatchName("YB_CONTI", PU_STATIC); + data.spec.bonuspatch = W_CachePatchName(data.spec.bonus.patch, PU_PATCH); + data.spec.pscore = W_CachePatchName("YB_SCORE", PU_PATCH); + data.spec.pcontinues = W_CachePatchName("YB_CONTI", PU_PATCH); // get background tile - bgtile = W_CachePatchName("SPECTILE", PU_STATIC); + bgtile = W_CachePatchName("SPECTILE", PU_PATCH); // grab an interscreen if appropriate if (mapheaderinfo[gamemap-1]->interscreen[0] != '#') { - interpic = W_CachePatchName(mapheaderinfo[gamemap-1]->interscreen, PU_STATIC); + interpic = W_CachePatchName(mapheaderinfo[gamemap-1]->interscreen, PU_PATCH); useinterpic = true; } else @@ -1175,14 +1175,14 @@ void Y_StartIntermission(void) // get special stage specific patches /* if (!stagefailed && ALL7EMERALDS(emeralds)) { - data.spec.cemerald = W_CachePatchName("GOTEMALL", PU_STATIC); + data.spec.cemerald = W_CachePatchName("GOTEMALL", PU_PATCH); data.spec.headx = 70; data.spec.nowsuper = players[consoleplayer].skin ? NULL : W_CachePatchName("NOWSUPER", PU_STATIC); } else { - data.spec.cemerald = W_CachePatchName("CEMERALD", PU_STATIC); + data.spec.cemerald = W_CachePatchName("CEMERALD", PU_PATCH); data.spec.headx = 48; data.spec.nowsuper = NULL; } */ @@ -1255,9 +1255,9 @@ void Y_StartIntermission(void) // get RESULT header data.match.result = - W_CachePatchName("RESULT", PU_STATIC); + W_CachePatchName("RESULT", PU_PATCH); - bgtile = W_CachePatchName("SRB2BACK", PU_STATIC); + bgtile = W_CachePatchName("SRB2BACK", PU_PATCH); usetile = true; useinterpic = false; break; @@ -1283,9 +1283,9 @@ void Y_StartIntermission(void) data.match.levelstring[sizeof data.match.levelstring - 1] = '\0'; // get RESULT header - data.match.result = W_CachePatchName("RESULT", PU_STATIC); + data.match.result = W_CachePatchName("RESULT", PU_PATCH); - bgtile = W_CachePatchName("SRB2BACK", PU_STATIC); + bgtile = W_CachePatchName("SRB2BACK", PU_PATCH); usetile = true; useinterpic = false; break; @@ -1322,7 +1322,7 @@ void Y_StartIntermission(void) data.match.blueflag = bmatcico; } - bgtile = W_CachePatchName("SRB2BACK", PU_STATIC); + bgtile = W_CachePatchName("SRB2BACK", PU_PATCH); usetile = true; useinterpic = false; break; @@ -1348,7 +1348,7 @@ void Y_StartIntermission(void) data.competition.levelstring[sizeof data.competition.levelstring - 1] = '\0'; // get background tile - bgtile = W_CachePatchName("SRB2BACK", PU_STATIC); + bgtile = W_CachePatchName("SRB2BACK", PU_PATCH); usetile = true; useinterpic = false; break; diff --git a/src/z_zone.h b/src/z_zone.h index 1424a3782..a62555243 100644 --- a/src/z_zone.h +++ b/src/z_zone.h @@ -39,6 +39,7 @@ #define PU_SOUND 11 // static while playing #define PU_MUSIC 12 // static while playing #define PU_HUDGFX 13 // static until WAD added +#define PU_PATCH 14 // static until renderer change #define PU_HWRPATCHINFO 21 // Hardware GLPatch_t struct for OpenGL texture cache #define PU_HWRPATCHCOLMIPMAP 22 // Hardware GLMipmap_t struct colromap variation of patch From 19e50062cc41aeb0efda24e2478ec98a645f6a97 Mon Sep 17 00:00:00 2001 From: Jaime Passos Date: Sun, 8 Sep 2019 18:59:49 -0300 Subject: [PATCH 003/746] more stuff. i hope i didnt mess this up. --- src/hardware/hw_main.c | 19 ++++++++++++------- src/m_menu.c | 7 ++++--- src/r_main.c | 3 ++- src/sdl/i_video.c | 23 ++++++++--------------- src/z_zone.h | 1 + 5 files changed, 27 insertions(+), 26 deletions(-) diff --git a/src/hardware/hw_main.c b/src/hardware/hw_main.c index 399a7bfd2..4f31b262a 100644 --- a/src/hardware/hw_main.c +++ b/src/hardware/hw_main.c @@ -6378,13 +6378,18 @@ static void Command_GrStats_f(void) //added by Hurdler: console varibale that are saved void HWR_AddCommands(void) { - CV_RegisterVar(&cv_grrounddown); - CV_RegisterVar(&cv_grfov); - CV_RegisterVar(&cv_grfogdensity); - CV_RegisterVar(&cv_grfiltermode); - CV_RegisterVar(&cv_granisotropicmode); - CV_RegisterVar(&cv_grcorrecttricks); - CV_RegisterVar(&cv_grsolvetjoin); + static boolean alreadycalled = false; + if (!alreadycalled) + { + CV_RegisterVar(&cv_grrounddown); + CV_RegisterVar(&cv_grfov); + CV_RegisterVar(&cv_grfogdensity); + CV_RegisterVar(&cv_grfiltermode); + CV_RegisterVar(&cv_granisotropicmode); + CV_RegisterVar(&cv_grcorrecttricks); + CV_RegisterVar(&cv_grsolvetjoin); + } + alreadycalled = true; } static inline void HWR_AddEngineCommands(void) diff --git a/src/m_menu.c b/src/m_menu.c index f6c47077e..8ae341e31 100644 --- a/src/m_menu.c +++ b/src/m_menu.c @@ -1101,7 +1101,8 @@ static menuitem_t OP_VideoOptionsMenu[] = {IT_STRING | IT_CALL, NULL, "Video Modes...", M_VideoModeMenu, 10}, #ifdef HWRENDER - {IT_SUBMENU|IT_STRING, NULL, "3D Card Options...", &OP_OpenGLOptionsDef, 20}, + {IT_STRING|IT_CVAR, NULL, "Renderer", &cv_renderer, 20}, + //{IT_SUBMENU|IT_STRING, NULL, "3D Card Options...", &OP_OpenGLOptionsDef, 20}, #endif #if (defined (__unix__) && !defined (MSDOS)) || defined (UNIXCOMMON) || defined (HAVE_SDL) @@ -2769,11 +2770,11 @@ void M_Init(void) quitmsg[QUIT3MSG5] = M_GetText("You'll be back to play soon, though...\n......right?\n\n(Press 'Y' to quit)"); quitmsg[QUIT3MSG6] = M_GetText("Aww, is Egg Rock Zone too\ndifficult for you?\n\n(Press 'Y' to quit)"); -#ifdef HWRENDER +/*#ifdef HWRENDER // Permanently hide some options based on render mode if (rendermode == render_soft) OP_VideoOptionsMenu[1].status = IT_DISABLED; -#endif +#endif*/ #ifndef NONET CV_RegisterVar(&cv_serversort); diff --git a/src/r_main.c b/src/r_main.c index f12fe23fe..f7678b928 100644 --- a/src/r_main.c +++ b/src/r_main.c @@ -1342,6 +1342,7 @@ void R_RenderPlayerView(player_t *player) #ifdef HWRENDER void R_InitHardwareMode(void) { + HWR_AddCommands(); if (gamestate == GS_LEVEL) { HWR_SetupLevel(); @@ -1432,7 +1433,7 @@ void R_RegisterEngineStuff(void) #endif #ifdef HWRENDER - if (rendermode != render_soft && rendermode != render_none) + if (rendermode == render_opengl) HWR_AddCommands(); #endif } diff --git a/src/sdl/i_video.c b/src/sdl/i_video.c index 45d9e3ed9..163e650b9 100644 --- a/src/sdl/i_video.c +++ b/src/sdl/i_video.c @@ -139,6 +139,7 @@ static SDL_bool borderlesswindow = SDL_FALSE; // SDL2 vars SDL_Window *window; SDL_Renderer *renderer; +static int renderflags; static SDL_Texture *texture; static SDL_bool havefocus = SDL_TRUE; static const char *fallback_resolution_name = "Fallback"; @@ -1260,11 +1261,6 @@ void VID_PrepareModeList(void) #endif } -// SOMETIME IN -// THE FUTURE -// WHEN I ACTUALLY RENDER -// THIS FRAME -static int renderflags; static SDL_bool Impl_CreateContext(int flags) { // Renderer-specific stuff @@ -1308,13 +1304,6 @@ void VID_CheckRenderer(void) { rendermode = setrenderneeded; Impl_CreateContext(renderflags); - if (rendermode == render_soft) - { -#ifdef HWRENDER - HWR_FreeTextureCache(); -#endif - SCR_SetDrawFuncs(); - } } SDLSetMode(vid.width, vid.height, USE_FULLSCREEN); @@ -1327,6 +1316,10 @@ void VID_CheckRenderer(void) bufSurface = NULL; } Impl_VideoSetupBuffer(); +#ifdef HWRENDER + HWR_FreeTextureCache(); +#endif + SCR_SetDrawFuncs(); } else if (rendermode == render_opengl) { @@ -1386,10 +1379,10 @@ static SDL_bool Impl_CreateWindow(SDL_bool fullscreen) if (borderlesswindow) flags |= SDL_WINDOW_BORDERLESS; -#ifdef HWRENDER - if (rendermode == render_opengl) +//#ifdef HWRENDER + //if (rendermode == render_opengl) flags |= SDL_WINDOW_OPENGL; -#endif +//#endif // Create a window window = SDL_CreateWindow("SRB2 "VERSIONSTRING, SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED, diff --git a/src/z_zone.h b/src/z_zone.h index a62555243..edf4c79ba 100644 --- a/src/z_zone.h +++ b/src/z_zone.h @@ -60,6 +60,7 @@ #define PU_HWRPATCHINFO_UNLOCKED 103 void Z_Init(void); +#define Z_FreeTag(tag) Z_FreeTags(tag, tag) void Z_FreeTags(INT32 lowtag, INT32 hightag); void Z_CheckMemCleanup(void); void Z_CheckHeap(INT32 i); From 725d0b4c44fbe88c566220603c56c66dcc787748 Mon Sep 17 00:00:00 2001 From: Jaime Passos Date: Sun, 8 Sep 2019 21:37:24 -0300 Subject: [PATCH 004/746] still making things better --- src/console.c | 5 +- src/f_finale.c | 30 +++++----- src/hardware/hw_bsp.c | 4 +- src/hardware/hw_cache.c | 30 +++++----- src/hardware/hw_glob.h | 1 + src/hardware/hw_main.c | 1 + src/hardware/hw_md2.c | 2 +- src/lua_hudlib.c | 2 +- src/m_menu.c | 5 +- src/p_setup.c | 37 ++++-------- src/r_data.c | 2 - src/r_data.h | 2 - src/r_main.c | 2 +- src/screen.c | 34 ++++++++--- src/sdl/i_video.c | 45 +++++--------- src/w_wad.c | 20 ++----- src/w_wad.h | 1 - src/y_inter.c | 128 ++++++++++++++++++++++++++++++---------- src/z_zone.c | 20 +++++++ src/z_zone.h | 5 ++ 20 files changed, 224 insertions(+), 152 deletions(-) diff --git a/src/console.c b/src/console.c index 826153ff0..6dd3fadff 100644 --- a/src/console.c +++ b/src/console.c @@ -1585,12 +1585,15 @@ void CON_Drawer(void) if (needpatchrecache) { - W_FlushCachedPatches(); + Z_FlushCachedPatches(); HU_LoadGraphics(); } if (con_recalc) + { CON_RecalcSize(); + CON_ClearHUD(); + } if (con_curlines > 0) CON_DrawConsole(); diff --git a/src/f_finale.c b/src/f_finale.c index 58d57948b..b97a6206e 100644 --- a/src/f_finale.c +++ b/src/f_finale.c @@ -1451,21 +1451,21 @@ void F_GameEndTicker(void) // ============== static void F_CacheTitleScreen(void) { - ttbanner = W_CachePatchName("TTBANNER", PU_LEVEL); - ttwing = W_CachePatchName("TTWING", PU_LEVEL); - ttsonic = W_CachePatchName("TTSONIC", PU_LEVEL); - ttswave1 = W_CachePatchName("TTSWAVE1", PU_LEVEL); - ttswave2 = W_CachePatchName("TTSWAVE2", PU_LEVEL); - ttswip1 = W_CachePatchName("TTSWIP1", PU_LEVEL); - ttsprep1 = W_CachePatchName("TTSPREP1", PU_LEVEL); - ttsprep2 = W_CachePatchName("TTSPREP2", PU_LEVEL); - ttspop1 = W_CachePatchName("TTSPOP1", PU_LEVEL); - ttspop2 = W_CachePatchName("TTSPOP2", PU_LEVEL); - ttspop3 = W_CachePatchName("TTSPOP3", PU_LEVEL); - ttspop4 = W_CachePatchName("TTSPOP4", PU_LEVEL); - ttspop5 = W_CachePatchName("TTSPOP5", PU_LEVEL); - ttspop6 = W_CachePatchName("TTSPOP6", PU_LEVEL); - ttspop7 = W_CachePatchName("TTSPOP7", PU_LEVEL); + ttbanner = W_CachePatchName("TTBANNER", PU_PATCH); + ttwing = W_CachePatchName("TTWING", PU_PATCH); + ttsonic = W_CachePatchName("TTSONIC", PU_PATCH); + ttswave1 = W_CachePatchName("TTSWAVE1", PU_PATCH); + ttswave2 = W_CachePatchName("TTSWAVE2", PU_PATCH); + ttswip1 = W_CachePatchName("TTSWIP1", PU_PATCH); + ttsprep1 = W_CachePatchName("TTSPREP1", PU_PATCH); + ttsprep2 = W_CachePatchName("TTSPREP2", PU_PATCH); + ttspop1 = W_CachePatchName("TTSPOP1", PU_PATCH); + ttspop2 = W_CachePatchName("TTSPOP2", PU_PATCH); + ttspop3 = W_CachePatchName("TTSPOP3", PU_PATCH); + ttspop4 = W_CachePatchName("TTSPOP4", PU_PATCH); + ttspop5 = W_CachePatchName("TTSPOP5", PU_PATCH); + ttspop6 = W_CachePatchName("TTSPOP6", PU_PATCH); + ttspop7 = W_CachePatchName("TTSPOP7", PU_PATCH); } void F_StartTitleScreen(void) diff --git a/src/hardware/hw_bsp.c b/src/hardware/hw_bsp.c index 21fd85a33..f8bf84c9a 100644 --- a/src/hardware/hw_bsp.c +++ b/src/hardware/hw_bsp.c @@ -835,8 +835,10 @@ static INT32 SolveTProblem(void) return 0; CONS_Debug(DBG_RENDER, "Solving T-joins. This may take a while. Please wait...\n"); +#ifdef HWR_LOADING_SCREEN CON_Drawer(); //let the user know what we are doing I_FinishUpdate(); // page flip or blit buffer +#endif numsplitpoly = 0; @@ -963,9 +965,9 @@ void HWR_CreatePlanePolygons(INT32 bspnum) CONS_Debug(DBG_RENDER, "Creating polygons, please wait...\n"); #ifdef HWR_LOADING_SCREEN ls_count = ls_percent = 0; // reset the loading status -#endif CON_Drawer(); //let the user know what we are doing I_FinishUpdate(); // page flip or blit buffer +#endif HWR_ClearPolys(); diff --git a/src/hardware/hw_cache.c b/src/hardware/hw_cache.c index 3857ad5d7..0716a130f 100644 --- a/src/hardware/hw_cache.c +++ b/src/hardware/hw_cache.c @@ -571,9 +571,18 @@ static void FreeMipmapColormap(INT32 patchnum, void *patch) } } -void HWR_FreeTextureCache(void) +void HWR_FreeColormaps(void) { INT32 i; + + // Alam: free the Z_Blocks before freeing it's users + // free all skin after each level: must be done after pfnClearMipMapCache! + for (i = 0; i < numwadfiles; i++) + M_AATreeIterate(wadfiles[i]->hwrcache, FreeMipmapColormap); +} + +void HWR_FreeTextureCache(void) +{ // free references to the textures HWD.pfnClearMipMapCache(); @@ -582,15 +591,6 @@ void HWR_FreeTextureCache(void) Z_FreeTags(PU_HWRCACHE, PU_HWRCACHE); Z_FreeTags(PU_HWRCACHE_UNLOCKED, PU_HWRCACHE_UNLOCKED); - // Alam: free the Z_Blocks before freeing it's users - - // free all skin after each level: must be done after pfnClearMipMapCache! - // temp fix, idk why this crashes - // is it because the colormaps were already freed anyway? - if (!needpatchrecache) - for (i = 0; i < numwadfiles; i++) - M_AATreeIterate(wadfiles[i]->hwrcache, FreeMipmapColormap); - // now the heap don't have any 'user' pointing to our // texturecache info, we can free it if (gr_textures) @@ -713,7 +713,7 @@ void HWR_GetFlat(lumpnum_t flatlumpnum) GLMipmap_t *grmip; if (needpatchflush) - W_FlushCachedPatches(); + Z_FlushCachedPatches(); grmip = &HWR_GetCachedGLPatch(flatlumpnum)->mipmap; @@ -752,7 +752,7 @@ static void HWR_LoadMappedPatch(GLMipmap_t *grmip, GLPatch_t *gpatch) void HWR_GetPatch(GLPatch_t *gpatch) { if (needpatchflush) - W_FlushCachedPatches(); + Z_FlushCachedPatches(); // is it in hardware cache if (!gpatch->mipmap.downloaded && !gpatch->mipmap.grInfo.data) @@ -782,7 +782,7 @@ void HWR_GetMappedPatch(GLPatch_t *gpatch, const UINT8 *colormap) GLMipmap_t *grmip, *newmip; if (needpatchflush) - W_FlushCachedPatches(); + Z_FlushCachedPatches(); if (colormap == colormaps || colormap == NULL) { @@ -910,7 +910,7 @@ GLPatch_t *HWR_GetPic(lumpnum_t lumpnum) GLPatch_t *grpatch; if (needpatchflush) - W_FlushCachedPatches(); + Z_FlushCachedPatches(); grpatch = HWR_GetCachedGLPatch(lumpnum); @@ -1110,7 +1110,7 @@ void HWR_GetFadeMask(lumpnum_t fademasklumpnum) GLMipmap_t *grmip; if (needpatchflush) - W_FlushCachedPatches(); + Z_FlushCachedPatches(); grmip = &HWR_GetCachedGLPatch(fademasklumpnum)->mipmap; diff --git a/src/hardware/hw_glob.h b/src/hardware/hw_glob.h index bdf219464..eb00802a3 100644 --- a/src/hardware/hw_glob.h +++ b/src/hardware/hw_glob.h @@ -98,6 +98,7 @@ void HWR_FreePolyPool(void); // -------- void HWR_InitTextureCache(void); void HWR_FreeTextureCache(void); +void HWR_FreeColormaps(void); void HWR_FreeExtraSubsectors(void); void HWR_GetFlat(lumpnum_t flatlumpnum); diff --git a/src/hardware/hw_main.c b/src/hardware/hw_main.c index 4f31b262a..bcda8361e 100644 --- a/src/hardware/hw_main.c +++ b/src/hardware/hw_main.c @@ -6461,6 +6461,7 @@ void HWR_Shutdown(void) HWR_FreeExtraSubsectors(); HWR_FreePolyPool(); HWR_FreeTextureCache(); + HWR_FreeColormaps(); HWD.pfnFlushScreenTextures(); } diff --git a/src/hardware/hw_md2.c b/src/hardware/hw_md2.c index 353e49f81..72ea8a4cf 100644 --- a/src/hardware/hw_md2.c +++ b/src/hardware/hw_md2.c @@ -857,7 +857,7 @@ void HWR_InitMD2(void) } } // no sprite/player skin name found?!? - CONS_Printf("Unknown sprite/player skin %s detected in md2.dat\n", name); + //CONS_Printf("Unknown sprite/player skin %s detected in md2.dat\n", name); md2found: // move on to next line... continue; diff --git a/src/lua_hudlib.c b/src/lua_hudlib.c index b16125395..ba8b3a6d9 100644 --- a/src/lua_hudlib.c +++ b/src/lua_hudlib.c @@ -334,7 +334,7 @@ static int libd_patchExists(lua_State *L) static int libd_cachePatch(lua_State *L) { HUDONLY - LUA_PushUserdata(L, W_CachePatchName(luaL_checkstring(L, 1), PU_STATIC), META_PATCH); + LUA_PushUserdata(L, W_CachePatchName(luaL_checkstring(L, 1), PU_PATCH), META_PATCH); return 1; } diff --git a/src/m_menu.c b/src/m_menu.c index 8ae341e31..9a55ced4b 100644 --- a/src/m_menu.c +++ b/src/m_menu.c @@ -2481,6 +2481,9 @@ void M_Drawer(void) if (currentMenu == &MessageDef) menuactive = true; + if (needpatchrecache) + R_ReloadHUDGraphics(); + if (menuactive) { // now that's more readable with a faded background (yeah like Quake...) @@ -5709,7 +5712,7 @@ static void M_DrawLevelStats(void) V_DrawCenteredString(BASEVIDWIDTH/2, 24, V_YELLOWMAP, "PAGE 2 OF 2"); V_DrawString(72, 48, 0, va("x %d/%d", M_CountEmblems(), numemblems+numextraemblems)); - V_DrawScaledPatch(40, 48-4, 0, W_CachePatchName("EMBLICON", PU_STATIC)); + V_DrawScaledPatch(40, 48-4, 0, W_CachePatchName("EMBLICON", PU_PATCH)); M_DrawStatsMaps(statsLocation); } diff --git a/src/p_setup.c b/src/p_setup.c index 0058f7def..82b9eb691 100644 --- a/src/p_setup.c +++ b/src/p_setup.c @@ -1424,7 +1424,6 @@ static void P_LoadRawSideDefs2(void *data) case 606: //SoM: 4/4/2000: Just colormap transfer // SoM: R_CreateColormap will only create a colormap in software mode... // Perhaps we should just call it instead of doing the calculations here. - if (rendermode == render_soft || rendermode == render_none) { if (msd->toptexture[0] == '#' || msd->bottomtexture[0] == '#') { @@ -1447,11 +1446,6 @@ static void P_LoadRawSideDefs2(void *data) else sd->bottomtexture = num; } - break; - } -#ifdef HWRENDER - else - { // for now, full support of toptexture only if ((msd->toptexture[0] == '#' && msd->toptexture[1] && msd->toptexture[2] && msd->toptexture[3] && msd->toptexture[4] && msd->toptexture[5] && msd->toptexture[6]) || (msd->bottomtexture[0] == '#' && msd->bottomtexture[1] && msd->bottomtexture[2] && msd->bottomtexture[3] && msd->bottomtexture[4] && msd->bottomtexture[5] && msd->bottomtexture[6])) @@ -1503,26 +1497,8 @@ static void P_LoadRawSideDefs2(void *data) #undef ALPHA2INT #undef HEX2INT } - else - { - if ((num = R_CheckTextureNumForName(msd->toptexture)) == -1) - sd->toptexture = 0; - else - sd->toptexture = num; - - if ((num = R_CheckTextureNumForName(msd->midtexture)) == -1) - sd->midtexture = 0; - else - sd->midtexture = num; - - if ((num = R_CheckTextureNumForName(msd->bottomtexture)) == -1) - sd->bottomtexture = 0; - else - sd->bottomtexture = num; - } break; } -#endif case 413: // Change music { @@ -2967,6 +2943,12 @@ boolean P_SetupLevel(boolean skipprecip) globalweather = mapheaderinfo[gamemap-1]->weather; #ifdef HWRENDER // not win32 only 19990829 by Kin + // gotta free this regardless of rendermode. + // maybe we're not in opengl anymore....... + if (extrasubsectors) + free(extrasubsectors); + extrasubsectors = NULL; + // stuff like HWR_CreatePlanePolygons is called there if (rendermode == render_opengl) HWR_SetupLevel(); #endif @@ -3116,7 +3098,10 @@ boolean P_SetupLevel(boolean skipprecip) // preload graphics #ifdef HWRENDER // not win32 only 19990829 by Kin if (rendermode == render_opengl) + { HWR_PrepLevelCache(numtextures); + //HWR_FreeColormaps(); + } #endif P_MapEnd(); @@ -3180,7 +3165,9 @@ void HWR_SetupLevel(void) #endif // Correct missing sidedefs & deep water trick HWR_CorrectSWTricks(); - HWR_CreatePlanePolygons((INT32)numnodes - 1); + // don't do it twice... + if (!extrasubsectors) + HWR_CreatePlanePolygons((INT32)numnodes - 1); } #endif diff --git a/src/r_data.c b/src/r_data.c index cd50272b0..a487601a3 100644 --- a/src/r_data.c +++ b/src/r_data.c @@ -95,8 +95,6 @@ size_t numspritelumps, max_spritelumps; // textures INT32 numtextures = 0; // total number of textures found, -boolean needpatchflush = false; -boolean needpatchrecache = false; // size of following tables texture_t **textures = NULL; diff --git a/src/r_data.h b/src/r_data.h index e6229d6c8..5de51ccd4 100644 --- a/src/r_data.h +++ b/src/r_data.h @@ -96,7 +96,5 @@ INT32 R_CreateColormap(char *p1, char *p2, char *p3); const char *R_ColormapNameForNum(INT32 num); extern INT32 numtextures; -extern boolean needpatchflush; -extern boolean needpatchrecache; #endif diff --git a/src/r_main.c b/src/r_main.c index f7678b928..d7196427c 100644 --- a/src/r_main.c +++ b/src/r_main.c @@ -1353,7 +1353,7 @@ void R_InitHardwareMode(void) void R_ReloadHUDGraphics(void) { - W_FlushCachedPatches(); + Z_FlushCachedPatches(); ST_LoadGraphics(); HU_LoadGraphics(); ST_ReloadSkinFaceGraphics(); diff --git a/src/screen.c b/src/screen.c index d485a6367..7c8bfb14a 100644 --- a/src/screen.c +++ b/src/screen.c @@ -72,11 +72,12 @@ consvar_t cv_scr_depth = {"scr_depth", "16 bits", CV_SAVE, scr_depth_cons_t, NUL #endif consvar_t cv_renderview = {"renderview", "On", 0, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL}; -static void SCR_ChangeRenderer (void); +static void SCR_ChangeRenderer(void); +static void SCR_ActuallyChangeRenderer(void); static CV_PossibleValue_t cv_renderer_t[] = {{1, "Software"}, {2, "OpenGL"}, {0, NULL}}; -consvar_t cv_renderer = {"renderer", "Software", CV_CALL, cv_renderer_t, SCR_ChangeRenderer, 0, NULL, NULL, 0, 0, NULL}; +consvar_t cv_renderer = {"renderer", "Software", CV_SAVE|CV_CALL, cv_renderer_t, SCR_ChangeRenderer, 0, NULL, NULL, 0, 0, NULL}; -static void SCR_ChangeFullscreen (void); +static void SCR_ChangeFullscreen(void); consvar_t cv_fullscreen = {"fullscreen", "Yes", CV_SAVE|CV_CALL, CV_YesNo, SCR_ChangeFullscreen, 0, NULL, NULL, 0, 0, NULL}; @@ -376,6 +377,8 @@ void SCR_CheckDefaultMode(void) // see note above setmodeneeded = VID_GetModeForSize(cv_scr_width.value, cv_scr_height.value) + 1; } + + SCR_ActuallyChangeRenderer(); } // sets the modenum as the new default video mode to be saved in the config file @@ -405,12 +408,28 @@ void SCR_ChangeFullscreen(void) #endif } +static int target_renderer = 0; + +void SCR_ActuallyChangeRenderer(void) +{ + setrenderneeded = target_renderer; + // setting the same renderer twice WILL crash your game, so let's not, please + if (rendermode == setrenderneeded) + setrenderneeded = 0; +} + void SCR_ChangeRenderer(void) { setrenderneeded = 0; if (con_startup) { + target_renderer = cv_renderer.value; + if (M_CheckParm("-opengl")) + target_renderer = rendermode = render_opengl; + else if (M_CheckParm("-software")) + target_renderer = rendermode = render_soft; + // set cv_renderer back if (rendermode == render_soft) CV_StealthSetValue(&cv_renderer, 1); else if (rendermode == render_opengl) @@ -419,13 +438,10 @@ void SCR_ChangeRenderer(void) } if (cv_renderer.value == 1) - setrenderneeded = render_soft; + target_renderer = render_soft; else if (cv_renderer.value == 2) - setrenderneeded = render_opengl; - - // setting the same renderer twice WILL crash your game, so let's not, please - if (rendermode == setrenderneeded) - setrenderneeded = 0; + target_renderer = render_opengl; + SCR_ActuallyChangeRenderer(); } boolean SCR_IsAspectCorrect(INT32 width, INT32 height) diff --git a/src/sdl/i_video.c b/src/sdl/i_video.c index 163e650b9..7c068205d 100644 --- a/src/sdl/i_video.c +++ b/src/sdl/i_video.c @@ -139,7 +139,6 @@ static SDL_bool borderlesswindow = SDL_FALSE; // SDL2 vars SDL_Window *window; SDL_Renderer *renderer; -static int renderflags; static SDL_Texture *texture; static SDL_bool havefocus = SDL_TRUE; static const char *fallback_resolution_name = "Fallback"; @@ -1261,7 +1260,7 @@ void VID_PrepareModeList(void) #endif } -static SDL_bool Impl_CreateContext(int flags) +static SDL_bool Impl_CreateContext(void) { // Renderer-specific stuff #ifdef HWRENDER @@ -1280,7 +1279,7 @@ static SDL_bool Impl_CreateContext(int flags) #endif if (rendermode == render_soft) { - flags = 0; // Use this to set SDL_RENDERER_* flags now + int flags = 0; // Use this to set SDL_RENDERER_* flags now if (usesdl2soft) flags |= SDL_RENDERER_SOFTWARE; else if (cv_vidwait.value) @@ -1300,10 +1299,13 @@ static SDL_bool Impl_CreateContext(int flags) void VID_CheckRenderer(void) { + if (dedicated) + return; + if (setrenderneeded) { rendermode = setrenderneeded; - Impl_CreateContext(renderflags); + Impl_CreateContext(); } SDLSetMode(vid.width, vid.height, USE_FULLSCREEN); @@ -1335,29 +1337,15 @@ INT32 VID_SetMode(INT32 modeNum) vid.recalc = 1; vid.bpp = 1; - if (modeNum >= 0 && modeNum < MAXWINMODES) - { - vid.width = windowedModes[modeNum][0]; - vid.height = windowedModes[modeNum][1]; - vid.modenum = modeNum; - } - else - { - // just set the desktop resolution as a fallback - SDL_DisplayMode mode; - SDL_GetWindowDisplayMode(window, &mode); - if (mode.w >= 2048) - { - vid.width = 1920; - vid.height = 1200; - } - else - { - vid.width = mode.w; - vid.height = mode.h; - } - vid.modenum = -1; - } + if (modeNum < 0) + modeNum = 0; + if (modeNum >= MAXWINMODES) + modeNum = MAXWINMODES-1; + + vid.width = windowedModes[modeNum][0]; + vid.height = windowedModes[modeNum][1]; + vid.modenum = modeNum; + //Impl_SetWindowName("SRB2 "VERSIONSTRING); VID_CheckRenderer(); return SDL_TRUE; @@ -1394,8 +1382,7 @@ static SDL_bool Impl_CreateWindow(SDL_bool fullscreen) return SDL_FALSE; } - renderflags = flags; - return Impl_CreateContext(flags); + return Impl_CreateContext(); } /* diff --git a/src/w_wad.c b/src/w_wad.c index 00797b87d..96381635a 100644 --- a/src/w_wad.c +++ b/src/w_wad.c @@ -831,7 +831,10 @@ void W_UnloadWadFile(UINT16 num) numwadfiles--; #ifdef HWRENDER if (rendermode != render_soft && rendermode != render_none) + { HWR_FreeTextureCache(); + HWR_FreeColormaps(); + } M_AATreeFree(delwad->hwrcache); #endif if (*lumpcache) @@ -1503,21 +1506,6 @@ void *W_CacheLumpName(const char *name, INT32 tag) // Cache a patch into heap memory, convert the patch format as necessary // -void W_FlushCachedPatches(void) -{ - if (needpatchflush) - { - Z_FreeTag(PU_CACHE); - Z_FreeTag(PU_PATCH); - Z_FreeTag(PU_HUDGFX); - Z_FreeTag(PU_HWRPATCHINFO); - Z_FreeTag(PU_HWRPATCHCOLMIPMAP); - Z_FreeTag(PU_HWRCACHE); - Z_FreeTags(PU_HWRCACHE_UNLOCKED, PU_HWRPATCHINFO_UNLOCKED); - } - needpatchflush = false; -} - // Software-only compile cache the data without conversion #ifdef HWRENDER static inline void *W_CachePatchNumPwad(UINT16 wad, UINT16 lump, INT32 tag) @@ -1525,7 +1513,7 @@ static inline void *W_CachePatchNumPwad(UINT16 wad, UINT16 lump, INT32 tag) GLPatch_t *grPatch; if (needpatchflush) - W_FlushCachedPatches(); + Z_FlushCachedPatches(); if (rendermode == render_soft || rendermode == render_none) return W_CacheLumpNumPwad(wad, lump, tag); diff --git a/src/w_wad.h b/src/w_wad.h index 84e921e75..87566c3ee 100644 --- a/src/w_wad.h +++ b/src/w_wad.h @@ -183,7 +183,6 @@ void *W_CachePatchNum(lumpnum_t lumpnum, INT32 tag); // return a patch_t #endif void W_UnlockCachedPatch(void *patch); -void W_FlushCachedPatches(void); void W_VerifyFileMD5(UINT16 wadfilenum, const char *matchmd5); diff --git a/src/y_inter.c b/src/y_inter.c index ab0af490d..ab27a00fe 100644 --- a/src/y_inter.c +++ b/src/y_inter.c @@ -144,6 +144,7 @@ static patch_t *interpic = NULL; // custom picture defined in map header static boolean usetile; boolean usebuffer = false; static boolean useinterpic; +static boolean safetorender = true; static INT32 timer; static INT32 intertic; @@ -158,6 +159,7 @@ static void Y_CalculateTimeRaceWinners(void); static void Y_CalculateMatchWinners(void); static void Y_FollowIntermission(void); static void Y_UnloadData(void); +static void Y_CleanupData(void); // Stuff copy+pasted from st_stuff.c static INT32 SCX(INT32 x) @@ -187,31 +189,41 @@ void Y_IntermissionDrawer(void) if (intertype == int_none || rendermode == render_none) return; - if (!usebuffer) + if (needpatchrecache) + { + Y_CleanupData(); + R_ReloadHUDGraphics(); + safetorender = false; + } + + if (!usebuffer || !safetorender) V_DrawFill(0, 0, BASEVIDWIDTH, BASEVIDHEIGHT, 31); - if (useinterpic) - V_DrawScaledPatch(0, 0, 0, interpic); - else if (!usetile) + if (safetorender) { - if (rendermode == render_soft && usebuffer) - VID_BlitLinearScreen(screens[1], screens[0], vid.width*vid.bpp, vid.height, vid.width*vid.bpp, vid.rowbytes); + if (useinterpic) + V_DrawScaledPatch(0, 0, 0, interpic); + else if (!usetile) + { + if (rendermode == render_soft && usebuffer) + VID_BlitLinearScreen(screens[1], screens[0], vid.width*vid.bpp, vid.height, vid.width*vid.bpp, vid.rowbytes); #ifdef HWRENDER - else if(rendermode != render_soft && usebuffer) - { - HWR_DrawIntermissionBG(); - } + else if(rendermode != render_soft && usebuffer) + { + HWR_DrawIntermissionBG(); + } #endif - else - { - if (widebgpatch && rendermode == render_soft && vid.width / vid.dupx == 400) - V_DrawScaledPatch(0, 0, V_SNAPTOLEFT, widebgpatch); else - V_DrawScaledPatch(0, 0, 0, bgpatch); + { + if (widebgpatch && rendermode == render_soft && vid.width / vid.dupx == 400) + V_DrawScaledPatch(0, 0, V_SNAPTOLEFT, widebgpatch); + else + V_DrawScaledPatch(0, 0, 0, bgpatch); + } } + else + V_DrawPatchFill(bgtile); } - else - V_DrawPatchFill(bgtile); if (intertype == int_coop) { @@ -249,19 +261,22 @@ void Y_IntermissionDrawer(void) V_DrawLevelTitle(data.coop.passedx1, 49, 0, data.coop.passed1); V_DrawLevelTitle(data.coop.passedx2, 49+V_LevelNameHeight(data.coop.passed2)+2, 0, data.coop.passed2); - if (mapheaderinfo[gamemap-1]->actnum) + if (mapheaderinfo[gamemap-1]->actnum && safetorender) V_DrawScaledPatch(244, 57, 0, data.coop.ttlnum); bonusy = 150; // Total - V_DrawScaledPatch(152, bonusy, 0, data.coop.ptotal); - V_DrawTallNum(BASEVIDWIDTH - 68, bonusy + 1, 0, data.coop.total); + if (safetorender) + { + V_DrawScaledPatch(152, bonusy, 0, data.coop.ptotal); + V_DrawTallNum(BASEVIDWIDTH - 68, bonusy + 1, 0, data.coop.total); + } bonusy -= (3*SHORT(tallnum[0]->height)/2) + 1; // Draw bonuses for (i = 3; i >= 0; --i) { - if (data.coop.bonuses[i].display) + if (data.coop.bonuses[i].display && safetorender) { V_DrawScaledPatch(152, bonusy, 0, data.coop.bonuspatches[i]); V_DrawTallNum(BASEVIDWIDTH - 68, bonusy + 1, 0, data.coop.bonuses[i].points); @@ -340,13 +355,16 @@ void Y_IntermissionDrawer(void) } } - V_DrawScaledPatch(152, 108, 0, data.spec.bonuspatch); - V_DrawTallNum(BASEVIDWIDTH - 68, 109, 0, data.spec.bonus.points); - V_DrawScaledPatch(152, 124, 0, data.spec.pscore); - V_DrawTallNum(BASEVIDWIDTH - 68, 125, 0, data.spec.score); + if (safetorender) + { + V_DrawScaledPatch(152, 108, 0, data.spec.bonuspatch); + V_DrawTallNum(BASEVIDWIDTH - 68, 109, 0, data.spec.bonus.points); + V_DrawScaledPatch(152, 124, 0, data.spec.pscore); + V_DrawTallNum(BASEVIDWIDTH - 68, 125, 0, data.spec.score); + } // Draw continues! - if (!multiplayer /* && (data.spec.continues & 0x80) */) // Always draw outside of netplay + if (!multiplayer && safetorender /* && (data.spec.continues & 0x80) */) // Always draw outside of netplay { UINT8 continues = data.spec.continues & 0x7F; @@ -368,7 +386,8 @@ void Y_IntermissionDrawer(void) char strtime[10]; // draw the header - V_DrawScaledPatch(112, 2, 0, data.match.result); + if (safetorender) + V_DrawScaledPatch(112, 2, 0, data.match.result); // draw the level name V_DrawCenteredString(BASEVIDWIDTH/2, 20, 0, data.match.levelstring); @@ -959,6 +978,8 @@ void Y_StartIntermission(void) I_Error("endtic is dirty"); #endif + safetorender = true; + if (!multiplayer) { timer = 0; @@ -1057,9 +1078,9 @@ void Y_StartIntermission(void) // get act number if (mapheaderinfo[prevmap]->actnum) data.coop.ttlnum = W_CachePatchName(va("TTL%.2d", mapheaderinfo[prevmap]->actnum), - PU_STATIC); + PU_PATCH); else - data.coop.ttlnum = W_CachePatchName("TTL01", PU_STATIC); + data.coop.ttlnum = W_CachePatchName("TTL01", PU_PATCH); // get background patches widebgpatch = W_CachePatchName("INTERSCW", PU_PATCH); @@ -1178,7 +1199,7 @@ void Y_StartIntermission(void) data.spec.cemerald = W_CachePatchName("GOTEMALL", PU_PATCH); data.spec.headx = 70; data.spec.nowsuper = players[consoleplayer].skin - ? NULL : W_CachePatchName("NOWSUPER", PU_STATIC); + ? NULL : W_CachePatchName("NOWSUPER", PU_PATCH); } else { @@ -1835,7 +1856,8 @@ static void Y_FollowIntermission(void) G_AfterIntermission(); } -#define UNLOAD(x) Z_ChangeTag(x, PU_CACHE); x = NULL +#define UNLOAD(x) if (x) {Z_ChangeTag(x, PU_CACHE);} x = NULL; +#define CLEANUP(x) x = NULL; // // Y_UnloadData @@ -1886,5 +1908,47 @@ static void Y_UnloadData(void) //are not handled break; } - +} + +static void Y_CleanupData(void) +{ + // unload the background patches + CLEANUP(bgpatch); + CLEANUP(widebgpatch); + CLEANUP(bgtile); + CLEANUP(interpic); + + switch (intertype) + { + case int_coop: + // unload the coop and single player patches + CLEANUP(data.coop.ttlnum); + CLEANUP(data.coop.bonuspatches[3]); + CLEANUP(data.coop.bonuspatches[2]); + CLEANUP(data.coop.bonuspatches[1]); + CLEANUP(data.coop.bonuspatches[0]); + CLEANUP(data.coop.ptotal); + break; + case int_spec: + // unload the special stage patches + //CLEANUP(data.spec.cemerald); + //CLEANUP(data.spec.nowsuper); + CLEANUP(data.spec.bonuspatch); + CLEANUP(data.spec.pscore); + CLEANUP(data.spec.pcontinues); + break; + case int_match: + case int_race: + CLEANUP(data.match.result); + break; + case int_ctf: + CLEANUP(data.match.blueflag); + CLEANUP(data.match.redflag); + break; + default: + //without this default, + //int_none, int_tag, int_chaos, and int_classicrace + //are not handled + break; + } } diff --git a/src/z_zone.c b/src/z_zone.c index a3e13422f..add18b568 100644 --- a/src/z_zone.c +++ b/src/z_zone.c @@ -411,6 +411,26 @@ void Z_FreeTags(INT32 lowtag, INT32 hightag) } } +// for renderer switching, free a bunch of stuff +boolean needpatchflush = false; +boolean needpatchrecache = false; + +void Z_FlushCachedPatches(void) +{ + if (needpatchflush) + { + Z_FreeTag(PU_CACHE); + Z_FreeTag(PU_PATCH); + Z_FreeTag(PU_HUDGFX); + Z_FreeTag(PU_HWRPATCHINFO); + Z_FreeTag(PU_HWRPATCHCOLMIPMAP); + Z_FreeTag(PU_HWRCACHE); + Z_FreeTag(PU_HWRCACHE_UNLOCKED); + Z_FreeTag(PU_HWRPATCHINFO_UNLOCKED); + } + needpatchflush = false; +} + // // Z_CheckMemCleanup // diff --git a/src/z_zone.h b/src/z_zone.h index edf4c79ba..700e3a1d5 100644 --- a/src/z_zone.h +++ b/src/z_zone.h @@ -70,6 +70,11 @@ void Z_ChangeTag2(void *ptr, INT32 tag, const char *file, INT32 line); void Z_ChangeTag2(void *ptr, INT32 tag); #endif +// for renderer switching, free a bunch of stuff +extern boolean needpatchflush; +extern boolean needpatchrecache; +void Z_FlushCachedPatches(void); + #ifdef PARANOIA void Z_SetUser2(void *ptr, void **newuser, const char *file, INT32 line); #else From dc93cafda9a0b3e5221e2041d2d668eebc550701 Mon Sep 17 00:00:00 2001 From: Jaime Passos Date: Sun, 8 Sep 2019 22:25:18 -0300 Subject: [PATCH 005/746] can i push this already? --- src/android/i_video.c | 1 + src/console.c | 6 +- src/d_main.c | 3 + src/djgppdos/i_video.c | 5 ++ src/dummy/i_video.c | 1 + src/i_video.h | 1 + src/nds/i_video.c | 41 ++++++++------ src/sdl/i_video.c | 106 ++++++++++++++++++------------------ src/sdl12/i_video.c | 121 ++++++++++++++++++++++------------------- src/win32/win_vid.c | 5 ++ src/win32ce/win_vid.c | 5 ++ 11 files changed, 164 insertions(+), 131 deletions(-) diff --git a/src/android/i_video.c b/src/android/i_video.c index 44e1cbac0..b8bb4fefb 100644 --- a/src/android/i_video.c +++ b/src/android/i_video.c @@ -19,6 +19,7 @@ boolean allow_fullscreen = false; consvar_t cv_vidwait = {"vid_wait", "On", CV_SAVE, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL}; void I_StartupGraphics(void){} +void I_StartupHardwareGraphics(void){} void I_ShutdownGraphics(void){} diff --git a/src/console.c b/src/console.c index 6dd3fadff..1ac181086 100644 --- a/src/console.c +++ b/src/console.c @@ -23,6 +23,7 @@ #include "g_input.h" #include "hu_stuff.h" #include "keys.h" +#include "r_main.h" #include "r_defs.h" #include "sounds.h" #include "st_stuff.h" @@ -1584,10 +1585,7 @@ void CON_Drawer(void) return; if (needpatchrecache) - { - Z_FlushCachedPatches(); - HU_LoadGraphics(); - } + R_ReloadHUDGraphics(); if (con_recalc) { diff --git a/src/d_main.c b/src/d_main.c index 06489ac7c..c84d6e7a2 100644 --- a/src/d_main.c +++ b/src/d_main.c @@ -495,6 +495,9 @@ static void D_Display(void) I_FinishUpdate(); // page flip or blit buffer } + // in the occasion no functions + // that require patches to be cached + // have been called. if (needpatchrecache) R_ReloadHUDGraphics(); diff --git a/src/djgppdos/i_video.c b/src/djgppdos/i_video.c index 612c72215..1658fa52b 100644 --- a/src/djgppdos/i_video.c +++ b/src/djgppdos/i_video.c @@ -331,3 +331,8 @@ void I_StartupGraphics(void) graphics_started = true; } + +void I_StartupHardwareGraphics(void) +{ + // oh yeah woo yeah oh yeah woo yeah oh yeah woo yeah oh yeah woo yeah oh yeah woo yeah oh yeah woo yeah oh yeah woo y +} diff --git a/src/dummy/i_video.c b/src/dummy/i_video.c index b8f40bed3..fafeee000 100644 --- a/src/dummy/i_video.c +++ b/src/dummy/i_video.c @@ -11,6 +11,7 @@ boolean allow_fullscreen = false; consvar_t cv_vidwait = {"vid_wait", "On", CV_SAVE, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL}; void I_StartupGraphics(void){} +void I_StartupHardwareGraphics(void){} void I_ShutdownGraphics(void){} diff --git a/src/i_video.h b/src/i_video.h index a62f3ff64..c57977306 100644 --- a/src/i_video.h +++ b/src/i_video.h @@ -44,6 +44,7 @@ extern boolean highcolor; /** \brief setup video mode */ void I_StartupGraphics(void); +void I_StartupHardwareGraphics(void); /** \brief restore old video mode */ diff --git a/src/nds/i_video.c b/src/nds/i_video.c index 3dfb99557..8ec1997fa 100644 --- a/src/nds/i_video.c +++ b/src/nds/i_video.c @@ -42,24 +42,7 @@ void I_StartupGraphics(void) vid.rowbytes = vid.width * vid.bpp; vid.recalc = true; - HWD.pfnInit = NDS3D_Init; - HWD.pfnShutdown = NDS3D_Shutdown; - HWD.pfnFinishUpdate = NDS3D_FinishUpdate; - HWD.pfnDraw2DLine = NDS3D_Draw2DLine; - HWD.pfnDrawPolygon = NDS3D_DrawPolygon; - HWD.pfnSetBlend = NDS3D_SetBlend; - HWD.pfnClearBuffer = NDS3D_ClearBuffer; - HWD.pfnSetTexture = NDS3D_SetTexture; - HWD.pfnReadRect = NDS3D_ReadRect; - HWD.pfnGClipRect = NDS3D_GClipRect; - HWD.pfnClearMipMapCache = NDS3D_ClearMipMapCache; - HWD.pfnSetSpecialState = NDS3D_SetSpecialState; - HWD.pfnSetPalette = NDS3D_SetPalette; - HWD.pfnGetTextureUsed = NDS3D_GetTextureUsed; - HWD.pfnDrawMD2 = NDS3D_DrawMD2; - HWD.pfnDrawMD2i = NDS3D_DrawMD2i; - HWD.pfnSetTransform = NDS3D_SetTransform; - HWD.pfnGetRenderVersion = NDS3D_GetRenderVersion; + I_StartupGraphicsHardware(); videoSetMode(MODE_0_3D); vramSetBankA(VRAM_A_TEXTURE); @@ -91,6 +74,28 @@ void I_StartupGraphics(void) HWR_Startup(); } +void I_StartupHardwareGraphics(void) +{ + HWD.pfnInit = NDS3D_Init; + HWD.pfnShutdown = NDS3D_Shutdown; + HWD.pfnFinishUpdate = NDS3D_FinishUpdate; + HWD.pfnDraw2DLine = NDS3D_Draw2DLine; + HWD.pfnDrawPolygon = NDS3D_DrawPolygon; + HWD.pfnSetBlend = NDS3D_SetBlend; + HWD.pfnClearBuffer = NDS3D_ClearBuffer; + HWD.pfnSetTexture = NDS3D_SetTexture; + HWD.pfnReadRect = NDS3D_ReadRect; + HWD.pfnGClipRect = NDS3D_GClipRect; + HWD.pfnClearMipMapCache = NDS3D_ClearMipMapCache; + HWD.pfnSetSpecialState = NDS3D_SetSpecialState; + HWD.pfnSetPalette = NDS3D_SetPalette; + HWD.pfnGetTextureUsed = NDS3D_GetTextureUsed; + HWD.pfnDrawMD2 = NDS3D_DrawMD2; + HWD.pfnDrawMD2i = NDS3D_DrawMD2i; + HWD.pfnSetTransform = NDS3D_SetTransform; + HWD.pfnGetRenderVersion = NDS3D_GetRenderVersion; +} + void I_ShutdownGraphics(void){} void I_SetPalette(RGBA_t *palette) diff --git a/src/sdl/i_video.c b/src/sdl/i_video.c index 7c068205d..4c2078b38 100644 --- a/src/sdl/i_video.c +++ b/src/sdl/i_video.c @@ -171,7 +171,6 @@ static void Impl_VideoSetupBuffer(void); static SDL_bool Impl_CreateWindow(SDL_bool fullscreen); //static void Impl_SetWindowName(const char *title); static void Impl_SetWindowIcon(void); -static void I_StartupGraphicsGL(void); static void SDLSetMode(INT32 width, INT32 height, SDL_bool fullscreen) { @@ -1323,11 +1322,13 @@ void VID_CheckRenderer(void) #endif SCR_SetDrawFuncs(); } +#ifdef HWRENDER else if (rendermode == render_opengl) { - I_StartupGraphicsGL(); + I_StartupHardwareGraphics(); R_InitHardwareMode(); } +#endif } INT32 VID_SetMode(INT32 modeNum) @@ -1367,10 +1368,9 @@ static SDL_bool Impl_CreateWindow(SDL_bool fullscreen) if (borderlesswindow) flags |= SDL_WINDOW_BORDERLESS; -//#ifdef HWRENDER - //if (rendermode == render_opengl) - flags |= SDL_WINDOW_OPENGL; -//#endif +#ifdef HWRENDER + flags |= SDL_WINDOW_OPENGL; +#endif // Create a window window = SDL_CreateWindow("SRB2 "VERSIONSTRING, SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED, @@ -1451,51 +1451,6 @@ static void Impl_VideoSetupBuffer(void) } } -static void I_StartupGraphicsGL(void) -{ -#ifdef HWRENDER - static boolean glstartup = false; - if (!glstartup) - { - HWD.pfnInit = hwSym("Init",NULL); - HWD.pfnFinishUpdate = NULL; - HWD.pfnDraw2DLine = hwSym("Draw2DLine",NULL); - HWD.pfnDrawPolygon = hwSym("DrawPolygon",NULL); - HWD.pfnSetBlend = hwSym("SetBlend",NULL); - HWD.pfnClearBuffer = hwSym("ClearBuffer",NULL); - HWD.pfnSetTexture = hwSym("SetTexture",NULL); - HWD.pfnReadRect = hwSym("ReadRect",NULL); - HWD.pfnGClipRect = hwSym("GClipRect",NULL); - HWD.pfnClearMipMapCache = hwSym("ClearMipMapCache",NULL); - HWD.pfnSetSpecialState = hwSym("SetSpecialState",NULL); - HWD.pfnSetPalette = hwSym("SetPalette",NULL); - HWD.pfnGetTextureUsed = hwSym("GetTextureUsed",NULL); - HWD.pfnDrawMD2 = hwSym("DrawMD2",NULL); - HWD.pfnDrawMD2i = hwSym("DrawMD2i",NULL); - HWD.pfnSetTransform = hwSym("SetTransform",NULL); - HWD.pfnGetRenderVersion = hwSym("GetRenderVersion",NULL); -#ifdef SHUFFLE - HWD.pfnPostImgRedraw = hwSym("PostImgRedraw",NULL); -#endif - HWD.pfnFlushScreenTextures=hwSym("FlushScreenTextures",NULL); - HWD.pfnStartScreenWipe = hwSym("StartScreenWipe",NULL); - HWD.pfnEndScreenWipe = hwSym("EndScreenWipe",NULL); - HWD.pfnDoScreenWipe = hwSym("DoScreenWipe",NULL); - HWD.pfnDrawIntermissionBG=hwSym("DrawIntermissionBG",NULL); - HWD.pfnMakeScreenTexture= hwSym("MakeScreenTexture",NULL); - HWD.pfnMakeScreenFinalTexture=hwSym("MakeScreenFinalTexture",NULL); - HWD.pfnDrawScreenFinalTexture=hwSym("DrawScreenFinalTexture",NULL); - // check gl renderer lib - if (HWD.pfnGetRenderVersion() != VERSION) - I_Error("%s", M_GetText("The version of the renderer doesn't match the version of the executable\nBe sure you have installed SRB2 properly.\n")); - if (!HWD.pfnInit(I_Error)) // let load the OpenGL library - rendermode = render_soft; - else - glstartup = true; - } -#endif -} - void I_StartupGraphics(void) { if (dedicated) @@ -1537,9 +1492,11 @@ void I_StartupGraphics(void) framebuffer = SDL_TRUE; } +#ifdef HWRENDER if (M_CheckParm("-opengl")) rendermode = render_opengl; else if (M_CheckParm("software")) +#endif rendermode = render_soft; usesdl2soft = M_CheckParm("-softblit"); @@ -1548,7 +1505,7 @@ void I_StartupGraphics(void) //SDL_EnableKeyRepeat(SDL_DEFAULT_REPEAT_DELAY>>1,SDL_DEFAULT_REPEAT_INTERVAL<<2); VID_Command_ModeList_f(); #ifdef HWRENDER - I_StartupGraphicsGL(); + I_StartupHardwareGraphics(); #endif // Fury: we do window initialization after GL setup to allow @@ -1608,6 +1565,51 @@ void I_StartupGraphics(void) graphics_started = true; } +void I_StartupHardwareGraphics(void) +{ +#ifdef HWRENDER + static boolean glstartup = false; + if (!glstartup) + { + HWD.pfnInit = hwSym("Init",NULL); + HWD.pfnFinishUpdate = NULL; + HWD.pfnDraw2DLine = hwSym("Draw2DLine",NULL); + HWD.pfnDrawPolygon = hwSym("DrawPolygon",NULL); + HWD.pfnSetBlend = hwSym("SetBlend",NULL); + HWD.pfnClearBuffer = hwSym("ClearBuffer",NULL); + HWD.pfnSetTexture = hwSym("SetTexture",NULL); + HWD.pfnReadRect = hwSym("ReadRect",NULL); + HWD.pfnGClipRect = hwSym("GClipRect",NULL); + HWD.pfnClearMipMapCache = hwSym("ClearMipMapCache",NULL); + HWD.pfnSetSpecialState = hwSym("SetSpecialState",NULL); + HWD.pfnSetPalette = hwSym("SetPalette",NULL); + HWD.pfnGetTextureUsed = hwSym("GetTextureUsed",NULL); + HWD.pfnDrawMD2 = hwSym("DrawMD2",NULL); + HWD.pfnDrawMD2i = hwSym("DrawMD2i",NULL); + HWD.pfnSetTransform = hwSym("SetTransform",NULL); + HWD.pfnGetRenderVersion = hwSym("GetRenderVersion",NULL); +#ifdef SHUFFLE + HWD.pfnPostImgRedraw = hwSym("PostImgRedraw",NULL); +#endif + HWD.pfnFlushScreenTextures=hwSym("FlushScreenTextures",NULL); + HWD.pfnStartScreenWipe = hwSym("StartScreenWipe",NULL); + HWD.pfnEndScreenWipe = hwSym("EndScreenWipe",NULL); + HWD.pfnDoScreenWipe = hwSym("DoScreenWipe",NULL); + HWD.pfnDrawIntermissionBG=hwSym("DrawIntermissionBG",NULL); + HWD.pfnMakeScreenTexture= hwSym("MakeScreenTexture",NULL); + HWD.pfnMakeScreenFinalTexture=hwSym("MakeScreenFinalTexture",NULL); + HWD.pfnDrawScreenFinalTexture=hwSym("DrawScreenFinalTexture",NULL); + // check gl renderer lib + if (HWD.pfnGetRenderVersion() != VERSION) + I_Error("%s", M_GetText("The version of the renderer doesn't match the version of the executable\nBe sure you have installed SRB2 properly.\n")); + if (!HWD.pfnInit(I_Error)) // let load the OpenGL library + rendermode = render_soft; + else + glstartup = true; + } +#endif +} + void I_ShutdownGraphics(void) { const rendermode_t oldrendermode = rendermode; diff --git a/src/sdl12/i_video.c b/src/sdl12/i_video.c index 349e06cba..b95a6a48d 100644 --- a/src/sdl12/i_video.c +++ b/src/sdl12/i_video.c @@ -1914,8 +1914,12 @@ void I_StartupGraphics(void) if (strncasecmp(vd, "gcvideo", 8) == 0 || strncasecmp(vd, "fbcon", 6) == 0 || strncasecmp(vd, "wii", 4) == 0 || strncasecmp(vd, "psl1ght", 8) == 0) framebuffer = SDL_TRUE; } - if (M_CheckParm("-software")) +#ifdef HWRENDER + if (M_CheckParm("-opengl")) + rendermode = render_opengl; + else if (M_CheckParm("-software")) rendermode = render_soft; +#endif SDL_EnableKeyRepeat(SDL_DEFAULT_REPEAT_DELAY>>1,SDL_DEFAULT_REPEAT_INTERVAL<<2); SDLESSet(); VID_Command_ModeList_f(); @@ -1949,62 +1953,9 @@ void I_StartupGraphics(void) #endif #ifdef HWRENDER - if (M_CheckParm("-opengl") || rendermode == render_opengl) - { - rendermode = render_opengl; - HWD.pfnInit = hwSym("Init",NULL); - HWD.pfnFinishUpdate = NULL; - HWD.pfnDraw2DLine = hwSym("Draw2DLine",NULL); - HWD.pfnDrawPolygon = hwSym("DrawPolygon",NULL); - HWD.pfnSetBlend = hwSym("SetBlend",NULL); - HWD.pfnClearBuffer = hwSym("ClearBuffer",NULL); - HWD.pfnSetTexture = hwSym("SetTexture",NULL); - HWD.pfnReadRect = hwSym("ReadRect",NULL); - HWD.pfnGClipRect = hwSym("GClipRect",NULL); - HWD.pfnClearMipMapCache = hwSym("ClearMipMapCache",NULL); - HWD.pfnSetSpecialState = hwSym("SetSpecialState",NULL); - HWD.pfnSetPalette = hwSym("SetPalette",NULL); - HWD.pfnGetTextureUsed = hwSym("GetTextureUsed",NULL); - HWD.pfnDrawMD2 = hwSym("DrawMD2",NULL); - HWD.pfnDrawMD2i = hwSym("DrawMD2i",NULL); - HWD.pfnSetTransform = hwSym("SetTransform",NULL); - HWD.pfnGetRenderVersion = hwSym("GetRenderVersion",NULL); -#ifdef SHUFFLE - HWD.pfnPostImgRedraw = hwSym("PostImgRedraw",NULL); -#endif - HWD.pfnFlushScreenTextures=hwSym("FlushScreenTextures",NULL); - HWD.pfnStartScreenWipe = hwSym("StartScreenWipe",NULL); - HWD.pfnEndScreenWipe = hwSym("EndScreenWipe",NULL); - HWD.pfnDoScreenWipe = hwSym("DoScreenWipe",NULL); - HWD.pfnDrawIntermissionBG=hwSym("DrawIntermissionBG",NULL); - HWD.pfnMakeScreenTexture= hwSym("MakeScreenTexture",NULL); - // check gl renderer lib - if (HWD.pfnGetRenderVersion() != VERSION) - I_Error("%s", M_GetText("The version of the renderer doesn't match the version of the executable\nBe sure you have installed SRB2 properly.\n")); -#if 1 //#ifdef _WIN32_WCE - vid.width = BASEVIDWIDTH; - vid.height = BASEVIDHEIGHT; -#else - vid.width = 640; // hack to make voodoo cards work in 640x480 - vid.height = 480; -#endif - if (HWD.pfnInit(I_Error)) // let load the OpenGL library - { - /* - * We want at least 1 bit R, G, and B, - * and at least 16 bpp. Why 1 bit? May be more? - */ - SDL_GL_SetAttribute(SDL_GL_RED_SIZE, 1); - SDL_GL_SetAttribute(SDL_GL_GREEN_SIZE, 1); - SDL_GL_SetAttribute(SDL_GL_BLUE_SIZE, 1); - SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1); - if (!OglSdlSurface(vid.width, vid.height, (USE_FULLSCREEN))) - if (!OglSdlSurface(vid.width, vid.height, !(USE_FULLSCREEN))) - rendermode = render_soft; - } - else - rendermode = render_soft; - } + I_StartupHardwareGraphics(); + if (rendermode == render_opengl) + I_StartupHardwareGraphics(); #else rendermode = render_soft; //force software mode when there no HWRENDER code #endif @@ -2058,6 +2009,62 @@ void I_StartupGraphics(void) graphics_started = true; } +void I_StartupHardwareGraphics(void) +{ + HWD.pfnInit = hwSym("Init",NULL); + HWD.pfnFinishUpdate = NULL; + HWD.pfnDraw2DLine = hwSym("Draw2DLine",NULL); + HWD.pfnDrawPolygon = hwSym("DrawPolygon",NULL); + HWD.pfnSetBlend = hwSym("SetBlend",NULL); + HWD.pfnClearBuffer = hwSym("ClearBuffer",NULL); + HWD.pfnSetTexture = hwSym("SetTexture",NULL); + HWD.pfnReadRect = hwSym("ReadRect",NULL); + HWD.pfnGClipRect = hwSym("GClipRect",NULL); + HWD.pfnClearMipMapCache = hwSym("ClearMipMapCache",NULL); + HWD.pfnSetSpecialState = hwSym("SetSpecialState",NULL); + HWD.pfnSetPalette = hwSym("SetPalette",NULL); + HWD.pfnGetTextureUsed = hwSym("GetTextureUsed",NULL); + HWD.pfnDrawMD2 = hwSym("DrawMD2",NULL); + HWD.pfnDrawMD2i = hwSym("DrawMD2i",NULL); + HWD.pfnSetTransform = hwSym("SetTransform",NULL); + HWD.pfnGetRenderVersion = hwSym("GetRenderVersion",NULL); +#ifdef SHUFFLE + HWD.pfnPostImgRedraw = hwSym("PostImgRedraw",NULL); +#endif + HWD.pfnFlushScreenTextures=hwSym("FlushScreenTextures",NULL); + HWD.pfnStartScreenWipe = hwSym("StartScreenWipe",NULL); + HWD.pfnEndScreenWipe = hwSym("EndScreenWipe",NULL); + HWD.pfnDoScreenWipe = hwSym("DoScreenWipe",NULL); + HWD.pfnDrawIntermissionBG=hwSym("DrawIntermissionBG",NULL); + HWD.pfnMakeScreenTexture= hwSym("MakeScreenTexture",NULL); + // check gl renderer lib + if (HWD.pfnGetRenderVersion() != VERSION) + I_Error("%s", M_GetText("The version of the renderer doesn't match the version of the executable\nBe sure you have installed SRB2 properly.\n")); +#if 1 //#ifdef _WIN32_WCE + vid.width = BASEVIDWIDTH; + vid.height = BASEVIDHEIGHT; +#else + vid.width = 640; // hack to make voodoo cards work in 640x480 + vid.height = 480; +#endif + if (HWD.pfnInit(I_Error)) // let load the OpenGL library + { + /* + * We want at least 1 bit R, G, and B, + * and at least 16 bpp. Why 1 bit? May be more? + */ + SDL_GL_SetAttribute(SDL_GL_RED_SIZE, 1); + SDL_GL_SetAttribute(SDL_GL_GREEN_SIZE, 1); + SDL_GL_SetAttribute(SDL_GL_BLUE_SIZE, 1); + SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1); + if (!OglSdlSurface(vid.width, vid.height, (USE_FULLSCREEN))) + if (!OglSdlSurface(vid.width, vid.height, !(USE_FULLSCREEN))) + rendermode = render_soft; + } + else + rendermode = render_soft; +} + void I_ShutdownGraphics(void) { const rendermode_t oldrendermode = rendermode; diff --git a/src/win32/win_vid.c b/src/win32/win_vid.c index a6d9cdfc1..54f8e110e 100644 --- a/src/win32/win_vid.c +++ b/src/win32/win_vid.c @@ -239,6 +239,11 @@ void I_StartupGraphics(void) if (!dedicated) graphics_started = true; } +void I_StartupHardwareGraphics(void) +{ + // oh yeah woo yeah oh yeah woo yeah oh yeah woo yeah oh yeah woo yeah oh yeah woo yeah oh yeah woo yeah oh yeah woo y +} + // ------------------ // I_ShutdownGraphics // Close the screen, restore previous video mode. diff --git a/src/win32ce/win_vid.c b/src/win32ce/win_vid.c index b9c2e131f..3b1c3fcfa 100644 --- a/src/win32ce/win_vid.c +++ b/src/win32ce/win_vid.c @@ -127,6 +127,11 @@ void I_StartupGraphics(void) if (!dedicated) graphics_started = true; } +void I_StartupHardwareGraphics(void) +{ + // oh yeah woo yeah oh yeah woo yeah oh yeah woo yeah oh yeah woo yeah oh yeah woo yeah oh yeah woo yeah oh yeah woo y +} + // ------------------ // I_ShutdownGraphics // Close the screen, restore previous video mode. From da93e0f1f55e69c9baa7ff7a4093bd40b2964f88 Mon Sep 17 00:00:00 2001 From: Jaime Passos Date: Mon, 9 Sep 2019 16:20:17 -0300 Subject: [PATCH 006/746] I am the CEO of renderers --- src/console.c | 8 +++---- src/d_main.c | 52 ++++++++++++++++++++++++++++++++++------- src/hardware/hw_cache.c | 15 ------------ src/hu_stuff.c | 3 --- src/m_menu.c | 3 --- src/p_setup.c | 3 --- src/r_main.c | 2 +- src/st_stuff.c | 3 --- src/w_wad.c | 7 ++---- src/y_inter.c | 1 - src/z_zone.c | 24 +++++++++---------- 11 files changed, 61 insertions(+), 60 deletions(-) diff --git a/src/console.c b/src/console.c index 1ac181086..10b569daa 100644 --- a/src/console.c +++ b/src/console.c @@ -1267,7 +1267,7 @@ void CONS_Printf(const char *fmt, ...) con_scrollup = 0; // if not in display loop, force screen update - if (con_startup) + if (con_startup && (!setrenderneeded)) { #if (defined (_WINDOWS)) || (defined (__OS2__) && !defined (HAVE_SDL)) patch_t *con_backpic = W_CachePatchName("CONSBACK", PU_PATCH); @@ -1584,13 +1584,11 @@ void CON_Drawer(void) if (!con_started || !graphics_started) return; - if (needpatchrecache) - R_ReloadHUDGraphics(); - if (con_recalc) { CON_RecalcSize(); - CON_ClearHUD(); + if (con_curlines <= 0) + CON_ClearHUD(); } if (con_curlines > 0) diff --git a/src/d_main.c b/src/d_main.c index c84d6e7a2..4b68f73ba 100644 --- a/src/d_main.c +++ b/src/d_main.c @@ -117,6 +117,8 @@ boolean devparm = false; // started game with -devparm boolean singletics = false; // timedemo boolean lastdraw = false; +static void D_CheckRendererState(void); + postimg_t postimgtype = postimg_none; INT32 postimgparam; postimg_t postimgtype2 = postimg_none; @@ -227,7 +229,7 @@ gamestate_t wipegamestate = GS_LEVEL; static void D_Display(void) { - INT32 setrenderstillneeded = setrenderneeded; + INT32 setrenderstillneeded = 0; boolean forcerefresh = false; static boolean wipe = false; INT32 wipedefindex = 0; @@ -242,9 +244,16 @@ static void D_Display(void) if (setrenderneeded && (moviemode != MM_OFF)) M_StopMovie(); - // check for change of screen size (video mode) - if ((setmodeneeded || setrenderneeded) && !wipe) + // check for change of renderer or screen size (video mode) + if ((setrenderneeded || setmodeneeded) && !wipe) + { + if (setrenderneeded) + { + CONS_Debug(DBG_RENDER, "setrenderneeded set (%d)\n", setrenderneeded); + setrenderstillneeded = setrenderneeded; + } SCR_SetMode(); // change video mode + } if (vid.recalc || setrenderstillneeded) SCR_Recalc(); // NOTE! setsizeneeded is set by SCR_Recalc() @@ -256,6 +265,8 @@ static void D_Display(void) forcerefresh = true; // force background redraw } + D_CheckRendererState(); + // draw buffered stuff to screen // Used only by linux GGI version I_UpdateNoBlit(); @@ -495,16 +506,24 @@ static void D_Display(void) I_FinishUpdate(); // page flip or blit buffer } - // in the occasion no functions - // that require patches to be cached - // have been called. - if (needpatchrecache) - R_ReloadHUDGraphics(); - needpatchflush = false; needpatchrecache = false; } +void D_CheckRendererState(void) +{ + // flush all patches from memory + // (also frees memory tagged with PU_CACHE) + // (which are not necessarily patches but I don't care) + if (needpatchflush) + Z_FlushCachedPatches(); + + // some patches have been freed, + // so cache them again + if (needpatchrecache) + R_ReloadHUDGraphics(); +} + // ========================================================================= // D_SRB2Loop // ========================================================================= @@ -1201,6 +1220,21 @@ void D_SRB2Main(void) // set user default mode or mode set at cmdline SCR_CheckDefaultMode(); + // renderer needs to change? + // ok cool please just change it + // exactly right now please. + if ((setrenderneeded != 0) && (setrenderneeded != rendermode)) + { + needpatchflush = true; + needpatchrecache = true; + VID_CheckRenderer(); + // set cv_renderer back + if (setrenderneeded == render_soft) + CV_StealthSetValue(&cv_renderer, 1); + else if (setrenderneeded == render_opengl) + CV_StealthSetValue(&cv_renderer, 2); + } + D_CheckRendererState(); wipegamestate = gamestate; diff --git a/src/hardware/hw_cache.c b/src/hardware/hw_cache.c index 0716a130f..7e9efd38b 100644 --- a/src/hardware/hw_cache.c +++ b/src/hardware/hw_cache.c @@ -712,9 +712,6 @@ void HWR_GetFlat(lumpnum_t flatlumpnum) { GLMipmap_t *grmip; - if (needpatchflush) - Z_FlushCachedPatches(); - grmip = &HWR_GetCachedGLPatch(flatlumpnum)->mipmap; if (!grmip->downloaded && !grmip->grInfo.data) @@ -751,9 +748,6 @@ static void HWR_LoadMappedPatch(GLMipmap_t *grmip, GLPatch_t *gpatch) // -----------------+ void HWR_GetPatch(GLPatch_t *gpatch) { - if (needpatchflush) - Z_FlushCachedPatches(); - // is it in hardware cache if (!gpatch->mipmap.downloaded && !gpatch->mipmap.grInfo.data) { @@ -781,9 +775,6 @@ void HWR_GetMappedPatch(GLPatch_t *gpatch, const UINT8 *colormap) { GLMipmap_t *grmip, *newmip; - if (needpatchflush) - Z_FlushCachedPatches(); - if (colormap == colormaps || colormap == NULL) { // Load the default (green) color in doom cache (temporary?) AND hardware cache @@ -909,9 +900,6 @@ GLPatch_t *HWR_GetPic(lumpnum_t lumpnum) { GLPatch_t *grpatch; - if (needpatchflush) - Z_FlushCachedPatches(); - grpatch = HWR_GetCachedGLPatch(lumpnum); if (!grpatch->mipmap.downloaded && !grpatch->mipmap.grInfo.data) @@ -1109,9 +1097,6 @@ void HWR_GetFadeMask(lumpnum_t fademasklumpnum) { GLMipmap_t *grmip; - if (needpatchflush) - Z_FlushCachedPatches(); - grmip = &HWR_GetCachedGLPatch(fademasklumpnum)->mipmap; if (!grmip->downloaded && !grmip->grInfo.data) diff --git a/src/hu_stuff.c b/src/hu_stuff.c index 2451f5c4d..a9a2b7504 100644 --- a/src/hu_stuff.c +++ b/src/hu_stuff.c @@ -1993,9 +1993,6 @@ static void HU_DrawDemoInfo(void) // void HU_Drawer(void) { - if (needpatchrecache) - R_ReloadHUDGraphics(); - #ifndef NONET // draw chat string plus cursor if (chat_on) diff --git a/src/m_menu.c b/src/m_menu.c index 9a55ced4b..ba3fb4c2d 100644 --- a/src/m_menu.c +++ b/src/m_menu.c @@ -2481,9 +2481,6 @@ void M_Drawer(void) if (currentMenu == &MessageDef) menuactive = true; - if (needpatchrecache) - R_ReloadHUDGraphics(); - if (menuactive) { // now that's more readable with a faded background (yeah like Quake...) diff --git a/src/p_setup.c b/src/p_setup.c index 82b9eb691..afd5ac06a 100644 --- a/src/p_setup.c +++ b/src/p_setup.c @@ -3098,10 +3098,7 @@ boolean P_SetupLevel(boolean skipprecip) // preload graphics #ifdef HWRENDER // not win32 only 19990829 by Kin if (rendermode == render_opengl) - { HWR_PrepLevelCache(numtextures); - //HWR_FreeColormaps(); - } #endif P_MapEnd(); diff --git a/src/r_main.c b/src/r_main.c index d7196427c..2cca68ff0 100644 --- a/src/r_main.c +++ b/src/r_main.c @@ -1353,7 +1353,7 @@ void R_InitHardwareMode(void) void R_ReloadHUDGraphics(void) { - Z_FlushCachedPatches(); + CONS_Debug(DBG_RENDER, "R_ReloadHUDGraphics()...\n"); ST_LoadGraphics(); HU_LoadGraphics(); ST_ReloadSkinFaceGraphics(); diff --git a/src/st_stuff.c b/src/st_stuff.c index 11bb9875d..287aea134 100644 --- a/src/st_stuff.c +++ b/src/st_stuff.c @@ -1909,9 +1909,6 @@ static void ST_overlayDrawer(void) void ST_Drawer(void) { - if (needpatchrecache) - R_ReloadHUDGraphics(); - #ifdef SEENAMES if (cv_seenames.value && cv_allowseenames.value && displayplayer == consoleplayer && seenplayer && seenplayer->mo) { diff --git a/src/w_wad.c b/src/w_wad.c index 96381635a..2a98ba0a7 100644 --- a/src/w_wad.c +++ b/src/w_wad.c @@ -830,10 +830,10 @@ void W_UnloadWadFile(UINT16 num) lumpcache = delwad->lumpcache; numwadfiles--; #ifdef HWRENDER - if (rendermode != render_soft && rendermode != render_none) + if (rendermode == render_opengl) { - HWR_FreeTextureCache(); HWR_FreeColormaps(); + HWR_FreeTextureCache(); } M_AATreeFree(delwad->hwrcache); #endif @@ -1512,9 +1512,6 @@ static inline void *W_CachePatchNumPwad(UINT16 wad, UINT16 lump, INT32 tag) { GLPatch_t *grPatch; - if (needpatchflush) - Z_FlushCachedPatches(); - if (rendermode == render_soft || rendermode == render_none) return W_CacheLumpNumPwad(wad, lump, tag); diff --git a/src/y_inter.c b/src/y_inter.c index ab27a00fe..080e380d1 100644 --- a/src/y_inter.c +++ b/src/y_inter.c @@ -192,7 +192,6 @@ void Y_IntermissionDrawer(void) if (needpatchrecache) { Y_CleanupData(); - R_ReloadHUDGraphics(); safetorender = false; } diff --git a/src/z_zone.c b/src/z_zone.c index add18b568..a0e34ec35 100644 --- a/src/z_zone.c +++ b/src/z_zone.c @@ -415,20 +415,20 @@ void Z_FreeTags(INT32 lowtag, INT32 hightag) boolean needpatchflush = false; boolean needpatchrecache = false; +// flush all patches from memory +// (also frees memory tagged with PU_CACHE) +// (which are not necessarily patches but I don't care) void Z_FlushCachedPatches(void) { - if (needpatchflush) - { - Z_FreeTag(PU_CACHE); - Z_FreeTag(PU_PATCH); - Z_FreeTag(PU_HUDGFX); - Z_FreeTag(PU_HWRPATCHINFO); - Z_FreeTag(PU_HWRPATCHCOLMIPMAP); - Z_FreeTag(PU_HWRCACHE); - Z_FreeTag(PU_HWRCACHE_UNLOCKED); - Z_FreeTag(PU_HWRPATCHINFO_UNLOCKED); - } - needpatchflush = false; + CONS_Debug(DBG_RENDER, "Z_FlushCachedPatches()...\n"); + Z_FreeTag(PU_CACHE); + Z_FreeTag(PU_PATCH); + Z_FreeTag(PU_HUDGFX); + Z_FreeTag(PU_HWRPATCHINFO); + Z_FreeTag(PU_HWRPATCHCOLMIPMAP); + Z_FreeTag(PU_HWRCACHE); + Z_FreeTag(PU_HWRCACHE_UNLOCKED); + Z_FreeTag(PU_HWRPATCHINFO_UNLOCKED); } // From ebc22b9df80e0e3a52977e3326bb8152e69e738e Mon Sep 17 00:00:00 2001 From: Jaime Passos Date: Mon, 9 Sep 2019 16:31:30 -0300 Subject: [PATCH 007/746] yet even more cleanup here --- src/d_main.c | 6 +----- src/screen.c | 15 ++++++++++----- src/screen.h | 3 +++ 3 files changed, 14 insertions(+), 10 deletions(-) diff --git a/src/d_main.c b/src/d_main.c index 4b68f73ba..34dc5ab65 100644 --- a/src/d_main.c +++ b/src/d_main.c @@ -1228,11 +1228,7 @@ void D_SRB2Main(void) needpatchflush = true; needpatchrecache = true; VID_CheckRenderer(); - // set cv_renderer back - if (setrenderneeded == render_soft) - CV_StealthSetValue(&cv_renderer, 1); - else if (setrenderneeded == render_opengl) - CV_StealthSetValue(&cv_renderer, 2); + SCR_ChangeRendererCVars(setrenderneeded); } D_CheckRendererState(); diff --git a/src/screen.c b/src/screen.c index 7c8bfb14a..26d8c7a9d 100644 --- a/src/screen.c +++ b/src/screen.c @@ -72,7 +72,6 @@ consvar_t cv_scr_depth = {"scr_depth", "16 bits", CV_SAVE, scr_depth_cons_t, NUL #endif consvar_t cv_renderview = {"renderview", "On", 0, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL}; -static void SCR_ChangeRenderer(void); static void SCR_ActuallyChangeRenderer(void); static CV_PossibleValue_t cv_renderer_t[] = {{1, "Software"}, {2, "OpenGL"}, {0, NULL}}; consvar_t cv_renderer = {"renderer", "Software", CV_SAVE|CV_CALL, cv_renderer_t, SCR_ChangeRenderer, 0, NULL, NULL, 0, 0, NULL}; @@ -430,10 +429,7 @@ void SCR_ChangeRenderer(void) else if (M_CheckParm("-software")) target_renderer = rendermode = render_soft; // set cv_renderer back - if (rendermode == render_soft) - CV_StealthSetValue(&cv_renderer, 1); - else if (rendermode == render_opengl) - CV_StealthSetValue(&cv_renderer, 2); + SCR_ChangeRendererCVars(rendermode); return; } @@ -444,6 +440,15 @@ void SCR_ChangeRenderer(void) SCR_ActuallyChangeRenderer(); } +void SCR_ChangeRendererCVars(INT32 mode) +{ + // set cv_renderer back + if (mode == render_soft) + CV_StealthSetValue(&cv_renderer, 1); + else if (mode == render_opengl) + CV_StealthSetValue(&cv_renderer, 2); +} + boolean SCR_IsAspectCorrect(INT32 width, INT32 height) { return diff --git a/src/screen.h b/src/screen.h index df0518421..cc45de3d6 100644 --- a/src/screen.h +++ b/src/screen.h @@ -154,6 +154,9 @@ extern boolean R_SSE2; // ---------------- extern viddef_t vid; extern INT32 setmodeneeded; // mode number to set if needed, or 0 + +void SCR_ChangeRenderer(void); +void SCR_ChangeRendererCVars(INT32 mode); extern INT32 setrenderneeded; extern INT32 scr_bpp; From 26569f494be6240cbbe31d838248adafc2b35650 Mon Sep 17 00:00:00 2001 From: Jaime Passos Date: Mon, 9 Sep 2019 17:24:13 -0300 Subject: [PATCH 008/746] lua stuff --- src/doomdef.h | 3 ++ src/lua_hudlib.c | 87 +++++++++++++++++++++++++++++++++++++++++++++++- src/r_defs.h | 18 ++++++++++ 3 files changed, 107 insertions(+), 1 deletion(-) diff --git a/src/doomdef.h b/src/doomdef.h index 1c034f5f7..593ad0358 100644 --- a/src/doomdef.h +++ b/src/doomdef.h @@ -538,4 +538,7 @@ extern const char *compdate, *comptime, *comprevision, *compbranch; /// SRB2CB itself ported this from PrBoom+ #define NEWCLIP +/// Cache patches in Lua more safely, so that renderer switching can work. +#define LUA_PATCH_SAFETY + #endif // __DOOMDEF__ diff --git a/src/lua_hudlib.c b/src/lua_hudlib.c index ba8b3a6d9..5e104c77a 100644 --- a/src/lua_hudlib.c +++ b/src/lua_hudlib.c @@ -34,6 +34,11 @@ static UINT8 hud_enabled[(hud_MAX/8)+1]; static UINT8 hudAvailable; // hud hooks field +#ifdef LUA_PATCH_SAFETY +static patchinfo_t *patchinfo, *patchinfohead; +static int numluapatches; +#endif + // must match enum hud in lua_hud.h static const char *const hud_disable_options[] = { "stagetitle", @@ -231,12 +236,17 @@ static int colormap_get(lua_State *L) static int patch_get(lua_State *L) { +#ifdef LUA_PATCH_SAFETY patch_t *patch = *((patch_t **)luaL_checkudata(L, 1, META_PATCH)); +#else + patchinfo_t *patch = *((patchinfo_t **)luaL_checkudata(L, 1, META_PATCH)); +#endif enum patch field = luaL_checkoption(L, 2, NULL, patch_opt); // patches are CURRENTLY always valid, expected to be cached with PU_STATIC // this may change in the future, so patch.valid still exists - I_Assert(patch != NULL); + if (!patch) + return LUA_ErrInvalid(L, "patch_t"); switch (field) { @@ -333,8 +343,59 @@ static int libd_patchExists(lua_State *L) static int libd_cachePatch(lua_State *L) { +#ifdef LUA_PATCH_SAFETY + int i; + lumpnum_t lumpnum; + patchinfo_t *luapat; + patch_t *realpatch; + + HUDONLY + + luapat = patchinfohead; + lumpnum = W_CheckNumForName(luaL_checkstring(L, 1)); + if (lumpnum == LUMPERROR) + lumpnum = W_GetNumForName("MISSING"); + + for (i = 0; i < numluapatches; i++) + { + // check if already cached + if (luapat->wadnum == WADFILENUM(lumpnum) && luapat->lumpnum == LUMPNUM(lumpnum)) + { + LUA_PushUserdata(L, luapat, META_PATCH); + return 1; + } + luapat = luapat->next; + if (!luapat) + break; + } + + if (numluapatches > 0) + { + patchinfo->next = Z_Malloc(sizeof(patchinfo_t), PU_STATIC, NULL); + patchinfo = patchinfo->next; + } + else + { + patchinfo = Z_Malloc(sizeof(patchinfo_t), PU_STATIC, NULL); + patchinfohead = patchinfo; + } + + realpatch = W_CachePatchNum(lumpnum, PU_PATCH); + + patchinfo->width = realpatch->width; + patchinfo->height = realpatch->height; + patchinfo->leftoffset = realpatch->leftoffset; + patchinfo->topoffset = realpatch->topoffset; + + patchinfo->wadnum = WADFILENUM(lumpnum); + patchinfo->lumpnum = LUMPNUM(lumpnum); + + LUA_PushUserdata(L, patchinfo, META_PATCH); + numluapatches++; +#else HUDONLY LUA_PushUserdata(L, W_CachePatchName(luaL_checkstring(L, 1), PU_PATCH), META_PATCH); +#endif return 1; } @@ -342,12 +403,22 @@ static int libd_draw(lua_State *L) { INT32 x, y, flags; patch_t *patch; +#ifdef LUA_PATCH_SAFETY + patchinfo_t *luapat; +#endif const UINT8 *colormap = NULL; HUDONLY x = luaL_checkinteger(L, 1); y = luaL_checkinteger(L, 2); +#ifdef LUA_PATCH_SAFETY + luapat = *((patchinfo_t **)luaL_checkudata(L, 3, META_PATCH)); + patch = W_CachePatchNum((luapat->wadnum<<16)+luapat->lumpnum, PU_PATCH); +#else patch = *((patch_t **)luaL_checkudata(L, 3, META_PATCH)); + if (!patch) + return LUA_ErrInvalid(L, "patch_t"); +#endif flags = luaL_optinteger(L, 4, 0); if (!lua_isnoneornil(L, 5)) colormap = *((UINT8 **)luaL_checkudata(L, 5, META_COLORMAP)); @@ -363,6 +434,9 @@ static int libd_drawScaled(lua_State *L) fixed_t x, y, scale; INT32 flags; patch_t *patch; +#ifdef LUA_PATCH_SAFETY + patchinfo_t *luapat; +#endif const UINT8 *colormap = NULL; HUDONLY @@ -371,7 +445,14 @@ static int libd_drawScaled(lua_State *L) scale = luaL_checkinteger(L, 3); if (scale < 0) return luaL_error(L, "negative scale"); +#ifdef LUA_PATCH_SAFETY + luapat = *((patchinfo_t **)luaL_checkudata(L, 4, META_PATCH)); + patch = W_CachePatchNum((luapat->wadnum<<16)+luapat->lumpnum, PU_PATCH); +#else patch = *((patch_t **)luaL_checkudata(L, 4, META_PATCH)); + if (!patch) + return LUA_ErrInvalid(L, "patch_t"); +#endif flags = luaL_optinteger(L, 5, 0); if (!lua_isnoneornil(L, 6)) colormap = *((UINT8 **)luaL_checkudata(L, 6, META_COLORMAP)); @@ -659,6 +740,10 @@ int LUA_HudLib(lua_State *L) { memset(hud_enabled, 0xff, (hud_MAX/8)+1); +#ifdef LUA_PATCH_SAFETY + numluapatches = 0; +#endif + lua_newtable(L); // HUD registry table lua_newtable(L); luaL_register(L, NULL, lib_draw); diff --git a/src/r_defs.h b/src/r_defs.h index 1cb4e0815..c09635bd5 100644 --- a/src/r_defs.h +++ b/src/r_defs.h @@ -726,6 +726,24 @@ typedef struct #pragma pack() #endif +// Same as a patch_t, except just the header +// and the wadnum/lumpnum combination that points +// to wherever the patch is in memory. +struct patchinfo_s +{ + INT16 width; // bounding box size + INT16 height; + INT16 leftoffset; // pixels to the left of origin + INT16 topoffset; // pixels below the origin + + UINT16 wadnum; // the software patch lump num for when the patch + UINT16 lumpnum; // was flushed, and we need to re-create it + + // next patchinfo_t in memory + struct patchinfo_s *next; +}; +typedef struct patchinfo_s patchinfo_t; + // // Sprites are patches with a special naming convention so they can be // recognized by R_InitSprites. From 02e327a4e463f202ed83afa30bab14d93dbfead5 Mon Sep 17 00:00:00 2001 From: Jaime Passos Date: Mon, 9 Sep 2019 17:35:38 -0300 Subject: [PATCH 009/746] D_SRB2Loop: Draw CONSBACK even in OpenGL --- src/d_main.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/d_main.c b/src/d_main.c index 34dc5ab65..4c9f78c02 100644 --- a/src/d_main.c +++ b/src/d_main.c @@ -571,8 +571,7 @@ void D_SRB2Loop(void) // hack to start on a nice clear console screen. COM_ImmedExecute("cls;version"); - if (rendermode == render_soft) - V_DrawScaledPatch(0, 0, 0, (patch_t *)W_CacheLumpNum(W_GetNumForName("CONSBACK"), PU_CACHE)); + V_DrawScaledPatch(0, 0, 0, W_CachePatchNum(W_GetNumForName("CONSBACK"), PU_CACHE)); I_FinishUpdate(); // page flip or blit buffer for (;;) From 6f4dadaa128f8190ab0ba8c17cdc5af5c451c0b6 Mon Sep 17 00:00:00 2001 From: Jaime Passos Date: Mon, 9 Sep 2019 17:53:34 -0300 Subject: [PATCH 010/746] menu changes --- src/m_menu.c | 16 +++++++++++++--- 1 file changed, 13 insertions(+), 3 deletions(-) diff --git a/src/m_menu.c b/src/m_menu.c index ba3fb4c2d..74d685fd5 100644 --- a/src/m_menu.c +++ b/src/m_menu.c @@ -257,6 +257,7 @@ static void M_ChangeControl(INT32 choice); // Video & Sound menu_t OP_VideoOptionsDef, OP_VideoModeDef; #ifdef HWRENDER +static void M_OpenGLOptionsMenu(void); menu_t OP_OpenGLOptionsDef, OP_OpenGLFogDef, OP_OpenGLColorDef; #endif menu_t OP_SoundOptionsDef; @@ -1100,10 +1101,7 @@ static menuitem_t OP_VideoOptionsMenu[] = { {IT_STRING | IT_CALL, NULL, "Video Modes...", M_VideoModeMenu, 10}, -#ifdef HWRENDER {IT_STRING|IT_CVAR, NULL, "Renderer", &cv_renderer, 20}, - //{IT_SUBMENU|IT_STRING, NULL, "3D Card Options...", &OP_OpenGLOptionsDef, 20}, -#endif #if (defined (__unix__) && !defined (MSDOS)) || defined (UNIXCOMMON) || defined (HAVE_SDL) {IT_STRING|IT_CVAR, NULL, "Fullscreen", &cv_fullscreen, 30}, @@ -1119,6 +1117,10 @@ static menuitem_t OP_VideoOptionsMenu[] = {IT_STRING | IT_CVAR, NULL, "Show FPS", &cv_ticrate, 110}, {IT_STRING | IT_CVAR, NULL, "Clear Before Redraw", &cv_homremoval, 120}, {IT_STRING | IT_CVAR, NULL, "Vertical Sync", &cv_vidwait, 130}, + +#ifdef HWRENDER + {IT_STRING | IT_CALL, NULL, "3D Card Options...", M_OpenGLOptionsMenu, 150}, +#endif }; static menuitem_t OP_VideoModeMenu[] = @@ -1712,6 +1714,14 @@ menu_t OP_MonitorToggleDef = }; #ifdef HWRENDER +static void M_OpenGLOptionsMenu(void) +{ + if (rendermode == render_opengl) + M_SetupNextMenu(&OP_OpenGLOptionsDef); + else + M_StartMessage(M_GetText("You must be in OpenGL mode\nto access this menu.\n\n(Press a key)\n"), NULL, MM_NOTHING); +} + menu_t OP_OpenGLOptionsDef = DEFAULTMENUSTYLE("M_VIDEO", OP_OpenGLOptionsMenu, &OP_VideoOptionsDef, 30, 30); #ifdef ALAM_LIGHTING menu_t OP_OpenGLLightingDef = DEFAULTMENUSTYLE("M_VIDEO", OP_OpenGLLightingMenu, &OP_OpenGLOptionsDef, 60, 40); From 0a973af5b8c1df0ab577e77198056ca9ba2296bf Mon Sep 17 00:00:00 2001 From: Jaime Passos Date: Mon, 9 Sep 2019 19:27:08 -0300 Subject: [PATCH 011/746] Comments --- src/d_main.c | 24 +++++++++++++++++++++--- src/f_finale.c | 1 + src/hardware/hw_cache.c | 1 + src/m_menu.c | 1 + src/p_setup.c | 6 +++--- src/r_main.c | 1 + src/screen.c | 2 ++ src/y_inter.c | 1 + 8 files changed, 31 insertions(+), 6 deletions(-) diff --git a/src/d_main.c b/src/d_main.c index 4c9f78c02..f42fc535e 100644 --- a/src/d_main.c +++ b/src/d_main.c @@ -240,6 +240,22 @@ static void D_Display(void) if (nodrawers) return; // for comparative timing/profiling + // Jimita: Switching renderers works by checking + // if the game has to do it right when the frame + // needs to render. If so, five things will happen: + // 1. Interface functions will be called so + // that switching to OpenGL creates a + // GL context, and switching to Software + // allocates screen buffers. + // 2. Software will set drawer functions, + // and OpenGL will load textures and + // create plane polygons, if necessary. + // 3. Functions related to switching video + // modes (resolution) are called. + // 4. Patch data is freed from memory, + // and recached if necessary. + // 5. The frame is ready to be drawn! + // stop movie if needs to change renderer if (setrenderneeded && (moviemode != MM_OFF)) M_StopMovie(); @@ -265,6 +281,7 @@ static void D_Display(void) forcerefresh = true; // force background redraw } + // Jimita D_CheckRendererState(); // draw buffered stuff to screen @@ -510,6 +527,8 @@ static void D_Display(void) needpatchrecache = false; } +// Jimita: Check the renderer's state +// after a possible renderer switch. void D_CheckRendererState(void) { // flush all patches from memory @@ -1219,9 +1238,8 @@ void D_SRB2Main(void) // set user default mode or mode set at cmdline SCR_CheckDefaultMode(); - // renderer needs to change? - // ok cool please just change it - // exactly right now please. + + // Jimita: Does the render mode need to change? if ((setrenderneeded != 0) && (setrenderneeded != rendermode)) { needpatchflush = true; diff --git a/src/f_finale.c b/src/f_finale.c index b97a6206e..637d4bd29 100644 --- a/src/f_finale.c +++ b/src/f_finale.c @@ -1495,6 +1495,7 @@ void F_TitleScreenDrawer(void) if (modeattacking) return; // We likely came here from retrying. Don't do a damn thing. + // Jimita: Load title screen patches. if (needpatchrecache) F_CacheTitleScreen(); diff --git a/src/hardware/hw_cache.c b/src/hardware/hw_cache.c index 7e9efd38b..a5e6d0eca 100644 --- a/src/hardware/hw_cache.c +++ b/src/hardware/hw_cache.c @@ -644,6 +644,7 @@ GLTexture_t *HWR_GetTexture(INT32 tex) if ((unsigned)tex >= gr_numtextures) I_Error("HWR_GetTexture: tex >= numtextures\n"); #endif + // Jimita if (needpatchrecache && (!gr_textures)) HWR_PrepLevelCache(gr_numtextures); diff --git a/src/m_menu.c b/src/m_menu.c index 74d685fd5..9bd8c0a7f 100644 --- a/src/m_menu.c +++ b/src/m_menu.c @@ -4135,6 +4135,7 @@ static void M_DrawAddons(void) return; } + // Jimita: Load addons menu patches. if (needpatchrecache) M_LoadAddonsPatches(); diff --git a/src/p_setup.c b/src/p_setup.c index afd5ac06a..7e600d66f 100644 --- a/src/p_setup.c +++ b/src/p_setup.c @@ -2943,8 +2943,8 @@ boolean P_SetupLevel(boolean skipprecip) globalweather = mapheaderinfo[gamemap-1]->weather; #ifdef HWRENDER // not win32 only 19990829 by Kin - // gotta free this regardless of rendermode. - // maybe we're not in opengl anymore....... + // Jimita: Free extrasubsectors regardless of renderer. + // Maybe we're not in OpenGL anymore. if (extrasubsectors) free(extrasubsectors); extrasubsectors = NULL; @@ -3162,7 +3162,7 @@ void HWR_SetupLevel(void) #endif // Correct missing sidedefs & deep water trick HWR_CorrectSWTricks(); - // don't do it twice... + // Jimita: Don't call this more than once! if (!extrasubsectors) HWR_CreatePlanePolygons((INT32)numnodes - 1); } diff --git a/src/r_main.c b/src/r_main.c index 2cca68ff0..766c548a2 100644 --- a/src/r_main.c +++ b/src/r_main.c @@ -1339,6 +1339,7 @@ void R_RenderPlayerView(player_t *player) skyVisible1 = skyVisible; } +// Jimita #ifdef HWRENDER void R_InitHardwareMode(void) { diff --git a/src/screen.c b/src/screen.c index 26d8c7a9d..c14beb6eb 100644 --- a/src/screen.c +++ b/src/screen.c @@ -172,6 +172,7 @@ void SCR_SetMode(void) if (!(setmodeneeded || setrenderneeded) || WipeInAction) return; // should never happen and don't change it during a wipe, BAD! + // Jimita if (setrenderneeded) { needpatchflush = true; @@ -417,6 +418,7 @@ void SCR_ActuallyChangeRenderer(void) setrenderneeded = 0; } +// Jimita void SCR_ChangeRenderer(void) { setrenderneeded = 0; diff --git a/src/y_inter.c b/src/y_inter.c index 080e380d1..d55046fff 100644 --- a/src/y_inter.c +++ b/src/y_inter.c @@ -189,6 +189,7 @@ void Y_IntermissionDrawer(void) if (intertype == int_none || rendermode == render_none) return; + // Jimita if (needpatchrecache) { Y_CleanupData(); From 1a9191dcd74b45a03c99d4100ae125d9e52b50b7 Mon Sep 17 00:00:00 2001 From: Jaime Passos Date: Mon, 9 Sep 2019 19:34:51 -0300 Subject: [PATCH 012/746] Attempt to fix warnings --- src/screen.c | 2 +- src/screen.h | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/screen.c b/src/screen.c index c14beb6eb..6f77631c2 100644 --- a/src/screen.c +++ b/src/screen.c @@ -56,7 +56,7 @@ void (*twosmultipatchtransfunc)(void); // for cols with transparent pixels AND t // ------------------ viddef_t vid; INT32 setmodeneeded; //video mode change needed if > 0 (the mode number to set + 1) -INT32 setrenderneeded = 0; +UINT8 setrenderneeded = 0; static CV_PossibleValue_t scr_depth_cons_t[] = {{8, "8 bits"}, {16, "16 bits"}, {24, "24 bits"}, {32, "32 bits"}, {0, NULL}}; diff --git a/src/screen.h b/src/screen.h index cc45de3d6..8792f7912 100644 --- a/src/screen.h +++ b/src/screen.h @@ -157,7 +157,7 @@ extern INT32 setmodeneeded; // mode number to set if needed, or 0 void SCR_ChangeRenderer(void); void SCR_ChangeRendererCVars(INT32 mode); -extern INT32 setrenderneeded; +extern UINT8 setrenderneeded; extern INT32 scr_bpp; extern UINT8 *scr_borderpatch; // patch used to fill the view borders From 6ab20060a7e356fe2cd614d4251eba85a849ceaf Mon Sep 17 00:00:00 2001 From: Jaime Passos Date: Tue, 10 Sep 2019 16:59:37 -0300 Subject: [PATCH 013/746] Disable LUA_PATCH_SAFETY because I trust Lua scripters enough haha........ha................. --- src/doomdef.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/doomdef.h b/src/doomdef.h index 593ad0358..0fb5d3b03 100644 --- a/src/doomdef.h +++ b/src/doomdef.h @@ -538,7 +538,7 @@ extern const char *compdate, *comptime, *comprevision, *compbranch; /// SRB2CB itself ported this from PrBoom+ #define NEWCLIP -/// Cache patches in Lua more safely, so that renderer switching can work. -#define LUA_PATCH_SAFETY +/// Cache patches in Lua in a way that renderer switching will work flawlessly. +//#define LUA_PATCH_SAFETY #endif // __DOOMDEF__ From f0019f2b2acc057f0af29ff63aa69de65ad95124 Mon Sep 17 00:00:00 2001 From: Jaime Passos Date: Tue, 10 Sep 2019 18:17:02 -0300 Subject: [PATCH 014/746] Oops. --- src/z_zone.c | 12 ------------ 1 file changed, 12 deletions(-) diff --git a/src/z_zone.c b/src/z_zone.c index e0ed1b296..ce38947cb 100644 --- a/src/z_zone.c +++ b/src/z_zone.c @@ -510,18 +510,6 @@ void Z_FlushCachedPatches(void) Z_FreeTag(PU_HWRPATCHINFO_UNLOCKED); } -// -// Z_CheckMemCleanup -// -// TODO: Currently blocks >= PU_PURGELEVEL are freed every -// CLEANUPCOUNT. It might be better to keep track of -// the total size of all purgable memory and free it when the -// size exceeds some value. -// -// This was in Z_Malloc, but was freeing data at -// unsafe times. Now it is only called when it is safe -// to cleanup memory. - // starting value of nextcleanup #define CLEANUPCOUNT 2000 From 347f9cda8b375f1019ec62f51d0dd9948f79a3a7 Mon Sep 17 00:00:00 2001 From: Jaime Passos Date: Tue, 10 Sep 2019 18:33:06 -0300 Subject: [PATCH 015/746] Fix title screen crash --- src/r_main.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/r_main.c b/src/r_main.c index d1952994c..63641a25a 100644 --- a/src/r_main.c +++ b/src/r_main.c @@ -1155,7 +1155,7 @@ void R_RenderPlayerView(player_t *player) void R_InitHardwareMode(void) { HWR_AddCommands(); - if (gamestate == GS_LEVEL) + if (gamestate == GS_LEVEL || gamestate == GS_TITLESCREEN) { HWR_SetupLevel(); HWR_PrepLevelCache(numtextures); From 00f5cbb1856eb355933c186b55955c8cd8dd9bd4 Mon Sep 17 00:00:00 2001 From: Jaime Passos Date: Tue, 10 Sep 2019 18:34:29 -0300 Subject: [PATCH 016/746] 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 c7d0d7b1c25614230f9790d6768cc900a7f75b6e Mon Sep 17 00:00:00 2001 From: Jaime Passos Date: Sat, 9 Nov 2019 01:36:53 -0300 Subject: [PATCH 017/746] Flats as walls textures support, WIP, doesn't support animations yet --- src/doomdef.h | 4 ++ src/p_spec.c | 2 +- src/r_data.c | 153 ++++++++++++++++++++++++++++++++++++++++++++++++-- src/r_data.h | 12 ++++ 4 files changed, 166 insertions(+), 5 deletions(-) diff --git a/src/doomdef.h b/src/doomdef.h index 676c86e0d..1f28f7a80 100644 --- a/src/doomdef.h +++ b/src/doomdef.h @@ -620,8 +620,12 @@ extern const char *compdate, *comptime, *comprevision, *compbranch; /// SRB2CB itself ported this from PrBoom+ #define NEWCLIP +/// PNG support #ifndef HAVE_PNG #define NO_PNG_LUMPS #endif +/// Render flats on walls +#define WALLFLATS + #endif // __DOOMDEF__ diff --git a/src/p_spec.c b/src/p_spec.c index 7fcdfd1e3..9ab50d947 100644 --- a/src/p_spec.c +++ b/src/p_spec.c @@ -464,7 +464,7 @@ static inline void P_FindAnimatedFlat(INT32 animnum) for (i = 0; i < numlevelflats; i++, foundflats++) { // is that levelflat from the flat anim sequence ? - if ((anims[animnum].istexture) && (foundflats->u.texture.num != 0 && foundflats->u.texture.num != -1) + if ((anims[animnum].istexture) && (foundflats->type == LEVELFLAT_TEXTURE) && ((UINT16)foundflats->u.texture.num >= startflatnum && (UINT16)foundflats->u.texture.num <= endflatnum)) { foundflats->u.texture.basenum = startflatnum; diff --git a/src/r_data.c b/src/r_data.c index fa5e5c43b..ac98aae77 100644 --- a/src/r_data.c +++ b/src/r_data.c @@ -456,6 +456,7 @@ static UINT8 *R_GenerateTexture(size_t texnum) texture_t *texture; texpatch_t *patch; patch_t *realpatch; + UINT8 *pdata; int x, x1, x2, i, width, height; size_t blocksize; column_t *patchcol; @@ -483,14 +484,17 @@ static UINT8 *R_GenerateTexture(size_t texnum) wadnum = patch->wad; lumpnum = patch->lump; lumplength = W_LumpLengthPwad(wadnum, lumpnum); - realpatch = W_CacheLumpNumPwad(wadnum, lumpnum, PU_CACHE); // can't use W_CachePatchNumPwad because OpenGL + pdata = W_CacheLumpNumPwad(wadnum, lumpnum, PU_CACHE); + realpatch = (patch_t *)pdata; #ifndef NO_PNG_LUMPS if (R_IsLumpPNG((UINT8 *)realpatch, lumplength)) - { - realpatch = R_PNGToPatch((UINT8 *)realpatch, lumplength, NULL, false); goto multipatch; - } +#endif + +#ifdef WALLFLATS + if (texture->type == TEXTURETYPE_FLAT) + goto multipatch; #endif // Check the patch for holes. @@ -582,6 +586,11 @@ static UINT8 *R_GenerateTexture(size_t texnum) #ifndef NO_PNG_LUMPS if (R_IsLumpPNG((UINT8 *)realpatch, lumplength)) realpatch = R_PNGToPatch((UINT8 *)realpatch, lumplength, NULL, false); + else +#endif +#ifdef WALLFLATS + if (texture->type == TEXTURETYPE_FLAT) + realpatch = R_FlatToPatch(pdata, texture->width, texture->height, 0, 0, NULL, false); #endif x1 = patch->originx; @@ -773,6 +782,39 @@ void R_LoadTextures(void) { numtextures += (UINT32)(texend - texstart); } + +#ifdef WALLFLATS + // Count flats + if (wadfiles[w]->type == RET_PK3) + { + texstart = W_CheckNumForFolderStartPK3("flats/", (UINT16)w, 0); + texend = W_CheckNumForFolderEndPK3("flats/", (UINT16)w, texstart); + } + else + { + texstart = W_CheckNumForNamePwad("F_START", (UINT16)w, 0); + texend = W_CheckNumForNamePwad("F_END", (UINT16)w, 0); + } + + if (texstart == INT16_MAX || texend == INT16_MAX) + continue; + + texstart++; // Do not count the first marker + + // PK3s have subfolders, so we can't just make a simple sum + if (wadfiles[w]->type == RET_PK3) + { + for (j = texstart; j < texend; j++) + { + if (!W_IsLumpFolder((UINT16)w, j)) // Check if lump is a folder; if not, then count it + numtextures++; + } + } + else // Add all the textures between F_START and F_END + { + numtextures += (UINT32)(texend - texstart); + } +#endif } // If no textures found by this point, bomb out @@ -866,6 +908,8 @@ void R_LoadTextures(void) texture->width = SHORT(patchlump->width); texture->height = SHORT(patchlump->height); } + + texture->type = TEXTURETYPE_SINGLEPATCH; texture->patchcount = 1; texture->holes = false; texture->flip = 0; @@ -884,6 +928,106 @@ void R_LoadTextures(void) textureheight[i] = texture->height << FRACBITS; i++; } + +#ifdef WALLFLATS + // Yes + if (wadfiles[w]->type == RET_PK3) + { + texstart = W_CheckNumForFolderStartPK3("flats/", (UINT16)w, 0); + texend = W_CheckNumForFolderEndPK3("flats/", (UINT16)w, texstart); + } + else + { + texstart = W_CheckNumForNamePwad("F_START", (UINT16)w, 0); + texend = W_CheckNumForNamePwad("F_END", (UINT16)w, 0); + } + + if (texstart == INT16_MAX || texend == INT16_MAX) + continue; + + texstart++; // Do not count the first marker + + // Work through each lump between the markers in the WAD. + for (j = 0; j < (texend - texstart); j++) + { + UINT8 *flatlump; + UINT16 wadnum = (UINT16)w; + lumpnum_t lumpnum = texstart + j; + size_t lumplength; + size_t flatsize = 0; + + if (wadfiles[w]->type == RET_PK3) + { + if (W_IsLumpFolder(wadnum, lumpnum)) // Check if lump is a folder + continue; // If it is then SKIP IT + } + + flatlump = W_CacheLumpNumPwad(wadnum, lumpnum, PU_CACHE); + lumplength = W_LumpLengthPwad(wadnum, lumpnum); + + switch (lumplength) + { + case 4194304: // 2048x2048 lump + flatsize = 2048; + break; + case 1048576: // 1024x1024 lump + flatsize = 1024; + break; + case 262144:// 512x512 lump + flatsize = 512; + break; + case 65536: // 256x256 lump + flatsize = 256; + break; + case 16384: // 128x128 lump + flatsize = 128; + break; + case 1024: // 32x32 lump + flatsize = 32; + break; + default: // 64x64 lump + flatsize = 64; + break; + } + + //CONS_Printf("\n\"%s\" is a flat, dimensions %d x %d",W_CheckNameForNumPwad((UINT16)w,texstart+j),flatsize,flatsize); + texture = textures[i] = Z_Calloc(sizeof(texture_t) + sizeof(texpatch_t), PU_STATIC, NULL); + + // Set texture properties. + M_Memcpy(texture->name, W_CheckNameForNumPwad(wadnum, lumpnum), sizeof(texture->name)); + +#ifndef NO_PNG_LUMPS + if (R_IsLumpPNG((UINT8 *)flatlump, lumplength)) + { + INT16 width, height; + R_PNGDimensions((UINT8 *)flatlump, &width, &height, lumplength); + texture->width = width; + texture->height = height; + } + else +#endif + texture->width = texture->height = flatsize; + + texture->type = TEXTURETYPE_FLAT; + texture->patchcount = 1; + texture->holes = false; + texture->flip = 0; + + // Allocate information for the texture's patches. + patch = &texture->patches[0]; + + patch->originx = patch->originy = 0; + patch->wad = (UINT16)w; + patch->lump = texstart + j; + patch->flip = 0; + + Z_Unlock(flatlump); + + texturewidth[i] = texture->width; + textureheight[i] = texture->height << FRACBITS; + i++; + } +#endif } } @@ -1195,6 +1339,7 @@ static texture_t *R_ParseTexture(boolean actuallyLoadTexture) M_Memcpy(resultTexture->name, newTextureName, 8); resultTexture->width = newTextureWidth; resultTexture->height = newTextureHeight; + resultTexture->type = TEXTURETYPE_COMPOSITE; } Z_Free(texturesToken); texturesToken = M_GetToken(NULL); diff --git a/src/r_data.h b/src/r_data.h index e71d45766..1d58a7815 100644 --- a/src/r_data.h +++ b/src/r_data.h @@ -45,6 +45,17 @@ typedef struct enum patchalphastyle style; } texpatch_t; +// texture type +enum +{ + TEXTURETYPE_UNKNOWN, + TEXTURETYPE_SINGLEPATCH, + TEXTURETYPE_COMPOSITE, +#ifdef WALLFLATS + TEXTURETYPE_FLAT, +#endif +}; + // A maptexturedef_t describes a rectangular texture, // which is composed of one or more mappatch_t structures // that arrange graphic patches. @@ -52,6 +63,7 @@ typedef struct { // Keep name for switch changing, etc. char name[8]; + UINT8 type; // TEXTURETYPE_ INT16 width, height; boolean holes; UINT8 flip; // 1 = flipx, 2 = flipy, 3 = both From 5e55a04f5f39bc3417bfde0303515b54b6dee26e Mon Sep 17 00:00:00 2001 From: Jaime Passos Date: Sat, 9 Nov 2019 01:50:47 -0300 Subject: [PATCH 018/746] minor tweaks --- src/r_data.c | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/src/r_data.c b/src/r_data.c index ac98aae77..e962d390c 100644 --- a/src/r_data.c +++ b/src/r_data.c @@ -456,6 +456,7 @@ static UINT8 *R_GenerateTexture(size_t texnum) texture_t *texture; texpatch_t *patch; patch_t *realpatch; + boolean dealloc = false; UINT8 *pdata; int x, x1, x2, i, width, height; size_t blocksize; @@ -583,6 +584,8 @@ static UINT8 *R_GenerateTexture(size_t texnum) lumpnum = patch->lump; lumplength = W_LumpLengthPwad(wadnum, lumpnum); realpatch = W_CacheLumpNumPwad(wadnum, lumpnum, PU_CACHE); + dealloc = true; + #ifndef NO_PNG_LUMPS if (R_IsLumpPNG((UINT8 *)realpatch, lumplength)) realpatch = R_PNGToPatch((UINT8 *)realpatch, lumplength, NULL, false); @@ -591,7 +594,9 @@ static UINT8 *R_GenerateTexture(size_t texnum) #ifdef WALLFLATS if (texture->type == TEXTURETYPE_FLAT) realpatch = R_FlatToPatch(pdata, texture->width, texture->height, 0, 0, NULL, false); + else #endif + dealloc = false; x1 = patch->originx; width = SHORT(realpatch->width); @@ -628,6 +633,9 @@ static UINT8 *R_GenerateTexture(size_t texnum) colofs[x] = LONG((x * texture->height) + (texture->width*4)); ColumnDrawerPointer(patchcol, block + LONG(colofs[x]), patch, texture->height, height); } + + if (dealloc) + Z_Free(realpatch); } done: From 3f1681e0b3e0bb5536da875a558554c52923dea8 Mon Sep 17 00:00:00 2001 From: Jaime Passos Date: Sat, 9 Nov 2019 02:09:10 -0300 Subject: [PATCH 019/746] fix uninitialized pdata* --- src/r_data.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/r_data.c b/src/r_data.c index e962d390c..d271e28f3 100644 --- a/src/r_data.c +++ b/src/r_data.c @@ -583,7 +583,8 @@ static UINT8 *R_GenerateTexture(size_t texnum) wadnum = patch->wad; lumpnum = patch->lump; lumplength = W_LumpLengthPwad(wadnum, lumpnum); - realpatch = W_CacheLumpNumPwad(wadnum, lumpnum, PU_CACHE); + pdata = W_CacheLumpNumPwad(wadnum, lumpnum, PU_CACHE); + realpatch = (patch_t *)pdata; dealloc = true; #ifndef NO_PNG_LUMPS From 3e7be585ca35a625bb426bef270f8bfcb1bc859c Mon Sep 17 00:00:00 2001 From: Jaime Passos Date: Sat, 9 Nov 2019 12:22:18 -0300 Subject: [PATCH 020/746] WORK!! --- src/r_data.c | 16 ++++++++++++---- 1 file changed, 12 insertions(+), 4 deletions(-) diff --git a/src/r_data.c b/src/r_data.c index d271e28f3..38c711b7b 100644 --- a/src/r_data.c +++ b/src/r_data.c @@ -752,7 +752,6 @@ void R_LoadTextures(void) for (w = 0, numtextures = 0; w < numwadfiles; w++) { // Count the textures from TEXTURES lumps - texturesLumpPos = W_CheckNumForNamePwad("TEXTURES", (UINT16)w, 0); while (texturesLumpPos != INT16_MAX) { @@ -761,7 +760,6 @@ void R_LoadTextures(void) } // Count single-patch textures - if (wadfiles[w]->type == RET_PK3) { texstart = W_CheckNumForFolderStartPK3("textures/", (UINT16)w, 0); @@ -774,7 +772,11 @@ void R_LoadTextures(void) } if (texstart == INT16_MAX || texend == INT16_MAX) +#ifdef WALLFLATS + goto countflats; +#else continue; +#endif texstart++; // Do not count the first marker @@ -793,6 +795,7 @@ void R_LoadTextures(void) } #ifdef WALLFLATS +countflats: // Count flats if (wadfiles[w]->type == RET_PK3) { @@ -802,7 +805,7 @@ void R_LoadTextures(void) else { texstart = W_CheckNumForNamePwad("F_START", (UINT16)w, 0); - texend = W_CheckNumForNamePwad("F_END", (UINT16)w, 0); + texend = W_CheckNumForNamePwad("F_END", (UINT16)w, texstart); } if (texstart == INT16_MAX || texend == INT16_MAX) @@ -873,7 +876,11 @@ void R_LoadTextures(void) } if (texstart == INT16_MAX || texend == INT16_MAX) +#ifdef WALLFLATS + goto checkflats; +#else continue; +#endif texstart++; // Do not count the first marker @@ -939,6 +946,7 @@ void R_LoadTextures(void) } #ifdef WALLFLATS +checkflats: // Yes if (wadfiles[w]->type == RET_PK3) { @@ -948,7 +956,7 @@ void R_LoadTextures(void) else { texstart = W_CheckNumForNamePwad("F_START", (UINT16)w, 0); - texend = W_CheckNumForNamePwad("F_END", (UINT16)w, 0); + texend = W_CheckNumForNamePwad("F_END", (UINT16)w, texstart); } if (texstart == INT16_MAX || texend == INT16_MAX) From 78a0048ee4f1555d2a43abbcd5d5a43404deda27 Mon Sep 17 00:00:00 2001 From: Jaime Passos Date: Sat, 9 Nov 2019 13:23:38 -0300 Subject: [PATCH 021/746] Support animations --- src/p_spec.c | 21 ++++++++++++++++++--- 1 file changed, 18 insertions(+), 3 deletions(-) diff --git a/src/p_spec.c b/src/p_spec.c index 9ab50d947..7248d3ffb 100644 --- a/src/p_spec.c +++ b/src/p_spec.c @@ -138,6 +138,13 @@ static size_t maxanims; static animdef_t *animdefs = NULL; +// Increase the size of animdefs to make room for a new animation definition +static void GrowAnimDefs(void) +{ + maxanims++; + animdefs = (animdef_t *)Z_Realloc(animdefs, sizeof(animdef_t)*(maxanims + 1), PU_STATIC, NULL); +} + // A prototype; here instead of p_spec.h, so they're "private" void P_ParseANIMDEFSLump(INT32 wadNum, UINT16 lumpnum); void P_ParseAnimationDefintion(SINT8 istexture); @@ -347,8 +354,7 @@ void P_ParseAnimationDefintion(SINT8 istexture) if (i == maxanims) { // Increase the size to make room for the new animation definition - maxanims++; - animdefs = (animdef_t *)Z_Realloc(animdefs, sizeof(animdef_t)*(maxanims + 1), PU_STATIC, NULL); + GrowAnimDefs(); strncpy(animdefs[i].startname, animdefsToken, 9); } @@ -434,8 +440,17 @@ void P_ParseAnimationDefintion(SINT8 istexture) } animdefs[i].speed = animSpeed; Z_Free(animdefsToken); -} +#ifdef WALLFLATS + // hehe... uhh..... + if (!istexture) + { + GrowAnimDefs(); + M_Memcpy(&animdefs[maxanims-1], &animdefs[i], sizeof(animdef_t)); + animdefs[maxanims-1].istexture = 1; + } +#endif +} /** Checks for flats in levelflats that are part of a flat animation sequence * and sets them up for animation. From a9e3e0c00e8ad52b9d5cf98101a12a604a860062 Mon Sep 17 00:00:00 2001 From: Jaime Passos Date: Sat, 9 Nov 2019 13:28:56 -0300 Subject: [PATCH 022/746] Support OpenGL --- src/hardware/hw_cache.c | 28 ++++++++++++++++++++-------- src/r_data.c | 6 ++++-- 2 files changed, 24 insertions(+), 10 deletions(-) diff --git a/src/hardware/hw_cache.c b/src/hardware/hw_cache.c index 0b47bc880..3b923d516 100644 --- a/src/hardware/hw_cache.c +++ b/src/hardware/hw_cache.c @@ -642,6 +642,7 @@ static void HWR_GenerateTexture(INT32 texnum, GLTexture_t *grtex) texture_t *texture; texpatch_t *patch; patch_t *realpatch; + UINT8 *pdata; INT32 i; boolean skyspecial = false; //poor hack for Legacy large skies.. @@ -690,19 +691,30 @@ static void HWR_GenerateTexture(INT32 texnum, GLTexture_t *grtex) // Composite the columns together. for (i = 0, patch = texture->patches; i < texture->patchcount; i++, patch++) { -#ifndef NO_PNG_LUMPS + boolean dealloc = true; size_t lumplength = W_LumpLengthPwad(patch->wad, patch->lump); -#endif - realpatch = W_CacheLumpNumPwad(patch->wad, patch->lump, PU_CACHE); + pdata = W_CacheLumpNumPwad(patch->wad, patch->lump, PU_CACHE); + realpatch = (patch_t *)pdata; + #ifndef NO_PNG_LUMPS if (R_IsLumpPNG((UINT8 *)realpatch, lumplength)) realpatch = R_PNGToPatch((UINT8 *)realpatch, lumplength, NULL, false); + else #endif - HWR_DrawTexturePatchInCache(&grtex->mipmap, - blockwidth, blockheight, - texture, patch, - realpatch); - Z_Unlock(realpatch); +#ifdef WALLFLATS + if (texture->type == TEXTURETYPE_FLAT) + realpatch = R_FlatToPatch(pdata, texture->width, texture->height, 0, 0, NULL, false); + else +#endif + { + (void)lumplength; + dealloc = false; + } + + HWR_DrawTexturePatchInCache(&grtex->mipmap, blockwidth, blockheight, texture, patch, realpatch); + + if (dealloc) + Z_Unlock(realpatch); } //Hurdler: not efficient at all but I don't remember exactly how HWR_DrawPatchInCache works :( if (format2bpp[grtex->mipmap.grInfo.format]==4) diff --git a/src/r_data.c b/src/r_data.c index 38c711b7b..2674319e7 100644 --- a/src/r_data.c +++ b/src/r_data.c @@ -456,7 +456,6 @@ static UINT8 *R_GenerateTexture(size_t texnum) texture_t *texture; texpatch_t *patch; patch_t *realpatch; - boolean dealloc = false; UINT8 *pdata; int x, x1, x2, i, width, height; size_t blocksize; @@ -574,6 +573,7 @@ static UINT8 *R_GenerateTexture(size_t texnum) // Composite the columns together. for (i = 0, patch = texture->patches; i < texture->patchcount; i++, patch++) { + boolean dealloc = true; static void (*ColumnDrawerPointer)(column_t *, UINT8 *, texpatch_t *, INT32, INT32); // Column drawing function pointer. if (patch->style != AST_COPY) ColumnDrawerPointer = (patch->flip & 2) ? R_DrawBlendFlippedColumnInCache : R_DrawBlendColumnInCache; @@ -585,7 +585,6 @@ static UINT8 *R_GenerateTexture(size_t texnum) lumplength = W_LumpLengthPwad(wadnum, lumpnum); pdata = W_CacheLumpNumPwad(wadnum, lumpnum, PU_CACHE); realpatch = (patch_t *)pdata; - dealloc = true; #ifndef NO_PNG_LUMPS if (R_IsLumpPNG((UINT8 *)realpatch, lumplength)) @@ -597,7 +596,10 @@ static UINT8 *R_GenerateTexture(size_t texnum) realpatch = R_FlatToPatch(pdata, texture->width, texture->height, 0, 0, NULL, false); else #endif + { + (void)lumplength; dealloc = false; + } x1 = patch->originx; width = SHORT(realpatch->width); From 61164ea3109883492b3fa608e8329a255635f033 Mon Sep 17 00:00:00 2001 From: Jaime Passos Date: Sat, 9 Nov 2019 14:09:20 -0300 Subject: [PATCH 023/746] Trying to make sense of chroma keying --- src/hardware/hw_cache.c | 40 ++++++++++++++++------------------------ src/hardware/hw_defs.h | 2 +- src/hardware/hw_glob.h | 1 - 3 files changed, 17 insertions(+), 26 deletions(-) diff --git a/src/hardware/hw_cache.c b/src/hardware/hw_cache.c index 3b923d516..edb8a51a0 100644 --- a/src/hardware/hw_cache.c +++ b/src/hardware/hw_cache.c @@ -32,10 +32,6 @@ #include "../r_draw.h" #include "../p_setup.h" -//Hurdler: 25/04/2000: used for new colormap code in hardware mode -//static UINT8 *gr_colormap = NULL; // by default it must be NULL ! (because colormap tables are not initialized) -boolean firetranslucent = false; - // Values set after a call to HWR_ResizeBlock() static INT32 blocksize, blockwidth, blockheight; @@ -121,18 +117,16 @@ static void HWR_DrawColumnInCache(const column_t *patchcol, UINT8 *block, GLMipm texel = source[yfrac>>FRACBITS]; - if (firetranslucent && (transtables[(texel<<8)+0x40000]!=texel)) - alpha = 0x80; + //Hurdler: 25/04/2000: now support colormap in hardware mode + if (mipmap->colormap) + texel = mipmap->colormap[texel]; + + // transparent pixel + if (texel == HWR_PATCHES_CHROMAKEY_COLORINDEX) + alpha = 0x00; else alpha = 0xff; - //Hurdler: not perfect, but better than holes - if (texel == HWR_PATCHES_CHROMAKEY_COLORINDEX && (mipmap->flags & TF_CHROMAKEYED)) - texel = HWR_CHROMAKEY_EQUIVALENTCOLORINDEX; - //Hurdler: 25/04/2000: now support colormap in hardware mode - else if (mipmap->colormap) - texel = mipmap->colormap[texel]; - // hope compiler will get this switch out of the loops (dreams...) // gcc do it ! but vcc not ! (why don't use cygwin gcc for win32 ?) // Alam: SRB2 uses Mingw, HUGS @@ -235,18 +229,16 @@ static void HWR_DrawFlippedColumnInCache(const column_t *patchcol, UINT8 *block, texel = source[yfrac>>FRACBITS]; - if (firetranslucent && (transtables[(texel<<8)+0x40000]!=texel)) - alpha = 0x80; + //Hurdler: 25/04/2000: now support colormap in hardware mode + if (mipmap->colormap) + texel = mipmap->colormap[texel]; + + // transparent pixel + if (texel == HWR_PATCHES_CHROMAKEY_COLORINDEX) + alpha = 0x00; else alpha = 0xff; - //Hurdler: not perfect, but better than holes - if (texel == HWR_PATCHES_CHROMAKEY_COLORINDEX && (mipmap->flags & TF_CHROMAKEYED)) - texel = HWR_CHROMAKEY_EQUIVALENTCOLORINDEX; - //Hurdler: 25/04/2000: now support colormap in hardware mode - else if (mipmap->colormap) - texel = mipmap->colormap[texel]; - // hope compiler will get this switch out of the loops (dreams...) // gcc do it ! but vcc not ! (why don't use cygwin gcc for win32 ?) // Alam: SRB2 uses Mingw, HUGS @@ -612,7 +604,7 @@ static UINT8 *MakeBlock(GLMipmap_t *grMipmap) { UINT8 *block; INT32 bpp, i; - UINT16 bu16 = ((0x00 <<8) | HWR_CHROMAKEY_EQUIVALENTCOLORINDEX); + UINT16 bu16 = ((0x00 <<8) | HWR_PATCHES_CHROMAKEY_COLORINDEX); bpp = format2bpp[grMipmap->grInfo.format]; block = Z_Malloc(blocksize*bpp, PU_HWRCACHE, &(grMipmap->grInfo.data)); @@ -675,7 +667,7 @@ static void HWR_GenerateTexture(INT32 texnum, GLTexture_t *grtex) INT32 j; RGBA_t col; - col = V_GetColor(HWR_CHROMAKEY_EQUIVALENTCOLORINDEX); + col = V_GetColor(HWR_PATCHES_CHROMAKEY_COLORINDEX); for (j = 0; j < blockheight; j++) { for (i = 0; i < blockwidth; i++) diff --git a/src/hardware/hw_defs.h b/src/hardware/hw_defs.h index 5dcead77c..b8d420f68 100644 --- a/src/hardware/hw_defs.h +++ b/src/hardware/hw_defs.h @@ -42,7 +42,7 @@ typedef unsigned char FBOOLEAN; // byte value for paletted graphics, which represent the transparent color #define HWR_PATCHES_CHROMAKEY_COLORINDEX 255 -#define HWR_CHROMAKEY_EQUIVALENTCOLORINDEX 130 +//#define HWR_CHROMAKEY_EQUIVALENTCOLORINDEX 130 // the chroma key color shows on border sprites, set it to black #define HWR_PATCHES_CHROMAKEY_COLORVALUE (0x00000000) //RGBA format as in grSstWinOpen() diff --git a/src/hardware/hw_glob.h b/src/hardware/hw_glob.h index 72365013d..16bd97092 100644 --- a/src/hardware/hw_glob.h +++ b/src/hardware/hw_glob.h @@ -123,6 +123,5 @@ extern consvar_t cv_grrounddown; // on/off extern INT32 patchformat; extern INT32 textureformat; -extern boolean firetranslucent; #endif //_HW_GLOB_ From 243cbc02ec54502f91f09485dd4c751d09abcbfb Mon Sep 17 00:00:00 2001 From: Jaime Passos Date: Sat, 9 Nov 2019 17:53:05 -0300 Subject: [PATCH 024/746] Big Miss Steak --- src/r_plane.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/r_plane.c b/src/r_plane.c index 53b58c274..89a76aed2 100644 --- a/src/r_plane.c +++ b/src/r_plane.c @@ -1007,6 +1007,8 @@ void R_DrawSinglePlane(visplane_t *pl) R_CheckFlatLength(W_LumpLength(levelflat->u.flat.lumpnum)); // Raw flats always have dimensions that are powers-of-two numbers. ds_powersoftwo = true; + if (spanfunc == basespanfunc) + spanfunc = mmxspanfunc; break; default: switch (type) From 615547ddd17a6f3bcb777e6202073cd730210821 Mon Sep 17 00:00:00 2001 From: Jaime Passos Date: Sat, 9 Nov 2019 19:32:06 -0300 Subject: [PATCH 025/746] Fix animated flats yet again --- src/p_spec.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/p_spec.c b/src/p_spec.c index 7248d3ffb..58fe5ef60 100644 --- a/src/p_spec.c +++ b/src/p_spec.c @@ -491,7 +491,8 @@ static inline void P_FindAnimatedFlat(INT32 animnum) atoi(sizeu1(i)), foundflats->name, foundflats->animseq, foundflats->numpics,foundflats->speed); } - else if (foundflats->u.flat.lumpnum >= startflatnum && foundflats->u.flat.lumpnum <= endflatnum) + else if ((!anims[animnum].istexture) && (foundflats->type == LEVELFLAT_FLAT) + && (foundflats->u.flat.lumpnum >= startflatnum && foundflats->u.flat.lumpnum <= endflatnum)) { foundflats->u.flat.baselumpnum = startflatnum; foundflats->animseq = foundflats->u.flat.lumpnum - startflatnum; @@ -5596,7 +5597,7 @@ void P_UpdateSpecials(void) if (foundflats->speed) // it is an animated flat { // update the levelflat texture number - if (foundflats->type == LEVELFLAT_TEXTURE) + if ((foundflats->type == LEVELFLAT_TEXTURE) && (foundflats->u.texture.basenum != -1)) foundflats->u.texture.num = foundflats->u.texture.basenum + ((leveltime/foundflats->speed + foundflats->animseq) % foundflats->numpics); // update the levelflat lump number else if ((foundflats->type == LEVELFLAT_FLAT) && (foundflats->u.flat.baselumpnum != LUMPERROR)) From d467d2b2295a9660631774b9edb29555cc5c30fe Mon Sep 17 00:00:00 2001 From: Jaime Passos Date: Sun, 10 Nov 2019 00:04:11 -0300 Subject: [PATCH 026/746] GIF recording --- src/hardware/hw_main.c | 4 ++-- src/m_anigif.c | 52 +++++++++++++++++++++++++++++++++++++++--- src/m_misc.c | 8 ++----- src/r_data.c | 3 +-- src/r_data.h | 2 ++ src/sdl/i_video.c | 5 ++-- src/v_video.c | 27 ++++++++++++++++++---- src/v_video.h | 12 ++++++++++ 8 files changed, 92 insertions(+), 21 deletions(-) diff --git a/src/hardware/hw_main.c b/src/hardware/hw_main.c index 7e0b369eb..f2c30107b 100644 --- a/src/hardware/hw_main.c +++ b/src/hardware/hw_main.c @@ -580,7 +580,7 @@ static void HWR_RenderPlane(sector_t *sector, extrasubsector_t *xsub, boolean is if (nrPlaneVerts < 3) //not even a triangle ? return; - if (nrPlaneVerts > UINT16_MAX) // FIXME: exceeds plVerts size + if (nrPlaneVerts > INT16_MAX) // FIXME: exceeds plVerts size { CONS_Debug(DBG_RENDER, "polygon size of %d exceeds max value of %d vertices\n", nrPlaneVerts, UINT16_MAX); return; @@ -3171,7 +3171,7 @@ static void HWR_RenderPolyObjectPlane(polyobj_t *polysector, boolean isceiling, if (nrPlaneVerts < 3) //not even a triangle ? return; - if (nrPlaneVerts > UINT16_MAX) // FIXME: exceeds plVerts size + if (nrPlaneVerts > INT16_MAX) // FIXME: exceeds plVerts size { CONS_Debug(DBG_RENDER, "polygon size of %s exceeds max value of %d vertices\n", sizeu1(nrPlaneVerts), UINT16_MAX); return; diff --git a/src/m_anigif.c b/src/m_anigif.c index 4e68819bc..f19679ef4 100644 --- a/src/m_anigif.c +++ b/src/m_anigif.c @@ -19,6 +19,10 @@ #include "v_video.h" #include "i_video.h" +#ifdef HWRENDER +#include "hardware/hw_main.h" +#endif + // GIFs are always little-endian #include "byteptr.h" @@ -452,6 +456,32 @@ const UINT8 gifframe_gchead[4] = {0x21,0xF9,0x04,0x04}; // GCE, bytes, packed by static UINT8 *gifframe_data = NULL; static size_t gifframe_size = 8192; +#ifdef HWRENDER +static void hwrconvert(void) +{ + UINT8 *linear = HWR_GetScreenshot(); + UINT8 *dest = screens[2]; + UINT8 r, g, b; + INT32 x, y; + size_t i = 0; + + InitColorLUT(); + + for (y = 0; y < vid.height; y++) + { + for (x = 0; x < vid.width; x++, i += 3) + { + r = (UINT8)linear[i]; + g = (UINT8)linear[i + 1]; + b = (UINT8)linear[i + 2]; + dest[(y * vid.width) + x] = colorlookup[r >> SHIFTCOLORBITS][g >> SHIFTCOLORBITS][b >> SHIFTCOLORBITS]; + } + } + + free(linear); +} +#endif + // // GIF_framewrite // writes a frame into the file. @@ -477,7 +507,12 @@ static void GIF_framewrite(void) GIF_optimizeregion(cur_screen, movie_screen, &blitx, &blity, &blitw, &blith); // blit to temp screen - I_ReadScreen(movie_screen); + if (rendermode == render_soft) + I_ReadScreen(movie_screen); +#ifdef HWRENDER + else if (rendermode == render_opengl) + hwrconvert(); +#endif } else { @@ -486,7 +521,18 @@ static void GIF_framewrite(void) blith = vid.height; if (gif_frames == 0) - I_ReadScreen(movie_screen); + { + if (rendermode == render_soft) + I_ReadScreen(movie_screen); +#ifdef HWRENDER + else if (rendermode == render_opengl) + { + hwrconvert(); + VID_BlitLinearScreen(screens[2], screens[0], vid.width*vid.bpp, vid.height, vid.width*vid.bpp, vid.rowbytes); + } +#endif + } + movie_screen = screens[0]; } @@ -575,7 +621,7 @@ static void GIF_framewrite(void) // INT32 GIF_open(const char *filename) { -#ifdef HWRENDER +#if 0 if (rendermode != render_soft) { CONS_Alert(CONS_WARNING, M_GetText("GIFs cannot be taken in non-software modes!\n")); diff --git a/src/m_misc.c b/src/m_misc.c index c5e4fa21c..b2f5c5465 100644 --- a/src/m_misc.c +++ b/src/m_misc.c @@ -1119,12 +1119,8 @@ void M_StartMovie(void) switch (cv_moviemode.value) { case MM_GIF: - if (rendermode == render_soft) - { - moviemode = M_StartMovieGIF(pathname); - break; - } - /* FALLTHRU */ + moviemode = M_StartMovieGIF(pathname); + break; case MM_APNG: moviemode = M_StartMovieAPNG(pathname); break; diff --git a/src/r_data.c b/src/r_data.c index bd12eb248..c57535920 100644 --- a/src/r_data.c +++ b/src/r_data.c @@ -1162,7 +1162,6 @@ INT32 R_ColormapNumForName(char *name) // static double deltas[256][3], map[256][3]; -static UINT8 NearestColor(UINT8 r, UINT8 g, UINT8 b); static int RoundUp(double number); INT32 R_CreateColormap(char *p1, char *p2, char *p3) @@ -1342,7 +1341,7 @@ INT32 R_CreateColormap(char *p1, char *p2, char *p3) // Thanks to quake2 source! // utils3/qdata/images.c -static UINT8 NearestColor(UINT8 r, UINT8 g, UINT8 b) +UINT8 NearestColor(UINT8 r, UINT8 g, UINT8 b) { int dr, dg, db; int distortion, bestdistortion = 256 * 256 * 4, bestcolor = 0, i; diff --git a/src/r_data.h b/src/r_data.h index 5de51ccd4..614082fac 100644 --- a/src/r_data.h +++ b/src/r_data.h @@ -95,6 +95,8 @@ INT32 R_ColormapNumForName(char *name); INT32 R_CreateColormap(char *p1, char *p2, char *p3); const char *R_ColormapNameForNum(INT32 num); +UINT8 NearestColor(UINT8 r, UINT8 g, UINT8 b); + extern INT32 numtextures; #endif diff --git a/src/sdl/i_video.c b/src/sdl/i_video.c index 77bf414cc..37beaefe6 100644 --- a/src/sdl/i_video.c +++ b/src/sdl/i_video.c @@ -1292,6 +1292,7 @@ INT32 VID_SetMode(INT32 modeNum) //Impl_SetWindowName("SRB2 "VERSIONSTRING); SDLSetMode(vid.width, vid.height, USE_FULLSCREEN); + Impl_VideoSetupBuffer(); if (rendermode == render_soft) { @@ -1300,8 +1301,6 @@ INT32 VID_SetMode(INT32 modeNum) SDL_FreeSurface(bufSurface); bufSurface = NULL; } - - Impl_VideoSetupBuffer(); } return SDL_TRUE; @@ -1424,7 +1423,7 @@ static void Impl_VideoSetupSDLBuffer(void) static void Impl_VideoSetupBuffer(void) { // Set up game's software render buffer - if (rendermode == render_soft) + //if (rendermode == render_soft) { vid.rowbytes = vid.width * vid.bpp; vid.direct = NULL; diff --git a/src/v_video.c b/src/v_video.c index c3b29e157..0a57e22ac 100644 --- a/src/v_video.c +++ b/src/v_video.c @@ -2207,6 +2207,27 @@ Unoptimized version #endif } +// Taken from my videos-in-SRB2 project +// Generates a color look-up table +// which has up to 64 colors at each channel +// (see the defines in v_video.h) + +UINT8 colorlookup[CLUTSIZE][CLUTSIZE][CLUTSIZE]; + +void InitColorLUT(void) +{ + UINT8 r, g, b; + static boolean clutinit = false; + if (!clutinit) + { + for (r = 0; r < CLUTSIZE; r++) + for (g = 0; g < CLUTSIZE; g++) + for (b = 0; b < CLUTSIZE; b++) + colorlookup[r][g][b] = NearestColor(r << SHIFTCOLORBITS, g << SHIFTCOLORBITS, b << SHIFTCOLORBITS); + clutinit = true; + } +} + // V_Init // old software stuff, buffers are allocated at video mode setup // here we set the screens[x] pointers accordingly @@ -2218,13 +2239,9 @@ void V_Init(void) const INT32 screensize = vid.rowbytes * vid.height; LoadMapPalette(); - // hardware modes do not use screens[] pointers + for (i = 0; i < NUMSCREENS; i++) screens[i] = NULL; - if (rendermode != render_soft) - { - return; // be sure to cause a NULL read/write error so we detect it, in case of.. - } // start address of NUMSCREENS * width*height vidbuffers if (base) diff --git a/src/v_video.h b/src/v_video.h index 877a619b5..92c24946f 100644 --- a/src/v_video.h +++ b/src/v_video.h @@ -33,6 +33,18 @@ extern consvar_t cv_ticrate, cv_usegamma, cv_allcaps, cv_constextsize; // Allocates buffer screens, call before R_Init. void V_Init(void); +// Taken from my videos-in-SRB2 project +// Generates a color look-up table +// which has up to 64 colors at each channel + +#define COLORBITS 6 +#define SHIFTCOLORBITS (8-COLORBITS) +#define CLUTSIZE (1< Date: Mon, 11 Nov 2019 00:02:22 -0300 Subject: [PATCH 027/746] Recreate the CLUT when the palette changes --- src/v_video.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/v_video.c b/src/v_video.c index 0a57e22ac..eaaa7cd26 100644 --- a/src/v_video.c +++ b/src/v_video.c @@ -2218,13 +2218,15 @@ void InitColorLUT(void) { UINT8 r, g, b; static boolean clutinit = false; - if (!clutinit) + static RGBA_t *lastpalette = NULL; + if ((!clutinit) || (lastpalette != pLocalPalette)) { for (r = 0; r < CLUTSIZE; r++) for (g = 0; g < CLUTSIZE; g++) for (b = 0; b < CLUTSIZE; b++) colorlookup[r][g][b] = NearestColor(r << SHIFTCOLORBITS, g << SHIFTCOLORBITS, b << SHIFTCOLORBITS); clutinit = true; + lastpalette = pLocalPalette; } } From 362be6f9da4fa31221a921c597059afb97308384 Mon Sep 17 00:00:00 2001 From: Jaime Passos Date: Tue, 12 Nov 2019 21:44:43 -0300 Subject: [PATCH 028/746] Make cv_renderer a hidden command Finally! Renderer switching IS SAVED!! :tada: :tada: :tada: :tada: :tada: :tada: --- src/screen.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/screen.c b/src/screen.c index dc25b2acf..6f6ebfbd6 100644 --- a/src/screen.c +++ b/src/screen.c @@ -73,7 +73,7 @@ consvar_t cv_renderview = {"renderview", "On", 0, CV_OnOff, NULL, 0, NULL, NULL, static void SCR_ActuallyChangeRenderer(void); static CV_PossibleValue_t cv_renderer_t[] = {{1, "Software"}, {2, "OpenGL"}, {0, NULL}}; -consvar_t cv_renderer = {"renderer", "Software", CV_SAVE|CV_CALL, cv_renderer_t, SCR_ChangeRenderer, 0, NULL, NULL, 0, 0, NULL}; +consvar_t cv_renderer = {"renderer", "Software", CV_HIDEN|CV_CALL, cv_renderer_t, SCR_ChangeRenderer, 0, NULL, NULL, 0, 0, NULL}; static void SCR_ChangeFullscreen(void); From 90d385b402ac10d4602fba2e051b568b224630eb Mon Sep 17 00:00:00 2001 From: Jaime Passos Date: Tue, 12 Nov 2019 22:03:40 -0300 Subject: [PATCH 029/746] 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 f602e5bfb7131dcecdec82ef7665f0e42ae6b923 Mon Sep 17 00:00:00 2001 From: toaster Date: Sun, 24 Nov 2019 14:35:31 +0000 Subject: [PATCH 030/746] "showconditionset" option for Unlockables and Extra Emblems. See merge request (coming shortly) for full description/prompt. --- src/dehacked.c | 4 ++++ src/m_cond.h | 14 ++++++++------ src/m_menu.c | 8 ++++++-- 3 files changed, 18 insertions(+), 8 deletions(-) diff --git a/src/dehacked.c b/src/dehacked.c index 49ad5dc67..5fa4902cb 100644 --- a/src/dehacked.c +++ b/src/dehacked.c @@ -3195,6 +3195,8 @@ static void readextraemblemdata(MYFILE *f, INT32 num) sizeof (extraemblems[num-1].description), va("Extra emblem %d: objective", num)); else if (fastcmp(word, "CONDITIONSET")) extraemblems[num-1].conditionset = (UINT8)value; + else if (fastcmp(word, "SHOWCONDITIONSET")) + extraemblems[num-1].showconditionset = (UINT8)value; else { strupr(word2); @@ -3281,6 +3283,8 @@ static void readunlockable(MYFILE *f, INT32 num) unlockables[num].height = (UINT16)i; else if (fastcmp(word, "CONDITIONSET")) unlockables[num].conditionset = (UINT8)i; + else if (fastcmp(word, "SHOWCONDITIONSET")) + unlockables[num].showconditionset = (UINT8)i; else if (fastcmp(word, "NOCECHO")) unlockables[num].nocecho = (UINT8)(i || word2[0] == 'T' || word2[0] == 'Y'); else if (fastcmp(word, "NOCHECKLIST")) diff --git a/src/m_cond.h b/src/m_cond.h index e9859cf11..f6d011a8f 100644 --- a/src/m_cond.h +++ b/src/m_cond.h @@ -97,12 +97,13 @@ typedef struct } emblem_t; typedef struct { - char name[20]; ///< Name of the goal (used in the "emblem awarded" cecho) - char description[40];///< Description of goal (used in statistics) - UINT8 conditionset; ///< Condition set that awards this emblem. - UINT8 sprite; ///< emblem sprite to use, 0 - 25 - UINT8 color; ///< skincolor to use - UINT8 collected; ///< Do you have this emblem? + char name[20]; ///< Name of the goal (used in the "emblem awarded" cecho) + char description[40]; ///< Description of goal (used in statistics) + UINT8 conditionset; ///< Condition set that awards this emblem. + UINT8 showconditionset; ///< Condition set that shows this emblem. + UINT8 sprite; ///< emblem sprite to use, 0 - 25 + UINT8 color; ///< skincolor to use + UINT8 collected; ///< Do you have this emblem? } extraemblem_t; // Unlockable information @@ -112,6 +113,7 @@ typedef struct char objective[64]; UINT16 height; // menu height UINT8 conditionset; + UINT8 showconditionset; INT16 type; INT16 variable; UINT8 nocecho; diff --git a/src/m_menu.c b/src/m_menu.c index 32efa3fed..df6a2d449 100644 --- a/src/m_menu.c +++ b/src/m_menu.c @@ -6685,7 +6685,8 @@ static void M_DrawChecklist(void) while (i < MAXUNLOCKABLES) { if (unlockables[i].name[0] == 0 //|| unlockables[i].nochecklist - || !unlockables[i].conditionset || unlockables[i].conditionset > MAXCONDITIONSETS) + || !unlockables[i].conditionset || unlockables[i].conditionset > MAXCONDITIONSETS + || (!unlockables[i].unlocked && unlockables[i].showconditionset && !M_Achieved(unlockables[i].showconditionset))) continue; V_DrawString(currentMenu->x, y, ((unlockables[i].unlocked) ? V_GREENMAP : V_TRANSLUCENT)|V_ALLOWLOWERCASE, ((unlockables[i].unlocked || !unlockables[i].nochecklist) ? unlockables[i].name : M_CreateSecretMenuOption(unlockables[i].name))); @@ -8901,7 +8902,10 @@ static void M_DrawStatsMaps(int location) else V_DrawSmallScaledPatch(292, y, 0, W_CachePatchName("NEEDIT", PU_CACHE)); - V_DrawString(20, y, V_YELLOWMAP|V_ALLOWLOWERCASE, va("%s", exemblem->description)); + V_DrawString(20, y, V_YELLOWMAP|V_ALLOWLOWERCASE, + (!exemblem->collected && exemblem->showconditionset && !M_Achieved(exemblem->showconditionset)) + ? M_CreateSecretMenuOption(exemblem->description) + : exemblem->description); } y += 8; From fd657d2ff4ac16a415f1b7cbdd32fc8860c1f197 Mon Sep 17 00:00:00 2001 From: toaster Date: Sun, 24 Nov 2019 15:06:37 +0000 Subject: [PATCH 031/746] Fix bugs discovered in testing. --- src/m_menu.c | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/src/m_menu.c b/src/m_menu.c index df6a2d449..303ba3453 100644 --- a/src/m_menu.c +++ b/src/m_menu.c @@ -6625,6 +6625,8 @@ static void M_HandleChecklist(INT32 choice) continue; if (unlockables[j].conditionset > MAXCONDITIONSETS) continue; + if (!unlockables[j].unlocked && unlockables[j].showconditionset && !M_Achieved(unlockables[j].showconditionset)) + continue; if (unlockables[j].conditionset == unlockables[check_on].conditionset) continue; break; @@ -6648,6 +6650,8 @@ static void M_HandleChecklist(INT32 choice) continue; if (unlockables[j].conditionset > MAXCONDITIONSETS) continue; + if (!unlockables[j].unlocked && unlockables[j].showconditionset && !M_Achieved(unlockables[j].showconditionset)) + continue; if (j && unlockables[j].conditionset == unlockables[j-1].conditionset) continue; break; @@ -6687,7 +6691,10 @@ static void M_DrawChecklist(void) if (unlockables[i].name[0] == 0 //|| unlockables[i].nochecklist || !unlockables[i].conditionset || unlockables[i].conditionset > MAXCONDITIONSETS || (!unlockables[i].unlocked && unlockables[i].showconditionset && !M_Achieved(unlockables[i].showconditionset))) + { + i++; continue; + } V_DrawString(currentMenu->x, y, ((unlockables[i].unlocked) ? V_GREENMAP : V_TRANSLUCENT)|V_ALLOWLOWERCASE, ((unlockables[i].unlocked || !unlockables[i].nochecklist) ? unlockables[i].name : M_CreateSecretMenuOption(unlockables[i].name))); @@ -6709,10 +6716,11 @@ static void M_DrawChecklist(void) if (unlockables[i].objective[0] != '/') { - addy(8); - V_DrawString(currentMenu->x, y, + addy(16); + V_DrawString(currentMenu->x, y-8, V_ALLOWLOWERCASE, va("\x1E %s", unlockables[i].objective)); + y -= 8; } else { From 6adb957f0f836349ee684d366d679505c9cfc0ec Mon Sep 17 00:00:00 2001 From: Jaime Passos Date: Wed, 4 Dec 2019 19:25:39 -0300 Subject: [PATCH 032/746] Slap colormap fades everywhere --- src/d_main.c | 16 ++++++++-- src/f_finale.c | 12 ++++---- src/f_finale.h | 7 ++++- src/f_wipe.c | 80 ++++++++++++++++++++++++++++++++++++++++---------- src/g_game.c | 9 +++--- src/g_game.h | 2 +- src/p_setup.c | 2 +- src/st_stuff.c | 5 ++-- src/st_stuff.h | 2 +- 9 files changed, 100 insertions(+), 35 deletions(-) diff --git a/src/d_main.c b/src/d_main.c index 5853fccf0..c26fbad0d 100644 --- a/src/d_main.c +++ b/src/d_main.c @@ -274,7 +274,10 @@ static void D_Display(void) && wipetypepre != UINT8_MAX) { F_WipeStartScreen(); - F_WipeColorFill(31); + // Check for Mega Genesis fade + wipestyleflags = WSF_FADEOUT; + if (F_TryColormapFade(31)) + wipetypepost = -1; // Don't run the fade below this one F_WipeEndScreen(); F_RunWipe(wipetypepre, gamestate != GS_TIMEATTACK && gamestate != GS_TITLESCREEN); } @@ -488,15 +491,24 @@ static void D_Display(void) if (rendermode != render_none) { F_WipeEndScreen(); + // Funny. if (WipeStageTitle && st_overlay) { lt_ticker--; lt_lasttic = lt_ticker; - ST_preLevelTitleCardDrawer(0, false); + ST_preLevelTitleCardDrawer(false); V_DrawFill(0, 0, BASEVIDWIDTH, BASEVIDHEIGHT, levelfadecol); F_WipeStartScreen(); } + + // Check for Mega Genesis fade + if (F_ShouldColormapFade()) + { + wipestyleflags |= WSF_FADEIN; + wipestyleflags &= ~WSF_FADEOUT; + } + F_RunWipe(wipetypepost, gamestate != GS_TIMEATTACK && gamestate != GS_TITLESCREEN); } diff --git a/src/f_finale.c b/src/f_finale.c index 306dad4e9..c33cbc16b 100644 --- a/src/f_finale.c +++ b/src/f_finale.c @@ -910,8 +910,9 @@ void F_IntroDrawer(void) { if (rendermode != render_none) { + wipestyleflags = WSF_FADEOUT; F_WipeStartScreen(); - F_WipeColorFill(31); + F_TryColormapFade(31); F_WipeEndScreen(); F_RunWipe(99,true); } @@ -920,12 +921,11 @@ void F_IntroDrawer(void) } else if (intro_scenenum == 10) { - // The only fade to white in the entire damn game. - // (not true) if (rendermode != render_none) { + wipestyleflags = (WSF_FADEOUT|WSF_TOWHITE); F_WipeStartScreen(); - F_WipeColorFill(0); + F_TryColormapFade(0); F_WipeEndScreen(); F_RunWipe(99,true); } @@ -934,8 +934,9 @@ void F_IntroDrawer(void) { if (rendermode != render_none) { + wipestyleflags = WSF_FADEOUT; F_WipeStartScreen(); - F_WipeColorFill(31); + F_TryColormapFade(31); F_WipeEndScreen(); F_RunWipe(99,true); } @@ -970,6 +971,7 @@ void F_IntroDrawer(void) F_WipeStartScreen(); wipegamestate = -1; + wipestyleflags = WSF_CROSSFADE; animtimer = stoptimer = 0; } diff --git a/src/f_finale.h b/src/f_finale.h index 0002cb3cf..5c03518a1 100644 --- a/src/f_finale.h +++ b/src/f_finale.h @@ -146,7 +146,7 @@ extern boolean WipeStageTitle; typedef enum { WIPESTYLE_NORMAL, - WIPESTYLE_LEVEL + WIPESTYLE_COLORMAP } wipestyle_t; extern wipestyle_t wipestyle; @@ -159,6 +159,11 @@ typedef enum } wipestyleflags_t; extern wipestyleflags_t wipestyleflags; +// Even my function names are borderline +boolean F_ShouldColormapFade(void); +boolean F_TryColormapFade(UINT8 wipecolor); +void F_DecideWipeStyle(void); + #define FADECOLORMAPDIV 8 #define FADECOLORMAPROWS (256/FADECOLORMAPDIV) diff --git a/src/f_wipe.c b/src/f_wipe.c index b88b39ef0..ea52042a5 100644 --- a/src/f_wipe.c +++ b/src/f_wipe.c @@ -161,7 +161,7 @@ static fademask_t *F_GetFadeMask(UINT8 masknum, UINT8 scrnnum) { { // Determine pixel to use from fademask pcolor = &pMasterPalette[*lump++]; - if (wipestyle == WIPESTYLE_LEVEL) + if (wipestyle == WIPESTYLE_COLORMAP) *mask++ = pcolor->s.red / FADECOLORMAPDIV; else *mask++ = FixedDiv((pcolor->s.red+1)<>FRACBITS; @@ -191,7 +191,7 @@ void F_WipeStageTitle(void) { // draw level title if ((WipeStageTitle && st_overlay) - && (wipestyle == WIPESTYLE_LEVEL) + && (wipestyle == WIPESTYLE_COLORMAP) && !(mapheaderinfo[gamemap-1]->levelflags & LF_NOTITLECARD) && *mapheaderinfo[gamemap-1]->lvlttl != '\0') { @@ -282,7 +282,7 @@ static void F_DoWipe(fademask_t *fademask) relativepos += vid.width; } } - else if (*mask >= ((wipestyle == WIPESTYLE_LEVEL) ? FADECOLORMAPROWS : 10)) + else if (*mask >= ((wipestyle == WIPESTYLE_COLORMAP) ? FADECOLORMAPROWS : 10)) { // shortcut - memcpy target to work while (draw_linestogo--) @@ -293,7 +293,7 @@ static void F_DoWipe(fademask_t *fademask) } else { - if (wipestyle == WIPESTYLE_LEVEL) + if (wipestyle == WIPESTYLE_COLORMAP) { int nmask; UINT8 *fade = fadecolormap; @@ -321,7 +321,7 @@ static void F_DoWipe(fademask_t *fademask) e = e_base + relativepos; draw_rowstogo = draw_rowend - draw_rowstart; - if (wipestyle == WIPESTYLE_LEVEL) + if (wipestyle == WIPESTYLE_COLORMAP) { while (draw_rowstogo--) *w++ = transtbl[*e++]; @@ -382,6 +382,62 @@ void F_WipeEndScreen(void) #endif } +/** Verifies every condition for a colormapped fade. + */ +boolean F_ShouldColormapFade(void) +{ + if ((wipestyleflags & (WSF_FADEIN|WSF_FADEOUT)) // only if one of those wipestyleflags are actually set + && !(wipestyleflags & WSF_CROSSFADE)) // and if not crossfading + { + // World + return (gamestate == GS_LEVEL + || gamestate == GS_TITLESCREEN + // Finales + || gamestate == GS_CONTINUING + || gamestate == GS_CREDITS + || gamestate == GS_EVALUATION + || gamestate == GS_INTRO + || gamestate == GS_ENDING + // Menus + || gamestate == GS_TIMEATTACK); + } + return false; +} + +/** Decides what wipe style to use. + */ +void F_DecideWipeStyle(void) +{ + // Set default wipe style + wipestyle = WIPESTYLE_NORMAL; + + // Check for colormap wipe style + if (F_ShouldColormapFade()) + wipestyle = WIPESTYLE_COLORMAP; +} + +/** Attempt to run a colormap fade, + provided all the conditionals were properly met. + Returns true if so. + I demand you call F_RunWipe after this function. + */ +boolean F_TryColormapFade(UINT8 wipecolor) +{ + if (F_ShouldColormapFade()) + { +#ifdef HWRENDER + if (rendermode == render_opengl) + F_WipeColorFill(wipecolor); +#endif + return true; + } + else + { + F_WipeColorFill(wipecolor); + return false; + } +} + /** After setting up the screens you want to wipe, * calling this will do a 'typical' wipe. */ @@ -399,18 +455,10 @@ void F_RunWipe(UINT8 wipetype, boolean drawMenu) paldiv = FixedDiv(257<levelflags & LF_NOTITLECARD) @@ -1828,7 +1825,7 @@ void G_StartTitleCard(void) // // Run the title card before fading in to the level. // -void G_PreLevelTitleCard(tic_t ticker, boolean update) +void G_PreLevelTitleCard(void) { tic_t starttime = I_GetTime(); tic_t endtime = starttime + (PRELEVELTIME*NEWTICRATERATIO); @@ -1842,13 +1839,15 @@ void G_PreLevelTitleCard(tic_t ticker, boolean update) lasttime = nowtime; ST_runTitleCard(); - ST_preLevelTitleCardDrawer(ticker, update); + ST_preLevelTitleCardDrawer(true); if (moviemode) M_SaveFrame(); if (takescreenshot) // Only take screenshots after drawing. M_DoScreenShot(); } + if (!st_overlay) + wipestyleflags = WSF_CROSSFADE; } INT32 pausedelay = 0; diff --git a/src/g_game.h b/src/g_game.h index 0a575c099..b4898a68f 100644 --- a/src/g_game.h +++ b/src/g_game.h @@ -141,7 +141,7 @@ void G_DeferedInitNew(boolean pultmode, const char *mapname, INT32 pickedchar, boolean SSSG, boolean FLS); void G_DoLoadLevel(boolean resetplayer); void G_StartTitleCard(void); -void G_PreLevelTitleCard(tic_t ticker, boolean update); +void G_PreLevelTitleCard(void); void G_DeferedPlayDemo(const char *demo); // Can be called by the startup code or M_Responder, calls P_SetupLevel. diff --git a/src/p_setup.c b/src/p_setup.c index 9054b582c..520f3136d 100644 --- a/src/p_setup.c +++ b/src/p_setup.c @@ -3265,7 +3265,7 @@ boolean P_SetupLevel(boolean skipprecip) // If so... if ((!(mapheaderinfo[gamemap-1]->levelflags & LF_NOTITLECARD)) && (*mapheaderinfo[gamemap-1]->lvlttl != '\0')) - G_PreLevelTitleCard(lt_ticker, true); + G_PreLevelTitleCard(); return true; } diff --git a/src/st_stuff.c b/src/st_stuff.c index 3a8a4d2f1..8e255a46e 100644 --- a/src/st_stuff.c +++ b/src/st_stuff.c @@ -1348,11 +1348,10 @@ luahook: // // Drawer for G_PreLevelTitleCard. // -void ST_preLevelTitleCardDrawer(tic_t ticker, boolean update) +void ST_preLevelTitleCardDrawer(boolean update) { V_DrawFill(0, 0, BASEVIDWIDTH, BASEVIDHEIGHT, levelfadecol); - if (ticker < PRELEVELTIME-1) - ST_drawWipeTitleCard(); + ST_drawWipeTitleCard(); I_OsPolling(); I_UpdateNoBlit(); diff --git a/src/st_stuff.h b/src/st_stuff.h index 33ffa957a..325114af5 100644 --- a/src/st_stuff.h +++ b/src/st_stuff.h @@ -52,7 +52,7 @@ void ST_startTitleCard(void); void ST_runTitleCard(void); void ST_drawTitleCard(void); void ST_preDrawTitleCard(void); -void ST_preLevelTitleCardDrawer(tic_t ticker, boolean update); +void ST_preLevelTitleCardDrawer(boolean update); void ST_drawWipeTitleCard(void); extern tic_t lt_ticker, lt_lasttic; From 7384522aef5dcd85ac5ef3171571c120e1887143 Mon Sep 17 00:00:00 2001 From: Jaime Passos Date: Thu, 5 Dec 2019 01:47:51 -0300 Subject: [PATCH 033/746] Fix Continue game state wipes --- src/f_finale.c | 2 ++ src/f_wipe.c | 2 +- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/src/f_finale.c b/src/f_finale.c index c33cbc16b..73a82523f 100644 --- a/src/f_finale.c +++ b/src/f_finale.c @@ -3569,6 +3569,8 @@ void F_StartContinue(void) return; } + wipestyleflags = WSF_FADEOUT; + F_TryColormapFade(31); G_SetGamestate(GS_CONTINUING); gameaction = ga_nothing; diff --git a/src/f_wipe.c b/src/f_wipe.c index ea52042a5..f9d03a149 100644 --- a/src/f_wipe.c +++ b/src/f_wipe.c @@ -56,7 +56,7 @@ UINT8 wipedefs[NUMWIPEDEFS] = { 0, // wipe_level_toblack UINT8_MAX, // wipe_intermission_toblack - UINT8_MAX, // wipe_continuing_toblack + 0, // wipe_continuing_toblack 0, // wipe_titlescreen_toblack 0, // wipe_timeattack_toblack 99, // wipe_credits_toblack From 514616c546777ca20e833d40c0a2488d10ef6add Mon Sep 17 00:00:00 2001 From: toaster Date: Thu, 5 Dec 2019 19:09:41 +0000 Subject: [PATCH 034/746] Allow for 10 emblem hints on a map by poking the drawer a bit. This is a very small diff, but I can understand if you'd not feel comfortable having this until after 2.2.0. --- src/m_menu.c | 34 ++++++++++++++++++++++++++++------ 1 file changed, 28 insertions(+), 6 deletions(-) diff --git a/src/m_menu.c b/src/m_menu.c index bd96b5d0d..b5a28d0f7 100644 --- a/src/m_menu.c +++ b/src/m_menu.c @@ -6955,11 +6955,23 @@ static void M_EmblemHints(INT32 choice) static void M_DrawEmblemHints(void) { - INT32 i, j = 0; - UINT32 collected = 0; + INT32 i, j = 0, x, y; + UINT32 collected = 0, local = 0; emblem_t *emblem; const char *hint; + for (i = 0; i < numemblems; i++) + { + emblem = &emblemlocations[i]; + if (emblem->level != gamemap || emblem->type > ET_SKIN) + continue; + if (++local >= NUMHINTS*2) + break; + } + + x = (local > NUMHINTS ? 4 : 12); + y = 8; + for (i = 0; i < numemblems; i++) { emblem = &emblemlocations[i]; @@ -6969,13 +6981,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(x, y+4, 0, W_CachePatchName(M_GetEmblemPatch(emblem, false), PU_CACHE), 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(x, y+4, 0, W_CachePatchName("NEEDIT", PU_CACHE)); } if (emblem->hint[0]) @@ -6983,9 +6995,19 @@ static void M_DrawEmblemHints(void) else hint = M_GetText("No hints available."); hint = V_WordWrap(40, BASEVIDWIDTH-12, 0, hint); - V_DrawString(40, 8+(28*j), V_RETURN8|V_ALLOWLOWERCASE|collected, hint); + if (local > NUMHINTS) + V_DrawThinString(x+28, y, V_RETURN8|V_ALLOWLOWERCASE|collected, hint); + else + V_DrawString(x+28, y, V_RETURN8|V_ALLOWLOWERCASE|collected, hint); - if (++j >= NUMHINTS) + y += 28; + + if (++j == NUMHINTS) + { + x = 4+(BASEVIDWIDTH/2); + y = 8; + } + else if (j >= NUMHINTS*2) break; } if (!j) From ed34cb8d793692694a0a2694af00ec68793a5f5c Mon Sep 17 00:00:00 2001 From: Jaime Passos Date: Thu, 5 Dec 2019 16:25:19 -0300 Subject: [PATCH 035/746] Change st_overlay to cv_showhud.value --- 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 6b987646a..4df8071ad 100644 --- a/src/g_game.c +++ b/src/g_game.c @@ -1847,7 +1847,7 @@ void G_PreLevelTitleCard(void) if (takescreenshot) // Only take screenshots after drawing. M_DoScreenShot(); } - if (!st_overlay) + if (!cv_showhud.value) wipestyleflags = WSF_CROSSFADE; } From b76a1d3df733754d2c56ac12e91cde10cceb82fe Mon Sep 17 00:00:00 2001 From: toaster Date: Thu, 5 Dec 2019 19:26:31 +0000 Subject: [PATCH 036/746] * Don't iterate through the list twice to print "No hidden emblems on this map". * Make it "No hint available for this emblem" instead of "No hints available", which people may confuse as the first message (I know I did!) --- src/m_menu.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/m_menu.c b/src/m_menu.c index b5a28d0f7..061ea1e96 100644 --- a/src/m_menu.c +++ b/src/m_menu.c @@ -6972,7 +6972,9 @@ static void M_DrawEmblemHints(void) x = (local > NUMHINTS ? 4 : 12); y = 8; - for (i = 0; i < numemblems; i++) + if (!local) + V_DrawCenteredString(160, 48, V_YELLOWMAP, "No hidden emblems on this map."); + else for (i = 0; i < numemblems; i++) { emblem = &emblemlocations[i]; if (emblem->level != gamemap || emblem->type > ET_SKIN) @@ -6993,7 +6995,7 @@ static void M_DrawEmblemHints(void) if (emblem->hint[0]) hint = emblem->hint; else - hint = M_GetText("No hints available."); + hint = M_GetText("No hint available for this emblem."); hint = V_WordWrap(40, BASEVIDWIDTH-12, 0, hint); if (local > NUMHINTS) V_DrawThinString(x+28, y, V_RETURN8|V_ALLOWLOWERCASE|collected, hint); @@ -7010,8 +7012,6 @@ static void M_DrawEmblemHints(void) else if (j >= NUMHINTS*2) break; } - if (!j) - V_DrawCenteredString(160, 48, V_YELLOWMAP, "No hidden emblems on this map."); M_DrawGenericMenu(); } From d87251f8537fe622ca5bbf0c2b42692eeff23a1a Mon Sep 17 00:00:00 2001 From: MascaraSnake Date: Sat, 7 Dec 2019 09:51:09 +0100 Subject: [PATCH 037/746] Rename SDURF to SURF and CastleBot FaceStabber to Lance-a-Bot for maximum pun --- extras/conf/SRB2-22.cfg | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/extras/conf/SRB2-22.cfg b/extras/conf/SRB2-22.cfg index e31402a6c..aa7e76eb0 100644 --- a/extras/conf/SRB2-22.cfg +++ b/extras/conf/SRB2-22.cfg @@ -3292,7 +3292,7 @@ thingtypes } 102 { - title = "Stupid Dumb Unnamed RoboFish"; + title = "Stupid Unnamed RoboFish"; sprite = "FISHA0"; width = 8; height = 28; @@ -3389,14 +3389,14 @@ thingtypes } 118 { - title = "CastleBot FaceStabber"; + title = "Lance-a-Bot"; sprite = "CBFSA1"; width = 32; height = 72; } 1113 { - title = "Suspicious FaceStabber Statue"; + title = "Suspicious Lance-a-Bot Statue"; sprite = "CBBSA1"; width = 32; height = 72; @@ -5006,7 +5006,7 @@ thingtypes { arrow = 1; blocking = 2; - title = "FaceStabber Statue"; + title = "Lance-a-Bot Statue"; sprite = "CBBSA1"; width = 32; height = 72; From 2775d5f52f64e713cc4c4d2530055d9c51b4d032 Mon Sep 17 00:00:00 2001 From: MascaraSnake Date: Sat, 7 Dec 2019 06:46:37 -0500 Subject: [PATCH 038/746] SDURF to SURF turned out to be contentious. --- extras/conf/SRB2-22.cfg | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/extras/conf/SRB2-22.cfg b/extras/conf/SRB2-22.cfg index aa7e76eb0..5bc48211c 100644 --- a/extras/conf/SRB2-22.cfg +++ b/extras/conf/SRB2-22.cfg @@ -3292,7 +3292,7 @@ thingtypes } 102 { - title = "Stupid Unnamed RoboFish"; + title = "Stupid Dumb Unnamed RoboFish"; sprite = "FISHA0"; width = 8; height = 28; From 9c5e55811718892847737510ff90a15fb5c066b5 Mon Sep 17 00:00:00 2001 From: Tasos Sahanidis Date: Sat, 7 Dec 2019 20:31:40 +0200 Subject: [PATCH 039/746] Remove patch.pk3 from cmake --- assets/CMakeLists.txt | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/assets/CMakeLists.txt b/assets/CMakeLists.txt index 881153682..8bc20e833 100644 --- a/assets/CMakeLists.txt +++ b/assets/CMakeLists.txt @@ -15,8 +15,7 @@ set(SRB2_ASSET_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}/installer" set(SRB2_ASSET_HASHED "srb2.pk3;\ player.dta;\ -zones.pk3;\ -patch.pk3" +zones.pk3" CACHE STRING "Asset filenames to apply MD5 checks. No spaces between entries!" ) From 0d41a55071eae9a9daf9ebf3a8f52f7a540a45f9 Mon Sep 17 00:00:00 2001 From: mazmazz Date: Sat, 7 Dec 2019 13:04:51 -0500 Subject: [PATCH 040/746] Deployer fixes for 2.2.0 --- CMakeLists.txt | 2 +- appveyor.yml | 14 +++++++------- assets/CMakeLists.txt | 10 +++++++--- deployer/travis/deployer_defaults.sh | 16 ++++++++-------- src/sdl/macosx/Srb2mac.xcodeproj/project.pbxproj | 4 ++-- 5 files changed, 25 insertions(+), 21 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 96e32a06d..dd9703914 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -2,7 +2,7 @@ cmake_minimum_required(VERSION 3.0) # DO NOT CHANGE THIS SRB2 STRING! Some variable names depend on this string. # Version change is fine. project(SRB2 - VERSION 2.1.25 + VERSION 2.2.0 LANGUAGES C) if(${PROJECT_SOURCE_DIR} MATCHES ${PROJECT_BINARY_DIR}) diff --git a/appveyor.yml b/appveyor.yml index d58976fd5..748babb88 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -1,4 +1,4 @@ -version: 2.1.25.{branch}-{build} +version: 2.2.0.{branch}-{build} os: MinGW environment: @@ -29,15 +29,15 @@ environment: ############################## DPL_ENABLED: 0 DPL_TAG_ENABLED: 0 - DPL_INSTALLER_NAME: SRB2-v2123 + DPL_INSTALLER_NAME: SRB2-v220 # Asset handling is barebones vs. Travis Deployer. We operate on 7z only. # Include the README files and the OpenGL batch in the main and patch archives. # The x86/x64 archives contain the DLL binaries. - ASSET_ARCHIVE_PATH: https://github.com/mazmazz/SRB2/releases/download/SRB2_assets/SRB2-v2122-assets.7z - ASSET_ARCHIVE_PATCH_PATH: https://github.com/mazmazz/SRB2/releases/download/SRB2_assets/SRB2-v2122-patch-assets.7z - ASSET_ARCHIVE_X86_PATH: https://github.com/mazmazz/SRB2/releases/download/SRB2_assets/SRB2-v2122-x86-assets.7z - ASSET_ARCHIVE_X64_PATH: https://github.com/mazmazz/SRB2/releases/download/SRB2_assets/SRB2-v2122-x64-assets.7z - ASSET_ARCHIVE_OPTIONAL_PATH: https://github.com/mazmazz/SRB2/releases/download/SRB2_assets/SRB2-v2122-optional-assets.7z + ASSET_ARCHIVE_PATH: https://github.com/mazmazz/SRB2/releases/download/SRB2_assets_220/SRB2-v220-assets.7z + ASSET_ARCHIVE_PATCH_PATH: https://github.com/mazmazz/SRB2/releases/download/SRB2_assets_220/SRB2-v220-patch-assets.7z + ASSET_ARCHIVE_X86_PATH: https://github.com/mazmazz/SRB2/releases/download/SRB2_assets_220/SRB2-v220-x86-assets.7z + ASSET_ARCHIVE_X64_PATH: https://github.com/mazmazz/SRB2/releases/download/SRB2_assets_220/SRB2-v220-x64-assets.7z + ASSET_ARCHIVE_OPTIONAL_PATH: https://github.com/mazmazz/SRB2/releases/download/SRB2_assets_220/SRB2-v220-optional-assets.7z # This is overridden to 1 for release tag builds ASSET_FILES_OPTIONAL_GET: 0 # For patches, also include the X86/X64 DLLs. diff --git a/assets/CMakeLists.txt b/assets/CMakeLists.txt index 881153682..0636c1e59 100644 --- a/assets/CMakeLists.txt +++ b/assets/CMakeLists.txt @@ -12,18 +12,22 @@ ENDFUNCTION(PREPEND) set(SRB2_ASSET_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}/installer" CACHE STRING "Path to directory that contains all asset files for the installer.") +#################### +# POST-V2.2 NOTE: Do not forget to add patch.pk3 to the end of this list! +#################### + set(SRB2_ASSET_HASHED "srb2.pk3;\ player.dta;\ -zones.pk3;\ -patch.pk3" +zones.pk3" CACHE STRING "Asset filenames to apply MD5 checks. No spaces between entries!" ) set(SRB2_ASSET_DOCS "README.txt;\ LICENSE.txt;\ -LICENSE-3RD-PARTY.txt" +LICENSE-3RD-PARTY.txt;\ +README-SDL.txt" CACHE STRING "Documentation filenames. In OS X, these are packaged separately from other assets. No spaces between entries!" ) diff --git a/deployer/travis/deployer_defaults.sh b/deployer/travis/deployer_defaults.sh index bccb7409a..343fbd967 100644 --- a/deployer/travis/deployer_defaults.sh +++ b/deployer/travis/deployer_defaults.sh @@ -27,10 +27,10 @@ : ${_DPL_PACKAGE_ASSET} # Build asset installation package. Linux only. # Asset File Parameters -: ${ASSET_ARCHIVE_PATH:=https://github.com/mazmazz/SRB2/releases/download/SRB2_assets/SRB2-v2122-assets.7z} -: ${ASSET_ARCHIVE_OPTIONAL_PATH:=https://github.com/mazmazz/SRB2/releases/download/SRB2_assets/SRB2-v2122-optional-assets.7z} -: ${ASSET_FILES_HASHED:=srb2.srb zones.dta player.dta rings.dta patch.dta} -: ${ASSET_FILES_DOCS:=README.txt LICENSE.txt LICENSE-3RD-PARTY.txt} +: ${ASSET_ARCHIVE_PATH:=https://github.com/mazmazz/SRB2/releases/download/SRB2_assets_220/SRB2-v220-assets.7z} +: ${ASSET_ARCHIVE_OPTIONAL_PATH:=https://github.com/mazmazz/SRB2/releases/download/SRB2_assets_220/SRB2-v220-optional-assets.7z} +: ${ASSET_FILES_HASHED:=srb2.pk3 zones.pk3 player.dta patch.pk3} +: ${ASSET_FILES_DOCS:=README.txt LICENSE.txt LICENSE-3RD-PARTY.txt README-SDL.txt} : ${ASSET_FILES_OPTIONAL_GET:=0} # FTP Parameters @@ -51,7 +51,7 @@ # Package Parameters : ${PACKAGE_NAME:=srb2} -: ${PACKAGE_VERSION:=2.1.23} +: ${PACKAGE_VERSION:=2.2.0} : ${PACKAGE_SUBVERSION} # Highly recommended to set this to reflect the distro series target (e.g., ~18.04bionic) : ${PACKAGE_REVISION} # Defaults to UTC timestamp : ${PACKAGE_INSTALL_PATH:=/usr/games/SRB2} @@ -62,12 +62,12 @@ : ${PACKAGE_GROUP_NAME_EMAIL:=Sonic Team Junior } : ${PACKAGE_WEBSITE:=} -: ${PACKAGE_ASSET_MINVERSION:=2.1.21} # Number this the version BEFORE the actual required version, because we do a > check -: ${PACKAGE_ASSET_MAXVERSION:=2.1.24} # Number this the version AFTER the actual required version, because we do a < check +: ${PACKAGE_ASSET_MINVERSION:=2.1.26} # Number this the version BEFORE the actual required version, because we do a > check +: ${PACKAGE_ASSET_MAXVERSION:=2.2.1} # Number this the version AFTER the actual required version, because we do a < check : ${PROGRAM_NAME:=Sonic Robo Blast 2} : ${PROGRAM_VENDOR:=Sonic Team Junior} -: ${PROGRAM_VERSION:=2.1.23} +: ${PROGRAM_VERSION:=2.2.0} : ${PROGRAM_DESCRIPTION:=A free 3D Sonic the Hedgehog fangame closely inspired by the original Sonic games on the Sega Genesis.} : ${PROGRAM_FILENAME:=srb2} diff --git a/src/sdl/macosx/Srb2mac.xcodeproj/project.pbxproj b/src/sdl/macosx/Srb2mac.xcodeproj/project.pbxproj index 9297833e2..ab3157c44 100644 --- a/src/sdl/macosx/Srb2mac.xcodeproj/project.pbxproj +++ b/src/sdl/macosx/Srb2mac.xcodeproj/project.pbxproj @@ -1219,7 +1219,7 @@ C01FCF4B08A954540054247B /* Debug */ = { isa = XCBuildConfiguration; buildSettings = { - CURRENT_PROJECT_VERSION = 2.1.25; + CURRENT_PROJECT_VERSION = 2.2.0; GCC_PREPROCESSOR_DEFINITIONS = ( "$(inherited)", NORMALSRB2, @@ -1231,7 +1231,7 @@ C01FCF4C08A954540054247B /* Release */ = { isa = XCBuildConfiguration; buildSettings = { - CURRENT_PROJECT_VERSION = 2.1.25; + CURRENT_PROJECT_VERSION = 2.2.0; GCC_ENABLE_FIX_AND_CONTINUE = NO; GCC_GENERATE_DEBUGGING_SYMBOLS = NO; GCC_PREPROCESSOR_DEFINITIONS = ( From 2a9a2c0f021b964f2955ec75f3526f638ae1e69d Mon Sep 17 00:00:00 2001 From: mazmazz Date: Sat, 7 Dec 2019 14:30:51 -0500 Subject: [PATCH 041/746] Travis yflip error --- src/hardware/r_opengl/r_opengl.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/hardware/r_opengl/r_opengl.c b/src/hardware/r_opengl/r_opengl.c index 25bcf153b..22b8675a0 100644 --- a/src/hardware/r_opengl/r_opengl.c +++ b/src/hardware/r_opengl/r_opengl.c @@ -1520,7 +1520,7 @@ static void gld_BuildSky(int row_count, int col_count) vertex_p = &vbo->data[0]; vbo->loopcount = 0; - for (yflip = 0; yflip < 2; yflip++) + for (yflip = 0; (UINT8)yflip < 2; yflip++) { vbo->loops[vbo->loopcount].mode = GL_TRIANGLE_FAN; vbo->loops[vbo->loopcount].vertexindex = vertex_p - &vbo->data[0]; From 9fa09c984243d3f31b18d0becf8b0aa22f18dba0 Mon Sep 17 00:00:00 2001 From: mazmazz Date: Sat, 7 Dec 2019 15:08:53 -0500 Subject: [PATCH 042/746] Travis Linux Deployer fixes --- .travis.yml | 84 +++++++++++++++++++++++++++++++++-------------------- 1 file changed, 52 insertions(+), 32 deletions(-) diff --git a/.travis.yml b/.travis.yml index f2ed43000..4579a4228 100644 --- a/.travis.yml +++ b/.travis.yml @@ -459,61 +459,46 @@ matrix: - os: linux addons: apt: + sources: + - ubuntu-toolchain-r-test + - sourceline: 'ppa:stjr/srb2' packages: - libsdl2-mixer-dev - libpng-dev - libgl1-mesa-dev - libgme-dev + - libopenmpt-dev - p7zip-full - gcc-4.8 compiler: gcc-4.8 - dist: xenial + dist: bionic if: env(DPL_ENABLED) = "1" AND (env(_DPL_JOB_ENABLED) = "1" OR env(DPL_JOB_ENABLE_ALL) = "1") AND (branch =~ /^.*deployer.*$/ OR (tag IS present AND env(DPL_TAG_ENABLED) = "1")) AND env(DPL_TERMINATE_MAIN) != "1" env: - _DPL_JOB_ENABLED=1 - - _DPL_JOB_NAME=bionic + - _DPL_JOB_NAME=eoan - _DPL_DPUT_TARGET=1 - _DPL_PACKAGE_SOURCE=1 - - PACKAGE_DISTRO=bionic - - PACKAGE_SUBVERSION=~18.04bionic + - PACKAGE_DISTRO=eoan + - PACKAGE_SUBVERSION=~19.10eoan #gcc-4.8 (Ubuntu 4.8.5-2ubuntu1~14.04.1) 4.8.5 - os: linux addons: apt: + sources: + - ubuntu-toolchain-r-test + - sourceline: 'ppa:stjr/srb2' packages: - libsdl2-mixer-dev - libpng-dev - libgl1-mesa-dev - libgme-dev + - libopenmpt-dev - p7zip-full - gcc-4.8 compiler: gcc-4.8 - dist: trusty - if: env(DPL_ENABLED) = "1" AND (env(_DPL_JOB_ENABLED) = "1" OR env(DPL_JOB_ENABLE_ALL) = "1") - AND (branch =~ /^.*deployer.*$/ OR (tag IS present AND env(DPL_TAG_ENABLED) = "1")) - AND env(DPL_TERMINATE_MAIN) != "1" - env: - - _DPL_JOB_ENABLED=1 - - _DPL_JOB_NAME=trusty - - _DPL_DPUT_TARGET=1 - - _DPL_PACKAGE_SOURCE=1 - - PACKAGE_DISTRO=trusty - - PACKAGE_SUBVERSION=~14.04trusty - #gcc-4.8 (Ubuntu 4.8.5-2ubuntu1~14.04.1) 4.8.5 - - os: linux - addons: - apt: - packages: - - libsdl2-mixer-dev - - libpng-dev - - libgl1-mesa-dev - - libgme-dev - - p7zip-full - - gcc-4.8 - compiler: gcc-4.8 - dist: xenial + dist: bionic if: env(DPL_ENABLED) = "1" AND (env(_DPL_JOB_ENABLED) = "1" OR env(DPL_JOB_ENABLE_ALL) = "1") AND (branch =~ /^.*deployer.*$/ OR (tag IS present AND env(DPL_TAG_ENABLED) = "1")) AND env(DPL_TERMINATE_MAIN) != "1" @@ -528,34 +513,42 @@ matrix: - os: linux addons: apt: + sources: + - ubuntu-toolchain-r-test + - sourceline: 'ppa:stjr/srb2' packages: - libsdl2-mixer-dev - libpng-dev - libgl1-mesa-dev - libgme-dev + - libopenmpt-dev - p7zip-full - gcc-4.8 compiler: gcc-4.8 - dist: xenial + dist: bionic if: env(DPL_ENABLED) = "1" AND (env(_DPL_JOB_ENABLED) = "1" OR env(DPL_JOB_ENABLE_ALL) = "1") AND (branch =~ /^.*deployer.*$/ OR (tag IS present AND env(DPL_TAG_ENABLED) = "1")) AND env(DPL_TERMINATE_MAIN) != "1" env: - _DPL_JOB_ENABLED=1 - - _DPL_JOB_NAME=cosmic + - _DPL_JOB_NAME=bionic - _DPL_DPUT_TARGET=1 - _DPL_PACKAGE_SOURCE=1 - - PACKAGE_DISTRO=cosmic - - PACKAGE_SUBVERSION=~18.10cosmic + - PACKAGE_DISTRO=bionic + - PACKAGE_SUBVERSION=~18.04bionic #gcc-4.8 (Ubuntu 4.8.5-2ubuntu1~14.04.1) 4.8.5 - os: linux addons: apt: + sources: + - ubuntu-toolchain-r-test + - sourceline: 'ppa:stjr/srb2' packages: - libsdl2-mixer-dev - libpng-dev - libgl1-mesa-dev - libgme-dev + - libopenmpt-dev - p7zip-full - gcc-4.8 compiler: gcc-4.8 @@ -571,6 +564,33 @@ matrix: - PACKAGE_DISTRO=xenial - PACKAGE_SUBVERSION=~16.04xenial #gcc-4.8 (Ubuntu 4.8.5-2ubuntu1~14.04.1) 4.8.5 + - os: linux + addons: + apt: + sources: + - ubuntu-toolchain-r-test + - sourceline: 'ppa:stjr/srb2' + packages: + - libsdl2-mixer-dev + - libpng-dev + - libgl1-mesa-dev + - libgme-dev + - libopenmpt-dev + - p7zip-full + - gcc-4.8 + compiler: gcc-4.8 + dist: trusty + if: env(DPL_ENABLED) = "1" AND (env(_DPL_JOB_ENABLED) = "1" OR env(DPL_JOB_ENABLE_ALL) = "1") + AND (branch =~ /^.*deployer.*$/ OR (tag IS present AND env(DPL_TAG_ENABLED) = "1")) + AND env(DPL_TERMINATE_MAIN) != "1" + env: + - _DPL_JOB_ENABLED=1 + - _DPL_JOB_NAME=trusty + - _DPL_DPUT_TARGET=1 + - _DPL_PACKAGE_SOURCE=1 + - PACKAGE_DISTRO=trusty + - PACKAGE_SUBVERSION=~14.04trusty + #gcc-4.8 (Ubuntu 4.8.5-2ubuntu1~14.04.1) 4.8.5 allow_failures: - compiler: clang-3.5 - compiler: clang-3.6 From 1f8c6574fbfb631d90bb3a7c8c2f9356af9a4dee Mon Sep 17 00:00:00 2001 From: mazmazz Date: Sat, 7 Dec 2019 15:31:31 -0500 Subject: [PATCH 043/746] Debian packaging fixes, libopenmpt --- debian-template/control | 2 ++ 1 file changed, 2 insertions(+) diff --git a/debian-template/control b/debian-template/control index e1348d704..a1f49da89 100644 --- a/debian-template/control +++ b/debian-template/control @@ -10,6 +10,7 @@ Build-Depends: debhelper (>= 7.0.50~), libpng-dev | libpng16-dev | libpng12-dev (>= 1.2.7), zlib1g-dev, libgme-dev, + libopenmpt-dev, libglu1-dev | libglu-dev, libosmesa6-dev | libgl-dev, nasm [i386] @@ -24,6 +25,7 @@ Depends: ${SHLIBS_DEPENDS}, ${MISC_DEPENDS}, libsdl2-mixer-2.0-0, zlib1g, libgme0, + libopenmpt, libpng | libpng16-16 | libpng12-0 Description: A cross-platform 3D Sonic fangame Sonic Robo Blast 2 is a 3D open-source Sonic the Hedgehog From 58650397e225ebef2ef49205129fdd0e1dd6a8a6 Mon Sep 17 00:00:00 2001 From: mazmazz Date: Sat, 7 Dec 2019 15:58:59 -0500 Subject: [PATCH 044/746] Travis Deployer: Use xenial instead of bionic for building installers Bionic breaks package signing because importing the private key is unsuccessful. Works in xenial. The buildbot distro doesn't matter because we're just sending source packages to Launchpad which builds on the target distro. --- .travis.yml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/.travis.yml b/.travis.yml index 4579a4228..9d91b77df 100644 --- a/.travis.yml +++ b/.travis.yml @@ -471,7 +471,7 @@ matrix: - p7zip-full - gcc-4.8 compiler: gcc-4.8 - dist: bionic + dist: xenial if: env(DPL_ENABLED) = "1" AND (env(_DPL_JOB_ENABLED) = "1" OR env(DPL_JOB_ENABLE_ALL) = "1") AND (branch =~ /^.*deployer.*$/ OR (tag IS present AND env(DPL_TAG_ENABLED) = "1")) AND env(DPL_TERMINATE_MAIN) != "1" @@ -498,7 +498,7 @@ matrix: - p7zip-full - gcc-4.8 compiler: gcc-4.8 - dist: bionic + dist: xenial if: env(DPL_ENABLED) = "1" AND (env(_DPL_JOB_ENABLED) = "1" OR env(DPL_JOB_ENABLE_ALL) = "1") AND (branch =~ /^.*deployer.*$/ OR (tag IS present AND env(DPL_TAG_ENABLED) = "1")) AND env(DPL_TERMINATE_MAIN) != "1" @@ -525,7 +525,7 @@ matrix: - p7zip-full - gcc-4.8 compiler: gcc-4.8 - dist: bionic + dist: xenial if: env(DPL_ENABLED) = "1" AND (env(_DPL_JOB_ENABLED) = "1" OR env(DPL_JOB_ENABLE_ALL) = "1") AND (branch =~ /^.*deployer.*$/ OR (tag IS present AND env(DPL_TAG_ENABLED) = "1")) AND env(DPL_TERMINATE_MAIN) != "1" From bca33bdb0e824e0ac7a6bbfa5ceb2d6c6805e593 Mon Sep 17 00:00:00 2001 From: mazmazz Date: Sat, 7 Dec 2019 16:26:28 -0500 Subject: [PATCH 045/746] Remove patch.pk3 from Deployer ASSET_FILES_HASHED --- deployer/travis/deployer_defaults.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/deployer/travis/deployer_defaults.sh b/deployer/travis/deployer_defaults.sh index 343fbd967..fe7ba6993 100644 --- a/deployer/travis/deployer_defaults.sh +++ b/deployer/travis/deployer_defaults.sh @@ -29,7 +29,7 @@ # Asset File Parameters : ${ASSET_ARCHIVE_PATH:=https://github.com/mazmazz/SRB2/releases/download/SRB2_assets_220/SRB2-v220-assets.7z} : ${ASSET_ARCHIVE_OPTIONAL_PATH:=https://github.com/mazmazz/SRB2/releases/download/SRB2_assets_220/SRB2-v220-optional-assets.7z} -: ${ASSET_FILES_HASHED:=srb2.pk3 zones.pk3 player.dta patch.pk3} +: ${ASSET_FILES_HASHED:=srb2.pk3 zones.pk3 player.dta} # POST v2.2 NOTE: Don't forget to add patch.pk3! : ${ASSET_FILES_DOCS:=README.txt LICENSE.txt LICENSE-3RD-PARTY.txt README-SDL.txt} : ${ASSET_FILES_OPTIONAL_GET:=0} From 5ba363fda6f2373ec815adaa804b2fb4497938a6 Mon Sep 17 00:00:00 2001 From: James R Date: Sat, 7 Dec 2019 14:28:03 -0800 Subject: [PATCH 046/746] Make the cmake version 2.2.0 --- CMakeLists.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 96e32a06d..dd9703914 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -2,7 +2,7 @@ cmake_minimum_required(VERSION 3.0) # DO NOT CHANGE THIS SRB2 STRING! Some variable names depend on this string. # Version change is fine. project(SRB2 - VERSION 2.1.25 + VERSION 2.2.0 LANGUAGES C) if(${PROJECT_SOURCE_DIR} MATCHES ${PROJECT_BINARY_DIR}) From cadaecbfcf6263f427a3ba2a5a92387bc7b77414 Mon Sep 17 00:00:00 2001 From: James R Date: Sat, 7 Dec 2019 15:47:18 -0800 Subject: [PATCH 047/746] memset this or the stupid masterserver (used to) show garbage bytes Also for security I guess... --- 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 188304fda..7b6c35eb6 100644 --- a/src/d_clisrv.c +++ b/src/d_clisrv.c @@ -1301,6 +1301,8 @@ static void SV_SendServerInfo(INT32 node, tic_t servertime) M_Memcpy(netbuffer->u.serverinfo.mapmd5, mapmd5, 16); + memset(netbuffer->u.serverinfo.maptitle, 0, sizeof netbuffer->u.serverinfo.maptitle); + if (mapheaderinfo[gamemap-1] && *mapheaderinfo[gamemap-1]->lvlttl) { char *read = mapheaderinfo[gamemap-1]->lvlttl, *writ = netbuffer->u.serverinfo.maptitle; @@ -1319,8 +1321,6 @@ static void SV_SendServerInfo(INT32 node, tic_t servertime) else strncpy(netbuffer->u.serverinfo.maptitle, "UNKNOWN", 32); - netbuffer->u.serverinfo.maptitle[32] = '\0'; - if (mapheaderinfo[gamemap-1] && !(mapheaderinfo[gamemap-1]->levelflags & LF_NOZONE)) netbuffer->u.serverinfo.iszone = 1; else From 65ca45c14700d12895c90126fd54e8e8ceaed626 Mon Sep 17 00:00:00 2001 From: mazmazz Date: Sat, 7 Dec 2019 20:32:04 -0500 Subject: [PATCH 048/746] Debian libopenmpt0 name fix --- debian-template/control | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/debian-template/control b/debian-template/control index a1f49da89..74d11ae90 100644 --- a/debian-template/control +++ b/debian-template/control @@ -25,7 +25,7 @@ Depends: ${SHLIBS_DEPENDS}, ${MISC_DEPENDS}, libsdl2-mixer-2.0-0, zlib1g, libgme0, - libopenmpt, + libopenmpt | libopenmpt0, libpng | libpng16-16 | libpng12-0 Description: A cross-platform 3D Sonic fangame Sonic Robo Blast 2 is a 3D open-source Sonic the Hedgehog From d5816d44f337c6eb82d937959f971fe45a5eec2a Mon Sep 17 00:00:00 2001 From: James R Date: Sat, 7 Dec 2019 17:03:46 -0800 Subject: [PATCH 049/746] Use a third variable of XOR nonsense --- src/strcasestr.c | 19 ++++++++++--------- 1 file changed, 10 insertions(+), 9 deletions(-) diff --git a/src/strcasestr.c b/src/strcasestr.c index 86c7ec5b0..4ff778bf1 100644 --- a/src/strcasestr.c +++ b/src/strcasestr.c @@ -23,13 +23,6 @@ ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -#define SWAP( a, b ) \ -(\ - (a) ^= (b),\ - (b) ^= (a),\ - (a) ^= (b)\ -) - static inline int trycmp (char **pp, char *cp, const char *q, size_t qn) @@ -45,8 +38,16 @@ trycmp (char **pp, char *cp, static inline void swapp (char ***ppap, char ***ppbp, char **cpap, char **cpbp) { - SWAP(*(intptr_t *)ppap, *(intptr_t *)ppbp); - SWAP(*(intptr_t *)cpap, *(intptr_t *)cpbp); + char **pp; + char *p; + + pp = *ppap; + *ppap = *ppbp; + *ppbp = pp; + + p = *cpap; + *cpap = *cpbp; + *cpbp = p; } char * From e9e0683d5efa1c21b0da5d698acd124421c90c42 Mon Sep 17 00:00:00 2001 From: Jaime Passos Date: Sat, 7 Dec 2019 23:46:05 -0300 Subject: [PATCH 050/746] Cleanup FreeMipmapColormap --- src/hardware/hw_cache.c | 32 +++++++++++++++++++++++--------- 1 file changed, 23 insertions(+), 9 deletions(-) diff --git a/src/hardware/hw_cache.c b/src/hardware/hw_cache.c index 328e623bd..fced24566 100644 --- a/src/hardware/hw_cache.c +++ b/src/hardware/hw_cache.c @@ -776,22 +776,36 @@ static void FreeMipmapColormap(INT32 patchnum, void *patch) { GLPatch_t* const pat = patch; (void)patchnum; //unused - while (pat->mipmap && pat->mipmap->nextcolormap) // The mipmap must be valid, obviously + + // The patch must be valid, obviously + if (!pat) + return; + + // The mipmap must be valid, obviously + while (pat->mipmap) { // Confusing at first, but pat->mipmap->nextcolormap // at the beginning of the loop is the first colormap - // from the linked list of colormaps - GLMipmap_t *next = pat->mipmap; - if (!next) // No mipmap in this patch, break out of loop. + // from the linked list of colormaps. + GLMipmap_t *next = NULL; + + // No mipmap in this patch, break out of the loop. + if (!pat->mipmap) break; - // Set the first colormap - // to the one that comes after it - next = next->nextcolormap; + + // No colormap mipmap either. + if (!pat->mipmap->nextcolormap) + break; + + // Set the first colormap to the one that comes after it. + next = pat->mipmap->nextcolormap; pat->mipmap->nextcolormap = next->nextcolormap; - // Free image data from memory + + // Free image data from memory. if (next->grInfo.data) Z_Free(next->grInfo.data); - // Free the old colormap from memory + + // Free the old colormap from memory. free(next); } } From 40b862967d3a4aef3cca63a10f6399ce1c7af47c Mon Sep 17 00:00:00 2001 From: Jaime Passos Date: Sat, 7 Dec 2019 23:55:28 -0300 Subject: [PATCH 051/746] Just in case? --- src/hardware/hw_main.c | 4 ++++ src/hardware/hw_md2.c | 2 ++ 2 files changed, 6 insertions(+) diff --git a/src/hardware/hw_main.c b/src/hardware/hw_main.c index 51c976973..c770448e6 100644 --- a/src/hardware/hw_main.c +++ b/src/hardware/hw_main.c @@ -6172,6 +6172,8 @@ void HWR_RenderSkyboxView(INT32 viewnumber, player_t *player) //04/01/2000: Hurdler: added for T&L // It should replace all other gr_viewxxx when finished + memset(&atransform, 0x00, sizeof(FTransform)); + atransform.anglex = (float)(aimingangle>>ANGLETOFINESHIFT)*(360.0f/(float)FINEANGLES); atransform.angley = (float)(viewangle>>ANGLETOFINESHIFT)*(360.0f/(float)FINEANGLES); @@ -6390,6 +6392,8 @@ void HWR_RenderPlayerView(INT32 viewnumber, player_t *player) //04/01/2000: Hurdler: added for T&L // It should replace all other gr_viewxxx when finished + memset(&atransform, 0x00, sizeof(FTransform)); + atransform.anglex = (float)(aimingangle>>ANGLETOFINESHIFT)*(360.0f/(float)FINEANGLES); atransform.angley = (float)(viewangle>>ANGLETOFINESHIFT)*(360.0f/(float)FINEANGLES); diff --git a/src/hardware/hw_md2.c b/src/hardware/hw_md2.c index 9d9171cea..9245d7fc2 100644 --- a/src/hardware/hw_md2.c +++ b/src/hardware/hw_md2.c @@ -915,6 +915,8 @@ void HWR_DrawModel(gr_vissprite_t *spr) if (spr->precip) return; + memset(&p, 0x00, sizeof(FTransform)); + // MD2 colormap fix // colormap test if (spr->mobj->subsector) From bc60a0a8876124b152084f5d45f03bece7e58ff2 Mon Sep 17 00:00:00 2001 From: Jaime Passos Date: Sun, 8 Dec 2019 01:54:03 -0300 Subject: [PATCH 052/746] Make some things clearer here. --- src/hardware/hw_cache.c | 43 +++++++++++++++++++++++++++-------------- 1 file changed, 28 insertions(+), 15 deletions(-) diff --git a/src/hardware/hw_cache.c b/src/hardware/hw_cache.c index fced24566..e19bd8331 100644 --- a/src/hardware/hw_cache.c +++ b/src/hardware/hw_cache.c @@ -760,15 +760,15 @@ void HWR_MakePatch (const patch_t *patch, GLPatch_t *grPatch, GLMipmap_t *grMipm // CACHING HANDLING // ================================================= -static size_t gr_numtextures; -static GLTexture_t *gr_textures; // for ALL Doom textures -static GLTexture_t *gr_textures2; +static size_t gr_numtextures; // Texture count +static GLTexture_t *gr_textures; // For all textures +static GLTexture_t *gr_flats; // For all (texture) flats, as normal flats don't need to be cached void HWR_InitTextureCache(void) { gr_numtextures = 0; gr_textures = NULL; - gr_textures2 = NULL; + gr_flats = NULL; } // Callback function for HWR_FreeTextureCache. @@ -831,10 +831,10 @@ void HWR_FreeTextureCache(void) // texturecache info, we can free it if (gr_textures) free(gr_textures); - if (gr_textures2) - free(gr_textures2); + if (gr_flats) + free(gr_flats); gr_textures = NULL; - gr_textures2 = NULL; + gr_flats = NULL; gr_numtextures = 0; } @@ -848,13 +848,15 @@ void HWR_PrepLevelCache(size_t pnumtextures) // we must free it since numtextures changed HWR_FreeTextureCache(); + // Why not Z_Malloc? gr_numtextures = pnumtextures; - gr_textures = calloc(pnumtextures, sizeof (*gr_textures)); - if (gr_textures == NULL) - I_Error("3D can't alloc gr_textures"); - gr_textures2 = calloc(pnumtextures, sizeof (*gr_textures2)); - if (gr_textures2 == NULL) - I_Error("3D can't alloc gr_textures2"); + gr_textures = calloc(gr_numtextures, sizeof(*gr_textures)); + gr_flats = calloc(gr_numtextures, sizeof(*gr_flats)); + + // Doesn't tell you which it _is_, but hopefully + // should never ever happen (right?!) + if ((gr_textures == NULL) || (gr_flats == NULL)) + I_Error("HWR_PrepLevelCache: ran out of memory for OpenGL textures. Sad!"); } void HWR_SetPalette(RGBA_t *palette) @@ -887,11 +889,16 @@ GLTexture_t *HWR_GetTexture(INT32 tex) if ((unsigned)tex >= gr_numtextures) I_Error("HWR_GetTexture: tex >= numtextures\n"); #endif + + // Every texture in memory, stored in the + // hardware renderer's bit depth format. Wow! grtex = &gr_textures[tex]; + // Generate texture if missing from the cache if (!grtex->mipmap.grInfo.data && !grtex->mipmap.downloaded) HWR_GenerateTexture(tex, grtex); + // Tell the hardware driver to bind the current texture to the flat's mipmap HWD.pfnSetTexture(&grtex->mipmap); // The system-memory data can be purged now. @@ -1003,13 +1010,19 @@ void HWR_GetLevelFlat(levelflat_t *levelflat) if ((unsigned)texturenum >= gr_numtextures) I_Error("HWR_GetLevelFlat: texturenum >= numtextures\n"); #endif + + // Who knows? if (texturenum == 0 || texturenum == -1) return; - grtex = &gr_textures2[texturenum]; + // Every texture in memory, stored as a 8-bit flat. Wow! + grtex = &gr_flats[texturenum]; + + // Generate flat if missing from the cache if (!grtex->mipmap.grInfo.data && !grtex->mipmap.downloaded) HWR_CacheTextureAsFlat(&grtex->mipmap, texturenum); + // Tell the hardware driver to bind the current texture to the flat's mipmap HWD.pfnSetTexture(&grtex->mipmap); // The system-memory data can be purged now. @@ -1033,6 +1046,7 @@ static void HWR_LoadMappedPatch(GLMipmap_t *grmip, GLPatch_t *gpatch) HWR_MakePatch(patch, gpatch, grmip, true); // You can't free rawpatch for some reason? + // (Obviously I can't, sprite rotation needs that...) if (!gpatch->rawpatch) Z_Free(patch); } @@ -1060,7 +1074,6 @@ void HWR_GetPatch(GLPatch_t *gpatch) // this is inefficient.. but the hardware patch in heap is purgeable so it should // not fragment memory, and besides the REAL cache here is the hardware memory - // You can't free rawpatch for some reason? if (!gpatch->rawpatch) Z_Free(ptr); } From 964978a33759cae86721eddb9bb9085ff1567e2c Mon Sep 17 00:00:00 2001 From: Jaime Passos Date: Sun, 8 Dec 2019 02:25:53 -0300 Subject: [PATCH 053/746] Delete md2_transform --- src/hardware/r_opengl/r_opengl.c | 3 --- 1 file changed, 3 deletions(-) diff --git a/src/hardware/r_opengl/r_opengl.c b/src/hardware/r_opengl/r_opengl.c index 25bcf153b..fbb5d9efe 100644 --- a/src/hardware/r_opengl/r_opengl.c +++ b/src/hardware/r_opengl/r_opengl.c @@ -85,7 +85,6 @@ static GLboolean MipMap = GL_FALSE; static GLint min_filter = GL_LINEAR; static GLint mag_filter = GL_LINEAR; static GLint anisotropic_filter = 0; -static FTransform md2_transform; const GLubyte *gl_extensions = NULL; @@ -2226,8 +2225,6 @@ EXPORT void HWRAPI(SetTransform) (FTransform *stransform) if (stransform) { boolean fovx90; - // keep a trace of the transformation for md2 - memcpy(&md2_transform, stransform, sizeof (md2_transform)); #ifdef USE_FTRANSFORM_MIRROR // mirroring from Kart From ce61b17117b887b2825ce6360c5b9aa9320ddbbc Mon Sep 17 00:00:00 2001 From: Jaime Passos Date: Sun, 8 Dec 2019 02:27:51 -0300 Subject: [PATCH 054/746] Update hw_main.c --- src/hardware/hw_main.c | 26 +++++++++++++------------- 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/src/hardware/hw_main.c b/src/hardware/hw_main.c index c770448e6..db4990436 100644 --- a/src/hardware/hw_main.c +++ b/src/hardware/hw_main.c @@ -5941,7 +5941,7 @@ static void HWR_DrawSkyBackground(player_t *player) { if (cv_grskydome.value) { - FTransform transform; + FTransform dometransform; const float fpov = FIXED_TO_FLOAT(cv_grfov.value+player->fovadd); postimg_t *type; @@ -5950,27 +5950,27 @@ static void HWR_DrawSkyBackground(player_t *player) else type = &postimgtype; - memset(&transform, 0x00, sizeof(FTransform)); + memset(&dometransform, 0x00, sizeof(FTransform)); //04/01/2000: Hurdler: added for T&L // It should replace all other gr_viewxxx when finished - transform.anglex = (float)(aimingangle>>ANGLETOFINESHIFT)*(360.0f/(float)FINEANGLES); - transform.angley = (float)((viewangle-ANGLE_270)>>ANGLETOFINESHIFT)*(360.0f/(float)FINEANGLES); + dometransform.anglex = (float)(aimingangle>>ANGLETOFINESHIFT)*(360.0f/(float)FINEANGLES); + dometransform.angley = (float)((viewangle-ANGLE_270)>>ANGLETOFINESHIFT)*(360.0f/(float)FINEANGLES); if (*type == postimg_flip) - transform.flip = true; + dometransform.flip = true; else - transform.flip = false; + dometransform.flip = false; - transform.scalex = 1; - transform.scaley = (float)vid.width/vid.height; - transform.scalez = 1; - transform.fovxangle = fpov; // Tails - transform.fovyangle = fpov; // Tails - transform.splitscreen = splitscreen; + dometransform.scalex = 1; + dometransform.scaley = (float)vid.width/vid.height; + dometransform.scalez = 1; + dometransform.fovxangle = fpov; // Tails + dometransform.fovyangle = fpov; // Tails + dometransform.splitscreen = splitscreen; HWR_GetTexture(texturetranslation[skytexture]); - HWD.pfnRenderSkyDome(skytexture, textures[skytexture]->width, textures[skytexture]->height, transform); + HWD.pfnRenderSkyDome(skytexture, textures[skytexture]->width, textures[skytexture]->height, dometransform); } else { From cc12496e9c3fce929546640bbe2c1b35056d7a86 Mon Sep 17 00:00:00 2001 From: Jaime Passos Date: Sun, 8 Dec 2019 03:23:37 -0300 Subject: [PATCH 055/746] Optimize mipmaps --- src/hardware/hw_cache.c | 22 ++++++++++++---------- src/hardware/hw_glob.h | 1 + src/hardware/hw_main.c | 1 + src/hardware/hw_main.h | 2 +- src/p_setup.c | 20 +++++++++++--------- src/r_data.c | 9 +++++++++ 6 files changed, 35 insertions(+), 20 deletions(-) diff --git a/src/hardware/hw_cache.c b/src/hardware/hw_cache.c index e19bd8331..aef97e817 100644 --- a/src/hardware/hw_cache.c +++ b/src/hardware/hw_cache.c @@ -804,15 +804,17 @@ static void FreeMipmapColormap(INT32 patchnum, void *patch) // Free image data from memory. if (next->grInfo.data) Z_Free(next->grInfo.data); + next->grInfo.data = NULL; - // Free the old colormap from memory. + // Free the old colormap mipmap from memory. free(next); } } -void HWR_FreeTextureCache(void) +void HWR_FreeMipmapCache(void) { INT32 i; + // free references to the textures HWD.pfnClearMipMapCache(); @@ -822,10 +824,15 @@ void HWR_FreeTextureCache(void) Z_FreeTag(PU_HWRCACHE_UNLOCKED); // Alam: free the Z_Blocks before freeing it's users - // free all patch colormaps after each level: must be done after ClearMipMapCache! for (i = 0; i < numwadfiles; i++) M_AATreeIterate(wadfiles[i]->hwrcache, FreeMipmapColormap); +} + +void HWR_FreeTextureCache(void) +{ + // free references to the textures + HWR_FreeMipmapCache(); // now the heap don't have any 'user' pointing to our // texturecache info, we can free it @@ -838,13 +845,8 @@ void HWR_FreeTextureCache(void) gr_numtextures = 0; } -void HWR_PrepLevelCache(size_t pnumtextures) +void HWR_LoadTextures(size_t pnumtextures) { - // problem: the mipmap cache management hold a list of mipmaps.. but they are - // reallocated on each level.. - //sub-optimal, but 1) just need re-download stuff in hardware cache VERY fast - // 2) sprite/menu stuff mixed with level textures so can't do anything else - // we must free it since numtextures changed HWR_FreeTextureCache(); @@ -856,7 +858,7 @@ void HWR_PrepLevelCache(size_t pnumtextures) // Doesn't tell you which it _is_, but hopefully // should never ever happen (right?!) if ((gr_textures == NULL) || (gr_flats == NULL)) - I_Error("HWR_PrepLevelCache: ran out of memory for OpenGL textures. Sad!"); + I_Error("HWR_LoadTextures: ran out of memory for OpenGL textures. Sad!"); } void HWR_SetPalette(RGBA_t *palette) diff --git a/src/hardware/hw_glob.h b/src/hardware/hw_glob.h index 69cf8bf46..d25f6cefd 100644 --- a/src/hardware/hw_glob.h +++ b/src/hardware/hw_glob.h @@ -100,6 +100,7 @@ void HWR_FreePolyPool(void); // -------- void HWR_InitTextureCache(void); void HWR_FreeTextureCache(void); +void HWR_FreeMipmapCache(void); void HWR_FreeExtraSubsectors(void); void HWR_GetLevelFlat(levelflat_t *levelflat); diff --git a/src/hardware/hw_main.c b/src/hardware/hw_main.c index db4990436..5baf89e6c 100644 --- a/src/hardware/hw_main.c +++ b/src/hardware/hw_main.c @@ -6687,6 +6687,7 @@ void HWR_Shutdown(void) CONS_Printf("HWR_Shutdown()\n"); HWR_FreeExtraSubsectors(); HWR_FreePolyPool(); + HWR_FreeMipmapCache(); HWR_FreeTextureCache(); HWD.pfnFlushScreenTextures(); } diff --git a/src/hardware/hw_main.h b/src/hardware/hw_main.h index e19c557d0..3ff7e98c9 100644 --- a/src/hardware/hw_main.h +++ b/src/hardware/hw_main.h @@ -47,7 +47,7 @@ void HWR_DrawCroppedPatch(GLPatch_t *gpatch, fixed_t x, fixed_t y, fixed_t scale void HWR_MakePatch(const patch_t *patch, GLPatch_t *grPatch, GLMipmap_t *grMipmap, boolean makebitmap); void HWR_CreatePlanePolygons(INT32 bspnum); void HWR_CreateStaticLightmaps(INT32 bspnum); -void HWR_PrepLevelCache(size_t pnumtextures); +void HWR_LoadTextures(size_t pnumtextures); void HWR_DrawFill(INT32 x, INT32 y, INT32 w, INT32 h, INT32 color); void HWR_DrawFadeFill(INT32 x, INT32 y, INT32 w, INT32 h, INT32 color, UINT16 actualcolor, UINT8 strength); void HWR_DrawConsoleFill(INT32 x, INT32 y, INT32 w, INT32 h, INT32 color, UINT32 actualcolor); // Lat: separate flags from color since color needs to be an uint to work right. diff --git a/src/p_setup.c b/src/p_setup.c index 673a9024e..d38a78bc8 100644 --- a/src/p_setup.c +++ b/src/p_setup.c @@ -3019,8 +3019,17 @@ boolean P_SetupLevel(boolean skipprecip) P_SpawnPrecipitation(); #ifdef HWRENDER // not win32 only 19990829 by Kin - if (rendermode != render_soft && rendermode != render_none) + if (rendermode == render_opengl) { + // Lactozilla (December 8, 2019) + // Level setup used to free EVERY mipmap from memory. + // Even mipmaps that aren't related to level textures. + // Presumably, the hardware render code used to store textures as level data. + // Meaning, they had memory allocated and marked with the PU_LEVEL tag. + // Now, only mipmaps that AREN'T level textures are freed between levels. + // Level textures are only reloaded after R_LoadTextures, which is + // when the texture list is loaded. + HWR_FreeMipmapCache(); #ifdef ALAM_LIGHTING // BP: reset light between levels (we draw preview frame lights on current frame) HWR_ResetLights(); @@ -3203,14 +3212,6 @@ boolean P_SetupLevel(boolean skipprecip) // Fab : 19-07-98 : start cd music for this level (note: can be remapped) I_PlayCD((UINT8)(gamemap), false); - // preload graphics -#ifdef HWRENDER // not win32 only 19990829 by Kin - if (rendermode != render_soft && rendermode != render_none) - { - HWR_PrepLevelCache(numtextures); - } -#endif - P_MapEnd(); // Remove the loading shit from the screen @@ -3540,6 +3541,7 @@ boolean P_AddWadFile(const char *wadfilename) #ifdef HWRENDER HWR_ReloadModels(); + HWR_FreeMipmapCache(); #endif // reload status bar (warning should have valid player!) diff --git a/src/r_data.c b/src/r_data.c index 5611ee6f8..c3f3bf8ff 100644 --- a/src/r_data.c +++ b/src/r_data.c @@ -32,6 +32,10 @@ #include // alloca(sizeof) #endif +#ifdef HWRENDER +#include "hardware/hw_main.h" // HWR_LoadTextures +#endif + #if defined(_MSC_VER) #pragma pack(1) #endif @@ -872,6 +876,11 @@ void R_LoadTextures(void) i++; } } + +#ifdef HWRENDER + if (rendermode == render_opengl) + HWR_LoadTextures(numtextures); +#endif } static texpatch_t *R_ParsePatch(boolean actuallyLoadPatch) From d8a804febcf730104917d03d9836378571a1863a Mon Sep 17 00:00:00 2001 From: Jaime Passos Date: Sun, 8 Dec 2019 04:15:25 -0300 Subject: [PATCH 056/746] LMFAOOOOOOOOOOOOOOOOOOOOOOOO --- src/hardware/hw_main.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/hardware/hw_main.c b/src/hardware/hw_main.c index 5baf89e6c..583a877fc 100644 --- a/src/hardware/hw_main.c +++ b/src/hardware/hw_main.c @@ -3431,7 +3431,7 @@ static void HWR_AddPolyObjectPlanes(void) { HWR_GetLevelFlat(&levelflats[polyobjsector->ceilingpic]); HWR_RenderPolyObjectPlane(po_ptrs[i], true, polyobjsector->ceilingheight, PF_Occlude, - (light == -1 ? gr_frontsector->lightlevel : *gr_frontsector->lightlist[light].lightlevel), &levelflats[polyobjsector->floorpic], + (light == -1 ? gr_frontsector->lightlevel : *gr_frontsector->lightlist[light].lightlevel), &levelflats[polyobjsector->ceilingpic], polyobjsector, 255, (light == -1 ? gr_frontsector->extra_colormap : *gr_frontsector->lightlist[light].extra_colormap)); } } From 4c808cb7e2c12f5f9c003c98746ffdb7a4331508 Mon Sep 17 00:00:00 2001 From: Jaime Passos Date: Sun, 8 Dec 2019 04:32:25 -0300 Subject: [PATCH 057/746] Actually don't even call HWR_FreeMipmapCache between levels because I feel like it's futile outside of PWAD loading --- src/p_setup.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/p_setup.c b/src/p_setup.c index d38a78bc8..186947060 100644 --- a/src/p_setup.c +++ b/src/p_setup.c @@ -3026,10 +3026,8 @@ boolean P_SetupLevel(boolean skipprecip) // Even mipmaps that aren't related to level textures. // Presumably, the hardware render code used to store textures as level data. // Meaning, they had memory allocated and marked with the PU_LEVEL tag. - // Now, only mipmaps that AREN'T level textures are freed between levels. // Level textures are only reloaded after R_LoadTextures, which is // when the texture list is loaded. - HWR_FreeMipmapCache(); #ifdef ALAM_LIGHTING // BP: reset light between levels (we draw preview frame lights on current frame) HWR_ResetLights(); From d74f2a003b5cb4cd9520ff596fc5b6404393f22b Mon Sep 17 00:00:00 2001 From: Jaime Passos Date: Sun, 8 Dec 2019 04:40:29 -0300 Subject: [PATCH 058/746] HWR_FreeMipmapCache already calls HWR_FreeMipmapCache indirectly (done by calling HWR_LoadTextures, which in turn calls HWR_FreeTextureCache) --- src/p_setup.c | 1 - 1 file changed, 1 deletion(-) diff --git a/src/p_setup.c b/src/p_setup.c index 186947060..bb6c34c0a 100644 --- a/src/p_setup.c +++ b/src/p_setup.c @@ -3539,7 +3539,6 @@ boolean P_AddWadFile(const char *wadfilename) #ifdef HWRENDER HWR_ReloadModels(); - HWR_FreeMipmapCache(); #endif // reload status bar (warning should have valid player!) From 35168ddeae00b2552a785ccc346103c4665cc36b Mon Sep 17 00:00:00 2001 From: Alam Ed Arias Date: Sun, 8 Dec 2019 12:32:23 -0500 Subject: [PATCH 059/746] OpenGL: yflip is used to hold more then true/false --- src/hardware/r_opengl/r_opengl.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/hardware/r_opengl/r_opengl.c b/src/hardware/r_opengl/r_opengl.c index 25bcf153b..7bab9d321 100644 --- a/src/hardware/r_opengl/r_opengl.c +++ b/src/hardware/r_opengl/r_opengl.c @@ -1435,7 +1435,7 @@ static const boolean gl_ext_arb_vertex_buffer_object = true; // The texture offset to be applied to the texture coordinates in SkyVertex(). static int rows, columns; -static boolean yflip; +static signed char yflip; static int texw, texh; static boolean foglayer; static float delta = 0.0f; From 623629b04ab72071e6ea4f0c4a3245e6cde72e2c Mon Sep 17 00:00:00 2001 From: Alam Ed Arias Date: Sun, 8 Dec 2019 12:33:11 -0500 Subject: [PATCH 060/746] OpenGL: note that the Buffer API is OpenGL 1.5, so we can be used in STATIC_OPENGL --- src/hardware/r_opengl/r_opengl.c | 27 +++++++++++++-------------- 1 file changed, 13 insertions(+), 14 deletions(-) diff --git a/src/hardware/r_opengl/r_opengl.c b/src/hardware/r_opengl/r_opengl.c index 7bab9d321..b85b75c24 100644 --- a/src/hardware/r_opengl/r_opengl.c +++ b/src/hardware/r_opengl/r_opengl.c @@ -221,11 +221,6 @@ FUNCPRINTF void DBG_Printf(const char *lpFmt, ...) #define pglDrawElements glDrawElements #define pglEnableClientState glEnableClientState #define pglDisableClientState glDisableClientState -#define pglClientActiveTexture glClientActiveTexture -#define pglGenBuffers glGenBuffers -#define pglBindBuffer glBindBuffer -#define pglBufferData glBufferData -#define pglDeleteBuffers glDeleteBuffers /* Lighting */ #define pglShadeModel glShadeModel @@ -331,15 +326,6 @@ typedef void (APIENTRY * PFNglEnableClientState) (GLenum cap); static PFNglEnableClientState pglEnableClientState; typedef void (APIENTRY * PFNglDisableClientState) (GLenum cap); static PFNglDisableClientState pglDisableClientState; -typedef void (APIENTRY * PFNglGenBuffers) (GLsizei n, GLuint *buffers); -static PFNglGenBuffers pglGenBuffers; -typedef void (APIENTRY * PFNglBindBuffer) (GLenum target, GLuint buffer); -static PFNglBindBuffer pglBindBuffer; -typedef void (APIENTRY * PFNglBufferData) (GLenum target, GLsizei size, const GLvoid *data, GLenum usage); -static PFNglBufferData pglBufferData; -typedef void (APIENTRY * PFNglDeleteBuffers) (GLsizei n, const GLuint *buffers); -static PFNglDeleteBuffers pglDeleteBuffers; - /* Lighting */ typedef void (APIENTRY * PFNglShadeModel) (GLenum mode); @@ -397,6 +383,17 @@ static PFNglMultiTexCoord2fv pglMultiTexCoord2fv; typedef void (APIENTRY *PFNglClientActiveTexture) (GLenum); static PFNglClientActiveTexture pglClientActiveTexture; +/* 1.5 functions for buffers */ +typedef void (APIENTRY * PFNglGenBuffers) (GLsizei n, GLuint *buffers); +static PFNglGenBuffers pglGenBuffers; +typedef void (APIENTRY * PFNglBindBuffer) (GLenum target, GLuint buffer); +static PFNglBindBuffer pglBindBuffer; +typedef void (APIENTRY * PFNglBufferData) (GLenum target, GLsizei size, const GLvoid *data, GLenum usage); +static PFNglBufferData pglBufferData; +typedef void (APIENTRY * PFNglDeleteBuffers) (GLsizei n, const GLuint *buffers); +static PFNglDeleteBuffers pglDeleteBuffers; + + /* 1.2 Parms */ /* GL_CLAMP_TO_EDGE_EXT */ #ifndef GL_CLAMP_TO_EDGE @@ -512,6 +509,8 @@ boolean SetupGLFunc13(void) pglMultiTexCoord2f = GetGLFunc("glMultiTexCoord2f"); pglClientActiveTexture = GetGLFunc("glClientActiveTexture"); pglMultiTexCoord2fv = GetGLFunc("glMultiTexCoord2fv"); + + /* 1.5 funcs */ pglGenBuffers = GetGLFunc("glGenBuffers"); pglBindBuffer = GetGLFunc("glBindBuffer"); pglBufferData = GetGLFunc("glBufferData"); From 1d0cd586ba33f91aa6bedf118133b1c44cb45c38 Mon Sep 17 00:00:00 2001 From: Alam Ed Arias Date: Sun, 8 Dec 2019 12:35:21 -0500 Subject: [PATCH 061/746] P_AddWadFile: the PK3 may not have folders --- src/p_setup.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/p_setup.c b/src/p_setup.c index 673a9024e..3c45509ee 100644 --- a/src/p_setup.c +++ b/src/p_setup.c @@ -3380,10 +3380,10 @@ boolean P_AddWadFile(const char *wadfilename) // WADs use markers for some resources, but others such as sounds are checked lump-by-lump anyway. // UINT16 luaPos, luaNum = 0; // UINT16 socPos, socNum = 0; - UINT16 sfxPos, sfxNum = 0; + UINT16 sfxPos = 0, sfxNum = 0; UINT16 musPos = 0, musNum = 0; // UINT16 sprPos, sprNum = 0; - UINT16 texPos, texNum = 0; + UINT16 texPos = 0, texNum = 0; // UINT16 patPos, patNum = 0; // UINT16 flaPos, flaNum = 0; // UINT16 mapPos, mapNum = 0; From 32c9c912abfda9c75921666a89deac4081cccad3 Mon Sep 17 00:00:00 2001 From: fickleheart Date: Sun, 8 Dec 2019 13:27:11 -0600 Subject: [PATCH 062/746] Consolidate G_BuildTiccmd --- src/d_clisrv.c | 4 +- src/g_game.c | 541 ++++++++++++------------------------------------- src/g_game.h | 3 +- src/g_input.h | 1 + 4 files changed, 131 insertions(+), 418 deletions(-) diff --git a/src/d_clisrv.c b/src/d_clisrv.c index 188304fda..394ce9b5d 100644 --- a/src/d_clisrv.c +++ b/src/d_clisrv.c @@ -4624,9 +4624,9 @@ static void Local_Maketic(INT32 realtics) // and G_MapEventsToControls if (!dedicated) rendergametic = gametic; // translate inputs (keyboard/mouse/joystick) into game controls - G_BuildTiccmd(&localcmds, realtics); + G_BuildTiccmd(&localcmds, realtics, 1); if (splitscreen || botingame) - G_BuildTiccmd2(&localcmds2, realtics); + G_BuildTiccmd(&localcmds2, realtics, 2); localcmds.angleturn |= TICCMD_RECEIVED; } diff --git a/src/g_game.c b/src/g_game.c index 2a12dd298..a55c1b1eb 100644 --- a/src/g_game.c +++ b/src/g_game.c @@ -965,6 +965,8 @@ static INT32 Joy2Axis(axis_input_e axissel) return retaxis; } +#define PlayerJoyAxis(p, ax) ((p) == 1 ? JoyAxis(ax) : Joy2Axis(ax)) + // // G_BuildTiccmd @@ -981,7 +983,7 @@ static fixed_t forwardmove[2] = {25<>16, 50<>16}; static fixed_t sidemove[2] = {25<>16, 50<>16}; // faster! static fixed_t angleturn[3] = {640, 1280, 320}; // + slow turn -void G_BuildTiccmd(ticcmd_t *cmd, INT32 realtics) +void G_BuildTiccmd(ticcmd_t *cmd, INT32 realtics, UINT8 ssplayer) { boolean forcestrafe = false; boolean forcefullinput = false; @@ -989,48 +991,81 @@ void G_BuildTiccmd(ticcmd_t *cmd, INT32 realtics) const INT32 speed = 1; // these ones used for multiple conditions boolean turnleft, turnright, strafelkey, straferkey, movefkey, movebkey, mouseaiming, analogjoystickmove, gamepadjoystickmove, thisjoyaiming; - player_t *player = &players[consoleplayer]; - camera_t *thiscam = &camera; + player_t *player = &players[ssplayer == 2 ? secondarydisplayplayer : consoleplayer]; + camera_t *thiscam = ((ssplayer == 1 || player->bot == 2) ? &camera : &camera2); + angle_t *myangle = (ssplayer == 1 ? &localangle : &localangle2); + INT32 *myaiming = (ssplayer == 1 ? &localaiming : &localaiming2); - static INT32 turnheld; // for accelerative turning - static boolean keyboard_look; // true if lookup/down using keyboard - static boolean resetdown; // don't cam reset every frame - static boolean joyaiming; // check the last frame's value if we need to reset the camera + INT32 chasecam, chasefreelook, alwaysfreelook, usejoystick, analog, invertmouse, mousemove; + INT32 *mx; INT32 *my; INT32 *mly; - G_CopyTiccmd(cmd, I_BaseTiccmd(), 1); // empty, or external driver + static INT32 turnheld[2]; // for accelerative turning + static boolean keyboard_look[2]; // true if lookup/down using keyboard + static boolean resetdown[2]; // don't cam reset every frame + static boolean joyaiming[2]; // check the last frame's value if we need to reset the camera + UINT8 forplayer = ssplayer-1; + + if (ssplayer == 1) + { + chasecam = cv_chasecam.value; + chasefreelook = cv_chasefreelook.value; + alwaysfreelook = cv_alwaysfreelook.value; + usejoystick = cv_usejoystick.value; + analog = cv_analog.value; + invertmouse = cv_invertmouse.value; + mousemove = cv_mousemove.value; + mx = &mousex; + my = &mousey; + mly = &mlooky; + G_CopyTiccmd(cmd, I_BaseTiccmd(), 1); // empty, or external driver + } + else + { + chasecam = cv_chasecam2.value; + chasefreelook = cv_chasefreelook2.value; + alwaysfreelook = cv_alwaysfreelook2.value; + usejoystick = cv_usejoystick2.value; + analog = cv_analog2.value; + invertmouse = cv_invertmouse2.value; + mousemove = cv_mousemove2.value; + mx = &mouse2x; + my = &mouse2y; + mly = &mlook2y; + G_CopyTiccmd(cmd, I_BaseTiccmd2(), 1); // empty, or external driver + } // why build a ticcmd if we're paused? // Or, for that matter, if we're being reborn. // ...OR if we're blindfolded. No looking into the floor. if (paused || P_AutoPause() || (gamestate == GS_LEVEL && (player->playerstate == PST_REBORN || ((gametype == GT_TAG || gametype == GT_HIDEANDSEEK) && (leveltime < hidetime * TICRATE) && (player->pflags & PF_TAGIT))))) - { - cmd->angleturn = (INT16)(localangle >> 16); - cmd->aiming = G_ClipAimingPitch(&localaiming); + {//@TODO splitscreen player + cmd->angleturn = (INT16)(*myangle >> 16); + cmd->aiming = G_ClipAimingPitch(myaiming); return; } - turnright = PLAYER1INPUTDOWN(gc_turnright); - turnleft = PLAYER1INPUTDOWN(gc_turnleft); + turnright = PLAYERINPUTDOWN(ssplayer, gc_turnright); + turnleft = PLAYERINPUTDOWN(ssplayer, gc_turnleft); - straferkey = PLAYER1INPUTDOWN(gc_straferight); - strafelkey = PLAYER1INPUTDOWN(gc_strafeleft); - movefkey = PLAYER1INPUTDOWN(gc_forward); - movebkey = PLAYER1INPUTDOWN(gc_backward); + straferkey = PLAYERINPUTDOWN(ssplayer, gc_straferight); + strafelkey = PLAYERINPUTDOWN(ssplayer, gc_strafeleft); + movefkey = PLAYERINPUTDOWN(ssplayer, gc_forward); + movebkey = PLAYERINPUTDOWN(ssplayer, gc_backward); - mouseaiming = (PLAYER1INPUTDOWN(gc_mouseaiming)) ^ - ((cv_chasecam.value && !player->spectator) ? cv_chasefreelook.value : cv_alwaysfreelook.value); - analogjoystickmove = cv_usejoystick.value && !Joystick.bGamepadStyle; - gamepadjoystickmove = cv_usejoystick.value && Joystick.bGamepadStyle; + mouseaiming = (PLAYERINPUTDOWN(ssplayer, gc_mouseaiming)) ^ + ((chasecam && !player->spectator) ? chasefreelook : alwaysfreelook); + analogjoystickmove = usejoystick && !Joystick.bGamepadStyle; + gamepadjoystickmove = usejoystick && Joystick.bGamepadStyle; - thisjoyaiming = (cv_chasecam.value && !player->spectator) ? cv_chasefreelook.value : cv_alwaysfreelook.value; + thisjoyaiming = (chasecam && !player->spectator) ? chasefreelook : alwaysfreelook; // Reset the vertical look if we're no longer joyaiming - if (!thisjoyaiming && joyaiming) - localaiming = 0; - joyaiming = thisjoyaiming; + if (!thisjoyaiming && joyaiming[forplayer]) + *myaiming = 0; + joyaiming[forplayer] = thisjoyaiming; - axis = JoyAxis(AXISTURN); + axis = PlayerJoyAxis(ssplayer, AXISTURN); if (gamepadjoystickmove && axis != 0) { turnright = turnright || (axis > 0); @@ -1041,17 +1076,17 @@ void G_BuildTiccmd(ticcmd_t *cmd, INT32 realtics) // use two stage accelerative turning // on the keyboard and joystick if (turnleft || turnright) - turnheld += realtics; + turnheld[forplayer] += realtics; else - turnheld = 0; + turnheld[forplayer] = 0; - if (turnheld < SLOWTURNTICS) + if (turnheld[forplayer] < SLOWTURNTICS) tspeed = 2; // slow turn else tspeed = speed; // let movement keys cancel each other out - if (cv_analog.value) // Analog + if (analog) // Analog { if (turnright) cmd->angleturn = (INT16)(cmd->angleturn - angleturn[tspeed]); @@ -1080,7 +1115,7 @@ void G_BuildTiccmd(ticcmd_t *cmd, INT32 realtics) side += ((axis * sidemove[1]) >> 10); } } - else if (cv_analog.value) // Analog + else if (analog) // Analog { if (turnright) cmd->buttons |= BT_CAMRIGHT; @@ -1101,7 +1136,7 @@ void G_BuildTiccmd(ticcmd_t *cmd, INT32 realtics) } } - axis = JoyAxis(AXISSTRAFE); + axis = PlayerJoyAxis(ssplayer, AXISSTRAFE); if (gamepadjoystickmove && axis != 0) { if (axis < 0) @@ -1116,15 +1151,15 @@ void G_BuildTiccmd(ticcmd_t *cmd, INT32 realtics) } // forward with key or button - axis = JoyAxis(AXISMOVE); - altaxis = JoyAxis(AXISLOOK); + axis = PlayerJoyAxis(ssplayer, AXISMOVE); + altaxis = PlayerJoyAxis(ssplayer, AXISLOOK); if (movefkey || (gamepadjoystickmove && axis < 0) || ((player->powers[pw_carry] == CR_NIGHTSMODE) - && (PLAYER1INPUTDOWN(gc_lookup) || (gamepadjoystickmove && altaxis < 0)))) + && (PLAYERINPUTDOWN(ssplayer, gc_lookup) || (gamepadjoystickmove && altaxis < 0)))) forward = forwardmove[speed]; if (movebkey || (gamepadjoystickmove && axis > 0) || ((player->powers[pw_carry] == CR_NIGHTSMODE) - && (PLAYER1INPUTDOWN(gc_lookdown) || (gamepadjoystickmove && altaxis > 0)))) + && (PLAYERINPUTDOWN(ssplayer, gc_lookdown) || (gamepadjoystickmove && altaxis > 0)))) forward -= forwardmove[speed]; if (analogjoystickmove && axis != 0) @@ -1137,9 +1172,9 @@ void G_BuildTiccmd(ticcmd_t *cmd, INT32 realtics) if (strafelkey) side -= sidemove[speed]; - if (PLAYER1INPUTDOWN(gc_weaponnext)) + if (PLAYERINPUTDOWN(ssplayer, gc_weaponnext)) cmd->buttons |= BT_WEAPONNEXT; // Next Weapon - if (PLAYER1INPUTDOWN(gc_weaponprev)) + if (PLAYERINPUTDOWN(ssplayer, gc_weaponprev)) cmd->buttons |= BT_WEAPONPREV; // Previous Weapon #if NUM_WEAPONS > 10 @@ -1148,119 +1183,120 @@ void G_BuildTiccmd(ticcmd_t *cmd, INT32 realtics) //use the four avaliable bits to determine the weapon. cmd->buttons &= ~BT_WEAPONMASK; for (i = 0; i < NUM_WEAPONS; ++i) - if (PLAYER1INPUTDOWN(gc_wepslot1 + i)) + if (PLAYERINPUTDOWN(ssplayer, gc_wepslot1 + i)) { cmd->buttons |= (UINT16)(i + 1); break; } // fire with any button/key - axis = JoyAxis(AXISFIRE); - if (PLAYER1INPUTDOWN(gc_fire) || (cv_usejoystick.value && axis > 0)) + axis = PlayerJoyAxis(ssplayer, AXISFIRE); + if (PLAYERINPUTDOWN(ssplayer, gc_fire) || (usejoystick && axis > 0)) cmd->buttons |= BT_ATTACK; // fire normal with any button/key - axis = JoyAxis(AXISFIRENORMAL); - if (PLAYER1INPUTDOWN(gc_firenormal) || (cv_usejoystick.value && axis > 0)) + axis = PlayerJoyAxis(ssplayer, AXISFIRENORMAL); + if (PLAYERINPUTDOWN(ssplayer, gc_firenormal) || (usejoystick && axis > 0)) cmd->buttons |= BT_FIRENORMAL; - if (PLAYER1INPUTDOWN(gc_tossflag)) + if (PLAYERINPUTDOWN(ssplayer, gc_tossflag)) cmd->buttons |= BT_TOSSFLAG; // Lua scriptable buttons - if (PLAYER1INPUTDOWN(gc_custom1)) + if (PLAYERINPUTDOWN(ssplayer, gc_custom1)) cmd->buttons |= BT_CUSTOM1; - if (PLAYER1INPUTDOWN(gc_custom2)) + if (PLAYERINPUTDOWN(ssplayer, gc_custom2)) cmd->buttons |= BT_CUSTOM2; - if (PLAYER1INPUTDOWN(gc_custom3)) + if (PLAYERINPUTDOWN(ssplayer, gc_custom3)) cmd->buttons |= BT_CUSTOM3; // use with any button/key - axis = JoyAxis(AXISSPIN); - if (PLAYER1INPUTDOWN(gc_use) || (cv_usejoystick.value && axis > 0)) + axis = PlayerJoyAxis(ssplayer, AXISSPIN); + if (PLAYERINPUTDOWN(ssplayer, gc_use) || (usejoystick && axis > 0)) cmd->buttons |= BT_USE; - if (PLAYER1INPUTDOWN(gc_camreset)) + if (PLAYERINPUTDOWN(ssplayer, gc_camreset)) { - if (camera.chase && !resetdown) - P_ResetCamera(&players[displayplayer], &camera); - resetdown = true; + if (camera.chase && !resetdown[forplayer]) + P_ResetCamera(&players[ssplayer == 1 ? displayplayer : secondarydisplayplayer], &camera); + resetdown[forplayer] = true; } else - resetdown = false; + resetdown[forplayer] = false; // jump button - axis = JoyAxis(AXISJUMP); - if (PLAYER1INPUTDOWN(gc_jump) || (cv_usejoystick.value && axis > 0)) + axis = PlayerJoyAxis(ssplayer, AXISJUMP); + if (PLAYERINPUTDOWN(ssplayer, gc_jump) || (usejoystick && axis > 0)) cmd->buttons |= BT_JUMP; // player aiming shit, ahhhh... { - INT32 player_invert = cv_invertmouse.value ? -1 : 1; + INT32 player_invert = invertmouse ? -1 : 1; INT32 screen_invert = (player->mo && (player->mo->eflags & MFE_VERTICALFLIP) && (!camera.chase || player->pflags & PF_FLIPCAM)) //because chasecam's not inverted ? -1 : 1; // set to -1 or 1 to multiply + INT32 lookaxis = ssplayer == 1 ? cv_lookaxis.value : cv_lookaxis2.value; // mouse look stuff (mouse look is not the same as mouse aim) if (mouseaiming) { - keyboard_look = false; + keyboard_look[forplayer] = false; // looking up/down - localaiming += (mlooky<<19)*player_invert*screen_invert; + *myaiming += (*mly<<19)*player_invert*screen_invert; } - axis = JoyAxis(AXISLOOK); - if (analogjoystickmove && joyaiming && axis != 0 && cv_lookaxis.value != 0) - localaiming += (axis<<16) * screen_invert; + axis = PlayerJoyAxis(ssplayer, AXISLOOK); + if (analogjoystickmove && joyaiming[forplayer] && axis != 0 && lookaxis != 0) + *myaiming += (axis<<16) * screen_invert; // spring back if not using keyboard neither mouselookin' - if (!keyboard_look && cv_lookaxis.value == 0 && !joyaiming && !mouseaiming) - localaiming = 0; + if (!keyboard_look[forplayer] && lookaxis == 0 && !joyaiming[forplayer] && !mouseaiming) + *myaiming = 0; if (!(player->powers[pw_carry] == CR_NIGHTSMODE)) { - if (PLAYER1INPUTDOWN(gc_lookup) || (gamepadjoystickmove && axis < 0)) + if (PLAYERINPUTDOWN(ssplayer, gc_lookup) || (gamepadjoystickmove && axis < 0)) { - localaiming += KB_LOOKSPEED * screen_invert; - keyboard_look = true; + *myaiming += KB_LOOKSPEED * screen_invert; + keyboard_look[forplayer] = true; } - else if (PLAYER1INPUTDOWN(gc_lookdown) || (gamepadjoystickmove && axis > 0)) + else if (PLAYERINPUTDOWN(ssplayer, gc_lookdown) || (gamepadjoystickmove && axis > 0)) { - localaiming -= KB_LOOKSPEED * screen_invert; - keyboard_look = true; + *myaiming -= KB_LOOKSPEED * screen_invert; + keyboard_look[forplayer] = true; } - else if (PLAYER1INPUTDOWN(gc_centerview)) - localaiming = 0; + else if (PLAYERINPUTDOWN(ssplayer, gc_centerview)) + *myaiming = 0; } // accept no mlook for network games if (!cv_allowmlook.value) - localaiming = 0; + *myaiming = 0; - cmd->aiming = G_ClipAimingPitch(&localaiming); + cmd->aiming = G_ClipAimingPitch(myaiming); } - if (!mouseaiming && cv_mousemove.value) - forward += mousey; + if (!mouseaiming && mousemove) + forward += *my; if ((!demoplayback && (player->pflags & PF_SLIDING))) // Analog for mouse - side += mousex*2; - else if (cv_analog.value) + side += *mx*2; + else if (analog) { - if (mousex) + if (*mx) { - if (mousex > 0) + if (*mx > 0) cmd->buttons |= BT_CAMRIGHT; else cmd->buttons |= BT_CAMLEFT; } } else - cmd->angleturn = (INT16)(cmd->angleturn - (mousex*8)); + cmd->angleturn = (INT16)(cmd->angleturn - (*mx*8)); - mousex = mousey = mlooky = 0; + *mx = *my = *mly = 0; if (forward > MAXPLMOVE) forward = MAXPLMOVE; @@ -1293,335 +1329,7 @@ void G_BuildTiccmd(ticcmd_t *cmd, INT32 realtics) cmd->forwardmove = (SINT8)(cmd->forwardmove + forward); cmd->sidemove = (SINT8)(cmd->sidemove + side); - if (cv_analog.value) { - if (player->awayviewtics) - cmd->angleturn = (INT16)(player->awayviewmobj->angle >> 16); - else - cmd->angleturn = (INT16)(thiscam->angle >> 16); - } - else - { - localangle += (cmd->angleturn<<16); - cmd->angleturn = (INT16)(localangle >> 16); - } - - //Reset away view if a command is given. - if ((cmd->forwardmove || cmd->sidemove || cmd->buttons) - && displayplayer != consoleplayer) - displayplayer = consoleplayer; -} - -// like the g_buildticcmd 1 but using mouse2, gamcontrolbis, ... -void G_BuildTiccmd2(ticcmd_t *cmd, INT32 realtics) -{ - boolean forcestrafe = false; - boolean forcefullinput = false; - INT32 tspeed, forward, side, axis, altaxis, i; - const INT32 speed = 1; - // these ones used for multiple conditions - boolean turnleft, turnright, strafelkey, straferkey, movefkey, movebkey, mouseaiming, analogjoystickmove, gamepadjoystickmove, thisjoyaiming; - player_t *player = &players[secondarydisplayplayer]; - camera_t *thiscam = (player->bot == 2 ? &camera : &camera2); - - static INT32 turnheld; // for accelerative turning - static boolean keyboard_look; // true if lookup/down using keyboard - static boolean resetdown; // don't cam reset every frame - static boolean joyaiming; // check the last frame's value if we need to reset the camera - - G_CopyTiccmd(cmd, I_BaseTiccmd2(), 1); // empty, or external driver - - //why build a ticcmd if we're paused? - // Or, for that matter, if we're being reborn. - if (paused || P_AutoPause() || player->playerstate == PST_REBORN) - { - cmd->angleturn = (INT16)(localangle2 >> 16); - cmd->aiming = G_ClipAimingPitch(&localaiming2); - return; - } - - turnright = PLAYER2INPUTDOWN(gc_turnright); - turnleft = PLAYER2INPUTDOWN(gc_turnleft); - - straferkey = PLAYER2INPUTDOWN(gc_straferight); - strafelkey = PLAYER2INPUTDOWN(gc_strafeleft); - movefkey = PLAYER2INPUTDOWN(gc_forward); - movebkey = PLAYER2INPUTDOWN(gc_backward); - - mouseaiming = (PLAYER2INPUTDOWN(gc_mouseaiming)) ^ - ((cv_chasecam2.value && !player->spectator) ? cv_chasefreelook2.value : cv_alwaysfreelook2.value); - analogjoystickmove = cv_usejoystick2.value && !Joystick2.bGamepadStyle; - gamepadjoystickmove = cv_usejoystick2.value && Joystick2.bGamepadStyle; - - thisjoyaiming = (cv_chasecam2.value && !player->spectator) ? cv_chasefreelook2.value : cv_alwaysfreelook2.value; - - // Reset the vertical look if we're no longer joyaiming - if (!thisjoyaiming && joyaiming) - localaiming2 = 0; - joyaiming = thisjoyaiming; - - axis = Joy2Axis(AXISTURN); - if (gamepadjoystickmove && axis != 0) - { - turnright = turnright || (axis > 0); - turnleft = turnleft || (axis < 0); - } - forward = side = 0; - - // use two stage accelerative turning - // on the keyboard and joystick - if (turnleft || turnright) - turnheld += realtics; - else - turnheld = 0; - - if (turnheld < SLOWTURNTICS) - tspeed = 2; // slow turn - else - tspeed = speed; - - // let movement keys cancel each other out - if (cv_analog2.value) // Analog - { - if (turnright) - cmd->angleturn = (INT16)(cmd->angleturn - angleturn[tspeed]); - if (turnleft) - cmd->angleturn = (INT16)(cmd->angleturn + angleturn[tspeed]); - } - if (twodlevel - || (player->mo && (player->mo->flags2 & MF2_TWOD)) - || (!demoplayback && (player->pflags & PF_SLIDING))) - forcefullinput = true; - if (twodlevel - || (player->mo && (player->mo->flags2 & MF2_TWOD)) - || player->climbing - || (player->powers[pw_carry] == CR_NIGHTSMODE) - || (player->pflags & (PF_SLIDING|PF_FORCESTRAFE))) // Analog - forcestrafe = true; - if (forcestrafe) // Analog - { - if (turnright) - side += sidemove[speed]; - if (turnleft) - side -= sidemove[speed]; - - if (analogjoystickmove && axis != 0) - { - // JOYAXISRANGE is supposed to be 1023 (divide by 1024) - side += ((axis * sidemove[1]) >> 10); - } - } - else if (cv_analog2.value) // Analog - { - if (turnright) - cmd->buttons |= BT_CAMRIGHT; - if (turnleft) - cmd->buttons |= BT_CAMLEFT; - } - else - { - if (turnright) - cmd->angleturn = (INT16)(cmd->angleturn - angleturn[tspeed]); - else if (turnleft) - cmd->angleturn = (INT16)(cmd->angleturn + angleturn[tspeed]); - - if (analogjoystickmove && axis != 0) - { - // JOYAXISRANGE should be 1023 (divide by 1024) - cmd->angleturn = (INT16)(cmd->angleturn - ((axis * angleturn[1]) >> 10)); // ANALOG! - } - } - - axis = Joy2Axis(AXISSTRAFE); - if (gamepadjoystickmove && axis != 0) - { - if (axis < 0) - side += sidemove[speed]; - else if (axis > 0) - side -= sidemove[speed]; - } - else if (analogjoystickmove && axis != 0) - { - // JOYAXISRANGE is supposed to be 1023 (divide by 1024) - side += ((axis * sidemove[1]) >> 10); - } - - // forward with key or button - axis = Joy2Axis(AXISMOVE); - altaxis = Joy2Axis(AXISLOOK); - if (movefkey || (gamepadjoystickmove && axis < 0) - || ((player->powers[pw_carry] == CR_NIGHTSMODE) - && (PLAYER2INPUTDOWN(gc_lookup) || (gamepadjoystickmove && altaxis < 0)))) - forward = forwardmove[speed]; - if (movebkey || (gamepadjoystickmove && axis > 0) - || ((player->powers[pw_carry] == CR_NIGHTSMODE) - && (PLAYER2INPUTDOWN(gc_lookdown) || (gamepadjoystickmove && altaxis > 0)))) - forward -= forwardmove[speed]; - - if (analogjoystickmove && axis != 0) - forward -= ((axis * forwardmove[1]) >> 10); // ANALOG! - - // some people strafe left & right with mouse buttons - // those people are (still) weird - if (straferkey) - side += sidemove[speed]; - if (strafelkey) - side -= sidemove[speed]; - - if (PLAYER2INPUTDOWN(gc_weaponnext)) - cmd->buttons |= BT_WEAPONNEXT; // Next Weapon - if (PLAYER2INPUTDOWN(gc_weaponprev)) - cmd->buttons |= BT_WEAPONPREV; // Previous Weapon - - //use the four avaliable bits to determine the weapon. - cmd->buttons &= ~BT_WEAPONMASK; - for (i = 0; i < NUM_WEAPONS; ++i) - if (PLAYER2INPUTDOWN(gc_wepslot1 + i)) - { - cmd->buttons |= (UINT16)(i + 1); - break; - } - - // fire with any button/key - axis = Joy2Axis(AXISFIRE); - if (PLAYER2INPUTDOWN(gc_fire) || (cv_usejoystick2.value && axis > 0)) - cmd->buttons |= BT_ATTACK; - - // fire normal with any button/key - axis = Joy2Axis(AXISFIRENORMAL); - if (PLAYER2INPUTDOWN(gc_firenormal) || (cv_usejoystick2.value && axis > 0)) - cmd->buttons |= BT_FIRENORMAL; - - if (PLAYER2INPUTDOWN(gc_tossflag)) - cmd->buttons |= BT_TOSSFLAG; - - // Lua scriptable buttons - if (PLAYER2INPUTDOWN(gc_custom1)) - cmd->buttons |= BT_CUSTOM1; - if (PLAYER2INPUTDOWN(gc_custom2)) - cmd->buttons |= BT_CUSTOM2; - if (PLAYER2INPUTDOWN(gc_custom3)) - cmd->buttons |= BT_CUSTOM3; - - // use with any button/key - axis = Joy2Axis(AXISSPIN); - if (PLAYER2INPUTDOWN(gc_use) || (cv_usejoystick2.value && axis > 0)) - cmd->buttons |= BT_USE; - - if (PLAYER2INPUTDOWN(gc_camreset)) - { - if (camera2.chase && !resetdown) - P_ResetCamera(&players[secondarydisplayplayer], &camera2); - resetdown = true; - } - else - resetdown = false; - - // jump button - axis = Joy2Axis(AXISJUMP); - if (PLAYER2INPUTDOWN(gc_jump) || (cv_usejoystick2.value && axis > 0)) - cmd->buttons |= BT_JUMP; - - // player aiming shit, ahhhh... - { - INT32 player_invert = cv_invertmouse2.value ? -1 : 1; - INT32 screen_invert = - (player->mo && (player->mo->eflags & MFE_VERTICALFLIP) - && (!camera2.chase || player->pflags & PF_FLIPCAM)) //because chasecam's not inverted - ? -1 : 1; // set to -1 or 1 to multiply - - // mouse look stuff (mouse look is not the same as mouse aim) - if (mouseaiming) - { - keyboard_look = false; - - // looking up/down - localaiming2 += (mlook2y<<19)*player_invert*screen_invert; - } - - axis = Joy2Axis(AXISLOOK); - if (analogjoystickmove && joyaiming && axis != 0 && cv_lookaxis2.value != 0) - localaiming2 += (axis<<16) * screen_invert; - - // spring back if not using keyboard neither mouselookin' - if (!keyboard_look && cv_lookaxis2.value == 0 && !joyaiming && !mouseaiming) - localaiming2 = 0; - - if (!(player->powers[pw_carry] == CR_NIGHTSMODE)) - { - if (PLAYER2INPUTDOWN(gc_lookup) || (gamepadjoystickmove && axis < 0)) - { - localaiming2 += KB_LOOKSPEED * screen_invert; - keyboard_look = true; - } - else if (PLAYER2INPUTDOWN(gc_lookdown) || (gamepadjoystickmove && axis > 0)) - { - localaiming2 -= KB_LOOKSPEED * screen_invert; - keyboard_look = true; - } - else if (PLAYER2INPUTDOWN(gc_centerview)) - localaiming2 = 0; - } - - // accept no mlook for network games - if (!cv_allowmlook.value) - localaiming2 = 0; - - cmd->aiming = G_ClipAimingPitch(&localaiming2); - } - - if (!mouseaiming && cv_mousemove2.value) - forward += mouse2y; - - if (player->climbing - || (player->pflags & PF_SLIDING)) // Analog for mouse - side += mouse2x*2; - else if (cv_analog2.value) - { - if (mouse2x) - { - if (mouse2x > 0) - cmd->buttons |= BT_CAMRIGHT; - else - cmd->buttons |= BT_CAMLEFT; - } - } - else - cmd->angleturn = (INT16)(cmd->angleturn - (mouse2x*8)); - - mouse2x = mouse2y = mlook2y = 0; - - if (forward > MAXPLMOVE) - forward = MAXPLMOVE; - else if (forward < -MAXPLMOVE) - forward = -MAXPLMOVE; - if (side > MAXPLMOVE) - side = MAXPLMOVE; - else if (side < -MAXPLMOVE) - side = -MAXPLMOVE; - - // No additional acceleration when moving forward/backward and strafing simultaneously. - // do this AFTER we cap to MAXPLMOVE so people can't find ways to cheese around this. - if (!forcefullinput && forward && side) - { - angle_t angle = R_PointToAngle2(0, 0, side << FRACBITS, forward << FRACBITS); - INT32 maxforward = abs(P_ReturnThrustY(NULL, angle, MAXPLMOVE)); - INT32 maxside = abs(P_ReturnThrustX(NULL, angle, MAXPLMOVE)); - forward = max(min(forward, maxforward), -maxforward); - side = max(min(side, maxside), -maxside); - } - - //Silly hack to make 2d mode *somewhat* playable with no chasecam. - if ((twodlevel || (player->mo && player->mo->flags2 & MF2_TWOD)) && !camera2.chase) - { - INT32 temp = forward; - forward = side; - side = temp; - } - - cmd->forwardmove = (SINT8)(cmd->forwardmove + forward); - cmd->sidemove = (SINT8)(cmd->sidemove + side); - - if (player->bot == 1) { + if (player->bot == 1) { // Tailsbot for P2 if (!player->powers[pw_tailsfly] && (cmd->forwardmove || cmd->sidemove || cmd->buttons)) { player->bot = 2; // A player-controlled bot. Returns to AI when it respawns. @@ -1634,7 +1342,7 @@ void G_BuildTiccmd2(ticcmd_t *cmd, INT32 realtics) } } - if (cv_analog2.value) { + if (analog) { if (player->awayviewtics) cmd->angleturn = (INT16)(player->awayviewmobj->angle >> 16); else @@ -1642,9 +1350,14 @@ void G_BuildTiccmd2(ticcmd_t *cmd, INT32 realtics) } else { - localangle2 += (cmd->angleturn<<16); - cmd->angleturn = (INT16)(localangle2 >> 16); + *myangle += (cmd->angleturn<<16); + cmd->angleturn = (INT16)(*myangle >> 16); } + + //Reset away view if a command is given. + if (ssplayer == 1 && (cmd->forwardmove || cmd->sidemove || cmd->buttons) + && displayplayer != consoleplayer) + displayplayer = consoleplayer; } // User has designated that they want diff --git a/src/g_game.h b/src/g_game.h index e7f4a4677..3067751ee 100644 --- a/src/g_game.h +++ b/src/g_game.h @@ -83,8 +83,7 @@ extern consvar_t cv_ghost_bestscore, cv_ghost_besttime, cv_ghost_bestrings, cv_g // build an internal map name MAPxx from map number const char *G_BuildMapName(INT32 map); -void G_BuildTiccmd(ticcmd_t *cmd, INT32 realtics); -void G_BuildTiccmd2(ticcmd_t *cmd, INT32 realtics); +void G_BuildTiccmd(ticcmd_t *cmd, INT32 realtics, UINT8 ssplayer); // copy ticcmd_t to and fro the normal way ticcmd_t *G_CopyTiccmd(ticcmd_t* dest, const ticcmd_t* src, const size_t n); diff --git a/src/g_input.h b/src/g_input.h index d089332c5..f7f952d72 100644 --- a/src/g_input.h +++ b/src/g_input.h @@ -132,6 +132,7 @@ extern INT32 gamecontroldefault[num_gamecontrolschemes][num_gamecontrols][2]; // extern INT32 gamecontrolbisdefault[num_gamecontrolschemes][num_gamecontrols][2]; #define PLAYER1INPUTDOWN(gc) (gamekeydown[gamecontrol[gc][0]] || gamekeydown[gamecontrol[gc][1]]) #define PLAYER2INPUTDOWN(gc) (gamekeydown[gamecontrolbis[gc][0]] || gamekeydown[gamecontrolbis[gc][1]]) +#define PLAYERINPUTDOWN(p, gc) ((p) == 2 ? PLAYER2INPUTDOWN(gc) : PLAYER1INPUTDOWN(gc)) #define num_gcl_tutorial_check 6 #define num_gcl_tutorial_used 8 From 075f751f674e0285f554e7d2569a04470e9ba902 Mon Sep 17 00:00:00 2001 From: fickleheart Date: Sun, 8 Dec 2019 14:17:48 -0600 Subject: [PATCH 063/746] Add cvar to use abilities in input direction --- src/d_netcmd.c | 4 ++++ src/g_game.c | 25 ++++++++++++++++++++++++- src/g_game.h | 3 +++ 3 files changed, 31 insertions(+), 1 deletion(-) diff --git a/src/d_netcmd.c b/src/d_netcmd.c index e80d07b76..f181c6e57 100644 --- a/src/d_netcmd.c +++ b/src/d_netcmd.c @@ -823,6 +823,10 @@ void D_RegisterClientCommands(void) CV_RegisterVar(&cv_autobrake); CV_RegisterVar(&cv_autobrake2); + // hi here's some new controls + CV_RegisterVar(&cv_abilitydirection[0]); + CV_RegisterVar(&cv_abilitydirection[1]); + // s_sound.c CV_RegisterVar(&cv_soundvolume); CV_RegisterVar(&cv_closedcaptioning); diff --git a/src/g_game.c b/src/g_game.c index a55c1b1eb..598f328aa 100644 --- a/src/g_game.c +++ b/src/g_game.c @@ -394,6 +394,12 @@ consvar_t cv_directionchar2 = {"directionchar2", "Movement", CV_SAVE|CV_CALL, di consvar_t cv_autobrake = {"autobrake", "On", CV_SAVE|CV_CALL, CV_OnOff, AutoBrake_OnChange, 0, NULL, NULL, 0, 0, NULL}; consvar_t cv_autobrake2 = {"autobrake2", "On", CV_SAVE|CV_CALL, CV_OnOff, AutoBrake2_OnChange, 0, NULL, NULL, 0, 0, NULL}; +// hi here's some new controls +consvar_t cv_abilitydirection[2] = { + {"abilitydirection", "Movement", CV_SAVE, directionchar_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL}, + {"abilitydirection2", "Movement", CV_SAVE, directionchar_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL}, +}; + typedef enum { AXISNONE = 0, @@ -996,7 +1002,7 @@ void G_BuildTiccmd(ticcmd_t *cmd, INT32 realtics, UINT8 ssplayer) angle_t *myangle = (ssplayer == 1 ? &localangle : &localangle2); INT32 *myaiming = (ssplayer == 1 ? &localaiming : &localaiming2); - INT32 chasecam, chasefreelook, alwaysfreelook, usejoystick, analog, invertmouse, mousemove; + INT32 chasecam, chasefreelook, alwaysfreelook, usejoystick, analog, invertmouse, mousemove, abilitydirection; INT32 *mx; INT32 *my; INT32 *mly; static INT32 turnheld[2]; // for accelerative turning @@ -1033,6 +1039,7 @@ void G_BuildTiccmd(ticcmd_t *cmd, INT32 realtics, UINT8 ssplayer) mly = &mlook2y; G_CopyTiccmd(cmd, I_BaseTiccmd2(), 1); // empty, or external driver } + abilitydirection = cv_abilitydirection[forplayer].value; // why build a ticcmd if we're paused? // Or, for that matter, if we're being reborn. @@ -1352,6 +1359,22 @@ void G_BuildTiccmd(ticcmd_t *cmd, INT32 realtics, UINT8 ssplayer) { *myangle += (cmd->angleturn<<16); cmd->angleturn = (INT16)(*myangle >> 16); + + if (abilitydirection && !player->climbing && !forcestrafe) + { + if (cmd->forwardmove || cmd->sidemove) + { + angle_t controlangle = R_PointToAngle2(0, 0, cmd->forwardmove << FRACBITS, -cmd->sidemove << FRACBITS); + cmd->angleturn += (controlangle>>16); + + cmd->forwardmove = R_PointToDist2(0, 0, cmd->forwardmove, cmd->sidemove); + if (cmd->forwardmove > MAXPLMOVE) + cmd->forwardmove = MAXPLMOVE; + cmd->sidemove = 0; + } + else + cmd->angleturn = (player->drawangle>>16); + } } //Reset away view if a command is given. diff --git a/src/g_game.h b/src/g_game.h index 3067751ee..86bcf3d59 100644 --- a/src/g_game.h +++ b/src/g_game.h @@ -76,6 +76,9 @@ extern consvar_t cv_sideaxis,cv_turnaxis,cv_moveaxis,cv_lookaxis,cv_jumpaxis,cv_ extern consvar_t cv_sideaxis2,cv_turnaxis2,cv_moveaxis2,cv_lookaxis2,cv_jumpaxis2,cv_spinaxis2,cv_fireaxis2,cv_firenaxis2; extern consvar_t cv_ghost_bestscore, cv_ghost_besttime, cv_ghost_bestrings, cv_ghost_last, cv_ghost_guest; +// hi here's some new controls +extern consvar_t cv_abilitydirection[2]; + // mouseaiming (looking up/down with the mouse or keyboard) #define KB_LOOKSPEED (1<<25) #define MAXPLMOVE (50) From 36fa94a22ce53810500146728a541b364ab09d84 Mon Sep 17 00:00:00 2001 From: fickleheart Date: Sun, 8 Dec 2019 14:35:50 -0600 Subject: [PATCH 064/746] Automatically rotate camera to reflect player actions --- src/d_netcmd.c | 6 ++++++ src/g_game.c | 43 ++++++++++++++++++++++++++++++++++++++++++- src/g_game.h | 2 +- src/p_user.c | 6 ++++++ 4 files changed, 55 insertions(+), 2 deletions(-) diff --git a/src/d_netcmd.c b/src/d_netcmd.c index f181c6e57..49d3d060c 100644 --- a/src/d_netcmd.c +++ b/src/d_netcmd.c @@ -826,6 +826,12 @@ void D_RegisterClientCommands(void) // hi here's some new controls CV_RegisterVar(&cv_abilitydirection[0]); CV_RegisterVar(&cv_abilitydirection[1]); + CV_RegisterVar(&cv_cam_turnfacing[0]); + CV_RegisterVar(&cv_cam_turnfacing[1]); + CV_RegisterVar(&cv_cam_turnfacingability[0]); + CV_RegisterVar(&cv_cam_turnfacingability[1]); + CV_RegisterVar(&cv_cam_turnfacinginput[0]); + CV_RegisterVar(&cv_cam_turnfacinginput[1]); // s_sound.c CV_RegisterVar(&cv_soundvolume); diff --git a/src/g_game.c b/src/g_game.c index 598f328aa..c55058b99 100644 --- a/src/g_game.c +++ b/src/g_game.c @@ -399,6 +399,19 @@ consvar_t cv_abilitydirection[2] = { {"abilitydirection", "Movement", CV_SAVE, directionchar_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL}, {"abilitydirection2", "Movement", CV_SAVE, directionchar_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL}, }; +static CV_PossibleValue_t zerotoone_cons_t[] = {{0, "MIN"}, {FRACUNIT, "MAX"}, {0, NULL}}; +consvar_t cv_cam_turnfacing[2] = { + {"cam_turnfacingchar", "0.002", CV_FLOAT|CV_SAVE, zerotoone_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL}, + {"cam2_turnfacingchar", "0.002", CV_FLOAT|CV_SAVE, zerotoone_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL}, +}; +consvar_t cv_cam_turnfacingability[2] = { + {"cam_turnfacingability", "0.125", CV_FLOAT|CV_SAVE, zerotoone_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL}, + {"cam2_turnfacingability", "0.125", CV_FLOAT|CV_SAVE, zerotoone_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL}, +}; +consvar_t cv_cam_turnfacinginput[2] = { + {"cam_turnfacinginput", "0.15", CV_FLOAT|CV_SAVE, zerotoone_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL}, + {"cam2_turnfacinginput", "0.15", CV_FLOAT|CV_SAVE, zerotoone_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL}, +}; typedef enum { @@ -1133,7 +1146,7 @@ void G_BuildTiccmd(ticcmd_t *cmd, INT32 realtics, UINT8 ssplayer) { if (turnright) cmd->angleturn = (INT16)(cmd->angleturn - angleturn[tspeed]); - else if (turnleft) + if (turnleft) cmd->angleturn = (INT16)(cmd->angleturn + angleturn[tspeed]); if (analogjoystickmove && axis != 0) @@ -1360,6 +1373,15 @@ void G_BuildTiccmd(ticcmd_t *cmd, INT32 realtics, UINT8 ssplayer) *myangle += (cmd->angleturn<<16); cmd->angleturn = (INT16)(*myangle >> 16); + // Adjust camera angle by player input + if (!forcestrafe && !turnheld[forplayer] && !player->climbing) + { + fixed_t camadjustfactor = cv_cam_turnfacinginput[forplayer].value; //@TODO cvar + + if (camadjustfactor) + *myangle -= cmd->sidemove * 50 * camadjustfactor; + } + if (abilitydirection && !player->climbing && !forcestrafe) { if (cmd->forwardmove || cmd->sidemove) @@ -1375,6 +1397,25 @@ void G_BuildTiccmd(ticcmd_t *cmd, INT32 realtics, UINT8 ssplayer) else cmd->angleturn = (player->drawangle>>16); } + + // Adjust camera angle to face player direction, depending on circumstances + // Nothing happens if cam left/right are held, so you can hold both to lock the camera in one direction + if (!forcestrafe && !turnheld[forplayer]) + { + fixed_t camadjustfactor; + + if (player->climbing || player->pflags & (PF_GLIDING|PF_STARTDASH)) + camadjustfactor = cv_cam_turnfacingability[forplayer].value; + else + camadjustfactor = cv_cam_turnfacing[forplayer].value; + + if (camadjustfactor) + { + INT32 anglediff = player->drawangle - *myangle; + + *myangle += FixedMul(anglediff, camadjustfactor); + } + } } //Reset away view if a command is given. diff --git a/src/g_game.h b/src/g_game.h index 86bcf3d59..ea2098f35 100644 --- a/src/g_game.h +++ b/src/g_game.h @@ -77,7 +77,7 @@ extern consvar_t cv_sideaxis2,cv_turnaxis2,cv_moveaxis2,cv_lookaxis2,cv_jumpaxis extern consvar_t cv_ghost_bestscore, cv_ghost_besttime, cv_ghost_bestrings, cv_ghost_last, cv_ghost_guest; // hi here's some new controls -extern consvar_t cv_abilitydirection[2]; +extern consvar_t cv_abilitydirection[2], cv_cam_turnfacing[2], cv_cam_turnfacingability[2], cv_cam_turnfacinginput[2]; // mouseaiming (looking up/down with the mouse or keyboard) #define KB_LOOKSPEED (1<<25) diff --git a/src/p_user.c b/src/p_user.c index ea42a2c36..21bc45502 100644 --- a/src/p_user.c +++ b/src/p_user.c @@ -5350,6 +5350,12 @@ static void P_DoJumpStuff(player_t *player, ticcmd_t *cmd) player->pflags &= ~(PF_SPINNING|PF_STARTDASH); player->pflags |= PF_THOKKED; + + // Change localangle to match? + if (player == &players[consoleplayer] && cv_cam_turnfacingability[0].value > 0) + localangle = player->mo->angle; + else if (player == &players[secondarydisplayplayer] && cv_cam_turnfacingability[1].value > 0) + localangle2 = player->mo->angle; } break; From ebd2861593a0e1f1a5262dd0edfbba1488883b03 Mon Sep 17 00:00:00 2001 From: fickleheart Date: Sun, 8 Dec 2019 14:43:25 -0600 Subject: [PATCH 065/746] Add menu options for new camera controls Crank everything down to zero and set ability direction to "Camera", and you're back to base 2.2 behavior. --- src/m_menu.c | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/src/m_menu.c b/src/m_menu.c index e367041e0..71d5b1bfb 100644 --- a/src/m_menu.c +++ b/src/m_menu.c @@ -1035,6 +1035,7 @@ static menuitem_t OP_P1ControlsMenu[] = //{IT_STRING | IT_CVAR, NULL, "Analog Control", &cv_useranalog, 100}, {IT_STRING | IT_CVAR, NULL, "Character angle", &cv_directionchar, 70}, {IT_STRING | IT_CVAR, NULL, "Automatic braking", &cv_autobrake, 80}, + {IT_STRING | IT_CVAR, NULL, "Ability angle", &cv_abilitydirection[0], 90}, }; static menuitem_t OP_P2ControlsMenu[] = @@ -1048,6 +1049,7 @@ static menuitem_t OP_P2ControlsMenu[] = //{IT_STRING | IT_CVAR, NULL, "Analog Control", &cv_useranalog2, 100}, {IT_STRING | IT_CVAR, NULL, "Character angle", &cv_directionchar2, 70}, {IT_STRING | IT_CVAR, NULL, "Automatic braking", &cv_autobrake2, 80}, + {IT_STRING | IT_CVAR, NULL, "Ability angle", &cv_abilitydirection[1], 90}, }; static menuitem_t OP_ChangeControlsMenu[] = @@ -1180,7 +1182,11 @@ static menuitem_t OP_CameraOptionsMenu[] = {IT_STRING | IT_CVAR | IT_CV_INTEGERSTEP, NULL, "Camera Height", &cv_cam_height, 70}, {IT_STRING | IT_CVAR | IT_CV_FLOATSLIDER, NULL, "Camera Speed", &cv_cam_speed, 80}, - {IT_STRING | IT_CVAR, NULL, "Crosshair", &cv_crosshair, 100}, + {IT_STRING | IT_CVAR | IT_CV_SLIDER, NULL, "Turn to character angle", &cv_cam_turnfacing[0], 100}, + {IT_STRING | IT_CVAR | IT_CV_SLIDER, NULL, "Turn to ability", &cv_cam_turnfacingability[0], 110}, + {IT_STRING | IT_CVAR | IT_CV_SLIDER, NULL, "Turn to input", &cv_cam_turnfacinginput[0], 120}, + + {IT_STRING | IT_CVAR, NULL, "Crosshair", &cv_crosshair, 140}, }; static menuitem_t OP_Camera2OptionsMenu[] = @@ -1194,7 +1200,11 @@ static menuitem_t OP_Camera2OptionsMenu[] = {IT_STRING | IT_CVAR | IT_CV_INTEGERSTEP, NULL, "Camera Height", &cv_cam2_height, 70}, {IT_STRING | IT_CVAR | IT_CV_FLOATSLIDER, NULL, "Camera Speed", &cv_cam2_speed, 80}, - {IT_STRING | IT_CVAR, NULL, "Crosshair", &cv_crosshair2, 100}, + {IT_STRING | IT_CVAR | IT_CV_SLIDER, NULL, "Turn to character angle", &cv_cam_turnfacing[1], 100}, + {IT_STRING | IT_CVAR | IT_CV_SLIDER, NULL, "Turn to ability", &cv_cam_turnfacingability[1], 110}, + {IT_STRING | IT_CVAR | IT_CV_SLIDER, NULL, "Turn to input", &cv_cam_turnfacinginput[1], 120}, + + {IT_STRING | IT_CVAR, NULL, "Crosshair", &cv_crosshair2, 140}, }; static menuitem_t OP_VideoOptionsMenu[] = From eee0d42b1f4de4c5c72512268ca2c37eb6e09261 Mon Sep 17 00:00:00 2001 From: fickleheart Date: Sun, 8 Dec 2019 15:05:44 -0600 Subject: [PATCH 066/746] Make first-person and directionchar-off work as expected --- src/g_game.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/g_game.c b/src/g_game.c index c55058b99..629f6b9c1 100644 --- a/src/g_game.c +++ b/src/g_game.c @@ -1374,7 +1374,7 @@ void G_BuildTiccmd(ticcmd_t *cmd, INT32 realtics, UINT8 ssplayer) cmd->angleturn = (INT16)(*myangle >> 16); // Adjust camera angle by player input - if (!forcestrafe && !turnheld[forplayer] && !player->climbing) + if (!forcestrafe && camera.chase && !turnheld[forplayer] && !player->climbing) { fixed_t camadjustfactor = cv_cam_turnfacinginput[forplayer].value; //@TODO cvar @@ -1382,7 +1382,7 @@ void G_BuildTiccmd(ticcmd_t *cmd, INT32 realtics, UINT8 ssplayer) *myangle -= cmd->sidemove * 50 * camadjustfactor; } - if (abilitydirection && !player->climbing && !forcestrafe) + if (abilitydirection && camera.chase && !player->climbing && !forcestrafe && (player->pflags & PF_DIRECTIONCHAR)) { if (cmd->forwardmove || cmd->sidemove) { @@ -1400,7 +1400,7 @@ void G_BuildTiccmd(ticcmd_t *cmd, INT32 realtics, UINT8 ssplayer) // Adjust camera angle to face player direction, depending on circumstances // Nothing happens if cam left/right are held, so you can hold both to lock the camera in one direction - if (!forcestrafe && !turnheld[forplayer]) + if (!forcestrafe && camera.chase && !turnheld[forplayer]) { fixed_t camadjustfactor; From c94d7895dfbe067acc4f1199be552f4ac888a212 Mon Sep 17 00:00:00 2001 From: fickleheart Date: Sun, 8 Dec 2019 15:17:46 -0600 Subject: [PATCH 067/746] Make cam_rotspeed affect non-mouse turn speed 10 remains the default and is vanilla behavior. --- src/g_game.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/g_game.c b/src/g_game.c index 629f6b9c1..d300fb80d 100644 --- a/src/g_game.c +++ b/src/g_game.c @@ -1154,6 +1154,9 @@ void G_BuildTiccmd(ticcmd_t *cmd, INT32 realtics, UINT8 ssplayer) // JOYAXISRANGE should be 1023 (divide by 1024) cmd->angleturn = (INT16)(cmd->angleturn - ((axis * angleturn[1]) >> 10)); // ANALOG! } + + // Make rotspeed affect turning speed :) + cmd->angleturn = (cmd->angleturn * (ssplayer == 1 ? cv_cam_rotspeed.value : cv_cam2_rotspeed.value)) / 10; } axis = PlayerJoyAxis(ssplayer, AXISSTRAFE); From 575b5027e8afa312ce6c7323f9b64a965cb22bed Mon Sep 17 00:00:00 2001 From: fickleheart Date: Sun, 8 Dec 2019 15:22:51 -0600 Subject: [PATCH 068/746] Don't snap thok if the player is holding a camera control --- src/p_user.c | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/src/p_user.c b/src/p_user.c index 21bc45502..b15531055 100644 --- a/src/p_user.c +++ b/src/p_user.c @@ -42,6 +42,8 @@ #include "b_bot.h" // Objectplace #include "m_cheat.h" +// Thok camera snap (ctrl-f "chalupa") +#include "g_input.h" #ifdef HW3SOUND #include "hardware/hw3sound.h" @@ -5351,10 +5353,10 @@ static void P_DoJumpStuff(player_t *player, ticcmd_t *cmd) player->pflags &= ~(PF_SPINNING|PF_STARTDASH); player->pflags |= PF_THOKKED; - // Change localangle to match? - if (player == &players[consoleplayer] && cv_cam_turnfacingability[0].value > 0) + // Change localangle to match? (P.S. chalupa) + if (player == &players[consoleplayer] && cv_cam_turnfacingability[0].value > 0 && !(PLAYER1INPUTDOWN(gc_turnleft) || PLAYER1INPUTDOWN(gc_turnright))) localangle = player->mo->angle; - else if (player == &players[secondarydisplayplayer] && cv_cam_turnfacingability[1].value > 0) + else if (player == &players[secondarydisplayplayer] && cv_cam_turnfacingability[1].value > 0 && !(PLAYER2INPUTDOWN(gc_turnleft) || PLAYER2INPUTDOWN(gc_turnright))) localangle2 = player->mo->angle; } break; From 4784eb68fa2916df99c0cae3f6fb77c0b9fbd6f1 Mon Sep 17 00:00:00 2001 From: fickleheart Date: Sun, 8 Dec 2019 15:49:10 -0600 Subject: [PATCH 069/746] Don't do thok camera snap in replays --- src/p_user.c | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/src/p_user.c b/src/p_user.c index b15531055..3b8b64e04 100644 --- a/src/p_user.c +++ b/src/p_user.c @@ -5354,10 +5354,13 @@ static void P_DoJumpStuff(player_t *player, ticcmd_t *cmd) player->pflags |= PF_THOKKED; // Change localangle to match? (P.S. chalupa) - if (player == &players[consoleplayer] && cv_cam_turnfacingability[0].value > 0 && !(PLAYER1INPUTDOWN(gc_turnleft) || PLAYER1INPUTDOWN(gc_turnright))) - localangle = player->mo->angle; - else if (player == &players[secondarydisplayplayer] && cv_cam_turnfacingability[1].value > 0 && !(PLAYER2INPUTDOWN(gc_turnleft) || PLAYER2INPUTDOWN(gc_turnright))) - localangle2 = player->mo->angle; + if (!demoplayback) + { + if (player == &players[consoleplayer] && cv_cam_turnfacingability[0].value > 0 && !(PLAYER1INPUTDOWN(gc_turnleft) || PLAYER1INPUTDOWN(gc_turnright))) + localangle = player->mo->angle; + else if (player == &players[secondarydisplayplayer] && cv_cam_turnfacingability[1].value > 0 && !(PLAYER2INPUTDOWN(gc_turnleft) || PLAYER2INPUTDOWN(gc_turnright))) + localangle2 = player->mo->angle; + } } break; From e92d7eca8e5c9ab2f62a6b40ac3ec7e7d78bd685 Mon Sep 17 00:00:00 2001 From: fickleheart Date: Sun, 8 Dec 2019 15:54:16 -0600 Subject: [PATCH 070/746] Shift camera sideways toward player angle --- src/d_netcmd.c | 2 ++ src/g_game.c | 4 ++++ src/g_game.h | 2 +- src/m_menu.c | 14 ++++++++------ src/p_user.c | 24 ++++++++++++++++++++++-- 5 files changed, 37 insertions(+), 9 deletions(-) diff --git a/src/d_netcmd.c b/src/d_netcmd.c index 49d3d060c..24df649fc 100644 --- a/src/d_netcmd.c +++ b/src/d_netcmd.c @@ -826,6 +826,8 @@ void D_RegisterClientCommands(void) // hi here's some new controls CV_RegisterVar(&cv_abilitydirection[0]); CV_RegisterVar(&cv_abilitydirection[1]); + CV_RegisterVar(&cv_cam_shiftfacing[0]); + CV_RegisterVar(&cv_cam_shiftfacing[1]); CV_RegisterVar(&cv_cam_turnfacing[0]); CV_RegisterVar(&cv_cam_turnfacing[1]); CV_RegisterVar(&cv_cam_turnfacingability[0]); diff --git a/src/g_game.c b/src/g_game.c index d300fb80d..2d44c8e00 100644 --- a/src/g_game.c +++ b/src/g_game.c @@ -400,6 +400,10 @@ consvar_t cv_abilitydirection[2] = { {"abilitydirection2", "Movement", CV_SAVE, directionchar_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL}, }; static CV_PossibleValue_t zerotoone_cons_t[] = {{0, "MIN"}, {FRACUNIT, "MAX"}, {0, NULL}}; +consvar_t cv_cam_shiftfacing[2] = { + {"cam_shiftfacingchar", "0.33", CV_FLOAT|CV_SAVE, zerotoone_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL}, + {"cam2_shiftfacingchar", "0.33", CV_FLOAT|CV_SAVE, zerotoone_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL}, +}; consvar_t cv_cam_turnfacing[2] = { {"cam_turnfacingchar", "0.002", CV_FLOAT|CV_SAVE, zerotoone_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL}, {"cam2_turnfacingchar", "0.002", CV_FLOAT|CV_SAVE, zerotoone_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL}, diff --git a/src/g_game.h b/src/g_game.h index ea2098f35..ea2cd1694 100644 --- a/src/g_game.h +++ b/src/g_game.h @@ -77,7 +77,7 @@ extern consvar_t cv_sideaxis2,cv_turnaxis2,cv_moveaxis2,cv_lookaxis2,cv_jumpaxis extern consvar_t cv_ghost_bestscore, cv_ghost_besttime, cv_ghost_bestrings, cv_ghost_last, cv_ghost_guest; // hi here's some new controls -extern consvar_t cv_abilitydirection[2], cv_cam_turnfacing[2], cv_cam_turnfacingability[2], cv_cam_turnfacinginput[2]; +extern consvar_t cv_abilitydirection[2], cv_cam_shiftfacing[2], cv_cam_turnfacing[2], cv_cam_turnfacingability[2], cv_cam_turnfacinginput[2]; // mouseaiming (looking up/down with the mouse or keyboard) #define KB_LOOKSPEED (1<<25) diff --git a/src/m_menu.c b/src/m_menu.c index 71d5b1bfb..4ae2b7036 100644 --- a/src/m_menu.c +++ b/src/m_menu.c @@ -1182,9 +1182,10 @@ static menuitem_t OP_CameraOptionsMenu[] = {IT_STRING | IT_CVAR | IT_CV_INTEGERSTEP, NULL, "Camera Height", &cv_cam_height, 70}, {IT_STRING | IT_CVAR | IT_CV_FLOATSLIDER, NULL, "Camera Speed", &cv_cam_speed, 80}, - {IT_STRING | IT_CVAR | IT_CV_SLIDER, NULL, "Turn to character angle", &cv_cam_turnfacing[0], 100}, - {IT_STRING | IT_CVAR | IT_CV_SLIDER, NULL, "Turn to ability", &cv_cam_turnfacingability[0], 110}, - {IT_STRING | IT_CVAR | IT_CV_SLIDER, NULL, "Turn to input", &cv_cam_turnfacinginput[0], 120}, + {IT_STRING | IT_CVAR | IT_CV_SLIDER, NULL, "Shift to character angle", &cv_cam_shiftfacing[0], 100}, + {IT_STRING | IT_CVAR | IT_CV_SLIDER, NULL, "Turn to character angle", &cv_cam_turnfacing[0], 110}, + {IT_STRING | IT_CVAR | IT_CV_SLIDER, NULL, "Turn to ability", &cv_cam_turnfacingability[0], 120}, + {IT_STRING | IT_CVAR | IT_CV_SLIDER, NULL, "Turn to input", &cv_cam_turnfacinginput[0], 130}, {IT_STRING | IT_CVAR, NULL, "Crosshair", &cv_crosshair, 140}, }; @@ -1200,9 +1201,10 @@ static menuitem_t OP_Camera2OptionsMenu[] = {IT_STRING | IT_CVAR | IT_CV_INTEGERSTEP, NULL, "Camera Height", &cv_cam2_height, 70}, {IT_STRING | IT_CVAR | IT_CV_FLOATSLIDER, NULL, "Camera Speed", &cv_cam2_speed, 80}, - {IT_STRING | IT_CVAR | IT_CV_SLIDER, NULL, "Turn to character angle", &cv_cam_turnfacing[1], 100}, - {IT_STRING | IT_CVAR | IT_CV_SLIDER, NULL, "Turn to ability", &cv_cam_turnfacingability[1], 110}, - {IT_STRING | IT_CVAR | IT_CV_SLIDER, NULL, "Turn to input", &cv_cam_turnfacinginput[1], 120}, + {IT_STRING | IT_CVAR | IT_CV_SLIDER, NULL, "Shift to character angle", &cv_cam_shiftfacing[1], 100}, + {IT_STRING | IT_CVAR | IT_CV_SLIDER, NULL, "Turn to character angle", &cv_cam_turnfacing[1], 110}, + {IT_STRING | IT_CVAR | IT_CV_SLIDER, NULL, "Turn to ability", &cv_cam_turnfacingability[1], 120}, + {IT_STRING | IT_CVAR | IT_CV_SLIDER, NULL, "Turn to input", &cv_cam_turnfacinginput[1], 130}, {IT_STRING | IT_CVAR, NULL, "Crosshair", &cv_crosshair2, 140}, }; diff --git a/src/p_user.c b/src/p_user.c index 3b8b64e04..0a3636884 100644 --- a/src/p_user.c +++ b/src/p_user.c @@ -9677,6 +9677,9 @@ boolean P_MoveChaseCamera(player_t *player, camera_t *thiscam, boolean resetcall subsector_t *newsubsec; fixed_t f1, f2; + static fixed_t camsideshift[2] = {0, 0}; + fixed_t shiftx = 0, shifty = 0; + // We probably shouldn't move the camera if there is no player or player mobj somehow if (!player || !player->mo) return true; @@ -9882,6 +9885,20 @@ boolean P_MoveChaseCamera(player_t *player, camera_t *thiscam, boolean resetcall } } + if (cv_abilitydirection[(thiscam == &camera) ? 0 : 1].value) + { + // Shift the camera slightly to the sides depending on the player facing direction + UINT8 forplayer = (thiscam == &camera) ? 0 : 1; + fixed_t shift = FixedMul(FINESINE((player->drawangle - angle) >> ANGLETOFINESHIFT), cv_cam_shiftfacing[forplayer].value); + + shift += FixedMul(camsideshift[forplayer] - shift, FRACUNIT-(camspeed>>3)); + camsideshift[forplayer] = shift; + + shift = FixedMul(shift, camdist); + shiftx = -FixedMul(FINESINE(angle>>ANGLETOFINESHIFT), shift); + shifty = FixedMul(FINECOSINE(angle>>ANGLETOFINESHIFT), shift); + } + // sets ideal cam pos if (twodlevel || (mo->flags2 & MF2_TWOD)) dist = 480<x + FixedMul(FINECOSINE((angle>>ANGLETOFINESHIFT) & FINEMASK), dist); - viewpointy = mo->y + FixedMul(FINESINE((angle>>ANGLETOFINESHIFT) & FINEMASK), dist); + viewpointx = mo->x + shiftx + FixedMul(FINECOSINE((angle>>ANGLETOFINESHIFT) & FINEMASK), dist); + viewpointy = mo->y + shifty + FixedMul(FINESINE((angle>>ANGLETOFINESHIFT) & FINEMASK), dist); } if (!camstill && !resetcalled && !paused) @@ -10270,6 +10287,9 @@ boolean P_MoveChaseCamera(player_t *player, camera_t *thiscam, boolean resetcall } else thiscam->momz = FixedMul(z - thiscam->z, camspeed); + + thiscam->momx += FixedMul(shiftx, camspeed); + thiscam->momy += FixedMul(shifty, camspeed); } // compute aming to look the viewed point From a30623e4ed4d16e6735267534b07df2e544386f1 Mon Sep 17 00:00:00 2001 From: fickleheart Date: Sun, 8 Dec 2019 15:54:37 -0600 Subject: [PATCH 071/746] Default to no turn-facing since it looks like controller drift --- src/g_game.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/g_game.c b/src/g_game.c index 2d44c8e00..5f34846b6 100644 --- a/src/g_game.c +++ b/src/g_game.c @@ -405,8 +405,8 @@ consvar_t cv_cam_shiftfacing[2] = { {"cam2_shiftfacingchar", "0.33", CV_FLOAT|CV_SAVE, zerotoone_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL}, }; consvar_t cv_cam_turnfacing[2] = { - {"cam_turnfacingchar", "0.002", CV_FLOAT|CV_SAVE, zerotoone_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL}, - {"cam2_turnfacingchar", "0.002", CV_FLOAT|CV_SAVE, zerotoone_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL}, + {"cam_turnfacingchar", "0.0", CV_FLOAT|CV_SAVE, zerotoone_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL}, + {"cam2_turnfacingchar", "0.0", CV_FLOAT|CV_SAVE, zerotoone_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL}, }; consvar_t cv_cam_turnfacingability[2] = { {"cam_turnfacingability", "0.125", CV_FLOAT|CV_SAVE, zerotoone_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL}, From 25464c867a57d479b292098ff0a1c377706c724c Mon Sep 17 00:00:00 2001 From: Jaime Passos Date: Sun, 8 Dec 2019 21:10:14 -0300 Subject: [PATCH 072/746] Translate the French --- src/hardware/r_opengl/r_opengl.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/hardware/r_opengl/r_opengl.c b/src/hardware/r_opengl/r_opengl.c index fbb5d9efe..9a80c0e36 100644 --- a/src/hardware/r_opengl/r_opengl.c +++ b/src/hardware/r_opengl/r_opengl.c @@ -723,8 +723,8 @@ void Flush(void) while (gr_cachehead) { - // ceci n'est pas du tout necessaire vu que tu les a charger normalement et - // donc il sont dans ta liste ! + // this is not necessary at all, because you have loaded them normally, + // and so they already are in your list! #if 0 //Hurdler: 25/04/2000: now support colormap in hardware mode FTextureInfo *tmp = gr_cachehead->nextskin; @@ -1296,11 +1296,11 @@ EXPORT void HWRAPI(SetTexture) (FTextureInfo *pTexInfo) pTexInfo->nextmipmap = NULL; if (gr_cachetail) - { // insertion en fin de liste + { // insertion at the tail gr_cachetail->nextmipmap = pTexInfo; gr_cachetail = pTexInfo; } - else // initialisation de la liste + else // initialization of the linked list gr_cachetail = gr_cachehead = pTexInfo; } } From 0cad5021a99f0bfa3f742ef324d510cfb3bb93ab Mon Sep 17 00:00:00 2001 From: fickleheart Date: Sun, 8 Dec 2019 18:26:20 -0600 Subject: [PATCH 073/746] Make input turn slow down when moving slowly --- 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 5f34846b6..f5bc56e1c 100644 --- a/src/g_game.c +++ b/src/g_game.c @@ -1386,7 +1386,7 @@ void G_BuildTiccmd(ticcmd_t *cmd, INT32 realtics, UINT8 ssplayer) fixed_t camadjustfactor = cv_cam_turnfacinginput[forplayer].value; //@TODO cvar if (camadjustfactor) - *myangle -= cmd->sidemove * 50 * camadjustfactor; + *myangle -= cmd->sidemove * min(50, player->speed / (FRACUNIT/7)) * camadjustfactor; } if (abilitydirection && camera.chase && !player->climbing && !forcestrafe && (player->pflags & PF_DIRECTIONCHAR)) From c6769e72205a5e5d1ff579c8a1ec422d3d0dfee2 Mon Sep 17 00:00:00 2001 From: Jaime Passos Date: Sun, 8 Dec 2019 22:12:56 -0300 Subject: [PATCH 074/746] Die --- src/hardware/hw_cache.c | 9 +------- src/hardware/hw_drv.h | 4 ++-- src/hardware/hw_main.h | 3 --- src/hardware/r_opengl/ogl_win.c | 8 +++---- src/m_menu.c | 37 +-------------------------------- src/r_main.c | 3 --- src/sdl/ogl_sdl.c | 12 +++++------ src/sdl/ogl_sdl.h | 2 +- src/v_video.c | 19 +---------------- src/win32/win_dll.c | 4 ++-- 10 files changed, 17 insertions(+), 84 deletions(-) diff --git a/src/hardware/hw_cache.c b/src/hardware/hw_cache.c index aef97e817..44fc7600e 100644 --- a/src/hardware/hw_cache.c +++ b/src/hardware/hw_cache.c @@ -863,14 +863,7 @@ void HWR_LoadTextures(size_t pnumtextures) void HWR_SetPalette(RGBA_t *palette) { - //Hudler: 16/10/99: added for OpenGL gamma correction - RGBA_t gamma_correction = {0x7F7F7F7F}; - - //Hurdler 16/10/99: added for OpenGL gamma correction - gamma_correction.s.red = (UINT8)cv_grgammared.value; - gamma_correction.s.green = (UINT8)cv_grgammagreen.value; - gamma_correction.s.blue = (UINT8)cv_grgammablue.value; - HWD.pfnSetPalette(palette, &gamma_correction); + HWD.pfnSetPalette(palette); // hardware driver will flush there own cache if cache is non paletized // now flush data texture cache so 32 bit texture are recomputed diff --git a/src/hardware/hw_drv.h b/src/hardware/hw_drv.h index aed1611f1..3e9f149ca 100644 --- a/src/hardware/hw_drv.h +++ b/src/hardware/hw_drv.h @@ -40,9 +40,9 @@ EXPORT void HWRAPI(Shutdown) (void); EXPORT void HWRAPI(GetModeList) (vmode_t **pvidmodes, INT32 *numvidmodes); #endif #if defined (PURESDL) || defined (macintosh) -EXPORT void HWRAPI(SetPalette) (INT32 *, RGBA_t *gamma); +EXPORT void HWRAPI(SetPalette) (INT32 *); #else -EXPORT void HWRAPI(SetPalette) (RGBA_t *ppal, RGBA_t *pgamma); +EXPORT void HWRAPI(SetPalette) (RGBA_t *ppal); #endif EXPORT void HWRAPI(FinishUpdate) (INT32 waitvbl); EXPORT void HWRAPI(Draw2DLine) (F2DCoord *v1, F2DCoord *v2, RGBA_t Color); diff --git a/src/hardware/hw_main.h b/src/hardware/hw_main.h index 3ff7e98c9..96ff62cff 100644 --- a/src/hardware/hw_main.h +++ b/src/hardware/hw_main.h @@ -89,9 +89,6 @@ extern consvar_t cv_grfog; extern consvar_t cv_grfogcolor; extern consvar_t cv_grfogdensity; extern consvar_t cv_grsoftwarefog; -extern consvar_t cv_grgammared; -extern consvar_t cv_grgammagreen; -extern consvar_t cv_grgammablue; extern consvar_t cv_grfiltermode; extern consvar_t cv_granisotropicmode; extern consvar_t cv_grcorrecttricks; diff --git a/src/hardware/r_opengl/ogl_win.c b/src/hardware/r_opengl/ogl_win.c index 562afe998..90376f276 100644 --- a/src/hardware/r_opengl/ogl_win.c +++ b/src/hardware/r_opengl/ogl_win.c @@ -564,15 +564,15 @@ EXPORT void HWRAPI(FinishUpdate) (INT32 waitvbl) // : in OpenGL, we store values for conversion of paletted graphics when // : they are downloaded to the 3D card. // -----------------+ -EXPORT void HWRAPI(SetPalette) (RGBA_t *pal, RGBA_t *gamma) +EXPORT void HWRAPI(SetPalette) (RGBA_t *pal) { INT32 i; for (i = 0; i < 256; i++) { - myPaletteData[i].s.red = (UINT8)MIN((pal[i].s.red*gamma->s.red)/127, 255); - myPaletteData[i].s.green = (UINT8)MIN((pal[i].s.green*gamma->s.green)/127, 255); - myPaletteData[i].s.blue = (UINT8)MIN((pal[i].s.blue*gamma->s.blue)/127, 255); + myPaletteData[i].s.red = pal[i].s.red; + myPaletteData[i].s.green = pal[i].s.green; + myPaletteData[i].s.blue = pal[i].s.blue; myPaletteData[i].s.alpha = pal[i].s.alpha; } diff --git a/src/m_menu.c b/src/m_menu.c index e367041e0..8ed85f501 100644 --- a/src/m_menu.c +++ b/src/m_menu.c @@ -309,7 +309,7 @@ static void M_ChangeControl(INT32 choice); // Video & Sound menu_t OP_VideoOptionsDef, OP_VideoModeDef, OP_ColorOptionsDef; #ifdef HWRENDER -menu_t OP_OpenGLOptionsDef, OP_OpenGLFogDef, OP_OpenGLColorDef; +menu_t OP_OpenGLOptionsDef, OP_OpenGLFogDef; #endif menu_t OP_SoundOptionsDef; menu_t OP_SoundAdvancedDef; @@ -355,7 +355,6 @@ static void M_DrawScreenshotMenu(void); static void M_DrawMonitorToggles(void); #ifdef HWRENDER static void M_OGL_DrawFogMenu(void); -static void M_OGL_DrawColorMenu(void); #endif #ifndef NONET static void M_DrawScreenshotMenu(void); @@ -1314,7 +1313,6 @@ static menuitem_t OP_OpenGLOptionsMenu[] = {IT_SUBMENU|IT_STRING, NULL, "Lighting...", &OP_OpenGLLightingDef, 100}, #endif {IT_SUBMENU|IT_STRING, NULL, "Fog...", &OP_OpenGLFogDef, 110}, - {IT_SUBMENU|IT_STRING, NULL, "Gamma...", &OP_OpenGLColorDef, 120}, }; #ifdef ALAM_LIGHTING @@ -1334,13 +1332,6 @@ static menuitem_t OP_OpenGLFogMenu[] = {IT_STRING|IT_CVAR, NULL, "Fog density", &cv_grfogdensity, 30}, {IT_STRING|IT_CVAR, NULL, "Software Fog",&cv_grsoftwarefog,40}, }; - -static menuitem_t OP_OpenGLColorMenu[] = -{ - {IT_STRING|IT_CVAR|IT_CV_SLIDER, NULL, "red", &cv_grgammared, 10}, - {IT_STRING|IT_CVAR|IT_CV_SLIDER, NULL, "green", &cv_grgammagreen, 20}, - {IT_STRING|IT_CVAR|IT_CV_SLIDER, NULL, "blue", &cv_grgammablue, 30}, -}; #endif static menuitem_t OP_SoundOptionsMenu[] = @@ -2027,18 +2018,6 @@ menu_t OP_OpenGLFogDef = 0, NULL }; -menu_t OP_OpenGLColorDef = -{ - MN_OP_MAIN + (MN_OP_VIDEO << 6) + (MN_OP_OPENGL << 12) + (MN_OP_OPENGL_COLOR << 18), - "M_VIDEO", - sizeof (OP_OpenGLColorMenu)/sizeof (menuitem_t), - &OP_OpenGLOptionsDef, - OP_OpenGLColorMenu, - M_OGL_DrawColorMenu, - 60, 40, - 0, - NULL -}; #endif menu_t OP_DataOptionsDef = DEFAULTMENUSTYLE( MN_OP_MAIN + (MN_OP_DATA << 6), @@ -11931,20 +11910,6 @@ static void M_OGL_DrawFogMenu(void) my + currentMenu->menuitems[FOG_COLOR_ITEM].alphaKey, '_' | 0x80,false); } -// ===================== -// M_OGL_DrawColorMenu() -// ===================== -static void M_OGL_DrawColorMenu(void) -{ - INT32 mx, my; - - mx = currentMenu->x; - my = currentMenu->y; - M_DrawGenericMenu(); // use generic drawer for cursor, items and title - V_DrawString(mx, my + currentMenu->menuitems[0].alphaKey - 10, - V_YELLOWMAP, "Gamma correction"); -} - //=================== // M_HandleFogColor() //=================== diff --git a/src/r_main.c b/src/r_main.c index dd1243868..541360025 100644 --- a/src/r_main.c +++ b/src/r_main.c @@ -1211,9 +1211,6 @@ void R_RegisterEngineStuff(void) #ifdef HWRENDER // GL-specific Commands - CV_RegisterVar(&cv_grgammablue); - CV_RegisterVar(&cv_grgammagreen); - CV_RegisterVar(&cv_grgammared); CV_RegisterVar(&cv_grfovchange); CV_RegisterVar(&cv_grfog); CV_RegisterVar(&cv_grfogcolor); diff --git a/src/sdl/ogl_sdl.c b/src/sdl/ogl_sdl.c index dd58aa99c..66980f1ad 100644 --- a/src/sdl/ogl_sdl.c +++ b/src/sdl/ogl_sdl.c @@ -222,17 +222,15 @@ void OglSdlFinishUpdate(boolean waitvbl) HWR_DrawScreenFinalTexture(realwidth, realheight); } -EXPORT void HWRAPI( OglSdlSetPalette) (RGBA_t *palette, RGBA_t *pgamma) +EXPORT void HWRAPI( OglSdlSetPalette) (RGBA_t *palette) { - INT32 i = -1; - UINT32 redgamma = pgamma->s.red, greengamma = pgamma->s.green, - bluegamma = pgamma->s.blue; + INT32 i; for (i = 0; i < 256; i++) { - myPaletteData[i].s.red = (UINT8)MIN((palette[i].s.red * redgamma) /127, 255); - myPaletteData[i].s.green = (UINT8)MIN((palette[i].s.green * greengamma)/127, 255); - myPaletteData[i].s.blue = (UINT8)MIN((palette[i].s.blue * bluegamma) /127, 255); + myPaletteData[i].s.red = palette[i].s.red; + myPaletteData[i].s.green = palette[i].s.green; + myPaletteData[i].s.blue = palette[i].s.blue; myPaletteData[i].s.alpha = palette[i].s.alpha; } Flush(); diff --git a/src/sdl/ogl_sdl.h b/src/sdl/ogl_sdl.h index 293c45116..88d7d0b6c 100644 --- a/src/sdl/ogl_sdl.h +++ b/src/sdl/ogl_sdl.h @@ -31,5 +31,5 @@ extern Uint16 realwidth; extern Uint16 realheight; #ifdef _CREATE_DLL_ -EXPORT void HWRAPI( OglSdlSetPalette ) (RGBA_t *palette, RGBA_t *pgamma); +EXPORT void HWRAPI( OglSdlSetPalette ) (RGBA_t *palette); #endif diff --git a/src/v_video.c b/src/v_video.c index 0e741df9f..25cbccee2 100644 --- a/src/v_video.c +++ b/src/v_video.c @@ -85,11 +85,9 @@ static void CV_constextsize_OnChange(void); consvar_t cv_constextsize = {"con_textsize", "Medium", CV_SAVE|CV_CALL, constextsize_cons_t, CV_constextsize_OnChange, 0, NULL, NULL, 0, 0, NULL}; #ifdef HWRENDER -static void CV_Gammaxxx_ONChange(void); // Saved hardware mode variables // - You can change them in software, // but they won't do anything. -static CV_PossibleValue_t grgamma_cons_t[] = {{1, "MIN"}, {255, "MAX"}, {0, NULL}}; static CV_PossibleValue_t grsoftwarefog_cons_t[] = {{0, "Off"}, {1, "On"}, {2, "LightPlanes"}, {0, NULL}}; static CV_PossibleValue_t grmodelinterpolation_cons_t[] = {{0, "Off"}, {1, "Sometimes"}, {2, "Always"}, {0, NULL}}; @@ -97,12 +95,7 @@ consvar_t cv_grfovchange = {"gr_fovchange", "Off", CV_SAVE, CV_OnOff, NULL, 0, N consvar_t cv_grfog = {"gr_fog", "On", CV_SAVE, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL}; consvar_t cv_grfogcolor = {"gr_fogcolor", "AAAAAA", CV_SAVE, NULL, NULL, 0, NULL, NULL, 0, 0, NULL}; consvar_t cv_grsoftwarefog = {"gr_softwarefog", "Off", CV_SAVE, grsoftwarefog_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL}; -consvar_t cv_grgammared = {"gr_gammared", "127", CV_SAVE|CV_CALL, grgamma_cons_t, - CV_Gammaxxx_ONChange, 0, NULL, NULL, 0, 0, NULL}; -consvar_t cv_grgammagreen = {"gr_gammagreen", "127", CV_SAVE|CV_CALL, grgamma_cons_t, - CV_Gammaxxx_ONChange, 0, NULL, NULL, 0, 0, NULL}; -consvar_t cv_grgammablue = {"gr_gammablue", "127", CV_SAVE|CV_CALL, grgamma_cons_t, - CV_Gammaxxx_ONChange, 0, NULL, NULL, 0, 0, NULL}; + #ifdef ALAM_LIGHTING consvar_t cv_grdynamiclighting = {"gr_dynamiclighting", "On", CV_SAVE, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL}; consvar_t cv_grstaticlighting = {"gr_staticlighting", "On", CV_SAVE, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL}; @@ -473,16 +466,6 @@ static void CV_palette_OnChange(void) V_SetPalette(0); } -// change the palette directly to see the change -#ifdef HWRENDER -static void CV_Gammaxxx_ONChange(void) -{ - if (rendermode != render_soft && rendermode != render_none) - V_SetPalette(0); -} -#endif - - #if defined (__GNUC__) && defined (__i386__) && !defined (NOASM) && !defined (__APPLE__) && !defined (NORUSEASM) void VID_BlitLinearScreen_ASM(const UINT8 *srcptr, UINT8 *destptr, INT32 width, INT32 height, size_t srcrowbytes, size_t destrowbytes); diff --git a/src/win32/win_dll.c b/src/win32/win_dll.c index 5378bb52f..986eb32dc 100644 --- a/src/win32/win_dll.c +++ b/src/win32/win_dll.c @@ -98,7 +98,7 @@ static loadfunc_t hwdFuncTable[] = { {"Init@4", &hwdriver.pfnInit}, {"Shutdown@0", &hwdriver.pfnShutdown}, {"GetModeList@8", &hwdriver.pfnGetModeList}, - {"SetPalette@8", &hwdriver.pfnSetPalette}, + {"SetPalette@4", &hwdriver.pfnSetPalette}, {"FinishUpdate@4", &hwdriver.pfnFinishUpdate}, {"Draw2DLine@12", &hwdriver.pfnDraw2DLine}, {"DrawPolygon@16", &hwdriver.pfnDrawPolygon}, @@ -110,7 +110,7 @@ static loadfunc_t hwdFuncTable[] = { {"GClipRect@20", &hwdriver.pfnGClipRect}, {"ClearMipMapCache@0", &hwdriver.pfnClearMipMapCache}, {"SetSpecialState@8", &hwdriver.pfnSetSpecialState}, - {"DrawModel@16", &hwdriver.pfnDrawModel}, + {"DrawModel@16", &hwdriver.pfnDrawModel}, {"SetTransform@4", &hwdriver.pfnSetTransform}, {"GetTextureUsed@0", &hwdriver.pfnGetTextureUsed}, {"GetRenderVersion@0", &hwdriver.pfnGetRenderVersion}, From 5c02bc59dbd6670a6100035e8dbd10f4e1ac7198 Mon Sep 17 00:00:00 2001 From: Jaime Passos Date: Sun, 8 Dec 2019 22:28:13 -0300 Subject: [PATCH 075/746] Speed up level loading Don't flush every texture just because the palette MAY have changed --- src/hardware/r_opengl/ogl_win.c | 17 ++++++----------- src/sdl/ogl_sdl.c | 13 +++++-------- 2 files changed, 11 insertions(+), 19 deletions(-) diff --git a/src/hardware/r_opengl/ogl_win.c b/src/hardware/r_opengl/ogl_win.c index 90376f276..e4a71734b 100644 --- a/src/hardware/r_opengl/ogl_win.c +++ b/src/hardware/r_opengl/ogl_win.c @@ -566,18 +566,13 @@ EXPORT void HWRAPI(FinishUpdate) (INT32 waitvbl) // -----------------+ EXPORT void HWRAPI(SetPalette) (RGBA_t *pal) { - INT32 i; - - for (i = 0; i < 256; i++) - { - myPaletteData[i].s.red = pal[i].s.red; - myPaletteData[i].s.green = pal[i].s.green; - myPaletteData[i].s.blue = pal[i].s.blue; - myPaletteData[i].s.alpha = pal[i].s.alpha; - } - + size_t palsize = (sizeof(RGBA_t) * 256); // on a palette change, you have to reload all of the textures - Flush(); + if (memcmp(&myPaletteData, pal, palsize)) + { + memcpy(&myPaletteData, pal, palsize); + Flush(); + } } #endif diff --git a/src/sdl/ogl_sdl.c b/src/sdl/ogl_sdl.c index 66980f1ad..6c0dd35a5 100644 --- a/src/sdl/ogl_sdl.c +++ b/src/sdl/ogl_sdl.c @@ -224,16 +224,13 @@ void OglSdlFinishUpdate(boolean waitvbl) EXPORT void HWRAPI( OglSdlSetPalette) (RGBA_t *palette) { - INT32 i; - - for (i = 0; i < 256; i++) + size_t palsize = (sizeof(RGBA_t) * 256); + // on a palette change, you have to reload all of the textures + if (memcmp(&myPaletteData, palette, palsize)) { - myPaletteData[i].s.red = palette[i].s.red; - myPaletteData[i].s.green = palette[i].s.green; - myPaletteData[i].s.blue = palette[i].s.blue; - myPaletteData[i].s.alpha = palette[i].s.alpha; + memcpy(&myPaletteData, palette, palsize); + Flush(); } - Flush(); } #endif //HWRENDER From 4d83db5bb2e4e61f643a83b265fca8dd4e3c1027 Mon Sep 17 00:00:00 2001 From: Jaime Passos Date: Sun, 8 Dec 2019 22:31:59 -0300 Subject: [PATCH 076/746] Die, Apple! --- src/hardware/hw_drv.h | 4 ---- 1 file changed, 4 deletions(-) diff --git a/src/hardware/hw_drv.h b/src/hardware/hw_drv.h index 3e9f149ca..3314fb015 100644 --- a/src/hardware/hw_drv.h +++ b/src/hardware/hw_drv.h @@ -39,11 +39,7 @@ EXPORT void HWRAPI(Shutdown) (void); #ifdef _WINDOWS EXPORT void HWRAPI(GetModeList) (vmode_t **pvidmodes, INT32 *numvidmodes); #endif -#if defined (PURESDL) || defined (macintosh) -EXPORT void HWRAPI(SetPalette) (INT32 *); -#else EXPORT void HWRAPI(SetPalette) (RGBA_t *ppal); -#endif EXPORT void HWRAPI(FinishUpdate) (INT32 waitvbl); EXPORT void HWRAPI(Draw2DLine) (F2DCoord *v1, F2DCoord *v2, RGBA_t Color); EXPORT void HWRAPI(DrawPolygon) (FSurfaceInfo *pSurf, FOutVector *pOutVerts, FUINT iNumPts, FBITFIELD PolyFlags); From c99b137298c7d3530b6039f68038459fdd5a261a Mon Sep 17 00:00:00 2001 From: fickleheart Date: Sun, 8 Dec 2019 20:47:11 -0600 Subject: [PATCH 077/746] Fix abilitydirection camera breaking minecarts --- src/g_game.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/g_game.c b/src/g_game.c index f5bc56e1c..b6d765693 100644 --- a/src/g_game.c +++ b/src/g_game.c @@ -1381,7 +1381,7 @@ void G_BuildTiccmd(ticcmd_t *cmd, INT32 realtics, UINT8 ssplayer) cmd->angleturn = (INT16)(*myangle >> 16); // Adjust camera angle by player input - if (!forcestrafe && camera.chase && !turnheld[forplayer] && !player->climbing) + if (!forcestrafe && camera.chase && !turnheld[forplayer] && !player->climbing && player->powers[pw_carry] != CR_MINECART) { fixed_t camadjustfactor = cv_cam_turnfacinginput[forplayer].value; //@TODO cvar @@ -1389,7 +1389,7 @@ void G_BuildTiccmd(ticcmd_t *cmd, INT32 realtics, UINT8 ssplayer) *myangle -= cmd->sidemove * min(50, player->speed / (FRACUNIT/7)) * camadjustfactor; } - if (abilitydirection && camera.chase && !player->climbing && !forcestrafe && (player->pflags & PF_DIRECTIONCHAR)) + if (abilitydirection && camera.chase && !player->climbing && !forcestrafe && (player->pflags & PF_DIRECTIONCHAR) && player->powers[pw_carry] != CR_MINECART) { if (cmd->forwardmove || cmd->sidemove) { @@ -1407,7 +1407,7 @@ void G_BuildTiccmd(ticcmd_t *cmd, INT32 realtics, UINT8 ssplayer) // Adjust camera angle to face player direction, depending on circumstances // Nothing happens if cam left/right are held, so you can hold both to lock the camera in one direction - if (!forcestrafe && camera.chase && !turnheld[forplayer]) + if (!forcestrafe && camera.chase && !turnheld[forplayer] && player->powers[pw_carry] != CR_MINECART) { fixed_t camadjustfactor; From 8ea7dd418a917d2677356d49c1e456567b1aa1ca Mon Sep 17 00:00:00 2001 From: Nev3r Date: Mon, 9 Dec 2019 13:26:31 +0100 Subject: [PATCH 078/746] Move the axis spawning code out of the mapthing read function, and read the mapthing z in the mapthing read function. --- src/p_setup.c | 55 ++++++++++++++++++++++++--------------------------- 1 file changed, 26 insertions(+), 29 deletions(-) diff --git a/src/p_setup.c b/src/p_setup.c index 3c45509ee..552617dbd 100644 --- a/src/p_setup.c +++ b/src/p_setup.c @@ -1009,35 +1009,27 @@ void P_ScanThings(INT16 mapnum, INT16 wadnum, INT16 lumpnum) static void P_PrepareRawThings(UINT8 *data, size_t i) { mapthing_t *mt; + sector_t *mtsector; nummapthings = i / (5 * sizeof (INT16)); mapthings = Z_Calloc(nummapthings * sizeof (*mapthings), PU_LEVEL, NULL); - // Spawn axis points first so they are - // at the front of the list for fast searching. - mt = mapthings; - for (i = 0; i < nummapthings; i++, mt++) + for (i = 0, mt = mapthings; i < nummapthings; i++, mt++) { mt->x = READINT16(data); mt->y = READINT16(data); + // Z for objects + mtsector = R_PointInSubsector(mt->x << FRACBITS, mt->y << FRACBITS)->sector; + mt->z = (INT16)( +#ifdef ESLOPE + mtsector->f_slope ? P_GetZAt(mtsector->f_slope, mt->x << FRACBITS, mt->y << FRACBITS) : +#endif + mtsector->floorheight)>>FRACBITS; mt->angle = READINT16(data); mt->type = READUINT16(data); mt->options = READUINT16(data); mt->extrainfo = (UINT8)(mt->type >> 12); - mt->type &= 4095; - - switch (mt->type) - { - case 1700: // MT_AXIS - case 1701: // MT_AXISTRANSFER - case 1702: // MT_AXISTRANSFERLINE - mt->mobj = NULL; - P_SpawnMapThing(mt); - break; - default: - break; - } } } @@ -1053,21 +1045,26 @@ static void P_LoadThings(boolean loademblems) size_t i; mapthing_t *mt; - // Loading the things lump itself into memory is now handled in P_PrepareThings, above - - mt = mapthings; - numhuntemeralds = 0; - for (i = 0; i < nummapthings; i++, mt++) + // Spawn axis points first so they are at the front of the list for fast searching. + for (i = 0, mt = mapthings; i < nummapthings; i++, mt++) { - sector_t *mtsector = R_PointInSubsector(mt->x << FRACBITS, mt->y << FRACBITS)->sector; + switch (mt->type) + { + case 1700: // MT_AXIS + case 1701: // MT_AXISTRANSFER + case 1702: // MT_AXISTRANSFERLINE + mt->mobj = NULL; + P_SpawnMapThing(mt); + break; + default: + break; + } + } - // Z for objects - mt->z = (INT16)( -#ifdef ESLOPE - mtsector->f_slope ? P_GetZAt(mtsector->f_slope, mt->x << FRACBITS, mt->y << FRACBITS) : -#endif - mtsector->floorheight)>>FRACBITS; + numhuntemeralds = 0; + for (i = 0, mt = mapthings; i < nummapthings; i++, mt++) + { if (mt->type == 1700 // MT_AXIS || mt->type == 1701 // MT_AXISTRANSFER || mt->type == 1702) // MT_AXISTRANSFERLINE From 6fe6db8e18dbe2907680e5d9c7805fc946679c29 Mon Sep 17 00:00:00 2001 From: Nev3r Date: Mon, 9 Dec 2019 14:05:22 +0100 Subject: [PATCH 079/746] Removed seemingly redundant (and incorrect) mapthing Z load code. The proper code seems to sit inside P_SpawnMapThing() and the SpawnHoop functions. Time will tell if I've actually commited an atrocity. --- src/p_setup.c | 15 ++------------- 1 file changed, 2 insertions(+), 13 deletions(-) diff --git a/src/p_setup.c b/src/p_setup.c index 552617dbd..d082e95b2 100644 --- a/src/p_setup.c +++ b/src/p_setup.c @@ -1009,7 +1009,6 @@ void P_ScanThings(INT16 mapnum, INT16 wadnum, INT16 lumpnum) static void P_PrepareRawThings(UINT8 *data, size_t i) { mapthing_t *mt; - sector_t *mtsector; nummapthings = i / (5 * sizeof (INT16)); mapthings = Z_Calloc(nummapthings * sizeof (*mapthings), PU_LEVEL, NULL); @@ -1018,13 +1017,8 @@ static void P_PrepareRawThings(UINT8 *data, size_t i) { mt->x = READINT16(data); mt->y = READINT16(data); - // Z for objects - mtsector = R_PointInSubsector(mt->x << FRACBITS, mt->y << FRACBITS)->sector; - mt->z = (INT16)( -#ifdef ESLOPE - mtsector->f_slope ? P_GetZAt(mtsector->f_slope, mt->x << FRACBITS, mt->y << FRACBITS) : -#endif - mtsector->floorheight)>>FRACBITS; + mt->z = 0; + mt->angle = READINT16(data); mt->type = READUINT16(data); mt->options = READUINT16(data); @@ -1137,11 +1131,6 @@ static void P_LoadThings(boolean loademblems) || mt->type == 1705 || mt->type == 1713) // hoops { mt->mobj = NULL; - - // Z for objects Tails 05-26-2002 - mt->z = (INT16)(R_PointInSubsector(mt->x << FRACBITS, mt->y << FRACBITS) - ->sector->floorheight>>FRACBITS); - P_SpawnHoopsAndRings(mt, false); } } From 4f9e227830be54010f8cdb55ade67a67d360f56a Mon Sep 17 00:00:00 2001 From: James R Date: Mon, 9 Dec 2019 16:30:03 -0800 Subject: [PATCH 080/746] Cvar and menu option to let user increase turn speed cam_turnmultiplier and cam2_turnmultiplier. "Camera Speed" has been renamed to "Camera Spacial Speed" in the menu. "Camera Turning Speed" is now an option. --- src/g_game.c | 13 +++++++------ src/m_menu.c | 6 ++++-- src/p_local.h | 4 ++-- src/p_user.c | 3 +++ src/r_main.c | 2 ++ 5 files changed, 18 insertions(+), 10 deletions(-) diff --git a/src/g_game.c b/src/g_game.c index 2a12dd298..ebc54ba78 100644 --- a/src/g_game.c +++ b/src/g_game.c @@ -1090,14 +1090,14 @@ void G_BuildTiccmd(ticcmd_t *cmd, INT32 realtics) else { if (turnright) - cmd->angleturn = (INT16)(cmd->angleturn - angleturn[tspeed]); + cmd->angleturn = (INT16)(cmd->angleturn - (FixedMul(angleturn[tspeed]<>FRACBITS)); else if (turnleft) - cmd->angleturn = (INT16)(cmd->angleturn + angleturn[tspeed]); + cmd->angleturn = (INT16)(cmd->angleturn + (FixedMul(angleturn[tspeed]<>FRACBITS)); if (analogjoystickmove && axis != 0) { // JOYAXISRANGE should be 1023 (divide by 1024) - cmd->angleturn = (INT16)(cmd->angleturn - ((axis * angleturn[1]) >> 10)); // ANALOG! + cmd->angleturn = (INT16)(cmd->angleturn - (FixedMul(((axis * angleturn[1]) >> 10)<>FRACBITS)); // ANALOG! } } @@ -1420,14 +1420,14 @@ void G_BuildTiccmd2(ticcmd_t *cmd, INT32 realtics) else { if (turnright) - cmd->angleturn = (INT16)(cmd->angleturn - angleturn[tspeed]); + cmd->angleturn = (INT16)(cmd->angleturn - (FixedMul(angleturn[tspeed]<>FRACBITS)); else if (turnleft) - cmd->angleturn = (INT16)(cmd->angleturn + angleturn[tspeed]); + cmd->angleturn = (INT16)(cmd->angleturn + (FixedMul(angleturn[tspeed]<>FRACBITS)); if (analogjoystickmove && axis != 0) { // JOYAXISRANGE should be 1023 (divide by 1024) - cmd->angleturn = (INT16)(cmd->angleturn - ((axis * angleturn[1]) >> 10)); // ANALOG! + cmd->angleturn = (INT16)(cmd->angleturn - (FixedMul(((axis * angleturn[1]) >> 10)<>FRACBITS)); // ANALOG! } } @@ -3652,6 +3652,7 @@ void G_LoadGameData(void) { rtemp = READUINT8(save_p); for (j = 0; j < 8 && j+i < MAXUNLOCKABLES; ++j) + //unlockables[j+i].unlocked = ((rtemp >> j) & 1); unlockables[j+i].unlocked = ((rtemp >> j) & 1); i += j; } diff --git a/src/m_menu.c b/src/m_menu.c index e367041e0..290aced86 100644 --- a/src/m_menu.c +++ b/src/m_menu.c @@ -1178,7 +1178,8 @@ static menuitem_t OP_CameraOptionsMenu[] = {IT_STRING | IT_CVAR | IT_CV_INTEGERSTEP, NULL, "Camera Distance", &cv_cam_dist, 60}, {IT_STRING | IT_CVAR | IT_CV_INTEGERSTEP, NULL, "Camera Height", &cv_cam_height, 70}, - {IT_STRING | IT_CVAR | IT_CV_FLOATSLIDER, NULL, "Camera Speed", &cv_cam_speed, 80}, + {IT_STRING | IT_CVAR | IT_CV_FLOATSLIDER, NULL, "Camera Spacial Speed", &cv_cam_speed, 80}, + {IT_STRING | IT_CVAR | IT_CV_FLOATSLIDER, NULL, "Camera Turning Speed", &cv_cam_turnmultiplier, 90}, {IT_STRING | IT_CVAR, NULL, "Crosshair", &cv_crosshair, 100}, }; @@ -1192,7 +1193,8 @@ static menuitem_t OP_Camera2OptionsMenu[] = {IT_STRING | IT_CVAR | IT_CV_INTEGERSTEP, NULL, "Camera Distance", &cv_cam2_dist, 60}, {IT_STRING | IT_CVAR | IT_CV_INTEGERSTEP, NULL, "Camera Height", &cv_cam2_height, 70}, - {IT_STRING | IT_CVAR | IT_CV_FLOATSLIDER, NULL, "Camera Speed", &cv_cam2_speed, 80}, + {IT_STRING | IT_CVAR | IT_CV_FLOATSLIDER, NULL, "Camera Spacial Speed", &cv_cam2_speed, 80}, + {IT_STRING | IT_CVAR | IT_CV_FLOATSLIDER, NULL, "Camera Turning Speed", &cv_cam2_turnmultiplier, 90}, {IT_STRING | IT_CVAR, NULL, "Crosshair", &cv_crosshair2, 100}, }; diff --git a/src/p_local.h b/src/p_local.h index 286d7201f..88deb0942 100644 --- a/src/p_local.h +++ b/src/p_local.h @@ -115,10 +115,10 @@ typedef struct camera_s extern camera_t camera, camera2; extern consvar_t cv_cam_dist, cv_cam_still, cv_cam_height; -extern consvar_t cv_cam_speed, cv_cam_rotate, cv_cam_rotspeed, cv_cam_orbit, cv_cam_adjust; +extern consvar_t cv_cam_speed, cv_cam_rotate, cv_cam_rotspeed, cv_cam_turnmultiplier, cv_cam_orbit, cv_cam_adjust; extern consvar_t cv_cam2_dist, cv_cam2_still, cv_cam2_height; -extern consvar_t cv_cam2_speed, cv_cam2_rotate, cv_cam2_rotspeed, cv_cam2_orbit, cv_cam2_adjust; +extern consvar_t cv_cam2_speed, cv_cam2_rotate, cv_cam2_rotspeed, cv_cam2_turnmultiplier, cv_cam2_orbit, cv_cam2_adjust; extern fixed_t t_cam_dist, t_cam_height, t_cam_rotate; extern fixed_t t_cam2_dist, t_cam2_height, t_cam2_rotate; diff --git a/src/p_user.c b/src/p_user.c index ea42a2c36..20fbc99f4 100644 --- a/src/p_user.c +++ b/src/p_user.c @@ -9589,6 +9589,7 @@ static void CV_CamRotate2_OnChange(void) static CV_PossibleValue_t CV_CamSpeed[] = {{0, "MIN"}, {1*FRACUNIT, "MAX"}, {0, NULL}}; static CV_PossibleValue_t rotation_cons_t[] = {{1, "MIN"}, {45, "MAX"}, {0, NULL}}; static CV_PossibleValue_t CV_CamRotate[] = {{-720, "MIN"}, {720, "MAX"}, {0, NULL}}; +static CV_PossibleValue_t multiplier_cons_t[] = {{0, "MIN"}, {3*FRACUNIT, "MAX"}, {0, NULL}}; consvar_t cv_cam_dist = {"cam_dist", "160", CV_FLOAT|CV_SAVE, NULL, NULL, 0, NULL, NULL, 0, 0, NULL}; consvar_t cv_cam_height = {"cam_height", "25", CV_FLOAT|CV_SAVE, NULL, NULL, 0, NULL, NULL, 0, 0, NULL}; @@ -9596,6 +9597,7 @@ consvar_t cv_cam_still = {"cam_still", "Off", 0, CV_OnOff, NULL, 0, NULL, NULL, consvar_t cv_cam_speed = {"cam_speed", "0.3", CV_FLOAT|CV_SAVE, CV_CamSpeed, NULL, 0, NULL, NULL, 0, 0, NULL}; consvar_t cv_cam_rotate = {"cam_rotate", "0", CV_CALL|CV_NOINIT, CV_CamRotate, CV_CamRotate_OnChange, 0, NULL, NULL, 0, 0, NULL}; consvar_t cv_cam_rotspeed = {"cam_rotspeed", "10", CV_SAVE, rotation_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL}; +consvar_t cv_cam_turnmultiplier = {"cam_turnmultiplier", "1.0", CV_FLOAT|CV_SAVE, multiplier_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL}; consvar_t cv_cam_orbit = {"cam_orbit", "Off", CV_SAVE, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL}; consvar_t cv_cam_adjust = {"cam_adjust", "On", CV_SAVE, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL}; consvar_t cv_cam2_dist = {"cam2_dist", "160", CV_FLOAT|CV_SAVE, NULL, NULL, 0, NULL, NULL, 0, 0, NULL}; @@ -9604,6 +9606,7 @@ consvar_t cv_cam2_still = {"cam2_still", "Off", 0, CV_OnOff, NULL, 0, NULL, NULL consvar_t cv_cam2_speed = {"cam2_speed", "0.3", CV_FLOAT|CV_SAVE, CV_CamSpeed, NULL, 0, NULL, NULL, 0, 0, NULL}; consvar_t cv_cam2_rotate = {"cam2_rotate", "0", CV_CALL|CV_NOINIT, CV_CamRotate, CV_CamRotate2_OnChange, 0, NULL, NULL, 0, 0, NULL}; consvar_t cv_cam2_rotspeed = {"cam2_rotspeed", "10", CV_SAVE, rotation_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL}; +consvar_t cv_cam2_turnmultiplier = {"cam2_turnmultiplier", "1.0", CV_FLOAT|CV_SAVE, multiplier_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL}; consvar_t cv_cam2_orbit = {"cam2_orbit", "Off", CV_SAVE, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL}; consvar_t cv_cam2_adjust = {"cam2_adjust", "On", CV_SAVE, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL}; diff --git a/src/r_main.c b/src/r_main.c index dd1243868..e8467eb29 100644 --- a/src/r_main.c +++ b/src/r_main.c @@ -1190,6 +1190,7 @@ void R_RegisterEngineStuff(void) CV_RegisterVar(&cv_cam_speed); CV_RegisterVar(&cv_cam_rotate); CV_RegisterVar(&cv_cam_rotspeed); + CV_RegisterVar(&cv_cam_turnmultiplier); CV_RegisterVar(&cv_cam_orbit); CV_RegisterVar(&cv_cam_adjust); @@ -1199,6 +1200,7 @@ void R_RegisterEngineStuff(void) CV_RegisterVar(&cv_cam2_speed); CV_RegisterVar(&cv_cam2_rotate); CV_RegisterVar(&cv_cam2_rotspeed); + CV_RegisterVar(&cv_cam2_turnmultiplier); CV_RegisterVar(&cv_cam2_orbit); CV_RegisterVar(&cv_cam2_adjust); From e4626e93965cb756ddf91fc7433ee889d248036b Mon Sep 17 00:00:00 2001 From: fickleheart Date: Mon, 9 Dec 2019 20:21:32 -0600 Subject: [PATCH 081/746] Lock camera behind player when holding cam reset This also disables abilitydirection movement temporarily. --- src/g_game.c | 18 +++++++++++------- src/g_game.h | 2 ++ src/p_user.c | 17 +++++++++++++++-- 3 files changed, 28 insertions(+), 9 deletions(-) diff --git a/src/g_game.c b/src/g_game.c index b6d765693..13396a3a0 100644 --- a/src/g_game.c +++ b/src/g_game.c @@ -1006,6 +1006,7 @@ static fixed_t forwardmove[2] = {25<>16, 50<>16}; static fixed_t sidemove[2] = {25<>16, 50<>16}; // faster! static fixed_t angleturn[3] = {640, 1280, 320}; // + slow turn +boolean ticcmd_resetdown[2]; // don't cam reset every frame void G_BuildTiccmd(ticcmd_t *cmd, INT32 realtics, UINT8 ssplayer) { boolean forcestrafe = false; @@ -1024,7 +1025,6 @@ void G_BuildTiccmd(ticcmd_t *cmd, INT32 realtics, UINT8 ssplayer) static INT32 turnheld[2]; // for accelerative turning static boolean keyboard_look[2]; // true if lookup/down using keyboard - static boolean resetdown[2]; // don't cam reset every frame static boolean joyaiming[2]; // check the last frame's value if we need to reset the camera UINT8 forplayer = ssplayer-1; @@ -1244,12 +1244,16 @@ void G_BuildTiccmd(ticcmd_t *cmd, INT32 realtics, UINT8 ssplayer) if (PLAYERINPUTDOWN(ssplayer, gc_camreset)) { - if (camera.chase && !resetdown[forplayer]) + if (camera.chase && !ticcmd_resetdown[forplayer]) + { + ticcmd_resetdown[forplayer] = true; P_ResetCamera(&players[ssplayer == 1 ? displayplayer : secondarydisplayplayer], &camera); - resetdown[forplayer] = true; + } + else + ticcmd_resetdown[forplayer] = true; } else - resetdown[forplayer] = false; + ticcmd_resetdown[forplayer] = false; // jump button axis = PlayerJoyAxis(ssplayer, AXISJUMP); @@ -1381,7 +1385,7 @@ void G_BuildTiccmd(ticcmd_t *cmd, INT32 realtics, UINT8 ssplayer) cmd->angleturn = (INT16)(*myangle >> 16); // Adjust camera angle by player input - if (!forcestrafe && camera.chase && !turnheld[forplayer] && !player->climbing && player->powers[pw_carry] != CR_MINECART) + if (!forcestrafe && camera.chase && !turnheld[forplayer] && !ticcmd_resetdown[forplayer] && !player->climbing && player->powers[pw_carry] != CR_MINECART) { fixed_t camadjustfactor = cv_cam_turnfacinginput[forplayer].value; //@TODO cvar @@ -1389,7 +1393,7 @@ void G_BuildTiccmd(ticcmd_t *cmd, INT32 realtics, UINT8 ssplayer) *myangle -= cmd->sidemove * min(50, player->speed / (FRACUNIT/7)) * camadjustfactor; } - if (abilitydirection && camera.chase && !player->climbing && !forcestrafe && (player->pflags & PF_DIRECTIONCHAR) && player->powers[pw_carry] != CR_MINECART) + if (abilitydirection && camera.chase && !ticcmd_resetdown[forplayer] && !player->climbing && !forcestrafe && (player->pflags & PF_DIRECTIONCHAR) && player->powers[pw_carry] != CR_MINECART) { if (cmd->forwardmove || cmd->sidemove) { @@ -1407,7 +1411,7 @@ void G_BuildTiccmd(ticcmd_t *cmd, INT32 realtics, UINT8 ssplayer) // Adjust camera angle to face player direction, depending on circumstances // Nothing happens if cam left/right are held, so you can hold both to lock the camera in one direction - if (!forcestrafe && camera.chase && !turnheld[forplayer] && player->powers[pw_carry] != CR_MINECART) + if (!forcestrafe && camera.chase && !turnheld[forplayer] && !ticcmd_resetdown[forplayer] && player->powers[pw_carry] != CR_MINECART) { fixed_t camadjustfactor; diff --git a/src/g_game.h b/src/g_game.h index ea2cd1694..2a030a49d 100644 --- a/src/g_game.h +++ b/src/g_game.h @@ -86,6 +86,8 @@ extern consvar_t cv_abilitydirection[2], cv_cam_shiftfacing[2], cv_cam_turnfacin // build an internal map name MAPxx from map number const char *G_BuildMapName(INT32 map); + +extern boolean ticcmd_resetdown[2]; // don't cam reset every frame void G_BuildTiccmd(ticcmd_t *cmd, INT32 realtics, UINT8 ssplayer); // copy ticcmd_t to and fro the normal way diff --git a/src/p_user.c b/src/p_user.c index 0a3636884..e9297b667 100644 --- a/src/p_user.c +++ b/src/p_user.c @@ -9651,7 +9651,17 @@ void P_ResetCamera(player_t *player, camera_t *thiscam) thiscam->y = y; thiscam->z = z; - if (!(thiscam == &camera && (cv_cam_still.value || cv_analog.value)) + if (thiscam == &camera && cv_abilitydirection[0].value && ticcmd_resetdown[0]) + { + localangle = player->mo->angle; + localaiming = thiscam->aiming = 0; + } + else if (thiscam == &camera2 && cv_abilitydirection[1].value && ticcmd_resetdown[1]) + { + localangle2 = player->mo->angle; + localaiming2 = thiscam->aiming = 0; + } + else if (!(thiscam == &camera && (cv_cam_still.value || cv_analog.value)) && !(thiscam == &camera2 && (cv_cam2_still.value || cv_analog2.value))) { thiscam->angle = player->mo->angle; @@ -9891,7 +9901,10 @@ boolean P_MoveChaseCamera(player_t *player, camera_t *thiscam, boolean resetcall UINT8 forplayer = (thiscam == &camera) ? 0 : 1; fixed_t shift = FixedMul(FINESINE((player->drawangle - angle) >> ANGLETOFINESHIFT), cv_cam_shiftfacing[forplayer].value); - shift += FixedMul(camsideshift[forplayer] - shift, FRACUNIT-(camspeed>>3)); + if (ticcmd_resetdown[(thiscam == &camera) ? 0 : 1]) + shift = FixedMul(camsideshift[forplayer], FRACUNIT-camspeed); + else + shift += FixedMul(camsideshift[forplayer] - shift, FRACUNIT-(camspeed>>3)); camsideshift[forplayer] = shift; shift = FixedMul(shift, camdist); From 27996ada0464f7e1f5331fc38361d1e0d758708d Mon Sep 17 00:00:00 2001 From: fickleheart Date: Mon, 9 Dec 2019 20:26:12 -0600 Subject: [PATCH 082/746] Scale down turn values (and increase defaults to compensate) This allows more granularity in menu sliders while limiting the maximums to reasonable amounts. --- src/g_game.c | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/src/g_game.c b/src/g_game.c index 13396a3a0..6f5ca6383 100644 --- a/src/g_game.c +++ b/src/g_game.c @@ -409,12 +409,12 @@ consvar_t cv_cam_turnfacing[2] = { {"cam2_turnfacingchar", "0.0", CV_FLOAT|CV_SAVE, zerotoone_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL}, }; consvar_t cv_cam_turnfacingability[2] = { - {"cam_turnfacingability", "0.125", CV_FLOAT|CV_SAVE, zerotoone_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL}, - {"cam2_turnfacingability", "0.125", CV_FLOAT|CV_SAVE, zerotoone_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL}, + {"cam_turnfacingability", "0.25", CV_FLOAT|CV_SAVE, zerotoone_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL}, + {"cam2_turnfacingability", "0.25", CV_FLOAT|CV_SAVE, zerotoone_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL}, }; consvar_t cv_cam_turnfacinginput[2] = { - {"cam_turnfacinginput", "0.15", CV_FLOAT|CV_SAVE, zerotoone_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL}, - {"cam2_turnfacinginput", "0.15", CV_FLOAT|CV_SAVE, zerotoone_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL}, + {"cam_turnfacinginput", "0.375", CV_FLOAT|CV_SAVE, zerotoone_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL}, + {"cam2_turnfacinginput", "0.375", CV_FLOAT|CV_SAVE, zerotoone_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL}, }; typedef enum @@ -1390,7 +1390,7 @@ void G_BuildTiccmd(ticcmd_t *cmd, INT32 realtics, UINT8 ssplayer) fixed_t camadjustfactor = cv_cam_turnfacinginput[forplayer].value; //@TODO cvar if (camadjustfactor) - *myangle -= cmd->sidemove * min(50, player->speed / (FRACUNIT/7)) * camadjustfactor; + *myangle -= cmd->sidemove * min(20, player->speed / (FRACUNIT/7)) * camadjustfactor; } if (abilitydirection && camera.chase && !ticcmd_resetdown[forplayer] && !player->climbing && !forcestrafe && (player->pflags & PF_DIRECTIONCHAR) && player->powers[pw_carry] != CR_MINECART) @@ -1416,9 +1416,9 @@ void G_BuildTiccmd(ticcmd_t *cmd, INT32 realtics, UINT8 ssplayer) fixed_t camadjustfactor; if (player->climbing || player->pflags & (PF_GLIDING|PF_STARTDASH)) - camadjustfactor = cv_cam_turnfacingability[forplayer].value; + camadjustfactor = cv_cam_turnfacingability[forplayer].value/2; else - camadjustfactor = cv_cam_turnfacing[forplayer].value; + camadjustfactor = cv_cam_turnfacing[forplayer].value/8; if (camadjustfactor) { From 3735134948e27b84fe99f4fcf39669870db9456d Mon Sep 17 00:00:00 2001 From: fickleheart Date: Mon, 9 Dec 2019 20:31:19 -0600 Subject: [PATCH 083/746] Fix smoothing into input-based camera rotation --- 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 6f5ca6383..95e612b28 100644 --- a/src/g_game.c +++ b/src/g_game.c @@ -1390,7 +1390,7 @@ void G_BuildTiccmd(ticcmd_t *cmd, INT32 realtics, UINT8 ssplayer) fixed_t camadjustfactor = cv_cam_turnfacinginput[forplayer].value; //@TODO cvar if (camadjustfactor) - *myangle -= cmd->sidemove * min(20, player->speed / (FRACUNIT/7)) * camadjustfactor; + *myangle -= cmd->sidemove * min(20, player->speed / FRACUNIT) * camadjustfactor; } if (abilitydirection && camera.chase && !ticcmd_resetdown[forplayer] && !player->climbing && !forcestrafe && (player->pflags & PF_DIRECTIONCHAR) && player->powers[pw_carry] != CR_MINECART) From 834a3bf3346b8f71518ae5330e1c3d0658d1c170 Mon Sep 17 00:00:00 2001 From: fickleheart Date: Mon, 9 Dec 2019 20:39:05 -0600 Subject: [PATCH 084/746] Port deadzone configuration from Kart I don't feel like getting out my gamepad, so I'll trust that this works. --- src/d_netcmd.c | 2 ++ src/g_game.c | 6 ++++-- src/g_game.h | 4 ++-- src/m_menu.c | 2 ++ 4 files changed, 10 insertions(+), 4 deletions(-) diff --git a/src/d_netcmd.c b/src/d_netcmd.c index 24df649fc..9c19fee5f 100644 --- a/src/d_netcmd.c +++ b/src/d_netcmd.c @@ -774,6 +774,8 @@ void D_RegisterClientCommands(void) CV_RegisterVar(&cv_fireaxis2); CV_RegisterVar(&cv_firenaxis); CV_RegisterVar(&cv_firenaxis2); + CV_RegisterVar(&cv_deadzone); + CV_RegisterVar(&cv_deadzone2); // filesrch.c CV_RegisterVar(&cv_addons_option); diff --git a/src/g_game.c b/src/g_game.c index 95e612b28..4cd527291 100644 --- a/src/g_game.c +++ b/src/g_game.c @@ -439,6 +439,7 @@ consvar_t cv_jumpaxis = {"joyaxis_jump", "None", CV_SAVE, joyaxis_cons_t, NULL, consvar_t cv_spinaxis = {"joyaxis_spin", "None", CV_SAVE, joyaxis_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL}; consvar_t cv_fireaxis = {"joyaxis_fire", "Z-Axis-", CV_SAVE, joyaxis_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL}; consvar_t cv_firenaxis = {"joyaxis_firenormal", "Z-Axis", CV_SAVE, joyaxis_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL}; +consvar_t cv_deadzone = {"joy_deadzone", "0.25", CV_FLOAT|CV_SAVE, zerotoone_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL}; consvar_t cv_turnaxis2 = {"joyaxis2_turn", "X-Rudder", CV_SAVE, joyaxis_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL}; consvar_t cv_moveaxis2 = {"joyaxis2_move", "Y-Axis", CV_SAVE, joyaxis_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL}; @@ -448,6 +449,7 @@ consvar_t cv_jumpaxis2 = {"joyaxis2_jump", "None", CV_SAVE, joyaxis_cons_t, NULL consvar_t cv_spinaxis2 = {"joyaxis2_spin", "None", CV_SAVE, joyaxis_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL}; consvar_t cv_fireaxis2 = {"joyaxis2_fire", "Z-Axis-", CV_SAVE, joyaxis_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL}; consvar_t cv_firenaxis2 = {"joyaxis2_firenormal", "Z-Axis", CV_SAVE, joyaxis_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL}; +consvar_t cv_deadzone2 = {"joy_deadzone2", "0.25", CV_FLOAT|CV_SAVE, zerotoone_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL}; #ifdef SEENAMES player_t *seenplayer; // player we're aiming at right now @@ -907,7 +909,7 @@ static INT32 JoyAxis(axis_input_e axissel) retaxis = +JOYAXISRANGE; if (!Joystick.bGamepadStyle && axissel < AXISDEAD) { - const INT32 jdeadzone = JOYAXISRANGE/4; + const INT32 jdeadzone = ((JOYAXISRANGE-1) * cv_deadzone.value) >> FRACBITS; if (-jdeadzone < retaxis && retaxis < jdeadzone) return 0; } @@ -980,7 +982,7 @@ static INT32 Joy2Axis(axis_input_e axissel) retaxis = +JOYAXISRANGE; if (!Joystick2.bGamepadStyle && axissel < AXISDEAD) { - const INT32 jdeadzone = JOYAXISRANGE/4; + const INT32 jdeadzone = ((JOYAXISRANGE-1) * cv_deadzone2.value) >> FRACBITS; if (-jdeadzone < retaxis && retaxis < jdeadzone) return 0; } diff --git a/src/g_game.h b/src/g_game.h index 2a030a49d..7da31f259 100644 --- a/src/g_game.h +++ b/src/g_game.h @@ -72,8 +72,8 @@ extern consvar_t cv_useranalog, cv_useranalog2; extern consvar_t cv_analog, cv_analog2; extern consvar_t cv_directionchar, cv_directionchar2; extern consvar_t cv_autobrake, cv_autobrake2; -extern consvar_t cv_sideaxis,cv_turnaxis,cv_moveaxis,cv_lookaxis,cv_jumpaxis,cv_spinaxis,cv_fireaxis,cv_firenaxis; -extern consvar_t cv_sideaxis2,cv_turnaxis2,cv_moveaxis2,cv_lookaxis2,cv_jumpaxis2,cv_spinaxis2,cv_fireaxis2,cv_firenaxis2; +extern consvar_t cv_sideaxis,cv_turnaxis,cv_moveaxis,cv_lookaxis,cv_jumpaxis,cv_spinaxis,cv_fireaxis,cv_firenaxis,cv_deadzone; +extern consvar_t cv_sideaxis2,cv_turnaxis2,cv_moveaxis2,cv_lookaxis2,cv_jumpaxis2,cv_spinaxis2,cv_fireaxis2,cv_firenaxis2,cv_deadzone2; extern consvar_t cv_ghost_bestscore, cv_ghost_besttime, cv_ghost_bestrings, cv_ghost_last, cv_ghost_guest; // hi here's some new controls diff --git a/src/m_menu.c b/src/m_menu.c index 4ae2b7036..5f65c894b 100644 --- a/src/m_menu.c +++ b/src/m_menu.c @@ -1121,6 +1121,7 @@ static menuitem_t OP_Joystick1Menu[] = {IT_STRING | IT_CVAR, NULL, "First-Person Vert-Look", &cv_alwaysfreelook, 120}, {IT_STRING | IT_CVAR, NULL, "Third-Person Vert-Look", &cv_chasefreelook, 130}, + {IT_STRING | IT_CVAR | IT_CV_FLOATSLIDER, NULL, "Deadzone", &cv_deadzone, 140}, }; static menuitem_t OP_Joystick2Menu[] = @@ -1137,6 +1138,7 @@ static menuitem_t OP_Joystick2Menu[] = {IT_STRING | IT_CVAR, NULL, "First-Person Vert-Look", &cv_alwaysfreelook2,120}, {IT_STRING | IT_CVAR, NULL, "Third-Person Vert-Look", &cv_chasefreelook2, 130}, + {IT_STRING | IT_CVAR | IT_CV_FLOATSLIDER, NULL, "Deadzone", &cv_deadzone2,140}, }; static menuitem_t OP_JoystickSetMenu[1+MAX_JOYSTICKS]; From b5f7f5f7326300fc160ee0354c6a50451011b0be Mon Sep 17 00:00:00 2001 From: fickleheart Date: Mon, 9 Dec 2019 22:06:50 -0600 Subject: [PATCH 085/746] Replace direction toggles with a playstyle selection It's kinda ugly right now... --- src/m_menu.c | 249 ++++++++++++++++++++++++++++++++++++++++++++++----- src/m_menu.h | 2 + src/p_user.c | 2 +- 3 files changed, 230 insertions(+), 23 deletions(-) diff --git a/src/m_menu.c b/src/m_menu.c index 5f65c894b..093d0b5ee 100644 --- a/src/m_menu.c +++ b/src/m_menu.c @@ -298,11 +298,14 @@ menu_t OP_MPControlsDef, OP_MiscControlsDef; menu_t OP_P1ControlsDef, OP_P2ControlsDef, OP_MouseOptionsDef; menu_t OP_Mouse2OptionsDef, OP_Joystick1Def, OP_Joystick2Def; menu_t OP_CameraOptionsDef, OP_Camera2OptionsDef; +menu_t OP_PlaystyleDef; static void M_VideoModeMenu(INT32 choice); static void M_Setup1PControlsMenu(INT32 choice); static void M_Setup2PControlsMenu(INT32 choice); static void M_Setup1PJoystickMenu(INT32 choice); static void M_Setup2PJoystickMenu(INT32 choice); +static void M_Setup1PPlaystyleMenu(INT32 choice); +static void M_Setup2PPlaystyleMenu(INT32 choice); static void M_AssignJoystick(INT32 choice); static void M_ChangeControl(INT32 choice); @@ -347,6 +350,8 @@ static void M_DrawLevelStats(void); static void M_DrawTimeAttackMenu(void); static void M_DrawNightsAttackMenu(void); static void M_DrawSetupChoosePlayerMenu(void); +static void M_DrawControlsDefMenu(void); +static void M_DrawPlaystyleMenu(void); static void M_DrawControl(void); static void M_DrawMainVideoMenu(void); static void M_DrawVideoMode(void); @@ -375,6 +380,7 @@ static void M_HandleSoundTest(INT32 choice); static void M_HandleImageDef(INT32 choice); static void M_HandleLoadSave(INT32 choice); static void M_HandleLevelStats(INT32 choice); +static void M_HandlePlaystyleMenu(INT32 choice); #ifndef NONET static boolean M_CancelConnect(void); static void M_HandleConnectIP(INT32 choice); @@ -1032,10 +1038,10 @@ static menuitem_t OP_P1ControlsMenu[] = {IT_SUBMENU | IT_STRING, NULL, "Camera Options...", &OP_CameraOptionsDef, 50}, - //{IT_STRING | IT_CVAR, NULL, "Analog Control", &cv_useranalog, 100}, - {IT_STRING | IT_CVAR, NULL, "Character angle", &cv_directionchar, 70}, - {IT_STRING | IT_CVAR, NULL, "Automatic braking", &cv_autobrake, 80}, - {IT_STRING | IT_CVAR, NULL, "Ability angle", &cv_abilitydirection[0], 90}, + //{IT_STRING | IT_CVAR, NULL, "Character angle", &cv_directionchar, 70}, + {IT_STRING | IT_CVAR, NULL, "Automatic braking", &cv_autobrake, 70}, + {IT_CALL | IT_STRING, NULL, "Play Style...", M_Setup1PPlaystyleMenu, 80}, + //{IT_STRING | IT_CVAR, NULL, "Ability angle", &cv_abilitydirection[0], 90}, }; static menuitem_t OP_P2ControlsMenu[] = @@ -1046,10 +1052,10 @@ static menuitem_t OP_P2ControlsMenu[] = {IT_SUBMENU | IT_STRING, NULL, "Camera Options...", &OP_Camera2OptionsDef, 50}, - //{IT_STRING | IT_CVAR, NULL, "Analog Control", &cv_useranalog2, 100}, - {IT_STRING | IT_CVAR, NULL, "Character angle", &cv_directionchar2, 70}, - {IT_STRING | IT_CVAR, NULL, "Automatic braking", &cv_autobrake2, 80}, - {IT_STRING | IT_CVAR, NULL, "Ability angle", &cv_abilitydirection[1], 90}, + //{IT_STRING | IT_CVAR, NULL, "Character angle", &cv_directionchar2, 70}, + {IT_STRING | IT_CVAR, NULL, "Automatic braking", &cv_autobrake2, 70}, + {IT_CALL | IT_STRING, NULL, "Play Style...", M_Setup2PPlaystyleMenu, 80}, + //{IT_STRING | IT_CVAR, NULL, "Ability angle", &cv_abilitydirection[1], 90}, }; static menuitem_t OP_ChangeControlsMenu[] = @@ -1183,13 +1189,14 @@ static menuitem_t OP_CameraOptionsMenu[] = {IT_STRING | IT_CVAR | IT_CV_INTEGERSTEP, NULL, "Camera Distance", &cv_cam_dist, 60}, {IT_STRING | IT_CVAR | IT_CV_INTEGERSTEP, NULL, "Camera Height", &cv_cam_height, 70}, {IT_STRING | IT_CVAR | IT_CV_FLOATSLIDER, NULL, "Camera Speed", &cv_cam_speed, 80}, + {IT_STRING | IT_CVAR | IT_CV_SLIDER, NULL, "Rotation Speed", &cv_cam_rotspeed, 90}, - {IT_STRING | IT_CVAR | IT_CV_SLIDER, NULL, "Shift to character angle", &cv_cam_shiftfacing[0], 100}, - {IT_STRING | IT_CVAR | IT_CV_SLIDER, NULL, "Turn to character angle", &cv_cam_turnfacing[0], 110}, - {IT_STRING | IT_CVAR | IT_CV_SLIDER, NULL, "Turn to ability", &cv_cam_turnfacingability[0], 120}, - {IT_STRING | IT_CVAR | IT_CV_SLIDER, NULL, "Turn to input", &cv_cam_turnfacinginput[0], 130}, + {IT_STRING | IT_CVAR | IT_CV_SLIDER, NULL, "Shift to character angle", &cv_cam_shiftfacing[0], 110}, + {IT_STRING | IT_CVAR | IT_CV_SLIDER, NULL, "Turn to character angle", &cv_cam_turnfacing[0], 120}, + {IT_STRING | IT_CVAR | IT_CV_SLIDER, NULL, "Turn to ability", &cv_cam_turnfacingability[0], 130}, + {IT_STRING | IT_CVAR | IT_CV_SLIDER, NULL, "Turn to input", &cv_cam_turnfacinginput[0], 140}, - {IT_STRING | IT_CVAR, NULL, "Crosshair", &cv_crosshair, 140}, + {IT_STRING | IT_CVAR, NULL, "Crosshair", &cv_crosshair, 160}, }; static menuitem_t OP_Camera2OptionsMenu[] = @@ -1202,13 +1209,14 @@ static menuitem_t OP_Camera2OptionsMenu[] = {IT_STRING | IT_CVAR | IT_CV_INTEGERSTEP, NULL, "Camera Distance", &cv_cam2_dist, 60}, {IT_STRING | IT_CVAR | IT_CV_INTEGERSTEP, NULL, "Camera Height", &cv_cam2_height, 70}, {IT_STRING | IT_CVAR | IT_CV_FLOATSLIDER, NULL, "Camera Speed", &cv_cam2_speed, 80}, + {IT_STRING | IT_CVAR | IT_CV_SLIDER, NULL, "Rotation Speed", &cv_cam2_rotspeed, 90}, - {IT_STRING | IT_CVAR | IT_CV_SLIDER, NULL, "Shift to character angle", &cv_cam_shiftfacing[1], 100}, - {IT_STRING | IT_CVAR | IT_CV_SLIDER, NULL, "Turn to character angle", &cv_cam_turnfacing[1], 110}, - {IT_STRING | IT_CVAR | IT_CV_SLIDER, NULL, "Turn to ability", &cv_cam_turnfacingability[1], 120}, - {IT_STRING | IT_CVAR | IT_CV_SLIDER, NULL, "Turn to input", &cv_cam_turnfacinginput[1], 130}, + {IT_STRING | IT_CVAR | IT_CV_SLIDER, NULL, "Shift to character angle", &cv_cam_shiftfacing[1], 110}, + {IT_STRING | IT_CVAR | IT_CV_SLIDER, NULL, "Turn to character angle", &cv_cam_turnfacing[1], 120}, + {IT_STRING | IT_CVAR | IT_CV_SLIDER, NULL, "Turn to ability", &cv_cam_turnfacingability[1], 130}, + {IT_STRING | IT_CVAR | IT_CV_SLIDER, NULL, "Turn to input", &cv_cam_turnfacinginput[1], 140}, - {IT_STRING | IT_CVAR, NULL, "Crosshair", &cv_crosshair2, 140}, + {IT_STRING | IT_CVAR, NULL, "Crosshair", &cv_crosshair2, 160}, }; static menuitem_t OP_VideoOptionsMenu[] = @@ -1924,12 +1932,24 @@ menu_t OP_MainDef = DEFAULTMENUSTYLE( menu_t OP_ChangeControlsDef = CONTROLMENUSTYLE( MN_OP_MAIN + (MN_OP_CHANGECONTROLS << 12), // second level (<<6) set on runtime OP_ChangeControlsMenu, &OP_MainDef); -menu_t OP_P1ControlsDef = DEFAULTMENUSTYLE( + +menu_t OP_P1ControlsDef = { MN_OP_MAIN + (MN_OP_P1CONTROLS << 6), - "M_CONTRO", OP_P1ControlsMenu, &OP_MainDef, 50, 30); -menu_t OP_P2ControlsDef = DEFAULTMENUSTYLE( + "M_CONTRO", + sizeof(OP_P1ControlsMenu)/sizeof(menuitem_t), + &OP_MainDef, + OP_P1ControlsMenu, + M_DrawControlsDefMenu, + 50, 30, 0, NULL}; +menu_t OP_P2ControlsDef = { MN_OP_MAIN + (MN_OP_P2CONTROLS << 6), - "M_CONTRO", OP_P2ControlsMenu, &OP_MainDef, 50, 30); + "M_CONTRO", + sizeof(OP_P2ControlsMenu)/sizeof(menuitem_t), + &OP_MainDef, + OP_P2ControlsMenu, + M_DrawControlsDefMenu, + 50, 30, 0, NULL}; + menu_t OP_MouseOptionsDef = DEFAULTMENUSTYLE( MN_OP_MAIN + (MN_OP_P1CONTROLS << 6) + (MN_OP_P1MOUSE << 12), "M_CONTRO", OP_MouseOptionsMenu, &OP_P1ControlsDef, 35, 30); @@ -1961,6 +1981,18 @@ menu_t OP_Camera2OptionsDef = DEFAULTMENUSTYLE( MN_OP_MAIN + (MN_OP_P2CONTROLS << 6) + (MN_OP_P2CAMERA << 12), "M_CONTRO", OP_Camera2OptionsMenu, &OP_P2ControlsDef, 35, 30); +static menuitem_t OP_PlaystyleMenu[] = {{IT_KEYHANDLER | IT_NOTHING, NULL, "", M_HandlePlaystyleMenu, 0}}; + +menu_t OP_PlaystyleDef = { + MN_OP_MAIN + (MN_OP_P1CONTROLS << 6) + (MN_OP_PLAYSTYLE << 12), + NULL, + 1, + &OP_P1ControlsDef, + OP_PlaystyleMenu, + M_DrawPlaystyleMenu, + 0, 0, 0, NULL +}; + menu_t OP_VideoOptionsDef = { @@ -4166,6 +4198,98 @@ static void M_DrawGenericMenu(void) } } +const char *PlaystyleNames[3] = {"Legacy", "Standard", "Simple"}; +const char *PlaystyleDesc[3] = { + // Legacy + "The play style used for\n" + "old-school SRB2.\n" + "\n" + "This play style is identical\n" + "to Standard, except that the\n" + "player always looks in the\n" + "direction of the camera." + , + + // Standard + "The default play style,\n" + "designed for full control\n" + "with a keyboard and mouse.\n" + "\n" + "The camera rotates only when\n" + "you tell it to. The player\n" + "looks in the direction they're\n" + "moving, but acts in the direction\n" + "the camera is facing.\n" + "\n" + "Mastery of this play style will\n" + "open up the highest level of play!" + , + + // Simple + "A play style designed for\n" + "gamepads and hassle-free play.\n" + "\n" + "The camera rotates automatically\n" + "as you move, and the player faces\n" + "and acts in the direction\n" + "they're moving.\n" + "\n" + "Hold \x82Reset Camera\x80 to lock the\n" + "camera behind the player!\n" +}; + +static void M_DrawControlsDefMenu(void) +{ + UINT8 opt = 0; + + M_DrawGenericMenu(); + + if (currentMenu == &OP_P1ControlsDef) + { + opt = (cv_abilitydirection[0].value ? 2 : cv_directionchar.value); + + if (opt == 2) + { + OP_CameraOptionsMenu[8].status = IT_STRING|IT_CVAR|IT_CV_SLIDER; + OP_CameraOptionsMenu[9].status = IT_STRING|IT_CVAR|IT_CV_SLIDER; + OP_CameraOptionsMenu[10].status = IT_STRING|IT_CVAR|IT_CV_SLIDER; + OP_CameraOptionsMenu[11].status = IT_STRING|IT_CVAR|IT_CV_SLIDER; + OP_CameraOptionsMenu[12].alphaKey = 160; + } + else + { + OP_CameraOptionsMenu[8].status = IT_DISABLED; + OP_CameraOptionsMenu[9].status = IT_DISABLED; + OP_CameraOptionsMenu[10].status = IT_DISABLED; + OP_CameraOptionsMenu[11].status = IT_DISABLED; + OP_CameraOptionsMenu[12].alphaKey = 110; + } + } + else + { + opt = (cv_abilitydirection[1].value ? 2 : cv_directionchar2.value); + + if (opt == 2) + { + OP_Camera2OptionsMenu[8].status = IT_STRING|IT_CVAR|IT_CV_SLIDER; + OP_Camera2OptionsMenu[9].status = IT_STRING|IT_CVAR|IT_CV_SLIDER; + OP_Camera2OptionsMenu[10].status = IT_STRING|IT_CVAR|IT_CV_SLIDER; + OP_Camera2OptionsMenu[11].status = IT_STRING|IT_CVAR|IT_CV_SLIDER; + OP_Camera2OptionsMenu[12].alphaKey = 160; + } + else + { + OP_Camera2OptionsMenu[8].status = IT_DISABLED; + OP_Camera2OptionsMenu[9].status = IT_DISABLED; + OP_Camera2OptionsMenu[10].status = IT_DISABLED; + OP_Camera2OptionsMenu[11].status = IT_DISABLED; + OP_Camera2OptionsMenu[12].alphaKey = 110; + } + } + + V_DrawRightAlignedString(BASEVIDWIDTH - currentMenu->x, currentMenu->y + 80, V_YELLOWMAP, PlaystyleNames[opt]); +} + #define scrollareaheight 72 // note that alphakey is multiplied by 2 for scrolling menus to allow greater usage in UINT8 range. @@ -11430,6 +11554,87 @@ static void M_ChangeControl(INT32 choice) M_StartMessage(tmp, M_ChangecontrolResponse, MM_EVENTHANDLER); } +static UINT8 playstyle_activeplayer = 0, playstyle_currentchoice = 0; + +static void M_Setup1PPlaystyleMenu(INT32 choice) +{ + (void)choice; + + playstyle_activeplayer = 0; + playstyle_currentchoice = (cv_abilitydirection[0].value ? 2 : cv_directionchar.value); + OP_PlaystyleDef.prevMenu = &OP_P1ControlsDef; + M_SetupNextMenu(&OP_PlaystyleDef); +} + +static void M_Setup2PPlaystyleMenu(INT32 choice) +{ + (void)choice; + + playstyle_activeplayer = 1; + playstyle_currentchoice = (cv_abilitydirection[1].value ? 2 : cv_directionchar2.value); + OP_PlaystyleDef.prevMenu = &OP_P2ControlsDef; + M_SetupNextMenu(&OP_PlaystyleDef); +} + +static void M_DrawPlaystyleMenu(void) +{ + size_t i; + + for (i = 0; i < 3; i++) + { + V_DrawCenteredString((i+1)*BASEVIDWIDTH/4, 20, (i == playstyle_currentchoice) ? V_YELLOWMAP : 0, PlaystyleNames[i]); + + if (i == playstyle_currentchoice) + { + V_DrawScaledPatch((i+1)*BASEVIDWIDTH/4 - 8, 10, 0, W_CachePatchName("M_CURSOR", PU_CACHE)); + V_DrawString(30, 50, V_ALLOWLOWERCASE, PlaystyleDesc[i]); + } + } +} + +static void M_HandlePlaystyleMenu(INT32 choice) +{ + switch (choice) + { + case KEY_ESCAPE: + case KEY_BACKSPACE: + M_SetupNextMenu(currentMenu->prevMenu); + break; + + case KEY_ENTER: + S_StartSound(NULL, sfx_menu1); + if (cv_abilitydirection[playstyle_activeplayer].value != (playstyle_currentchoice/2)) + { + if (cv_abilitydirection[playstyle_activeplayer].value) + { + CV_Set((playstyle_activeplayer ? &cv_cam2_dist : &cv_cam_dist), cv_cam_dist.defaultvalue); + CV_Set((playstyle_activeplayer ? &cv_cam2_height : &cv_cam_height), cv_cam_height.defaultvalue); + } + else + { + CV_SetValue((playstyle_activeplayer ? &cv_cam2_dist : &cv_cam_dist), 224); + CV_SetValue((playstyle_activeplayer ? &cv_cam2_height : &cv_cam_height), 50); + } + + CV_SetValue(&cv_abilitydirection[playstyle_activeplayer], playstyle_currentchoice/2); + } + CV_SetValue((playstyle_activeplayer ? &cv_directionchar2 : &cv_directionchar), playstyle_currentchoice ? 1 : 0); + + M_SetupNextMenu(currentMenu->prevMenu); + break; + + case KEY_LEFTARROW: + S_StartSound(NULL, sfx_menu1); + playstyle_currentchoice = (playstyle_currentchoice+2)%3; + break; + + case KEY_RIGHTARROW: + S_StartSound(NULL, sfx_menu1); + playstyle_currentchoice = (playstyle_currentchoice+1)%3; + break; + } +} + // =============== // VIDEO MODE MENU // =============== diff --git a/src/m_menu.h b/src/m_menu.h index ce9b422dc..09bf371cb 100644 --- a/src/m_menu.h +++ b/src/m_menu.h @@ -81,6 +81,8 @@ typedef enum MN_OP_P2JOYSTICK, MN_OP_P2CAMERA, + MN_OP_PLAYSTYLE, + MN_OP_VIDEO, MN_OP_VIDEOMODE, MN_OP_COLOR, diff --git a/src/p_user.c b/src/p_user.c index e9297b667..c0381c380 100644 --- a/src/p_user.c +++ b/src/p_user.c @@ -9598,7 +9598,7 @@ static void CV_CamRotate2_OnChange(void) } static CV_PossibleValue_t CV_CamSpeed[] = {{0, "MIN"}, {1*FRACUNIT, "MAX"}, {0, NULL}}; -static CV_PossibleValue_t rotation_cons_t[] = {{1, "MIN"}, {45, "MAX"}, {0, NULL}}; +static CV_PossibleValue_t rotation_cons_t[] = {{1, "MIN"}, {25, "MAX"}, {0, NULL}}; static CV_PossibleValue_t CV_CamRotate[] = {{-720, "MIN"}, {720, "MAX"}, {0, NULL}}; consvar_t cv_cam_dist = {"cam_dist", "160", CV_FLOAT|CV_SAVE, NULL, NULL, 0, NULL, NULL, 0, 0, NULL}; From 2a9819947eefec9b1d226a7d68dc51da7eabb38a Mon Sep 17 00:00:00 2001 From: fickleheart Date: Mon, 9 Dec 2019 22:09:58 -0600 Subject: [PATCH 086/746] Disable all new camera behavior if playstyle is not Simple --- src/g_game.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/g_game.c b/src/g_game.c index 4cd527291..654747da4 100644 --- a/src/g_game.c +++ b/src/g_game.c @@ -1387,7 +1387,7 @@ void G_BuildTiccmd(ticcmd_t *cmd, INT32 realtics, UINT8 ssplayer) cmd->angleturn = (INT16)(*myangle >> 16); // Adjust camera angle by player input - if (!forcestrafe && camera.chase && !turnheld[forplayer] && !ticcmd_resetdown[forplayer] && !player->climbing && player->powers[pw_carry] != CR_MINECART) + if (abilitydirection && !forcestrafe && camera.chase && !turnheld[forplayer] && !ticcmd_resetdown[forplayer] && !player->climbing && player->powers[pw_carry] != CR_MINECART) { fixed_t camadjustfactor = cv_cam_turnfacinginput[forplayer].value; //@TODO cvar @@ -1413,7 +1413,7 @@ void G_BuildTiccmd(ticcmd_t *cmd, INT32 realtics, UINT8 ssplayer) // Adjust camera angle to face player direction, depending on circumstances // Nothing happens if cam left/right are held, so you can hold both to lock the camera in one direction - if (!forcestrafe && camera.chase && !turnheld[forplayer] && !ticcmd_resetdown[forplayer] && player->powers[pw_carry] != CR_MINECART) + if (abilitydirection && !forcestrafe && camera.chase && !turnheld[forplayer] && !ticcmd_resetdown[forplayer] && player->powers[pw_carry] != CR_MINECART) { fixed_t camadjustfactor; From a3961efc4314b0870751530a26cbd0bc8dcb9513 Mon Sep 17 00:00:00 2001 From: fickleheart Date: Mon, 9 Dec 2019 22:12:19 -0600 Subject: [PATCH 087/746] Draw crosshair in Simple mode while holding cam reset I think this gives extra indication that abilities face toward the camera now. --- src/hu_stuff.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/hu_stuff.c b/src/hu_stuff.c index 91a167a60..03489101d 100644 --- a/src/hu_stuff.c +++ b/src/hu_stuff.c @@ -2194,10 +2194,10 @@ void HU_Drawer(void) return; // draw the crosshair, not when viewing demos nor with chasecam - if (!automapactive && cv_crosshair.value && !demoplayback && !camera.chase && !players[displayplayer].spectator) + if (!automapactive && cv_crosshair.value && !demoplayback && (!camera.chase || (cv_abilitydirection[0].value && ticcmd_resetdown[0])) && !players[displayplayer].spectator) HU_DrawCrosshair(); - if (!automapactive && cv_crosshair2.value && !demoplayback && !camera2.chase && !players[secondarydisplayplayer].spectator) + if (!automapactive && cv_crosshair2.value && !demoplayback && (!camera2.chase || (cv_abilitydirection[1].value && ticcmd_resetdown[1])) && !players[secondarydisplayplayer].spectator) HU_DrawCrosshair2(); // draw desynch text From 2fa1e750168fb4d4dbc9f55c50feaf788f2ca8c6 Mon Sep 17 00:00:00 2001 From: fickleheart Date: Mon, 9 Dec 2019 22:45:34 -0600 Subject: [PATCH 088/746] I'm hilarious --- src/m_menu.c | 30 ++++++++++++++++++++++-------- 1 file changed, 22 insertions(+), 8 deletions(-) diff --git a/src/m_menu.c b/src/m_menu.c index 093d0b5ee..5cde16712 100644 --- a/src/m_menu.c +++ b/src/m_menu.c @@ -4198,8 +4198,8 @@ static void M_DrawGenericMenu(void) } } -const char *PlaystyleNames[3] = {"Legacy", "Standard", "Simple"}; -const char *PlaystyleDesc[3] = { +const char *PlaystyleNames[4] = {"Legacy", "Standard", "Simple", "Old Analog??"}; +const char *PlaystyleDesc[4] = { // Legacy "The play style used for\n" "old-school SRB2.\n" @@ -4236,6 +4236,18 @@ const char *PlaystyleDesc[3] = { "\n" "Hold \x82Reset Camera\x80 to lock the\n" "camera behind the player!\n" + , + + // Old Analog + "I see.\n" + "\n" + "You really liked the old analog mode,\n" + "so when 2.2 came out, you opened up\n" + "your config file and brought it back.\n" + "\n" + "That's absolutely valid, but I implore\n" + "you to try the new Simple play style\n" + "instead!" }; static void M_DrawControlsDefMenu(void) @@ -4246,7 +4258,7 @@ static void M_DrawControlsDefMenu(void) if (currentMenu == &OP_P1ControlsDef) { - opt = (cv_abilitydirection[0].value ? 2 : cv_directionchar.value); + opt = cv_useranalog.value ? 3 : (cv_abilitydirection[0].value ? 2 : cv_directionchar.value); if (opt == 2) { @@ -4267,7 +4279,7 @@ static void M_DrawControlsDefMenu(void) } else { - opt = (cv_abilitydirection[1].value ? 2 : cv_directionchar2.value); + opt = cv_useranalog2.value ? 3 : (cv_abilitydirection[1].value ? 2 : cv_directionchar2.value); if (opt == 2) { @@ -11561,7 +11573,7 @@ static void M_Setup1PPlaystyleMenu(INT32 choice) (void)choice; playstyle_activeplayer = 0; - playstyle_currentchoice = (cv_abilitydirection[0].value ? 2 : cv_directionchar.value); + playstyle_currentchoice = cv_useranalog.value ? 3 : (cv_abilitydirection[0].value ? 2 : cv_directionchar.value); OP_PlaystyleDef.prevMenu = &OP_P1ControlsDef; M_SetupNextMenu(&OP_PlaystyleDef); } @@ -11571,7 +11583,7 @@ static void M_Setup2PPlaystyleMenu(INT32 choice) (void)choice; playstyle_activeplayer = 1; - playstyle_currentchoice = (cv_abilitydirection[1].value ? 2 : cv_directionchar2.value); + playstyle_currentchoice = cv_useranalog2.value ? 3 : (cv_abilitydirection[1].value ? 2 : cv_directionchar2.value); OP_PlaystyleDef.prevMenu = &OP_P2ControlsDef; M_SetupNextMenu(&OP_PlaystyleDef); } @@ -11580,9 +11592,10 @@ static void M_DrawPlaystyleMenu(void) { size_t i; - for (i = 0; i < 3; i++) + for (i = 0; i < 4; i++) { - V_DrawCenteredString((i+1)*BASEVIDWIDTH/4, 20, (i == playstyle_currentchoice) ? V_YELLOWMAP : 0, PlaystyleNames[i]); + if (i != 3) + V_DrawCenteredString((i+1)*BASEVIDWIDTH/4, 20, (i == playstyle_currentchoice) ? V_YELLOWMAP : 0, PlaystyleNames[i]); if (i == playstyle_currentchoice) { @@ -11619,6 +11632,7 @@ static void M_HandlePlaystyleMenu(INT32 choice) CV_SetValue(&cv_abilitydirection[playstyle_activeplayer], playstyle_currentchoice/2); } CV_SetValue((playstyle_activeplayer ? &cv_directionchar2 : &cv_directionchar), playstyle_currentchoice ? 1 : 0); + CV_SetValue((playstyle_activeplayer ? &cv_useranalog2 : &cv_useranalog), 0); M_SetupNextMenu(currentMenu->prevMenu); break; From 3dfa526eead55b4407576b6954c51d3c1a23c876 Mon Sep 17 00:00:00 2001 From: Nev3r Date: Tue, 10 Dec 2019 14:21:08 +0100 Subject: [PATCH 089/746] Separate Emerald Hunt emerald spawning into another function. --- src/p_setup.c | 96 ++++++++++++++++++++++++++++----------------------- 1 file changed, 52 insertions(+), 44 deletions(-) diff --git a/src/p_setup.c b/src/p_setup.c index d082e95b2..86cc9d810 100644 --- a/src/p_setup.c +++ b/src/p_setup.c @@ -1017,13 +1017,18 @@ static void P_PrepareRawThings(UINT8 *data, size_t i) { mt->x = READINT16(data); mt->y = READINT16(data); - mt->z = 0; mt->angle = READINT16(data); mt->type = READUINT16(data); mt->options = READUINT16(data); mt->extrainfo = (UINT8)(mt->type >> 12); + mt->type &= 4095; + + if (mt->type == 1705 || (mt->type == 750 && mt->extrainfo)) // NiGHTS Hoops + mt->z = mthing->options; + else + mt->z = mthing->options >> ZSHIFT; } } @@ -1034,6 +1039,51 @@ static void P_PrepareThings(lumpnum_t lumpnum) Z_Free(data); } +static void SpawnEmeraldHunt (void) +{ + INT32 emer1, emer2, emer3; + INT32 timeout = 0; // keeps from getting stuck + + emer1 = emer2 = emer3 = 0; + + //increment spawn numbers because zero is valid. + emer1 = (P_RandomKey(numhuntemeralds)) + 1; + while (timeout++ < 100) + { + emer2 = (P_RandomKey(numhuntemeralds)) + 1; + + if (emer2 != emer1) + break; + } + + timeout = 0; + while (timeout++ < 100) + { + emer3 = (P_RandomKey(numhuntemeralds)) + 1; + + if (emer3 != emer2 && emer3 != emer1) + break; + } + + //decrement spawn values to the actual number because zero is valid. + if (emer1--) + P_SpawnMobj(huntemeralds[emer1]->x<y<z<x<y<z<x<y<z<x<y<z<x<y<z<x<y<z< Date: Tue, 10 Dec 2019 07:54:27 -0600 Subject: [PATCH 090/746] Disable thok camera snap --- src/p_user.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/src/p_user.c b/src/p_user.c index c0381c380..c5d4e2846 100644 --- a/src/p_user.c +++ b/src/p_user.c @@ -5353,14 +5353,15 @@ static void P_DoJumpStuff(player_t *player, ticcmd_t *cmd) player->pflags &= ~(PF_SPINNING|PF_STARTDASH); player->pflags |= PF_THOKKED; - // Change localangle to match? (P.S. chalupa) - if (!demoplayback) + // Change localangle to match for simple controls? (P.S. chalupa) + // disabled because it seemed to disorient people and Z-targeting exists now + /*if (!demoplayback) { if (player == &players[consoleplayer] && cv_cam_turnfacingability[0].value > 0 && !(PLAYER1INPUTDOWN(gc_turnleft) || PLAYER1INPUTDOWN(gc_turnright))) localangle = player->mo->angle; else if (player == &players[secondarydisplayplayer] && cv_cam_turnfacingability[1].value > 0 && !(PLAYER2INPUTDOWN(gc_turnleft) || PLAYER2INPUTDOWN(gc_turnright))) localangle2 = player->mo->angle; - } + }*/ } break; From e1d4e2edcb79d1a72d4a5fbe6f8a555bcdc2c4aa Mon Sep 17 00:00:00 2001 From: fickleheart Date: Tue, 10 Dec 2019 07:58:50 -0600 Subject: [PATCH 091/746] Suspend directionchar while holding cam reset This should make it completely clear that thok will face the camera while it's held. --- src/g_game.c | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/src/g_game.c b/src/g_game.c index 654747da4..4f2258f6f 100644 --- a/src/g_game.c +++ b/src/g_game.c @@ -1250,13 +1250,21 @@ void G_BuildTiccmd(ticcmd_t *cmd, INT32 realtics, UINT8 ssplayer) { ticcmd_resetdown[forplayer] = true; P_ResetCamera(&players[ssplayer == 1 ? displayplayer : secondarydisplayplayer], &camera); + + if (abilitydirection) + CV_SetValue((ssplayer == 1 ? &cv_directionchar : &cv_directionchar2), 0); } else ticcmd_resetdown[forplayer] = true; } else + { ticcmd_resetdown[forplayer] = false; + if (abilitydirection) + CV_SetValue((ssplayer == 1 ? &cv_directionchar : &cv_directionchar2), 1); + } + // jump button axis = PlayerJoyAxis(ssplayer, AXISJUMP); if (PLAYERINPUTDOWN(ssplayer, gc_jump) || (usejoystick && axis > 0)) From 194e77a6f08cb194c64ecf5bf0d188b692b7b037 Mon Sep 17 00:00:00 2001 From: fickleheart Date: Tue, 10 Dec 2019 08:07:41 -0600 Subject: [PATCH 092/746] Give spindash turn a separate slider --- src/d_netcmd.c | 2 ++ src/g_game.c | 8 +++++++- src/g_game.h | 3 ++- src/m_menu.c | 26 ++++++++++++++++---------- 4 files changed, 27 insertions(+), 12 deletions(-) diff --git a/src/d_netcmd.c b/src/d_netcmd.c index 9c19fee5f..2b7bb3302 100644 --- a/src/d_netcmd.c +++ b/src/d_netcmd.c @@ -834,6 +834,8 @@ void D_RegisterClientCommands(void) CV_RegisterVar(&cv_cam_turnfacing[1]); CV_RegisterVar(&cv_cam_turnfacingability[0]); CV_RegisterVar(&cv_cam_turnfacingability[1]); + CV_RegisterVar(&cv_cam_turnfacingspindash[0]); + CV_RegisterVar(&cv_cam_turnfacingspindash[1]); CV_RegisterVar(&cv_cam_turnfacinginput[0]); CV_RegisterVar(&cv_cam_turnfacinginput[1]); diff --git a/src/g_game.c b/src/g_game.c index 4f2258f6f..25ed91f27 100644 --- a/src/g_game.c +++ b/src/g_game.c @@ -412,6 +412,10 @@ consvar_t cv_cam_turnfacingability[2] = { {"cam_turnfacingability", "0.25", CV_FLOAT|CV_SAVE, zerotoone_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL}, {"cam2_turnfacingability", "0.25", CV_FLOAT|CV_SAVE, zerotoone_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL}, }; +consvar_t cv_cam_turnfacingspindash[2] = { + {"cam_turnfacingspindash", "0.25", CV_FLOAT|CV_SAVE, zerotoone_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL}, + {"cam2_turnfacingspindash", "0.25", CV_FLOAT|CV_SAVE, zerotoone_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL}, +}; consvar_t cv_cam_turnfacinginput[2] = { {"cam_turnfacinginput", "0.375", CV_FLOAT|CV_SAVE, zerotoone_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL}, {"cam2_turnfacinginput", "0.375", CV_FLOAT|CV_SAVE, zerotoone_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL}, @@ -1425,8 +1429,10 @@ void G_BuildTiccmd(ticcmd_t *cmd, INT32 realtics, UINT8 ssplayer) { fixed_t camadjustfactor; - if (player->climbing || player->pflags & (PF_GLIDING|PF_STARTDASH)) + if (player->climbing || player->pflags & PF_GLIDING) camadjustfactor = cv_cam_turnfacingability[forplayer].value/2; + else if (player->pflags & PF_STARTDASH) + camadjustfactor = cv_cam_turnfacingspindash[forplayer].value/2; else camadjustfactor = cv_cam_turnfacing[forplayer].value/8; diff --git a/src/g_game.h b/src/g_game.h index 7da31f259..312e7e663 100644 --- a/src/g_game.h +++ b/src/g_game.h @@ -77,7 +77,8 @@ extern consvar_t cv_sideaxis2,cv_turnaxis2,cv_moveaxis2,cv_lookaxis2,cv_jumpaxis extern consvar_t cv_ghost_bestscore, cv_ghost_besttime, cv_ghost_bestrings, cv_ghost_last, cv_ghost_guest; // hi here's some new controls -extern consvar_t cv_abilitydirection[2], cv_cam_shiftfacing[2], cv_cam_turnfacing[2], cv_cam_turnfacingability[2], cv_cam_turnfacinginput[2]; +extern consvar_t cv_abilitydirection[2], cv_cam_shiftfacing[2], cv_cam_turnfacing[2], + cv_cam_turnfacingability[2], cv_cam_turnfacingspindash[2], cv_cam_turnfacinginput[2]; // mouseaiming (looking up/down with the mouse or keyboard) #define KB_LOOKSPEED (1<<25) diff --git a/src/m_menu.c b/src/m_menu.c index 5cde16712..6d317950d 100644 --- a/src/m_menu.c +++ b/src/m_menu.c @@ -1191,9 +1191,10 @@ static menuitem_t OP_CameraOptionsMenu[] = {IT_STRING | IT_CVAR | IT_CV_FLOATSLIDER, NULL, "Camera Speed", &cv_cam_speed, 80}, {IT_STRING | IT_CVAR | IT_CV_SLIDER, NULL, "Rotation Speed", &cv_cam_rotspeed, 90}, - {IT_STRING | IT_CVAR | IT_CV_SLIDER, NULL, "Shift to character angle", &cv_cam_shiftfacing[0], 110}, - {IT_STRING | IT_CVAR | IT_CV_SLIDER, NULL, "Turn to character angle", &cv_cam_turnfacing[0], 120}, - {IT_STRING | IT_CVAR | IT_CV_SLIDER, NULL, "Turn to ability", &cv_cam_turnfacingability[0], 130}, + {IT_STRING | IT_CVAR | IT_CV_SLIDER, NULL, "Shift to player angle", &cv_cam_shiftfacing[0], 100}, + {IT_STRING | IT_CVAR | IT_CV_SLIDER, NULL, "Turn to player angle", &cv_cam_turnfacing[0], 110}, + {IT_STRING | IT_CVAR | IT_CV_SLIDER, NULL, "Turn to ability", &cv_cam_turnfacingability[0], 120}, + {IT_STRING | IT_CVAR | IT_CV_SLIDER, NULL, "Turn to spindash", &cv_cam_turnfacingspindash[0], 130}, {IT_STRING | IT_CVAR | IT_CV_SLIDER, NULL, "Turn to input", &cv_cam_turnfacinginput[0], 140}, {IT_STRING | IT_CVAR, NULL, "Crosshair", &cv_crosshair, 160}, @@ -1211,9 +1212,10 @@ static menuitem_t OP_Camera2OptionsMenu[] = {IT_STRING | IT_CVAR | IT_CV_FLOATSLIDER, NULL, "Camera Speed", &cv_cam2_speed, 80}, {IT_STRING | IT_CVAR | IT_CV_SLIDER, NULL, "Rotation Speed", &cv_cam2_rotspeed, 90}, - {IT_STRING | IT_CVAR | IT_CV_SLIDER, NULL, "Shift to character angle", &cv_cam_shiftfacing[1], 110}, - {IT_STRING | IT_CVAR | IT_CV_SLIDER, NULL, "Turn to character angle", &cv_cam_turnfacing[1], 120}, - {IT_STRING | IT_CVAR | IT_CV_SLIDER, NULL, "Turn to ability", &cv_cam_turnfacingability[1], 130}, + {IT_STRING | IT_CVAR | IT_CV_SLIDER, NULL, "Shift to character angle", &cv_cam_shiftfacing[1], 100}, + {IT_STRING | IT_CVAR | IT_CV_SLIDER, NULL, "Turn to character angle", &cv_cam_turnfacing[1], 110}, + {IT_STRING | IT_CVAR | IT_CV_SLIDER, NULL, "Turn to ability", &cv_cam_turnfacingability[1], 120}, + {IT_STRING | IT_CVAR | IT_CV_SLIDER, NULL, "Turn to spindash", &cv_cam_turnfacingspindash[1], 130}, {IT_STRING | IT_CVAR | IT_CV_SLIDER, NULL, "Turn to input", &cv_cam_turnfacinginput[1], 140}, {IT_STRING | IT_CVAR, NULL, "Crosshair", &cv_crosshair2, 160}, @@ -4266,7 +4268,8 @@ static void M_DrawControlsDefMenu(void) OP_CameraOptionsMenu[9].status = IT_STRING|IT_CVAR|IT_CV_SLIDER; OP_CameraOptionsMenu[10].status = IT_STRING|IT_CVAR|IT_CV_SLIDER; OP_CameraOptionsMenu[11].status = IT_STRING|IT_CVAR|IT_CV_SLIDER; - OP_CameraOptionsMenu[12].alphaKey = 160; + OP_CameraOptionsMenu[12].status = IT_STRING|IT_CVAR|IT_CV_SLIDER; + OP_CameraOptionsMenu[13].alphaKey = 160; } else { @@ -4274,7 +4277,8 @@ static void M_DrawControlsDefMenu(void) OP_CameraOptionsMenu[9].status = IT_DISABLED; OP_CameraOptionsMenu[10].status = IT_DISABLED; OP_CameraOptionsMenu[11].status = IT_DISABLED; - OP_CameraOptionsMenu[12].alphaKey = 110; + OP_CameraOptionsMenu[12].status = IT_DISABLED; + OP_CameraOptionsMenu[13].alphaKey = 110; } } else @@ -4287,7 +4291,8 @@ static void M_DrawControlsDefMenu(void) OP_Camera2OptionsMenu[9].status = IT_STRING|IT_CVAR|IT_CV_SLIDER; OP_Camera2OptionsMenu[10].status = IT_STRING|IT_CVAR|IT_CV_SLIDER; OP_Camera2OptionsMenu[11].status = IT_STRING|IT_CVAR|IT_CV_SLIDER; - OP_Camera2OptionsMenu[12].alphaKey = 160; + OP_Camera2OptionsMenu[12].status = IT_STRING|IT_CVAR|IT_CV_SLIDER; + OP_Camera2OptionsMenu[13].alphaKey = 160; } else { @@ -4295,7 +4300,8 @@ static void M_DrawControlsDefMenu(void) OP_Camera2OptionsMenu[9].status = IT_DISABLED; OP_Camera2OptionsMenu[10].status = IT_DISABLED; OP_Camera2OptionsMenu[11].status = IT_DISABLED; - OP_Camera2OptionsMenu[12].alphaKey = 110; + OP_Camera2OptionsMenu[12].status = IT_DISABLED; + OP_Camera2OptionsMenu[13].alphaKey = 110; } } From 72cf5d9927a56f2af9315331db0b9ce4933e43f5 Mon Sep 17 00:00:00 2001 From: fickleheart Date: Tue, 10 Dec 2019 08:17:41 -0600 Subject: [PATCH 093/746] Don't flood directionchar commands!!! --- 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 25ed91f27..394e9a09d 100644 --- a/src/g_game.c +++ b/src/g_game.c @@ -1261,7 +1261,7 @@ void G_BuildTiccmd(ticcmd_t *cmd, INT32 realtics, UINT8 ssplayer) else ticcmd_resetdown[forplayer] = true; } - else + else if (ticcmd_resetdown[forplayer]) { ticcmd_resetdown[forplayer] = false; From 2b70b4bf36887854f3e08e70cdbb11863802f961 Mon Sep 17 00:00:00 2001 From: fickleheart Date: Tue, 10 Dec 2019 09:08:30 -0600 Subject: [PATCH 094/746] TODO --- src/g_game.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/g_game.c b/src/g_game.c index 394e9a09d..a05812768 100644 --- a/src/g_game.c +++ b/src/g_game.c @@ -1409,6 +1409,11 @@ void G_BuildTiccmd(ticcmd_t *cmd, INT32 realtics, UINT8 ssplayer) if (abilitydirection && camera.chase && !ticcmd_resetdown[forplayer] && !player->climbing && !forcestrafe && (player->pflags & PF_DIRECTIONCHAR) && player->powers[pw_carry] != CR_MINECART) { + ///@TODO This block of code is a hack to get the desired abilitydirection and player angle behaviors while remaining netplay-compatible with EXEs without those features. + // This has side effects like making F12 spectate look kind of weird, and making the input viewer inaccurate. + // In a perfect world, this will be removed and player behavior would use facing direction in a way that mimics this. + // But that's a lot more work and I want to A) have this out quickly B) be netplay-compatible. + if (cmd->forwardmove || cmd->sidemove) { angle_t controlangle = R_PointToAngle2(0, 0, cmd->forwardmove << FRACBITS, -cmd->sidemove << FRACBITS); From 8466dc5813db9ffd7edf9f80e59fa336e5b45c3f Mon Sep 17 00:00:00 2001 From: Nev3r Date: Tue, 10 Dec 2019 18:03:15 +0100 Subject: [PATCH 095/746] Move mobj spawn Z calculating to a separate function. --- src/p_mobj.c | 181 +++++++++++++++++++++----------------------------- src/p_setup.c | 6 +- 2 files changed, 79 insertions(+), 108 deletions(-) diff --git a/src/p_mobj.c b/src/p_mobj.c index dea4a7a4d..e64fb1537 100644 --- a/src/p_mobj.c +++ b/src/p_mobj.c @@ -11550,6 +11550,80 @@ void P_MovePlayerToStarpost(INT32 playernum) mapthing_t *huntemeralds[MAXHUNTEMERALDS]; INT32 numhuntemeralds; + +static fixed_t GetMobjSpawnHeight (const mobjtype_t i, const mapthing_t* mthing, const fixed_t x, const fixed_t y) +{ + subsector_t *ss = R_PointInSubsector(x, y); + fixed_t z; + fixed_t extraoffset = 0; + fixed_t heightoffset = 0; + boolean flip; + + switch (i) + { + // Bumpers never spawn flipped. + case MT_NIGHTSBUMPER: + flip = false; + break; + + // Axis objects snap to the floor. + case MT_AXIS: + case MT_AXISTRANSFER: + case MT_AXISTRANSFERLINE: + return ONFLOORZ; + + // Objects with a non-zero default height. + case MT_CRAWLACOMMANDER: + case MT_DETON: + case MT_JETTBOMBER: + case MT_JETTGUNNER: + case MT_EGGMOBILE2: + heightoffset = mthing->z ? 0 : 33*FRACUNIT; + goto atend; + case MT_EGGMOBILE: + heightoffset = mthing->z ? 0 : 128*FRACUNIT; + goto atend; + case MT_GOLDBUZZ: + case MT_REDBUZZ: + heightoffset = mthing->z ? 0 : 288*FRACUNIT; + goto atend; + + // Ring-like items, may float additional units with MTF_AMBUSH. + case MT_SPIKEBALL: + case MT_EMERALDSPAWN: + case MT_TOKEN: + case MT_EMBLEM: + weaponfloat: + flip = mthing->options & MTF_OBJECTFLIP; + extraoffset = mthing->options & MTF_AMBUSH ? 24*FRACUNIT : 0; + heightoffset = mthing->z*FRACUNIT; + break; + + // Remaining objects. + default: + if (P_WeaponOrPanel(i)) + goto weaponfloat; // Ring-like items don't use MF_SPAWNCEILING to consider flips. + + atend: + heightoffset = mthing->z*FRACUNIT; + flip = (!!(mobjinfo[i].flags & MF_SPAWNCEILING) ^ !!(mthing->options & MTF_OBJECTFLIP)); + } + + // Establish height. + if (flip) + return ( +#ifdef ESLOPE + ss->sector->c_slope ? P_GetZAt(ss->sector->c_slope, x, y) : +#endif + ss->sector->ceilingheight) - extraoffset - mobjinfo[i].height; + else + return ( +#ifdef ESLOPE + ss->sector->f_slope ? P_GetZAt(ss->sector->f_slope, x, y) : +#endif + ss->sector->floorheight) + extraoffset + heightoffset; +} + // // P_SpawnMapThing // The fields of the mapthing should @@ -11560,7 +11634,6 @@ void P_SpawnMapThing(mapthing_t *mthing) mobjtype_t i; mobj_t *mobj; fixed_t x, y, z; - subsector_t *ss; boolean doangle = true; if (!mthing->type) @@ -11685,13 +11758,6 @@ You should think about modifying the deathmatch starts to take full advantage of if (gametype != GT_COOP) return; - ss = R_PointInSubsector(mthing->x << FRACBITS, mthing->y << FRACBITS); - mthing->z = (INT16)((( -#ifdef ESLOPE - ss->sector->f_slope ? P_GetZAt(ss->sector->f_slope, mthing->x << FRACBITS, mthing->y << FRACBITS) : -#endif - ss->sector->floorheight)>>FRACBITS) + (mthing->options >> ZSHIFT)); - if (numhuntemeralds < MAXHUNTEMERALDS) huntemeralds[numhuntemeralds++] = mthing; return; @@ -11820,102 +11886,7 @@ You should think about modifying the deathmatch starts to take full advantage of // spawn it x = mthing->x << FRACBITS; y = mthing->y << FRACBITS; - ss = R_PointInSubsector(x, y); - - if (i == MT_NIGHTSBUMPER) - z = ( -#ifdef ESLOPE - ss->sector->f_slope ? P_GetZAt(ss->sector->f_slope, x, y) : -#endif - ss->sector->floorheight) + ((mthing->options >> ZSHIFT) << FRACBITS); - else if (i == MT_AXIS || i == MT_AXISTRANSFER || i == MT_AXISTRANSFERLINE) - z = ONFLOORZ; - else if (i == MT_SPIKEBALL || P_WeaponOrPanel(i) || i == MT_EMERALDSPAWN || i == MT_TOKEN || i == MT_EMBLEM) - { - if (mthing->options & MTF_OBJECTFLIP) - { - z = ( -#ifdef ESLOPE - ss->sector->c_slope ? P_GetZAt(ss->sector->c_slope, x, y) : -#endif - ss->sector->ceilingheight); - - if (mthing->options & MTF_AMBUSH) // Special flag for rings - z -= 24*FRACUNIT; - if (mthing->options >> ZSHIFT) - z -= (mthing->options >> ZSHIFT)*FRACUNIT; - - z -= mobjinfo[i].height; //Don't forget the height! - } - else - { - z = ( -#ifdef ESLOPE - ss->sector->f_slope ? P_GetZAt(ss->sector->f_slope, x, y) : -#endif - ss->sector->floorheight); - - if (mthing->options & MTF_AMBUSH) // Special flag for rings - z += 24*FRACUNIT; - if (mthing->options >> ZSHIFT) - z += (mthing->options >> ZSHIFT)*FRACUNIT; - } - - if (z == ONFLOORZ) - mthing->z = 0; - else - mthing->z = (INT16)(z>>FRACBITS); - } - else - { - fixed_t offset = 0; - boolean flip = (!!(mobjinfo[i].flags & MF_SPAWNCEILING) ^ !!(mthing->options & MTF_OBJECTFLIP)); - - // base positions - if (flip) - z = ( -#ifdef ESLOPE - ss->sector->c_slope ? P_GetZAt(ss->sector->c_slope, x, y) : -#endif - ss->sector->ceilingheight) - mobjinfo[i].height; - else - z = ( -#ifdef ESLOPE - ss->sector->f_slope ? P_GetZAt(ss->sector->f_slope, x, y) : -#endif - ss->sector->floorheight); - - // offsetting - if (mthing->options >> ZSHIFT) - offset = ((mthing->options >> ZSHIFT) << FRACBITS); - else if (i == MT_CRAWLACOMMANDER || i == MT_DETON || i == MT_JETTBOMBER || i == MT_JETTGUNNER || i == MT_EGGMOBILE2) - offset = 33*FRACUNIT; - else if (i == MT_EGGMOBILE) - offset = 128*FRACUNIT; - else if (i == MT_GOLDBUZZ || i == MT_REDBUZZ) - offset = 288*FRACUNIT; - - // applying offsets! (if any) - if (flip) - { - if (offset) - z -= offset; - else - z = ONCEILINGZ; - } - else - { - if (offset) - z += offset; - else - z = ONFLOORZ; - } - - if (z == ONFLOORZ) - mthing->z = 0; - else - mthing->z = (INT16)(z>>FRACBITS); - } + z = GetMobjSpawnHeight(i, mthing, x, y); mobj = P_SpawnMobj(x, y, z, i); mobj->spawnpoint = mthing; @@ -12019,7 +11990,7 @@ You should think about modifying the deathmatch starts to take full advantage of if (mthing->angle) mobj->health = mthing->angle; else - mobj->health = FixedMul(ss->sector->ceilingheight-ss->sector->floorheight, 3*(FRACUNIT/4))>>FRACBITS; + mobj->health = FixedMul(mobj->subsector->sector->ceilingheight - mobj->subsector->sector->floorheight, 3*(FRACUNIT/4))>>FRACBITS; break; case MT_METALSONIC_RACE: case MT_METALSONIC_BATTLE: diff --git a/src/p_setup.c b/src/p_setup.c index 86cc9d810..d40c728ab 100644 --- a/src/p_setup.c +++ b/src/p_setup.c @@ -1025,10 +1025,10 @@ static void P_PrepareRawThings(UINT8 *data, size_t i) mt->type &= 4095; - if (mt->type == 1705 || (mt->type == 750 && mt->extrainfo)) // NiGHTS Hoops - mt->z = mthing->options; + if (mt->type == 1705 || (mt->type == 750 && mt->extrainfo)) + mt->z = mt->options; // NiGHTS Hoops use the full flags bits to set the height. else - mt->z = mthing->options >> ZSHIFT; + mt->z = mt->options >> ZSHIFT; } } From 9ab00049dcaefee2aa872d26602e13bf6a08ab44 Mon Sep 17 00:00:00 2001 From: Steel Titanium Date: Tue, 10 Dec 2019 12:53:15 -0500 Subject: [PATCH 096/746] appveyor: Forgot to change version to 2.2.0 --- appveyor.yml | 290 +++++++++++++++++++++++++-------------------------- 1 file changed, 145 insertions(+), 145 deletions(-) diff --git a/appveyor.yml b/appveyor.yml index d58976fd5..90ee0048a 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -1,145 +1,145 @@ -version: 2.1.25.{branch}-{build} -os: MinGW - -environment: - CC: ccache - CCACHE_CC: i686-w64-mingw32-gcc - CCACHE_CC_64: x86_64-w64-mingw32-gcc - WINDRES: windres - # c:\mingw-w64 i686 has gcc 6.3.0, so use c:\msys64 7.3.0 instead - MINGW_SDK: c:\msys64\mingw32 - # c:\msys64 x86_64 has gcc 8.2.0, so use c:\mingw-w64 7.3.0 instead - MINGW_SDK_64: C:\mingw-w64\x86_64-7.3.0-posix-seh-rt_v5-rev0\mingw64 - CFLAGS: -Wall -W -Werror -Wno-error=implicit-fallthrough -Wimplicit-fallthrough=3 -Wno-tautological-compare -Wno-error=suggest-attribute=noreturn - NASM_ZIP: nasm-2.12.01 - NASM_URL: http://www.nasm.us/pub/nasm/releasebuilds/2.12.01/win64/nasm-2.12.01-win64.zip - UPX_ZIP: upx391w - UPX_URL: http://upx.sourceforge.net/download/upx391w.zip - CCACHE_EXE: ccache.exe - CCACHE_URL: http://alam.srb2.org/ccache.exe - CCACHE_COMPRESS: true - CCACHE_DIR: C:\Users\appveyor\.ccache - # Disable UPX by default. The user can override this in their Appveyor project settings - NOUPX: 1 - ############################## - # DEPLOYER VARIABLES - # DPL_ENABLED=1 builds installers for branch names starting with `deployer`. - # DPL_TAG_ENABLED=1 will also build installers for release tags. DPL_ENABLED=1 must also be set. - # Set these in the Appveyor project settings - ############################## - DPL_ENABLED: 0 - DPL_TAG_ENABLED: 0 - DPL_INSTALLER_NAME: SRB2-v2123 - # Asset handling is barebones vs. Travis Deployer. We operate on 7z only. - # Include the README files and the OpenGL batch in the main and patch archives. - # The x86/x64 archives contain the DLL binaries. - ASSET_ARCHIVE_PATH: https://github.com/mazmazz/SRB2/releases/download/SRB2_assets/SRB2-v2122-assets.7z - ASSET_ARCHIVE_PATCH_PATH: https://github.com/mazmazz/SRB2/releases/download/SRB2_assets/SRB2-v2122-patch-assets.7z - ASSET_ARCHIVE_X86_PATH: https://github.com/mazmazz/SRB2/releases/download/SRB2_assets/SRB2-v2122-x86-assets.7z - ASSET_ARCHIVE_X64_PATH: https://github.com/mazmazz/SRB2/releases/download/SRB2_assets/SRB2-v2122-x64-assets.7z - ASSET_ARCHIVE_OPTIONAL_PATH: https://github.com/mazmazz/SRB2/releases/download/SRB2_assets/SRB2-v2122-optional-assets.7z - # This is overridden to 1 for release tag builds - ASSET_FILES_OPTIONAL_GET: 0 - # For patches, also include the X86/X64 DLLs. - PACKAGE_PATCH_DLL_GET: 0 - # Delete all asset downloads so they can be redownloaded - ASSET_CLEAN: 0 - -cache: -- nasm-2.12.01.zip -- upx391w.zip -- ccache.exe -- C:\Users\appveyor\.ccache -- C:\Users\appveyor\srb2_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%" ) - -- if not exist "%NASM_ZIP%.zip" appveyor DownloadFile "%NASM_URL%" -FileName "%NASM_ZIP%.zip" -- 7z x -y "%NASM_ZIP%.zip" -o%TMP% >null -- robocopy /S /xx /ns /nc /nfl /ndl /np /njh /njs "%TMP%\%NASM_ZIP%" "%MINGW_SDK%\bin" nasm.exe || exit 0 - -- if not exist "%UPX_ZIP%.zip" appveyor DownloadFile "%UPX_URL%" -FileName "%UPX_ZIP%.zip" -- 7z x -y "%UPX_ZIP%.zip" -o%TMP% >null -- robocopy /S /xx /ns /nc /nfl /ndl /np /njh /njs "%TMP%\%UPX_ZIP%" "%MINGW_SDK%\bin" upx.exe || exit 0 - -- if not exist "%CCACHE_EXE%" appveyor DownloadFile "%CCACHE_URL%" -FileName "%CCACHE_EXE%" -- ccache -M 99M -- xcopy /Y /V /I ccache.exe "%MINGW_SDK%\bin" - -configuration: -- SDL -- SDL64 -- DD -- DD64 - -matrix: - allow_failures: - - configuration: DD - - configuration: DD64 - -before_build: -- set "Path=%MINGW_SDK%\bin;%Path%" -- if [%X86_64%] == [1] ( x86_64-w64-mingw32-gcc --version ) else ( i686-w64-mingw32-gcc --version ) -- mingw32-make --version -- if not [%X86_64%] == [1] ( nasm -v ) -- if not [%NOUPX%] == [1] ( upx -V ) -- ccache -V -- ccache -s -- if [%NOUPX%] == [1] ( set "NOUPX=NOUPX=1" ) else ( set "NOUPX=" ) -- set "SRB2_MFLAGS=-C src WARNINGMODE=1 CCACHE=1 GCC73=1 NOOBJDUMP=1 %NOUPX%" -- if [%X86_64%] == [1] ( set "MINGW_FLAGS=MINGW64=1 X86_64=1" ) else ( set "MINGW_FLAGS=MINGW=1 GCC91=1" ) -- set "SRB2_MFLAGS=%SRB2_MFLAGS% %MINGW_FLAGS% %CONFIGURATION%=1" - -build_script: -- cmd: mingw32-make.exe %SRB2_MFLAGS% clean -- cmd: mingw32-make.exe %SRB2_MFLAGS% ERRORMODE=1 -k - -after_build: -- if [%X86_64%] == [1] ( - set "BUILD_PATH=bin\Mingw64\Release" - ) else ( - set "BUILD_PATH=bin\Mingw\Release" - ) -- if [%X86_64%] == [1] ( set "CONFIGURATION=%CONFIGURATION%64" ) -- ccache -s -- cmd: git rev-parse --short %APPVEYOR_REPO_COMMIT%>%TMP%/gitshort.txt -- cmd: set /P GITSHORT=<%TMP%/gitshort.txt -- set BUILD_ARCHIVE=%APPVEYOR_REPO_BRANCH%-%GITSHORT%-%CONFIGURATION%.7z -- set BUILDSARCHIVE=%APPVEYOR_REPO_BRANCH%-%CONFIGURATION%.7z -- cmd: 7z a %BUILD_ARCHIVE% %BUILD_PATH% -xr!.gitignore -- appveyor PushArtifact %BUILD_ARCHIVE% -- cmd: copy %BUILD_ARCHIVE% %BUILDSARCHIVE% -- appveyor PushArtifact %BUILDSARCHIVE% -############################## -# DEPLOYER SCRIPT -############################## -- if [%DPL_ENABLED%] == [1] ( call "deployer\appveyor\deployer.bat" ) - -test: off - -#deploy: -# - provider: FTP -# protocol: ftps -# host: -# secure: NsLJEPIBvmwCOj8Tg8RoRQ== -# username: -# secure: ejxi5mvk7oLYu7QtbYojajEPigMy0mokaKhuEVuDZcA= -# password: -# secure: Hbn6Uy3lT0YZ88yFJ3aW4w== -# folder: appveyor -# application: -# active_mode: false -# on: -# branch: master -# appveyor_repo_tag: true - - -on_finish: -#- cmd: echo xfreerdp /u:appveyor /cert-ignore +clipboard /v:: -#- ps: $blockRdp = $true; iex ((new-object net.webclient).DownloadString('https://raw.githubusercontent.com/appveyor/ci/master/scripts/enable-rdp.ps1')) +version: 2.2.0.{branch}-{build} +os: MinGW + +environment: + CC: ccache + CCACHE_CC: i686-w64-mingw32-gcc + CCACHE_CC_64: x86_64-w64-mingw32-gcc + WINDRES: windres + # c:\mingw-w64 i686 has gcc 6.3.0, so use c:\msys64 7.3.0 instead + MINGW_SDK: c:\msys64\mingw32 + # c:\msys64 x86_64 has gcc 8.2.0, so use c:\mingw-w64 7.3.0 instead + MINGW_SDK_64: C:\mingw-w64\x86_64-7.3.0-posix-seh-rt_v5-rev0\mingw64 + CFLAGS: -Wall -W -Werror -Wno-error=implicit-fallthrough -Wimplicit-fallthrough=3 -Wno-tautological-compare -Wno-error=suggest-attribute=noreturn + NASM_ZIP: nasm-2.12.01 + NASM_URL: http://www.nasm.us/pub/nasm/releasebuilds/2.12.01/win64/nasm-2.12.01-win64.zip + UPX_ZIP: upx391w + UPX_URL: http://upx.sourceforge.net/download/upx391w.zip + CCACHE_EXE: ccache.exe + CCACHE_URL: http://alam.srb2.org/ccache.exe + CCACHE_COMPRESS: true + CCACHE_DIR: C:\Users\appveyor\.ccache + # Disable UPX by default. The user can override this in their Appveyor project settings + NOUPX: 1 + ############################## + # DEPLOYER VARIABLES + # DPL_ENABLED=1 builds installers for branch names starting with `deployer`. + # DPL_TAG_ENABLED=1 will also build installers for release tags. DPL_ENABLED=1 must also be set. + # Set these in the Appveyor project settings + ############################## + DPL_ENABLED: 0 + DPL_TAG_ENABLED: 0 + DPL_INSTALLER_NAME: SRB2-v2123 + # Asset handling is barebones vs. Travis Deployer. We operate on 7z only. + # Include the README files and the OpenGL batch in the main and patch archives. + # The x86/x64 archives contain the DLL binaries. + ASSET_ARCHIVE_PATH: https://github.com/mazmazz/SRB2/releases/download/SRB2_assets/SRB2-v2122-assets.7z + ASSET_ARCHIVE_PATCH_PATH: https://github.com/mazmazz/SRB2/releases/download/SRB2_assets/SRB2-v2122-patch-assets.7z + ASSET_ARCHIVE_X86_PATH: https://github.com/mazmazz/SRB2/releases/download/SRB2_assets/SRB2-v2122-x86-assets.7z + ASSET_ARCHIVE_X64_PATH: https://github.com/mazmazz/SRB2/releases/download/SRB2_assets/SRB2-v2122-x64-assets.7z + ASSET_ARCHIVE_OPTIONAL_PATH: https://github.com/mazmazz/SRB2/releases/download/SRB2_assets/SRB2-v2122-optional-assets.7z + # This is overridden to 1 for release tag builds + ASSET_FILES_OPTIONAL_GET: 0 + # For patches, also include the X86/X64 DLLs. + PACKAGE_PATCH_DLL_GET: 0 + # Delete all asset downloads so they can be redownloaded + ASSET_CLEAN: 0 + +cache: +- nasm-2.12.01.zip +- upx391w.zip +- ccache.exe +- C:\Users\appveyor\.ccache +- C:\Users\appveyor\srb2_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%" ) + +- if not exist "%NASM_ZIP%.zip" appveyor DownloadFile "%NASM_URL%" -FileName "%NASM_ZIP%.zip" +- 7z x -y "%NASM_ZIP%.zip" -o%TMP% >null +- robocopy /S /xx /ns /nc /nfl /ndl /np /njh /njs "%TMP%\%NASM_ZIP%" "%MINGW_SDK%\bin" nasm.exe || exit 0 + +- if not exist "%UPX_ZIP%.zip" appveyor DownloadFile "%UPX_URL%" -FileName "%UPX_ZIP%.zip" +- 7z x -y "%UPX_ZIP%.zip" -o%TMP% >null +- robocopy /S /xx /ns /nc /nfl /ndl /np /njh /njs "%TMP%\%UPX_ZIP%" "%MINGW_SDK%\bin" upx.exe || exit 0 + +- if not exist "%CCACHE_EXE%" appveyor DownloadFile "%CCACHE_URL%" -FileName "%CCACHE_EXE%" +- ccache -M 99M +- xcopy /Y /V /I ccache.exe "%MINGW_SDK%\bin" + +configuration: +- SDL +- SDL64 +- DD +- DD64 + +matrix: + allow_failures: + - configuration: DD + - configuration: DD64 + +before_build: +- set "Path=%MINGW_SDK%\bin;%Path%" +- if [%X86_64%] == [1] ( x86_64-w64-mingw32-gcc --version ) else ( i686-w64-mingw32-gcc --version ) +- mingw32-make --version +- if not [%X86_64%] == [1] ( nasm -v ) +- if not [%NOUPX%] == [1] ( upx -V ) +- ccache -V +- ccache -s +- if [%NOUPX%] == [1] ( set "NOUPX=NOUPX=1" ) else ( set "NOUPX=" ) +- set "SRB2_MFLAGS=-C src WARNINGMODE=1 CCACHE=1 GCC73=1 NOOBJDUMP=1 %NOUPX%" +- if [%X86_64%] == [1] ( set "MINGW_FLAGS=MINGW64=1 X86_64=1" ) else ( set "MINGW_FLAGS=MINGW=1 GCC91=1" ) +- set "SRB2_MFLAGS=%SRB2_MFLAGS% %MINGW_FLAGS% %CONFIGURATION%=1" + +build_script: +- cmd: mingw32-make.exe %SRB2_MFLAGS% clean +- cmd: mingw32-make.exe %SRB2_MFLAGS% ERRORMODE=1 -k + +after_build: +- if [%X86_64%] == [1] ( + set "BUILD_PATH=bin\Mingw64\Release" + ) else ( + set "BUILD_PATH=bin\Mingw\Release" + ) +- if [%X86_64%] == [1] ( set "CONFIGURATION=%CONFIGURATION%64" ) +- ccache -s +- cmd: git rev-parse --short %APPVEYOR_REPO_COMMIT%>%TMP%/gitshort.txt +- cmd: set /P GITSHORT=<%TMP%/gitshort.txt +- set BUILD_ARCHIVE=%APPVEYOR_REPO_BRANCH%-%GITSHORT%-%CONFIGURATION%.7z +- set BUILDSARCHIVE=%APPVEYOR_REPO_BRANCH%-%CONFIGURATION%.7z +- cmd: 7z a %BUILD_ARCHIVE% %BUILD_PATH% -xr!.gitignore +- appveyor PushArtifact %BUILD_ARCHIVE% +- cmd: copy %BUILD_ARCHIVE% %BUILDSARCHIVE% +- appveyor PushArtifact %BUILDSARCHIVE% +############################## +# DEPLOYER SCRIPT +############################## +- if [%DPL_ENABLED%] == [1] ( call "deployer\appveyor\deployer.bat" ) + +test: off + +#deploy: +# - provider: FTP +# protocol: ftps +# host: +# secure: NsLJEPIBvmwCOj8Tg8RoRQ== +# username: +# secure: ejxi5mvk7oLYu7QtbYojajEPigMy0mokaKhuEVuDZcA= +# password: +# secure: Hbn6Uy3lT0YZ88yFJ3aW4w== +# folder: appveyor +# application: +# active_mode: false +# on: +# branch: master +# appveyor_repo_tag: true + + +on_finish: +#- cmd: echo xfreerdp /u:appveyor /cert-ignore +clipboard /v:: +#- ps: $blockRdp = $true; iex ((new-object net.webclient).DownloadString('https://raw.githubusercontent.com/appveyor/ci/master/scripts/enable-rdp.ps1')) From ca6a7ffbb3e720cc99c1355a58a51f15fdd97282 Mon Sep 17 00:00:00 2001 From: Nev3r Date: Tue, 10 Dec 2019 18:53:49 +0100 Subject: [PATCH 097/746] Fix NiGHTS bumpers height. --- src/p_mobj.c | 1 + 1 file changed, 1 insertion(+) diff --git a/src/p_mobj.c b/src/p_mobj.c index e64fb1537..3321107c7 100644 --- a/src/p_mobj.c +++ b/src/p_mobj.c @@ -11563,6 +11563,7 @@ static fixed_t GetMobjSpawnHeight (const mobjtype_t i, const mapthing_t* mthing, { // Bumpers never spawn flipped. case MT_NIGHTSBUMPER: + heightoffset = mthing->z*FRACUNIT; flip = false; break; From f51253a0a8ade242e4fa085ab76230d5dae2705a Mon Sep 17 00:00:00 2001 From: Jaime Passos Date: Tue, 10 Dec 2019 17:01:19 -0300 Subject: [PATCH 098/746] Tilted water --- src/r_draw.c | 3 +- src/r_draw.h | 6 +- src/r_draw8.c | 285 +++++++++++++++++++++++++++++++++++++++++++------- src/r_plane.c | 233 +++++++++++++++++++++++++---------------- 4 files changed, 397 insertions(+), 130 deletions(-) diff --git a/src/r_draw.c b/src/r_draw.c index db64805a4..ec53d79fc 100644 --- a/src/r_draw.c +++ b/src/r_draw.c @@ -107,7 +107,8 @@ UINT8 *ds_transmap; // one of the translucency tables #ifdef ESLOPE pslope_t *ds_slope; // Current slope being used -floatv3_t ds_su, ds_sv, ds_sz; // Vectors for... stuff? +floatv3_t ds_su[MAXVIDHEIGHT], ds_sv[MAXVIDHEIGHT], ds_sz[MAXVIDHEIGHT]; // Vectors for... stuff? +floatv3_t *ds_sup, *ds_svp, *ds_szp; float focallengthf, zeroheight; #endif diff --git a/src/r_draw.h b/src/r_draw.h index d033f221d..392eb3827 100644 --- a/src/r_draw.h +++ b/src/r_draw.h @@ -68,7 +68,8 @@ typedef struct { } floatv3_t; extern pslope_t *ds_slope; // Current slope being used -extern floatv3_t ds_su, ds_sv, ds_sz; // Vectors for... stuff? +extern floatv3_t ds_su[MAXVIDHEIGHT], ds_sv[MAXVIDHEIGHT], ds_sz[MAXVIDHEIGHT]; // Vectors for... stuff? +extern floatv3_t *ds_sup, *ds_svp, *ds_szp; extern float focallengthf, zeroheight; #endif @@ -163,6 +164,9 @@ void R_DrawSpan_8(void); void R_CalcTiltedLighting(fixed_t start, fixed_t end); void R_DrawTiltedSpan_8(void); void R_DrawTiltedTranslucentSpan_8(void); +#ifndef NOWATER +void R_DrawTiltedTranslucentWaterSpan_8(void); +#endif void R_DrawTiltedSplat_8(void); #endif void R_DrawSplat_8(void); diff --git a/src/r_draw8.c b/src/r_draw8.c index 11cdd5dca..609ce6d5c 100644 --- a/src/r_draw8.c +++ b/src/r_draw8.c @@ -692,22 +692,22 @@ void R_DrawTiltedSpan_8(void) double endz, endu, endv; UINT32 stepu, stepv; - iz = ds_sz.z + ds_sz.y*(centery-ds_y) + ds_sz.x*(ds_x1-centerx); + iz = ds_szp->z + ds_szp->y*(centery-ds_y) + ds_szp->x*(ds_x1-centerx); // Lighting is simple. It's just linear interpolation from start to end { float planelightfloat = BASEVIDWIDTH*BASEVIDWIDTH/vid.width / (zeroheight - FIXED_TO_FLOAT(viewz)) / 21.0f; float lightstart, lightend; - lightend = (iz + ds_sz.x*width) * planelightfloat; + lightend = (iz + ds_szp->x*width) * planelightfloat; lightstart = iz * planelightfloat; R_CalcTiltedLighting(FLOAT_TO_FIXED(lightstart), FLOAT_TO_FIXED(lightend)); //CONS_Printf("tilted lighting %f to %f (foc %f)\n", lightstart, lightend, focallengthf); } - uz = ds_su.z + ds_su.y*(centery-ds_y) + ds_su.x*(ds_x1-centerx); - vz = ds_sv.z + ds_sv.y*(centery-ds_y) + ds_sv.x*(ds_x1-centerx); + uz = ds_sup->z + ds_sup->y*(centery-ds_y) + ds_sup->x*(ds_x1-centerx); + vz = ds_svp->z + ds_svp->y*(centery-ds_y) + ds_svp->x*(ds_x1-centerx); dest = ylookup[ds_y] + columnofs[ds_x1]; source = ds_source; @@ -743,9 +743,9 @@ void R_DrawTiltedSpan_8(void) else *dest = colormap[source[((v >> nflatyshift) & nflatmask) | (u >> nflatxshift)]]; dest++; - iz += ds_sz.x; - uz += ds_su.x; - vz += ds_sv.x; + iz += ds_szp->x; + uz += ds_sup->x; + vz += ds_svp->x; } while (--width >= 0); #else #define SPANSIZE 16 @@ -755,9 +755,9 @@ void R_DrawTiltedSpan_8(void) startu = uz*startz; startv = vz*startz; - izstep = ds_sz.x * SPANSIZE; - uzstep = ds_su.x * SPANSIZE; - vzstep = ds_sv.x * SPANSIZE; + izstep = ds_szp->x * SPANSIZE; + uzstep = ds_sup->x * SPANSIZE; + vzstep = ds_svp->x * SPANSIZE; //x1 = 0; width++; @@ -833,9 +833,9 @@ void R_DrawTiltedSpan_8(void) else { double left = width; - iz += ds_sz.x * left; - uz += ds_su.x * left; - vz += ds_sv.x * left; + iz += ds_szp->x * left; + uz += ds_sup->x * left; + vz += ds_svp->x * left; endz = 1.f/iz; endu = uz*endz; @@ -896,22 +896,22 @@ void R_DrawTiltedTranslucentSpan_8(void) double endz, endu, endv; UINT32 stepu, stepv; - iz = ds_sz.z + ds_sz.y*(centery-ds_y) + ds_sz.x*(ds_x1-centerx); + iz = ds_szp->z + ds_szp->y*(centery-ds_y) + ds_szp->x*(ds_x1-centerx); // Lighting is simple. It's just linear interpolation from start to end { float planelightfloat = BASEVIDWIDTH*BASEVIDWIDTH/vid.width / (zeroheight - FIXED_TO_FLOAT(viewz)) / 21.0f; float lightstart, lightend; - lightend = (iz + ds_sz.x*width) * planelightfloat; + lightend = (iz + ds_szp->x*width) * planelightfloat; lightstart = iz * planelightfloat; R_CalcTiltedLighting(FLOAT_TO_FIXED(lightstart), FLOAT_TO_FIXED(lightend)); //CONS_Printf("tilted lighting %f to %f (foc %f)\n", lightstart, lightend, focallengthf); } - uz = ds_su.z + ds_su.y*(centery-ds_y) + ds_su.x*(ds_x1-centerx); - vz = ds_sv.z + ds_sv.y*(centery-ds_y) + ds_sv.x*(ds_x1-centerx); + uz = ds_sup->z + ds_sup->y*(centery-ds_y) + ds_sup->x*(ds_x1-centerx); + vz = ds_svp->z + ds_svp->y*(centery-ds_y) + ds_svp->x*(ds_x1-centerx); dest = ylookup[ds_y] + columnofs[ds_x1]; source = ds_source; @@ -946,9 +946,9 @@ void R_DrawTiltedTranslucentSpan_8(void) else *dest = *(ds_transmap + (colormap[source[((v >> nflatyshift) & nflatmask) | (u >> nflatxshift)]] << 8) + *dest); dest++; - iz += ds_sz.x; - uz += ds_su.x; - vz += ds_sv.x; + iz += ds_szp->x; + uz += ds_sup->x; + vz += ds_svp->x; } while (--width >= 0); #else #define SPANSIZE 16 @@ -958,9 +958,9 @@ void R_DrawTiltedTranslucentSpan_8(void) startu = uz*startz; startv = vz*startz; - izstep = ds_sz.x * SPANSIZE; - uzstep = ds_su.x * SPANSIZE; - vzstep = ds_sv.x * SPANSIZE; + izstep = ds_szp->x * SPANSIZE; + uzstep = ds_sup->x * SPANSIZE; + vzstep = ds_svp->x * SPANSIZE; //x1 = 0; width++; @@ -1036,9 +1036,9 @@ void R_DrawTiltedTranslucentSpan_8(void) else { double left = width; - iz += ds_sz.x * left; - uz += ds_su.x * left; - vz += ds_sv.x * left; + iz += ds_szp->x * left; + uz += ds_sup->x * left; + vz += ds_svp->x * left; endz = 1.f/iz; endu = uz*endz; @@ -1079,6 +1079,213 @@ void R_DrawTiltedTranslucentSpan_8(void) #endif } +#ifndef NOWATER +/** \brief The R_DrawTiltedTranslucentWaterSpan_8 function + Like DrawTiltedTranslucentSpan, but for water +*/ +void R_DrawTiltedTranslucentWaterSpan_8(void) +{ + // x1, x2 = ds_x1, ds_x2 + int width = ds_x2 - ds_x1; + double iz, uz, vz; + UINT32 u, v; + int i; + + UINT8 *source; + UINT8 *colormap; + UINT8 *dest; + UINT8 *dsrc; + + double startz, startu, startv; + double izstep, uzstep, vzstep; + double endz, endu, endv; + UINT32 stepu, stepv; + + iz = ds_szp->z + ds_szp->y*(centery-ds_y) + ds_szp->x*(ds_x1-centerx); + + // Lighting is simple. It's just linear interpolation from start to end + { + float planelightfloat = BASEVIDWIDTH*BASEVIDWIDTH/vid.width / (zeroheight - FIXED_TO_FLOAT(viewz)) / 21.0f; + float lightstart, lightend; + + lightend = (iz + ds_szp->x*width) * planelightfloat; + lightstart = iz * planelightfloat; + + R_CalcTiltedLighting(FLOAT_TO_FIXED(lightstart), FLOAT_TO_FIXED(lightend)); + //CONS_Printf("tilted lighting %f to %f (foc %f)\n", lightstart, lightend, focallengthf); + } + + uz = ds_sup->z + ds_sup->y*(centery-ds_y) + ds_sup->x*(ds_x1-centerx); + vz = ds_svp->z + ds_svp->y*(centery-ds_y) + ds_svp->x*(ds_x1-centerx); + + dest = ylookup[ds_y] + columnofs[ds_x1]; + dsrc = screens[1] + (ds_y+ds_bgofs)*vid.width + ds_x1; + source = ds_source; + //colormap = ds_colormap; + +#if 0 // The "perfect" reference version of this routine. Pretty slow. + // Use it only to see how things are supposed to look. + i = 0; + do + { + double z = 1.f/iz; + u = (INT64)(uz*z) + viewx; + v = (INT64)(vz*z) + viewy; + + colormap = planezlight[tiltlighting[ds_x1++]] + (ds_colormap - colormaps); + if (!ds_powersoftwo) + { + fixed_t x = (((fixed_t)u-viewx) >> FRACBITS); + fixed_t y = (((fixed_t)v-viewy) >> FRACBITS); + + // Carefully align all of my Friends. + if (x < 0) + x = ds_flatwidth - ((UINT32)(ds_flatwidth - x) % ds_flatwidth); + if (y < 0) + y = ds_flatheight - ((UINT32)(ds_flatheight - y) % ds_flatheight); + + x %= ds_flatwidth; + y %= ds_flatheight; + + *dest = *(ds_transmap + (colormap[source[((y * ds_flatwidth) + x)]] << 8) + *dsrc++); + } + else + *dest = *(ds_transmap + (colormap[source[((v >> nflatyshift) & nflatmask) | (u >> nflatxshift)]] << 8) + *dsrc++); + dest++; + iz += ds_szp->x; + uz += ds_sup->x; + vz += ds_svp->x; + } while (--width >= 0); +#else +#define SPANSIZE 16 +#define INVSPAN 0.0625f + + startz = 1.f/iz; + startu = uz*startz; + startv = vz*startz; + + izstep = ds_szp->x * SPANSIZE; + uzstep = ds_sup->x * SPANSIZE; + vzstep = ds_svp->x * SPANSIZE; + //x1 = 0; + width++; + + while (width >= SPANSIZE) + { + iz += izstep; + uz += uzstep; + vz += vzstep; + + endz = 1.f/iz; + endu = uz*endz; + endv = vz*endz; + stepu = (INT64)((endu - startu) * INVSPAN); + stepv = (INT64)((endv - startv) * INVSPAN); + u = (INT64)(startu) + viewx; + v = (INT64)(startv) + viewy; + + for (i = SPANSIZE-1; i >= 0; i--) + { + colormap = planezlight[tiltlighting[ds_x1++]] + (ds_colormap - colormaps); + if (!ds_powersoftwo) + { + fixed_t x = (((fixed_t)u-viewx) >> FRACBITS); + fixed_t y = (((fixed_t)v-viewy) >> FRACBITS); + + // Carefully align all of my Friends. + if (x < 0) + x = ds_flatwidth - ((UINT32)(ds_flatwidth - x) % ds_flatwidth); + if (y < 0) + y = ds_flatheight - ((UINT32)(ds_flatheight - y) % ds_flatheight); + + x %= ds_flatwidth; + y %= ds_flatheight; + + *dest = *(ds_transmap + (colormap[source[((y * ds_flatwidth) + x)]] << 8) + *dsrc++); + } + else + *dest = *(ds_transmap + (colormap[source[((v >> nflatyshift) & nflatmask) | (u >> nflatxshift)]] << 8) + *dsrc++); + dest++; + u += stepu; + v += stepv; + } + startu = endu; + startv = endv; + width -= SPANSIZE; + } + if (width > 0) + { + if (width == 1) + { + u = (INT64)(startu); + v = (INT64)(startv); + colormap = planezlight[tiltlighting[ds_x1++]] + (ds_colormap - colormaps); + if (!ds_powersoftwo) + { + fixed_t x = (((fixed_t)u-viewx) >> FRACBITS); + fixed_t y = (((fixed_t)v-viewy) >> FRACBITS); + + // Carefully align all of my Friends. + if (x < 0) + x = ds_flatwidth - ((UINT32)(ds_flatwidth - x) % ds_flatwidth); + if (y < 0) + y = ds_flatheight - ((UINT32)(ds_flatheight - y) % ds_flatheight); + + x %= ds_flatwidth; + y %= ds_flatheight; + + *dest = *(ds_transmap + (colormap[source[((y * ds_flatwidth) + x)]] << 8) + *dsrc++); + } + else + *dest = *(ds_transmap + (colormap[source[((v >> nflatyshift) & nflatmask) | (u >> nflatxshift)]] << 8) + *dsrc++); + } + else + { + double left = width; + iz += ds_szp->x * left; + uz += ds_sup->x * left; + vz += ds_svp->x * left; + + endz = 1.f/iz; + endu = uz*endz; + endv = vz*endz; + left = 1.f/left; + stepu = (INT64)((endu - startu) * left); + stepv = (INT64)((endv - startv) * left); + u = (INT64)(startu) + viewx; + v = (INT64)(startv) + viewy; + + for (; width != 0; width--) + { + colormap = planezlight[tiltlighting[ds_x1++]] + (ds_colormap - colormaps); + if (!ds_powersoftwo) + { + fixed_t x = (((fixed_t)u-viewx) >> FRACBITS); + fixed_t y = (((fixed_t)v-viewy) >> FRACBITS); + + // Carefully align all of my Friends. + if (x < 0) + x = ds_flatwidth - ((UINT32)(ds_flatwidth - x) % ds_flatwidth); + if (y < 0) + y = ds_flatheight - ((UINT32)(ds_flatheight - y) % ds_flatheight); + + x %= ds_flatwidth; + y %= ds_flatheight; + + *dest = *(ds_transmap + (colormap[source[((y * ds_flatwidth) + x)]] << 8) + *dsrc++); + } + else + *dest = *(ds_transmap + (colormap[source[((v >> nflatyshift) & nflatmask) | (u >> nflatxshift)]] << 8) + *dsrc++); + dest++; + u += stepu; + v += stepv; + } + } + } +#endif +} +#endif // NOWATER + void R_DrawTiltedSplat_8(void) { // x1, x2 = ds_x1, ds_x2 @@ -1098,22 +1305,22 @@ void R_DrawTiltedSplat_8(void) double endz, endu, endv; UINT32 stepu, stepv; - iz = ds_sz.z + ds_sz.y*(centery-ds_y) + ds_sz.x*(ds_x1-centerx); + iz = ds_szp->z + ds_szp->y*(centery-ds_y) + ds_szp->x*(ds_x1-centerx); // Lighting is simple. It's just linear interpolation from start to end { float planelightfloat = BASEVIDWIDTH*BASEVIDWIDTH/vid.width / (zeroheight - FIXED_TO_FLOAT(viewz)) / 21.0f; float lightstart, lightend; - lightend = (iz + ds_sz.x*width) * planelightfloat; + lightend = (iz + ds_szp->x*width) * planelightfloat; lightstart = iz * planelightfloat; R_CalcTiltedLighting(FLOAT_TO_FIXED(lightstart), FLOAT_TO_FIXED(lightend)); //CONS_Printf("tilted lighting %f to %f (foc %f)\n", lightstart, lightend, focallengthf); } - uz = ds_su.z + ds_su.y*(centery-ds_y) + ds_su.x*(ds_x1-centerx); - vz = ds_sv.z + ds_sv.y*(centery-ds_y) + ds_sv.x*(ds_x1-centerx); + uz = ds_sup->z + ds_sup->y*(centery-ds_y) + ds_sup->x*(ds_x1-centerx); + vz = ds_svp->z + ds_svp->y*(centery-ds_y) + ds_svp->x*(ds_x1-centerx); dest = ylookup[ds_y] + columnofs[ds_x1]; source = ds_source; @@ -1153,9 +1360,9 @@ void R_DrawTiltedSplat_8(void) *dest = colormap[val]; dest++; - iz += ds_sz.x; - uz += ds_su.x; - vz += ds_sv.x; + iz += ds_szp->x; + uz += ds_sup->x; + vz += ds_svp->x; } while (--width >= 0); #else #define SPANSIZE 16 @@ -1165,9 +1372,9 @@ void R_DrawTiltedSplat_8(void) startu = uz*startz; startv = vz*startz; - izstep = ds_sz.x * SPANSIZE; - uzstep = ds_su.x * SPANSIZE; - vzstep = ds_sv.x * SPANSIZE; + izstep = ds_szp->x * SPANSIZE; + uzstep = ds_sup->x * SPANSIZE; + vzstep = ds_svp->x * SPANSIZE; //x1 = 0; width++; @@ -1247,9 +1454,9 @@ void R_DrawTiltedSplat_8(void) else { double left = width; - iz += ds_sz.x * left; - uz += ds_su.x * left; - vz += ds_sv.x * left; + iz += ds_szp->x * left; + uz += ds_sup->x * left; + vz += ds_svp->x * left; endz = 1.f/iz; endu = uz*endz; diff --git a/src/r_plane.c b/src/r_plane.c index f96e7950e..97a4ca9f8 100644 --- a/src/r_plane.c +++ b/src/r_plane.c @@ -190,6 +190,15 @@ void R_MapPlane(INT32 y, INT32 x1, INT32 x2) ds_xfrac += FixedMul(FINECOSINE(angle), (ds_bgofs<slope) + { + ds_sup = &ds_su[y]; + ds_svp = &ds_sv[y]; + ds_szp = &ds_sz[y]; + } +#endif + if (y+ds_bgofs>=viewheight) ds_bgofs = viewheight-y-1; if (y+ds_bgofs<0) @@ -833,6 +842,100 @@ static UINT8 *R_GetTextureFlat(levelflat_t *levelflat, boolean leveltexture, boo return flat; } +// Lactokaiju +#ifdef ESLOPE +static void R_SlopeVectors(visplane_t *pl, INT32 i, float fudge) +{ + // Potentially override other stuff for now cus we're mean. :< But draw a slope plane! + // I copied ZDoom's code and adapted it to SRB2... -Red + floatv3_t p, m, n; + float ang; + float vx, vy, vz; + // compiler complains when P_GetZAt is used in FLOAT_TO_FIXED directly + // use this as a temp var to store P_GetZAt's return value each time + fixed_t temp; + + vx = FIXED_TO_FLOAT(pl->viewx+xoffs); + vy = FIXED_TO_FLOAT(pl->viewy-yoffs); + vz = FIXED_TO_FLOAT(pl->viewz); + + temp = P_GetZAt(pl->slope, pl->viewx, pl->viewy); + zeroheight = FIXED_TO_FLOAT(temp); + + // p is the texture origin in view space + // Don't add in the offsets at this stage, because doing so can result in + // errors if the flat is rotated. + ang = ANG2RAD(ANGLE_270 - pl->viewangle); + p.x = vx * cos(ang) - vy * sin(ang); + p.z = vx * sin(ang) + vy * cos(ang); + temp = P_GetZAt(pl->slope, -xoffs, yoffs); + p.y = FIXED_TO_FLOAT(temp) - vz; + + // m is the v direction vector in view space + ang = ANG2RAD(ANGLE_180 - (pl->viewangle + pl->plangle)); + m.x = cos(ang); + m.z = sin(ang); + + // n is the u direction vector in view space + n.x = sin(ang); + n.z = -cos(ang); + + ang = ANG2RAD(pl->plangle); + temp = P_GetZAt(pl->slope, pl->viewx + FLOAT_TO_FIXED(sin(ang)), pl->viewy + FLOAT_TO_FIXED(cos(ang))); + m.y = FIXED_TO_FLOAT(temp) - zeroheight; + temp = P_GetZAt(pl->slope, pl->viewx + FLOAT_TO_FIXED(cos(ang)), pl->viewy - FLOAT_TO_FIXED(sin(ang))); + n.y = FIXED_TO_FLOAT(temp) - zeroheight; + + if (ds_powersoftwo) + { + m.x /= fudge; + m.y /= fudge; + m.z /= fudge; + + n.x *= fudge; + n.y *= fudge; + n.z *= fudge; + } + + // Eh. I tried making this stuff fixed-point and it exploded on me. Here's a macro for the only floating-point vector function I recall using. +#define CROSS(d, v1, v2) \ +d.x = (v1.y * v2.z) - (v1.z * v2.y);\ +d.y = (v1.z * v2.x) - (v1.x * v2.z);\ +d.z = (v1.x * v2.y) - (v1.y * v2.x) + CROSS(ds_su[i], p, m); + CROSS(ds_sv[i], p, n); + CROSS(ds_sz[i], m, n); +#undef CROSS + + ds_su[i].z *= focallengthf; + ds_sv[i].z *= focallengthf; + ds_sz[i].z *= focallengthf; + + // Premultiply the texture vectors with the scale factors +#define SFMULT 65536.f + if (ds_powersoftwo) + { + ds_su[i].x *= (SFMULT * (1<lightlevel >> LIGHTSEGSHIFT); #ifndef NOWATER - if (pl->ffloor->flags & FF_RIPPLE -#ifdef ESLOPE - && !pl->slope -#endif - ) + if (pl->ffloor->flags & FF_RIPPLE) { INT32 top, bottom; @@ -1045,25 +1144,18 @@ void R_DrawSinglePlane(visplane_t *pl) light = 0; #ifdef ESLOPE - if (pl->slope) { - // Potentially override other stuff for now cus we're mean. :< But draw a slope plane! - // I copied ZDoom's code and adapted it to SRB2... -Red - floatv3_t p, m, n; - float ang; - float vx, vy, vz; - float fudge = 0; - // compiler complains when P_GetZAt is used in FLOAT_TO_FIXED directly - // use this as a temp var to store P_GetZAt's return value each time - fixed_t temp; - + if (pl->slope) + { + float fudgecanyon = 0; angle_t hack = (pl->plangle & (ANGLE_90-1)); yoffs *= 1; if (ds_powersoftwo) { + fixed_t temp; // Okay, look, don't ask me why this works, but without this setup there's a disgusting-looking misalignment with the textures. -Red - fudge = ((1<slope->o.x + (1 << (31-nflatshiftup))) & ~((1 << (32-nflatshiftup))-1); yoffs += (pl->slope->o.y + (1 << (31-nflatshiftup))) & ~((1 << (32-nflatshiftup))-1); } - xoffs = (fixed_t)(xoffs*fudge); - yoffs = (fixed_t)(yoffs/fudge); + xoffs = (fixed_t)(xoffs*fudgecanyon); + yoffs = (fixed_t)(yoffs/fudgecanyon); } - vx = FIXED_TO_FLOAT(pl->viewx+xoffs); - vy = FIXED_TO_FLOAT(pl->viewy-yoffs); - vz = FIXED_TO_FLOAT(pl->viewz); + ds_sup = &ds_su[0]; + ds_svp = &ds_sv[0]; + ds_szp = &ds_sz[0]; - temp = P_GetZAt(pl->slope, pl->viewx, pl->viewy); - zeroheight = FIXED_TO_FLOAT(temp); - - // p is the texture origin in view space - // Don't add in the offsets at this stage, because doing so can result in - // errors if the flat is rotated. - ang = ANG2RAD(ANGLE_270 - pl->viewangle); - p.x = vx * cos(ang) - vy * sin(ang); - p.z = vx * sin(ang) + vy * cos(ang); - temp = P_GetZAt(pl->slope, -xoffs, yoffs); - p.y = FIXED_TO_FLOAT(temp) - vz; - - // m is the v direction vector in view space - ang = ANG2RAD(ANGLE_180 - (pl->viewangle + pl->plangle)); - m.x = cos(ang); - m.z = sin(ang); - - // n is the u direction vector in view space - n.x = sin(ang); - n.z = -cos(ang); - - ang = ANG2RAD(pl->plangle); - temp = P_GetZAt(pl->slope, pl->viewx + FLOAT_TO_FIXED(sin(ang)), pl->viewy + FLOAT_TO_FIXED(cos(ang))); - m.y = FIXED_TO_FLOAT(temp) - zeroheight; - temp = P_GetZAt(pl->slope, pl->viewx + FLOAT_TO_FIXED(cos(ang)), pl->viewy - FLOAT_TO_FIXED(sin(ang))); - n.y = FIXED_TO_FLOAT(temp) - zeroheight; - - if (ds_powersoftwo) +#ifndef NOWATER + if (itswater) { - m.x /= fudge; - m.y /= fudge; - m.z /= fudge; + INT32 i; + fixed_t rxoffs = xoffs; + fixed_t ryoffs = yoffs; - n.x *= fudge; - n.y *= fudge; - n.z *= fudge; - } + R_PlaneBounds(pl); - // Eh. I tried making this stuff fixed-point and it exploded on me. Here's a macro for the only floating-point vector function I recall using. -#define CROSS(d, v1, v2) \ - d.x = (v1.y * v2.z) - (v1.z * v2.y);\ - d.y = (v1.z * v2.x) - (v1.x * v2.z);\ - d.z = (v1.x * v2.y) - (v1.y * v2.x) - CROSS(ds_su, p, m); - CROSS(ds_sv, p, n); - CROSS(ds_sz, m, n); -#undef CROSS + for (i = pl->high; i < pl->low; i++) + { + // Fuck it + fixed_t plheight = abs(P_GetZAt(pl->slope, pl->viewx, pl->viewy) - pl->viewz); + fixed_t distance = FixedMul(plheight, yslope[i]); + const INT32 yay = (wtofs + (distance>>9) ) & 8191; + // ripples da water texture + ds_bgofs = FixedDiv(FINESINE(yay), (1<<12) + (distance>>11))>>FRACBITS; + angle = (pl->viewangle + pl->plangle)>>ANGLETOFINESHIFT; - ds_su.z *= focallengthf; - ds_sv.z *= focallengthf; - ds_sz.z *= focallengthf; + angle = (angle + 2048) & 8191; // 90 degrees + xoffs = rxoffs + FixedMul(FINECOSINE(angle), (ds_bgofs< Date: Tue, 10 Dec 2019 23:40:15 -0300 Subject: [PATCH 099/746] 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 054d51dac6fae047fb1f98e630642ad6beb35ce2 Mon Sep 17 00:00:00 2001 From: fickleheart Date: Tue, 10 Dec 2019 21:14:50 -0600 Subject: [PATCH 100/746] Make input turn speed tween by lateral momentum, not total --- src/g_game.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/g_game.c b/src/g_game.c index a05812768..dacf86bcf 100644 --- a/src/g_game.c +++ b/src/g_game.c @@ -1404,7 +1404,10 @@ void G_BuildTiccmd(ticcmd_t *cmd, INT32 realtics, UINT8 ssplayer) fixed_t camadjustfactor = cv_cam_turnfacinginput[forplayer].value; //@TODO cvar if (camadjustfactor) - *myangle -= cmd->sidemove * min(20, player->speed / FRACUNIT) * camadjustfactor; + { + fixed_t sine = FINESINE((R_PointToAngle2(0, 0, player->rmomx, player->rmomy) - localangle)>>ANGLETOFINESHIFT); + *myangle -= cmd->sidemove * min(20, FixedMul(player->speed, abs(sine)) / FRACUNIT) * camadjustfactor; + } } if (abilitydirection && camera.chase && !ticcmd_resetdown[forplayer] && !player->climbing && !forcestrafe && (player->pflags & PF_DIRECTIONCHAR) && player->powers[pw_carry] != CR_MINECART) From a89f8e91f792ef9c95e214cb1b746b4ec50269fb Mon Sep 17 00:00:00 2001 From: fickleheart Date: Tue, 10 Dec 2019 21:24:43 -0600 Subject: [PATCH 101/746] Change defaults and factors of simplecam options --- src/g_game.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/src/g_game.c b/src/g_game.c index dacf86bcf..3126499cf 100644 --- a/src/g_game.c +++ b/src/g_game.c @@ -409,16 +409,16 @@ consvar_t cv_cam_turnfacing[2] = { {"cam2_turnfacingchar", "0.0", CV_FLOAT|CV_SAVE, zerotoone_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL}, }; consvar_t cv_cam_turnfacingability[2] = { - {"cam_turnfacingability", "0.25", CV_FLOAT|CV_SAVE, zerotoone_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL}, - {"cam2_turnfacingability", "0.25", CV_FLOAT|CV_SAVE, zerotoone_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL}, + {"cam_turnfacingability", "0.0", CV_FLOAT|CV_SAVE, zerotoone_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL}, + {"cam2_turnfacingability", "0.0", CV_FLOAT|CV_SAVE, zerotoone_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL}, }; consvar_t cv_cam_turnfacingspindash[2] = { {"cam_turnfacingspindash", "0.25", CV_FLOAT|CV_SAVE, zerotoone_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL}, {"cam2_turnfacingspindash", "0.25", CV_FLOAT|CV_SAVE, zerotoone_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL}, }; consvar_t cv_cam_turnfacinginput[2] = { - {"cam_turnfacinginput", "0.375", CV_FLOAT|CV_SAVE, zerotoone_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL}, - {"cam2_turnfacinginput", "0.375", CV_FLOAT|CV_SAVE, zerotoone_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL}, + {"cam_turnfacinginput", "0.4375", CV_FLOAT|CV_SAVE, zerotoone_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL}, + {"cam2_turnfacinginput", "0.4375", CV_FLOAT|CV_SAVE, zerotoone_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL}, }; typedef enum @@ -1438,9 +1438,9 @@ void G_BuildTiccmd(ticcmd_t *cmd, INT32 realtics, UINT8 ssplayer) fixed_t camadjustfactor; if (player->climbing || player->pflags & PF_GLIDING) - camadjustfactor = cv_cam_turnfacingability[forplayer].value/2; + camadjustfactor = cv_cam_turnfacingability[forplayer].value/4; else if (player->pflags & PF_STARTDASH) - camadjustfactor = cv_cam_turnfacingspindash[forplayer].value/2; + camadjustfactor = cv_cam_turnfacingspindash[forplayer].value/4; else camadjustfactor = cv_cam_turnfacing[forplayer].value/8; From cdf5287fccd1fe875b230acc2a224e350c7ef8f2 Mon Sep 17 00:00:00 2001 From: fickleheart Date: Tue, 10 Dec 2019 21:34:57 -0600 Subject: [PATCH 102/746] Turn camera with strafe keys in camlock while charging spindash --- src/g_game.c | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/src/g_game.c b/src/g_game.c index 3126499cf..25f99c66f 100644 --- a/src/g_game.c +++ b/src/g_game.c @@ -1399,15 +1399,25 @@ void G_BuildTiccmd(ticcmd_t *cmd, INT32 realtics, UINT8 ssplayer) cmd->angleturn = (INT16)(*myangle >> 16); // Adjust camera angle by player input - if (abilitydirection && !forcestrafe && camera.chase && !turnheld[forplayer] && !ticcmd_resetdown[forplayer] && !player->climbing && player->powers[pw_carry] != CR_MINECART) + if (abilitydirection && !forcestrafe && camera.chase && !turnheld[forplayer] && + !(ticcmd_resetdown[forplayer] && !(player->pflags & PF_STARTDASH)) + && !player->climbing && player->powers[pw_carry] != CR_MINECART) { fixed_t camadjustfactor = cv_cam_turnfacinginput[forplayer].value; //@TODO cvar if (camadjustfactor) { fixed_t sine = FINESINE((R_PointToAngle2(0, 0, player->rmomx, player->rmomy) - localangle)>>ANGLETOFINESHIFT); - *myangle -= cmd->sidemove * min(20, FixedMul(player->speed, abs(sine)) / FRACUNIT) * camadjustfactor; + fixed_t factor = min(20, FixedMul(player->speed, abs(sine)) / FRACUNIT); + + if (ticcmd_resetdown[forplayer] && (player->pflags & PF_STARTDASH)) + factor = (ssplayer == 1 ? cv_cam_rotspeed.value : cv_cam2_rotspeed.value); // Turn while in startdash and locking camera + + *myangle -= cmd->sidemove * factor * camadjustfactor; } + + if (ticcmd_resetdown[forplayer] && (player->pflags & PF_STARTDASH)) + cmd->sidemove = 0; } if (abilitydirection && camera.chase && !ticcmd_resetdown[forplayer] && !player->climbing && !forcestrafe && (player->pflags & PF_DIRECTIONCHAR) && player->powers[pw_carry] != CR_MINECART) From 69b623e086f85c702aa48cc92e948571b2774157 Mon Sep 17 00:00:00 2001 From: fickleheart Date: Tue, 10 Dec 2019 22:01:17 -0600 Subject: [PATCH 103/746] Add option to always turn with input while locked Uhhh also camera options scrolls now. --- src/d_netcmd.c | 2 ++ src/g_game.c | 15 +++++++--- src/g_game.h | 3 +- src/m_menu.c | 78 ++++++++++++++++++++++++++++---------------------- 4 files changed, 58 insertions(+), 40 deletions(-) diff --git a/src/d_netcmd.c b/src/d_netcmd.c index 2b7bb3302..512451b85 100644 --- a/src/d_netcmd.c +++ b/src/d_netcmd.c @@ -838,6 +838,8 @@ void D_RegisterClientCommands(void) CV_RegisterVar(&cv_cam_turnfacingspindash[1]); CV_RegisterVar(&cv_cam_turnfacinginput[0]); CV_RegisterVar(&cv_cam_turnfacinginput[1]); + CV_RegisterVar(&cv_cam_lockedinput[0]); + CV_RegisterVar(&cv_cam_lockedinput[1]); // s_sound.c CV_RegisterVar(&cv_soundvolume); diff --git a/src/g_game.c b/src/g_game.c index 25f99c66f..0ba7081fa 100644 --- a/src/g_game.c +++ b/src/g_game.c @@ -421,6 +421,13 @@ consvar_t cv_cam_turnfacinginput[2] = { {"cam2_turnfacinginput", "0.4375", CV_FLOAT|CV_SAVE, zerotoone_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL}, }; +static CV_PossibleValue_t lockedinput_cons_t[] = {{0, "Strafe"}, {1, "Turn Slow"}, {2, "Turn"}, {0, NULL}}; + +consvar_t cv_cam_lockedinput[2] = { + {"cam_lockedinput", "Strafe", CV_SAVE, lockedinput_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL}, + {"cam2_lockedinput", "Strafe", CV_SAVE, lockedinput_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL}, +}; + typedef enum { AXISNONE = 0, @@ -1400,7 +1407,7 @@ void G_BuildTiccmd(ticcmd_t *cmd, INT32 realtics, UINT8 ssplayer) // Adjust camera angle by player input if (abilitydirection && !forcestrafe && camera.chase && !turnheld[forplayer] && - !(ticcmd_resetdown[forplayer] && !(player->pflags & PF_STARTDASH)) + !(ticcmd_resetdown[forplayer] && !(cv_cam_lockedinput[forplayer].value || (player->pflags & PF_STARTDASH))) && !player->climbing && player->powers[pw_carry] != CR_MINECART) { fixed_t camadjustfactor = cv_cam_turnfacinginput[forplayer].value; //@TODO cvar @@ -1410,13 +1417,13 @@ void G_BuildTiccmd(ticcmd_t *cmd, INT32 realtics, UINT8 ssplayer) fixed_t sine = FINESINE((R_PointToAngle2(0, 0, player->rmomx, player->rmomy) - localangle)>>ANGLETOFINESHIFT); fixed_t factor = min(20, FixedMul(player->speed, abs(sine)) / FRACUNIT); - if (ticcmd_resetdown[forplayer] && (player->pflags & PF_STARTDASH)) - factor = (ssplayer == 1 ? cv_cam_rotspeed.value : cv_cam2_rotspeed.value); // Turn while in startdash and locking camera + if (ticcmd_resetdown[forplayer] && (cv_cam_lockedinput[forplayer].value || (player->pflags & PF_STARTDASH))) + factor = (ssplayer == 1 ? cv_cam_rotspeed.value : cv_cam2_rotspeed.value) * (cv_cam_lockedinput[forplayer].value ?: 1); // Turn while in startdash and locking camera *myangle -= cmd->sidemove * factor * camadjustfactor; } - if (ticcmd_resetdown[forplayer] && (player->pflags & PF_STARTDASH)) + if (ticcmd_resetdown[forplayer] && (cv_cam_lockedinput[forplayer].value || (player->pflags & PF_STARTDASH))) cmd->sidemove = 0; } diff --git a/src/g_game.h b/src/g_game.h index 312e7e663..2775382c9 100644 --- a/src/g_game.h +++ b/src/g_game.h @@ -78,7 +78,8 @@ extern consvar_t cv_ghost_bestscore, cv_ghost_besttime, cv_ghost_bestrings, cv_g // hi here's some new controls extern consvar_t cv_abilitydirection[2], cv_cam_shiftfacing[2], cv_cam_turnfacing[2], - cv_cam_turnfacingability[2], cv_cam_turnfacingspindash[2], cv_cam_turnfacinginput[2]; + cv_cam_turnfacingability[2], cv_cam_turnfacingspindash[2], cv_cam_turnfacinginput[2], + cv_cam_lockedinput[2]; // mouseaiming (looking up/down with the mouse or keyboard) #define KB_LOOKSPEED (1<<25) diff --git a/src/m_menu.c b/src/m_menu.c index 6d317950d..668e6b3d6 100644 --- a/src/m_menu.c +++ b/src/m_menu.c @@ -1181,44 +1181,46 @@ static menuitem_t OP_Mouse2OptionsMenu[] = static menuitem_t OP_CameraOptionsMenu[] = { - {IT_STRING | IT_CVAR, NULL, "Third-person Camera" , &cv_chasecam , 10}, - {IT_STRING | IT_CVAR, NULL, "Flip Camera with Gravity" , &cv_flipcam , 20}, - {IT_STRING | IT_CVAR, NULL, "Orbital Looking" , &cv_cam_orbit , 30}, - {IT_STRING | IT_CVAR, NULL, "Downhill Slope Adjustment", &cv_cam_adjust, 40}, + {IT_STRING | IT_CVAR, NULL, "Third-person Camera" , &cv_chasecam , 5}, + {IT_STRING | IT_CVAR, NULL, "Flip Camera with Gravity" , &cv_flipcam , 10}, + {IT_STRING | IT_CVAR, NULL, "Orbital Looking" , &cv_cam_orbit , 15}, + {IT_STRING | IT_CVAR, NULL, "Downhill Slope Adjustment", &cv_cam_adjust, 20}, - {IT_STRING | IT_CVAR | IT_CV_INTEGERSTEP, NULL, "Camera Distance", &cv_cam_dist, 60}, - {IT_STRING | IT_CVAR | IT_CV_INTEGERSTEP, NULL, "Camera Height", &cv_cam_height, 70}, - {IT_STRING | IT_CVAR | IT_CV_FLOATSLIDER, NULL, "Camera Speed", &cv_cam_speed, 80}, - {IT_STRING | IT_CVAR | IT_CV_SLIDER, NULL, "Rotation Speed", &cv_cam_rotspeed, 90}, + {IT_STRING | IT_CVAR | IT_CV_INTEGERSTEP, NULL, "Camera Distance", &cv_cam_dist, 30}, + {IT_STRING | IT_CVAR | IT_CV_INTEGERSTEP, NULL, "Camera Height", &cv_cam_height, 35}, + {IT_STRING | IT_CVAR | IT_CV_FLOATSLIDER, NULL, "Camera Speed", &cv_cam_speed, 40}, + {IT_STRING | IT_CVAR | IT_CV_SLIDER, NULL, "Rotation Speed", &cv_cam_rotspeed, 45}, - {IT_STRING | IT_CVAR | IT_CV_SLIDER, NULL, "Shift to player angle", &cv_cam_shiftfacing[0], 100}, - {IT_STRING | IT_CVAR | IT_CV_SLIDER, NULL, "Turn to player angle", &cv_cam_turnfacing[0], 110}, - {IT_STRING | IT_CVAR | IT_CV_SLIDER, NULL, "Turn to ability", &cv_cam_turnfacingability[0], 120}, - {IT_STRING | IT_CVAR | IT_CV_SLIDER, NULL, "Turn to spindash", &cv_cam_turnfacingspindash[0], 130}, - {IT_STRING | IT_CVAR | IT_CV_SLIDER, NULL, "Turn to input", &cv_cam_turnfacinginput[0], 140}, + {IT_STRING | IT_CVAR | IT_CV_SLIDER, NULL, "Shift to player angle", &cv_cam_shiftfacing[0], 55}, + {IT_STRING | IT_CVAR | IT_CV_SLIDER, NULL, "Turn to player angle", &cv_cam_turnfacing[0], 60}, + {IT_STRING | IT_CVAR | IT_CV_SLIDER, NULL, "Turn to ability", &cv_cam_turnfacingability[0], 65}, + {IT_STRING | IT_CVAR | IT_CV_SLIDER, NULL, "Turn to spindash", &cv_cam_turnfacingspindash[0], 70}, + {IT_STRING | IT_CVAR | IT_CV_SLIDER, NULL, "Turn to input", &cv_cam_turnfacinginput[0], 75}, + {IT_STRING | IT_CVAR, NULL, "Locked movement", &cv_cam_lockedinput[0], 80}, - {IT_STRING | IT_CVAR, NULL, "Crosshair", &cv_crosshair, 160}, + {IT_STRING | IT_CVAR, NULL, "Crosshair", &cv_crosshair, 90}, }; static menuitem_t OP_Camera2OptionsMenu[] = { - {IT_STRING | IT_CVAR, NULL, "Third-person Camera" , &cv_chasecam2 , 10}, - {IT_STRING | IT_CVAR, NULL, "Flip Camera with Gravity" , &cv_flipcam2 , 20}, - {IT_STRING | IT_CVAR, NULL, "Orbital Looking" , &cv_cam2_orbit , 30}, - {IT_STRING | IT_CVAR, NULL, "Downhill Slope Adjustment", &cv_cam2_adjust, 40}, + {IT_STRING | IT_CVAR, NULL, "Third-person Camera" , &cv_chasecam2 , 5}, + {IT_STRING | IT_CVAR, NULL, "Flip Camera with Gravity" , &cv_flipcam2 , 10}, + {IT_STRING | IT_CVAR, NULL, "Orbital Looking" , &cv_cam2_orbit , 15}, + {IT_STRING | IT_CVAR, NULL, "Downhill Slope Adjustment", &cv_cam2_adjust, 20}, - {IT_STRING | IT_CVAR | IT_CV_INTEGERSTEP, NULL, "Camera Distance", &cv_cam2_dist, 60}, - {IT_STRING | IT_CVAR | IT_CV_INTEGERSTEP, NULL, "Camera Height", &cv_cam2_height, 70}, - {IT_STRING | IT_CVAR | IT_CV_FLOATSLIDER, NULL, "Camera Speed", &cv_cam2_speed, 80}, - {IT_STRING | IT_CVAR | IT_CV_SLIDER, NULL, "Rotation Speed", &cv_cam2_rotspeed, 90}, + {IT_STRING | IT_CVAR | IT_CV_INTEGERSTEP, NULL, "Camera Distance", &cv_cam2_dist, 30}, + {IT_STRING | IT_CVAR | IT_CV_INTEGERSTEP, NULL, "Camera Height", &cv_cam2_height, 35}, + {IT_STRING | IT_CVAR | IT_CV_FLOATSLIDER, NULL, "Camera Speed", &cv_cam2_speed, 40}, + {IT_STRING | IT_CVAR | IT_CV_SLIDER, NULL, "Rotation Speed", &cv_cam2_rotspeed, 45}, - {IT_STRING | IT_CVAR | IT_CV_SLIDER, NULL, "Shift to character angle", &cv_cam_shiftfacing[1], 100}, - {IT_STRING | IT_CVAR | IT_CV_SLIDER, NULL, "Turn to character angle", &cv_cam_turnfacing[1], 110}, - {IT_STRING | IT_CVAR | IT_CV_SLIDER, NULL, "Turn to ability", &cv_cam_turnfacingability[1], 120}, - {IT_STRING | IT_CVAR | IT_CV_SLIDER, NULL, "Turn to spindash", &cv_cam_turnfacingspindash[1], 130}, - {IT_STRING | IT_CVAR | IT_CV_SLIDER, NULL, "Turn to input", &cv_cam_turnfacinginput[1], 140}, + {IT_STRING | IT_CVAR | IT_CV_SLIDER, NULL, "Shift to character angle", &cv_cam_shiftfacing[1], 55}, + {IT_STRING | IT_CVAR | IT_CV_SLIDER, NULL, "Turn to character angle", &cv_cam_turnfacing[1], 60}, + {IT_STRING | IT_CVAR | IT_CV_SLIDER, NULL, "Turn to ability", &cv_cam_turnfacingability[1], 65}, + {IT_STRING | IT_CVAR | IT_CV_SLIDER, NULL, "Turn to spindash", &cv_cam_turnfacingspindash[1], 70}, + {IT_STRING | IT_CVAR | IT_CV_SLIDER, NULL, "Turn to input", &cv_cam_turnfacinginput[1], 75}, + {IT_STRING | IT_CVAR, NULL, "Locked movement", &cv_cam_lockedinput[0], 80}, - {IT_STRING | IT_CVAR, NULL, "Crosshair", &cv_crosshair2, 160}, + {IT_STRING | IT_CVAR, NULL, "Crosshair", &cv_crosshair2, 90}, }; static menuitem_t OP_VideoOptionsMenu[] = @@ -1976,10 +1978,10 @@ menu_t OP_JoystickSetDef = 0, NULL }; -menu_t OP_CameraOptionsDef = DEFAULTMENUSTYLE( +menu_t OP_CameraOptionsDef = DEFAULTSCROLLMENUSTYLE( MN_OP_MAIN + (MN_OP_P1CONTROLS << 6) + (MN_OP_P1CAMERA << 12), "M_CONTRO", OP_CameraOptionsMenu, &OP_P1ControlsDef, 35, 30); -menu_t OP_Camera2OptionsDef = DEFAULTMENUSTYLE( +menu_t OP_Camera2OptionsDef = DEFAULTSCROLLMENUSTYLE( MN_OP_MAIN + (MN_OP_P2CONTROLS << 6) + (MN_OP_P2CAMERA << 12), "M_CONTRO", OP_Camera2OptionsMenu, &OP_P2ControlsDef, 35, 30); @@ -4269,7 +4271,8 @@ static void M_DrawControlsDefMenu(void) OP_CameraOptionsMenu[10].status = IT_STRING|IT_CVAR|IT_CV_SLIDER; OP_CameraOptionsMenu[11].status = IT_STRING|IT_CVAR|IT_CV_SLIDER; OP_CameraOptionsMenu[12].status = IT_STRING|IT_CVAR|IT_CV_SLIDER; - OP_CameraOptionsMenu[13].alphaKey = 160; + OP_CameraOptionsMenu[13].status = IT_STRING|IT_CVAR; + OP_CameraOptionsMenu[14].alphaKey = 90; } else { @@ -4278,7 +4281,8 @@ static void M_DrawControlsDefMenu(void) OP_CameraOptionsMenu[10].status = IT_DISABLED; OP_CameraOptionsMenu[11].status = IT_DISABLED; OP_CameraOptionsMenu[12].status = IT_DISABLED; - OP_CameraOptionsMenu[13].alphaKey = 110; + OP_CameraOptionsMenu[13].status = IT_DISABLED; + OP_CameraOptionsMenu[14].alphaKey = 55; } } else @@ -4292,7 +4296,8 @@ static void M_DrawControlsDefMenu(void) OP_Camera2OptionsMenu[10].status = IT_STRING|IT_CVAR|IT_CV_SLIDER; OP_Camera2OptionsMenu[11].status = IT_STRING|IT_CVAR|IT_CV_SLIDER; OP_Camera2OptionsMenu[12].status = IT_STRING|IT_CVAR|IT_CV_SLIDER; - OP_Camera2OptionsMenu[13].alphaKey = 160; + OP_Camera2OptionsMenu[13].status = IT_STRING|IT_CVAR; + OP_Camera2OptionsMenu[14].alphaKey = 90; } else { @@ -4301,7 +4306,8 @@ static void M_DrawControlsDefMenu(void) OP_Camera2OptionsMenu[10].status = IT_DISABLED; OP_Camera2OptionsMenu[11].status = IT_DISABLED; OP_Camera2OptionsMenu[12].status = IT_DISABLED; - OP_Camera2OptionsMenu[13].alphaKey = 110; + OP_Camera2OptionsMenu[13].status = IT_DISABLED; + OP_Camera2OptionsMenu[14].alphaKey = 55; } } @@ -4319,7 +4325,9 @@ static void M_DrawGenericScrollMenu(void) x = currentMenu->x; y = currentMenu->y; - if ((currentMenu->menuitems[itemOn].alphaKey*2 - currentMenu->menuitems[0].alphaKey*2) <= scrollareaheight) + if (currentMenu->menuitems[currentMenu->numitems-1].alphaKey < scrollareaheight) + tempcentery = currentMenu->y; // Not tall enough to scroll, but this thinker is used in case it becomes so + else if ((currentMenu->menuitems[itemOn].alphaKey*2 - currentMenu->menuitems[0].alphaKey*2) <= scrollareaheight) tempcentery = currentMenu->y - currentMenu->menuitems[0].alphaKey*2; else if ((currentMenu->menuitems[currentMenu->numitems-1].alphaKey*2 - currentMenu->menuitems[itemOn].alphaKey*2) <= scrollareaheight) tempcentery = currentMenu->y - currentMenu->menuitems[currentMenu->numitems-1].alphaKey*2 + 2*scrollareaheight; From 2ab83bac6007cb9e5e5003bafef08cd4e3dd2b0a Mon Sep 17 00:00:00 2001 From: fickleheart Date: Tue, 10 Dec 2019 23:18:46 -0600 Subject: [PATCH 104/746] Run camera movement in the camera options menu It's really nice to see adjustments reflected in real time. --- src/m_menu.c | 39 +++++++++++++++++++++++++++++++++++---- 1 file changed, 35 insertions(+), 4 deletions(-) diff --git a/src/m_menu.c b/src/m_menu.c index 668e6b3d6..92f2e21d8 100644 --- a/src/m_menu.c +++ b/src/m_menu.c @@ -351,6 +351,7 @@ static void M_DrawTimeAttackMenu(void); static void M_DrawNightsAttackMenu(void); static void M_DrawSetupChoosePlayerMenu(void); static void M_DrawControlsDefMenu(void); +static void M_DrawCameraOptionsMenu(void); static void M_DrawPlaystyleMenu(void); static void M_DrawControl(void); static void M_DrawMainVideoMenu(void); @@ -1978,12 +1979,29 @@ menu_t OP_JoystickSetDef = 0, NULL }; -menu_t OP_CameraOptionsDef = DEFAULTSCROLLMENUSTYLE( + +menu_t OP_CameraOptionsDef = { MN_OP_MAIN + (MN_OP_P1CONTROLS << 6) + (MN_OP_P1CAMERA << 12), - "M_CONTRO", OP_CameraOptionsMenu, &OP_P1ControlsDef, 35, 30); -menu_t OP_Camera2OptionsDef = DEFAULTSCROLLMENUSTYLE( + "M_CONTRO", + sizeof (OP_CameraOptionsMenu)/sizeof (menuitem_t), + &OP_P1ControlsDef, + OP_CameraOptionsMenu, + M_DrawCameraOptionsMenu, + 35, 30, + 0, + NULL +}; +menu_t OP_Camera2OptionsDef = { MN_OP_MAIN + (MN_OP_P2CONTROLS << 6) + (MN_OP_P2CAMERA << 12), - "M_CONTRO", OP_Camera2OptionsMenu, &OP_P2ControlsDef, 35, 30); + "M_CONTRO", + sizeof (OP_Camera2OptionsMenu)/sizeof (menuitem_t), + &OP_P2ControlsDef, + OP_Camera2OptionsMenu, + M_DrawCameraOptionsMenu, + 35, 30, + 0, + NULL +}; static menuitem_t OP_PlaystyleMenu[] = {{IT_KEYHANDLER | IT_NOTHING, NULL, "", M_HandlePlaystyleMenu, 0}}; @@ -11663,6 +11681,19 @@ static void M_HandlePlaystyleMenu(INT32 choice) } } +static void M_DrawCameraOptionsMenu(void) +{ + M_DrawGenericScrollMenu(); + + if (gamestate == GS_LEVEL && (paused || P_AutoPause())) + { + if (currentMenu == &OP_Camera2OptionsDef && splitscreen && camera2.chase) + P_MoveChaseCamera(&players[secondarydisplayplayer], &camera2, false); + if (currentMenu == &OP_CameraOptionsDef && camera.chase) + P_MoveChaseCamera(&players[displayplayer], &camera, false); + } +} + // =============== // VIDEO MODE MENU // =============== From 07316fc5bd81e986295cb1b7c00a9a709f5f05d3 Mon Sep 17 00:00:00 2001 From: GoldenTails Date: Tue, 10 Dec 2019 23:55:52 -0600 Subject: [PATCH 105/746] Stop characters from being able to activate their abilities when doing a shield ability! Fixes #61. --- 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 ea42a2c36..d409f6bcd 100644 --- a/src/p_user.c +++ b/src/p_user.c @@ -5273,7 +5273,7 @@ static void P_DoJumpStuff(player_t *player, ticcmd_t *cmd) player->secondjump = 0; player->pflags &= ~PF_THOKKED; } - else if (player->pflags & PF_SLIDING || (gametype == GT_CTF && player->gotflag)) + else if (player->pflags & PF_SLIDING || (gametype == GT_CTF && player->gotflag) || player->pflags & PF_SHIELDABILITY) ; /*else if (P_SuperReady(player)) { From f74d7163e68191faf31600d45a610a33beab0aec Mon Sep 17 00:00:00 2001 From: fickleheart Date: Wed, 11 Dec 2019 01:26:43 -0600 Subject: [PATCH 106/746] Fix RVZ camera stuff --- src/g_game.c | 5 +++-- src/p_user.c | 3 +++ 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/src/g_game.c b/src/g_game.c index 0ba7081fa..f198301a9 100644 --- a/src/g_game.c +++ b/src/g_game.c @@ -1033,6 +1033,7 @@ void G_BuildTiccmd(ticcmd_t *cmd, INT32 realtics, UINT8 ssplayer) angle_t *myangle = (ssplayer == 1 ? &localangle : &localangle2); INT32 *myaiming = (ssplayer == 1 ? &localaiming : &localaiming2); + angle_t drawangleoffset = (player->powers[pw_carry] == CR_ROLLOUT) ? ANGLE_180 : 0; INT32 chasecam, chasefreelook, alwaysfreelook, usejoystick, analog, invertmouse, mousemove, abilitydirection; INT32 *mx; INT32 *my; INT32 *mly; @@ -1445,7 +1446,7 @@ void G_BuildTiccmd(ticcmd_t *cmd, INT32 realtics, UINT8 ssplayer) cmd->sidemove = 0; } else - cmd->angleturn = (player->drawangle>>16); + cmd->angleturn = (player->drawangle+drawangleoffset)>>16; } // Adjust camera angle to face player direction, depending on circumstances @@ -1463,7 +1464,7 @@ void G_BuildTiccmd(ticcmd_t *cmd, INT32 realtics, UINT8 ssplayer) if (camadjustfactor) { - INT32 anglediff = player->drawangle - *myangle; + INT32 anglediff = player->drawangle + drawangleoffset - *myangle; *myangle += FixedMul(anglediff, camadjustfactor); } diff --git a/src/p_user.c b/src/p_user.c index c5d4e2846..8dd76d0ef 100644 --- a/src/p_user.c +++ b/src/p_user.c @@ -9902,6 +9902,9 @@ boolean P_MoveChaseCamera(player_t *player, camera_t *thiscam, boolean resetcall UINT8 forplayer = (thiscam == &camera) ? 0 : 1; fixed_t shift = FixedMul(FINESINE((player->drawangle - angle) >> ANGLETOFINESHIFT), cv_cam_shiftfacing[forplayer].value); + if (player->powers[pw_carry] == CR_ROLLOUT) + shift = -shift; + if (ticcmd_resetdown[(thiscam == &camera) ? 0 : 1]) shift = FixedMul(camsideshift[forplayer], FRACUNIT-camspeed); else From 584348b91e67371719dba6ed017bdda20a7431a4 Mon Sep 17 00:00:00 2001 From: Nev3r Date: Wed, 11 Dec 2019 10:13:52 +0100 Subject: [PATCH 107/746] Do not use mapthing flags to spawn hoops and rings; use the the previously set mapthing Z instead. --- src/p_mobj.c | 33 ++++++++++++++++----------------- 1 file changed, 16 insertions(+), 17 deletions(-) diff --git a/src/p_mobj.c b/src/p_mobj.c index 3321107c7..34d33f788 100644 --- a/src/p_mobj.c +++ b/src/p_mobj.c @@ -13077,7 +13077,7 @@ void P_SpawnHoopsAndRings(mapthing_t *mthing, boolean bonustime) mobj_t *hoopcenter; INT16 spewangle; - z = mthing->options << FRACBITS; + z = mthing->z << FRACBITS; hoopcenter = P_SpawnMobj(x, y, z, MT_HOOPCENTER); @@ -13217,8 +13217,7 @@ void P_SpawnHoopsAndRings(mapthing_t *mthing, boolean bonustime) INT32 hoopsize; INT32 hoopplacement; - // Save our flags! - z = (mthing->options>>ZSHIFT) << FRACBITS; + z = mthing->z << FRACBITS; hoopcenter = P_SpawnMobj(x, y, z, MT_HOOPCENTER); hoopcenter->spawnpoint = mthing; @@ -13360,8 +13359,8 @@ void P_SpawnHoopsAndRings(mapthing_t *mthing, boolean bonustime) sec->c_slope ? P_GetZAt(sec->c_slope, x, y) : #endif sec->ceilingheight) - mobjinfo[ringthing].height; - if (mthing->options >> ZSHIFT) - z -= ((mthing->options >> ZSHIFT) << FRACBITS); + if (mthing->z) + z -= (mthing->z << FRACBITS); } else { @@ -13370,8 +13369,8 @@ void P_SpawnHoopsAndRings(mapthing_t *mthing, boolean bonustime) sec->f_slope ? P_GetZAt(sec->f_slope, x, y) : #endif sec->floorheight); - if (mthing->options >> ZSHIFT) - z += ((mthing->options >> ZSHIFT) << FRACBITS); + if (mthing->z) + z += (mthing->z << FRACBITS); } for (r = 1; r <= 5; r++) @@ -13420,8 +13419,8 @@ void P_SpawnHoopsAndRings(mapthing_t *mthing, boolean bonustime) sec->c_slope ? P_GetZAt(sec->c_slope, x, y) : #endif sec->ceilingheight) - mobjinfo[ringthing].height; - if (mthing->options >> ZSHIFT) - z -= ((mthing->options >> ZSHIFT) << FRACBITS); + if (mthing->z) + z -= (mthing->z << FRACBITS); } else { @@ -13430,8 +13429,8 @@ void P_SpawnHoopsAndRings(mapthing_t *mthing, boolean bonustime) sec->f_slope ? P_GetZAt(sec->f_slope, x, y) : #endif sec->floorheight); - if (mthing->options >> ZSHIFT) - z += ((mthing->options >> ZSHIFT) << FRACBITS); + if (mthing->z) + z += (mthing->z << FRACBITS); } for (r = 1; r <= iterations; r++) @@ -13477,8 +13476,8 @@ void P_SpawnHoopsAndRings(mapthing_t *mthing, boolean bonustime) sec->f_slope ? P_GetZAt(sec->f_slope, x, y) : #endif sec->floorheight; - if (mthing->options >> ZSHIFT) - z += ((mthing->options >> ZSHIFT) << FRACBITS); + if (mthing->z) + z += (mthing->z << FRACBITS); closestangle = FixedAngle(mthing->angle*FRACUNIT); @@ -13582,8 +13581,8 @@ void P_SpawnHoopsAndRings(mapthing_t *mthing, boolean bonustime) sec->c_slope ? P_GetZAt(sec->c_slope, x, y) : #endif sec->ceilingheight) - mobjinfo[ringthing].height; - if (mthing->options >> ZSHIFT) - z -= ((mthing->options >> ZSHIFT) << FRACBITS); + if (mthing->z) + z -= (mthing->z << FRACBITS); } else { @@ -13592,8 +13591,8 @@ void P_SpawnHoopsAndRings(mapthing_t *mthing, boolean bonustime) sec->f_slope ? P_GetZAt(sec->f_slope, x, y) : #endif sec->floorheight; - if (mthing->options >> ZSHIFT) - z += ((mthing->options >> ZSHIFT) << FRACBITS); + if (mthing->z) + z += (mthing->z << FRACBITS); } if (mthing->options & MTF_AMBUSH) // Special flag for rings From d2cbdd4fb1ebaf0a2ef2c093197e0a4c6f59a35f Mon Sep 17 00:00:00 2001 From: Nev3r Date: Wed, 11 Dec 2019 10:57:24 +0100 Subject: [PATCH 108/746] Do not overwrite the mapthing Z when spawning rings and similars, as it now causes them to respawn in wrong places because it is being actually used now. --- src/p_mobj.c | 3 --- src/p_setup.c | 4 ---- 2 files changed, 7 deletions(-) diff --git a/src/p_mobj.c b/src/p_mobj.c index 34d33f788..3d26b28f3 100644 --- a/src/p_mobj.c +++ b/src/p_mobj.c @@ -11554,7 +11554,6 @@ INT32 numhuntemeralds; static fixed_t GetMobjSpawnHeight (const mobjtype_t i, const mapthing_t* mthing, const fixed_t x, const fixed_t y) { subsector_t *ss = R_PointInSubsector(x, y); - fixed_t z; fixed_t extraoffset = 0; fixed_t heightoffset = 0; boolean flip; @@ -13603,8 +13602,6 @@ void P_SpawnHoopsAndRings(mapthing_t *mthing, boolean bonustime) z += 24*FRACUNIT; } - mthing->z = (INT16)(z>>FRACBITS); - mobj = P_SpawnMobj(x, y, z, ringthing); mobj->spawnpoint = mthing; diff --git a/src/p_setup.c b/src/p_setup.c index d40c728ab..628292fe0 100644 --- a/src/p_setup.c +++ b/src/p_setup.c @@ -906,10 +906,6 @@ void P_ReloadRings(void) { mt->mobj = NULL; - // Z for objects Tails 05-26-2002 - mt->z = (INT16)(R_PointInSubsector(mt->x << FRACBITS, mt->y << FRACBITS) - ->sector->floorheight>>FRACBITS); - P_SpawnHoopsAndRings(mt, true); } } From 854d50f479f1ab775bfe1e8a3e86aeeb3edb06d6 Mon Sep 17 00:00:00 2001 From: Nev3r Date: Wed, 11 Dec 2019 11:44:46 +0100 Subject: [PATCH 109/746] Added 'virtual resource' mechanism for temporary memory loaded lump lists. If you can come up with a better name then I'm all ears. --- src/w_wad.c | 95 +++++++++++++++++++++++++++++++++++++++++++++++++++++ src/w_wad.h | 19 +++++++++++ 2 files changed, 114 insertions(+) diff --git a/src/w_wad.c b/src/w_wad.c index 801f50edd..2e2d00516 100644 --- a/src/w_wad.c +++ b/src/w_wad.c @@ -1888,3 +1888,98 @@ int W_VerifyNMUSlumps(const char *filename) }; return W_VerifyFile(filename, NMUSlist, false); } + +/** \brief Generates a virtual resource used for level data loading. + * + * \param lumpnum_t reference + * \return Virtual resource + * + */ +virtres_t* vres_GetMap (lumpnum_t lumpnum) +{ + UINT32 i; + virtres_t* vres = NULL; + virtlump_t* vlumps = NULL; + size_t numlumps = 0; + + if (W_IsLumpWad(lumpnum)) + { + // Remember that we're assuming that the WAD will have a specific set of lumps in a specific order. + UINT8 *wadData = W_CacheLumpNum(lumpnum, PU_LEVEL); + filelump_t *fileinfo = (filelump_t *)(wadData + ((wadinfo_t *)wadData)->infotableofs); + numlumps = ((wadinfo_t *)wadData)->numlumps; + vlumps = Z_Malloc(sizeof(virtlump_t)*numlumps, PU_LEVEL, NULL); + + // Build the lumps. + for (i = 0; i < numlumps; i++) + { + vlumps[i].size = (size_t)(((filelump_t *)(fileinfo + i))->size); + // Play it safe with the name in this case. + memcpy(vlumps[i].name, (fileinfo + i)->name, 8); + vlumps[i].name[8] = '\0'; + vlumps[i].data = Z_Malloc(vlumps[i].size, PU_LEVEL, NULL); // This is memory inefficient, sorry about that. + memcpy(vlumps[i].data, wadData + (fileinfo + i)->filepos, vlumps[i].size); + } + + Z_Free(wadData); + } + else + { + // Count number of lumps until the end of resource OR up until next "MAPXX" lump. + lumpnum_t lumppos = lumpnum + 1; + for (i = LUMPNUM(lumppos); i < wadfiles[WADFILENUM(lumpnum)]->numlumps; i++, lumppos++, numlumps++) + if (memcmp(W_CheckNameForNum(lumppos), "MAP", 3) == 0) + break; + numlumps++; + + vlumps = Z_Malloc(sizeof(virtlump_t)*numlumps, PU_LEVEL, NULL); + for (i = 0; i < numlumps; i++, lumpnum++) + { + vlumps[i].size = W_LumpLength(lumpnum); + memcpy(vlumps[i].name, W_CheckNameForNum(lumpnum), 8); + vlumps[i].name[8] = '\0'; + vlumps[i].data = W_CacheLumpNum(lumpnum, PU_LEVEL); + } + } + vres = Z_Malloc(sizeof(virtres_t), PU_LEVEL, NULL); + vres->vlumps = vlumps; + vres->numlumps = numlumps; + return vres; +} + +/** \brief Frees zone memory for a given virtual resource. + * + * \param Virtual resource + */ +void vres_Free (virtres_t* vres) +{ + while (vres->numlumps--) + Z_Free(vres->vlumps[vres->numlumps].data); + Z_Free(vres->vlumps); + Z_Free(vres); +} + +/** (Debug) Prints lumps from a virtual resource into console. + */ +static void vres_Diag (const virtres_t* vres) +{ + UINT32 i; + for (i = 0; i < vres->numlumps; i++) + CONS_Printf("%s\n", vres->vlumps[i].name); +} + +/** \brief Finds a lump in a given virtual resource. + * + * \param Virtual resource + * \param Lump name to look for + * \return Virtual lump if found, NULL otherwise + * + */ +virtlump_t* vres_Find(const virtres_t* vres, const char* name) +{ + UINT32 i; + for (i = 0; i < vres->numlumps; i++) + if (fastcmp(name, vres->vlumps[i].name)) + return &vres->vlumps[i]; + return NULL; +} diff --git a/src/w_wad.h b/src/w_wad.h index a8be13ece..a265d78a9 100644 --- a/src/w_wad.h +++ b/src/w_wad.h @@ -72,6 +72,25 @@ typedef struct compmethod compression; // lump compression method } lumpinfo_t; +// ========================================================================= +// 'VIRTUAL' RESOURCES +// ========================================================================= + +typedef struct { + char name[9]; + UINT8* data; + size_t size; +} virtlump_t; + +typedef struct { + size_t numlumps; + virtlump_t* vlumps; +} virtres_t; + +virtres_t* vres_GetMap (lumpnum_t); +void vres_Free (virtres_t*); +virtlump_t* vres_Find (const virtres_t*, const char*); + // ========================================================================= // DYNAMIC WAD LOADING // ========================================================================= From f7c69f0c1cb81206f45db21ec93d15329b8ff188 Mon Sep 17 00:00:00 2001 From: Nev3r Date: Wed, 11 Dec 2019 12:48:41 +0100 Subject: [PATCH 110/746] P_SetupLevel() no longer makes distinction on whether the map is a WAD in a PK3 or not. --- src/p_setup.c | 128 ++++++++++++++------------------------------------ 1 file changed, 34 insertions(+), 94 deletions(-) diff --git a/src/p_setup.c b/src/p_setup.c index 3c45509ee..74d33f8f5 100644 --- a/src/p_setup.c +++ b/src/p_setup.c @@ -1950,7 +1950,7 @@ static boolean P_LoadBlockMap(lumpnum_t lumpnum) // because making both the WAD and PK3 loading code use // the same functions is trickier than it looks for blockmap // -- Monster Iestyn 09/01/18 -static boolean P_LoadRawBlockMap(UINT8 *data, size_t count, const char *lumpname) +static boolean P_LoadRawBlockMap(UINT8 *data, size_t count) { #if 0 (void)data; @@ -1958,12 +1958,6 @@ static boolean P_LoadRawBlockMap(UINT8 *data, size_t count, const char *lumpname (void)lumpname; return false; #else - // Check if the lump is named "BLOCKMAP" - if (!lumpname || memcmp(lumpname, "BLOCKMAP", 8) != 0) - { - CONS_Printf("No blockmap lump found for pk3!\n"); - return false; - } if (!count || count >= 0x20000) return false; @@ -2120,16 +2114,8 @@ static void P_LoadReject(lumpnum_t lumpnum) // PK3 version // -- Monster Iestyn 09/01/18 -static void P_LoadRawReject(UINT8 *data, size_t count, const char *lumpname) +static void P_LoadRawReject(UINT8 *data, size_t count) { - // Check if the lump is named "REJECT" - if (!lumpname || memcmp(lumpname, "REJECT\0\0", 8) != 0) - { - rejectmatrix = NULL; - CONS_Debug(DBG_SETUP, "P_LoadRawReject: No valid REJECT lump found\n"); - return; - } - if (!count) // zero length, someone probably used ZDBSP { rejectmatrix = NULL; @@ -2892,51 +2878,42 @@ boolean P_SetupLevel(boolean skipprecip) P_MakeMapMD5(lastloadedmaplumpnum, &mapmd5); - // HACK ALERT: Cache the WAD, get the map data into the tables, free memory. - // As it is implemented right now, we're assuming an uncompressed WAD. - // (As in, a normal PWAD, not ZWAD or anything. The lump itself can be compressed.) - // We're not accounting for extra lumps and scrambled lump positions. Any additional data will cause an error. - if (W_IsLumpWad(lastloadedmaplumpnum)) + if (lastloadedmaplumpnum) { - // Remember that we're assuming that the WAD will have a specific set of lumps in a specific order. - UINT8 *wadData = W_CacheLumpNum(lastloadedmaplumpnum, PU_STATIC); - //filelump_t *fileinfo = wadData + ((wadinfo_t *)wadData)->infotableofs; - filelump_t *fileinfo = (filelump_t *)(wadData + ((wadinfo_t *)wadData)->infotableofs); - UINT32 numlumps = ((wadinfo_t *)wadData)->numlumps; + virtres_t* virt = vres_GetMap(lastloadedmaplumpnum); + virtlump_t* virtthings = vres_Find(virt, "THINGS"); + virtlump_t* virtvertexes = vres_Find(virt, "VERTEXES"); + virtlump_t* virtsectors = vres_Find(virt, "SECTORS"); + virtlump_t* virtsidedefs = vres_Find(virt, "SIDEDEFS"); + virtlump_t* virtlinedefs = vres_Find(virt, "LINEDEFS"); - if (numlumps < ML_REJECT) // at least 9 lumps should be in the wad for a map to be loaded - { - I_Error("Bad WAD file for map %s!\n", maplumpname); - } + virtlump_t* virtssectors = vres_Find(virt, "SSECTORS"); + virtlump_t* virtsegs = vres_Find(virt, "SEGS"); + virtlump_t* virtnodes = vres_Find(virt, "NODES"); - if (numlumps > ML_BLOCKMAP) // enough room for a BLOCKMAP lump at least - { - loadedbm = P_LoadRawBlockMap( - wadData + (fileinfo + ML_BLOCKMAP)->filepos, - (fileinfo + ML_BLOCKMAP)->size, - (fileinfo + ML_BLOCKMAP)->name); - } - P_LoadRawVertexes(wadData + (fileinfo + ML_VERTEXES)->filepos, (fileinfo + ML_VERTEXES)->size); - P_LoadRawSectors(wadData + (fileinfo + ML_SECTORS)->filepos, (fileinfo + ML_SECTORS)->size); - P_LoadRawSideDefs((fileinfo + ML_SIDEDEFS)->size); - P_LoadRawLineDefs(wadData + (fileinfo + ML_LINEDEFS)->filepos, (fileinfo + ML_LINEDEFS)->size); - P_LoadRawSideDefs2(wadData + (fileinfo + ML_SIDEDEFS)->filepos); - P_LoadRawSubsectors(wadData + (fileinfo + ML_SSECTORS)->filepos, (fileinfo + ML_SSECTORS)->size); - P_LoadRawNodes(wadData + (fileinfo + ML_NODES)->filepos, (fileinfo + ML_NODES)->size); - P_LoadRawSegs(wadData + (fileinfo + ML_SEGS)->filepos, (fileinfo + ML_SEGS)->size); - if (numlumps > ML_REJECT) // enough room for a REJECT lump at least - { - P_LoadRawReject( - wadData + (fileinfo + ML_REJECT)->filepos, - (fileinfo + ML_REJECT)->size, - (fileinfo + ML_REJECT)->name); - } + virtlump_t* virtblockmap = vres_Find(virt, "BLOCKMAP"); + virtlump_t* virtreject = vres_Find(virt, "REJECT"); + + P_LoadRawVertexes(virtvertexes->data, virtvertexes->size); + P_LoadRawSectors(virtsectors->data, virtsectors->size); + P_LoadRawSideDefs(virtsidedefs->size); + P_LoadRawLineDefs(virtlinedefs->data, virtlinedefs->size); + P_LoadRawSideDefs2(virtsidedefs->data); + P_LoadRawSubsectors(virtssectors->data, virtssectors->size); + P_LoadRawNodes(virtnodes->data, virtnodes->size); + P_LoadRawSegs(virtsegs->data, virtsegs->size); + + if (virtreject) + P_LoadRawReject(virtreject->data, virtreject->size); + else + rejectmatrix = NULL; + + if (!(virtblockmap && P_LoadRawBlockMap(virtblockmap->data, virtblockmap->size))) + P_CreateBlockMap(); - // Important: take care of the ordering of the next functions. - if (!loadedbm) - P_CreateBlockMap(); // Graue 02-29-2004 P_LoadLineDefs2(); P_GroupLines(); + numdmstarts = numredctfstarts = numbluectfstarts = 0; // reset the player starts @@ -2954,46 +2931,9 @@ boolean P_SetupLevel(boolean skipprecip) P_MapStart(); - P_PrepareRawThings(wadData + (fileinfo + ML_THINGS)->filepos, (fileinfo + ML_THINGS)->size); - Z_Free(wadData); - } - else - { - // Important: take care of the ordering of the next functions. - loadedbm = P_LoadBlockMap(lastloadedmaplumpnum + ML_BLOCKMAP); - P_LoadVertexes(lastloadedmaplumpnum + ML_VERTEXES); - P_LoadSectors(lastloadedmaplumpnum + ML_SECTORS); - P_LoadSideDefs(lastloadedmaplumpnum + ML_SIDEDEFS); - P_LoadLineDefs(lastloadedmaplumpnum + ML_LINEDEFS); - P_LoadSideDefs2(lastloadedmaplumpnum + ML_SIDEDEFS); - P_LoadSubsectors(lastloadedmaplumpnum + ML_SSECTORS); - P_LoadNodes(lastloadedmaplumpnum + ML_NODES); - P_LoadSegs(lastloadedmaplumpnum + ML_SEGS); - P_LoadReject(lastloadedmaplumpnum + ML_REJECT); + P_PrepareRawThings(virtthings->data, virtthings->size); - // Important: take care of the ordering of the next functions. - if (!loadedbm) - P_CreateBlockMap(); // Graue 02-29-2004 - P_LoadLineDefs2(); - P_GroupLines(); - numdmstarts = numredctfstarts = numbluectfstarts = 0; - - // reset the player starts - for (i = 0; i < MAXPLAYERS; i++) - playerstarts[i] = bluectfstarts[i] = redctfstarts[i] = NULL; - - for (i = 0; i < MAX_DM_STARTS; i++) - deathmatchstarts[i] = NULL; - - for (i = 0; i < 2; i++) - skyboxmo[i] = NULL; - - for (i = 0; i < 16; i++) - skyboxviewpnts[i] = skyboxcenterpnts[i] = NULL; - - P_MapStart(); - - P_PrepareThings(lastloadedmaplumpnum + ML_THINGS); + vres_Free(virt); } // init gravity, tag lists, From bf5a2c68d594c09d802f8f99720845b9b4e96029 Mon Sep 17 00:00:00 2001 From: Nev3r Date: Wed, 11 Dec 2019 12:48:41 +0100 Subject: [PATCH 111/746] P_SetupLevel() no longer makes distinction on whether the map is a WAD in a PK3 or not. --- src/p_saveg.c | 28 ++--------- src/p_setup.c | 128 ++++++++++++++------------------------------------ 2 files changed, 39 insertions(+), 117 deletions(-) diff --git a/src/p_saveg.c b/src/p_saveg.c index 89447db80..c876713e4 100644 --- a/src/p_saveg.c +++ b/src/p_saveg.c @@ -781,9 +781,10 @@ static void P_NetArchiveWorld(void) UINT8 *put; // reload the map just to see difference - mapsector_t *ms; - mapsidedef_t *msd; - maplinedef_t *mld; + virtres_t* virt = vres_GetMap(lastloadedmaplumpnum); + mapsector_t *ms = (mapsector_t*) vres_Find(virt, "SECTORS")->data; + mapsidedef_t *msd = (mapsidedef_t*) vres_Find(virt, "SIDEDEFS")->data; + maplinedef_t *mld = (maplinedef_t*) vres_Find(virt, "LINEDEFS")->data; const sector_t *ss = sectors; UINT8 diff, diff2, diff3; @@ -793,26 +794,6 @@ static void P_NetArchiveWorld(void) WRITEUINT32(save_p, ARCHIVEBLOCK_WORLD); put = save_p; - if (W_IsLumpWad(lastloadedmaplumpnum)) // welp it's a map wad in a pk3 - { // HACK: Open wad file rather quickly so we can get the data from the relevant lumps - UINT8 *wadData = W_CacheLumpNum(lastloadedmaplumpnum, PU_STATIC); - filelump_t *fileinfo = (filelump_t *)(wadData + ((wadinfo_t *)wadData)->infotableofs); -#define retrieve_mapdata(d, f)\ - d = Z_Malloc((f)->size, PU_CACHE, NULL); \ - M_Memcpy(d, wadData + (f)->filepos, (f)->size) - retrieve_mapdata(ms, fileinfo + ML_SECTORS); - retrieve_mapdata(mld, fileinfo + ML_LINEDEFS); - retrieve_mapdata(msd, fileinfo + ML_SIDEDEFS); -#undef retrieve_mapdata - Z_Free(wadData); // we're done with this now - } - else // phew it's just a WAD - { - ms = W_CacheLumpNum(lastloadedmaplumpnum+ML_SECTORS, PU_CACHE); - mld = W_CacheLumpNum(lastloadedmaplumpnum+ML_LINEDEFS, PU_CACHE); - msd = W_CacheLumpNum(lastloadedmaplumpnum+ML_SIDEDEFS, PU_CACHE); - } - for (i = 0; i < numsectors; i++, ss++, ms++) { diff = diff2 = diff3 = 0; @@ -1037,6 +1018,7 @@ static void P_NetArchiveWorld(void) WRITEUINT16(put, 0xffff); R_ClearTextureNumCache(false); + vres_Free(virt); save_p = put; } diff --git a/src/p_setup.c b/src/p_setup.c index 3c45509ee..74d33f8f5 100644 --- a/src/p_setup.c +++ b/src/p_setup.c @@ -1950,7 +1950,7 @@ static boolean P_LoadBlockMap(lumpnum_t lumpnum) // because making both the WAD and PK3 loading code use // the same functions is trickier than it looks for blockmap // -- Monster Iestyn 09/01/18 -static boolean P_LoadRawBlockMap(UINT8 *data, size_t count, const char *lumpname) +static boolean P_LoadRawBlockMap(UINT8 *data, size_t count) { #if 0 (void)data; @@ -1958,12 +1958,6 @@ static boolean P_LoadRawBlockMap(UINT8 *data, size_t count, const char *lumpname (void)lumpname; return false; #else - // Check if the lump is named "BLOCKMAP" - if (!lumpname || memcmp(lumpname, "BLOCKMAP", 8) != 0) - { - CONS_Printf("No blockmap lump found for pk3!\n"); - return false; - } if (!count || count >= 0x20000) return false; @@ -2120,16 +2114,8 @@ static void P_LoadReject(lumpnum_t lumpnum) // PK3 version // -- Monster Iestyn 09/01/18 -static void P_LoadRawReject(UINT8 *data, size_t count, const char *lumpname) +static void P_LoadRawReject(UINT8 *data, size_t count) { - // Check if the lump is named "REJECT" - if (!lumpname || memcmp(lumpname, "REJECT\0\0", 8) != 0) - { - rejectmatrix = NULL; - CONS_Debug(DBG_SETUP, "P_LoadRawReject: No valid REJECT lump found\n"); - return; - } - if (!count) // zero length, someone probably used ZDBSP { rejectmatrix = NULL; @@ -2892,51 +2878,42 @@ boolean P_SetupLevel(boolean skipprecip) P_MakeMapMD5(lastloadedmaplumpnum, &mapmd5); - // HACK ALERT: Cache the WAD, get the map data into the tables, free memory. - // As it is implemented right now, we're assuming an uncompressed WAD. - // (As in, a normal PWAD, not ZWAD or anything. The lump itself can be compressed.) - // We're not accounting for extra lumps and scrambled lump positions. Any additional data will cause an error. - if (W_IsLumpWad(lastloadedmaplumpnum)) + if (lastloadedmaplumpnum) { - // Remember that we're assuming that the WAD will have a specific set of lumps in a specific order. - UINT8 *wadData = W_CacheLumpNum(lastloadedmaplumpnum, PU_STATIC); - //filelump_t *fileinfo = wadData + ((wadinfo_t *)wadData)->infotableofs; - filelump_t *fileinfo = (filelump_t *)(wadData + ((wadinfo_t *)wadData)->infotableofs); - UINT32 numlumps = ((wadinfo_t *)wadData)->numlumps; + virtres_t* virt = vres_GetMap(lastloadedmaplumpnum); + virtlump_t* virtthings = vres_Find(virt, "THINGS"); + virtlump_t* virtvertexes = vres_Find(virt, "VERTEXES"); + virtlump_t* virtsectors = vres_Find(virt, "SECTORS"); + virtlump_t* virtsidedefs = vres_Find(virt, "SIDEDEFS"); + virtlump_t* virtlinedefs = vres_Find(virt, "LINEDEFS"); - if (numlumps < ML_REJECT) // at least 9 lumps should be in the wad for a map to be loaded - { - I_Error("Bad WAD file for map %s!\n", maplumpname); - } + virtlump_t* virtssectors = vres_Find(virt, "SSECTORS"); + virtlump_t* virtsegs = vres_Find(virt, "SEGS"); + virtlump_t* virtnodes = vres_Find(virt, "NODES"); - if (numlumps > ML_BLOCKMAP) // enough room for a BLOCKMAP lump at least - { - loadedbm = P_LoadRawBlockMap( - wadData + (fileinfo + ML_BLOCKMAP)->filepos, - (fileinfo + ML_BLOCKMAP)->size, - (fileinfo + ML_BLOCKMAP)->name); - } - P_LoadRawVertexes(wadData + (fileinfo + ML_VERTEXES)->filepos, (fileinfo + ML_VERTEXES)->size); - P_LoadRawSectors(wadData + (fileinfo + ML_SECTORS)->filepos, (fileinfo + ML_SECTORS)->size); - P_LoadRawSideDefs((fileinfo + ML_SIDEDEFS)->size); - P_LoadRawLineDefs(wadData + (fileinfo + ML_LINEDEFS)->filepos, (fileinfo + ML_LINEDEFS)->size); - P_LoadRawSideDefs2(wadData + (fileinfo + ML_SIDEDEFS)->filepos); - P_LoadRawSubsectors(wadData + (fileinfo + ML_SSECTORS)->filepos, (fileinfo + ML_SSECTORS)->size); - P_LoadRawNodes(wadData + (fileinfo + ML_NODES)->filepos, (fileinfo + ML_NODES)->size); - P_LoadRawSegs(wadData + (fileinfo + ML_SEGS)->filepos, (fileinfo + ML_SEGS)->size); - if (numlumps > ML_REJECT) // enough room for a REJECT lump at least - { - P_LoadRawReject( - wadData + (fileinfo + ML_REJECT)->filepos, - (fileinfo + ML_REJECT)->size, - (fileinfo + ML_REJECT)->name); - } + virtlump_t* virtblockmap = vres_Find(virt, "BLOCKMAP"); + virtlump_t* virtreject = vres_Find(virt, "REJECT"); + + P_LoadRawVertexes(virtvertexes->data, virtvertexes->size); + P_LoadRawSectors(virtsectors->data, virtsectors->size); + P_LoadRawSideDefs(virtsidedefs->size); + P_LoadRawLineDefs(virtlinedefs->data, virtlinedefs->size); + P_LoadRawSideDefs2(virtsidedefs->data); + P_LoadRawSubsectors(virtssectors->data, virtssectors->size); + P_LoadRawNodes(virtnodes->data, virtnodes->size); + P_LoadRawSegs(virtsegs->data, virtsegs->size); + + if (virtreject) + P_LoadRawReject(virtreject->data, virtreject->size); + else + rejectmatrix = NULL; + + if (!(virtblockmap && P_LoadRawBlockMap(virtblockmap->data, virtblockmap->size))) + P_CreateBlockMap(); - // Important: take care of the ordering of the next functions. - if (!loadedbm) - P_CreateBlockMap(); // Graue 02-29-2004 P_LoadLineDefs2(); P_GroupLines(); + numdmstarts = numredctfstarts = numbluectfstarts = 0; // reset the player starts @@ -2954,46 +2931,9 @@ boolean P_SetupLevel(boolean skipprecip) P_MapStart(); - P_PrepareRawThings(wadData + (fileinfo + ML_THINGS)->filepos, (fileinfo + ML_THINGS)->size); - Z_Free(wadData); - } - else - { - // Important: take care of the ordering of the next functions. - loadedbm = P_LoadBlockMap(lastloadedmaplumpnum + ML_BLOCKMAP); - P_LoadVertexes(lastloadedmaplumpnum + ML_VERTEXES); - P_LoadSectors(lastloadedmaplumpnum + ML_SECTORS); - P_LoadSideDefs(lastloadedmaplumpnum + ML_SIDEDEFS); - P_LoadLineDefs(lastloadedmaplumpnum + ML_LINEDEFS); - P_LoadSideDefs2(lastloadedmaplumpnum + ML_SIDEDEFS); - P_LoadSubsectors(lastloadedmaplumpnum + ML_SSECTORS); - P_LoadNodes(lastloadedmaplumpnum + ML_NODES); - P_LoadSegs(lastloadedmaplumpnum + ML_SEGS); - P_LoadReject(lastloadedmaplumpnum + ML_REJECT); + P_PrepareRawThings(virtthings->data, virtthings->size); - // Important: take care of the ordering of the next functions. - if (!loadedbm) - P_CreateBlockMap(); // Graue 02-29-2004 - P_LoadLineDefs2(); - P_GroupLines(); - numdmstarts = numredctfstarts = numbluectfstarts = 0; - - // reset the player starts - for (i = 0; i < MAXPLAYERS; i++) - playerstarts[i] = bluectfstarts[i] = redctfstarts[i] = NULL; - - for (i = 0; i < MAX_DM_STARTS; i++) - deathmatchstarts[i] = NULL; - - for (i = 0; i < 2; i++) - skyboxmo[i] = NULL; - - for (i = 0; i < 16; i++) - skyboxviewpnts[i] = skyboxcenterpnts[i] = NULL; - - P_MapStart(); - - P_PrepareThings(lastloadedmaplumpnum + ML_THINGS); + vres_Free(virt); } // init gravity, tag lists, From 4d86dc11a639043e44794fd2159dd6ed954a522d Mon Sep 17 00:00:00 2001 From: Nev3r Date: Wed, 11 Dec 2019 13:54:15 +0100 Subject: [PATCH 112/746] 'prepare' mapthings using virtres in P_LevelInitStuff(). Whether 'preparing' them or not is actually necessary is another matter. --- src/p_setup.c | 16 +++++----------- 1 file changed, 5 insertions(+), 11 deletions(-) diff --git a/src/p_setup.c b/src/p_setup.c index 74d33f8f5..587b0b55a 100644 --- a/src/p_setup.c +++ b/src/p_setup.c @@ -2303,6 +2303,8 @@ void P_LoadThingsOnly(void) // Search through all the thinkers. thinker_t *think; INT32 i, viewid = -1, centerid = -1; // for skyboxes + virtres_t* virt = vres_GetMap(lastloadedmaplumpnum); + virtlump_t* vth = vres_Find(virt, "THINGS"); // check if these are any of the normal viewpoint/centerpoint mobjs in the level or not if (skyboxmo[0] || skyboxmo[1]) @@ -2314,7 +2316,6 @@ void P_LoadThingsOnly(void) centerid = i; // save id just in case } - for (think = thlist[THINK_MOBJ].next; think != &thlist[THINK_MOBJ]; think = think->next) { if (think->function.acp1 == (actionf_p1)P_RemoveThinkerDelayed) @@ -2324,18 +2325,11 @@ void P_LoadThingsOnly(void) P_LevelInitStuff(); - if (W_IsLumpWad(lastloadedmaplumpnum)) // welp it's a map wad in a pk3 - { // HACK: Open wad file rather quickly so we can use the things lump - UINT8 *wadData = W_CacheLumpNum(lastloadedmaplumpnum, PU_STATIC); - filelump_t *fileinfo = (filelump_t *)(wadData + ((wadinfo_t *)wadData)->infotableofs); - fileinfo += ML_THINGS; // we only need the THINGS lump - P_PrepareRawThings(wadData + fileinfo->filepos, fileinfo->size); - Z_Free(wadData); // we're done with this now - } - else // phew it's just a WAD - P_PrepareThings(lastloadedmaplumpnum + ML_THINGS); + P_PrepareRawThings(vth->data, vth->size); P_LoadThings(true); + vres_Free(virt); + // restore skybox viewpoint/centerpoint if necessary, set them to defaults if we can't do that skyboxmo[0] = skyboxviewpnts[(viewid >= 0) ? viewid : 0]; skyboxmo[1] = skyboxcenterpnts[(centerid >= 0) ? centerid : 0]; From 14ad3b938e7ece8aee71ba4c856ff1b3780186c6 Mon Sep 17 00:00:00 2001 From: Nev3r Date: Wed, 11 Dec 2019 14:04:09 +0100 Subject: [PATCH 113/746] Use virtres in P_SpawnSpecials(). Whether accessing the lump again here is right or not is also a different question. --- src/p_spec.c | 20 ++++++++------------ 1 file changed, 8 insertions(+), 12 deletions(-) diff --git a/src/p_spec.c b/src/p_spec.c index dba4e17b5..8ec1646ce 100644 --- a/src/p_spec.c +++ b/src/p_spec.c @@ -6425,7 +6425,7 @@ void P_SpawnSpecials(INT32 fromnetsave) INT32 j; thinkerlist_t *secthinkers; thinker_t *th; - + virtres_t* virt = NULL; // This used to be used, and *should* be used in the future, // but currently isn't. (void)fromnetsave; @@ -7177,17 +7177,10 @@ void P_SpawnSpecials(INT32 fromnetsave) UINT8 *data; UINT16 b; - if (W_IsLumpWad(lastloadedmaplumpnum)) // welp it's a map wad in a pk3 - { // HACK: Open wad file rather quickly so we can get the data from the sidedefs lump - UINT8 *wadData = W_CacheLumpNum(lastloadedmaplumpnum, PU_STATIC); - filelump_t *fileinfo = (filelump_t *)(wadData + ((wadinfo_t *)wadData)->infotableofs); - fileinfo += ML_SIDEDEFS; // we only need the SIDEDEFS lump - data = Z_Malloc(fileinfo->size, PU_STATIC, NULL); - M_Memcpy(data, wadData + fileinfo->filepos, fileinfo->size); // copy data - Z_Free(wadData); // we're done with this now - } - else // phew it's just a WAD - data = W_CacheLumpNum(lastloadedmaplumpnum + ML_SIDEDEFS,PU_STATIC); + if (!virt) + virt = vres_GetMap(lastloadedmaplumpnum); + + data = (UINT8*) vres_Find(virt, "SIDEDEFS")->data; for (b = 0; b < (INT16)numsides; b++) { @@ -7433,6 +7426,9 @@ void P_SpawnSpecials(INT32 fromnetsave) } } + if (virt) + vres_Free(virt); + // Allocate each list for (i = 0; i < numsectors; i++) if(secthinkers[i].thinkers) From 9952bae5ee5174c2c1a63da4db435c9eeeb3982b Mon Sep 17 00:00:00 2001 From: Nev3r Date: Wed, 11 Dec 2019 14:20:08 +0100 Subject: [PATCH 114/746] P_MakeMapMD5() now uses virtres. --- src/p_setup.c | 27 +++++++++++---------------- 1 file changed, 11 insertions(+), 16 deletions(-) diff --git a/src/p_setup.c b/src/p_setup.c index 587b0b55a..e2d67581b 100644 --- a/src/p_setup.c +++ b/src/p_setup.c @@ -2361,7 +2361,7 @@ static INT32 P_MakeBufferMD5(const char *buffer, size_t len, void *resblock) #endif } -static void P_MakeMapMD5(lumpnum_t maplumpnum, void *dest) +static void P_MakeMapMD5(virtres_t* virt, void *dest) { unsigned char linemd5[16]; unsigned char sectormd5[16]; @@ -2372,20 +2372,15 @@ static void P_MakeMapMD5(lumpnum_t maplumpnum, void *dest) // Create a hash for the current map // get the actual lumps! - UINT8 *datalines = W_CacheLumpNum(maplumpnum + ML_LINEDEFS, PU_CACHE); - UINT8 *datasectors = W_CacheLumpNum(maplumpnum + ML_SECTORS, PU_CACHE); - UINT8 *datathings = W_CacheLumpNum(maplumpnum + ML_THINGS, PU_CACHE); - UINT8 *datasides = W_CacheLumpNum(maplumpnum + ML_SIDEDEFS, PU_CACHE); + virtlump_t* virtlines = vres_Find(virt, "LINEDEFS"); + virtlump_t* virtsectors = vres_Find(virt, "SECTORS"); + virtlump_t* virtmthings = vres_Find(virt, "THINGS"); + virtlump_t* virtsides = vres_Find(virt, "SIDEDEFS"); - P_MakeBufferMD5((char*)datalines, W_LumpLength(maplumpnum + ML_LINEDEFS), linemd5); - P_MakeBufferMD5((char*)datasectors, W_LumpLength(maplumpnum + ML_SECTORS), sectormd5); - P_MakeBufferMD5((char*)datathings, W_LumpLength(maplumpnum + ML_THINGS), thingmd5); - P_MakeBufferMD5((char*)datasides, W_LumpLength(maplumpnum + ML_SIDEDEFS), sidedefmd5); - - Z_Free(datalines); - Z_Free(datasectors); - Z_Free(datathings); - Z_Free(datasides); + P_MakeBufferMD5((char*)virtlines->data, virtlines->size, linemd5); + P_MakeBufferMD5((char*)virtsectors->data, virtsectors->size, sectormd5); + P_MakeBufferMD5((char*)virtmthings->data, virtmthings->size, thingmd5); + P_MakeBufferMD5((char*)virtsides->data, virtsides->size, sidedefmd5); for (i = 0; i < 16; i++) resmd5[i] = (linemd5[i] + sectormd5[i] + thingmd5[i] + sidedefmd5[i]) & 0xFF; @@ -2870,8 +2865,6 @@ boolean P_SetupLevel(boolean skipprecip) // SRB2 determines the sky texture to be used depending on the map header. P_SetupLevelSky(mapheaderinfo[gamemap-1]->skynum, true); - P_MakeMapMD5(lastloadedmaplumpnum, &mapmd5); - if (lastloadedmaplumpnum) { virtres_t* virt = vres_GetMap(lastloadedmaplumpnum); @@ -2888,6 +2881,8 @@ boolean P_SetupLevel(boolean skipprecip) virtlump_t* virtblockmap = vres_Find(virt, "BLOCKMAP"); virtlump_t* virtreject = vres_Find(virt, "REJECT"); + P_MakeMapMD5(virt, &mapmd5); + P_LoadRawVertexes(virtvertexes->data, virtvertexes->size); P_LoadRawSectors(virtsectors->data, virtsectors->size); P_LoadRawSideDefs(virtsidedefs->size); From a87a9e6ff6a9844d75d5be29ad70ef2d5b0e2bbe Mon Sep 17 00:00:00 2001 From: Nev3r Date: Wed, 11 Dec 2019 14:40:31 +0100 Subject: [PATCH 115/746] Remove wrappers and dupes for map lump reading, as they are no longer used. --- src/p_setup.c | 168 -------------------------------------------------- 1 file changed, 168 deletions(-) diff --git a/src/p_setup.c b/src/p_setup.c index e2d67581b..17909ee58 100644 --- a/src/p_setup.c +++ b/src/p_setup.c @@ -397,13 +397,6 @@ static inline void P_LoadRawVertexes(UINT8 *data, size_t i) } } -static inline void P_LoadVertexes(lumpnum_t lumpnum) -{ - UINT8 *data = W_CacheLumpNum(lumpnum, PU_STATIC); - P_LoadRawVertexes(data, W_LumpLength(lumpnum)); - Z_Free(data); -} - /** Computes the length of a seg in fracunits. * * \param seg Seg to compute length for. @@ -488,14 +481,6 @@ static void P_LoadRawSegs(UINT8 *data, size_t i) } } -static void P_LoadSegs(lumpnum_t lumpnum) -{ - UINT8 *data = W_CacheLumpNum(lumpnum, PU_STATIC); - P_LoadRawSegs(data, W_LumpLength(lumpnum)); - Z_Free(data); -} - - /** Loads the SSECTORS resource from a level. * * \param lump Lump number of the SSECTORS resource. @@ -525,13 +510,6 @@ static inline void P_LoadRawSubsectors(void *data, size_t i) } } -static void P_LoadSubsectors(lumpnum_t lumpnum) -{ - UINT8 *data = W_CacheLumpNum(lumpnum, PU_STATIC); - P_LoadRawSubsectors(data, W_LumpLength(lumpnum)); - Z_Free(data); -} - // // levelflats // @@ -805,13 +783,6 @@ static void P_LoadRawSectors(UINT8 *data, size_t i) P_SetupLevelFlatAnims(); } -static void P_LoadSectors(lumpnum_t lumpnum) -{ - UINT8 *data = W_CacheLumpNum(lumpnum, PU_STATIC); - P_LoadRawSectors(data, W_LumpLength(lumpnum)); - Z_Free(data); -} - // // P_LoadNodes // @@ -844,13 +815,6 @@ static void P_LoadRawNodes(UINT8 *data, size_t i) } } -static void P_LoadNodes(lumpnum_t lumpnum) -{ - UINT8 *data = W_CacheLumpNum(lumpnum, PU_STATIC); - P_LoadRawNodes(data, W_LumpLength(lumpnum)); - Z_Free(data); -} - // // P_ReloadRings // Used by NiGHTS, clears all ring/wing/etc items and respawns them @@ -1041,13 +1005,6 @@ static void P_PrepareRawThings(UINT8 *data, size_t i) } } -static void P_PrepareThings(lumpnum_t lumpnum) -{ - UINT8 *data = W_CacheLumpNum(lumpnum, PU_STATIC); - P_PrepareRawThings(data, W_LumpLength(lumpnum)); - Z_Free(data); -} - static void P_LoadThings(boolean loademblems) { size_t i; @@ -1300,13 +1257,6 @@ static void P_LoadRawLineDefs(UINT8 *data, size_t i) } } -static void P_LoadLineDefs(lumpnum_t lumpnum) -{ - UINT8 *data = W_CacheLumpNum(lumpnum, PU_STATIC); - P_LoadRawLineDefs(data, W_LumpLength(lumpnum)); - Z_Free(data); -} - static void P_LoadLineDefs2(void) { size_t i = numlines; @@ -1419,12 +1369,6 @@ static inline void P_LoadRawSideDefs(size_t i) sides = Z_Calloc(numsides * sizeof (*sides), PU_LEVEL, NULL); } -static inline void P_LoadSideDefs(lumpnum_t lumpnum) -{ - P_LoadRawSideDefs(W_LumpLength(lumpnum)); -} - - static void P_LoadRawSideDefs2(void *data) { UINT16 i; @@ -1585,15 +1529,6 @@ static void P_LoadRawSideDefs2(void *data) R_ClearTextureNumCache(true); } -// Delay loading texture names until after loaded linedefs. -static void P_LoadSideDefs2(lumpnum_t lumpnum) -{ - UINT8 *data = W_CacheLumpNum(lumpnum, PU_STATIC); - P_LoadRawSideDefs2(data); - Z_Free(data); -} - - static boolean LineInBlock(fixed_t cx1, fixed_t cy1, fixed_t cx2, fixed_t cy2, fixed_t bx1, fixed_t by1) { fixed_t bbox[4]; @@ -1873,79 +1808,6 @@ static void P_ReadBlockMapLump(INT16 *wadblockmaplump, size_t count) } } -// -// P_LoadBlockMap -// -// Levels might not have a blockmap, so if one does not exist -// this should return false. -static boolean P_LoadBlockMap(lumpnum_t lumpnum) -{ -#if 0 - (void)lumpnum; - return false; -#else - size_t count; - const char *lumpname = W_CheckNameForNum(lumpnum); - - // Check if the lump exists, and if it's named "BLOCKMAP" - if (!lumpname || memcmp(lumpname, "BLOCKMAP", 8) != 0) - { - return false; - } - - count = W_LumpLength(lumpnum); - - if (!count || count >= 0x20000) - return false; - - { - INT16 *wadblockmaplump = malloc(count); //INT16 *wadblockmaplump = W_CacheLumpNum (lump, PU_LEVEL); - if (!wadblockmaplump) - return false; - W_ReadLump(lumpnum, wadblockmaplump); - count /= 2; - P_ReadBlockMapLump(wadblockmaplump, count); - free(wadblockmaplump); - } - - bmaporgx = blockmaplump[0]< Date: Wed, 11 Dec 2019 15:16:56 +0100 Subject: [PATCH 116/746] Oversight, do not free the data yet vres_Free() does it already at the end. --- src/p_spec.c | 1 - 1 file changed, 1 deletion(-) diff --git a/src/p_spec.c b/src/p_spec.c index 8ec1646ce..b50fc66c0 100644 --- a/src/p_spec.c +++ b/src/p_spec.c @@ -7200,7 +7200,6 @@ void P_SpawnSpecials(INT32 fromnetsave) I_Error("Make-Your-Own-FOF (tag %d) needs a value in the linedef's second side upper texture field.", lines[i].tag); } } - Z_Free(data); } else I_Error("Make-Your-Own FOF (tag %d) found without a 2nd linedef side!", lines[i].tag); From dedd5527dadd2827a2468ab70ff732eddd7c8bd3 Mon Sep 17 00:00:00 2001 From: Jaime Passos Date: Wed, 11 Dec 2019 11:35:34 -0300 Subject: [PATCH 117/746] Restore portal culling code that went gone by pure accident --- src/r_bsp.c | 8 ++++++++ src/r_main.c | 2 ++ src/r_portal.c | 1 + src/r_portal.h | 1 + 4 files changed, 12 insertions(+) diff --git a/src/r_bsp.c b/src/r_bsp.c index 2fcaf9e43..51d9bd3fd 100644 --- a/src/r_bsp.c +++ b/src/r_bsp.c @@ -1378,5 +1378,13 @@ void R_RenderBSPNode(INT32 bspnum) bspnum = bsp->children[side^1]; } + // PORTAL CULLING + if (portalcullsector) { + sector_t *sect = subsectors[bspnum & ~NF_SUBSECTOR].sector; + if (sect != portalcullsector) + return; + portalcullsector = NULL; + } + R_Subsector(bspnum == -1 ? 0 : bspnum & ~NF_SUBSECTOR); } diff --git a/src/r_main.c b/src/r_main.c index dd1243868..c21d339aa 100644 --- a/src/r_main.c +++ b/src/r_main.c @@ -1008,11 +1008,13 @@ static void R_PortalFrame(portal_t *portal) if (portal->clipline != -1) { portalclipline = &lines[portal->clipline]; + portalcullsector = portalclipline->frontsector; viewsector = portalclipline->frontsector; } else { portalclipline = NULL; + portalcullsector = NULL; viewsector = R_PointInSubsector(viewx, viewy)->sector; } } diff --git a/src/r_portal.c b/src/r_portal.c index 8995eaac4..576b606ec 100644 --- a/src/r_portal.c +++ b/src/r_portal.c @@ -26,6 +26,7 @@ UINT8 portalrender; /**< When rendering a portal, it establishes the depth of portal_t *portal_base, *portal_cap; line_t *portalclipline; +sector_t *portalcullsector; INT32 portalclipstart, portalclipend; boolean portalline; // is curline a portal seg? diff --git a/src/r_portal.h b/src/r_portal.h index 5990d1959..c46ddfdab 100644 --- a/src/r_portal.h +++ b/src/r_portal.h @@ -45,6 +45,7 @@ extern portal_t* portal_cap; extern UINT8 portalrender; extern line_t *portalclipline; +extern sector_t *portalcullsector; extern INT32 portalclipstart, portalclipend; void Portal_InitList (void); From d34fd4b755f7cf80cf84ca6ed31e337ff2ad762c Mon Sep 17 00:00:00 2001 From: Nev3r Date: Wed, 11 Dec 2019 15:48:44 +0100 Subject: [PATCH 118/746] Epic oversight in upside-down spawn offset. --- src/p_mobj.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/p_mobj.c b/src/p_mobj.c index 3d26b28f3..dae891afd 100644 --- a/src/p_mobj.c +++ b/src/p_mobj.c @@ -11615,7 +11615,7 @@ static fixed_t GetMobjSpawnHeight (const mobjtype_t i, const mapthing_t* mthing, #ifdef ESLOPE ss->sector->c_slope ? P_GetZAt(ss->sector->c_slope, x, y) : #endif - ss->sector->ceilingheight) - extraoffset - mobjinfo[i].height; + ss->sector->ceilingheight) - extraoffset - heightoffset - mobjinfo[i].height; else return ( #ifdef ESLOPE From be13f463f025ff9187003283179f3df66e986fd7 Mon Sep 17 00:00:00 2001 From: Jaime Passos Date: Wed, 11 Dec 2019 12:36:54 -0300 Subject: [PATCH 119/746] Update r_plane.c --- src/r_plane.c | 49 +++++++++++++++++++++++++++---------------------- 1 file changed, 27 insertions(+), 22 deletions(-) diff --git a/src/r_plane.c b/src/r_plane.c index 97a4ca9f8..aa7f9c6d1 100644 --- a/src/r_plane.c +++ b/src/r_plane.c @@ -135,6 +135,21 @@ INT32 ds_waterofs; static INT32 wtofs=0; static boolean itswater; +static fixed_t ripple_xfrac; +static fixed_t ripple_yfrac; + +static void R_PlaneRipple(visplane_t *plane, INT32 y, fixed_t plheight) +{ + fixed_t distance = FixedMul(plheight, yslope[y]); + const INT32 yay = (wtofs + (distance>>9) ) & 8191; + // ripples da water texture + angle_t angle = (plane->viewangle + plane->plangle)>>ANGLETOFINESHIFT; + ds_bgofs = FixedDiv(FINESINE(yay), (1<<12) + (distance>>11))>>FRACBITS; + + angle = (angle + 2048) & 8191; // 90 degrees + ripple_xfrac = FixedMul(FINECOSINE(angle), (ds_bgofs<>9) ) & 8191; - // ripples da water texture - ds_bgofs = FixedDiv(FINESINE(yay), (1<<12) + (distance>>11))>>FRACBITS; - angle = (currentplane->viewangle + currentplane->plangle + xtoviewangle[x1])>>ANGLETOFINESHIFT; - - angle = (angle + 2048) & 8191; // 90 degrees - ds_xfrac += FixedMul(FINECOSINE(angle), (ds_bgofs<slope) @@ -197,7 +206,12 @@ void R_MapPlane(INT32 y, INT32 x1, INT32 x2) ds_svp = &ds_sv[y]; ds_szp = &ds_sz[y]; } + else #endif + { + ds_xfrac += ripple_xfrac; + ds_yfrac += ripple_yfrac; + } if (y+ds_bgofs>=viewheight) ds_bgofs = viewheight-y-1; @@ -842,7 +856,6 @@ static UINT8 *R_GetTextureFlat(levelflat_t *levelflat, boolean leveltexture, boo return flat; } -// Lactokaiju #ifdef ESLOPE static void R_SlopeVectors(visplane_t *pl, INT32 i, float fudge) { @@ -924,7 +937,7 @@ d.z = (v1.x * v2.y) - (v1.y * v2.x) } else { - // I'm essentially multiplying the vectors by FRACUNIT... + // Lactozilla: I'm essentially multiplying the vectors by FRACUNIT... ds_su[i].x *= SFMULT; ds_su[i].y *= SFMULT; ds_su[i].z *= SFMULT; @@ -1209,6 +1222,7 @@ void R_DrawSinglePlane(visplane_t *pl) if (itswater) { INT32 i; + fixed_t plheight = abs(P_GetZAt(pl->slope, pl->viewx, pl->viewy) - pl->viewz); fixed_t rxoffs = xoffs; fixed_t ryoffs = yoffs; @@ -1216,18 +1230,9 @@ void R_DrawSinglePlane(visplane_t *pl) for (i = pl->high; i < pl->low; i++) { - // Fuck it - fixed_t plheight = abs(P_GetZAt(pl->slope, pl->viewx, pl->viewy) - pl->viewz); - fixed_t distance = FixedMul(plheight, yslope[i]); - const INT32 yay = (wtofs + (distance>>9) ) & 8191; - // ripples da water texture - ds_bgofs = FixedDiv(FINESINE(yay), (1<<12) + (distance>>11))>>FRACBITS; - angle = (pl->viewangle + pl->plangle)>>ANGLETOFINESHIFT; - - angle = (angle + 2048) & 8191; // 90 degrees - xoffs = rxoffs + FixedMul(FINECOSINE(angle), (ds_bgofs< Date: Wed, 11 Dec 2019 16:37:41 +0100 Subject: [PATCH 120/746] Treat warnings as errors; comment out unused function. --- src/w_wad.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/w_wad.c b/src/w_wad.c index 2e2d00516..f16e8eb5b 100644 --- a/src/w_wad.c +++ b/src/w_wad.c @@ -1944,6 +1944,7 @@ virtres_t* vres_GetMap (lumpnum_t lumpnum) vres = Z_Malloc(sizeof(virtres_t), PU_LEVEL, NULL); vres->vlumps = vlumps; vres->numlumps = numlumps; + return vres; } @@ -1961,12 +1962,14 @@ void vres_Free (virtres_t* vres) /** (Debug) Prints lumps from a virtual resource into console. */ +/* static void vres_Diag (const virtres_t* vres) { UINT32 i; for (i = 0; i < vres->numlumps; i++) CONS_Printf("%s\n", vres->vlumps[i].name); } +*/ /** \brief Finds a lump in a given virtual resource. * From 9340557d2de00ecdd8d3c4604ff92206c852a986 Mon Sep 17 00:00:00 2001 From: Jaime Passos Date: Wed, 11 Dec 2019 13:09:27 -0300 Subject: [PATCH 121/746] Update f_wipe.c --- src/f_wipe.c | 152 ++++++++++++++++++++++++++++++++++++++++----------- 1 file changed, 121 insertions(+), 31 deletions(-) diff --git a/src/f_wipe.c b/src/f_wipe.c index 829bceae0..fc6fc6b6d 100644 --- a/src/f_wipe.c +++ b/src/f_wipe.c @@ -282,7 +282,7 @@ static void F_DoWipe(fademask_t *fademask) relativepos += vid.width; } } - else if (*mask >= ((wipestyle == WIPESTYLE_COLORMAP) ? FADECOLORMAPROWS : 10)) + else if (*mask >= 10) { // shortcut - memcpy target to work while (draw_linestogo--) @@ -293,25 +293,8 @@ static void F_DoWipe(fademask_t *fademask) } else { - if (wipestyle == WIPESTYLE_COLORMAP) - { - int nmask; - UINT8 *fade = fadecolormap; - - if (wipestyleflags & WSF_TOWHITE) - fade = fadecolormap + (FADECOLORMAPROWS * 256); - - nmask = *mask; - if (wipestyleflags & WSF_FADEIN) - nmask = (FADECOLORMAPROWS-1) - nmask; - - transtbl = fade + (nmask * 256); - } - else - { - // pointer to transtable that this mask would use - transtbl = transtables + ((9 - *mask)<= fademask->width) + ++masky, maskx = 0; + } while (++mask < maskend); + + free(scrxpos); + free(scrypos); + } +} + +static void F_DoColormapWipe(fademask_t *fademask, UINT8 *colormap) +{ + // Lactozilla: F_DoWipe for WIPESTYLE_COLORMAP + { + // wipe screen, start, end + UINT8 *w = wipe_scr; + const UINT8 *s = wipe_scr_start; + const UINT8 *e = wipe_scr_end; + + // first pixel for each screen + UINT8 *w_base = w; + const UINT8 *s_base = s; + const UINT8 *e_base = e; + + // mask data, end + UINT8 *transtbl; + const UINT8 *mask = fademask->mask; + const UINT8 *maskend = mask + fademask->size; + + // rectangle draw hints + UINT32 draw_linestart, draw_rowstart; + UINT32 draw_lineend, draw_rowend; + UINT32 draw_linestogo, draw_rowstogo; + + // rectangle coordinates, etc. + UINT16* scrxpos = (UINT16*)malloc((fademask->width + 1) * sizeof(UINT16)); + UINT16* scrypos = (UINT16*)malloc((fademask->height + 1) * sizeof(UINT16)); + UINT16 maskx, masky; + UINT32 relativepos; + + // --- + // Screw it, we do the fixed point math ourselves up front. + scrxpos[0] = 0; + for (relativepos = 0, maskx = 1; maskx < fademask->width; ++maskx) + scrxpos[maskx] = (relativepos += fademask->xscale)>>FRACBITS; + scrxpos[fademask->width] = vid.width; + + scrypos[0] = 0; + for (relativepos = 0, masky = 1; masky < fademask->height; ++masky) + scrypos[masky] = (relativepos += fademask->yscale)>>FRACBITS; + scrypos[fademask->height] = vid.height; + // --- + + maskx = masky = 0; + do + { + draw_rowstart = scrxpos[maskx]; + draw_rowend = scrxpos[maskx + 1]; + draw_linestart = scrypos[masky]; + draw_lineend = scrypos[masky + 1]; + + relativepos = (draw_linestart * vid.width) + draw_rowstart; + draw_linestogo = draw_lineend - draw_linestart; + + if (*mask == 0) + { + // shortcut - memcpy source to work + while (draw_linestogo--) + { + M_Memcpy(w_base+relativepos, s_base+relativepos, draw_rowend-draw_rowstart); + relativepos += vid.width; + } + } + else if (*mask >= FADECOLORMAPROWS) + { + // shortcut - memcpy target to work + while (draw_linestogo--) + { + M_Memcpy(w_base+relativepos, e_base+relativepos, draw_rowend-draw_rowstart); + relativepos += vid.width; + } + } + else + { + int nmask = *mask; + if (wipestyleflags & WSF_FADEIN) + nmask = (FADECOLORMAPROWS-1) - nmask; + + transtbl = colormap + (nmask * 256); + + // DRAWING LOOP + while (draw_linestogo--) + { + w = w_base + relativepos; + s = s_base + relativepos; + e = e_base + relativepos; + draw_rowstogo = draw_rowend - draw_rowstart; + + while (draw_rowstogo--) + *w++ = transtbl[*e++]; relativepos += vid.width; } @@ -484,7 +564,17 @@ void F_RunWipe(UINT8 wipetype, boolean drawMenu) } else #endif - F_DoWipe(fmask); + { + if (wipestyle == WIPESTYLE_COLORMAP) + { + UINT8 *colormap = fadecolormap; + if (wipestyleflags & WSF_TOWHITE) + colormap += (FADECOLORMAPROWS * 256); + F_DoColormapWipe(fmask, colormap); + } + else + F_DoWipe(fmask); + } if (wipestyle == WIPESTYLE_COLORMAP) F_WipeStageTitle(); From 37679bb44e94779d8ae9c4804030cc77ccfd3ccc Mon Sep 17 00:00:00 2001 From: Jaime Passos Date: Wed, 11 Dec 2019 13:26:28 -0300 Subject: [PATCH 122/746] Organise --- src/f_wipe.c | 32 ++++++++++++++++++++------------ 1 file changed, 20 insertions(+), 12 deletions(-) diff --git a/src/f_wipe.c b/src/f_wipe.c index fc6fc6b6d..a83d104f2 100644 --- a/src/f_wipe.c +++ b/src/f_wipe.c @@ -553,32 +553,40 @@ void F_RunWipe(UINT8 wipetype, boolean drawMenu) I_Sleep(); lastwipetic = nowtime; + // Wipe styles + if (wipestyle == WIPESTYLE_COLORMAP) + { #ifdef HWRENDER - if (rendermode == render_opengl) - { - // send in the wipe type and wipe frame because we need to cache the graphic - if (wipestyle == WIPESTYLE_COLORMAP) + if (rendermode == render_opengl) + { + // send in the wipe type and wipe frame because we need to cache the graphic HWR_DoTintedWipe(wipetype, wipeframe-1); + } else - HWR_DoWipe(wipetype, wipeframe-1); - } - else #endif - { - if (wipestyle == WIPESTYLE_COLORMAP) { UINT8 *colormap = fadecolormap; if (wipestyleflags & WSF_TOWHITE) colormap += (FADECOLORMAPROWS * 256); F_DoColormapWipe(fmask, colormap); } + + // Draw the title card above the wipe + F_WipeStageTitle(); + } + else + { +#ifdef HWRENDER + if (rendermode == render_opengl) + { + // send in the wipe type and wipe frame because we need to cache the graphic + HWR_DoWipe(wipetype, wipeframe-1); + } else +#endif F_DoWipe(fmask); } - if (wipestyle == WIPESTYLE_COLORMAP) - F_WipeStageTitle(); - I_OsPolling(); I_UpdateNoBlit(); From 8a70759e0a2aec24d69a5db8a16322d7f1858a6e Mon Sep 17 00:00:00 2001 From: lachwright Date: Thu, 12 Dec 2019 01:27:41 +0800 Subject: [PATCH 123/746] Add TC_DASHMODE color shader --- src/hardware/hw_md2.c | 33 +++++++++++++++++++++++++++++++++ 1 file changed, 33 insertions(+) diff --git a/src/hardware/hw_md2.c b/src/hardware/hw_md2.c index 9d9171cea..61afee0ab 100644 --- a/src/hardware/hw_md2.c +++ b/src/hardware/hw_md2.c @@ -729,6 +729,39 @@ static void HWR_CreateBlendedTexture(GLPatch_t *gpatch, GLPatch_t *blendgpatch, cur++; image++; blendimage++; } } + else if (skinnum == TC_DASHMODE) + { + while (size--) + { + if (image->s.alpha == 0 && blendimage->s.alpha == 0) + { + // Don't bother with blending the pixel if the alpha of the blend pixel is 0 + cur->rgba = image->rgba; + } + else + { + UINT8 ialpha = 255 - blendimage->s.alpha, balpha = blendimage->s.alpha; + RGBA_t icolor = *image, bcolor; + + if (blendimage->s.alpha) + { + bcolor.s.blue = 0; + bcolor.s.red = 255; + bcolor.s.green = (blendimage->s.red + blendimage->s.green + blendimage->s.blue) / 3; + } + if (image->s.alpha && image->s.red > image->s.green << 1) // this is pretty arbitrary, but it works well for Metal Sonic + { + icolor.s.red = image->s.blue; + icolor.s.blue = image->s.red; + } + cur->s.red = (ialpha * icolor.s.red + balpha * bcolor.s.red)/255; + cur->s.green = (ialpha * icolor.s.green + balpha * bcolor.s.green)/255; + cur->s.blue = (ialpha * icolor.s.blue + balpha * bcolor.s.blue)/255; + cur->s.alpha = image->s.alpha; + } + cur++; image++; blendimage++; + } + } else { while (size--) From 6464df9876e472d1210aabce4237d02af38377e1 Mon Sep 17 00:00:00 2001 From: James R Date: Mon, 9 Dec 2019 20:04:09 -0800 Subject: [PATCH 124/746] Maybe I'm mistaken but this probably isn't needed --- 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 e80d07b76..00cb6e65e 100644 --- a/src/d_netcmd.c +++ b/src/d_netcmd.c @@ -1907,7 +1907,7 @@ static void Command_Map_f(void) } } - if (newmapnum == 0 || !mapheaderinfo[newmapnum-1]) + if (newmapnum == 0) { CONS_Alert(CONS_ERROR, M_GetText("Could not find any map described as '%s'.\n"), mapname); Z_Free(mapname); From e01eb1904488672ee5dd4b73d9590471128a1b29 Mon Sep 17 00:00:00 2001 From: Jaime Passos Date: Wed, 11 Dec 2019 22:11:00 -0300 Subject: [PATCH 125/746] Sad! --- src/r_data.c | 1 - 1 file changed, 1 deletion(-) diff --git a/src/r_data.c b/src/r_data.c index e8da4e4d3..a0655e611 100644 --- a/src/r_data.c +++ b/src/r_data.c @@ -438,7 +438,6 @@ static UINT8 *R_GenerateTexture(size_t texnum) texpatch_t *patch; patch_t *realpatch; UINT8 *pdata; - boolean dealloc = false; int x, x1, x2, i, width, height; size_t blocksize; column_t *patchcol; From d40359ee02a876efafdec5c77e9122ce166c0e58 Mon Sep 17 00:00:00 2001 From: Tatsuru Date: Wed, 11 Dec 2019 02:07:09 -0300 Subject: [PATCH 126/746] Hugging now requires being in the same Z position Don't try this at home --- src/p_mobj.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/p_mobj.c b/src/p_mobj.c index dea4a7a4d..a6812ff01 100644 --- a/src/p_mobj.c +++ b/src/p_mobj.c @@ -7833,7 +7833,8 @@ void P_MobjThinker(mobj_t *mobj) boolean dojump = false, targonground, love, makeheart = false; if (mobj->target != player->mo) P_SetTarget(&mobj->target, player->mo); - targonground = (P_IsObjectOnGround(mobj->target) && (player->panim == PA_IDLE || player->panim == PA_WALK || player->panim == PA_RUN)); + // Tatsuru: Don't try to hug them if they're above or below you! + targonground = (P_IsObjectOnGround(mobj->target) && (player->panim == PA_IDLE || player->panim == PA_WALK || player->panim == PA_RUN) && player->mo->z == mobj->z); love = (player->skin == 0 || player->skin == 5); switch (stat) From ea129f701c86f87daa7355e6f031d0633951cdfa Mon Sep 17 00:00:00 2001 From: Jaime Passos Date: Wed, 11 Dec 2019 22:45:47 -0300 Subject: [PATCH 127/746] Fix Ploadflat closing the game with "Too many flats in level" error message --- src/p_setup.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/p_setup.c b/src/p_setup.c index 3c45509ee..8a927d65a 100644 --- a/src/p_setup.c +++ b/src/p_setup.c @@ -672,7 +672,7 @@ INT32 P_AddLevelFlat(const char *flatname, levelflat_t *levelflat) // INT32 P_AddLevelFlatRuntime(const char *flatname) { - return Ploadflat(0, flatname); + return Ploadflat(levelflats, flatname); } // help function for $$$.sav checking From f1b5a2b2d33809600d83d5cf45f52177b6f4da77 Mon Sep 17 00:00:00 2001 From: fickleheart Date: Wed, 11 Dec 2019 21:09:23 -0600 Subject: [PATCH 128/746] Move Z-targeting behavior to Center View --- src/g_game.c | 51 +++++++++++++++++++++++++++++--------------------- src/g_game.h | 2 +- src/hu_stuff.c | 4 ++-- src/m_menu.c | 2 +- src/p_user.c | 14 ++------------ 5 files changed, 36 insertions(+), 37 deletions(-) diff --git a/src/g_game.c b/src/g_game.c index f198301a9..86a0252ac 100644 --- a/src/g_game.c +++ b/src/g_game.c @@ -1019,7 +1019,7 @@ static fixed_t forwardmove[2] = {25<>16, 50<>16}; static fixed_t sidemove[2] = {25<>16, 50<>16}; // faster! static fixed_t angleturn[3] = {640, 1280, 320}; // + slow turn -boolean ticcmd_resetdown[2]; // don't cam reset every frame +boolean ticcmd_centerviewdown[2]; // For simple controls, lock the camera behind the player void G_BuildTiccmd(ticcmd_t *cmd, INT32 realtics, UINT8 ssplayer) { boolean forcestrafe = false; @@ -1039,6 +1039,7 @@ void G_BuildTiccmd(ticcmd_t *cmd, INT32 realtics, UINT8 ssplayer) static INT32 turnheld[2]; // for accelerative turning static boolean keyboard_look[2]; // true if lookup/down using keyboard + static boolean resetdown[2]; // don't cam reset every frame static boolean joyaiming[2]; // check the last frame's value if we need to reset the camera UINT8 forplayer = ssplayer-1; @@ -1256,26 +1257,34 @@ void G_BuildTiccmd(ticcmd_t *cmd, INT32 realtics, UINT8 ssplayer) if (PLAYERINPUTDOWN(ssplayer, gc_use) || (usejoystick && axis > 0)) cmd->buttons |= BT_USE; + if (PLAYERINPUTDOWN(ssplayer, gc_centerview)) + { + if (abilitydirection) + { + CV_SetValue((ssplayer == 1 ? &cv_directionchar : &cv_directionchar2), 0); + *myangle = player->mo->angle; + *myaiming = 0; + } + + ticcmd_centerviewdown[forplayer] = true; + } + else + { + CV_SetValue((ssplayer == 1 ? &cv_directionchar : &cv_directionchar2), 1); + + ticcmd_centerviewdown[forplayer] = false; + } + if (PLAYERINPUTDOWN(ssplayer, gc_camreset)) { - if (camera.chase && !ticcmd_resetdown[forplayer]) - { - ticcmd_resetdown[forplayer] = true; + if (camera.chase && !resetdown[forplayer]) P_ResetCamera(&players[ssplayer == 1 ? displayplayer : secondarydisplayplayer], &camera); - if (abilitydirection) - CV_SetValue((ssplayer == 1 ? &cv_directionchar : &cv_directionchar2), 0); - } - else - ticcmd_resetdown[forplayer] = true; + resetdown[forplayer] = true; } - else if (ticcmd_resetdown[forplayer]) - { - ticcmd_resetdown[forplayer] = false; + else + resetdown[forplayer] = false; - if (abilitydirection) - CV_SetValue((ssplayer == 1 ? &cv_directionchar : &cv_directionchar2), 1); - } // jump button axis = PlayerJoyAxis(ssplayer, AXISJUMP); @@ -1320,7 +1329,7 @@ void G_BuildTiccmd(ticcmd_t *cmd, INT32 realtics, UINT8 ssplayer) *myaiming -= KB_LOOKSPEED * screen_invert; keyboard_look[forplayer] = true; } - else if (PLAYERINPUTDOWN(ssplayer, gc_centerview)) + else if (ticcmd_centerviewdown[forplayer]) *myaiming = 0; } @@ -1408,7 +1417,7 @@ void G_BuildTiccmd(ticcmd_t *cmd, INT32 realtics, UINT8 ssplayer) // Adjust camera angle by player input if (abilitydirection && !forcestrafe && camera.chase && !turnheld[forplayer] && - !(ticcmd_resetdown[forplayer] && !(cv_cam_lockedinput[forplayer].value || (player->pflags & PF_STARTDASH))) + !(ticcmd_centerviewdown[forplayer] && !(cv_cam_lockedinput[forplayer].value || (player->pflags & PF_STARTDASH))) && !player->climbing && player->powers[pw_carry] != CR_MINECART) { fixed_t camadjustfactor = cv_cam_turnfacinginput[forplayer].value; //@TODO cvar @@ -1418,17 +1427,17 @@ void G_BuildTiccmd(ticcmd_t *cmd, INT32 realtics, UINT8 ssplayer) fixed_t sine = FINESINE((R_PointToAngle2(0, 0, player->rmomx, player->rmomy) - localangle)>>ANGLETOFINESHIFT); fixed_t factor = min(20, FixedMul(player->speed, abs(sine)) / FRACUNIT); - if (ticcmd_resetdown[forplayer] && (cv_cam_lockedinput[forplayer].value || (player->pflags & PF_STARTDASH))) + if (ticcmd_centerviewdown[forplayer] && (cv_cam_lockedinput[forplayer].value || (player->pflags & PF_STARTDASH))) factor = (ssplayer == 1 ? cv_cam_rotspeed.value : cv_cam2_rotspeed.value) * (cv_cam_lockedinput[forplayer].value ?: 1); // Turn while in startdash and locking camera *myangle -= cmd->sidemove * factor * camadjustfactor; } - if (ticcmd_resetdown[forplayer] && (cv_cam_lockedinput[forplayer].value || (player->pflags & PF_STARTDASH))) + if (ticcmd_centerviewdown[forplayer] && (cv_cam_lockedinput[forplayer].value || (player->pflags & PF_STARTDASH))) cmd->sidemove = 0; } - if (abilitydirection && camera.chase && !ticcmd_resetdown[forplayer] && !player->climbing && !forcestrafe && (player->pflags & PF_DIRECTIONCHAR) && player->powers[pw_carry] != CR_MINECART) + if (abilitydirection && camera.chase && !ticcmd_centerviewdown[forplayer] && !player->climbing && !forcestrafe && (player->pflags & PF_DIRECTIONCHAR) && player->powers[pw_carry] != CR_MINECART) { ///@TODO This block of code is a hack to get the desired abilitydirection and player angle behaviors while remaining netplay-compatible with EXEs without those features. // This has side effects like making F12 spectate look kind of weird, and making the input viewer inaccurate. @@ -1451,7 +1460,7 @@ void G_BuildTiccmd(ticcmd_t *cmd, INT32 realtics, UINT8 ssplayer) // Adjust camera angle to face player direction, depending on circumstances // Nothing happens if cam left/right are held, so you can hold both to lock the camera in one direction - if (abilitydirection && !forcestrafe && camera.chase && !turnheld[forplayer] && !ticcmd_resetdown[forplayer] && player->powers[pw_carry] != CR_MINECART) + if (abilitydirection && !forcestrafe && camera.chase && !turnheld[forplayer] && !ticcmd_centerviewdown[forplayer] && player->powers[pw_carry] != CR_MINECART) { fixed_t camadjustfactor; diff --git a/src/g_game.h b/src/g_game.h index 2775382c9..f0cdcd844 100644 --- a/src/g_game.h +++ b/src/g_game.h @@ -89,7 +89,7 @@ extern consvar_t cv_abilitydirection[2], cv_cam_shiftfacing[2], cv_cam_turnfacin // build an internal map name MAPxx from map number const char *G_BuildMapName(INT32 map); -extern boolean ticcmd_resetdown[2]; // don't cam reset every frame +extern boolean ticcmd_centerviewdown[2]; // For simple controls, lock the camera behind the player void G_BuildTiccmd(ticcmd_t *cmd, INT32 realtics, UINT8 ssplayer); // copy ticcmd_t to and fro the normal way diff --git a/src/hu_stuff.c b/src/hu_stuff.c index 03489101d..e1e271064 100644 --- a/src/hu_stuff.c +++ b/src/hu_stuff.c @@ -2194,10 +2194,10 @@ void HU_Drawer(void) return; // draw the crosshair, not when viewing demos nor with chasecam - if (!automapactive && cv_crosshair.value && !demoplayback && (!camera.chase || (cv_abilitydirection[0].value && ticcmd_resetdown[0])) && !players[displayplayer].spectator) + if (!automapactive && cv_crosshair.value && !demoplayback && (!camera.chase || (cv_abilitydirection[0].value && ticcmd_centerviewdown[0])) && !players[displayplayer].spectator) HU_DrawCrosshair(); - if (!automapactive && cv_crosshair2.value && !demoplayback && (!camera2.chase || (cv_abilitydirection[1].value && ticcmd_resetdown[1])) && !players[secondarydisplayplayer].spectator) + if (!automapactive && cv_crosshair2.value && !demoplayback && (!camera2.chase || (cv_abilitydirection[1].value && ticcmd_centerviewdown[1])) && !players[secondarydisplayplayer].spectator) HU_DrawCrosshair2(); // draw desynch text diff --git a/src/m_menu.c b/src/m_menu.c index 92f2e21d8..c57126805 100644 --- a/src/m_menu.c +++ b/src/m_menu.c @@ -4256,7 +4256,7 @@ const char *PlaystyleDesc[4] = { "and acts in the direction\n" "they're moving.\n" "\n" - "Hold \x82Reset Camera\x80 to lock the\n" + "Hold \x82Center View\x80 to lock the\n" "camera behind the player!\n" , diff --git a/src/p_user.c b/src/p_user.c index 8dd76d0ef..6930f3da7 100644 --- a/src/p_user.c +++ b/src/p_user.c @@ -9652,17 +9652,7 @@ void P_ResetCamera(player_t *player, camera_t *thiscam) thiscam->y = y; thiscam->z = z; - if (thiscam == &camera && cv_abilitydirection[0].value && ticcmd_resetdown[0]) - { - localangle = player->mo->angle; - localaiming = thiscam->aiming = 0; - } - else if (thiscam == &camera2 && cv_abilitydirection[1].value && ticcmd_resetdown[1]) - { - localangle2 = player->mo->angle; - localaiming2 = thiscam->aiming = 0; - } - else if (!(thiscam == &camera && (cv_cam_still.value || cv_analog.value)) + if (!(thiscam == &camera && (cv_cam_still.value || cv_analog.value)) && !(thiscam == &camera2 && (cv_cam2_still.value || cv_analog2.value))) { thiscam->angle = player->mo->angle; @@ -9905,7 +9895,7 @@ boolean P_MoveChaseCamera(player_t *player, camera_t *thiscam, boolean resetcall if (player->powers[pw_carry] == CR_ROLLOUT) shift = -shift; - if (ticcmd_resetdown[(thiscam == &camera) ? 0 : 1]) + if (ticcmd_centerviewdown[(thiscam == &camera) ? 0 : 1]) shift = FixedMul(camsideshift[forplayer], FRACUNIT-camspeed); else shift += FixedMul(camsideshift[forplayer] - shift, FRACUNIT-(camspeed>>3)); From a830a20c52664a16d494ac3918d270a7839a12f4 Mon Sep 17 00:00:00 2001 From: fickleheart Date: Wed, 11 Dec 2019 21:12:38 -0600 Subject: [PATCH 129/746] [pink text] nter View --- 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 c57126805..16a398cde 100644 --- a/src/m_menu.c +++ b/src/m_menu.c @@ -4256,7 +4256,7 @@ const char *PlaystyleDesc[4] = { "and acts in the direction\n" "they're moving.\n" "\n" - "Hold \x82Center View\x80 to lock the\n" + "Hold \x82" "Center View\x80 to lock the\n" "camera behind the player!\n" , From a0ecb4b71d12acea5396e96699ec659164f6ad6c Mon Sep 17 00:00:00 2001 From: fickleheart Date: Wed, 11 Dec 2019 21:20:07 -0600 Subject: [PATCH 130/746] Fix the console spam issue AGAIN --- src/g_game.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/src/g_game.c b/src/g_game.c index 86a0252ac..d92209d4e 100644 --- a/src/g_game.c +++ b/src/g_game.c @@ -1259,7 +1259,7 @@ void G_BuildTiccmd(ticcmd_t *cmd, INT32 realtics, UINT8 ssplayer) if (PLAYERINPUTDOWN(ssplayer, gc_centerview)) { - if (abilitydirection) + if (abilitydirection && !ticcmd_centerviewdown[forplayer]) { CV_SetValue((ssplayer == 1 ? &cv_directionchar : &cv_directionchar2), 0); *myangle = player->mo->angle; @@ -1268,9 +1268,10 @@ void G_BuildTiccmd(ticcmd_t *cmd, INT32 realtics, UINT8 ssplayer) ticcmd_centerviewdown[forplayer] = true; } - else + else if (ticcmd_centerviewdown[forplayer]) { - CV_SetValue((ssplayer == 1 ? &cv_directionchar : &cv_directionchar2), 1); + if (abilitydirection) + CV_SetValue((ssplayer == 1 ? &cv_directionchar : &cv_directionchar2), 1); ticcmd_centerviewdown[forplayer] = false; } From 34706515ca02e948f5cf9fce558f862abf235f3e Mon Sep 17 00:00:00 2001 From: fickleheart Date: Wed, 11 Dec 2019 21:34:32 -0600 Subject: [PATCH 131/746] Make locked input turn act the same as normal turning --- src/g_game.c | 22 +++++++++++++++++----- 1 file changed, 17 insertions(+), 5 deletions(-) diff --git a/src/g_game.c b/src/g_game.c index d92209d4e..1663b147c 100644 --- a/src/g_game.c +++ b/src/g_game.c @@ -421,7 +421,7 @@ consvar_t cv_cam_turnfacinginput[2] = { {"cam2_turnfacinginput", "0.4375", CV_FLOAT|CV_SAVE, zerotoone_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL}, }; -static CV_PossibleValue_t lockedinput_cons_t[] = {{0, "Strafe"}, {1, "Turn Slow"}, {2, "Turn"}, {0, NULL}}; +static CV_PossibleValue_t lockedinput_cons_t[] = {{0, "Strafe"}, {1, "Turn"}, {0, NULL}}; consvar_t cv_cam_lockedinput[2] = { {"cam_lockedinput", "Strafe", CV_SAVE, lockedinput_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL}, @@ -1028,6 +1028,7 @@ void G_BuildTiccmd(ticcmd_t *cmd, INT32 realtics, UINT8 ssplayer) const INT32 speed = 1; // these ones used for multiple conditions boolean turnleft, turnright, strafelkey, straferkey, movefkey, movebkey, mouseaiming, analogjoystickmove, gamepadjoystickmove, thisjoyaiming; + boolean strafeisturn; // Simple controls only player_t *player = &players[ssplayer == 2 ? secondarydisplayplayer : consoleplayer]; camera_t *thiscam = ((ssplayer == 1 || player->bot == 2) ? &camera : &camera2); angle_t *myangle = (ssplayer == 1 ? &localangle : &localangle2); @@ -1073,6 +1074,10 @@ void G_BuildTiccmd(ticcmd_t *cmd, INT32 realtics, UINT8 ssplayer) } abilitydirection = cv_abilitydirection[forplayer].value; + strafeisturn = abilitydirection && ticcmd_centerviewdown[forplayer] && + (cv_cam_lockedinput[forplayer].value || (player->pflags & PF_STARTDASH)) && + !player->climbing && player->powers[pw_carry] != CR_MINECART; + // why build a ticcmd if we're paused? // Or, for that matter, if we're being reborn. // ...OR if we're blindfolded. No looking into the floor. @@ -1092,6 +1097,13 @@ void G_BuildTiccmd(ticcmd_t *cmd, INT32 realtics, UINT8 ssplayer) movefkey = PLAYERINPUTDOWN(ssplayer, gc_forward); movebkey = PLAYERINPUTDOWN(ssplayer, gc_backward); + if (strafeisturn) + { + turnright |= straferkey; + turnleft |= strafelkey; + straferkey = strafelkey = false; + } + mouseaiming = (PLAYERINPUTDOWN(ssplayer, gc_mouseaiming)) ^ ((chasecam && !player->spectator) ? chasefreelook : alwaysfreelook); analogjoystickmove = usejoystick && !Joystick.bGamepadStyle; @@ -1105,6 +1117,8 @@ void G_BuildTiccmd(ticcmd_t *cmd, INT32 realtics, UINT8 ssplayer) joyaiming[forplayer] = thisjoyaiming; axis = PlayerJoyAxis(ssplayer, AXISTURN); + if (strafeisturn) + axis += PlayerJoyAxis(ssplayer, AXISSTRAFE); if (gamepadjoystickmove && axis != 0) { turnright = turnright || (axis > 0); @@ -1178,7 +1192,7 @@ void G_BuildTiccmd(ticcmd_t *cmd, INT32 realtics, UINT8 ssplayer) cmd->angleturn = (cmd->angleturn * (ssplayer == 1 ? cv_cam_rotspeed.value : cv_cam2_rotspeed.value)) / 10; } - axis = PlayerJoyAxis(ssplayer, AXISSTRAFE); + axis = strafeisturn ? 0 : PlayerJoyAxis(ssplayer, AXISSTRAFE); if (gamepadjoystickmove && axis != 0) { if (axis < 0) @@ -1417,9 +1431,7 @@ void G_BuildTiccmd(ticcmd_t *cmd, INT32 realtics, UINT8 ssplayer) cmd->angleturn = (INT16)(*myangle >> 16); // Adjust camera angle by player input - if (abilitydirection && !forcestrafe && camera.chase && !turnheld[forplayer] && - !(ticcmd_centerviewdown[forplayer] && !(cv_cam_lockedinput[forplayer].value || (player->pflags & PF_STARTDASH))) - && !player->climbing && player->powers[pw_carry] != CR_MINECART) + if (abilitydirection && !forcestrafe && camera.chase && !turnheld[forplayer] && !player->climbing && player->powers[pw_carry] != CR_MINECART) { fixed_t camadjustfactor = cv_cam_turnfacinginput[forplayer].value; //@TODO cvar From 3ca0fbf5c30fa871f647bcdc98be118d842e81f3 Mon Sep 17 00:00:00 2001 From: Jaime Passos Date: Thu, 12 Dec 2019 01:29:59 -0300 Subject: [PATCH 132/746] 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 efec52c48aecced4d412f44104043b47add1d720 Mon Sep 17 00:00:00 2001 From: fickleheart Date: Wed, 11 Dec 2019 22:47:09 -0600 Subject: [PATCH 133/746] Fix input turning still happening with centered view --- 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 1663b147c..7e23a757f 100644 --- a/src/g_game.c +++ b/src/g_game.c @@ -1431,7 +1431,7 @@ void G_BuildTiccmd(ticcmd_t *cmd, INT32 realtics, UINT8 ssplayer) cmd->angleturn = (INT16)(*myangle >> 16); // Adjust camera angle by player input - if (abilitydirection && !forcestrafe && camera.chase && !turnheld[forplayer] && !player->climbing && player->powers[pw_carry] != CR_MINECART) + if (abilitydirection && !forcestrafe && camera.chase && !turnheld[forplayer] && !ticcmd_centerviewdown[forplayer] && !player->climbing && player->powers[pw_carry] != CR_MINECART) { fixed_t camadjustfactor = cv_cam_turnfacinginput[forplayer].value; //@TODO cvar From 0ff421d0017f3039e698c51452cd01658b7328fb Mon Sep 17 00:00:00 2001 From: James R Date: Wed, 11 Dec 2019 22:10:22 -0800 Subject: [PATCH 134/746] Move I_ShutdownConsole to I_ShutdownSystem --- src/sdl/i_system.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/src/sdl/i_system.c b/src/sdl/i_system.c index 13fb25bea..03eeb634f 100644 --- a/src/sdl/i_system.c +++ b/src/sdl/i_system.c @@ -2169,7 +2169,6 @@ void I_Quit(void) if (quiting) goto death; SDLforceUngrabMouse(); quiting = SDL_FALSE; - I_ShutdownConsole(); M_SaveConfig(NULL); //save game config, cvars.. #ifndef NONET D_SaveBan(); // save the ban list @@ -2287,8 +2286,6 @@ void I_Error(const char *error, ...) I_OutputMsg("\nI_Error(): %s\n", buffer); // --- - I_ShutdownConsole(); - M_SaveConfig(NULL); // save game config, cvars.. #ifndef NONET D_SaveBan(); // save the ban list @@ -2388,6 +2385,8 @@ void I_ShutdownSystem(void) { INT32 c; + I_ShutdownConsole(); + for (c = MAX_QUIT_FUNCS-1; c >= 0; c--) if (quit_funcs[c]) (*quit_funcs[c])(); From a188cd5db8eff18c95af0105ead0fe0b9bf00899 Mon Sep 17 00:00:00 2001 From: fickleheart Date: Thu, 12 Dec 2019 00:48:15 -0600 Subject: [PATCH 135/746] Add boss target assist and finally organize camera options --- src/d_netcmd.c | 2 + src/g_game.c | 42 ++++++++++++++++ src/g_game.h | 3 +- src/hu_stuff.c | 8 ++- src/m_menu.c | 132 ++++++++++++++++++++++++++++++------------------- src/p_local.h | 2 + src/p_user.c | 88 +++++++++++++++++++++++++++++++++ 7 files changed, 223 insertions(+), 54 deletions(-) diff --git a/src/d_netcmd.c b/src/d_netcmd.c index 512451b85..d05c5cc45 100644 --- a/src/d_netcmd.c +++ b/src/d_netcmd.c @@ -840,6 +840,8 @@ void D_RegisterClientCommands(void) CV_RegisterVar(&cv_cam_turnfacinginput[1]); CV_RegisterVar(&cv_cam_lockedinput[0]); CV_RegisterVar(&cv_cam_lockedinput[1]); + CV_RegisterVar(&cv_cam_lockonboss[0]); + CV_RegisterVar(&cv_cam_lockonboss[1]); // s_sound.c CV_RegisterVar(&cv_soundvolume); diff --git a/src/g_game.c b/src/g_game.c index 7e23a757f..a118ec09d 100644 --- a/src/g_game.c +++ b/src/g_game.c @@ -428,6 +428,11 @@ consvar_t cv_cam_lockedinput[2] = { {"cam2_lockedinput", "Strafe", CV_SAVE, lockedinput_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL}, }; +consvar_t cv_cam_lockonboss[2] = { + {"cam_lockonboss", "On", CV_SAVE, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL}, + {"cam2_lockonboss", "On", CV_SAVE, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL}, +}; + typedef enum { AXISNONE = 0, @@ -1020,6 +1025,7 @@ static fixed_t sidemove[2] = {25<>16, 50<>16}; // faster! static fixed_t angleturn[3] = {640, 1280, 320}; // + slow turn boolean ticcmd_centerviewdown[2]; // For simple controls, lock the camera behind the player +mobj_t *ticcmd_ztargetfocus[2]; // Locking onto an object? void G_BuildTiccmd(ticcmd_t *cmd, INT32 realtics, UINT8 ssplayer) { boolean forcestrafe = false; @@ -1278,6 +1284,9 @@ void G_BuildTiccmd(ticcmd_t *cmd, INT32 realtics, UINT8 ssplayer) CV_SetValue((ssplayer == 1 ? &cv_directionchar : &cv_directionchar2), 0); *myangle = player->mo->angle; *myaiming = 0; + + if (cv_cam_lockonboss[forplayer].value) + P_SetTarget(&ticcmd_ztargetfocus[forplayer], P_LookForFocusTarget(player, NULL, 0)); } ticcmd_centerviewdown[forplayer] = true; @@ -1285,11 +1294,44 @@ void G_BuildTiccmd(ticcmd_t *cmd, INT32 realtics, UINT8 ssplayer) else if (ticcmd_centerviewdown[forplayer]) { if (abilitydirection) + { + P_SetTarget(&ticcmd_ztargetfocus[forplayer], NULL); CV_SetValue((ssplayer == 1 ? &cv_directionchar : &cv_directionchar2), 1); + } ticcmd_centerviewdown[forplayer] = false; } + if (ticcmd_ztargetfocus[forplayer]) + { + if ( + P_MobjWasRemoved(ticcmd_ztargetfocus[forplayer]) || + !ticcmd_ztargetfocus[forplayer]->health || + (ticcmd_ztargetfocus[forplayer]->flags2 & MF2_FRET) || + (ticcmd_ztargetfocus[forplayer]->type == MT_EGGMOBILE3 && !ticcmd_ztargetfocus[forplayer]->movecount) // Sea Egg is moving around underground and shouldn't be tracked + ) + P_SetTarget(&ticcmd_ztargetfocus[forplayer], NULL); + else + { + if (P_AproxDistance( + player->mo->x - ticcmd_ztargetfocus[forplayer]->x, + player->mo->y - ticcmd_ztargetfocus[forplayer]->y + ) > 50*player->mo->scale) + { + INT32 anglediff = R_PointToAngle2(player->mo->x, player->mo->y, ticcmd_ztargetfocus[forplayer]->x, ticcmd_ztargetfocus[forplayer]->y) - *myangle; + const INT32 maxturn = ANG10/2; + anglediff /= 4; + + if (anglediff > maxturn) + anglediff = maxturn; + else if (anglediff < -maxturn) + anglediff = -maxturn; + + *myangle += anglediff; + } + } + } + if (PLAYERINPUTDOWN(ssplayer, gc_camreset)) { if (camera.chase && !resetdown[forplayer]) diff --git a/src/g_game.h b/src/g_game.h index f0cdcd844..f6e7acede 100644 --- a/src/g_game.h +++ b/src/g_game.h @@ -79,7 +79,7 @@ extern consvar_t cv_ghost_bestscore, cv_ghost_besttime, cv_ghost_bestrings, cv_g // hi here's some new controls extern consvar_t cv_abilitydirection[2], cv_cam_shiftfacing[2], cv_cam_turnfacing[2], cv_cam_turnfacingability[2], cv_cam_turnfacingspindash[2], cv_cam_turnfacinginput[2], - cv_cam_lockedinput[2]; + cv_cam_lockedinput[2], cv_cam_lockonboss[2]; // mouseaiming (looking up/down with the mouse or keyboard) #define KB_LOOKSPEED (1<<25) @@ -90,6 +90,7 @@ extern consvar_t cv_abilitydirection[2], cv_cam_shiftfacing[2], cv_cam_turnfacin const char *G_BuildMapName(INT32 map); extern boolean ticcmd_centerviewdown[2]; // For simple controls, lock the camera behind the player +extern mobj_t *ticcmd_ztargetfocus[2]; // Locking onto an object? void G_BuildTiccmd(ticcmd_t *cmd, INT32 realtics, UINT8 ssplayer); // copy ticcmd_t to and fro the normal way diff --git a/src/hu_stuff.c b/src/hu_stuff.c index e1e271064..c1818bd4b 100644 --- a/src/hu_stuff.c +++ b/src/hu_stuff.c @@ -2194,10 +2194,14 @@ void HU_Drawer(void) return; // draw the crosshair, not when viewing demos nor with chasecam - if (!automapactive && cv_crosshair.value && !demoplayback && (!camera.chase || (cv_abilitydirection[0].value && ticcmd_centerviewdown[0])) && !players[displayplayer].spectator) + if (!automapactive && cv_crosshair.value && !demoplayback && + (!camera.chase || (cv_abilitydirection[0].value && ticcmd_centerviewdown[0] && ticcmd_ztargetfocus[0])) + && !players[displayplayer].spectator) HU_DrawCrosshair(); - if (!automapactive && cv_crosshair2.value && !demoplayback && (!camera2.chase || (cv_abilitydirection[1].value && ticcmd_centerviewdown[1])) && !players[secondarydisplayplayer].spectator) + if (!automapactive && cv_crosshair2.value && !demoplayback && + (!camera2.chase || (cv_abilitydirection[1].value && ticcmd_centerviewdown[1] && ticcmd_ztargetfocus[1])) + && !players[secondarydisplayplayer].spectator) HU_DrawCrosshair2(); // draw desynch text diff --git a/src/m_menu.c b/src/m_menu.c index 16a398cde..6d42fddda 100644 --- a/src/m_menu.c +++ b/src/m_menu.c @@ -1182,46 +1182,96 @@ static menuitem_t OP_Mouse2OptionsMenu[] = static menuitem_t OP_CameraOptionsMenu[] = { + {IT_HEADER, NULL, "General Toggles", NULL, 0}, {IT_STRING | IT_CVAR, NULL, "Third-person Camera" , &cv_chasecam , 5}, {IT_STRING | IT_CVAR, NULL, "Flip Camera with Gravity" , &cv_flipcam , 10}, {IT_STRING | IT_CVAR, NULL, "Orbital Looking" , &cv_cam_orbit , 15}, {IT_STRING | IT_CVAR, NULL, "Downhill Slope Adjustment", &cv_cam_adjust, 20}, - {IT_STRING | IT_CVAR | IT_CV_INTEGERSTEP, NULL, "Camera Distance", &cv_cam_dist, 30}, - {IT_STRING | IT_CVAR | IT_CV_INTEGERSTEP, NULL, "Camera Height", &cv_cam_height, 35}, - {IT_STRING | IT_CVAR | IT_CV_FLOATSLIDER, NULL, "Camera Speed", &cv_cam_speed, 40}, - {IT_STRING | IT_CVAR | IT_CV_SLIDER, NULL, "Rotation Speed", &cv_cam_rotspeed, 45}, + {IT_HEADER, NULL, "Camera Positioning", NULL, 30}, + {IT_STRING | IT_CVAR | IT_CV_INTEGERSTEP, NULL, "Camera Distance", &cv_cam_dist, 35}, + {IT_STRING | IT_CVAR | IT_CV_INTEGERSTEP, NULL, "Camera Height", &cv_cam_height, 40}, + {IT_STRING | IT_CVAR | IT_CV_FLOATSLIDER, NULL, "Camera Speed", &cv_cam_speed, 45}, + {IT_STRING | IT_CVAR | IT_CV_SLIDER, NULL, "Rotation Speed", &cv_cam_rotspeed, 50}, - {IT_STRING | IT_CVAR | IT_CV_SLIDER, NULL, "Shift to player angle", &cv_cam_shiftfacing[0], 55}, - {IT_STRING | IT_CVAR | IT_CV_SLIDER, NULL, "Turn to player angle", &cv_cam_turnfacing[0], 60}, - {IT_STRING | IT_CVAR | IT_CV_SLIDER, NULL, "Turn to ability", &cv_cam_turnfacingability[0], 65}, - {IT_STRING | IT_CVAR | IT_CV_SLIDER, NULL, "Turn to spindash", &cv_cam_turnfacingspindash[0], 70}, - {IT_STRING | IT_CVAR | IT_CV_SLIDER, NULL, "Turn to input", &cv_cam_turnfacinginput[0], 75}, - {IT_STRING | IT_CVAR, NULL, "Locked movement", &cv_cam_lockedinput[0], 80}, - - {IT_STRING | IT_CVAR, NULL, "Crosshair", &cv_crosshair, 90}, + {IT_HEADER, NULL, "Display Options", NULL, 60}, + {IT_STRING | IT_CVAR, NULL, "Crosshair", &cv_crosshair, 65}, }; static menuitem_t OP_Camera2OptionsMenu[] = { + {IT_HEADER, NULL, "General Toggles", NULL, 0}, {IT_STRING | IT_CVAR, NULL, "Third-person Camera" , &cv_chasecam2 , 5}, {IT_STRING | IT_CVAR, NULL, "Flip Camera with Gravity" , &cv_flipcam2 , 10}, {IT_STRING | IT_CVAR, NULL, "Orbital Looking" , &cv_cam2_orbit , 15}, {IT_STRING | IT_CVAR, NULL, "Downhill Slope Adjustment", &cv_cam2_adjust, 20}, - {IT_STRING | IT_CVAR | IT_CV_INTEGERSTEP, NULL, "Camera Distance", &cv_cam2_dist, 30}, - {IT_STRING | IT_CVAR | IT_CV_INTEGERSTEP, NULL, "Camera Height", &cv_cam2_height, 35}, - {IT_STRING | IT_CVAR | IT_CV_FLOATSLIDER, NULL, "Camera Speed", &cv_cam2_speed, 40}, - {IT_STRING | IT_CVAR | IT_CV_SLIDER, NULL, "Rotation Speed", &cv_cam2_rotspeed, 45}, + {IT_HEADER, NULL, "Camera Positioning", NULL, 30}, + {IT_STRING | IT_CVAR | IT_CV_INTEGERSTEP, NULL, "Camera Distance", &cv_cam2_dist, 35}, + {IT_STRING | IT_CVAR | IT_CV_INTEGERSTEP, NULL, "Camera Height", &cv_cam2_height, 40}, + {IT_STRING | IT_CVAR | IT_CV_FLOATSLIDER, NULL, "Camera Speed", &cv_cam2_speed, 45}, + {IT_STRING | IT_CVAR | IT_CV_SLIDER, NULL, "Rotation Speed", &cv_cam2_rotspeed, 50}, - {IT_STRING | IT_CVAR | IT_CV_SLIDER, NULL, "Shift to character angle", &cv_cam_shiftfacing[1], 55}, - {IT_STRING | IT_CVAR | IT_CV_SLIDER, NULL, "Turn to character angle", &cv_cam_turnfacing[1], 60}, - {IT_STRING | IT_CVAR | IT_CV_SLIDER, NULL, "Turn to ability", &cv_cam_turnfacingability[1], 65}, - {IT_STRING | IT_CVAR | IT_CV_SLIDER, NULL, "Turn to spindash", &cv_cam_turnfacingspindash[1], 70}, - {IT_STRING | IT_CVAR | IT_CV_SLIDER, NULL, "Turn to input", &cv_cam_turnfacinginput[1], 75}, - {IT_STRING | IT_CVAR, NULL, "Locked movement", &cv_cam_lockedinput[0], 80}, + {IT_HEADER, NULL, "Display Options", NULL, 60}, + {IT_STRING | IT_CVAR, NULL, "Crosshair", &cv_crosshair2, 65}, +}; - {IT_STRING | IT_CVAR, NULL, "Crosshair", &cv_crosshair2, 90}, +static menuitem_t OP_CameraExtendedOptionsMenu[] = +{ + {IT_HEADER, NULL, "General Toggles", NULL, 0}, + {IT_STRING | IT_CVAR, NULL, "Third-person Camera" , &cv_chasecam , 5}, + {IT_STRING | IT_CVAR, NULL, "Flip Camera with Gravity" , &cv_flipcam , 10}, + {IT_STRING | IT_CVAR, NULL, "Orbital Looking" , &cv_cam_orbit , 15}, + {IT_STRING | IT_CVAR, NULL, "Downhill Slope Adjustment", &cv_cam_adjust, 20}, + + {IT_HEADER, NULL, "Camera Positioning", NULL, 30}, + {IT_STRING | IT_CVAR | IT_CV_INTEGERSTEP, NULL, "Camera Distance", &cv_cam_dist, 35}, + {IT_STRING | IT_CVAR | IT_CV_INTEGERSTEP, NULL, "Camera Height", &cv_cam_height, 40}, + {IT_STRING | IT_CVAR | IT_CV_FLOATSLIDER, NULL, "Camera Speed", &cv_cam_speed, 45}, + {IT_STRING | IT_CVAR | IT_CV_SLIDER, NULL, "Rotation Speed", &cv_cam_rotspeed, 50}, + + {IT_HEADER, NULL, "Automatic Camera Options", NULL, 60}, + {IT_STRING | IT_CVAR | IT_CV_SLIDER, NULL, "Shift to player angle", &cv_cam_shiftfacing[0], 65}, + {IT_STRING | IT_CVAR | IT_CV_SLIDER, NULL, "Turn to player angle", &cv_cam_turnfacing[0], 70}, + {IT_STRING | IT_CVAR | IT_CV_SLIDER, NULL, "Turn to ability", &cv_cam_turnfacingability[0], 75}, + {IT_STRING | IT_CVAR | IT_CV_SLIDER, NULL, "Turn to spindash", &cv_cam_turnfacingspindash[0], 80}, + {IT_STRING | IT_CVAR | IT_CV_SLIDER, NULL, "Turn to input", &cv_cam_turnfacinginput[0], 85}, + + {IT_HEADER, NULL, "Locked Camera Options", NULL, 95}, + {IT_STRING | IT_CVAR, NULL, "Sideways movement", &cv_cam_lockedinput[0], 100}, + {IT_STRING | IT_CVAR, NULL, "Boss targeting assist", &cv_cam_lockonboss[0], 105}, + + {IT_HEADER, NULL, "Display Options", NULL, 115}, + {IT_STRING | IT_CVAR, NULL, "Crosshair", &cv_crosshair, 120}, +}; + +static menuitem_t OP_Camera2ExtendedOptionsMenu[] = +{ + {IT_HEADER, NULL, "General Toggles", NULL, 0}, + {IT_STRING | IT_CVAR, NULL, "Third-person Camera" , &cv_chasecam2 , 5}, + {IT_STRING | IT_CVAR, NULL, "Flip Camera with Gravity" , &cv_flipcam2 , 10}, + {IT_STRING | IT_CVAR, NULL, "Orbital Looking" , &cv_cam2_orbit , 15}, + {IT_STRING | IT_CVAR, NULL, "Downhill Slope Adjustment", &cv_cam2_adjust, 20}, + + {IT_HEADER, NULL, "Camera Positioning", NULL, 30}, + {IT_STRING | IT_CVAR | IT_CV_INTEGERSTEP, NULL, "Camera Distance", &cv_cam2_dist, 35}, + {IT_STRING | IT_CVAR | IT_CV_INTEGERSTEP, NULL, "Camera Height", &cv_cam2_height, 40}, + {IT_STRING | IT_CVAR | IT_CV_FLOATSLIDER, NULL, "Camera Speed", &cv_cam2_speed, 45}, + {IT_STRING | IT_CVAR | IT_CV_SLIDER, NULL, "Rotation Speed", &cv_cam2_rotspeed, 50}, + + {IT_HEADER, NULL, "Automatic Camera Options", NULL, 60}, + {IT_STRING | IT_CVAR | IT_CV_SLIDER, NULL, "Shift to player angle", &cv_cam_shiftfacing[1], 65}, + {IT_STRING | IT_CVAR | IT_CV_SLIDER, NULL, "Turn to player angle", &cv_cam_turnfacing[1], 70}, + {IT_STRING | IT_CVAR | IT_CV_SLIDER, NULL, "Turn to ability", &cv_cam_turnfacingability[1], 75}, + {IT_STRING | IT_CVAR | IT_CV_SLIDER, NULL, "Turn to spindash", &cv_cam_turnfacingspindash[1], 80}, + {IT_STRING | IT_CVAR | IT_CV_SLIDER, NULL, "Turn to input", &cv_cam_turnfacinginput[1], 85}, + + {IT_HEADER, NULL, "Locked Camera Options", NULL, 95}, + {IT_STRING | IT_CVAR, NULL, "Sideways movement", &cv_cam_lockedinput[1], 100}, + {IT_STRING | IT_CVAR, NULL, "Boss targeting assist", &cv_cam_lockonboss[1], 105}, + + {IT_HEADER, NULL, "Display Options", NULL, 115}, + {IT_STRING | IT_CVAR, NULL, "Crosshair", &cv_crosshair2, 120}, }; static menuitem_t OP_VideoOptionsMenu[] = @@ -4284,23 +4334,13 @@ static void M_DrawControlsDefMenu(void) if (opt == 2) { - OP_CameraOptionsMenu[8].status = IT_STRING|IT_CVAR|IT_CV_SLIDER; - OP_CameraOptionsMenu[9].status = IT_STRING|IT_CVAR|IT_CV_SLIDER; - OP_CameraOptionsMenu[10].status = IT_STRING|IT_CVAR|IT_CV_SLIDER; - OP_CameraOptionsMenu[11].status = IT_STRING|IT_CVAR|IT_CV_SLIDER; - OP_CameraOptionsMenu[12].status = IT_STRING|IT_CVAR|IT_CV_SLIDER; - OP_CameraOptionsMenu[13].status = IT_STRING|IT_CVAR; - OP_CameraOptionsMenu[14].alphaKey = 90; + OP_CameraOptionsDef.menuitems = OP_CameraExtendedOptionsMenu; + OP_CameraOptionsDef.numitems = sizeof (OP_CameraExtendedOptionsMenu) / sizeof (menuitem_t); } else { - OP_CameraOptionsMenu[8].status = IT_DISABLED; - OP_CameraOptionsMenu[9].status = IT_DISABLED; - OP_CameraOptionsMenu[10].status = IT_DISABLED; - OP_CameraOptionsMenu[11].status = IT_DISABLED; - OP_CameraOptionsMenu[12].status = IT_DISABLED; - OP_CameraOptionsMenu[13].status = IT_DISABLED; - OP_CameraOptionsMenu[14].alphaKey = 55; + OP_CameraOptionsDef.menuitems = OP_CameraOptionsMenu; + OP_CameraOptionsDef.numitems = sizeof (OP_CameraOptionsMenu) / sizeof (menuitem_t); } } else @@ -4309,23 +4349,13 @@ static void M_DrawControlsDefMenu(void) if (opt == 2) { - OP_Camera2OptionsMenu[8].status = IT_STRING|IT_CVAR|IT_CV_SLIDER; - OP_Camera2OptionsMenu[9].status = IT_STRING|IT_CVAR|IT_CV_SLIDER; - OP_Camera2OptionsMenu[10].status = IT_STRING|IT_CVAR|IT_CV_SLIDER; - OP_Camera2OptionsMenu[11].status = IT_STRING|IT_CVAR|IT_CV_SLIDER; - OP_Camera2OptionsMenu[12].status = IT_STRING|IT_CVAR|IT_CV_SLIDER; - OP_Camera2OptionsMenu[13].status = IT_STRING|IT_CVAR; - OP_Camera2OptionsMenu[14].alphaKey = 90; + OP_Camera2OptionsDef.menuitems = OP_Camera2ExtendedOptionsMenu; + OP_Camera2OptionsDef.numitems = sizeof (OP_Camera2ExtendedOptionsMenu) / sizeof (menuitem_t); } else { - OP_Camera2OptionsMenu[8].status = IT_DISABLED; - OP_Camera2OptionsMenu[9].status = IT_DISABLED; - OP_Camera2OptionsMenu[10].status = IT_DISABLED; - OP_Camera2OptionsMenu[11].status = IT_DISABLED; - OP_Camera2OptionsMenu[12].status = IT_DISABLED; - OP_Camera2OptionsMenu[13].status = IT_DISABLED; - OP_Camera2OptionsMenu[14].alphaKey = 55; + OP_Camera2OptionsDef.menuitems = OP_Camera2OptionsMenu; + OP_Camera2OptionsDef.numitems = sizeof (OP_Camera2OptionsMenu) / sizeof (menuitem_t); } } diff --git a/src/p_local.h b/src/p_local.h index 286d7201f..f87930e28 100644 --- a/src/p_local.h +++ b/src/p_local.h @@ -181,6 +181,8 @@ fixed_t P_ReturnThrustX(mobj_t *mo, angle_t angle, fixed_t move); fixed_t P_ReturnThrustY(mobj_t *mo, angle_t angle, fixed_t move); void P_InstaThrustEvenIn2D(mobj_t *mo, angle_t angle, fixed_t move); +mobj_t *P_LookForFocusTarget(player_t *player, mobj_t *exclude, SINT8 direction); + mobj_t *P_LookForEnemies(player_t *player, boolean nonenemies, boolean bullet); void P_NukeEnemies(mobj_t *inflictor, mobj_t *source, fixed_t radius); boolean P_HomingAttack(mobj_t *source, mobj_t *enemy); /// \todo doesn't belong in p_user diff --git a/src/p_user.c b/src/p_user.c index 6930f3da7..e57c56aa4 100644 --- a/src/p_user.c +++ b/src/p_user.c @@ -9135,6 +9135,94 @@ void P_NukeEnemies(mobj_t *inflictor, mobj_t *source, fixed_t radius) } } +// +// P_LookForFocusTarget +// Looks for a target for a player to focus on, for Z-targeting etc. +// exclude would be the current focus target, to ignore. +// direction, if set, requires the target to be to the left (1) or right (-1) of the angle +// mobjflags can be used to limit the flags of objects that can be focused +// +mobj_t *P_LookForFocusTarget(player_t *player, mobj_t *exclude, SINT8 direction) +{ + mobj_t *mo; + thinker_t *think; + mobj_t *closestmo = NULL; + const fixed_t maxdist = 2560*player->mo->scale; + const angle_t span = ANGLE_45; + fixed_t dist, closestdist = 0; + angle_t dangle, closestdangle = 0; + + for (think = thlist[THINK_MOBJ].next; think != &thlist[THINK_MOBJ]; think = think->next) + { + if (think->function.acp1 == (actionf_p1)P_RemoveThinkerDelayed) + continue; + + mo = (mobj_t *)think; + + if (mo->flags & MF_NOCLIPTHING) + continue; + + if (mo->health <= 0) // dead + continue; + + if (!(mo->flags & MF_BOSS && (mo->flags & MF_SHOOTABLE)) == !(mo->flags2 & MF2_INVERTAIMABLE)) // allows if it has the flags desired XOR it has the invert aimable flag + continue; // not a valid target + + if (mo == player->mo) + continue; + + if (mo->flags2 & MF2_FRET) + continue; + + if (mo->type == MT_DETON) // Don't be STUPID, Sonic! + continue; + + { + fixed_t zdist = (player->mo->z + player->mo->height/2) - (mo->z + mo->height/2); + dist = P_AproxDistance(player->mo->x-mo->x, player->mo->y-mo->y); + + if (abs(zdist) > dist) + continue; // Don't home outside of desired angle! + + dist = P_AproxDistance(dist, zdist); + if (dist > maxdist) + continue; // out of range + } + + if ((twodlevel || player->mo->flags2 & MF2_TWOD) + && abs(player->mo->y-mo->y) > player->mo->radius) + continue; // not in your 2d plane + + if (mo->type == MT_PLAYER) // Don't chase after other players! + continue; + + dangle = R_PointToAngle2(player->mo->x + P_ReturnThrustX(player->mo, player->mo->angle, player->mo->radius), player->mo->y + P_ReturnThrustY(player->mo, player->mo->angle, player->mo->radius), mo->x, mo->y) - player->mo->angle; + + if ((dangle + span) > span*2) + continue; // behind back + + if (direction) + { + if (direction == 1 && dangle > ANGLE_180) + continue; // To the right of the player + if (direction == -1 && dangle < ANGLE_180) + continue; // To the left of the player + } + + if (closestmo && (exclude ? (dangle > closestdangle) : (dist > closestdist))) + continue; + + if (!P_CheckSight(player->mo, mo)) + continue; // out of sight + + closestmo = mo; + closestdist = dist; + closestdangle = dangle; + } + + return closestmo; +} + // // P_LookForEnemies // Looks for something you can hit - Used for homing attack From 7c383e4a1f75b530d7759178c04d4ecfd7fc2dd1 Mon Sep 17 00:00:00 2001 From: James R Date: Wed, 11 Dec 2019 23:46:57 -0800 Subject: [PATCH 136/746] nix: Fork before game code and wait to catch signals and coredumps Ditched signal_handler to avoid worrying about async-signal-safe functions. D_QuitNetGame is not called, so players whose programs are interrupted by a signal will time out from the server. Because the game runs in a child process, the window can close before the "Signal Caught" text box appears. "(core dumped)" is also included in the message if core dumping could be determined. --- src/doomdef.h | 4 ++++ src/i_system.h | 4 ++++ src/sdl/i_main.c | 52 ++++++++++++++++++++++++++++++++++++++++++++++ src/sdl/i_system.c | 33 +++++++++++++++++++++++------ 4 files changed, 87 insertions(+), 6 deletions(-) diff --git a/src/doomdef.h b/src/doomdef.h index d13ff9bc0..216b4fd90 100644 --- a/src/doomdef.h +++ b/src/doomdef.h @@ -125,6 +125,10 @@ #define LOGMESSAGES // write message in log.txt #endif +#if (defined (__unix__) && !defined (_MSDOS)) || defined (UNIXCOMMON) +#define NEWSIGNALHANDLER +#endif + #ifdef LOGMESSAGES extern FILE *logstream; #endif diff --git a/src/i_system.h b/src/i_system.h index 831acda32..131557ae9 100644 --- a/src/i_system.h +++ b/src/i_system.h @@ -84,6 +84,10 @@ ticcmd_t *I_BaseTiccmd2(void); */ void I_Quit(void) FUNCNORETURN; +/** \brief Print a message and text box about a signal that was raised. +*/ +void I_ReportSignal(int num, int coredumped); + typedef enum { EvilForce = -1, diff --git a/src/sdl/i_main.c b/src/sdl/i_main.c index 029febc05..16d0a242c 100644 --- a/src/sdl/i_main.c +++ b/src/sdl/i_main.c @@ -28,6 +28,11 @@ #include "time.h" // For log timestamps +#ifdef NEWSIGNALHANDLER +#include +#include +#endif + #ifdef HAVE_SDL #ifdef HAVE_TTF @@ -181,6 +186,53 @@ int main(int argc, char **argv) #endif MakeCodeWritable(); #endif + +#ifdef NEWSIGNALHANDLER + switch (fork()) + { + case -1: + I_Error( + "Error setting up signal reporting: fork(): %s\n", + strerror(errno) + ); + break; + case 0: + break; + default: + { + int status; + int signum; + if (wait(&status) == -1) + { + I_Error( + "Error setting up signal reporting: fork(): %s\n", + strerror(errno) + ); + } + else + { + if (WIFSIGNALED (status)) + { + signum = WTERMSIG (status); +#ifdef WCOREDUMP + I_ReportSignal(signum, WCOREDUMP (status)); +#else + I_ReportSignal(signum, 0); +#endif + status = 128 + signum; + } + else if (WIFEXITED (status)) + { + status = WEXITSTATUS (status); + } + + I_ShutdownSystem(); + exit(status); + } + } + } +#endif/*NEWSIGNALHANDLER*/ + // startup SRB2 CONS_Printf("Setting up SRB2...\n"); D_SRB2Main(); diff --git a/src/sdl/i_system.c b/src/sdl/i_system.c index 03eeb634f..e58691de6 100644 --- a/src/sdl/i_system.c +++ b/src/sdl/i_system.c @@ -229,13 +229,11 @@ SDL_bool framebuffer = SDL_FALSE; UINT8 keyboard_started = false; -FUNCNORETURN static ATTRNORETURN void signal_handler(INT32 num) +void I_ReportSignal(int num, int coredumped) { //static char msg[] = "oh no! back to reality!\r\n"; const char * sigmsg; - char sigdef[32]; - - D_QuitNetGame(); // Fix server freezes + char msg[128]; switch (num) { @@ -261,8 +259,21 @@ FUNCNORETURN static ATTRNORETURN void signal_handler(INT32 num) sigmsg = "SIGABRT - abnormal termination triggered by abort call"; break; default: - sprintf(sigdef,"signal number %d", num); - sigmsg = sigdef; + sprintf(msg,"signal number %d", num); + if (coredumped) + sigmsg = 0; + else + sigmsg = msg; + } + + if (coredumped) + { + if (sigmsg) + sprintf(msg, "%s (core dumped)", sigmsg); + else + strcat(msg, " (core dumped)"); + + sigmsg = msg; } I_OutputMsg("\nsignal_handler() error: %s\n", sigmsg); @@ -270,11 +281,19 @@ FUNCNORETURN static ATTRNORETURN void signal_handler(INT32 num) SDL_ShowSimpleMessageBox(SDL_MESSAGEBOX_ERROR, "Signal caught", sigmsg, NULL); +} + +#ifndef NEWSIGNALHANDLER +FUNCNORETURN static ATTRNORETURN void signal_handler(INT32 num) +{ + D_QuitNetGame(); // Fix server freezes + I_ReportSignal(num, 0); I_ShutdownSystem(); signal(num, SIG_DFL); //default signal action raise(num); I_Quit(); } +#endif FUNCNORETURN static ATTRNORETURN void quit_handler(int num) { @@ -664,10 +683,12 @@ void I_StartupKeyboard (void) // If these defines don't exist, // then compilation would have failed above us... +#ifndef NEWSIGNALHANDLER signal(SIGILL , signal_handler); signal(SIGSEGV , signal_handler); signal(SIGABRT , signal_handler); signal(SIGFPE , signal_handler); +#endif } // From 43cbad200cfb340c4d13ee0b3808570e60c86aa4 Mon Sep 17 00:00:00 2001 From: Nev3r Date: Thu, 12 Dec 2019 10:35:38 +0100 Subject: [PATCH 137/746] Move loading functions around a bit and refactor the stage data allocation code. --- src/p_setup.c | 173 +++++++++++++++++++++++++------------------------- 1 file changed, 87 insertions(+), 86 deletions(-) diff --git a/src/p_setup.c b/src/p_setup.c index 17909ee58..f569c4b73 100644 --- a/src/p_setup.c +++ b/src/p_setup.c @@ -373,21 +373,11 @@ UINT32 P_GetScoreForGrade(INT16 map, UINT8 mare, UINT8 grade) * \sa ML_VERTEXES */ -static inline void P_LoadRawVertexes(UINT8 *data, size_t i) +static inline void P_LoadRawVertexes(UINT8 *data) { - mapvertex_t *ml; - vertex_t *li; - - numvertexes = i / sizeof (mapvertex_t); - - if (numvertexes <= 0) - I_Error("Level has no vertices"); // instead of crashing - - // Allocate zone memory for buffer. - vertexes = Z_Calloc(numvertexes * sizeof (*vertexes), PU_LEVEL, NULL); - - ml = (mapvertex_t *)data; - li = vertexes; + mapvertex_t *ml = (mapvertex_t *)data; + vertex_t *li = vertexes; + size_t i; // Copy and convert vertex coordinates, internal representation as fixed. for (i = 0; i < numvertexes; i++, li++, ml++) @@ -677,19 +667,12 @@ INT32 P_CheckLevelFlat(const char *flatname) // Sets up the ingame sectors structures. // Lumpnum is the lumpnum of a SECTORS lump. -static void P_LoadRawSectors(UINT8 *data, size_t i) +static void P_LoadRawSectors(UINT8 *data) { - mapsector_t *ms; - sector_t *ss; + mapsector_t *ms = (mapsector_t *)data; + sector_t *ss = sectors; levelflat_t *foundflats; - - // We count how many sectors we got. - numsectors = i / sizeof (mapsector_t); - if (numsectors <= 0) - I_Error("Level has no sectors"); - - // Allocate as much memory as we need into the global sectors table. - sectors = Z_Calloc(numsectors*sizeof (*sectors), PU_LEVEL, NULL); + size_t i; // Allocate a big chunk of memory as big as our MAXLEVELFLATS limit. //Fab : FIXME: allocate for whatever number of flats - 512 different flats per level should be plenty @@ -700,8 +683,6 @@ static void P_LoadRawSectors(UINT8 *data, size_t i) numlevelflats = 0; // For each counted sector, copy the sector raw data from our cache pointer ms, to the global table pointer ss. - ms = (mapsector_t *)data; - ss = sectors; for (i = 0; i < numsectors; i++, ss++, ms++) { ss->floorheight = SHORT(ms->floorheight)<flags = SHORT(mld->flags); ld->special = SHORT(mld->special); ld->tag = SHORT(mld->tag); - v1 = ld->v1 = &vertexes[SHORT(mld->v1)]; - v2 = ld->v2 = &vertexes[SHORT(mld->v2)]; - ld->dx = v2->x - v1->x; - ld->dy = v2->y - v1->y; + ld->v1 = &vertexes[SHORT(mld->v1)]; + ld->v2 = &vertexes[SHORT(mld->v2)]; + + ld->sidenum[0] = SHORT(mld->sidenum[0]); + ld->sidenum[1] = SHORT(mld->sidenum[1]); + } +} + +static void SetupLines (void) +{ + line_t *ld = lines; + size_t i; + + for (i = 0; i < numlines; i++, ld++) + { + vertex_t *v1 = ld->v1; + vertex_t *v2 = ld->v2; #ifdef WALLSPLATS ld->splats = NULL; #endif +#ifdef POLYOBJECTS + ld->polyobj = NULL; +#endif + + ld->dx = v2->x - v1->x; + ld->dy = v2->y - v1->y; + if (!ld->dx) ld->slopetype = ST_VERTICAL; else if (!ld->dy) @@ -1208,52 +1202,43 @@ static void P_LoadRawLineDefs(UINT8 *data, size_t i) ld->bbox[BOXTOP] = v1->y; } - ld->sidenum[0] = SHORT(mld->sidenum[0]); - ld->sidenum[1] = SHORT(mld->sidenum[1]); - { // cph 2006/09/30 - fix sidedef errors right away. // cph 2002/07/20 - these errors are fatal if not fixed, so apply them UINT8 j; for (j=0; j < 2; j++) - { if (ld->sidenum[j] != 0xffff && ld->sidenum[j] >= (UINT16)numsides) { ld->sidenum[j] = 0xffff; CONS_Debug(DBG_SETUP, "P_LoadRawLineDefs: linedef %s has out-of-range sidedef number\n", sizeu1(numlines-i-1)); } - } } ld->frontsector = ld->backsector = NULL; ld->validcount = 0; ld->firsttag = ld->nexttag = -1; ld->callcount = 0; - // killough 11/98: fix common wad errors (missing sidedefs): + // killough 11/98: fix common wad errors (missing sidedefs): if (ld->sidenum[0] == 0xffff) { ld->sidenum[0] = 0; // Substitute dummy sidedef for missing right side // cph - print a warning about the bug - CONS_Debug(DBG_SETUP, "P_LoadRawLineDefs: linedef %s missing first sidedef\n", sizeu1(numlines-i-1)); + CONS_Debug(DBG_SETUP, "Linedef %s missing first sidedef\n", sizeu1(numlines-i-1)); } if ((ld->sidenum[1] == 0xffff) && (ld->flags & ML_TWOSIDED)) { ld->flags &= ~ML_TWOSIDED; // Clear 2s flag for missing left side // cph - print a warning about the bug - CONS_Debug(DBG_SETUP, "P_LoadRawLineDefs: linedef %s has two-sided flag set, but no second sidedef\n", sizeu1(numlines-i-1)); + CONS_Debug(DBG_SETUP, "Linedef %s has two-sided flag set, but no second sidedef\n", sizeu1(numlines-i-1)); } if (ld->sidenum[0] != 0xffff && ld->special) sides[ld->sidenum[0]].special = ld->special; if (ld->sidenum[1] != 0xffff && ld->special) sides[ld->sidenum[1]].special = ld->special; - -#ifdef POLYOBJECTS - ld->polyobj = NULL; -#endif } } @@ -1359,16 +1344,6 @@ static void P_LoadLineDefs2(void) } } - - -static inline void P_LoadRawSideDefs(size_t i) -{ - numsides = i / sizeof (mapsidedef_t); - if (numsides <= 0) - I_Error("Level has no sidedefs"); - sides = Z_Calloc(numsides * sizeof (*sides), PU_LEVEL, NULL); -} - static void P_LoadRawSideDefs2(void *data) { UINT16 i; @@ -2697,6 +2672,23 @@ boolean P_SetupLevel(boolean skipprecip) // SRB2 determines the sky texture to be used depending on the map header. P_SetupLevelSky(mapheaderinfo[gamemap-1]->skynum, true); + numdmstarts = numredctfstarts = numbluectfstarts = 0; + + // reset the player starts + for (i = 0; i < MAXPLAYERS; i++) + playerstarts[i] = bluectfstarts[i] = redctfstarts[i] = NULL; + + for (i = 0; i < MAX_DM_STARTS; i++) + deathmatchstarts[i] = NULL; + + for (i = 0; i < 2; i++) + skyboxmo[i] = NULL; + + for (i = 0; i < 16; i++) + skyboxviewpnts[i] = skyboxcenterpnts[i] = NULL; + + P_MapStart(); + if (lastloadedmaplumpnum) { virtres_t* virt = vres_GetMap(lastloadedmaplumpnum); @@ -2713,17 +2705,41 @@ boolean P_SetupLevel(boolean skipprecip) virtlump_t* virtblockmap = vres_Find(virt, "BLOCKMAP"); virtlump_t* virtreject = vres_Find(virt, "REJECT"); - P_MakeMapMD5(virt, &mapmd5); + // Traditional doom map format just assumes the number of elements from the lump sixes. + numvertexes = virtvertexes->size / sizeof (mapvertex_t); + numsectors = virtsectors->size / sizeof (mapsector_t); + numsides = virtsidedefs->size / sizeof (mapsidedef_t); + numlines = virtlinedefs->size / sizeof (maplinedef_t); + nummapthings = virtthings->size / (5 * sizeof (INT16)); - P_LoadRawVertexes(virtvertexes->data, virtvertexes->size); - P_LoadRawSectors(virtsectors->data, virtsectors->size); - P_LoadRawSideDefs(virtsidedefs->size); - P_LoadRawLineDefs(virtlinedefs->data, virtlinedefs->size); + if (numvertexes <= 0) + I_Error("Level has no vertices"); + if (numsectors <= 0) + I_Error("Level has no sectors"); + if (numsides <= 0) + I_Error("Level has no sidedefs"); + if (numlines <= 0) + I_Error("Level has no linedefs"); + + vertexes = Z_Calloc(numvertexes * sizeof (*vertexes), PU_LEVEL, NULL); + sectors = Z_Calloc(numsectors * sizeof (*sectors), PU_LEVEL, NULL); + sides = Z_Calloc(numsides * sizeof (*sides), PU_LEVEL, NULL); + lines = Z_Calloc(numlines * sizeof (*lines), PU_LEVEL, NULL); + mapthings= Z_Calloc(nummapthings * sizeof (*mapthings), PU_LEVEL, NULL); + + // Strict map data + P_LoadRawVertexes(virtvertexes->data); + P_LoadRawSectors(virtsectors->data); + P_LoadRawLineDefs(virtlinedefs->data); + SetupLines(); P_LoadRawSideDefs2(virtsidedefs->data); + + // Nodes P_LoadRawSubsectors(virtssectors->data, virtssectors->size); P_LoadRawNodes(virtnodes->data, virtnodes->size); P_LoadRawSegs(virtsegs->data, virtsegs->size); + // Lookup tables if (virtreject) P_LoadRawReject(virtreject->data, virtreject->size); else @@ -2735,25 +2751,10 @@ boolean P_SetupLevel(boolean skipprecip) P_LoadLineDefs2(); P_GroupLines(); - numdmstarts = numredctfstarts = numbluectfstarts = 0; - - // reset the player starts - for (i = 0; i < MAXPLAYERS; i++) - playerstarts[i] = bluectfstarts[i] = redctfstarts[i] = NULL; - - for (i = 0; i < MAX_DM_STARTS; i++) - deathmatchstarts[i] = NULL; - - for (i = 0; i < 2; i++) - skyboxmo[i] = NULL; - - for (i = 0; i < 16; i++) - skyboxviewpnts[i] = skyboxcenterpnts[i] = NULL; - - P_MapStart(); - P_PrepareRawThings(virtthings->data, virtthings->size); + P_MakeMapMD5(virt, &mapmd5); + vres_Free(virt); } From ec9f727e531ca11b735bcee2fc390af8e9080e0b Mon Sep 17 00:00:00 2001 From: Nev3r Date: Thu, 12 Dec 2019 11:16:55 +0100 Subject: [PATCH 138/746] Move map data load procedure to separate functions. --- src/p_setup.c | 161 ++++++++++++++++++++++++++++++-------------------- 1 file changed, 98 insertions(+), 63 deletions(-) diff --git a/src/p_setup.c b/src/p_setup.c index f569c4b73..0430ab997 100644 --- a/src/p_setup.c +++ b/src/p_setup.c @@ -951,16 +951,13 @@ void P_ScanThings(INT16 mapnum, INT16 wadnum, INT16 lumpnum) } #endif -static void P_PrepareRawThings(UINT8 *data, size_t i) +static void P_PrepareRawThings(UINT8 *data) { - mapthing_t *mt; - - nummapthings = i / (5 * sizeof (INT16)); - mapthings = Z_Calloc(nummapthings * sizeof (*mapthings), PU_LEVEL, NULL); + mapthing_t *mt = mapthings; + size_t i; // Spawn axis points first so they are // at the front of the list for fast searching. - mt = mapthings; for (i = 0; i < nummapthings; i++, mt++) { mt->x = READINT16(data); @@ -1936,6 +1933,97 @@ static void P_LoadRawReject(UINT8 *data, size_t count) } } +static void LoadMapBSP (const virtres_t* virt) +{ + virtlump_t* virtssectors = vres_Find(virt, "SSECTORS"); + virtlump_t* virtsegs = vres_Find(virt, "SEGS"); + virtlump_t* virtnodes = vres_Find(virt, "NODES"); + + // Nodes + P_LoadRawSubsectors(virtssectors->data, virtssectors->size); + P_LoadRawNodes(virtnodes->data, virtnodes->size); + P_LoadRawSegs(virtsegs->data, virtsegs->size); +} + +static void LoadMapLUT (const virtres_t* virt) +{ + virtlump_t* virtblockmap = vres_Find(virt, "BLOCKMAP"); + virtlump_t* virtreject = vres_Find(virt, "REJECT"); + + // Lookup tables + if (virtreject) + P_LoadRawReject(virtreject->data, virtreject->size); + else + rejectmatrix = NULL; + + if (!(virtblockmap && P_LoadRawBlockMap(virtblockmap->data, virtblockmap->size))) + P_CreateBlockMap(); +} + +static void LoadMapData (const virtres_t* virt) +{ + virtlump_t* virtvertexes = NULL, * virtsectors = NULL, * virtsidedefs = NULL, * virtlinedefs = NULL, * virtthings = NULL; + virtlump_t* textmap = vres_Find(virt, "TEXTMAP"); + + // Count map data. + if (textmap) + { + nummapthings = 0; + numlines = 0; + numsides = 0; + numvertexes = 0; + numsectors = 0; + + // Count how many entries for each type we got in textmap. + //TextmapCount(vtextmap->data, vtextmap->size); + } + else + { + virtthings = vres_Find(virt, "THINGS"); + virtvertexes = vres_Find(virt, "VERTEXES"); + virtsectors = vres_Find(virt, "SECTORS"); + virtsidedefs = vres_Find(virt, "SIDEDEFS"); + virtlinedefs = vres_Find(virt, "LINEDEFS"); + + // Traditional doom map format just assumes the number of elements from the lump sixes. + numvertexes = virtvertexes->size / sizeof (mapvertex_t); + numsectors = virtsectors->size / sizeof (mapsector_t); + numsides = virtsidedefs->size / sizeof (mapsidedef_t); + numlines = virtlinedefs->size / sizeof (maplinedef_t); + nummapthings = virtthings->size / (5 * sizeof (INT16)); + } + + if (numvertexes <= 0) + I_Error("Level has no vertices"); + if (numsectors <= 0) + I_Error("Level has no sectors"); + if (numsides <= 0) + I_Error("Level has no sidedefs"); + if (numlines <= 0) + I_Error("Level has no linedefs"); + + vertexes = Z_Calloc(numvertexes * sizeof (*vertexes), PU_LEVEL, NULL); + sectors = Z_Calloc(numsectors * sizeof (*sectors), PU_LEVEL, NULL); + sides = Z_Calloc(numsides * sizeof (*sides), PU_LEVEL, NULL); + lines = Z_Calloc(numlines * sizeof (*lines), PU_LEVEL, NULL); + mapthings= Z_Calloc(nummapthings * sizeof (*mapthings), PU_LEVEL, NULL); + + if (textmap) + { + + } + else + { + // Strict map data + P_LoadRawVertexes(virtvertexes->data); + P_LoadRawSectors(virtsectors->data); + P_LoadRawLineDefs(virtlinedefs->data); + SetupLines(); + P_LoadRawSideDefs2(virtsidedefs->data); + P_PrepareRawThings(virtthings->data); + } +} + #if 0 static char *levellumps[] = { @@ -2133,7 +2221,7 @@ void P_LoadThingsOnly(void) P_LevelInitStuff(); - P_PrepareRawThings(vth->data, vth->size); + P_PrepareRawThings(vth->data); P_LoadThings(true); vres_Free(virt); @@ -2692,67 +2780,14 @@ boolean P_SetupLevel(boolean skipprecip) if (lastloadedmaplumpnum) { virtres_t* virt = vres_GetMap(lastloadedmaplumpnum); - virtlump_t* virtthings = vres_Find(virt, "THINGS"); - virtlump_t* virtvertexes = vres_Find(virt, "VERTEXES"); - virtlump_t* virtsectors = vres_Find(virt, "SECTORS"); - virtlump_t* virtsidedefs = vres_Find(virt, "SIDEDEFS"); - virtlump_t* virtlinedefs = vres_Find(virt, "LINEDEFS"); - virtlump_t* virtssectors = vres_Find(virt, "SSECTORS"); - virtlump_t* virtsegs = vres_Find(virt, "SEGS"); - virtlump_t* virtnodes = vres_Find(virt, "NODES"); - - virtlump_t* virtblockmap = vres_Find(virt, "BLOCKMAP"); - virtlump_t* virtreject = vres_Find(virt, "REJECT"); - - // Traditional doom map format just assumes the number of elements from the lump sixes. - numvertexes = virtvertexes->size / sizeof (mapvertex_t); - numsectors = virtsectors->size / sizeof (mapsector_t); - numsides = virtsidedefs->size / sizeof (mapsidedef_t); - numlines = virtlinedefs->size / sizeof (maplinedef_t); - nummapthings = virtthings->size / (5 * sizeof (INT16)); - - if (numvertexes <= 0) - I_Error("Level has no vertices"); - if (numsectors <= 0) - I_Error("Level has no sectors"); - if (numsides <= 0) - I_Error("Level has no sidedefs"); - if (numlines <= 0) - I_Error("Level has no linedefs"); - - vertexes = Z_Calloc(numvertexes * sizeof (*vertexes), PU_LEVEL, NULL); - sectors = Z_Calloc(numsectors * sizeof (*sectors), PU_LEVEL, NULL); - sides = Z_Calloc(numsides * sizeof (*sides), PU_LEVEL, NULL); - lines = Z_Calloc(numlines * sizeof (*lines), PU_LEVEL, NULL); - mapthings= Z_Calloc(nummapthings * sizeof (*mapthings), PU_LEVEL, NULL); - - // Strict map data - P_LoadRawVertexes(virtvertexes->data); - P_LoadRawSectors(virtsectors->data); - P_LoadRawLineDefs(virtlinedefs->data); - SetupLines(); - P_LoadRawSideDefs2(virtsidedefs->data); - - // Nodes - P_LoadRawSubsectors(virtssectors->data, virtssectors->size); - P_LoadRawNodes(virtnodes->data, virtnodes->size); - P_LoadRawSegs(virtsegs->data, virtsegs->size); - - // Lookup tables - if (virtreject) - P_LoadRawReject(virtreject->data, virtreject->size); - else - rejectmatrix = NULL; - - if (!(virtblockmap && P_LoadRawBlockMap(virtblockmap->data, virtblockmap->size))) - P_CreateBlockMap(); + LoadMapData(virt); + LoadMapBSP(virt); + LoadMapLUT(virt); P_LoadLineDefs2(); P_GroupLines(); - P_PrepareRawThings(virtthings->data, virtthings->size); - P_MakeMapMD5(virt, &mapmd5); vres_Free(virt); From c64a9d7ae9d0d3756c348397c00b5e8460c504a0 Mon Sep 17 00:00:00 2001 From: Nev3r Date: Thu, 12 Dec 2019 11:37:48 +0100 Subject: [PATCH 139/746] Stop things from becoming Chocapic in THZ3, ACZ2, and special stages. Temporarily revert function call order for mapthings. --- src/p_setup.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/src/p_setup.c b/src/p_setup.c index 0430ab997..cc53f2d3d 100644 --- a/src/p_setup.c +++ b/src/p_setup.c @@ -1963,6 +1963,7 @@ static void LoadMapLUT (const virtres_t* virt) static void LoadMapData (const virtres_t* virt) { virtlump_t* virtvertexes = NULL, * virtsectors = NULL, * virtsidedefs = NULL, * virtlinedefs = NULL, * virtthings = NULL; +#ifdef UDMF virtlump_t* textmap = vres_Find(virt, "TEXTMAP"); // Count map data. @@ -1978,6 +1979,7 @@ static void LoadMapData (const virtres_t* virt) //TextmapCount(vtextmap->data, vtextmap->size); } else +#endif { virtthings = vres_Find(virt, "THINGS"); virtvertexes = vres_Find(virt, "VERTEXES"); @@ -2008,11 +2010,13 @@ static void LoadMapData (const virtres_t* virt) lines = Z_Calloc(numlines * sizeof (*lines), PU_LEVEL, NULL); mapthings= Z_Calloc(nummapthings * sizeof (*mapthings), PU_LEVEL, NULL); +#ifdef UDMF if (textmap) { } else +#endif { // Strict map data P_LoadRawVertexes(virtvertexes->data); @@ -2020,7 +2024,6 @@ static void LoadMapData (const virtres_t* virt) P_LoadRawLineDefs(virtlinedefs->data); SetupLines(); P_LoadRawSideDefs2(virtsidedefs->data); - P_PrepareRawThings(virtthings->data); } } @@ -2788,6 +2791,8 @@ boolean P_SetupLevel(boolean skipprecip) P_LoadLineDefs2(); P_GroupLines(); + P_PrepareRawThings(vres_Find(virt, "THINGS")->data); + P_MakeMapMD5(virt, &mapmd5); vres_Free(virt); From c5d8fe47527c9cd1c4d354b8f730f7be5bd3350e Mon Sep 17 00:00:00 2001 From: Nev3r Date: Thu, 12 Dec 2019 15:04:48 +0100 Subject: [PATCH 140/746] Fix oversight on mapthing spawn Z calculation; ONFLOORZ and ONCEILINGZ don't equal to spawning the object at the base plane intersection. --- src/p_mobj.c | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/src/p_mobj.c b/src/p_mobj.c index dae891afd..ed12407ff 100644 --- a/src/p_mobj.c +++ b/src/p_mobj.c @@ -11609,6 +11609,14 @@ static fixed_t GetMobjSpawnHeight (const mobjtype_t i, const mapthing_t* mthing, flip = (!!(mobjinfo[i].flags & MF_SPAWNCEILING) ^ !!(mthing->options & MTF_OBJECTFLIP)); } + if (heightoffset + extraoffset == 0) // Snap to the surfaces when there's no offset set. + { + if (flip) + return ONCEILINGZ; + else + return ONFLOORZ; + } + // Establish height. if (flip) return ( From 792750ee48159323896b75c24fe54ceea6acab98 Mon Sep 17 00:00:00 2001 From: Jaime Passos Date: Thu, 12 Dec 2019 16:48:37 -0300 Subject: [PATCH 141/746] Add HWD_SET_MODEL_LIGHTING state --- src/hardware/hw_defs.h | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/hardware/hw_defs.h b/src/hardware/hw_defs.h index 965f06980..979093dc8 100644 --- a/src/hardware/hw_defs.h +++ b/src/hardware/hw_defs.h @@ -220,11 +220,10 @@ typedef struct FSurfaceInfo FSurfaceInfo; //Hurdler: added for backward compatibility enum hwdsetspecialstate { - HWD_SET_FOG_TABLE = 1, + HWD_SET_MODEL_LIGHTING = 1, HWD_SET_FOG_MODE, HWD_SET_FOG_COLOR, HWD_SET_FOG_DENSITY, - HWD_SET_FOV, HWD_SET_TEXTUREFILTERMODE, HWD_SET_TEXTUREANISOTROPICMODE, HWD_NUMSTATE From 08e3caf9bb92bab973696fcb4c6aab4ef1c01eec Mon Sep 17 00:00:00 2001 From: Jaime Passos Date: Thu, 12 Dec 2019 16:53:31 -0300 Subject: [PATCH 142/746] Remove unused cvars --- src/hardware/hw_main.c | 13 ++----------- 1 file changed, 2 insertions(+), 11 deletions(-) diff --git a/src/hardware/hw_main.c b/src/hardware/hw_main.c index 583a877fc..0a38894de 100644 --- a/src/hardware/hw_main.c +++ b/src/hardware/hw_main.c @@ -108,9 +108,6 @@ boolean drawsky = true; #ifndef NEWCLIP static consvar_t cv_grclipwalls = {"gr_clipwalls", "Off", 0, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL}; #endif -//development variables for diverse uses -static consvar_t cv_gralpha = {"gr_alpha", "160", 0, CV_Unsigned, NULL, 0, NULL, NULL, 0, 0, NULL}; -static consvar_t cv_grbeta = {"gr_beta", "0", 0, CV_Unsigned, NULL, 0, NULL, NULL, 0, 0, NULL}; consvar_t cv_grrounddown = {"gr_rounddown", "Off", 0, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL}; consvar_t cv_grfov = {"gr_fov", "90", CV_FLOAT|CV_CALL, grfov_cons_t, CV_grFov_OnChange, 0, NULL, NULL, 0, 0, NULL}; @@ -122,7 +119,7 @@ consvar_t cv_grfiltermode = {"gr_filtermode", "Nearest", CV_CALL, grfiltermode_c CV_filtermode_ONChange, 0, NULL, NULL, 0, 0, NULL}; consvar_t cv_granisotropicmode = {"gr_anisotropicmode", "1", CV_CALL, granisotropicmode_cons_t, CV_anisotropic_ONChange, 0, NULL, NULL, 0, 0, NULL}; -//static consvar_t cv_grzbuffer = {"gr_zbuffer", "On", 0, CV_OnOff}; + consvar_t cv_grcorrecttricks = {"gr_correcttricks", "Off", 0, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL}; consvar_t cv_grsolvetjoin = {"gr_solvetjoin", "On", 0, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL}; @@ -2477,7 +2474,7 @@ static cliprange_t gr_solidsegs[MAXSEGS]; static void printsolidsegs(void) { cliprange_t * start; - if (!hw_newend || cv_grbeta.value != 2) + if (!hw_newend) return; for (start = gr_solidsegs;start != hw_newend;start++) { @@ -6627,16 +6624,10 @@ void HWR_AddCommands(void) static inline void HWR_AddEngineCommands(void) { // engine state variables - //CV_RegisterVar(&cv_grzbuffer); #ifndef NEWCLIP CV_RegisterVar(&cv_grclipwalls); #endif - // engine development mode variables - // - usage may vary from version to version.. - CV_RegisterVar(&cv_gralpha); - CV_RegisterVar(&cv_grbeta); - // engine commands COM_AddCommand("gr_stats", Command_GrStats_f); } From b7c7529e75a07b7a0e4e689ebdb81d289dd607be Mon Sep 17 00:00:00 2001 From: Jaime Passos Date: Thu, 12 Dec 2019 17:06:04 -0300 Subject: [PATCH 143/746] Don't reset the FOV --- src/p_setup.c | 5 ----- 1 file changed, 5 deletions(-) diff --git a/src/p_setup.c b/src/p_setup.c index 0a3c85521..4ee74195f 100644 --- a/src/p_setup.c +++ b/src/p_setup.c @@ -3182,11 +3182,6 @@ boolean P_SetupLevel(boolean skipprecip) if (!cv_analog2.changed) CV_SetValue(&cv_analog2, 0); -#ifdef HWRENDER - if (rendermode != render_soft && rendermode != render_none) - CV_Set(&cv_grfov, cv_grfov.defaultvalue); -#endif - displayplayer = consoleplayer; // Start with your OWN view, please! } From 4af0cfae36bb7bb3a61451d4635bb91a515c4c4c Mon Sep 17 00:00:00 2001 From: Steel Titanium Date: Thu, 12 Dec 2019 15:17:50 -0500 Subject: [PATCH 144/746] Init MUSICDEFs if started game with music off and toggled on --- src/s_sound.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/s_sound.c b/src/s_sound.c index a49499040..1d9c06cca 100644 --- a/src/s_sound.c +++ b/src/s_sound.c @@ -2543,6 +2543,7 @@ void GameDigiMusic_OnChange(void) I_StartupSound(); // will return early if initialised I_InitMusic(); S_StopMusic(); + S_InitMusicDefs(); if (Playing()) P_RestoreMusic(&players[consoleplayer]); else @@ -2585,6 +2586,7 @@ void GameMIDIMusic_OnChange(void) midi_disabled = false; I_StartupSound(); // will return early if initialised I_InitMusic(); + S_InitMusicDefs(); if (Playing()) P_RestoreMusic(&players[consoleplayer]); else From bf520b9e333318142d043b8421a9a5639102fcf2 Mon Sep 17 00:00:00 2001 From: Jaime Passos Date: Thu, 12 Dec 2019 17:30:19 -0300 Subject: [PATCH 145/746] Please, for the love of God, Jesus and Bastet, ADD EVERY OPENGL COMMAND REGARDLESS OF THE FREAKING RENDERER!!!!!!!!!!!!!!!!!!!!!!!!!!! --- src/d_main.c | 7 ++ src/hardware/hw_main.c | 152 +++++++++++++++++++++++++---------------- src/r_main.c | 23 ------- src/v_video.c | 26 ------- 4 files changed, 100 insertions(+), 108 deletions(-) diff --git a/src/d_main.c b/src/d_main.c index 397406293..ef6502aec 100644 --- a/src/d_main.c +++ b/src/d_main.c @@ -1193,6 +1193,13 @@ void D_SRB2Main(void) CONS_Printf("I_StartupGraphics()...\n"); I_StartupGraphics(); +#ifdef HWRENDER + // Lactozilla: Add every hardware mode CVAR and CCMD. + // Has to be done before the configuration file loads, + // but after the OpenGL library loads. + HWR_AddCommands(); +#endif + //--------------------------------------------------------- CONSOLE // setup loading screen SCR_Startup(); diff --git a/src/hardware/hw_main.c b/src/hardware/hw_main.c index 0a38894de..4eb15e1ea 100644 --- a/src/hardware/hw_main.c +++ b/src/hardware/hw_main.c @@ -85,59 +85,8 @@ static void HWR_RenderTransparentWalls(void); static void HWR_FoggingOn(void); static UINT32 atohex(const char *s); -static void CV_filtermode_ONChange(void); -static void CV_anisotropic_ONChange(void); -static void CV_FogDensity_ONChange(void); -static void CV_grFov_OnChange(void); -// ========================================================================== -// 3D ENGINE COMMANDS & CONSOLE VARS -// ========================================================================== - -static CV_PossibleValue_t grfov_cons_t[] = {{0, "MIN"}, {179*FRACUNIT, "MAX"}, {0, NULL}}; -static CV_PossibleValue_t grfiltermode_cons_t[]= {{HWD_SET_TEXTUREFILTER_POINTSAMPLED, "Nearest"}, - {HWD_SET_TEXTUREFILTER_BILINEAR, "Bilinear"}, {HWD_SET_TEXTUREFILTER_TRILINEAR, "Trilinear"}, - {HWD_SET_TEXTUREFILTER_MIXED1, "Linear_Nearest"}, - {HWD_SET_TEXTUREFILTER_MIXED2, "Nearest_Linear"}, - {HWD_SET_TEXTUREFILTER_MIXED3, "Nearest_Mipmap"}, - {0, NULL}}; -CV_PossibleValue_t granisotropicmode_cons_t[] = {{1, "MIN"}, {16, "MAX"}, {0, NULL}}; - boolean drawsky = true; -// needs fix: walls are incorrectly clipped one column less -#ifndef NEWCLIP -static consvar_t cv_grclipwalls = {"gr_clipwalls", "Off", 0, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL}; -#endif - -consvar_t cv_grrounddown = {"gr_rounddown", "Off", 0, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL}; -consvar_t cv_grfov = {"gr_fov", "90", CV_FLOAT|CV_CALL, grfov_cons_t, CV_grFov_OnChange, 0, NULL, NULL, 0, 0, NULL}; -consvar_t cv_grfogdensity = {"gr_fogdensity", "150", CV_CALL|CV_NOINIT, CV_Unsigned, - CV_FogDensity_ONChange, 0, NULL, NULL, 0, 0, NULL}; - -// Unfortunately, this can no longer be saved.. -consvar_t cv_grfiltermode = {"gr_filtermode", "Nearest", CV_CALL, grfiltermode_cons_t, - CV_filtermode_ONChange, 0, NULL, NULL, 0, 0, NULL}; -consvar_t cv_granisotropicmode = {"gr_anisotropicmode", "1", CV_CALL, granisotropicmode_cons_t, - CV_anisotropic_ONChange, 0, NULL, NULL, 0, 0, NULL}; - -consvar_t cv_grcorrecttricks = {"gr_correcttricks", "Off", 0, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL}; -consvar_t cv_grsolvetjoin = {"gr_solvetjoin", "On", 0, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL}; - -static void CV_FogDensity_ONChange(void) -{ - HWD.pfnSetSpecialState(HWD_SET_FOG_DENSITY, cv_grfogdensity.value); -} - -static void CV_filtermode_ONChange(void) -{ - HWD.pfnSetSpecialState(HWD_SET_TEXTUREFILTERMODE, cv_grfiltermode.value); -} - -static void CV_anisotropic_ONChange(void) -{ - HWD.pfnSetSpecialState(HWD_SET_TEXTUREANISOTROPICMODE, cv_granisotropicmode.value); -} - /* * lookuptable for lightvalues * calculated as follow: @@ -2470,6 +2419,8 @@ static boolean CheckClip(seg_t * seg, sector_t * afrontsector, sector_t * abacks static cliprange_t * hw_newend; static cliprange_t gr_solidsegs[MAXSEGS]; +// needs fix: walls are incorrectly clipped one column less +static consvar_t cv_grclipwalls = {"gr_clipwalls", "Off", 0, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL}; static void printsolidsegs(void) { @@ -6585,13 +6536,6 @@ static void HWR_FoggingOn(void) // 3D ENGINE COMMANDS // ========================================================================== - -static void CV_grFov_OnChange(void) -{ - if ((netgame || multiplayer) && !cv_debug && cv_grfov.value != 90*FRACUNIT) - CV_Set(&cv_grfov, cv_grfov.defaultvalue); -} - static void Command_GrStats_f(void) { Z_CheckHeap(9875); // debug @@ -6609,14 +6553,104 @@ static void Command_GrStats_f(void) // -------------------------------------------------------------------------- // Add hardware engine commands & consvars // -------------------------------------------------------------------------- +static CV_PossibleValue_t grsoftwarefog_cons_t[] = {{0, "Off"}, {1, "On"}, {2, "LightPlanes"}, {0, NULL}}; +static CV_PossibleValue_t grmodelinterpolation_cons_t[] = {{0, "Off"}, {1, "Sometimes"}, {2, "Always"}, {0, NULL}}; + +static void CV_grfiltermode_OnChange(void); +static void CV_granisotropic_OnChange(void); +static void CV_grfogdensity_OnChange(void); +static void CV_grfov_OnChange(void); + +static CV_PossibleValue_t grfov_cons_t[] = {{0, "MIN"}, {179*FRACUNIT, "MAX"}, {0, NULL}}; +static CV_PossibleValue_t grfiltermode_cons_t[]= {{HWD_SET_TEXTUREFILTER_POINTSAMPLED, "Nearest"}, + {HWD_SET_TEXTUREFILTER_BILINEAR, "Bilinear"}, {HWD_SET_TEXTUREFILTER_TRILINEAR, "Trilinear"}, + {HWD_SET_TEXTUREFILTER_MIXED1, "Linear_Nearest"}, + {HWD_SET_TEXTUREFILTER_MIXED2, "Nearest_Linear"}, + {HWD_SET_TEXTUREFILTER_MIXED3, "Nearest_Mipmap"}, + {0, NULL}}; +CV_PossibleValue_t granisotropicmode_cons_t[] = {{1, "MIN"}, {16, "MAX"}, {0, NULL}}; + +consvar_t cv_grfovchange = {"gr_fovchange", "Off", CV_SAVE, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL}; +consvar_t cv_grfog = {"gr_fog", "On", CV_SAVE, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL}; +consvar_t cv_grfogcolor = {"gr_fogcolor", "AAAAAA", CV_SAVE, NULL, NULL, 0, NULL, NULL, 0, 0, NULL}; +consvar_t cv_grsoftwarefog = {"gr_softwarefog", "Off", CV_SAVE, grsoftwarefog_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL}; + +#ifdef ALAM_LIGHTING +consvar_t cv_grdynamiclighting = {"gr_dynamiclighting", "On", CV_SAVE, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL}; +consvar_t cv_grstaticlighting = {"gr_staticlighting", "On", CV_SAVE, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL}; +consvar_t cv_grcoronas = {"gr_coronas", "On", CV_SAVE, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL}; +consvar_t cv_grcoronasize = {"gr_coronasize", "1", CV_SAVE| CV_FLOAT, 0, NULL, 0, NULL, NULL, 0, 0, NULL}; +#endif + +consvar_t cv_grmodels = {"gr_models", "Off", CV_SAVE, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL}; +consvar_t cv_grmodelinterpolation = {"gr_modelinterpolation", "Sometimes", CV_SAVE, grmodelinterpolation_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL}; + +consvar_t cv_grspritebillboarding = {"gr_spritebillboarding", "Off", CV_SAVE, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL}; +consvar_t cv_grskydome = {"gr_skydome", "On", CV_SAVE, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL}; + +consvar_t cv_grrounddown = {"gr_rounddown", "Off", 0, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL}; +consvar_t cv_grfov = {"gr_fov", "90", CV_FLOAT|CV_CALL, grfov_cons_t, CV_grfov_OnChange, 0, NULL, NULL, 0, 0, NULL}; +consvar_t cv_grfogdensity = {"gr_fogdensity", "150", CV_CALL|CV_NOINIT, CV_Unsigned, + CV_grfogdensity_OnChange, 0, NULL, NULL, 0, 0, NULL}; + +consvar_t cv_grfiltermode = {"gr_filtermode", "Nearest", CV_CALL, grfiltermode_cons_t, + CV_grfiltermode_OnChange, 0, NULL, NULL, 0, 0, NULL}; +consvar_t cv_granisotropicmode = {"gr_anisotropicmode", "1", CV_CALL, granisotropicmode_cons_t, + CV_granisotropic_OnChange, 0, NULL, NULL, 0, 0, NULL}; + +consvar_t cv_grcorrecttricks = {"gr_correcttricks", "Off", 0, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL}; +consvar_t cv_grsolvetjoin = {"gr_solvetjoin", "On", 0, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL}; + +static void CV_grfogdensity_OnChange(void) +{ + if (rendermode == render_opengl) + HWD.pfnSetSpecialState(HWD_SET_FOG_DENSITY, cv_grfogdensity.value); +} + +static void CV_grfiltermode_OnChange(void) +{ + if (rendermode == render_opengl) + HWD.pfnSetSpecialState(HWD_SET_TEXTUREFILTERMODE, cv_grfiltermode.value); +} + +static void CV_granisotropic_OnChange(void) +{ + if (rendermode == render_opengl) + HWD.pfnSetSpecialState(HWD_SET_TEXTUREANISOTROPICMODE, cv_granisotropicmode.value); +} + +static void CV_grfov_OnChange(void) +{ + if ((netgame || multiplayer) && !cv_debug && cv_grfov.value != 90*FRACUNIT) + CV_Set(&cv_grfov, cv_grfov.defaultvalue); +} + //added by Hurdler: console varibale that are saved void HWR_AddCommands(void) { - CV_RegisterVar(&cv_grrounddown); + CV_RegisterVar(&cv_grfovchange); CV_RegisterVar(&cv_grfov); + CV_RegisterVar(&cv_grfogdensity); + CV_RegisterVar(&cv_grfogcolor); + CV_RegisterVar(&cv_grfog); + CV_RegisterVar(&cv_grsoftwarefog); + +#ifdef ALAM_LIGHTING + CV_RegisterVar(&cv_grstaticlighting); + CV_RegisterVar(&cv_grdynamiclighting); + CV_RegisterVar(&cv_grcoronasize); + CV_RegisterVar(&cv_grcoronas); +#endif + + CV_RegisterVar(&cv_grmodelinterpolation); + CV_RegisterVar(&cv_grmodels); + CV_RegisterVar(&cv_grskydome); + CV_RegisterVar(&cv_grspritebillboarding); + CV_RegisterVar(&cv_grfiltermode); CV_RegisterVar(&cv_granisotropicmode); + CV_RegisterVar(&cv_grrounddown); CV_RegisterVar(&cv_grcorrecttricks); CV_RegisterVar(&cv_grsolvetjoin); } diff --git a/src/r_main.c b/src/r_main.c index 541360025..a710daf3b 100644 --- a/src/r_main.c +++ b/src/r_main.c @@ -1208,27 +1208,4 @@ void R_RegisterEngineStuff(void) CV_RegisterVar(&cv_maxportals); CV_RegisterVar(&cv_movebob); - -#ifdef HWRENDER - // GL-specific Commands - CV_RegisterVar(&cv_grfovchange); - CV_RegisterVar(&cv_grfog); - CV_RegisterVar(&cv_grfogcolor); - CV_RegisterVar(&cv_grsoftwarefog); -#ifdef ALAM_LIGHTING - CV_RegisterVar(&cv_grstaticlighting); - CV_RegisterVar(&cv_grdynamiclighting); - CV_RegisterVar(&cv_grcoronas); - CV_RegisterVar(&cv_grcoronasize); -#endif - CV_RegisterVar(&cv_grmodelinterpolation); - CV_RegisterVar(&cv_grmodels); - CV_RegisterVar(&cv_grspritebillboarding); - CV_RegisterVar(&cv_grskydome); -#endif - -#ifdef HWRENDER - if (rendermode != render_soft && rendermode != render_none) - HWR_AddCommands(); -#endif } diff --git a/src/v_video.c b/src/v_video.c index 25cbccee2..1c5cbbc0a 100644 --- a/src/v_video.c +++ b/src/v_video.c @@ -84,32 +84,6 @@ static CV_PossibleValue_t constextsize_cons_t[] = { static void CV_constextsize_OnChange(void); consvar_t cv_constextsize = {"con_textsize", "Medium", CV_SAVE|CV_CALL, constextsize_cons_t, CV_constextsize_OnChange, 0, NULL, NULL, 0, 0, NULL}; -#ifdef HWRENDER -// Saved hardware mode variables -// - You can change them in software, -// but they won't do anything. -static CV_PossibleValue_t grsoftwarefog_cons_t[] = {{0, "Off"}, {1, "On"}, {2, "LightPlanes"}, {0, NULL}}; -static CV_PossibleValue_t grmodelinterpolation_cons_t[] = {{0, "Off"}, {1, "Sometimes"}, {2, "Always"}, {0, NULL}}; - -consvar_t cv_grfovchange = {"gr_fovchange", "Off", CV_SAVE, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL}; -consvar_t cv_grfog = {"gr_fog", "On", CV_SAVE, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL}; -consvar_t cv_grfogcolor = {"gr_fogcolor", "AAAAAA", CV_SAVE, NULL, NULL, 0, NULL, NULL, 0, 0, NULL}; -consvar_t cv_grsoftwarefog = {"gr_softwarefog", "Off", CV_SAVE, grsoftwarefog_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL}; - -#ifdef ALAM_LIGHTING -consvar_t cv_grdynamiclighting = {"gr_dynamiclighting", "On", CV_SAVE, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL}; -consvar_t cv_grstaticlighting = {"gr_staticlighting", "On", CV_SAVE, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL}; -consvar_t cv_grcoronas = {"gr_coronas", "On", CV_SAVE, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL}; -consvar_t cv_grcoronasize = {"gr_coronasize", "1", CV_SAVE| CV_FLOAT, 0, NULL, 0, NULL, NULL, 0, 0, NULL}; -#endif - -consvar_t cv_grmodels = {"gr_models", "Off", CV_SAVE, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL}; -consvar_t cv_grmodelinterpolation = {"gr_modelinterpolation", "Sometimes", CV_SAVE, grmodelinterpolation_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL}; - -consvar_t cv_grspritebillboarding = {"gr_spritebillboarding", "Off", CV_SAVE, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL}; -consvar_t cv_grskydome = {"gr_skydome", "On", CV_SAVE, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL}; -#endif - // local copy of the palette for V_GetColor() RGBA_t *pLocalPalette = NULL; RGBA_t *pMasterPalette = NULL; From db61d1a705acd3390dfdf4d4c542357d2081d7f8 Mon Sep 17 00:00:00 2001 From: Jaime Passos Date: Thu, 12 Dec 2019 17:35:41 -0300 Subject: [PATCH 146/746] Remove HWR_AddEngineCommands --- src/hardware/hw_main.c | 28 ---------------------------- 1 file changed, 28 deletions(-) diff --git a/src/hardware/hw_main.c b/src/hardware/hw_main.c index 4eb15e1ea..a42e43928 100644 --- a/src/hardware/hw_main.c +++ b/src/hardware/hw_main.c @@ -6536,23 +6536,6 @@ static void HWR_FoggingOn(void) // 3D ENGINE COMMANDS // ========================================================================== -static void Command_GrStats_f(void) -{ - Z_CheckHeap(9875); // debug - - CONS_Printf(M_GetText("Patch info headers: %7s kb\n"), sizeu1(Z_TagUsage(PU_HWRPATCHINFO)>>10)); - CONS_Printf(M_GetText("3D Texture cache : %7s kb\n"), sizeu1(Z_TagUsage(PU_HWRCACHE)>>10)); - CONS_Printf(M_GetText("Plane polygon : %7s kb\n"), sizeu1(Z_TagUsage(PU_HWRPLANE)>>10)); -} - - -// ************************************************************************** -// 3D ENGINE SETUP -// ************************************************************************** - -// -------------------------------------------------------------------------- -// Add hardware engine commands & consvars -// -------------------------------------------------------------------------- static CV_PossibleValue_t grsoftwarefog_cons_t[] = {{0, "Off"}, {1, "On"}, {2, "LightPlanes"}, {0, NULL}}; static CV_PossibleValue_t grmodelinterpolation_cons_t[] = {{0, "Off"}, {1, "Sometimes"}, {2, "Always"}, {0, NULL}}; @@ -6653,17 +6636,10 @@ void HWR_AddCommands(void) CV_RegisterVar(&cv_grrounddown); CV_RegisterVar(&cv_grcorrecttricks); CV_RegisterVar(&cv_grsolvetjoin); -} -static inline void HWR_AddEngineCommands(void) -{ - // engine state variables #ifndef NEWCLIP CV_RegisterVar(&cv_grclipwalls); #endif - - // engine commands - COM_AddCommand("gr_stats", Command_GrStats_f); } @@ -6686,12 +6662,8 @@ void HWR_Startup(void) { CONS_Printf("HWR_Startup()...\n"); HWR_InitPolyPool(); - // add console cmds & vars - HWR_AddEngineCommands(); HWR_InitTextureCache(); - HWR_InitModels(); - #ifdef ALAM_LIGHTING HWR_InitLight(); #endif From f077d173011379e39e82f4467d857ab9a015df2b Mon Sep 17 00:00:00 2001 From: Jaime Passos Date: Thu, 12 Dec 2019 17:37:55 -0300 Subject: [PATCH 147/746] Save filtering mode and anisotropic mode cvars to config --- src/hardware/hw_main.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/hardware/hw_main.c b/src/hardware/hw_main.c index a42e43928..09ace5682 100644 --- a/src/hardware/hw_main.c +++ b/src/hardware/hw_main.c @@ -6562,7 +6562,7 @@ consvar_t cv_grsoftwarefog = {"gr_softwarefog", "Off", CV_SAVE, grsoftwarefog_co consvar_t cv_grdynamiclighting = {"gr_dynamiclighting", "On", CV_SAVE, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL}; consvar_t cv_grstaticlighting = {"gr_staticlighting", "On", CV_SAVE, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL}; consvar_t cv_grcoronas = {"gr_coronas", "On", CV_SAVE, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL}; -consvar_t cv_grcoronasize = {"gr_coronasize", "1", CV_SAVE| CV_FLOAT, 0, NULL, 0, NULL, NULL, 0, 0, NULL}; +consvar_t cv_grcoronasize = {"gr_coronasize", "1", CV_SAVE|CV_FLOAT, 0, NULL, 0, NULL, NULL, 0, 0, NULL}; #endif consvar_t cv_grmodels = {"gr_models", "Off", CV_SAVE, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL}; @@ -6576,9 +6576,9 @@ consvar_t cv_grfov = {"gr_fov", "90", CV_FLOAT|CV_CALL, grfov_cons_t, CV_grfov_O consvar_t cv_grfogdensity = {"gr_fogdensity", "150", CV_CALL|CV_NOINIT, CV_Unsigned, CV_grfogdensity_OnChange, 0, NULL, NULL, 0, 0, NULL}; -consvar_t cv_grfiltermode = {"gr_filtermode", "Nearest", CV_CALL, grfiltermode_cons_t, +consvar_t cv_grfiltermode = {"gr_filtermode", "Nearest", CV_SAVE|CV_CALL, grfiltermode_cons_t, CV_grfiltermode_OnChange, 0, NULL, NULL, 0, 0, NULL}; -consvar_t cv_granisotropicmode = {"gr_anisotropicmode", "1", CV_CALL, granisotropicmode_cons_t, +consvar_t cv_granisotropicmode = {"gr_anisotropicmode", "1", CV_SAVE|CV_CALL, granisotropicmode_cons_t, CV_granisotropic_OnChange, 0, NULL, NULL, 0, 0, NULL}; consvar_t cv_grcorrecttricks = {"gr_correcttricks", "Off", 0, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL}; From a4b0195430c78ebb98f83656457d305d4c54551d Mon Sep 17 00:00:00 2001 From: Jaime Passos Date: Thu, 12 Dec 2019 17:48:29 -0300 Subject: [PATCH 148/746] Model lighting --- src/hardware/hw_main.c | 10 ++++++++++ src/hardware/r_opengl/r_opengl.c | 32 ++++++++++++++++++-------------- 2 files changed, 28 insertions(+), 14 deletions(-) diff --git a/src/hardware/hw_main.c b/src/hardware/hw_main.c index 09ace5682..07a666066 100644 --- a/src/hardware/hw_main.c +++ b/src/hardware/hw_main.c @@ -6539,6 +6539,7 @@ static void HWR_FoggingOn(void) static CV_PossibleValue_t grsoftwarefog_cons_t[] = {{0, "Off"}, {1, "On"}, {2, "LightPlanes"}, {0, NULL}}; static CV_PossibleValue_t grmodelinterpolation_cons_t[] = {{0, "Off"}, {1, "Sometimes"}, {2, "Always"}, {0, NULL}}; +static void CV_grmodellighting_OnChange(void); static void CV_grfiltermode_OnChange(void); static void CV_granisotropic_OnChange(void); static void CV_grfogdensity_OnChange(void); @@ -6567,6 +6568,7 @@ consvar_t cv_grcoronasize = {"gr_coronasize", "1", CV_SAVE|CV_FLOAT, 0, NULL, 0, consvar_t cv_grmodels = {"gr_models", "Off", CV_SAVE, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL}; consvar_t cv_grmodelinterpolation = {"gr_modelinterpolation", "Sometimes", CV_SAVE, grmodelinterpolation_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL}; +consvar_t cv_grmodellighting = {"gr_modellighting", "Off", CV_SAVE|CV_CALL, CV_OnOff, CV_grmodellighting_OnChange, 0, NULL, NULL, 0, 0, NULL}; consvar_t cv_grspritebillboarding = {"gr_spritebillboarding", "Off", CV_SAVE, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL}; consvar_t cv_grskydome = {"gr_skydome", "On", CV_SAVE, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL}; @@ -6584,6 +6586,12 @@ consvar_t cv_granisotropicmode = {"gr_anisotropicmode", "1", CV_SAVE|CV_CALL, gr consvar_t cv_grcorrecttricks = {"gr_correcttricks", "Off", 0, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL}; consvar_t cv_grsolvetjoin = {"gr_solvetjoin", "On", 0, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL}; +static void CV_grmodellighting_OnChange(void) +{ + if (rendermode == render_opengl) + HWD.pfnSetSpecialState(HWD_SET_MODEL_LIGHTING, cv_grmodellighting.value); +} + static void CV_grfogdensity_OnChange(void) { if (rendermode == render_opengl) @@ -6626,8 +6634,10 @@ void HWR_AddCommands(void) CV_RegisterVar(&cv_grcoronas); #endif + CV_RegisterVar(&cv_grmodellighting); CV_RegisterVar(&cv_grmodelinterpolation); CV_RegisterVar(&cv_grmodels); + CV_RegisterVar(&cv_grskydome); CV_RegisterVar(&cv_grspritebillboarding); diff --git a/src/hardware/r_opengl/r_opengl.c b/src/hardware/r_opengl/r_opengl.c index 16c1ad010..129bf5678 100644 --- a/src/hardware/r_opengl/r_opengl.c +++ b/src/hardware/r_opengl/r_opengl.c @@ -85,6 +85,7 @@ static GLboolean MipMap = GL_FALSE; static GLint min_filter = GL_LINEAR; static GLint mag_filter = GL_LINEAR; static GLint anisotropic_filter = 0; +static boolean model_lighting = true; const GLubyte *gl_extensions = NULL; @@ -1658,16 +1659,9 @@ EXPORT void HWRAPI(SetSpecialState) (hwdspecialstate_t IdState, INT32 Value) { switch (IdState) { - -#if 0 - case 77: - { - //08/01/00: Hurdler this is a test for mirror - if (!Value) - ClearBuffer(false, true, 0); // clear depth buffer + case HWD_SET_MODEL_LIGHTING: + model_lighting = Value; break; - } -#endif case HWD_SET_FOG_COLOR: { @@ -1680,6 +1674,7 @@ EXPORT void HWRAPI(SetSpecialState) (hwdspecialstate_t IdState, INT32 Value) pglFogfv(GL_FOG_COLOR, fogcolor); break; } + case HWD_SET_FOG_DENSITY: pglFogf(GL_FOG_DENSITY, Value*1200/(500*1000000.0f)); break; @@ -2044,16 +2039,25 @@ static void DrawModelEx(model_t *model, INT32 frameIndex, INT32 duration, INT32 } #endif - pglLightfv(GL_LIGHT0, GL_POSITION, LightPos); + if (model_lighting) + { + pglLightfv(GL_LIGHT0, GL_POSITION, LightPos); + pglShadeModel(GL_SMOOTH); + } - pglShadeModel(GL_SMOOTH); if (color) { #ifdef GL_LIGHT_MODEL_AMBIENT - pglEnable(GL_LIGHTING); - pglMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT, ambient); - pglMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, diffuse); + if (model_lighting) + { + pglEnable(GL_LIGHTING); + pglMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT, ambient); + pglMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, diffuse); + } + else #endif + pglColor4ubv((GLubyte*)color); + if (color[3] < 255) SetBlend(PF_Translucent|PF_Modulated|PF_Clip); else From 58a08504c8cbbed5851c637b1533ed3816f593b3 Mon Sep 17 00:00:00 2001 From: Jaime Passos Date: Thu, 12 Dec 2019 17:48:43 -0300 Subject: [PATCH 149/746] Make gr_spritebillboarding on by default sorry not sorry Azeon --- src/hardware/hw_main.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/hardware/hw_main.c b/src/hardware/hw_main.c index 07a666066..cc181733c 100644 --- a/src/hardware/hw_main.c +++ b/src/hardware/hw_main.c @@ -6570,7 +6570,7 @@ consvar_t cv_grmodels = {"gr_models", "Off", CV_SAVE, CV_OnOff, NULL, 0, NULL, N consvar_t cv_grmodelinterpolation = {"gr_modelinterpolation", "Sometimes", CV_SAVE, grmodelinterpolation_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL}; consvar_t cv_grmodellighting = {"gr_modellighting", "Off", CV_SAVE|CV_CALL, CV_OnOff, CV_grmodellighting_OnChange, 0, NULL, NULL, 0, 0, NULL}; -consvar_t cv_grspritebillboarding = {"gr_spritebillboarding", "Off", CV_SAVE, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL}; +consvar_t cv_grspritebillboarding = {"gr_spritebillboarding", "On", CV_SAVE, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL}; consvar_t cv_grskydome = {"gr_skydome", "On", CV_SAVE, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL}; consvar_t cv_grrounddown = {"gr_rounddown", "Off", 0, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL}; From 3bebfb279e020ee14432df552920546dacdd0615 Mon Sep 17 00:00:00 2001 From: Jaime Passos Date: Thu, 12 Dec 2019 18:28:05 -0300 Subject: [PATCH 150/746] Fix gr_anisotropicmode --- src/hardware/hw_main.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/src/hardware/hw_main.c b/src/hardware/hw_main.c index cc181733c..1e1935c44 100644 --- a/src/hardware/hw_main.c +++ b/src/hardware/hw_main.c @@ -6580,7 +6580,7 @@ consvar_t cv_grfogdensity = {"gr_fogdensity", "150", CV_CALL|CV_NOINIT, CV_Unsig consvar_t cv_grfiltermode = {"gr_filtermode", "Nearest", CV_SAVE|CV_CALL, grfiltermode_cons_t, CV_grfiltermode_OnChange, 0, NULL, NULL, 0, 0, NULL}; -consvar_t cv_granisotropicmode = {"gr_anisotropicmode", "1", CV_SAVE|CV_CALL, granisotropicmode_cons_t, +consvar_t cv_granisotropicmode = {"gr_anisotropicmode", "1", CV_CALL, granisotropicmode_cons_t, CV_granisotropic_OnChange, 0, NULL, NULL, 0, 0, NULL}; consvar_t cv_grcorrecttricks = {"gr_correcttricks", "Off", 0, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL}; @@ -6642,7 +6642,6 @@ void HWR_AddCommands(void) CV_RegisterVar(&cv_grspritebillboarding); CV_RegisterVar(&cv_grfiltermode); - CV_RegisterVar(&cv_granisotropicmode); CV_RegisterVar(&cv_grrounddown); CV_RegisterVar(&cv_grcorrecttricks); CV_RegisterVar(&cv_grsolvetjoin); @@ -6652,6 +6651,10 @@ void HWR_AddCommands(void) #endif } +void HWR_AddSessionCommands(void) +{ + CV_RegisterVar(&cv_granisotropicmode); +} // -------------------------------------------------------------------------- // Setup the hardware renderer @@ -6672,6 +6675,7 @@ void HWR_Startup(void) { CONS_Printf("HWR_Startup()...\n"); HWR_InitPolyPool(); + HWR_AddSessionCommands(); HWR_InitTextureCache(); HWR_InitModels(); #ifdef ALAM_LIGHTING From eb787c2b59ef6391bb4db8c25b514f9ab972f342 Mon Sep 17 00:00:00 2001 From: Steel Titanium Date: Thu, 12 Dec 2019 16:32:40 -0500 Subject: [PATCH 151/746] Move S_InitMusicDefs call outside of the check. As far as I know, this is competely safe. --- src/d_main.c | 3 ++- src/s_sound.c | 2 -- 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/src/d_main.c b/src/d_main.c index 397406293..ae2750da8 100644 --- a/src/d_main.c +++ b/src/d_main.c @@ -1281,9 +1281,10 @@ void D_SRB2Main(void) I_StartupSound(); I_InitMusic(); S_InitSfxChannels(cv_soundvolume.value); - S_InitMusicDefs(); } + S_InitMusicDefs(); + CONS_Printf("ST_Init(): Init status bar.\n"); ST_Init(); diff --git a/src/s_sound.c b/src/s_sound.c index 1d9c06cca..a49499040 100644 --- a/src/s_sound.c +++ b/src/s_sound.c @@ -2543,7 +2543,6 @@ void GameDigiMusic_OnChange(void) I_StartupSound(); // will return early if initialised I_InitMusic(); S_StopMusic(); - S_InitMusicDefs(); if (Playing()) P_RestoreMusic(&players[consoleplayer]); else @@ -2586,7 +2585,6 @@ void GameMIDIMusic_OnChange(void) midi_disabled = false; I_StartupSound(); // will return early if initialised I_InitMusic(); - S_InitMusicDefs(); if (Playing()) P_RestoreMusic(&players[consoleplayer]); else From 55f3f27b55802589062de99aad4318e08e58354d Mon Sep 17 00:00:00 2001 From: James R Date: Thu, 12 Dec 2019 14:00:13 -0800 Subject: [PATCH 152/746] Fix NOHW warnings --- src/dehacked.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/dehacked.c b/src/dehacked.c index bcf842c8d..175c1fcfa 100644 --- a/src/dehacked.c +++ b/src/dehacked.c @@ -242,6 +242,7 @@ INT32 flags; Bits = 3232 MF_SOLID|MF_SHOOTABLE|MF_DROPOFF|M INT32 raisestate; Respawn frame = 32 S_NULL // raisestate }, */ +#ifdef HWRENDER static INT32 searchvalue(const char *s) { while (s[0] != '=' && s[0]) @@ -255,7 +256,6 @@ static INT32 searchvalue(const char *s) } } -#ifdef HWRENDER static float searchfvalue(const char *s) { while (s[0] != '=' && s[0]) @@ -886,7 +886,9 @@ static void readspriteinfo(MYFILE *f, INT32 num, boolean sprite2) char *s = Z_Malloc(MAXLINELEN, PU_STATIC, NULL); char *word, *word2; char *tmp; +#ifdef HWRENDER INT32 value; +#endif char *lastline; INT32 skinnumbers[MAXSKINS]; INT32 foundskins = 0; @@ -947,9 +949,9 @@ static void readspriteinfo(MYFILE *f, INT32 num, boolean sprite2) break; } strupr(word); +#ifdef HWRENDER value = atoi(word2); // used for numerical settings -#ifdef HWRENDER if (fastcmp(word, "LIGHTTYPE")) { if (sprite2) From 6c3111d809c4e9237fb8bbf4b579b80f66e6f0ca Mon Sep 17 00:00:00 2001 From: Jaime Passos Date: Thu, 12 Dec 2019 19:54:47 -0300 Subject: [PATCH 153/746] Stop crashing with models because someone keeps freeing those tags --- src/hardware/hw_md2.c | 10 +++++----- src/z_zone.h | 1 + 2 files changed, 6 insertions(+), 5 deletions(-) diff --git a/src/hardware/hw_md2.c b/src/hardware/hw_md2.c index 9245d7fc2..8f8e7c333 100644 --- a/src/hardware/hw_md2.c +++ b/src/hardware/hw_md2.c @@ -239,7 +239,7 @@ static GrTextureFormat_t PNG_Load(const char *filename, int *w, int *h, GLPatch_ { png_uint_32 i, pitch = png_get_rowbytes(png_ptr, png_info_ptr); - png_bytep PNG_image = Z_Malloc(pitch*height, PU_HWRCACHE, &grpatch->mipmap->grInfo.data); + png_bytep PNG_image = Z_Malloc(pitch*height, PU_HWRMODELTEXTURE, &grpatch->mipmap->grInfo.data); png_bytepp row_pointers = png_malloc(png_ptr, height * sizeof (png_bytep)); for (i = 0; i < height; i++) row_pointers[i] = PNG_image + i*pitch; @@ -313,7 +313,7 @@ static GrTextureFormat_t PCX_Load(const char *filename, int *w, int *h, pw = *w = header.xmax - header.xmin + 1; ph = *h = header.ymax - header.ymin + 1; - image = Z_Malloc(pw*ph*4, PU_HWRCACHE, &grpatch->mipmap->grInfo.data); + image = Z_Malloc(pw*ph*4, PU_HWRMODELTEXTURE, &grpatch->mipmap->grInfo.data); if (fread(palette, sizeof (UINT8), PALSIZE, file) != PALSIZE) { @@ -661,7 +661,7 @@ static void HWR_CreateBlendedTexture(GLPatch_t *gpatch, GLPatch_t *blendgpatch, Z_Free(grmip->grInfo.data); grmip->grInfo.data = NULL; - cur = Z_Malloc(size*4, PU_HWRCACHE, &grmip->grInfo.data); + cur = Z_Malloc(size*4, PU_HWRMODELTEXTURE, &grmip->grInfo.data); memset(cur, 0x00, size*4); image = gpatch->mipmap->grInfo.data; @@ -794,7 +794,7 @@ static void HWR_GetBlendedTexture(GLPatch_t *gpatch, GLPatch_t *blendgpatch, INT if (grmip->downloaded && grmip->grInfo.data) { HWD.pfnSetTexture(grmip); // found the colormap, set it to the correct texture - Z_ChangeTag(grmip->grInfo.data, PU_HWRCACHE_UNLOCKED); + Z_ChangeTag(grmip->grInfo.data, PU_HWRMODELTEXTURE); return; } } @@ -816,7 +816,7 @@ static void HWR_GetBlendedTexture(GLPatch_t *gpatch, GLPatch_t *blendgpatch, INT HWR_CreateBlendedTexture(gpatch, blendgpatch, newmip, skinnum, color); HWD.pfnSetTexture(newmip); - Z_ChangeTag(newmip->grInfo.data, PU_HWRCACHE_UNLOCKED); + Z_ChangeTag(newmip->grInfo.data, PU_HWRMODELTEXTURE); } #define NORMALFOG 0x00000000 diff --git a/src/z_zone.h b/src/z_zone.h index 67da1f7e8..635c334cf 100644 --- a/src/z_zone.h +++ b/src/z_zone.h @@ -46,6 +46,7 @@ enum PU_HWRPATCHINFO = 21, // Hardware GLPatch_t struct for OpenGL texture cache PU_HWRPATCHCOLMIPMAP = 22, // Hardware GLMipmap_t struct colormap variation of patch + PU_HWRMODELTEXTURE = 23, // Hardware model texture PU_HWRCACHE = 48, // static until unlocked PU_CACHE = 49, // static until unlocked From 6dcdb8d95179cc6efd67c70ec63232816e18d10c Mon Sep 17 00:00:00 2001 From: James R Date: Thu, 12 Dec 2019 15:07:59 -0800 Subject: [PATCH 154/746] Move everything to i_system.c This also simplifies things; SDL isn't initialized in the parent process. --- src/doomdef.h | 4 ---- src/i_system.h | 4 ---- src/sdl/i_main.c | 51 ---------------------------------------- src/sdl/i_system.c | 58 +++++++++++++++++++++++++++++++++++++++++++++- 4 files changed, 57 insertions(+), 60 deletions(-) diff --git a/src/doomdef.h b/src/doomdef.h index 216b4fd90..d13ff9bc0 100644 --- a/src/doomdef.h +++ b/src/doomdef.h @@ -125,10 +125,6 @@ #define LOGMESSAGES // write message in log.txt #endif -#if (defined (__unix__) && !defined (_MSDOS)) || defined (UNIXCOMMON) -#define NEWSIGNALHANDLER -#endif - #ifdef LOGMESSAGES extern FILE *logstream; #endif diff --git a/src/i_system.h b/src/i_system.h index 131557ae9..831acda32 100644 --- a/src/i_system.h +++ b/src/i_system.h @@ -84,10 +84,6 @@ ticcmd_t *I_BaseTiccmd2(void); */ void I_Quit(void) FUNCNORETURN; -/** \brief Print a message and text box about a signal that was raised. -*/ -void I_ReportSignal(int num, int coredumped); - typedef enum { EvilForce = -1, diff --git a/src/sdl/i_main.c b/src/sdl/i_main.c index 16d0a242c..69e49b4a7 100644 --- a/src/sdl/i_main.c +++ b/src/sdl/i_main.c @@ -28,11 +28,6 @@ #include "time.h" // For log timestamps -#ifdef NEWSIGNALHANDLER -#include -#include -#endif - #ifdef HAVE_SDL #ifdef HAVE_TTF @@ -187,52 +182,6 @@ int main(int argc, char **argv) MakeCodeWritable(); #endif -#ifdef NEWSIGNALHANDLER - switch (fork()) - { - case -1: - I_Error( - "Error setting up signal reporting: fork(): %s\n", - strerror(errno) - ); - break; - case 0: - break; - default: - { - int status; - int signum; - if (wait(&status) == -1) - { - I_Error( - "Error setting up signal reporting: fork(): %s\n", - strerror(errno) - ); - } - else - { - if (WIFSIGNALED (status)) - { - signum = WTERMSIG (status); -#ifdef WCOREDUMP - I_ReportSignal(signum, WCOREDUMP (status)); -#else - I_ReportSignal(signum, 0); -#endif - status = 128 + signum; - } - else if (WIFEXITED (status)) - { - status = WEXITSTATUS (status); - } - - I_ShutdownSystem(); - exit(status); - } - } - } -#endif/*NEWSIGNALHANDLER*/ - // startup SRB2 CONS_Printf("Setting up SRB2...\n"); D_SRB2Main(); diff --git a/src/sdl/i_system.c b/src/sdl/i_system.c index e58691de6..9245673cc 100644 --- a/src/sdl/i_system.c +++ b/src/sdl/i_system.c @@ -102,6 +102,12 @@ typedef LPVOID (WINAPI *p_MapViewOfFile) (HANDLE, DWORD, DWORD, DWORD, SIZE_T); #endif #endif +#if (defined (__unix__) && !defined (_MSDOS)) || defined (UNIXCOMMON) +#include +#include +#define NEWSIGNALHANDLER +#endif + #ifndef NOMUMBLE #ifdef __linux__ // need -lrt #include @@ -229,7 +235,7 @@ SDL_bool framebuffer = SDL_FALSE; UINT8 keyboard_started = false; -void I_ReportSignal(int num, int coredumped) +static void I_ReportSignal(int num, int coredumped) { //static char msg[] = "oh no! back to reality!\r\n"; const char * sigmsg; @@ -2160,6 +2166,53 @@ void I_Sleep(void) SDL_Delay(cv_sleep.value); } +#ifdef NEWSIGNALHANDLER +static void I_Fork(void) +{ + int status; + int signum; + switch (fork()) + { + case -1: + I_Error( + "Error setting up signal reporting: fork(): %s\n", + strerror(errno) + ); + break; + case 0: + break; + default: + if (wait(&status)) + { + I_Error( + "Error setting up signal reporting: fork(): %s\n", + strerror(errno) + ); + } + else + { + if (WIFSIGNALED (status)) + { + signum = WTERMSIG (status); +#ifdef WCOREDUMP + I_ReportSignal(signum, WCOREDUMP (status)); +#else + I_ReportSignal(signum, 0); +#endif + status = 128 + signum; + } + else if (WIFEXITED (status)) + { + status = WEXITSTATUS (status); + } + + I_ShutdownSystem(); + exit(status); + } + } +} +#endif/*NEWSIGNALHANDLER*/ + INT32 I_StartupSystem(void) { SDL_version SDLcompiled; @@ -2167,6 +2220,9 @@ INT32 I_StartupSystem(void) SDL_VERSION(&SDLcompiled) SDL_GetVersion(&SDLlinked); I_StartupConsole(); +#ifdef NEWSIGNALHANDLER + I_Fork(); +#endif I_OutputMsg("Compiled for SDL version: %d.%d.%d\n", SDLcompiled.major, SDLcompiled.minor, SDLcompiled.patch); I_OutputMsg("Linked with SDL version: %d.%d.%d\n", From 08d4a36f6381c25ffc48b7aa76c1b00ad401fb00 Mon Sep 17 00:00:00 2001 From: Jaime Passos Date: Thu, 12 Dec 2019 21:22:36 -0300 Subject: [PATCH 155/746] Texture blending port Co-authored-by: TehRealSalt --- src/hardware/hw_md2.c | 285 +++++++++++++++++++++++++++++++----------- 1 file changed, 209 insertions(+), 76 deletions(-) diff --git a/src/hardware/hw_md2.c b/src/hardware/hw_md2.c index 8f8e7c333..7e2b2d3fc 100644 --- a/src/hardware/hw_md2.c +++ b/src/hardware/hw_md2.c @@ -637,15 +637,18 @@ spritemd2found: // 0.7152 to green // 0.0722 to blue #define SETBRIGHTNESS(brightness,r,g,b) \ - brightness = (UINT8)(((1063*((UINT16)r)/5000) + (3576*((UINT16)g)/5000) + (361*((UINT16)b)/5000)) / 3) + brightness = (UINT8)(((1063*(UINT16)(r))/5000) + ((3576*(UINT16)(g))/5000) + ((361*(UINT16)(b))/5000)) static void HWR_CreateBlendedTexture(GLPatch_t *gpatch, GLPatch_t *blendgpatch, GLMipmap_t *grmip, INT32 skinnum, skincolors_t color) { - UINT8 i; UINT16 w = gpatch->width, h = gpatch->height; UINT32 size = w*h; RGBA_t *image, *blendimage, *cur, blendcolor; + // vanilla port + UINT8 translation[16]; + memset(translation, 0, sizeof(translation)); + if (grmip->width == 0) { @@ -658,113 +661,243 @@ static void HWR_CreateBlendedTexture(GLPatch_t *gpatch, GLPatch_t *blendgpatch, grmip->grInfo.format = GR_RGBA; } - Z_Free(grmip->grInfo.data); - grmip->grInfo.data = NULL; + if (grmip->grInfo.data) + { + Z_Free(grmip->grInfo.data); + grmip->grInfo.data = NULL; + } cur = Z_Malloc(size*4, PU_HWRMODELTEXTURE, &grmip->grInfo.data); memset(cur, 0x00, size*4); image = gpatch->mipmap->grInfo.data; blendimage = blendgpatch->mipmap->grInfo.data; + blendcolor = V_GetColor(0); // initialize - // Average all of the translation's colors - if (color == SKINCOLOR_NONE || color >= MAXTRANSLATIONS) - blendcolor = V_GetColor(0xff); - else + if (color != SKINCOLOR_NONE) + memcpy(&translation, &Color_Index[color - 1], 16); + + while (size--) { - const UINT8 div = 6; - const UINT8 start = 4; - UINT32 r, g, b; - - blendcolor = V_GetColor(Color_Index[color-1][start]); - r = (UINT32)(blendcolor.s.red*blendcolor.s.red); - g = (UINT32)(blendcolor.s.green*blendcolor.s.green); - b = (UINT32)(blendcolor.s.blue*blendcolor.s.blue); - - for (i = 1; i < div; i++) + if (skinnum == TC_BOSS) { - RGBA_t nextcolor = V_GetColor(Color_Index[color-1][start+i]); - r += (UINT32)(nextcolor.s.red*nextcolor.s.red); - g += (UINT32)(nextcolor.s.green*nextcolor.s.green); - b += (UINT32)(nextcolor.s.blue*nextcolor.s.blue); - } - - blendcolor.s.red = (UINT8)(FixedSqrt((r/div)<>FRACBITS); - blendcolor.s.green = (UINT8)(FixedSqrt((g/div)<>FRACBITS); - blendcolor.s.blue = (UINT8)(FixedSqrt((b/div)<>FRACBITS); - } - - // rainbow support, could theoretically support boss ones too - if (skinnum == TC_RAINBOW) - { - while (size--) - { - if (image->s.alpha == 0 && blendimage->s.alpha == 0) + // Pure black turns into white + if (image->s.red == 0 && image->s.green == 0 && image->s.blue == 0) { - // Don't bother with blending the pixel if the alpha of the blend pixel is 0 - cur->rgba = image->rgba; + cur->s.red = cur->s.green = cur->s.blue = 255; } else + { + cur->s.red = image->s.red; + cur->s.green = image->s.green; + cur->s.blue = image->s.blue; + } + + cur->s.alpha = image->s.alpha; + } + else if (skinnum == TC_METALSONIC) + { + // Turn everything below a certain blue threshold white + if (image->s.red == 0 && image->s.green == 0 && image->s.blue <= 82) + { + cur->s.red = cur->s.green = cur->s.blue = 255; + } + else + { + cur->s.red = image->s.red; + cur->s.green = image->s.green; + cur->s.blue = image->s.blue; + } + + cur->s.alpha = image->s.alpha; + } + else if (skinnum == TC_ALLWHITE) + { + // Turn everything white + cur->s.red = cur->s.green = cur->s.blue = 255; + cur->s.alpha = image->s.alpha; + } + else + { + UINT16 brightness; + + // Don't bother with blending the pixel if the alpha of the blend pixel is 0 + if (skinnum == TC_RAINBOW) + { + if (image->s.alpha == 0 && blendimage->s.alpha == 0) + { + cur->rgba = image->rgba; + cur++; image++; blendimage++; + continue; + } + else + { + UINT16 imagebright, blendbright; + SETBRIGHTNESS(imagebright,image->s.red,image->s.green,image->s.blue); + SETBRIGHTNESS(blendbright,blendimage->s.red,blendimage->s.green,blendimage->s.blue); + // slightly dumb average between the blend image color and base image colour, usually one or the other will be fully opaque anyway + brightness = (imagebright*(255-blendimage->s.alpha))/255 + (blendbright*blendimage->s.alpha)/255; + } + } + else + { + if (blendimage->s.alpha == 0) + { + cur->rgba = image->rgba; + cur++; image++; blendimage++; + continue; + } + else + { + SETBRIGHTNESS(brightness,blendimage->s.red,blendimage->s.green,blendimage->s.blue); + } + } + + // Calculate a sort of "gradient" for the skincolor + // (Me splitting this into a function didn't work, so I had to ruin this entire function's groove...) + { + RGBA_t nextcolor; + UINT8 firsti, secondi, mul; + UINT32 r, g, b; + + // Rainbow needs to find the closest match to the textures themselves, instead of matching brightnesses to other colors. + // Ensue horrible mess. + if (skinnum == TC_RAINBOW) + { + UINT16 brightdif = 256; + UINT8 colorbrightnesses[16]; + INT32 compare, m, d; + UINT8 i; + + // Ignore pure white & pitch black + if (brightness > 253 || brightness < 2) + { + cur->rgba = image->rgba; + cur++; image++; blendimage++; + continue; + } + + firsti = 0; + mul = 0; + + for (i = 0; i < 16; i++) + { + RGBA_t tempc = V_GetColor(translation[i]); + SETBRIGHTNESS(colorbrightnesses[i], tempc.s.red, tempc.s.green, tempc.s.blue); // store brightnesses for comparison + } + + for (i = 0; i < 16; i++) + { + if (brightness > colorbrightnesses[i]) // don't allow greater matches (because calculating a makeshift gradient for this is already a huge mess as is) + continue; + compare = abs((INT16)(colorbrightnesses[i]) - (INT16)(brightness)); + if (compare < brightdif) + { + brightdif = (UINT16)compare; + firsti = i; // best matching color that's equal brightness or darker + } + } + + secondi = firsti+1; // next color in line + if (secondi == 16) + { + m = (INT16)brightness; // - 0; + d = (INT16)colorbrightnesses[firsti]; // - 0; + } + else + { + m = (INT16)brightness - (INT16)colorbrightnesses[secondi]; + d = (INT16)colorbrightnesses[firsti] - (INT16)colorbrightnesses[secondi]; + } + + if (m >= d) + m = d-1; + + // calculate the "gradient" multiplier based on how close this color is to the one next in line + if (m <= 0 || d <= 0) + mul = 0; + else + mul = 15 - ((m * 16) / d); + } + else + { + // Thankfully, it's normally way more simple. + // Just convert brightness to a skincolor value, use remainder to find the gradient multipler + firsti = ((UINT8)(255-brightness) / 16); + secondi = firsti+1; + mul = ((UINT8)(255-brightness) % 16); + } + + blendcolor = V_GetColor(translation[firsti]); + + if (mul > 0 // If it's 0, then we only need the first color. + && translation[firsti] != translation[secondi]) // Some colors have duplicate colors in a row, so let's just save the process + { + if (secondi == 16) // blend to black + nextcolor = V_GetColor(31); + else + nextcolor = V_GetColor(translation[secondi]); + + // Find difference between points + r = (UINT32)(nextcolor.s.red - blendcolor.s.red); + g = (UINT32)(nextcolor.s.green - blendcolor.s.green); + b = (UINT32)(nextcolor.s.blue - blendcolor.s.blue); + + // Find the gradient of the two points + r = ((mul * r) / 16); + g = ((mul * g) / 16); + b = ((mul * b) / 16); + + // Add gradient value to color + blendcolor.s.red += r; + blendcolor.s.green += g; + blendcolor.s.blue += b; + } + } + + if (skinnum == TC_RAINBOW) { UINT32 tempcolor; - UINT16 imagebright, blendbright, finalbright, colorbright; - SETBRIGHTNESS(imagebright,image->s.red,image->s.green,image->s.blue); - SETBRIGHTNESS(blendbright,blendimage->s.red,blendimage->s.green,blendimage->s.blue); - // slightly dumb average between the blend image color and base image colour, usually one or the other will be fully opaque anyway - finalbright = (imagebright*(255-blendimage->s.alpha))/255 + (blendbright*blendimage->s.alpha)/255; - SETBRIGHTNESS(colorbright,blendcolor.s.red,blendcolor.s.green,blendcolor.s.blue); + UINT16 colorbright; - tempcolor = (finalbright*blendcolor.s.red)/colorbright; + SETBRIGHTNESS(colorbright,blendcolor.s.red,blendcolor.s.green,blendcolor.s.blue); + if (colorbright == 0) + colorbright = 1; // no dividing by 0 please + + tempcolor = (brightness * blendcolor.s.red) / colorbright; tempcolor = min(255, tempcolor); cur->s.red = (UINT8)tempcolor; - tempcolor = (finalbright*blendcolor.s.green)/colorbright; + + tempcolor = (brightness * blendcolor.s.green) / colorbright; tempcolor = min(255, tempcolor); cur->s.green = (UINT8)tempcolor; - tempcolor = (finalbright*blendcolor.s.blue)/colorbright; + + tempcolor = (brightness * blendcolor.s.blue) / colorbright; tempcolor = min(255, tempcolor); cur->s.blue = (UINT8)tempcolor; cur->s.alpha = image->s.alpha; } - - cur++; image++; blendimage++; - } - } - else - { - while (size--) - { - if (blendimage->s.alpha == 0) - { - // Don't bother with blending the pixel if the alpha of the blend pixel is 0 - cur->rgba = image->rgba; - } else { + // Color strength depends on image alpha INT32 tempcolor; - INT16 tempmult, tempalpha; - tempalpha = -(abs(blendimage->s.red-127)-127)*2; - if (tempalpha > 255) - tempalpha = 255; - else if (tempalpha < 0) - tempalpha = 0; - tempmult = (blendimage->s.red-127)*2; - if (tempmult > 255) - tempmult = 255; - else if (tempmult < 0) - tempmult = 0; - - tempcolor = (image->s.red*(255-blendimage->s.alpha))/255 + ((tempmult + ((tempalpha*blendcolor.s.red)/255)) * blendimage->s.alpha)/255; + tempcolor = ((image->s.red * (255-blendimage->s.alpha)) / 255) + ((blendcolor.s.red * blendimage->s.alpha) / 255); + tempcolor = min(255, tempcolor); cur->s.red = (UINT8)tempcolor; - tempcolor = (image->s.green*(255-blendimage->s.alpha))/255 + ((tempmult + ((tempalpha*blendcolor.s.green)/255)) * blendimage->s.alpha)/255; + + tempcolor = ((image->s.green * (255-blendimage->s.alpha)) / 255) + ((blendcolor.s.green * blendimage->s.alpha) / 255); + tempcolor = min(255, tempcolor); cur->s.green = (UINT8)tempcolor; - tempcolor = (image->s.blue*(255-blendimage->s.alpha))/255 + ((tempmult + ((tempalpha*blendcolor.s.blue)/255)) * blendimage->s.alpha)/255; + + tempcolor = ((image->s.blue * (255-blendimage->s.alpha)) / 255) + ((blendcolor.s.blue * blendimage->s.alpha) / 255); + tempcolor = min(255, tempcolor); cur->s.blue = (UINT8)tempcolor; cur->s.alpha = image->s.alpha; } - - cur++; image++; blendimage++; } + + cur++; image++; blendimage++; } return; From d80bfb4e940c6b57770ecdc071068df058cf608c Mon Sep 17 00:00:00 2001 From: Jaime Passos Date: Thu, 12 Dec 2019 21:23:55 -0300 Subject: [PATCH 156/746] =?UTF-8?q?PU=5FHWRCACHE=5FUNLOCKED=20bmomento=20b?= =?UTF-8?q?r=C3=B3der?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/hardware/hw_md2.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/hardware/hw_md2.c b/src/hardware/hw_md2.c index 7e2b2d3fc..77cdfa0d3 100644 --- a/src/hardware/hw_md2.c +++ b/src/hardware/hw_md2.c @@ -397,7 +397,6 @@ static void md2_loadTexture(md2_t *model) #endif } HWD.pfnSetTexture(grpatch->mipmap); - HWR_UnlockCachedPatch(grpatch); } // -----------------+ @@ -453,7 +452,6 @@ static void md2_loadBlendTexture(md2_t *model) #endif } HWD.pfnSetTexture(grpatch->mipmap); // We do need to do this so that it can be cleared and knows to recreate it when necessary - HWR_UnlockCachedPatch(grpatch); Z_Free(filename); } From af3cf936830a14f789898ec773898e3c7620bf41 Mon Sep 17 00:00:00 2001 From: Jaime Passos Date: Thu, 12 Dec 2019 21:41:13 -0300 Subject: [PATCH 157/746] grafik designe is m passion --- src/hardware/hw_main.h | 1 + src/m_menu.c | 27 ++++++++++++++++----------- 2 files changed, 17 insertions(+), 11 deletions(-) diff --git a/src/hardware/hw_main.h b/src/hardware/hw_main.h index 96ff62cff..ce0e66b4d 100644 --- a/src/hardware/hw_main.h +++ b/src/hardware/hw_main.h @@ -85,6 +85,7 @@ extern consvar_t cv_grcoronasize; extern consvar_t cv_grfov; extern consvar_t cv_grmodels; extern consvar_t cv_grmodelinterpolation; +extern consvar_t cv_grmodellighting; extern consvar_t cv_grfog; extern consvar_t cv_grfogcolor; extern consvar_t cv_grfogdensity; diff --git a/src/m_menu.c b/src/m_menu.c index 8ed85f501..f20a8e22e 100644 --- a/src/m_menu.c +++ b/src/m_menu.c @@ -1299,20 +1299,25 @@ static menuitem_t OP_ColorOptionsMenu[] = #ifdef HWRENDER static menuitem_t OP_OpenGLOptionsMenu[] = { - {IT_STRING|IT_CVAR, NULL, "Models", &cv_grmodels, 10}, - {IT_STRING|IT_CVAR, NULL, "Model interpolation", &cv_grmodelinterpolation, 20}, + {IT_HEADER, NULL, "3D Models", NULL, 0}, + {IT_STRING|IT_CVAR, NULL, "Models", &cv_grmodels, 12}, + {IT_STRING|IT_CVAR, NULL, "Model interpolation", &cv_grmodelinterpolation, 22}, + {IT_STRING|IT_CVAR, NULL, "Model lighting", &cv_grmodellighting, 32}, - {IT_STRING|IT_CVAR, NULL, "Field of view", &cv_grfov, 40}, - {IT_STRING|IT_CVAR, NULL, "Quality", &cv_scr_depth, 50}, - {IT_STRING|IT_CVAR, NULL, "Texture Filter", &cv_grfiltermode, 60}, - {IT_STRING|IT_CVAR, NULL, "Anisotropic", &cv_granisotropicmode,70}, -#if defined (_WINDOWS) && (!((defined (__unix__) && !defined (MSDOS)) || defined (UNIXCOMMON) || defined (HAVE_SDL))) - {IT_STRING|IT_CVAR, NULL, "Fullscreen", &cv_fullscreen, 80}, -#endif + {IT_HEADER, NULL, "General", NULL, 51}, + {IT_STRING|IT_CVAR, NULL, "Field of view", &cv_grfov, 62}, + {IT_STRING|IT_CVAR, NULL, "Quality", &cv_scr_depth, 72}, + {IT_STRING|IT_CVAR, NULL, "Texture Filter", &cv_grfiltermode, 82}, + {IT_STRING|IT_CVAR, NULL, "Anisotropic", &cv_granisotropicmode,92}, + + {IT_HEADER, NULL, "Miscellaneous", NULL, 111}, + {IT_SUBMENU|IT_STRING, NULL, "Fog...", &OP_OpenGLFogDef, 123}, #ifdef ALAM_LIGHTING - {IT_SUBMENU|IT_STRING, NULL, "Lighting...", &OP_OpenGLLightingDef, 100}, + {IT_SUBMENU|IT_STRING, NULL, "Lighting...", &OP_OpenGLLightingDef, 133}, +#endif +#if defined (_WINDOWS) && (!((defined (__unix__) && !defined (MSDOS)) || defined (UNIXCOMMON) || defined (HAVE_SDL))) + {IT_STRING|IT_CVAR, NULL, "Fullscreen", &cv_fullscreen, 143}, #endif - {IT_SUBMENU|IT_STRING, NULL, "Fog...", &OP_OpenGLFogDef, 110}, }; #ifdef ALAM_LIGHTING From ff348fb60ab62edd90d5bbc4357732e183e37c61 Mon Sep 17 00:00:00 2001 From: Jaime Passos Date: Thu, 12 Dec 2019 21:43:19 -0300 Subject: [PATCH 158/746] Add missing prototype, ugh --- src/hardware/hw_main.h | 1 + 1 file changed, 1 insertion(+) diff --git a/src/hardware/hw_main.h b/src/hardware/hw_main.h index ce0e66b4d..e46aa9801 100644 --- a/src/hardware/hw_main.h +++ b/src/hardware/hw_main.h @@ -57,6 +57,7 @@ UINT8 *HWR_GetScreenshot(void); boolean HWR_Screenshot(const char *pathname); void HWR_AddCommands(void); +void HWR_AddSessionCommands(void); void HWR_CorrectSWTricks(void); void transform(float *cx, float *cy, float *cz); FBITFIELD HWR_TranstableToAlpha(INT32 transtablenum, FSurfaceInfo *pSurf); From 01399c70760f7b0ae7ecdb396ebd4ffb9fb41caf Mon Sep 17 00:00:00 2001 From: Jaime Passos Date: Thu, 12 Dec 2019 21:52:59 -0300 Subject: [PATCH 159/746] Update hw_main.c --- src/hardware/hw_main.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/hardware/hw_main.c b/src/hardware/hw_main.c index 1e1935c44..51bc1cec0 100644 --- a/src/hardware/hw_main.c +++ b/src/hardware/hw_main.c @@ -6570,7 +6570,7 @@ consvar_t cv_grmodels = {"gr_models", "Off", CV_SAVE, CV_OnOff, NULL, 0, NULL, N consvar_t cv_grmodelinterpolation = {"gr_modelinterpolation", "Sometimes", CV_SAVE, grmodelinterpolation_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL}; consvar_t cv_grmodellighting = {"gr_modellighting", "Off", CV_SAVE|CV_CALL, CV_OnOff, CV_grmodellighting_OnChange, 0, NULL, NULL, 0, 0, NULL}; -consvar_t cv_grspritebillboarding = {"gr_spritebillboarding", "On", CV_SAVE, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL}; +consvar_t cv_grspritebillboarding = {"gr_spritebillboarding", "Off", CV_SAVE, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL}; consvar_t cv_grskydome = {"gr_skydome", "On", CV_SAVE, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL}; consvar_t cv_grrounddown = {"gr_rounddown", "Off", 0, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL}; From 08794559f06c929fc107c909a8a631cabe83fd41 Mon Sep 17 00:00:00 2001 From: Jaime Passos Date: Thu, 12 Dec 2019 22:26:28 -0300 Subject: [PATCH 160/746] Fix TC_ blending --- src/hardware/hw_data.h | 1 + src/hardware/hw_md2.c | 32 ++++++++++++++++++++------------ 2 files changed, 21 insertions(+), 12 deletions(-) diff --git a/src/hardware/hw_data.h b/src/hardware/hw_data.h index ef57426a4..f525e041f 100644 --- a/src/hardware/hw_data.h +++ b/src/hardware/hw_data.h @@ -48,6 +48,7 @@ struct GLMipmap_s struct GLMipmap_s *nextcolormap; const UINT8 *colormap; + INT32 tcindex; // opengl struct GLMipmap_s *nextmipmap; // opengl : liste of all texture in opengl driver diff --git a/src/hardware/hw_md2.c b/src/hardware/hw_md2.c index 77cdfa0d3..467f35ec4 100644 --- a/src/hardware/hw_md2.c +++ b/src/hardware/hw_md2.c @@ -649,7 +649,6 @@ static void HWR_CreateBlendedTexture(GLPatch_t *gpatch, GLPatch_t *blendgpatch, if (grmip->width == 0) { - grmip->width = gpatch->width; grmip->height = gpatch->height; @@ -679,10 +678,11 @@ static void HWR_CreateBlendedTexture(GLPatch_t *gpatch, GLPatch_t *blendgpatch, { if (skinnum == TC_BOSS) { - // Pure black turns into white - if (image->s.red == 0 && image->s.green == 0 && image->s.blue == 0) + // Turn everything below a certain threshold white + if ((image->s.red == image->s.green) && (image->s.green == image->s.blue) && image->s.blue <= 82) { - cur->s.red = cur->s.green = cur->s.blue = 255; + // Lactozilla: Invert the colors + cur->s.red = cur->s.green = cur->s.blue = (255 - image->s.blue); } else { @@ -908,19 +908,19 @@ static void HWR_GetBlendedTexture(GLPatch_t *gpatch, GLPatch_t *blendgpatch, INT // mostly copied from HWR_GetMappedPatch, hence the similarities and comment GLMipmap_t *grmip, *newmip; - if (colormap == colormaps || colormap == NULL) + if ((colormap == colormaps || colormap == NULL) && (skinnum > TC_DEFAULT)) { // Don't do any blending HWD.pfnSetTexture(gpatch->mipmap); return; } - // search for the mimmap + // search for the mipmap // skip the first (no colormap translated) for (grmip = gpatch->mipmap; grmip->nextcolormap; ) { grmip = grmip->nextcolormap; - if (grmip->colormap == colormap) + if (grmip->colormap == colormap || grmip->tcindex == skinnum) { if (grmip->downloaded && grmip->grInfo.data) { @@ -943,6 +943,7 @@ static void HWR_GetBlendedTexture(GLPatch_t *gpatch, GLPatch_t *blendgpatch, INT I_Error("%s: Out of memory", "HWR_GetMappedPatch"); grmip->nextcolormap = newmip; newmip->colormap = colormap; + newmip->tcindex = skinnum; HWR_CreateBlendedTexture(gpatch, blendgpatch, newmip, skinnum, color); @@ -1167,11 +1168,10 @@ void HWR_DrawModel(gr_vissprite_t *spr) if (gpatch && gpatch->mipmap->grInfo.format) // else if meant that if a texture couldn't be loaded, it would just end up using something else's texture { - if ((skincolors_t)spr->mobj->color != SKINCOLOR_NONE && - md2->blendgrpatch && ((GLPatch_t *)md2->blendgrpatch)->mipmap->grInfo.format + if (md2->blendgrpatch && ((GLPatch_t *)md2->blendgrpatch)->mipmap->grInfo.format && gpatch->width == ((GLPatch_t *)md2->blendgrpatch)->width && gpatch->height == ((GLPatch_t *)md2->blendgrpatch)->height) { - INT32 skinnum = TC_DEFAULT; + INT32 skinnum = INT32_MAX; if ((spr->mobj->flags & (MF_ENEMY|MF_BOSS)) && (spr->mobj->flags2 & MF2_FRET) && !(spr->mobj->flags & MF_GRENADEBOUNCE) && (leveltime & 1)) // Bosses "flash" { if (spr->mobj->type == MT_CYBRAKDEMON || spr->mobj->colorized) @@ -1181,7 +1181,7 @@ void HWR_DrawModel(gr_vissprite_t *spr) else skinnum = TC_BOSS; } - else if (spr->mobj->color) + else if ((skincolors_t)spr->mobj->color != SKINCOLOR_NONE) { if (spr->mobj->colorized) skinnum = TC_RAINBOW; @@ -1199,7 +1199,15 @@ void HWR_DrawModel(gr_vissprite_t *spr) else skinnum = TC_DEFAULT; } - HWR_GetBlendedTexture(gpatch, (GLPatch_t *)md2->blendgrpatch, skinnum, spr->colormap, (skincolors_t)spr->mobj->color); + + // Translation or skin number found + if (skinnum != INT32_MAX) + HWR_GetBlendedTexture(gpatch, (GLPatch_t *)md2->blendgrpatch, skinnum, spr->colormap, (skincolors_t)spr->mobj->color); + else + { + // Sorry nothing + HWD.pfnSetTexture(gpatch->mipmap); + } } else { From ca83bafae8fba68a376b5640ab39fa583c709c97 Mon Sep 17 00:00:00 2001 From: Jaime Passos Date: Thu, 12 Dec 2019 22:32:19 -0300 Subject: [PATCH 161/746] Initialise the variable, obviously --- src/hardware/hw_md2.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/hardware/hw_md2.c b/src/hardware/hw_md2.c index 105321e8d..b329e4097 100644 --- a/src/hardware/hw_md2.c +++ b/src/hardware/hw_md2.c @@ -721,6 +721,8 @@ static void HWR_CreateBlendedTexture(GLPatch_t *gpatch, GLPatch_t *blendgpatch, UINT8 ialpha = 255 - blendimage->s.alpha, balpha = blendimage->s.alpha; RGBA_t icolor = *image, bcolor; + memset(&bcolor, 0x00, sizeof(RGBA_t)); + if (blendimage->s.alpha) { bcolor.s.blue = 0; From 228b29e23b5efb466845c37514d409decd8ddfb7 Mon Sep 17 00:00:00 2001 From: Jaime Passos Date: Thu, 12 Dec 2019 22:53:19 -0300 Subject: [PATCH 162/746] HWR_AllowModel --- src/hardware/hw_main.c | 10 ++++++++-- src/hardware/hw_md2.c | 27 ++++++++++++++++++++++----- src/hardware/hw_md2.h | 2 +- 3 files changed, 31 insertions(+), 8 deletions(-) diff --git a/src/hardware/hw_main.c b/src/hardware/hw_main.c index 51bc1cec0..6ef48f222 100644 --- a/src/hardware/hw_main.c +++ b/src/hardware/hw_main.c @@ -5368,14 +5368,20 @@ static void HWR_DrawSprites(void) if (!cv_grmodels.value || md2_playermodels[(skin_t*)spr->mobj->skin-skins].notfound || md2_playermodels[(skin_t*)spr->mobj->skin-skins].scale < 0.0f) HWR_DrawSprite(spr); else - HWR_DrawModel(spr); + { + if (!HWR_DrawModel(spr)) + HWR_DrawSprite(spr); + } } else { if (!cv_grmodels.value || md2_models[spr->mobj->sprite].notfound || md2_models[spr->mobj->sprite].scale < 0.0f) HWR_DrawSprite(spr); else - HWR_DrawModel(spr); + { + if (!HWR_DrawModel(spr)) + HWR_DrawSprite(spr); + } } } } diff --git a/src/hardware/hw_md2.c b/src/hardware/hw_md2.c index b329e4097..f857b11b8 100644 --- a/src/hardware/hw_md2.c +++ b/src/hardware/hw_md2.c @@ -985,6 +985,16 @@ static void HWR_GetBlendedTexture(GLPatch_t *gpatch, GLPatch_t *blendgpatch, INT #define NORMALFOG 0x00000000 #define FADEFOG 0x19000000 +static boolean HWR_AllowModel(mobj_t *mobj) +{ + // Signpost overlay. Not needed. + if (mobj->state-states == S_PLAY_SIGN) + return false; + + // Otherwise, render the model. + return true; +} + static boolean HWR_CanInterpolateModel(mobj_t *mobj, model_t *model) { if (cv_grmodelinterpolation.value == 2) // Always interpolate @@ -1060,7 +1070,7 @@ static UINT8 HWR_GetModelSprite2(md2_t *md2, skin_t *skin, UINT8 spr2, player_t // HWR_DrawModel // -void HWR_DrawModel(gr_vissprite_t *spr) +boolean HWR_DrawModel(gr_vissprite_t *spr) { FSurfaceInfo Surf; @@ -1073,10 +1083,10 @@ void HWR_DrawModel(gr_vissprite_t *spr) UINT8 color[4]; if (!cv_grmodels.value) - return; + return false; if (spr->precip) - return; + return false; memset(&p, 0x00, sizeof(FTransform)); @@ -1166,7 +1176,7 @@ void HWR_DrawModel(gr_vissprite_t *spr) } if (md2->error) - return; // we already failed loading this before :( + return false; // we already failed loading this before :( if (!md2->model) { //CONS_Debug(DBG_RENDER, "Loading model... (%s)", sprnames[spr->mobj->sprite]); @@ -1182,9 +1192,14 @@ void HWR_DrawModel(gr_vissprite_t *spr) { //CONS_Debug(DBG_RENDER, " FAILED\n"); md2->error = true; // prevent endless fail - return; + return false; } } + + // Lactozilla: Disallow certain models from rendering + if (!HWR_AllowModel(spr->mobj)) + return false; + //HWD.pfnSetBlend(blend); // This seems to actually break translucency? finalscale = md2->scale; //Hurdler: arf, I don't like that implementation at all... too much crappy @@ -1416,6 +1431,8 @@ void HWR_DrawModel(gr_vissprite_t *spr) HWD.pfnDrawModel(md2->model, frame, durs, tics, nextFrame, &p, finalscale, flip, color); } + + return true; } #endif //HWRENDER diff --git a/src/hardware/hw_md2.h b/src/hardware/hw_md2.h index a5f5fc117..6f5985a44 100644 --- a/src/hardware/hw_md2.h +++ b/src/hardware/hw_md2.h @@ -45,8 +45,8 @@ extern md2_t md2_models[NUMSPRITES]; extern md2_t md2_playermodels[MAXSKINS]; void HWR_InitModels(void); -void HWR_DrawModel(gr_vissprite_t *spr); void HWR_AddPlayerModel(INT32 skin); void HWR_AddSpriteModel(size_t spritenum); +boolean HWR_DrawModel(gr_vissprite_t *spr); #endif // _HW_MD2_H_ From 4e814cd4248889b39407b957ad28f9b43f6cd5a4 Mon Sep 17 00:00:00 2001 From: Jaime Passos Date: Thu, 12 Dec 2019 23:18:39 -0300 Subject: [PATCH 163/746] FINALLY, COLORCUBIUM --- src/hardware/hw_md2.c | 12 +++++++ src/v_video.c | 74 +++++++++++++++++++++++-------------------- src/v_video.h | 2 ++ 3 files changed, 54 insertions(+), 34 deletions(-) diff --git a/src/hardware/hw_md2.c b/src/hardware/hw_md2.c index f857b11b8..13ba007ee 100644 --- a/src/hardware/hw_md2.c +++ b/src/hardware/hw_md2.c @@ -373,6 +373,9 @@ static void md2_loadTexture(md2_t *model) if (!grpatch->mipmap->downloaded && !grpatch->mipmap->grInfo.data) { int w = 0, h = 0; + UINT32 size; + RGBA_t *image; + #ifdef HAVE_PNG grpatch->mipmap->grInfo.format = PNG_Load(filename, &w, &h, grpatch); if (grpatch->mipmap->grInfo.format == 0) @@ -389,6 +392,15 @@ static void md2_loadTexture(md2_t *model) grpatch->mipmap->width = (UINT16)w; grpatch->mipmap->height = (UINT16)h; + // Lactozilla: Apply colour cube + image = grpatch->mipmap->grInfo.data; + size = w*h; + while (size--) + { + V_CubeApply(&image->s.red, &image->s.green, &image->s.blue); + image++; + } + #ifdef GLIDE_API_COMPATIBILITY // not correct! grpatch->mipmap->grInfo.smallLodLog2 = GR_LOD_LOG2_256; diff --git a/src/v_video.c b/src/v_video.c index 1c5cbbc0a..ea1d1169e 100644 --- a/src/v_video.c +++ b/src/v_video.c @@ -95,6 +95,7 @@ Please check it out if you're trying to maintain this. toast 18/04/17 */ float Cubepal[2][2][2][3]; +boolean Cubeapply = false; // returns whether to apply cube, selectively avoiding expensive operations static boolean InitCube(void) @@ -310,7 +311,7 @@ const UINT8 correctiontable[256] = // keep a copy of the palette so that we can get the RGB value for a color index at any time. static void LoadPalette(const char *lumpname) { - boolean cube = InitCube(); + Cubeapply = InitCube(); lumpnum_t lumpnum = W_GetNumForName(lumpname); size_t i, palsize = W_LumpLength(lumpnum)/3; UINT8 *pal; @@ -336,43 +337,48 @@ static void LoadPalette(const char *lumpname) pMasterPalette[i].s.alpha = pLocalPalette[i].s.alpha = 0xFF; // lerp of colour cubing! if you want, make it smoother yourself - if (cube) - { - float working[4][3]; - float linear; - UINT8 q; + V_CubeApply(&pLocalPalette[i].s.red, &pLocalPalette[i].s.green, &pLocalPalette[i].s.blue); + } +} - linear = (pLocalPalette[i].s.red/255.0); +void V_CubeApply(UINT8 *red, UINT8 *green, UINT8 *blue) +{ + float working[4][3]; + float linear; + UINT8 q; + + if (!Cubeapply) + return; + + linear = (*red/255.0); #define dolerp(e1, e2) ((1 - linear)*e1 + linear*e2) - for (q = 0; q < 3; q++) - { - working[0][q] = dolerp(Cubepal[0][0][0][q], Cubepal[1][0][0][q]); - working[1][q] = dolerp(Cubepal[0][1][0][q], Cubepal[1][1][0][q]); - working[2][q] = dolerp(Cubepal[0][0][1][q], Cubepal[1][0][1][q]); - working[3][q] = dolerp(Cubepal[0][1][1][q], Cubepal[1][1][1][q]); - } - linear = (pLocalPalette[i].s.green/255.0); - for (q = 0; q < 3; q++) - { - working[0][q] = dolerp(working[0][q], working[1][q]); - working[1][q] = dolerp(working[2][q], working[3][q]); - } - linear = (pLocalPalette[i].s.blue/255.0); - for (q = 0; q < 3; q++) - { - working[0][q] = 255*dolerp(working[0][q], working[1][q]); - if (working[0][q] > 255.0) - working[0][q] = 255.0; - else if (working[0][q] < 0.0) - working[0][q] = 0.0; - } + for (q = 0; q < 3; q++) + { + working[0][q] = dolerp(Cubepal[0][0][0][q], Cubepal[1][0][0][q]); + working[1][q] = dolerp(Cubepal[0][1][0][q], Cubepal[1][1][0][q]); + working[2][q] = dolerp(Cubepal[0][0][1][q], Cubepal[1][0][1][q]); + working[3][q] = dolerp(Cubepal[0][1][1][q], Cubepal[1][1][1][q]); + } + linear = (*green/255.0); + for (q = 0; q < 3; q++) + { + working[0][q] = dolerp(working[0][q], working[1][q]); + working[1][q] = dolerp(working[2][q], working[3][q]); + } + linear = (*blue/255.0); + for (q = 0; q < 3; q++) + { + working[0][q] = 255*dolerp(working[0][q], working[1][q]); + if (working[0][q] > 255.0) + working[0][q] = 255.0; + else if (working[0][q] < 0.0) + working[0][q] = 0.0; + } #undef dolerp - pLocalPalette[i].s.red = (UINT8)(working[0][0]); - pLocalPalette[i].s.green = (UINT8)(working[0][1]); - pLocalPalette[i].s.blue = (UINT8)(working[0][2]); - } - } + *red = (UINT8)(working[0][0]); + *green = (UINT8)(working[0][1]); + *blue = (UINT8)(working[0][2]); } const char *R_GetPalname(UINT16 num) diff --git a/src/v_video.h b/src/v_video.h index 81f410f40..2434fec81 100644 --- a/src/v_video.h +++ b/src/v_video.h @@ -48,6 +48,8 @@ const char *GetPalette(void); extern RGBA_t *pLocalPalette; extern RGBA_t *pMasterPalette; +void V_CubeApply(UINT8 *red, UINT8 *green, UINT8 *blue); + // Retrieve the ARGB value from a palette color index #define V_GetColor(color) (pLocalPalette[color&0xFF]) From b0ffe7ed700cf82085729b2bfc988c83917619eb Mon Sep 17 00:00:00 2001 From: Jaime Passos Date: Thu, 12 Dec 2019 23:30:09 -0300 Subject: [PATCH 164/746] Update v_video.c --- src/v_video.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/v_video.c b/src/v_video.c index ea1d1169e..dad8e8513 100644 --- a/src/v_video.c +++ b/src/v_video.c @@ -337,7 +337,8 @@ static void LoadPalette(const char *lumpname) pMasterPalette[i].s.alpha = pLocalPalette[i].s.alpha = 0xFF; // lerp of colour cubing! if you want, make it smoother yourself - V_CubeApply(&pLocalPalette[i].s.red, &pLocalPalette[i].s.green, &pLocalPalette[i].s.blue); + if (Cubeapply) + V_CubeApply(&pLocalPalette[i].s.red, &pLocalPalette[i].s.green, &pLocalPalette[i].s.blue); } } From 4941ef4aac380b396f7106094b1841b54fc1666e Mon Sep 17 00:00:00 2001 From: fickleheart Date: Thu, 12 Dec 2019 22:13:44 -0600 Subject: [PATCH 165/746] Don't turn strafe keys into turn when locked onto something --- 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 a118ec09d..522777ee5 100644 --- a/src/g_game.c +++ b/src/g_game.c @@ -1081,7 +1081,7 @@ void G_BuildTiccmd(ticcmd_t *cmd, INT32 realtics, UINT8 ssplayer) abilitydirection = cv_abilitydirection[forplayer].value; strafeisturn = abilitydirection && ticcmd_centerviewdown[forplayer] && - (cv_cam_lockedinput[forplayer].value || (player->pflags & PF_STARTDASH)) && + ((cv_cam_lockedinput[forplayer].value && !ticcmd_ztargetfocus[forplayer]) || (player->pflags & PF_STARTDASH)) && !player->climbing && player->powers[pw_carry] != CR_MINECART; // why build a ticcmd if we're paused? From d14fa39d7aeb8189616b98c0c4a9fb0908194dc8 Mon Sep 17 00:00:00 2001 From: fickleheart Date: Thu, 12 Dec 2019 23:03:51 -0600 Subject: [PATCH 166/746] Expand options for aim assist This will need a lot of testing to ensure each type works properly. --- src/g_game.c | 15 ++++++++--- src/g_game.h | 8 ++++++ src/m_menu.c | 4 +-- src/p_local.h | 2 +- src/p_user.c | 72 +++++++++++++++++++++++++++++++++++++++------------ 5 files changed, 78 insertions(+), 23 deletions(-) diff --git a/src/g_game.c b/src/g_game.c index 522777ee5..6ea14bcff 100644 --- a/src/g_game.c +++ b/src/g_game.c @@ -428,9 +428,18 @@ consvar_t cv_cam_lockedinput[2] = { {"cam2_lockedinput", "Strafe", CV_SAVE, lockedinput_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL}, }; +static CV_PossibleValue_t lockedassist_cons_t[] = { + {0, "Off"}, + {LOCK_BOSS, "Bosses"}, + {LOCK_BOSS|LOCK_ENEMY, "Enemies"}, + {LOCK_BOSS|LOCK_INTERESTS, "Interests"}, + {LOCK_BOSS|LOCK_ENEMY|LOCK_INTERESTS, "Full"}, + {0, NULL} +}; + consvar_t cv_cam_lockonboss[2] = { - {"cam_lockonboss", "On", CV_SAVE, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL}, - {"cam2_lockonboss", "On", CV_SAVE, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL}, + {"cam_lockaimassist", "Bosses", CV_SAVE, lockedassist_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL}, + {"cam2_lockaimassist", "Bosses", CV_SAVE, lockedassist_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL}, }; typedef enum @@ -1286,7 +1295,7 @@ void G_BuildTiccmd(ticcmd_t *cmd, INT32 realtics, UINT8 ssplayer) *myaiming = 0; if (cv_cam_lockonboss[forplayer].value) - P_SetTarget(&ticcmd_ztargetfocus[forplayer], P_LookForFocusTarget(player, NULL, 0)); + P_SetTarget(&ticcmd_ztargetfocus[forplayer], P_LookForFocusTarget(player, NULL, 0, cv_cam_lockonboss[forplayer].value)); } ticcmd_centerviewdown[forplayer] = true; diff --git a/src/g_game.h b/src/g_game.h index f6e7acede..0a018e253 100644 --- a/src/g_game.h +++ b/src/g_game.h @@ -81,6 +81,14 @@ extern consvar_t cv_abilitydirection[2], cv_cam_shiftfacing[2], cv_cam_turnfacin cv_cam_turnfacingability[2], cv_cam_turnfacingspindash[2], cv_cam_turnfacinginput[2], cv_cam_lockedinput[2], cv_cam_lockonboss[2]; +typedef enum +{ + LOCK_BOSS = 1<<0, + LOCK_ENEMY = 1<<1, + LOCK_INTERESTS = 1<<2, +} lockassist_e; + + // mouseaiming (looking up/down with the mouse or keyboard) #define KB_LOOKSPEED (1<<25) #define MAXPLMOVE (50) diff --git a/src/m_menu.c b/src/m_menu.c index 6d42fddda..bfe118af1 100644 --- a/src/m_menu.c +++ b/src/m_menu.c @@ -1239,7 +1239,7 @@ static menuitem_t OP_CameraExtendedOptionsMenu[] = {IT_HEADER, NULL, "Locked Camera Options", NULL, 95}, {IT_STRING | IT_CVAR, NULL, "Sideways movement", &cv_cam_lockedinput[0], 100}, - {IT_STRING | IT_CVAR, NULL, "Boss targeting assist", &cv_cam_lockonboss[0], 105}, + {IT_STRING | IT_CVAR, NULL, "Targeting assist", &cv_cam_lockonboss[0], 105}, {IT_HEADER, NULL, "Display Options", NULL, 115}, {IT_STRING | IT_CVAR, NULL, "Crosshair", &cv_crosshair, 120}, @@ -1268,7 +1268,7 @@ static menuitem_t OP_Camera2ExtendedOptionsMenu[] = {IT_HEADER, NULL, "Locked Camera Options", NULL, 95}, {IT_STRING | IT_CVAR, NULL, "Sideways movement", &cv_cam_lockedinput[1], 100}, - {IT_STRING | IT_CVAR, NULL, "Boss targeting assist", &cv_cam_lockonboss[1], 105}, + {IT_STRING | IT_CVAR, NULL, "Targeting assist", &cv_cam_lockonboss[1], 105}, {IT_HEADER, NULL, "Display Options", NULL, 115}, {IT_STRING | IT_CVAR, NULL, "Crosshair", &cv_crosshair2, 120}, diff --git a/src/p_local.h b/src/p_local.h index f87930e28..ee52ac808 100644 --- a/src/p_local.h +++ b/src/p_local.h @@ -181,7 +181,7 @@ fixed_t P_ReturnThrustX(mobj_t *mo, angle_t angle, fixed_t move); fixed_t P_ReturnThrustY(mobj_t *mo, angle_t angle, fixed_t move); void P_InstaThrustEvenIn2D(mobj_t *mo, angle_t angle, fixed_t move); -mobj_t *P_LookForFocusTarget(player_t *player, mobj_t *exclude, SINT8 direction); +mobj_t *P_LookForFocusTarget(player_t *player, mobj_t *exclude, SINT8 direction, UINT8 lockonflags); mobj_t *P_LookForEnemies(player_t *player, boolean nonenemies, boolean bullet); void P_NukeEnemies(mobj_t *inflictor, mobj_t *source, fixed_t radius); diff --git a/src/p_user.c b/src/p_user.c index e57c56aa4..9c4c8a100 100644 --- a/src/p_user.c +++ b/src/p_user.c @@ -9142,7 +9142,7 @@ void P_NukeEnemies(mobj_t *inflictor, mobj_t *source, fixed_t radius) // direction, if set, requires the target to be to the left (1) or right (-1) of the angle // mobjflags can be used to limit the flags of objects that can be focused // -mobj_t *P_LookForFocusTarget(player_t *player, mobj_t *exclude, SINT8 direction) +mobj_t *P_LookForFocusTarget(player_t *player, mobj_t *exclude, SINT8 direction, UINT8 lockonflags) { mobj_t *mo; thinker_t *think; @@ -9162,20 +9162,53 @@ mobj_t *P_LookForFocusTarget(player_t *player, mobj_t *exclude, SINT8 direction) if (mo->flags & MF_NOCLIPTHING) continue; - if (mo->health <= 0) // dead - continue; - - if (!(mo->flags & MF_BOSS && (mo->flags & MF_SHOOTABLE)) == !(mo->flags2 & MF2_INVERTAIMABLE)) // allows if it has the flags desired XOR it has the invert aimable flag - continue; // not a valid target - if (mo == player->mo) continue; - if (mo->flags2 & MF2_FRET) + if (mo->health <= 0) // dead continue; - if (mo->type == MT_DETON) // Don't be STUPID, Sonic! - continue; + switch (mo->type) + { + case MT_TNTBARREL: + if (lockonflags & LOCK_INTERESTS) + break; + /*fallthru*/ + case MT_PLAYER: // Don't chase other players! + case MT_DETON: + continue; // Don't be STUPID, Sonic! + + case MT_FAKEMOBILE: + if (!(lockonflags & LOCK_BOSS)) + continue; + break; + + case MT_EGGSHIELD: + if (!(lockonflags & LOCK_ENEMY)) + continue; + break; + + case MT_EGGSTATUE: + if (tutorialmode) + break; // Always focus egg statue in the tutorial + /*fallthru*/ + default: + + if ((lockonflags & LOCK_BOSS) && ((mo->flags & (MF_BOSS|MF_SHOOTABLE)) == (MF_BOSS|MF_SHOOTABLE))) // allows if it has the flags desired XOR it has the invert aimable flag + { + if (mo->flags2 & MF2_FRET) + continue; + break; + } + + if ((lockonflags & LOCK_ENEMY) && (!((mo->flags & (MF_ENEMY|MF_SHOOTABLE)) == (MF_ENEMY|MF_SHOOTABLE)) != !(mo->flags2 & MF2_INVERTAIMABLE))) // allows if it has the flags desired XOR it has the invert aimable flag + break; + + if ((lockonflags & LOCK_INTERESTS) && (mo->flags & (MF_PUSHABLE|MF_MONITOR))) // allows if it has the flags desired XOR it has the invert aimable flag + break; + + continue; // not a valid object + } { fixed_t zdist = (player->mo->z + player->mo->height/2) - (mo->z + mo->height/2); @@ -9193,13 +9226,9 @@ mobj_t *P_LookForFocusTarget(player_t *player, mobj_t *exclude, SINT8 direction) && abs(player->mo->y-mo->y) > player->mo->radius) continue; // not in your 2d plane - if (mo->type == MT_PLAYER) // Don't chase after other players! - continue; - - dangle = R_PointToAngle2(player->mo->x + P_ReturnThrustX(player->mo, player->mo->angle, player->mo->radius), player->mo->y + P_ReturnThrustY(player->mo, player->mo->angle, player->mo->radius), mo->x, mo->y) - player->mo->angle; - - if ((dangle + span) > span*2) - continue; // behind back + dangle = R_PointToAngle2(player->mo->x, player->mo->y, mo->x, mo->y) - ( + !exclude ? player->mo->angle : R_PointToAngle2(player->mo->x, player->mo->y, exclude->x, exclude->y) + ); if (direction) { @@ -9209,6 +9238,15 @@ mobj_t *P_LookForFocusTarget(player_t *player, mobj_t *exclude, SINT8 direction) continue; // To the left of the player } + if (dangle > ANGLE_180) + dangle = InvAngle(dangle); + + if (dangle > span) + continue; // behind back + + // Inflate dist by angle difference to bias toward objects at a closer angle + dist = FixedDiv(dist, FINECOSINE(dangle>>ANGLETOFINESHIFT)*3); + if (closestmo && (exclude ? (dangle > closestdangle) : (dist > closestdist))) continue; From f34886850ff59c51b2b70afeee755bf4e378a500 Mon Sep 17 00:00:00 2001 From: James R Date: Thu, 12 Dec 2019 21:20:51 -0800 Subject: [PATCH 167/746] Fix idiot mistake --- src/sdl/i_system.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/sdl/i_system.c b/src/sdl/i_system.c index 9245673cc..c3b469bca 100644 --- a/src/sdl/i_system.c +++ b/src/sdl/i_system.c @@ -2182,7 +2182,7 @@ static void I_Fork(void) case 0: break; default: - if (wait(&status)) + if (wait(&status) == -1) { I_Error( "Error setting up signal reporting: fork(): %s\n", From 72ee91702cf7cec3a2076cb73e19835104dcc41d Mon Sep 17 00:00:00 2001 From: James R Date: Thu, 12 Dec 2019 21:21:25 -0800 Subject: [PATCH 168/746] Kill child when wait fails, so I_Error exits both --- src/sdl/i_system.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/src/sdl/i_system.c b/src/sdl/i_system.c index c3b469bca..7d1405268 100644 --- a/src/sdl/i_system.c +++ b/src/sdl/i_system.c @@ -2169,9 +2169,13 @@ void I_Sleep(void) #ifdef NEWSIGNALHANDLER static void I_Fork(void) { + int child; int status; int signum; - switch (fork()) + + child = fork(); + + switch (child) { case -1: I_Error( @@ -2184,6 +2188,7 @@ static void I_Fork(void) default: if (wait(&status) == -1) { + kill(child, SIGKILL); I_Error( "Error setting up signal reporting: fork(): %s\n", strerror(errno) From 35053adfb2fdb5cf224b5170dd9fa1ee57413723 Mon Sep 17 00:00:00 2001 From: James R Date: Thu, 12 Dec 2019 21:30:35 -0800 Subject: [PATCH 169/746] Rename I_StartupKeyboard to I_RegisterSignals and call it in a sane place --- src/d_main.c | 3 --- src/i_system.h | 4 ---- src/sdl/i_system.c | 3 ++- 3 files changed, 2 insertions(+), 8 deletions(-) diff --git a/src/d_main.c b/src/d_main.c index 397406293..00647048d 100644 --- a/src/d_main.c +++ b/src/d_main.c @@ -562,9 +562,6 @@ void D_SRB2Loop(void) // Pushing of + parameters is now done back in D_SRB2Main, not here. - CONS_Printf("I_StartupKeyboard()...\n"); - I_StartupKeyboard(); - #ifdef _WINDOWS CONS_Printf("I_StartupMouse()...\n"); I_DoStartupMouse(); diff --git a/src/i_system.h b/src/i_system.h index 831acda32..2532ba0ee 100644 --- a/src/i_system.h +++ b/src/i_system.h @@ -184,10 +184,6 @@ void I_StartupMouse(void); */ void I_StartupMouse2(void); -/** \brief keyboard startup, shutdown, handler -*/ -void I_StartupKeyboard(void); - /** \brief setup timer irq and user timer routine. */ void I_StartupTimer(void); diff --git a/src/sdl/i_system.c b/src/sdl/i_system.c index 7d1405268..95745497c 100644 --- a/src/sdl/i_system.c +++ b/src/sdl/i_system.c @@ -675,7 +675,7 @@ static inline void I_ShutdownConsole(void){} // // StartupKeyboard // -void I_StartupKeyboard (void) +void I_RegisterSignals (void) { #ifdef SIGINT signal(SIGINT , quit_handler); @@ -2228,6 +2228,7 @@ INT32 I_StartupSystem(void) #ifdef NEWSIGNALHANDLER I_Fork(); #endif + I_RegisterSignals(); I_OutputMsg("Compiled for SDL version: %d.%d.%d\n", SDLcompiled.major, SDLcompiled.minor, SDLcompiled.patch); I_OutputMsg("Linked with SDL version: %d.%d.%d\n", From bc4b1e1abefc6f1b469b50147bb63695307e589b Mon Sep 17 00:00:00 2001 From: fickleheart Date: Thu, 12 Dec 2019 23:52:13 -0600 Subject: [PATCH 170/746] Allow switching lockon targets with turn buttons --- src/g_game.c | 21 +++++++++++++++++++++ src/p_user.c | 2 +- 2 files changed, 22 insertions(+), 1 deletion(-) diff --git a/src/g_game.c b/src/g_game.c index 6ea14bcff..7eca22aac 100644 --- a/src/g_game.c +++ b/src/g_game.c @@ -1057,6 +1057,7 @@ void G_BuildTiccmd(ticcmd_t *cmd, INT32 realtics, UINT8 ssplayer) static boolean keyboard_look[2]; // true if lookup/down using keyboard static boolean resetdown[2]; // don't cam reset every frame static boolean joyaiming[2]; // check the last frame's value if we need to reset the camera + static boolean zchange[2]; // only switch z targets once per press UINT8 forplayer = ssplayer-1; if (ssplayer == 1) @@ -1322,6 +1323,26 @@ void G_BuildTiccmd(ticcmd_t *cmd, INT32 realtics, UINT8 ssplayer) P_SetTarget(&ticcmd_ztargetfocus[forplayer], NULL); else { + mobj_t *newtarget = NULL; + if (zchange[forplayer]) + { + if (!turnleft && !turnright && abs(cmd->angleturn) < angleturn[0]) + zchange[forplayer] = false; + } + else if (turnleft || cmd->angleturn > angleturn[0]) + { + zchange[forplayer] = true; + newtarget = P_LookForFocusTarget(player, ticcmd_ztargetfocus[forplayer], 1, cv_cam_lockonboss[forplayer].value); + } + else if (turnright || cmd->angleturn < -angleturn[0]) + { + zchange[forplayer] = true; + newtarget = P_LookForFocusTarget(player, ticcmd_ztargetfocus[forplayer], -1, cv_cam_lockonboss[forplayer].value); + } + + if (newtarget) + P_SetTarget(&ticcmd_ztargetfocus[forplayer], newtarget); + if (P_AproxDistance( player->mo->x - ticcmd_ztargetfocus[forplayer]->x, player->mo->y - ticcmd_ztargetfocus[forplayer]->y diff --git a/src/p_user.c b/src/p_user.c index 9c4c8a100..c7347462c 100644 --- a/src/p_user.c +++ b/src/p_user.c @@ -9162,7 +9162,7 @@ mobj_t *P_LookForFocusTarget(player_t *player, mobj_t *exclude, SINT8 direction, if (mo->flags & MF_NOCLIPTHING) continue; - if (mo == player->mo) + if (mo == player->mo || mo == exclude) continue; if (mo->health <= 0) // dead From 838850ffc1a240a1a1381f4b297995d49dcd0ddc Mon Sep 17 00:00:00 2001 From: James R Date: Thu, 12 Dec 2019 21:57:54 -0800 Subject: [PATCH 171/746] Fix signal handler setup error reporting --- src/sdl/i_system.c | 34 +++++++++++++++++++++++----------- 1 file changed, 23 insertions(+), 11 deletions(-) diff --git a/src/sdl/i_system.c b/src/sdl/i_system.c index 95745497c..4bed8e7f2 100644 --- a/src/sdl/i_system.c +++ b/src/sdl/i_system.c @@ -2167,6 +2167,26 @@ void I_Sleep(void) } #ifdef NEWSIGNALHANDLER +static void newsignalhandler_Warn(const char *pr) +{ + char text[128]; + + snprintf(text, sizeof text, + "Error while setting up signal reporting: %s: %s", + pr, + strerror(errno) + ); + + I_OutputMsg("%s\n", text); + + SDL_ShowSimpleMessageBox(SDL_MESSAGEBOX_ERROR, + "Startup error", + text, NULL); + + I_ShutdownConsole(); + exit(-1); +} + static void I_Fork(void) { int child; @@ -2178,10 +2198,7 @@ static void I_Fork(void) switch (child) { case -1: - I_Error( - "Error setting up signal reporting: fork(): %s\n", - strerror(errno) - ); + newsignalhandler_Warn("fork()"); break; case 0: break; @@ -2189,10 +2206,7 @@ static void I_Fork(void) if (wait(&status) == -1) { kill(child, SIGKILL); - I_Error( - "Error setting up signal reporting: fork(): %s\n", - strerror(errno) - ); + newsignalhandler_Warn("wait()"); } else { @@ -2211,7 +2225,7 @@ static void I_Fork(void) status = WEXITSTATUS (status); } - I_ShutdownSystem(); + I_ShutdownConsole(); exit(status); } } @@ -2468,8 +2482,6 @@ void I_ShutdownSystem(void) { INT32 c; - I_ShutdownConsole(); - for (c = MAX_QUIT_FUNCS-1; c >= 0; c--) if (quit_funcs[c]) (*quit_funcs[c])(); From 8bea7f6dbc87f29239286644627167cb516bc9d4 Mon Sep 17 00:00:00 2001 From: James R Date: Thu, 12 Dec 2019 22:01:16 -0800 Subject: [PATCH 172/746] Rename signal caught message to be more obvious --- src/sdl/i_system.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/sdl/i_system.c b/src/sdl/i_system.c index 4bed8e7f2..a28fadc02 100644 --- a/src/sdl/i_system.c +++ b/src/sdl/i_system.c @@ -282,10 +282,10 @@ static void I_ReportSignal(int num, int coredumped) sigmsg = msg; } - I_OutputMsg("\nsignal_handler() error: %s\n", sigmsg); + I_OutputMsg("\nProcess killed by signal: %s\n\n", sigmsg); SDL_ShowSimpleMessageBox(SDL_MESSAGEBOX_ERROR, - "Signal caught", + "Process killed by signal", sigmsg, NULL); } From 098c99a834eb0282a22cc694e438edd5879a04ef Mon Sep 17 00:00:00 2001 From: fickleheart Date: Fri, 13 Dec 2019 00:34:34 -0600 Subject: [PATCH 173/746] Adjust how turn-to-angle tweens --- src/g_game.c | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/src/g_game.c b/src/g_game.c index 7eca22aac..08f9396fc 100644 --- a/src/g_game.c +++ b/src/g_game.c @@ -1548,18 +1548,33 @@ void G_BuildTiccmd(ticcmd_t *cmd, INT32 realtics, UINT8 ssplayer) if (abilitydirection && !forcestrafe && camera.chase && !turnheld[forplayer] && !ticcmd_centerviewdown[forplayer] && player->powers[pw_carry] != CR_MINECART) { fixed_t camadjustfactor; + boolean alt = false; // Reduce intensity on diagonals and prevent backwards movement from turning the camera if (player->climbing || player->pflags & PF_GLIDING) camadjustfactor = cv_cam_turnfacingability[forplayer].value/4; else if (player->pflags & PF_STARTDASH) camadjustfactor = cv_cam_turnfacingspindash[forplayer].value/4; else + { + alt = true; camadjustfactor = cv_cam_turnfacing[forplayer].value/8; + } if (camadjustfactor) { INT32 anglediff = player->drawangle + drawangleoffset - *myangle; + if (alt) + { + fixed_t sine = FINESINE((angle_t) (anglediff)>>ANGLETOFINESHIFT); + sine = abs(sine); + + if (abs(anglediff) > ANGLE_90) + sine = max(0, sine*3 - 2*FRACUNIT); // At about 135 degrees, this will stop turning + + anglediff = FixedMul(anglediff, sine); + } + *myangle += FixedMul(anglediff, camadjustfactor); } } From c41b2e7456f8a9808655b6d6c4f2b05cfd1a35bb Mon Sep 17 00:00:00 2001 From: fickleheart Date: Fri, 13 Dec 2019 00:52:48 -0600 Subject: [PATCH 174/746] Suspend turn-to-angle when rotating the camera --- src/g_game.c | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/src/g_game.c b/src/g_game.c index 08f9396fc..6292683eb 100644 --- a/src/g_game.c +++ b/src/g_game.c @@ -1058,6 +1058,7 @@ void G_BuildTiccmd(ticcmd_t *cmd, INT32 realtics, UINT8 ssplayer) static boolean resetdown[2]; // don't cam reset every frame static boolean joyaiming[2]; // check the last frame's value if we need to reset the camera static boolean zchange[2]; // only switch z targets once per press + static fixed_t tta_factor[2] = {FRACUNIT, FRACUNIT}; // disables turn-to-angle when manually turning camera until movement happens UINT8 forplayer = ssplayer-1; if (ssplayer == 1) @@ -1204,6 +1205,9 @@ void G_BuildTiccmd(ticcmd_t *cmd, INT32 realtics, UINT8 ssplayer) cmd->angleturn = (INT16)(cmd->angleturn - ((axis * angleturn[1]) >> 10)); // ANALOG! } + if (turnright || turnleft || abs(cmd->angleturn) > angleturn[1]) + tta_factor[forplayer] = 0; // suspend turn to angle + // Make rotspeed affect turning speed :) cmd->angleturn = (cmd->angleturn * (ssplayer == 1 ? cv_cam_rotspeed.value : cv_cam2_rotspeed.value)) / 10; } @@ -1557,9 +1561,14 @@ void G_BuildTiccmd(ticcmd_t *cmd, INT32 realtics, UINT8 ssplayer) else { alt = true; - camadjustfactor = cv_cam_turnfacing[forplayer].value/8; + camadjustfactor = FixedMul(cv_cam_turnfacing[forplayer].value/8, tta_factor[forplayer]); } + if (tta_factor[forplayer] < FRACUNIT && (!alt || cmd->forwardmove || cmd->sidemove || tta_factor[forplayer] >= FRACUNIT/3)) + tta_factor[forplayer] += FRACUNIT>>5; + else if (tta_factor[forplayer] && tta_factor[forplayer] < FRACUNIT/3) + tta_factor[forplayer] -= FRACUNIT>>5; + if (camadjustfactor) { INT32 anglediff = player->drawangle + drawangleoffset - *myangle; From fa58c1fb26e11f4ee2fd3d363ede6160628a2a4d Mon Sep 17 00:00:00 2001 From: Jaime Passos Date: Fri, 13 Dec 2019 12:26:47 -0300 Subject: [PATCH 175/746] stuff --- src/r_draw.h | 3 -- src/r_draw8.c | 4 +-- src/r_plane.c | 49 ++++++++++++++++--------------- src/r_segs.c | 50 ++++++++++++++++---------------- src/r_splats.c | 2 +- src/r_things.c | 30 +++++++------------ src/screen.c | 78 +++++++++++++++++++++++++++----------------------- src/screen.h | 54 +++++++++++++++++++++++++--------- 8 files changed, 146 insertions(+), 124 deletions(-) diff --git a/src/r_draw.h b/src/r_draw.h index d033f221d..d7a098f32 100644 --- a/src/r_draw.h +++ b/src/r_draw.h @@ -138,19 +138,16 @@ void R_DrawViewBorder(void); // ----------------- void R_DrawColumn_8(void); -#define R_DrawWallColumn_8 R_DrawColumn_8 void R_DrawShadeColumn_8(void); void R_DrawTranslucentColumn_8(void); #ifdef USEASM void ASMCALL R_DrawColumn_8_ASM(void); -#define R_DrawWallColumn_8_ASM R_DrawColumn_8_ASM void ASMCALL R_DrawShadeColumn_8_ASM(void); void ASMCALL R_DrawTranslucentColumn_8_ASM(void); void ASMCALL R_Draw2sMultiPatchColumn_8_ASM(void); void ASMCALL R_DrawColumn_8_MMX(void); -#define R_DrawWallColumn_8_MMX R_DrawColumn_8_MMX void ASMCALL R_Draw2sMultiPatchColumn_8_MMX(void); void ASMCALL R_DrawSpan_8_MMX(void); diff --git a/src/r_draw8.c b/src/r_draw8.c index 11cdd5dca..db9bc4c3c 100644 --- a/src/r_draw8.c +++ b/src/r_draw8.c @@ -1880,7 +1880,7 @@ void R_DrawColumnShadowed_8(void) if (dc_yh > realyh) dc_yh = realyh; - basecolfunc(); // R_DrawColumn_8 for the appropriate architecture + (colfuncs[BASEDRAWFUNC])(); // R_DrawColumn_8 for the appropriate architecture if (solid) dc_yl = bheight; else @@ -1890,5 +1890,5 @@ void R_DrawColumnShadowed_8(void) } dc_yh = realyh; if (dc_yl <= realyh) - walldrawerfunc(); // R_DrawWallColumn_8 for the appropriate architecture + (colfuncs[BASEDRAWFUNC])(); // R_DrawWallColumn_8 for the appropriate architecture } diff --git a/src/r_plane.c b/src/r_plane.c index f96e7950e..8c644700e 100644 --- a/src/r_plane.c +++ b/src/r_plane.c @@ -587,8 +587,7 @@ void R_DrawPlanes(void) // Note: are these two lines really needed? // R_DrawSinglePlane and R_DrawSkyPlane do span/column drawer resets themselves anyway - spanfunc = basespanfunc; - wallcolfunc = walldrawerfunc; + spanfunc = spanfuncs[BASEDRAWFUNC]; for (i = 0; i < MAXVISPLANES; i++, pl++) { @@ -622,7 +621,7 @@ static void R_DrawSkyPlane(visplane_t *pl) // Reset column drawer function (note: couldn't we just call walldrawerfunc directly?) // (that is, unless we'll need to switch drawers in future for some reason) - wallcolfunc = walldrawerfunc; + colfunc = colfuncs[BASEDRAWFUNC]; // use correct aspect ratio scale dc_iscale = skyscale; @@ -648,7 +647,7 @@ static void R_DrawSkyPlane(visplane_t *pl) dc_source = R_GetColumn(texturetranslation[skytexture], -angle); // get negative of angle for each column to display sky correct way round! --Monster Iestyn 27/01/18 - wallcolfunc(); + colfunc(); } } } @@ -856,11 +855,11 @@ void R_DrawSinglePlane(visplane_t *pl) #ifndef NOWATER itswater = false; #endif - spanfunc = basespanfunc; + spanfunc = spanfuncs[BASEDRAWFUNC]; #ifdef POLYOBJECTS_PLANES if (pl->polyobj && pl->polyobj->translucency != 0) { - spanfunc = R_DrawTranslucentSpan_8; + spanfunc = spanfuncs[SPANDRAWFUNC_TRANS]; // Hacked up support for alpha value in software mode Tails 09-24-2002 (sidenote: ported to polys 10-15-2014, there was no time travel involved -Red) if (pl->polyobj->translucency >= 10) @@ -868,10 +867,10 @@ void R_DrawSinglePlane(visplane_t *pl) else if (pl->polyobj->translucency > 0) ds_transmap = transtables + ((pl->polyobj->translucency-1)<extra_colormap && (pl->extra_colormap->fog & 4))) + if ((spanfunc == spanfuncs[SPANDRAWFUNC_SPLAT]) != (pl->extra_colormap && (pl->extra_colormap->fog & 4))) #else if (!pl->extra_colormap || !(pl->extra_colormap->fog & 2)) #endif @@ -902,7 +901,7 @@ void R_DrawSinglePlane(visplane_t *pl) if (pl->ffloor->flags & FF_TRANSLUCENT) { - spanfunc = R_DrawTranslucentSpan_8; + spanfunc = spanfuncs[SPANDRAWFUNC_TRANS]; // Hacked up support for alpha value in software mode Tails 09-24-2002 if (pl->ffloor->alpha < 12) @@ -926,10 +925,10 @@ void R_DrawSinglePlane(visplane_t *pl) else if (pl->ffloor->alpha < 243) ds_transmap = transtables + ((tr_trans10-1)<extra_colormap && (pl->extra_colormap->fog & 4))) + if ((spanfunc == spanfuncs[SPANDRAWFUNC_SPLAT]) != (pl->extra_colormap && (pl->extra_colormap->fog & 4))) #else if (!pl->extra_colormap || !(pl->extra_colormap->fog & 2)) #endif @@ -939,7 +938,7 @@ void R_DrawSinglePlane(visplane_t *pl) } else if (pl->ffloor->flags & FF_FOG) { - spanfunc = R_DrawFogSpan_8; + spanfunc = spanfuncs[SPANDRAWFUNC_FOG]; light = (pl->lightlevel >> LIGHTSEGSHIFT); } else light = (pl->lightlevel >> LIGHTSEGSHIFT); @@ -954,9 +953,9 @@ void R_DrawSinglePlane(visplane_t *pl) INT32 top, bottom; itswater = true; - if (spanfunc == R_DrawTranslucentSpan_8) + if (spanfunc == spanfuncs[SPANDRAWFUNC_TRANS]) { - spanfunc = R_DrawTranslucentWaterSpan_8; + spanfunc = spanfuncs[SPANDRAWFUNC_WATER]; // Copy the current scene, ugh top = pl->high-8; @@ -1007,8 +1006,8 @@ void R_DrawSinglePlane(visplane_t *pl) R_CheckFlatLength(W_LumpLength(levelflat->u.flat.lumpnum)); // Raw flats always have dimensions that are powers-of-two numbers. ds_powersoftwo = true; - if (spanfunc == basespanfunc) - spanfunc = mmxspanfunc; + if (spanfunc == spanfuncs[BASEDRAWFUNC]) + spanfunc = spanfuncs[SPANDRAWFUNC_MMX]; break; default: switch (type) @@ -1033,8 +1032,8 @@ void R_DrawSinglePlane(visplane_t *pl) if (R_CheckPowersOfTwo()) { R_CheckFlatLength(ds_flatwidth * ds_flatheight); - if (spanfunc == basespanfunc) - spanfunc = mmxspanfunc; + if (spanfunc == spanfuncs[BASEDRAWFUNC]) + spanfunc = spanfuncs[SPANDRAWFUNC_MMX]; } } @@ -1188,12 +1187,12 @@ void R_DrawSinglePlane(visplane_t *pl) } #undef SFMULT - if (spanfunc == R_DrawTranslucentSpan_8) - spanfunc = R_DrawTiltedTranslucentSpan_8; - else if (spanfunc == splatfunc) - spanfunc = R_DrawTiltedSplat_8; + if (spanfunc == spanfuncs[SPANDRAWFUNC_TRANS]) + spanfunc = spanfuncs[SPANDRAWFUNC_TILTEDTRANS]; + else if (spanfunc == spanfuncs[SPANDRAWFUNC_SPLAT]) + spanfunc = spanfuncs[SPANDRAWFUNC_TILTEDSPLAT]; else - spanfunc = R_DrawTiltedSpan_8; + spanfunc = spanfuncs[SPANDRAWFUNC_TILTED]; planezlight = scalelight[light]; } else @@ -1240,11 +1239,11 @@ a 'smoothing' of the texture while using the palette colors. */ #ifdef QUINCUNX - if (spanfunc == R_DrawSpan_8) + if (spanfunc == spanfuncs[BASEDRAWFUNC]) { INT32 i; ds_transmap = transtables + ((tr_trans50-1)<xoffs; diff --git a/src/r_segs.c b/src/r_segs.c index d22a706ac..29120ebb8 100644 --- a/src/r_segs.c +++ b/src/r_segs.c @@ -177,20 +177,20 @@ static void R_DrawWallSplats(void) switch (splat->flags & SPLATDRAWMODE_MASK) { case SPLATDRAWMODE_OPAQUE: - colfunc = basecolfunc; + colfunc = colfuncs[BASEDRAWFUNC]; break; case SPLATDRAWMODE_TRANS: if (!cv_translucency.value) - colfunc = basecolfunc; + colfunc = colfuncs[BASEDRAWFUNC]; else { dc_transmap = transtables + ((tr_trans50 - 1)<special-900)<ceilingheight; windowbottom = frontsector->floorheight; break; default: - colfunc = wallcolfunc; + colfunc = colfuncs[BASEDRAWFUNC]; break; } @@ -345,7 +345,7 @@ void R_RenderMaskedSegRange(drawseg_t *ds, INT32 x1, INT32 x2) return; dc_transmap = transtables + ((curline->polyseg->translucency-1)<flags & FF_FOG || (rlight->extra_colormap && rlight->extra_colormap->fog)) lightnum = (rlight->lightlevel >> LIGHTSEGSHIFT); - else if (colfunc == fuzzcolfunc) + else if (colfunc == colfuncs[COLDRAWFUNC_FUZZY]) lightnum = LIGHTLEVELS - 1; else lightnum = (rlight->lightlevel >> LIGHTSEGSHIFT); @@ -436,7 +436,7 @@ void R_RenderMaskedSegRange(drawseg_t *ds, INT32 x1, INT32 x2) } else { - if (colfunc == fuzzcolfunc) + if (colfunc == colfuncs[COLDRAWFUNC_FUZZY]) { if (frontsector->extra_colormap && frontsector->extra_colormap->fog) lightnum = (frontsector->lightlevel >> LIGHTSEGSHIFT); @@ -446,7 +446,7 @@ void R_RenderMaskedSegRange(drawseg_t *ds, INT32 x1, INT32 x2) else lightnum = (frontsector->lightlevel >> LIGHTSEGSHIFT); - if (colfunc == R_DrawFogColumn_8 + if (colfunc == colfuncs[COLDRAWFUNC_FOG] || (frontsector->extra_colormap && frontsector->extra_colormap->fog)) ; else if (curline->v1->y == curline->v2->y) @@ -718,7 +718,7 @@ void R_RenderMaskedSegRange(drawseg_t *ds, INT32 x1, INT32 x2) spryscale += rw_scalestep; } } - colfunc = wallcolfunc; + colfunc = colfuncs[BASEDRAWFUNC]; } // Loop through R_DrawMaskedColumn calls @@ -789,7 +789,7 @@ void R_RenderThickSideRange(drawseg_t *ds, INT32 x1, INT32 x2, ffloor_t *pfloor) frontsector = curline->frontsector == pfloor->target ? curline->backsector : curline->frontsector; texnum = R_GetTextureNum(sides[pfloor->master->sidenum[0]].midtexture); - colfunc = wallcolfunc; + colfunc = colfuncs[BASEDRAWFUNC]; if (pfloor->master->flags & ML_TFERLINE) { @@ -827,10 +827,10 @@ void R_RenderThickSideRange(drawseg_t *ds, INT32 x1, INT32 x2, ffloor_t *pfloor) fuzzy = false; // Opaque if (fuzzy) - colfunc = fuzzcolfunc; + colfunc = colfuncs[COLDRAWFUNC_FUZZY]; } else if (pfloor->flags & FF_FOG) - colfunc = R_DrawFogColumn_8; + colfunc = colfuncs[COLDRAWFUNC_FOG]; #ifdef ESLOPE range = max(ds->x2-ds->x1, 1); @@ -965,7 +965,7 @@ void R_RenderThickSideRange(drawseg_t *ds, INT32 x1, INT32 x2, ffloor_t *pfloor) lightnum = (frontsector->lightlevel >> LIGHTSEGSHIFT); else if (pfloor->flags & FF_FOG) lightnum = (pfloor->master->frontsector->lightlevel >> LIGHTSEGSHIFT); - else if (colfunc == fuzzcolfunc) + else if (colfunc == colfuncs[COLDRAWFUNC_FUZZY]) lightnum = LIGHTLEVELS-1; else lightnum = R_FakeFlat(frontsector, &tempsec, &templight, &templight, false) @@ -1297,7 +1297,7 @@ void R_RenderThickSideRange(drawseg_t *ds, INT32 x1, INT32 x2, ffloor_t *pfloor) spryscale += rw_scalestep; } } - colfunc = wallcolfunc; + colfunc = colfuncs[BASEDRAWFUNC]; #undef CLAMPMAX #undef CLAMPMIN @@ -1530,7 +1530,7 @@ static void R_RenderSegLoop (void) else dc_lightlist[i].rcolormap = xwalllights[pindex]; - colfunc = R_DrawColumnShadowed_8; + colfunc = colfuncs[COLDRAWFUNC_SHADOWED]; } } @@ -1736,6 +1736,8 @@ void R_StoreWallRange(INT32 start, INT32 stop) memset(&segright, 0x00, sizeof(segright)); #endif + colfunc = colfuncs[BASEDRAWFUNC]; + if (ds_p == drawsegs+maxdrawsegs) { size_t curpos = curdrawsegs - drawsegs; @@ -3186,7 +3188,7 @@ void R_StoreWallRange(INT32 start, INT32 stop) else #endif R_RenderSegLoop(); - colfunc = wallcolfunc; + colfunc = colfuncs[BASEDRAWFUNC]; if (portalline) // if curline is a portal, set portalrender for drawseg ds_p->portalpass = portalrender+1; diff --git a/src/r_splats.c b/src/r_splats.c index 1b4b939a5..414e93eb6 100644 --- a/src/r_splats.c +++ b/src/r_splats.c @@ -512,7 +512,7 @@ static void R_RenderFloorSplat(floorsplat_t *pSplat, vertex_t *verts, UINT8 *pTe ds_x1 = x1; ds_x2 = x2; ds_transmap = transtables + ((tr_trans50-1)<colormap; if (!(vis->cut & SC_PRECIP) && (vis->mobj->flags & (MF_ENEMY|MF_BOSS)) && (vis->mobj->flags2 & MF2_FRET) && !(vis->mobj->flags & MF_GRENADEBOUNCE) && (leveltime & 1)) // Bosses "flash" { // translate certain pixels to white - colfunc = transcolfunc; + colfunc = colfuncs[COLDRAWFUNC_TRANS]; if (vis->mobj->type == MT_CYBRAKDEMON || vis->mobj->colorized) dc_translation = R_GetTranslationColormap(TC_ALLWHITE, 0, GTC_CACHE); else if (vis->mobj->type == MT_METALSONIC_BATTLE) @@ -791,7 +783,7 @@ static void R_DrawVisSprite(vissprite_t *vis) } else if (vis->mobj->color && vis->transmap) // Color mapping { - colfunc = transtransfunc; + colfunc = colfuncs[COLDRAWFUNC_TRANSTRANS]; dc_transmap = vis->transmap; if (!(vis->cut & SC_PRECIP) && vis->mobj->colorized) dc_translation = R_GetTranslationColormap(TC_RAINBOW, vis->mobj->color, GTC_CACHE); @@ -815,13 +807,13 @@ static void R_DrawVisSprite(vissprite_t *vis) } else if (vis->transmap) { - colfunc = fuzzcolfunc; + colfunc = colfuncs[COLDRAWFUNC_FUZZY]; dc_transmap = vis->transmap; //Fab : 29-04-98: translucency table } else if (vis->mobj->color) { // translate green skin to another color - colfunc = transcolfunc; + colfunc = colfuncs[COLDRAWFUNC_TRANS]; // New colormap stuff for skins Tails 06-07-2002 if (!(vis->cut & SC_PRECIP) && vis->mobj->colorized) @@ -846,7 +838,7 @@ static void R_DrawVisSprite(vissprite_t *vis) } else if (vis->mobj->sprite == SPR_PLAY) // Looks like a player, but doesn't have a color? Get rid of green sonic syndrome. { - colfunc = transcolfunc; + colfunc = colfuncs[COLDRAWFUNC_TRANS]; dc_translation = R_GetTranslationColormap(TC_DEFAULT, SKINCOLOR_BLUE, GTC_CACHE); } @@ -926,7 +918,7 @@ static void R_DrawVisSprite(vissprite_t *vis) spryscale += vis->scalestep; } - colfunc = basecolfunc; + colfunc = colfuncs[BASEDRAWFUNC]; dc_hires = 0; vis->x1 = x1; @@ -956,7 +948,7 @@ static void R_DrawPrecipitationVisSprite(vissprite_t *vis) if (vis->transmap) { - colfunc = fuzzcolfunc; + colfunc = colfuncs[COLDRAWFUNC_FUZZY]; dc_transmap = vis->transmap; //Fab : 29-04-98: translucency table } @@ -992,7 +984,7 @@ static void R_DrawPrecipitationVisSprite(vissprite_t *vis) R_DrawMaskedColumn(column); } - colfunc = basecolfunc; + colfunc = colfuncs[BASEDRAWFUNC]; } // diff --git a/src/screen.c b/src/screen.c index 3c4b2bc62..5c88d8471 100644 --- a/src/screen.c +++ b/src/screen.c @@ -41,20 +41,11 @@ // -------------------------------------------- // assembly or c drawer routines for 8bpp/16bpp // -------------------------------------------- -void (*wallcolfunc)(void); // new wall column drawer to draw posts >128 high -void (*colfunc)(void); // standard column, up to 128 high posts +void (*colfunc)(void); +void (*colfuncs[COLDRAWFUNC_MAX])(void); -void (*basecolfunc)(void); -void (*fuzzcolfunc)(void); // standard fuzzy effect column drawer -void (*transcolfunc)(void); // translation column drawer -void (*shadecolfunc)(void); // smokie test.. -void (*spanfunc)(void); // span drawer, use a 64x64 tile -void (*mmxspanfunc)(void); // span drawer in MMX assembly -void (*splatfunc)(void); // span drawer w/ transparency -void (*basespanfunc)(void); // default span func for color mode -void (*transtransfunc)(void); // translucent translated column drawer -void (*twosmultipatchfunc)(void); // for cols with transparent pixels -void (*twosmultipatchtransfunc)(void); // for cols with transparent pixels AND translucency +void (*spanfunc)(void); +void (*spanfuncs[SPANDRAWFUNC_MAX])(void); // ------------------ // global video state @@ -113,36 +104,53 @@ void SCR_SetMode(void) // if (true)//vid.bpp == 1) //Always run in 8bpp. todo: remove all 16bpp code? { - spanfunc = basespanfunc = mmxspanfunc = R_DrawSpan_8; - splatfunc = R_DrawSplat_8; - transcolfunc = R_DrawTranslatedColumn_8; - transtransfunc = R_DrawTranslatedTranslucentColumn_8; + colfuncs[BASEDRAWFUNC] = R_DrawColumn_8; + spanfuncs[BASEDRAWFUNC] = R_DrawSpan_8; + + colfunc = colfuncs[BASEDRAWFUNC]; + spanfunc = spanfuncs[BASEDRAWFUNC]; + + colfuncs[COLDRAWFUNC_FUZZY] = R_DrawTranslucentColumn_8; + colfuncs[COLDRAWFUNC_TRANS] = R_DrawTranslatedColumn_8; + colfuncs[COLDRAWFUNC_SHADE] = R_DrawShadeColumn_8; + colfuncs[COLDRAWFUNC_SHADOWED] = R_DrawColumnShadowed_8; + colfuncs[COLDRAWFUNC_TRANSTRANS] = R_DrawTranslatedTranslucentColumn_8; + colfuncs[COLDRAWFUNC_TWOSMULTIPATCH] = R_Draw2sMultiPatchColumn_8; + colfuncs[COLDRAWFUNC_TWOSMULTIPATCHTRANS] = R_Draw2sMultiPatchTranslucentColumn_8; + colfuncs[COLDRAWFUNC_FOG] = R_DrawFogColumn_8; + + spanfuncs[SPANDRAWFUNC_TRANS] = R_DrawTranslucentSpan_8; + spanfuncs[SPANDRAWFUNC_SPLAT] = R_DrawSplat_8; + spanfuncs[SPANDRAWFUNC_TRANSSPLAT] = R_DrawTranslucentSplat_8; + spanfuncs[SPANDRAWFUNC_FOG] = R_DrawFogSpan_8; + spanfuncs[SPANDRAWFUNC_MMX] = spanfuncs[BASEDRAWFUNC]; +#ifndef NOWATER + spanfuncs[SPANDRAWFUNC_WATER] = R_DrawTranslucentWaterSpan_8; +#endif +#ifdef ESLOPE + spanfuncs[SPANDRAWFUNC_TILTED] = R_DrawTiltedSpan_8; + spanfuncs[SPANDRAWFUNC_TILTEDTRANS] = R_DrawTiltedTranslucentSpan_8; + spanfuncs[SPANDRAWFUNC_TILTEDSPLAT] = R_DrawTiltedSplat_8; +#endif + - colfunc = basecolfunc = R_DrawColumn_8; - shadecolfunc = R_DrawShadeColumn_8; - fuzzcolfunc = R_DrawTranslucentColumn_8; - walldrawerfunc = R_DrawWallColumn_8; - twosmultipatchfunc = R_Draw2sMultiPatchColumn_8; - twosmultipatchtransfunc = R_Draw2sMultiPatchTranslucentColumn_8; #ifdef RUSEASM if (R_ASM) { if (R_MMX) { - colfunc = basecolfunc = R_DrawColumn_8_MMX; - //shadecolfunc = R_DrawShadeColumn_8_ASM; - //fuzzcolfunc = R_DrawTranslucentColumn_8_ASM; - walldrawerfunc = R_DrawWallColumn_8_MMX; - twosmultipatchfunc = R_Draw2sMultiPatchColumn_8_MMX; - mmxspanfunc = R_DrawSpan_8_MMX; + colfuncs[BASEDRAWFUNC] = R_DrawColumn_8_MMX; + //colfuncs[COLDRAWFUNC_SHADE] = R_DrawShadeColumn_8_ASM; + //colfuncs[COLDRAWFUNC_FUZZY] = R_DrawTranslucentColumn_8_ASM; + colfuncs[COLDRAWFUNC_TWOSMULTIPATCH] = R_Draw2sMultiPatchColumn_8_MMX; + spanfuncs[SPANDRAWFUNC_MMX] = R_DrawSpan_8_MMX; } else { - colfunc = basecolfunc = R_DrawColumn_8_ASM; - //shadecolfunc = R_DrawShadeColumn_8_ASM; - //fuzzcolfunc = R_DrawTranslucentColumn_8_ASM; - walldrawerfunc = R_DrawWallColumn_8_ASM; - twosmultipatchfunc = R_Draw2sMultiPatchColumn_8_ASM; + colfuncs[BASEDRAWFUNC] = R_DrawColumn_8_ASM; + //colfuncs[COLDRAWFUNC_SHADE] = R_DrawShadeColumn_8_ASM; + //colfuncs[COLDRAWFUNC_FUZZY] = R_DrawTranslucentColumn_8_ASM; + colfuncs[COLDRAWFUNC_TWOSMULTIPATCH] = R_Draw2sMultiPatchColumn_8_ASM; } } #endif @@ -166,8 +174,6 @@ void SCR_SetMode(void) CONS_Alert(CONS_WARNING, M_GetText("Resolution is not aspect-correct!\nUse a multiple of %dx%d\n"), BASEVIDWIDTH, BASEVIDHEIGHT); */ - wallcolfunc = walldrawerfunc; - // set the apprpriate drawer for the sky (tall or INT16) setmodeneeded = 0; } diff --git a/src/screen.h b/src/screen.h index 4a41e5879..ffed931fa 100644 --- a/src/screen.h +++ b/src/screen.h @@ -110,19 +110,48 @@ extern vmode_t specialmodes[NUMSPECIALMODES]; // color mode dependent drawer function pointers // --------------------------------------------- -extern void (*wallcolfunc)(void); +#define BASEDRAWFUNC 0 + +enum +{ + COLDRAWFUNC_BASE = BASEDRAWFUNC, + COLDRAWFUNC_FUZZY, + COLDRAWFUNC_TRANS, + COLDRAWFUNC_SHADE, + COLDRAWFUNC_SHADOWED, + COLDRAWFUNC_TRANSTRANS, + COLDRAWFUNC_TWOSMULTIPATCH, + COLDRAWFUNC_TWOSMULTIPATCHTRANS, + COLDRAWFUNC_FOG, + + COLDRAWFUNC_MAX +}; + extern void (*colfunc)(void); -extern void (*basecolfunc)(void); -extern void (*fuzzcolfunc)(void); -extern void (*transcolfunc)(void); -extern void (*shadecolfunc)(void); +extern void (*colfuncs[COLDRAWFUNC_MAX])(void); + +enum +{ + SPANDRAWFUNC_BASE = BASEDRAWFUNC, + SPANDRAWFUNC_MMX, + SPANDRAWFUNC_TRANS, + SPANDRAWFUNC_SPLAT, + SPANDRAWFUNC_TRANSSPLAT, + SPANDRAWFUNC_FOG, +#ifndef NOWATER + SPANDRAWFUNC_WATER, +#endif +#ifdef ESLOPE + SPANDRAWFUNC_TILTED, + SPANDRAWFUNC_TILTEDTRANS, + SPANDRAWFUNC_TILTEDSPLAT, +#endif + + SPANDRAWFUNC_MAX +}; + extern void (*spanfunc)(void); -extern void (*basespanfunc)(void); -extern void (*mmxspanfunc)(void); -extern void (*splatfunc)(void); -extern void (*transtransfunc)(void); -extern void (*twosmultipatchfunc)(void); -extern void (*twosmultipatchtransfunc)(void); +extern void (*spanfuncs[SPANDRAWFUNC_MAX])(void); // ----- // CPUID @@ -148,9 +177,6 @@ extern consvar_t cv_scr_width, cv_scr_height, cv_scr_depth, cv_renderview, cv_fu // wait for page flipping to end or not extern consvar_t cv_vidwait; -// quick fix for tall/short skies, depending on bytesperpixel -extern void (*walldrawerfunc)(void); - // Change video mode, only at the start of a refresh. void SCR_SetMode(void); // Recalc screen size dependent stuff From 672027996952ff7f7b26ddc01fbf69a521e5a04e Mon Sep 17 00:00:00 2001 From: Jaime Passos Date: Fri, 13 Dec 2019 13:11:56 -0300 Subject: [PATCH 176/746] Separate non-powers-of-two draw routines into its own file --- src/r_draw.c | 1 + src/r_draw.h | 63 +- src/r_draw8.c | 874 ++++++++----------------- src/r_draw8_npo2.c | 845 ++++++++++++++++++++++++ src/r_plane.c | 47 +- src/screen.c | 16 + src/screen.h | 1 + src/sdl/Srb2SDL-vc10.vcxproj | 3 + src/sdl/Srb2SDL-vc10.vcxproj.filters | 3 + src/win32/Srb2win-vc10.vcxproj | 3 + src/win32/Srb2win-vc10.vcxproj.filters | 3 + 11 files changed, 1224 insertions(+), 635 deletions(-) create mode 100644 src/r_draw8_npo2.c diff --git a/src/r_draw.c b/src/r_draw.c index db64805a4..5c91f87e8 100644 --- a/src/r_draw.c +++ b/src/r_draw.c @@ -960,6 +960,7 @@ void R_DrawViewBorder(void) // ========================================================================== #include "r_draw8.c" +#include "r_draw8_npo2.c" // ========================================================================== // INCLUDE 16bpp DRAWING CODE HERE diff --git a/src/r_draw.h b/src/r_draw.h index d7a098f32..95ab80ed2 100644 --- a/src/r_draw.h +++ b/src/r_draw.h @@ -140,6 +140,44 @@ void R_DrawViewBorder(void); void R_DrawColumn_8(void); void R_DrawShadeColumn_8(void); void R_DrawTranslucentColumn_8(void); +void R_DrawTranslatedColumn_8(void); +void R_DrawTranslatedTranslucentColumn_8(void); +void R_Draw2sMultiPatchColumn_8(void); +void R_Draw2sMultiPatchTranslucentColumn_8(void); +void R_DrawFogColumn_8(void); +void R_DrawColumnShadowed_8(void); + +void R_DrawSpan_8(void); +void R_DrawSplat_8(void); +void R_DrawTranslucentSpan_8(void); +void R_DrawTranslucentSplat_8(void); +#ifdef ESLOPE +void R_DrawTiltedSpan_8(void); +void R_DrawTiltedTranslucentSpan_8(void); +void R_DrawTiltedSplat_8(void); +void R_CalcTiltedLighting(fixed_t start, fixed_t end); +extern INT32 tiltlighting[MAXVIDWIDTH]; +#endif +#ifndef NOWATER +void R_DrawTranslucentWaterSpan_8(void); +extern INT32 ds_bgofs; +extern INT32 ds_waterofs; +#endif +void R_DrawFogSpan_8(void); + +// Lactozilla: Non-powers-of-two +void R_DrawSpan_NPO2_8(void); +void R_DrawTranslucentSpan_NPO2_8(void); +void R_DrawSplat_NPO2_8(void); +void R_DrawTranslucentSplat_NPO2_8(void); +#ifdef ESLOPE +void R_DrawTiltedSpan_NPO2_8(void); +void R_DrawTiltedTranslucentSpan_NPO2_8(void); +void R_DrawTiltedSplat_NPO2_8(void); +#endif +#ifndef NOWATER +void R_DrawTranslucentWaterSpan_NPO2_8(void); +#endif #ifdef USEASM void ASMCALL R_DrawColumn_8_ASM(void); @@ -153,31 +191,6 @@ void ASMCALL R_Draw2sMultiPatchColumn_8_MMX(void); void ASMCALL R_DrawSpan_8_MMX(void); #endif -void R_DrawTranslatedColumn_8(void); -void R_DrawTranslatedTranslucentColumn_8(void); -void R_DrawSpan_8(void); -#ifdef ESLOPE -void R_CalcTiltedLighting(fixed_t start, fixed_t end); -void R_DrawTiltedSpan_8(void); -void R_DrawTiltedTranslucentSpan_8(void); -void R_DrawTiltedSplat_8(void); -#endif -void R_DrawSplat_8(void); -void R_DrawTranslucentSplat_8(void); -void R_DrawTranslucentSpan_8(void); -void R_Draw2sMultiPatchColumn_8(void); -void R_Draw2sMultiPatchTranslucentColumn_8(void); -void R_DrawFogSpan_8(void); -void R_DrawFogColumn_8(void); -void R_DrawColumnShadowed_8(void); - -#ifndef NOWATER -void R_DrawTranslucentWaterSpan_8(void); - -extern INT32 ds_bgofs; -extern INT32 ds_waterofs; -#endif - // ------------------ // 16bpp DRAWING CODE // ------------------ diff --git a/src/r_draw8.c b/src/r_draw8.c index db9bc4c3c..a6a400945 100644 --- a/src/r_draw8.c +++ b/src/r_draw8.c @@ -562,11 +562,8 @@ void R_DrawSpan_8 (void) // bit per power of two (obviously) // Ok, because I was able to eliminate the variable spot below, this function is now FASTER // than the original span renderer. Whodathunkit? - if (ds_powersoftwo) - { - xposition <<= nflatshiftup; yposition <<= nflatshiftup; - xstep <<= nflatshiftup; ystep <<= nflatshiftup; - } + xposition <<= nflatshiftup; yposition <<= nflatshiftup; + xstep <<= nflatshiftup; ystep <<= nflatshiftup; source = ds_source; colormap = ds_colormap; @@ -575,82 +572,58 @@ void R_DrawSpan_8 (void) if (dest+8 > deststop) return; - if (!ds_powersoftwo) + while (count >= 8) { - while (count-- && dest <= deststop) - { - fixed_t x = (xposition >> FRACBITS); - fixed_t y = (yposition >> FRACBITS); + // SoM: Why didn't I see this earlier? the spot variable is a waste now because we don't + // have the uber complicated math to calculate it now, so that was a memory write we didn't + // need! + dest[0] = colormap[source[(((UINT32)yposition >> nflatyshift) & nflatmask) | ((UINT32)xposition >> nflatxshift)]]; + xposition += xstep; + yposition += ystep; - // Carefully align all of my Friends. - if (x < 0) - x = ds_flatwidth - ((UINT32)(ds_flatwidth - x) % ds_flatwidth); - if (y < 0) - y = ds_flatheight - ((UINT32)(ds_flatheight - y) % ds_flatheight); + dest[1] = colormap[source[(((UINT32)yposition >> nflatyshift) & nflatmask) | ((UINT32)xposition >> nflatxshift)]]; + xposition += xstep; + yposition += ystep; - x %= ds_flatwidth; - y %= ds_flatheight; + dest[2] = colormap[source[(((UINT32)yposition >> nflatyshift) & nflatmask) | ((UINT32)xposition >> nflatxshift)]]; + xposition += xstep; + yposition += ystep; - *dest++ = colormap[source[((y * ds_flatwidth) + x)]]; - xposition += xstep; - yposition += ystep; - } + dest[3] = colormap[source[(((UINT32)yposition >> nflatyshift) & nflatmask) | ((UINT32)xposition >> nflatxshift)]]; + xposition += xstep; + yposition += ystep; + + dest[4] = colormap[source[(((UINT32)yposition >> nflatyshift) & nflatmask) | ((UINT32)xposition >> nflatxshift)]]; + xposition += xstep; + yposition += ystep; + + dest[5] = colormap[source[(((UINT32)yposition >> nflatyshift) & nflatmask) | ((UINT32)xposition >> nflatxshift)]]; + xposition += xstep; + yposition += ystep; + + dest[6] = colormap[source[(((UINT32)yposition >> nflatyshift) & nflatmask) | ((UINT32)xposition >> nflatxshift)]]; + xposition += xstep; + yposition += ystep; + + dest[7] = colormap[source[(((UINT32)yposition >> nflatyshift) & nflatmask) | ((UINT32)xposition >> nflatxshift)]]; + xposition += xstep; + yposition += ystep; + + dest += 8; + count -= 8; } - else + while (count-- && dest <= deststop) { - while (count >= 8) - { - // SoM: Why didn't I see this earlier? the spot variable is a waste now because we don't - // have the uber complicated math to calculate it now, so that was a memory write we didn't - // need! - dest[0] = colormap[source[(((UINT32)yposition >> nflatyshift) & nflatmask) | ((UINT32)xposition >> nflatxshift)]]; - xposition += xstep; - yposition += ystep; - - dest[1] = colormap[source[(((UINT32)yposition >> nflatyshift) & nflatmask) | ((UINT32)xposition >> nflatxshift)]]; - xposition += xstep; - yposition += ystep; - - dest[2] = colormap[source[(((UINT32)yposition >> nflatyshift) & nflatmask) | ((UINT32)xposition >> nflatxshift)]]; - xposition += xstep; - yposition += ystep; - - dest[3] = colormap[source[(((UINT32)yposition >> nflatyshift) & nflatmask) | ((UINT32)xposition >> nflatxshift)]]; - xposition += xstep; - yposition += ystep; - - dest[4] = colormap[source[(((UINT32)yposition >> nflatyshift) & nflatmask) | ((UINT32)xposition >> nflatxshift)]]; - xposition += xstep; - yposition += ystep; - - dest[5] = colormap[source[(((UINT32)yposition >> nflatyshift) & nflatmask) | ((UINT32)xposition >> nflatxshift)]]; - xposition += xstep; - yposition += ystep; - - dest[6] = colormap[source[(((UINT32)yposition >> nflatyshift) & nflatmask) | ((UINT32)xposition >> nflatxshift)]]; - xposition += xstep; - yposition += ystep; - - dest[7] = colormap[source[(((UINT32)yposition >> nflatyshift) & nflatmask) | ((UINT32)xposition >> nflatxshift)]]; - xposition += xstep; - yposition += ystep; - - dest += 8; - count -= 8; - } - while (count-- && dest <= deststop) - { - *dest++ = colormap[source[(((UINT32)yposition >> nflatyshift) & nflatmask) | ((UINT32)xposition >> nflatxshift)]]; - xposition += xstep; - yposition += ystep; - } + *dest++ = colormap[source[(((UINT32)yposition >> nflatyshift) & nflatmask) | ((UINT32)xposition >> nflatxshift)]]; + xposition += xstep; + yposition += ystep; } } #ifdef ESLOPE // R_CalcTiltedLighting // Exactly what it says on the tin. I wish I wasn't too lazy to explain things properly. -static INT32 tiltlighting[MAXVIDWIDTH]; +INT32 tiltlighting[MAXVIDWIDTH]; void R_CalcTiltedLighting(fixed_t start, fixed_t end) { // ZDoom uses a different lighting setup to us, and I couldn't figure out how to adapt their version @@ -724,24 +697,7 @@ void R_DrawTiltedSpan_8(void) colormap = planezlight[tiltlighting[ds_x1++]] + (ds_colormap - colormaps); - if (!ds_powersoftwo) - { - fixed_t x = (((fixed_t)u-viewx) >> FRACBITS); - fixed_t y = (((fixed_t)v-viewy) >> FRACBITS); - - // Carefully align all of my Friends. - if (x < 0) - x = ds_flatwidth - ((UINT32)(ds_flatwidth - x) % ds_flatwidth); - if (y < 0) - y = ds_flatheight - ((UINT32)(ds_flatheight - y) % ds_flatheight); - - x %= ds_flatwidth; - y %= ds_flatheight; - - *dest = colormap[source[((y * ds_flatwidth) + x)]]; - } - else - *dest = colormap[source[((v >> nflatyshift) & nflatmask) | (u >> nflatxshift)]]; + *dest = colormap[source[((v >> nflatyshift) & nflatmask) | (u >> nflatxshift)]]; dest++; iz += ds_sz.x; uz += ds_su.x; @@ -778,24 +734,7 @@ void R_DrawTiltedSpan_8(void) for (i = SPANSIZE-1; i >= 0; i--) { colormap = planezlight[tiltlighting[ds_x1++]] + (ds_colormap - colormaps); - if (!ds_powersoftwo) - { - fixed_t x = (((fixed_t)u-viewx) >> FRACBITS); - fixed_t y = (((fixed_t)v-viewy) >> FRACBITS); - - // Carefully align all of my Friends. - if (x < 0) - x = ds_flatwidth - ((UINT32)(ds_flatwidth - x) % ds_flatwidth); - if (y < 0) - y = ds_flatheight - ((UINT32)(ds_flatheight - y) % ds_flatheight); - - x %= ds_flatwidth; - y %= ds_flatheight; - - *dest = colormap[source[((y * ds_flatwidth) + x)]]; - } - else - *dest = colormap[source[((v >> nflatyshift) & nflatmask) | (u >> nflatxshift)]]; + *dest = colormap[source[((v >> nflatyshift) & nflatmask) | (u >> nflatxshift)]]; dest++; u += stepu; v += stepv; @@ -811,24 +750,7 @@ void R_DrawTiltedSpan_8(void) u = (INT64)(startu); v = (INT64)(startv); colormap = planezlight[tiltlighting[ds_x1++]] + (ds_colormap - colormaps); - if (!ds_powersoftwo) - { - fixed_t x = (((fixed_t)u-viewx) >> FRACBITS); - fixed_t y = (((fixed_t)v-viewy) >> FRACBITS); - - // Carefully align all of my Friends. - if (x < 0) - x = ds_flatwidth - ((UINT32)(ds_flatwidth - x) % ds_flatwidth); - if (y < 0) - y = ds_flatheight - ((UINT32)(ds_flatheight - y) % ds_flatheight); - - x %= ds_flatwidth; - y %= ds_flatheight; - - *dest = colormap[source[((y * ds_flatwidth) + x)]]; - } - else - *dest = colormap[source[((v >> nflatyshift) & nflatmask) | (u >> nflatxshift)]]; + *dest = colormap[source[((v >> nflatyshift) & nflatmask) | (u >> nflatxshift)]]; } else { @@ -849,24 +771,7 @@ void R_DrawTiltedSpan_8(void) for (; width != 0; width--) { colormap = planezlight[tiltlighting[ds_x1++]] + (ds_colormap - colormaps); - if (!ds_powersoftwo) - { - fixed_t x = (((fixed_t)u-viewx) >> FRACBITS); - fixed_t y = (((fixed_t)v-viewy) >> FRACBITS); - - // Carefully align all of my Friends. - if (x < 0) - x = ds_flatwidth - ((UINT32)(ds_flatwidth - x) % ds_flatwidth); - if (y < 0) - y = ds_flatheight - ((UINT32)(ds_flatheight - y) % ds_flatheight); - - x %= ds_flatwidth; - y %= ds_flatheight; - - *dest = colormap[source[((y * ds_flatwidth) + x)]]; - } - else - *dest = colormap[source[((v >> nflatyshift) & nflatmask) | (u >> nflatxshift)]]; + *dest = colormap[source[((v >> nflatyshift) & nflatmask) | (u >> nflatxshift)]]; dest++; u += stepu; v += stepv; @@ -927,24 +832,7 @@ void R_DrawTiltedTranslucentSpan_8(void) v = (INT64)(vz*z) + viewy; colormap = planezlight[tiltlighting[ds_x1++]] + (ds_colormap - colormaps); - if (!ds_powersoftwo) - { - fixed_t x = (((fixed_t)u-viewx) >> FRACBITS); - fixed_t y = (((fixed_t)v-viewy) >> FRACBITS); - - // Carefully align all of my Friends. - if (x < 0) - x = ds_flatwidth - ((UINT32)(ds_flatwidth - x) % ds_flatwidth); - if (y < 0) - y = ds_flatheight - ((UINT32)(ds_flatheight - y) % ds_flatheight); - - x %= ds_flatwidth; - y %= ds_flatheight; - - *dest = *(ds_transmap + (colormap[source[((y * ds_flatwidth) + x)]] << 8) + *dest); - } - else - *dest = *(ds_transmap + (colormap[source[((v >> nflatyshift) & nflatmask) | (u >> nflatxshift)]] << 8) + *dest); + *dest = *(ds_transmap + (colormap[source[((v >> nflatyshift) & nflatmask) | (u >> nflatxshift)]] << 8) + *dest); dest++; iz += ds_sz.x; uz += ds_su.x; @@ -981,24 +869,7 @@ void R_DrawTiltedTranslucentSpan_8(void) for (i = SPANSIZE-1; i >= 0; i--) { colormap = planezlight[tiltlighting[ds_x1++]] + (ds_colormap - colormaps); - if (!ds_powersoftwo) - { - fixed_t x = (((fixed_t)u-viewx) >> FRACBITS); - fixed_t y = (((fixed_t)v-viewy) >> FRACBITS); - - // Carefully align all of my Friends. - if (x < 0) - x = ds_flatwidth - ((UINT32)(ds_flatwidth - x) % ds_flatwidth); - if (y < 0) - y = ds_flatheight - ((UINT32)(ds_flatheight - y) % ds_flatheight); - - x %= ds_flatwidth; - y %= ds_flatheight; - - *dest = *(ds_transmap + (colormap[source[((y * ds_flatwidth) + x)]] << 8) + *dest); - } - else - *dest = *(ds_transmap + (colormap[source[((v >> nflatyshift) & nflatmask) | (u >> nflatxshift)]] << 8) + *dest); + *dest = *(ds_transmap + (colormap[source[((v >> nflatyshift) & nflatmask) | (u >> nflatxshift)]] << 8) + *dest); dest++; u += stepu; v += stepv; @@ -1014,24 +885,7 @@ void R_DrawTiltedTranslucentSpan_8(void) u = (INT64)(startu); v = (INT64)(startv); colormap = planezlight[tiltlighting[ds_x1++]] + (ds_colormap - colormaps); - if (!ds_powersoftwo) - { - fixed_t x = (((fixed_t)u-viewx) >> FRACBITS); - fixed_t y = (((fixed_t)v-viewy) >> FRACBITS); - - // Carefully align all of my Friends. - if (x < 0) - x = ds_flatwidth - ((UINT32)(ds_flatwidth - x) % ds_flatwidth); - if (y < 0) - y = ds_flatheight - ((UINT32)(ds_flatheight - y) % ds_flatheight); - - x %= ds_flatwidth; - y %= ds_flatheight; - - *dest = *(ds_transmap + (colormap[source[((y * ds_flatwidth) + x)]] << 8) + *dest); - } - else - *dest = *(ds_transmap + (colormap[source[((v >> nflatyshift) & nflatmask) | (u >> nflatxshift)]] << 8) + *dest); + *dest = *(ds_transmap + (colormap[source[((v >> nflatyshift) & nflatmask) | (u >> nflatxshift)]] << 8) + *dest); } else { @@ -1052,24 +906,7 @@ void R_DrawTiltedTranslucentSpan_8(void) for (; width != 0; width--) { colormap = planezlight[tiltlighting[ds_x1++]] + (ds_colormap - colormaps); - if (!ds_powersoftwo) - { - fixed_t x = (((fixed_t)u-viewx) >> FRACBITS); - fixed_t y = (((fixed_t)v-viewy) >> FRACBITS); - - // Carefully align all of my Friends. - if (x < 0) - x = ds_flatwidth - ((UINT32)(ds_flatwidth - x) % ds_flatwidth); - if (y < 0) - y = ds_flatheight - ((UINT32)(ds_flatheight - y) % ds_flatheight); - - x %= ds_flatwidth; - y %= ds_flatheight; - - *dest = *(ds_transmap + (colormap[source[((y * ds_flatwidth) + x)]] << 8) + *dest); - } - else - *dest = *(ds_transmap + (colormap[source[((v >> nflatyshift) & nflatmask) | (u >> nflatxshift)]] << 8) + *dest); + *dest = *(ds_transmap + (colormap[source[((v >> nflatyshift) & nflatmask) | (u >> nflatxshift)]] << 8) + *dest); dest++; u += stepu; v += stepv; @@ -1130,25 +967,7 @@ void R_DrawTiltedSplat_8(void) colormap = planezlight[tiltlighting[ds_x1++]] + (ds_colormap - colormaps); - if (!ds_powersoftwo) - { - fixed_t x = (((fixed_t)u-viewx) >> FRACBITS); - fixed_t y = (((fixed_t)v-viewy) >> FRACBITS); - - // Carefully align all of my Friends. - if (x < 0) - x = ds_flatwidth - ((UINT32)(ds_flatwidth - x) % ds_flatwidth); - if (y < 0) - y = ds_flatheight - ((UINT32)(ds_flatheight - y) % ds_flatheight); - - x %= ds_flatwidth; - y %= ds_flatheight; - - val = source[((y * ds_flatwidth) + x)]; - } - else - val = source[((v >> nflatyshift) & nflatmask) | (u >> nflatxshift)]; - + val = source[((v >> nflatyshift) & nflatmask) | (u >> nflatxshift)]; if (val != TRANSPARENTPIXEL) *dest = colormap[val]; @@ -1188,24 +1007,7 @@ void R_DrawTiltedSplat_8(void) for (i = SPANSIZE-1; i >= 0; i--) { colormap = planezlight[tiltlighting[ds_x1++]] + (ds_colormap - colormaps); - if (!ds_powersoftwo) - { - fixed_t x = (((fixed_t)u-viewx) >> FRACBITS); - fixed_t y = (((fixed_t)v-viewy) >> FRACBITS); - - // Carefully align all of my Friends. - if (x < 0) - x = ds_flatwidth - ((UINT32)(ds_flatwidth - x) % ds_flatwidth); - if (y < 0) - y = ds_flatheight - ((UINT32)(ds_flatheight - y) % ds_flatheight); - - x %= ds_flatwidth; - y %= ds_flatheight; - - val = source[((y * ds_flatwidth) + x)]; - } - else - val = source[((v >> nflatyshift) & nflatmask) | (u >> nflatxshift)]; + val = source[((v >> nflatyshift) & nflatmask) | (u >> nflatxshift)]; if (val != TRANSPARENTPIXEL) *dest = colormap[val]; dest++; @@ -1223,24 +1025,7 @@ void R_DrawTiltedSplat_8(void) u = (INT64)(startu); v = (INT64)(startv); colormap = planezlight[tiltlighting[ds_x1++]] + (ds_colormap - colormaps); - if (!ds_powersoftwo) - { - fixed_t x = (((fixed_t)u-viewx) >> FRACBITS); - fixed_t y = (((fixed_t)v-viewy) >> FRACBITS); - - // Carefully align all of my Friends. - if (x < 0) - x = ds_flatwidth - ((UINT32)(ds_flatwidth - x) % ds_flatwidth); - if (y < 0) - y = ds_flatheight - ((UINT32)(ds_flatheight - y) % ds_flatheight); - - x %= ds_flatwidth; - y %= ds_flatheight; - - val = source[((y * ds_flatwidth) + x)]; - } - else - val = source[((v >> nflatyshift) & nflatmask) | (u >> nflatxshift)]; + val = source[((v >> nflatyshift) & nflatmask) | (u >> nflatxshift)]; if (val != TRANSPARENTPIXEL) *dest = colormap[val]; } @@ -1264,24 +1049,6 @@ void R_DrawTiltedSplat_8(void) { colormap = planezlight[tiltlighting[ds_x1++]] + (ds_colormap - colormaps); val = source[((v >> nflatyshift) & nflatmask) | (u >> nflatxshift)]; - if (!ds_powersoftwo) - { - fixed_t x = (((fixed_t)u-viewx) >> FRACBITS); - fixed_t y = (((fixed_t)v-viewy) >> FRACBITS); - - // Carefully align all of my Friends. - if (x < 0) - x = ds_flatwidth - ((UINT32)(ds_flatwidth - x) % ds_flatwidth); - if (y < 0) - y = ds_flatheight - ((UINT32)(ds_flatheight - y) % ds_flatheight); - - x %= ds_flatwidth; - y %= ds_flatheight; - - val = source[((y * ds_flatwidth) + x)]; - } - else - val = source[((v >> nflatyshift) & nflatmask) | (u >> nflatxshift)]; if (val != TRANSPARENTPIXEL) *dest = colormap[val]; dest++; @@ -1321,125 +1088,95 @@ void R_DrawSplat_8 (void) // bit per power of two (obviously) // Ok, because I was able to eliminate the variable spot below, this function is now FASTER // than the original span renderer. Whodathunkit? - if (ds_powersoftwo) - { - xposition <<= nflatshiftup; yposition <<= nflatshiftup; - xstep <<= nflatshiftup; ystep <<= nflatshiftup; - } + xposition <<= nflatshiftup; yposition <<= nflatshiftup; + xstep <<= nflatshiftup; ystep <<= nflatshiftup; source = ds_source; colormap = ds_colormap; dest = ylookup[ds_y] + columnofs[ds_x1]; - if (!ds_powersoftwo) + while (count >= 8) { - while (count-- && dest <= deststop) - { - fixed_t x = (xposition >> FRACBITS); - fixed_t y = (yposition >> FRACBITS); + // SoM: Why didn't I see this earlier? the spot variable is a waste now because we don't + // have the uber complicated math to calculate it now, so that was a memory write we didn't + // need! + // + // 4194303 = (2048x2048)-1 (2048x2048 is maximum flat size) + val = (((UINT32)yposition >> nflatyshift) & nflatmask) | ((UINT32)xposition >> nflatxshift); + val &= 4194303; + val = source[val]; + if (val != TRANSPARENTPIXEL) + dest[0] = colormap[val]; + xposition += xstep; + yposition += ystep; - // Carefully align all of my Friends. - if (x < 0) - x = ds_flatwidth - ((UINT32)(ds_flatwidth - x) % ds_flatwidth); - if (y < 0) - y = ds_flatheight - ((UINT32)(ds_flatheight - y) % ds_flatheight); + val = (((UINT32)yposition >> nflatyshift) & nflatmask) | ((UINT32)xposition >> nflatxshift); + val &= 4194303; + val = source[val]; + if (val != TRANSPARENTPIXEL) + dest[1] = colormap[val]; + xposition += xstep; + yposition += ystep; - x %= ds_flatwidth; - y %= ds_flatheight; + val = (((UINT32)yposition >> nflatyshift) & nflatmask) | ((UINT32)xposition >> nflatxshift); + val &= 4194303; + val = source[val]; + if (val != TRANSPARENTPIXEL) + dest[2] = colormap[val]; + xposition += xstep; + yposition += ystep; - val = source[((y * ds_flatwidth) + x)]; - if (val != TRANSPARENTPIXEL) - *dest = colormap[val]; - dest++; - xposition += xstep; - yposition += ystep; - } + val = (((UINT32)yposition >> nflatyshift) & nflatmask) | ((UINT32)xposition >> nflatxshift); + val &= 4194303; + val = source[val]; + if (val != TRANSPARENTPIXEL) + dest[3] = colormap[val]; + xposition += xstep; + yposition += ystep; + + val = (((UINT32)yposition >> nflatyshift) & nflatmask) | ((UINT32)xposition >> nflatxshift); + val &= 4194303; + val = source[val]; + if (val != TRANSPARENTPIXEL) + dest[4] = colormap[val]; + xposition += xstep; + yposition += ystep; + + val = (((UINT32)yposition >> nflatyshift) & nflatmask) | ((UINT32)xposition >> nflatxshift); + val &= 4194303; + val = source[val]; + if (val != TRANSPARENTPIXEL) + dest[5] = colormap[val]; + xposition += xstep; + yposition += ystep; + + val = (((UINT32)yposition >> nflatyshift) & nflatmask) | ((UINT32)xposition >> nflatxshift); + val &= 4194303; + val = source[val]; + if (val != TRANSPARENTPIXEL) + dest[6] = colormap[val]; + xposition += xstep; + yposition += ystep; + + val = (((UINT32)yposition >> nflatyshift) & nflatmask) | ((UINT32)xposition >> nflatxshift); + val &= 4194303; + val = source[val]; + if (val != TRANSPARENTPIXEL) + dest[7] = colormap[val]; + xposition += xstep; + yposition += ystep; + + dest += 8; + count -= 8; } - else + while (count-- && dest <= deststop) { - while (count >= 8) - { - // SoM: Why didn't I see this earlier? the spot variable is a waste now because we don't - // have the uber complicated math to calculate it now, so that was a memory write we didn't - // need! - // - // 4194303 = (2048x2048)-1 (2048x2048 is maximum flat size) - val = (((UINT32)yposition >> nflatyshift) & nflatmask) | ((UINT32)xposition >> nflatxshift); - val &= 4194303; - val = source[val]; - if (val != TRANSPARENTPIXEL) - dest[0] = colormap[val]; - xposition += xstep; - yposition += ystep; - - val = (((UINT32)yposition >> nflatyshift) & nflatmask) | ((UINT32)xposition >> nflatxshift); - val &= 4194303; - val = source[val]; - if (val != TRANSPARENTPIXEL) - dest[1] = colormap[val]; - xposition += xstep; - yposition += ystep; - - val = (((UINT32)yposition >> nflatyshift) & nflatmask) | ((UINT32)xposition >> nflatxshift); - val &= 4194303; - val = source[val]; - if (val != TRANSPARENTPIXEL) - dest[2] = colormap[val]; - xposition += xstep; - yposition += ystep; - - val = (((UINT32)yposition >> nflatyshift) & nflatmask) | ((UINT32)xposition >> nflatxshift); - val &= 4194303; - val = source[val]; - if (val != TRANSPARENTPIXEL) - dest[3] = colormap[val]; - xposition += xstep; - yposition += ystep; - - val = (((UINT32)yposition >> nflatyshift) & nflatmask) | ((UINT32)xposition >> nflatxshift); - val &= 4194303; - val = source[val]; - if (val != TRANSPARENTPIXEL) - dest[4] = colormap[val]; - xposition += xstep; - yposition += ystep; - - val = (((UINT32)yposition >> nflatyshift) & nflatmask) | ((UINT32)xposition >> nflatxshift); - val &= 4194303; - val = source[val]; - if (val != TRANSPARENTPIXEL) - dest[5] = colormap[val]; - xposition += xstep; - yposition += ystep; - - val = (((UINT32)yposition >> nflatyshift) & nflatmask) | ((UINT32)xposition >> nflatxshift); - val &= 4194303; - val = source[val]; - if (val != TRANSPARENTPIXEL) - dest[6] = colormap[val]; - xposition += xstep; - yposition += ystep; - - val = (((UINT32)yposition >> nflatyshift) & nflatmask) | ((UINT32)xposition >> nflatxshift); - val &= 4194303; - val = source[val]; - if (val != TRANSPARENTPIXEL) - dest[7] = colormap[val]; - xposition += xstep; - yposition += ystep; - - dest += 8; - count -= 8; - } - while (count-- && dest <= deststop) - { - val = source[(((UINT32)yposition >> nflatyshift) & nflatmask) | ((UINT32)xposition >> nflatxshift)]; - if (val != TRANSPARENTPIXEL) - *dest = colormap[val]; - dest++; - xposition += xstep; - yposition += ystep; - } + val = source[(((UINT32)yposition >> nflatyshift) & nflatmask) | ((UINT32)xposition >> nflatxshift)]; + if (val != TRANSPARENTPIXEL) + *dest = colormap[val]; + dest++; + xposition += xstep; + yposition += ystep; } } @@ -1470,112 +1207,82 @@ void R_DrawTranslucentSplat_8 (void) // bit per power of two (obviously) // Ok, because I was able to eliminate the variable spot below, this function is now FASTER // than the original span renderer. Whodathunkit? - if (ds_powersoftwo) - { - xposition <<= nflatshiftup; yposition <<= nflatshiftup; - xstep <<= nflatshiftup; ystep <<= nflatshiftup; - } + xposition <<= nflatshiftup; yposition <<= nflatshiftup; + xstep <<= nflatshiftup; ystep <<= nflatshiftup; source = ds_source; colormap = ds_colormap; dest = ylookup[ds_y] + columnofs[ds_x1]; - if (!ds_powersoftwo) + while (count >= 8) { - while (count-- && dest <= deststop) - { - fixed_t x = (xposition >> FRACBITS); - fixed_t y = (yposition >> FRACBITS); + // SoM: Why didn't I see this earlier? the spot variable is a waste now because we don't + // have the uber complicated math to calculate it now, so that was a memory write we didn't + // need! + val = source[(((UINT32)yposition >> nflatyshift) & nflatmask) | ((UINT32)xposition >> nflatxshift)]; + if (val != TRANSPARENTPIXEL) + dest[0] = *(ds_transmap + (colormap[val] << 8) + dest[0]); + xposition += xstep; + yposition += ystep; - // Carefully align all of my Friends. - if (x < 0) - x = ds_flatwidth - ((UINT32)(ds_flatwidth - x) % ds_flatwidth); - if (y < 0) - y = ds_flatheight - ((UINT32)(ds_flatheight - y) % ds_flatheight); + val = source[(((UINT32)yposition >> nflatyshift) & nflatmask) | ((UINT32)xposition >> nflatxshift)]; + if (val != TRANSPARENTPIXEL) + dest[1] = *(ds_transmap + (colormap[val] << 8) + dest[1]); + xposition += xstep; + yposition += ystep; - x %= ds_flatwidth; - y %= ds_flatheight; + val = source[(((UINT32)yposition >> nflatyshift) & nflatmask) | ((UINT32)xposition >> nflatxshift)]; + if (val != TRANSPARENTPIXEL) + dest[2] = *(ds_transmap + (colormap[val] << 8) + dest[2]); + xposition += xstep; + yposition += ystep; - val = source[((y * ds_flatwidth) + x)]; - if (val != TRANSPARENTPIXEL) - *dest = *(ds_transmap + (colormap[val] << 8) + *dest); - dest++; - xposition += xstep; - yposition += ystep; - } + val = source[(((UINT32)yposition >> nflatyshift) & nflatmask) | ((UINT32)xposition >> nflatxshift)]; + if (val != TRANSPARENTPIXEL) + dest[3] = *(ds_transmap + (colormap[val] << 8) + dest[3]); + xposition += xstep; + yposition += ystep; + + val = source[(((UINT32)yposition >> nflatyshift) & nflatmask) | ((UINT32)xposition >> nflatxshift)]; + if (val != TRANSPARENTPIXEL) + dest[4] = *(ds_transmap + (colormap[val] << 8) + dest[4]); + xposition += xstep; + yposition += ystep; + + val = source[(((UINT32)yposition >> nflatyshift) & nflatmask) | ((UINT32)xposition >> nflatxshift)]; + if (val != TRANSPARENTPIXEL) + dest[5] = *(ds_transmap + (colormap[val] << 8) + dest[5]); + xposition += xstep; + yposition += ystep; + + val = source[(((UINT32)yposition >> nflatyshift) & nflatmask) | ((UINT32)xposition >> nflatxshift)]; + if (val != TRANSPARENTPIXEL) + dest[6] = *(ds_transmap + (colormap[val] << 8) + dest[6]); + xposition += xstep; + yposition += ystep; + + val = source[(((UINT32)yposition >> nflatyshift) & nflatmask) | ((UINT32)xposition >> nflatxshift)]; + if (val != TRANSPARENTPIXEL) + dest[7] = *(ds_transmap + (colormap[val] << 8) + dest[7]); + xposition += xstep; + yposition += ystep; + + dest += 8; + count -= 8; } - else + while (count-- && dest <= deststop) { - while (count >= 8) - { - // SoM: Why didn't I see this earlier? the spot variable is a waste now because we don't - // have the uber complicated math to calculate it now, so that was a memory write we didn't - // need! - val = source[(((UINT32)yposition >> nflatyshift) & nflatmask) | ((UINT32)xposition >> nflatxshift)]; - if (val != TRANSPARENTPIXEL) - dest[0] = *(ds_transmap + (colormap[val] << 8) + dest[0]); - xposition += xstep; - yposition += ystep; - - val = source[(((UINT32)yposition >> nflatyshift) & nflatmask) | ((UINT32)xposition >> nflatxshift)]; - if (val != TRANSPARENTPIXEL) - dest[1] = *(ds_transmap + (colormap[val] << 8) + dest[1]); - xposition += xstep; - yposition += ystep; - - val = source[(((UINT32)yposition >> nflatyshift) & nflatmask) | ((UINT32)xposition >> nflatxshift)]; - if (val != TRANSPARENTPIXEL) - dest[2] = *(ds_transmap + (colormap[val] << 8) + dest[2]); - xposition += xstep; - yposition += ystep; - - val = source[(((UINT32)yposition >> nflatyshift) & nflatmask) | ((UINT32)xposition >> nflatxshift)]; - if (val != TRANSPARENTPIXEL) - dest[3] = *(ds_transmap + (colormap[val] << 8) + dest[3]); - xposition += xstep; - yposition += ystep; - - val = source[(((UINT32)yposition >> nflatyshift) & nflatmask) | ((UINT32)xposition >> nflatxshift)]; - if (val != TRANSPARENTPIXEL) - dest[4] = *(ds_transmap + (colormap[val] << 8) + dest[4]); - xposition += xstep; - yposition += ystep; - - val = source[(((UINT32)yposition >> nflatyshift) & nflatmask) | ((UINT32)xposition >> nflatxshift)]; - if (val != TRANSPARENTPIXEL) - dest[5] = *(ds_transmap + (colormap[val] << 8) + dest[5]); - xposition += xstep; - yposition += ystep; - - val = source[(((UINT32)yposition >> nflatyshift) & nflatmask) | ((UINT32)xposition >> nflatxshift)]; - if (val != TRANSPARENTPIXEL) - dest[6] = *(ds_transmap + (colormap[val] << 8) + dest[6]); - xposition += xstep; - yposition += ystep; - - val = source[(((UINT32)yposition >> nflatyshift) & nflatmask) | ((UINT32)xposition >> nflatxshift)]; - if (val != TRANSPARENTPIXEL) - dest[7] = *(ds_transmap + (colormap[val] << 8) + dest[7]); - xposition += xstep; - yposition += ystep; - - dest += 8; - count -= 8; - } - while (count-- && dest <= deststop) - { - val = source[(((UINT32)yposition >> nflatyshift) & nflatmask) | ((UINT32)xposition >> nflatxshift)]; - if (val != TRANSPARENTPIXEL) - *dest = *(ds_transmap + (colormap[val] << 8) + *dest); - dest++; - xposition += xstep; - yposition += ystep; - } + val = source[(((UINT32)yposition >> nflatyshift) & nflatmask) | ((UINT32)xposition >> nflatxshift)]; + if (val != TRANSPARENTPIXEL) + *dest = *(ds_transmap + (colormap[val] << 8) + *dest); + dest++; + xposition += xstep; + yposition += ystep; } } /** \brief The R_DrawTranslucentSpan_8 function - Draws the actual span with translucent. + Draws the actual span with translucency. */ void R_DrawTranslucentSpan_8 (void) { @@ -1601,109 +1308,76 @@ void R_DrawTranslucentSpan_8 (void) // bit per power of two (obviously) // Ok, because I was able to eliminate the variable spot below, this function is now FASTER // than the original span renderer. Whodathunkit? - if (ds_powersoftwo) - { - xposition <<= nflatshiftup; yposition <<= nflatshiftup; - xstep <<= nflatshiftup; ystep <<= nflatshiftup; - } + xposition <<= nflatshiftup; yposition <<= nflatshiftup; + xstep <<= nflatshiftup; ystep <<= nflatshiftup; source = ds_source; colormap = ds_colormap; dest = ylookup[ds_y] + columnofs[ds_x1]; - if (!ds_powersoftwo) + while (count >= 8) { - while (count-- && dest <= deststop) - { - fixed_t x = (xposition >> FRACBITS); - fixed_t y = (yposition >> FRACBITS); + // SoM: Why didn't I see this earlier? the spot variable is a waste now because we don't + // have the uber complicated math to calculate it now, so that was a memory write we didn't + // need! + dest[0] = *(ds_transmap + (colormap[source[(((UINT32)yposition >> nflatyshift) & nflatmask) | ((UINT32)xposition >> nflatxshift)]] << 8) + dest[0]); + xposition += xstep; + yposition += ystep; - // Carefully align all of my Friends. - if (x < 0) - x = ds_flatwidth - ((UINT32)(ds_flatwidth - x) % ds_flatwidth); - if (y < 0) - y = ds_flatheight - ((UINT32)(ds_flatheight - y) % ds_flatheight); + dest[1] = *(ds_transmap + (colormap[source[(((UINT32)yposition >> nflatyshift) & nflatmask) | ((UINT32)xposition >> nflatxshift)]] << 8) + dest[1]); + xposition += xstep; + yposition += ystep; - x %= ds_flatwidth; - y %= ds_flatheight; + dest[2] = *(ds_transmap + (colormap[source[(((UINT32)yposition >> nflatyshift) & nflatmask) | ((UINT32)xposition >> nflatxshift)]] << 8) + dest[2]); + xposition += xstep; + yposition += ystep; - val = ((y * ds_flatwidth) + x); - *dest = *(ds_transmap + (colormap[source[val]] << 8) + *dest); - dest++; - xposition += xstep; - yposition += ystep; - } + dest[3] = *(ds_transmap + (colormap[source[(((UINT32)yposition >> nflatyshift) & nflatmask) | ((UINT32)xposition >> nflatxshift)]] << 8) + dest[3]); + xposition += xstep; + yposition += ystep; + + dest[4] = *(ds_transmap + (colormap[source[(((UINT32)yposition >> nflatyshift) & nflatmask) | ((UINT32)xposition >> nflatxshift)]] << 8) + dest[4]); + xposition += xstep; + yposition += ystep; + + dest[5] = *(ds_transmap + (colormap[source[(((UINT32)yposition >> nflatyshift) & nflatmask) | ((UINT32)xposition >> nflatxshift)]] << 8) + dest[5]); + xposition += xstep; + yposition += ystep; + + dest[6] = *(ds_transmap + (colormap[source[(((UINT32)yposition >> nflatyshift) & nflatmask) | ((UINT32)xposition >> nflatxshift)]] << 8) + dest[6]); + xposition += xstep; + yposition += ystep; + + dest[7] = *(ds_transmap + (colormap[source[(((UINT32)yposition >> nflatyshift) & nflatmask) | ((UINT32)xposition >> nflatxshift)]] << 8) + dest[7]); + xposition += xstep; + yposition += ystep; + + dest += 8; + count -= 8; } - else + while (count-- && dest <= deststop) { - while (count >= 8) - { - // SoM: Why didn't I see this earlier? the spot variable is a waste now because we don't - // have the uber complicated math to calculate it now, so that was a memory write we didn't - // need! - dest[0] = *(ds_transmap + (colormap[source[(((UINT32)yposition >> nflatyshift) & nflatmask) | ((UINT32)xposition >> nflatxshift)]] << 8) + dest[0]); - xposition += xstep; - yposition += ystep; - - dest[1] = *(ds_transmap + (colormap[source[(((UINT32)yposition >> nflatyshift) & nflatmask) | ((UINT32)xposition >> nflatxshift)]] << 8) + dest[1]); - xposition += xstep; - yposition += ystep; - - dest[2] = *(ds_transmap + (colormap[source[(((UINT32)yposition >> nflatyshift) & nflatmask) | ((UINT32)xposition >> nflatxshift)]] << 8) + dest[2]); - xposition += xstep; - yposition += ystep; - - dest[3] = *(ds_transmap + (colormap[source[(((UINT32)yposition >> nflatyshift) & nflatmask) | ((UINT32)xposition >> nflatxshift)]] << 8) + dest[3]); - xposition += xstep; - yposition += ystep; - - dest[4] = *(ds_transmap + (colormap[source[(((UINT32)yposition >> nflatyshift) & nflatmask) | ((UINT32)xposition >> nflatxshift)]] << 8) + dest[4]); - xposition += xstep; - yposition += ystep; - - dest[5] = *(ds_transmap + (colormap[source[(((UINT32)yposition >> nflatyshift) & nflatmask) | ((UINT32)xposition >> nflatxshift)]] << 8) + dest[5]); - xposition += xstep; - yposition += ystep; - - dest[6] = *(ds_transmap + (colormap[source[(((UINT32)yposition >> nflatyshift) & nflatmask) | ((UINT32)xposition >> nflatxshift)]] << 8) + dest[6]); - xposition += xstep; - yposition += ystep; - - dest[7] = *(ds_transmap + (colormap[source[(((UINT32)yposition >> nflatyshift) & nflatmask) | ((UINT32)xposition >> nflatxshift)]] << 8) + dest[7]); - xposition += xstep; - yposition += ystep; - - dest += 8; - count -= 8; - } - while (count-- && dest <= deststop) - { - val = (((UINT32)yposition >> nflatyshift) & nflatmask) | ((UINT32)xposition >> nflatxshift); - *dest = *(ds_transmap + (colormap[source[val]] << 8) + *dest); - dest++; - xposition += xstep; - yposition += ystep; - } + val = (((UINT32)yposition >> nflatyshift) & nflatmask) | ((UINT32)xposition >> nflatxshift); + *dest = *(ds_transmap + (colormap[source[val]] << 8) + *dest); + dest++; + xposition += xstep; + yposition += ystep; } } #ifndef NOWATER void R_DrawTranslucentWaterSpan_8(void) { - fixed_t xposition; - fixed_t yposition; - fixed_t xstep, ystep; + UINT32 xposition; + UINT32 yposition; + UINT32 xstep, ystep; UINT8 *source; UINT8 *colormap; UINT8 *dest; UINT8 *dsrc; - const UINT8 *deststop = screens[0] + vid.rowbytes * vid.height; - size_t count = (ds_x2 - ds_x1 + 1); - - xposition = ds_xfrac; yposition = (ds_yfrac + ds_waterofs); - xstep = ds_xstep; ystep = ds_ystep; + size_t count; // SoM: we only need 6 bits for the integer part (0 thru 63) so the rest // can be used for the fraction part. This allows calculation of the memory address in the @@ -1712,46 +1386,60 @@ void R_DrawTranslucentWaterSpan_8(void) // bit per power of two (obviously) // Ok, because I was able to eliminate the variable spot below, this function is now FASTER // than the original span renderer. Whodathunkit? - if (ds_powersoftwo) - { - xposition <<= nflatshiftup; yposition <<= nflatshiftup; - xstep <<= nflatshiftup; ystep <<= nflatshiftup; - } + xposition = ds_xfrac << nflatshiftup; yposition = (ds_yfrac + ds_waterofs) << nflatshiftup; + xstep = ds_xstep << nflatshiftup; ystep = ds_ystep << nflatshiftup; source = ds_source; colormap = ds_colormap; dest = ylookup[ds_y] + columnofs[ds_x1]; dsrc = screens[1] + (ds_y+ds_bgofs)*vid.width + ds_x1; + count = ds_x2 - ds_x1 + 1; - if (!ds_powersoftwo) + while (count >= 8) { - while (count-- && dest <= deststop) - { - fixed_t x = (xposition >> FRACBITS); - fixed_t y = (yposition >> FRACBITS); + // SoM: Why didn't I see this earlier? the spot variable is a waste now because we don't + // have the uber complicated math to calculate it now, so that was a memory write we didn't + // need! + dest[0] = colormap[*(ds_transmap + (source[((yposition >> nflatyshift) & nflatmask) | (xposition >> nflatxshift)] << 8) + *dsrc++)]; + xposition += xstep; + yposition += ystep; - // Carefully align all of my Friends. - if (x < 0) - x = ds_flatwidth - ((UINT32)(ds_flatwidth - x) % ds_flatwidth); - if (y < 0) - y = ds_flatheight - ((UINT32)(ds_flatheight - y) % ds_flatheight); + dest[1] = colormap[*(ds_transmap + (source[((yposition >> nflatyshift) & nflatmask) | (xposition >> nflatxshift)] << 8) + *dsrc++)]; + xposition += xstep; + yposition += ystep; - x %= ds_flatwidth; - y %= ds_flatheight; + dest[2] = colormap[*(ds_transmap + (source[((yposition >> nflatyshift) & nflatmask) | (xposition >> nflatxshift)] << 8) + *dsrc++)]; + xposition += xstep; + yposition += ystep; - *dest++ = colormap[*(ds_transmap + (source[((y * ds_flatwidth) + x)] << 8) + *dsrc++)]; - xposition += xstep; - yposition += ystep; - } + dest[3] = colormap[*(ds_transmap + (source[((yposition >> nflatyshift) & nflatmask) | (xposition >> nflatxshift)] << 8) + *dsrc++)]; + xposition += xstep; + yposition += ystep; + + dest[4] = colormap[*(ds_transmap + (source[((yposition >> nflatyshift) & nflatmask) | (xposition >> nflatxshift)] << 8) + *dsrc++)]; + xposition += xstep; + yposition += ystep; + + dest[5] = colormap[*(ds_transmap + (source[((yposition >> nflatyshift) & nflatmask) | (xposition >> nflatxshift)] << 8) + *dsrc++)]; + xposition += xstep; + yposition += ystep; + + dest[6] = colormap[*(ds_transmap + (source[((yposition >> nflatyshift) & nflatmask) | (xposition >> nflatxshift)] << 8) + *dsrc++)]; + xposition += xstep; + yposition += ystep; + + dest[7] = colormap[*(ds_transmap + (source[((yposition >> nflatyshift) & nflatmask) | (xposition >> nflatxshift)] << 8) + *dsrc++)]; + xposition += xstep; + yposition += ystep; + + dest += 8; + count -= 8; } - else + while (count--) { - while (count-- && dest <= deststop) - { - *dest++ = colormap[*(ds_transmap + (source[(((UINT32)yposition >> nflatyshift) & nflatmask) | ((UINT32)xposition >> nflatxshift)] << 8) + *dsrc++)]; - xposition += xstep; - yposition += ystep; - } + *dest++ = colormap[*(ds_transmap + (source[((yposition >> nflatyshift) & nflatmask) | (xposition >> nflatxshift)] << 8) + *dsrc++)]; + xposition += xstep; + yposition += ystep; } } #endif diff --git a/src/r_draw8_npo2.c b/src/r_draw8_npo2.c new file mode 100644 index 000000000..3ed6acd00 --- /dev/null +++ b/src/r_draw8_npo2.c @@ -0,0 +1,845 @@ +// SONIC ROBO BLAST 2 +//----------------------------------------------------------------------------- +// Copyright (C) 1998-2000 by DooM Legacy Team. +// Copyright (C) 1999-2019 by Sonic Team Junior. +// +// This program is free software distributed under the +// terms of the GNU General Public License, version 2. +// See the 'LICENSE' file for more details. +//----------------------------------------------------------------------------- +/// \file r_draw8_npo2.c +/// \brief 8bpp span drawer functions (for non-powers-of-two flat dimensions) +/// \note no includes because this is included as part of r_draw.c + +// ========================================================================== +// SPANS +// ========================================================================== + +/** \brief The R_DrawSpan_NPO2_8 function + Draws the actual span. +*/ +void R_DrawSpan_NPO2_8 (void) +{ + fixed_t xposition; + fixed_t yposition; + fixed_t xstep, ystep; + + UINT8 *source; + UINT8 *colormap; + UINT8 *dest; + const UINT8 *deststop = screens[0] + vid.rowbytes * vid.height; + + size_t count = (ds_x2 - ds_x1 + 1); + + xposition = ds_xfrac; yposition = ds_yfrac; + xstep = ds_xstep; ystep = ds_ystep; + + source = ds_source; + colormap = ds_colormap; + dest = ylookup[ds_y] + columnofs[ds_x1]; + + if (dest+8 > deststop) + return; + + while (count-- && dest <= deststop) + { + fixed_t x = (xposition >> FRACBITS); + fixed_t y = (yposition >> FRACBITS); + + // Carefully align all of my Friends. + if (x < 0) + x = ds_flatwidth - ((UINT32)(ds_flatwidth - x) % ds_flatwidth); + if (y < 0) + y = ds_flatheight - ((UINT32)(ds_flatheight - y) % ds_flatheight); + + x %= ds_flatwidth; + y %= ds_flatheight; + + *dest++ = colormap[source[((y * ds_flatwidth) + x)]]; + xposition += xstep; + yposition += ystep; + } +} + +#ifdef ESLOPE +/** \brief The R_DrawTiltedSpan_NPO2_8 function + Draw slopes! Holy sheit! +*/ +void R_DrawTiltedSpan_NPO2_8(void) +{ + // x1, x2 = ds_x1, ds_x2 + int width = ds_x2 - ds_x1; + double iz, uz, vz; + UINT32 u, v; + int i; + + UINT8 *source; + UINT8 *colormap; + UINT8 *dest; + + double startz, startu, startv; + double izstep, uzstep, vzstep; + double endz, endu, endv; + UINT32 stepu, stepv; + + iz = ds_sz.z + ds_sz.y*(centery-ds_y) + ds_sz.x*(ds_x1-centerx); + + // Lighting is simple. It's just linear interpolation from start to end + { + float planelightfloat = BASEVIDWIDTH*BASEVIDWIDTH/vid.width / (zeroheight - FIXED_TO_FLOAT(viewz)) / 21.0f; + float lightstart, lightend; + + lightend = (iz + ds_sz.x*width) * planelightfloat; + lightstart = iz * planelightfloat; + + R_CalcTiltedLighting(FLOAT_TO_FIXED(lightstart), FLOAT_TO_FIXED(lightend)); + //CONS_Printf("tilted lighting %f to %f (foc %f)\n", lightstart, lightend, focallengthf); + } + + uz = ds_su.z + ds_su.y*(centery-ds_y) + ds_su.x*(ds_x1-centerx); + vz = ds_sv.z + ds_sv.y*(centery-ds_y) + ds_sv.x*(ds_x1-centerx); + + dest = ylookup[ds_y] + columnofs[ds_x1]; + source = ds_source; + //colormap = ds_colormap; + +#if 0 // The "perfect" reference version of this routine. Pretty slow. + // Use it only to see how things are supposed to look. + i = 0; + do + { + double z = 1.f/iz; + u = (INT64)(uz*z) + viewx; + v = (INT64)(vz*z) + viewy; + + colormap = planezlight[tiltlighting[ds_x1++]] + (ds_colormap - colormaps); + + // Lactozilla: Non-powers-of-two + { + fixed_t x = (((fixed_t)u-viewx) >> FRACBITS); + fixed_t y = (((fixed_t)v-viewy) >> FRACBITS); + + // Carefully align all of my Friends. + if (x < 0) + x = ds_flatwidth - ((UINT32)(ds_flatwidth - x) % ds_flatwidth); + if (y < 0) + y = ds_flatheight - ((UINT32)(ds_flatheight - y) % ds_flatheight); + + x %= ds_flatwidth; + y %= ds_flatheight; + + *dest = colormap[source[((y * ds_flatwidth) + x)]]; + } + dest++; + iz += ds_sz.x; + uz += ds_su.x; + vz += ds_sv.x; + } while (--width >= 0); +#else +#define SPANSIZE 16 +#define INVSPAN 0.0625f + + startz = 1.f/iz; + startu = uz*startz; + startv = vz*startz; + + izstep = ds_sz.x * SPANSIZE; + uzstep = ds_su.x * SPANSIZE; + vzstep = ds_sv.x * SPANSIZE; + //x1 = 0; + width++; + + while (width >= SPANSIZE) + { + iz += izstep; + uz += uzstep; + vz += vzstep; + + endz = 1.f/iz; + endu = uz*endz; + endv = vz*endz; + stepu = (INT64)((endu - startu) * INVSPAN); + stepv = (INT64)((endv - startv) * INVSPAN); + u = (INT64)(startu) + viewx; + v = (INT64)(startv) + viewy; + + for (i = SPANSIZE-1; i >= 0; i--) + { + colormap = planezlight[tiltlighting[ds_x1++]] + (ds_colormap - colormaps); + // Lactozilla: Non-powers-of-two + { + fixed_t x = (((fixed_t)u-viewx) >> FRACBITS); + fixed_t y = (((fixed_t)v-viewy) >> FRACBITS); + + // Carefully align all of my Friends. + if (x < 0) + x = ds_flatwidth - ((UINT32)(ds_flatwidth - x) % ds_flatwidth); + if (y < 0) + y = ds_flatheight - ((UINT32)(ds_flatheight - y) % ds_flatheight); + + x %= ds_flatwidth; + y %= ds_flatheight; + + *dest = colormap[source[((y * ds_flatwidth) + x)]]; + } + dest++; + u += stepu; + v += stepv; + } + startu = endu; + startv = endv; + width -= SPANSIZE; + } + if (width > 0) + { + if (width == 1) + { + u = (INT64)(startu); + v = (INT64)(startv); + colormap = planezlight[tiltlighting[ds_x1++]] + (ds_colormap - colormaps); + // Lactozilla: Non-powers-of-two + { + fixed_t x = (((fixed_t)u-viewx) >> FRACBITS); + fixed_t y = (((fixed_t)v-viewy) >> FRACBITS); + + // Carefully align all of my Friends. + if (x < 0) + x = ds_flatwidth - ((UINT32)(ds_flatwidth - x) % ds_flatwidth); + if (y < 0) + y = ds_flatheight - ((UINT32)(ds_flatheight - y) % ds_flatheight); + + x %= ds_flatwidth; + y %= ds_flatheight; + + *dest = colormap[source[((y * ds_flatwidth) + x)]]; + } + } + else + { + double left = width; + iz += ds_sz.x * left; + uz += ds_su.x * left; + vz += ds_sv.x * left; + + endz = 1.f/iz; + endu = uz*endz; + endv = vz*endz; + left = 1.f/left; + stepu = (INT64)((endu - startu) * left); + stepv = (INT64)((endv - startv) * left); + u = (INT64)(startu) + viewx; + v = (INT64)(startv) + viewy; + + for (; width != 0; width--) + { + colormap = planezlight[tiltlighting[ds_x1++]] + (ds_colormap - colormaps); + // Lactozilla: Non-powers-of-two + { + fixed_t x = (((fixed_t)u-viewx) >> FRACBITS); + fixed_t y = (((fixed_t)v-viewy) >> FRACBITS); + + // Carefully align all of my Friends. + if (x < 0) + x = ds_flatwidth - ((UINT32)(ds_flatwidth - x) % ds_flatwidth); + if (y < 0) + y = ds_flatheight - ((UINT32)(ds_flatheight - y) % ds_flatheight); + + x %= ds_flatwidth; + y %= ds_flatheight; + + *dest = colormap[source[((y * ds_flatwidth) + x)]]; + } + dest++; + u += stepu; + v += stepv; + } + } + } +#endif +} + +/** \brief The R_DrawTiltedTranslucentSpan_NPO2_8 function + Like DrawTiltedSpan_NPO2, but translucent +*/ +void R_DrawTiltedTranslucentSpan_NPO2_8(void) +{ + // x1, x2 = ds_x1, ds_x2 + int width = ds_x2 - ds_x1; + double iz, uz, vz; + UINT32 u, v; + int i; + + UINT8 *source; + UINT8 *colormap; + UINT8 *dest; + + double startz, startu, startv; + double izstep, uzstep, vzstep; + double endz, endu, endv; + UINT32 stepu, stepv; + + iz = ds_sz.z + ds_sz.y*(centery-ds_y) + ds_sz.x*(ds_x1-centerx); + + // Lighting is simple. It's just linear interpolation from start to end + { + float planelightfloat = BASEVIDWIDTH*BASEVIDWIDTH/vid.width / (zeroheight - FIXED_TO_FLOAT(viewz)) / 21.0f; + float lightstart, lightend; + + lightend = (iz + ds_sz.x*width) * planelightfloat; + lightstart = iz * planelightfloat; + + R_CalcTiltedLighting(FLOAT_TO_FIXED(lightstart), FLOAT_TO_FIXED(lightend)); + //CONS_Printf("tilted lighting %f to %f (foc %f)\n", lightstart, lightend, focallengthf); + } + + uz = ds_su.z + ds_su.y*(centery-ds_y) + ds_su.x*(ds_x1-centerx); + vz = ds_sv.z + ds_sv.y*(centery-ds_y) + ds_sv.x*(ds_x1-centerx); + + dest = ylookup[ds_y] + columnofs[ds_x1]; + source = ds_source; + //colormap = ds_colormap; + +#if 0 // The "perfect" reference version of this routine. Pretty slow. + // Use it only to see how things are supposed to look. + i = 0; + do + { + double z = 1.f/iz; + u = (INT64)(uz*z) + viewx; + v = (INT64)(vz*z) + viewy; + + colormap = planezlight[tiltlighting[ds_x1++]] + (ds_colormap - colormaps); + // Lactozilla: Non-powers-of-two + { + fixed_t x = (((fixed_t)u-viewx) >> FRACBITS); + fixed_t y = (((fixed_t)v-viewy) >> FRACBITS); + + // Carefully align all of my Friends. + if (x < 0) + x = ds_flatwidth - ((UINT32)(ds_flatwidth - x) % ds_flatwidth); + if (y < 0) + y = ds_flatheight - ((UINT32)(ds_flatheight - y) % ds_flatheight); + + x %= ds_flatwidth; + y %= ds_flatheight; + + *dest = *(ds_transmap + (colormap[source[((y * ds_flatwidth) + x)]] << 8) + *dest); + } + dest++; + iz += ds_sz.x; + uz += ds_su.x; + vz += ds_sv.x; + } while (--width >= 0); +#else +#define SPANSIZE 16 +#define INVSPAN 0.0625f + + startz = 1.f/iz; + startu = uz*startz; + startv = vz*startz; + + izstep = ds_sz.x * SPANSIZE; + uzstep = ds_su.x * SPANSIZE; + vzstep = ds_sv.x * SPANSIZE; + //x1 = 0; + width++; + + while (width >= SPANSIZE) + { + iz += izstep; + uz += uzstep; + vz += vzstep; + + endz = 1.f/iz; + endu = uz*endz; + endv = vz*endz; + stepu = (INT64)((endu - startu) * INVSPAN); + stepv = (INT64)((endv - startv) * INVSPAN); + u = (INT64)(startu) + viewx; + v = (INT64)(startv) + viewy; + + for (i = SPANSIZE-1; i >= 0; i--) + { + colormap = planezlight[tiltlighting[ds_x1++]] + (ds_colormap - colormaps); + // Lactozilla: Non-powers-of-two + { + fixed_t x = (((fixed_t)u-viewx) >> FRACBITS); + fixed_t y = (((fixed_t)v-viewy) >> FRACBITS); + + // Carefully align all of my Friends. + if (x < 0) + x = ds_flatwidth - ((UINT32)(ds_flatwidth - x) % ds_flatwidth); + if (y < 0) + y = ds_flatheight - ((UINT32)(ds_flatheight - y) % ds_flatheight); + + x %= ds_flatwidth; + y %= ds_flatheight; + + *dest = *(ds_transmap + (colormap[source[((y * ds_flatwidth) + x)]] << 8) + *dest); + } + dest++; + u += stepu; + v += stepv; + } + startu = endu; + startv = endv; + width -= SPANSIZE; + } + if (width > 0) + { + if (width == 1) + { + u = (INT64)(startu); + v = (INT64)(startv); + colormap = planezlight[tiltlighting[ds_x1++]] + (ds_colormap - colormaps); + // Lactozilla: Non-powers-of-two + { + fixed_t x = (((fixed_t)u-viewx) >> FRACBITS); + fixed_t y = (((fixed_t)v-viewy) >> FRACBITS); + + // Carefully align all of my Friends. + if (x < 0) + x = ds_flatwidth - ((UINT32)(ds_flatwidth - x) % ds_flatwidth); + if (y < 0) + y = ds_flatheight - ((UINT32)(ds_flatheight - y) % ds_flatheight); + + x %= ds_flatwidth; + y %= ds_flatheight; + + *dest = *(ds_transmap + (colormap[source[((y * ds_flatwidth) + x)]] << 8) + *dest); + } + } + else + { + double left = width; + iz += ds_sz.x * left; + uz += ds_su.x * left; + vz += ds_sv.x * left; + + endz = 1.f/iz; + endu = uz*endz; + endv = vz*endz; + left = 1.f/left; + stepu = (INT64)((endu - startu) * left); + stepv = (INT64)((endv - startv) * left); + u = (INT64)(startu) + viewx; + v = (INT64)(startv) + viewy; + + for (; width != 0; width--) + { + colormap = planezlight[tiltlighting[ds_x1++]] + (ds_colormap - colormaps); + // Lactozilla: Non-powers-of-two + { + fixed_t x = (((fixed_t)u-viewx) >> FRACBITS); + fixed_t y = (((fixed_t)v-viewy) >> FRACBITS); + + // Carefully align all of my Friends. + if (x < 0) + x = ds_flatwidth - ((UINT32)(ds_flatwidth - x) % ds_flatwidth); + if (y < 0) + y = ds_flatheight - ((UINT32)(ds_flatheight - y) % ds_flatheight); + + x %= ds_flatwidth; + y %= ds_flatheight; + + *dest = *(ds_transmap + (colormap[source[((y * ds_flatwidth) + x)]] << 8) + *dest); + } + dest++; + u += stepu; + v += stepv; + } + } + } +#endif +} + +void R_DrawTiltedSplat_NPO2_8(void) +{ + // x1, x2 = ds_x1, ds_x2 + int width = ds_x2 - ds_x1; + double iz, uz, vz; + UINT32 u, v; + int i; + + UINT8 *source; + UINT8 *colormap; + UINT8 *dest; + + UINT8 val; + + double startz, startu, startv; + double izstep, uzstep, vzstep; + double endz, endu, endv; + UINT32 stepu, stepv; + + iz = ds_sz.z + ds_sz.y*(centery-ds_y) + ds_sz.x*(ds_x1-centerx); + + // Lighting is simple. It's just linear interpolation from start to end + { + float planelightfloat = BASEVIDWIDTH*BASEVIDWIDTH/vid.width / (zeroheight - FIXED_TO_FLOAT(viewz)) / 21.0f; + float lightstart, lightend; + + lightend = (iz + ds_sz.x*width) * planelightfloat; + lightstart = iz * planelightfloat; + + R_CalcTiltedLighting(FLOAT_TO_FIXED(lightstart), FLOAT_TO_FIXED(lightend)); + //CONS_Printf("tilted lighting %f to %f (foc %f)\n", lightstart, lightend, focallengthf); + } + + uz = ds_su.z + ds_su.y*(centery-ds_y) + ds_su.x*(ds_x1-centerx); + vz = ds_sv.z + ds_sv.y*(centery-ds_y) + ds_sv.x*(ds_x1-centerx); + + dest = ylookup[ds_y] + columnofs[ds_x1]; + source = ds_source; + //colormap = ds_colormap; + +#if 0 // The "perfect" reference version of this routine. Pretty slow. + // Use it only to see how things are supposed to look. + i = 0; + do + { + double z = 1.f/iz; + u = (INT64)(uz*z) + viewx; + v = (INT64)(vz*z) + viewy; + + colormap = planezlight[tiltlighting[ds_x1++]] + (ds_colormap - colormaps); + + // Lactozilla: Non-powers-of-two + { + fixed_t x = (((fixed_t)u-viewx) >> FRACBITS); + fixed_t y = (((fixed_t)v-viewy) >> FRACBITS); + + // Carefully align all of my Friends. + if (x < 0) + x = ds_flatwidth - ((UINT32)(ds_flatwidth - x) % ds_flatwidth); + if (y < 0) + y = ds_flatheight - ((UINT32)(ds_flatheight - y) % ds_flatheight); + + x %= ds_flatwidth; + y %= ds_flatheight; + + val = source[((y * ds_flatwidth) + x)]; + } + + if (val != TRANSPARENTPIXEL) + *dest = colormap[val]; + + dest++; + iz += ds_sz.x; + uz += ds_su.x; + vz += ds_sv.x; + } while (--width >= 0); +#else +#define SPANSIZE 16 +#define INVSPAN 0.0625f + + startz = 1.f/iz; + startu = uz*startz; + startv = vz*startz; + + izstep = ds_sz.x * SPANSIZE; + uzstep = ds_su.x * SPANSIZE; + vzstep = ds_sv.x * SPANSIZE; + //x1 = 0; + width++; + + while (width >= SPANSIZE) + { + iz += izstep; + uz += uzstep; + vz += vzstep; + + endz = 1.f/iz; + endu = uz*endz; + endv = vz*endz; + stepu = (INT64)((endu - startu) * INVSPAN); + stepv = (INT64)((endv - startv) * INVSPAN); + u = (INT64)(startu) + viewx; + v = (INT64)(startv) + viewy; + + for (i = SPANSIZE-1; i >= 0; i--) + { + colormap = planezlight[tiltlighting[ds_x1++]] + (ds_colormap - colormaps); + // Lactozilla: Non-powers-of-two + { + fixed_t x = (((fixed_t)u-viewx) >> FRACBITS); + fixed_t y = (((fixed_t)v-viewy) >> FRACBITS); + + // Carefully align all of my Friends. + if (x < 0) + x = ds_flatwidth - ((UINT32)(ds_flatwidth - x) % ds_flatwidth); + if (y < 0) + y = ds_flatheight - ((UINT32)(ds_flatheight - y) % ds_flatheight); + + x %= ds_flatwidth; + y %= ds_flatheight; + + val = source[((y * ds_flatwidth) + x)]; + } + if (val != TRANSPARENTPIXEL) + *dest = colormap[val]; + dest++; + u += stepu; + v += stepv; + } + startu = endu; + startv = endv; + width -= SPANSIZE; + } + if (width > 0) + { + if (width == 1) + { + u = (INT64)(startu); + v = (INT64)(startv); + colormap = planezlight[tiltlighting[ds_x1++]] + (ds_colormap - colormaps); + // Lactozilla: Non-powers-of-two + { + fixed_t x = (((fixed_t)u-viewx) >> FRACBITS); + fixed_t y = (((fixed_t)v-viewy) >> FRACBITS); + + // Carefully align all of my Friends. + if (x < 0) + x = ds_flatwidth - ((UINT32)(ds_flatwidth - x) % ds_flatwidth); + if (y < 0) + y = ds_flatheight - ((UINT32)(ds_flatheight - y) % ds_flatheight); + + x %= ds_flatwidth; + y %= ds_flatheight; + + val = source[((y * ds_flatwidth) + x)]; + } + if (val != TRANSPARENTPIXEL) + *dest = colormap[val]; + } + else + { + double left = width; + iz += ds_sz.x * left; + uz += ds_su.x * left; + vz += ds_sv.x * left; + + endz = 1.f/iz; + endu = uz*endz; + endv = vz*endz; + left = 1.f/left; + stepu = (INT64)((endu - startu) * left); + stepv = (INT64)((endv - startv) * left); + u = (INT64)(startu) + viewx; + v = (INT64)(startv) + viewy; + + for (; width != 0; width--) + { + colormap = planezlight[tiltlighting[ds_x1++]] + (ds_colormap - colormaps); + val = source[((v >> nflatyshift) & nflatmask) | (u >> nflatxshift)]; + // Lactozilla: Non-powers-of-two + { + fixed_t x = (((fixed_t)u-viewx) >> FRACBITS); + fixed_t y = (((fixed_t)v-viewy) >> FRACBITS); + + // Carefully align all of my Friends. + if (x < 0) + x = ds_flatwidth - ((UINT32)(ds_flatwidth - x) % ds_flatwidth); + if (y < 0) + y = ds_flatheight - ((UINT32)(ds_flatheight - y) % ds_flatheight); + + x %= ds_flatwidth; + y %= ds_flatheight; + + val = source[((y * ds_flatwidth) + x)]; + } + if (val != TRANSPARENTPIXEL) + *dest = colormap[val]; + dest++; + u += stepu; + v += stepv; + } + } + } +#endif +} +#endif // ESLOPE + +/** \brief The R_DrawSplat_NPO2_8 function + Just like R_DrawSpan_NPO2_8, but skips transparent pixels. +*/ +void R_DrawSplat_NPO2_8 (void) +{ + fixed_t xposition; + fixed_t yposition; + fixed_t xstep, ystep; + + UINT8 *source; + UINT8 *colormap; + UINT8 *dest; + const UINT8 *deststop = screens[0] + vid.rowbytes * vid.height; + + size_t count = (ds_x2 - ds_x1 + 1); + UINT32 val; + + xposition = ds_xfrac; yposition = ds_yfrac; + xstep = ds_xstep; ystep = ds_ystep; + + source = ds_source; + colormap = ds_colormap; + dest = ylookup[ds_y] + columnofs[ds_x1]; + + while (count-- && dest <= deststop) + { + fixed_t x = (xposition >> FRACBITS); + fixed_t y = (yposition >> FRACBITS); + + // Carefully align all of my Friends. + if (x < 0) + x = ds_flatwidth - ((UINT32)(ds_flatwidth - x) % ds_flatwidth); + if (y < 0) + y = ds_flatheight - ((UINT32)(ds_flatheight - y) % ds_flatheight); + + x %= ds_flatwidth; + y %= ds_flatheight; + + val = source[((y * ds_flatwidth) + x)]; + if (val != TRANSPARENTPIXEL) + *dest = colormap[val]; + dest++; + xposition += xstep; + yposition += ystep; + } +} + +/** \brief The R_DrawTranslucentSplat_NPO2_8 function + Just like R_DrawSplat_NPO2_8, but is translucent! +*/ +void R_DrawTranslucentSplat_NPO2_8 (void) +{ + fixed_t xposition; + fixed_t yposition; + fixed_t xstep, ystep; + + UINT8 *source; + UINT8 *colormap; + UINT8 *dest; + const UINT8 *deststop = screens[0] + vid.rowbytes * vid.height; + + size_t count = (ds_x2 - ds_x1 + 1); + UINT32 val; + + xposition = ds_xfrac; yposition = ds_yfrac; + xstep = ds_xstep; ystep = ds_ystep; + + source = ds_source; + colormap = ds_colormap; + dest = ylookup[ds_y] + columnofs[ds_x1]; + + while (count-- && dest <= deststop) + { + fixed_t x = (xposition >> FRACBITS); + fixed_t y = (yposition >> FRACBITS); + + // Carefully align all of my Friends. + if (x < 0) + x = ds_flatwidth - ((UINT32)(ds_flatwidth - x) % ds_flatwidth); + if (y < 0) + y = ds_flatheight - ((UINT32)(ds_flatheight - y) % ds_flatheight); + + x %= ds_flatwidth; + y %= ds_flatheight; + + val = source[((y * ds_flatwidth) + x)]; + if (val != TRANSPARENTPIXEL) + *dest = *(ds_transmap + (colormap[val] << 8) + *dest); + dest++; + xposition += xstep; + yposition += ystep; + } +} + +/** \brief The R_DrawTranslucentSpan_NPO2_8 function + Draws the actual span with translucency. +*/ +void R_DrawTranslucentSpan_NPO2_8 (void) +{ + fixed_t xposition; + fixed_t yposition; + fixed_t xstep, ystep; + + UINT8 *source; + UINT8 *colormap; + UINT8 *dest; + const UINT8 *deststop = screens[0] + vid.rowbytes * vid.height; + + size_t count = (ds_x2 - ds_x1 + 1); + UINT32 val; + + xposition = ds_xfrac; yposition = ds_yfrac; + xstep = ds_xstep; ystep = ds_ystep; + + source = ds_source; + colormap = ds_colormap; + dest = ylookup[ds_y] + columnofs[ds_x1]; + + while (count-- && dest <= deststop) + { + fixed_t x = (xposition >> FRACBITS); + fixed_t y = (yposition >> FRACBITS); + + // Carefully align all of my Friends. + if (x < 0) + x = ds_flatwidth - ((UINT32)(ds_flatwidth - x) % ds_flatwidth); + if (y < 0) + y = ds_flatheight - ((UINT32)(ds_flatheight - y) % ds_flatheight); + + x %= ds_flatwidth; + y %= ds_flatheight; + + val = ((y * ds_flatwidth) + x); + *dest = *(ds_transmap + (colormap[source[val]] << 8) + *dest); + dest++; + xposition += xstep; + yposition += ystep; + } +} + +#ifndef NOWATER +void R_DrawTranslucentWaterSpan_NPO2_8(void) +{ + fixed_t xposition; + fixed_t yposition; + fixed_t xstep, ystep; + + UINT8 *source; + UINT8 *colormap; + UINT8 *dest; + UINT8 *dsrc; + const UINT8 *deststop = screens[0] + vid.rowbytes * vid.height; + + size_t count = (ds_x2 - ds_x1 + 1); + + xposition = ds_xfrac; yposition = (ds_yfrac + ds_waterofs); + xstep = ds_xstep; ystep = ds_ystep; + + source = ds_source; + colormap = ds_colormap; + dest = ylookup[ds_y] + columnofs[ds_x1]; + dsrc = screens[1] + (ds_y+ds_bgofs)*vid.width + ds_x1; + + while (count-- && dest <= deststop) + { + fixed_t x = (xposition >> FRACBITS); + fixed_t y = (yposition >> FRACBITS); + + // Carefully align all of my Friends. + if (x < 0) + x = ds_flatwidth - ((UINT32)(ds_flatwidth - x) % ds_flatwidth); + if (y < 0) + y = ds_flatheight - ((UINT32)(ds_flatheight - y) % ds_flatheight); + + x %= ds_flatwidth; + y %= ds_flatheight; + + *dest++ = colormap[*(ds_transmap + (source[((y * ds_flatwidth) + x)] << 8) + *dsrc++)]; + xposition += xstep; + yposition += ystep; + } +} +#endif diff --git a/src/r_plane.c b/src/r_plane.c index 8c644700e..3745c28be 100644 --- a/src/r_plane.c +++ b/src/r_plane.c @@ -841,6 +841,7 @@ void R_DrawSinglePlane(visplane_t *pl) ffloor_t *rover; levelflat_t *levelflat; int type; + int spanfunctype = BASEDRAWFUNC; if (!(pl->minx <= pl->maxx)) return; @@ -858,8 +859,9 @@ void R_DrawSinglePlane(visplane_t *pl) spanfunc = spanfuncs[BASEDRAWFUNC]; #ifdef POLYOBJECTS_PLANES - if (pl->polyobj && pl->polyobj->translucency != 0) { - spanfunc = spanfuncs[SPANDRAWFUNC_TRANS]; + if (pl->polyobj && pl->polyobj->translucency != 0) + { + spanfunctype = SPANDRAWFUNC_TRANS; // Hacked up support for alpha value in software mode Tails 09-24-2002 (sidenote: ported to polys 10-15-2014, there was no time travel involved -Red) if (pl->polyobj->translucency >= 10) @@ -867,10 +869,10 @@ void R_DrawSinglePlane(visplane_t *pl) else if (pl->polyobj->translucency > 0) ds_transmap = transtables + ((pl->polyobj->translucency-1)<extra_colormap && (pl->extra_colormap->fog & 4))) + if ((spanfunctype == SPANDRAWFUNC_SPLAT) != (pl->extra_colormap && (pl->extra_colormap->fog & 4))) #else if (!pl->extra_colormap || !(pl->extra_colormap->fog & 2)) #endif @@ -901,7 +903,7 @@ void R_DrawSinglePlane(visplane_t *pl) if (pl->ffloor->flags & FF_TRANSLUCENT) { - spanfunc = spanfuncs[SPANDRAWFUNC_TRANS]; + spanfunctype = SPANDRAWFUNC_TRANS; // Hacked up support for alpha value in software mode Tails 09-24-2002 if (pl->ffloor->alpha < 12) @@ -925,10 +927,10 @@ void R_DrawSinglePlane(visplane_t *pl) else if (pl->ffloor->alpha < 243) ds_transmap = transtables + ((tr_trans10-1)<extra_colormap && (pl->extra_colormap->fog & 4))) + if ((spanfunctype == SPANDRAWFUNC_SPLAT) != (pl->extra_colormap && (pl->extra_colormap->fog & 4))) #else if (!pl->extra_colormap || !(pl->extra_colormap->fog & 2)) #endif @@ -938,7 +940,7 @@ void R_DrawSinglePlane(visplane_t *pl) } else if (pl->ffloor->flags & FF_FOG) { - spanfunc = spanfuncs[SPANDRAWFUNC_FOG]; + spanfunctype = SPANDRAWFUNC_FOG; light = (pl->lightlevel >> LIGHTSEGSHIFT); } else light = (pl->lightlevel >> LIGHTSEGSHIFT); @@ -953,9 +955,9 @@ void R_DrawSinglePlane(visplane_t *pl) INT32 top, bottom; itswater = true; - if (spanfunc == spanfuncs[SPANDRAWFUNC_TRANS]) + if (spanfunctype == SPANDRAWFUNC_TRANS) { - spanfunc = spanfuncs[SPANDRAWFUNC_WATER]; + spanfunctype = SPANDRAWFUNC_WATER; // Copy the current scene, ugh top = pl->high-8; @@ -1032,8 +1034,8 @@ void R_DrawSinglePlane(visplane_t *pl) if (R_CheckPowersOfTwo()) { R_CheckFlatLength(ds_flatwidth * ds_flatheight); - if (spanfunc == spanfuncs[BASEDRAWFUNC]) - spanfunc = spanfuncs[SPANDRAWFUNC_MMX]; + if (spanfunctype == BASEDRAWFUNC) + spanfunctype = SPANDRAWFUNC_MMX; } } @@ -1187,12 +1189,12 @@ void R_DrawSinglePlane(visplane_t *pl) } #undef SFMULT - if (spanfunc == spanfuncs[SPANDRAWFUNC_TRANS]) - spanfunc = spanfuncs[SPANDRAWFUNC_TILTEDTRANS]; - else if (spanfunc == spanfuncs[SPANDRAWFUNC_SPLAT]) - spanfunc = spanfuncs[SPANDRAWFUNC_TILTEDSPLAT]; + if (spanfunctype == SPANDRAWFUNC_TRANS) + spanfunctype = SPANDRAWFUNC_TILTEDTRANS; + else if (spanfunctype == SPANDRAWFUNC_SPLAT) + spanfunctype = SPANDRAWFUNC_TILTEDSPLAT; else - spanfunc = spanfuncs[SPANDRAWFUNC_TILTED]; + spanfunctype = SPANDRAWFUNC_TILTED; planezlight = scalelight[light]; } else @@ -1200,6 +1202,17 @@ void R_DrawSinglePlane(visplane_t *pl) planezlight = zlight[light]; + // Use the correct span drawer depending on the powers-of-twoness + if (!ds_powersoftwo) + { + if (spanfuncs_npo2[spanfunctype]) + spanfunc = spanfuncs_npo2[spanfunctype]; + else + spanfunc = spanfuncs[spanfunctype]; + } + else + spanfunc = spanfuncs[spanfunctype]; + // set the maximum value for unsigned pl->top[pl->maxx+1] = 0xffff; pl->top[pl->minx-1] = 0xffff; diff --git a/src/screen.c b/src/screen.c index 5c88d8471..83421a1cc 100644 --- a/src/screen.c +++ b/src/screen.c @@ -46,6 +46,7 @@ void (*colfuncs[COLDRAWFUNC_MAX])(void); void (*spanfunc)(void); void (*spanfuncs[SPANDRAWFUNC_MAX])(void); +void (*spanfuncs_npo2[SPANDRAWFUNC_MAX])(void); // ------------------ // global video state @@ -133,6 +134,21 @@ void SCR_SetMode(void) spanfuncs[SPANDRAWFUNC_TILTEDSPLAT] = R_DrawTiltedSplat_8; #endif + // Lactozilla: Non-powers-of-two + spanfuncs_npo2[BASEDRAWFUNC] = R_DrawSpan_NPO2_8; + spanfuncs_npo2[SPANDRAWFUNC_TRANS] = R_DrawTranslucentSpan_NPO2_8; + spanfuncs_npo2[SPANDRAWFUNC_SPLAT] = R_DrawSplat_NPO2_8; + spanfuncs_npo2[SPANDRAWFUNC_TRANSSPLAT] = R_DrawTranslucentSplat_NPO2_8; + spanfuncs_npo2[SPANDRAWFUNC_FOG] = NULL; // Not needed + spanfuncs_npo2[SPANDRAWFUNC_MMX] = NULL; // Same +#ifndef NOWATER + spanfuncs_npo2[SPANDRAWFUNC_WATER] = R_DrawTranslucentWaterSpan_NPO2_8; +#endif +#ifdef ESLOPE + spanfuncs_npo2[SPANDRAWFUNC_TILTED] = R_DrawTiltedSpan_NPO2_8; + spanfuncs_npo2[SPANDRAWFUNC_TILTEDTRANS] = R_DrawTiltedTranslucentSpan_NPO2_8; + spanfuncs_npo2[SPANDRAWFUNC_TILTEDSPLAT] = R_DrawTiltedSplat_NPO2_8; +#endif #ifdef RUSEASM if (R_ASM) diff --git a/src/screen.h b/src/screen.h index ffed931fa..9a4d48dcf 100644 --- a/src/screen.h +++ b/src/screen.h @@ -152,6 +152,7 @@ enum extern void (*spanfunc)(void); extern void (*spanfuncs[SPANDRAWFUNC_MAX])(void); +extern void (*spanfuncs_npo2[SPANDRAWFUNC_MAX])(void); // ----- // CPUID diff --git a/src/sdl/Srb2SDL-vc10.vcxproj b/src/sdl/Srb2SDL-vc10.vcxproj index 0d1fa1a4b..b334f6313 100644 --- a/src/sdl/Srb2SDL-vc10.vcxproj +++ b/src/sdl/Srb2SDL-vc10.vcxproj @@ -438,6 +438,9 @@ true + + true + diff --git a/src/sdl/Srb2SDL-vc10.vcxproj.filters b/src/sdl/Srb2SDL-vc10.vcxproj.filters index cface6377..3f61e8709 100644 --- a/src/sdl/Srb2SDL-vc10.vcxproj.filters +++ b/src/sdl/Srb2SDL-vc10.vcxproj.filters @@ -837,6 +837,9 @@ R_Rend + + R_Rend + R_Rend diff --git a/src/win32/Srb2win-vc10.vcxproj b/src/win32/Srb2win-vc10.vcxproj index 7a79861b3..387d65da9 100644 --- a/src/win32/Srb2win-vc10.vcxproj +++ b/src/win32/Srb2win-vc10.vcxproj @@ -295,6 +295,9 @@ true + + true + diff --git a/src/win32/Srb2win-vc10.vcxproj.filters b/src/win32/Srb2win-vc10.vcxproj.filters index 3d5c021d4..2f380c473 100644 --- a/src/win32/Srb2win-vc10.vcxproj.filters +++ b/src/win32/Srb2win-vc10.vcxproj.filters @@ -369,6 +369,9 @@ R_Rend + + R_Rend + R_Rend From ad776e560c18644d8dadde16aac0dd98fa962633 Mon Sep 17 00:00:00 2001 From: Steel Titanium Date: Fri, 13 Dec 2019 16:36:33 -0500 Subject: [PATCH 177/746] Rework G_SetCustomExitVars to allow skipstats 2 --- src/lua_baselib.c | 22 ++++++++-------------- 1 file changed, 8 insertions(+), 14 deletions(-) diff --git a/src/lua_baselib.c b/src/lua_baselib.c index b68d16c2a..018529722 100644 --- a/src/lua_baselib.c +++ b/src/lua_baselib.c @@ -2664,23 +2664,17 @@ static int lib_gSetCustomExitVars(lua_State *L) // Supported: // G_SetCustomExitVars(); [reset to defaults] // G_SetCustomExitVars(int) [nextmap override only] - // G_SetCustomExitVars(bool) [skipstats only] - // G_SetCustomExitVars(int, bool) [both of the above] + // G_SetCustomExitVars(nil, int) [skipstats only] + // G_SetCustomExitVars(int, int) [both of the above] + + nextmapoverride = 0; + skipstats = 0; + if (n >= 1) { - if (lua_isnumber(L, 1) || n >= 2) - { - nextmapoverride = (INT16)luaL_checknumber(L, 1); - lua_remove(L, 1); // remove nextmapoverride; skipstats now 1 if available - } - skipstats = luaL_optinteger(L, 2, 0); + nextmapoverride = (INT16)luaL_optinteger(L, 1, 0); + skipstats = (INT16)luaL_optinteger(L, 2, 0); } - else - { - nextmapoverride = 0; - skipstats = 0; - } - // --- return 0; } From a27a225a81b58acb8443b576885e6bb713949e6d Mon Sep 17 00:00:00 2001 From: Jaime Passos Date: Fri, 13 Dec 2019 19:02:36 -0300 Subject: [PATCH 178/746] Remove SPANDRAWFUNC_MMX, as it's not needed anymore. --- src/r_plane.c | 6 ------ src/screen.c | 4 +--- src/screen.h | 1 - 3 files changed, 1 insertion(+), 10 deletions(-) diff --git a/src/r_plane.c b/src/r_plane.c index 3745c28be..1dd487b48 100644 --- a/src/r_plane.c +++ b/src/r_plane.c @@ -1008,8 +1008,6 @@ void R_DrawSinglePlane(visplane_t *pl) R_CheckFlatLength(W_LumpLength(levelflat->u.flat.lumpnum)); // Raw flats always have dimensions that are powers-of-two numbers. ds_powersoftwo = true; - if (spanfunc == spanfuncs[BASEDRAWFUNC]) - spanfunc = spanfuncs[SPANDRAWFUNC_MMX]; break; default: switch (type) @@ -1032,11 +1030,7 @@ void R_DrawSinglePlane(visplane_t *pl) } // Check if this texture or patch has power-of-two dimensions. if (R_CheckPowersOfTwo()) - { R_CheckFlatLength(ds_flatwidth * ds_flatheight); - if (spanfunctype == BASEDRAWFUNC) - spanfunctype = SPANDRAWFUNC_MMX; - } } if (light >= LIGHTLEVELS) diff --git a/src/screen.c b/src/screen.c index 83421a1cc..7a2e1a455 100644 --- a/src/screen.c +++ b/src/screen.c @@ -124,7 +124,6 @@ void SCR_SetMode(void) spanfuncs[SPANDRAWFUNC_SPLAT] = R_DrawSplat_8; spanfuncs[SPANDRAWFUNC_TRANSSPLAT] = R_DrawTranslucentSplat_8; spanfuncs[SPANDRAWFUNC_FOG] = R_DrawFogSpan_8; - spanfuncs[SPANDRAWFUNC_MMX] = spanfuncs[BASEDRAWFUNC]; #ifndef NOWATER spanfuncs[SPANDRAWFUNC_WATER] = R_DrawTranslucentWaterSpan_8; #endif @@ -140,7 +139,6 @@ void SCR_SetMode(void) spanfuncs_npo2[SPANDRAWFUNC_SPLAT] = R_DrawSplat_NPO2_8; spanfuncs_npo2[SPANDRAWFUNC_TRANSSPLAT] = R_DrawTranslucentSplat_NPO2_8; spanfuncs_npo2[SPANDRAWFUNC_FOG] = NULL; // Not needed - spanfuncs_npo2[SPANDRAWFUNC_MMX] = NULL; // Same #ifndef NOWATER spanfuncs_npo2[SPANDRAWFUNC_WATER] = R_DrawTranslucentWaterSpan_NPO2_8; #endif @@ -159,7 +157,7 @@ void SCR_SetMode(void) //colfuncs[COLDRAWFUNC_SHADE] = R_DrawShadeColumn_8_ASM; //colfuncs[COLDRAWFUNC_FUZZY] = R_DrawTranslucentColumn_8_ASM; colfuncs[COLDRAWFUNC_TWOSMULTIPATCH] = R_Draw2sMultiPatchColumn_8_MMX; - spanfuncs[SPANDRAWFUNC_MMX] = R_DrawSpan_8_MMX; + spanfuncs[BASEDRAWFUNC] = R_DrawSpan_8_MMX; } else { diff --git a/src/screen.h b/src/screen.h index 9a4d48dcf..eb0042be6 100644 --- a/src/screen.h +++ b/src/screen.h @@ -133,7 +133,6 @@ extern void (*colfuncs[COLDRAWFUNC_MAX])(void); enum { SPANDRAWFUNC_BASE = BASEDRAWFUNC, - SPANDRAWFUNC_MMX, SPANDRAWFUNC_TRANS, SPANDRAWFUNC_SPLAT, SPANDRAWFUNC_TRANSSPLAT, From 7f092b884b7eb0a89a5b86b2a832a925bab22d80 Mon Sep 17 00:00:00 2001 From: Jaime Passos Date: Thu, 12 Dec 2019 22:32:19 -0300 Subject: [PATCH 179/746] Initialise the variable, obviously --- src/hardware/hw_md2.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/hardware/hw_md2.c b/src/hardware/hw_md2.c index 61afee0ab..fea7f50bd 100644 --- a/src/hardware/hw_md2.c +++ b/src/hardware/hw_md2.c @@ -743,6 +743,8 @@ static void HWR_CreateBlendedTexture(GLPatch_t *gpatch, GLPatch_t *blendgpatch, UINT8 ialpha = 255 - blendimage->s.alpha, balpha = blendimage->s.alpha; RGBA_t icolor = *image, bcolor; + memset(&bcolor, 0x00, sizeof(RGBA_t)); + if (blendimage->s.alpha) { bcolor.s.blue = 0; From 553ad46c74cd99b77300589ec9a592370b80441e Mon Sep 17 00:00:00 2001 From: James R Date: Fri, 13 Dec 2019 15:04:31 -0800 Subject: [PATCH 180/746] Add this back for Windoodoo because I'm an idiot --- src/sdl/i_system.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/sdl/i_system.c b/src/sdl/i_system.c index a28fadc02..effdec8e2 100644 --- a/src/sdl/i_system.c +++ b/src/sdl/i_system.c @@ -2482,6 +2482,10 @@ void I_ShutdownSystem(void) { INT32 c; +#ifndef NEWSIGNALHANDLER + I_ShutdownConsole(); +#endif + for (c = MAX_QUIT_FUNCS-1; c >= 0; c--) if (quit_funcs[c]) (*quit_funcs[c])(); From 87ad91a2be223338613204e17afad85d77de813d Mon Sep 17 00:00:00 2001 From: fickleheart Date: Fri, 13 Dec 2019 17:35:48 -0600 Subject: [PATCH 181/746] LMAO right stick checking used the wrong value --- 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 6292683eb..f7ecbe0e1 100644 --- a/src/g_game.c +++ b/src/g_game.c @@ -1205,7 +1205,7 @@ void G_BuildTiccmd(ticcmd_t *cmd, INT32 realtics, UINT8 ssplayer) cmd->angleturn = (INT16)(cmd->angleturn - ((axis * angleturn[1]) >> 10)); // ANALOG! } - if (turnright || turnleft || abs(cmd->angleturn) > angleturn[1]) + if (turnright || turnleft || abs(cmd->angleturn) > angleturn[2]) tta_factor[forplayer] = 0; // suspend turn to angle // Make rotspeed affect turning speed :) From 8a23ff0bc857d93eb9c7218f6a957fc8f4db6335 Mon Sep 17 00:00:00 2001 From: James R Date: Fri, 13 Dec 2019 16:51:49 -0800 Subject: [PATCH 182/746] Handle log file in parent properly --- src/doomdef.h | 1 + src/sdl/i_main.c | 12 +++++++----- src/sdl/i_system.c | 15 ++++++++++++++- 3 files changed, 22 insertions(+), 6 deletions(-) diff --git a/src/doomdef.h b/src/doomdef.h index d13ff9bc0..b2be062c3 100644 --- a/src/doomdef.h +++ b/src/doomdef.h @@ -127,6 +127,7 @@ #ifdef LOGMESSAGES extern FILE *logstream; +extern char logfilename[1024]; #endif //#define DEVELOP // Disable this for release builds to remove excessive cheat commands and enable MD5 checking and stuff, all in one go. :3 diff --git a/src/sdl/i_main.c b/src/sdl/i_main.c index 69e49b4a7..d0830396f 100644 --- a/src/sdl/i_main.c +++ b/src/sdl/i_main.c @@ -47,6 +47,7 @@ extern int SDL_main(int argc, char *argv[]); #ifdef LOGMESSAGES FILE *logstream = NULL; +char logfilename[1024]; #endif #ifndef DOXYGEN @@ -116,7 +117,6 @@ int main(int argc, char **argv) #endif { const char *logdir = NULL; - char logfile[MAX_WADPATH]; myargc = argc; myargv = argv; /// \todo pull out path to exe from this string @@ -141,7 +141,7 @@ int main(int argc, char **argv) timeinfo = localtime(&my_time); strftime(buf, 26, "%Y-%m-%d %H-%M-%S", timeinfo); - strcpy(logfile, va("log-%s.txt", buf)); + strcpy(logfilename, va("log-%s.txt", buf)); #ifdef DEFAULTDIR if (logdir) @@ -149,14 +149,16 @@ int main(int argc, char **argv) // Create dirs here because D_SRB2Main() is too late. I_mkdir(va("%s%s"DEFAULTDIR, logdir, PATHSEP), 0755); I_mkdir(va("%s%s"DEFAULTDIR"%slogs",logdir, PATHSEP, PATHSEP), 0755); - logstream = fopen(va("%s%s"DEFAULTDIR"%slogs%s%s",logdir, PATHSEP, PATHSEP, PATHSEP, logfile), "wt"); + strcpy(logfilename, va("%s%s"DEFAULTDIR"%slogs%s%s",logdir, PATHSEP, PATHSEP, PATHSEP, logfilename)); } else #endif { I_mkdir("."PATHSEP"logs"PATHSEP, 0755); - logstream = fopen(va("."PATHSEP"logs"PATHSEP"%s", logfile), "wt"); + strcpy(logfilename, va("."PATHSEP"logs"PATHSEP"%s", logfilename)); } + + logstream = fopen(logfilename, "wt"); } #endif @@ -187,7 +189,7 @@ int main(int argc, char **argv) D_SRB2Main(); #ifdef LOGMESSAGES if (!M_CheckParm("-nolog")) - CONS_Printf("Logfile: %s\n", logfile); + CONS_Printf("Logfile: %s\n", logfilename); #endif CONS_Printf("Entering main game loop...\n"); // never return diff --git a/src/sdl/i_system.c b/src/sdl/i_system.c index effdec8e2..a5e536bf5 100644 --- a/src/sdl/i_system.c +++ b/src/sdl/i_system.c @@ -2192,6 +2192,7 @@ static void I_Fork(void) int child; int status; int signum; + int c; child = fork(); @@ -2203,7 +2204,19 @@ static void I_Fork(void) case 0: break; default: - if (wait(&status) == -1) + if (logstream) + fclose(logstream);/* the child has this */ + + c = wait(&status); + +#ifdef LOGMESSAGES + /* By the way, exit closes files. */ + logstream = fopen(logfilename, "at"); +#else + logstream = 0; +#endif + + if (c == -1) { kill(child, SIGKILL); newsignalhandler_Warn("wait()"); From 1a60f7a2ad572947e447edc93d9cab0340a120a8 Mon Sep 17 00:00:00 2001 From: fickleheart Date: Fri, 13 Dec 2019 19:30:19 -0600 Subject: [PATCH 183/746] Fix wacky CEZ2 platform camera --- 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 c37926adf..6637d238c 100644 --- a/src/p_polyobj.c +++ b/src/p_polyobj.c @@ -1341,9 +1341,9 @@ static void Polyobj_rotateThings(polyobj_t *po, vertex_t origin, angle_t delta, if (turnthings == 2 || (turnthings == 1 && !mo->player)) { mo->angle += delta; if (mo->player == &players[consoleplayer]) - localangle = mo->angle; + localangle += delta; else if (mo->player == &players[secondarydisplayplayer]) - localangle2 = mo->angle; + localangle2 += delta; } } } From a03ab5e29437686c409ff05a499bf802059b7722 Mon Sep 17 00:00:00 2001 From: fickleheart Date: Fri, 13 Dec 2019 19:37:01 -0600 Subject: [PATCH 184/746] Patch slight camera turn when airbraking --- src/g_game.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/g_game.c b/src/g_game.c index f7ecbe0e1..c08973b6e 100644 --- a/src/g_game.c +++ b/src/g_game.c @@ -1571,7 +1571,10 @@ void G_BuildTiccmd(ticcmd_t *cmd, INT32 realtics, UINT8 ssplayer) if (camadjustfactor) { - INT32 anglediff = player->drawangle + drawangleoffset - *myangle; + INT32 anglediff = + // This check to potentially use angleturn fixes the judder when holding back in the air to brake + ((alt && (forward || side) && !P_IsObjectOnGround(player->mo)) ? (cmd->angleturn<<16) : player->drawangle) + + drawangleoffset - *myangle; if (alt) { From 022a44fb01c7a900226e180cfd3a194feaad5c8f Mon Sep 17 00:00:00 2001 From: fickleheart Date: Fri, 13 Dec 2019 19:49:56 -0600 Subject: [PATCH 185/746] Don't turn-to-ability while climbing --- 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 c08973b6e..ff330278a 100644 --- a/src/g_game.c +++ b/src/g_game.c @@ -1554,7 +1554,7 @@ void G_BuildTiccmd(ticcmd_t *cmd, INT32 realtics, UINT8 ssplayer) fixed_t camadjustfactor; boolean alt = false; // Reduce intensity on diagonals and prevent backwards movement from turning the camera - if (player->climbing || player->pflags & PF_GLIDING) + if (player->pflags & PF_GLIDING) camadjustfactor = cv_cam_turnfacingability[forplayer].value/4; else if (player->pflags & PF_STARTDASH) camadjustfactor = cv_cam_turnfacingspindash[forplayer].value/4; From f82f1513ba3d5620d508057b354d3500f293a11f Mon Sep 17 00:00:00 2001 From: fickleheart Date: Fri, 13 Dec 2019 20:17:31 -0600 Subject: [PATCH 186/746] Tweaks to camera shifting --- src/p_user.c | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/src/p_user.c b/src/p_user.c index c7347462c..835fe7f67 100644 --- a/src/p_user.c +++ b/src/p_user.c @@ -10012,7 +10012,7 @@ boolean P_MoveChaseCamera(player_t *player, camera_t *thiscam, boolean resetcall } } - if (cv_abilitydirection[(thiscam == &camera) ? 0 : 1].value) + if (cv_abilitydirection[(thiscam == &camera) ? 0 : 1].value && !sign) { // Shift the camera slightly to the sides depending on the player facing direction UINT8 forplayer = (thiscam == &camera) ? 0 : 1; @@ -10021,6 +10021,12 @@ boolean P_MoveChaseCamera(player_t *player, camera_t *thiscam, boolean resetcall if (player->powers[pw_carry] == CR_ROLLOUT) shift = -shift; + if (player->powers[pw_carry] == CR_NIGHTSMODE) + { + fixed_t cos = FINECOSINE((angle_t) (player->flyangle * ANG1)>>ANGLETOFINESHIFT); + shift = FixedMul(shift, min(FRACUNIT, player->speed*abs(cos)/6000)); + } + if (ticcmd_centerviewdown[(thiscam == &camera) ? 0 : 1]) shift = FixedMul(camsideshift[forplayer], FRACUNIT-camspeed); else From fdc3347e2229c221debba4419463be9c3c44456e Mon Sep 17 00:00:00 2001 From: fickleheart Date: Fri, 13 Dec 2019 20:19:38 -0600 Subject: [PATCH 187/746] More turn-to-angle changes --- src/g_game.c | 5 +---- src/p_user.c | 2 +- 2 files changed, 2 insertions(+), 5 deletions(-) diff --git a/src/g_game.c b/src/g_game.c index ff330278a..20b9a656e 100644 --- a/src/g_game.c +++ b/src/g_game.c @@ -1571,10 +1571,7 @@ void G_BuildTiccmd(ticcmd_t *cmd, INT32 realtics, UINT8 ssplayer) if (camadjustfactor) { - INT32 anglediff = - // This check to potentially use angleturn fixes the judder when holding back in the air to brake - ((alt && (forward || side) && !P_IsObjectOnGround(player->mo)) ? (cmd->angleturn<<16) : player->drawangle) - + drawangleoffset - *myangle; + INT32 anglediff = (cmd->angleturn<<16) + drawangleoffset - *myangle; if (alt) { diff --git a/src/p_user.c b/src/p_user.c index 835fe7f67..93c3c2ef0 100644 --- a/src/p_user.c +++ b/src/p_user.c @@ -10016,7 +10016,7 @@ boolean P_MoveChaseCamera(player_t *player, camera_t *thiscam, boolean resetcall { // Shift the camera slightly to the sides depending on the player facing direction UINT8 forplayer = (thiscam == &camera) ? 0 : 1; - fixed_t shift = FixedMul(FINESINE((player->drawangle - angle) >> ANGLETOFINESHIFT), cv_cam_shiftfacing[forplayer].value); + fixed_t shift = FixedMul(FINESINE((player->mo->angle - angle) >> ANGLETOFINESHIFT), cv_cam_shiftfacing[forplayer].value); if (player->powers[pw_carry] == CR_ROLLOUT) shift = -shift; From 097fc48f52181c30a52ea943e5270f87b1414ffd Mon Sep 17 00:00:00 2001 From: fickleheart Date: Fri, 13 Dec 2019 20:30:56 -0600 Subject: [PATCH 188/746] Even MORE tta changes: - All automatic turning is suspended upon manual rotation - Dest angle uses drawangle again for rolling only --- src/g_game.c | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/src/g_game.c b/src/g_game.c index 20b9a656e..c3f4be3cd 100644 --- a/src/g_game.c +++ b/src/g_game.c @@ -1561,17 +1561,19 @@ void G_BuildTiccmd(ticcmd_t *cmd, INT32 realtics, UINT8 ssplayer) else { alt = true; - camadjustfactor = FixedMul(cv_cam_turnfacing[forplayer].value/8, tta_factor[forplayer]); + camadjustfactor = cv_cam_turnfacing[forplayer].value/8; } - if (tta_factor[forplayer] < FRACUNIT && (!alt || cmd->forwardmove || cmd->sidemove || tta_factor[forplayer] >= FRACUNIT/3)) + camadjustfactor = FixedMul(camadjustfactor, tta_factor[forplayer]); + + if (tta_factor[forplayer] < FRACUNIT && (cmd->forwardmove || cmd->sidemove || tta_factor[forplayer] >= FRACUNIT/3)) tta_factor[forplayer] += FRACUNIT>>5; else if (tta_factor[forplayer] && tta_factor[forplayer] < FRACUNIT/3) tta_factor[forplayer] -= FRACUNIT>>5; if (camadjustfactor) { - INT32 anglediff = (cmd->angleturn<<16) + drawangleoffset - *myangle; + INT32 anglediff = ((player->pflags & PF_SPINNING) ? player->drawangle : (cmd->angleturn<<16)) + drawangleoffset - *myangle; if (alt) { From 252b77c6519e106d03658a5de79968d928326db7 Mon Sep 17 00:00:00 2001 From: fickleheart Date: Fri, 13 Dec 2019 22:30:04 -0600 Subject: [PATCH 189/746] Scale angle-related camera turns by player speed They also operate at full when idle, too. --- src/g_game.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/g_game.c b/src/g_game.c index c3f4be3cd..c85a291fe 100644 --- a/src/g_game.c +++ b/src/g_game.c @@ -1564,6 +1564,8 @@ void G_BuildTiccmd(ticcmd_t *cmd, INT32 realtics, UINT8 ssplayer) camadjustfactor = cv_cam_turnfacing[forplayer].value/8; } + camadjustfactor = FixedMul(camadjustfactor, max(FRACUNIT - player->speed, min(player->speed/18, FRACUNIT))); + camadjustfactor = FixedMul(camadjustfactor, tta_factor[forplayer]); if (tta_factor[forplayer] < FRACUNIT && (cmd->forwardmove || cmd->sidemove || tta_factor[forplayer] >= FRACUNIT/3)) From bc2ed5262581ebcf877c156b4b21fe658203fce6 Mon Sep 17 00:00:00 2001 From: fickleheart Date: Fri, 13 Dec 2019 22:55:34 -0600 Subject: [PATCH 190/746] Double sensitivity and halve default of turn to input --- src/g_game.c | 11 ++++------- 1 file changed, 4 insertions(+), 7 deletions(-) diff --git a/src/g_game.c b/src/g_game.c index c85a291fe..6b5eff4ad 100644 --- a/src/g_game.c +++ b/src/g_game.c @@ -417,8 +417,8 @@ consvar_t cv_cam_turnfacingspindash[2] = { {"cam2_turnfacingspindash", "0.25", CV_FLOAT|CV_SAVE, zerotoone_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL}, }; consvar_t cv_cam_turnfacinginput[2] = { - {"cam_turnfacinginput", "0.4375", CV_FLOAT|CV_SAVE, zerotoone_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL}, - {"cam2_turnfacinginput", "0.4375", CV_FLOAT|CV_SAVE, zerotoone_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL}, + {"cam_turnfacinginput", "0.25", CV_FLOAT|CV_SAVE, zerotoone_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL}, + {"cam2_turnfacinginput", "0.25", CV_FLOAT|CV_SAVE, zerotoone_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL}, }; static CV_PossibleValue_t lockedinput_cons_t[] = {{0, "Strafe"}, {1, "Turn"}, {0, NULL}}; @@ -1509,15 +1509,12 @@ void G_BuildTiccmd(ticcmd_t *cmd, INT32 realtics, UINT8 ssplayer) // Adjust camera angle by player input if (abilitydirection && !forcestrafe && camera.chase && !turnheld[forplayer] && !ticcmd_centerviewdown[forplayer] && !player->climbing && player->powers[pw_carry] != CR_MINECART) { - fixed_t camadjustfactor = cv_cam_turnfacinginput[forplayer].value; //@TODO cvar + fixed_t camadjustfactor = cv_cam_turnfacinginput[forplayer].value; if (camadjustfactor) { fixed_t sine = FINESINE((R_PointToAngle2(0, 0, player->rmomx, player->rmomy) - localangle)>>ANGLETOFINESHIFT); - fixed_t factor = min(20, FixedMul(player->speed, abs(sine)) / FRACUNIT); - - if (ticcmd_centerviewdown[forplayer] && (cv_cam_lockedinput[forplayer].value || (player->pflags & PF_STARTDASH))) - factor = (ssplayer == 1 ? cv_cam_rotspeed.value : cv_cam2_rotspeed.value) * (cv_cam_lockedinput[forplayer].value ?: 1); // Turn while in startdash and locking camera + fixed_t factor = min(40, FixedMul(player->speed, abs(sine))*2 / FRACUNIT); *myangle -= cmd->sidemove * factor * camadjustfactor; } From 0047dba279490ba65f5212188d64e4f4a1b6dac3 Mon Sep 17 00:00:00 2001 From: fickleheart Date: Fri, 13 Dec 2019 23:05:36 -0600 Subject: [PATCH 191/746] Fix float cvars saving wrong when set to max --- src/command.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/src/command.c b/src/command.c index 33d8ead96..889ea3f02 100644 --- a/src/command.c +++ b/src/command.c @@ -2060,7 +2060,12 @@ void CV_SaveVariables(FILE *f) // Silly hack for Min/Max vars if (!strcmp(cvar->string, "MAX") || !strcmp(cvar->string, "MIN")) - sprintf(stringtowrite, "%d", cvar->value); + { + if (cvar->flags & CV_FLOAT) + sprintf(stringtowrite, "%f", FIXED_TO_FLOAT(cvar->value)); + else + sprintf(stringtowrite, "%d", cvar->value); + } else strcpy(stringtowrite, cvar->string); From 2a22adaa601d71b3abe0180332e05e5a3de330ef Mon Sep 17 00:00:00 2001 From: James R Date: Sat, 14 Dec 2019 12:55:11 -0800 Subject: [PATCH 192/746] Oops C90 --- src/v_video.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/v_video.c b/src/v_video.c index dad8e8513..c6ec22767 100644 --- a/src/v_video.c +++ b/src/v_video.c @@ -311,11 +311,12 @@ const UINT8 correctiontable[256] = // keep a copy of the palette so that we can get the RGB value for a color index at any time. static void LoadPalette(const char *lumpname) { - Cubeapply = InitCube(); lumpnum_t lumpnum = W_GetNumForName(lumpname); size_t i, palsize = W_LumpLength(lumpnum)/3; UINT8 *pal; + Cubeapply = InitCube(); + Z_Free(pLocalPalette); Z_Free(pMasterPalette); From 87b816e408fec280637957af9e08bd1f20bbceb6 Mon Sep 17 00:00:00 2001 From: Zachary McAlpin Date: Sat, 14 Dec 2019 15:28:24 -0600 Subject: [PATCH 193/746] Added PlayerThink hook --- src/lua_hook.h | 2 ++ src/lua_hooklib.c | 2 ++ src/p_user.c | 23 ++++++++++++++++++++++- 3 files changed, 26 insertions(+), 1 deletion(-) diff --git a/src/lua_hook.h b/src/lua_hook.h index 6617bca93..073773f52 100644 --- a/src/lua_hook.h +++ b/src/lua_hook.h @@ -51,6 +51,7 @@ enum hook { hook_PlayerCanDamage, hook_PlayerQuit, hook_IntermissionThinker, + hook_PlayerThink, hook_MAX // last hook }; @@ -93,5 +94,6 @@ boolean LUAh_FollowMobj(player_t *player, mobj_t *mobj); // Hook for P_PlayerAft UINT8 LUAh_PlayerCanDamage(player_t *player, mobj_t *mobj); // Hook for P_PlayerCanDamage void LUAh_PlayerQuit(player_t *plr, int reason); // Hook for player quitting void LUAh_IntermissionThinker(void); // Hook for Y_Ticker +#define LUAh_PlayerThink(player) LUAh_PlayerHook(player, hook_PlayerThink) // Hook for P_PlayerThink #endif diff --git a/src/lua_hooklib.c b/src/lua_hooklib.c index ef87d0b6f..30ab27da1 100644 --- a/src/lua_hooklib.c +++ b/src/lua_hooklib.c @@ -62,6 +62,7 @@ const char *const hookNames[hook_MAX+1] = { "PlayerCanDamage", "PlayerQuit", "IntermissionThinker", + "PlayerThink", NULL }; @@ -205,6 +206,7 @@ static int lib_addHook(lua_State *L) case hook_PlayerCanDamage: case hook_ShieldSpawn: case hook_ShieldSpecial: + case hook_PlayerThink: lastp = &playerhooks; break; case hook_LinedefExecute: diff --git a/src/p_user.c b/src/p_user.c index ea42a2c36..6b9cde62a 100644 --- a/src/p_user.c +++ b/src/p_user.c @@ -11313,7 +11313,12 @@ void P_PlayerThink(player_t *player) player->playerstate = PST_REBORN; } if (player->playerstate == PST_REBORN) + { +#ifdef HAVE_BLUA + LUAh_PlayerThink(player); +#endif return; + } } #ifdef SEENAMES @@ -11414,7 +11419,12 @@ void P_PlayerThink(player_t *player) player->lives = 0; if (player->playerstate == PST_DEAD) + { +#ifdef HAVE_BLUA + LUAh_PlayerThink(player); return; +#endif + } } } @@ -11533,7 +11543,9 @@ void P_PlayerThink(player_t *player) { player->mo->flags2 &= ~MF2_SHADOW; P_DeathThink(player); - +#ifdef HAVE_BLUA + LUAh_PlayerThink(player); +#endif return; } @@ -11574,7 +11586,12 @@ void P_PlayerThink(player_t *player) if (player->spectator && cmd->buttons & BT_ATTACK && !player->powers[pw_flashing] && G_GametypeHasSpectators()) { if (P_SpectatorJoinGame(player)) + { +#ifdef HAVE_BLUA + LUAh_PlayerThink(player); +#endif return; // player->mo was removed. + } } // Even if not NiGHTS, pull in nearby objects when walking around as John Q. Elliot. @@ -11675,6 +11692,10 @@ void P_PlayerThink(player_t *player) P_MovePlayer(player); } +#ifdef HAVE_BLUA + LUAh_PlayerThink(player); +#endif + if (!player->mo) return; // P_MovePlayer removed player->mo. From c1d54007e4f5c8386a6ac02edb5c5259a812c567 Mon Sep 17 00:00:00 2001 From: James R Date: Sat, 14 Dec 2019 13:30:10 -0800 Subject: [PATCH 194/746] Fix C90 error from NOHW --- src/w_wad.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/w_wad.c b/src/w_wad.c index 801f50edd..950294b1f 100644 --- a/src/w_wad.c +++ b/src/w_wad.c @@ -1516,8 +1516,8 @@ void *W_CachePatchNumPwad(UINT16 wad, UINT16 lump, INT32 tag) #ifdef HWRENDER // Software-only compile cache the data without conversion if (rendermode == render_soft || rendermode == render_none) - { #endif + { lumpcache_t *lumpcache = wadfiles[wad]->patchcache; if (!lumpcache[lump]) { @@ -1551,8 +1551,8 @@ void *W_CachePatchNumPwad(UINT16 wad, UINT16 lump, INT32 tag) Z_ChangeTag(lumpcache[lump], tag); return lumpcache[lump]; -#ifdef HWRENDER } +#ifdef HWRENDER grPatch = HWR_GetCachedGLPatchPwad(wad, lump); From 4d87bcca1375ecf1b91f0a59aa16d83a3345a64a Mon Sep 17 00:00:00 2001 From: Jaime Passos Date: Sat, 14 Dec 2019 19:50:40 -0300 Subject: [PATCH 195/746] Move position of R_PlaneRipple in the file so this looks more organised --- src/r_plane.c | 26 ++++++++++++++++---------- 1 file changed, 16 insertions(+), 10 deletions(-) diff --git a/src/r_plane.c b/src/r_plane.c index 88214d5f7..3214fa23d 100644 --- a/src/r_plane.c +++ b/src/r_plane.c @@ -117,17 +117,10 @@ void R_InitPlanes(void) } // -// R_MapPlane +// Water ripple effect!! +// Needs the height of the plane, and the vertical position of the span. +// Sets ripple_xfrac and ripple_yfrac, added to ds_xfrac and ds_yfrac, if the span is not tilted. // -// Uses global vars: -// basexscale -// baseyscale -// centerx -// viewx -// viewy -// viewsin -// viewcos -// viewheight #ifndef NOWATER INT32 ds_bgofs; @@ -152,6 +145,19 @@ static void R_PlaneRipple(visplane_t *plane, INT32 y, fixed_t plheight) } #endif +// +// R_MapPlane +// +// Uses global vars: +// basexscale +// baseyscale +// centerx +// viewx +// viewy +// viewsin +// viewcos +// viewheight + void R_MapPlane(INT32 y, INT32 x1, INT32 x2) { angle_t angle, planecos, planesin; From bcfd9fe504464c8186e4c1ca2d83e5b3bb44d8d3 Mon Sep 17 00:00:00 2001 From: MascaraSnake Date: Sun, 15 Dec 2019 00:22:17 +0100 Subject: [PATCH 196/746] Cleaned up GetMobjSpawnHeight a bit. Ring-likes no longer ignore MF_SPAWNCEILING, because why should they? --- src/p_mobj.c | 48 +++++++++++++++++++++--------------------------- 1 file changed, 21 insertions(+), 27 deletions(-) diff --git a/src/p_mobj.c b/src/p_mobj.c index ed12407ff..9af9f8791 100644 --- a/src/p_mobj.c +++ b/src/p_mobj.c @@ -11551,18 +11551,16 @@ mapthing_t *huntemeralds[MAXHUNTEMERALDS]; INT32 numhuntemeralds; -static fixed_t GetMobjSpawnHeight (const mobjtype_t i, const mapthing_t* mthing, const fixed_t x, const fixed_t y) +static fixed_t P_GetMobjSpawnHeight(const mobjtype_t mobjtype, const mapthing_t* mthing, const fixed_t x, const fixed_t y) { - subsector_t *ss = R_PointInSubsector(x, y); - fixed_t extraoffset = 0; - fixed_t heightoffset = 0; - boolean flip; + const subsector_t *ss = R_PointInSubsector(x, y); + fixed_t offset = mthing->z << FRACBITS; + boolean flip = (!!(mobjinfo[mobjtype].flags & MF_SPAWNCEILING) ^ !!(mthing->options & MTF_OBJECTFLIP)); - switch (i) + switch (mobjtype) { // Bumpers never spawn flipped. case MT_NIGHTSBUMPER: - heightoffset = mthing->z*FRACUNIT; flip = false; break; @@ -11578,38 +11576,34 @@ static fixed_t GetMobjSpawnHeight (const mobjtype_t i, const mapthing_t* mthing, case MT_JETTBOMBER: case MT_JETTGUNNER: case MT_EGGMOBILE2: - heightoffset = mthing->z ? 0 : 33*FRACUNIT; - goto atend; + if (!offset) + offset = 33*FRACUNIT; + break; case MT_EGGMOBILE: - heightoffset = mthing->z ? 0 : 128*FRACUNIT; - goto atend; + if (!offset) + offset = 128*FRACUNIT; + break; case MT_GOLDBUZZ: case MT_REDBUZZ: - heightoffset = mthing->z ? 0 : 288*FRACUNIT; - goto atend; + if (!offset) + offset = 288*FRACUNIT; + break; // Ring-like items, may float additional units with MTF_AMBUSH. case MT_SPIKEBALL: case MT_EMERALDSPAWN: case MT_TOKEN: case MT_EMBLEM: - weaponfloat: - flip = mthing->options & MTF_OBJECTFLIP; - extraoffset = mthing->options & MTF_AMBUSH ? 24*FRACUNIT : 0; - heightoffset = mthing->z*FRACUNIT; + offset += mthing->options & MTF_AMBUSH ? 24*FRACUNIT : 0; break; // Remaining objects. default: - if (P_WeaponOrPanel(i)) - goto weaponfloat; // Ring-like items don't use MF_SPAWNCEILING to consider flips. - - atend: - heightoffset = mthing->z*FRACUNIT; - flip = (!!(mobjinfo[i].flags & MF_SPAWNCEILING) ^ !!(mthing->options & MTF_OBJECTFLIP)); + if (P_WeaponOrPanel(mobjtype)) + offset += mthing->options & MTF_AMBUSH ? 24 * FRACUNIT : 0; } - if (heightoffset + extraoffset == 0) // Snap to the surfaces when there's no offset set. + if (!offset) // Snap to the surfaces when there's no offset set. { if (flip) return ONCEILINGZ; @@ -11623,13 +11617,13 @@ static fixed_t GetMobjSpawnHeight (const mobjtype_t i, const mapthing_t* mthing, #ifdef ESLOPE ss->sector->c_slope ? P_GetZAt(ss->sector->c_slope, x, y) : #endif - ss->sector->ceilingheight) - extraoffset - heightoffset - mobjinfo[i].height; + ss->sector->ceilingheight) - offset - mobjinfo[mobjtype].height; else return ( #ifdef ESLOPE ss->sector->f_slope ? P_GetZAt(ss->sector->f_slope, x, y) : #endif - ss->sector->floorheight) + extraoffset + heightoffset; + ss->sector->floorheight) + offset; } // @@ -11894,7 +11888,7 @@ You should think about modifying the deathmatch starts to take full advantage of // spawn it x = mthing->x << FRACBITS; y = mthing->y << FRACBITS; - z = GetMobjSpawnHeight(i, mthing, x, y); + z = P_GetMobjSpawnHeight(i, mthing, x, y); mobj = P_SpawnMobj(x, y, z, i); mobj->spawnpoint = mthing; From a812ddd88e5642b5a0033f062e8478d2fd2c8f3a Mon Sep 17 00:00:00 2001 From: fickleheart Date: Sat, 14 Dec 2019 19:04:29 -0600 Subject: [PATCH 197/746] Fix turn-to-input jerk when braking sideways --- src/g_game.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/g_game.c b/src/g_game.c index 6b5eff4ad..b91e0a797 100644 --- a/src/g_game.c +++ b/src/g_game.c @@ -1514,6 +1514,10 @@ void G_BuildTiccmd(ticcmd_t *cmd, INT32 realtics, UINT8 ssplayer) if (camadjustfactor) { fixed_t sine = FINESINE((R_PointToAngle2(0, 0, player->rmomx, player->rmomy) - localangle)>>ANGLETOFINESHIFT); + + if ((sine > 0) == (cmd->sidemove > 0)) + sine = 0; // Prevent jerking right when braking from going left, or vice versa + fixed_t factor = min(40, FixedMul(player->speed, abs(sine))*2 / FRACUNIT); *myangle -= cmd->sidemove * factor * camadjustfactor; From 0702e366b61a1da58ba8024719349c8daffc9eef Mon Sep 17 00:00:00 2001 From: fickleheart Date: Sat, 14 Dec 2019 19:17:41 -0600 Subject: [PATCH 198/746] Allow setting center view to a toggle --- src/d_netcmd.c | 2 ++ src/g_game.c | 30 +++++++++++++++++++++++++++--- src/g_game.h | 2 +- src/m_menu.c | 18 ++++++++++-------- 4 files changed, 40 insertions(+), 12 deletions(-) diff --git a/src/d_netcmd.c b/src/d_netcmd.c index d05c5cc45..3574f2e90 100644 --- a/src/d_netcmd.c +++ b/src/d_netcmd.c @@ -838,6 +838,8 @@ void D_RegisterClientCommands(void) CV_RegisterVar(&cv_cam_turnfacingspindash[1]); CV_RegisterVar(&cv_cam_turnfacinginput[0]); CV_RegisterVar(&cv_cam_turnfacinginput[1]); + CV_RegisterVar(&cv_cam_centertoggle[0]); + CV_RegisterVar(&cv_cam_centertoggle[1]); CV_RegisterVar(&cv_cam_lockedinput[0]); CV_RegisterVar(&cv_cam_lockedinput[1]); CV_RegisterVar(&cv_cam_lockonboss[0]); diff --git a/src/g_game.c b/src/g_game.c index b91e0a797..6fed500b3 100644 --- a/src/g_game.c +++ b/src/g_game.c @@ -421,8 +421,13 @@ consvar_t cv_cam_turnfacinginput[2] = { {"cam2_turnfacinginput", "0.25", CV_FLOAT|CV_SAVE, zerotoone_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL}, }; -static CV_PossibleValue_t lockedinput_cons_t[] = {{0, "Strafe"}, {1, "Turn"}, {0, NULL}}; +static CV_PossibleValue_t centertoggle_cons_t[] = {{0, "Hold"}, {1, "Toggle"}, {0, NULL}}; +consvar_t cv_cam_centertoggle[2] = { + {"cam_centertoggle", "Hold", CV_SAVE, centertoggle_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL}, + {"cam2_centertoggle", "Hold", CV_SAVE, centertoggle_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL}, +}; +static CV_PossibleValue_t lockedinput_cons_t[] = {{0, "Strafe"}, {1, "Turn"}, {0, NULL}}; consvar_t cv_cam_lockedinput[2] = { {"cam_lockedinput", "Strafe", CV_SAVE, lockedinput_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL}, {"cam2_lockedinput", "Strafe", CV_SAVE, lockedinput_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL}, @@ -436,7 +441,6 @@ static CV_PossibleValue_t lockedassist_cons_t[] = { {LOCK_BOSS|LOCK_ENEMY|LOCK_INTERESTS, "Full"}, {0, NULL} }; - consvar_t cv_cam_lockonboss[2] = { {"cam_lockaimassist", "Bosses", CV_SAVE, lockedassist_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL}, {"cam2_lockaimassist", "Bosses", CV_SAVE, lockedassist_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL}, @@ -1057,8 +1061,12 @@ void G_BuildTiccmd(ticcmd_t *cmd, INT32 realtics, UINT8 ssplayer) static boolean keyboard_look[2]; // true if lookup/down using keyboard static boolean resetdown[2]; // don't cam reset every frame static boolean joyaiming[2]; // check the last frame's value if we need to reset the camera + + // simple mode vars static boolean zchange[2]; // only switch z targets once per press static fixed_t tta_factor[2] = {FRACUNIT, FRACUNIT}; // disables turn-to-angle when manually turning camera until movement happens + boolean centerviewdown = false; + UINT8 forplayer = ssplayer-1; if (ssplayer == 1) @@ -1291,7 +1299,23 @@ void G_BuildTiccmd(ticcmd_t *cmd, INT32 realtics, UINT8 ssplayer) if (PLAYERINPUTDOWN(ssplayer, gc_use) || (usejoystick && axis > 0)) cmd->buttons |= BT_USE; - if (PLAYERINPUTDOWN(ssplayer, gc_centerview)) + // Centerview can be a toggle in simple mode! + { + static boolean last_centerviewdown[2], centerviewhold[2]; // detect taps for toggle behavior + boolean down = PLAYERINPUTDOWN(ssplayer, gc_centerview); + + if (!(abilitydirection && cv_cam_centertoggle[forplayer].value)) + centerviewdown = down; + else + { + if (down && !last_centerviewdown[forplayer]) + centerviewhold[forplayer] = !centerviewhold[forplayer]; + last_centerviewdown[forplayer] = down; + centerviewdown = centerviewhold[forplayer]; + } + } + + if (centerviewdown) { if (abilitydirection && !ticcmd_centerviewdown[forplayer]) { diff --git a/src/g_game.h b/src/g_game.h index 0a018e253..8ba3bc373 100644 --- a/src/g_game.h +++ b/src/g_game.h @@ -79,7 +79,7 @@ extern consvar_t cv_ghost_bestscore, cv_ghost_besttime, cv_ghost_bestrings, cv_g // hi here's some new controls extern consvar_t cv_abilitydirection[2], cv_cam_shiftfacing[2], cv_cam_turnfacing[2], cv_cam_turnfacingability[2], cv_cam_turnfacingspindash[2], cv_cam_turnfacinginput[2], - cv_cam_lockedinput[2], cv_cam_lockonboss[2]; + cv_cam_centertoggle[2], cv_cam_lockedinput[2], cv_cam_lockonboss[2]; typedef enum { diff --git a/src/m_menu.c b/src/m_menu.c index bfe118af1..fb1737f10 100644 --- a/src/m_menu.c +++ b/src/m_menu.c @@ -1238,11 +1238,12 @@ static menuitem_t OP_CameraExtendedOptionsMenu[] = {IT_STRING | IT_CVAR | IT_CV_SLIDER, NULL, "Turn to input", &cv_cam_turnfacinginput[0], 85}, {IT_HEADER, NULL, "Locked Camera Options", NULL, 95}, - {IT_STRING | IT_CVAR, NULL, "Sideways movement", &cv_cam_lockedinput[0], 100}, - {IT_STRING | IT_CVAR, NULL, "Targeting assist", &cv_cam_lockonboss[0], 105}, + {IT_STRING | IT_CVAR, NULL, "Lock button behavior", &cv_cam_centertoggle[0], 100}, + {IT_STRING | IT_CVAR, NULL, "Sideways movement", &cv_cam_lockedinput[0], 105}, + {IT_STRING | IT_CVAR, NULL, "Targeting assist", &cv_cam_lockonboss[0], 110}, - {IT_HEADER, NULL, "Display Options", NULL, 115}, - {IT_STRING | IT_CVAR, NULL, "Crosshair", &cv_crosshair, 120}, + {IT_HEADER, NULL, "Display Options", NULL, 120}, + {IT_STRING | IT_CVAR, NULL, "Crosshair", &cv_crosshair, 125}, }; static menuitem_t OP_Camera2ExtendedOptionsMenu[] = @@ -1267,11 +1268,12 @@ static menuitem_t OP_Camera2ExtendedOptionsMenu[] = {IT_STRING | IT_CVAR | IT_CV_SLIDER, NULL, "Turn to input", &cv_cam_turnfacinginput[1], 85}, {IT_HEADER, NULL, "Locked Camera Options", NULL, 95}, - {IT_STRING | IT_CVAR, NULL, "Sideways movement", &cv_cam_lockedinput[1], 100}, - {IT_STRING | IT_CVAR, NULL, "Targeting assist", &cv_cam_lockonboss[1], 105}, + {IT_STRING | IT_CVAR, NULL, "Lock button behavior", &cv_cam_centertoggle[1], 100}, + {IT_STRING | IT_CVAR, NULL, "Sideways movement", &cv_cam_lockedinput[1], 105}, + {IT_STRING | IT_CVAR, NULL, "Targeting assist", &cv_cam_lockonboss[1], 110}, - {IT_HEADER, NULL, "Display Options", NULL, 115}, - {IT_STRING | IT_CVAR, NULL, "Crosshair", &cv_crosshair2, 120}, + {IT_HEADER, NULL, "Display Options", NULL, 120}, + {IT_STRING | IT_CVAR, NULL, "Crosshair", &cv_crosshair2, 125}, }; static menuitem_t OP_VideoOptionsMenu[] = From 7fd2153c0887c3b35d1e776860b5f0b6ba88258b Mon Sep 17 00:00:00 2001 From: fickleheart Date: Sat, 14 Dec 2019 19:20:19 -0600 Subject: [PATCH 199/746] Realign camera options menu options --- src/m_menu.c | 104 +++++++++++++++++++++++++-------------------------- 1 file changed, 52 insertions(+), 52 deletions(-) diff --git a/src/m_menu.c b/src/m_menu.c index fb1737f10..89c0b04bd 100644 --- a/src/m_menu.c +++ b/src/m_menu.c @@ -1183,97 +1183,97 @@ static menuitem_t OP_Mouse2OptionsMenu[] = static menuitem_t OP_CameraOptionsMenu[] = { {IT_HEADER, NULL, "General Toggles", NULL, 0}, - {IT_STRING | IT_CVAR, NULL, "Third-person Camera" , &cv_chasecam , 5}, - {IT_STRING | IT_CVAR, NULL, "Flip Camera with Gravity" , &cv_flipcam , 10}, - {IT_STRING | IT_CVAR, NULL, "Orbital Looking" , &cv_cam_orbit , 15}, - {IT_STRING | IT_CVAR, NULL, "Downhill Slope Adjustment", &cv_cam_adjust, 20}, + {IT_STRING | IT_CVAR, NULL, "Third-person Camera" , &cv_chasecam , 6}, + {IT_STRING | IT_CVAR, NULL, "Flip Camera with Gravity" , &cv_flipcam , 11}, + {IT_STRING | IT_CVAR, NULL, "Orbital Looking" , &cv_cam_orbit , 16}, + {IT_STRING | IT_CVAR, NULL, "Downhill Slope Adjustment", &cv_cam_adjust, 21}, {IT_HEADER, NULL, "Camera Positioning", NULL, 30}, - {IT_STRING | IT_CVAR | IT_CV_INTEGERSTEP, NULL, "Camera Distance", &cv_cam_dist, 35}, - {IT_STRING | IT_CVAR | IT_CV_INTEGERSTEP, NULL, "Camera Height", &cv_cam_height, 40}, - {IT_STRING | IT_CVAR | IT_CV_FLOATSLIDER, NULL, "Camera Speed", &cv_cam_speed, 45}, - {IT_STRING | IT_CVAR | IT_CV_SLIDER, NULL, "Rotation Speed", &cv_cam_rotspeed, 50}, + {IT_STRING | IT_CVAR | IT_CV_INTEGERSTEP, NULL, "Camera Distance", &cv_cam_dist, 36}, + {IT_STRING | IT_CVAR | IT_CV_INTEGERSTEP, NULL, "Camera Height", &cv_cam_height, 41}, + {IT_STRING | IT_CVAR | IT_CV_FLOATSLIDER, NULL, "Camera Speed", &cv_cam_speed, 46}, + {IT_STRING | IT_CVAR | IT_CV_SLIDER, NULL, "Rotation Speed", &cv_cam_rotspeed, 51}, {IT_HEADER, NULL, "Display Options", NULL, 60}, - {IT_STRING | IT_CVAR, NULL, "Crosshair", &cv_crosshair, 65}, + {IT_STRING | IT_CVAR, NULL, "Crosshair", &cv_crosshair, 66}, }; static menuitem_t OP_Camera2OptionsMenu[] = { {IT_HEADER, NULL, "General Toggles", NULL, 0}, - {IT_STRING | IT_CVAR, NULL, "Third-person Camera" , &cv_chasecam2 , 5}, - {IT_STRING | IT_CVAR, NULL, "Flip Camera with Gravity" , &cv_flipcam2 , 10}, - {IT_STRING | IT_CVAR, NULL, "Orbital Looking" , &cv_cam2_orbit , 15}, - {IT_STRING | IT_CVAR, NULL, "Downhill Slope Adjustment", &cv_cam2_adjust, 20}, + {IT_STRING | IT_CVAR, NULL, "Third-person Camera" , &cv_chasecam2 , 6}, + {IT_STRING | IT_CVAR, NULL, "Flip Camera with Gravity" , &cv_flipcam2 , 11}, + {IT_STRING | IT_CVAR, NULL, "Orbital Looking" , &cv_cam2_orbit , 16}, + {IT_STRING | IT_CVAR, NULL, "Downhill Slope Adjustment", &cv_cam2_adjust, 21}, {IT_HEADER, NULL, "Camera Positioning", NULL, 30}, - {IT_STRING | IT_CVAR | IT_CV_INTEGERSTEP, NULL, "Camera Distance", &cv_cam2_dist, 35}, - {IT_STRING | IT_CVAR | IT_CV_INTEGERSTEP, NULL, "Camera Height", &cv_cam2_height, 40}, - {IT_STRING | IT_CVAR | IT_CV_FLOATSLIDER, NULL, "Camera Speed", &cv_cam2_speed, 45}, - {IT_STRING | IT_CVAR | IT_CV_SLIDER, NULL, "Rotation Speed", &cv_cam2_rotspeed, 50}, + {IT_STRING | IT_CVAR | IT_CV_INTEGERSTEP, NULL, "Camera Distance", &cv_cam2_dist, 36}, + {IT_STRING | IT_CVAR | IT_CV_INTEGERSTEP, NULL, "Camera Height", &cv_cam2_height, 41}, + {IT_STRING | IT_CVAR | IT_CV_FLOATSLIDER, NULL, "Camera Speed", &cv_cam2_speed, 46}, + {IT_STRING | IT_CVAR | IT_CV_SLIDER, NULL, "Rotation Speed", &cv_cam2_rotspeed, 51}, {IT_HEADER, NULL, "Display Options", NULL, 60}, - {IT_STRING | IT_CVAR, NULL, "Crosshair", &cv_crosshair2, 65}, + {IT_STRING | IT_CVAR, NULL, "Crosshair", &cv_crosshair2, 66}, }; static menuitem_t OP_CameraExtendedOptionsMenu[] = { {IT_HEADER, NULL, "General Toggles", NULL, 0}, - {IT_STRING | IT_CVAR, NULL, "Third-person Camera" , &cv_chasecam , 5}, - {IT_STRING | IT_CVAR, NULL, "Flip Camera with Gravity" , &cv_flipcam , 10}, - {IT_STRING | IT_CVAR, NULL, "Orbital Looking" , &cv_cam_orbit , 15}, - {IT_STRING | IT_CVAR, NULL, "Downhill Slope Adjustment", &cv_cam_adjust, 20}, + {IT_STRING | IT_CVAR, NULL, "Third-person Camera" , &cv_chasecam , 6}, + {IT_STRING | IT_CVAR, NULL, "Flip Camera with Gravity" , &cv_flipcam , 11}, + {IT_STRING | IT_CVAR, NULL, "Orbital Looking" , &cv_cam_orbit , 16}, + {IT_STRING | IT_CVAR, NULL, "Downhill Slope Adjustment", &cv_cam_adjust, 21}, {IT_HEADER, NULL, "Camera Positioning", NULL, 30}, - {IT_STRING | IT_CVAR | IT_CV_INTEGERSTEP, NULL, "Camera Distance", &cv_cam_dist, 35}, - {IT_STRING | IT_CVAR | IT_CV_INTEGERSTEP, NULL, "Camera Height", &cv_cam_height, 40}, - {IT_STRING | IT_CVAR | IT_CV_FLOATSLIDER, NULL, "Camera Speed", &cv_cam_speed, 45}, - {IT_STRING | IT_CVAR | IT_CV_SLIDER, NULL, "Rotation Speed", &cv_cam_rotspeed, 50}, + {IT_STRING | IT_CVAR | IT_CV_INTEGERSTEP, NULL, "Camera Distance", &cv_cam_dist, 36}, + {IT_STRING | IT_CVAR | IT_CV_INTEGERSTEP, NULL, "Camera Height", &cv_cam_height, 41}, + {IT_STRING | IT_CVAR | IT_CV_FLOATSLIDER, NULL, "Camera Speed", &cv_cam_speed, 46}, + {IT_STRING | IT_CVAR | IT_CV_SLIDER, NULL, "Rotation Speed", &cv_cam_rotspeed, 51}, {IT_HEADER, NULL, "Automatic Camera Options", NULL, 60}, - {IT_STRING | IT_CVAR | IT_CV_SLIDER, NULL, "Shift to player angle", &cv_cam_shiftfacing[0], 65}, - {IT_STRING | IT_CVAR | IT_CV_SLIDER, NULL, "Turn to player angle", &cv_cam_turnfacing[0], 70}, - {IT_STRING | IT_CVAR | IT_CV_SLIDER, NULL, "Turn to ability", &cv_cam_turnfacingability[0], 75}, - {IT_STRING | IT_CVAR | IT_CV_SLIDER, NULL, "Turn to spindash", &cv_cam_turnfacingspindash[0], 80}, - {IT_STRING | IT_CVAR | IT_CV_SLIDER, NULL, "Turn to input", &cv_cam_turnfacinginput[0], 85}, + {IT_STRING | IT_CVAR | IT_CV_SLIDER, NULL, "Shift to player angle", &cv_cam_shiftfacing[0], 66}, + {IT_STRING | IT_CVAR | IT_CV_SLIDER, NULL, "Turn to player angle", &cv_cam_turnfacing[0], 71}, + {IT_STRING | IT_CVAR | IT_CV_SLIDER, NULL, "Turn to ability", &cv_cam_turnfacingability[0], 76}, + {IT_STRING | IT_CVAR | IT_CV_SLIDER, NULL, "Turn to spindash", &cv_cam_turnfacingspindash[0], 81}, + {IT_STRING | IT_CVAR | IT_CV_SLIDER, NULL, "Turn to input", &cv_cam_turnfacinginput[0], 86}, {IT_HEADER, NULL, "Locked Camera Options", NULL, 95}, - {IT_STRING | IT_CVAR, NULL, "Lock button behavior", &cv_cam_centertoggle[0], 100}, - {IT_STRING | IT_CVAR, NULL, "Sideways movement", &cv_cam_lockedinput[0], 105}, - {IT_STRING | IT_CVAR, NULL, "Targeting assist", &cv_cam_lockonboss[0], 110}, + {IT_STRING | IT_CVAR, NULL, "Lock button behavior", &cv_cam_centertoggle[0], 101}, + {IT_STRING | IT_CVAR, NULL, "Sideways movement", &cv_cam_lockedinput[0], 106}, + {IT_STRING | IT_CVAR, NULL, "Targeting assist", &cv_cam_lockonboss[0], 111}, {IT_HEADER, NULL, "Display Options", NULL, 120}, - {IT_STRING | IT_CVAR, NULL, "Crosshair", &cv_crosshair, 125}, + {IT_STRING | IT_CVAR, NULL, "Crosshair", &cv_crosshair, 126}, }; static menuitem_t OP_Camera2ExtendedOptionsMenu[] = { {IT_HEADER, NULL, "General Toggles", NULL, 0}, - {IT_STRING | IT_CVAR, NULL, "Third-person Camera" , &cv_chasecam2 , 5}, - {IT_STRING | IT_CVAR, NULL, "Flip Camera with Gravity" , &cv_flipcam2 , 10}, - {IT_STRING | IT_CVAR, NULL, "Orbital Looking" , &cv_cam2_orbit , 15}, - {IT_STRING | IT_CVAR, NULL, "Downhill Slope Adjustment", &cv_cam2_adjust, 20}, + {IT_STRING | IT_CVAR, NULL, "Third-person Camera" , &cv_chasecam2 , 6}, + {IT_STRING | IT_CVAR, NULL, "Flip Camera with Gravity" , &cv_flipcam2 , 11}, + {IT_STRING | IT_CVAR, NULL, "Orbital Looking" , &cv_cam2_orbit , 16}, + {IT_STRING | IT_CVAR, NULL, "Downhill Slope Adjustment", &cv_cam2_adjust, 21}, {IT_HEADER, NULL, "Camera Positioning", NULL, 30}, - {IT_STRING | IT_CVAR | IT_CV_INTEGERSTEP, NULL, "Camera Distance", &cv_cam2_dist, 35}, - {IT_STRING | IT_CVAR | IT_CV_INTEGERSTEP, NULL, "Camera Height", &cv_cam2_height, 40}, - {IT_STRING | IT_CVAR | IT_CV_FLOATSLIDER, NULL, "Camera Speed", &cv_cam2_speed, 45}, - {IT_STRING | IT_CVAR | IT_CV_SLIDER, NULL, "Rotation Speed", &cv_cam2_rotspeed, 50}, + {IT_STRING | IT_CVAR | IT_CV_INTEGERSTEP, NULL, "Camera Distance", &cv_cam2_dist, 36}, + {IT_STRING | IT_CVAR | IT_CV_INTEGERSTEP, NULL, "Camera Height", &cv_cam2_height, 41}, + {IT_STRING | IT_CVAR | IT_CV_FLOATSLIDER, NULL, "Camera Speed", &cv_cam2_speed, 46}, + {IT_STRING | IT_CVAR | IT_CV_SLIDER, NULL, "Rotation Speed", &cv_cam2_rotspeed, 51}, {IT_HEADER, NULL, "Automatic Camera Options", NULL, 60}, - {IT_STRING | IT_CVAR | IT_CV_SLIDER, NULL, "Shift to player angle", &cv_cam_shiftfacing[1], 65}, - {IT_STRING | IT_CVAR | IT_CV_SLIDER, NULL, "Turn to player angle", &cv_cam_turnfacing[1], 70}, - {IT_STRING | IT_CVAR | IT_CV_SLIDER, NULL, "Turn to ability", &cv_cam_turnfacingability[1], 75}, - {IT_STRING | IT_CVAR | IT_CV_SLIDER, NULL, "Turn to spindash", &cv_cam_turnfacingspindash[1], 80}, - {IT_STRING | IT_CVAR | IT_CV_SLIDER, NULL, "Turn to input", &cv_cam_turnfacinginput[1], 85}, + {IT_STRING | IT_CVAR | IT_CV_SLIDER, NULL, "Shift to player angle", &cv_cam_shiftfacing[1], 66}, + {IT_STRING | IT_CVAR | IT_CV_SLIDER, NULL, "Turn to player angle", &cv_cam_turnfacing[1], 71}, + {IT_STRING | IT_CVAR | IT_CV_SLIDER, NULL, "Turn to ability", &cv_cam_turnfacingability[1], 76}, + {IT_STRING | IT_CVAR | IT_CV_SLIDER, NULL, "Turn to spindash", &cv_cam_turnfacingspindash[1], 81}, + {IT_STRING | IT_CVAR | IT_CV_SLIDER, NULL, "Turn to input", &cv_cam_turnfacinginput[1], 86}, {IT_HEADER, NULL, "Locked Camera Options", NULL, 95}, - {IT_STRING | IT_CVAR, NULL, "Lock button behavior", &cv_cam_centertoggle[1], 100}, - {IT_STRING | IT_CVAR, NULL, "Sideways movement", &cv_cam_lockedinput[1], 105}, - {IT_STRING | IT_CVAR, NULL, "Targeting assist", &cv_cam_lockonboss[1], 110}, + {IT_STRING | IT_CVAR, NULL, "Lock button behavior", &cv_cam_centertoggle[1], 101}, + {IT_STRING | IT_CVAR, NULL, "Sideways movement", &cv_cam_lockedinput[1], 106}, + {IT_STRING | IT_CVAR, NULL, "Targeting assist", &cv_cam_lockonboss[1], 111}, {IT_HEADER, NULL, "Display Options", NULL, 120}, - {IT_STRING | IT_CVAR, NULL, "Crosshair", &cv_crosshair2, 125}, + {IT_STRING | IT_CVAR, NULL, "Crosshair", &cv_crosshair2, 126}, }; static menuitem_t OP_VideoOptionsMenu[] = From 3db7e48c73701dff825878cf881c5c49ae555eed Mon Sep 17 00:00:00 2001 From: fickleheart Date: Sat, 14 Dec 2019 19:21:11 -0600 Subject: [PATCH 200/746] [POTENTIALLY RISKY] Show target arrow above lock-on target My judgement on "is this netgame-safe" is "Gunslinger's targeting spawns this only for the local player, so maybe". --- src/g_game.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/g_game.c b/src/g_game.c index 6fed500b3..f0275bbf4 100644 --- a/src/g_game.c +++ b/src/g_game.c @@ -1371,6 +1371,10 @@ void G_BuildTiccmd(ticcmd_t *cmd, INT32 realtics, UINT8 ssplayer) if (newtarget) P_SetTarget(&ticcmd_ztargetfocus[forplayer], newtarget); + // I assume this is netgame-safe because gunslinger spawns this for only the local player...... *sweats intensely* + newtarget = P_SpawnMobj(ticcmd_ztargetfocus[forplayer]->x, ticcmd_ztargetfocus[forplayer]->y, ticcmd_ztargetfocus[forplayer]->z, MT_LOCKON); // positioning, flip handled in P_SceneryThinker + P_SetTarget(&newtarget->target, ticcmd_ztargetfocus[forplayer]); + if (P_AproxDistance( player->mo->x - ticcmd_ztargetfocus[forplayer]->x, player->mo->y - ticcmd_ztargetfocus[forplayer]->y From fce6ea03842e8ad0b9d90dbe3229dcbc327e3d76 Mon Sep 17 00:00:00 2001 From: Zachary McAlpin Date: Sat, 14 Dec 2019 19:32:49 -0600 Subject: [PATCH 201/746] Fixed mistake with #endif placement --- 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 22f92791a..3baf8cd04 100644 --- a/src/p_user.c +++ b/src/p_user.c @@ -11422,8 +11422,8 @@ void P_PlayerThink(player_t *player) { #ifdef HAVE_BLUA LUAh_PlayerThink(player); - return; #endif + return; } } } From a885380e8a8a5650ce8a0c5a10be48819dc7b872 Mon Sep 17 00:00:00 2001 From: fickleheart Date: Sat, 14 Dec 2019 19:41:54 -0600 Subject: [PATCH 202/746] Add analog deadzone option separate from digital deadzones --- src/d_netcmd.c | 2 ++ src/g_game.c | 14 ++++++++------ src/g_game.h | 4 ++-- src/m_menu.c | 6 ++++-- 4 files changed, 16 insertions(+), 10 deletions(-) diff --git a/src/d_netcmd.c b/src/d_netcmd.c index 3574f2e90..165c89b58 100644 --- a/src/d_netcmd.c +++ b/src/d_netcmd.c @@ -776,6 +776,8 @@ void D_RegisterClientCommands(void) CV_RegisterVar(&cv_firenaxis2); CV_RegisterVar(&cv_deadzone); CV_RegisterVar(&cv_deadzone2); + CV_RegisterVar(&cv_digitaldeadzone); + CV_RegisterVar(&cv_digitaldeadzone2); // filesrch.c CV_RegisterVar(&cv_addons_option); diff --git a/src/g_game.c b/src/g_game.c index f0275bbf4..d5cd0c991 100644 --- a/src/g_game.c +++ b/src/g_game.c @@ -468,7 +468,8 @@ consvar_t cv_jumpaxis = {"joyaxis_jump", "None", CV_SAVE, joyaxis_cons_t, NULL, consvar_t cv_spinaxis = {"joyaxis_spin", "None", CV_SAVE, joyaxis_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL}; consvar_t cv_fireaxis = {"joyaxis_fire", "Z-Axis-", CV_SAVE, joyaxis_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL}; consvar_t cv_firenaxis = {"joyaxis_firenormal", "Z-Axis", CV_SAVE, joyaxis_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL}; -consvar_t cv_deadzone = {"joy_deadzone", "0.25", CV_FLOAT|CV_SAVE, zerotoone_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL}; +consvar_t cv_deadzone = {"joy_deadzone", "0.125", CV_FLOAT|CV_SAVE, zerotoone_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL}; +consvar_t cv_digitaldeadzone = {"joy_digdeadzone", "0.25", CV_FLOAT|CV_SAVE, zerotoone_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL}; consvar_t cv_turnaxis2 = {"joyaxis2_turn", "X-Rudder", CV_SAVE, joyaxis_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL}; consvar_t cv_moveaxis2 = {"joyaxis2_move", "Y-Axis", CV_SAVE, joyaxis_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL}; @@ -478,7 +479,8 @@ consvar_t cv_jumpaxis2 = {"joyaxis2_jump", "None", CV_SAVE, joyaxis_cons_t, NULL consvar_t cv_spinaxis2 = {"joyaxis2_spin", "None", CV_SAVE, joyaxis_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL}; consvar_t cv_fireaxis2 = {"joyaxis2_fire", "Z-Axis-", CV_SAVE, joyaxis_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL}; consvar_t cv_firenaxis2 = {"joyaxis2_firenormal", "Z-Axis", CV_SAVE, joyaxis_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL}; -consvar_t cv_deadzone2 = {"joy_deadzone2", "0.25", CV_FLOAT|CV_SAVE, zerotoone_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL}; +consvar_t cv_deadzone2 = {"joy_deadzone2", "0.125", CV_FLOAT|CV_SAVE, zerotoone_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL}; +consvar_t cv_digitaldeadzone2 = {"joy_digdeadzone2", "0.25", CV_FLOAT|CV_SAVE, zerotoone_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL}; #ifdef SEENAMES player_t *seenplayer; // player we're aiming at right now @@ -936,9 +938,9 @@ static INT32 JoyAxis(axis_input_e axissel) retaxis = -JOYAXISRANGE; if (retaxis > (+JOYAXISRANGE)) retaxis = +JOYAXISRANGE; - if (!Joystick.bGamepadStyle && axissel < AXISDEAD) + if (!Joystick.bGamepadStyle) { - const INT32 jdeadzone = ((JOYAXISRANGE-1) * cv_deadzone.value) >> FRACBITS; + const INT32 jdeadzone = ((JOYAXISRANGE-1) * ((axissel < AXISDEAD) ? cv_deadzone.value : cv_digitaldeadzone.value)) >> FRACBITS; if (-jdeadzone < retaxis && retaxis < jdeadzone) return 0; } @@ -1009,9 +1011,9 @@ static INT32 Joy2Axis(axis_input_e axissel) retaxis = -JOYAXISRANGE; if (retaxis > (+JOYAXISRANGE)) retaxis = +JOYAXISRANGE; - if (!Joystick2.bGamepadStyle && axissel < AXISDEAD) + if (!Joystick2.bGamepadStyle) { - const INT32 jdeadzone = ((JOYAXISRANGE-1) * cv_deadzone2.value) >> FRACBITS; + const INT32 jdeadzone = ((JOYAXISRANGE-1) * ((axissel < AXISDEAD) ? cv_deadzone2.value : cv_digitaldeadzone2.value)) >> FRACBITS; if (-jdeadzone < retaxis && retaxis < jdeadzone) return 0; } diff --git a/src/g_game.h b/src/g_game.h index 8ba3bc373..5f094fbda 100644 --- a/src/g_game.h +++ b/src/g_game.h @@ -72,8 +72,8 @@ extern consvar_t cv_useranalog, cv_useranalog2; extern consvar_t cv_analog, cv_analog2; extern consvar_t cv_directionchar, cv_directionchar2; extern consvar_t cv_autobrake, cv_autobrake2; -extern consvar_t cv_sideaxis,cv_turnaxis,cv_moveaxis,cv_lookaxis,cv_jumpaxis,cv_spinaxis,cv_fireaxis,cv_firenaxis,cv_deadzone; -extern consvar_t cv_sideaxis2,cv_turnaxis2,cv_moveaxis2,cv_lookaxis2,cv_jumpaxis2,cv_spinaxis2,cv_fireaxis2,cv_firenaxis2,cv_deadzone2; +extern consvar_t cv_sideaxis,cv_turnaxis,cv_moveaxis,cv_lookaxis,cv_jumpaxis,cv_spinaxis,cv_fireaxis,cv_firenaxis,cv_deadzone,cv_digitaldeadzone; +extern consvar_t cv_sideaxis2,cv_turnaxis2,cv_moveaxis2,cv_lookaxis2,cv_jumpaxis2,cv_spinaxis2,cv_fireaxis2,cv_firenaxis2,cv_deadzone2,cv_digitaldeadzone2; extern consvar_t cv_ghost_bestscore, cv_ghost_besttime, cv_ghost_bestrings, cv_ghost_last, cv_ghost_guest; // hi here's some new controls diff --git a/src/m_menu.c b/src/m_menu.c index 89c0b04bd..a6a933114 100644 --- a/src/m_menu.c +++ b/src/m_menu.c @@ -1128,7 +1128,8 @@ static menuitem_t OP_Joystick1Menu[] = {IT_STRING | IT_CVAR, NULL, "First-Person Vert-Look", &cv_alwaysfreelook, 120}, {IT_STRING | IT_CVAR, NULL, "Third-Person Vert-Look", &cv_chasefreelook, 130}, - {IT_STRING | IT_CVAR | IT_CV_FLOATSLIDER, NULL, "Deadzone", &cv_deadzone, 140}, + {IT_STRING | IT_CVAR | IT_CV_FLOATSLIDER, NULL, "Analog Deadzone", &cv_deadzone, 140}, + {IT_STRING | IT_CVAR | IT_CV_FLOATSLIDER, NULL, "Digital Deadzone", &cv_digitaldeadzone, 150}, }; static menuitem_t OP_Joystick2Menu[] = @@ -1145,7 +1146,8 @@ static menuitem_t OP_Joystick2Menu[] = {IT_STRING | IT_CVAR, NULL, "First-Person Vert-Look", &cv_alwaysfreelook2,120}, {IT_STRING | IT_CVAR, NULL, "Third-Person Vert-Look", &cv_chasefreelook2, 130}, - {IT_STRING | IT_CVAR | IT_CV_FLOATSLIDER, NULL, "Deadzone", &cv_deadzone2,140}, + {IT_STRING | IT_CVAR | IT_CV_FLOATSLIDER, NULL, "Analog Deadzone", &cv_deadzone2,140}, + {IT_STRING | IT_CVAR | IT_CV_FLOATSLIDER, NULL, "Digital Deadzone", &cv_digitaldeadzone2,150}, }; static menuitem_t OP_JoystickSetMenu[1+MAX_JOYSTICKS]; From 11f5911943ce1c3dcef656fd1f1dc884efcb0874 Mon Sep 17 00:00:00 2001 From: Eidolon Date: Sun, 15 Dec 2019 00:39:04 -0600 Subject: [PATCH 203/746] [cmake] Use same executable names as Makefile --- src/sdl/CMakeLists.txt | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/src/sdl/CMakeLists.txt b/src/sdl/CMakeLists.txt index f1aa135b9..38d557a3f 100644 --- a/src/sdl/CMakeLists.txt +++ b/src/sdl/CMakeLists.txt @@ -140,7 +140,13 @@ if(${SDL2_FOUND}) endif() add_executable(SRB2SDL2 MACOSX_BUNDLE WIN32 ${SRB2_SDL2_TOTAL_SOURCES}) - set_target_properties(SRB2SDL2 PROPERTIES OUTPUT_NAME ${SRB2_SDL2_EXE_NAME}) + if(${CMAKE_SYSTEM} MATCHES Windows) + set_target_properties(SRB2SDL2 PROPERTIES OUTPUT_NAME srb2win) + elseif(${CMAKE_SYSTEM} MATCHES Linux) + set_target_properties(SRB2SDL2 PROPERTIES OUTPUT_NAME lsdlsrb2) + else() + set_target_properties(SRB2SDL2 PROPERTIES OUTPUT_NAME srb2) + endif() if(${CMAKE_SYSTEM} MATCHES Darwin) find_library(CORE_LIB CoreFoundation) From d63ad82dc568af8fe0f85cc75dce34bb5aa6fd12 Mon Sep 17 00:00:00 2001 From: Eidolon Date: Sun, 15 Dec 2019 00:47:58 -0600 Subject: [PATCH 204/746] [cmake] Remove srb2dd target --- CMakeLists.txt | 1 - src/CMakeLists.txt | 6 +----- 2 files changed, 1 insertion(+), 6 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index dd9703914..8bbf46945 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -95,7 +95,6 @@ set(CMAKE_PDB_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/bin") # Set EXE names so the assets CMakeLists can refer to its target set(SRB2_SDL2_EXE_NAME srb2 CACHE STRING "Executable binary output name") -set(SRB2_WIN_EXE_NAME srb2dd CACHE STRING "Executable binary output name for DirectDraw build") include_directories(${CMAKE_CURRENT_BINARY_DIR}/src) diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 97feae18b..e8c9c3182 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -518,10 +518,6 @@ add_definitions(-DCMAKECONFIG) add_subdirectory(sdl) -if(${CMAKE_SYSTEM} MATCHES Windows) - add_subdirectory(win32) -endif() - -if(NOT ${SRB2_SDL2_AVAILABLE} AND NOT ${SRB2_WIN32_AVAILABLE}) +if(NOT ${SRB2_SDL2_AVAILABLE}) message(FATAL_ERROR "There are no targets available to build an SRB2 executable. :(") endif() From 8a6e244e60c0f760be4716346e8f4b6d20946e7f Mon Sep 17 00:00:00 2001 From: MascaraSnake Date: Sun, 15 Dec 2019 09:49:54 +0100 Subject: [PATCH 205/746] SpawnEmeraldHunt() -> P_SpawnEmeraldHunt() --- src/p_setup.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/p_setup.c b/src/p_setup.c index 628292fe0..9a546c5b5 100644 --- a/src/p_setup.c +++ b/src/p_setup.c @@ -1035,7 +1035,7 @@ static void P_PrepareThings(lumpnum_t lumpnum) Z_Free(data); } -static void SpawnEmeraldHunt (void) +static void P_SpawnEmeraldHunt(void) { INT32 emer1, emer2, emer3; INT32 timeout = 0; // keeps from getting stuck @@ -1119,7 +1119,7 @@ static void P_LoadThings(boolean loademblems) // random emeralds for hunt if (numhuntemeralds) - SpawnEmeraldHunt(); + P_SpawnEmeraldHunt(); if (metalrecording) // Metal Sonic gets no rings to distract him. return; From 23b3f5a649fcd43c3eefd46b5ca54ee40559278e Mon Sep 17 00:00:00 2001 From: GoldenTails Date: Sun, 15 Dec 2019 04:09:56 -0600 Subject: [PATCH 206/746] Fix a divide by zero crash when mindash and maxdash were the same. Props to rumia1 for finding this and Lach for figuring out this was a divide by zero error. --- 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 ea42a2c36..2c9a766bc 100644 --- a/src/p_user.c +++ b/src/p_user.c @@ -4635,7 +4635,7 @@ static void P_DoSpinAbility(player_t *player, ticcmd_t *cmd) S_StartSound(player->mo, sfx_spin); break; } - if (player->dashspeed < player->maxdash) + if (player->dashspeed < player->maxdash && player->mindash != player->maxdash) { #define chargecalculation (6*(player->dashspeed - player->mindash))/(player->maxdash - player->mindash) fixed_t soundcalculation = chargecalculation; From b17bf5d836d21652dfc83072b032e277598e8e87 Mon Sep 17 00:00:00 2001 From: Sryder Date: Sun, 15 Dec 2019 14:37:30 +0000 Subject: [PATCH 207/746] Use Scaled Radial Deadzones, instead of Axial deadzones. Additionally fixes some weird padscale 0 stuff that was flipped. This does have gameplay implications in both NiGHTS and regular gameplay. Notably you won't feel like you're locked into up/down left/right when you want to turn, but this can make running perfectly straight a little bit more tricky. --- src/g_game.c | 210 ++++++++++++++++++++++++++++++++++----------------- 1 file changed, 142 insertions(+), 68 deletions(-) diff --git a/src/g_game.c b/src/g_game.c index 2a12dd298..0105b88c6 100644 --- a/src/g_game.c +++ b/src/g_game.c @@ -275,6 +275,12 @@ static UINT8 *metalbuffer = NULL; static UINT8 *metal_p; static UINT16 metalversion; +typedef struct joystickvector2_s +{ + INT32 xaxis; + INT32 yaxis; +} joystickvector2_t; + // extra data stuff (events registered this frame while recording) static struct { UINT8 flags; // EZT flags @@ -882,12 +888,6 @@ static INT32 JoyAxis(axis_input_e axissel) retaxis = -JOYAXISRANGE; if (retaxis > (+JOYAXISRANGE)) retaxis = +JOYAXISRANGE; - if (!Joystick.bGamepadStyle && axissel < AXISDEAD) - { - const INT32 jdeadzone = JOYAXISRANGE/4; - if (-jdeadzone < retaxis && retaxis < jdeadzone) - return 0; - } if (flp) retaxis = -retaxis; //flip it around return retaxis; } @@ -955,16 +955,74 @@ static INT32 Joy2Axis(axis_input_e axissel) retaxis = -JOYAXISRANGE; if (retaxis > (+JOYAXISRANGE)) retaxis = +JOYAXISRANGE; - if (!Joystick2.bGamepadStyle && axissel < AXISDEAD) - { - const INT32 jdeadzone = JOYAXISRANGE/4; - if (-jdeadzone < retaxis && retaxis < jdeadzone) - return 0; - } if (flp) retaxis = -retaxis; //flip it around return retaxis; } +// Take a magnitude of two axes, and adjust it to take out the deadzone +// Will return a value between 0 and JOYAXISRANGE +static INT32 G_BasicDeadZoneCalculation(INT32 magnitude) +{ + // TODO: console variable for deadzone setting + const INT32 jdeadzone = JOYAXISRANGE/4; + INT32 deadzoneAppliedValue = 0; + + if (jdeadzone > 0) + { + if (magnitude > jdeadzone) + { + INT32 adjustedMagnitude = abs(magnitude); + adjustedMagnitude = min(adjustedMagnitude, JOYAXISRANGE); + + adjustedMagnitude -= jdeadzone; + + deadzoneAppliedValue = (adjustedMagnitude * JOYAXISRANGE) / (JOYAXISRANGE - jdeadzone); + } + } + + return deadzoneAppliedValue; +} + +// Get the actual sensible radial value for a joystick axis when accounting for a deadzone +static void G_HandleAxisDeadZone(UINT8 splitnum, joystickvector2_t *joystickvector) +{ + INT32 gamepadStyle = Joystick.bGamepadStyle; + + if (splitnum == 1) + { + gamepadStyle = Joystick2.bGamepadStyle; + } + + // When gamepadstyle is "true" the values are just -1, 0, or 1. This is done in the interface code. + if (!gamepadStyle) + { + // Get the total magnitude of the 2 axes + INT32 magnitude = (joystickvector->xaxis * joystickvector->xaxis) + (joystickvector->yaxis * joystickvector->yaxis); + INT32 normalisedxaxis; + INT32 normalisedyaxis; + INT32 normalisedMagnitude; + double dMagnitude = sqrt((double)magnitude); + magnitude = (INT32)dMagnitude; + + // Get the normalised xy values from the magnitude + normalisedxaxis = (joystickvector->xaxis * magnitude) / JOYAXISRANGE; + normalisedyaxis = (joystickvector->yaxis * magnitude) / JOYAXISRANGE; + + // Apply the deadzone to the magnitude to give a correct value between 0 and JOYAXISRANGE + normalisedMagnitude = G_BasicDeadZoneCalculation(magnitude); + + // Apply the deadzone to the xy axes + joystickvector->xaxis = (normalisedxaxis * normalisedMagnitude) / JOYAXISRANGE; + joystickvector->yaxis = (normalisedyaxis * normalisedMagnitude) / JOYAXISRANGE; + + // Cap the values so they don't go above the correct maximum + joystickvector->xaxis = min(joystickvector->xaxis, JOYAXISRANGE); + joystickvector->xaxis = max(joystickvector->xaxis, -JOYAXISRANGE); + joystickvector->yaxis = min(joystickvector->yaxis, JOYAXISRANGE); + joystickvector->yaxis = max(joystickvector->yaxis, -JOYAXISRANGE); + } +} + // // G_BuildTiccmd @@ -985,12 +1043,13 @@ void G_BuildTiccmd(ticcmd_t *cmd, INT32 realtics) { boolean forcestrafe = false; boolean forcefullinput = false; - INT32 tspeed, forward, side, axis, altaxis, i; + INT32 tspeed, forward, side, axis, strafeaxis, moveaxis, turnaxis, lookaxis, i; const INT32 speed = 1; // these ones used for multiple conditions boolean turnleft, turnright, strafelkey, straferkey, movefkey, movebkey, mouseaiming, analogjoystickmove, gamepadjoystickmove, thisjoyaiming; player_t *player = &players[consoleplayer]; camera_t *thiscam = &camera; + joystickvector2_t movejoystickvector, lookjoystickvector; static INT32 turnheld; // for accelerative turning static boolean keyboard_look; // true if lookup/down using keyboard @@ -1030,11 +1089,16 @@ void G_BuildTiccmd(ticcmd_t *cmd, INT32 realtics) localaiming = 0; joyaiming = thisjoyaiming; - axis = JoyAxis(AXISTURN); - if (gamepadjoystickmove && axis != 0) + turnaxis = JoyAxis(AXISTURN); + lookaxis = JoyAxis(AXISLOOK); + lookjoystickvector.xaxis = turnaxis; + lookjoystickvector.yaxis = lookaxis; + G_HandleAxisDeadZone(0, &lookjoystickvector); + + if (gamepadjoystickmove && lookjoystickvector.xaxis != 0) { - turnright = turnright || (axis > 0); - turnleft = turnleft || (axis < 0); + turnright = turnright || (lookjoystickvector.xaxis > 0); + turnleft = turnleft || (lookjoystickvector.xaxis < 0); } forward = side = 0; @@ -1074,10 +1138,10 @@ void G_BuildTiccmd(ticcmd_t *cmd, INT32 realtics) if (turnleft) side -= sidemove[speed]; - if (analogjoystickmove && axis != 0) + if (analogjoystickmove && lookjoystickvector.xaxis != 0) { // JOYAXISRANGE is supposed to be 1023 (divide by 1024) - side += ((axis * sidemove[1]) >> 10); + side += ((lookjoystickvector.xaxis * sidemove[1]) >> 10); } } else if (cv_analog.value) // Analog @@ -1094,41 +1158,44 @@ void G_BuildTiccmd(ticcmd_t *cmd, INT32 realtics) else if (turnleft) cmd->angleturn = (INT16)(cmd->angleturn + angleturn[tspeed]); - if (analogjoystickmove && axis != 0) + if (analogjoystickmove && lookjoystickvector.xaxis != 0) { // JOYAXISRANGE should be 1023 (divide by 1024) - cmd->angleturn = (INT16)(cmd->angleturn - ((axis * angleturn[1]) >> 10)); // ANALOG! + cmd->angleturn = (INT16)(cmd->angleturn - ((lookjoystickvector.xaxis * angleturn[1]) >> 10)); // ANALOG! } } - axis = JoyAxis(AXISSTRAFE); - if (gamepadjoystickmove && axis != 0) + strafeaxis = JoyAxis(AXISSTRAFE); + moveaxis = JoyAxis(AXISMOVE); + movejoystickvector.xaxis = strafeaxis; + movejoystickvector.yaxis = moveaxis; + G_HandleAxisDeadZone(0, &movejoystickvector); + + if (gamepadjoystickmove && movejoystickvector.xaxis != 0) { - if (axis < 0) + if (movejoystickvector.xaxis > 0) side += sidemove[speed]; - else if (axis > 0) + else if (movejoystickvector.xaxis < 0) side -= sidemove[speed]; } - else if (analogjoystickmove && axis != 0) + else if (analogjoystickmove && movejoystickvector.xaxis != 0) { // JOYAXISRANGE is supposed to be 1023 (divide by 1024) - side += ((axis * sidemove[1]) >> 10); + side += ((movejoystickvector.xaxis * sidemove[1]) >> 10); } // forward with key or button - axis = JoyAxis(AXISMOVE); - altaxis = JoyAxis(AXISLOOK); - if (movefkey || (gamepadjoystickmove && axis < 0) + if (movefkey || (gamepadjoystickmove && movejoystickvector.yaxis < 0) || ((player->powers[pw_carry] == CR_NIGHTSMODE) - && (PLAYER1INPUTDOWN(gc_lookup) || (gamepadjoystickmove && altaxis < 0)))) + && (PLAYER1INPUTDOWN(gc_lookup) || (gamepadjoystickmove && lookjoystickvector.yaxis > 0)))) forward = forwardmove[speed]; - if (movebkey || (gamepadjoystickmove && axis > 0) + if (movebkey || (gamepadjoystickmove && movejoystickvector.yaxis > 0) || ((player->powers[pw_carry] == CR_NIGHTSMODE) - && (PLAYER1INPUTDOWN(gc_lookdown) || (gamepadjoystickmove && altaxis > 0)))) + && (PLAYER1INPUTDOWN(gc_lookdown) || (gamepadjoystickmove && lookjoystickvector.yaxis < 0)))) forward -= forwardmove[speed]; - if (analogjoystickmove && axis != 0) - forward -= ((axis * forwardmove[1]) >> 10); // ANALOG! + if (analogjoystickmove && movejoystickvector.yaxis != 0) + forward -= ((movejoystickvector.yaxis * forwardmove[1]) >> 10); // ANALOG! // some people strafe left & right with mouse buttons // those people are weird @@ -1211,9 +1278,8 @@ void G_BuildTiccmd(ticcmd_t *cmd, INT32 realtics) localaiming += (mlooky<<19)*player_invert*screen_invert; } - axis = JoyAxis(AXISLOOK); - if (analogjoystickmove && joyaiming && axis != 0 && cv_lookaxis.value != 0) - localaiming += (axis<<16) * screen_invert; + if (analogjoystickmove && joyaiming && lookjoystickvector.yaxis != 0 && cv_lookaxis.value != 0) + localaiming += (lookjoystickvector.yaxis<<16) * screen_invert; // spring back if not using keyboard neither mouselookin' if (!keyboard_look && cv_lookaxis.value == 0 && !joyaiming && !mouseaiming) @@ -1221,12 +1287,12 @@ void G_BuildTiccmd(ticcmd_t *cmd, INT32 realtics) if (!(player->powers[pw_carry] == CR_NIGHTSMODE)) { - if (PLAYER1INPUTDOWN(gc_lookup) || (gamepadjoystickmove && axis < 0)) + if (PLAYER1INPUTDOWN(gc_lookup) || (gamepadjoystickmove && lookjoystickvector.yaxis > 0)) { localaiming += KB_LOOKSPEED * screen_invert; keyboard_look = true; } - else if (PLAYER1INPUTDOWN(gc_lookdown) || (gamepadjoystickmove && axis > 0)) + else if (PLAYER1INPUTDOWN(gc_lookdown) || (gamepadjoystickmove && lookjoystickvector.yaxis < 0)) { localaiming -= KB_LOOKSPEED * screen_invert; keyboard_look = true; @@ -1316,12 +1382,13 @@ void G_BuildTiccmd2(ticcmd_t *cmd, INT32 realtics) { boolean forcestrafe = false; boolean forcefullinput = false; - INT32 tspeed, forward, side, axis, altaxis, i; + INT32 tspeed, forward, side, axis, strafeaxis, moveaxis, turnaxis, lookaxis, i; const INT32 speed = 1; // these ones used for multiple conditions boolean turnleft, turnright, strafelkey, straferkey, movefkey, movebkey, mouseaiming, analogjoystickmove, gamepadjoystickmove, thisjoyaiming; player_t *player = &players[secondarydisplayplayer]; camera_t *thiscam = (player->bot == 2 ? &camera : &camera2); + joystickvector2_t movejoystickvector, lookjoystickvector; static INT32 turnheld; // for accelerative turning static boolean keyboard_look; // true if lookup/down using keyboard @@ -1359,11 +1426,16 @@ void G_BuildTiccmd2(ticcmd_t *cmd, INT32 realtics) localaiming2 = 0; joyaiming = thisjoyaiming; - axis = Joy2Axis(AXISTURN); - if (gamepadjoystickmove && axis != 0) + turnaxis = Joy2Axis(AXISTURN); + lookaxis = Joy2Axis(AXISLOOK); + lookjoystickvector.xaxis = turnaxis; + lookjoystickvector.yaxis = lookaxis; + G_HandleAxisDeadZone(1, &lookjoystickvector); + + if (gamepadjoystickmove && lookjoystickvector.xaxis != 0) { - turnright = turnright || (axis > 0); - turnleft = turnleft || (axis < 0); + turnright = turnright || (lookjoystickvector.xaxis > 0); + turnleft = turnleft || (lookjoystickvector.xaxis < 0); } forward = side = 0; @@ -1404,10 +1476,10 @@ void G_BuildTiccmd2(ticcmd_t *cmd, INT32 realtics) if (turnleft) side -= sidemove[speed]; - if (analogjoystickmove && axis != 0) + if (analogjoystickmove && lookjoystickvector.xaxis != 0) { // JOYAXISRANGE is supposed to be 1023 (divide by 1024) - side += ((axis * sidemove[1]) >> 10); + side += ((lookjoystickvector.xaxis * sidemove[1]) >> 10); } } else if (cv_analog2.value) // Analog @@ -1424,41 +1496,44 @@ void G_BuildTiccmd2(ticcmd_t *cmd, INT32 realtics) else if (turnleft) cmd->angleturn = (INT16)(cmd->angleturn + angleturn[tspeed]); - if (analogjoystickmove && axis != 0) + if (analogjoystickmove && lookjoystickvector.xaxis != 0) { // JOYAXISRANGE should be 1023 (divide by 1024) - cmd->angleturn = (INT16)(cmd->angleturn - ((axis * angleturn[1]) >> 10)); // ANALOG! + cmd->angleturn = (INT16)(cmd->angleturn - ((lookjoystickvector.xaxis * angleturn[1]) >> 10)); // ANALOG! } } - axis = Joy2Axis(AXISSTRAFE); - if (gamepadjoystickmove && axis != 0) + strafeaxis = Joy2Axis(AXISSTRAFE); + moveaxis = Joy2Axis(AXISMOVE); + movejoystickvector.xaxis = strafeaxis; + movejoystickvector.yaxis = moveaxis; + G_HandleAxisDeadZone(1, &movejoystickvector); + + if (gamepadjoystickmove && movejoystickvector.xaxis != 0) { - if (axis < 0) + if (movejoystickvector.xaxis > 0) side += sidemove[speed]; - else if (axis > 0) + else if (movejoystickvector.xaxis < 0) side -= sidemove[speed]; } - else if (analogjoystickmove && axis != 0) + else if (analogjoystickmove && movejoystickvector.xaxis != 0) { // JOYAXISRANGE is supposed to be 1023 (divide by 1024) - side += ((axis * sidemove[1]) >> 10); + side += ((movejoystickvector.xaxis * sidemove[1]) >> 10); } // forward with key or button - axis = Joy2Axis(AXISMOVE); - altaxis = Joy2Axis(AXISLOOK); - if (movefkey || (gamepadjoystickmove && axis < 0) + if (movefkey || (gamepadjoystickmove && movejoystickvector.yaxis < 0) || ((player->powers[pw_carry] == CR_NIGHTSMODE) - && (PLAYER2INPUTDOWN(gc_lookup) || (gamepadjoystickmove && altaxis < 0)))) + && (PLAYER2INPUTDOWN(gc_lookup) || (gamepadjoystickmove && lookjoystickvector.yaxis > 0)))) forward = forwardmove[speed]; - if (movebkey || (gamepadjoystickmove && axis > 0) + if (movebkey || (gamepadjoystickmove && movejoystickvector.yaxis > 0) || ((player->powers[pw_carry] == CR_NIGHTSMODE) - && (PLAYER2INPUTDOWN(gc_lookdown) || (gamepadjoystickmove && altaxis > 0)))) + && (PLAYER2INPUTDOWN(gc_lookdown) || (gamepadjoystickmove && lookjoystickvector.yaxis < 0)))) forward -= forwardmove[speed]; - if (analogjoystickmove && axis != 0) - forward -= ((axis * forwardmove[1]) >> 10); // ANALOG! + if (analogjoystickmove && movejoystickvector.yaxis != 0) + forward -= ((movejoystickvector.yaxis * forwardmove[1]) >> 10); // ANALOG! // some people strafe left & right with mouse buttons // those people are (still) weird @@ -1538,9 +1613,8 @@ void G_BuildTiccmd2(ticcmd_t *cmd, INT32 realtics) localaiming2 += (mlook2y<<19)*player_invert*screen_invert; } - axis = Joy2Axis(AXISLOOK); - if (analogjoystickmove && joyaiming && axis != 0 && cv_lookaxis2.value != 0) - localaiming2 += (axis<<16) * screen_invert; + if (analogjoystickmove && joyaiming && lookjoystickvector.yaxis != 0 && cv_lookaxis2.value != 0) + localaiming2 += (lookjoystickvector.yaxis<<16) * screen_invert; // spring back if not using keyboard neither mouselookin' if (!keyboard_look && cv_lookaxis2.value == 0 && !joyaiming && !mouseaiming) @@ -1548,12 +1622,12 @@ void G_BuildTiccmd2(ticcmd_t *cmd, INT32 realtics) if (!(player->powers[pw_carry] == CR_NIGHTSMODE)) { - if (PLAYER2INPUTDOWN(gc_lookup) || (gamepadjoystickmove && axis < 0)) + if (PLAYER2INPUTDOWN(gc_lookup) || (gamepadjoystickmove && lookjoystickvector.yaxis > 0)) { localaiming2 += KB_LOOKSPEED * screen_invert; keyboard_look = true; } - else if (PLAYER2INPUTDOWN(gc_lookdown) || (gamepadjoystickmove && axis > 0)) + else if (PLAYER2INPUTDOWN(gc_lookdown) || (gamepadjoystickmove && lookjoystickvector.yaxis < 0)) { localaiming2 -= KB_LOOKSPEED * screen_invert; keyboard_look = true; From 76d59330f7ad201d50efb055846cccea7b4d51d5 Mon Sep 17 00:00:00 2001 From: Sryder Date: Sun, 15 Dec 2019 15:36:13 +0000 Subject: [PATCH 208/746] Port the deadzone cvar stuff from kart. Add menu items for deadzone. --- src/d_netcmd.c | 4 ++++ src/g_game.c | 27 ++++++++++++++++----------- src/g_game.h | 1 + src/m_menu.c | 6 +++++- 4 files changed, 26 insertions(+), 12 deletions(-) diff --git a/src/d_netcmd.c b/src/d_netcmd.c index e80d07b76..f622966c5 100644 --- a/src/d_netcmd.c +++ b/src/d_netcmd.c @@ -823,6 +823,10 @@ void D_RegisterClientCommands(void) CV_RegisterVar(&cv_autobrake); CV_RegisterVar(&cv_autobrake2); + // Ported from kart + CV_RegisterVar(&cv_deadzone); + CV_RegisterVar(&cv_deadzone2); + // s_sound.c CV_RegisterVar(&cv_soundvolume); CV_RegisterVar(&cv_closedcaptioning); diff --git a/src/g_game.c b/src/g_game.c index 0105b88c6..d2d27528c 100644 --- a/src/g_game.c +++ b/src/g_game.c @@ -400,6 +400,11 @@ consvar_t cv_directionchar2 = {"directionchar2", "Movement", CV_SAVE|CV_CALL, di consvar_t cv_autobrake = {"autobrake", "On", CV_SAVE|CV_CALL, CV_OnOff, AutoBrake_OnChange, 0, NULL, NULL, 0, 0, NULL}; consvar_t cv_autobrake2 = {"autobrake2", "On", CV_SAVE|CV_CALL, CV_OnOff, AutoBrake2_OnChange, 0, NULL, NULL, 0, 0, NULL}; +static CV_PossibleValue_t deadzone_cons_t[] = {{0, "MIN"}, {FRACUNIT, "MAX"}, {0, NULL}}; +consvar_t cv_deadzone = {"deadzone", "0.25", CV_FLOAT|CV_SAVE, deadzone_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL}; +consvar_t cv_deadzone2 = {"deadzone2", "0.25", CV_FLOAT|CV_SAVE, deadzone_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL}; + + typedef enum { AXISNONE = 0, @@ -407,7 +412,6 @@ typedef enum AXISMOVE, AXISLOOK, AXISSTRAFE, - AXISDEAD, //Axises that don't want deadzones AXISJUMP, AXISSPIN, AXISFIRE, @@ -961,10 +965,9 @@ static INT32 Joy2Axis(axis_input_e axissel) // Take a magnitude of two axes, and adjust it to take out the deadzone // Will return a value between 0 and JOYAXISRANGE -static INT32 G_BasicDeadZoneCalculation(INT32 magnitude) +static INT32 G_BasicDeadZoneCalculation(INT32 magnitude, fixed_t deadZone) { - // TODO: console variable for deadzone setting - const INT32 jdeadzone = JOYAXISRANGE/4; + const INT32 jdeadzone = (JOYAXISRANGE * deadZone) / FRACUNIT; INT32 deadzoneAppliedValue = 0; if (jdeadzone > 0) @@ -987,10 +990,12 @@ static INT32 G_BasicDeadZoneCalculation(INT32 magnitude) static void G_HandleAxisDeadZone(UINT8 splitnum, joystickvector2_t *joystickvector) { INT32 gamepadStyle = Joystick.bGamepadStyle; + fixed_t deadZone = cv_deadzone.value; if (splitnum == 1) { gamepadStyle = Joystick2.bGamepadStyle; + deadZone = cv_deadzone2.value; } // When gamepadstyle is "true" the values are just -1, 0, or 1. This is done in the interface code. @@ -998,22 +1003,22 @@ static void G_HandleAxisDeadZone(UINT8 splitnum, joystickvector2_t *joystickvect { // Get the total magnitude of the 2 axes INT32 magnitude = (joystickvector->xaxis * joystickvector->xaxis) + (joystickvector->yaxis * joystickvector->yaxis); - INT32 normalisedxaxis; - INT32 normalisedyaxis; + INT32 normalisedXAxis; + INT32 normalisedYAxis; INT32 normalisedMagnitude; double dMagnitude = sqrt((double)magnitude); magnitude = (INT32)dMagnitude; // Get the normalised xy values from the magnitude - normalisedxaxis = (joystickvector->xaxis * magnitude) / JOYAXISRANGE; - normalisedyaxis = (joystickvector->yaxis * magnitude) / JOYAXISRANGE; + normalisedXAxis = (joystickvector->xaxis * magnitude) / JOYAXISRANGE; + normalisedYAxis = (joystickvector->yaxis * magnitude) / JOYAXISRANGE; // Apply the deadzone to the magnitude to give a correct value between 0 and JOYAXISRANGE - normalisedMagnitude = G_BasicDeadZoneCalculation(magnitude); + normalisedMagnitude = G_BasicDeadZoneCalculation(magnitude, deadZone); // Apply the deadzone to the xy axes - joystickvector->xaxis = (normalisedxaxis * normalisedMagnitude) / JOYAXISRANGE; - joystickvector->yaxis = (normalisedyaxis * normalisedMagnitude) / JOYAXISRANGE; + joystickvector->xaxis = (normalisedXAxis * normalisedMagnitude) / JOYAXISRANGE; + joystickvector->yaxis = (normalisedYAxis * normalisedMagnitude) / JOYAXISRANGE; // Cap the values so they don't go above the correct maximum joystickvector->xaxis = min(joystickvector->xaxis, JOYAXISRANGE); diff --git a/src/g_game.h b/src/g_game.h index e7f4a4677..c19faebe4 100644 --- a/src/g_game.h +++ b/src/g_game.h @@ -72,6 +72,7 @@ extern consvar_t cv_useranalog, cv_useranalog2; extern consvar_t cv_analog, cv_analog2; extern consvar_t cv_directionchar, cv_directionchar2; extern consvar_t cv_autobrake, cv_autobrake2; +extern consvar_t cv_deadzone, cv_deadzone2; extern consvar_t cv_sideaxis,cv_turnaxis,cv_moveaxis,cv_lookaxis,cv_jumpaxis,cv_spinaxis,cv_fireaxis,cv_firenaxis; extern consvar_t cv_sideaxis2,cv_turnaxis2,cv_moveaxis2,cv_lookaxis2,cv_jumpaxis2,cv_spinaxis2,cv_fireaxis2,cv_firenaxis2; extern consvar_t cv_ghost_bestscore, cv_ghost_besttime, cv_ghost_bestrings, cv_ghost_last, cv_ghost_guest; diff --git a/src/m_menu.c b/src/m_menu.c index e367041e0..cbcc3bdb6 100644 --- a/src/m_menu.c +++ b/src/m_menu.c @@ -1119,6 +1119,8 @@ static menuitem_t OP_Joystick1Menu[] = {IT_STRING | IT_CVAR, NULL, "First-Person Vert-Look", &cv_alwaysfreelook, 120}, {IT_STRING | IT_CVAR, NULL, "Third-Person Vert-Look", &cv_chasefreelook, 130}, + {IT_STRING | IT_CVAR | IT_CV_FLOATSLIDER, + NULL, "Deadzone", &cv_deadzone, 140 }, }; static menuitem_t OP_Joystick2Menu[] = @@ -1135,6 +1137,8 @@ static menuitem_t OP_Joystick2Menu[] = {IT_STRING | IT_CVAR, NULL, "First-Person Vert-Look", &cv_alwaysfreelook2,120}, {IT_STRING | IT_CVAR, NULL, "Third-Person Vert-Look", &cv_chasefreelook2, 130}, + {IT_STRING | IT_CVAR | IT_CV_FLOATSLIDER, + NULL, "Deadzone", &cv_deadzone2, 140 }, }; static menuitem_t OP_JoystickSetMenu[1+MAX_JOYSTICKS]; @@ -3025,7 +3029,7 @@ boolean M_Responder(event_t *ev) } else if (ev->type == ev_joystick && ev->data1 == 0 && joywait < I_GetTime()) { - const INT32 jdeadzone = JOYAXISRANGE/4; + const INT32 jdeadzone = (JOYAXISRANGE * cv_deadzone.value) / FRACUNIT; if (ev->data3 != INT32_MAX) { if (Joystick.bGamepadStyle || abs(ev->data3) > jdeadzone) From eb179e4d6a7c4668ed7a2f9fafae7d943c8f57ca Mon Sep 17 00:00:00 2001 From: Monster Iestyn Date: Sun, 15 Dec 2019 15:40:56 +0000 Subject: [PATCH 209/746] Remove anti-Tails restriction for the Allow super Pandora's Box cheat. Despite popular belief, this was just some experimenting from 2.2 development that we forgot to remove! --- src/m_menu.c | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/src/m_menu.c b/src/m_menu.c index f20a8e22e..23dc10701 100644 --- a/src/m_menu.c +++ b/src/m_menu.c @@ -6370,11 +6370,7 @@ static void M_PandorasBox(INT32 choice) else CV_StealthSetValue(&cv_dummylives, max(players[consoleplayer].lives, 1)); CV_StealthSetValue(&cv_dummycontinues, players[consoleplayer].continues); - SR_PandorasBox[6].status = ((players[consoleplayer].charflags & SF_SUPER) -#ifndef DEVELOP - || cv_skin.value == 1 -#endif - ) ? (IT_GRAYEDOUT) : (IT_STRING | IT_CALL); + SR_PandorasBox[6].status = (players[consoleplayer].charflags & SF_SUPER) ? (IT_GRAYEDOUT) : (IT_STRING | IT_CALL); SR_PandorasBox[7].status = (emeralds == ((EMERALD7)*2)-1) ? (IT_GRAYEDOUT) : (IT_STRING | IT_CALL); M_SetupNextMenu(&SR_PandoraDef); } From 1f88c70d6ad77fbba9f8a994a30a9eb4ff18d596 Mon Sep 17 00:00:00 2001 From: fickleheart Date: Sun, 15 Dec 2019 13:33:21 -0600 Subject: [PATCH 210/746] Fix RVZ autocam AGAIN --- src/g_game.c | 2 +- src/p_user.c | 7 ++----- 2 files changed, 3 insertions(+), 6 deletions(-) diff --git a/src/g_game.c b/src/g_game.c index d5cd0c991..bd88c5dd5 100644 --- a/src/g_game.c +++ b/src/g_game.c @@ -1606,7 +1606,7 @@ void G_BuildTiccmd(ticcmd_t *cmd, INT32 realtics, UINT8 ssplayer) if (camadjustfactor) { - INT32 anglediff = ((player->pflags & PF_SPINNING) ? player->drawangle : (cmd->angleturn<<16)) + drawangleoffset - *myangle; + INT32 anglediff = ((player->pflags & PF_SPINNING) ? player->drawangle + drawangleoffset : (cmd->angleturn<<16)) - *myangle; if (alt) { diff --git a/src/p_user.c b/src/p_user.c index 93c3c2ef0..d6db2e26f 100644 --- a/src/p_user.c +++ b/src/p_user.c @@ -10018,16 +10018,13 @@ boolean P_MoveChaseCamera(player_t *player, camera_t *thiscam, boolean resetcall UINT8 forplayer = (thiscam == &camera) ? 0 : 1; fixed_t shift = FixedMul(FINESINE((player->mo->angle - angle) >> ANGLETOFINESHIFT), cv_cam_shiftfacing[forplayer].value); - if (player->powers[pw_carry] == CR_ROLLOUT) - shift = -shift; - if (player->powers[pw_carry] == CR_NIGHTSMODE) { fixed_t cos = FINECOSINE((angle_t) (player->flyangle * ANG1)>>ANGLETOFINESHIFT); shift = FixedMul(shift, min(FRACUNIT, player->speed*abs(cos)/6000)); + shift += FixedMul(camsideshift[forplayer] - shift, FRACUNIT-(camspeed>>2)); } - - if (ticcmd_centerviewdown[(thiscam == &camera) ? 0 : 1]) + else if (ticcmd_centerviewdown[(thiscam == &camera) ? 0 : 1]) shift = FixedMul(camsideshift[forplayer], FRACUNIT-camspeed); else shift += FixedMul(camsideshift[forplayer] - shift, FRACUNIT-(camspeed>>3)); From 230006553dea1907f9d6ad04e946b725a56c66a9 Mon Sep 17 00:00:00 2001 From: MascaraSnake Date: Sun, 15 Dec 2019 21:43:50 +0100 Subject: [PATCH 211/746] Set mapthing z in OP_CreateNewMapThing --- src/m_cheat.c | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/src/m_cheat.c b/src/m_cheat.c index e31ce7869..0451a5fb3 100644 --- a/src/m_cheat.c +++ b/src/m_cheat.c @@ -1106,7 +1106,7 @@ static mapthing_t *OP_CreateNewMapThing(player_t *player, UINT16 type, boolean c #else fixed_t cheight = sec->ceilingheight; #endif - mt->options = (UINT16)((cheight - player->mo->z - player->mo->height)>>FRACBITS); + mt->z = (UINT16)((cheight - player->mo->z - player->mo->height)>>FRACBITS); } else { @@ -1115,12 +1115,11 @@ static mapthing_t *OP_CreateNewMapThing(player_t *player, UINT16 type, boolean c #else fixed_t fheight = sec->floorheight; #endif - mt->options = (UINT16)((player->mo->z - fheight)>>FRACBITS); + mt->z = (UINT16)((player->mo->z - fheight)>>FRACBITS); } - mt->options <<= ZSHIFT; mt->angle = (INT16)(FixedInt(AngleFixed(player->mo->angle))); - mt->options |= (UINT16)cv_opflags.value; + mt->options = (mt->z << ZSHIFT) | (UINT16)cv_opflags.value; return mt; } From bb3440d02127af605dbb75ccfa5c7878efebeece Mon Sep 17 00:00:00 2001 From: MascaraSnake Date: Mon, 16 Dec 2019 00:04:48 +0100 Subject: [PATCH 212/746] Minor cleanup of virtual resources code --- src/p_setup.c | 24 +++++++++--------------- src/w_wad.c | 16 ++++++++-------- src/w_wad.h | 6 +++--- 3 files changed, 20 insertions(+), 26 deletions(-) diff --git a/src/p_setup.c b/src/p_setup.c index cc53f2d3d..f1607c272 100644 --- a/src/p_setup.c +++ b/src/p_setup.c @@ -367,12 +367,7 @@ UINT32 P_GetScoreForGrade(INT16 map, UINT8 mare, UINT8 grade) return mapheaderinfo[map-1]->grades[mare].grade[grade-1]; } -/** Loads the vertexes for a level. - * - * \param lump VERTEXES lump number. - * \sa ML_VERTEXES - */ - +// Loads the vertexes for a level. static inline void P_LoadRawVertexes(UINT8 *data) { mapvertex_t *ml = (mapvertex_t *)data; @@ -666,7 +661,6 @@ INT32 P_CheckLevelFlat(const char *flatname) } // Sets up the ingame sectors structures. -// Lumpnum is the lumpnum of a SECTORS lump. static void P_LoadRawSectors(UINT8 *data) { mapsector_t *ms = (mapsector_t *)data; @@ -1147,7 +1141,7 @@ static void P_LoadRawLineDefs(UINT8 *data) } } -static void SetupLines (void) +static void P_SetupLines(void) { line_t *ld = lines; size_t i; @@ -1933,7 +1927,7 @@ static void P_LoadRawReject(UINT8 *data, size_t count) } } -static void LoadMapBSP (const virtres_t* virt) +static void P_LoadMapBSP(const virtres_t* virt) { virtlump_t* virtssectors = vres_Find(virt, "SSECTORS"); virtlump_t* virtsegs = vres_Find(virt, "SEGS"); @@ -1945,7 +1939,7 @@ static void LoadMapBSP (const virtres_t* virt) P_LoadRawSegs(virtsegs->data, virtsegs->size); } -static void LoadMapLUT (const virtres_t* virt) +static void P_LoadMapLUT(const virtres_t* virt) { virtlump_t* virtblockmap = vres_Find(virt, "BLOCKMAP"); virtlump_t* virtreject = vres_Find(virt, "REJECT"); @@ -1960,7 +1954,7 @@ static void LoadMapLUT (const virtres_t* virt) P_CreateBlockMap(); } -static void LoadMapData (const virtres_t* virt) +static void P_LoadMapData(const virtres_t* virt) { virtlump_t* virtvertexes = NULL, * virtsectors = NULL, * virtsidedefs = NULL, * virtlinedefs = NULL, * virtthings = NULL; #ifdef UDMF @@ -2022,7 +2016,7 @@ static void LoadMapData (const virtres_t* virt) P_LoadRawVertexes(virtvertexes->data); P_LoadRawSectors(virtsectors->data); P_LoadRawLineDefs(virtlinedefs->data); - SetupLines(); + P_SetupLines(); P_LoadRawSideDefs2(virtsidedefs->data); } } @@ -2784,9 +2778,9 @@ boolean P_SetupLevel(boolean skipprecip) { virtres_t* virt = vres_GetMap(lastloadedmaplumpnum); - LoadMapData(virt); - LoadMapBSP(virt); - LoadMapLUT(virt); + P_LoadMapData(virt); + P_LoadMapBSP(virt); + P_LoadMapLUT(virt); P_LoadLineDefs2(); P_GroupLines(); diff --git a/src/w_wad.c b/src/w_wad.c index f16e8eb5b..9cedd242f 100644 --- a/src/w_wad.c +++ b/src/w_wad.c @@ -1895,12 +1895,12 @@ int W_VerifyNMUSlumps(const char *filename) * \return Virtual resource * */ -virtres_t* vres_GetMap (lumpnum_t lumpnum) +virtres_t* vres_GetMap(lumpnum_t lumpnum) { UINT32 i; - virtres_t* vres = NULL; - virtlump_t* vlumps = NULL; - size_t numlumps = 0; + virtres_t* vres = NULL; + virtlump_t* vlumps = NULL; + size_t numlumps = 0; if (W_IsLumpWad(lumpnum)) { @@ -1942,8 +1942,8 @@ virtres_t* vres_GetMap (lumpnum_t lumpnum) } } vres = Z_Malloc(sizeof(virtres_t), PU_LEVEL, NULL); - vres->vlumps = vlumps; - vres->numlumps = numlumps; + vres->vlumps = vlumps; + vres->numlumps = numlumps; return vres; } @@ -1952,7 +1952,7 @@ virtres_t* vres_GetMap (lumpnum_t lumpnum) * * \param Virtual resource */ -void vres_Free (virtres_t* vres) +void vres_Free(virtres_t* vres) { while (vres->numlumps--) Z_Free(vres->vlumps[vres->numlumps].data); @@ -1963,7 +1963,7 @@ void vres_Free (virtres_t* vres) /** (Debug) Prints lumps from a virtual resource into console. */ /* -static void vres_Diag (const virtres_t* vres) +static void vres_Diag(const virtres_t* vres) { UINT32 i; for (i = 0; i < vres->numlumps; i++) diff --git a/src/w_wad.h b/src/w_wad.h index a265d78a9..8008a577c 100644 --- a/src/w_wad.h +++ b/src/w_wad.h @@ -87,9 +87,9 @@ typedef struct { virtlump_t* vlumps; } virtres_t; -virtres_t* vres_GetMap (lumpnum_t); -void vres_Free (virtres_t*); -virtlump_t* vres_Find (const virtres_t*, const char*); +virtres_t* vres_GetMap(lumpnum_t); +void vres_Free(virtres_t*); +virtlump_t* vres_Find(const virtres_t*, const char*); // ========================================================================= // DYNAMIC WAD LOADING From 79350992dffa88f5982df44174b9a04b608b13be Mon Sep 17 00:00:00 2001 From: MascaraSnake Date: Mon, 16 Dec 2019 00:17:20 +0100 Subject: [PATCH 213/746] Some more cleanup of map loading code --- src/p_setup.c | 90 ++++++++++++++++++++++----------------------------- 1 file changed, 39 insertions(+), 51 deletions(-) diff --git a/src/p_setup.c b/src/p_setup.c index f1607c272..ca99c8705 100644 --- a/src/p_setup.c +++ b/src/p_setup.c @@ -413,25 +413,15 @@ static inline float P_SegLengthFloat(seg_t *seg) } #endif -/** Loads the SEGS resource from a level. - * - * \param lump Lump number of the SEGS resource. - * \sa ::ML_SEGS - */ -static void P_LoadRawSegs(UINT8 *data, size_t i) +// Loads the SEGS resource from a level. +static void P_LoadRawSegs(UINT8 *data) { INT32 linedef, side; - mapseg_t *ml; - seg_t *li; + mapseg_t *ml = (mapseg_t*)data; + seg_t *li = segs; line_t *ldef; + size_t i; - numsegs = i / sizeof (mapseg_t); - if (numsegs <= 0) - I_Error("Level has no segs"); // instead of crashing - segs = Z_Calloc(numsegs * sizeof (*segs), PU_LEVEL, NULL); - - ml = (mapseg_t *)data; - li = segs; for (i = 0; i < numsegs; i++, li++, ml++) { li->v1 = &vertexes[SHORT(ml->v1)]; @@ -456,7 +446,7 @@ static void P_LoadRawSegs(UINT8 *data, size_t i) li->side = side = SHORT(ml->side); li->sidedef = &sides[ldef->sidenum[side]]; li->frontsector = sides[ldef->sidenum[side]].sector; - if (ldef-> flags & ML_TWOSIDED) + if (ldef->flags & ML_TWOSIDED) li->backsector = sides[ldef->sidenum[side^1]].sector; else li->backsector = 0; @@ -466,22 +456,12 @@ static void P_LoadRawSegs(UINT8 *data, size_t i) } } -/** Loads the SSECTORS resource from a level. - * - * \param lump Lump number of the SSECTORS resource. - * \sa ::ML_SSECTORS - */ -static inline void P_LoadRawSubsectors(void *data, size_t i) +// Loads the SSECTORS resource from a level. +static inline void P_LoadRawSubsectors(void *data) { - mapsubsector_t *ms; - subsector_t *ss; - - numsubsectors = i / sizeof (mapsubsector_t); - if (numsubsectors <= 0) - I_Error("Level has no subsectors (did you forget to run it through a nodesbuilder?)"); - ss = subsectors = Z_Calloc(numsubsectors * sizeof (*subsectors), PU_LEVEL, NULL); - - ms = (mapsubsector_t *)data; + mapsubsector_t *ms = (mapsubsector_t*)data; + subsector_t *ss = subsectors; + size_t i; for (i = 0; i < numsubsectors; i++, ss++, ms++) { @@ -761,19 +741,12 @@ static void P_LoadRawSectors(UINT8 *data) // // P_LoadNodes // -static void P_LoadRawNodes(UINT8 *data, size_t i) +static void P_LoadRawNodes(UINT8 *data) { UINT8 j, k; - mapnode_t *mn; - node_t *no; - - numnodes = i / sizeof (mapnode_t); - if (numnodes <= 0) - I_Error("Level has no nodes"); - nodes = Z_Calloc(numnodes * sizeof (*nodes), PU_LEVEL, NULL); - - mn = (mapnode_t *)data; - no = nodes; + mapnode_t *mn = (mapnode_t*)data; + node_t *no = nodes; + size_t i; for (i = 0; i < numnodes; i++, no++, mn++) { @@ -1933,10 +1906,25 @@ static void P_LoadMapBSP(const virtres_t* virt) virtlump_t* virtsegs = vres_Find(virt, "SEGS"); virtlump_t* virtnodes = vres_Find(virt, "NODES"); + numsubsectors = virtssectors->size / sizeof(mapsubsector_t); + numnodes = virtnodes->size / sizeof(mapnode_t); + numsegs = virtsegs->size / sizeof(mapseg_t); + + if (numsubsectors <= 0) + I_Error("Level has no subsectors (did you forget to run it through a nodesbuilder?)"); + if (numnodes <= 0) + I_Error("Level has no nodes"); + if (numsegs <= 0) + I_Error("Level has no segs"); + + subsectors = Z_Calloc(numsubsectors * sizeof(*subsectors), PU_LEVEL, NULL); + nodes = Z_Calloc(numnodes * sizeof(*nodes), PU_LEVEL, NULL); + segs = Z_Calloc(numsegs * sizeof(*segs), PU_LEVEL, NULL); + // Nodes - P_LoadRawSubsectors(virtssectors->data, virtssectors->size); - P_LoadRawNodes(virtnodes->data, virtnodes->size); - P_LoadRawSegs(virtsegs->data, virtsegs->size); + P_LoadRawSubsectors(virtssectors->data); + P_LoadRawNodes(virtnodes->data); + P_LoadRawSegs(virtsegs->data); } static void P_LoadMapLUT(const virtres_t* virt) @@ -1981,7 +1969,7 @@ static void P_LoadMapData(const virtres_t* virt) virtsidedefs = vres_Find(virt, "SIDEDEFS"); virtlinedefs = vres_Find(virt, "LINEDEFS"); - // Traditional doom map format just assumes the number of elements from the lump sixes. + // Traditional doom map format just assumes the number of elements from the lump sizes. numvertexes = virtvertexes->size / sizeof (mapvertex_t); numsectors = virtsectors->size / sizeof (mapsector_t); numsides = virtsidedefs->size / sizeof (mapsidedef_t); @@ -1998,11 +1986,11 @@ static void P_LoadMapData(const virtres_t* virt) if (numlines <= 0) I_Error("Level has no linedefs"); - vertexes = Z_Calloc(numvertexes * sizeof (*vertexes), PU_LEVEL, NULL); - sectors = Z_Calloc(numsectors * sizeof (*sectors), PU_LEVEL, NULL); - sides = Z_Calloc(numsides * sizeof (*sides), PU_LEVEL, NULL); - lines = Z_Calloc(numlines * sizeof (*lines), PU_LEVEL, NULL); - mapthings= Z_Calloc(nummapthings * sizeof (*mapthings), PU_LEVEL, NULL); + vertexes = Z_Calloc(numvertexes * sizeof (*vertexes), PU_LEVEL, NULL); + sectors = Z_Calloc(numsectors * sizeof (*sectors), PU_LEVEL, NULL); + sides = Z_Calloc(numsides * sizeof (*sides), PU_LEVEL, NULL); + lines = Z_Calloc(numlines * sizeof (*lines), PU_LEVEL, NULL); + mapthings = Z_Calloc(nummapthings * sizeof (*mapthings), PU_LEVEL, NULL); #ifdef UDMF if (textmap) From f028bb021947d4ab9dc69566c2f95efc41a9acdd Mon Sep 17 00:00:00 2001 From: Monster Iestyn Date: Mon, 16 Dec 2019 17:46:27 +0000 Subject: [PATCH 214/746] Fix `numoflines` calculations in sectorlines_* functions by first typecasting seclines (the sector.lines address) to size_t before doing any math on it, then (after the math) typecast the result to size_t * and dereference it. And yes, this time I tested it to make sure it works :) --- src/lua_maplib.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/lua_maplib.c b/src/lua_maplib.c index 0fe1df0b6..b35bb6a41 100644 --- a/src/lua_maplib.c +++ b/src/lua_maplib.c @@ -445,7 +445,7 @@ static int sectorlines_get(lua_State *L) // get the "linecount" by shifting our retrieved memory address of "lines" to where "linecount" is in the sector_t, then dereferencing the result // we need this to determine the array's actual size, and therefore also the maximum value allowed as an index // this only works if seclines is actually a pointer to a sector's lines member in memory, oh boy - numoflines = (size_t)(*(seclines - (offsetof(sector_t, lines) - offsetof(sector_t, linecount)))); + numoflines = (size_t)(*(size_t *)(((size_t)seclines) - (offsetof(sector_t, lines) - offsetof(sector_t, linecount)))); /* OLD HACK // check first linedef to figure which of its sectors owns this sector->lines pointer @@ -479,7 +479,7 @@ static int sectorlines_num(lua_State *L) return luaL_error(L, "accessed sector_t.lines doesn't exist anymore."); // see comments in the _get function above - numoflines = (size_t)(*(seclines - (offsetof(sector_t, lines) - offsetof(sector_t, linecount)))); + numoflines = (size_t)(*(size_t *)(((size_t)seclines) - (offsetof(sector_t, lines) - offsetof(sector_t, linecount)))); lua_pushinteger(L, numoflines); return 1; } From 46f431616c51c29af69dc5f42302f63be789eeae Mon Sep 17 00:00:00 2001 From: Monster Iestyn Date: Mon, 16 Dec 2019 20:26:19 +0000 Subject: [PATCH 215/746] Added a lot of SOC-editable variables to Lua, as well as the tutorialmode boolean --- src/dehacked.c | 72 ++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 72 insertions(+) diff --git a/src/dehacked.c b/src/dehacked.c index 175c1fcfa..938699516 100644 --- a/src/dehacked.c +++ b/src/dehacked.c @@ -10479,12 +10479,84 @@ static inline int lib_getenum(lua_State *L) } else if (fastcmp(word,"paused")) { lua_pushboolean(L, paused); return 1; + // begin map vars + } else if (fastcmp(word,"spstage_start")) { + lua_pushinteger(L, spstage_start); + return 1; + } else if (fastcmp(word,"sstage_start")) { + lua_pushinteger(L, sstage_start); + return 1; + } else if (fastcmp(word,"sstage_end")) { + lua_pushinteger(L, sstage_end); + return 1; + } else if (fastcmp(word,"smpstage_start")) { + lua_pushinteger(L, smpstage_start); + return 1; + } else if (fastcmp(word,"smpstage_end")) { + lua_pushinteger(L, smpstage_end); + return 1; } else if (fastcmp(word,"titlemap")) { lua_pushinteger(L, titlemap); return 1; } else if (fastcmp(word,"titlemapinaction")) { lua_pushboolean(L, (titlemapinaction != TITLEMAP_OFF)); return 1; + } else if (fastcmp(word,"bootmap")) { + lua_pushinteger(L, bootmap); + return 1; + } else if (fastcmp(word,"tutorialmap")) { + lua_pushinteger(L, tutorialmap); + return 1; + } else if (fastcmp(word,"tutorialmode")) { + lua_pushboolean(L, tutorialmode); + return 1; + // end map vars + // begin CTF colors + } else if (fastcmp(word,"skincolor_redteam")) { + lua_pushinteger(L, skincolor_redteam); + return 1; + } else if (fastcmp(word,"skincolor_blueteam")) { + lua_pushinteger(L, skincolor_blueteam); + return 1; + } else if (fastcmp(word,"skincolor_redring")) { + lua_pushinteger(L, skincolor_redring); + return 1; + } else if (fastcmp(word,"skincolor_bluering")) { + lua_pushinteger(L, skincolor_bluering); + return 1; + // end CTF colors + // begin timers + } else if (fastcmp(word,"invulntics")) { + lua_pushinteger(L, invulntics); + return 1; + } else if (fastcmp(word,"sneakertics")) { + lua_pushinteger(L, sneakertics); + return 1; + } else if (fastcmp(word,"flashingtics")) { + lua_pushinteger(L, flashingtics); + return 1; + } else if (fastcmp(word,"tailsflytics")) { + lua_pushinteger(L, tailsflytics); + return 1; + } else if (fastcmp(word,"underwatertics")) { + lua_pushinteger(L, underwatertics); + return 1; + } else if (fastcmp(word,"spacetimetics")) { + lua_pushinteger(L, spacetimetics); + return 1; + } else if (fastcmp(word,"extralifetics")) { + lua_pushinteger(L, extralifetics); + return 1; + } else if (fastcmp(word,"nightslinktics")) { + lua_pushinteger(L, nightslinktics); + return 1; + } else if (fastcmp(word,"gameovertics")) { + lua_pushinteger(L, gameovertics); + return 1; + } else if (fastcmp(word,"ammoremovaltics")) { + lua_pushinteger(L, ammoremovaltics); + return 1; + // end timers } else if (fastcmp(word,"gametype")) { lua_pushinteger(L, gametype); return 1; From 0ab31b3de0136aa66b553ddd2b07c6df6c5cd588 Mon Sep 17 00:00:00 2001 From: Tatsuru Date: Mon, 16 Dec 2019 17:58:00 -0300 Subject: [PATCH 216/746] Let Lua toggle Match/CTF team scores HUD element --- src/lua_hud.h | 1 + src/lua_hudlib.c | 1 + src/st_stuff.c | 45 ++++++++++++++++++++++++++++++++++++++------- 3 files changed, 40 insertions(+), 7 deletions(-) diff --git a/src/lua_hud.h b/src/lua_hud.h index abfbba441..23e3ef834 100644 --- a/src/lua_hud.h +++ b/src/lua_hud.h @@ -21,6 +21,7 @@ enum hud { // Match / CTF / Tag / Ringslinger hud_weaponrings, hud_powerstones, + hud_teamscores, // NiGHTS mode hud_nightslink, hud_nightsdrill, diff --git a/src/lua_hudlib.c b/src/lua_hudlib.c index a2f48c4ad..5b5aa3b4b 100644 --- a/src/lua_hudlib.c +++ b/src/lua_hudlib.c @@ -48,6 +48,7 @@ static const char *const hud_disable_options[] = { "weaponrings", "powerstones", + "teamscores", "nightslink", "nightsdrill", diff --git a/src/st_stuff.c b/src/st_stuff.c index 1b8107edb..1b116a7f3 100644 --- a/src/st_stuff.c +++ b/src/st_stuff.c @@ -2320,14 +2320,20 @@ static void ST_drawTeamHUD(void) p = bflagico; else p = bmatcico; - + +#ifdef HAVE_BLUA + if (LUA_HudEnabled(hud_teamscores)) +#endif V_DrawSmallScaledPatch(BASEVIDWIDTH/2 - SEP - SHORT(p->width)/4, 4, V_HUDTRANS|V_PERPLAYER|V_SNAPTOTOP, p); - + if (gametype == GT_CTF) p = rflagico; else p = rmatcico; - + +#ifdef HAVE_BLUA + if (LUA_HudEnabled(hud_teamscores)) +#endif V_DrawSmallScaledPatch(BASEVIDWIDTH/2 + SEP - SHORT(p->width)/4, 4, V_HUDTRANS|V_PERPLAYER|V_SNAPTOTOP, p); if (gametype != GT_CTF) @@ -2339,28 +2345,53 @@ static void ST_drawTeamHUD(void) // Show which flags aren't at base. for (i = 0; i < MAXPLAYERS; i++) { - if (players[i].gotflag & GF_BLUEFLAG) // Blue flag isn't at base + if (players[i].gotflag & GF_BLUEFLAG // Blue flag isn't at base +#ifdef HAVE_BLUA + && LUA_HudEnabled(hud_teamscores) +#endif + ) V_DrawScaledPatch(BASEVIDWIDTH/2 - SEP - SHORT(nonicon->width)/2, 0, V_HUDTRANS|V_PERPLAYER|V_SNAPTOTOP, nonicon); - if (players[i].gotflag & GF_REDFLAG) // Red flag isn't at base + + if (players[i].gotflag & GF_REDFLAG // Red flag isn't at base +#ifdef HAVE_BLUA + && LUA_HudEnabled(hud_teamscores) +#endif + ) V_DrawScaledPatch(BASEVIDWIDTH/2 + SEP - SHORT(nonicon2->width)/2, 0, V_HUDTRANS|V_PERPLAYER|V_SNAPTOTOP, nonicon2); whichflag |= players[i].gotflag; + if ((whichflag & (GF_REDFLAG|GF_BLUEFLAG)) == (GF_REDFLAG|GF_BLUEFLAG)) break; // both flags were found, let's stop early } // Display a countdown timer showing how much time left until the flag returns to base. { - if (blueflag && blueflag->fuse > 1) + if (blueflag && blueflag->fuse > 1 +#ifdef HAVE_BLUA + && LUA_HudEnabled(hud_teamscores) +#endif + ) V_DrawCenteredString(BASEVIDWIDTH/2 - SEP, 8, V_YELLOWMAP|V_HUDTRANS|V_PERPLAYER|V_SNAPTOTOP, va("%u", (blueflag->fuse / TICRATE))); - if (redflag && redflag->fuse > 1) + if (redflag && redflag->fuse > 1 +#ifdef HAVE_BLUA + && LUA_HudEnabled(hud_teamscores) +#endif + ) V_DrawCenteredString(BASEVIDWIDTH/2 + SEP, 8, V_YELLOWMAP|V_HUDTRANS|V_PERPLAYER|V_SNAPTOTOP, va("%u", (redflag->fuse / TICRATE))); } } num: +#ifdef HAVE_BLUA + if (LUA_HudEnabled(hud_teamscores)) +#endif V_DrawCenteredString(BASEVIDWIDTH/2 - SEP, 16, V_HUDTRANS|V_PERPLAYER|V_SNAPTOTOP, va("%u", bluescore)); + +#ifdef HAVE_BLUA + if (LUA_HudEnabled(hud_teamscores)) +#endif V_DrawCenteredString(BASEVIDWIDTH/2 + SEP, 16, V_HUDTRANS|V_PERPLAYER|V_SNAPTOTOP, va("%u", redscore)); #undef SEP From 0e371774c828bd401af02d4f801a2802532a3bb2 Mon Sep 17 00:00:00 2001 From: Steel Titanium Date: Mon, 16 Dec 2019 21:25:41 -0500 Subject: [PATCH 217/746] Fix crash on mapload when removing Dragonbomber with Lua --- src/p_enemy.c | 31 +++++++++++++++++++++++-------- 1 file changed, 23 insertions(+), 8 deletions(-) diff --git a/src/p_enemy.c b/src/p_enemy.c index 74a11fe67..5361f453b 100644 --- a/src/p_enemy.c +++ b/src/p_enemy.c @@ -14712,20 +14712,35 @@ void A_DragonWing(mobj_t *actor) void A_DragonSegment(mobj_t *actor) { mobj_t *target = actor->target; - fixed_t dist = P_AproxDistance(P_AproxDistance(actor->x - target->x, actor->y - target->y), actor->z - target->z); - fixed_t radius = actor->radius + target->radius; - angle_t hangle = R_PointToAngle2(target->x, target->y, actor->x, actor->y); - angle_t zangle = R_PointToAngle2(0, target->z, dist, actor->z); - fixed_t hdist = P_ReturnThrustX(target, zangle, radius); - fixed_t xdist = P_ReturnThrustX(target, hangle, hdist); - fixed_t ydist = P_ReturnThrustY(target, hangle, hdist); - fixed_t zdist = P_ReturnThrustY(target, zangle, radius); + fixed_t dist; + fixed_t radius; + angle_t hangle; + angle_t zangle; + fixed_t hdist; + fixed_t xdist; + fixed_t ydist; + fixed_t zdist; #ifdef HAVE_BLUA if (LUA_CallAction("A_DragonSegment", actor)) return; #endif + if (target == NULL || !target->health) + { + P_RemoveMobj(actor); + return; + } + + dist = P_AproxDistance(P_AproxDistance(actor->x - target->x, actor->y - target->y), actor->z - target->z); + radius = actor->radius + target->radius; + hangle = R_PointToAngle2(target->x, target->y, actor->x, actor->y); + zangle = R_PointToAngle2(0, target->z, dist, actor->z); + hdist = P_ReturnThrustX(target, zangle, radius); + xdist = P_ReturnThrustX(target, hangle, hdist); + ydist = P_ReturnThrustY(target, hangle, hdist); + zdist = P_ReturnThrustY(target, zangle, radius); + actor->angle = hangle; P_TeleportMove(actor, target->x + xdist, target->y + ydist, target->z + zdist); } From 369563ad923af4948ab74c1c821c5dae481fdab2 Mon Sep 17 00:00:00 2001 From: Jaime Passos Date: Tue, 17 Dec 2019 12:50:41 -0300 Subject: [PATCH 218/746] allow models to change colors more than once. --- src/hardware/hw_md2.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/hardware/hw_md2.c b/src/hardware/hw_md2.c index 13ba007ee..ba7b70333 100644 --- a/src/hardware/hw_md2.c +++ b/src/hardware/hw_md2.c @@ -963,7 +963,7 @@ static void HWR_GetBlendedTexture(GLPatch_t *gpatch, GLPatch_t *blendgpatch, INT for (grmip = gpatch->mipmap; grmip->nextcolormap; ) { grmip = grmip->nextcolormap; - if (grmip->colormap == colormap || grmip->tcindex == skinnum) + if (grmip->colormap == colormap || (skinnum < 1 && grmip->tcindex == skinnum)) { if (grmip->downloaded && grmip->grInfo.data) { From 7e55dd31f5489fd4119781a7eccb0310abf7974c Mon Sep 17 00:00:00 2001 From: Jaime Passos Date: Tue, 17 Dec 2019 12:53:26 -0300 Subject: [PATCH 219/746] fix menu spacing --- src/m_menu.c | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/src/m_menu.c b/src/m_menu.c index 23dc10701..ab30d0707 100644 --- a/src/m_menu.c +++ b/src/m_menu.c @@ -1305,18 +1305,18 @@ static menuitem_t OP_OpenGLOptionsMenu[] = {IT_STRING|IT_CVAR, NULL, "Model lighting", &cv_grmodellighting, 32}, {IT_HEADER, NULL, "General", NULL, 51}, - {IT_STRING|IT_CVAR, NULL, "Field of view", &cv_grfov, 62}, - {IT_STRING|IT_CVAR, NULL, "Quality", &cv_scr_depth, 72}, - {IT_STRING|IT_CVAR, NULL, "Texture Filter", &cv_grfiltermode, 82}, - {IT_STRING|IT_CVAR, NULL, "Anisotropic", &cv_granisotropicmode,92}, + {IT_STRING|IT_CVAR, NULL, "Field of view", &cv_grfov, 63}, + {IT_STRING|IT_CVAR, NULL, "Quality", &cv_scr_depth, 73}, + {IT_STRING|IT_CVAR, NULL, "Texture Filter", &cv_grfiltermode, 83}, + {IT_STRING|IT_CVAR, NULL, "Anisotropic", &cv_granisotropicmode,93}, - {IT_HEADER, NULL, "Miscellaneous", NULL, 111}, - {IT_SUBMENU|IT_STRING, NULL, "Fog...", &OP_OpenGLFogDef, 123}, + {IT_HEADER, NULL, "Miscellaneous", NULL, 112}, + {IT_SUBMENU|IT_STRING, NULL, "Fog...", &OP_OpenGLFogDef, 124}, #ifdef ALAM_LIGHTING - {IT_SUBMENU|IT_STRING, NULL, "Lighting...", &OP_OpenGLLightingDef, 133}, + {IT_SUBMENU|IT_STRING, NULL, "Lighting...", &OP_OpenGLLightingDef, 134}, #endif #if defined (_WINDOWS) && (!((defined (__unix__) && !defined (MSDOS)) || defined (UNIXCOMMON) || defined (HAVE_SDL))) - {IT_STRING|IT_CVAR, NULL, "Fullscreen", &cv_fullscreen, 143}, + {IT_STRING|IT_CVAR, NULL, "Fullscreen", &cv_fullscreen, 144}, #endif }; From 6a5ea548e62891cc23db79a14bff5dc44db011dd Mon Sep 17 00:00:00 2001 From: Jaime Passos Date: Tue, 17 Dec 2019 13:00:50 -0300 Subject: [PATCH 220/746] make ROTANGLES be 360 --- src/doomdef.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/doomdef.h b/src/doomdef.h index d13ff9bc0..026498ca1 100644 --- a/src/doomdef.h +++ b/src/doomdef.h @@ -625,7 +625,7 @@ extern const char *compdate, *comptime, *comprevision, *compbranch; /// Sprite rotation #define ROTSPRITE -#define ROTANGLES 24 // Needs to be a divisor of 360 (45, 60, 90, 120...) +#define ROTANGLES 360 // Needs to be a divisor of 360 (45, 60, 90, 120...) #define ROTANGDIFF (360 / ROTANGLES) #ifndef HAVE_PNG From c6f36fc470f568ed904231862abea974b54c4f2e Mon Sep 17 00:00:00 2001 From: Jaime Passos Date: Tue, 17 Dec 2019 13:09:25 -0300 Subject: [PATCH 221/746] un-ROTSPRITE rollangle and spriteinfo --- src/d_clisrv.c | 6 ------ src/dehacked.c | 6 ------ src/hardware/hw_defs.h | 2 -- src/hardware/hw_md2.c | 8 -------- src/hardware/r_opengl/r_opengl.c | 2 -- src/info.h | 2 -- src/lua_baselib.c | 2 -- src/lua_infolib.c | 14 +------------- src/lua_libs.h | 2 -- src/lua_mobjlib.c | 8 -------- src/p_enemy.c | 23 ----------------------- src/p_inter.c | 2 -- src/p_mobj.c | 2 -- src/p_mobj.h | 4 ---- src/p_saveg.c | 10 ---------- src/p_user.c | 14 -------------- src/r_patch.c | 6 ------ src/r_patch.h | 4 ---- 18 files changed, 1 insertion(+), 116 deletions(-) diff --git a/src/d_clisrv.c b/src/d_clisrv.c index 7b6c35eb6..99c922a8a 100644 --- a/src/d_clisrv.c +++ b/src/d_clisrv.c @@ -611,11 +611,7 @@ static inline void resynch_write_player(resynch_pak *rsp, const size_t i) rsp->health = LONG(players[i].mo->health); rsp->angle = (angle_t)LONG(players[i].mo->angle); -#ifdef ROTSPRITE rsp->rollangle = (angle_t)LONG(players[i].mo->rollangle); -#else - rsp->rollangle = 0; -#endif rsp->x = LONG(players[i].mo->x); rsp->y = LONG(players[i].mo->y); rsp->z = LONG(players[i].mo->z); @@ -766,9 +762,7 @@ static void resynch_read_player(resynch_pak *rsp) //At this point, the player should have a body, whether they were respawned or not. P_UnsetThingPosition(players[i].mo); players[i].mo->angle = (angle_t)LONG(rsp->angle); -#ifdef ROTSPRITE players[i].mo->rollangle = (angle_t)LONG(rsp->rollangle); -#endif players[i].mo->eflags = (UINT16)SHORT(rsp->eflags); players[i].mo->flags = LONG(rsp->flags); players[i].mo->flags2 = LONG(rsp->flags2); diff --git a/src/dehacked.c b/src/dehacked.c index 175c1fcfa..b9fe96edd 100644 --- a/src/dehacked.c +++ b/src/dehacked.c @@ -863,14 +863,12 @@ static void readspriteframe(MYFILE *f, spriteinfo_t *sprinfo, UINT8 frame) strupr(word); value = atoi(word2); // used for numerical settings -#ifdef ROTSPRITE if (fastcmp(word, "XPIVOT")) sprinfo->pivot[frame].x = value; else if (fastcmp(word, "YPIVOT")) sprinfo->pivot[frame].y = value; else if (fastcmp(word, "ROTAXIS")) sprinfo->pivot[frame].rotaxis = value; -#endif else { f->curpos = lastline; @@ -2673,11 +2671,9 @@ static actionpointer_t actionpointers[] = {{A_SpawnObjectRelative}, "A_SPAWNOBJECTRELATIVE"}, {{A_ChangeAngleRelative}, "A_CHANGEANGLERELATIVE"}, {{A_ChangeAngleAbsolute}, "A_CHANGEANGLEABSOLUTE"}, -#ifdef ROTSPRITE {{A_RollAngle}, "A_ROLLANGLE"}, {{A_ChangeRollAngleRelative},"A_CHANGEROLLANGLERELATIVE"}, {{A_ChangeRollAngleAbsolute},"A_CHANGEROLLANGLEABSOLUTE"}, -#endif {{A_PlaySound}, "A_PLAYSOUND"}, {{A_FindTarget}, "A_FINDTARGET"}, {{A_FindTracer}, "A_FINDTRACER"}, @@ -9412,12 +9408,10 @@ struct { {"DI_SOUTHEAST",DI_SOUTHEAST}, {"NUMDIRS",NUMDIRS}, -#ifdef ROTSPRITE // Sprite rotation axis (rotaxis_t) {"ROTAXIS_X",ROTAXIS_X}, {"ROTAXIS_Y",ROTAXIS_Y}, {"ROTAXIS_Z",ROTAXIS_Z}, -#endif // Buttons (ticcmd_t) {"BT_WEAPONMASK",BT_WEAPONMASK}, //our first four bits. diff --git a/src/hardware/hw_defs.h b/src/hardware/hw_defs.h index 979093dc8..aa483fcef 100644 --- a/src/hardware/hw_defs.h +++ b/src/hardware/hw_defs.h @@ -115,13 +115,11 @@ typedef struct FLOAT fovxangle, fovyangle; UINT8 splitscreen; boolean flip; // screenflip -#ifdef ROTSPRITE boolean roll; SINT8 rollflip; FLOAT rollangle; // done to not override USE_FTRANSFORM_ANGLEZ UINT8 rotaxis; FLOAT centerx, centery; -#endif #ifdef USE_FTRANSFORM_MIRROR boolean mirror; // SRB2Kart: Encore Mode #endif diff --git a/src/hardware/hw_md2.c b/src/hardware/hw_md2.c index 13ba007ee..9f8537b61 100644 --- a/src/hardware/hw_md2.c +++ b/src/hardware/hw_md2.c @@ -1148,10 +1148,8 @@ boolean HWR_DrawModel(gr_vissprite_t *spr) const UINT8 flip = (UINT8)(!(spr->mobj->eflags & MFE_VERTICALFLIP) != !(spr->mobj->frame & FF_VERTICALFLIP)); spritedef_t *sprdef; spriteframe_t *sprframe; -#ifdef ROTSPRITE spriteinfo_t *sprinfo; angle_t ang; -#endif INT32 mod; float finalscale; @@ -1175,16 +1173,12 @@ boolean HWR_DrawModel(gr_vissprite_t *spr) { md2 = &md2_playermodels[(skin_t*)spr->mobj->skin-skins]; md2->skin = (skin_t*)spr->mobj->skin-skins; -#ifdef ROTSPRITE sprinfo = &((skin_t *)spr->mobj->skin)->sprinfo[spr->mobj->sprite2]; -#endif } else { md2 = &md2_models[spr->mobj->sprite]; -#ifdef ROTSPRITE sprinfo = &spriteinfo[spr->mobj->sprite]; -#endif } if (md2->error) @@ -1384,7 +1378,6 @@ boolean HWR_DrawModel(gr_vissprite_t *spr) p.angley = FIXED_TO_FLOAT(anglef); } -#ifdef ROTSPRITE p.rollangle = 0.0f; p.rollflip = 0; p.rotaxis = 0; @@ -1409,7 +1402,6 @@ boolean HWR_DrawModel(gr_vissprite_t *spr) else if ((sprframe->rotate & SRF_LEFT) && (ang >= ANGLE_180)) // See from left p.rollflip = -1; } -#endif p.anglex = 0.0f; diff --git a/src/hardware/r_opengl/r_opengl.c b/src/hardware/r_opengl/r_opengl.c index 129bf5678..97b3b98be 100644 --- a/src/hardware/r_opengl/r_opengl.c +++ b/src/hardware/r_opengl/r_opengl.c @@ -2076,7 +2076,6 @@ static void DrawModelEx(model_t *model, INT32 frameIndex, INT32 duration, INT32 pglRotatef(pos->angley, 0.0f, -1.0f, 0.0f); pglRotatef(pos->anglex, 1.0f, 0.0f, 0.0f); -#ifdef ROTSPRITE if (pos->roll) { float roll = (1.0f * pos->rollflip); @@ -2089,7 +2088,6 @@ static void DrawModelEx(model_t *model, INT32 frameIndex, INT32 duration, INT32 pglRotatef(pos->rollangle, roll, 0.0f, 0.0f); pglTranslatef(-pos->centerx, -pos->centery, 0); } -#endif pglScalef(scalex, scaley, scalez); diff --git a/src/info.h b/src/info.h index 26fb1738d..261abbac5 100644 --- a/src/info.h +++ b/src/info.h @@ -155,11 +155,9 @@ void A_SpawnObjectAbsolute(); void A_SpawnObjectRelative(); void A_ChangeAngleRelative(); void A_ChangeAngleAbsolute(); -#ifdef ROTSPRITE void A_RollAngle(); void A_ChangeRollAngleRelative(); void A_ChangeRollAngleAbsolute(); -#endif void A_PlaySound(); void A_FindTarget(); void A_FindTracer(); diff --git a/src/lua_baselib.c b/src/lua_baselib.c index b68d16c2a..0df2ac45c 100644 --- a/src/lua_baselib.c +++ b/src/lua_baselib.c @@ -144,10 +144,8 @@ static const struct { {META_MOBJINFO, "mobjinfo_t"}, {META_SFXINFO, "sfxinfo_t"}, {META_SPRITEINFO, "spriteinfo_t"}, -#ifdef ROTSPRITE {META_PIVOTLIST, "spriteframepivot_t[]"}, {META_FRAMEPIVOT, "spriteframepivot_t"}, -#endif {META_MOBJ, "mobj_t"}, {META_MAPTHING, "mapthing_t"}, diff --git a/src/lua_infolib.c b/src/lua_infolib.c index b617a7a14..7a2465ef7 100644 --- a/src/lua_infolib.c +++ b/src/lua_infolib.c @@ -266,7 +266,6 @@ static int lib_getSpriteInfo(lua_State *L) #define FIELDERROR(f, e) luaL_error(L, "bad value for " LUA_QL(f) " in table passed to spriteinfo[] (%s)", e); #define TYPEERROR(f, t1, t2) FIELDERROR(f, va("%s expected, got %s", lua_typename(L, t1), lua_typename(L, t2))) -#ifdef ROTSPRITE static int PopPivotSubTable(spriteframepivot_t *pivot, lua_State *L, int stk, int idx) { int okcool = 0; @@ -360,7 +359,6 @@ static int PopPivotTable(spriteinfo_t *info, lua_State *L, int stk) return 0; } -#endif static int lib_setSpriteInfo(lua_State *L) { @@ -393,14 +391,11 @@ static int lib_setSpriteInfo(lua_State *L) if (lua_isnumber(L, 2)) { i = lua_tointeger(L, 2); -#ifndef ROTSPRITE i++; // shift index in case of missing rotsprite support -#endif } else str = luaL_checkstring(L, 2); -#ifdef ROTSPRITE if (i == 1 || (str && fastcmp(str, "pivot"))) { // pivot[] is a table @@ -409,7 +404,6 @@ static int lib_setSpriteInfo(lua_State *L) else FIELDERROR("pivot", va("%s expected, got %s", lua_typename(L, LUA_TTABLE), luaL_typename(L, -1))) } -#endif lua_pop(L, 1); } @@ -434,7 +428,6 @@ static int spriteinfo_get(lua_State *L) I_Assert(sprinfo != NULL); -#ifdef ROTSPRITE // push spriteframepivot_t userdata if (fastcmp(field, "pivot")) { @@ -448,7 +441,6 @@ static int spriteinfo_get(lua_State *L) return 1; } else -#endif return luaL_error(L, LUA_QL("spriteinfo_t") " has no field named " LUA_QS, field); return 0; @@ -473,6 +465,7 @@ static int spriteinfo_set(lua_State *L) #ifdef ROTSPRITE if (sprites != NULL) R_FreeSingleRotSprite(&sprites[sprinfo-spriteinfo]); +#endif if (fastcmp(field, "pivot")) { @@ -488,7 +481,6 @@ static int spriteinfo_set(lua_State *L) } } else -#endif return luaL_error(L, va("Field %s does not exist in spriteinfo_t", field)); return 0; @@ -506,7 +498,6 @@ static int spriteinfo_num(lua_State *L) } // framepivot_t -#ifdef ROTSPRITE static int pivotlist_get(lua_State *L) { void **userdata; @@ -616,7 +607,6 @@ static int framepivot_num(lua_State *L) lua_pushinteger(L, 2); return 1; } -#endif //////////////// // STATE INFO // @@ -1538,7 +1528,6 @@ int LUA_InfoLib(lua_State *L) lua_setfield(L, -2, "__len"); lua_pop(L, 1); -#ifdef ROTSPRITE luaL_newmetatable(L, META_PIVOTLIST); lua_pushcfunction(L, pivotlist_get); lua_setfield(L, -2, "__index"); @@ -1560,7 +1549,6 @@ int LUA_InfoLib(lua_State *L) lua_pushcfunction(L, framepivot_num); lua_setfield(L, -2, "__len"); lua_pop(L, 1); -#endif lua_newuserdata(L, 0); lua_createtable(L, 0, 2); diff --git a/src/lua_libs.h b/src/lua_libs.h index 104a1e51c..6a908d03d 100644 --- a/src/lua_libs.h +++ b/src/lua_libs.h @@ -23,10 +23,8 @@ extern lua_State *gL; #define META_MOBJINFO "MOBJINFO_T*" #define META_SFXINFO "SFXINFO_T*" #define META_SPRITEINFO "SPRITEINFO_T*" -#ifdef ROTSPRITE #define META_PIVOTLIST "SPRITEFRAMEPIVOT_T[]" #define META_FRAMEPIVOT "SPRITEFRAMEPIVOT_T*" -#endif #define META_MOBJ "MOBJ_T*" #define META_MAPTHING "MAPTHING_T*" diff --git a/src/lua_mobjlib.c b/src/lua_mobjlib.c index 49f93d29c..222487751 100644 --- a/src/lua_mobjlib.c +++ b/src/lua_mobjlib.c @@ -32,9 +32,7 @@ enum mobj_e { mobj_snext, mobj_sprev, mobj_angle, -#ifdef ROTSPRITE mobj_rollangle, -#endif mobj_sprite, mobj_frame, mobj_sprite2, @@ -101,9 +99,7 @@ static const char *const mobj_opt[] = { "snext", "sprev", "angle", -#ifdef ROTSPRITE "rollangle", -#endif "sprite", "frame", "sprite2", @@ -205,11 +201,9 @@ static int mobj_get(lua_State *L) case mobj_angle: lua_pushangle(L, mo->angle); break; -#ifdef ROTSPRITE case mobj_rollangle: lua_pushangle(L, mo->rollangle); break; -#endif case mobj_sprite: lua_pushinteger(L, mo->sprite); break; @@ -462,11 +456,9 @@ static int mobj_set(lua_State *L) else if (mo->player == &players[secondarydisplayplayer]) localangle2 = mo->angle; break; -#ifdef ROTSPRITE case mobj_rollangle: mo->rollangle = luaL_checkangle(L, 3); break; -#endif case mobj_sprite: mo->sprite = luaL_checkinteger(L, 3); break; diff --git a/src/p_enemy.c b/src/p_enemy.c index 74a11fe67..9404c5735 100644 --- a/src/p_enemy.c +++ b/src/p_enemy.c @@ -181,11 +181,9 @@ void A_SpawnObjectAbsolute(mobj_t *actor); void A_SpawnObjectRelative(mobj_t *actor); void A_ChangeAngleRelative(mobj_t *actor); void A_ChangeAngleAbsolute(mobj_t *actor); -#ifdef ROTSPRITE void A_RollAngle(mobj_t *actor); void A_ChangeRollAngleRelative(mobj_t *actor); void A_ChangeRollAngleAbsolute(mobj_t *actor); -#endif // ROTSPRITE void A_PlaySound(mobj_t *actor); void A_FindTarget(mobj_t *actor); void A_FindTracer(mobj_t *actor); @@ -8627,7 +8625,6 @@ void A_ChangeAngleAbsolute(mobj_t *actor) actor->angle = FixedAngle(P_RandomRange(amin, amax)); } -#ifdef ROTSPRITE // Function: A_RollAngle // // Description: Changes the roll angle. @@ -8663,16 +8660,10 @@ void A_RollAngle(mobj_t *actor) // void A_ChangeRollAngleRelative(mobj_t *actor) { - // Oh god, the old code /sucked/. Changed this and the absolute version to get a random range using amin and amax instead of - // getting a random angle from the _entire_ spectrum and then clipping. While we're at it, do the angle conversion to the result - // rather than the ranges, so <0 and >360 work as possible values. -Red INT32 locvar1 = var1; INT32 locvar2 = var2; - //angle_t angle = (P_RandomByte()+1)<<24; const fixed_t amin = locvar1*FRACUNIT; const fixed_t amax = locvar2*FRACUNIT; - //const angle_t amin = FixedAngle(locvar1*FRACUNIT); - //const angle_t amax = FixedAngle(locvar2*FRACUNIT); #ifdef HAVE_BLUA if (LUA_CallAction("A_ChangeRollAngleRelative", actor)) return; @@ -8682,11 +8673,6 @@ void A_ChangeRollAngleRelative(mobj_t *actor) if (amin > amax) I_Error("A_ChangeRollAngleRelative: var1 is greater than var2"); #endif -/* - if (angle < amin) - angle = amin; - if (angle > amax) - angle = amax;*/ actor->rollangle += FixedAngle(P_RandomRange(amin, amax)); } @@ -8702,11 +8688,8 @@ void A_ChangeRollAngleAbsolute(mobj_t *actor) { INT32 locvar1 = var1; INT32 locvar2 = var2; - //angle_t angle = (P_RandomByte()+1)<<24; const fixed_t amin = locvar1*FRACUNIT; const fixed_t amax = locvar2*FRACUNIT; - //const angle_t amin = FixedAngle(locvar1*FRACUNIT); - //const angle_t amax = FixedAngle(locvar2*FRACUNIT); #ifdef HAVE_BLUA if (LUA_CallAction("A_ChangeRollAngleAbsolute", actor)) return; @@ -8716,15 +8699,9 @@ void A_ChangeRollAngleAbsolute(mobj_t *actor) if (amin > amax) I_Error("A_ChangeRollAngleAbsolute: var1 is greater than var2"); #endif -/* - if (angle < amin) - angle = amin; - if (angle > amax) - angle = amax;*/ actor->rollangle = FixedAngle(P_RandomRange(amin, amax)); } -#endif // ROTSPRITE // Function: A_PlaySound // diff --git a/src/p_inter.c b/src/p_inter.c index 70fb01fd0..00733bbd3 100644 --- a/src/p_inter.c +++ b/src/p_inter.c @@ -3005,9 +3005,7 @@ static inline void P_NiGHTSDamage(mobj_t *target, mobj_t *source) P_SetPlayerMobjState(target, S_PLAY_NIGHTS_STUN); S_StartSound(target, sfx_nghurt); -#ifdef ROTSPRITE player->mo->rollangle = 0; -#endif if (oldnightstime > 10*TICRATE && player->nightstime < 10*TICRATE) diff --git a/src/p_mobj.c b/src/p_mobj.c index dea4a7a4d..ef6be4844 100644 --- a/src/p_mobj.c +++ b/src/p_mobj.c @@ -9735,14 +9735,12 @@ void P_MobjThinker(mobj_t *mobj) } break; case MT_MINUS: -#ifdef ROTSPRITE { if (P_IsObjectOnGround(mobj)) mobj->rollangle = 0; else mobj->rollangle = R_PointToAngle2(0, 0, mobj->momz, (mobj->scale << 1) - min(abs(mobj->momz), mobj->scale << 1)); } -#endif break; case MT_SPINFIRE: if (mobj->flags & MF_NOGRAVITY) diff --git a/src/p_mobj.h b/src/p_mobj.h index 40d850f16..744578d01 100644 --- a/src/p_mobj.h +++ b/src/p_mobj.h @@ -279,9 +279,7 @@ typedef struct mobj_s // More drawing info: to determine current sprite. angle_t angle; // orientation -#ifdef ROTSPRITE angle_t rollangle; -#endif spritenum_t sprite; // used to find patch_t and flip value UINT32 frame; // frame number, plus bits see p_pspr.h UINT8 sprite2; // player sprites @@ -402,9 +400,7 @@ typedef struct precipmobj_s // More drawing info: to determine current sprite. angle_t angle; // orientation -#ifdef ROTSPRITE angle_t rollangle; -#endif spritenum_t sprite; // used to find patch_t and flip value UINT32 frame; // frame number, plus bits see p_pspr.h UINT8 sprite2; // player sprites diff --git a/src/p_saveg.c b/src/p_saveg.c index 89447db80..068ac0295 100644 --- a/src/p_saveg.c +++ b/src/p_saveg.c @@ -1277,9 +1277,7 @@ typedef enum MD2_SLOPE = 1<<11, #endif MD2_COLORIZED = 1<<12, -#ifdef ROTSPRITE MD2_ROLLANGLE = 1<<13, -#endif } mobj_diff2_t; typedef enum @@ -1499,10 +1497,8 @@ static void SaveMobjThinker(const thinker_t *th, const UINT8 type) #endif if (mobj->colorized) diff2 |= MD2_COLORIZED; -#ifdef ROTSPRITE if (mobj->rollangle) diff2 |= MD2_ROLLANGLE; -#endif if (diff2 != 0) diff |= MD_MORE; @@ -1667,10 +1663,8 @@ static void SaveMobjThinker(const thinker_t *th, const UINT8 type) #endif if (diff2 & MD2_COLORIZED) WRITEUINT8(save_p, mobj->colorized); -#ifdef ROTSPRITE if (diff2 & MD2_ROLLANGLE) WRITEANGLE(save_p, mobj->rollangle); -#endif WRITEUINT32(save_p, mobj->mobjnum); } @@ -2747,12 +2741,8 @@ static thinker_t* LoadMobjThinker(actionf_p1 thinker) #endif if (diff2 & MD2_COLORIZED) mobj->colorized = READUINT8(save_p); -#ifdef ROTSPRITE if (diff2 & MD2_ROLLANGLE) mobj->rollangle = READANGLE(save_p); - else - mobj->rollangle = 0; -#endif if (diff & MD_REDFLAG) { diff --git a/src/p_user.c b/src/p_user.c index ea42a2c36..2968a53bc 100644 --- a/src/p_user.c +++ b/src/p_user.c @@ -638,9 +638,7 @@ static void P_DeNightserizePlayer(player_t *player) player->marebonuslap = 0; player->flyangle = 0; player->anotherflyangle = 0; -#ifdef ROTSPRITE player->mo->rollangle = 0; -#endif P_SetTarget(&player->mo->target, NULL); P_SetTarget(&player->axis1, P_SetTarget(&player->axis2, NULL)); @@ -768,9 +766,7 @@ void P_NightserizePlayer(player_t *player, INT32 nighttime) player->secondjump = 0; player->flyangle = 0; player->anotherflyangle = 0; -#ifdef ROTSPRITE player->mo->rollangle = 0; -#endif player->powers[pw_shield] = SH_NONE; player->powers[pw_super] = 0; @@ -6824,7 +6820,6 @@ static void P_DoNiGHTSCapsule(player_t *player) P_SetPlayerMobjState(player->mo, S_PLAY_ROLL); } -#ifdef ROTSPRITE if (!(player->charflags & SF_NONIGHTSROTATION)) { if ((player->mo->state == &states[S_PLAY_NIGHTS_PULL]) @@ -6833,7 +6828,6 @@ static void P_DoNiGHTSCapsule(player_t *player) else player->mo->rollangle = 0; } -#endif if (G_IsSpecialStage(gamemap)) { // In special stages, share rings. Everyone gives up theirs to the capsule player always, because we can't have any individualism here! @@ -7096,9 +7090,7 @@ static void P_NiGHTSMovement(player_t *player) INT32 i; statenum_t flystate; UINT16 visangle; -#ifdef ROTSPRITE angle_t rollangle = 0; -#endif player->pflags &= ~PF_DRILLING; @@ -7283,9 +7275,7 @@ static void P_NiGHTSMovement(player_t *player) && player->mo->state <= &states[S_PLAY_NIGHTS_TRANS6]) { player->mo->momx = player->mo->momy = player->mo->momz = 0; -#ifdef ROTSPRITE player->mo->rollangle = 0; -#endif return; } @@ -7611,7 +7601,6 @@ static void P_NiGHTSMovement(player_t *player) flystate += (visangle*2); // S_PLAY_NIGHTS_FLY0-C - the *2 is to skip over drill states #endif } -#ifdef ROTSPRITE else { angle_t a = R_PointToAngle(player->mo->x, player->mo->y) - player->mo->angle; @@ -7629,18 +7618,15 @@ static void P_NiGHTSMovement(player_t *player) rollangle = FixedAngle(visangle<mo->state != &states[flystate]) P_SetPlayerMobjState(player->mo, flystate); -#ifdef ROTSPRITE if (player->charflags & SF_NONIGHTSROTATION) player->mo->rollangle = 0; else player->mo->rollangle = rollangle; -#endif if (player == &players[consoleplayer]) localangle = player->mo->angle; diff --git a/src/r_patch.c b/src/r_patch.c index d4bfa9cbd..e538c1775 100644 --- a/src/r_patch.c +++ b/src/r_patch.c @@ -789,11 +789,9 @@ static void R_ParseSpriteInfoFrame(spriteinfo_t *info) size_t sprinfoTokenLength; char *frameChar = NULL; UINT8 frameFrame = 0xFF; -#ifdef ROTSPRITE INT16 frameXPivot = 0; INT16 frameYPivot = 0; rotaxis_t frameRotAxis = 0; -#endif // Sprite identifier sprinfoToken = M_GetToken(NULL); @@ -828,7 +826,6 @@ static void R_ParseSpriteInfoFrame(spriteinfo_t *info) } while (strcmp(sprinfoToken,"}")!=0) { -#ifdef ROTSPRITE if (stricmp(sprinfoToken, "XPIVOT")==0) { Z_Free(sprinfoToken); @@ -852,7 +849,6 @@ static void R_ParseSpriteInfoFrame(spriteinfo_t *info) else if ((stricmp(sprinfoToken, "Z")==0) || (stricmp(sprinfoToken, "ZAXIS")==0) || (stricmp(sprinfoToken, "YAW")==0)) frameRotAxis = ROTAXIS_Z; } -#endif Z_Free(sprinfoToken); sprinfoToken = M_GetToken(NULL); @@ -866,11 +862,9 @@ static void R_ParseSpriteInfoFrame(spriteinfo_t *info) } // set fields -#ifdef ROTSPRITE info->pivot[frameFrame].x = frameXPivot; info->pivot[frameFrame].y = frameYPivot; info->pivot[frameFrame].rotaxis = frameRotAxis; -#endif } // diff --git a/src/r_patch.h b/src/r_patch.h index 8a8ab5602..c534debdb 100644 --- a/src/r_patch.h +++ b/src/r_patch.h @@ -18,7 +18,6 @@ #include "doomdef.h" // Structs -#ifdef ROTSPRITE typedef enum { ROTAXIS_X, // Roll (the default) @@ -31,13 +30,10 @@ typedef struct INT32 x, y; rotaxis_t rotaxis; } spriteframepivot_t; -#endif typedef struct { -#ifdef ROTSPRITE spriteframepivot_t pivot[64]; -#endif boolean available; } spriteinfo_t; From 8422c88063405162a0a065bef827193120fd80ab Mon Sep 17 00:00:00 2001 From: Jaime Passos Date: Tue, 17 Dec 2019 13:25:55 -0300 Subject: [PATCH 222/746] optimise R_CacheRotSprite --- src/r_patch.c | 60 ++++++++++++++++++++++++++++++++------------------- 1 file changed, 38 insertions(+), 22 deletions(-) diff --git a/src/r_patch.c b/src/r_patch.c index e538c1775..e7ee9dd05 100644 --- a/src/r_patch.c +++ b/src/r_patch.c @@ -1096,6 +1096,35 @@ void R_LoadSpriteInfoLumps(UINT16 wadnum, UINT16 numlumps) } } +static UINT16 GetPatchPixel(patch_t *patch, INT32 x, INT32 y, boolean flip) +{ + fixed_t ofs; + column_t *column; + UINT8 *source; + + if (x < SHORT(patch->width)) + { + INT32 topdelta, prevdelta = -1; + column = (column_t *)((UINT8 *)patch + LONG(patch->columnofs[flip ? (patch->width-1-x) : x])); + while (column->topdelta != 0xff) + { + topdelta = column->topdelta; + if (topdelta <= prevdelta) + topdelta += prevdelta; + prevdelta = topdelta; + source = (UINT8 *)(column) + 3; + for (ofs = 0; ofs < column->length; ofs++) + { + if ((topdelta + ofs) == y) + return source[ofs]; + } + column = (column_t *)((UINT8 *)column + column->length + 4); + } + } + + return 0xFF00; +} + #ifdef ROTSPRITE // // R_CacheRotSprite @@ -1108,8 +1137,8 @@ void R_CacheRotSprite(spritenum_t sprnum, UINT8 frame, spriteinfo_t *sprinfo, sp INT32 angle; patch_t *patch; patch_t *newpatch; - UINT16 *rawsrc, *rawdst; - size_t size, size2; + UINT16 *rawdst; + size_t size; INT32 bflip = (flip != 0x00); #define SPRITE_XCENTER (leftoffset) @@ -1154,16 +1183,6 @@ void R_CacheRotSprite(spritenum_t sprnum, UINT8 frame, spriteinfo_t *sprinfo, sp leftoffset = width - leftoffset; } - // Draw the sprite to a temporary buffer. - size = (width*height); - rawsrc = Z_Malloc(size * sizeof(UINT16), PU_STATIC, NULL); - - // can't memset here - for (i = 0; i < size; i++) - rawsrc[i] = 0xFF00; - - R_PatchToFlat_16bpp(patch, rawsrc, bflip); - // Don't cache angle = 0 for (angle = 1; angle < ROTANGLES; angle++) { @@ -1231,17 +1250,15 @@ void R_CacheRotSprite(spritenum_t sprnum, UINT8 frame, spriteinfo_t *sprinfo, sp #undef BOUNDARYADJUST } - size2 = (newwidth * newheight); - if (!size2) - size2 = size; + // Draw the rotated sprite to a temporary buffer. + size = (newwidth * newheight); + if (!size) + size = (width * height); - rawdst = Z_Malloc(size2 * sizeof(UINT16), PU_STATIC, NULL); - - // can't memset here - for (i = 0; i < size2; i++) + rawdst = Z_Malloc(size * sizeof(UINT16), PU_STATIC, NULL); + for (i = 0; i < size; i++) rawdst[i] = 0xFF00; - // Draw the rotated sprite to a temporary buffer. for (dy = 0; dy < newheight; dy++) { for (dx = 0; dx < newwidth; dx++) @@ -1253,7 +1270,7 @@ void R_CacheRotSprite(spritenum_t sprnum, UINT8 frame, spriteinfo_t *sprinfo, sp sx >>= FRACBITS; sy >>= FRACBITS; if (sx >= 0 && sy >= 0 && sx < width && sy < height) - rawdst[(dy*newwidth)+dx] = rawsrc[(sy*width)+sx]; + rawdst[(dy*newwidth)+dx] = GetPatchPixel(patch, sx, sy, bflip); } } @@ -1290,7 +1307,6 @@ void R_CacheRotSprite(spritenum_t sprnum, UINT8 frame, spriteinfo_t *sprinfo, sp sprframe->rotsprite.cached[rot] = true; // free image data - Z_Free(rawsrc); Z_Free(patch); } #undef SPRITE_XCENTER From aff5b52ebaabca852ecdb6759b3d2b06bb8cfbe8 Mon Sep 17 00:00:00 2001 From: Jaime Passos Date: Tue, 17 Dec 2019 13:39:26 -0300 Subject: [PATCH 223/746] change ROTANGLES to 72 --- src/doomdef.h | 2 +- src/r_patch.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/doomdef.h b/src/doomdef.h index 026498ca1..579030a1c 100644 --- a/src/doomdef.h +++ b/src/doomdef.h @@ -625,7 +625,7 @@ extern const char *compdate, *comptime, *comprevision, *compbranch; /// Sprite rotation #define ROTSPRITE -#define ROTANGLES 360 // Needs to be a divisor of 360 (45, 60, 90, 120...) +#define ROTANGLES 72 // Needs to be a divisor of 360 (45, 60, 90, 120...) #define ROTANGDIFF (360 / ROTANGLES) #ifndef HAVE_PNG diff --git a/src/r_patch.c b/src/r_patch.c index e7ee9dd05..8d300f041 100644 --- a/src/r_patch.c +++ b/src/r_patch.c @@ -1102,7 +1102,7 @@ static UINT16 GetPatchPixel(patch_t *patch, INT32 x, INT32 y, boolean flip) column_t *column; UINT8 *source; - if (x < SHORT(patch->width)) + if (x >= 0 && x < SHORT(patch->width)) { INT32 topdelta, prevdelta = -1; column = (column_t *)((UINT8 *)patch + LONG(patch->columnofs[flip ? (patch->width-1-x) : x])); From e3ab21c85f5f4f328e2aab23c65bc7be44405e7b Mon Sep 17 00:00:00 2001 From: Jaime Passos Date: Tue, 17 Dec 2019 13:48:48 -0300 Subject: [PATCH 224/746] opengl --- src/hardware/hw_md2.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/hardware/hw_md2.c b/src/hardware/hw_md2.c index 9f8537b61..c18422145 100644 --- a/src/hardware/hw_md2.c +++ b/src/hardware/hw_md2.c @@ -1379,7 +1379,7 @@ boolean HWR_DrawModel(gr_vissprite_t *spr) } p.rollangle = 0.0f; - p.rollflip = 0; + p.rollflip = 1; p.rotaxis = 0; if (spr->mobj->rollangle) { From 0af71fafc57fb842a8c7a9a4853d8c7fbb2bf7fc Mon Sep 17 00:00:00 2001 From: Jaime Passos Date: Tue, 17 Dec 2019 15:20:22 -0300 Subject: [PATCH 225/746] Don't use the local palette, because OpenGL mixes it into the textures themselves --- src/m_anigif.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/src/m_anigif.c b/src/m_anigif.c index aec53b874..91f70dcfe 100644 --- a/src/m_anigif.c +++ b/src/m_anigif.c @@ -432,8 +432,11 @@ static void GIF_headwrite(void) // write color table { - RGBA_t *pal = ((cv_screenshot_colorprofile.value) - ? pLocalPalette + RGBA_t *pal = ((cv_screenshot_colorprofile.value +#ifdef HWRENDER + && (rendermode == render_soft) +#endif + ) ? pLocalPalette : pMasterPalette); for (i = 0; i < 256; i++) From c3f0e6aa4472f0754a7f392759b9f93cb3c7651b Mon Sep 17 00:00:00 2001 From: Jaime Passos Date: Tue, 17 Dec 2019 15:37:43 -0300 Subject: [PATCH 226/746] Avoid recreating the color LUT mid-recording-frame --- src/m_anigif.c | 21 +++++++++++++-------- src/v_video.c | 6 +++--- src/v_video.h | 2 +- 3 files changed, 17 insertions(+), 12 deletions(-) diff --git a/src/m_anigif.c b/src/m_anigif.c index 91f70dcfe..f761db143 100644 --- a/src/m_anigif.c +++ b/src/m_anigif.c @@ -33,6 +33,7 @@ consvar_t cv_gif_downscale = {"gif_downscale", "On", CV_SAVE, CV_OnOff, NULL, 0 #ifdef HAVE_ANIGIF static boolean gif_optimize = false; // So nobody can do something dumb static boolean gif_downscale = false; // like changing cvars mid output +static RGBA_t *gif_palette = NULL; static FILE *gif_out = NULL; static INT32 gif_frames = 0; @@ -432,13 +433,7 @@ static void GIF_headwrite(void) // write color table { - RGBA_t *pal = ((cv_screenshot_colorprofile.value -#ifdef HWRENDER - && (rendermode == render_soft) -#endif - ) ? pLocalPalette - : pMasterPalette); - + RGBA_t *pal = gif_palette; for (i = 0; i < 256; i++) { WRITEUINT8(p, pal[i].s.red); @@ -473,7 +468,7 @@ static void hwrconvert(void) INT32 x, y; size_t i = 0; - InitColorLUT(); + InitColorLUT(gif_palette); for (y = 0; y < vid.height; y++) { @@ -643,6 +638,16 @@ INT32 GIF_open(const char *filename) gif_optimize = (!!cv_gif_optimize.value); gif_downscale = (!!cv_gif_downscale.value); + + // GIF color table + // In hardware mode, uses the master palette + gif_palette = ((cv_screenshot_colorprofile.value +#ifdef HWRENDER + && (rendermode == render_soft) +#endif + ) ? pLocalPalette + : pMasterPalette); + GIF_headwrite(); gif_frames = 0; return 1; diff --git a/src/v_video.c b/src/v_video.c index 1e901f2b3..c91e5f213 100644 --- a/src/v_video.c +++ b/src/v_video.c @@ -3251,19 +3251,19 @@ Unoptimized version UINT8 colorlookup[CLUTSIZE][CLUTSIZE][CLUTSIZE]; -void InitColorLUT(void) +void InitColorLUT(RGBA_t *palette) { UINT8 r, g, b; static boolean clutinit = false; static RGBA_t *lastpalette = NULL; - if ((!clutinit) || (lastpalette != pLocalPalette)) + if ((!clutinit) || (lastpalette != palette)) { for (r = 0; r < CLUTSIZE; r++) for (g = 0; g < CLUTSIZE; g++) for (b = 0; b < CLUTSIZE; b++) colorlookup[r][g][b] = NearestColor(r << SHIFTCOLORBITS, g << SHIFTCOLORBITS, b << SHIFTCOLORBITS); clutinit = true; - lastpalette = pLocalPalette; + lastpalette = palette; } } diff --git a/src/v_video.h b/src/v_video.h index 0cd78d2e5..36d1914af 100644 --- a/src/v_video.h +++ b/src/v_video.h @@ -47,7 +47,7 @@ void V_Init(void); extern UINT8 colorlookup[CLUTSIZE][CLUTSIZE][CLUTSIZE]; -void InitColorLUT(void); +void InitColorLUT(RGBA_t *palette); // Set the current RGB palette lookup to use for palettized graphics void V_SetPalette(INT32 palettenum); From a0971d0756e1edd08a46695e8cf1c1bfee687fe7 Mon Sep 17 00:00:00 2001 From: Jaime Passos Date: Tue, 17 Dec 2019 15:56:56 -0300 Subject: [PATCH 227/746] Put loadgame patch loading back in M_ReadSaveStrings --- src/m_menu.c | 20 ++++++++------------ 1 file changed, 8 insertions(+), 12 deletions(-) diff --git a/src/m_menu.c b/src/m_menu.c index 9ddaf27d7..6107a3f8f 100644 --- a/src/m_menu.c +++ b/src/m_menu.c @@ -7669,18 +7669,6 @@ static void M_DrawLoadGameData(void) INT32 i, savetodraw, x, y, hsep = 90; skin_t *charskin = NULL; - // Lactozilla: Intentional, because there is - // no way to know if those patches were ever - // flushed from memory, other than pointers - // to nowhere. - savselp[0] = W_CachePatchName("SAVEBACK", PU_PATCH); - savselp[1] = W_CachePatchName("SAVENONE", PU_PATCH); - savselp[2] = W_CachePatchName("ULTIMATE", PU_PATCH); - - savselp[3] = W_CachePatchName("GAMEDONE", PU_PATCH); - savselp[4] = W_CachePatchName("BLACXLVL", PU_PATCH); - savselp[5] = W_CachePatchName("BLANKLVL", PU_PATCH); - if (vid.width != BASEVIDWIDTH*vid.dupx) hsep = (hsep*vid.width)/(BASEVIDWIDTH*vid.dupx); @@ -8159,6 +8147,14 @@ static void M_ReadSaveStrings(void) } M_ReadSavegameInfo(i); } + + savselp[0] = W_CachePatchName("SAVEBACK", PU_PATCH); + savselp[1] = W_CachePatchName("SAVENONE", PU_PATCH); + savselp[2] = W_CachePatchName("ULTIMATE", PU_PATCH); + + savselp[3] = W_CachePatchName("GAMEDONE", PU_PATCH); + savselp[4] = W_CachePatchName("BLACXLVL", PU_PATCH); + savselp[5] = W_CachePatchName("BLANKLVL", PU_PATCH); } // From e359f802fd7370d5462a594b6f4b60675a58503c Mon Sep 17 00:00:00 2001 From: Jaime Passos Date: Tue, 17 Dec 2019 16:14:26 -0300 Subject: [PATCH 228/746] Update comments --- src/d_main.c | 8 ++++---- src/hardware/hw_cache.c | 2 +- src/m_menu.c | 2 +- src/p_setup.c | 2 +- src/r_main.c | 2 +- src/screen.c | 4 ++-- src/y_inter.c | 2 +- 7 files changed, 11 insertions(+), 11 deletions(-) diff --git a/src/d_main.c b/src/d_main.c index 45cac3cf7..9d420dd22 100644 --- a/src/d_main.c +++ b/src/d_main.c @@ -225,7 +225,7 @@ static void D_Display(void) if (nodrawers) return; // for comparative timing/profiling - // Jimita: Switching renderers works by checking + // Lactozilla: Switching renderers works by checking // if the game has to do it right when the frame // needs to render. If so, five things will happen: // 1. Interface functions will be called so @@ -273,7 +273,7 @@ static void D_Display(void) forcerefresh = true; // force background redraw } - // Jimita + // Lactozilla: Renderer switching D_CheckRendererState(); // draw buffered stuff to screen @@ -583,7 +583,7 @@ static void D_Display(void) needpatchrecache = false; } -// Jimita: Check the renderer's state +// Lactozilla: Check the renderer's state // after a possible renderer switch. void D_CheckRendererState(void) { @@ -1281,7 +1281,7 @@ void D_SRB2Main(void) // set user default mode or mode set at cmdline SCR_CheckDefaultMode(); - // Jimita: Does the render mode need to change? + // Lactozilla: Does the render mode need to change? if ((setrenderneeded != 0) && (setrenderneeded != rendermode)) { needpatchflush = true; diff --git a/src/hardware/hw_cache.c b/src/hardware/hw_cache.c index e7a4637c9..2c7539f2c 100644 --- a/src/hardware/hw_cache.c +++ b/src/hardware/hw_cache.c @@ -884,7 +884,7 @@ GLTexture_t *HWR_GetTexture(INT32 tex) I_Error("HWR_GetTexture: tex >= numtextures\n"); #endif - // Jimita + // Lactozilla: Renderer switching if (needpatchrecache && (!gr_textures)) HWR_LoadTextures(gr_numtextures); diff --git a/src/m_menu.c b/src/m_menu.c index 4cac6dada..e108c421c 100644 --- a/src/m_menu.c +++ b/src/m_menu.c @@ -6022,7 +6022,7 @@ static void M_DrawAddons(void) return; } - // Jimita: Load addons menu patches. + // Lactozilla: Load addons menu patches. if (needpatchrecache) M_LoadAddonsPatches(); diff --git a/src/p_setup.c b/src/p_setup.c index dd9a6d5fe..42a6438a0 100644 --- a/src/p_setup.c +++ b/src/p_setup.c @@ -3019,7 +3019,7 @@ boolean P_SetupLevel(boolean skipprecip) P_SpawnPrecipitation(); #ifdef HWRENDER // not win32 only 19990829 by Kin - // Jimita: Free extrasubsectors regardless of renderer. + // Lactozilla: Free extrasubsectors regardless of renderer. // Maybe we're not in OpenGL anymore. if (extrasubsectors) free(extrasubsectors); diff --git a/src/r_main.c b/src/r_main.c index 06556e342..713480397 100644 --- a/src/r_main.c +++ b/src/r_main.c @@ -1156,7 +1156,7 @@ void R_RenderPlayerView(player_t *player) free(masks); } -// Jimita +// Lactozilla: Renderer switching #ifdef HWRENDER void R_InitHardwareMode(void) { diff --git a/src/screen.c b/src/screen.c index 56cdfba3c..f739a5177 100644 --- a/src/screen.c +++ b/src/screen.c @@ -197,7 +197,7 @@ void SCR_SetMode(void) if (!(setmodeneeded || setrenderneeded) || WipeInAction) return; // should never happen and don't change it during a wipe, BAD! - // Jimita + // Lactozilla: Renderer switching if (setrenderneeded) { needpatchflush = true; @@ -443,7 +443,7 @@ void SCR_ActuallyChangeRenderer(void) setrenderneeded = 0; } -// Jimita +// Lactozilla: Renderer switching void SCR_ChangeRenderer(void) { setrenderneeded = 0; diff --git a/src/y_inter.c b/src/y_inter.c index 51d267bd4..5123f2f97 100644 --- a/src/y_inter.c +++ b/src/y_inter.c @@ -323,7 +323,7 @@ void Y_IntermissionDrawer(void) if (intertype == int_none || rendermode == render_none) return; - // Jimita + // Lactozilla: Renderer switching if (needpatchrecache) { Y_CleanupData(); From 53885e5ac0c30cbd9dd8a704b297eaebfb747ec4 Mon Sep 17 00:00:00 2001 From: Jaime Passos Date: Tue, 17 Dec 2019 16:28:32 -0300 Subject: [PATCH 229/746] Free PU_HWRMODELTEXTURE tag --- src/w_wad.c | 2 +- src/z_zone.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/w_wad.c b/src/w_wad.c index 1d4b160a7..f889d2659 100644 --- a/src/w_wad.c +++ b/src/w_wad.c @@ -1512,7 +1512,7 @@ void W_FlushCachedPatches(void) Z_FreeTag(PU_PATCH); Z_FreeTag(PU_HUDGFX); Z_FreeTag(PU_HWRPATCHINFO); - Z_FreeTag(PU_HWRPATCHCOLMIPMAP); + Z_FreeTag(PU_HWRMODELTEXTURE); Z_FreeTag(PU_HWRCACHE); Z_FreeTags(PU_HWRCACHE_UNLOCKED, PU_HWRPATCHINFO_UNLOCKED); } diff --git a/src/z_zone.c b/src/z_zone.c index c1056b163..e0c56ced6 100644 --- a/src/z_zone.c +++ b/src/z_zone.c @@ -511,7 +511,7 @@ void Z_FlushCachedPatches(void) Z_FreeTag(PU_PATCH); Z_FreeTag(PU_HUDGFX); Z_FreeTag(PU_HWRPATCHINFO); - Z_FreeTag(PU_HWRPATCHCOLMIPMAP); + Z_FreeTag(PU_HWRMODELTEXTURE); Z_FreeTag(PU_HWRCACHE); Z_FreeTag(PU_HWRCACHE_UNLOCKED); Z_FreeTag(PU_HWRPATCHINFO_UNLOCKED); From 79daafd893d776d9b0b56ac31fd2ce3c0fc22626 Mon Sep 17 00:00:00 2001 From: Jaime Passos Date: Tue, 17 Dec 2019 18:04:05 -0300 Subject: [PATCH 230/746] 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 d1b944121ae68de10f6ef02207f26ac0e76ae2fa Mon Sep 17 00:00:00 2001 From: James R Date: Tue, 17 Dec 2019 14:11:45 -0800 Subject: [PATCH 231/746] Fix "SRB2" SOC directive, though its usefulness is debatable --- src/dehacked.c | 30 ++++++++++++++++++++++-------- src/dehacked.h | 2 +- 2 files changed, 23 insertions(+), 9 deletions(-) diff --git a/src/dehacked.c b/src/dehacked.c index 175c1fcfa..9abb708a9 100644 --- a/src/dehacked.c +++ b/src/dehacked.c @@ -4462,20 +4462,34 @@ static void DEH_LoadDehackedFile(MYFILE *f, boolean mainfile) ignorelines(f); } } - // Last I heard this crashes the game if you try to use it - // so this is disabled for now - // -- Monster Iestyn -/* else if (fastcmp(word, "SRB2")) + else if (fastcmp(word, "SRB2")) { - INT32 ver = searchvalue(strtok(NULL, "\n")); - if (ver != PATCHVERSION) - deh_warning("Patch is for SRB2 version %d,\nonly version %d is supported", ver, PATCHVERSION); + if (isdigit(word2[0])) + { + i = atoi(word2); + if (i != PATCHVERSION) + { + deh_warning( + "Patch is for SRB2 version %d, " + "only version %d is supported", + i, + PATCHVERSION + ); + } + } + else + { + deh_warning( + "SRB2 version definition has incorrect format, " + "use \"SRB2 %d\"", + PATCHVERSION + ); + } } // Clear all data in certain locations (mostly for unlocks) // Unless you REALLY want to piss people off, // define a custom gamedata /before/ doing this!! // (then again, modifiedgame will prevent game data saving anyway) -*/ else if (fastcmp(word, "CLEAR")) { boolean clearall = (fastcmp(word2, "ALL")); diff --git a/src/dehacked.h b/src/dehacked.h index d4fb07df0..2b34377fd 100644 --- a/src/dehacked.h +++ b/src/dehacked.h @@ -47,7 +47,7 @@ extern const char *superactions[MAXRECURSION]; extern UINT8 superstack; // If the dehacked patch does not match this version, we throw a warning -#define PATCHVERSION 210 +#define PATCHVERSION 220 #define MAXLINELEN 1024 From fc70164f93722414057e728e5de477f75ee6f131 Mon Sep 17 00:00:00 2001 From: Zachary McAlpin Date: Tue, 17 Dec 2019 18:41:26 -0600 Subject: [PATCH 232/746] Don't execute LUAh_PlayerThink(player) for respawning bots --- src/p_user.c | 5 ----- 1 file changed, 5 deletions(-) diff --git a/src/p_user.c b/src/p_user.c index 3baf8cd04..6682c128b 100644 --- a/src/p_user.c +++ b/src/p_user.c @@ -11313,12 +11313,7 @@ void P_PlayerThink(player_t *player) player->playerstate = PST_REBORN; } if (player->playerstate == PST_REBORN) - { -#ifdef HAVE_BLUA - LUAh_PlayerThink(player); -#endif return; - } } #ifdef SEENAMES From 3fc1069082fa3cc60e2b1929e0a25571007e1ad9 Mon Sep 17 00:00:00 2001 From: Zachary McAlpin Date: Tue, 17 Dec 2019 19:20:46 -0600 Subject: [PATCH 233/746] Don't run the LUAh_PlayerThink function if the time ran out in Race or Competition --- src/p_user.c | 5 ----- 1 file changed, 5 deletions(-) diff --git a/src/p_user.c b/src/p_user.c index 6682c128b..0ec02c3f4 100644 --- a/src/p_user.c +++ b/src/p_user.c @@ -11414,12 +11414,7 @@ void P_PlayerThink(player_t *player) player->lives = 0; if (player->playerstate == PST_DEAD) - { -#ifdef HAVE_BLUA - LUAh_PlayerThink(player); -#endif return; - } } } From 254d812901c6ba5c2ba53d70f4d0e8e0d9c14dc2 Mon Sep 17 00:00:00 2001 From: Jaime Passos Date: Wed, 18 Dec 2019 00:28:58 -0300 Subject: [PATCH 234/746] More customisable title card Add TitleCardZigZag, TitleCardZigZagText and TitleCardActDiamond fields to SOC. Add the same fields to Lua under their internal names. Turn map header level flags into an UINT16, so that NoTitleCard works. (NOBODY caught this, I'm actually disappointed.) --- src/dehacked.c | 19 ++++++++++++++++++- src/doomstat.h | 7 ++++++- src/lua_maplib.c | 6 ++++++ src/p_setup.c | 3 +++ src/st_stuff.c | 36 ++++++++++++++++++++++++------------ 5 files changed, 57 insertions(+), 14 deletions(-) diff --git a/src/dehacked.c b/src/dehacked.c index 175c1fcfa..c66f3589d 100644 --- a/src/dehacked.c +++ b/src/dehacked.c @@ -1520,10 +1520,27 @@ static void readlevelheader(MYFILE *f, INT32 num) deh_warning("Level header %d: invalid bonus type number %d", num, i); } + // Title card + else if (fastcmp(word, "TITLECARDZIGZAG")) + { + deh_strlcpy(mapheaderinfo[num-1]->ltzzpatch, word2, + sizeof(mapheaderinfo[num-1]->ltzzpatch), va("Level header %d: title card zigzag patch name", num)); + } + else if (fastcmp(word, "TITLECARDZIGZAGTEXT")) + { + deh_strlcpy(mapheaderinfo[num-1]->ltzztext, word2, + sizeof(mapheaderinfo[num-1]->ltzztext), va("Level header %d: title card zigzag text patch name", num)); + } + else if (fastcmp(word, "TITLECARDACTDIAMOND")) + { + deh_strlcpy(mapheaderinfo[num-1]->ltactdiamond, word2, + sizeof(mapheaderinfo[num-1]->ltactdiamond), va("Level header %d: title card act diamond patch name", num)); + } + else if (fastcmp(word, "MAXBONUSLIVES")) mapheaderinfo[num-1]->maxbonuslives = (SINT8)i; else if (fastcmp(word, "LEVELFLAGS")) - mapheaderinfo[num-1]->levelflags = (UINT8)i; + mapheaderinfo[num-1]->levelflags = (UINT16)i; else if (fastcmp(word, "MENUFLAGS")) mapheaderinfo[num-1]->menuflags = (UINT8)i; diff --git a/src/doomstat.h b/src/doomstat.h index 3c0b4773a..a42591f47 100644 --- a/src/doomstat.h +++ b/src/doomstat.h @@ -310,12 +310,17 @@ typedef struct SINT8 bonustype; ///< What type of bonus does this level have? (-1 for null.) SINT8 maxbonuslives; ///< How many bonus lives to award at Intermission? (-1 for unlimited.) - UINT8 levelflags; ///< LF_flags: merged booleans into one UINT8 for space, see below + UINT16 levelflags; ///< LF_flags: merged booleans into one UINT16 for space, see below UINT8 menuflags; ///< LF2_flags: options that affect record attack / nights mode menus char selectheading[22]; ///< Level select heading. Allows for controllable grouping. UINT16 startrings; ///< Number of rings players start with. + // Title card. + char ltzzpatch[8]; ///< Zig zag patch. + char ltzztext[8]; ///< Zig zag text. + char ltactdiamond[8]; ///< Act diamond. + // Freed animals stuff. UINT8 numFlickies; ///< Internal. For freed flicky support. mobjtype_t *flickies; ///< List of freeable flickies in this level. Allocated dynamically for space reasons. Be careful. diff --git a/src/lua_maplib.c b/src/lua_maplib.c index 0fe1df0b6..dd939c31b 100644 --- a/src/lua_maplib.c +++ b/src/lua_maplib.c @@ -2071,6 +2071,12 @@ static int mapheaderinfo_get(lua_State *L) lua_pushinteger(L, header->levelselect); else if (fastcmp(field,"bonustype")) lua_pushinteger(L, header->bonustype); + else if (fastcmp(field,"ltzzpatch")) + lua_pushstring(L, header->ltzzpatch); + else if (fastcmp(field,"ltzztext")) + lua_pushstring(L, header->ltzztext); + else if (fastcmp(field,"ltactdiamond")) + lua_pushstring(L, header->ltactdiamond); else if (fastcmp(field,"maxbonuslives")) lua_pushinteger(L, header->maxbonuslives); else if (fastcmp(field,"levelflags")) diff --git a/src/p_setup.c b/src/p_setup.c index bf3493d8c..2bbfe3924 100644 --- a/src/p_setup.c +++ b/src/p_setup.c @@ -210,6 +210,9 @@ static void P_ClearSingleMapHeaderInfo(INT16 i) mapheaderinfo[num]->lvlttl[0] = '\0'; mapheaderinfo[num]->selectheading[0] = '\0'; mapheaderinfo[num]->subttl[0] = '\0'; + mapheaderinfo[num]->ltzzpatch[0] = '\0'; + mapheaderinfo[num]->ltzztext[0] = '\0'; + mapheaderinfo[num]->ltactdiamond[0] = '\0'; mapheaderinfo[num]->actnum = 0; mapheaderinfo[num]->typeoflevel = 0; mapheaderinfo[num]->nextlevel = (INT16)(i + 1); diff --git a/src/st_stuff.c b/src/st_stuff.c index 1b8107edb..ec0590419 100644 --- a/src/st_stuff.c +++ b/src/st_stuff.c @@ -1177,21 +1177,33 @@ tic_t lt_exitticker = 0, lt_endtime = 0; // // Load the graphics for the title card. +// Don't let LJ see this // static void ST_cacheLevelTitle(void) { - if (!(mapheaderinfo[gamemap-1]->levelflags & LF_WARNINGTITLE)) - { - lt_patches[0] = (patch_t *)W_CachePatchName("LTACTBLU", PU_HUDGFX); - lt_patches[1] = (patch_t *)W_CachePatchName("LTZIGZAG", PU_HUDGFX); - lt_patches[2] = (patch_t *)W_CachePatchName("LTZZTEXT", PU_HUDGFX); - } - else // boss map - { - lt_patches[0] = (patch_t *)W_CachePatchName("LTACTRED", PU_HUDGFX); - lt_patches[1] = (patch_t *)W_CachePatchName("LTZIGRED", PU_HUDGFX); - lt_patches[2] = (patch_t *)W_CachePatchName("LTZZWARN", PU_HUDGFX); - } +#define SETPATCH(default, warning, custom, idx) \ +{ \ + lumpnum_t patlumpnum = LUMPERROR; \ + if (mapheaderinfo[gamemap-1]->custom[0] != '\0') \ + { \ + patlumpnum = W_CheckNumForName(mapheaderinfo[gamemap-1]->custom); \ + if (patlumpnum != LUMPERROR) \ + lt_patches[idx] = (patch_t *)W_CachePatchNum(patlumpnum, PU_HUDGFX); \ + } \ + if (patlumpnum == LUMPERROR) \ + { \ + if (!(mapheaderinfo[gamemap-1]->levelflags & LF_WARNINGTITLE)) \ + lt_patches[idx] = (patch_t *)W_CachePatchName(default, PU_HUDGFX); \ + else \ + lt_patches[idx] = (patch_t *)W_CachePatchName(warning, PU_HUDGFX); \ + } \ +} + + SETPATCH("LTACTBLU", "LTACTRED", ltactdiamond, 0) + SETPATCH("LTZIGZAG", "LTZIGRED", ltzzpatch, 1) + SETPATCH("LTZZTEXT", "LTZZWARN", ltzztext, 2) + +#undef SETPATCH } // From 317191ec7c5416374c79dcc5531bda3dd072029a Mon Sep 17 00:00:00 2001 From: Jaime Passos Date: Wed, 18 Dec 2019 00:52:50 -0300 Subject: [PATCH 235/746] Freeslot moment! --- src/doomstat.h | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/doomstat.h b/src/doomstat.h index 3c0b4773a..772f6b3fb 100644 --- a/src/doomstat.h +++ b/src/doomstat.h @@ -386,6 +386,7 @@ enum TypeOfLevel }; // Gametypes +#define NUMGAMETYPEFREESLOTS 512 enum GameType { GT_COOP = 0, // also used in single player @@ -400,6 +401,8 @@ enum GameType GT_CTF, // capture the flag + GT_FIRSTFREESLOT, + GT_LASTFREESLOT = GT_FIRSTFREESLOT + NUMGAMETYPEFREESLOTS - 1, NUMGAMETYPES }; // If you alter this list, update dehacked.c, MISC_ChangeGameTypeMenu in m_menu.c, and Gametype_Names in g_game.c From 7bfdc2caa0f9473069767aa5e405623940c70841 Mon Sep 17 00:00:00 2001 From: Jaime Passos Date: Wed, 18 Dec 2019 01:25:57 -0300 Subject: [PATCH 236/746] Gametype rules draft, mind the debug command --- src/d_clisrv.c | 4 ++-- src/d_main.c | 4 ++-- src/d_netcmd.c | 12 +++++++++++- src/doomstat.h | 12 ++++++++++++ src/g_game.c | 46 ++++++++++++++++++++++++++++++++++++++++------ src/g_game.h | 1 + 6 files changed, 68 insertions(+), 11 deletions(-) diff --git a/src/d_clisrv.c b/src/d_clisrv.c index 7b6c35eb6..14901360d 100644 --- a/src/d_clisrv.c +++ b/src/d_clisrv.c @@ -3461,7 +3461,7 @@ void SV_StartSinglePlayerServer(void) server = true; netgame = false; multiplayer = false; - gametype = GT_COOP; + G_SetGametype(GT_COOP); // no more tic the game with this settings! SV_StopServer(); @@ -3740,7 +3740,7 @@ static void HandlePacketFromAwayNode(SINT8 node) if (client) { maketic = gametic = neededtic = (tic_t)LONG(netbuffer->u.servercfg.gametic); - gametype = netbuffer->u.servercfg.gametype; + G_SetGametype(netbuffer->u.servercfg.gametype); modifiedgame = netbuffer->u.servercfg.modifiedgame; for (j = 0; j < MAXPLAYERS; j++) adminplayers[j] = netbuffer->u.servercfg.adminplayers[j]; diff --git a/src/d_main.c b/src/d_main.c index ef6502aec..815136440 100644 --- a/src/d_main.c +++ b/src/d_main.c @@ -753,7 +753,7 @@ void D_StartTitle(void) gameaction = ga_nothing; displayplayer = consoleplayer = 0; - gametype = GT_COOP; + G_SetGametype(GT_COOP); paused = false; advancedemo = false; F_InitMenuPresValues(); @@ -1416,7 +1416,7 @@ void D_SRB2Main(void) if (newgametype != -1) { j = gametype; - gametype = newgametype; + G_SetGametype(newgametype); D_GameTypeChanged(j); } } diff --git a/src/d_netcmd.c b/src/d_netcmd.c index 00cb6e65e..40d626185 100644 --- a/src/d_netcmd.c +++ b/src/d_netcmd.c @@ -125,6 +125,7 @@ static void Command_Version_f(void); static void Command_ModDetails_f(void); #endif static void Command_ShowGametype_f(void); +static void Command_SetGametype_f(void); FUNCNORETURN static ATTRNORETURN void Command_Quit_f(void); static void Command_Playintro_f(void); @@ -381,6 +382,7 @@ char timedemo_csv_id[256]; boolean timedemo_quit; INT16 gametype = GT_COOP; +INT16 gametyperules = 0; boolean splitscreen = false; boolean circuitmap = false; INT32 adminplayers[MAXPLAYERS]; @@ -480,6 +482,7 @@ void D_RegisterServerCommands(void) COM_AddCommand("suicide", Command_Suicide); COM_AddCommand("gametype", Command_ShowGametype_f); + COM_AddCommand("setgametype", Command_SetGametype_f); COM_AddCommand("version", Command_Version_f); #ifdef UPDATE_ALERT COM_AddCommand("mod_details", Command_ModDetails_f); @@ -2065,6 +2068,7 @@ static void Got_Mapcmd(UINT8 **cp, INT32 playernum) lastgametype = gametype; gametype = READUINT8(*cp); + G_SetGametype(gametype); // I fear putting that macro as an argument if (gametype < 0 || gametype >= NUMGAMETYPES) gametype = lastgametype; @@ -3623,6 +3627,12 @@ static void Command_ShowGametype_f(void) CONS_Printf(M_GetText("Unknown gametype set (%d)\n"), gametype); } +static void Command_SetGametype_f(void) +{ + if (COM_Argc() > 1) + G_SetGametype(atoi(COM_Argv(1))); +} + /** Plays the intro. */ static void Command_Playintro_f(void) @@ -3935,7 +3945,7 @@ void D_GameTypeChanged(INT32 lastgametype) } else if (!multiplayer && !netgame) { - gametype = GT_COOP; + G_SetGametype(GT_COOP); // These shouldn't matter anymore //CV_Set(&cv_itemrespawntime, cv_itemrespawntime.defaultvalue); //CV_SetValue(&cv_itemrespawn, 0); diff --git a/src/doomstat.h b/src/doomstat.h index 772f6b3fb..2b493c917 100644 --- a/src/doomstat.h +++ b/src/doomstat.h @@ -84,6 +84,7 @@ extern boolean addedtogame; // true after the server has added you extern boolean multiplayer; extern INT16 gametype; +extern INT16 gametyperules; extern boolean splitscreen; extern boolean circuitmap; // Does this level have 'circuit mode'? extern boolean fromlevelselect; @@ -407,6 +408,17 @@ enum GameType }; // If you alter this list, update dehacked.c, MISC_ChangeGameTypeMenu in m_menu.c, and Gametype_Names in g_game.c +// Game type rules +enum GameTypeRules +{ + GTR_PLATFORM = 1, // Co-op, Competition, Race + GTR_TAG = 1<<1, // Tag, Hide and Seek + GTR_RINGSLINGER = 1<<2, // Not Co-op, not Competition, and not Race (overriden by cv_ringslinger) + GTR_SPECTATORS = 1<<3, // Not Co-op, not Competition, and not Race + GTR_TEAMS = 1<<4, // Team Match, CTF + GTR_LIVES = 1<<5, // A lot of special cases in G_GametypeUsesLives actually, but just Co-op and Competition +}; + // String names for gametypes extern const char *Gametype_Names[NUMGAMETYPES]; diff --git a/src/g_game.c b/src/g_game.c index 2a12dd298..d1fc61c35 100644 --- a/src/g_game.c +++ b/src/g_game.c @@ -3058,6 +3058,34 @@ const char *Gametype_Names[NUMGAMETYPES] = "CTF" // GT_CTF }; +// Game type rules +INT16 gametypedefaultrules[NUMGAMETYPES] = +{ + GTR_PLATFORM|GTR_LIVES, // GT_COOP + GTR_PLATFORM|GTR_LIVES, // GT_COMPETITION + GTR_PLATFORM, // GT_RACE + + GTR_RINGSLINGER|GTR_SPECTATORS, // GT_MATCH + GTR_RINGSLINGER|GTR_TEAMS|GTR_SPECTATORS, // GT_TEAMMATCH + + GTR_RINGSLINGER|GTR_TAG|GTR_SPECTATORS, // GT_TAG + GTR_RINGSLINGER|GTR_TAG|GTR_SPECTATORS, // GT_HIDEANDSEEK + + GTR_RINGSLINGER|GTR_TEAMS|GTR_SPECTATORS // GT_CTF +}; + +// +// G_SetGametype +// +// Set a new gametype, also setting gametype rules accordingly. Yay! +// +void G_SetGametype(INT16 gtype) +{ + gametype = gtype; + gametyperules = gametypedefaultrules[gametype]; + CONS_Printf("Gametype set to %s (%d)\n", Gametype_Names[gametype], gametype); +} + // // G_GetGametypeByName // @@ -3101,7 +3129,8 @@ boolean G_IsSpecialStage(INT32 mapnum) boolean G_GametypeUsesLives(void) { // Coop, Competitive - if ((gametype == GT_COOP || gametype == GT_COMPETITION) + //if ((gametype == GT_COOP || gametype == GT_COMPETITION) + if ((gametyperules & GTR_LIVES) && !(modeattacking || metalrecording) // No lives in Time Attack && !G_IsSpecialStage(gamemap) && !(maptol & TOL_NIGHTS)) // No lives in NiGHTS @@ -3117,7 +3146,8 @@ boolean G_GametypeUsesLives(void) // boolean G_GametypeHasTeams(void) { - return (gametype == GT_TEAMMATCH || gametype == GT_CTF); + return (gametyperules & GTR_TEAMS); + //return (gametype == GT_TEAMMATCH || gametype == GT_CTF); } // @@ -3128,7 +3158,8 @@ boolean G_GametypeHasTeams(void) // boolean G_GametypeHasSpectators(void) { - return (gametype != GT_COOP && gametype != GT_COMPETITION && gametype != GT_RACE); + return (gametyperules & GTR_SPECTATORS); + //return (gametype != GT_COOP && gametype != GT_COMPETITION && gametype != GT_RACE); } // @@ -3139,7 +3170,8 @@ boolean G_GametypeHasSpectators(void) // boolean G_RingSlingerGametype(void) { - return ((gametype != GT_COOP && gametype != GT_COMPETITION && gametype != GT_RACE) || (cv_ringslinger.value)); + return ((gametyperules & GTR_RINGSLINGER) || (cv_ringslinger.value)); + //return ((gametype != GT_COOP && gametype != GT_COMPETITION && gametype != GT_RACE) || (cv_ringslinger.value)); } // @@ -3149,7 +3181,8 @@ boolean G_RingSlingerGametype(void) // boolean G_PlatformGametype(void) { - return (gametype == GT_COOP || gametype == GT_RACE || gametype == GT_COMPETITION); + return (gametyperules & GTR_PLATFORM); + //return (gametype == GT_COOP || gametype == GT_RACE || gametype == GT_COMPETITION); } // @@ -3159,7 +3192,8 @@ boolean G_PlatformGametype(void) // boolean G_TagGametype(void) { - return (gametype == GT_TAG || gametype == GT_HIDEANDSEEK); + return (gametyperules & GTR_TAG); + //return (gametype == GT_TAG || gametype == GT_HIDEANDSEEK); } /** Get the typeoflevel flag needed to indicate support of a gametype. diff --git a/src/g_game.h b/src/g_game.h index e7f4a4677..a925e14c1 100644 --- a/src/g_game.h +++ b/src/g_game.h @@ -201,6 +201,7 @@ ATTRNORETURN void FUNCNORETURN G_StopMetalRecording(boolean kill); void G_StopDemo(void); boolean G_CheckDemoStatus(void); +void G_SetGametype(INT16 gametype); INT32 G_GetGametypeByName(const char *gametypestr); boolean G_IsSpecialStage(INT32 mapnum); boolean G_GametypeUsesLives(void); From 23951cf93833dba49d3eed2d706af4223aa79624 Mon Sep 17 00:00:00 2001 From: James R Date: Tue, 17 Dec 2019 20:54:44 -0800 Subject: [PATCH 237/746] bleh --- src/g_game.c | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/src/g_game.c b/src/g_game.c index ebc54ba78..b399d0bd8 100644 --- a/src/g_game.c +++ b/src/g_game.c @@ -1090,14 +1090,14 @@ void G_BuildTiccmd(ticcmd_t *cmd, INT32 realtics) else { if (turnright) - cmd->angleturn = (INT16)(cmd->angleturn - (FixedMul(angleturn[tspeed]<>FRACBITS)); + cmd->angleturn = (INT16)(cmd->angleturn - ((angleturn[tspeed] * cv_cam_turnmultiplier.value)>>FRACBITS)); else if (turnleft) - cmd->angleturn = (INT16)(cmd->angleturn + (FixedMul(angleturn[tspeed]<>FRACBITS)); + cmd->angleturn = (INT16)(cmd->angleturn + ((angleturn[tspeed] * cv_cam_turnmultiplier.value)>>FRACBITS)); if (analogjoystickmove && axis != 0) { // JOYAXISRANGE should be 1023 (divide by 1024) - cmd->angleturn = (INT16)(cmd->angleturn - (FixedMul(((axis * angleturn[1]) >> 10)<>FRACBITS)); // ANALOG! + cmd->angleturn = (INT16)(cmd->angleturn - ((((axis * angleturn[1]) >> 10) * cv_cam_turnmultiplier.value)>>FRACBITS)); // ANALOG! } } @@ -3652,7 +3652,6 @@ void G_LoadGameData(void) { rtemp = READUINT8(save_p); for (j = 0; j < 8 && j+i < MAXUNLOCKABLES; ++j) - //unlockables[j+i].unlocked = ((rtemp >> j) & 1); unlockables[j+i].unlocked = ((rtemp >> j) & 1); i += j; } From ea5e0d28ed117292a64a491c6de7bdc60df81c13 Mon Sep 17 00:00:00 2001 From: Jaime Passos Date: Wed, 18 Dec 2019 01:54:45 -0300 Subject: [PATCH 238/746] More gametype rules yay!! --- src/d_clisrv.c | 2 +- src/d_netcmd.c | 12 ++++++++---- src/doomstat.h | 26 ++++++++++++++++++++------ src/g_game.c | 28 ++++++++++++++++++---------- src/p_inter.c | 2 +- src/p_map.c | 2 +- src/p_mobj.c | 4 ++-- src/p_setup.c | 3 +-- src/p_spec.c | 2 +- src/p_user.c | 24 ++++++++++++------------ src/st_stuff.c | 18 +++++++++--------- 11 files changed, 74 insertions(+), 49 deletions(-) diff --git a/src/d_clisrv.c b/src/d_clisrv.c index 14901360d..3786c75d6 100644 --- a/src/d_clisrv.c +++ b/src/d_clisrv.c @@ -2512,7 +2512,7 @@ static void CL_RemovePlayer(INT32 playernum, INT32 reason) if (G_TagGametype()) //Check if you still have a game. Location flexible. =P P_CheckSurvivors(); - else if (gametype == GT_RACE || gametype == GT_COMPETITION) + else if (gametyperules & GTR_RACE) P_CheckRacers(); } diff --git a/src/d_netcmd.c b/src/d_netcmd.c index 40d626185..0b7e3de18 100644 --- a/src/d_netcmd.c +++ b/src/d_netcmd.c @@ -1125,7 +1125,7 @@ UINT8 CanChangeSkin(INT32 playernum) return true; // Can change skin during initial countdown. - if ((gametype == GT_RACE || gametype == GT_COMPETITION) && leveltime < 4*TICRATE) + if ((gametyperules & GTR_RACE) && leveltime < 4*TICRATE) return true; if (G_TagGametype()) @@ -2413,7 +2413,7 @@ static void Command_Teamchange_f(void) } //additional check for hide and seek. Don't allow change of status after hidetime ends. - if (gametype == GT_HIDEANDSEEK && leveltime >= (hidetime * TICRATE)) + if ((gametyperules & GTR_HIDETIMEFROZEN) && leveltime >= (hidetime * TICRATE)) { CONS_Alert(CONS_NOTICE, M_GetText("Hiding time expired; no Hide and Seek status changes allowed!\n")); return; @@ -2510,7 +2510,7 @@ static void Command_Teamchange2_f(void) } //additional check for hide and seek. Don't allow change of status after hidetime ends. - if (gametype == GT_HIDEANDSEEK && leveltime >= (hidetime * TICRATE)) + if ((gametyperules & GTR_HIDETIMEFROZEN) && leveltime >= (hidetime * TICRATE)) { CONS_Alert(CONS_NOTICE, M_GetText("Hiding time expired; no Hide and Seek status changes allowed!\n")); return; @@ -2639,7 +2639,7 @@ static void Command_ServerTeamChange_f(void) } //additional check for hide and seek. Don't allow change of status after hidetime ends. - if (gametype == GT_HIDEANDSEEK && leveltime >= (hidetime * TICRATE)) + if ((gametyperules & GTR_HIDETIMEFROZEN) && leveltime >= (hidetime * TICRATE)) { CONS_Alert(CONS_NOTICE, M_GetText("Hiding time expired; no Hide and Seek status changes allowed!\n")); return; @@ -2728,6 +2728,10 @@ static void Got_Teamchange(UINT8 **cp, INT32 playernum) return; } + //no status changes after hidetime + if ((gametyperules & GTR_HIDETIMEFROZEN) && (leveltime >= (hidetime * TICRATE))) + error = true; + //Make sure that the right team number is sent. Keep in mind that normal clients cannot change to certain teams in certain gametypes. switch (gametype) { diff --git a/src/doomstat.h b/src/doomstat.h index 2b493c917..90aa185b7 100644 --- a/src/doomstat.h +++ b/src/doomstat.h @@ -411,12 +411,26 @@ enum GameType // Game type rules enum GameTypeRules { - GTR_PLATFORM = 1, // Co-op, Competition, Race - GTR_TAG = 1<<1, // Tag, Hide and Seek - GTR_RINGSLINGER = 1<<2, // Not Co-op, not Competition, and not Race (overriden by cv_ringslinger) - GTR_SPECTATORS = 1<<3, // Not Co-op, not Competition, and not Race - GTR_TEAMS = 1<<4, // Team Match, CTF - GTR_LIVES = 1<<5, // A lot of special cases in G_GametypeUsesLives actually, but just Co-op and Competition + GTR_PLATFORM = 1, // Co-op, Competition, and Race + GTR_TAG = 1<<1, // Tag and Hide and Seek + GTR_RINGSLINGER = 1<<2, // Not Co-op, not Competition, and not Race (overriden by cv_ringslinger) + GTR_SPECTATORS = 1<<3, // Not Co-op, not Competition, and not Race + GTR_TEAMS = 1<<4, // Team Match, CTF + GTR_LIVES = 1<<5, // A lot of special cases in G_GametypeUsesLives actually, but just Co-op and Competition + GTR_RACE = 1<<6, // Race and Competition + + // Lactozilla + // Awesome! Those are new game type rules + // provided by yours truly to allow for more + // flexibility! Those will replace some + // straight-up gametype checks scattered + // around the source code! + GTR_CHASECAM = 1<<7, // Prefer chasecam at map load + GTR_TIMELIMIT = 1<<8, // Ringslinger time limit + GTR_HIDETIME = 1<<9, // Tag and Hide and Seek + GTR_HIDETIMEFROZEN = 1<<10, // Hide and Seek, but not Tag + GTR_BLINDFOLDED = 1<<11, // Blindfolded view for Tag and Hide and Seek + GTR_EMERALDS = 1<<12, // Ringslinger emeralds }; // String names for gametypes diff --git a/src/g_game.c b/src/g_game.c index d1fc61c35..59764e0fc 100644 --- a/src/g_game.c +++ b/src/g_game.c @@ -1002,7 +1002,7 @@ void G_BuildTiccmd(ticcmd_t *cmd, INT32 realtics) // why build a ticcmd if we're paused? // Or, for that matter, if we're being reborn. // ...OR if we're blindfolded. No looking into the floor. - if (paused || P_AutoPause() || (gamestate == GS_LEVEL && (player->playerstate == PST_REBORN || ((gametype == GT_TAG || gametype == GT_HIDEANDSEEK) + if (paused || P_AutoPause() || (gamestate == GS_LEVEL && (player->playerstate == PST_REBORN || ((gametyperules & GTR_TAG) && (leveltime < hidetime * TICRATE) && (player->pflags & PF_TAGIT))))) { cmd->angleturn = (INT16)(localangle >> 16); @@ -3061,17 +3061,25 @@ const char *Gametype_Names[NUMGAMETYPES] = // Game type rules INT16 gametypedefaultrules[NUMGAMETYPES] = { - GTR_PLATFORM|GTR_LIVES, // GT_COOP - GTR_PLATFORM|GTR_LIVES, // GT_COMPETITION - GTR_PLATFORM, // GT_RACE + // Co-op + GTR_PLATFORM|GTR_LIVES|GTR_CHASECAM, + // Competition + GTR_PLATFORM|GTR_LIVES|GTR_RACE|GTR_CHASECAM, + // Race + GTR_PLATFORM|GTR_RACE|GTR_CHASECAM, - GTR_RINGSLINGER|GTR_SPECTATORS, // GT_MATCH - GTR_RINGSLINGER|GTR_TEAMS|GTR_SPECTATORS, // GT_TEAMMATCH + // Match + GTR_RINGSLINGER|GTR_SPECTATORS|GTR_TIMELIMIT|GTR_EMERALDS, + // Team Match + GTR_RINGSLINGER|GTR_TEAMS|GTR_SPECTATORS|GTR_TIMELIMIT, - GTR_RINGSLINGER|GTR_TAG|GTR_SPECTATORS, // GT_TAG - GTR_RINGSLINGER|GTR_TAG|GTR_SPECTATORS, // GT_HIDEANDSEEK + // Tag + GTR_RINGSLINGER|GTR_TAG|GTR_SPECTATORS|GTR_TIMELIMIT|GTR_HIDETIME|GTR_BLINDFOLDED, + // Hide and Seek + GTR_RINGSLINGER|GTR_TAG|GTR_SPECTATORS|GTR_TIMELIMIT|GTR_HIDETIME|GTR_BLINDFOLDED, - GTR_RINGSLINGER|GTR_TEAMS|GTR_SPECTATORS // GT_CTF + // CTF + GTR_RINGSLINGER|GTR_TEAMS|GTR_SPECTATORS|GTR_TIMELIMIT|GTR_EMERALDS, }; // @@ -3384,7 +3392,7 @@ static void G_DoCompleted(void) I_Error("Followed map %d to invalid map %d\n", prevmap + 1, nextmap + 1); // wrap around in race - if (nextmap >= 1100-1 && nextmap <= 1102-1 && (gametype == GT_RACE || gametype == GT_COMPETITION)) + if (nextmap >= 1100-1 && nextmap <= 1102-1 && (gametyperules & GTR_RACE)) nextmap = (INT16)(spstage_start-1); if ((gottoken = (gametype == GT_COOP && token))) diff --git a/src/p_inter.c b/src/p_inter.c index 70fb01fd0..7b5839e03 100644 --- a/src/p_inter.c +++ b/src/p_inter.c @@ -2978,7 +2978,7 @@ static inline void P_NiGHTSDamage(mobj_t *target, mobj_t *source) player->flyangle += 180; // Shuffle's BETTERNIGHTSMOVEMENT? player->flyangle %= 360; - if (gametype == GT_RACE || gametype == GT_COMPETITION) + if (gametyperules & GTR_RACE) player->drillmeter -= 5*20; else { diff --git a/src/p_map.c b/src/p_map.c index 2d36f747c..1b6f23cde 100644 --- a/src/p_map.c +++ b/src/p_map.c @@ -615,7 +615,7 @@ static void P_DoTailsCarry(player_t *sonic, player_t *tails) // Why block opposing teams from tailsflying each other? // Sneaking into the hands of a flying tails player in Race might be a viable strategy, who knows. /* - if (gametype == GT_RACE || gametype == GT_COMPETITION + if ((gametyperules & GTR_RACE) || (netgame && (tails->spectator || sonic->spectator)) || (G_TagGametype() && (!(tails->pflags & PF_TAGIT) != !(sonic->pflags & PF_TAGIT))) || (gametype == GT_MATCH) diff --git a/src/p_mobj.c b/src/p_mobj.c index dea4a7a4d..df89fbfde 100644 --- a/src/p_mobj.c +++ b/src/p_mobj.c @@ -11702,7 +11702,7 @@ You should think about modifying the deathmatch starts to take full advantage of if (!cv_powerstones.value) return; - if (!(gametype == GT_MATCH || gametype == GT_CTF)) + if (!(gametyperules & GTR_EMERALDS)) return; runemeraldmanager = true; @@ -11722,7 +11722,7 @@ You should think about modifying the deathmatch starts to take full advantage of // Yeah, this is a dirty hack. if ((mobjinfo[i].flags & (MF_MONITOR|MF_GRENADEBOUNCE)) == MF_MONITOR) { - if (gametype == GT_COMPETITION || gametype == GT_RACE) + if (gametyperules & GTR_RACE) { // Set powerup boxes to user settings for competition. if (cv_competitionboxes.value == 1) // Mystery diff --git a/src/p_setup.c b/src/p_setup.c index bf3493d8c..7e6bdcc67 100644 --- a/src/p_setup.c +++ b/src/p_setup.c @@ -2683,8 +2683,7 @@ boolean P_SetupLevel(boolean skipprecip) // chasecam on in chaos, race, coop // chasecam off in match, tag, capture the flag - chase = (gametype == GT_RACE || gametype == GT_COMPETITION || gametype == GT_COOP) - || (maptol & TOL_2D); + chase = (gametyperules & GTR_CHASECAM) || (maptol & TOL_2D); if (!dedicated) { diff --git a/src/p_spec.c b/src/p_spec.c index dba4e17b5..4bdb99520 100644 --- a/src/p_spec.c +++ b/src/p_spec.c @@ -7224,7 +7224,7 @@ void P_SpawnSpecials(INT32 fromnetsave) break; case 308: // Race-only linedef executor. Triggers once. - if (gametype != GT_RACE && gametype != GT_COMPETITION) + if (!(gametyperules & GTR_RACE)) lines[i].special = 0; break; diff --git a/src/p_user.c b/src/p_user.c index ea42a2c36..a8ae383cf 100644 --- a/src/p_user.c +++ b/src/p_user.c @@ -387,7 +387,7 @@ UINT8 P_FindLowestMare(void) mobj_t *mo2; UINT8 mare = UINT8_MAX; - if (gametype == GT_RACE || gametype == GT_COMPETITION) + if (gametyperules & GTR_RACE) return 0; // scan the thinkers @@ -793,7 +793,7 @@ void P_NightserizePlayer(player_t *player, INT32 nighttime) P_RestoreMusic(player); } - if (gametype == GT_RACE || gametype == GT_COMPETITION) + if (gametyperules & GTR_RACE) { if (player->drillmeter < 48*20) player->drillmeter = 48*20; @@ -2181,7 +2181,7 @@ void P_DoPlayerExit(player_t *player) if (cv_allowexitlevel.value == 0 && !G_PlatformGametype()) return; - else if (gametype == GT_RACE || gametype == GT_COMPETITION) // If in Race Mode, allow + else if (gametyperules & GTR_RACE) // If in Race Mode, allow { if (!countdown) // a 60-second wait ala Sonic 2. countdown = (cv_countdowntime.value - 1)*TICRATE + 1; // Use cv_countdowntime @@ -4670,7 +4670,7 @@ static void P_DoSpinAbility(player_t *player, ticcmd_t *cmd) if (player->powers[pw_carry] == CR_BRAKGOOP) player->dashspeed = 0; - if (!((gametype == GT_RACE || gametype == GT_COMPETITION) && leveltime < 4*TICRATE)) + if (!((gametyperules & GTR_RACE) && leveltime < 4*TICRATE)) { if (player->dashspeed) { @@ -7137,7 +7137,7 @@ static void P_NiGHTSMovement(player_t *player) && !player->exiting) player->nightstime--; } - else if (gametype != GT_RACE && gametype != GT_COMPETITION + else if (!(gametyperules & GTR_RACE) && !(player->mo->state >= &states[S_PLAY_NIGHTS_TRANS1] && player->mo->state <= &states[S_PLAY_NIGHTS_TRANS6]) && !(player->capsule && player->capsule->reactiontime) @@ -7293,7 +7293,7 @@ static void P_NiGHTSMovement(player_t *player) { player->mo->momx = player->mo->momy = 0; - if (gametype != GT_RACE && gametype != GT_COMPETITION) + if (!(gametyperules & GTR_RACE)) P_SetObjectMomZ(player->mo, FRACUNIT/2, (P_MobjFlip(player->mo)*player->mo->momz >= 0)); else player->mo->momz = 0; @@ -9535,12 +9535,12 @@ static void P_DeathThink(player_t *player) player->playerstate = PST_REBORN; } - if (gametype == GT_RACE || gametype == GT_COMPETITION || (gametype == GT_COOP && (multiplayer || netgame))) + if ((gametyperules & GTR_RACE) || (gametype == GT_COOP && (multiplayer || netgame))) { // Keep time rolling in race mode if (!(countdown2 && !countdown) && !player->exiting && !(player->pflags & PF_GAMETYPEOVER) && !stoppedclock) { - if (gametype == GT_RACE || gametype == GT_COMPETITION) + if (gametyperules & GTR_RACE) { if (leveltime >= 4*TICRATE) player->realtime = leveltime - 4*TICRATE; @@ -11372,7 +11372,7 @@ void P_PlayerThink(player_t *player) I_Error("player %s is in PST_REBORN\n", sizeu1(playeri)); #endif - if (gametype == GT_RACE || gametype == GT_COMPETITION) + if (gametyperules & GTR_RACE) { INT32 i; @@ -11435,7 +11435,7 @@ void P_PlayerThink(player_t *player) player->exiting > 0 && player->exiting <= 1*TICRATE && (!multiplayer || gametype == GT_COOP ? !mapheaderinfo[gamemap-1]->musinterfadeout : true) && // don't fade if we're fading during intermission. follows Y_StartIntermission intertype = int_coop - (gametype == GT_RACE || gametype == GT_COMPETITION ? countdown2 == 0 : true) && // don't fade on timeout + ((gametyperules & GTR_RACE) ? countdown2 == 0 : true) && // don't fade on timeout player->lives > 0 && // don't fade on game over (competition) P_IsLocalPlayer(player)) { @@ -11550,7 +11550,7 @@ void P_PlayerThink(player_t *player) player->lives = cv_startinglives.value; } - if ((gametype == GT_RACE || gametype == GT_COMPETITION) && leveltime < 4*TICRATE) + if ((gametyperules & GTR_RACE) && leveltime < 4*TICRATE) { cmd->buttons &= BT_USE; // Remove all buttons except BT_USE cmd->forwardmove = 0; @@ -11560,7 +11560,7 @@ void P_PlayerThink(player_t *player) // Synchronizes the "real" amount of time spent in the level. if (!player->exiting && !stoppedclock) { - if (gametype == GT_RACE || gametype == GT_COMPETITION) + if (gametyperules & GTR_RACE) { if (leveltime >= 4*TICRATE) player->realtime = leveltime - 4*TICRATE; diff --git a/src/st_stuff.c b/src/st_stuff.c index 1b8107edb..6e8c64127 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 ((gametype == GT_TAG || gametype == GT_HIDEANDSEEK) && (stplyr->realtime <= (hidetime*TICRATE))) + if ((gametyperules & GTR_HIDETIME) && (stplyr->realtime <= (hidetime*TICRATE))) { tics = (hidetime*TICRATE - stplyr->realtime); if (tics < 3*TICRATE) @@ -705,11 +705,11 @@ static void ST_drawTime(void) else { // Hidetime finish! - if ((gametype == GT_TAG || gametype == GT_HIDEANDSEEK) && (stplyr->realtime < ((hidetime+1)*TICRATE))) + if ((gametyperules & GTR_HIDETIME) && (stplyr->realtime < ((hidetime+1)*TICRATE))) ST_drawRaceNum(hidetime*TICRATE - stplyr->realtime); // Time limit? - if (gametype != GT_COOP && gametype != GT_RACE && gametype != GT_COMPETITION && cv_timelimit.value && timelimitintics > 0) + if ((gametyperules & GTR_TIMELIMIT) && cv_timelimit.value && timelimitintics > 0) { if (timelimitintics > stplyr->realtime) { @@ -723,7 +723,7 @@ static void ST_drawTime(void) downwards = true; } // Post-hidetime normal. - else if (gametype == GT_TAG || gametype == GT_HIDEANDSEEK) + else if (gametyperules & GTR_TAG) 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!" @@ -912,7 +912,7 @@ static void ST_drawLivesArea(void) else if (stplyr->spectator) v_colmap = V_GRAYMAP; // Tag - else if (gametype == GT_TAG || gametype == GT_HIDEANDSEEK) + else if (gametyperules & GTR_TAG) { if (stplyr->pflags & PF_TAGIT) { @@ -1762,7 +1762,7 @@ static void ST_drawNiGHTSHUD(void) ST_drawNiGHTSLink(); } - if (gametype == GT_RACE || gametype == GT_COMPETITION) + if (gametyperules & GTR_RACE) { ST_drawScore(); ST_drawTime(); @@ -2273,7 +2273,7 @@ static void ST_drawTextHUD(void) } } } - else if ((gametype == GT_TAG || gametype == GT_HIDEANDSEEK) && (!stplyr->spectator)) + else if ((gametyperules & GTR_TAG) && (!stplyr->spectator)) { if (leveltime < hidetime * TICRATE) { @@ -2648,7 +2648,7 @@ static void ST_overlayDrawer(void) ST_drawMatchHUD(); // Race HUD Stuff - if (gametype == GT_RACE || gametype == GT_COMPETITION) + if (gametyperules & GTR_RACE) ST_drawRaceHUD(); // Emerald Hunt Indicators @@ -2753,7 +2753,7 @@ void ST_Drawer(void) if (rendermode != render_none) ST_doPaletteStuff(); // Blindfold! - if ((gametype == GT_TAG || gametype == GT_HIDEANDSEEK) + if ((gametyperules & GTR_BLINDFOLDED) && (leveltime < hidetime * TICRATE)) { if (players[displayplayer].pflags & PF_TAGIT) From 185fa2799de073fcea7cc0afeb1667a9d5f0741c Mon Sep 17 00:00:00 2001 From: Jaime Passos Date: Wed, 18 Dec 2019 11:33:56 -0300 Subject: [PATCH 239/746] Update comments --- src/doomstat.h | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/doomstat.h b/src/doomstat.h index 90aa185b7..5569e3197 100644 --- a/src/doomstat.h +++ b/src/doomstat.h @@ -425,12 +425,12 @@ enum GameTypeRules // flexibility! Those will replace some // straight-up gametype checks scattered // around the source code! - GTR_CHASECAM = 1<<7, // Prefer chasecam at map load - GTR_TIMELIMIT = 1<<8, // Ringslinger time limit + GTR_CHASECAM = 1<<7, // Prefer chasecam at map load (All platform gametypes) + GTR_TIMELIMIT = 1<<8, // Ringslinger time limit (Tag and Hide and Seek) GTR_HIDETIME = 1<<9, // Tag and Hide and Seek GTR_HIDETIMEFROZEN = 1<<10, // Hide and Seek, but not Tag - GTR_BLINDFOLDED = 1<<11, // Blindfolded view for Tag and Hide and Seek - GTR_EMERALDS = 1<<12, // Ringslinger emeralds + GTR_BLINDFOLDED = 1<<11, // Blindfolded view (Tag and Hide and Seek) + GTR_EMERALDS = 1<<12, // Ringslinger emeralds (Match and CTF) }; // String names for gametypes From 299f2bd8cdafcfdfff889c40cb33f7e6975c6b53 Mon Sep 17 00:00:00 2001 From: Jaime Passos Date: Wed, 18 Dec 2019 11:43:50 -0300 Subject: [PATCH 240/746] GTR_TEAMFLAGS --- src/d_clisrv.c | 6 +++--- src/doomstat.h | 1 + src/g_game.c | 4 ++-- src/hu_stuff.c | 4 ++-- src/m_cheat.c | 2 +- src/p_enemy.c | 8 ++++---- src/p_inter.c | 8 ++++---- src/p_mobj.c | 8 ++++---- src/p_spec.c | 6 +++--- src/p_user.c | 8 ++++---- src/st_stuff.c | 12 +++++++----- 11 files changed, 35 insertions(+), 32 deletions(-) diff --git a/src/d_clisrv.c b/src/d_clisrv.c index 3786c75d6..bfc478bd5 100644 --- a/src/d_clisrv.c +++ b/src/d_clisrv.c @@ -1025,7 +1025,7 @@ static void SV_SendResynch(INT32 node) netbuffer->packettype = PT_RESYNCHEND; netbuffer->u.resynchend.randomseed = P_GetRandSeed(); - if (gametype == GT_CTF) + if (gametyperules & GTR_TEAMFLAGS) resynch_write_ctf(&netbuffer->u.resynchend); resynch_write_others(&netbuffer->u.resynchend); @@ -2430,7 +2430,7 @@ static void CL_RemovePlayer(INT32 playernum, INT32 reason) } } - if (gametype == GT_CTF) + if (gametyperules & GTR_TEAMFLAGS) P_PlayerFlagBurst(&players[playernum], false); // Don't take the flag with you! // If in a special stage, redistribute the player's spheres across @@ -4124,7 +4124,7 @@ static void HandlePacketFromPlayer(SINT8 node) P_SetRandSeed(netbuffer->u.resynchend.randomseed); - if (gametype == GT_CTF) + if (gametyperules & GTR_TEAMFLAGS) resynch_read_ctf(&netbuffer->u.resynchend); resynch_read_others(&netbuffer->u.resynchend); diff --git a/src/doomstat.h b/src/doomstat.h index 5569e3197..06e114eb1 100644 --- a/src/doomstat.h +++ b/src/doomstat.h @@ -431,6 +431,7 @@ enum GameTypeRules GTR_HIDETIMEFROZEN = 1<<10, // Hide and Seek, but not Tag GTR_BLINDFOLDED = 1<<11, // Blindfolded view (Tag and Hide and Seek) GTR_EMERALDS = 1<<12, // Ringslinger emeralds (Match and CTF) + GTR_TEAMFLAGS = 1<<13, // Gametype has team flags (CTF) }; // String names for gametypes diff --git a/src/g_game.c b/src/g_game.c index 59764e0fc..1f6bde833 100644 --- a/src/g_game.c +++ b/src/g_game.c @@ -2564,7 +2564,7 @@ void G_SpawnPlayer(INT32 playernum, boolean starpost) // -- CTF -- // Order: CTF->DM->Coop - if (gametype == GT_CTF && players[playernum].ctfteam) + if ((gametyperules & GTR_TEAMFLAGS) && players[playernum].ctfteam) { if (!(spawnpoint = G_FindCTFStart(playernum)) // find a CTF start && !(spawnpoint = G_FindMatchStart(playernum))) // find a DM start @@ -3079,7 +3079,7 @@ INT16 gametypedefaultrules[NUMGAMETYPES] = GTR_RINGSLINGER|GTR_TAG|GTR_SPECTATORS|GTR_TIMELIMIT|GTR_HIDETIME|GTR_BLINDFOLDED, // CTF - GTR_RINGSLINGER|GTR_TEAMS|GTR_SPECTATORS|GTR_TIMELIMIT|GTR_EMERALDS, + GTR_RINGSLINGER|GTR_TEAMS|GTR_SPECTATORS|GTR_TIMELIMIT|GTR_EMERALDS|GTR_TEAMFLAGS, }; // diff --git a/src/hu_stuff.c b/src/hu_stuff.c index 91a167a60..e67249953 100644 --- a/src/hu_stuff.c +++ b/src/hu_stuff.c @@ -2541,7 +2541,7 @@ static void HU_Draw32TeamTabRankings(playersort_t *tab, INT32 whiteplayer) | (greycheck ? 0 : V_TRANSLUCENT) | V_ALLOWLOWERCASE, name); - if (gametype == GT_CTF) + if (gametyperules & GTR_TEAMFLAGS) { if (players[tab[i].num].gotflag & GF_REDFLAG) // Red V_DrawFixedPatch((x-10)*FRACUNIT, (y)*FRACUNIT, FRACUNIT/4, 0, rflagico, 0); @@ -2669,7 +2669,7 @@ void HU_DrawTeamTabRankings(playersort_t *tab, INT32 whiteplayer) | (greycheck ? V_TRANSLUCENT : 0) | V_ALLOWLOWERCASE, name); - if (gametype == GT_CTF) + if (gametyperules & GTR_TEAMFLAGS) { if (players[tab[i].num].gotflag & GF_REDFLAG) // Red V_DrawSmallScaledPatch(x-28, y-4, 0, rflagico); diff --git a/src/m_cheat.c b/src/m_cheat.c index e31ce7869..1d4fa3b5d 100644 --- a/src/m_cheat.c +++ b/src/m_cheat.c @@ -778,7 +778,7 @@ void Command_CauseCfail_f(void) P_SetThingPosition(players[consoleplayer].mo); // CTF consistency test - if (gametype == GT_CTF) + if (gametyperules & GTR_TEAMFLAGS) { if (blueflag) { P_RemoveMobj(blueflag); diff --git a/src/p_enemy.c b/src/p_enemy.c index 74a11fe67..30284a2dd 100644 --- a/src/p_enemy.c +++ b/src/p_enemy.c @@ -4985,7 +4985,7 @@ void A_ThrownRing(mobj_t *actor) continue; // Don't home in on teammates. - if (gametype == GT_CTF + if ((gametyperules & GTR_TEAMFLAGS) && actor->target->player->ctfteam == player->ctfteam) continue; } @@ -6591,7 +6591,7 @@ void A_OldRingExplode(mobj_t *actor) { if (changecolor) { - if (gametype != GT_CTF) + if (!(gametyperules & GTR_TEAMFLAGS)) mo->color = actor->target->color; //copy color else if (actor->target->player->ctfteam == 2) mo->color = skincolor_bluering; @@ -6607,7 +6607,7 @@ void A_OldRingExplode(mobj_t *actor) { if (changecolor) { - if (gametype != GT_CTF) + if (!(gametyperules & GTR_TEAMFLAGS)) mo->color = actor->target->color; //copy color else if (actor->target->player->ctfteam == 2) mo->color = skincolor_bluering; @@ -6622,7 +6622,7 @@ void A_OldRingExplode(mobj_t *actor) { if (changecolor) { - if (gametype != GT_CTF) + if (!(gametyperules & GTR_TEAMFLAGS)) mo->color = actor->target->color; //copy color else if (actor->target->player->ctfteam == 2) mo->color = skincolor_bluering; diff --git a/src/p_inter.c b/src/p_inter.c index 7b5839e03..33a124133 100644 --- a/src/p_inter.c +++ b/src/p_inter.c @@ -3224,7 +3224,7 @@ static void P_KillPlayer(player_t *player, mobj_t *source, INT32 damage) player->mo->flags2 &= ~MF2_DONTDRAW; P_SetPlayerMobjState(player->mo, player->mo->info->deathstate); - if (gametype == GT_CTF && (player->gotflag & (GF_REDFLAG|GF_BLUEFLAG))) + if ((gametyperules & GTR_TEAMFLAGS) && (player->gotflag & (GF_REDFLAG|GF_BLUEFLAG))) { P_PlayerFlagBurst(player, false); if (source && source->player) @@ -3349,7 +3349,7 @@ static void P_ShieldDamage(player_t *player, mobj_t *inflictor, mobj_t *source, else S_StartSound (player->mo, sfx_shldls); // Ba-Dum! Shield loss. - if (gametype == GT_CTF && (player->gotflag & (GF_REDFLAG|GF_BLUEFLAG))) + if ((gametyperules & GTR_TEAMFLAGS) && (player->gotflag & (GF_REDFLAG|GF_BLUEFLAG))) { P_PlayerFlagBurst(player, false); if (source && source->player) @@ -3383,7 +3383,7 @@ static void P_RingDamage(player_t *player, mobj_t *inflictor, mobj_t *source, IN P_AddPlayerScore(source->player, 50); } - if (gametype == GT_CTF && (player->gotflag & (GF_REDFLAG|GF_BLUEFLAG))) + if ((gametyperules & GTR_TEAMFLAGS) && (player->gotflag & (GF_REDFLAG|GF_BLUEFLAG))) { P_PlayerFlagBurst(player, false); if (source && source->player) @@ -3442,7 +3442,7 @@ void P_SpecialStageDamage(player_t *player, mobj_t *inflictor, mobj_t *source) P_DoPlayerPain(player, inflictor, source); - if (gametype == GT_CTF && player->gotflag & (GF_REDFLAG|GF_BLUEFLAG)) + if ((gametyperules & GTR_TEAMFLAGS) && player->gotflag & (GF_REDFLAG|GF_BLUEFLAG)) P_PlayerFlagBurst(player, false); if (oldnightstime > 10*TICRATE diff --git a/src/p_mobj.c b/src/p_mobj.c index df89fbfde..193746db8 100644 --- a/src/p_mobj.c +++ b/src/p_mobj.c @@ -11179,7 +11179,7 @@ void P_RespawnSpecials(void) } //CTF rings should continue to respawn as normal rings outside of CTF. - if (gametype != GT_CTF) + if (!(gametyperules & GTR_TEAMFLAGS)) { if (i == MT_REDTEAMRING || i == MT_BLUETEAMRING) i = MT_RING; @@ -11750,7 +11750,7 @@ You should think about modifying the deathmatch starts to take full advantage of } } - if (gametype != GT_CTF) // CTF specific things + if (!(gametyperules & GTR_TEAMFLAGS)) // CTF specific things { if (i == MT_RING_BLUEBOX || i == MT_RING_REDBOX) i = MT_RING_BOX; @@ -13597,9 +13597,9 @@ void P_SpawnHoopsAndRings(mapthing_t *mthing, boolean bonustime) else if (mthing->type == mobjinfo[MT_COIN].doomednum) ringthing = MT_COIN; else if (mthing->type == mobjinfo[MT_REDTEAMRING].doomednum) // No team rings in non-CTF - ringthing = (gametype == GT_CTF) ? MT_REDTEAMRING : MT_RING; + ringthing = (gametyperules & GTR_TEAMFLAGS) ? MT_REDTEAMRING : MT_RING; else if (mthing->type == mobjinfo[MT_BLUETEAMRING].doomednum) // Ditto - ringthing = (gametype == GT_CTF) ? MT_BLUETEAMRING : MT_RING; + ringthing = (gametyperules & GTR_TEAMFLAGS) ? MT_BLUETEAMRING : MT_RING; } // Set proper height diff --git a/src/p_spec.c b/src/p_spec.c index 4bdb99520..161d73e0e 100644 --- a/src/p_spec.c +++ b/src/p_spec.c @@ -4713,7 +4713,7 @@ DoneSection2: break; case 3: // Red Team's Base - if (gametype == GT_CTF && P_IsObjectOnGround(player->mo)) + if ((gametyperules & GTR_TEAMFLAGS) && P_IsObjectOnGround(player->mo)) { if (player->ctfteam == 1 && (player->gotflag & GF_BLUEFLAG)) { @@ -4746,7 +4746,7 @@ DoneSection2: break; case 4: // Blue Team's Base - if (gametype == GT_CTF && P_IsObjectOnGround(player->mo)) + if ((gametyperules & GTR_TEAMFLAGS) && P_IsObjectOnGround(player->mo)) { if (player->ctfteam == 2 && (player->gotflag & GF_REDFLAG)) { @@ -7231,7 +7231,7 @@ void P_SpawnSpecials(INT32 fromnetsave) // Linedef executor triggers for CTF teams. case 309: case 311: - if (gametype != GT_CTF) + if (!(gametyperules & GTR_TEAMFLAGS)) lines[i].special = 0; break; diff --git a/src/p_user.c b/src/p_user.c index a8ae383cf..c94f18af1 100644 --- a/src/p_user.c +++ b/src/p_user.c @@ -3110,7 +3110,7 @@ static void P_DoPlayerHeadSigns(player_t *player) } } } - else if (gametype == GT_CTF && (player->gotflag & (GF_REDFLAG|GF_BLUEFLAG))) // If you have the flag (duh). + else if ((gametyperules & GTR_TEAMFLAGS) && (player->gotflag & (GF_REDFLAG|GF_BLUEFLAG))) // If you have the flag (duh). { // Spawn a got-flag message over the head of the player that // has it (but not on your own screen if you have the flag). @@ -5048,7 +5048,7 @@ static void P_DoJumpStuff(player_t *player, ticcmd_t *cmd) { if (onground || player->climbing || player->powers[pw_carry]) ; - else if (gametype == GT_CTF && player->gotflag) + else if ((gametyperules & GTR_TEAMFLAGS) && player->gotflag) ; else if (player->pflags & (PF_GLIDING|PF_SLIDING|PF_SHIELDABILITY)) // If the player has used an ability previously ; @@ -5273,7 +5273,7 @@ static void P_DoJumpStuff(player_t *player, ticcmd_t *cmd) player->secondjump = 0; player->pflags &= ~PF_THOKKED; } - else if (player->pflags & PF_SLIDING || (gametype == GT_CTF && player->gotflag)) + else if (player->pflags & PF_SLIDING || ((gametyperules & GTR_TEAMFLAGS) && player->gotflag)) ; /*else if (P_SuperReady(player)) { @@ -5560,7 +5560,7 @@ static void P_DoJumpStuff(player_t *player, ticcmd_t *cmd) { player->pflags |= PF_JUMPDOWN; - if ((gametype != GT_CTF || !player->gotflag) && !player->exiting) + if ((!(gametyperules & GTR_TEAMFLAGS) || !player->gotflag) && !player->exiting) { if (player->secondjump == 1 && player->charability != CA_DOUBLEJUMP) { diff --git a/src/st_stuff.c b/src/st_stuff.c index 6e8c64127..061189f53 100644 --- a/src/st_stuff.c +++ b/src/st_stuff.c @@ -2279,7 +2279,8 @@ static void ST_drawTextHUD(void) { if (stplyr->pflags & PF_TAGIT) { - textHUDdraw(M_GetText("\x82""You are blindfolded!")) + if (gametyperules & GTR_BLINDFOLDED) + textHUDdraw(M_GetText("\x82""You are blindfolded!")) textHUDdraw(M_GetText("Waiting for players to hide...")) } else if (gametype == GT_HIDEANDSEEK) @@ -2294,7 +2295,8 @@ static void ST_drawTextHUD(void) textHUDdraw(M_GetText("\x82""VIEWPOINT:""\x80 Switch view")) donef12 = true; } - textHUDdraw(M_GetText("You cannot move while hiding.")) + if (gametyperules & GTR_HIDETIMEFROZEN) + textHUDdraw(M_GetText("You cannot move while hiding.")) } } @@ -2316,21 +2318,21 @@ static void ST_drawTeamHUD(void) if (F_GetPromptHideHud(0)) // y base is 0 return; - if (gametype == GT_CTF) + if (gametyperules & GTR_TEAMFLAGS) p = bflagico; else p = bmatcico; V_DrawSmallScaledPatch(BASEVIDWIDTH/2 - SEP - SHORT(p->width)/4, 4, V_HUDTRANS|V_PERPLAYER|V_SNAPTOTOP, p); - if (gametype == GT_CTF) + if (gametyperules & GTR_TEAMFLAGS) p = rflagico; else p = rmatcico; V_DrawSmallScaledPatch(BASEVIDWIDTH/2 + SEP - SHORT(p->width)/4, 4, V_HUDTRANS|V_PERPLAYER|V_SNAPTOTOP, p); - if (gametype != GT_CTF) + if (!(gametyperules & GTR_TEAMFLAGS)) goto num; { INT32 i; From 1b81232d32a696e3aba9d40be3290fe6f65075e6 Mon Sep 17 00:00:00 2001 From: Jaime Passos Date: Wed, 18 Dec 2019 11:47:26 -0300 Subject: [PATCH 241/746] sike --- src/hardware/hw_md2.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/hardware/hw_md2.c b/src/hardware/hw_md2.c index ba7b70333..630c1e181 100644 --- a/src/hardware/hw_md2.c +++ b/src/hardware/hw_md2.c @@ -963,7 +963,7 @@ static void HWR_GetBlendedTexture(GLPatch_t *gpatch, GLPatch_t *blendgpatch, INT for (grmip = gpatch->mipmap; grmip->nextcolormap; ) { grmip = grmip->nextcolormap; - if (grmip->colormap == colormap || (skinnum < 1 && grmip->tcindex == skinnum)) + if (grmip->colormap == colormap || (skinnum < TC_DEFAULT && grmip->tcindex == skinnum)) { if (grmip->downloaded && grmip->grInfo.data) { From 83732f38a9cb8668c0346552e5d28c6fc94b339c Mon Sep 17 00:00:00 2001 From: Jaime Passos Date: Wed, 18 Dec 2019 12:09:44 -0300 Subject: [PATCH 242/746] GTR_PITYSHIELD --- src/doomstat.h | 1 + src/g_game.c | 6 +++--- src/p_user.c | 2 +- 3 files changed, 5 insertions(+), 4 deletions(-) diff --git a/src/doomstat.h b/src/doomstat.h index 06e114eb1..743d64282 100644 --- a/src/doomstat.h +++ b/src/doomstat.h @@ -432,6 +432,7 @@ enum GameTypeRules GTR_BLINDFOLDED = 1<<11, // Blindfolded view (Tag and Hide and Seek) GTR_EMERALDS = 1<<12, // Ringslinger emeralds (Match and CTF) GTR_TEAMFLAGS = 1<<13, // Gametype has team flags (CTF) + GTR_PITYSHIELD = 1<<14, // Award pity shield }; // String names for gametypes diff --git a/src/g_game.c b/src/g_game.c index 1f6bde833..a9474eb4f 100644 --- a/src/g_game.c +++ b/src/g_game.c @@ -3069,9 +3069,9 @@ INT16 gametypedefaultrules[NUMGAMETYPES] = GTR_PLATFORM|GTR_RACE|GTR_CHASECAM, // Match - GTR_RINGSLINGER|GTR_SPECTATORS|GTR_TIMELIMIT|GTR_EMERALDS, + GTR_RINGSLINGER|GTR_SPECTATORS|GTR_TIMELIMIT|GTR_EMERALDS|GTR_PITYSHIELD, // Team Match - GTR_RINGSLINGER|GTR_TEAMS|GTR_SPECTATORS|GTR_TIMELIMIT, + GTR_RINGSLINGER|GTR_TEAMS|GTR_SPECTATORS|GTR_TIMELIMIT|GTR_PITYSHIELD, // Tag GTR_RINGSLINGER|GTR_TAG|GTR_SPECTATORS|GTR_TIMELIMIT|GTR_HIDETIME|GTR_BLINDFOLDED, @@ -3079,7 +3079,7 @@ INT16 gametypedefaultrules[NUMGAMETYPES] = GTR_RINGSLINGER|GTR_TAG|GTR_SPECTATORS|GTR_TIMELIMIT|GTR_HIDETIME|GTR_BLINDFOLDED, // CTF - GTR_RINGSLINGER|GTR_TEAMS|GTR_SPECTATORS|GTR_TIMELIMIT|GTR_EMERALDS|GTR_TEAMFLAGS, + GTR_RINGSLINGER|GTR_TEAMS|GTR_SPECTATORS|GTR_TIMELIMIT|GTR_EMERALDS|GTR_TEAMFLAGS|GTR_PITYSHIELD, }; // diff --git a/src/p_user.c b/src/p_user.c index c94f18af1..b8164c173 100644 --- a/src/p_user.c +++ b/src/p_user.c @@ -10539,7 +10539,7 @@ void P_DoPityCheck(player_t *player) { // No pity outside of match or CTF. if (player->spectator - || !(gametype == GT_MATCH || gametype == GT_TEAMMATCH || gametype == GT_CTF)) + || !(gametyperules & GTR_PITYSHIELD)) return; // Apply pity shield if available. From da4e759a73928ab9ffdc55874914a2e65396e407 Mon Sep 17 00:00:00 2001 From: Jaime Passos Date: Wed, 18 Dec 2019 12:13:24 -0300 Subject: [PATCH 243/746] GTR_DEATHPENALTY --- src/doomstat.h | 1 + src/g_game.c | 2 +- src/p_inter.c | 2 +- 3 files changed, 3 insertions(+), 2 deletions(-) diff --git a/src/doomstat.h b/src/doomstat.h index 743d64282..3f76e770e 100644 --- a/src/doomstat.h +++ b/src/doomstat.h @@ -433,6 +433,7 @@ enum GameTypeRules GTR_EMERALDS = 1<<12, // Ringslinger emeralds (Match and CTF) GTR_TEAMFLAGS = 1<<13, // Gametype has team flags (CTF) GTR_PITYSHIELD = 1<<14, // Award pity shield + GTR_DEATHPENALTY = 1<<15, // Death score penalty }; // String names for gametypes diff --git a/src/g_game.c b/src/g_game.c index a9474eb4f..cb25dd954 100644 --- a/src/g_game.c +++ b/src/g_game.c @@ -3069,7 +3069,7 @@ INT16 gametypedefaultrules[NUMGAMETYPES] = GTR_PLATFORM|GTR_RACE|GTR_CHASECAM, // Match - GTR_RINGSLINGER|GTR_SPECTATORS|GTR_TIMELIMIT|GTR_EMERALDS|GTR_PITYSHIELD, + GTR_RINGSLINGER|GTR_SPECTATORS|GTR_TIMELIMIT|GTR_EMERALDS|GTR_PITYSHIELD|GTR_DEATHPENALTY, // Team Match GTR_RINGSLINGER|GTR_TEAMS|GTR_SPECTATORS|GTR_TIMELIMIT|GTR_PITYSHIELD, diff --git a/src/p_inter.c b/src/p_inter.c index 33a124133..21c3d4049 100644 --- a/src/p_inter.c +++ b/src/p_inter.c @@ -2389,7 +2389,7 @@ void P_KillMobj(mobj_t *target, mobj_t *inflictor, mobj_t *source, UINT8 damaget { if (metalrecording) // Ack! Metal Sonic shouldn't die! Cut the tape, end recording! G_StopMetalRecording(true); - if (gametype == GT_MATCH // note, no team match suicide penalty + if ((gametyperules & GTR_DEATHPENALTY) // note, no team match suicide penalty && ((target == source) || (source == NULL && inflictor == NULL) || (source && !source->player))) { // Suicide penalty if (target->player->score >= 50) From 6660d6302896b54e37a5bdd832e869037955eb73 Mon Sep 17 00:00:00 2001 From: Jaime Passos Date: Wed, 18 Dec 2019 12:14:18 -0300 Subject: [PATCH 244/746] There are only so many bits --- src/d_netcmd.c | 2 +- src/doomstat.h | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/d_netcmd.c b/src/d_netcmd.c index 0b7e3de18..a806a1052 100644 --- a/src/d_netcmd.c +++ b/src/d_netcmd.c @@ -382,7 +382,7 @@ char timedemo_csv_id[256]; boolean timedemo_quit; INT16 gametype = GT_COOP; -INT16 gametyperules = 0; +UINT32 gametyperules = 0; boolean splitscreen = false; boolean circuitmap = false; INT32 adminplayers[MAXPLAYERS]; diff --git a/src/doomstat.h b/src/doomstat.h index 3f76e770e..c51b98c3f 100644 --- a/src/doomstat.h +++ b/src/doomstat.h @@ -84,7 +84,7 @@ extern boolean addedtogame; // true after the server has added you extern boolean multiplayer; extern INT16 gametype; -extern INT16 gametyperules; +extern UINT32 gametyperules; extern boolean splitscreen; extern boolean circuitmap; // Does this level have 'circuit mode'? extern boolean fromlevelselect; From 15862ed02c888feb74cc2cabd64c546cd503df73 Mon Sep 17 00:00:00 2001 From: Jaime Passos Date: Wed, 18 Dec 2019 12:23:42 -0300 Subject: [PATCH 245/746] G_NewGametype --- src/d_netcmd.c | 2 ++ src/doomstat.h | 2 ++ src/g_game.c | 27 +++++++++++++++++++++++++++ src/g_game.h | 2 ++ 4 files changed, 33 insertions(+) diff --git a/src/d_netcmd.c b/src/d_netcmd.c index a806a1052..7b8095555 100644 --- a/src/d_netcmd.c +++ b/src/d_netcmd.c @@ -383,6 +383,8 @@ boolean timedemo_quit; INT16 gametype = GT_COOP; UINT32 gametyperules = 0; +INT16 numgametypes = (GT_CTF + 1); + boolean splitscreen = false; boolean circuitmap = false; INT32 adminplayers[MAXPLAYERS]; diff --git a/src/doomstat.h b/src/doomstat.h index c51b98c3f..66f7f3008 100644 --- a/src/doomstat.h +++ b/src/doomstat.h @@ -85,6 +85,8 @@ extern boolean multiplayer; extern INT16 gametype; extern UINT32 gametyperules; +extern INT16 numgametypes; + extern boolean splitscreen; extern boolean circuitmap; // Does this level have 'circuit mode'? extern boolean fromlevelselect; diff --git a/src/g_game.c b/src/g_game.c index cb25dd954..e70d4a6d1 100644 --- a/src/g_game.c +++ b/src/g_game.c @@ -3094,6 +3094,33 @@ void G_SetGametype(INT16 gtype) CONS_Printf("Gametype set to %s (%d)\n", Gametype_Names[gametype], gametype); } +// +// G_NewGametype +// +// Create a new gametype. Returns the new gametype number. +// +INT16 G_NewGametype(UINT32 rules) +{ + INT32 i; + INT16 newgtype = numgametypes; + numgametypes++; + + // Set gametype rules. + gametypedefaultrules[newgtype] = numgametypes; + Gametype_Names[newgtype] = "???"; + + // Update gametype_cons_t accordingly. + for (i = 0; i < numgametypes; i++) + { + gametype_cons_t[i].value = i; + gametype_cons_t[i].strvalue = Gametype_Names[i]; + } + gametype_cons_t[NUMGAMETYPES].value = 0; + gametype_cons_t[NUMGAMETYPES].strvalue = NULL; + + return newgtype; +} + // // G_GetGametypeByName // diff --git a/src/g_game.h b/src/g_game.h index a925e14c1..ef3e9ffab 100644 --- a/src/g_game.h +++ b/src/g_game.h @@ -202,6 +202,8 @@ void G_StopDemo(void); boolean G_CheckDemoStatus(void); void G_SetGametype(INT16 gametype); +INT16 G_NewGametype(UINT32 rules); + INT32 G_GetGametypeByName(const char *gametypestr); boolean G_IsSpecialStage(INT32 mapnum); boolean G_GametypeUsesLives(void); From 86ac94817af5940a351a2546d632c4f37137086a Mon Sep 17 00:00:00 2001 From: Jaime Passos Date: Wed, 18 Dec 2019 12:28:01 -0300 Subject: [PATCH 246/746] Spectator HUD tweaks --- src/st_stuff.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/src/st_stuff.c b/src/st_stuff.c index 061189f53..54bd36ac0 100644 --- a/src/st_stuff.c +++ b/src/st_stuff.c @@ -2203,9 +2203,10 @@ static void ST_drawTextHUD(void) if (G_IsSpecialStage(gamemap)) textHUDdraw(M_GetText("\x82""Wait for the stage to end...")) - else if (gametype == GT_COOP) + else if (G_PlatformGametype()) { - if (stplyr->lives <= 0 + if (gametype == GT_COOP + && stplyr->lives <= 0 && cv_cooplives.value == 2 && (netgame || multiplayer)) { @@ -2230,7 +2231,7 @@ static void ST_drawTextHUD(void) else textHUDdraw(M_GetText("Wait to respawn...")) } - else + else if (G_GametypeHasSpectators()) textHUDdraw(M_GetText("\x82""FIRE:""\x80 Enter game")) } From 78074246335834088fc14a3f80ad133f095a1476 Mon Sep 17 00:00:00 2001 From: Jaime Passos Date: Wed, 18 Dec 2019 12:30:01 -0300 Subject: [PATCH 247/746] NUMGAMETYPES vs gametypecount --- src/d_clisrv.c | 2 +- src/d_main.c | 2 +- src/d_netcmd.c | 14 +++++++------- src/doomstat.h | 2 +- src/g_game.c | 8 ++++---- src/hu_stuff.c | 2 +- src/m_menu.c | 2 +- 7 files changed, 16 insertions(+), 16 deletions(-) diff --git a/src/d_clisrv.c b/src/d_clisrv.c index bfc478bd5..4468502d0 100644 --- a/src/d_clisrv.c +++ b/src/d_clisrv.c @@ -2114,7 +2114,7 @@ static void CL_ConnectToServer(boolean viams) UINT8 num = serverlist[i].info.gametype; const char *gametypestr = NULL; CONS_Printf(M_GetText("Connecting to: %s\n"), serverlist[i].info.servername); - if (num < NUMGAMETYPES) + if (num < gametypecount) gametypestr = Gametype_Names[num]; if (gametypestr) CONS_Printf(M_GetText("Gametype: %s\n"), gametypestr); diff --git a/src/d_main.c b/src/d_main.c index 815136440..50da0a629 100644 --- a/src/d_main.c +++ b/src/d_main.c @@ -1409,7 +1409,7 @@ void D_SRB2Main(void) if (newgametype == -1) // reached end of the list with no match { j = atoi(sgametype); // assume they gave us a gametype number, which is okay too - if (j >= 0 && j < NUMGAMETYPES) + if (j >= 0 && j < gametypecount) newgametype = (INT16)j; } diff --git a/src/d_netcmd.c b/src/d_netcmd.c index 7b8095555..e0cc32914 100644 --- a/src/d_netcmd.c +++ b/src/d_netcmd.c @@ -383,7 +383,7 @@ boolean timedemo_quit; INT16 gametype = GT_COOP; UINT32 gametyperules = 0; -INT16 numgametypes = (GT_CTF + 1); +INT16 gametypecount = (GT_CTF + 1); boolean splitscreen = false; boolean circuitmap = false; @@ -1943,7 +1943,7 @@ static void Command_Map_f(void) if (isdigit(gametypename[0])) { d = atoi(gametypename); - if (d >= 0 && d < NUMGAMETYPES) + if (d >= 0 && d < gametypecount) newgametype = d; else { @@ -1951,7 +1951,7 @@ static void Command_Map_f(void) "Gametype number %d is out of range. Use a number between" " 0 and %d inclusive. ...Or just use the name. :v\n", d, - NUMGAMETYPES-1); + gametypecount-1); Z_Free(realmapname); Z_Free(mapname); return; @@ -2072,7 +2072,7 @@ static void Got_Mapcmd(UINT8 **cp, INT32 playernum) gametype = READUINT8(*cp); G_SetGametype(gametype); // I fear putting that macro as an argument - if (gametype < 0 || gametype >= NUMGAMETYPES) + if (gametype < 0 || gametype >= gametypecount) gametype = lastgametype; else if (gametype != lastgametype) D_GameTypeChanged(lastgametype); // emulate consvar_t behavior for gametype @@ -3624,7 +3624,7 @@ static void Command_ShowGametype_f(void) } // get name string for current gametype - if (gametype >= 0 && gametype < NUMGAMETYPES) + if (gametype >= 0 && gametype < gametypecount) gametypestr = Gametype_Names[gametype]; if (gametypestr) @@ -3891,9 +3891,9 @@ void D_GameTypeChanged(INT32 lastgametype) { const char *oldgt = NULL, *newgt = NULL; - if (lastgametype >= 0 && lastgametype < NUMGAMETYPES) + if (lastgametype >= 0 && lastgametype < gametypecount) oldgt = Gametype_Names[lastgametype]; - if (gametype >= 0 && lastgametype < NUMGAMETYPES) + if (gametype >= 0 && lastgametype < gametypecount) newgt = Gametype_Names[gametype]; if (oldgt && newgt) diff --git a/src/doomstat.h b/src/doomstat.h index 66f7f3008..f51f75fb8 100644 --- a/src/doomstat.h +++ b/src/doomstat.h @@ -85,7 +85,7 @@ extern boolean multiplayer; extern INT16 gametype; extern UINT32 gametyperules; -extern INT16 numgametypes; +extern INT16 gametypecount; extern boolean splitscreen; extern boolean circuitmap; // Does this level have 'circuit mode'? diff --git a/src/g_game.c b/src/g_game.c index e70d4a6d1..619950882 100644 --- a/src/g_game.c +++ b/src/g_game.c @@ -3102,15 +3102,15 @@ void G_SetGametype(INT16 gtype) INT16 G_NewGametype(UINT32 rules) { INT32 i; - INT16 newgtype = numgametypes; - numgametypes++; + INT16 newgtype = gametypecount; + gametypecount++; // Set gametype rules. - gametypedefaultrules[newgtype] = numgametypes; + gametypedefaultrules[newgtype] = gametypecount; Gametype_Names[newgtype] = "???"; // Update gametype_cons_t accordingly. - for (i = 0; i < numgametypes; i++) + for (i = 0; i < gametypecount; i++) { gametype_cons_t[i].value = i; gametype_cons_t[i].strvalue = Gametype_Names[i]; diff --git a/src/hu_stuff.c b/src/hu_stuff.c index e67249953..1e9b4f14a 100644 --- a/src/hu_stuff.c +++ b/src/hu_stuff.c @@ -2066,7 +2066,7 @@ static void HU_drawGametype(void) { const char *strvalue = NULL; - if (gametype < 0 || gametype >= NUMGAMETYPES) + if (gametype < 0 || gametype >= gametypecount) return; // not a valid gametype??? strvalue = Gametype_Names[gametype]; diff --git a/src/m_menu.c b/src/m_menu.c index 23dc10701..c257adfd6 100644 --- a/src/m_menu.c +++ b/src/m_menu.c @@ -9932,7 +9932,7 @@ static void M_DrawConnectMenu(void) va("Ping: %u", (UINT32)LONG(serverlist[slindex].info.time))); gt = "Unknown"; - if (serverlist[slindex].info.gametype < NUMGAMETYPES) + if (serverlist[slindex].info.gametype < gametypecount) gt = Gametype_Names[serverlist[slindex].info.gametype]; V_DrawSmallString(currentMenu->x+46,S_LINEY(i)+8, globalflags, From aa619e1b34c6d0481096c4e98e980f5662f27421 Mon Sep 17 00:00:00 2001 From: Jaime Passos Date: Wed, 18 Dec 2019 12:36:02 -0300 Subject: [PATCH 248/746] Rankings tweaks --- src/d_clisrv.c | 2 +- src/hu_stuff.c | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/d_clisrv.c b/src/d_clisrv.c index 4468502d0..d1dee3985 100644 --- a/src/d_clisrv.c +++ b/src/d_clisrv.c @@ -2111,7 +2111,7 @@ static void CL_ConnectToServer(boolean viams) if (i != -1) { - UINT8 num = serverlist[i].info.gametype; + UINT16 num = serverlist[i].info.gametype; const char *gametypestr = NULL; CONS_Printf(M_GetText("Connecting to: %s\n"), serverlist[i].info.servername); if (num < gametypecount) diff --git a/src/hu_stuff.c b/src/hu_stuff.c index 1e9b4f14a..8cbfa77d3 100644 --- a/src/hu_stuff.c +++ b/src/hu_stuff.c @@ -3026,7 +3026,7 @@ static void HU_DrawRankings(void) // draw the current gametype in the lower right HU_drawGametype(); - if (gametype != GT_RACE && gametype != GT_COMPETITION && gametype != GT_COOP) + if (!G_PlatformGametype()) { if (cv_timelimit.value && timelimitintics > 0) { @@ -3083,7 +3083,7 @@ static void HU_DrawRankings(void) if (!playeringame[j]) continue; - if (gametype != GT_COOP && players[j].spectator) + if (!G_PlatformGametype() && players[j].spectator) continue; for (i = 0; i < MAXPLAYERS; i++) @@ -3091,7 +3091,7 @@ static void HU_DrawRankings(void) if (!playeringame[i]) continue; - if (gametype != GT_COOP && players[i].spectator) + if (!G_PlatformGametype() && players[i].spectator) continue; if (gametype == GT_RACE) From 45580ce5576acc7b59e8b67008483e52bb41b050 Mon Sep 17 00:00:00 2001 From: Jaime Passos Date: Wed, 18 Dec 2019 12:36:54 -0300 Subject: [PATCH 249/746] Make NUMGAMETYPEFREESLOTS lower because netcode --- src/doomstat.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/doomstat.h b/src/doomstat.h index f51f75fb8..4d17b5c79 100644 --- a/src/doomstat.h +++ b/src/doomstat.h @@ -389,7 +389,7 @@ enum TypeOfLevel }; // Gametypes -#define NUMGAMETYPEFREESLOTS 512 +#define NUMGAMETYPEFREESLOTS 128 enum GameType { GT_COOP = 0, // also used in single player From b759ebf62292a2833df742562aea78d66c5fc6b8 Mon Sep 17 00:00:00 2001 From: Jaime Passos Date: Wed, 18 Dec 2019 12:40:46 -0300 Subject: [PATCH 250/746] Death of TOL_CUSTOM --- src/dehacked.c | 3 --- src/doomstat.h | 4 ++-- 2 files changed, 2 insertions(+), 5 deletions(-) diff --git a/src/dehacked.c b/src/dehacked.c index 175c1fcfa..5cfe953b8 100644 --- a/src/dehacked.c +++ b/src/dehacked.c @@ -1114,8 +1114,6 @@ static const struct { {"TAG",TOL_TAG}, {"CTF",TOL_CTF}, - {"CUSTOM",TOL_CUSTOM}, - {"2D",TOL_2D}, {"MARIO",TOL_MARIO}, {"NIGHTS",TOL_NIGHTS}, @@ -9042,7 +9040,6 @@ struct { {"TOL_MATCH",TOL_MATCH}, {"TOL_TAG",TOL_TAG}, {"TOL_CTF",TOL_CTF}, - {"TOL_CUSTOM",TOL_CUSTOM}, {"TOL_2D",TOL_2D}, {"TOL_MARIO",TOL_MARIO}, {"TOL_NIGHTS",TOL_NIGHTS}, diff --git a/src/doomstat.h b/src/doomstat.h index 4d17b5c79..5bc64ae7e 100644 --- a/src/doomstat.h +++ b/src/doomstat.h @@ -287,7 +287,7 @@ typedef struct char lvlttl[22]; ///< Level name without "Zone". (21 character limit instead of 32, 21 characters can display on screen max anyway) char subttl[33]; ///< Subtitle for level UINT8 actnum; ///< Act number or 0 for none. - UINT16 typeoflevel; ///< Combination of typeoflevel flags. + UINT32 typeoflevel; ///< Combination of typeoflevel flags. INT16 nextlevel; ///< Map number of next level, or 1100-1102 to end. char musname[7]; ///< Music track to play. "" for no music. UINT16 mustrack; ///< Subsong to play. Only really relevant for music modules and specific formats supported by GME. 0 to ignore. @@ -379,7 +379,7 @@ enum TypeOfLevel TOL_CTF = 0x40, ///< Capture the Flag // CTF default = 64 - TOL_CUSTOM = 0x80, ///< Custom (Lua-scripted, etc.) + //TOL_CUSTOM = 0x80, ///< Custom (Lua-scripted, etc.) TOL_2D = 0x0100, ///< 2D TOL_MARIO = 0x0200, ///< Mario From 79d5192b7c8de8d8afe27b431e714d9f76020e3f Mon Sep 17 00:00:00 2001 From: Jaime Passos Date: Wed, 18 Dec 2019 13:24:10 -0300 Subject: [PATCH 251/746] TOL/Level platter stuff --- src/dehacked.c | 6 ++--- src/doomstat.h | 61 +++++++++++++++++++++++++++-------------------- src/g_game.c | 64 ++++++++++++++++++++++++++++++++++++++++++++++---- src/g_game.h | 7 +++++- src/m_menu.c | 5 +++- src/m_menu.h | 1 + 6 files changed, 109 insertions(+), 35 deletions(-) diff --git a/src/dehacked.c b/src/dehacked.c index 5cfe953b8..3f018bee8 100644 --- a/src/dehacked.c +++ b/src/dehacked.c @@ -1095,10 +1095,8 @@ static void readsprite2(MYFILE *f, INT32 num) Z_Free(s); } -static const struct { - const char *name; - const UINT16 flag; -} TYPEOFLEVEL[] = { +INT32 numtolinfo = NUMBASETOL; +tolinfo_t TYPEOFLEVEL[NUMMAXTOL] = { {"SOLO",TOL_SP}, {"SP",TOL_SP}, {"SINGLEPLAYER",TOL_SP}, diff --git a/src/doomstat.h b/src/doomstat.h index 5bc64ae7e..f143151af 100644 --- a/src/doomstat.h +++ b/src/doomstat.h @@ -39,7 +39,7 @@ extern UINT32 mapmusposition; #define MUSIC_FORCERESET 0x4000 // -*-------------- // Use other bits if necessary. -extern INT16 maptol; +extern UINT32 maptol; extern UINT8 globalweather; extern INT32 curWeather; extern INT32 cursaveslot; @@ -364,30 +364,6 @@ typedef struct extern mapheader_t* mapheaderinfo[NUMMAPS]; -enum TypeOfLevel -{ - TOL_SP = 0x01, ///< Single Player - TOL_COOP = 0x02, ///< Cooperative - TOL_COMPETITION = 0x04, ///< Competition - TOL_RACE = 0x08, ///< Race -// Single Player default = 15 - - TOL_MATCH = 0x10, ///< Match - TOL_TAG = 0x20, ///< Tag -// Match/Tag default = 48 - - TOL_CTF = 0x40, ///< Capture the Flag -// CTF default = 64 - - //TOL_CUSTOM = 0x80, ///< Custom (Lua-scripted, etc.) - - TOL_2D = 0x0100, ///< 2D - TOL_MARIO = 0x0200, ///< Mario - TOL_NIGHTS = 0x0400, ///< NiGHTS - TOL_ERZ3 = 0x0800, ///< ERZ3 - TOL_XMAS = 0x1000 ///< Christmas NiGHTS -}; - // Gametypes #define NUMGAMETYPEFREESLOTS 128 enum GameType @@ -441,6 +417,41 @@ enum GameTypeRules // String names for gametypes extern const char *Gametype_Names[NUMGAMETYPES]; +enum TypeOfLevel +{ + TOL_SP = 0x01, ///< Single Player + TOL_COOP = 0x02, ///< Cooperative + TOL_COMPETITION = 0x04, ///< Competition + TOL_RACE = 0x08, ///< Race +// Single Player default = 15 + + TOL_MATCH = 0x10, ///< Match + TOL_TAG = 0x20, ///< Tag +// Match/Tag default = 48 + + TOL_CTF = 0x40, ///< Capture the Flag +// CTF default = 64 + + // 0x80 was here + + TOL_2D = 0x0100, ///< 2D + TOL_MARIO = 0x0200, ///< Mario + TOL_NIGHTS = 0x0400, ///< NiGHTS + TOL_ERZ3 = 0x0800, ///< ERZ3 + TOL_XMAS = 0x1000, ///< Christmas NiGHTS +}; + +#define NUMBASETOL 18 +#define NUMMAXTOL (18 + NUMGAMETYPEFREESLOTS) + +typedef struct +{ + const char *name; + UINT32 flag; +} tolinfo_t; +extern tolinfo_t TYPEOFLEVEL[NUMMAXTOL]; +extern INT32 numtolinfo; + extern tic_t totalplaytime; extern UINT8 stagefailed; diff --git a/src/g_game.c b/src/g_game.c index 619950882..d66a7454f 100644 --- a/src/g_game.c +++ b/src/g_game.c @@ -79,7 +79,7 @@ UINT16 mapmusflags; // Track and reset bit UINT32 mapmusposition; // Position to jump to INT16 gamemap = 1; -INT16 maptol; +UINT32 maptol; UINT8 globalweather = 0; INT32 curWeather = PRECIP_NONE; INT32 cursaveslot = 0; // Auto-save 1p savegame slot @@ -3095,11 +3095,11 @@ void G_SetGametype(INT16 gtype) } // -// G_NewGametype +// G_AddGametype // -// Create a new gametype. Returns the new gametype number. +// Add a gametype. Returns the new gametype number. // -INT16 G_NewGametype(UINT32 rules) +INT16 G_AddGametype(UINT32 rules) { INT32 i; INT16 newgtype = gametypecount; @@ -3121,6 +3121,59 @@ INT16 G_NewGametype(UINT32 rules) return newgtype; } +// +// G_SetGametypeDescription +// +// Set a description for the specified gametype. +// (Level platter) +// +void G_SetGametypeDescription(INT16 gtype, const char *description, UINT8 leftcolor, UINT8 rightcolor) +{ + strncpy(gametypedesc[gtype].notes, description, 441); + gametypedesc[gtype].col[0] = leftcolor; + gametypedesc[gtype].col[1] = rightcolor; +} + +UINT32 gametypetol[NUMGAMETYPES] = +{ + TOL_COOP, // Co-op + TOL_COMPETITION, // Competition + TOL_RACE, // Race + + TOL_MATCH, // Match + TOL_MATCH, // Team Match + + TOL_TAG, // Tag + TOL_TAG, // Hide and Seek + + TOL_CTF, // CTF +}; + +// +// G_AddTOL +// +// Adds a type of level. +// +void G_AddTOL(UINT32 newtol, const char *tolname) +{ + TYPEOFLEVEL[numtolinfo].name = tolname; + TYPEOFLEVEL[numtolinfo].flag = newtol; + numtolinfo++; + + TYPEOFLEVEL[numtolinfo].name = NULL; + TYPEOFLEVEL[numtolinfo].flag = 0; +} + +// +// G_AddTOL +// +// Assigns a type of level to a gametype. +// +void G_AddGametypeTOL(INT16 gametype, UINT32 newtol) +{ + gametypetol[gametype] = newtol; +} + // // G_GetGametypeByName // @@ -3240,6 +3293,8 @@ boolean G_TagGametype(void) INT16 G_TOLFlag(INT32 pgametype) { if (!multiplayer) return TOL_SP; + return gametypetol[pgametype]; +#if 0 if (pgametype == GT_COOP) return TOL_COOP; if (pgametype == GT_COMPETITION) return TOL_COMPETITION; if (pgametype == GT_RACE) return TOL_RACE; @@ -3251,6 +3306,7 @@ INT16 G_TOLFlag(INT32 pgametype) CONS_Alert(CONS_ERROR, M_GetText("Unknown gametype! %d\n"), pgametype); return INT16_MAX; +#endif } /** Select a random map with the given typeoflevel flags. diff --git a/src/g_game.h b/src/g_game.h index ef3e9ffab..fa2ba95fb 100644 --- a/src/g_game.h +++ b/src/g_game.h @@ -201,8 +201,13 @@ ATTRNORETURN void FUNCNORETURN G_StopMetalRecording(boolean kill); void G_StopDemo(void); boolean G_CheckDemoStatus(void); +extern INT16 gametypedefaultrules[NUMGAMETYPES]; +extern UINT32 gametypetol[NUMGAMETYPES]; + void G_SetGametype(INT16 gametype); -INT16 G_NewGametype(UINT32 rules); +INT16 G_AddGametype(UINT32 rules); +void G_AddTOL(UINT32 newtol, const char *tolname); +void G_AddGametypeTOL(INT16 gametype, UINT32 newtol); INT32 G_GetGametypeByName(const char *gametypestr); boolean G_IsSpecialStage(INT32 mapnum); diff --git a/src/m_menu.c b/src/m_menu.c index c257adfd6..6699ed924 100644 --- a/src/m_menu.c +++ b/src/m_menu.c @@ -605,7 +605,7 @@ static menuitem_t MISC_ChangeTeamMenu[] = {IT_WHITESTRING|IT_CALL, NULL, "Confirm", M_ConfirmTeamChange, 90}, }; -static const gtdesc_t gametypedesc[] = +gtdesc_t gametypedesc[NUMGAMETYPES] = { {{ 54, 54}, "Play through the single-player campaign with your friends, teaming up to beat Dr Eggman's nefarious challenges!"}, {{103, 103}, "Speed your way through the main acts, competing in several different categories to see who's the best."}, @@ -4684,6 +4684,9 @@ 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])) + return true; + return false; case LLM_LEVELSELECT: diff --git a/src/m_menu.h b/src/m_menu.h index ce9b422dc..19858e2fc 100644 --- a/src/m_menu.h +++ b/src/m_menu.h @@ -371,6 +371,7 @@ typedef struct UINT8 col[2]; char notes[441]; } gtdesc_t; +extern gtdesc_t gametypedesc[NUMGAMETYPES]; // mode descriptions for video mode menu typedef struct From 1e2331d672f7ca349efe9624a7b9e37526eeeb22 Mon Sep 17 00:00:00 2001 From: Jaime Passos Date: Wed, 18 Dec 2019 14:37:48 -0300 Subject: [PATCH 252/746] SOC stuff --- src/dehacked.c | 246 ++++++++++++++++++++++++++++++++++++++++++++++++- src/doomstat.h | 1 + src/g_game.c | 34 ++++++- src/g_game.h | 2 + 4 files changed, 278 insertions(+), 5 deletions(-) diff --git a/src/dehacked.c b/src/dehacked.c index 3f018bee8..5ade1b2bd 100644 --- a/src/dehacked.c +++ b/src/dehacked.c @@ -76,6 +76,7 @@ static UINT16 get_mus(const char *word, UINT8 dehacked_mode); static hudnum_t get_huditem(const char *word); static menutype_t get_menutype(const char *word); #ifndef HAVE_BLUA +static INT16 get_gametype(const char *word); static powertype_t get_power(const char *word); #endif @@ -1124,6 +1125,145 @@ tolinfo_t TYPEOFLEVEL[NUMMAXTOL] = { {NULL, 0} }; +// copypasted from readPlayer :sleep: +static void readgametype(MYFILE *f, char *gtname) +{ + char *s = Z_Malloc(MAXLINELEN, PU_STATIC, NULL); + char *word; + char *word2; + char *tmp; + INT32 i; + + INT16 newgtidx = 0; + UINT32 newgtrules = 0; + UINT32 newgttol = 0; + UINT8 newgtleftcolor = 0; + UINT8 newgtrightcolor = 0; + char gtdescription[441]; + const char *gtnamestring; + + do + { + if (myfgets(s, MAXLINELEN, f)) + { + if (s[0] == '\n') + break; + + word = strtok(s, " "); + if (word) + strupr(word); + else + break; + + if (fastcmp(word, "DESCRIPTION")) + { + char *descr = NULL; + + for (i = 0; i < MAXLINELEN-3; i++) + { + if (s[i] == '=') + { + descr = &s[i+2]; + break; + } + } + if (descr) + { + strcpy(gtdescription, descr); + strcat(gtdescription, myhashfgets(descr, sizeof (gtdescription), f)); + } + else + strcpy(gtdescription, ""); + + // For some reason, cutting the string did not work above. Most likely due to strcpy or strcat... + // It works down here, though. + { + INT32 numline = 0; + for (i = 0; i < MAXLINELEN-1; i++) + { + if (numline < 20 && gtdescription[i] == '\n') + numline++; + + if (numline >= 20 || gtdescription[i] == '\0' || gtdescription[i] == '#') + break; + } + } + gtdescription[strlen(gtdescription)-1] = '\0'; + gtdescription[i] = '\0'; + continue; + } + + word2 = strtok(NULL, " = "); + if (word2) + strupr(word2); + else + break; + + if (word2[strlen(word2)-1] == '\n') + word2[strlen(word2)-1] = '\0'; + i = atoi(word2); + + if (fastcmp(word, "RULES")) + { + // Game type rules (GTR_) + newgtrules = (UINT32)get_number(word2); + } + else if (fastcmp(word, "HEADERCOLOR") || fastcmp(word, "HEADERCOLOUR")) + { + // Level platter + newgtleftcolor = newgtrightcolor = (UINT8)get_number(word2); + } + else if (fastcmp(word, "HEADERLEFTCOLOR") || fastcmp(word, "HEADERLEFTCOLOUR")) + { + // Level platter + newgtleftcolor = (UINT8)get_number(word2); + } + else if (fastcmp(word, "HEADERRIGHTCOLOR") || fastcmp(word, "HEADERRIGHTCOLOUR")) + { + // Level platter + newgtrightcolor = (UINT8)get_number(word2); + } + else if (fastcmp(word, "TYPEOFLEVEL")) + { + if (i) // it's just a number + newgttol = (UINT16)i; + else + { + UINT16 tol = 0; + tmp = strtok(word2,","); + do { + for (i = 0; TYPEOFLEVEL[i].name; i++) + if (fastcmp(tmp, TYPEOFLEVEL[i].name)) + break; + if (!TYPEOFLEVEL[i].name) + deh_warning("readgametype %s: unknown typeoflevel flag %s\n", gtname, tmp); + tol |= TYPEOFLEVEL[i].flag; + } while((tmp = strtok(NULL,",")) != NULL); + newgttol = tol; + } + } + else + deh_warning("readgametype %s: unknown word '%s'", gtname, word); + } + } while (!myfeof(f)); // finish when the line is empty + Z_Free(s); + + // Add the new gametype + newgtidx = G_AddGametype(newgtrules); + G_AddGametypeTOL(newgtidx, newgttol); + G_SetGametypeDescription(newgtidx, gtdescription, newgtleftcolor, newgtrightcolor); + + // Write the new gametype name. + gtnamestring = Z_Malloc(MAXLINELEN, PU_STATIC, NULL); + memcpy((void *)gtnamestring, gtname, MAXLINELEN); + Gametype_Names[newgtidx] = gtnamestring; + + // Update gametype_cons_t accordingly. + G_UpdateGametypeSelections(); + + CONS_Printf("Added gametype %s\n", Gametype_Names[newgtidx]); +} + static const struct { const char *name; const mobjtype_t type; @@ -4151,6 +4291,7 @@ static void ignorelines(MYFILE *f) static void DEH_LoadDehackedFile(MYFILE *f, boolean mainfile) { char *s = Z_Malloc(MAXLINELEN, PU_STATIC, NULL); + char textline[MAXLINELEN]; char *word; char *word2; INT32 i; @@ -4171,6 +4312,7 @@ static void DEH_LoadDehackedFile(MYFILE *f, boolean mainfile) char *traverse; myfgets(s, MAXLINELEN, f); + memcpy(textline, s, MAXLINELEN); if (s[0] == '\n' || s[0] == '#') continue; @@ -4359,6 +4501,36 @@ static void DEH_LoadDehackedFile(MYFILE *f, boolean mainfile) ignorelines(f); } } + else if (fastcmp(word, "GAMETYPE")) + { + // Get the gametype name from textline + // instead of word2, so that gametype names + // aren't allcaps + INT32 i; + for (i = 0; i < MAXLINELEN; i++) + { + if (textline[i] == '\0') + break; + if (textline[i] == ' ') + { + char *gtname = (textline+i+1); + if (gtname) + { + // remove funny characters + INT32 j; + for (j = 0; j < (MAXLINELEN - i); j++) + { + if (gtname[j] == '\0') + break; + if (gtname[j] < 32 || gtname[j] > 127) + gtname[j] = '\0'; + } + readgametype(f, gtname); + } + break; + } + } + } else if (fastcmp(word, "CUTSCENE")) { if (i > 0 && i < 129) @@ -8615,6 +8787,26 @@ static const char *const PLAYERFLAG_LIST[] = { NULL // stop loop here. }; +static const char *const GAMETYPERULE_LIST[] = { + "PLATFORM", + "TAG", + "RINGSLINGER", + "SPECTATORS", + "TEAMS", + "LIVES", + "RACE", + "CHASECAM", + "TIMELIMIT", + "HIDETIME", + "HIDETIMEFROZEN", + "BLINDFOLDED", + "EMERALDS", + "TEAMFLAGS", + "PITYSHIELD", + "DEATHPENALTY", + NULL +}; + #ifdef HAVE_BLUA // Linedef flags static const char *const ML_LIST[16] = { @@ -9227,6 +9419,7 @@ struct { {"DMG_DEATHMASK",DMG_DEATHMASK}, // Gametypes, for use with global var "gametype" + // Left them here just in case?? {"GT_COOP",GT_COOP}, {"GT_COMPETITION",GT_COMPETITION}, {"GT_RACE",GT_RACE}, @@ -9679,6 +9872,20 @@ static menutype_t get_menutype(const char *word) } #ifndef HAVE_BLUA +static INT16 get_gametype(const char *word) +{ // Returns the value of GT_ enumerations + INT16 i; + if (*word >= '0' && *word <= '9') + return atoi(word); + if (fastncmp("GT_",word,3)) + word += 3; // take off the GT_ + for (i = 0; i < NUMGAMETYPES; i++) + if (fastcmp(word, Gametype_ConstantNames[i]+3)) + return i; + deh_warning("Couldn't find gametype named 'GT_%s'",word); + return GT_COOP; +} + static powertype_t get_power(const char *word) { // Returns the vlaue of pw_ enumerations powertype_t i; @@ -9842,6 +10049,19 @@ static fixed_t find_const(const char **rword) free(word); return 0; } + else if (fastncmp("GTR_", word, 4)) { + char *p = word+4; + for (i = 0; GAMETYPERULE_LIST[i]; i++) + if (fastcmp(p, GAMETYPERULE_LIST[i])) { + free(word); + return (1< Date: Wed, 18 Dec 2019 14:47:39 -0300 Subject: [PATCH 253/746] GTR_NOSPECTATORSPAWN --- src/d_netcmd.c | 7 ++++++- src/dehacked.c | 1 + src/doomstat.h | 41 ++++++++++++++++++++--------------------- 3 files changed, 27 insertions(+), 22 deletions(-) diff --git a/src/d_netcmd.c b/src/d_netcmd.c index e0cc32914..959ed875f 100644 --- a/src/d_netcmd.c +++ b/src/d_netcmd.c @@ -3636,7 +3636,11 @@ static void Command_ShowGametype_f(void) static void Command_SetGametype_f(void) { if (COM_Argc() > 1) + { + INT16 oldgametype = gametype; G_SetGametype(atoi(COM_Argv(1))); + D_GameTypeChanged(oldgametype); + } } /** Plays the intro. @@ -3978,6 +3982,7 @@ void D_GameTypeChanged(INT32 lastgametype) // When swapping to a gametype that supports spectators, // make everyone a spectator initially. + // Averted with GTR_NOSPECTATORSPAWN. if (!splitscreen && (G_GametypeHasSpectators())) { INT32 i; @@ -3985,7 +3990,7 @@ void D_GameTypeChanged(INT32 lastgametype) if (playeringame[i]) { players[i].ctfteam = 0; - players[i].spectator = true; + players[i].spectator = (gametyperules & GTR_NOSPECTATORSPAWN) ? false : true; } } diff --git a/src/dehacked.c b/src/dehacked.c index 5ade1b2bd..b316fb40e 100644 --- a/src/dehacked.c +++ b/src/dehacked.c @@ -8804,6 +8804,7 @@ static const char *const GAMETYPERULE_LIST[] = { "TEAMFLAGS", "PITYSHIELD", "DEATHPENALTY", + "NOSPECTATORSPAWN", NULL }; diff --git a/src/doomstat.h b/src/doomstat.h index 1d6d85017..7d6839e52 100644 --- a/src/doomstat.h +++ b/src/doomstat.h @@ -389,29 +389,28 @@ enum GameType // Game type rules enum GameTypeRules { - GTR_PLATFORM = 1, // Co-op, Competition, and Race - GTR_TAG = 1<<1, // Tag and Hide and Seek - GTR_RINGSLINGER = 1<<2, // Not Co-op, not Competition, and not Race (overriden by cv_ringslinger) - GTR_SPECTATORS = 1<<3, // Not Co-op, not Competition, and not Race - GTR_TEAMS = 1<<4, // Team Match, CTF - GTR_LIVES = 1<<5, // A lot of special cases in G_GametypeUsesLives actually, but just Co-op and Competition - GTR_RACE = 1<<6, // Race and Competition + GTR_PLATFORM = 1, // Co-op, Competition, and Race + GTR_TAG = 1<<1, // Tag and Hide and Seek + GTR_RINGSLINGER = 1<<2, // Not Co-op, not Competition, and not Race (overriden by cv_ringslinger) + GTR_SPECTATORS = 1<<3, // Not Co-op, not Competition, and not Race + GTR_TEAMS = 1<<4, // Team Match, CTF + GTR_LIVES = 1<<5, // A lot of special cases in G_GametypeUsesLives actually, but just Co-op and Competition + GTR_RACE = 1<<6, // Race and Competition // Lactozilla - // Awesome! Those are new game type rules - // provided by yours truly to allow for more - // flexibility! Those will replace some - // straight-up gametype checks scattered - // around the source code! - GTR_CHASECAM = 1<<7, // Prefer chasecam at map load (All platform gametypes) - GTR_TIMELIMIT = 1<<8, // Ringslinger time limit (Tag and Hide and Seek) - GTR_HIDETIME = 1<<9, // Tag and Hide and Seek - GTR_HIDETIMEFROZEN = 1<<10, // Hide and Seek, but not Tag - GTR_BLINDFOLDED = 1<<11, // Blindfolded view (Tag and Hide and Seek) - GTR_EMERALDS = 1<<12, // Ringslinger emeralds (Match and CTF) - GTR_TEAMFLAGS = 1<<13, // Gametype has team flags (CTF) - GTR_PITYSHIELD = 1<<14, // Award pity shield - GTR_DEATHPENALTY = 1<<15, // Death score penalty + // Awesome! Those are new game type rules provided by yours truly to allow for more + // flexibility! Those will replace some straight-up gametype checks scattered around the source code! + + GTR_CHASECAM = 1<<7, // Prefer chasecam at map load (All platform gametypes) + GTR_TIMELIMIT = 1<<8, // Ringslinger time limit (Tag and Hide and Seek) + GTR_HIDETIME = 1<<9, // Tag and Hide and Seek + GTR_HIDETIMEFROZEN = 1<<10, // Hide and Seek, but not Tag + GTR_BLINDFOLDED = 1<<11, // Blindfolded view (Tag and Hide and Seek) + GTR_EMERALDS = 1<<12, // Ringslinger emeralds (Match and CTF) + GTR_TEAMFLAGS = 1<<13, // Gametype has team flags (CTF) + GTR_PITYSHIELD = 1<<14, // Award pity shield + GTR_DEATHPENALTY = 1<<15, // Death score penalty + GTR_NOSPECTATORSPAWN = 1<<16, // For use with GTR_SPECTATORS - spawn in the map instead of with the spectators }; // String names for gametypes From d3d91726f54184969a69463b8fedf70417224af5 Mon Sep 17 00:00:00 2001 From: Jaime Passos Date: Wed, 18 Dec 2019 14:57:42 -0300 Subject: [PATCH 254/746] GTR_EMERALDHUNT and GTR_SPAWNENEMIES --- src/dehacked.c | 2 ++ src/doomstat.h | 2 ++ src/g_game.c | 9 ++++----- src/g_game.h | 2 +- src/p_mobj.c | 4 ++-- 5 files changed, 11 insertions(+), 8 deletions(-) diff --git a/src/dehacked.c b/src/dehacked.c index b316fb40e..7e584cbf8 100644 --- a/src/dehacked.c +++ b/src/dehacked.c @@ -8805,6 +8805,8 @@ static const char *const GAMETYPERULE_LIST[] = { "PITYSHIELD", "DEATHPENALTY", "NOSPECTATORSPAWN", + "EMERALDHUNT", + "SPAWNENEMIES", NULL }; diff --git a/src/doomstat.h b/src/doomstat.h index 7d6839e52..a1c347b62 100644 --- a/src/doomstat.h +++ b/src/doomstat.h @@ -411,6 +411,8 @@ enum GameTypeRules GTR_PITYSHIELD = 1<<14, // Award pity shield GTR_DEATHPENALTY = 1<<15, // Death score penalty GTR_NOSPECTATORSPAWN = 1<<16, // For use with GTR_SPECTATORS - spawn in the map instead of with the spectators + GTR_EMERALDHUNT = 1<<17, // Emerald Hunt + GTR_SPAWNENEMIES = 1<<18, // Spawn enemies }; // String names for gametypes diff --git a/src/g_game.c b/src/g_game.c index 07a6034bb..1974c271f 100644 --- a/src/g_game.c +++ b/src/g_game.c @@ -3075,14 +3075,14 @@ const char *Gametype_ConstantNames[NUMGAMETYPES] = }; // Game type rules -INT16 gametypedefaultrules[NUMGAMETYPES] = +UINT32 gametypedefaultrules[NUMGAMETYPES] = { // Co-op - GTR_PLATFORM|GTR_LIVES|GTR_CHASECAM, + GTR_PLATFORM|GTR_LIVES|GTR_CHASECAM|GTR_EMERALDHUNT|GTR_SPAWNENEMIES, // Competition - GTR_PLATFORM|GTR_LIVES|GTR_RACE|GTR_CHASECAM, + GTR_PLATFORM|GTR_LIVES|GTR_RACE|GTR_CHASECAM|GTR_SPAWNENEMIES, // Race - GTR_PLATFORM|GTR_RACE|GTR_CHASECAM, + GTR_PLATFORM|GTR_RACE|GTR_CHASECAM|GTR_SPAWNENEMIES, // Match GTR_RINGSLINGER|GTR_SPECTATORS|GTR_TIMELIMIT|GTR_EMERALDS|GTR_PITYSHIELD|GTR_DEATHPENALTY, @@ -3116,7 +3116,6 @@ void G_SetGametype(INT16 gtype) // INT16 G_AddGametype(UINT32 rules) { - INT32 i; INT16 newgtype = gametypecount; gametypecount++; diff --git a/src/g_game.h b/src/g_game.h index e2eea52c1..81998b6e6 100644 --- a/src/g_game.h +++ b/src/g_game.h @@ -201,7 +201,7 @@ ATTRNORETURN void FUNCNORETURN G_StopMetalRecording(boolean kill); void G_StopDemo(void); boolean G_CheckDemoStatus(void); -extern INT16 gametypedefaultrules[NUMGAMETYPES]; +extern UINT32 gametypedefaultrules[NUMGAMETYPES]; extern UINT32 gametypetol[NUMGAMETYPES]; void G_SetGametype(INT16 gametype); diff --git a/src/p_mobj.c b/src/p_mobj.c index 193746db8..1913ef91f 100644 --- a/src/p_mobj.c +++ b/src/p_mobj.c @@ -11682,7 +11682,7 @@ You should think about modifying the deathmatch starts to take full advantage of if (i == MT_EMERHUNT) { // Emerald Hunt is Coop only. - if (gametype != GT_COOP) + if (!(gametyperules & GTR_EMERALDHUNT)) return; ss = R_PointInSubsector(mthing->x << FRACBITS, mthing->y << FRACBITS); @@ -11708,7 +11708,7 @@ You should think about modifying the deathmatch starts to take full advantage of runemeraldmanager = true; } - if (!G_PlatformGametype()) // No enemies in match or CTF modes + if (!(gametyperules & GTR_SPAWNENEMIES)) // No enemies in match or CTF modes if ((mobjinfo[i].flags & MF_ENEMY) || (mobjinfo[i].flags & MF_BOSS)) return; From 7768e2c7f9ff46fcd82bf7bbd3e270fec34b29d2 Mon Sep 17 00:00:00 2001 From: Jaime Passos Date: Wed, 18 Dec 2019 15:14:24 -0300 Subject: [PATCH 255/746] More spectator tweaks --- src/p_mobj.c | 6 +++++- src/st_stuff.c | 36 +++++++++++++++++++----------------- 2 files changed, 24 insertions(+), 18 deletions(-) diff --git a/src/p_mobj.c b/src/p_mobj.c index 1913ef91f..12409a18a 100644 --- a/src/p_mobj.c +++ b/src/p_mobj.c @@ -11249,8 +11249,12 @@ void P_SpawnPlayer(INT32 playernum) else { p->outofcoop = false; + p->spectator = false; if (netgame && p->jointime < 1) - p->spectator = true; + { + // Averted by GTR_NOSPECTATORSPAWN. + p->spectator = (gametyperules & GTR_NOSPECTATORSPAWN) ? false : true; + } else if (multiplayer && !netgame) { // If you're in a team game and you don't have a team assigned yet... diff --git a/src/st_stuff.c b/src/st_stuff.c index 54bd36ac0..1c9b4614e 100644 --- a/src/st_stuff.c +++ b/src/st_stuff.c @@ -2205,31 +2205,33 @@ static void ST_drawTextHUD(void) textHUDdraw(M_GetText("\x82""Wait for the stage to end...")) else if (G_PlatformGametype()) { - if (gametype == GT_COOP - && stplyr->lives <= 0 - && cv_cooplives.value == 2 - && (netgame || multiplayer)) + if (gametype == GT_COOP) { - INT32 i; - for (i = 0; i < MAXPLAYERS; i++) + if (stplyr->lives <= 0 + && cv_cooplives.value == 2 + && (netgame || multiplayer)) { - if (!playeringame[i]) - continue; + INT32 i; + for (i = 0; i < MAXPLAYERS; i++) + { + if (!playeringame[i]) + continue; - if (&players[i] == stplyr) - continue; + if (&players[i] == stplyr) + continue; - if (players[i].lives > 1) - break; - } + if (players[i].lives > 1) + break; + } - if (i != MAXPLAYERS) - textHUDdraw(M_GetText("You'll steal a life on respawn...")) + if (i != MAXPLAYERS) + textHUDdraw(M_GetText("You'll steal a life on respawn...")) + else + textHUDdraw(M_GetText("Wait to respawn...")) + } else textHUDdraw(M_GetText("Wait to respawn...")) } - else - textHUDdraw(M_GetText("Wait to respawn...")) } else if (G_GametypeHasSpectators()) textHUDdraw(M_GetText("\x82""FIRE:""\x80 Enter game")) From 7c3cde4564c84475514689d0998e75d8e08db12e Mon Sep 17 00:00:00 2001 From: Jaime Passos Date: Wed, 18 Dec 2019 15:23:41 -0300 Subject: [PATCH 256/746] How did I mess this up? --- src/g_game.c | 2 +- src/p_mobj.c | 1 - 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/src/g_game.c b/src/g_game.c index 1974c271f..fe4c93de9 100644 --- a/src/g_game.c +++ b/src/g_game.c @@ -3120,7 +3120,7 @@ INT16 G_AddGametype(UINT32 rules) gametypecount++; // Set gametype rules. - gametypedefaultrules[newgtype] = gametypecount; + gametypedefaultrules[newgtype] = rules; Gametype_Names[newgtype] = "???"; // Update gametype_cons_t accordingly. diff --git a/src/p_mobj.c b/src/p_mobj.c index 12409a18a..8c5497e26 100644 --- a/src/p_mobj.c +++ b/src/p_mobj.c @@ -11249,7 +11249,6 @@ void P_SpawnPlayer(INT32 playernum) else { p->outofcoop = false; - p->spectator = false; if (netgame && p->jointime < 1) { // Averted by GTR_NOSPECTATORSPAWN. From 94f2b8f9709d1e15fc4a6edb60c78c14a196d8b2 Mon Sep 17 00:00:00 2001 From: Jaime Passos Date: Wed, 18 Dec 2019 15:41:03 -0300 Subject: [PATCH 257/746] Fix warnings --- src/dehacked.c | 19 ++++++++----------- src/g_game.c | 10 +++++----- src/g_game.h | 6 +++--- 3 files changed, 16 insertions(+), 19 deletions(-) diff --git a/src/dehacked.c b/src/dehacked.c index 7e584cbf8..b62f0cfbe 100644 --- a/src/dehacked.c +++ b/src/dehacked.c @@ -1140,7 +1140,6 @@ static void readgametype(MYFILE *f, char *gtname) UINT8 newgtleftcolor = 0; UINT8 newgtrightcolor = 0; char gtdescription[441]; - const char *gtnamestring; do { @@ -1254,9 +1253,7 @@ static void readgametype(MYFILE *f, char *gtname) G_SetGametypeDescription(newgtidx, gtdescription, newgtleftcolor, newgtrightcolor); // Write the new gametype name. - gtnamestring = Z_Malloc(MAXLINELEN, PU_STATIC, NULL); - memcpy((void *)gtnamestring, gtname, MAXLINELEN); - Gametype_Names[newgtidx] = gtnamestring; + Gametype_Names[newgtidx] = Z_StrDup((const char *)gtname); // Update gametype_cons_t accordingly. G_UpdateGametypeSelections(); @@ -4506,23 +4503,23 @@ static void DEH_LoadDehackedFile(MYFILE *f, boolean mainfile) // Get the gametype name from textline // instead of word2, so that gametype names // aren't allcaps - INT32 i; - for (i = 0; i < MAXLINELEN; i++) + INT32 c; + for (c = 0; c < MAXLINELEN; c++) { - if (textline[i] == '\0') + if (textline[c] == '\0') break; - if (textline[i] == ' ') + if (textline[c] == ' ') { - char *gtname = (textline+i+1); + char *gtname = (textline+c+1); if (gtname) { // remove funny characters INT32 j; - for (j = 0; j < (MAXLINELEN - i); j++) + for (j = 0; j < (MAXLINELEN - c); j++) { if (gtname[j] == '\0') break; - if (gtname[j] < 32 || gtname[j] > 127) + if (gtname[j] < 32) gtname[j] = '\0'; } readgametype(f, gtname); diff --git a/src/g_game.c b/src/g_game.c index fe4c93de9..aa1d2a174 100644 --- a/src/g_game.c +++ b/src/g_game.c @@ -3152,9 +3152,9 @@ void G_UpdateGametypeSelections(void) // Set a description for the specified gametype. // (Level platter) // -void G_SetGametypeDescription(INT16 gtype, char *description, UINT8 leftcolor, UINT8 rightcolor) +void G_SetGametypeDescription(INT16 gtype, char *descriptiontext, UINT8 leftcolor, UINT8 rightcolor) { - strncpy(gametypedesc[gtype].notes, description, 441); + strncpy(gametypedesc[gtype].notes, descriptiontext, 441); gametypedesc[gtype].col[0] = leftcolor; gametypedesc[gtype].col[1] = rightcolor; } @@ -3194,9 +3194,9 @@ void G_AddTOL(UINT32 newtol, const char *tolname) // // Assigns a type of level to a gametype. // -void G_AddGametypeTOL(INT16 gametype, UINT32 newtol) +void G_AddGametypeTOL(INT16 gtype, UINT32 newtol) { - gametypetol[gametype] = newtol; + gametypetol[gtype] = newtol; } // @@ -3342,7 +3342,7 @@ INT16 G_TOLFlag(INT32 pgametype) * has those flags. * \author Graue */ -static INT16 RandMap(INT16 tolflags, INT16 pprevmap) +static INT16 RandMap(UINT32 tolflags, INT16 pprevmap) { INT16 *okmaps = Z_Malloc(NUMMAPS * sizeof(INT16), PU_STATIC, NULL); INT32 numokmaps = 0; diff --git a/src/g_game.h b/src/g_game.h index 81998b6e6..6b29ef836 100644 --- a/src/g_game.h +++ b/src/g_game.h @@ -206,10 +206,10 @@ extern UINT32 gametypetol[NUMGAMETYPES]; void G_SetGametype(INT16 gametype); INT16 G_AddGametype(UINT32 rules); -void G_UpdateGametypeSelections(); +void G_UpdateGametypeSelections(void); void G_AddTOL(UINT32 newtol, const char *tolname); -void G_AddGametypeTOL(INT16 gametype, UINT32 newtol); -void G_SetGametypeDescription(INT16 gtype, char *description, UINT8 leftcolor, UINT8 rightcolor); +void G_AddGametypeTOL(INT16 gtype, UINT32 newtol); +void G_SetGametypeDescription(INT16 gtype, char *descriptiontext, UINT8 leftcolor, UINT8 rightcolor); INT32 G_GetGametypeByName(const char *gametypestr); boolean G_IsSpecialStage(INT32 mapnum); From 5b0a094f67fe881934f788b40702c6e186be0e5e Mon Sep 17 00:00:00 2001 From: Jaime Passos Date: Wed, 18 Dec 2019 16:00:02 -0300 Subject: [PATCH 258/746] TOL stuff --- src/dehacked.c | 9 ++++++++- src/doomstat.h | 1 + src/g_game.c | 2 +- 3 files changed, 10 insertions(+), 2 deletions(-) diff --git a/src/dehacked.c b/src/dehacked.c index b62f0cfbe..e3685e77c 100644 --- a/src/dehacked.c +++ b/src/dehacked.c @@ -591,6 +591,11 @@ static void readfreeslots(MYFILE *f) } else CONS_Alert(CONS_WARNING, "Ran out of free SPR2 slots!\n"); } + else if (fastcmp(type, "TOL")) + { + G_AddTOL(lastcustomtol, word); + lastcustomtol <<= 1; + } else deh_warning("Freeslots: unknown enum class '%s' for '%s_%s'", type, type, word); } @@ -1097,6 +1102,8 @@ static void readsprite2(MYFILE *f, INT32 num) } INT32 numtolinfo = NUMBASETOL; +UINT32 lastcustomtol = (TOL_XMAS << 1); + tolinfo_t TYPEOFLEVEL[NUMMAXTOL] = { {"SOLO",TOL_SP}, {"SP",TOL_SP}, @@ -1232,7 +1239,7 @@ static void readgametype(MYFILE *f, char *gtname) tmp = strtok(word2,","); do { for (i = 0; TYPEOFLEVEL[i].name; i++) - if (fastcmp(tmp, TYPEOFLEVEL[i].name)) + if (fasticmp(tmp, TYPEOFLEVEL[i].name)) break; if (!TYPEOFLEVEL[i].name) deh_warning("readgametype %s: unknown typeoflevel flag %s\n", gtname, tmp); diff --git a/src/doomstat.h b/src/doomstat.h index a1c347b62..daf36647c 100644 --- a/src/doomstat.h +++ b/src/doomstat.h @@ -453,6 +453,7 @@ typedef struct } tolinfo_t; extern tolinfo_t TYPEOFLEVEL[NUMMAXTOL]; extern INT32 numtolinfo; +extern UINT32 lastcustomtol; extern tic_t totalplaytime; diff --git a/src/g_game.c b/src/g_game.c index aa1d2a174..a2f95b5d9 100644 --- a/src/g_game.c +++ b/src/g_game.c @@ -3181,7 +3181,7 @@ UINT32 gametypetol[NUMGAMETYPES] = // void G_AddTOL(UINT32 newtol, const char *tolname) { - TYPEOFLEVEL[numtolinfo].name = tolname; + TYPEOFLEVEL[numtolinfo].name = Z_StrDup(tolname); TYPEOFLEVEL[numtolinfo].flag = newtol; numtolinfo++; From e3584e82302da82a18c372fa23789fb55979b382 Mon Sep 17 00:00:00 2001 From: Jaime Passos Date: Wed, 18 Dec 2019 16:52:05 -0300 Subject: [PATCH 259/746] GTR_ALLOWEXIT --- src/dehacked.c | 1 + src/doomstat.h | 1 + src/g_game.c | 6 +++--- src/p_spec.c | 2 +- 4 files changed, 6 insertions(+), 4 deletions(-) diff --git a/src/dehacked.c b/src/dehacked.c index e3685e77c..9b2c07838 100644 --- a/src/dehacked.c +++ b/src/dehacked.c @@ -8811,6 +8811,7 @@ static const char *const GAMETYPERULE_LIST[] = { "NOSPECTATORSPAWN", "EMERALDHUNT", "SPAWNENEMIES", + "ALLOWEXIT", NULL }; diff --git a/src/doomstat.h b/src/doomstat.h index daf36647c..dc551536e 100644 --- a/src/doomstat.h +++ b/src/doomstat.h @@ -413,6 +413,7 @@ enum GameTypeRules GTR_NOSPECTATORSPAWN = 1<<16, // For use with GTR_SPECTATORS - spawn in the map instead of with the spectators GTR_EMERALDHUNT = 1<<17, // Emerald Hunt GTR_SPAWNENEMIES = 1<<18, // Spawn enemies + GTR_ALLOWEXIT = 1<<19, // Allow exit sectors }; // String names for gametypes diff --git a/src/g_game.c b/src/g_game.c index a2f95b5d9..4110bd37e 100644 --- a/src/g_game.c +++ b/src/g_game.c @@ -3078,11 +3078,11 @@ const char *Gametype_ConstantNames[NUMGAMETYPES] = UINT32 gametypedefaultrules[NUMGAMETYPES] = { // Co-op - GTR_PLATFORM|GTR_LIVES|GTR_CHASECAM|GTR_EMERALDHUNT|GTR_SPAWNENEMIES, + GTR_PLATFORM|GTR_LIVES|GTR_CHASECAM|GTR_EMERALDHUNT|GTR_SPAWNENEMIES|GTR_ALLOWEXIT, // Competition - GTR_PLATFORM|GTR_LIVES|GTR_RACE|GTR_CHASECAM|GTR_SPAWNENEMIES, + GTR_PLATFORM|GTR_LIVES|GTR_RACE|GTR_CHASECAM|GTR_SPAWNENEMIES|GTR_ALLOWEXIT, // Race - GTR_PLATFORM|GTR_RACE|GTR_CHASECAM|GTR_SPAWNENEMIES, + GTR_PLATFORM|GTR_RACE|GTR_CHASECAM|GTR_SPAWNENEMIES|GTR_ALLOWEXIT, // Match GTR_RINGSLINGER|GTR_SPECTATORS|GTR_TIMELIMIT|GTR_EMERALDS|GTR_PITYSHIELD|GTR_DEATHPENALTY, diff --git a/src/p_spec.c b/src/p_spec.c index 161d73e0e..2aa91e95e 100644 --- a/src/p_spec.c +++ b/src/p_spec.c @@ -4678,7 +4678,7 @@ DoneSection2: } case 2: // Special stage GOAL sector / Exit Sector / CTF Flag Return - if (player->bot || !G_PlatformGametype()) + if (player->bot || !(gametyperules & GTR_ALLOWEXIT)) break; if (!(maptol & TOL_NIGHTS) && G_IsSpecialStage(gamemap) && player->nightstime > 6) { From 5f73d4861490ad336d8ee27042aea55790574740 Mon Sep 17 00:00:00 2001 From: Jaime Passos Date: Wed, 18 Dec 2019 17:13:05 -0300 Subject: [PATCH 260/746] Some sort of intermission tally support. --- src/dehacked.c | 119 ++++++++++++++++++++++++++++++++----------------- src/doomstat.h | 1 + src/g_game.c | 16 +++---- src/y_inter.c | 5 ++- src/y_inter.h | 1 + 5 files changed, 91 insertions(+), 51 deletions(-) diff --git a/src/dehacked.c b/src/dehacked.c index 9b2c07838..4bf0f31ae 100644 --- a/src/dehacked.c +++ b/src/dehacked.c @@ -22,6 +22,7 @@ #include "m_menu.h" #include "m_misc.h" #include "f_finale.h" +#include "y_inter.h" #include "dehacked.h" #include "st_stuff.h" #include "i_system.h" @@ -1137,7 +1138,7 @@ static void readgametype(MYFILE *f, char *gtname) { char *s = Z_Malloc(MAXLINELEN, PU_STATIC, NULL); char *word; - char *word2; + char *word2, *word2lwr = NULL; char *tmp; INT32 i; @@ -1146,6 +1147,7 @@ static void readgametype(MYFILE *f, char *gtname) UINT32 newgttol = 0; UINT8 newgtleftcolor = 0; UINT8 newgtrightcolor = 0; + int newgtinttype = 0; char gtdescription[441]; do @@ -1201,7 +1203,12 @@ static void readgametype(MYFILE *f, char *gtname) word2 = strtok(NULL, " = "); if (word2) + { + if (!word2lwr) + word2lwr = Z_Malloc(MAXLINELEN, PU_STATIC, NULL); + strcpy(word2lwr, word2); strupr(word2); + } else break; @@ -1229,10 +1236,15 @@ static void readgametype(MYFILE *f, char *gtname) // Level platter newgtrightcolor = (UINT8)get_number(word2); } + else if (fastcmp(word, "INTERMISSIONTYPE")) + { + // Case sensitive + newgtinttype = (int)get_number(word2lwr); + } else if (fastcmp(word, "TYPEOFLEVEL")) { if (i) // it's just a number - newgttol = (UINT16)i; + newgttol = (UINT32)i; else { UINT16 tol = 0; @@ -1253,11 +1265,14 @@ static void readgametype(MYFILE *f, char *gtname) } } while (!myfeof(f)); // finish when the line is empty Z_Free(s); + if (word2lwr) + Z_Free(word2lwr); // Add the new gametype newgtidx = G_AddGametype(newgtrules); G_AddGametypeTOL(newgtidx, newgttol); G_SetGametypeDescription(newgtidx, gtdescription, newgtleftcolor, newgtrightcolor); + intermissiontypes[newgtidx] = newgtinttype; // Write the new gametype name. Gametype_Names[newgtidx] = Z_StrDup((const char *)gtname); @@ -1535,7 +1550,7 @@ static void readlevelheader(MYFILE *f, INT32 num) else if (fastcmp(word, "TYPEOFLEVEL")) { if (i) // it's just a number - mapheaderinfo[num-1]->typeoflevel = (UINT16)i; + mapheaderinfo[num-1]->typeoflevel = (UINT32)i; else { UINT16 tol = 0; @@ -8812,6 +8827,7 @@ static const char *const GAMETYPERULE_LIST[] = { "EMERALDHUNT", "SPAWNENEMIES", "ALLOWEXIT", + "ROUNDENDMESSAGE", NULL }; @@ -9230,20 +9246,6 @@ struct { {"tr_trans90",tr_trans90}, {"NUMTRANSMAPS",NUMTRANSMAPS}, - // Type of levels - {"TOL_SP",TOL_SP}, - {"TOL_COOP",TOL_COOP}, - {"TOL_COMPETITION",TOL_COMPETITION}, - {"TOL_RACE",TOL_RACE}, - {"TOL_MATCH",TOL_MATCH}, - {"TOL_TAG",TOL_TAG}, - {"TOL_CTF",TOL_CTF}, - {"TOL_2D",TOL_2D}, - {"TOL_MARIO",TOL_MARIO}, - {"TOL_NIGHTS",TOL_NIGHTS}, - {"TOL_ERZ3",TOL_ERZ3}, - {"TOL_XMAS",TOL_XMAS}, - // Level flags {"LF_SCRIPTISFILE",LF_SCRIPTISFILE}, {"LF_SPEEDMUSIC",LF_SPEEDMUSIC}, @@ -9426,16 +9428,16 @@ struct { {"DMG_CANHURTSELF",DMG_CANHURTSELF}, {"DMG_DEATHMASK",DMG_DEATHMASK}, - // Gametypes, for use with global var "gametype" - // Left them here just in case?? - {"GT_COOP",GT_COOP}, - {"GT_COMPETITION",GT_COMPETITION}, - {"GT_RACE",GT_RACE}, - {"GT_MATCH",GT_MATCH}, - {"GT_TEAMMATCH",GT_TEAMMATCH}, - {"GT_TAG",GT_TAG}, - {"GT_HIDEANDSEEK",GT_HIDEANDSEEK}, - {"GT_CTF",GT_CTF}, + // Intermission types + {"int_none",int_none}, + {"int_coop",int_coop}, + {"int_match",int_match}, + {"int_teammatch",int_teammatch}, + //{"int_tag",int_tag}, + {"int_ctf",int_ctf}, + {"int_spec",int_spec}, + {"int_race",int_race}, + {"int_comp",int_comp}, // Jingles (jingletype_t) {"JT_NONE",JT_NONE}, @@ -9728,7 +9730,7 @@ struct { }; static mobjtype_t get_mobjtype(const char *word) -{ // Returns the vlaue of MT_ enumerations +{ // Returns the value of MT_ enumerations mobjtype_t i; if (*word >= '0' && *word <= '9') return atoi(word); @@ -9895,7 +9897,7 @@ static INT16 get_gametype(const char *word) } static powertype_t get_power(const char *word) -{ // Returns the vlaue of pw_ enumerations +{ // Returns the value of pw_ enumerations powertype_t i; if (*word >= '0' && *word <= '9') return atoi(word); @@ -10057,19 +10059,6 @@ static fixed_t find_const(const char **rword) free(word); return 0; } - else if (fastncmp("GTR_", word, 4)) { - char *p = word+4; - for (i = 0; GAMETYPERULE_LIST[i]; i++) - if (fastcmp(p, GAMETYPERULE_LIST[i])) { - free(word); - return (1< Date: Wed, 18 Dec 2019 18:09:56 -0300 Subject: [PATCH 261/746] Intermission HUD hook for Lua --- src/lua_hud.h | 6 +++++- src/lua_hudlib.c | 30 ++++++++++++++++++++++++++++++ src/y_inter.c | 26 +++++++++++++++++++++++++- 3 files changed, 60 insertions(+), 2 deletions(-) diff --git a/src/lua_hud.h b/src/lua_hud.h index abfbba441..396ca8988 100644 --- a/src/lua_hud.h +++ b/src/lua_hud.h @@ -33,6 +33,9 @@ enum hud { hud_coopemeralds, hud_tokens, hud_tabemblems, + // Intermission + hud_intermissiontally, + hud_intermissionmessages, hud_MAX }; @@ -43,4 +46,5 @@ boolean LUA_HudEnabled(enum hud option); void LUAh_GameHUD(player_t *stplyr); void LUAh_ScoresHUD(void); void LUAh_TitleHUD(void); -void LUAh_TitleCardHUD(player_t *stplyr); +void LUAh_TitleCardHUD(player_t *stplayr); +void LUAh_IntermissionHUD(void); diff --git a/src/lua_hudlib.c b/src/lua_hudlib.c index a2f48c4ad..211c8a828 100644 --- a/src/lua_hudlib.c +++ b/src/lua_hudlib.c @@ -60,6 +60,9 @@ static const char *const hud_disable_options[] = { "coopemeralds", "tokens", "tabemblems", + + "intermissiontally", + "intermissionmessages", NULL}; enum hudinfo { @@ -92,12 +95,14 @@ static const char *const patch_opt[] = { enum hudhook { hudhook_game = 0, hudhook_scores, + hudhook_intermission, hudhook_title, hudhook_titlecard }; static const char *const hudhook_opt[] = { "game", "scores", + "intermission", "title", "titlecard", NULL}; @@ -1228,4 +1233,29 @@ void LUAh_TitleCardHUD(player_t *stplayr) hud_running = false; } +void LUAh_IntermissionHUD(void) +{ + if (!gL || !(hudAvailable & (1< Date: Wed, 18 Dec 2019 18:30:24 -0300 Subject: [PATCH 262/746] Fix lib_getenum. Also, adding gametypes also creates constant names for them. --- src/dehacked.c | 63 ++++++++++++++++++++++++++++++++++++++++---------- 1 file changed, 51 insertions(+), 12 deletions(-) diff --git a/src/dehacked.c b/src/dehacked.c index 4bf0f31ae..474ad2de3 100644 --- a/src/dehacked.c +++ b/src/dehacked.c @@ -1140,6 +1140,7 @@ static void readgametype(MYFILE *f, char *gtname) char *word; char *word2, *word2lwr = NULL; char *tmp; + char *gtconst; INT32 i; INT16 newgtidx = 0; @@ -1277,6 +1278,53 @@ static void readgametype(MYFILE *f, char *gtname) // Write the new gametype name. Gametype_Names[newgtidx] = Z_StrDup((const char *)gtname); + // Write the constant name. + gtconst = Z_Malloc(strlen((const char *)gtname) + 3, PU_STATIC, NULL); + // Copy GT_ and the gametype name. + strcpy(gtconst, "GT_"); + strcat(gtconst, (const char *)gtname); + // Make uppercase. + strupr(gtconst); + // Remove characters. +#define REMOVECHAR(chr) \ + word = strchr(gtconst, chr); \ + while (word) \ + { \ + *word = '_'; \ + word = strchr(word, chr); \ + } + + // 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 + + // Finally, set the constant string. + Gametype_ConstantNames[newgtidx] = gtconst; + // Update gametype_cons_t accordingly. G_UpdateGametypeSelections(); @@ -10441,13 +10489,13 @@ static inline int lib_getenum(lua_State *L) return 0; } else if (fastncmp("GT_", word, 3)) { - p = word+3; + p = word; for (i = 0; Gametype_ConstantNames[i]; i++) if (fastcmp(p, Gametype_ConstantNames[i])) { - lua_pushinteger(L, ((lua_Integer)1< Date: Wed, 18 Dec 2019 18:39:59 -0300 Subject: [PATCH 263/746] GTR_NOTITLECARD --- src/dehacked.c | 1 + src/doomstat.h | 1 + src/g_game.c | 2 +- 3 files changed, 3 insertions(+), 1 deletion(-) diff --git a/src/dehacked.c b/src/dehacked.c index 474ad2de3..5309058c4 100644 --- a/src/dehacked.c +++ b/src/dehacked.c @@ -8876,6 +8876,7 @@ static const char *const GAMETYPERULE_LIST[] = { "SPAWNENEMIES", "ALLOWEXIT", "ROUNDENDMESSAGE", + "NOTITLECARD", NULL }; diff --git a/src/doomstat.h b/src/doomstat.h index d9c93553c..ffce0c814 100644 --- a/src/doomstat.h +++ b/src/doomstat.h @@ -415,6 +415,7 @@ enum GameTypeRules GTR_SPAWNENEMIES = 1<<18, // Spawn enemies GTR_ALLOWEXIT = 1<<19, // Allow exit sectors GTR_ROUNDENDMESSAGE = 1<<20, // Prints "The round has ended." into the console + GTR_NOTITLECARD = 1<<21, // Don't show the title card }; // String names for gametypes diff --git a/src/g_game.c b/src/g_game.c index 62b2eed82..005d37702 100644 --- a/src/g_game.c +++ b/src/g_game.c @@ -1809,7 +1809,7 @@ void G_StartTitleCard(void) // The title card has been disabled for this map. // Oh well. - if (mapheaderinfo[gamemap-1]->levelflags & LF_NOTITLECARD) + if ((mapheaderinfo[gamemap-1]->levelflags & LF_NOTITLECARD) || (gametyperules & GTR_NOTITLECARD)) { WipeStageTitle = false; return; From b8d47dbc60baa88b4748804facf3b061dd28816f Mon Sep 17 00:00:00 2001 From: Jaime Passos Date: Wed, 18 Dec 2019 18:50:04 -0300 Subject: [PATCH 264/746] Accept gametype rules in SOC by just their names as parameters. --- src/dehacked.c | 23 +++++++++++++++++++++-- 1 file changed, 21 insertions(+), 2 deletions(-) diff --git a/src/dehacked.c b/src/dehacked.c index 5309058c4..1ea3dd0c4 100644 --- a/src/dehacked.c +++ b/src/dehacked.c @@ -1134,6 +1134,7 @@ tolinfo_t TYPEOFLEVEL[NUMMAXTOL] = { }; // copypasted from readPlayer :sleep: +static const char *const GAMETYPERULE_LIST[]; static void readgametype(MYFILE *f, char *gtname) { char *s = Z_Malloc(MAXLINELEN, PU_STATIC, NULL); @@ -1141,7 +1142,7 @@ static void readgametype(MYFILE *f, char *gtname) char *word2, *word2lwr = NULL; char *tmp; char *gtconst; - INT32 i; + INT32 i, j; INT16 newgtidx = 0; UINT32 newgtrules = 0; @@ -1261,8 +1262,26 @@ static void readgametype(MYFILE *f, char *gtname) newgttol = tol; } } + // The SOC probably provided gametype rules as words, + // instead of using the RULES keyword. + // Like for example "NOSPECTATORSPAWN = 1". + // This is completely valid, and looks better anyway. else - deh_warning("readgametype %s: unknown word '%s'", gtname, word); + { + UINT32 wordgt = 0; + for (j = 0; GAMETYPERULE_LIST[j]; j++) + if (fastcmp(word, GAMETYPERULE_LIST[j])) { + if (!j) // GTR_PLATFORM + wordgt |= 1; + else + wordgt |= (1< Date: Wed, 18 Dec 2019 18:52:10 -0300 Subject: [PATCH 265/746] Fix comment --- src/dehacked.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/dehacked.c b/src/dehacked.c index 1ea3dd0c4..670a16e69 100644 --- a/src/dehacked.c +++ b/src/dehacked.c @@ -1264,7 +1264,7 @@ static void readgametype(MYFILE *f, char *gtname) } // The SOC probably provided gametype rules as words, // instead of using the RULES keyword. - // Like for example "NOSPECTATORSPAWN = 1". + // Like for example "NOSPECTATORSPAWN = TRUE". // This is completely valid, and looks better anyway. else { From eadb3dec9e4344e59cbbfe37a4d0b20a35c86ee2 Mon Sep 17 00:00:00 2001 From: Jaime Passos Date: Wed, 18 Dec 2019 18:59:47 -0300 Subject: [PATCH 266/746] Limits checking --- src/dehacked.c | 18 +++++++++++++++--- 1 file changed, 15 insertions(+), 3 deletions(-) diff --git a/src/dehacked.c b/src/dehacked.c index 670a16e69..29dbd0b19 100644 --- a/src/dehacked.c +++ b/src/dehacked.c @@ -594,8 +594,13 @@ static void readfreeslots(MYFILE *f) } else if (fastcmp(type, "TOL")) { - G_AddTOL(lastcustomtol, word); - lastcustomtol <<= 1; + if (lastcustomtol > 31) + CONS_Alert(CONS_WARNING, "Ran out of free typeoflevel slots!\n"); + else + { + G_AddTOL((1< Date: Wed, 18 Dec 2019 19:26:45 -0300 Subject: [PATCH 267/746] Ringslinger tweaks --- src/d_netcmd.c | 6 +++--- src/dehacked.c | 5 ++++- src/doomstat.h | 5 ++++- src/g_game.c | 10 +++++----- src/hu_stuff.c | 2 +- src/p_inter.c | 6 +++--- src/st_stuff.c | 2 +- 7 files changed, 21 insertions(+), 15 deletions(-) diff --git a/src/d_netcmd.c b/src/d_netcmd.c index 959ed875f..67a230289 100644 --- a/src/d_netcmd.c +++ b/src/d_netcmd.c @@ -3696,7 +3696,7 @@ void ItemFinder_OnChange(void) static void PointLimit_OnChange(void) { // Don't allow pointlimit in Single Player/Co-Op/Race! - if (server && Playing() && G_PlatformGametype()) + if (server && Playing() && !(gametyperules & GTR_POINTLIMIT)) { if (cv_pointlimit.value) CV_StealthSetValue(&cv_pointlimit, 0); @@ -3859,7 +3859,7 @@ UINT32 timelimitintics = 0; static void TimeLimit_OnChange(void) { // Don't allow timelimit in Single Player/Co-Op/Race! - if (server && Playing() && cv_timelimit.value != 0 && G_PlatformGametype()) + if (server && Playing() && cv_timelimit.value != 0 && !(gametyperules & GTR_TIMELIMIT)) { CV_SetValue(&cv_timelimit, 0); return; @@ -3964,7 +3964,7 @@ void D_GameTypeChanged(INT32 lastgametype) // reset timelimit and pointlimit in race/coop, prevent stupid cheats if (server) { - if (G_PlatformGametype()) + if (!(gametyperules & GTR_POINTLIMIT)) { if (cv_timelimit.value) CV_SetValue(&cv_timelimit, 0); diff --git a/src/dehacked.c b/src/dehacked.c index 29dbd0b19..abd0cad7c 100644 --- a/src/dehacked.c +++ b/src/dehacked.c @@ -8894,7 +8894,7 @@ static const char *const GAMETYPERULE_LIST[] = { "LIVES", "RACE", "CHASECAM", - "TIMELIMIT", + "\x01", // 1<<8, empty "HIDETIME", "HIDETIMEFROZEN", "BLINDFOLDED", @@ -8908,6 +8908,9 @@ static const char *const GAMETYPERULE_LIST[] = { "ALLOWEXIT", "ROUNDENDMESSAGE", "NOTITLECARD", + "POINTLIMIT", + "TIMELIMIT", + "OVERTIME", NULL }; diff --git a/src/doomstat.h b/src/doomstat.h index ffce0c814..de0058766 100644 --- a/src/doomstat.h +++ b/src/doomstat.h @@ -402,7 +402,7 @@ enum GameTypeRules // flexibility! Those will replace some straight-up gametype checks scattered around the source code! GTR_CHASECAM = 1<<7, // Prefer chasecam at map load (All platform gametypes) - GTR_TIMELIMIT = 1<<8, // Ringslinger time limit (Tag and Hide and Seek) + // 1<<8, empty GTR_HIDETIME = 1<<9, // Tag and Hide and Seek GTR_HIDETIMEFROZEN = 1<<10, // Hide and Seek, but not Tag GTR_BLINDFOLDED = 1<<11, // Blindfolded view (Tag and Hide and Seek) @@ -416,6 +416,9 @@ enum GameTypeRules GTR_ALLOWEXIT = 1<<19, // Allow exit sectors GTR_ROUNDENDMESSAGE = 1<<20, // Prints "The round has ended." into the console GTR_NOTITLECARD = 1<<21, // Don't show the title card + GTR_POINTLIMIT = 1<<22, // Ringslinger point limit + GTR_TIMELIMIT = 1<<23, // Ringslinger time limit + GTR_OVERTIME = 1<<24, // Allow overtime }; // String names for gametypes diff --git a/src/g_game.c b/src/g_game.c index 005d37702..443ea69a7 100644 --- a/src/g_game.c +++ b/src/g_game.c @@ -3085,17 +3085,17 @@ UINT32 gametypedefaultrules[NUMGAMETYPES] = GTR_PLATFORM|GTR_RACE|GTR_CHASECAM|GTR_SPAWNENEMIES|GTR_ALLOWEXIT|GTR_ROUNDENDMESSAGE, // Match - GTR_RINGSLINGER|GTR_SPECTATORS|GTR_TIMELIMIT|GTR_EMERALDS|GTR_PITYSHIELD|GTR_DEATHPENALTY|GTR_ROUNDENDMESSAGE, + GTR_RINGSLINGER|GTR_SPECTATORS|GTR_POINTLIMIT|GTR_TIMELIMIT|GTR_EMERALDS|GTR_PITYSHIELD|GTR_DEATHPENALTY|GTR_ROUNDENDMESSAGE, // Team Match - GTR_RINGSLINGER|GTR_TEAMS|GTR_SPECTATORS|GTR_TIMELIMIT|GTR_PITYSHIELD|GTR_ROUNDENDMESSAGE, + GTR_RINGSLINGER|GTR_TEAMS|GTR_POINTLIMIT|GTR_SPECTATORS|GTR_TIMELIMIT|GTR_PITYSHIELD|GTR_ROUNDENDMESSAGE, // Tag - GTR_RINGSLINGER|GTR_TAG|GTR_SPECTATORS|GTR_TIMELIMIT|GTR_HIDETIME|GTR_BLINDFOLDED|GTR_ROUNDENDMESSAGE, + GTR_RINGSLINGER|GTR_TAG|GTR_SPECTATORS|GTR_POINTLIMIT|GTR_TIMELIMIT|GTR_HIDETIME|GTR_BLINDFOLDED|GTR_ROUNDENDMESSAGE, // Hide and Seek - GTR_RINGSLINGER|GTR_TAG|GTR_SPECTATORS|GTR_TIMELIMIT|GTR_HIDETIME|GTR_BLINDFOLDED|GTR_ROUNDENDMESSAGE, + GTR_RINGSLINGER|GTR_TAG|GTR_SPECTATORS|GTR_POINTLIMIT||GTR_TIMELIMIT|GTR_HIDETIME|GTR_BLINDFOLDED|GTR_ROUNDENDMESSAGE, // CTF - GTR_RINGSLINGER|GTR_TEAMS|GTR_SPECTATORS|GTR_TIMELIMIT|GTR_EMERALDS|GTR_TEAMFLAGS|GTR_PITYSHIELD|GTR_ROUNDENDMESSAGE, + GTR_RINGSLINGER|GTR_TEAMS|GTR_SPECTATORS|GTR_POINTLIMIT|GTR_TIMELIMIT|GTR_EMERALDS|GTR_TEAMFLAGS|GTR_PITYSHIELD|GTR_ROUNDENDMESSAGE, }; // diff --git a/src/hu_stuff.c b/src/hu_stuff.c index 8cbfa77d3..bcad6ebef 100644 --- a/src/hu_stuff.c +++ b/src/hu_stuff.c @@ -3026,7 +3026,7 @@ static void HU_DrawRankings(void) // draw the current gametype in the lower right HU_drawGametype(); - if (!G_PlatformGametype()) + if (gametyperules & GTR_POINTLIMIT) { if (cv_timelimit.value && timelimitintics > 0) { diff --git a/src/p_inter.c b/src/p_inter.c index 21c3d4049..1f2390de0 100644 --- a/src/p_inter.c +++ b/src/p_inter.c @@ -2093,7 +2093,7 @@ void P_CheckTimeLimit(void) if (!(multiplayer || netgame)) return; - if (G_PlatformGametype()) + if (!(gametyperules & GTR_TIMELIMIT)) return; if (leveltime < timelimitintics) @@ -2124,7 +2124,7 @@ void P_CheckTimeLimit(void) } //Optional tie-breaker for Match/CTF - else if (cv_overtime.value) + else if ((cv_overtime.value) && (gametyperules & GTR_OVERTIME)) { INT32 playerarray[MAXPLAYERS]; INT32 tempplayer = 0; @@ -2206,7 +2206,7 @@ void P_CheckPointLimit(void) if (!(multiplayer || netgame)) return; - if (G_PlatformGametype()) + if (!(gametyperules & GTR_POINTLIMIT)) return; // pointlimit is nonzero, check if it's been reached by this player diff --git a/src/st_stuff.c b/src/st_stuff.c index 1c9b4614e..4c3f57412 100644 --- a/src/st_stuff.c +++ b/src/st_stuff.c @@ -2638,7 +2638,7 @@ static void ST_overlayDrawer(void) } // If you are in overtime, put a big honkin' flashin' message on the screen. - if (G_RingSlingerGametype() && cv_overtime.value + if (((gametyperules & GTR_TIMELIMIT) && (gametyperules & GTR_OVERTIME)) && cv_overtime.value && (leveltime > (timelimitintics + TICRATE/2)) && cv_timelimit.value && (leveltime/TICRATE % 2 == 0)) V_DrawCenteredString(BASEVIDWIDTH/2, 184, V_PERPLAYER, M_GetText("OVERTIME!")); From 04ee98a1a179793835a799b285c4c03ac7148276 Mon Sep 17 00:00:00 2001 From: Jaime Passos Date: Wed, 18 Dec 2019 19:43:12 -0300 Subject: [PATCH 268/746] point limit/time limit --- src/d_netcmd.c | 13 +++++++++++++ src/d_netcmd.h | 5 ++++- src/dehacked.c | 26 ++++++++++++++++---------- 3 files changed, 33 insertions(+), 11 deletions(-) diff --git a/src/d_netcmd.c b/src/d_netcmd.c index 67a230289..aaaf33cb5 100644 --- a/src/d_netcmd.c +++ b/src/d_netcmd.c @@ -328,6 +328,10 @@ consvar_t cv_numlaps = {"numlaps", "4", CV_NETVAR|CV_CALL|CV_NOINIT, numlaps_con static CV_PossibleValue_t basenumlaps_cons_t[] = {{1, "MIN"}, {50, "MAX"}, {0, "Map default"}, {0, NULL}}; consvar_t cv_basenumlaps = {"basenumlaps", "Map default", CV_NETVAR|CV_CALL|CV_CHEAT, basenumlaps_cons_t, BaseNumLaps_OnChange, 0, NULL, NULL, 0, 0, NULL}; +// Point and time limits for every gametype +INT32 pointlimits[NUMGAMETYPES]; +INT32 timelimits[NUMGAMETYPES]; + // log elemental hazards -- not a netvar, is local to current player consvar_t cv_hazardlog = {"hazardlog", "Yes", 0, CV_YesNo, NULL, 0, NULL, NULL, 0, 0, NULL}; @@ -3951,6 +3955,15 @@ void D_GameTypeChanged(INT32 lastgametype) if (!cv_itemrespawntime.changed) CV_Set(&cv_itemrespawntime, cv_itemrespawntime.defaultvalue); // respawn normally break; + default: + if (!cv_timelimit.changed && !cv_pointlimit.changed) // user hasn't changed limits + { + CV_SetValue(&cv_timelimit, timelimits[gametype]); + CV_SetValue(&cv_pointlimit, pointlimits[gametype]); + } + if (!cv_itemrespawntime.changed) + CV_Set(&cv_itemrespawntime, cv_itemrespawntime.defaultvalue); // respawn normally + break; } } else if (!multiplayer && !netgame) diff --git a/src/d_netcmd.h b/src/d_netcmd.h index 8f857c6db..cd2efe2e3 100644 --- a/src/d_netcmd.h +++ b/src/d_netcmd.h @@ -60,9 +60,12 @@ extern consvar_t cv_flagtime; extern consvar_t cv_touchtag; extern consvar_t cv_hidetime; -extern consvar_t cv_friendlyfire; extern consvar_t cv_pointlimit; extern consvar_t cv_timelimit; +extern INT32 pointlimits[NUMGAMETYPES]; +extern INT32 timelimits[NUMGAMETYPES]; + +extern consvar_t cv_friendlyfire; extern consvar_t cv_numlaps; extern consvar_t cv_basenumlaps; extern UINT32 timelimitintics; diff --git a/src/dehacked.c b/src/dehacked.c index abd0cad7c..cbbbe8d77 100644 --- a/src/dehacked.c +++ b/src/dehacked.c @@ -1152,6 +1152,8 @@ static void readgametype(MYFILE *f, char *gtname) INT16 newgtidx = 0; UINT32 newgtrules = 0; UINT32 newgttol = 0; + INT32 newgtpointlimit = 0; + INT32 newgttimelimit = 0; UINT8 newgtleftcolor = 0; UINT8 newgtrightcolor = 0; int newgtinttype = 0; @@ -1223,31 +1225,31 @@ static void readgametype(MYFILE *f, char *gtname) word2[strlen(word2)-1] = '\0'; i = atoi(word2); + // Game type rules if (fastcmp(word, "RULES")) { - // Game type rules (GTR_) + // GTR_ newgtrules = (UINT32)get_number(word2); } + // Point and time limits + else if (fastcmp(word, "DEFAULTPOINTLIMIT")) + newgtpointlimit = (INT32)i; + else if (fastcmp(word, "DEFAULTTIMELIMIT")) + newgttimelimit = (INT32)i; + // Level platter else if (fastcmp(word, "HEADERCOLOR") || fastcmp(word, "HEADERCOLOUR")) - { - // Level platter newgtleftcolor = newgtrightcolor = (UINT8)get_number(word2); - } else if (fastcmp(word, "HEADERLEFTCOLOR") || fastcmp(word, "HEADERLEFTCOLOUR")) - { - // Level platter newgtleftcolor = (UINT8)get_number(word2); - } else if (fastcmp(word, "HEADERRIGHTCOLOR") || fastcmp(word, "HEADERRIGHTCOLOUR")) - { - // Level platter newgtrightcolor = (UINT8)get_number(word2); - } + // Type of intermission else if (fastcmp(word, "INTERMISSIONTYPE")) { // Case sensitive newgtinttype = (int)get_number(word2lwr); } + // Type of level else if (fastcmp(word, "TYPEOFLEVEL")) { if (i) // it's just a number @@ -1304,7 +1306,11 @@ static void readgametype(MYFILE *f, char *gtname) newgtidx = G_AddGametype(newgtrules); G_AddGametypeTOL(newgtidx, newgttol); G_SetGametypeDescription(newgtidx, gtdescription, newgtleftcolor, newgtrightcolor); + + // Not covered by G_AddGametype alone. intermissiontypes[newgtidx] = newgtinttype; + pointlimits[newgtidx] = newgtpointlimit; + timelimits[newgtidx] = newgttimelimit; // Write the new gametype name. Gametype_Names[newgtidx] = Z_StrDup((const char *)gtname); From d0e18444fbc5ba14119b0bfaf53a3e4a18b791e8 Mon Sep 17 00:00:00 2001 From: Jaime Passos Date: Wed, 18 Dec 2019 20:12:52 -0300 Subject: [PATCH 269/746] GTR_FRIENDLYFIRE, renamed GTR_HIDETIMEFROZEN, fixed other mistakes --- src/d_netcmd.c | 8 ++++---- src/d_netcmd.h | 5 +---- src/dehacked.c | 4 ++-- src/doomstat.h | 10 +++++++--- src/g_game.c | 2 +- src/p_inter.c | 12 ++++++------ src/st_stuff.c | 2 +- 7 files changed, 22 insertions(+), 21 deletions(-) diff --git a/src/d_netcmd.c b/src/d_netcmd.c index aaaf33cb5..158b1f802 100644 --- a/src/d_netcmd.c +++ b/src/d_netcmd.c @@ -2419,7 +2419,7 @@ static void Command_Teamchange_f(void) } //additional check for hide and seek. Don't allow change of status after hidetime ends. - if ((gametyperules & GTR_HIDETIMEFROZEN) && leveltime >= (hidetime * TICRATE)) + if ((gametyperules & GTR_HIDEFROZEN) && leveltime >= (hidetime * TICRATE)) { CONS_Alert(CONS_NOTICE, M_GetText("Hiding time expired; no Hide and Seek status changes allowed!\n")); return; @@ -2516,7 +2516,7 @@ static void Command_Teamchange2_f(void) } //additional check for hide and seek. Don't allow change of status after hidetime ends. - if ((gametyperules & GTR_HIDETIMEFROZEN) && leveltime >= (hidetime * TICRATE)) + if ((gametyperules & GTR_HIDEFROZEN) && leveltime >= (hidetime * TICRATE)) { CONS_Alert(CONS_NOTICE, M_GetText("Hiding time expired; no Hide and Seek status changes allowed!\n")); return; @@ -2645,7 +2645,7 @@ static void Command_ServerTeamChange_f(void) } //additional check for hide and seek. Don't allow change of status after hidetime ends. - if ((gametyperules & GTR_HIDETIMEFROZEN) && leveltime >= (hidetime * TICRATE)) + if ((gametyperules & GTR_HIDEFROZEN) && leveltime >= (hidetime * TICRATE)) { CONS_Alert(CONS_NOTICE, M_GetText("Hiding time expired; no Hide and Seek status changes allowed!\n")); return; @@ -2735,7 +2735,7 @@ static void Got_Teamchange(UINT8 **cp, INT32 playernum) } //no status changes after hidetime - if ((gametyperules & GTR_HIDETIMEFROZEN) && (leveltime >= (hidetime * TICRATE))) + if ((gametyperules & GTR_HIDEFROZEN) && (leveltime >= (hidetime * TICRATE))) error = true; //Make sure that the right team number is sent. Keep in mind that normal clients cannot change to certain teams in certain gametypes. diff --git a/src/d_netcmd.h b/src/d_netcmd.h index cd2efe2e3..8f857c6db 100644 --- a/src/d_netcmd.h +++ b/src/d_netcmd.h @@ -60,12 +60,9 @@ extern consvar_t cv_flagtime; extern consvar_t cv_touchtag; extern consvar_t cv_hidetime; +extern consvar_t cv_friendlyfire; extern consvar_t cv_pointlimit; extern consvar_t cv_timelimit; -extern INT32 pointlimits[NUMGAMETYPES]; -extern INT32 timelimits[NUMGAMETYPES]; - -extern consvar_t cv_friendlyfire; extern consvar_t cv_numlaps; extern consvar_t cv_basenumlaps; extern UINT32 timelimitintics; diff --git a/src/dehacked.c b/src/dehacked.c index cbbbe8d77..676d0e144 100644 --- a/src/dehacked.c +++ b/src/dehacked.c @@ -8900,9 +8900,9 @@ static const char *const GAMETYPERULE_LIST[] = { "LIVES", "RACE", "CHASECAM", - "\x01", // 1<<8, empty + "FRIENDLYFIRE", "HIDETIME", - "HIDETIMEFROZEN", + "HIDEFROZEN", "BLINDFOLDED", "EMERALDS", "TEAMFLAGS", diff --git a/src/doomstat.h b/src/doomstat.h index de0058766..459bfc88f 100644 --- a/src/doomstat.h +++ b/src/doomstat.h @@ -402,9 +402,9 @@ enum GameTypeRules // flexibility! Those will replace some straight-up gametype checks scattered around the source code! GTR_CHASECAM = 1<<7, // Prefer chasecam at map load (All platform gametypes) - // 1<<8, empty - GTR_HIDETIME = 1<<9, // Tag and Hide and Seek - GTR_HIDETIMEFROZEN = 1<<10, // Hide and Seek, but not Tag + GTR_FRIENDLYFIRE = 1<<8, // Always allow friendly fire + GTR_HIDETIME = 1<<9, // Hide time (Tag and Hide and Seek) + GTR_HIDEFROZEN = 1<<10, // Frozen after hide time (Hide and Seek, but not Tag) GTR_BLINDFOLDED = 1<<11, // Blindfolded view (Tag and Hide and Seek) GTR_EMERALDS = 1<<12, // Ringslinger emeralds (Match and CTF) GTR_TEAMFLAGS = 1<<13, // Gametype has team flags (CTF) @@ -425,6 +425,10 @@ enum GameTypeRules extern const char *Gametype_Names[NUMGAMETYPES]; extern const char *Gametype_ConstantNames[NUMGAMETYPES]; +// Point and time limits for every gametype +extern INT32 pointlimits[NUMGAMETYPES]; +extern INT32 timelimits[NUMGAMETYPES]; + enum TypeOfLevel { TOL_SP = 0x01, ///< Single Player diff --git a/src/g_game.c b/src/g_game.c index 443ea69a7..02b32bd48 100644 --- a/src/g_game.c +++ b/src/g_game.c @@ -3092,7 +3092,7 @@ UINT32 gametypedefaultrules[NUMGAMETYPES] = // Tag GTR_RINGSLINGER|GTR_TAG|GTR_SPECTATORS|GTR_POINTLIMIT|GTR_TIMELIMIT|GTR_HIDETIME|GTR_BLINDFOLDED|GTR_ROUNDENDMESSAGE, // Hide and Seek - GTR_RINGSLINGER|GTR_TAG|GTR_SPECTATORS|GTR_POINTLIMIT||GTR_TIMELIMIT|GTR_HIDETIME|GTR_BLINDFOLDED|GTR_ROUNDENDMESSAGE, + GTR_RINGSLINGER|GTR_TAG|GTR_SPECTATORS|GTR_POINTLIMIT|GTR_TIMELIMIT|GTR_HIDETIME|GTR_BLINDFOLDED|GTR_ROUNDENDMESSAGE, // CTF GTR_RINGSLINGER|GTR_TEAMS|GTR_SPECTATORS|GTR_POINTLIMIT|GTR_TIMELIMIT|GTR_EMERALDS|GTR_TEAMFLAGS|GTR_PITYSHIELD|GTR_ROUNDENDMESSAGE, diff --git a/src/p_inter.c b/src/p_inter.c index 1f2390de0..900435a99 100644 --- a/src/p_inter.c +++ b/src/p_inter.c @@ -3042,7 +3042,7 @@ static inline boolean P_TagDamage(mobj_t *target, mobj_t *inflictor, mobj_t *sou return false; // Ignore IT players shooting each other, unless friendlyfire is on. - if ((player->pflags & PF_TAGIT && !((cv_friendlyfire.value || (damagetype & DMG_CANHURTSELF)) && + if ((player->pflags & PF_TAGIT && !((cv_friendlyfire.value || (gametyperules & GTR_FRIENDLYFIRE) || (damagetype & DMG_CANHURTSELF)) && source && source->player && source->player->pflags & PF_TAGIT))) { if (inflictor->type == MT_LHRT && !(player->powers[pw_shield] & SH_NOSTACK)) @@ -3058,7 +3058,7 @@ static inline boolean P_TagDamage(mobj_t *target, mobj_t *inflictor, mobj_t *sou // Don't allow players on the same team to hurt one another, // unless cv_friendlyfire is on. - if (!(cv_friendlyfire.value || (damagetype & DMG_CANHURTSELF)) && (player->pflags & PF_TAGIT) == (source->player->pflags & PF_TAGIT)) + if (!(cv_friendlyfire.value || (gametyperules & GTR_FRIENDLYFIRE) || (damagetype & DMG_CANHURTSELF)) && (player->pflags & PF_TAGIT) == (source->player->pflags & PF_TAGIT)) { if (inflictor->type == MT_LHRT && !(player->powers[pw_shield] & SH_NOSTACK)) { @@ -3143,7 +3143,7 @@ static inline boolean P_PlayerHitsPlayer(mobj_t *target, mobj_t *inflictor, mobj return false; // In COOP/RACE, you can't hurt other players unless cv_friendlyfire is on - if (!cv_friendlyfire.value && (G_PlatformGametype())) + if (!(cv_friendlyfire.value || (gametyperules & GTR_FRIENDLYFIRE)) && (G_PlatformGametype())) { if (gametype == GT_COOP && inflictor->type == MT_LHRT && !(player->powers[pw_shield] & SH_NOSTACK)) // co-op only { @@ -3166,7 +3166,7 @@ static inline boolean P_PlayerHitsPlayer(mobj_t *target, mobj_t *inflictor, mobj { // Don't allow players on the same team to hurt one another, // unless cv_friendlyfire is on. - if (!cv_friendlyfire.value && target->player->ctfteam == source->player->ctfteam) + if (!(cv_friendlyfire.value || (gametyperules & GTR_FRIENDLYFIRE)) && target->player->ctfteam == source->player->ctfteam) { if (inflictor->type == MT_LHRT && !(player->powers[pw_shield] & SH_NOSTACK)) { @@ -3593,7 +3593,7 @@ boolean P_DamageMobj(mobj_t *target, mobj_t *inflictor, mobj_t *source, INT32 da { if (source == target) return false; // Don't hit yourself with your own paraloop, baka - if (source && source->player && !cv_friendlyfire.value + if (source && source->player && !(cv_friendlyfire.value || (gametyperules & GTR_FRIENDLYFIRE)) && (gametype == GT_COOP || (G_GametypeHasTeams() && player->ctfteam == source->player->ctfteam))) return false; // Don't run eachother over in special stages and team games and such @@ -3688,7 +3688,7 @@ boolean P_DamageMobj(mobj_t *target, mobj_t *inflictor, mobj_t *source, INT32 da // by friendly fire. Spilling their rings and other items is enough. else if (!force && G_GametypeHasTeams() && source && source->player && (source->player->ctfteam == player->ctfteam) - && cv_friendlyfire.value) + && (cv_friendlyfire.value || (gametyperules & GTR_FRIENDLYFIRE))) { damage = 0; P_ShieldDamage(player, inflictor, source, damage, damagetype); diff --git a/src/st_stuff.c b/src/st_stuff.c index 4c3f57412..b822678ff 100644 --- a/src/st_stuff.c +++ b/src/st_stuff.c @@ -2298,7 +2298,7 @@ static void ST_drawTextHUD(void) textHUDdraw(M_GetText("\x82""VIEWPOINT:""\x80 Switch view")) donef12 = true; } - if (gametyperules & GTR_HIDETIMEFROZEN) + if (gametyperules & GTR_HIDEFROZEN) textHUDdraw(M_GetText("You cannot move while hiding.")) } } From f584b61c93a97e1a9852f306acba673ced21e03a Mon Sep 17 00:00:00 2001 From: James R Date: Wed, 18 Dec 2019 15:34:55 -0800 Subject: [PATCH 270/746] Use a random port when connecting --- src/d_clisrv.c | 2 +- src/d_net.h | 2 ++ src/i_tcp.c | 14 ++++++++++---- 3 files changed, 13 insertions(+), 5 deletions(-) diff --git a/src/d_clisrv.c b/src/d_clisrv.c index 7b6c35eb6..6520a1aa1 100644 --- a/src/d_clisrv.c +++ b/src/d_clisrv.c @@ -70,7 +70,7 @@ boolean server = true; // true or false but !server == client #define client (!server) boolean nodownload = false; -static boolean serverrunning = false; +boolean serverrunning = false; INT32 serverplayer = 0; char motd[254], server_context[8]; // Message of the Day, Unique Context (even without Mumble support) diff --git a/src/d_net.h b/src/d_net.h index 8fd6c67b2..c6fe4a27f 100644 --- a/src/d_net.h +++ b/src/d_net.h @@ -40,6 +40,8 @@ extern SINT8 nodetoplayer2[MAXNETNODES]; // Say the numplayer for this node if a extern UINT8 playerpernode[MAXNETNODES]; // Used specially for splitscreen extern boolean nodeingame[MAXNETNODES]; // Set false as nodes leave game +extern boolean serverrunning; + INT32 Net_GetFreeAcks(boolean urgent); void Net_AckTicker(void); diff --git a/src/i_tcp.c b/src/i_tcp.c index 2dd9f0591..bd35a292a 100644 --- a/src/i_tcp.c +++ b/src/i_tcp.c @@ -887,6 +887,7 @@ static boolean UDP_Socket(void) #ifdef HAVE_IPV6 const INT32 b_ipv6 = M_CheckParm("-ipv6"); #endif + const char *serv; for (s = 0; s < mysocketses; s++) @@ -902,11 +903,16 @@ static boolean UDP_Socket(void) hints.ai_socktype = SOCK_DGRAM; hints.ai_protocol = IPPROTO_UDP; + if (serverrunning) + serv = port_name; + else + serv = NULL;/* any port */ + if (M_CheckParm("-bindaddr")) { while (M_IsNextParm()) { - gaie = I_getaddrinfo(M_GetNextParm(), port_name, &hints, &ai); + gaie = I_getaddrinfo(M_GetNextParm(), serv, &hints, &ai); if (gaie == 0) { runp = ai; @@ -927,7 +933,7 @@ static boolean UDP_Socket(void) } else { - gaie = I_getaddrinfo("0.0.0.0", port_name, &hints, &ai); + gaie = I_getaddrinfo("0.0.0.0", serv, &hints, &ai); if (gaie == 0) { runp = ai; @@ -960,7 +966,7 @@ static boolean UDP_Socket(void) { while (M_IsNextParm()) { - gaie = I_getaddrinfo(M_GetNextParm(), port_name, &hints, &ai); + gaie = I_getaddrinfo(M_GetNextParm(), serv, &hints, &ai); if (gaie == 0) { runp = ai; @@ -981,7 +987,7 @@ static boolean UDP_Socket(void) } else { - gaie = I_getaddrinfo("::", port_name, &hints, &ai); + gaie = I_getaddrinfo("::", serv, &hints, &ai); if (gaie == 0) { runp = ai; From 4e321012894b2aa87e312597f19be26b30545a8b Mon Sep 17 00:00:00 2001 From: James R Date: Wed, 18 Dec 2019 15:43:29 -0800 Subject: [PATCH 271/746] Use a pointer for port_name Using strcpy is stupid because we don't know how long the argument would be. There's no need for a buffer anyway. --- src/i_tcp.c | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/src/i_tcp.c b/src/i_tcp.c index bd35a292a..8ead73c3a 100644 --- a/src/i_tcp.c +++ b/src/i_tcp.c @@ -209,7 +209,7 @@ static size_t numbans = 0; static boolean SOCK_bannednode[MAXNETNODES+1]; /// \note do we really need the +1? static boolean init_tcp_driver = false; -static char port_name[8] = DEFAULTPORT; +static const char *port_name = DEFAULTPORT; #ifndef NONET @@ -1431,10 +1431,11 @@ boolean I_InitTcpNetwork(void) // Combined -udpport and -clientport into -port // As it was really redundant having two seperate parms that does the same thing { - if (M_IsNextParm()) - strcpy(port_name, M_GetNextParm()); - else - strcpy(port_name, "0"); + /* + If it's NULL, that's okay! Because then + we'll get a random port from getaddrinfo. + */ + port_name = M_GetNextParm(); } // parse network game options, From 0421c81e042f89af988d12c83b56cef20eb95986 Mon Sep 17 00:00:00 2001 From: Jaime Passos Date: Wed, 18 Dec 2019 20:43:54 -0300 Subject: [PATCH 272/746] ViewpointSwitch hook for Lua --- src/g_game.c | 10 ++++++++++ src/lua_hook.h | 2 ++ src/lua_hooklib.c | 47 +++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 59 insertions(+) diff --git a/src/g_game.c b/src/g_game.c index 02b32bd48..f84829386 100644 --- a/src/g_game.c +++ b/src/g_game.c @@ -1956,6 +1956,16 @@ boolean G_Responder(event_t *ev) if (!playeringame[displayplayer]) continue; +#ifdef HAVE_BLUA + { + UINT8 canSwitchView = LUAh_ViewpointSwitch(&players[consoleplayer], &players[displayplayer]); + if (canSwitchView == 1) // Set viewpoint to this player + break; + else if (canSwitchView == 2) // Skip this player + continue; + } +#endif + if (players[displayplayer].spectator) continue; diff --git a/src/lua_hook.h b/src/lua_hook.h index 6617bca93..592a93acc 100644 --- a/src/lua_hook.h +++ b/src/lua_hook.h @@ -51,6 +51,7 @@ enum hook { hook_PlayerCanDamage, hook_PlayerQuit, hook_IntermissionThinker, + hook_ViewpointSwitch, hook_MAX // last hook }; @@ -93,5 +94,6 @@ boolean LUAh_FollowMobj(player_t *player, mobj_t *mobj); // Hook for P_PlayerAft UINT8 LUAh_PlayerCanDamage(player_t *player, mobj_t *mobj); // Hook for P_PlayerCanDamage void LUAh_PlayerQuit(player_t *plr, int reason); // Hook for player quitting void LUAh_IntermissionThinker(void); // Hook for Y_Ticker +UINT8 LUAh_ViewpointSwitch(player_t *player, player_t *newdisplayplayer); // Hook for spy mode in G_Responder #endif diff --git a/src/lua_hooklib.c b/src/lua_hooklib.c index ef87d0b6f..b1f702f7c 100644 --- a/src/lua_hooklib.c +++ b/src/lua_hooklib.c @@ -62,6 +62,7 @@ const char *const hookNames[hook_MAX+1] = { "PlayerCanDamage", "PlayerQuit", "IntermissionThinker", + "ViewpointSwitch", NULL }; @@ -203,6 +204,7 @@ static int lib_addHook(lua_State *L) case hook_PlayerSpawn: case hook_FollowMobj: case hook_PlayerCanDamage: + case hook_ViewpointSwitch: case hook_ShieldSpawn: case hook_ShieldSpecial: lastp = &playerhooks; @@ -1346,4 +1348,49 @@ void LUAh_IntermissionThinker(void) } } +// Hook for spy mode in G_Responder +UINT8 LUAh_ViewpointSwitch(player_t *player, player_t *newdisplayplayer) +{ + hook_p hookp; + UINT8 canSwitchView = 0; // 0 = default, 1 = force yes, 2 = force no. + if (!gL || !(hooksAvailable[hook_ViewpointSwitch/8] & (1<<(hook_ViewpointSwitch%8)))) + return 0; + + lua_settop(gL, 0); + + for (hookp = playerhooks; hookp; hookp = hookp->next) + { + if (hookp->type != hook_ViewpointSwitch) + continue; + + if (lua_gettop(gL) == 0) + { + LUA_PushUserdata(gL, player, META_PLAYER); + LUA_PushUserdata(gL, newdisplayplayer, 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)) + { // if nil, leave canSwitchView = 0. + if (lua_toboolean(gL, -1)) + canSwitchView = 1; // Force viewpoint switch + else + canSwitchView = 2; // Skip viewpoint switch + } + lua_pop(gL, 1); + } + + lua_settop(gL, 0); + return canSwitchView; +} + #endif From 843d9b9f0a345330d97c579e94f208eb2b65c156 Mon Sep 17 00:00:00 2001 From: James R Date: Wed, 18 Dec 2019 15:47:47 -0800 Subject: [PATCH 273/746] -clientport (it's back!) and -serverport, which is an alias to -port If you ever need to, you can change the client port number. --- src/i_tcp.c | 18 +++++++++++------- 1 file changed, 11 insertions(+), 7 deletions(-) diff --git a/src/i_tcp.c b/src/i_tcp.c index 8ead73c3a..502eb6732 100644 --- a/src/i_tcp.c +++ b/src/i_tcp.c @@ -209,7 +209,8 @@ static size_t numbans = 0; static boolean SOCK_bannednode[MAXNETNODES+1]; /// \note do we really need the +1? static boolean init_tcp_driver = false; -static const char *port_name = DEFAULTPORT; +static const char *serverport_name = DEFAULTPORT; +static const char *clientport_name;/* any port */ #ifndef NONET @@ -904,9 +905,9 @@ static boolean UDP_Socket(void) hints.ai_protocol = IPPROTO_UDP; if (serverrunning) - serv = port_name; + serv = serverport_name; else - serv = NULL;/* any port */ + serv = clientport_name; if (M_CheckParm("-bindaddr")) { @@ -948,8 +949,8 @@ static boolean UDP_Socket(void) #ifdef HAVE_MINIUPNPC if (UPNP_support) { - I_UPnP_rem(port_name, "UDP"); - I_UPnP_add(NULL, port_name, "UDP"); + I_UPnP_rem(serverport_name, "UDP"); + I_UPnP_add(NULL, serverport_name, "UDP"); } #endif } @@ -1427,16 +1428,19 @@ boolean I_InitTcpNetwork(void) if (!I_InitTcpDriver()) return false; - if (M_CheckParm("-port")) + if (M_CheckParm("-port") || M_CheckParm("-serverport")) // Combined -udpport and -clientport into -port // As it was really redundant having two seperate parms that does the same thing + /* Sorry Steel, I'm adding these back. But -udpport is a stupid name. */ { /* If it's NULL, that's okay! Because then we'll get a random port from getaddrinfo. */ - port_name = M_GetNextParm(); + serverport_name = M_GetNextParm(); } + if (M_CheckParm("-clientport")) + clientport_name = M_GetNextParm(); // parse network game options, if (M_CheckParm("-server") || dedicated) From 5e818e1dab6934be29c55b8f5ae4fb14e353a5cf Mon Sep 17 00:00:00 2001 From: Jaime Passos Date: Wed, 18 Dec 2019 22:02:37 -0300 Subject: [PATCH 274/746] Custom gametype rankings --- src/dehacked.c | 12 +++++++++++- src/g_game.c | 19 ++++++++++++++++++- src/g_game.h | 1 + src/hu_stuff.c | 24 ++++++++++++------------ 4 files changed, 42 insertions(+), 14 deletions(-) diff --git a/src/dehacked.c b/src/dehacked.c index 676d0e144..254f94ade 100644 --- a/src/dehacked.c +++ b/src/dehacked.c @@ -1156,6 +1156,7 @@ static void readgametype(MYFILE *f, char *gtname) INT32 newgttimelimit = 0; UINT8 newgtleftcolor = 0; UINT8 newgtrightcolor = 0; + INT16 newgtrankingstype = -1; int newgtinttype = 0; char gtdescription[441]; @@ -1243,7 +1244,13 @@ static void readgametype(MYFILE *f, char *gtname) newgtleftcolor = (UINT8)get_number(word2); else if (fastcmp(word, "HEADERRIGHTCOLOR") || fastcmp(word, "HEADERRIGHTCOLOUR")) newgtrightcolor = (UINT8)get_number(word2); - // Type of intermission + // Rankings type + else if (fastcmp(word, "RANKINGTYPE")) + { + // Case insensitive + newgtrankingstype = (int)get_number(word2); + } + // Intermission type else if (fastcmp(word, "INTERMISSIONTYPE")) { // Case sensitive @@ -1308,6 +1315,9 @@ static void readgametype(MYFILE *f, char *gtname) G_SetGametypeDescription(newgtidx, gtdescription, newgtleftcolor, newgtrightcolor); // Not covered by G_AddGametype alone. + if (newgtrankingstype == -1) + newgtrankingstype = newgtidx; + gametyperankings[newgtidx] = newgtrankingstype; intermissiontypes[newgtidx] = newgtinttype; pointlimits[newgtidx] = newgtpointlimit; timelimits[newgtidx] = newgttimelimit; diff --git a/src/g_game.c b/src/g_game.c index f84829386..04722acbb 100644 --- a/src/g_game.c +++ b/src/g_game.c @@ -3084,7 +3084,7 @@ const char *Gametype_ConstantNames[NUMGAMETYPES] = "GT_CTF" // GT_CTF }; -// Game type rules +// Gametype rules UINT32 gametypedefaultrules[NUMGAMETYPES] = { // Co-op @@ -3169,6 +3169,23 @@ void G_SetGametypeDescription(INT16 gtype, char *descriptiontext, UINT8 leftcolo gametypedesc[gtype].col[1] = rightcolor; } +// Gametype rankings +INT16 gametyperankings[NUMGAMETYPES] = +{ + GT_COOP, + GT_COMPETITION, + GT_RACE, + + GT_MATCH, + GT_TEAMMATCH, + + GT_TAG, + GT_HIDEANDSEEK, + + GT_CTF, +}; + +// Gametype to TOL (Type Of Level) UINT32 gametypetol[NUMGAMETYPES] = { TOL_COOP, // Co-op diff --git a/src/g_game.h b/src/g_game.h index 6b29ef836..bd0dc0180 100644 --- a/src/g_game.h +++ b/src/g_game.h @@ -203,6 +203,7 @@ boolean G_CheckDemoStatus(void); extern UINT32 gametypedefaultrules[NUMGAMETYPES]; extern UINT32 gametypetol[NUMGAMETYPES]; +extern INT16 gametyperankings[NUMGAMETYPES]; void G_SetGametype(INT16 gametype); INT16 G_AddGametype(UINT32 rules); diff --git a/src/hu_stuff.c b/src/hu_stuff.c index bcad6ebef..e95ab7b1b 100644 --- a/src/hu_stuff.c +++ b/src/hu_stuff.c @@ -2371,7 +2371,7 @@ void HU_DrawTabRankings(INT32 x, INT32 y, playersort_t *tab, INT32 scorelines, I for (i = 0; i < scorelines; i++) { - if (players[tab[i].num].spectator && gametype != GT_COOP) + if (players[tab[i].num].spectator && gametyperankings[gametype] != GT_COOP) continue; //ignore them. greycheck = greycheckdef; @@ -2434,7 +2434,7 @@ void HU_DrawTabRankings(INT32 x, INT32 y, playersort_t *tab, INT32 scorelines, I } } - if (G_GametypeUsesLives() && !(gametype == GT_COOP && (cv_cooplives.value == 0 || cv_cooplives.value == 3)) && (players[tab[i].num].lives != INFLIVES)) //show lives + if (G_GametypeUsesLives() && !(gametyperankings[gametype] == GT_COOP && (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) { @@ -2447,7 +2447,7 @@ void HU_DrawTabRankings(INT32 x, INT32 y, playersort_t *tab, INT32 scorelines, I if (players[tab[i].num].exiting || (players[tab[i].num].pflags & PF_FINISHED)) V_DrawSmallScaledPatch(x - SHORT(exiticon->width)/2 - 1, y-3, 0, exiticon); - if (gametype == GT_RACE) + if (gametyperankings[gametype] == GT_RACE) { if (circuitmap) { @@ -2726,7 +2726,7 @@ void HU_DrawDualTabRankings(INT32 x, INT32 y, playersort_t *tab, INT32 scoreline for (i = 0; i < scorelines; i++) { - if (players[tab[i].num].spectator && gametype != GT_COOP) + if (players[tab[i].num].spectator && gametyperankings[gametype] != GT_COOP) continue; //ignore them. greycheck = greycheckdef; @@ -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() && !(gametype == GT_COOP && (cv_cooplives.value == 0 || cv_cooplives.value == 3)) && (players[tab[i].num].lives != INFLIVES)) //show lives + if (G_GametypeUsesLives() && !(gametyperankings[gametype] == GT_COOP && (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); @@ -2792,7 +2792,7 @@ void HU_DrawDualTabRankings(INT32 x, INT32 y, playersort_t *tab, INT32 scoreline } // All data drawn with thin string for space. - if (gametype == GT_RACE) + if (gametyperankings[gametype] == GT_RACE) { if (circuitmap) { @@ -2832,7 +2832,7 @@ static void HU_Draw32TabRankings(INT32 x, INT32 y, playersort_t *tab, INT32 scor for (i = 0; i < scorelines; i++) { - if (players[tab[i].num].spectator && gametype != GT_COOP) + if (players[tab[i].num].spectator && gametyperankings[gametype] != GT_COOP) continue; //ignore them. greycheck = greycheckdef; @@ -2902,7 +2902,7 @@ static void HU_Draw32TabRankings(INT32 x, INT32 y, playersort_t *tab, INT32 scor } // All data drawn with thin string for space. - if (gametype == GT_RACE) + if (gametyperankings[gametype] == GT_RACE) { if (circuitmap) { @@ -3040,7 +3040,7 @@ static void HU_DrawRankings(void) V_DrawCenteredString(256, 16, 0, va("%d", cv_pointlimit.value)); } } - else if (gametype == GT_COOP) + else if (gametyperankings[gametype] == GT_COOP) { INT32 totalscore = 0; for (i = 0; i < MAXPLAYERS; i++) @@ -3074,7 +3074,7 @@ static void HU_DrawRankings(void) tab[i].num = -1; tab[i].name = 0; - if (gametype == GT_RACE && !circuitmap) + if (gametyperankings[gametype] == GT_RACE && !circuitmap) tab[i].count = INT32_MAX; } @@ -3094,7 +3094,7 @@ static void HU_DrawRankings(void) if (!G_PlatformGametype() && players[i].spectator) continue; - if (gametype == GT_RACE) + if (gametyperankings[gametype] == GT_RACE) { if (circuitmap) { @@ -3117,7 +3117,7 @@ static void HU_DrawRankings(void) } } } - else if (gametype == GT_COMPETITION) + else if (gametyperankings[gametype] == GT_COMPETITION) { // todo put something more fitting for the gametype here, such as current // number of categories led From 9228f99260c329370a9c1a9dc6ed5ca29650c5d3 Mon Sep 17 00:00:00 2001 From: Jaime Passos Date: Wed, 18 Dec 2019 22:23:30 -0300 Subject: [PATCH 275/746] Fix timelimit/pointlimit checks in HU_DrawRankings, organise rules in gametypedefaultrules a bit --- src/g_game.c | 4 ++-- src/hu_stuff.c | 6 +++--- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/src/g_game.c b/src/g_game.c index 04722acbb..2675930a4 100644 --- a/src/g_game.c +++ b/src/g_game.c @@ -3097,7 +3097,7 @@ UINT32 gametypedefaultrules[NUMGAMETYPES] = // Match GTR_RINGSLINGER|GTR_SPECTATORS|GTR_POINTLIMIT|GTR_TIMELIMIT|GTR_EMERALDS|GTR_PITYSHIELD|GTR_DEATHPENALTY|GTR_ROUNDENDMESSAGE, // Team Match - GTR_RINGSLINGER|GTR_TEAMS|GTR_POINTLIMIT|GTR_SPECTATORS|GTR_TIMELIMIT|GTR_PITYSHIELD|GTR_ROUNDENDMESSAGE, + GTR_RINGSLINGER|GTR_SPECTATORS|GTR_TEAMS|GTR_POINTLIMIT|GTR_TIMELIMIT|GTR_PITYSHIELD|GTR_ROUNDENDMESSAGE, // Tag GTR_RINGSLINGER|GTR_TAG|GTR_SPECTATORS|GTR_POINTLIMIT|GTR_TIMELIMIT|GTR_HIDETIME|GTR_BLINDFOLDED|GTR_ROUNDENDMESSAGE, @@ -3105,7 +3105,7 @@ UINT32 gametypedefaultrules[NUMGAMETYPES] = GTR_RINGSLINGER|GTR_TAG|GTR_SPECTATORS|GTR_POINTLIMIT|GTR_TIMELIMIT|GTR_HIDETIME|GTR_BLINDFOLDED|GTR_ROUNDENDMESSAGE, // CTF - GTR_RINGSLINGER|GTR_TEAMS|GTR_SPECTATORS|GTR_POINTLIMIT|GTR_TIMELIMIT|GTR_EMERALDS|GTR_TEAMFLAGS|GTR_PITYSHIELD|GTR_ROUNDENDMESSAGE, + GTR_RINGSLINGER|GTR_SPECTATORS|GTR_TEAMS|GTR_POINTLIMIT|GTR_TIMELIMIT|GTR_EMERALDS|GTR_TEAMFLAGS|GTR_PITYSHIELD|GTR_ROUNDENDMESSAGE, }; // diff --git a/src/hu_stuff.c b/src/hu_stuff.c index e95ab7b1b..d9801793b 100644 --- a/src/hu_stuff.c +++ b/src/hu_stuff.c @@ -3026,15 +3026,15 @@ static void HU_DrawRankings(void) // draw the current gametype in the lower right HU_drawGametype(); - if (gametyperules & GTR_POINTLIMIT) + if (gametyperules & (GTR_TIMELIMIT|GTR_POINTLIMIT)) { - if (cv_timelimit.value && timelimitintics > 0) + if ((gametyperules & GTR_TIMELIMIT) && cv_timelimit.value && timelimitintics > 0) { V_DrawCenteredString(64, 8, 0, "TIME"); V_DrawCenteredString(64, 16, 0, va("%i:%02i", G_TicsToMinutes(stplyr->realtime, true), G_TicsToSeconds(stplyr->realtime))); } - if (cv_pointlimit.value > 0) + if ((gametyperules & GTR_POINTLIMIT) && cv_pointlimit.value > 0) { V_DrawCenteredString(256, 8, 0, "POINT LIMIT"); V_DrawCenteredString(256, 16, 0, va("%d", cv_pointlimit.value)); From 5daedc70e75057ed1323db4ab9e68f876dbd585d Mon Sep 17 00:00:00 2001 From: Jaime Passos Date: Wed, 18 Dec 2019 22:46:17 -0300 Subject: [PATCH 276/746] Special Stages/token stuff --- src/dehacked.c | 2 ++ src/doomstat.h | 18 ++++++++++-------- src/g_game.c | 6 +++--- src/p_inter.c | 2 +- src/p_mobj.c | 2 +- 5 files changed, 17 insertions(+), 13 deletions(-) diff --git a/src/dehacked.c b/src/dehacked.c index 254f94ade..e60bcae5d 100644 --- a/src/dehacked.c +++ b/src/dehacked.c @@ -8919,6 +8919,8 @@ static const char *const GAMETYPERULE_LIST[] = { "PITYSHIELD", "DEATHPENALTY", "NOSPECTATORSPAWN", + "SPECIALSTAGES", + "EMERALDTOKENS", "EMERALDHUNT", "SPAWNENEMIES", "ALLOWEXIT", diff --git a/src/doomstat.h b/src/doomstat.h index 459bfc88f..b79edb93c 100644 --- a/src/doomstat.h +++ b/src/doomstat.h @@ -411,14 +411,16 @@ enum GameTypeRules GTR_PITYSHIELD = 1<<14, // Award pity shield GTR_DEATHPENALTY = 1<<15, // Death score penalty GTR_NOSPECTATORSPAWN = 1<<16, // For use with GTR_SPECTATORS - spawn in the map instead of with the spectators - GTR_EMERALDHUNT = 1<<17, // Emerald Hunt - GTR_SPAWNENEMIES = 1<<18, // Spawn enemies - GTR_ALLOWEXIT = 1<<19, // Allow exit sectors - GTR_ROUNDENDMESSAGE = 1<<20, // Prints "The round has ended." into the console - GTR_NOTITLECARD = 1<<21, // Don't show the title card - GTR_POINTLIMIT = 1<<22, // Ringslinger point limit - GTR_TIMELIMIT = 1<<23, // Ringslinger time limit - GTR_OVERTIME = 1<<24, // Allow overtime + GTR_SPECIALSTAGES = 1<<17, // Allow special stages + GTR_EMERALDTOKENS = 1<<18, // Spawn emerald tokens + GTR_EMERALDHUNT = 1<<19, // Emerald Hunt + GTR_SPAWNENEMIES = 1<<20, // Spawn enemies + GTR_ALLOWEXIT = 1<<21, // Allow exit sectors + GTR_ROUNDENDMESSAGE = 1<<22, // Prints "The round has ended." into the console + GTR_NOTITLECARD = 1<<23, // Don't show the title card + GTR_POINTLIMIT = 1<<24, // Ringslinger point limit + GTR_TIMELIMIT = 1<<25, // Ringslinger time limit + GTR_OVERTIME = 1<<26, // Allow overtime }; // String names for gametypes diff --git a/src/g_game.c b/src/g_game.c index 2675930a4..74fd82be6 100644 --- a/src/g_game.c +++ b/src/g_game.c @@ -3088,9 +3088,9 @@ const char *Gametype_ConstantNames[NUMGAMETYPES] = UINT32 gametypedefaultrules[NUMGAMETYPES] = { // Co-op - GTR_PLATFORM|GTR_LIVES|GTR_CHASECAM|GTR_EMERALDHUNT|GTR_SPAWNENEMIES|GTR_ALLOWEXIT, + GTR_PLATFORM|GTR_LIVES|GTR_CHASECAM|GTR_EMERALDHUNT|GTR_SPAWNENEMIES|GTR_ALLOWEXIT|GTR_EMERALDTOKENS|GTR_SPECIALSTAGES, // Competition - GTR_PLATFORM|GTR_LIVES|GTR_RACE|GTR_CHASECAM|GTR_SPAWNENEMIES|GTR_ALLOWEXIT|GTR_ROUNDENDMESSAGE, + GTR_PLATFORM|GTR_LIVES|GTR_RACE|GTR_CHASECAM|GTR_SPAWNENEMIES|GTR_ALLOWEXIT|GTR_ROUNDENDMESSAGE|GTR_EMERALDTOKENS, // Race GTR_PLATFORM|GTR_RACE|GTR_CHASECAM|GTR_SPAWNENEMIES|GTR_ALLOWEXIT|GTR_ROUNDENDMESSAGE, @@ -3530,7 +3530,7 @@ static void G_DoCompleted(void) if (nextmap >= 1100-1 && nextmap <= 1102-1 && (gametyperules & GTR_RACE)) nextmap = (INT16)(spstage_start-1); - if ((gottoken = (gametype == GT_COOP && token))) + if ((gottoken = ((gametyperules & GTR_SPECIALSTAGES) && token))) { token--; diff --git a/src/p_inter.c b/src/p_inter.c index 900435a99..08e8a62a1 100644 --- a/src/p_inter.c +++ b/src/p_inter.c @@ -625,7 +625,7 @@ void P_TouchSpecialThing(mobj_t *special, mobj_t *toucher, boolean heightcheck) P_AddPlayerScore(player, 1000); - if (gametype != GT_COOP || modeattacking) // score only? + if (!(gametyperules & GTR_SPECIALSTAGES) || modeattacking) // score only? { S_StartSound(toucher, sfx_chchng); break; diff --git a/src/p_mobj.c b/src/p_mobj.c index 8c5497e26..c85d2566c 100644 --- a/src/p_mobj.c +++ b/src/p_mobj.c @@ -11811,7 +11811,7 @@ You should think about modifying the deathmatch starts to take full advantage of return; // no doubles } - if (i == MT_TOKEN && ((gametype != GT_COOP && gametype != GT_COMPETITION) || tokenbits == 30 || tokenlist & (1 << tokenbits++))) + if (i == MT_TOKEN && (!(gametyperules & GTR_EMERALDTOKENS) || tokenbits == 30 || tokenlist & (1 << tokenbits++))) return; // you already got this token, or there are too many, or the gametype's not right if (i == MT_EMBLEM && (netgame || multiplayer || (modifiedgame && !savemoddata))) // No cheating!! From ef7e53488db6cf25cf777a530603943597d85116 Mon Sep 17 00:00:00 2001 From: Jaime Passos Date: Wed, 18 Dec 2019 22:50:49 -0300 Subject: [PATCH 277/746] GTR_CAMPAIGN and GTR_NOGAMEEND --- src/doomstat.h | 12 +++++++----- src/g_game.c | 10 +++++----- 2 files changed, 12 insertions(+), 10 deletions(-) diff --git a/src/doomstat.h b/src/doomstat.h index b79edb93c..6730254a2 100644 --- a/src/doomstat.h +++ b/src/doomstat.h @@ -416,11 +416,13 @@ enum GameTypeRules GTR_EMERALDHUNT = 1<<19, // Emerald Hunt GTR_SPAWNENEMIES = 1<<20, // Spawn enemies GTR_ALLOWEXIT = 1<<21, // Allow exit sectors - GTR_ROUNDENDMESSAGE = 1<<22, // Prints "The round has ended." into the console - GTR_NOTITLECARD = 1<<23, // Don't show the title card - GTR_POINTLIMIT = 1<<24, // Ringslinger point limit - GTR_TIMELIMIT = 1<<25, // Ringslinger time limit - GTR_OVERTIME = 1<<26, // Allow overtime + GTR_CAMPAIGN = 1<<22, // Linear Co-op map progression. Don't allow random maps. + GTR_NOGAMEEND = 1<<23, // Don't end the game. That is, wrap around the maps instead of starting the ending. + GTR_ROUNDENDMESSAGE = 1<<24, // Prints "The round has ended." into the console + GTR_NOTITLECARD = 1<<25, // Don't show the title card + GTR_POINTLIMIT = 1<<26, // Ringslinger point limit + GTR_TIMELIMIT = 1<<27, // Ringslinger time limit + GTR_OVERTIME = 1<<28, // Allow overtime }; // String names for gametypes diff --git a/src/g_game.c b/src/g_game.c index 74fd82be6..d73df8139 100644 --- a/src/g_game.c +++ b/src/g_game.c @@ -3088,11 +3088,11 @@ const char *Gametype_ConstantNames[NUMGAMETYPES] = UINT32 gametypedefaultrules[NUMGAMETYPES] = { // Co-op - GTR_PLATFORM|GTR_LIVES|GTR_CHASECAM|GTR_EMERALDHUNT|GTR_SPAWNENEMIES|GTR_ALLOWEXIT|GTR_EMERALDTOKENS|GTR_SPECIALSTAGES, + GTR_PLATFORM|GTR_CAMPAIGN|GTR_LIVES|GTR_CHASECAM|GTR_EMERALDHUNT|GTR_SPAWNENEMIES|GTR_ALLOWEXIT|GTR_EMERALDTOKENS|GTR_SPECIALSTAGES, // Competition - GTR_PLATFORM|GTR_LIVES|GTR_RACE|GTR_CHASECAM|GTR_SPAWNENEMIES|GTR_ALLOWEXIT|GTR_ROUNDENDMESSAGE|GTR_EMERALDTOKENS, + GTR_PLATFORM|GTR_NOGAMEEND|GTR_LIVES|GTR_RACE|GTR_CHASECAM|GTR_SPAWNENEMIES|GTR_ALLOWEXIT|GTR_ROUNDENDMESSAGE|GTR_EMERALDTOKENS, // Race - GTR_PLATFORM|GTR_RACE|GTR_CHASECAM|GTR_SPAWNENEMIES|GTR_ALLOWEXIT|GTR_ROUNDENDMESSAGE, + GTR_PLATFORM|GTR_NOGAMEEND|GTR_RACE|GTR_CHASECAM|GTR_SPAWNENEMIES|GTR_ALLOWEXIT|GTR_ROUNDENDMESSAGE, // Match GTR_RINGSLINGER|GTR_SPECTATORS|GTR_POINTLIMIT|GTR_TIMELIMIT|GTR_EMERALDS|GTR_PITYSHIELD|GTR_DEATHPENALTY|GTR_ROUNDENDMESSAGE, @@ -3527,7 +3527,7 @@ static void G_DoCompleted(void) I_Error("Followed map %d to invalid map %d\n", prevmap + 1, nextmap + 1); // wrap around in race - if (nextmap >= 1100-1 && nextmap <= 1102-1 && (gametyperules & GTR_RACE)) + if (nextmap >= 1100-1 && nextmap <= 1102-1 && (gametyperules & GTR_NOGAMEEND)) nextmap = (INT16)(spstage_start-1); if ((gottoken = ((gametyperules & GTR_SPECIALSTAGES) && token))) @@ -3550,7 +3550,7 @@ static void G_DoCompleted(void) automapactive = false; - if (gametype != GT_COOP) + if (!(gametyperules & GTR_CAMPAIGN)) { if (cv_advancemap.value == 0) // Stay on same map. nextmap = prevmap; From b496cc0d62e220d17c40a14da3b5a07569067919 Mon Sep 17 00:00:00 2001 From: Jaime Passos Date: Wed, 18 Dec 2019 23:02:07 -0300 Subject: [PATCH 278/746] Whoops --- src/dehacked.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/dehacked.c b/src/dehacked.c index e60bcae5d..871fe72a0 100644 --- a/src/dehacked.c +++ b/src/dehacked.c @@ -8924,6 +8924,8 @@ static const char *const GAMETYPERULE_LIST[] = { "EMERALDHUNT", "SPAWNENEMIES", "ALLOWEXIT", + "CAMPAIGN", + "NOGAMEEND", "ROUNDENDMESSAGE", "NOTITLECARD", "POINTLIMIT", From 96cf03b716414bfb28c890d6a1c622896465820a Mon Sep 17 00:00:00 2001 From: Steel Titanium Date: Wed, 18 Dec 2019 21:28:34 -0500 Subject: [PATCH 279/746] Don't uncurl from spin if Elemental Stomp is used --- src/p_user.c | 4 ---- 1 file changed, 4 deletions(-) diff --git a/src/p_user.c b/src/p_user.c index ea42a2c36..78c5137bc 100644 --- a/src/p_user.c +++ b/src/p_user.c @@ -5128,11 +5128,7 @@ static void P_DoJumpStuff(player_t *player, ticcmd_t *cmd) boolean elem = ((player->powers[pw_shield] & SH_NOSTACK) == SH_ELEMENTAL); player->pflags |= PF_THOKKED|PF_SHIELDABILITY; if (elem) - { - player->pflags |= PF_NOJUMPDAMAGE; - P_SetPlayerMobjState(player->mo, S_PLAY_FALL); S_StartSound(player->mo, sfx_s3k43); - } else { player->pflags &= ~PF_NOJUMPDAMAGE; From be5fd1a0dbd91e402f9f20fb31d4dc74b3973bbb Mon Sep 17 00:00:00 2001 From: Jaime Passos Date: Wed, 18 Dec 2019 23:40:58 -0300 Subject: [PATCH 280/746] TeamSwitch hook for Lua --- src/d_netcmd.c | 6 ++++++ src/lua_hook.h | 2 ++ src/lua_hooklib.c | 49 +++++++++++++++++++++++++++++++++++++++++++++++ src/p_user.c | 11 ++++++++++- 4 files changed, 67 insertions(+), 1 deletion(-) diff --git a/src/d_netcmd.c b/src/d_netcmd.c index 158b1f802..807daa9ef 100644 --- a/src/d_netcmd.c +++ b/src/d_netcmd.c @@ -2734,6 +2734,12 @@ static void Got_Teamchange(UINT8 **cp, INT32 playernum) return; } +#ifdef HAVE_BLUA + // Don't switch team, just go away, please, go awaayyyy, aaauuauugghhhghgh + if (!LUAh_TeamSwitch(&players[playernum], NetPacket.packet.newteam, players[playernum].spectator, NetPacket.packet.autobalance, NetPacket.packet.scrambled)) + return; +#endif + //no status changes after hidetime if ((gametyperules & GTR_HIDEFROZEN) && (leveltime >= (hidetime * TICRATE))) error = true; diff --git a/src/lua_hook.h b/src/lua_hook.h index 592a93acc..524526df2 100644 --- a/src/lua_hook.h +++ b/src/lua_hook.h @@ -51,6 +51,7 @@ enum hook { hook_PlayerCanDamage, hook_PlayerQuit, hook_IntermissionThinker, + hook_TeamSwitch, hook_ViewpointSwitch, hook_MAX // last hook @@ -94,6 +95,7 @@ boolean LUAh_FollowMobj(player_t *player, mobj_t *mobj); // Hook for P_PlayerAft UINT8 LUAh_PlayerCanDamage(player_t *player, mobj_t *mobj); // Hook for P_PlayerCanDamage 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 autobalance, boolean scrambled); // Hook for team switching in... uh.... UINT8 LUAh_ViewpointSwitch(player_t *player, player_t *newdisplayplayer); // Hook for spy mode in G_Responder #endif diff --git a/src/lua_hooklib.c b/src/lua_hooklib.c index b1f702f7c..08ffeec03 100644 --- a/src/lua_hooklib.c +++ b/src/lua_hooklib.c @@ -62,6 +62,7 @@ const char *const hookNames[hook_MAX+1] = { "PlayerCanDamage", "PlayerQuit", "IntermissionThinker", + "TeamSwitch", "ViewpointSwitch", NULL }; @@ -204,6 +205,7 @@ static int lib_addHook(lua_State *L) case hook_PlayerSpawn: case hook_FollowMobj: case hook_PlayerCanDamage: + case hook_TeamSwitch: case hook_ViewpointSwitch: case hook_ShieldSpawn: case hook_ShieldSpecial: @@ -1348,6 +1350,53 @@ void LUAh_IntermissionThinker(void) } } +// Hook for team switching +// It's just an edit of LUAh_ViewpointSwitch. +boolean LUAh_TeamSwitch(player_t *player, int newteam, boolean fromspectators, boolean autobalance, boolean scrambled) +{ + hook_p hookp; + boolean canSwitchTeam = true; + if (!gL || !(hooksAvailable[hook_TeamSwitch/8] & (1<<(hook_TeamSwitch%8)))) + return 0; + + lua_settop(gL, 0); + + for (hookp = playerhooks; hookp; hookp = hookp->next) + { + if (hookp->type != hook_TeamSwitch) + continue; + + if (lua_gettop(gL) == 0) + { + LUA_PushUserdata(gL, player, META_PLAYER); + lua_pushinteger(gL, newteam); + lua_pushboolean(gL, fromspectators); + lua_pushboolean(gL, autobalance); + lua_pushboolean(gL, scrambled); + } + lua_pushfstring(gL, FMT_HOOKID, hookp->id); + lua_gettable(gL, LUA_REGISTRYINDEX); + lua_pushvalue(gL, -6); + lua_pushvalue(gL, -6); + lua_pushvalue(gL, -6); + lua_pushvalue(gL, -6); + lua_pushvalue(gL, -6); + if (lua_pcall(gL, 5, 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)) + canSwitchTeam = false; // Can't switch team + lua_pop(gL, 1); + } + + lua_settop(gL, 0); + return canSwitchTeam; +} + // Hook for spy mode in G_Responder UINT8 LUAh_ViewpointSwitch(player_t *player, player_t *newdisplayplayer) { diff --git a/src/p_user.c b/src/p_user.c index b8164c173..b6f352450 100644 --- a/src/p_user.c +++ b/src/p_user.c @@ -10364,6 +10364,11 @@ boolean P_SpectatorJoinGame(player_t *player) else changeto = (P_RandomFixed() & 1) + 1; +#ifdef HAVE_BLUA + if (!LUAh_TeamSwitch(player, changeto, true, false, false)) + return false; +#endif + if (player->mo) { P_RemoveMobj(player->mo); @@ -10389,8 +10394,12 @@ boolean P_SpectatorJoinGame(player_t *player) { // Exception for hide and seek. Don't join a game when you simply // respawn in place and sit there for the rest of the round. - if (!(gametype == GT_HIDEANDSEEK && leveltime > (hidetime * TICRATE))) + if (!((gametyperules & GTR_HIDEFROZEN) && leveltime > (hidetime * TICRATE))) { +#ifdef HAVE_BLUA + if (!LUAh_TeamSwitch(player, 3, true, false, false)) + return false; +#endif if (player->mo) { P_RemoveMobj(player->mo); From 6f857df5e52fc62126b5ff9cd1b90a1a8444d012 Mon Sep 17 00:00:00 2001 From: Jaime Passos Date: Wed, 18 Dec 2019 23:47:17 -0300 Subject: [PATCH 281/746] ViewpointSwitch hack so nobody does anything evil Prints the generic "can't do this in a HUD hook" message. Whatever. I'm tired. --- src/lua_hooklib.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/lua_hooklib.c b/src/lua_hooklib.c index 08ffeec03..9604faf4c 100644 --- a/src/lua_hooklib.c +++ b/src/lua_hooklib.c @@ -1406,6 +1406,7 @@ UINT8 LUAh_ViewpointSwitch(player_t *player, player_t *newdisplayplayer) return 0; lua_settop(gL, 0); + hud_running = true; for (hookp = playerhooks; hookp; hookp = hookp->next) { @@ -1439,6 +1440,8 @@ UINT8 LUAh_ViewpointSwitch(player_t *player, player_t *newdisplayplayer) } lua_settop(gL, 0); + hud_running = false; + return canSwitchView; } From 5da55e8b7692ef8bd0ee1147b3578c37469c5950 Mon Sep 17 00:00:00 2001 From: Jaime Passos Date: Wed, 18 Dec 2019 23:53:26 -0300 Subject: [PATCH 282/746] Shadowed variable declarations whoopsie!!! uwu --- src/lua_hook.h | 2 +- src/lua_hooklib.c | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/lua_hook.h b/src/lua_hook.h index 524526df2..8d780490e 100644 --- a/src/lua_hook.h +++ b/src/lua_hook.h @@ -95,7 +95,7 @@ boolean LUAh_FollowMobj(player_t *player, mobj_t *mobj); // Hook for P_PlayerAft UINT8 LUAh_PlayerCanDamage(player_t *player, mobj_t *mobj); // Hook for P_PlayerCanDamage 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 autobalance, boolean scrambled); // Hook for team switching in... uh.... +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); // Hook for spy mode in G_Responder #endif diff --git a/src/lua_hooklib.c b/src/lua_hooklib.c index 9604faf4c..0393a3577 100644 --- a/src/lua_hooklib.c +++ b/src/lua_hooklib.c @@ -1352,7 +1352,7 @@ void LUAh_IntermissionThinker(void) // Hook for team switching // It's just an edit of LUAh_ViewpointSwitch. -boolean LUAh_TeamSwitch(player_t *player, int newteam, boolean fromspectators, boolean autobalance, boolean scrambled) +boolean LUAh_TeamSwitch(player_t *player, int newteam, boolean fromspectators, boolean tryingautobalance, boolean tryingscramble) { hook_p hookp; boolean canSwitchTeam = true; @@ -1371,8 +1371,8 @@ boolean LUAh_TeamSwitch(player_t *player, int newteam, boolean fromspectators, b LUA_PushUserdata(gL, player, META_PLAYER); lua_pushinteger(gL, newteam); lua_pushboolean(gL, fromspectators); - lua_pushboolean(gL, autobalance); - lua_pushboolean(gL, scrambled); + lua_pushboolean(gL, tryingautobalance); + lua_pushboolean(gL, tryingscramble); } lua_pushfstring(gL, FMT_HOOKID, hookp->id); lua_gettable(gL, LUA_REGISTRYINDEX); From e4b4b60cb6e38760b6a795795acde922b136c55b Mon Sep 17 00:00:00 2001 From: Jaime Passos Date: Thu, 19 Dec 2019 00:15:19 -0300 Subject: [PATCH 283/746] Remove this debugging command, as I don't need it anymore. --- src/d_netcmd.c | 12 ------------ 1 file changed, 12 deletions(-) diff --git a/src/d_netcmd.c b/src/d_netcmd.c index 807daa9ef..2a4bc75a7 100644 --- a/src/d_netcmd.c +++ b/src/d_netcmd.c @@ -125,7 +125,6 @@ static void Command_Version_f(void); static void Command_ModDetails_f(void); #endif static void Command_ShowGametype_f(void); -static void Command_SetGametype_f(void); FUNCNORETURN static ATTRNORETURN void Command_Quit_f(void); static void Command_Playintro_f(void); @@ -488,7 +487,6 @@ void D_RegisterServerCommands(void) COM_AddCommand("suicide", Command_Suicide); COM_AddCommand("gametype", Command_ShowGametype_f); - COM_AddCommand("setgametype", Command_SetGametype_f); COM_AddCommand("version", Command_Version_f); #ifdef UPDATE_ALERT COM_AddCommand("mod_details", Command_ModDetails_f); @@ -3643,16 +3641,6 @@ static void Command_ShowGametype_f(void) CONS_Printf(M_GetText("Unknown gametype set (%d)\n"), gametype); } -static void Command_SetGametype_f(void) -{ - if (COM_Argc() > 1) - { - INT16 oldgametype = gametype; - G_SetGametype(atoi(COM_Argv(1))); - D_GameTypeChanged(oldgametype); - } -} - /** Plays the intro. */ static void Command_Playintro_f(void) From 00440224d2d6a25afe5347565d26b7509d2c66fa Mon Sep 17 00:00:00 2001 From: Jaime Passos Date: Thu, 19 Dec 2019 00:31:13 -0300 Subject: [PATCH 284/746] De-fuck team change --- src/lua_hooklib.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/lua_hooklib.c b/src/lua_hooklib.c index 0393a3577..d213bd307 100644 --- a/src/lua_hooklib.c +++ b/src/lua_hooklib.c @@ -1357,7 +1357,7 @@ boolean LUAh_TeamSwitch(player_t *player, int newteam, boolean fromspectators, b hook_p hookp; boolean canSwitchTeam = true; if (!gL || !(hooksAvailable[hook_TeamSwitch/8] & (1<<(hook_TeamSwitch%8)))) - return 0; + return true; lua_settop(gL, 0); From d401ba558dea325841bbf9b1112505ae0af7715f Mon Sep 17 00:00:00 2001 From: lachwright Date: Thu, 19 Dec 2019 12:03:36 +0800 Subject: [PATCH 285/746] Fix pflags not being properly reset when entering dust devil from top --- src/p_enemy.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/p_enemy.c b/src/p_enemy.c index 5361f453b..6b60a697f 100644 --- a/src/p_enemy.c +++ b/src/p_enemy.c @@ -13614,12 +13614,12 @@ static boolean PIT_DustDevilLaunch(mobj_t *thing) } else { //Player on the top of the tornado. + P_ResetPlayer(player); thing->z = dustdevil->z + dustdevil->height; thrust = 20 * FRACUNIT; player->powers[pw_nocontrol] = 0; S_StartSound(thing, sfx_wdjump); P_SetPlayerMobjState(thing, S_PLAY_FALL); - player->pflags &= ~PF_JUMPED; } thing->momz = thrust; From fb6f2fc9b0a232ad4d994757156e82f22459d135 Mon Sep 17 00:00:00 2001 From: Jaime Passos Date: Thu, 19 Dec 2019 02:13:09 -0300 Subject: [PATCH 286/746] Lua! Lua! Lua! Expecting the buildbot to complain --- src/dehacked.c | 61 ++++++---------------- src/g_game.c | 56 ++++++++++++++++++++ src/g_game.h | 1 + src/lua_baselib.c | 130 ++++++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 202 insertions(+), 46 deletions(-) diff --git a/src/dehacked.c b/src/dehacked.c index 871fe72a0..5301bef68 100644 --- a/src/dehacked.c +++ b/src/dehacked.c @@ -1146,7 +1146,6 @@ static void readgametype(MYFILE *f, char *gtname) char *word; char *word2, *word2lwr = NULL; char *tmp; - char *gtconst; INT32 i, j; INT16 newgtidx = 0; @@ -1326,51 +1325,7 @@ static void readgametype(MYFILE *f, char *gtname) Gametype_Names[newgtidx] = Z_StrDup((const char *)gtname); // Write the constant name. - gtconst = Z_Malloc(strlen((const char *)gtname) + 3, PU_STATIC, NULL); - // Copy GT_ and the gametype name. - strcpy(gtconst, "GT_"); - strcat(gtconst, (const char *)gtname); - // Make uppercase. - strupr(gtconst); - // Remove characters. -#define REMOVECHAR(chr) \ - word = strchr(gtconst, chr); \ - while (word) \ - { \ - *word = '_'; \ - word = strchr(word, chr); \ - } - - // 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 - - // Finally, set the constant string. - Gametype_ConstantNames[newgtidx] = gtconst; + G_AddGametypeConstant(newgtidx, (const char *)gtname); // Update gametype_cons_t accordingly. G_UpdateGametypeSelections(); @@ -10439,6 +10394,20 @@ static inline int lib_freeslot(lua_State *L) } r++; } + else if (fastcmp(type, "TOL")) + { + if (lastcustomtol > 31) + CONS_Alert(CONS_WARNING, "Ran out of free typeoflevel slots!\n"); + else + { + UINT32 newtol = (1<') + REMOVECHAR('(') + REMOVECHAR(')') + REMOVECHAR('{') + REMOVECHAR('}') + REMOVECHAR('[') + REMOVECHAR(']') + REMOVECHAR(':') + REMOVECHAR(';') + REMOVECHAR(',') + REMOVECHAR('.') + +#undef REMOVECHAR + + // Finally, set the constant string. + Gametype_ConstantNames[gtype] = gtconst; +} + // // G_UpdateGametypeSelections // diff --git a/src/g_game.h b/src/g_game.h index bd0dc0180..de644756f 100644 --- a/src/g_game.h +++ b/src/g_game.h @@ -207,6 +207,7 @@ extern INT16 gametyperankings[NUMGAMETYPES]; void G_SetGametype(INT16 gametype); INT16 G_AddGametype(UINT32 rules); +void G_AddGametypeConstant(INT16 gtype, const char *newgtconst); void G_UpdateGametypeSelections(void); void G_AddTOL(UINT32 newtol, const char *tolname); void G_AddGametypeTOL(INT16 gtype, UINT32 newtol); diff --git a/src/lua_baselib.c b/src/lua_baselib.c index b68d16c2a..450da6576 100644 --- a/src/lua_baselib.c +++ b/src/lua_baselib.c @@ -12,6 +12,7 @@ #include "doomdef.h" #ifdef HAVE_BLUA +#include "fastcmp.h" #include "p_local.h" #include "p_setup.h" // So we can have P_SetupLevelSky #ifdef ESLOPE @@ -23,6 +24,7 @@ #include "m_random.h" #include "s_sound.h" #include "g_game.h" +#include "y_inter.h" #include "hu_stuff.h" // HU_AddChatText #include "console.h" #include "d_netcmd.h" // IsPlayerAdmin @@ -2632,6 +2634,133 @@ static int lib_sStartMusicCaption(lua_State *L) // G_GAME //////////// +// Copypasted from lib_cvRegisterVar :] +static int lib_gAddGametype(lua_State *L) +{ + const char *k; + lua_Integer i; + + const char *gtname = NULL; + const char *gtdescription = NULL; + INT16 newgtidx = 0; + UINT32 newgtrules = 0; + UINT32 newgttol = 0; + INT32 newgtpointlimit = 0; + INT32 newgttimelimit = 0; + UINT8 newgtleftcolor = 0; + UINT8 newgtrightcolor = 0; + INT16 newgtrankingstype = -1; + int newgtinttype = 0; + + luaL_checktype(L, 1, LUA_TTABLE); + lua_settop(L, 1); // Clear out all other possible arguments, leaving only the first one. + + if (!lua_lumploading) + return luaL_error(L, "This function cannot be called from within a hook or coroutine!"); + +#define FIELDERROR(f, e) luaL_error(L, "bad value for " LUA_QL(f) " in table passed to " LUA_QL("G_AddGametype") " (%s)", e); +#define TYPEERROR(f, t) FIELDERROR(f, va("%s expected, got %s", lua_typename(L, t), luaL_typename(L, -1))) + + lua_pushnil(L); + while (lua_next(L, 1)) { + // stack: gametype table, key/index, value + // 1 2 3 + i = 0; + k = NULL; + if (lua_isnumber(L, 2)) + i = lua_tointeger(L, 2); + else if (lua_isstring(L, 2)) + k = lua_tostring(L, 2); + + // Sorry, no gametype rules as key names. + if (i == 1 || (k && fasticmp(k, "name"))) { + if (!lua_isstring(L, 3)) + TYPEERROR("name", LUA_TSTRING) + gtname = Z_StrDup(lua_tostring(L, 3)); + } else if (i == 2 || (k && fasticmp(k, "rules"))) { + if (!lua_isnumber(L, 3)) + TYPEERROR("rules", LUA_TNUMBER) + newgtrules = (UINT32)lua_tointeger(L, 3); + } else if (i == 3 || (k && fasticmp(k, "typeoflevel"))) { + if (!lua_isnumber(L, 3)) + TYPEERROR("typeoflevel", LUA_TNUMBER) + newgttol = (UINT32)lua_tointeger(L, 3); + } else if (i == 4 || (k && fasticmp(k, "rankingtype"))) { + if (!lua_isnumber(L, 3)) + TYPEERROR("rankingtype", LUA_TNUMBER) + newgtrankingstype = (INT16)lua_tointeger(L, 3); + } else if (i == 5 || (k && fasticmp(k, "intermissiontype"))) { + if (!lua_isnumber(L, 3)) + TYPEERROR("intermissiontype", LUA_TNUMBER) + newgtinttype = (int)lua_tointeger(L, 3); + } else if (i == 6 || (k && fasticmp(k, "defaultpointlimit"))) { + if (!lua_isnumber(L, 3)) + TYPEERROR("defaultpointlimit", LUA_TNUMBER) + newgtpointlimit = (INT32)lua_tointeger(L, 3); + } else if (i == 7 || (k && fasticmp(k, "defaulttimelimit"))) { + if (!lua_isnumber(L, 3)) + TYPEERROR("defaulttimelimit", LUA_TNUMBER) + newgttimelimit = (INT32)lua_tointeger(L, 3); + } else if (i == 8 || (k && fasticmp(k, "description"))) { + if (!lua_isstring(L, 3)) + TYPEERROR("description", LUA_TSTRING) + gtdescription = Z_StrDup(lua_tostring(L, 3)); + } else if (i == 9 || (k && fasticmp(k, "headerleftcolor"))) { + if (!lua_isnumber(L, 3)) + TYPEERROR("headerleftcolor", LUA_TNUMBER) + newgtleftcolor = (UINT8)lua_tointeger(L, 3); + } else if (i == 10 || (k && fasticmp(k, "headerrightcolor"))) { + if (!lua_isnumber(L, 3)) + TYPEERROR("headerrightcolor", LUA_TNUMBER) + newgtrightcolor = (UINT8)lua_tointeger(L, 3); + // Key name specified + } else if ((!i) && (k && fasticmp(k, "headercolor"))) { + if (!lua_isnumber(L, 3)) + TYPEERROR("headercolor", LUA_TNUMBER) + newgtleftcolor = newgtrightcolor = (UINT8)lua_tointeger(L, 3); + } + lua_pop(L, 1); + } + +#undef FIELDERROR +#undef TYPEERROR + + // pop gametype table + lua_pop(L, 1); + + // Set defaults + if (gtname == NULL) + gtname = Z_StrDup("Unnamed gametype"); + if (gtdescription == NULL) + gtdescription = Z_StrDup("???"); + + // Add the new gametype + newgtidx = G_AddGametype(newgtrules); + G_AddGametypeTOL(newgtidx, newgttol); + G_SetGametypeDescription(newgtidx, (char *)gtdescription, newgtleftcolor, newgtrightcolor); + + // Not covered by G_AddGametype alone. + if (newgtrankingstype == -1) + newgtrankingstype = newgtidx; + gametyperankings[newgtidx] = newgtrankingstype; + intermissiontypes[newgtidx] = newgtinttype; + pointlimits[newgtidx] = newgtpointlimit; + timelimits[newgtidx] = newgttimelimit; + + // Write the new gametype name. + Gametype_Names[newgtidx] = gtname; + + // Write the constant name. + G_AddGametypeConstant(newgtidx, gtname); + + // Update gametype_cons_t accordingly. + G_UpdateGametypeSelections(); + + // done + CONS_Printf("Added gametype %s\n", Gametype_Names[newgtidx]); + return 0; +} + static int lib_gBuildMapName(lua_State *L) { INT32 map = luaL_optinteger(L, 1, gamemap); @@ -2997,6 +3126,7 @@ static luaL_Reg lib[] = { {"S_StartMusicCaption", lib_sStartMusicCaption}, // g_game + {"G_AddGametype", lib_gAddGametype}, {"G_BuildMapName",lib_gBuildMapName}, {"G_DoReborn",lib_gDoReborn}, {"G_SetCustomExitVars",lib_gSetCustomExitVars}, From 019e52a4f431ad93075a719bab64a4d0d80fa22d Mon Sep 17 00:00:00 2001 From: Jaime Passos Date: Thu, 19 Dec 2019 02:17:03 -0300 Subject: [PATCH 287/746] allow CTF spawns in GTR_TEAMS gametype rule --- 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 7c00f0131..96a7ed423 100644 --- a/src/g_game.c +++ b/src/g_game.c @@ -2574,7 +2574,7 @@ void G_SpawnPlayer(INT32 playernum, boolean starpost) // -- CTF -- // Order: CTF->DM->Coop - if ((gametyperules & GTR_TEAMFLAGS) && players[playernum].ctfteam) + if ((gametyperules & (GTR_TEAMFLAGS|GTR_TEAMS)) && players[playernum].ctfteam) { if (!(spawnpoint = G_FindCTFStart(playernum)) // find a CTF start && !(spawnpoint = G_FindMatchStart(playernum))) // find a DM start From ebdd9c62572076bcd4dd151ebba1f5bf47d40a1a Mon Sep 17 00:00:00 2001 From: Jaime Passos Date: Thu, 19 Dec 2019 02:20:49 -0300 Subject: [PATCH 288/746] fix warnings --- src/g_game.c | 3 ++- src/lua_baselib.c | 4 +++- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/src/g_game.c b/src/g_game.c index 96a7ed423..0c085c84e 100644 --- a/src/g_game.c +++ b/src/g_game.c @@ -3220,7 +3220,8 @@ void G_UpdateGametypeSelections(void) // void G_SetGametypeDescription(INT16 gtype, char *descriptiontext, UINT8 leftcolor, UINT8 rightcolor) { - strncpy(gametypedesc[gtype].notes, descriptiontext, 441); + if (descriptiontext != NULL) + strncpy(gametypedesc[gtype].notes, descriptiontext, 441); gametypedesc[gtype].col[0] = leftcolor; gametypedesc[gtype].col[1] = rightcolor; } diff --git a/src/lua_baselib.c b/src/lua_baselib.c index 7ff967b40..5f9d3dbf6 100644 --- a/src/lua_baselib.c +++ b/src/lua_baselib.c @@ -24,6 +24,7 @@ #include "m_random.h" #include "s_sound.h" #include "g_game.h" +#include "m_menu.h" #include "y_inter.h" #include "hu_stuff.h" // HU_AddChatText #include "console.h" @@ -2737,7 +2738,8 @@ static int lib_gAddGametype(lua_State *L) // Add the new gametype newgtidx = G_AddGametype(newgtrules); G_AddGametypeTOL(newgtidx, newgttol); - G_SetGametypeDescription(newgtidx, (char *)gtdescription, newgtleftcolor, newgtrightcolor); + G_SetGametypeDescription(newgtidx, NULL, newgtleftcolor, newgtrightcolor); + strncpy(gametypedesc[newgtidx].notes, gtdescription, 441); // Not covered by G_AddGametype alone. if (newgtrankingstype == -1) From ce0e4201b810c1cdd2d3a19f99bfe485f6d2ac3b Mon Sep 17 00:00:00 2001 From: Jaime Passos Date: Thu, 19 Dec 2019 02:26:17 -0300 Subject: [PATCH 289/746] GTR_DEATHMATCHSTARTS --- src/dehacked.c | 1 + src/doomstat.h | 25 +++++++++++++------------ src/g_game.c | 2 +- 3 files changed, 15 insertions(+), 13 deletions(-) diff --git a/src/dehacked.c b/src/dehacked.c index 9b4656627..dedeeb87f 100644 --- a/src/dehacked.c +++ b/src/dehacked.c @@ -8874,6 +8874,7 @@ static const char *const GAMETYPERULE_LIST[] = { "PITYSHIELD", "DEATHPENALTY", "NOSPECTATORSPAWN", + "DEATHMATCHSTARTS", "SPECIALSTAGES", "EMERALDTOKENS", "EMERALDHUNT", diff --git a/src/doomstat.h b/src/doomstat.h index 6730254a2..d24de58f1 100644 --- a/src/doomstat.h +++ b/src/doomstat.h @@ -411,18 +411,19 @@ enum GameTypeRules GTR_PITYSHIELD = 1<<14, // Award pity shield GTR_DEATHPENALTY = 1<<15, // Death score penalty GTR_NOSPECTATORSPAWN = 1<<16, // For use with GTR_SPECTATORS - spawn in the map instead of with the spectators - GTR_SPECIALSTAGES = 1<<17, // Allow special stages - GTR_EMERALDTOKENS = 1<<18, // Spawn emerald tokens - GTR_EMERALDHUNT = 1<<19, // Emerald Hunt - GTR_SPAWNENEMIES = 1<<20, // Spawn enemies - GTR_ALLOWEXIT = 1<<21, // Allow exit sectors - GTR_CAMPAIGN = 1<<22, // Linear Co-op map progression. Don't allow random maps. - GTR_NOGAMEEND = 1<<23, // Don't end the game. That is, wrap around the maps instead of starting the ending. - GTR_ROUNDENDMESSAGE = 1<<24, // Prints "The round has ended." into the console - GTR_NOTITLECARD = 1<<25, // Don't show the title card - GTR_POINTLIMIT = 1<<26, // Ringslinger point limit - GTR_TIMELIMIT = 1<<27, // Ringslinger time limit - GTR_OVERTIME = 1<<28, // Allow overtime + GTR_DEATHMATCHSTARTS = 1<<17, // Use deathmatch starts + GTR_SPECIALSTAGES = 1<<18, // Allow special stages + GTR_EMERALDTOKENS = 1<<19, // Spawn emerald tokens + GTR_EMERALDHUNT = 1<<20, // Emerald Hunt + GTR_SPAWNENEMIES = 1<<21, // Spawn enemies + GTR_ALLOWEXIT = 1<<22, // Allow exit sectors + GTR_CAMPAIGN = 1<<23, // Linear Co-op map progression. Don't allow random maps. + GTR_NOGAMEEND = 1<<24, // Don't end the game. That is, wrap around the maps instead of starting the ending. + GTR_ROUNDENDMESSAGE = 1<<25, // Prints "The round has ended." into the console + GTR_NOTITLECARD = 1<<26, // Don't show the title card + GTR_POINTLIMIT = 1<<27, // Ringslinger point limit + GTR_TIMELIMIT = 1<<28, // Ringslinger time limit + GTR_OVERTIME = 1<<29, // Allow overtime }; // String names for gametypes diff --git a/src/g_game.c b/src/g_game.c index 0c085c84e..9c51e4741 100644 --- a/src/g_game.c +++ b/src/g_game.c @@ -2583,7 +2583,7 @@ void G_SpawnPlayer(INT32 playernum, boolean starpost) // -- DM/Tag/CTF-spectator/etc -- // Order: DM->CTF->Coop - else if (gametype == GT_MATCH || gametype == GT_TEAMMATCH || gametype == GT_CTF + 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))) { if (!(spawnpoint = G_FindMatchStart(playernum)) // find a DM start From 1771c7c8ce163fe52e960bbccfb94eea9d48326b Mon Sep 17 00:00:00 2001 From: Alam Ed Arias Date: Thu, 19 Dec 2019 10:25:54 -0500 Subject: [PATCH 290/746] Revert "Travis yflip error" This reverts commit 2a9a2c0f021b964f2955ec75f3526f638ae1e69d. --- src/hardware/r_opengl/r_opengl.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/hardware/r_opengl/r_opengl.c b/src/hardware/r_opengl/r_opengl.c index 0887a0fb5..129bf5678 100644 --- a/src/hardware/r_opengl/r_opengl.c +++ b/src/hardware/r_opengl/r_opengl.c @@ -1519,7 +1519,7 @@ static void gld_BuildSky(int row_count, int col_count) vertex_p = &vbo->data[0]; vbo->loopcount = 0; - for (yflip = 0; (UINT8)yflip < 2; yflip++) + for (yflip = 0; yflip < 2; yflip++) { vbo->loops[vbo->loopcount].mode = GL_TRIANGLE_FAN; vbo->loops[vbo->loopcount].vertexindex = vertex_p - &vbo->data[0]; From 768080977fea335d7d4da77fc434ba495464ca04 Mon Sep 17 00:00:00 2001 From: Jaime Passos Date: Thu, 19 Dec 2019 15:47:37 -0300 Subject: [PATCH 291/746] Remove GTR_ROUNDENDMESSAGE --- src/dehacked.c | 1 - src/doomstat.h | 9 ++++----- src/g_game.c | 16 ++++++++-------- 3 files changed, 12 insertions(+), 14 deletions(-) diff --git a/src/dehacked.c b/src/dehacked.c index dedeeb87f..84abc9139 100644 --- a/src/dehacked.c +++ b/src/dehacked.c @@ -8882,7 +8882,6 @@ static const char *const GAMETYPERULE_LIST[] = { "ALLOWEXIT", "CAMPAIGN", "NOGAMEEND", - "ROUNDENDMESSAGE", "NOTITLECARD", "POINTLIMIT", "TIMELIMIT", diff --git a/src/doomstat.h b/src/doomstat.h index d24de58f1..58d9d4896 100644 --- a/src/doomstat.h +++ b/src/doomstat.h @@ -419,11 +419,10 @@ enum GameTypeRules GTR_ALLOWEXIT = 1<<22, // Allow exit sectors GTR_CAMPAIGN = 1<<23, // Linear Co-op map progression. Don't allow random maps. GTR_NOGAMEEND = 1<<24, // Don't end the game. That is, wrap around the maps instead of starting the ending. - GTR_ROUNDENDMESSAGE = 1<<25, // Prints "The round has ended." into the console - GTR_NOTITLECARD = 1<<26, // Don't show the title card - GTR_POINTLIMIT = 1<<27, // Ringslinger point limit - GTR_TIMELIMIT = 1<<28, // Ringslinger time limit - GTR_OVERTIME = 1<<29, // Allow overtime + GTR_NOTITLECARD = 1<<25, // Don't show the title card + GTR_POINTLIMIT = 1<<26, // Ringslinger point limit + GTR_TIMELIMIT = 1<<27, // Ringslinger time limit + GTR_OVERTIME = 1<<28, // Allow overtime }; // String names for gametypes diff --git a/src/g_game.c b/src/g_game.c index 9c51e4741..80fa42dea 100644 --- a/src/g_game.c +++ b/src/g_game.c @@ -3036,7 +3036,7 @@ void G_ExitLevel(void) CV_SetValue(&cv_teamscramble, cv_scrambleonchange.value); } - if (gametyperules & GTR_ROUNDENDMESSAGE) + if (!(gametyperules & GTR_CAMPAIGN)) CONS_Printf(M_GetText("The round has ended.\n")); // Remove CEcho text on round end. @@ -3090,22 +3090,22 @@ UINT32 gametypedefaultrules[NUMGAMETYPES] = // Co-op GTR_PLATFORM|GTR_CAMPAIGN|GTR_LIVES|GTR_CHASECAM|GTR_EMERALDHUNT|GTR_SPAWNENEMIES|GTR_ALLOWEXIT|GTR_EMERALDTOKENS|GTR_SPECIALSTAGES, // Competition - GTR_PLATFORM|GTR_NOGAMEEND|GTR_LIVES|GTR_RACE|GTR_CHASECAM|GTR_SPAWNENEMIES|GTR_ALLOWEXIT|GTR_ROUNDENDMESSAGE|GTR_EMERALDTOKENS, + GTR_PLATFORM|GTR_NOGAMEEND|GTR_LIVES|GTR_RACE|GTR_CHASECAM|GTR_SPAWNENEMIES|GTR_ALLOWEXIT|GTR_EMERALDTOKENS, // Race - GTR_PLATFORM|GTR_NOGAMEEND|GTR_RACE|GTR_CHASECAM|GTR_SPAWNENEMIES|GTR_ALLOWEXIT|GTR_ROUNDENDMESSAGE, + GTR_PLATFORM|GTR_NOGAMEEND|GTR_RACE|GTR_CHASECAM|GTR_SPAWNENEMIES|GTR_ALLOWEXIT, // Match - GTR_RINGSLINGER|GTR_SPECTATORS|GTR_POINTLIMIT|GTR_TIMELIMIT|GTR_EMERALDS|GTR_PITYSHIELD|GTR_DEATHPENALTY|GTR_ROUNDENDMESSAGE, + GTR_RINGSLINGER|GTR_SPECTATORS|GTR_POINTLIMIT|GTR_TIMELIMIT|GTR_EMERALDS|GTR_PITYSHIELD|GTR_DEATHPENALTY, // Team Match - GTR_RINGSLINGER|GTR_SPECTATORS|GTR_TEAMS|GTR_POINTLIMIT|GTR_TIMELIMIT|GTR_PITYSHIELD|GTR_ROUNDENDMESSAGE, + GTR_RINGSLINGER|GTR_SPECTATORS|GTR_TEAMS|GTR_POINTLIMIT|GTR_TIMELIMIT|GTR_PITYSHIELD, // Tag - GTR_RINGSLINGER|GTR_TAG|GTR_SPECTATORS|GTR_POINTLIMIT|GTR_TIMELIMIT|GTR_HIDETIME|GTR_BLINDFOLDED|GTR_ROUNDENDMESSAGE, + GTR_RINGSLINGER|GTR_TAG|GTR_SPECTATORS|GTR_POINTLIMIT|GTR_TIMELIMIT|GTR_HIDETIME|GTR_BLINDFOLDED, // Hide and Seek - GTR_RINGSLINGER|GTR_TAG|GTR_SPECTATORS|GTR_POINTLIMIT|GTR_TIMELIMIT|GTR_HIDETIME|GTR_BLINDFOLDED|GTR_ROUNDENDMESSAGE, + GTR_RINGSLINGER|GTR_TAG|GTR_SPECTATORS|GTR_POINTLIMIT|GTR_TIMELIMIT|GTR_HIDETIME|GTR_BLINDFOLDED, // CTF - GTR_RINGSLINGER|GTR_SPECTATORS|GTR_TEAMS|GTR_POINTLIMIT|GTR_TIMELIMIT|GTR_EMERALDS|GTR_TEAMFLAGS|GTR_PITYSHIELD|GTR_ROUNDENDMESSAGE, + GTR_RINGSLINGER|GTR_SPECTATORS|GTR_TEAMS|GTR_POINTLIMIT|GTR_TIMELIMIT|GTR_EMERALDS|GTR_TEAMFLAGS|GTR_PITYSHIELD, }; // From 6d7262e9855409b128dbeed1495ba0a2cca39be6 Mon Sep 17 00:00:00 2001 From: Jaime Passos Date: Thu, 19 Dec 2019 16:05:03 -0300 Subject: [PATCH 292/746] Remove GTR_PLATFORM --- src/dehacked.c | 2 +- src/doomstat.h | 2 +- src/g_game.c | 9 ++++----- 3 files changed, 6 insertions(+), 7 deletions(-) diff --git a/src/dehacked.c b/src/dehacked.c index 84abc9139..e078d2f69 100644 --- a/src/dehacked.c +++ b/src/dehacked.c @@ -8857,7 +8857,7 @@ static const char *const PLAYERFLAG_LIST[] = { }; static const char *const GAMETYPERULE_LIST[] = { - "PLATFORM", + "\x01", "TAG", "RINGSLINGER", "SPECTATORS", diff --git a/src/doomstat.h b/src/doomstat.h index 58d9d4896..0abc6a467 100644 --- a/src/doomstat.h +++ b/src/doomstat.h @@ -389,7 +389,7 @@ enum GameType // Game type rules enum GameTypeRules { - GTR_PLATFORM = 1, // Co-op, Competition, and Race + GTR_SORRYNOTHING = 1, GTR_TAG = 1<<1, // Tag and Hide and Seek GTR_RINGSLINGER = 1<<2, // Not Co-op, not Competition, and not Race (overriden by cv_ringslinger) GTR_SPECTATORS = 1<<3, // Not Co-op, not Competition, and not Race diff --git a/src/g_game.c b/src/g_game.c index 80fa42dea..2e25b5c2f 100644 --- a/src/g_game.c +++ b/src/g_game.c @@ -3088,11 +3088,11 @@ const char *Gametype_ConstantNames[NUMGAMETYPES] = UINT32 gametypedefaultrules[NUMGAMETYPES] = { // Co-op - GTR_PLATFORM|GTR_CAMPAIGN|GTR_LIVES|GTR_CHASECAM|GTR_EMERALDHUNT|GTR_SPAWNENEMIES|GTR_ALLOWEXIT|GTR_EMERALDTOKENS|GTR_SPECIALSTAGES, + GTR_CAMPAIGN|GTR_LIVES|GTR_CHASECAM|GTR_SPAWNENEMIES|GTR_ALLOWEXIT|GTR_EMERALDHUNT|GTR_EMERALDTOKENS|GTR_SPECIALSTAGES, // Competition - GTR_PLATFORM|GTR_NOGAMEEND|GTR_LIVES|GTR_RACE|GTR_CHASECAM|GTR_SPAWNENEMIES|GTR_ALLOWEXIT|GTR_EMERALDTOKENS, + GTR_RACE|GTR_LIVES|GTR_CHASECAM|GTR_SPAWNENEMIES|GTR_EMERALDTOKENS|GTR_ALLOWEXIT|GTR_NOGAMEEND, // Race - GTR_PLATFORM|GTR_NOGAMEEND|GTR_RACE|GTR_CHASECAM|GTR_SPAWNENEMIES|GTR_ALLOWEXIT, + GTR_RACE|GTR_CHASECAM|GTR_SPAWNENEMIES|GTR_ALLOWEXIT|GTR_NOGAMEEND, // Match GTR_RINGSLINGER|GTR_SPECTATORS|GTR_POINTLIMIT|GTR_TIMELIMIT|GTR_EMERALDS|GTR_PITYSHIELD|GTR_DEATHPENALTY, @@ -3378,8 +3378,7 @@ boolean G_RingSlingerGametype(void) // boolean G_PlatformGametype(void) { - return (gametyperules & GTR_PLATFORM); - //return (gametype == GT_COOP || gametype == GT_RACE || gametype == GT_COMPETITION); + return (!G_RingSlingerGametype()); } // From f4bb618f9387f1045a7ae03433b2858adead2a84 Mon Sep 17 00:00:00 2001 From: Jaime Passos Date: Thu, 19 Dec 2019 16:12:10 -0300 Subject: [PATCH 293/746] Organise rules --- src/dehacked.c | 19 ++++++++-------- src/doomstat.h | 60 +++++++++++++++++++++++--------------------------- src/g_game.c | 4 ++-- src/p_mobj.c | 2 +- 4 files changed, 39 insertions(+), 46 deletions(-) diff --git a/src/dehacked.c b/src/dehacked.c index e078d2f69..a4467c699 100644 --- a/src/dehacked.c +++ b/src/dehacked.c @@ -8857,19 +8857,21 @@ static const char *const PLAYERFLAG_LIST[] = { }; static const char *const GAMETYPERULE_LIST[] = { - "\x01", - "TAG", + "CAMPAIGN", "RINGSLINGER", "SPECTATORS", - "TEAMS", - "LIVES", - "RACE", - "CHASECAM", "FRIENDLYFIRE", + "LIVES", + "TEAMS", + "RACE", + "TAG", + "POINTLIMIT", + "TIMELIMIT", "HIDETIME", "HIDEFROZEN", "BLINDFOLDED", - "EMERALDS", + "CHASECAM", + "MATCHEMERALDS", "TEAMFLAGS", "PITYSHIELD", "DEATHPENALTY", @@ -8880,11 +8882,8 @@ static const char *const GAMETYPERULE_LIST[] = { "EMERALDHUNT", "SPAWNENEMIES", "ALLOWEXIT", - "CAMPAIGN", "NOGAMEEND", "NOTITLECARD", - "POINTLIMIT", - "TIMELIMIT", "OVERTIME", NULL }; diff --git a/src/doomstat.h b/src/doomstat.h index 0abc6a467..c8d3b492a 100644 --- a/src/doomstat.h +++ b/src/doomstat.h @@ -389,40 +389,34 @@ enum GameType // Game type rules enum GameTypeRules { - GTR_SORRYNOTHING = 1, - GTR_TAG = 1<<1, // Tag and Hide and Seek - GTR_RINGSLINGER = 1<<2, // Not Co-op, not Competition, and not Race (overriden by cv_ringslinger) - GTR_SPECTATORS = 1<<3, // Not Co-op, not Competition, and not Race - GTR_TEAMS = 1<<4, // Team Match, CTF - GTR_LIVES = 1<<5, // A lot of special cases in G_GametypeUsesLives actually, but just Co-op and Competition + 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_RACE = 1<<6, // Race and Competition - - // Lactozilla - // Awesome! Those are new game type rules provided by yours truly to allow for more - // flexibility! Those will replace some straight-up gametype checks scattered around the source code! - - GTR_CHASECAM = 1<<7, // Prefer chasecam at map load (All platform gametypes) - GTR_FRIENDLYFIRE = 1<<8, // Always allow friendly fire - GTR_HIDETIME = 1<<9, // Hide time (Tag and Hide and Seek) - GTR_HIDEFROZEN = 1<<10, // Frozen after hide time (Hide and Seek, but not Tag) - GTR_BLINDFOLDED = 1<<11, // Blindfolded view (Tag and Hide and Seek) - GTR_EMERALDS = 1<<12, // Ringslinger emeralds (Match and CTF) - GTR_TEAMFLAGS = 1<<13, // Gametype has team flags (CTF) - GTR_PITYSHIELD = 1<<14, // Award pity shield - GTR_DEATHPENALTY = 1<<15, // Death score penalty - GTR_NOSPECTATORSPAWN = 1<<16, // For use with GTR_SPECTATORS - spawn in the map instead of with the spectators - GTR_DEATHMATCHSTARTS = 1<<17, // Use deathmatch starts - GTR_SPECIALSTAGES = 1<<18, // Allow special stages - GTR_EMERALDTOKENS = 1<<19, // Spawn emerald tokens - GTR_EMERALDHUNT = 1<<20, // Emerald Hunt - GTR_SPAWNENEMIES = 1<<21, // Spawn enemies - GTR_ALLOWEXIT = 1<<22, // Allow exit sectors - GTR_CAMPAIGN = 1<<23, // Linear Co-op map progression. Don't allow random maps. - GTR_NOGAMEEND = 1<<24, // Don't end the game. That is, wrap around the maps instead of starting the ending. - GTR_NOTITLECARD = 1<<25, // Don't show the title card - GTR_POINTLIMIT = 1<<26, // Ringslinger point limit - GTR_TIMELIMIT = 1<<27, // Ringslinger time limit - GTR_OVERTIME = 1<<28, // Allow overtime + 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_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_CHASECAM = 1<<13, // Prefer chasecam at map load (All platform gametypes) + GTR_MATCHEMERALDS = 1<<14, // Ringslinger emeralds (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, // For 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_NOGAMEEND = 1<<25, // Don't end the game. That is, wrap around the maps instead of starting the ending. + GTR_NOTITLECARD = 1<<26, // Don't show the title card + GTR_OVERTIME = 1<<27, // Allow overtime }; // String names for gametypes diff --git a/src/g_game.c b/src/g_game.c index 2e25b5c2f..47e1dc9f0 100644 --- a/src/g_game.c +++ b/src/g_game.c @@ -3095,7 +3095,7 @@ UINT32 gametypedefaultrules[NUMGAMETYPES] = GTR_RACE|GTR_CHASECAM|GTR_SPAWNENEMIES|GTR_ALLOWEXIT|GTR_NOGAMEEND, // Match - GTR_RINGSLINGER|GTR_SPECTATORS|GTR_POINTLIMIT|GTR_TIMELIMIT|GTR_EMERALDS|GTR_PITYSHIELD|GTR_DEATHPENALTY, + GTR_RINGSLINGER|GTR_SPECTATORS|GTR_POINTLIMIT|GTR_TIMELIMIT|GTR_MATCHEMERALDS|GTR_PITYSHIELD|GTR_DEATHPENALTY, // Team Match GTR_RINGSLINGER|GTR_SPECTATORS|GTR_TEAMS|GTR_POINTLIMIT|GTR_TIMELIMIT|GTR_PITYSHIELD, @@ -3105,7 +3105,7 @@ UINT32 gametypedefaultrules[NUMGAMETYPES] = GTR_RINGSLINGER|GTR_TAG|GTR_SPECTATORS|GTR_POINTLIMIT|GTR_TIMELIMIT|GTR_HIDETIME|GTR_BLINDFOLDED, // CTF - GTR_RINGSLINGER|GTR_SPECTATORS|GTR_TEAMS|GTR_POINTLIMIT|GTR_TIMELIMIT|GTR_EMERALDS|GTR_TEAMFLAGS|GTR_PITYSHIELD, + GTR_RINGSLINGER|GTR_SPECTATORS|GTR_TEAMS|GTR_POINTLIMIT|GTR_TIMELIMIT|GTR_MATCHEMERALDS|GTR_TEAMFLAGS|GTR_PITYSHIELD, }; // diff --git a/src/p_mobj.c b/src/p_mobj.c index 69d352c5b..dcf3a9127 100644 --- a/src/p_mobj.c +++ b/src/p_mobj.c @@ -11774,7 +11774,7 @@ You should think about modifying the deathmatch starts to take full advantage of if (!cv_powerstones.value) return; - if (!(gametyperules & GTR_EMERALDS)) + if (!(gametyperules & GTR_MATCHEMERALDS)) return; runemeraldmanager = true; From 7efd9662d1c2289451cb54dedefe605a840c9eef Mon Sep 17 00:00:00 2001 From: Jaime Passos Date: Thu, 19 Dec 2019 16:13:27 -0300 Subject: [PATCH 294/746] Remove GTR_NOGAMEEND --- src/dehacked.c | 1 - src/doomstat.h | 5 ++--- src/g_game.c | 6 +++--- 3 files changed, 5 insertions(+), 7 deletions(-) diff --git a/src/dehacked.c b/src/dehacked.c index a4467c699..6bad6a6dd 100644 --- a/src/dehacked.c +++ b/src/dehacked.c @@ -8882,7 +8882,6 @@ static const char *const GAMETYPERULE_LIST[] = { "EMERALDHUNT", "SPAWNENEMIES", "ALLOWEXIT", - "NOGAMEEND", "NOTITLECARD", "OVERTIME", NULL diff --git a/src/doomstat.h b/src/doomstat.h index c8d3b492a..0ab8c1bff 100644 --- a/src/doomstat.h +++ b/src/doomstat.h @@ -414,9 +414,8 @@ enum GameTypeRules GTR_EMERALDHUNT = 1<<22, // Emerald Hunt GTR_SPAWNENEMIES = 1<<23, // Spawn enemies GTR_ALLOWEXIT = 1<<24, // Allow exit sectors - GTR_NOGAMEEND = 1<<25, // Don't end the game. That is, wrap around the maps instead of starting the ending. - GTR_NOTITLECARD = 1<<26, // Don't show the title card - GTR_OVERTIME = 1<<27, // Allow overtime + GTR_NOTITLECARD = 1<<25, // Don't show the title card + GTR_OVERTIME = 1<<26, // Allow overtime }; // String names for gametypes diff --git a/src/g_game.c b/src/g_game.c index 47e1dc9f0..2367f23f4 100644 --- a/src/g_game.c +++ b/src/g_game.c @@ -3090,9 +3090,9 @@ UINT32 gametypedefaultrules[NUMGAMETYPES] = // Co-op GTR_CAMPAIGN|GTR_LIVES|GTR_CHASECAM|GTR_SPAWNENEMIES|GTR_ALLOWEXIT|GTR_EMERALDHUNT|GTR_EMERALDTOKENS|GTR_SPECIALSTAGES, // Competition - GTR_RACE|GTR_LIVES|GTR_CHASECAM|GTR_SPAWNENEMIES|GTR_EMERALDTOKENS|GTR_ALLOWEXIT|GTR_NOGAMEEND, + GTR_RACE|GTR_LIVES|GTR_CHASECAM|GTR_SPAWNENEMIES|GTR_EMERALDTOKENS|GTR_ALLOWEXIT, // Race - GTR_RACE|GTR_CHASECAM|GTR_SPAWNENEMIES|GTR_ALLOWEXIT|GTR_NOGAMEEND, + GTR_RACE|GTR_CHASECAM|GTR_SPAWNENEMIES|GTR_ALLOWEXIT, // Match GTR_RINGSLINGER|GTR_SPECTATORS|GTR_POINTLIMIT|GTR_TIMELIMIT|GTR_MATCHEMERALDS|GTR_PITYSHIELD|GTR_DEATHPENALTY, @@ -3583,7 +3583,7 @@ static void G_DoCompleted(void) I_Error("Followed map %d to invalid map %d\n", prevmap + 1, nextmap + 1); // wrap around in race - if (nextmap >= 1100-1 && nextmap <= 1102-1 && (gametyperules & GTR_NOGAMEEND)) + if (nextmap >= 1100-1 && nextmap <= 1102-1 && !(gametyperules & GTR_CAMPAIGN)) nextmap = (INT16)(spstage_start-1); if ((gottoken = ((gametyperules & GTR_SPECIALSTAGES) && token))) From a39b6a12861242ce7aaca6a6217eae5dc7e734bb Mon Sep 17 00:00:00 2001 From: Steel Titanium Date: Thu, 19 Dec 2019 01:14:34 -0500 Subject: [PATCH 295/746] Allow access to bluescore and redscore --- src/dehacked.c | 8 ++++++++ src/lua_script.c | 11 +++++++++++ 2 files changed, 19 insertions(+) diff --git a/src/dehacked.c b/src/dehacked.c index 6bad6a6dd..8633a31c3 100644 --- a/src/dehacked.c +++ b/src/dehacked.c @@ -10822,6 +10822,12 @@ static inline int lib_getenum(lua_State *L) } else if (fastcmp(word,"paused")) { lua_pushboolean(L, paused); return 1; + } else if (fastcmp(word,"bluescore")) { + lua_pushinteger(L, bluescore); + return 1; + } else if (fastcmp(word,"redscore")) { + lua_pushinteger(L, redscore); + return 1; // begin map vars } else if (fastcmp(word,"spstage_start")) { lua_pushinteger(L, spstage_start); @@ -11035,6 +11041,8 @@ static int lib_getActionName(lua_State *L) return luaL_typerror(L, 1, "action userdata or Lua function"); } + + int LUA_SOCLib(lua_State *L) { lua_register(L,"freeslot",lib_freeslot); diff --git a/src/lua_script.c b/src/lua_script.c index fe3c2f10d..13592815b 100644 --- a/src/lua_script.c +++ b/src/lua_script.c @@ -106,6 +106,17 @@ static int noglobals(lua_State *L) return 0; } + if (fastcmp(csname,"redscore")) + { + redscore = (UINT32)luaL_checkinteger(L, 2); + return 0; + } + else if (fastcmp(csname,"bluescore")) + { + bluescore = (UINT32)luaL_checkinteger(L, 2); + return 0; + } + Z_Free(name); return luaL_error(L, "Implicit global " LUA_QS " prevented. Create a local variable instead.", csname); } From 9b2b526eb49f12e62ed10ea3c9cea7e47f0d04a4 Mon Sep 17 00:00:00 2001 From: Jaime Passos Date: Thu, 19 Dec 2019 16:22:55 -0300 Subject: [PATCH 296/746] Removing commented out code --- src/dehacked.c | 2 +- src/g_game.c | 23 +++-------------------- 2 files changed, 4 insertions(+), 21 deletions(-) diff --git a/src/dehacked.c b/src/dehacked.c index 8633a31c3..12014b8b6 100644 --- a/src/dehacked.c +++ b/src/dehacked.c @@ -1284,7 +1284,7 @@ static void readgametype(MYFILE *f, char *gtname) UINT32 wordgt = 0; for (j = 0; GAMETYPERULE_LIST[j]; j++) if (fastcmp(word, GAMETYPERULE_LIST[j])) { - if (!j) // GTR_PLATFORM + if (!j) // GTR_CAMPAIGN wordgt |= 1; else wordgt |= (1< Date: Thu, 19 Dec 2019 16:31:38 -0300 Subject: [PATCH 297/746] Make G_PlatformGametype only check the gametype rules, to avoid unintended side effects --- 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 582d61989..3cc11c4d1 100644 --- a/src/g_game.c +++ b/src/g_game.c @@ -3374,7 +3374,7 @@ boolean G_RingSlingerGametype(void) // boolean G_PlatformGametype(void) { - return (!G_RingSlingerGametype()); + return (!(gametyperules & GTR_RINGSLINGER)); } // From 4ad1727b66770cf9a8467b9c13a4373d31f3ee40 Mon Sep 17 00:00:00 2001 From: Jaime Passos Date: Thu, 19 Dec 2019 17:06:07 -0300 Subject: [PATCH 298/746] Don't spawn End Level Signs without the GTR_ALLOWEXIT rule --- src/p_mobj.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/p_mobj.c b/src/p_mobj.c index dcf3a9127..6ee615cdd 100644 --- a/src/p_mobj.c +++ b/src/p_mobj.c @@ -11838,8 +11838,10 @@ You should think about modifying the deathmatch starts to take full advantage of } } - if (!G_PlatformGametype() && (i == MT_SIGN || i == MT_STARPOST)) - return; // Don't spawn exit signs or starposts in wrong game modes + if (!(gametyperules & GTR_ALLOWEXIT) && i == MT_SIGN) + return; // Don't spawn exit signs without the necessary gametype rule + if (!G_PlatformGametype() && i == MT_STARPOST) + return; // Don't spawn starposts in wrong game modes if (modeattacking) // Record Attack special stuff { From 77747c66df62e4c110c899f3b8be252a0c0db0aa Mon Sep 17 00:00:00 2001 From: James R Date: Tue, 1 Oct 2019 23:52:08 -0700 Subject: [PATCH 299/746] Fix switching to software Would show a black screen for me on Linux. My suspsicion is that some things are not initialized with just VID_CheckRenderer. --- src/screen.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/screen.c b/src/screen.c index f739a5177..b21b6815a 100644 --- a/src/screen.c +++ b/src/screen.c @@ -203,6 +203,8 @@ void SCR_SetMode(void) needpatchflush = true; needpatchrecache = true; VID_CheckRenderer(); + if (!setmodeneeded) + VID_SetMode(vid.modenum); } if (setmodeneeded) From 4e349cbd0f527a3c2d7247d4517a12ab8fcfa3ad Mon Sep 17 00:00:00 2001 From: Jaime Passos Date: Thu, 19 Dec 2019 17:14:56 -0300 Subject: [PATCH 300/746] 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 551828607c83eb90cb9f66e90024f563f92192d4 Mon Sep 17 00:00:00 2001 From: Jaime Passos Date: Thu, 19 Dec 2019 17:25:19 -0300 Subject: [PATCH 301/746] Load SPR_ lumps as SpriteInfo --- src/r_patch.c | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/src/r_patch.c b/src/r_patch.c index 8d300f041..7c9d0ea83 100644 --- a/src/r_patch.c +++ b/src/r_patch.c @@ -1087,12 +1087,9 @@ void R_LoadSpriteInfoLumps(UINT16 wadnum, UINT16 numlumps) for (i = 0; i < numlumps; i++, lumpinfo++) { name = lumpinfo->name; - // load SPRTINFO lumps - if (!stricmp(name, "SPRTINFO")) + // Load SPRTINFO and SPR_ lumps as SpriteInfo + if (!memcmp(name, "SPRTINFO", 8) || !memcmp(name, "SPR_", 4)) R_ParseSPRTINFOLump(wadnum, i); - // load SPR_ lumps (as DEHACKED lump) - else if (!memcmp(name, "SPR_", 4)) - DEH_LoadDehackedLumpPwad(wadnum, i, false); } } From c1815bfe11ee173264b8419e3f5745184c5e6f4d Mon Sep 17 00:00:00 2001 From: Zachary McAlpin Date: Thu, 19 Dec 2019 15:07:28 -0600 Subject: [PATCH 302/746] Revert "Don't execute LUAh_PlayerThink(player) for respawning bots" This reverts commit fc70164f93722414057e728e5de477f75ee6f131. --- src/p_user.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/p_user.c b/src/p_user.c index 0ec02c3f4..83e28ece3 100644 --- a/src/p_user.c +++ b/src/p_user.c @@ -11313,7 +11313,12 @@ void P_PlayerThink(player_t *player) player->playerstate = PST_REBORN; } if (player->playerstate == PST_REBORN) + { +#ifdef HAVE_BLUA + LUAh_PlayerThink(player); +#endif return; + } } #ifdef SEENAMES From e82b3174519d76c4698ef1ee8162e70d4f8d14ef Mon Sep 17 00:00:00 2001 From: Zachary McAlpin Date: Thu, 19 Dec 2019 15:07:34 -0600 Subject: [PATCH 303/746] Revert "Don't run the LUAh_PlayerThink function if the time ran out in Race or Competition" This reverts commit 3fc1069082fa3cc60e2b1929e0a25571007e1ad9. --- src/p_user.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/p_user.c b/src/p_user.c index 83e28ece3..3baf8cd04 100644 --- a/src/p_user.c +++ b/src/p_user.c @@ -11419,7 +11419,12 @@ void P_PlayerThink(player_t *player) player->lives = 0; if (player->playerstate == PST_DEAD) + { +#ifdef HAVE_BLUA + LUAh_PlayerThink(player); +#endif return; + } } } From 6d7bdf8fdbf827d753011bc12ab92b4ff1c86ba8 Mon Sep 17 00:00:00 2001 From: Jaime Passos Date: Thu, 19 Dec 2019 18:27:11 -0300 Subject: [PATCH 304/746] Lua gametyperules --- src/dehacked.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/dehacked.c b/src/dehacked.c index 12014b8b6..e3fac0a4b 100644 --- a/src/dehacked.c +++ b/src/dehacked.c @@ -10909,6 +10909,9 @@ static inline int lib_getenum(lua_State *L) } else if (fastcmp(word,"gametype")) { lua_pushinteger(L, gametype); return 1; + } else if (fastcmp(word,"gametyperules")) { + lua_pushinteger(L, gametyperules); + return 1; } else if (fastcmp(word,"leveltime")) { lua_pushinteger(L, leveltime); return 1; From 9f82cdb4010cd38994cfc09e5b75212085050230 Mon Sep 17 00:00:00 2001 From: Zachary McAlpin Date: Thu, 19 Dec 2019 16:41:25 -0600 Subject: [PATCH 305/746] Added CalculateCamera Hook --- src/lua_hook.h | 2 ++ src/lua_hooklib.c | 41 +++++++++++++++++++++++++++++++++++++++++ src/p_user.c | 33 ++++++++++++++++++++------------- 3 files changed, 63 insertions(+), 13 deletions(-) diff --git a/src/lua_hook.h b/src/lua_hook.h index 073773f52..4b31fda28 100644 --- a/src/lua_hook.h +++ b/src/lua_hook.h @@ -52,6 +52,7 @@ enum hook { hook_PlayerQuit, hook_IntermissionThinker, hook_PlayerThink, + hook_CalculateCamera, hook_MAX // last hook }; @@ -95,5 +96,6 @@ UINT8 LUAh_PlayerCanDamage(player_t *player, mobj_t *mobj); // Hook for P_Player void LUAh_PlayerQuit(player_t *plr, int reason); // Hook for player quitting void LUAh_IntermissionThinker(void); // Hook for Y_Ticker #define LUAh_PlayerThink(player) LUAh_PlayerHook(player, hook_PlayerThink) // Hook for P_PlayerThink +boolean LUAh_CalculateCamera(player_t *player, camera_t *camera); // Hook for P_PlayerAfterThink Camera calculations #endif diff --git a/src/lua_hooklib.c b/src/lua_hooklib.c index 30ab27da1..b7e544ed0 100644 --- a/src/lua_hooklib.c +++ b/src/lua_hooklib.c @@ -63,6 +63,7 @@ const char *const hookNames[hook_MAX+1] = { "PlayerQuit", "IntermissionThinker", "PlayerThink", + "CalculateCamera", NULL }; @@ -207,6 +208,7 @@ static int lib_addHook(lua_State *L) case hook_ShieldSpawn: case hook_ShieldSpecial: case hook_PlayerThink: + case hook_CalculateCamera: lastp = &playerhooks; break; case hook_LinedefExecute: @@ -1348,4 +1350,43 @@ void LUAh_IntermissionThinker(void) } } +boolean LUAh_CalculateCamera(player_t *player, camera_t *camera) +{ + hook_p hookp; + boolean hooked; + if (!gL || !(hooksAvailable[hook_CalculateCamera/8] & (1<<(hook_CalculateCamera%8)))) + return 0; + + lua_settop(gL, 0); + + for (hookp = playerhooks; hookp; hookp = hookp->next) + { + if (hookp->type != hook_CalculateCamera) + continue; + + if (lua_gettop(gL) == 0) + { + LUA_PushUserdata(gL, player, META_PLAYER); + LUA_PushUserdata(gL, camera, META_CAMERA); + } + 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_toboolean(gL, -1)) + hooked = true; + lua_pop(gL, 1); + } + + lua_settop(gL, 0); + return hooked; +} + #endif diff --git a/src/p_user.c b/src/p_user.c index 3baf8cd04..6eedec10f 100644 --- a/src/p_user.c +++ b/src/p_user.c @@ -12626,22 +12626,29 @@ void P_PlayerAfterThink(player_t *player) if (thiscam) { - if (!thiscam->chase) // bob view only if looking through the player's eyes - { - P_CalcHeight(player); - P_CalcPostImg(player); - } +#ifdef HAVE_BLUA + if (LUAh_CalculateCamera(player, thiscam)) + {;} else +#endif { - // defaults to make sure 1st person cam doesn't do anything weird on startup - player->deltaviewheight = 0; - player->viewheight = FixedMul(41*player->height/48, player->mo->scale); - if (player->mo->eflags & MFE_VERTICALFLIP) - player->viewz = player->mo->z + player->mo->height - player->viewheight; + if (!thiscam->chase) // bob view only if looking through the player's eyes + { + P_CalcHeight(player); + P_CalcPostImg(player); + } else - player->viewz = player->mo->z + player->viewheight; - if (server || addedtogame) - P_MoveChaseCamera(player, thiscam, false); // calculate the camera movement + { + // defaults to make sure 1st person cam doesn't do anything weird on startup + player->deltaviewheight = 0; + player->viewheight = FixedMul(41*player->height/48, player->mo->scale); + if (player->mo->eflags & MFE_VERTICALFLIP) + player->viewz = player->mo->z + player->mo->height - player->viewheight; + else + player->viewz = player->mo->z + player->viewheight; + if (server || addedtogame) + P_MoveChaseCamera(player, thiscam, false); // calculate the camera movement + } } } From c1465c5accd1844db55b86696f062879aa24f313 Mon Sep 17 00:00:00 2001 From: Zachary McAlpin Date: Thu, 19 Dec 2019 17:17:17 -0600 Subject: [PATCH 306/746] Fix CalculateCamera compiling error --- src/lua_hook.h | 1 + 1 file changed, 1 insertion(+) diff --git a/src/lua_hook.h b/src/lua_hook.h index 4b31fda28..6bdcada24 100644 --- a/src/lua_hook.h +++ b/src/lua_hook.h @@ -14,6 +14,7 @@ #include "r_defs.h" #include "d_player.h" +#include "p_local.h" enum hook { hook_NetVars=0, From f5c2341f59a98dfc2ac9009cc3bbb69fde160005 Mon Sep 17 00:00:00 2001 From: Zachary McAlpin Date: Thu, 19 Dec 2019 17:21:46 -0600 Subject: [PATCH 307/746] Revert "Fix CalculateCamera compiling error" This reverts commit c1465c5accd1844db55b86696f062879aa24f313. --- src/lua_hook.h | 1 - 1 file changed, 1 deletion(-) diff --git a/src/lua_hook.h b/src/lua_hook.h index 6bdcada24..4b31fda28 100644 --- a/src/lua_hook.h +++ b/src/lua_hook.h @@ -14,7 +14,6 @@ #include "r_defs.h" #include "d_player.h" -#include "p_local.h" enum hook { hook_NetVars=0, From 124a0754a60e896cfd86546c37ac7350d2937e34 Mon Sep 17 00:00:00 2001 From: Zachary McAlpin Date: Thu, 19 Dec 2019 17:21:55 -0600 Subject: [PATCH 308/746] Revert "Added CalculateCamera Hook" This reverts commit 9f82cdb4010cd38994cfc09e5b75212085050230. --- src/lua_hook.h | 2 -- src/lua_hooklib.c | 41 ----------------------------------------- src/p_user.c | 35 ++++++++++++++--------------------- 3 files changed, 14 insertions(+), 64 deletions(-) diff --git a/src/lua_hook.h b/src/lua_hook.h index 4b31fda28..073773f52 100644 --- a/src/lua_hook.h +++ b/src/lua_hook.h @@ -52,7 +52,6 @@ enum hook { hook_PlayerQuit, hook_IntermissionThinker, hook_PlayerThink, - hook_CalculateCamera, hook_MAX // last hook }; @@ -96,6 +95,5 @@ UINT8 LUAh_PlayerCanDamage(player_t *player, mobj_t *mobj); // Hook for P_Player void LUAh_PlayerQuit(player_t *plr, int reason); // Hook for player quitting void LUAh_IntermissionThinker(void); // Hook for Y_Ticker #define LUAh_PlayerThink(player) LUAh_PlayerHook(player, hook_PlayerThink) // Hook for P_PlayerThink -boolean LUAh_CalculateCamera(player_t *player, camera_t *camera); // Hook for P_PlayerAfterThink Camera calculations #endif diff --git a/src/lua_hooklib.c b/src/lua_hooklib.c index b7e544ed0..30ab27da1 100644 --- a/src/lua_hooklib.c +++ b/src/lua_hooklib.c @@ -63,7 +63,6 @@ const char *const hookNames[hook_MAX+1] = { "PlayerQuit", "IntermissionThinker", "PlayerThink", - "CalculateCamera", NULL }; @@ -208,7 +207,6 @@ static int lib_addHook(lua_State *L) case hook_ShieldSpawn: case hook_ShieldSpecial: case hook_PlayerThink: - case hook_CalculateCamera: lastp = &playerhooks; break; case hook_LinedefExecute: @@ -1350,43 +1348,4 @@ void LUAh_IntermissionThinker(void) } } -boolean LUAh_CalculateCamera(player_t *player, camera_t *camera) -{ - hook_p hookp; - boolean hooked; - if (!gL || !(hooksAvailable[hook_CalculateCamera/8] & (1<<(hook_CalculateCamera%8)))) - return 0; - - lua_settop(gL, 0); - - for (hookp = playerhooks; hookp; hookp = hookp->next) - { - if (hookp->type != hook_CalculateCamera) - continue; - - if (lua_gettop(gL) == 0) - { - LUA_PushUserdata(gL, player, META_PLAYER); - LUA_PushUserdata(gL, camera, META_CAMERA); - } - 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_toboolean(gL, -1)) - hooked = true; - lua_pop(gL, 1); - } - - lua_settop(gL, 0); - return hooked; -} - #endif diff --git a/src/p_user.c b/src/p_user.c index d42b08c5f..c2834f777 100644 --- a/src/p_user.c +++ b/src/p_user.c @@ -12626,29 +12626,22 @@ void P_PlayerAfterThink(player_t *player) if (thiscam) { -#ifdef HAVE_BLUA - if (LUAh_CalculateCamera(player, thiscam)) - {;} - else -#endif + if (!thiscam->chase) // bob view only if looking through the player's eyes { - if (!thiscam->chase) // bob view only if looking through the player's eyes - { - P_CalcHeight(player); - P_CalcPostImg(player); - } + P_CalcHeight(player); + P_CalcPostImg(player); + } + else + { + // defaults to make sure 1st person cam doesn't do anything weird on startup + player->deltaviewheight = 0; + player->viewheight = FixedMul(41*player->height/48, player->mo->scale); + if (player->mo->eflags & MFE_VERTICALFLIP) + player->viewz = player->mo->z + player->mo->height - player->viewheight; else - { - // defaults to make sure 1st person cam doesn't do anything weird on startup - player->deltaviewheight = 0; - player->viewheight = FixedMul(41*player->height/48, player->mo->scale); - if (player->mo->eflags & MFE_VERTICALFLIP) - player->viewz = player->mo->z + player->mo->height - player->viewheight; - else - player->viewz = player->mo->z + player->viewheight; - if (server || addedtogame) - P_MoveChaseCamera(player, thiscam, false); // calculate the camera movement - } + player->viewz = player->mo->z + player->viewheight; + if (server || addedtogame) + P_MoveChaseCamera(player, thiscam, false); // calculate the camera movement } } From a2faa975cb67c6110ec7ef4a281271758ae09588 Mon Sep 17 00:00:00 2001 From: GoldenTails Date: Fri, 20 Dec 2019 16:39:19 -0600 Subject: [PATCH 309/746] Allow Clipboard actions. --- src/m_menu.c | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) diff --git a/src/m_menu.c b/src/m_menu.c index e367041e0..eb9bbaffe 100644 --- a/src/m_menu.c +++ b/src/m_menu.c @@ -10436,6 +10436,28 @@ static void M_HandleConnectIP(INT32 choice) if (l >= 28-1) break; + const char *paste = I_ClipboardPaste(); // Paste clipboard into char + + if ( ctrldown ) { + switch (choice) { + case 118: // ctrl+v, pasting + if (paste != NULL) + strcat(setupm_ip, paste); // Concat the ip field with clipboard + setupm_ip[127] = 0; // Truncate to maximum length + break; + case 99: // ctrl+c, copying + I_ClipboardCopy(setupm_ip, l); + break; + case 120: // ctrl+x, cutting + I_ClipboardCopy(setupm_ip, l); + setupm_ip[0] = 0; + break; + default: // otherwise do nothing + break; + } + break; // break + } + // Rudimentary number and period enforcing - also allows letters so hostnames can be used instead if ((choice >= '-' && choice <= ':') || (choice >= 'A' && choice <= 'Z') || (choice >= 'a' && choice <= 'z')) { From ed847e831b562ee86f4d1eba49013ba844d76d2b Mon Sep 17 00:00:00 2001 From: GoldenTails Date: Fri, 20 Dec 2019 20:28:30 -0600 Subject: [PATCH 310/746] Fix pasting going out of bounds and dash the possibility of memory leaks while pasting. --- src/m_menu.c | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/src/m_menu.c b/src/m_menu.c index eb9bbaffe..ad0f70eb2 100644 --- a/src/m_menu.c +++ b/src/m_menu.c @@ -10436,14 +10436,16 @@ static void M_HandleConnectIP(INT32 choice) if (l >= 28-1) break; - const char *paste = I_ClipboardPaste(); // Paste clipboard into char + char *paste = (char *)I_ClipboardPaste(); // Paste clipboard into char if ( ctrldown ) { switch (choice) { case 118: // ctrl+v, pasting - if (paste != NULL) + if (paste != NULL) { + if (strlen(paste) + strlen(setupm_ip) >= 28-1) + paste[28-1 - strlen(setupm_ip)] = 0; strcat(setupm_ip, paste); // Concat the ip field with clipboard - setupm_ip[127] = 0; // Truncate to maximum length + } break; case 99: // ctrl+c, copying I_ClipboardCopy(setupm_ip, l); From ace202daf08fdce5a1e7d2475403d2f1cf0c32e4 Mon Sep 17 00:00:00 2001 From: Steel Titanium Date: Fri, 20 Dec 2019 23:22:45 -0500 Subject: [PATCH 311/746] Fix Amy and Fang being able to attack other players in MP Special Stages --- src/p_inter.c | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/src/p_inter.c b/src/p_inter.c index 70fb01fd0..4da942f72 100644 --- a/src/p_inter.c +++ b/src/p_inter.c @@ -3426,6 +3426,17 @@ void P_SpecialStageDamage(player_t *player, mobj_t *inflictor, mobj_t *source) if (player->powers[pw_invulnerability] || player->powers[pw_flashing] || player->powers[pw_super]) return; + // Don't allow players to hurt one another, + // unless cv_friendlyfire is on. + if (!cv_friendlyfire.value) + { + if (inflictor->type == MT_LHRT) + return; + + if (source->player->ctfteam == player->ctfteam) + return; + } + if (player->powers[pw_shield] || player->bot) //If One-Hit Shield { P_RemoveShield(player); From de1d25cf08f649cd7c3726aa47b31c252f323ed9 Mon Sep 17 00:00:00 2001 From: Steel Titanium Date: Fri, 20 Dec 2019 23:45:32 -0500 Subject: [PATCH 312/746] Fix super theme ending early if invincibility expired --- 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 7a86d9419..2b82ae697 100644 --- a/src/p_user.c +++ b/src/p_user.c @@ -1600,7 +1600,7 @@ void P_RestoreMusic(player_t *player) P_PlayJingle(player, JT_SUPER); // Invulnerability - else if (player->powers[pw_invulnerability] > 1) + else if (player->powers[pw_invulnerability] > 1 && !player->powers[pw_super]) { strlcpy(S_sfx[sfx_None].caption, "Invincibility", 14); S_StartCaption(sfx_None, -1, player->powers[pw_invulnerability]); From dacd5614f9589fae25ebfffe463eef7e4fa7fafb Mon Sep 17 00:00:00 2001 From: MascaraSnake Date: Sun, 22 Dec 2019 17:37:54 +0100 Subject: [PATCH 313/746] Make both NiGHTS hoop types use the same spawning code. As a result, the old generic hoops now use 24 sprites instead of 32. --- src/p_mobj.c | 368 ++++++++++++++++----------------------------------- 1 file changed, 114 insertions(+), 254 deletions(-) diff --git a/src/p_mobj.c b/src/p_mobj.c index dea4a7a4d..98b640da5 100644 --- a/src/p_mobj.c +++ b/src/p_mobj.c @@ -13082,6 +13082,115 @@ ML_EFFECT5 : Don't stop thinking when too far away mthing->mobj = mobj; } +static void P_SpawnHoop(mapthing_t* mthing, fixed_t x, fixed_t y, fixed_t z, sector_t* sec, INT32 hoopsize, fixed_t sizefactor) +{ + mobj_t *mobj = NULL; + mobj_t *nextmobj = NULL; + mobj_t *hoopcenter; + TMatrix *pitchmatrix, *yawmatrix; + fixed_t radius = hoopsize*sizefactor; + INT32 i; + angle_t fa; + TVector v, *res; + + z += +#ifdef ESLOPE + sec->f_slope ? P_GetZAt(sec->f_slope, x, y) : +#endif + sec->floorheight; + + hoopcenter = P_SpawnMobj(x, y, z, MT_HOOPCENTER); + hoopcenter->spawnpoint = mthing; + hoopcenter->z -= hoopcenter->height/2; + + P_UnsetThingPosition(hoopcenter); + hoopcenter->x = x; + hoopcenter->y = y; + P_SetThingPosition(hoopcenter); + + // Scale 0-255 to 0-359 =( + hoopcenter->movedir = ((mthing->angle & 255)*360)/256; // Pitch + pitchmatrix = RotateXMatrix(FixedAngle(hoopcenter->movedir << FRACBITS)); + hoopcenter->movecount = (((UINT16)mthing->angle >> 8)*360)/256; // Yaw + yawmatrix = RotateZMatrix(FixedAngle(hoopcenter->movecount << FRACBITS)); + + // For the hoop when it flies away + hoopcenter->extravalue1 = hoopsize; + hoopcenter->extravalue2 = radius/12; + + // Create the hoop! + for (i = 0; i < hoopsize; i++) + { + fa = i*(FINEANGLES/hoopsize); + v[0] = FixedMul(FINECOSINE(fa), radius); + v[1] = 0; + v[2] = FixedMul(FINESINE(fa), radius); + v[3] = FRACUNIT; + + res = VectorMatrixMultiply(v, *pitchmatrix); + M_Memcpy(&v, res, sizeof(v)); + res = VectorMatrixMultiply(v, *yawmatrix); + M_Memcpy(&v, res, sizeof(v)); + + mobj = P_SpawnMobj(x + v[0], y + v[1], z + v[2], MT_HOOP); + mobj->z -= mobj->height/2; + + if (maptol & TOL_XMAS) + P_SetMobjState(mobj, mobj->info->seestate + (i & 1)); + + P_SetTarget(&mobj->target, hoopcenter); // Link the sprite to the center. + mobj->fuse = 0; + + // Link all the sprites in the hoop together + if (nextmobj) + { + P_SetTarget(&mobj->hprev, nextmobj); + P_SetTarget(&mobj->hprev->hnext, mobj); + } + else + P_SetTarget(&mobj->hprev, P_SetTarget(&mobj->hnext, NULL)); + + nextmobj = mobj; + } + + // Create the collision detectors! + // Create them until the size is less than 8 + // But always create at least ONE set of collision detectors + do + { + if (hoopsize >= 32) + hoopsize -= 16; + else + hoopsize /= 2; + + radius = hoopsize*sizefactor; + + for (i = 0; i < hoopsize; i++) + { + fa = i*(FINEANGLES/hoopsize); + v[0] = FixedMul(FINECOSINE(fa), radius); + v[1] = 0; + v[2] = FixedMul(FINESINE(fa), radius); + v[3] = FRACUNIT; + + res = VectorMatrixMultiply(v, *pitchmatrix); + M_Memcpy(&v, res, sizeof(v)); + res = VectorMatrixMultiply(v, *yawmatrix); + M_Memcpy(&v, res, sizeof(v)); + + mobj = P_SpawnMobj(x + v[0], y + v[1], z + v[2], MT_HOOPCOLLIDE); + mobj->z -= mobj->height/2; + + // Link all the collision sprites together. + P_SetTarget(&mobj->hnext, NULL); + P_SetTarget(&mobj->hprev, nextmobj); + P_SetTarget(&mobj->hprev->hnext, mobj); + + nextmobj = mobj; + } + } while (hoopsize >= 8); +} + void P_SpawnHoopsAndRings(mapthing_t *mthing, boolean bonustime) { mobjtype_t ringthing = MT_RING; @@ -13101,267 +13210,18 @@ void P_SpawnHoopsAndRings(mapthing_t *mthing, boolean bonustime) // NiGHTS hoop! if (mthing->type == 1705) { - mobj_t *nextmobj = NULL; - mobj_t *hoopcenter; - INT16 spewangle; - z = mthing->options << FRACBITS; - - hoopcenter = P_SpawnMobj(x, y, z, MT_HOOPCENTER); - - hoopcenter->spawnpoint = mthing; - - // Screw these damn hoops, I need this thinker. - //hoopcenter->flags |= MF_NOTHINK; - - z += -#ifdef ESLOPE - sec->f_slope ? P_GetZAt(sec->f_slope, x, y) : -#endif - sec->floorheight; - - hoopcenter->z = z - hoopcenter->height/2; - - P_UnsetThingPosition(hoopcenter); - hoopcenter->x = x; - hoopcenter->y = y; - P_SetThingPosition(hoopcenter); - - // Scale 0-255 to 0-359 =( - closestangle = FixedAngle(FixedMul((mthing->angle>>8)*FRACUNIT, - 360*(FRACUNIT/256))); - - hoopcenter->movedir = FixedInt(FixedMul((mthing->angle&255)*FRACUNIT, - 360*(FRACUNIT/256))); - hoopcenter->movecount = FixedInt(AngleFixed(closestangle)); - - // For the hoop when it flies away - hoopcenter->extravalue1 = 32; - hoopcenter->extravalue2 = 8 * FRACUNIT; - - spewangle = (INT16)hoopcenter->movedir; - - // Create the hoop! - for (i = 0; i < 32; i++) - { - fa = i*(FINEANGLES/32); - v[0] = FixedMul(FINECOSINE(fa),96*FRACUNIT); - v[1] = 0; - v[2] = FixedMul(FINESINE(fa),96*FRACUNIT); - v[3] = FRACUNIT; - - res = VectorMatrixMultiply(v, *RotateXMatrix(FixedAngle(spewangle*FRACUNIT))); - M_Memcpy(&v, res, sizeof (v)); - res = VectorMatrixMultiply(v, *RotateZMatrix(closestangle)); - M_Memcpy(&v, res, sizeof (v)); - - finalx = x + v[0]; - finaly = y + v[1]; - finalz = z + v[2]; - - mobj = P_SpawnMobj(finalx, finaly, finalz, MT_HOOP); - - if (maptol & TOL_XMAS) - P_SetMobjState(mobj, mobj->info->seestate + (i & 1)); - - mobj->z -= mobj->height/2; - P_SetTarget(&mobj->target, hoopcenter); // Link the sprite to the center. - mobj->fuse = 0; - - // Link all the sprites in the hoop together - if (nextmobj) - { - P_SetTarget(&mobj->hprev, nextmobj); - P_SetTarget(&mobj->hprev->hnext, mobj); - } - else - P_SetTarget(&mobj->hprev, P_SetTarget(&mobj->hnext, NULL)); - - nextmobj = mobj; - } - - // Create the collision detectors! - for (i = 0; i < 16; i++) - { - fa = i*FINEANGLES/16; - v[0] = FixedMul(FINECOSINE(fa),32*FRACUNIT); - v[1] = 0; - v[2] = FixedMul(FINESINE(fa),32*FRACUNIT); - v[3] = FRACUNIT; - res = VectorMatrixMultiply(v, *RotateXMatrix(FixedAngle(spewangle*FRACUNIT))); - M_Memcpy(&v, res, sizeof (v)); - res = VectorMatrixMultiply(v, *RotateZMatrix(closestangle)); - M_Memcpy(&v, res, sizeof (v)); - - finalx = x + v[0]; - finaly = y + v[1]; - finalz = z + v[2]; - - mobj = P_SpawnMobj(finalx, finaly, finalz, MT_HOOPCOLLIDE); - mobj->z -= mobj->height/2; - - // Link all the collision sprites together. - P_SetTarget(&mobj->hnext, NULL); - P_SetTarget(&mobj->hprev, nextmobj); - P_SetTarget(&mobj->hprev->hnext, mobj); - - nextmobj = mobj; - } - // Create the collision detectors! - for (i = 0; i < 16; i++) - { - fa = i*FINEANGLES/16; - v[0] = FixedMul(FINECOSINE(fa),64*FRACUNIT); - v[1] = 0; - v[2] = FixedMul(FINESINE(fa),64*FRACUNIT); - v[3] = FRACUNIT; - res = VectorMatrixMultiply(v, *RotateXMatrix(FixedAngle(spewangle*FRACUNIT))); - M_Memcpy(&v, res, sizeof (v)); - res = VectorMatrixMultiply(v, *RotateZMatrix(closestangle)); - M_Memcpy(&v, res, sizeof (v)); - - finalx = x + v[0]; - finaly = y + v[1]; - finalz = z + v[2]; - - mobj = P_SpawnMobj(finalx, finaly, finalz, MT_HOOPCOLLIDE); - mobj->z -= mobj->height/2; - - // Link all the collision sprites together. - P_SetTarget(&mobj->hnext, NULL); - P_SetTarget(&mobj->hprev, nextmobj); - P_SetTarget(&mobj->hprev->hnext, mobj); - - nextmobj = mobj; - } + P_SpawnHoop(mthing, x, y, z, sec, 24, 4*FRACUNIT); return; } // CUSTOMIZABLE NiGHTS hoop! else if (mthing->type == 1713) { - mobj_t *nextmobj = NULL; - mobj_t *hoopcenter; - INT16 spewangle; - INT32 hoopsize; - INT32 hoopplacement; - - // Save our flags! - z = (mthing->options>>ZSHIFT) << FRACBITS; - - hoopcenter = P_SpawnMobj(x, y, z, MT_HOOPCENTER); - hoopcenter->spawnpoint = mthing; - - z += -#ifdef ESLOPE - sec->f_slope ? P_GetZAt(sec->f_slope, x, y) : -#endif - sec->floorheight; - hoopcenter->z = z - hoopcenter->height/2; - - P_UnsetThingPosition(hoopcenter); - hoopcenter->x = x; - hoopcenter->y = y; - P_SetThingPosition(hoopcenter); - - // Scale 0-255 to 0-359 =( - closestangle = FixedAngle(FixedMul((mthing->angle>>8)*FRACUNIT, - 360*(FRACUNIT/256))); - - hoopcenter->movedir = FixedInt(FixedMul((mthing->angle&255)*FRACUNIT, - 360*(FRACUNIT/256))); - hoopcenter->movecount = FixedInt(AngleFixed(closestangle)); - - spewangle = (INT16)hoopcenter->movedir; - // Super happy fun time - // For each flag add 4 fracunits to the size - // Default (0 flags) is 8 fracunits - hoopsize = 8 + (4 * (mthing->options & 0xF)); - hoopplacement = hoopsize * (4*FRACUNIT); - - // For the hoop when it flies away - hoopcenter->extravalue1 = hoopsize; - hoopcenter->extravalue2 = FixedDiv(hoopplacement, 12*FRACUNIT); - - // Create the hoop! - for (i = 0; i < hoopsize; i++) - { - fa = i*(FINEANGLES/hoopsize); - v[0] = FixedMul(FINECOSINE(fa), hoopplacement); - v[1] = 0; - v[2] = FixedMul(FINESINE(fa), hoopplacement); - v[3] = FRACUNIT; - - res = VectorMatrixMultiply(v, *RotateXMatrix(FixedAngle(spewangle*FRACUNIT))); - M_Memcpy(&v, res, sizeof (v)); - res = VectorMatrixMultiply(v, *RotateZMatrix(closestangle)); - M_Memcpy(&v, res, sizeof (v)); - - finalx = x + v[0]; - finaly = y + v[1]; - finalz = z + v[2]; - - mobj = P_SpawnMobj(finalx, finaly, finalz, MT_HOOP); - - if (maptol & TOL_XMAS) - P_SetMobjState(mobj, mobj->info->seestate + (i & 1)); - - mobj->z -= mobj->height/2; - P_SetTarget(&mobj->target, hoopcenter); // Link the sprite to the center. - mobj->fuse = 0; - - // Link all the sprites in the hoop together - if (nextmobj) - { - P_SetTarget(&mobj->hprev, nextmobj); - P_SetTarget(&mobj->hprev->hnext, mobj); - } - else - P_SetTarget(&mobj->hprev, P_SetTarget(&mobj->hnext, NULL)); - - nextmobj = mobj; - } - - // Create the collision detectors! - // Create them until the size is less than 8 - // But always create at least ONE set of collision detectors - do - { - if (hoopsize >= 32) - hoopsize -= 16; - else - hoopsize /= 2; - - hoopplacement = hoopsize * (4*FRACUNIT); - - for (i = 0; i < hoopsize; i++) - { - fa = i*FINEANGLES/hoopsize; - v[0] = FixedMul(FINECOSINE(fa), hoopplacement); - v[1] = 0; - v[2] = FixedMul(FINESINE(fa), hoopplacement); - v[3] = FRACUNIT; - res = VectorMatrixMultiply(v, *RotateXMatrix(FixedAngle(spewangle*FRACUNIT))); - M_Memcpy(&v, res, sizeof (v)); - res = VectorMatrixMultiply(v, *RotateZMatrix(closestangle)); - M_Memcpy(&v, res, sizeof (v)); - - finalx = x + v[0]; - finaly = y + v[1]; - finalz = z + v[2]; - - mobj = P_SpawnMobj(finalx, finaly, finalz, MT_HOOPCOLLIDE); - mobj->z -= mobj->height/2; - - // Link all the collision sprites together. - P_SetTarget(&mobj->hnext, NULL); - P_SetTarget(&mobj->hprev, nextmobj); - P_SetTarget(&mobj->hprev->hnext, mobj); - - nextmobj = mobj; - } - } while (hoopsize >= 8); - + // For each flag add 16 fracunits to the size + // Default (0 flags) is 32 fracunits + z = (mthing->options >> ZSHIFT) << FRACBITS; + P_SpawnHoop(mthing, x, y, z, sec, 8 + (4*(mthing->options & 0xF)), 4*FRACUNIT); return; } // *** From 579362fd3bd0d5dcbda606680459302e408f9b08 Mon Sep 17 00:00:00 2001 From: MascaraSnake Date: Sun, 22 Dec 2019 23:22:15 +0100 Subject: [PATCH 314/746] P_LoadMapData(): Throw an error if resources are not found. --- src/p_setup.c | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/src/p_setup.c b/src/p_setup.c index 14d2cc9e6..bc736588e 100644 --- a/src/p_setup.c +++ b/src/p_setup.c @@ -1960,6 +1960,17 @@ static void P_LoadMapData(const virtres_t* virt) virtsidedefs = vres_Find(virt, "SIDEDEFS"); virtlinedefs = vres_Find(virt, "LINEDEFS"); + if (!virtthings) + I_Error("THINGS lump not found"); + if (!virtvertexes) + I_Error("VERTEXES lump not found"); + if (!virtsectors) + I_Error("SECTORS lump not found"); + if (!virtsidedefs) + I_Error("SIDEDEFS lump not found"); + if (!virtlinedefs) + I_Error("LINEDEFS lump not found"); + // Traditional doom map format just assumes the number of elements from the lump sizes. numvertexes = virtvertexes->size / sizeof (mapvertex_t); numsectors = virtsectors->size / sizeof (mapsector_t); From 356b25def45606a61e805f68e486264277c52167 Mon Sep 17 00:00:00 2001 From: Steel Titanium Date: Mon, 23 Dec 2019 00:28:06 -0500 Subject: [PATCH 315/746] Spawn Amy's shields for other players --- src/p_inter.c | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/src/p_inter.c b/src/p_inter.c index 4da942f72..5ec1161ea 100644 --- a/src/p_inter.c +++ b/src/p_inter.c @@ -3430,6 +3430,15 @@ void P_SpecialStageDamage(player_t *player, mobj_t *inflictor, mobj_t *source) // unless cv_friendlyfire is on. if (!cv_friendlyfire.value) { + if (inflictor->type == MT_LHRT && !(player->powers[pw_shield] & SH_NOSTACK)) + { + if (player->revitem != MT_LHRT && player->spinitem != MT_LHRT && player->thokitem != MT_LHRT) // Healers do not get to heal other healers. + { + P_SwitchShield(player, SH_PINK); + S_StartSound(player->mo, mobjinfo[MT_PITY_ICON].seesound); + } + } + if (inflictor->type == MT_LHRT) return; From f574cd0ce239181e86f1abb96c9714cdc251ede9 Mon Sep 17 00:00:00 2001 From: James R Date: Sun, 22 Dec 2019 21:29:41 -0800 Subject: [PATCH 316/746] Whoops I forgot player 2 --- src/g_game.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/g_game.c b/src/g_game.c index 381d72cfe..dd983834b 100644 --- a/src/g_game.c +++ b/src/g_game.c @@ -1497,14 +1497,14 @@ void G_BuildTiccmd2(ticcmd_t *cmd, INT32 realtics) else { if (turnright) - cmd->angleturn = (INT16)(cmd->angleturn - (FixedMul(angleturn[tspeed]<>FRACBITS)); + cmd->angleturn = (INT16)(cmd->angleturn - (((angleturn[tspeed]<>FRACBITS)); else if (turnleft) - cmd->angleturn = (INT16)(cmd->angleturn + (FixedMul(angleturn[tspeed]<>FRACBITS)); + cmd->angleturn = (INT16)(cmd->angleturn + (((angleturn[tspeed]<>FRACBITS)); if (analogjoystickmove && lookjoystickvector.xaxis != 0) { // JOYAXISRANGE should be 1023 (divide by 1024) - cmd->angleturn = (INT16)(cmd->angleturn - (FixedMul(((lookjoystickvector.xaxis * angleturn[1]) >> 10)<>FRACBITS)); // ANALOG! + cmd->angleturn = (INT16)(cmd->angleturn - ((((lookjoystickvector.xaxis * angleturn[1]) >> 10) * cv_cam2_turnmultiplier.value)>>FRACBITS)); // ANALOG! } } From efb47b3786ad163faf5116cc5eb39fa4ec149b21 Mon Sep 17 00:00:00 2001 From: MascaraSnake Date: Mon, 23 Dec 2019 12:07:03 +0100 Subject: [PATCH 317/746] Move spawning of ring-like items into its own function, use P_GetMobjSpawnHeight() --- src/p_mobj.c | 129 +++++++++++++++++++++++---------------------------- 1 file changed, 57 insertions(+), 72 deletions(-) diff --git a/src/p_mobj.c b/src/p_mobj.c index 87ec1fe9f..b74c70dd3 100644 --- a/src/p_mobj.c +++ b/src/p_mobj.c @@ -11595,13 +11595,21 @@ static fixed_t P_GetMobjSpawnHeight(const mobjtype_t mobjtype, const mapthing_t* case MT_EMERALDSPAWN: case MT_TOKEN: case MT_EMBLEM: + case MT_RING: + case MT_REDTEAMRING: + case MT_BLUETEAMRING: + case MT_COIN: + case MT_BLUESPHERE: + case MT_BOMBSPHERE: + case MT_NIGHTSCHIP: + case MT_NIGHTSSTAR: offset += mthing->options & MTF_AMBUSH ? 24*FRACUNIT : 0; break; // Remaining objects. default: if (P_WeaponOrPanel(mobjtype)) - offset += mthing->options & MTF_AMBUSH ? 24 * FRACUNIT : 0; + offset += mthing->options & MTF_AMBUSH ? 24*FRACUNIT : 0; } if (!offset) // Snap to the surfaces when there's no offset set. @@ -13165,6 +13173,53 @@ static void P_SpawnHoop(mapthing_t* mthing, fixed_t x, fixed_t y, fixed_t z, sec } while (hoopsize >= 8); } +static void P_SpawnRingItem(mapthing_t *mthing, fixed_t x, fixed_t y, boolean bonustime, boolean nightsreplace) +{ + mobjtype_t ringthing = MT_RING; + mobj_t *mobj = NULL; + fixed_t z; + + // Which ringthing to use + if (mthing->type == mobjinfo[MT_BLUESPHERE].doomednum) + ringthing = (nightsreplace) ? MT_NIGHTSCHIP : MT_BLUESPHERE; + else if (mthing->type == mobjinfo[MT_BOMBSPHERE].doomednum) + ringthing = MT_BOMBSPHERE; + else + { + if (ultimatemode) + return; // No rings in Ultimate! + + if (nightsreplace) + ringthing = MT_NIGHTSSTAR; + else if (mthing->type == mobjinfo[MT_COIN].doomednum) + ringthing = MT_COIN; + else if (mthing->type == mobjinfo[MT_REDTEAMRING].doomednum) // No team rings in non-CTF + ringthing = (gametype == GT_CTF) ? MT_REDTEAMRING : MT_RING; + else if (mthing->type == mobjinfo[MT_BLUETEAMRING].doomednum) // Ditto + ringthing = (gametype == GT_CTF) ? MT_BLUETEAMRING : MT_RING; + } + + z = P_GetMobjSpawnHeight(ringthing, mthing, x, y); + mobj = P_SpawnMobj(x, y, z, ringthing); + mobj->spawnpoint = mthing; + + if (mthing->options & MTF_OBJECTFLIP) + { + mobj->eflags |= MFE_VERTICALFLIP; + mobj->flags2 |= MF2_OBJECTFLIP; + } + + mobj->angle = FixedAngle(mthing->angle << FRACBITS); + mthing->mobj = mobj; + if (mthing->options & MTF_AMBUSH) + mobj->flags2 |= MF2_AMBUSH; + + if (bonustime && (ringthing == MT_BLUESPHERE || ringthing == MT_NIGHTSCHIP)) + P_SetMobjState(mobj, mobj->info->raisestate); + else if ((maptol & TOL_XMAS) && (ringthing == MT_NIGHTSSTAR)) + P_SetMobjState(mobj, mobj->info->seestate); +} + void P_SpawnHoopsAndRings(mapthing_t *mthing, boolean bonustime) { mobjtype_t ringthing = MT_RING; @@ -13414,77 +13469,7 @@ void P_SpawnHoopsAndRings(mapthing_t *mthing, boolean bonustime) } // All manners of rings and coins else - { - - // Which ringthing to use - if (mthing->type == mobjinfo[MT_BLUESPHERE].doomednum) - ringthing = (nightsreplace) ? MT_NIGHTSCHIP : MT_BLUESPHERE; - else if (mthing->type == mobjinfo[MT_BOMBSPHERE].doomednum) - ringthing = MT_BOMBSPHERE; - else - { - if (ultimatemode) - return; // No rings in Ultimate! - - if (nightsreplace) - ringthing = MT_NIGHTSSTAR; - else if (mthing->type == mobjinfo[MT_COIN].doomednum) - ringthing = MT_COIN; - else if (mthing->type == mobjinfo[MT_REDTEAMRING].doomednum) // No team rings in non-CTF - ringthing = (gametype == GT_CTF) ? MT_REDTEAMRING : MT_RING; - else if (mthing->type == mobjinfo[MT_BLUETEAMRING].doomednum) // Ditto - ringthing = (gametype == GT_CTF) ? MT_BLUETEAMRING : MT_RING; - } - - // Set proper height - if (mthing->options & MTF_OBJECTFLIP) - { - z = ( -#ifdef ESLOPE - sec->c_slope ? P_GetZAt(sec->c_slope, x, y) : -#endif - sec->ceilingheight) - mobjinfo[ringthing].height; - if (mthing->z) - z -= (mthing->z << FRACBITS); - } - else - { - z = -#ifdef ESLOPE - sec->f_slope ? P_GetZAt(sec->f_slope, x, y) : -#endif - sec->floorheight; - if (mthing->z) - z += (mthing->z << FRACBITS); - } - - if (mthing->options & MTF_AMBUSH) // Special flag for rings - { - if (mthing->options & MTF_OBJECTFLIP) - z -= 24*FRACUNIT; - else - z += 24*FRACUNIT; - } - - mobj = P_SpawnMobj(x, y, z, ringthing); - mobj->spawnpoint = mthing; - - if (mthing->options & MTF_OBJECTFLIP) - { - mobj->eflags |= MFE_VERTICALFLIP; - mobj->flags2 |= MF2_OBJECTFLIP; - } - - mobj->angle = FixedAngle(mthing->angle*FRACUNIT); - mthing->mobj = mobj; - if (mthing->options & MTF_AMBUSH) - mobj->flags2 |= MF2_AMBUSH; - - if (bonustime && (ringthing == MT_BLUESPHERE || ringthing == MT_NIGHTSCHIP)) - P_SetMobjState(mobj, mobj->info->raisestate); - else if ((maptol & TOL_XMAS) && (ringthing == MT_NIGHTSSTAR)) - P_SetMobjState(mobj, mobj->info->seestate); - } + P_SpawnRingItem(mthing, x, y, bonustime, nightsreplace); } // From eadf9539571a60b98bea01fda60bb4e65db62e98 Mon Sep 17 00:00:00 2001 From: Nev3r Date: Mon, 23 Dec 2019 12:30:01 +0100 Subject: [PATCH 318/746] Store a copy of sectors, lines and sides in memory so that P_NetArchiveWorld() can soon use them instead of relying on re-opening the original lumps. Fix print type issue. --- src/p_setup.c | 12 ++++++++++++ src/r_state.h | 3 +++ 2 files changed, 15 insertions(+) diff --git a/src/p_setup.c b/src/p_setup.c index bc736588e..529cab798 100644 --- a/src/p_setup.c +++ b/src/p_setup.c @@ -103,6 +103,9 @@ node_t *nodes; line_t *lines; side_t *sides; mapthing_t *mapthings; +sector_t *spawnsectors; +line_t *spawnlines; +side_t *spawnsides; INT32 numstarposts; UINT16 bossdisabled; boolean stoppedclock; @@ -2775,6 +2778,15 @@ boolean P_SetupLevel(boolean skipprecip) P_LoadLineDefs2(); P_GroupLines(); + // Copy relevant map data for NetArchive purposes. + spawnsectors = Z_Calloc(numsectors * sizeof (*sectors), PU_LEVEL, NULL); + spawnlines = Z_Calloc(numlines * sizeof (*lines), PU_LEVEL, NULL); + spawnsides = Z_Calloc(numsides * sizeof (*sides), PU_LEVEL, NULL); + + memcpy(spawnsectors, sectors, numsectors * sizeof (*sectors)); + memcpy(spawnlines, lines, numlines * sizeof (*lines)); + memcpy(spawnsides, sides, numsides * sizeof (*sides)); + P_PrepareRawThings(vres_Find(virt, "THINGS")->data); P_MakeMapMD5(virt, &mapmd5); diff --git a/src/r_state.h b/src/r_state.h index 75566923b..4e1eb388e 100644 --- a/src/r_state.h +++ b/src/r_state.h @@ -63,6 +63,7 @@ extern seg_t *segs; extern size_t numsectors; extern sector_t *sectors; +extern sector_t *spawnsectors; extern size_t numsubsectors; extern subsector_t *subsectors; @@ -72,9 +73,11 @@ extern node_t *nodes; extern size_t numlines; extern line_t *lines; +extern line_t *spawnlines; extern size_t numsides; extern side_t *sides; +extern side_t *spawnsides; // // POV data. From 21dcbc856cc6ce9f77faf54a149e76195d4815cb Mon Sep 17 00:00:00 2001 From: MascaraSnake Date: Mon, 23 Dec 2019 12:42:09 +0100 Subject: [PATCH 319/746] Split up P_SpawnHoopsAndRings() into subfunctions --- src/p_mobj.c | 480 ++++++++++++++++++++++++++------------------------- 1 file changed, 248 insertions(+), 232 deletions(-) diff --git a/src/p_mobj.c b/src/p_mobj.c index b74c70dd3..459a7c003 100644 --- a/src/p_mobj.c +++ b/src/p_mobj.c @@ -13220,256 +13220,272 @@ static void P_SpawnRingItem(mapthing_t *mthing, fixed_t x, fixed_t y, boolean bo P_SetMobjState(mobj, mobj->info->seestate); } -void P_SpawnHoopsAndRings(mapthing_t *mthing, boolean bonustime) +static void P_SpawnVerticalSpringRings(mapthing_t *mthing, fixed_t x, fixed_t y, sector_t* sec, boolean nightsreplace) { mobjtype_t ringthing = MT_RING; - mobj_t *mobj = NULL; - INT32 r, i; - fixed_t x, y, z, finalx, finaly, finalz; - sector_t *sec; - TVector v, *res; - angle_t closestangle, fa; - boolean nightsreplace = ((maptol & TOL_NIGHTS) && !G_IsSpecialStage(gamemap)); + mobj_t* mobj = NULL; + fixed_t z; + INT32 r; - x = mthing->x << FRACBITS; - y = mthing->y << FRACBITS; + INT32 dist = 64*FRACUNIT; + if (mthing->type == 601) + dist = 128*FRACUNIT; - sec = R_PointInSubsector(x, y)->sector; + if (ultimatemode) + return; // No rings in Ultimate! - // NiGHTS hoop! - if (mthing->type == 1705) + if (nightsreplace) + ringthing = MT_NIGHTSSTAR; + + if (mthing->options & MTF_OBJECTFLIP) { - z = mthing->z << FRACBITS; - P_SpawnHoop(mthing, x, y, z, sec, 24, 4*FRACUNIT); - return; - } - // CUSTOMIZABLE NiGHTS hoop! - else if (mthing->type == 1713) - { - // Super happy fun time - // For each flag add 16 fracunits to the size - // Default (0 flags) is 32 fracunits - z = mthing->z << FRACBITS; - P_SpawnHoop(mthing, x, y, z, sec, 8 + (4*(mthing->options & 0xF)), 4*FRACUNIT); - return; - } - // *** - // Special placement patterns - // *** - - // Vertical Rings - Stack of 5 (handles both red and yellow) - else if (mthing->type == 600 || mthing->type == 601) - { - INT32 dist = 64*FRACUNIT; - if (mthing->type == 601) - dist = 128*FRACUNIT; - - if (ultimatemode) - return; // No rings in Ultimate! - - if (nightsreplace) - ringthing = MT_NIGHTSSTAR; - - if (mthing->options & MTF_OBJECTFLIP) - { - z = ( + z = ( #ifdef ESLOPE - sec->c_slope ? P_GetZAt(sec->c_slope, x, y) : + sec->c_slope ? P_GetZAt(sec->c_slope, x, y) : #endif - sec->ceilingheight) - mobjinfo[ringthing].height; - if (mthing->z) - z -= (mthing->z << FRACBITS); - } - else - { - z = ( -#ifdef ESLOPE - sec->f_slope ? P_GetZAt(sec->f_slope, x, y) : -#endif - sec->floorheight); - if (mthing->z) - z += (mthing->z << FRACBITS); - } - - for (r = 1; r <= 5; r++) - { - if (mthing->options & MTF_OBJECTFLIP) - z -= dist; - else - z += dist; - - mobj = P_SpawnMobj(x, y, z, ringthing); - - if (mthing->options & MTF_OBJECTFLIP) - { - mobj->eflags |= MFE_VERTICALFLIP; - mobj->flags2 |= MF2_OBJECTFLIP; - } - - mobj->angle = FixedAngle(mthing->angle*FRACUNIT); - if (mthing->options & MTF_AMBUSH) - mobj->flags2 |= MF2_AMBUSH; - - if ((maptol & TOL_XMAS) && (ringthing == MT_NIGHTSSTAR)) - P_SetMobjState(mobj, mobj->info->seestate); - } + sec->ceilingheight) - mobjinfo[ringthing].height; + if (mthing->z) + z -= (mthing->z << FRACBITS); } - // Diagonal rings (handles both types) - else if (mthing->type == 602 || mthing->type == 603) // Diagonal rings (5) + else { - INT32 iterations = 5; - if (mthing->type == 603) - iterations = 10; - - if (ultimatemode) - return; // No rings in Ultimate! - - if (nightsreplace) - ringthing = MT_NIGHTSSTAR; - - closestangle = FixedAngle(mthing->angle*FRACUNIT); - fa = (closestangle >> ANGLETOFINESHIFT); - - if (mthing->options & MTF_OBJECTFLIP) - { - z = ( -#ifdef ESLOPE - sec->c_slope ? P_GetZAt(sec->c_slope, x, y) : -#endif - sec->ceilingheight) - mobjinfo[ringthing].height; - if (mthing->z) - z -= (mthing->z << FRACBITS); - } - else - { - z = ( -#ifdef ESLOPE - sec->f_slope ? P_GetZAt(sec->f_slope, x, y) : -#endif - sec->floorheight); - if (mthing->z) - z += (mthing->z << FRACBITS); - } - - for (r = 1; r <= iterations; r++) - { - x += FixedMul(64*FRACUNIT, FINECOSINE(fa)); - y += FixedMul(64*FRACUNIT, FINESINE(fa)); - - if (mthing->options & MTF_OBJECTFLIP) - z -= 64*FRACUNIT; - else - z += 64*FRACUNIT; - - mobj = P_SpawnMobj(x, y, z, ringthing); - - if (mthing->options & MTF_OBJECTFLIP) - { - mobj->eflags |= MFE_VERTICALFLIP; - mobj->flags2 |= MF2_OBJECTFLIP; - } - - mobj->angle = closestangle; - if (mthing->options & MTF_AMBUSH) - mobj->flags2 |= MF2_AMBUSH; - - if ((maptol & TOL_XMAS) && (ringthing == MT_NIGHTSSTAR)) - P_SetMobjState(mobj, mobj->info->seestate); - } - } - // Rings of items (all six of them) - else if (mthing->type >= 604 && mthing->type <= 609) - { - INT32 numitems = 8; - INT32 size = 96*FRACUNIT; - - if (mthing->type & 1) - { - numitems = 16; - size = 192*FRACUNIT; - } - - z = + z = ( #ifdef ESLOPE sec->f_slope ? P_GetZAt(sec->f_slope, x, y) : #endif - sec->floorheight; + sec->floorheight); if (mthing->z) z += (mthing->z << FRACBITS); - - closestangle = FixedAngle(mthing->angle*FRACUNIT); - - switch (mthing->type) - { - case 604: - case 605: - if (ultimatemode) - return; // No rings in Ultimate! - if (nightsreplace) - ringthing = MT_NIGHTSSTAR; - break; - case 608: - case 609: - /*ringthing = (i & 1) ? MT_RING : MT_BLUESPHERE; -- i == 0 is bluesphere - break;*/ - case 606: - case 607: - ringthing = (nightsreplace) ? MT_NIGHTSCHIP : MT_BLUESPHERE; - break; - default: - break; - } - - // Create the hoop! - for (i = 0; i < numitems; i++) - { - if (mthing->type == 608 || mthing->type == 609) - { - if (i & 1) - { - if (ultimatemode) - continue; // No rings in Ultimate! - ringthing = (nightsreplace) ? MT_NIGHTSSTAR : MT_RING; - } - else - ringthing = (nightsreplace) ? MT_NIGHTSCHIP : MT_BLUESPHERE; - } - - fa = i*FINEANGLES/numitems; - v[0] = FixedMul(FINECOSINE(fa),size); - v[1] = 0; - v[2] = FixedMul(FINESINE(fa),size); - v[3] = FRACUNIT; - - res = VectorMatrixMultiply(v, *RotateZMatrix(closestangle)); - M_Memcpy(&v, res, sizeof (v)); - - finalx = x + v[0]; - finaly = y + v[1]; - finalz = z + v[2]; - - mobj = P_SpawnMobj(finalx, finaly, finalz, ringthing); - mobj->z -= mobj->height/2; - - if (mthing->options & MTF_OBJECTFLIP) - { - mobj->eflags |= MFE_VERTICALFLIP; - mobj->flags2 |= MF2_OBJECTFLIP; - } - - mobj->angle = closestangle; - if (mthing->options & MTF_AMBUSH) - mobj->flags2 |= MF2_AMBUSH; - - if (bonustime && (ringthing == MT_BLUESPHERE || ringthing == MT_NIGHTSCHIP)) - P_SetMobjState(mobj, mobj->info->raisestate); - else if ((maptol & TOL_XMAS) && (ringthing == MT_NIGHTSSTAR)) - P_SetMobjState(mobj, mobj->info->seestate); - } } - // All manners of rings and coins + + for (r = 1; r <= 5; r++) + { + if (mthing->options & MTF_OBJECTFLIP) + z -= dist; + else + z += dist; + + mobj = P_SpawnMobj(x, y, z, ringthing); + + if (mthing->options & MTF_OBJECTFLIP) + { + mobj->eflags |= MFE_VERTICALFLIP; + mobj->flags2 |= MF2_OBJECTFLIP; + } + + mobj->angle = FixedAngle(mthing->angle << FRACBITS); + if (mthing->options & MTF_AMBUSH) + mobj->flags2 |= MF2_AMBUSH; + + if ((maptol & TOL_XMAS) && (ringthing == MT_NIGHTSSTAR)) + P_SetMobjState(mobj, mobj->info->seestate); + } +} + +static void P_SpawnDiagonalSpringRings(mapthing_t* mthing, fixed_t x, fixed_t y, sector_t* sec, boolean nightsreplace) +{ + mobjtype_t ringthing = MT_RING; + mobj_t *mobj = NULL; + fixed_t z; + INT32 r; + angle_t closestangle, fa; + + INT32 iterations = 5; + if (mthing->type == 603) + iterations = 10; + + if (ultimatemode) + return; // No rings in Ultimate! + + if (nightsreplace) + ringthing = MT_NIGHTSSTAR; + + closestangle = FixedAngle(mthing->angle << FRACBITS); + fa = (closestangle >> ANGLETOFINESHIFT); + + if (mthing->options & MTF_OBJECTFLIP) + { + z = ( +#ifdef ESLOPE + sec->c_slope ? P_GetZAt(sec->c_slope, x, y) : +#endif + sec->ceilingheight) - mobjinfo[ringthing].height; + if (mthing->z) + z -= (mthing->z << FRACBITS); + } else + { + z = ( +#ifdef ESLOPE + sec->f_slope ? P_GetZAt(sec->f_slope, x, y) : +#endif + sec->floorheight); + if (mthing->z) + z += (mthing->z << FRACBITS); + } + + for (r = 1; r <= iterations; r++) + { + x += FixedMul(64*FRACUNIT, FINECOSINE(fa)); + y += FixedMul(64*FRACUNIT, FINESINE(fa)); + + if (mthing->options & MTF_OBJECTFLIP) + z -= 64*FRACUNIT; + else + z += 64*FRACUNIT; + + mobj = P_SpawnMobj(x, y, z, ringthing); + + if (mthing->options & MTF_OBJECTFLIP) + { + mobj->eflags |= MFE_VERTICALFLIP; + mobj->flags2 |= MF2_OBJECTFLIP; + } + + mobj->angle = closestangle; + if (mthing->options & MTF_AMBUSH) + mobj->flags2 |= MF2_AMBUSH; + + if ((maptol & TOL_XMAS) && (ringthing == MT_NIGHTSSTAR)) + P_SetMobjState(mobj, mobj->info->seestate); + } +} + +static void P_SpawnItemCircle(mapthing_t* mthing, fixed_t x, fixed_t y, sector_t* sec, boolean bonustime, boolean nightsreplace) +{ + mobjtype_t ringthing = MT_RING; + mobj_t *mobj = NULL; + fixed_t z, finalx, finaly, finalz; + angle_t closestangle, fa; + INT32 i; + TVector v, *res; + INT32 numitems = 8; + INT32 size = 96*FRACUNIT; + + if (mthing->type & 1) + { + numitems = 16; + size = 192*FRACUNIT; + } + + z = +#ifdef ESLOPE + sec->f_slope ? P_GetZAt(sec->f_slope, x, y) : +#endif + sec->floorheight; + if (mthing->z) + z += (mthing->z << FRACBITS); + + closestangle = FixedAngle(mthing->angle << FRACBITS); + + switch (mthing->type) + { + case 604: + case 605: + if (ultimatemode) + return; // No rings in Ultimate! + if (nightsreplace) + ringthing = MT_NIGHTSSTAR; + break; + case 608: + case 609: + /*ringthing = (i & 1) ? MT_RING : MT_BLUESPHERE; -- i == 0 is bluesphere + break;*/ + case 606: + case 607: + ringthing = (nightsreplace) ? MT_NIGHTSCHIP : MT_BLUESPHERE; + break; + default: + break; + } + + // Create the hoop! + for (i = 0; i < numitems; i++) + { + if (mthing->type == 608 || mthing->type == 609) + { + if (i & 1) + { + if (ultimatemode) + continue; // No rings in Ultimate! + ringthing = (nightsreplace) ? MT_NIGHTSSTAR : MT_RING; + } + else + ringthing = (nightsreplace) ? MT_NIGHTSCHIP : MT_BLUESPHERE; + } + + fa = i * FINEANGLES/numitems; + v[0] = FixedMul(FINECOSINE(fa), size); + v[1] = 0; + v[2] = FixedMul(FINESINE(fa), size); + v[3] = FRACUNIT; + + res = VectorMatrixMultiply(v, *RotateZMatrix(closestangle)); + M_Memcpy(&v, res, sizeof(v)); + + finalx = x + v[0]; + finaly = y + v[1]; + finalz = z + v[2]; + + mobj = P_SpawnMobj(finalx, finaly, finalz, ringthing); + mobj->z -= mobj->height/2; + + if (mthing->options & MTF_OBJECTFLIP) + { + mobj->eflags |= MFE_VERTICALFLIP; + mobj->flags2 |= MF2_OBJECTFLIP; + } + + mobj->angle = closestangle; + if (mthing->options & MTF_AMBUSH) + mobj->flags2 |= MF2_AMBUSH; + + if (bonustime && (ringthing == MT_BLUESPHERE || ringthing == MT_NIGHTSCHIP)) + P_SetMobjState(mobj, mobj->info->raisestate); + else if ((maptol & TOL_XMAS) && (ringthing == MT_NIGHTSSTAR)) + P_SetMobjState(mobj, mobj->info->seestate); + } +} + +void P_SpawnHoopsAndRings(mapthing_t *mthing, boolean bonustime) +{ + fixed_t x = mthing->x << FRACBITS; + fixed_t y = mthing->y << FRACBITS; + fixed_t z = mthing->z << FRACBITS; + sector_t *sec = R_PointInSubsector(x, y)->sector; + boolean nightsreplace = ((maptol & TOL_NIGHTS) && !G_IsSpecialStage(gamemap)); + + switch (mthing->type) + { + // Special placement patterns + case 600: // 5 vertical rings (yellow spring) + case 601: // 5 vertical rings (red spring) + P_SpawnVerticalSpringRings(mthing, x, y, sec, nightsreplace); + return; + case 602: // 5 diagonal rings (yellow spring) + case 603: // 10 diagonal rings (red spring) + P_SpawnDiagonalSpringRings(mthing, x, y, sec, nightsreplace); + return; + case 604: // Circle of rings (8 items) + case 605: // Circle of rings (16 bits) + case 606: // Circle of blue spheres (8 items) + case 607: // Circle of blue spheres (16 items) + case 608: // Circle of rings and blue spheres (8 items) + case 609: // Circle of rings and blue spheres (16 items) + P_SpawnItemCircle(mthing, x, y, sec, bonustime, nightsreplace); + return; + // Hoops + case 1705: // Generic NiGHTS hoop + P_SpawnHoop(mthing, x, y, z, sec, 24, 4*FRACUNIT); + return; + case 1713: // Customizable NiGHTS hoop + // For each flag add 16 fracunits to the size + // Default (0 flags) is 32 fracunits + P_SpawnHoop(mthing, x, y, z, sec, 8 + (4*(mthing->options & 0xF)), 4*FRACUNIT); + return; + default: // All manners of rings and coins P_SpawnRingItem(mthing, x, y, bonustime, nightsreplace); + } } // From bb54597552df972c4a4e27144df4876da7757e5c Mon Sep 17 00:00:00 2001 From: Nev3r Date: Mon, 23 Dec 2019 12:42:38 +0100 Subject: [PATCH 320/746] Remove redundant netarchive-related sector vars as they're not used anymore. Replace lump-based difference checks for sectors in P_NetArchiveWorld(), now it uses the mapload-created copy instead. --- src/p_saveg.c | 34 +++++++++++++++++----------------- src/p_setup.c | 4 ---- src/p_spec.c | 12 ++---------- src/r_defs.h | 11 ----------- 4 files changed, 19 insertions(+), 42 deletions(-) diff --git a/src/p_saveg.c b/src/p_saveg.c index c876713e4..356d696a5 100644 --- a/src/p_saveg.c +++ b/src/p_saveg.c @@ -782,10 +782,10 @@ static void P_NetArchiveWorld(void) // reload the map just to see difference virtres_t* virt = vres_GetMap(lastloadedmaplumpnum); - mapsector_t *ms = (mapsector_t*) vres_Find(virt, "SECTORS")->data; mapsidedef_t *msd = (mapsidedef_t*) vres_Find(virt, "SIDEDEFS")->data; maplinedef_t *mld = (maplinedef_t*) vres_Find(virt, "LINEDEFS")->data; const sector_t *ss = sectors; + const sector_t *spawnss = spawnsectors; UINT8 diff, diff2, diff3; // initialize colormap vars because paranoia @@ -794,45 +794,45 @@ static void P_NetArchiveWorld(void) WRITEUINT32(save_p, ARCHIVEBLOCK_WORLD); put = save_p; - for (i = 0; i < numsectors; i++, ss++, ms++) + for (i = 0; i < numsectors; i++, ss++, spawnss++) { diff = diff2 = diff3 = 0; - if (ss->floorheight != SHORT(ms->floorheight)<floorheight != spawnss->floorheight) diff |= SD_FLOORHT; - if (ss->ceilingheight != SHORT(ms->ceilingheight)<ceilingheight != spawnss->ceilingheight) diff |= SD_CEILHT; // // flats // - if (ss->floorpic != P_CheckLevelFlat(ms->floorpic)) + if (ss->floorpic != spawnss->floorpic) diff |= SD_FLOORPIC; - if (ss->ceilingpic != P_CheckLevelFlat(ms->ceilingpic)) + if (ss->ceilingpic != spawnss->ceilingpic) diff |= SD_CEILPIC; - if (ss->lightlevel != SHORT(ms->lightlevel)) + if (ss->lightlevel != spawnss->lightlevel) diff |= SD_LIGHT; - if (ss->special != SHORT(ms->special)) + if (ss->special != spawnss->special) diff |= SD_SPECIAL; - if (ss->floor_xoffs != ss->spawn_flr_xoffs) + if (ss->floor_xoffs != spawnss->floor_xoffs) diff2 |= SD_FXOFFS; - if (ss->floor_yoffs != ss->spawn_flr_yoffs) + if (ss->floor_yoffs != spawnss->floor_yoffs) diff2 |= SD_FYOFFS; - if (ss->ceiling_xoffs != ss->spawn_ceil_xoffs) + if (ss->ceiling_xoffs != spawnss->ceiling_xoffs) diff2 |= SD_CXOFFS; - if (ss->ceiling_yoffs != ss->spawn_ceil_yoffs) + if (ss->ceiling_yoffs != spawnss->ceiling_yoffs) diff2 |= SD_CYOFFS; - if (ss->floorpic_angle != ss->spawn_flrpic_angle) + if (ss->floorpic_angle != spawnss->floorpic_angle) diff2 |= SD_FLOORANG; - if (ss->ceilingpic_angle != ss->spawn_flrpic_angle) + if (ss->ceilingpic_angle != spawnss->ceilingpic_angle) diff2 |= SD_CEILANG; - if (ss->tag != SHORT(ms->tag)) + if (ss->tag != spawnss->tag) diff2 |= SD_TAG; - if (ss->nexttag != ss->spawn_nexttag || ss->firsttag != ss->spawn_firsttag) + if (ss->nexttag != spawnss->nexttag || ss->firsttag != spawnss->firsttag) diff3 |= SD_TAGLIST; - if (ss->extra_colormap != ss->spawn_extra_colormap) + if (ss->extra_colormap != spawnss->extra_colormap) diff3 |= SD_COLORMAP; // Check if any of the sector's FOFs differ from how they spawned diff --git a/src/p_setup.c b/src/p_setup.c index 529cab798..6e6c1a72b 100644 --- a/src/p_setup.c +++ b/src/p_setup.c @@ -669,11 +669,9 @@ static void P_LoadRawSectors(UINT8 *data) ss->ceilingpic = P_AddLevelFlat(ms->ceilingpic, foundflats); ss->lightlevel = SHORT(ms->lightlevel); - ss->spawn_lightlevel = SHORT(ms->lightlevel); ss->special = SHORT(ms->special); ss->tag = SHORT(ms->tag); ss->nexttag = ss->firsttag = -1; - ss->spawn_nexttag = ss->spawn_firsttag = -1; memset(&ss->soundorg, 0, sizeof(ss->soundorg)); ss->validcount = 0; @@ -708,9 +706,7 @@ static void P_LoadRawSectors(UINT8 *data) ss->spawn_extra_colormap = NULL; ss->floor_xoffs = ss->ceiling_xoffs = ss->floor_yoffs = ss->ceiling_yoffs = 0; - ss->spawn_flr_xoffs = ss->spawn_ceil_xoffs = ss->spawn_flr_yoffs = ss->spawn_ceil_yoffs = 0; ss->floorpic_angle = ss->ceilingpic_angle = 0; - ss->spawn_flrpic_angle = ss->spawn_ceilpic_angle = 0; ss->gravity = NULL; ss->cullheight = NULL; ss->verticalflip = false; diff --git a/src/p_spec.c b/src/p_spec.c index bf7f6210a..297c9a427 100644 --- a/src/p_spec.c +++ b/src/p_spec.c @@ -1603,8 +1603,6 @@ static inline void P_InitTagLists(void) size_t j = (unsigned)sectors[i].tag % numsectors; sectors[i].nexttag = sectors[j].firsttag; sectors[j].firsttag = (INT32)i; - sectors[i].spawn_nexttag = sectors[i].nexttag; - sectors[j].spawn_firsttag = sectors[j].firsttag; } for (i = numlines - 1; i != (size_t)-1; i--) @@ -6405,22 +6403,16 @@ static void P_ApplyFlatAlignment(line_t *master, sector_t *sector, angle_t flata { if (!(master->flags & ML_NETONLY)) // Modify floor flat alignment unless ML_NETONLY flag is set { - sector->spawn_flrpic_angle = sector->floorpic_angle = flatangle; + sector->floorpic_angle = flatangle; sector->floor_xoffs += xoffs; sector->floor_yoffs += yoffs; - // saved for netgames - sector->spawn_flr_xoffs = sector->floor_xoffs; - sector->spawn_flr_yoffs = sector->floor_yoffs; } if (!(master->flags & ML_NONET)) // Modify ceiling flat alignment unless ML_NONET flag is set { - sector->spawn_ceilpic_angle = sector->ceilingpic_angle = flatangle; + sector->ceilingpic_angle = flatangle; sector->ceiling_xoffs += xoffs; sector->ceiling_yoffs += yoffs; - // saved for netgames - sector->spawn_ceil_xoffs = sector->ceiling_xoffs; - sector->spawn_ceil_yoffs = sector->ceiling_yoffs; } } diff --git a/src/r_defs.h b/src/r_defs.h index 3cc780545..353dc572b 100644 --- a/src/r_defs.h +++ b/src/r_defs.h @@ -384,17 +384,6 @@ typedef struct sector_s // for fade thinker INT16 spawn_lightlevel; - // these are saved for netgames, so do not let Lua touch these! - INT32 spawn_nexttag, spawn_firsttag; // the actual nexttag/firsttag values may differ if the sector's tag was changed - - // offsets sector spawned with (via linedef type 7) - fixed_t spawn_flr_xoffs, spawn_flr_yoffs; - fixed_t spawn_ceil_xoffs, spawn_ceil_yoffs; - - // flag angles sector spawned with (via linedef type 7) - angle_t spawn_flrpic_angle; - angle_t spawn_ceilpic_angle; - // colormap structure extracolormap_t *spawn_extra_colormap; } sector_t; From 1221c108c67db0b16ce21de288eae411fda9e14f Mon Sep 17 00:00:00 2001 From: Nev3r Date: Mon, 23 Dec 2019 12:47:40 +0100 Subject: [PATCH 321/746] Make lines and sides use the mapload copies in P_NetArchiveWorld() too; do no longer use vres stuff there. --- src/p_saveg.c | 37 +++++++++++++++---------------------- 1 file changed, 15 insertions(+), 22 deletions(-) diff --git a/src/p_saveg.c b/src/p_saveg.c index 356d696a5..5af72cd46 100644 --- a/src/p_saveg.c +++ b/src/p_saveg.c @@ -777,13 +777,11 @@ static void P_NetArchiveWorld(void) size_t i; INT32 statsec = 0, statline = 0; const line_t *li = lines; + const line_t *spawnli = spawnlines; const side_t *si; + const side_t *spawnsi; UINT8 *put; - // reload the map just to see difference - virtres_t* virt = vres_GetMap(lastloadedmaplumpnum); - mapsidedef_t *msd = (mapsidedef_t*) vres_Find(virt, "SIDEDEFS")->data; - maplinedef_t *mld = (maplinedef_t*) vres_Find(virt, "LINEDEFS")->data; const sector_t *ss = sectors; const sector_t *spawnss = spawnsectors; UINT8 diff, diff2, diff3; @@ -936,45 +934,41 @@ static void P_NetArchiveWorld(void) WRITEUINT16(put, 0xffff); // do lines - for (i = 0; i < numlines; i++, mld++, li++) + for (i = 0; i < numlines; i++, spawnli++, li++) { diff = diff2 = diff3 = 0; - if (li->special != SHORT(mld->special)) + if (li->special != spawnli->special) diff |= LD_SPECIAL; - if (SHORT(mld->special) == 321 || SHORT(mld->special) == 322) // only reason li->callcount would be non-zero is if either of these are involved + if (spawnli->special == 321 || spawnli->special == 322) // only reason li->callcount would be non-zero is if either of these are involved diff |= LD_CLLCOUNT; if (li->sidenum[0] != 0xffff) { si = &sides[li->sidenum[0]]; - if (si->textureoffset != SHORT(msd[li->sidenum[0]].textureoffset)<sidenum[0]]; + if (si->textureoffset != spawnsi->textureoffset) diff |= LD_S1TEXOFF; //SoM: 4/1/2000: Some textures are colormaps. Don't worry about invalid textures. - if (R_CheckTextureNumForName(msd[li->sidenum[0]].toptexture) != -1 - && si->toptexture != R_TextureNumForName(msd[li->sidenum[0]].toptexture)) + if (si->toptexture != spawnsi->toptexture) diff |= LD_S1TOPTEX; - if (R_CheckTextureNumForName(msd[li->sidenum[0]].bottomtexture) != -1 - && si->bottomtexture != R_TextureNumForName(msd[li->sidenum[0]].bottomtexture)) + if (si->bottomtexture != spawnsi->bottomtexture) diff |= LD_S1BOTTEX; - if (R_CheckTextureNumForName(msd[li->sidenum[0]].midtexture) != -1 - && si->midtexture != R_TextureNumForName(msd[li->sidenum[0]].midtexture)) + if (si->midtexture != spawnsi->midtexture) diff |= LD_S1MIDTEX; } if (li->sidenum[1] != 0xffff) { si = &sides[li->sidenum[1]]; - if (si->textureoffset != SHORT(msd[li->sidenum[1]].textureoffset)<sidenum[1]]; + if (si->textureoffset != spawnsi->textureoffset) diff2 |= LD_S2TEXOFF; - if (R_CheckTextureNumForName(msd[li->sidenum[1]].toptexture) != -1 - && si->toptexture != R_TextureNumForName(msd[li->sidenum[1]].toptexture)) + if (si->toptexture != spawnsi->toptexture) diff2 |= LD_S2TOPTEX; - if (R_CheckTextureNumForName(msd[li->sidenum[1]].bottomtexture) != -1 - && si->bottomtexture != R_TextureNumForName(msd[li->sidenum[1]].bottomtexture)) + if (si->bottomtexture != spawnsi->bottomtexture) diff2 |= LD_S2BOTTEX; - if (R_CheckTextureNumForName(msd[li->sidenum[1]].midtexture) != -1 - && si->midtexture != R_TextureNumForName(msd[li->sidenum[1]].midtexture)) + if (si->midtexture != spawnsi->midtexture) diff2 |= LD_S2MIDTEX; if (diff2) diff |= LD_DIFF2; @@ -1018,7 +1012,6 @@ static void P_NetArchiveWorld(void) WRITEUINT16(put, 0xffff); R_ClearTextureNumCache(false); - vres_Free(virt); save_p = put; } From 112b15cca2f459559a00b6608af8bed23e624482 Mon Sep 17 00:00:00 2001 From: MascaraSnake Date: Mon, 23 Dec 2019 14:45:43 +0100 Subject: [PATCH 322/746] Add P_GetMobjtype for finding the mobjtype for a given mapthingnum --- src/p_mobj.c | 50 ++++++++++++++++++++++---------------------------- 1 file changed, 22 insertions(+), 28 deletions(-) diff --git a/src/p_mobj.c b/src/p_mobj.c index 459a7c003..112ef67f3 100644 --- a/src/p_mobj.c +++ b/src/p_mobj.c @@ -11159,17 +11159,12 @@ void P_RespawnSpecials(void) if (mthing) { - mobjtype_t i; + mobjtype_t i = P_GetMobjtype(mthing->type); x = mthing->x << FRACBITS; y = mthing->y << FRACBITS; ss = R_PointInSubsector(x, y); - // find which type to spawn - for (i = 0; i < NUMMOBJTYPES; i++) - if (mthing->type == mobjinfo[i].doomednum) - break; - - if (i == NUMMOBJTYPES) // prevent creation of objects with this type -- Monster Iestyn 17/12/17 + if (i == MT_UNKNOWN) // prevent creation of objects with this type -- Monster Iestyn 17/12/17 { // 3D Mode start Thing is unlikely to be added to the que, // so don't bother checking for that specific type @@ -11635,6 +11630,19 @@ static fixed_t P_GetMobjSpawnHeight(const mobjtype_t mobjtype, const mapthing_t* ss->sector->floorheight) + offset; } +/** Returns corresponding mobj type from mapthing number. + * \param mthingtype Mapthing number in question. + * \return Mobj type; MT_UNKNOWN if nothing found. + */ +static mobjtype_t P_GetMobjtype(UINT16 mthingtype) +{ + mobjtype_t i; + for (i = 0; i < NUMMOBJTYPES; i++) + if (mthingtype == mobjinfo[i].doomednum) + return i; + return MT_UNKNOWN; +} + // // P_SpawnMapThing // The fields of the mapthing should @@ -11650,22 +11658,17 @@ void P_SpawnMapThing(mapthing_t *mthing) if (!mthing->type) return; // Ignore type-0 things as NOPs + if (mthing->type == 3328) // 3D Mode start Thing + return; + // Always spawn in objectplace. // Skip all returning code. if (objectplacing) { // find which type to spawn - for (i = 0; i < NUMMOBJTYPES; i++) - if (mthing->type == mobjinfo[i].doomednum) - break; - - if (i == NUMMOBJTYPES) - { - if (mthing->type == 3328) // 3D Mode start Thing - return; + i = P_GetMobjtype(mthing->type); + if (i == MT_UNKNOWN) CONS_Alert(CONS_WARNING, M_GetText("Unknown thing type %d placed at (%d, %d)\n"), mthing->type, mthing->x, mthing->y); - i = MT_UNKNOWN; - } goto noreturns; } @@ -11734,18 +11737,9 @@ You should think about modifying the deathmatch starts to take full advantage of return; } - // find which type to spawn - for (i = 0; i < NUMMOBJTYPES; i++) - if (mthing->type == mobjinfo[i].doomednum) - break; - - if (i == NUMMOBJTYPES) - { - if (mthing->type == 3328) // 3D Mode start Thing - return; + i = P_GetMobjtype(mthing->type); + if (i == MT_UNKNOWN) CONS_Alert(CONS_WARNING, M_GetText("Unknown thing type %d placed at (%d, %d)\n"), mthing->type, mthing->x, mthing->y); - i = MT_UNKNOWN; - } if (metalrecording) // Metal Sonic can't use these things. if (mobjinfo[i].flags & (MF_ENEMY|MF_BOSS) || i == MT_TOKEN || i == MT_STARPOST) From 6779c508e743054cccab0de8c883ef3d70c773f8 Mon Sep 17 00:00:00 2001 From: Jaime Passos Date: Mon, 23 Dec 2019 12:17:39 -0300 Subject: [PATCH 323/746] Satisfy rollangle table with a 3deg angle --- src/r_patch.c | 3 +-- src/r_things.c | 8 +++++--- 2 files changed, 6 insertions(+), 5 deletions(-) diff --git a/src/r_patch.c b/src/r_patch.c index 7c9d0ea83..69d5ad1a2 100644 --- a/src/r_patch.c +++ b/src/r_patch.c @@ -1180,8 +1180,7 @@ void R_CacheRotSprite(spritenum_t sprnum, UINT8 frame, spriteinfo_t *sprinfo, sp leftoffset = width - leftoffset; } - // Don't cache angle = 0 - for (angle = 1; angle < ROTANGLES; angle++) + for (angle = 0; angle < ROTANGLES; angle++) { INT32 newwidth, newheight; diff --git a/src/r_things.c b/src/r_things.c index aa2a73515..d29baa711 100644 --- a/src/r_things.c +++ b/src/r_things.c @@ -500,7 +500,7 @@ void R_InitSprites(void) { size_t i; #ifdef ROTSPRITE - INT32 angle, realangle = 0; + INT32 angle, ra; float fa; #endif @@ -510,10 +510,12 @@ void R_InitSprites(void) #ifdef ROTSPRITE for (angle = 0; angle < ROTANGLES; angle++) { - fa = ANG2RAD(FixedAngle(realangle< Date: Mon, 23 Dec 2019 16:36:26 +0100 Subject: [PATCH 324/746] P_PrepareRawThings() is now where it was supposed to be at; moved save and flat & texture caching related functions to the end of P_LoadMapData(). --- src/p_setup.c | 46 +++++++++++++++++++++++----------------------- 1 file changed, 23 insertions(+), 23 deletions(-) diff --git a/src/p_setup.c b/src/p_setup.c index 6e6c1a72b..7ac713044 100644 --- a/src/p_setup.c +++ b/src/p_setup.c @@ -485,6 +485,7 @@ static inline void P_LoadRawSubsectors(void *data) size_t numlevelflats; levelflat_t *levelflats; +levelflat_t *foundflats; //SoM: Other files want this info. size_t P_PrecacheLevelFlats(void) @@ -648,7 +649,6 @@ static void P_LoadRawSectors(UINT8 *data) { mapsector_t *ms = (mapsector_t *)data; sector_t *ss = sectors; - levelflat_t *foundflats; size_t i; // Allocate a big chunk of memory as big as our MAXLEVELFLATS limit. @@ -725,16 +725,6 @@ static void P_LoadRawSectors(UINT8 *data) ss->lineoutLength = -1.0l; #endif // ----- end special tricks ----- } - - // set the sky flat num - skyflatnum = P_AddLevelFlat(SKYFLATNAME, foundflats); - - // copy table for global usage - levelflats = M_Memcpy(Z_Calloc(numlevelflats * sizeof (*levelflats), PU_LEVEL, NULL), foundflats, numlevelflats * sizeof (levelflat_t)); - free(foundflats); - - // search for animated flats and set up - P_SetupLevelFlatAnims(); } // @@ -1455,7 +1445,6 @@ static void P_LoadRawSideDefs2(void *data) break; } } - R_ClearTextureNumCache(true); } static boolean LineInBlock(fixed_t cx1, fixed_t cy1, fixed_t cx2, fixed_t cy2, fixed_t bx1, fixed_t by1) @@ -2007,7 +1996,29 @@ static void P_LoadMapData(const virtres_t* virt) P_LoadRawLineDefs(virtlinedefs->data); P_SetupLines(); P_LoadRawSideDefs2(virtsidedefs->data); + P_PrepareRawThings(virtthings->data); } + + R_ClearTextureNumCache(true); + + // set the sky flat num + skyflatnum = P_AddLevelFlat(SKYFLATNAME, foundflats); + + // copy table for global usage + levelflats = M_Memcpy(Z_Calloc(numlevelflats * sizeof (*levelflats), PU_LEVEL, NULL), foundflats, numlevelflats * sizeof (levelflat_t)); + free(foundflats); + + // search for animated flats and set up + P_SetupLevelFlatAnims(); + + // Copy relevant map data for NetArchive purposes. + spawnsectors = Z_Calloc(numsectors * sizeof (*sectors), PU_LEVEL, NULL); + spawnlines = Z_Calloc(numlines * sizeof (*lines), PU_LEVEL, NULL); + spawnsides = Z_Calloc(numsides * sizeof (*sides), PU_LEVEL, NULL); + + memcpy(spawnsectors, sectors, numsectors * sizeof (*sectors)); + memcpy(spawnlines, lines, numlines * sizeof (*lines)); + memcpy(spawnsides, sides, numsides * sizeof (*sides)); } #if 0 @@ -2774,17 +2785,6 @@ boolean P_SetupLevel(boolean skipprecip) P_LoadLineDefs2(); P_GroupLines(); - // Copy relevant map data for NetArchive purposes. - spawnsectors = Z_Calloc(numsectors * sizeof (*sectors), PU_LEVEL, NULL); - spawnlines = Z_Calloc(numlines * sizeof (*lines), PU_LEVEL, NULL); - spawnsides = Z_Calloc(numsides * sizeof (*sides), PU_LEVEL, NULL); - - memcpy(spawnsectors, sectors, numsectors * sizeof (*sectors)); - memcpy(spawnlines, lines, numlines * sizeof (*lines)); - memcpy(spawnsides, sides, numsides * sizeof (*sides)); - - P_PrepareRawThings(vres_Find(virt, "THINGS")->data); - P_MakeMapMD5(virt, &mapmd5); vres_Free(virt); From 9a9f72f59899143f1b0483c7d828b5b260de8151 Mon Sep 17 00:00:00 2001 From: Nev3r Date: Mon, 23 Dec 2019 16:37:44 +0100 Subject: [PATCH 325/746] Don't reload mapthings in P_LoadThingsOnly() as they should no longer be modified past the mapload procedure. --- src/p_setup.c | 5 ----- 1 file changed, 5 deletions(-) diff --git a/src/p_setup.c b/src/p_setup.c index 7ac713044..f5d4c26e2 100644 --- a/src/p_setup.c +++ b/src/p_setup.c @@ -2196,8 +2196,6 @@ void P_LoadThingsOnly(void) // Search through all the thinkers. thinker_t *think; INT32 i, viewid = -1, centerid = -1; // for skyboxes - virtres_t* virt = vres_GetMap(lastloadedmaplumpnum); - virtlump_t* vth = vres_Find(virt, "THINGS"); // check if these are any of the normal viewpoint/centerpoint mobjs in the level or not if (skyboxmo[0] || skyboxmo[1]) @@ -2218,11 +2216,8 @@ void P_LoadThingsOnly(void) P_LevelInitStuff(); - P_PrepareRawThings(vth->data); P_LoadThings(true); - vres_Free(virt); - // restore skybox viewpoint/centerpoint if necessary, set them to defaults if we can't do that skyboxmo[0] = skyboxviewpnts[(viewid >= 0) ? viewid : 0]; skyboxmo[1] = skyboxcenterpnts[(centerid >= 0) ? centerid : 0]; From 6a69aa4ffa7619c4094d922891035831ba5291a3 Mon Sep 17 00:00:00 2001 From: MascaraSnake Date: Mon, 23 Dec 2019 16:53:45 +0100 Subject: [PATCH 326/746] Separate handling of non-mobj mapthings in P_SpawnMapThing into its own function --- src/p_mobj.c | 120 +++++++++++++++++++++++++-------------------------- 1 file changed, 59 insertions(+), 61 deletions(-) diff --git a/src/p_mobj.c b/src/p_mobj.c index 112ef67f3..714eef737 100644 --- a/src/p_mobj.c +++ b/src/p_mobj.c @@ -11643,6 +11643,61 @@ static mobjtype_t P_GetMobjtype(UINT16 mthingtype) return MT_UNKNOWN; } +static boolean P_SpawnNonMobjMapThing(mapthing_t *mthing) +{ +#if MAXPLAYERS > 32 + You should think about modifying the deathmatch starts to take full advantage of this! +#endif + if (mthing->type <= MAXPLAYERS) // Player starts + { + // save spots for respawning in network games + if (!metalrecording) + playerstarts[mthing->type - 1] = mthing; + return true; + } + else if (mthing->type == 33) // Match starts + { + if (numdmstarts < MAX_DM_STARTS) + { + deathmatchstarts[numdmstarts] = mthing; + mthing->type = 0; + numdmstarts++; + } + return true; + } + else if (mthing->type == 34) // Red CTF starts + { + if (numredctfstarts < MAXPLAYERS) + { + redctfstarts[numredctfstarts] = mthing; + mthing->type = 0; + numredctfstarts++; + } + return true; + } + else if (mthing->type == 35) // Blue CTF starts + { + if (numbluectfstarts < MAXPLAYERS) + { + bluectfstarts[numbluectfstarts] = mthing; + mthing->type = 0; + numbluectfstarts++; + } + return true; + } + else if (metalrecording && mthing->type == mobjinfo[MT_METALSONIC_RACE].doomednum) + { // If recording, you ARE Metal Sonic. Do not spawn it, do not save normal spawnpoints. + playerstarts[0] = mthing; + return true; + } + else if (mthing->type == 750 // Slope vertex point (formerly chaos spawn) + || (mthing->type >= 600 && mthing->type <= 609) // Special placement patterns + || mthing->type == 1705 || mthing->type == 1713) // Hoops + return true; // These are handled elsewhere. + + return false; +} + // // P_SpawnMapThing // The fields of the mapthing should @@ -11672,70 +11727,13 @@ void P_SpawnMapThing(mapthing_t *mthing) goto noreturns; } - // count deathmatch start positions - if (mthing->type == 33) - { - if (numdmstarts < MAX_DM_STARTS) - { - deathmatchstarts[numdmstarts] = mthing; - mthing->type = 0; - numdmstarts++; - } - return; - } - - else if (mthing->type == 34) // Red CTF Starts - { - if (numredctfstarts < MAXPLAYERS) - { - redctfstarts[numredctfstarts] = mthing; - mthing->type = 0; - numredctfstarts++; - } - return; - } - - else if (mthing->type == 35) // Blue CTF Starts - { - if (numbluectfstarts < MAXPLAYERS) - { - bluectfstarts[numbluectfstarts] = mthing; - mthing->type = 0; - numbluectfstarts++; - } - return; - } - - else if (mthing->type == 750) // Slope vertex point (formerly chaos spawn) + if (P_SpawnNonMobjMapThing(mthing)) return; - else if (mthing->type == mobjinfo[MT_RING].doomednum || mthing->type == mobjinfo[MT_COIN].doomednum + if (mthing->type == mobjinfo[MT_RING].doomednum || mthing->type == mobjinfo[MT_COIN].doomednum || mthing->type == mobjinfo[MT_REDTEAMRING].doomednum || mthing->type == mobjinfo[MT_BLUETEAMRING].doomednum - || mthing->type == mobjinfo[MT_BLUESPHERE].doomednum || mthing->type == mobjinfo[MT_BOMBSPHERE].doomednum - || (mthing->type >= 600 && mthing->type <= 609) // circles and diagonals - || mthing->type == 1705 || mthing->type == 1713) // hoops - { - // Don't spawn hoops, wings, or rings yet! - return; - } - - // check for players specially -#if MAXPLAYERS > 32 -You should think about modifying the deathmatch starts to take full advantage of this! -#endif - if (mthing->type > 0 && mthing->type <= MAXPLAYERS) - { - // save spots for respawning in network games - if (!metalrecording) - playerstarts[mthing->type-1] = mthing; - return; - } - - if (metalrecording && mthing->type == mobjinfo[MT_METALSONIC_RACE].doomednum) - { // If recording, you ARE Metal Sonic. Do not spawn it, do not save normal spawnpoints. - playerstarts[0] = mthing; - return; - } + || mthing->type == mobjinfo[MT_BLUESPHERE].doomednum || mthing->type == mobjinfo[MT_BOMBSPHERE].doomednum) // hoops + return; // These are handled in P_SpawnHoopsAndRings(). i = P_GetMobjtype(mthing->type); if (i == MT_UNKNOWN) From e90eb9a5e73c69c7996c2b258a34f42108f63a51 Mon Sep 17 00:00:00 2001 From: MascaraSnake Date: Mon, 23 Dec 2019 16:54:26 +0100 Subject: [PATCH 327/746] Move P_GetMobjtype above first use --- src/p_mobj.c | 26 +++++++++++++------------- 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/src/p_mobj.c b/src/p_mobj.c index 714eef737..f607fdf8a 100644 --- a/src/p_mobj.c +++ b/src/p_mobj.c @@ -11121,6 +11121,19 @@ void P_PrecipitationEffects(void) } } +/** Returns corresponding mobj type from mapthing number. + * \param mthingtype Mapthing number in question. + * \return Mobj type; MT_UNKNOWN if nothing found. + */ +static mobjtype_t P_GetMobjtype(UINT16 mthingtype) +{ + mobjtype_t i; + for (i = 0; i < NUMMOBJTYPES; i++) + if (mthingtype == mobjinfo[i].doomednum) + return i; + return MT_UNKNOWN; +} + // // P_RespawnSpecials // @@ -11630,19 +11643,6 @@ static fixed_t P_GetMobjSpawnHeight(const mobjtype_t mobjtype, const mapthing_t* ss->sector->floorheight) + offset; } -/** Returns corresponding mobj type from mapthing number. - * \param mthingtype Mapthing number in question. - * \return Mobj type; MT_UNKNOWN if nothing found. - */ -static mobjtype_t P_GetMobjtype(UINT16 mthingtype) -{ - mobjtype_t i; - for (i = 0; i < NUMMOBJTYPES; i++) - if (mthingtype == mobjinfo[i].doomednum) - return i; - return MT_UNKNOWN; -} - static boolean P_SpawnNonMobjMapThing(mapthing_t *mthing) { #if MAXPLAYERS > 32 From 8ddd078b20a82e9abe35c177bc997470507d6120 Mon Sep 17 00:00:00 2001 From: MascaraSnake Date: Mon, 23 Dec 2019 17:28:21 +0100 Subject: [PATCH 328/746] P_MapThingSpawn(): Move early returning/substitution code into their own functions --- src/p_mobj.c | 358 ++++++++++++++++++++++++++++----------------------- 1 file changed, 199 insertions(+), 159 deletions(-) diff --git a/src/p_mobj.c b/src/p_mobj.c index f607fdf8a..c2b40a96b 100644 --- a/src/p_mobj.c +++ b/src/p_mobj.c @@ -11698,6 +11698,198 @@ static boolean P_SpawnNonMobjMapThing(mapthing_t *mthing) return false; } +static boolean P_AllowMobjSpawn(mapthing_t* mthing, mobjtype_t i) +{ + switch (i) + { + case MT_RING: + case MT_COIN: + case MT_REDTEAMRING: + case MT_BLUETEAMRING: + case MT_BLUESPHERE: + case MT_BOMBSPHERE: + case MT_NIGHTSSTAR: + case MT_NIGHTSCHIP: + return false; // These are handled in P_SpawnHoopsAndRings(). + case MT_EMERALD1: + case MT_EMERALD2: + case MT_EMERALD3: + case MT_EMERALD4: + case MT_EMERALD5: + case MT_EMERALD6: + case MT_EMERALD7: + if (gametype != GT_COOP) // Don't place emeralds in non-coop modes + return false; + + if (metalrecording) + return false; // Metal Sonic isn't for collecting emeralds. + + if (emeralds & mobjinfo[i].speed) // You already have this emerald! + return false; + + break; + case MT_EMERHUNT: + // Emerald Hunt is Coop only. + if (gametype != GT_COOP) + return false; + + if (numhuntemeralds < MAXHUNTEMERALDS) + huntemeralds[numhuntemeralds++] = mthing; + return false; + case MT_EMERALDSPAWN: + if (!cv_powerstones.value) + return false; + + if (!(gametype == GT_MATCH || gametype == GT_CTF)) + return false; + + runemeraldmanager = true; + break; + case MT_ROSY: + if (!(gametype == GT_COOP || (mthing->options & MTF_EXTRA))) + return false; // she doesn't hang out here + + if (!mariomode && !(netgame || multiplayer) && players[consoleplayer].skin == 3) + return false; // no doubles + + break; + case MT_TOKEN: + if (gametype != GT_COOP && gametype != GT_COMPETITION) + return false; // Gametype's not right + + if (tokenbits == 30) + return false; // Too many tokens + + if (tokenlist & (1 << tokenbits++)) + return false; // You already got this token + + break; + case MT_EMBLEM: + if (netgame || multiplayer) + return false; // Single player + + if (modifiedgame && !savemoddata) + return false; // No cheating!! + + break; + default: + break; + } + + if (metalrecording) // Metal Sonic can't use these things. + if (mobjinfo[i].flags & (MF_ENEMY|MF_BOSS) || i == MT_TOKEN || i == MT_STARPOST) + return false; + + if (!G_PlatformGametype()) + { + if ((mobjinfo[i].flags & MF_ENEMY) || (mobjinfo[i].flags & MF_BOSS)) + return false; // No enemies in ringslinger modes + + if (i == MT_SIGN || i == MT_STARPOST) + return false; // Don't spawn exit signs or starposts in wrong game modes + } + + if (!G_RingSlingerGametype() || !cv_specialrings.value) + if (P_WeaponOrPanel(i)) + return false; // Don't place weapons/panels in non-ringslinger modes + + if (gametype != GT_CTF) // CTF specific things + { + if (i == MT_BLUEFLAG || i == MT_REDFLAG) + return false; // No flags in non-CTF modes! + } + else + { + if ((i == MT_BLUEFLAG && blueflag) || (i == MT_REDFLAG && redflag)) + { + CONS_Alert(CONS_ERROR, M_GetText("Only one flag per team allowed in CTF!\n")); + return false; + } + } + + if (modeattacking) // Record Attack special stuff + { + // Don't spawn starposts that wouldn't be usable + if (i == MT_STARPOST) + return false; + } + + if (ultimatemode) + { + if (i == MT_PITY_BOX || i == MT_ELEMENTAL_BOX || i == MT_ATTRACT_BOX + || i == MT_FORCE_BOX || i == MT_ARMAGEDDON_BOX || i == MT_WHIRLWIND_BOX + || i == MT_FLAMEAURA_BOX || i == MT_BUBBLEWRAP_BOX || i == MT_THUNDERCOIN_BOX + || i == MT_RING_BOX || i == MT_STARPOST) + return false; // No rings or shields in Ultimate mode + + // Don't include the gold repeating boxes here please. + // They're likely facets of the level's design and therefore required to progress. + } + + return true; +} + +static mobjtype_t P_GetMobjtypeSubstitute(mapthing_t *mthing, mobjtype_t i) +{ + // Altering monitor spawns via cvars + // If MF_GRENADEBOUNCE is set in the monitor's info, + // skip this step. (Used for gold monitors) + // Yeah, this is a dirty hack. + if ((mobjinfo[i].flags & (MF_MONITOR|MF_GRENADEBOUNCE)) == MF_MONITOR) + { + if (gametype == GT_COMPETITION || gametype == GT_RACE) + { + // Set powerup boxes to user settings for competition. + switch (cv_competitionboxes.value) + { + case 1: // Mystery + return MT_MYSTERY_BOX; + case 2: // Teleport + return MT_MIXUP_BOX; + case 3: // None + return MT_NULL; // Don't spawn! + default: + return i; + } + } + // Set powerup boxes to user settings for other netplay modes + else if (gametype != GT_COOP) + { + switch (cv_matchboxes.value) + { + case 1: // Mystery + return MT_MYSTERY_BOX; + case 2: // Unchanging + if (i == MT_MYSTERY_BOX) + return MT_NULL; // don't spawn + mthing->options &= ~(MTF_AMBUSH|MTF_OBJECTSPECIAL); // no random respawning! + return i; + case 3: // Don't spawn + return MT_NULL; + default: + return i; + } + } + } + + if (gametype != GT_CTF && (i == MT_RING_BLUEBOX || i == MT_RING_REDBOX)) + return MT_RING_BOX; + + if (modeattacking && i == MT_1UP_BOX) // 1UPs -->> Score TVs + { + // Either or, doesn't matter which. + if (mthing->options & (MTF_AMBUSH | MTF_OBJECTSPECIAL)) + return MT_SCORE10K_BOX; // 10,000 + else + return MT_SCORE1K_BOX; // 1,000 + } + + if (mariomode && i == MT_ROSY) + return MT_TOAD; // don't remove on penalty of death + + return i; +} + // // P_SpawnMapThing // The fields of the mapthing should @@ -11716,176 +11908,24 @@ void P_SpawnMapThing(mapthing_t *mthing) if (mthing->type == 3328) // 3D Mode start Thing return; - // Always spawn in objectplace. - // Skip all returning code. - if (objectplacing) - { - // find which type to spawn - i = P_GetMobjtype(mthing->type); - if (i == MT_UNKNOWN) - CONS_Alert(CONS_WARNING, M_GetText("Unknown thing type %d placed at (%d, %d)\n"), mthing->type, mthing->x, mthing->y); - goto noreturns; - } - - if (P_SpawnNonMobjMapThing(mthing)) + if (!objectplacing && P_SpawnNonMobjMapThing(mthing)) return; - if (mthing->type == mobjinfo[MT_RING].doomednum || mthing->type == mobjinfo[MT_COIN].doomednum - || mthing->type == mobjinfo[MT_REDTEAMRING].doomednum || mthing->type == mobjinfo[MT_BLUETEAMRING].doomednum - || mthing->type == mobjinfo[MT_BLUESPHERE].doomednum || mthing->type == mobjinfo[MT_BOMBSPHERE].doomednum) // hoops - return; // These are handled in P_SpawnHoopsAndRings(). - i = P_GetMobjtype(mthing->type); if (i == MT_UNKNOWN) CONS_Alert(CONS_WARNING, M_GetText("Unknown thing type %d placed at (%d, %d)\n"), mthing->type, mthing->x, mthing->y); - if (metalrecording) // Metal Sonic can't use these things. - if (mobjinfo[i].flags & (MF_ENEMY|MF_BOSS) || i == MT_TOKEN || i == MT_STARPOST) + // Skip all returning/substitution code in objectplace. + if (!objectplacing) + { + if (!P_AllowMobjSpawn(mthing, i)) return; - if (i >= MT_EMERALD1 && i <= MT_EMERALD7) // Pickupable Emeralds - { - if (gametype != GT_COOP) // Don't place emeralds in non-coop modes - return; - - if (metalrecording) - return; // Metal Sonic isn't for collecting emeralds. - - if (emeralds & mobjinfo[i].speed) // You already have this emerald! + i = P_GetMobjtypeSubstitute(mthing, i); + if (i == MT_NULL) // Don't spawn mobj return; } - if (i == MT_EMERHUNT) - { - // Emerald Hunt is Coop only. - if (gametype != GT_COOP) - return; - - if (numhuntemeralds < MAXHUNTEMERALDS) - huntemeralds[numhuntemeralds++] = mthing; - return; - } - - if (i == MT_EMERALDSPAWN) - { - if (!cv_powerstones.value) - return; - - if (!(gametype == GT_MATCH || gametype == GT_CTF)) - return; - - runemeraldmanager = true; - } - - if (!G_PlatformGametype()) // No enemies in match or CTF modes - if ((mobjinfo[i].flags & MF_ENEMY) || (mobjinfo[i].flags & MF_BOSS)) - return; - - if (!G_RingSlingerGametype() || !cv_specialrings.value) - if (P_WeaponOrPanel(i)) - return; // Don't place weapons/panels in non-ringslinger modes - - // Altering monitor spawns via cvars - // If MF_GRENADEBOUNCE is set in the monitor's info, - // skip this step. (Used for gold monitors) - // Yeah, this is a dirty hack. - if ((mobjinfo[i].flags & (MF_MONITOR|MF_GRENADEBOUNCE)) == MF_MONITOR) - { - if (gametype == GT_COMPETITION || gametype == GT_RACE) - { - // Set powerup boxes to user settings for competition. - if (cv_competitionboxes.value == 1) // Mystery - i = MT_MYSTERY_BOX; - else if (cv_competitionboxes.value == 2) // Teleport - i = MT_MIXUP_BOX; - else if (cv_competitionboxes.value == 3) // None - return; // Don't spawn! - // default case: normal - } - // Set powerup boxes to user settings for other netplay modes - else if (gametype != GT_COOP) - { - if (cv_matchboxes.value == 1) // Mystery - i = MT_MYSTERY_BOX; - else if (cv_matchboxes.value == 2) // Unchanging - { - if (i == MT_MYSTERY_BOX) - return; // don't spawn - mthing->options &= ~(MTF_AMBUSH|MTF_OBJECTSPECIAL); // no random respawning! - } - else if (cv_matchboxes.value == 3) // Don't spawn - return; - // default case: normal - } - } - - if (gametype != GT_CTF) // CTF specific things - { - if (i == MT_RING_BLUEBOX || i == MT_RING_REDBOX) - i = MT_RING_BOX; - else if (i == MT_BLUEFLAG || i == MT_REDFLAG) - return; // No flags in non-CTF modes! - } - else - { - if ((i == MT_BLUEFLAG && blueflag) || (i == MT_REDFLAG && redflag)) - { - CONS_Alert(CONS_ERROR, M_GetText("Only one flag per team allowed in CTF!\n")); - return; - } - } - - if (!G_PlatformGametype() && (i == MT_SIGN || i == MT_STARPOST)) - return; // Don't spawn exit signs or starposts in wrong game modes - - if (modeattacking) // Record Attack special stuff - { - // Don't spawn starposts that wouldn't be usable - if (i == MT_STARPOST) - return; - - // 1UPs -->> Score TVs - else if (i == MT_1UP_BOX) // 1UP - { - // Either or, doesn't matter which. - if (mthing->options & (MTF_AMBUSH|MTF_OBJECTSPECIAL)) - i = MT_SCORE10K_BOX; // 10,000 - else - i = MT_SCORE1K_BOX; // 1,000 - } - } - - if (ultimatemode) - { - if (i == MT_PITY_BOX || i == MT_ELEMENTAL_BOX || i == MT_ATTRACT_BOX - || i == MT_FORCE_BOX || i == MT_ARMAGEDDON_BOX || i == MT_WHIRLWIND_BOX - || i == MT_FLAMEAURA_BOX || i == MT_BUBBLEWRAP_BOX || i == MT_THUNDERCOIN_BOX - || i == MT_RING_BOX || i == MT_STARPOST) - return; // No rings or shields in Ultimate mode - - // Don't include the gold repeating boxes here please. - // They're likely facets of the level's design and therefore required to progress. - } - - if (i == MT_ROSY) - { - if (!(gametype == GT_COOP || (mthing->options & MTF_EXTRA))) - return; // she doesn't hang out here - else if (mariomode) - i = MT_TOAD; // don't remove on penalty of death - else if (!(netgame || multiplayer) && players[consoleplayer].skin == 3) - return; // no doubles - } - - if (i == MT_TOKEN && ((gametype != GT_COOP && gametype != GT_COMPETITION) || tokenbits == 30 || tokenlist & (1 << tokenbits++))) - return; // you already got this token, or there are too many, or the gametype's not right - - if (i == MT_EMBLEM && (netgame || multiplayer || (modifiedgame && !savemoddata))) // No cheating!! - return; - - // Objectplace landing point - noreturns: - // spawn it x = mthing->x << FRACBITS; y = mthing->y << FRACBITS; From e382c2e09464dcb4c6bb8d51e9c1b5d362a53f68 Mon Sep 17 00:00:00 2001 From: MascaraSnake Date: Mon, 23 Dec 2019 18:59:11 +0100 Subject: [PATCH 329/746] P_SpawnMapThing(): Separated the giant post-Lua hook switch-case statement into its own function, and separated some of the larger cases into their own function as well --- src/p_mobj.c | 1539 +++++++++++++++++++++++++------------------------- 1 file changed, 759 insertions(+), 780 deletions(-) diff --git a/src/p_mobj.c b/src/p_mobj.c index c2b40a96b..0397451d0 100644 --- a/src/p_mobj.c +++ b/src/p_mobj.c @@ -11890,116 +11890,626 @@ static mobjtype_t P_GetMobjtypeSubstitute(mapthing_t *mthing, mobjtype_t i) return i; } -// -// P_SpawnMapThing -// The fields of the mapthing should -// already be in host byte order. -// -void P_SpawnMapThing(mapthing_t *mthing) +static boolean P_SetupEmblem(mapthing_t *mthing, mobj_t *mobj) { - mobjtype_t i; - mobj_t *mobj; - fixed_t x, y, z; - boolean doangle = true; + INT32 j; + emblem_t* emblem = M_GetLevelEmblems(gamemap); + skincolors_t emcolor; - if (!mthing->type) - return; // Ignore type-0 things as NOPs - - if (mthing->type == 3328) // 3D Mode start Thing - return; - - if (!objectplacing && P_SpawnNonMobjMapThing(mthing)) - return; - - i = P_GetMobjtype(mthing->type); - if (i == MT_UNKNOWN) - CONS_Alert(CONS_WARNING, M_GetText("Unknown thing type %d placed at (%d, %d)\n"), mthing->type, mthing->x, mthing->y); - - // Skip all returning/substitution code in objectplace. - if (!objectplacing) + while (emblem) { - if (!P_AllowMobjSpawn(mthing, i)) - return; - - i = P_GetMobjtypeSubstitute(mthing, i); - if (i == MT_NULL) // Don't spawn mobj - return; - } - - // spawn it - x = mthing->x << FRACBITS; - y = mthing->y << FRACBITS; - z = P_GetMobjSpawnHeight(i, mthing, x, y); - - mobj = P_SpawnMobj(x, y, z, i); - mobj->spawnpoint = mthing; - -#ifdef HAVE_BLUA - if (LUAh_MapThingSpawn(mobj, mthing)) - { - if (P_MobjWasRemoved(mobj)) - return; - } - else if (P_MobjWasRemoved(mobj)) - return; - else -#endif - switch(mobj->type) - { - case MT_EMBLEM: - { - INT32 j; - emblem_t *emblem = M_GetLevelEmblems(gamemap); - skincolors_t emcolor; - - while (emblem) - { - if ((emblem->type == ET_GLOBAL || emblem->type == ET_SKIN) && emblem->tag == mthing->angle) - break; - - emblem = M_GetLevelEmblems(-1); - } - - if (!emblem) - { - CONS_Debug(DBG_GAMELOGIC, "No map emblem for map %d with tag %d found!\n", gamemap, mthing->angle); + if ((emblem->type == ET_GLOBAL || emblem->type == ET_SKIN) && emblem->tag == mthing->angle) break; - } - j = emblem - emblemlocations; + emblem = M_GetLevelEmblems(-1); + } - I_Assert(emblemlocations[j].sprite >= 'A' && emblemlocations[j].sprite <= 'Z'); - P_SetMobjState(mobj, mobj->info->spawnstate + (emblemlocations[j].sprite - 'A')); + if (!emblem) + { + CONS_Debug(DBG_GAMELOGIC, "No map emblem for map %d with tag %d found!\n", gamemap, mthing->angle); + return false; + } - mobj->health = j + 1; - emcolor = M_GetEmblemColor(&emblemlocations[j]); // workaround for compiler complaint about bad function casting - mobj->color = (UINT8)emcolor; + j = emblem - emblemlocations; - if (emblemlocations[j].collected - || (emblemlocations[j].type == ET_SKIN && emblemlocations[j].var != players[0].skin)) + I_Assert(emblemlocations[j].sprite >= 'A' && emblemlocations[j].sprite <= 'Z'); + P_SetMobjState(mobj, mobj->info->spawnstate + (emblemlocations[j].sprite - 'A')); + + mobj->health = j + 1; + emcolor = M_GetEmblemColor(&emblemlocations[j]); // workaround for compiler complaint about bad function casting + mobj->color = (UINT8)emcolor; + + if (emblemlocations[j].collected + || (emblemlocations[j].type == ET_SKIN && emblemlocations[j].var != players[0].skin)) + { + P_UnsetThingPosition(mobj); + mobj->flags |= MF_NOCLIP; + mobj->flags &= ~MF_SPECIAL; + mobj->flags |= MF_NOBLOCKMAP; + mobj->frame |= (tr_trans50 << FF_TRANSSHIFT); + P_SetThingPosition(mobj); + } + else + { + mobj->frame &= ~FF_TRANSMASK; + + if (emblemlocations[j].type == ET_GLOBAL) { - P_UnsetThingPosition(mobj); - mobj->flags |= MF_NOCLIP; - mobj->flags &= ~MF_SPECIAL; - mobj->flags |= MF_NOBLOCKMAP; - mobj->frame |= (tr_trans50 << FF_TRANSSHIFT); - P_SetThingPosition(mobj); + mobj->reactiontime = emblemlocations[j].var; + if (emblemlocations[j].var & GE_NIGHTSITEM) + { + mobj->flags |= MF_NIGHTSITEM; + mobj->flags &= ~MF_SPECIAL; + mobj->flags2 |= MF2_DONTDRAW; + } + } + } + return true; +} + +static boolean P_SetupMace(mapthing_t *mthing, mobj_t *mobj, boolean *doangle) +{ + fixed_t mlength, mmaxlength, mlengthset, mspeed, mphase, myaw, mpitch, mminlength, mnumspokes, mpinch, mroll, mnumnospokes, mwidth, mwidthset, mmin, msound, radiusfactor, widthfactor; + angle_t mspokeangle; + mobjtype_t chainlink, macetype, firsttype, linktype; + boolean mdosound, mdocenter, mchainlike = false; + mobj_t *spawnee = NULL, *hprev = mobj; + mobjflag_t mflagsapply; + mobjflag2_t mflags2apply; + mobjeflag_t meflagsapply; + INT32 line; + const size_t mthingi = (size_t)(mthing - mapthings); + + // Find the corresponding linedef special, using angle as tag + // P_FindSpecialLineFromTag works here now =D + line = P_FindSpecialLineFromTag(9, mthing->angle, -1); + + if (line == -1) + { + CONS_Debug(DBG_GAMELOGIC, "Mace chain (mapthing #%s) needs to be tagged to a #9 parameter line (trying to find tag %d).\n", sizeu1(mthingi), mthing->angle); + return false; + } + /* + mapthing - + MTF_AMBUSH : + MT_SPRINGBALLPOINT - upgrade from yellow to red spring + anything else - bigger mace/chain theory + MTF_OBJECTSPECIAL - force silent + MTF_GRAVFLIP - flips objects, doesn't affect chain arrangements + Parameter value : number of "spokes" + + linedef - + ML_NOCLIMB : + MT_CHAINPOINT/MT_CHAINMACEPOINT with ML_EFFECT1 applied - Direction not controllable + anything else - no functionality + ML_EFFECT1 : Swings instead of spins + ML_EFFECT2 : Linktype is replaced with macetype for all spokes not ending in chains (inverted for MT_FIREBARPOINT) + ML_EFFECT3 : Spawn a bonus linktype at the hinge point + ML_EFFECT4 : Don't clip inside the ground + ML_EFFECT5 : Don't stop thinking when too far away + */ + mlength = abs(lines[line].dx >> FRACBITS); + mspeed = abs(lines[line].dy >> (FRACBITS - 4)); + mphase = (sides[lines[line].sidenum[0]].textureoffset >> FRACBITS) % 360; + if ((mminlength = -sides[lines[line].sidenum[0]].rowoffset >> FRACBITS) < 0) + mminlength = 0; + else if (mminlength > mlength - 1) + mminlength = mlength - 1; + mpitch = (lines[line].frontsector->floorheight >> FRACBITS) % 360; + myaw = (lines[line].frontsector->ceilingheight >> FRACBITS) % 360; + + mnumspokes = mthing->extrainfo + 1; + mspokeangle = FixedAngle((360*FRACUNIT)/mnumspokes) >> ANGLETOFINESHIFT; + + if (lines[line].backsector) + { + mpinch = (lines[line].backsector->floorheight >> FRACBITS) % 360; + mroll = (lines[line].backsector->ceilingheight >> FRACBITS) % 360; + mnumnospokes = (sides[lines[line].sidenum[1]].textureoffset >> FRACBITS); + if ((mwidth = sides[lines[line].sidenum[1]].rowoffset >> FRACBITS) < 0) + mwidth = 0; + } + else + mpinch = mroll = mnumnospokes = mwidth = 0; + + CONS_Debug(DBG_GAMELOGIC, "Mace/Chain (mapthing #%s):\n" + "Length is %d (minus %d)\n" + "Speed is %d\n" + "Phase is %d\n" + "Yaw is %d\n" + "Pitch is %d\n" + "No. of spokes is %d (%d antispokes)\n" + "Pinch is %d\n" + "Roll is %d\n" + "Width is %d\n", + sizeu1(mthingi), mlength, mminlength, mspeed, mphase, myaw, mpitch, mnumspokes, mnumnospokes, mpinch, mroll, mwidth); + + if (mnumnospokes > 0 && (mnumnospokes < mnumspokes)) + mnumnospokes = mnumspokes/mnumnospokes; + else + mnumnospokes = ((mobj->type == MT_CHAINMACEPOINT) ? (mnumspokes) : 0); + + mobj->lastlook = mspeed; + mobj->movecount = mobj->lastlook; + mobj->angle = FixedAngle(myaw << FRACBITS); + *doangle = false; + mobj->threshold = (FixedAngle(mpitch << FRACBITS) >> ANGLETOFINESHIFT); + mobj->movefactor = mpinch; + mobj->movedir = 0; + + // Mobjtype selection + switch (mobj->type) + { + case MT_SPRINGBALLPOINT: + macetype = ((mthing->options & MTF_AMBUSH) + ? MT_REDSPRINGBALL + : MT_YELLOWSPRINGBALL); + chainlink = MT_SMALLMACECHAIN; + break; + case MT_FIREBARPOINT: + macetype = ((mthing->options & MTF_AMBUSH) + ? MT_BIGFIREBAR + : MT_SMALLFIREBAR); + chainlink = MT_NULL; + break; + case MT_CUSTOMMACEPOINT: + macetype = (mobjtype_t)sides[lines[line].sidenum[0]].toptexture; + if (lines[line].backsector) + chainlink = (mobjtype_t)sides[lines[line].sidenum[1]].toptexture; + else + chainlink = MT_NULL; + break; + case MT_CHAINPOINT: + if (mthing->options & MTF_AMBUSH) + { + macetype = MT_BIGGRABCHAIN; + chainlink = MT_BIGMACECHAIN; } else { - mobj->frame &= ~FF_TRANSMASK; + macetype = MT_SMALLGRABCHAIN; + chainlink = MT_SMALLMACECHAIN; + } + mchainlike = true; + break; + default: + if (mthing->options & MTF_AMBUSH) + { + macetype = MT_BIGMACE; + chainlink = MT_BIGMACECHAIN; + } + else + { + macetype = MT_SMALLMACE; + chainlink = MT_SMALLMACECHAIN; + } + break; + } - if (emblemlocations[j].type == ET_GLOBAL) + if (!macetype && !chainlink) + return true; + + if (mobj->type == MT_CHAINPOINT) + { + if (!mlength) + return true; + } + else + mlength++; + + firsttype = macetype; + + // Adjustable direction + if (lines[line].flags & ML_NOCLIMB) + mobj->flags |= MF_SLIDEME; + + // Swinging + if (lines[line].flags & ML_EFFECT1) + { + mobj->flags2 |= MF2_STRONGBOX; + mmin = ((mnumnospokes > 1) ? 1 : 0); + } + else + mmin = mnumspokes; + + // If over distance away, don't move UNLESS this flag is applied + if (lines[line].flags & ML_EFFECT5) + mobj->flags2 |= MF2_BOSSNOTRAP; + + // Make the links the same type as the end - repeated below + if ((mobj->type != MT_CHAINPOINT) && (((lines[line].flags & ML_EFFECT2) == ML_EFFECT2) != (mobj->type == MT_FIREBARPOINT))) // exclusive or + { + linktype = macetype; + radiusfactor = 2; // Double the radius. + } + else + radiusfactor = (((linktype = chainlink) == MT_NULL) ? 2 : 1); + + if (!mchainlike) + mchainlike = (firsttype == chainlink); + widthfactor = (mchainlike ? 1 : 2); + + mflagsapply = ((lines[line].flags & ML_EFFECT4) ? 0 : (MF_NOCLIP | MF_NOCLIPHEIGHT)); + mflags2apply = ((mthing->options & MTF_OBJECTFLIP) ? MF2_OBJECTFLIP : 0); + meflagsapply = ((mthing->options & MTF_OBJECTFLIP) ? MFE_VERTICALFLIP : 0); + + msound = (mchainlike ? 0 : (mwidth & 1)); + + // Quick and easy preparatory variable setting + mphase = (FixedAngle(mphase << FRACBITS) >> ANGLETOFINESHIFT); + mroll = (FixedAngle(mroll << FRACBITS) >> ANGLETOFINESHIFT); + +#define makemace(mobjtype, dist, moreflags2) {\ + spawnee = P_SpawnMobj(mobj->x, mobj->y, mobj->z, mobjtype);\ + P_SetTarget(&spawnee->tracer, mobj);\ + spawnee->threshold = mphase;\ + spawnee->friction = mroll;\ + spawnee->movefactor = mwidthset;\ + spawnee->movecount = dist;\ + spawnee->angle = myaw;\ + spawnee->flags |= (MF_NOGRAVITY|mflagsapply);\ + spawnee->flags2 |= (mflags2apply|moreflags2);\ + spawnee->eflags |= meflagsapply;\ + P_SetTarget(&hprev->hnext, spawnee);\ + P_SetTarget(&spawnee->hprev, hprev);\ + hprev = spawnee;\ +} + + mdosound = (mspeed && !(mthing->options & MTF_OBJECTSPECIAL)); + mdocenter = (macetype && (lines[line].flags & ML_EFFECT3)); + + // The actual spawning of spokes + while (mnumspokes-- > 0) + { + // Offsets + if (lines[line].flags & ML_EFFECT1) // Swinging + mroll = (mroll - mspokeangle) & FINEMASK; + else // Spinning + mphase = (mphase - mspokeangle) & FINEMASK; + + if (mnumnospokes && !(mnumspokes % mnumnospokes)) // Skipping a "missing" spoke + { + if (mobj->type != MT_CHAINMACEPOINT) + continue; + + linktype = chainlink; + firsttype = ((mthing->options & MTF_AMBUSH) ? MT_BIGGRABCHAIN : MT_SMALLGRABCHAIN); + mmaxlength = 1 + (mlength - 1) * radiusfactor; + radiusfactor = widthfactor = 1; + } + else + { + if (mobj->type == MT_CHAINMACEPOINT) { - mobj->reactiontime = emblemlocations[j].var; - if (emblemlocations[j].var & GE_NIGHTSITEM) + // Make the links the same type as the end - repeated above + if (lines[line].flags & ML_EFFECT2) { - mobj->flags |= MF_NIGHTSITEM; - mobj->flags &= ~MF_SPECIAL; - mobj->flags2 |= MF2_DONTDRAW; + linktype = macetype; + radiusfactor = 2; + } + else + radiusfactor = (((linktype = chainlink) == MT_NULL) ? 2 : 1); + + firsttype = macetype; + widthfactor = 2; + } + + mmaxlength = mlength; + } + + mwidthset = mwidth; + mlengthset = mminlength; + + if (mdocenter) // Innermost link + makemace(linktype, 0, 0); + + // Out from the center... + if (linktype) + { + while ((++mlengthset) < mmaxlength) + makemace(linktype, radiusfactor*mlengthset, 0); + } + else + mlengthset = mmaxlength; + + // Outermost mace/link + if (firsttype) + makemace(firsttype, radiusfactor*mlengthset, MF2_AMBUSH); + + if (!mwidth) + { + if (mdosound && mnumspokes <= mmin) // Can it make a sound? + spawnee->flags2 |= MF2_BOSSNOTRAP; + } + else + { + // Across the bar! + if (!firsttype) + mwidthset = -mwidth; + else if (mwidth > 0) + { + while ((mwidthset -= widthfactor) > -mwidth) + { + makemace(firsttype, radiusfactor*mlengthset, MF2_AMBUSH); + if (mdosound && (mwidthset == msound) && mnumspokes <= mmin) // Can it make a sound? + spawnee->flags2 |= MF2_BOSSNOTRAP; } } + else + { + while ((mwidthset += widthfactor) < -mwidth) + { + makemace(firsttype, radiusfactor*mlengthset, MF2_AMBUSH); + if (mdosound && (mwidthset == msound) && mnumspokes <= mmin) // Can it make a sound? + spawnee->flags2 |= MF2_BOSSNOTRAP; + } + } + mwidth = -mwidth; + + // Outermost mace/link again! + if (firsttype) + makemace(firsttype, radiusfactor*(mlengthset--), MF2_AMBUSH); + + // ...and then back into the center! + if (linktype) + while (mlengthset > mminlength) + makemace(linktype, radiusfactor*(mlengthset--), 0); + + if (mdocenter) // Innermost link + makemace(linktype, 0, 0); } + } +#undef makemace + return true; +} + +static boolean P_SetupParticleGen(mapthing_t *mthing, mobj_t *mobj) +{ + fixed_t radius, speed; + INT32 type, numdivisions, anglespeed, ticcount; + angle_t angledivision; + INT32 line; + const size_t mthingi = (size_t)(mthing - mapthings); + + // Find the corresponding linedef special, using angle as tag + line = P_FindSpecialLineFromTag(15, mthing->angle, -1); + + if (line == -1) + { + CONS_Debug(DBG_GAMELOGIC, "Particle generator (mapthing #%s) needs to be tagged to a #15 parameter line (trying to find tag %d).\n", sizeu1(mthingi), mthing->angle); + return false; + } + + if (sides[lines[line].sidenum[0]].toptexture) + type = sides[lines[line].sidenum[0]].toptexture; // Set as object type in p_setup.c... + else + type = (INT32)MT_PARTICLE; + + if (!lines[line].backsector + || (ticcount = (sides[lines[line].sidenum[1]].textureoffset >> FRACBITS)) < 1) + ticcount = 3; + + numdivisions = (mthing->options >> ZSHIFT); + + if (numdivisions) + { + radius = R_PointToDist2(lines[line].v1->x, lines[line].v1->y, lines[line].v2->x, lines[line].v2->y); + anglespeed = (sides[lines[line].sidenum[0]].rowoffset >> FRACBITS) % 360; + angledivision = 360/numdivisions; + } + else + { + numdivisions = 1; // Simple trick to make A_ParticleSpawn simpler. + radius = 0; + anglespeed = 0; + angledivision = 0; + } + + speed = abs(sides[lines[line].sidenum[0]].textureoffset); + if (mthing->options & MTF_OBJECTFLIP) + speed *= -1; + + CONS_Debug(DBG_GAMELOGIC, "Particle Generator (mapthing #%s):\n" + "Radius is %d\n" + "Speed is %d\n" + "Anglespeed is %d\n" + "Numdivisions is %d\n" + "Angledivision is %d\n" + "Type is %d\n" + "Tic seperation is %d\n", + sizeu1(mthingi), radius, speed, anglespeed, numdivisions, angledivision, type, ticcount); + + mobj->angle = 0; + mobj->movefactor = speed; + mobj->lastlook = numdivisions; + mobj->movedir = angledivision*ANG1; + mobj->movecount = anglespeed*ANG1; + mobj->friction = radius; + mobj->threshold = type; + mobj->reactiontime = ticcount; + mobj->cvmem = line; + mobj->watertop = mobj->waterbottom = 0; + return true; +} + +static boolean P_SetupNiGHTSDrone(mapthing_t* mthing, mobj_t* mobj) +{ + boolean flip = mthing->options & MTF_OBJECTFLIP; + boolean topaligned = (mthing->options & MTF_OBJECTSPECIAL) && !(mthing->options & MTF_EXTRA); + boolean middlealigned = (mthing->options & MTF_EXTRA) && !(mthing->options & MTF_OBJECTSPECIAL); + boolean bottomoffsetted = !(mthing->options & MTF_OBJECTSPECIAL) && !(mthing->options & MTF_EXTRA); + + INT16 timelimit = mthing->angle & 0xFFF; + fixed_t hitboxradius = ((mthing->angle & 0xF000) >> 12)*32*FRACUNIT; + fixed_t hitboxheight = mthing->extrainfo*32*FRACUNIT; + fixed_t oldheight = mobj->height; + fixed_t dronemanoffset, goaloffset, sparkleoffset, droneboxmandiff, dronemangoaldiff; + + if (timelimit > 0) + mobj->health = timelimit; + + if (hitboxradius > 0) + mobj->radius = hitboxradius; + + if (hitboxheight > 0) + mobj->height = hitboxheight; + else + mobj->height = mobjinfo[MT_NIGHTSDRONE].height; + + droneboxmandiff = max(mobj->height - mobjinfo[MT_NIGHTSDRONE_MAN].height, 0); + dronemangoaldiff = max(mobjinfo[MT_NIGHTSDRONE_MAN].height - mobjinfo[MT_NIGHTSDRONE_GOAL].height, 0); + + if (flip && mobj->height != oldheight) + P_TeleportMove(mobj, mobj->x, mobj->y, mobj->z - (mobj->height - oldheight)); + + if (!flip) + { + if (topaligned) // Align droneman to top of hitbox + { + dronemanoffset = droneboxmandiff; + goaloffset = dronemangoaldiff/2 + dronemanoffset; + } + else if (middlealigned) // Align droneman to center of hitbox + { + dronemanoffset = droneboxmandiff/2; + goaloffset = dronemangoaldiff/2 + dronemanoffset; + } + else if (bottomoffsetted) + { + dronemanoffset = 24*FRACUNIT; + goaloffset = dronemangoaldiff + dronemanoffset; + } + else + { + dronemanoffset = 0; + goaloffset = dronemangoaldiff/2 + dronemanoffset; + } + + sparkleoffset = goaloffset - FixedMul(15*FRACUNIT, mobj->scale); + } + else + { + mobj->eflags |= MFE_VERTICALFLIP; + mobj->flags2 |= MF2_OBJECTFLIP; + + if (topaligned) // Align droneman to top of hitbox + { + dronemanoffset = 0; + goaloffset = dronemangoaldiff/2 + dronemanoffset; + } + else if (middlealigned) // Align droneman to center of hitbox + { + dronemanoffset = droneboxmandiff/2; + goaloffset = dronemangoaldiff/2 + dronemanoffset; + } + else if (bottomoffsetted) + { + dronemanoffset = droneboxmandiff - FixedMul(24*FRACUNIT, mobj->scale); + goaloffset = dronemangoaldiff + dronemanoffset; + } + else + { + dronemanoffset = droneboxmandiff; + goaloffset = dronemangoaldiff/2 + dronemanoffset; + } + + sparkleoffset = goaloffset + FixedMul(15*FRACUNIT, mobj->scale); + } + + // spawn visual elements + { + mobj_t* goalpost = P_SpawnMobjFromMobj(mobj, 0, 0, goaloffset, MT_NIGHTSDRONE_GOAL); + mobj_t* sparkle = P_SpawnMobjFromMobj(mobj, 0, 0, sparkleoffset, MT_NIGHTSDRONE_SPARKLING); + mobj_t* droneman = P_SpawnMobjFromMobj(mobj, 0, 0, dronemanoffset, MT_NIGHTSDRONE_MAN); + + P_SetTarget(&mobj->target, goalpost); + P_SetTarget(&goalpost->target, sparkle); + P_SetTarget(&goalpost->tracer, droneman); + + // correct Z position + if (flip) + { + P_TeleportMove(goalpost, goalpost->x, goalpost->y, mobj->z + goaloffset); + P_TeleportMove(sparkle, sparkle->x, sparkle->y, mobj->z + sparkleoffset); + P_TeleportMove(droneman, droneman->x, droneman->y, mobj->z + dronemanoffset); + } + + // Remember position preference for later + mobj->flags &= ~(MF_SLIDEME|MF_GRENADEBOUNCE); + if (topaligned) + mobj->flags |= MF_SLIDEME; + else if (middlealigned) + mobj->flags |= MF_GRENADEBOUNCE; + else if (!bottomoffsetted) + mobj->flags |= MF_SLIDEME|MF_GRENADEBOUNCE; + + // Remember old Z position and flags for correction detection + goalpost->movefactor = mobj->z; + goalpost->friction = mobj->height; + goalpost->threshold = mobj->flags & (MF_SLIDEME|MF_GRENADEBOUNCE); + } + return true; +} + +static boolean P_SetupBooster(mapthing_t* mthing, mobj_t* mobj, boolean strong) +{ + angle_t angle = FixedAngle(mthing->angle << FRACBITS); + fixed_t x1 = FINECOSINE((angle >> ANGLETOFINESHIFT) & FINEMASK); + fixed_t y1 = FINESINE((angle >> ANGLETOFINESHIFT) & FINEMASK); + fixed_t x2 = FINECOSINE(((angle + ANGLE_90) >> ANGLETOFINESHIFT) & FINEMASK); + fixed_t y2 = FINESINE(((angle + ANGLE_90) >> ANGLETOFINESHIFT) & FINEMASK); + statenum_t facestate = strong ? S_REDBOOSTERSEG_FACE : S_YELLOWBOOSTERSEG_FACE; + statenum_t leftstate = strong ? S_REDBOOSTERSEG_LEFT : S_YELLOWBOOSTERSEG_LEFT; + statenum_t rightstate = strong ? S_REDBOOSTERSEG_RIGHT : S_YELLOWBOOSTERSEG_RIGHT; + statenum_t rollerstate = strong ? S_REDBOOSTERROLLER : S_YELLOWBOOSTERROLLER; + + mobj_t *seg = P_SpawnMobjFromMobj(mobj, 26*x1, 26*y1, 0, MT_BOOSTERSEG); + seg->angle = angle - ANGLE_90; + P_SetMobjState(seg, facestate); + seg = P_SpawnMobjFromMobj(mobj, -26*x1, -26*y1, 0, MT_BOOSTERSEG); + seg->angle = angle + ANGLE_90; + P_SetMobjState(seg, facestate); + seg = P_SpawnMobjFromMobj(mobj, 21*x2, 21*y2, 0, MT_BOOSTERSEG); + seg->angle = angle; + P_SetMobjState(seg, leftstate); + seg = P_SpawnMobjFromMobj(mobj, -21*x2, -21*y2, 0, MT_BOOSTERSEG); + seg->angle = angle; + P_SetMobjState(seg, rightstate); + + seg = P_SpawnMobjFromMobj(mobj, 13*(x1 + x2), 13*(y1 + y2), 0, MT_BOOSTERROLLER); + seg->angle = angle; + P_SetMobjState(seg, rollerstate); + seg = P_SpawnMobjFromMobj(mobj, 13*(x1 - x2), 13*(y1 - y2), 0, MT_BOOSTERROLLER); + seg->angle = angle; + P_SetMobjState(seg, rollerstate); + seg = P_SpawnMobjFromMobj(mobj, -13*(x1 + x2), -13*(y1 + y2), 0, MT_BOOSTERROLLER); + seg->angle = angle; + P_SetMobjState(seg, rollerstate); + seg = P_SpawnMobjFromMobj(mobj, -13*(x1 - x2), -13*(y1 - y2), 0, MT_BOOSTERROLLER); + seg->angle = angle; + P_SetMobjState(seg, rollerstate); + + return true; +} + +static boolean P_SetupSpawnedMapThing(mapthing_t *mthing, mobj_t *mobj, boolean *doangle) +{ +#ifdef HAVE_BLUA + boolean override = LUAh_MapThingSpawn(mobj, mthing); + + if (P_MobjWasRemoved(mobj)) + return false; + + if (override) + return true; +#endif + + switch (mobj->type) + { + case MT_EMBLEM: + { + if (!P_SetupEmblem(mthing, mobj)) + return false; break; } case MT_SKYBOX: @@ -12033,7 +12543,7 @@ void P_SpawnMapThing(mapthing_t *mthing) if (mthing->angle) mobj->health = mthing->angle; else - mobj->health = FixedMul(mobj->subsector->sector->ceilingheight - mobj->subsector->sector->floorheight, 3*(FRACUNIT/4))>>FRACBITS; + mobj->health = FixedMul(mobj->subsector->sector->ceilingheight - mobj->subsector->sector->floorheight, 3*(FRACUNIT/4)) >> FRACBITS; break; case MT_METALSONIC_RACE: case MT_METALSONIC_BATTLE: @@ -12048,7 +12558,7 @@ void P_SpawnMapThing(mapthing_t *mthing) break; case MT_BALLOON: if (mthing->angle > 0) - mobj->color = ((mthing->angle-1) % (MAXSKINCOLORS-1))+1; + mobj->color = ((mthing->angle - 1) % (MAXSKINCOLORS - 1)) + 1; break; #define makesoftwarecorona(mo, h) \ corona = P_SpawnMobjFromMobj(mo, 0, 0, h<angle) - mobj->tics = 3*TICRATE + mthing->angle; - else - mobj->tics = 3*TICRATE; + mobj->tics = 3*TICRATE + mthing->angle; break; case MT_FLAMEJET: case MT_VERTICALFLAMEJET: @@ -12120,391 +12627,13 @@ void P_SpawnMapThing(mapthing_t *mthing) case MT_CHAINPOINT: case MT_FIREBARPOINT: case MT_CUSTOMMACEPOINT: - { - fixed_t mlength, mmaxlength, mlengthset, mspeed, mphase, myaw, mpitch, mminlength, mnumspokes, mpinch, mroll, mnumnospokes, mwidth, mwidthset, mmin, msound, radiusfactor, widthfactor; - angle_t mspokeangle; - mobjtype_t chainlink, macetype, firsttype, linktype; - boolean mdosound, mdocenter, mchainlike = false; - mobj_t *spawnee = NULL, *hprev = mobj; - mobjflag_t mflagsapply; - mobjflag2_t mflags2apply; - mobjeflag_t meflagsapply; - INT32 line; - const size_t mthingi = (size_t)(mthing - mapthings); - - // Find the corresponding linedef special, using angle as tag - // P_FindSpecialLineFromTag works here now =D - line = P_FindSpecialLineFromTag(9, mthing->angle, -1); - - if (line == -1) - { - CONS_Debug(DBG_GAMELOGIC, "Mace chain (mapthing #%s) needs to be tagged to a #9 parameter line (trying to find tag %d).\n", sizeu1(mthingi), mthing->angle); - return; - } -/* -mapthing - -MTF_AMBUSH : - MT_SPRINGBALLPOINT - upgrade from yellow to red spring - anything else - bigger mace/chain theory -MTF_OBJECTSPECIAL - force silent -MTF_GRAVFLIP - flips objects, doesn't affect chain arrangements -Parameter value : number of "spokes" - -linedef - -ML_NOCLIMB : - MT_CHAINPOINT/MT_CHAINMACEPOINT with ML_EFFECT1 applied - Direction not controllable - anything else - no functionality -ML_EFFECT1 : Swings instead of spins -ML_EFFECT2 : Linktype is replaced with macetype for all spokes not ending in chains (inverted for MT_FIREBARPOINT) -ML_EFFECT3 : Spawn a bonus linktype at the hinge point -ML_EFFECT4 : Don't clip inside the ground -ML_EFFECT5 : Don't stop thinking when too far away -*/ - mlength = abs(lines[line].dx >> FRACBITS); - mspeed = abs(lines[line].dy >> (FRACBITS - 4)); - mphase = (sides[lines[line].sidenum[0]].textureoffset >> FRACBITS) % 360; - if ((mminlength = -sides[lines[line].sidenum[0]].rowoffset>>FRACBITS) < 0) - mminlength = 0; - else if (mminlength > mlength-1) - mminlength = mlength-1; - mpitch = (lines[line].frontsector->floorheight >> FRACBITS) % 360; - myaw = (lines[line].frontsector->ceilingheight >> FRACBITS) % 360; - - mnumspokes = mthing->extrainfo + 1; - mspokeangle = FixedAngle((360*FRACUNIT)/mnumspokes)>>ANGLETOFINESHIFT; - - if (lines[line].backsector) - { - mpinch = (lines[line].backsector->floorheight >> FRACBITS) % 360; - mroll = (lines[line].backsector->ceilingheight >> FRACBITS) % 360; - mnumnospokes = (sides[lines[line].sidenum[1]].textureoffset >> FRACBITS); - if ((mwidth = sides[lines[line].sidenum[1]].rowoffset >> FRACBITS) < 0) - mwidth = 0; - } - else - mpinch = mroll = mnumnospokes = mwidth = 0; - - CONS_Debug(DBG_GAMELOGIC, "Mace/Chain (mapthing #%s):\n" - "Length is %d (minus %d)\n" - "Speed is %d\n" - "Phase is %d\n" - "Yaw is %d\n" - "Pitch is %d\n" - "No. of spokes is %d (%d antispokes)\n" - "Pinch is %d\n" - "Roll is %d\n" - "Width is %d\n", - sizeu1(mthingi), mlength, mminlength, mspeed, mphase, myaw, mpitch, mnumspokes, mnumnospokes, mpinch, mroll, mwidth); - - if (mnumnospokes > 0 && (mnumnospokes < mnumspokes)) - mnumnospokes = mnumspokes/mnumnospokes; - else - mnumnospokes = ((mobj->type == MT_CHAINMACEPOINT) ? (mnumspokes) : 0); - - mobj->lastlook = mspeed; - mobj->movecount = mobj->lastlook; - mobj->angle = FixedAngle(myaw*FRACUNIT); - doangle = false; - mobj->threshold = (FixedAngle(mpitch*FRACUNIT)>>ANGLETOFINESHIFT); - mobj->movefactor = mpinch; - mobj->movedir = 0; - - // Mobjtype selection - switch(mobj->type) - { - case MT_SPRINGBALLPOINT: - macetype = ((mthing->options & MTF_AMBUSH) - ? MT_REDSPRINGBALL - : MT_YELLOWSPRINGBALL); - chainlink = MT_SMALLMACECHAIN; - break; - case MT_FIREBARPOINT: - macetype = ((mthing->options & MTF_AMBUSH) - ? MT_BIGFIREBAR - : MT_SMALLFIREBAR); - chainlink = MT_NULL; - break; - case MT_CUSTOMMACEPOINT: - macetype = (mobjtype_t)sides[lines[line].sidenum[0]].toptexture; - if (lines[line].backsector) - chainlink = (mobjtype_t)sides[lines[line].sidenum[1]].toptexture; - else - chainlink = MT_NULL; - break; - case MT_CHAINPOINT: - if (mthing->options & MTF_AMBUSH) - { - macetype = MT_BIGGRABCHAIN; - chainlink = MT_BIGMACECHAIN; - } - else - { - macetype = MT_SMALLGRABCHAIN; - chainlink = MT_SMALLMACECHAIN; - } - mchainlike = true; - break; - default: - if (mthing->options & MTF_AMBUSH) - { - macetype = MT_BIGMACE; - chainlink = MT_BIGMACECHAIN; - } - else - { - macetype = MT_SMALLMACE; - chainlink = MT_SMALLMACECHAIN; - } - break; - } - - if (!macetype && !chainlink) - break; - - if (mobj->type == MT_CHAINPOINT) - { - if (!mlength) - break; - } - else - mlength++; - - firsttype = macetype; - - // Adjustable direction - if (lines[line].flags & ML_NOCLIMB) - mobj->flags |= MF_SLIDEME; - - // Swinging - if (lines[line].flags & ML_EFFECT1) - { - mobj->flags2 |= MF2_STRONGBOX; - mmin = ((mnumnospokes > 1) ? 1 : 0); - } - else - mmin = mnumspokes; - - // If over distance away, don't move UNLESS this flag is applied - if (lines[line].flags & ML_EFFECT5) - mobj->flags2 |= MF2_BOSSNOTRAP; - - // Make the links the same type as the end - repeated below - if ((mobj->type != MT_CHAINPOINT) && (((lines[line].flags & ML_EFFECT2) == ML_EFFECT2) != (mobj->type == MT_FIREBARPOINT))) // exclusive or - { - linktype = macetype; - radiusfactor = 2; // Double the radius. - } - else - radiusfactor = (((linktype = chainlink) == MT_NULL) ? 2 : 1); - - if (!mchainlike) - mchainlike = (firsttype == chainlink); - widthfactor = (mchainlike ? 1 : 2); - - mflagsapply = ((lines[line].flags & ML_EFFECT4) ? 0 : (MF_NOCLIP|MF_NOCLIPHEIGHT)); - mflags2apply = ((mthing->options & MTF_OBJECTFLIP) ? MF2_OBJECTFLIP : 0); - meflagsapply = ((mthing->options & MTF_OBJECTFLIP) ? MFE_VERTICALFLIP : 0); - - msound = (mchainlike ? 0 : (mwidth & 1)); - - // Quick and easy preparatory variable setting - mphase = (FixedAngle(mphase*FRACUNIT)>>ANGLETOFINESHIFT); - mroll = (FixedAngle(mroll*FRACUNIT)>>ANGLETOFINESHIFT); - -#define makemace(mobjtype, dist, moreflags2) {\ - spawnee = P_SpawnMobj(mobj->x, mobj->y, mobj->z, mobjtype);\ - P_SetTarget(&spawnee->tracer, mobj);\ - spawnee->threshold = mphase;\ - spawnee->friction = mroll;\ - spawnee->movefactor = mwidthset;\ - spawnee->movecount = dist;\ - spawnee->angle = myaw;\ - spawnee->flags |= (MF_NOGRAVITY|mflagsapply);\ - spawnee->flags2 |= (mflags2apply|moreflags2);\ - spawnee->eflags |= meflagsapply;\ - P_SetTarget(&hprev->hnext, spawnee);\ - P_SetTarget(&spawnee->hprev, hprev);\ - hprev = spawnee;\ -} - - mdosound = (mspeed && !(mthing->options & MTF_OBJECTSPECIAL)); - mdocenter = (macetype && (lines[line].flags & ML_EFFECT3)); - - // The actual spawning of spokes - while (mnumspokes-- > 0) - { - // Offsets - if (lines[line].flags & ML_EFFECT1) // Swinging - mroll = (mroll - mspokeangle) & FINEMASK; - else // Spinning - mphase = (mphase - mspokeangle) & FINEMASK; - - if (mnumnospokes && !(mnumspokes % mnumnospokes)) // Skipping a "missing" spoke - { - if (mobj->type != MT_CHAINMACEPOINT) - continue; - - linktype = chainlink; - firsttype = ((mthing->options & MTF_AMBUSH) ? MT_BIGGRABCHAIN : MT_SMALLGRABCHAIN); - mmaxlength = 1 + (mlength - 1)*radiusfactor; - radiusfactor = widthfactor = 1; - } - else - { - if (mobj->type == MT_CHAINMACEPOINT) - { - // Make the links the same type as the end - repeated above - if (lines[line].flags & ML_EFFECT2) - { - linktype = macetype; - radiusfactor = 2; - } - else - radiusfactor = (((linktype = chainlink) == MT_NULL) ? 2 : 1); - - firsttype = macetype; - widthfactor = 2; - } - - mmaxlength = mlength; - } - - mwidthset = mwidth; - mlengthset = mminlength; - - if (mdocenter) // Innermost link - makemace(linktype, 0, 0); - - // Out from the center... - if (linktype) - { - while ((++mlengthset) < mmaxlength) - makemace(linktype, radiusfactor*mlengthset, 0); - } - else - mlengthset = mmaxlength; - - // Outermost mace/link - if (firsttype) - makemace(firsttype, radiusfactor*mlengthset, MF2_AMBUSH); - - if (!mwidth) - { - if (mdosound && mnumspokes <= mmin) // Can it make a sound? - spawnee->flags2 |= MF2_BOSSNOTRAP; - } - else - { - // Across the bar! - if (!firsttype) - mwidthset = -mwidth; - else if (mwidth > 0) - { - while ((mwidthset -= widthfactor) > -mwidth) - { - makemace(firsttype, radiusfactor*mlengthset, MF2_AMBUSH); - if (mdosound && (mwidthset == msound) && mnumspokes <= mmin) // Can it make a sound? - spawnee->flags2 |= MF2_BOSSNOTRAP; - } - } - else - { - while ((mwidthset += widthfactor) < -mwidth) - { - makemace(firsttype, radiusfactor*mlengthset, MF2_AMBUSH); - if (mdosound && (mwidthset == msound) && mnumspokes <= mmin) // Can it make a sound? - spawnee->flags2 |= MF2_BOSSNOTRAP; - } - } - mwidth = -mwidth; - - // Outermost mace/link again! - if (firsttype) - makemace(firsttype, radiusfactor*(mlengthset--), MF2_AMBUSH); - - // ...and then back into the center! - if (linktype) - while (mlengthset > mminlength) - makemace(linktype, radiusfactor*(mlengthset--), 0); - - if (mdocenter) // Innermost link - makemace(linktype, 0, 0); - } - } - -#undef makemace - + if (!P_SetupMace(mthing, mobj, doangle)) + return false; break; - } case MT_PARTICLEGEN: - { - fixed_t radius, speed; - INT32 type, numdivisions, anglespeed, ticcount; - angle_t angledivision; - INT32 line; - const size_t mthingi = (size_t)(mthing - mapthings); - - // Find the corresponding linedef special, using angle as tag - line = P_FindSpecialLineFromTag(15, mthing->angle, -1); - - if (line == -1) - { - CONS_Debug(DBG_GAMELOGIC, "Particle generator (mapthing #%s) needs to be tagged to a #15 parameter line (trying to find tag %d).\n", sizeu1(mthingi), mthing->angle); - return; - } - - if (sides[lines[line].sidenum[0]].toptexture) - type = sides[lines[line].sidenum[0]].toptexture; // Set as object type in p_setup.c... - else - type = (INT32)MT_PARTICLE; - - if (!lines[line].backsector - || (ticcount = (sides[lines[line].sidenum[1]].textureoffset >> FRACBITS)) < 1) - ticcount = 3; - - numdivisions = (mthing->options >> ZSHIFT); - - if (numdivisions) - { - radius = R_PointToDist2(lines[line].v1->x, lines[line].v1->y, lines[line].v2->x, lines[line].v2->y); - anglespeed = (sides[lines[line].sidenum[0]].rowoffset >> FRACBITS) % 360; - angledivision = 360/numdivisions; - } - else - { - numdivisions = 1; // Simple trick to make A_ParticleSpawn simpler. - radius = 0; - anglespeed = 0; - angledivision = 0; - } - - speed = abs(sides[lines[line].sidenum[0]].textureoffset); - if (mthing->options & MTF_OBJECTFLIP) - speed *= -1; - - CONS_Debug(DBG_GAMELOGIC, "Particle Generator (mapthing #%s):\n" - "Radius is %d\n" - "Speed is %d\n" - "Anglespeed is %d\n" - "Numdivisions is %d\n" - "Angledivision is %d\n" - "Type is %d\n" - "Tic seperation is %d\n", - sizeu1(mthingi), radius, speed, anglespeed, numdivisions, angledivision, type, ticcount); - - mobj->angle = 0; - mobj->movefactor = speed; - mobj->lastlook = numdivisions; - mobj->movedir = angledivision*ANG1; - mobj->movecount = anglespeed*ANG1; - mobj->friction = radius; - mobj->threshold = type; - mobj->reactiontime = ticcount; - mobj->cvmem = line; - mobj->watertop = mobj->waterbottom = 0; - + if (!P_SetupParticleGen(mthing, mobj)) + return false; break; - } case MT_ROCKSPAWNER: mobj->threshold = mthing->angle; mobj->movecount = mthing->extrainfo; @@ -12519,7 +12648,7 @@ ML_EFFECT5 : Don't stop thinking when too far away // Lower 4 bits specify the angle of // the bumper in 30 degree increments. mobj->threshold = (mthing->options & 15) % 12; // It loops over, etc - P_SetMobjState(mobj, mobj->info->spawnstate+mobj->threshold); + P_SetMobjState(mobj, mobj->info->spawnstate + mobj->threshold); break; case MT_EGGCAPSULE: if (mthing->angle <= 0) @@ -12536,122 +12665,8 @@ ML_EFFECT5 : Don't stop thinking when too far away mobj->health = mthing->extrainfo; break; case MT_NIGHTSDRONE: - { - boolean flip = mthing->options & MTF_OBJECTFLIP; - boolean topaligned = (mthing->options & MTF_OBJECTSPECIAL) && !(mthing->options & MTF_EXTRA); - boolean middlealigned = (mthing->options & MTF_EXTRA) && !(mthing->options & MTF_OBJECTSPECIAL); - boolean bottomoffsetted = !(mthing->options & MTF_OBJECTSPECIAL) && !(mthing->options & MTF_EXTRA); - - INT16 timelimit = mthing->angle & 0xFFF; - fixed_t hitboxradius = ((mthing->angle & 0xF000) >> 12) * 32 * FRACUNIT; - fixed_t hitboxheight = mthing->extrainfo * 32 * FRACUNIT; - fixed_t oldheight = mobj->height; - fixed_t dronemanoffset, goaloffset, sparkleoffset, droneboxmandiff, dronemangoaldiff; - - if (timelimit > 0) - mobj->health = timelimit; - - if (hitboxradius > 0) - mobj->radius = hitboxradius; - - if (hitboxheight > 0) - mobj->height = hitboxheight; - else - mobj->height = mobjinfo[MT_NIGHTSDRONE].height; - - droneboxmandiff = max(mobj->height - mobjinfo[MT_NIGHTSDRONE_MAN].height, 0); - dronemangoaldiff = max(mobjinfo[MT_NIGHTSDRONE_MAN].height - mobjinfo[MT_NIGHTSDRONE_GOAL].height, 0); - - if (flip && mobj->height != oldheight) - P_TeleportMove(mobj, mobj->x, mobj->y, mobj->z - (mobj->height - oldheight)); - - if (!flip) - { - if (topaligned) // Align droneman to top of hitbox - { - dronemanoffset = droneboxmandiff; - goaloffset = dronemangoaldiff / 2 + dronemanoffset; - } - else if (middlealigned) // Align droneman to center of hitbox - { - dronemanoffset = droneboxmandiff / 2; - goaloffset = dronemangoaldiff / 2 + dronemanoffset; - } - else if (bottomoffsetted) - { - dronemanoffset = 24*FRACUNIT; - goaloffset = dronemangoaldiff + dronemanoffset; - } - else - { - dronemanoffset = 0; - goaloffset = dronemangoaldiff / 2 + dronemanoffset; - } - - sparkleoffset = goaloffset - FixedMul(15*FRACUNIT, mobj->scale); - } - else - { - mobj->eflags |= MFE_VERTICALFLIP; - mobj->flags2 |= MF2_OBJECTFLIP; - - if (topaligned) // Align droneman to top of hitbox - { - dronemanoffset = 0; - goaloffset = dronemangoaldiff / 2 + dronemanoffset; - } - else if (middlealigned) // Align droneman to center of hitbox - { - dronemanoffset = droneboxmandiff / 2; - goaloffset = dronemangoaldiff / 2 + dronemanoffset; - } - else if (bottomoffsetted) - { - dronemanoffset = droneboxmandiff - FixedMul(24*FRACUNIT, mobj->scale); - goaloffset = dronemangoaldiff + dronemanoffset; - } - else - { - dronemanoffset = droneboxmandiff; - goaloffset = dronemangoaldiff / 2 + dronemanoffset; - } - - sparkleoffset = goaloffset + FixedMul(15*FRACUNIT, mobj->scale); - } - - // spawn visual elements - { - mobj_t *goalpost = P_SpawnMobjFromMobj(mobj, 0, 0, goaloffset, MT_NIGHTSDRONE_GOAL); - mobj_t *sparkle = P_SpawnMobjFromMobj(mobj, 0, 0, sparkleoffset, MT_NIGHTSDRONE_SPARKLING); - mobj_t *droneman = P_SpawnMobjFromMobj(mobj, 0, 0, dronemanoffset, MT_NIGHTSDRONE_MAN); - - P_SetTarget(&mobj->target, goalpost); - P_SetTarget(&goalpost->target, sparkle); - P_SetTarget(&goalpost->tracer, droneman); - - // correct Z position - if (flip) - { - P_TeleportMove(goalpost, goalpost->x, goalpost->y, mobj->z + goaloffset); - P_TeleportMove(sparkle, sparkle->x, sparkle->y, mobj->z + sparkleoffset); - P_TeleportMove(droneman, droneman->x, droneman->y, mobj->z + dronemanoffset); - } - - // Remember position preference for later - mobj->flags &= ~(MF_SLIDEME | MF_GRENADEBOUNCE); - if (topaligned) - mobj->flags |= MF_SLIDEME; - else if (middlealigned) - mobj->flags |= MF_GRENADEBOUNCE; - else if (!bottomoffsetted) - mobj->flags |= MF_SLIDEME | MF_GRENADEBOUNCE; - - // Remember old Z position and flags for correction detection - goalpost->movefactor = mobj->z; - goalpost->friction = mobj->height; - goalpost->threshold = mobj->flags & (MF_SLIDEME | MF_GRENADEBOUNCE); - } - } + if (!P_SetupNiGHTSDrone(mthing, mobj)) + return false; break; case MT_HIVEELEMENTAL: if (mthing->extrainfo) @@ -12662,7 +12677,7 @@ ML_EFFECT5 : Don't stop thinking when too far away case MT_GLAREGOYLEDOWN: case MT_GLAREGOYLELONG: if (mthing->angle >= 360) - mobj->tics += 7*(mthing->angle / 360) + 1; // starting delay + mobj->tics += 7*(mthing->angle/360) + 1; // starting delay break; case MT_DSZSTALAGMITE: case MT_DSZ2STALAGMITE: @@ -12673,39 +12688,39 @@ ML_EFFECT5 : Don't stop thinking when too far away } break; case MT_THZTREE: - { // Spawn the branches - angle_t mobjangle = FixedAngle((mthing->angle % 113)<angle = mobjangle + ANGLE_22h; - P_SpawnMobjFromMobj(mobj, 0, 1*FRACUNIT, 0, MT_THZTREEBRANCH)->angle = mobjangle + ANGLE_157h; - P_SpawnMobjFromMobj(mobj, -1*FRACUNIT, 0, 0, MT_THZTREEBRANCH)->angle = mobjangle + ANGLE_270; - } - break; + { // Spawn the branches + angle_t mobjangle = FixedAngle((mthing->angle % 113) << FRACBITS); + P_SpawnMobjFromMobj(mobj, FRACUNIT, 0, 0, MT_THZTREEBRANCH)->angle = mobjangle + ANGLE_22h; + P_SpawnMobjFromMobj(mobj, 0, FRACUNIT, 0, MT_THZTREEBRANCH)->angle = mobjangle + ANGLE_157h; + P_SpawnMobjFromMobj(mobj, -FRACUNIT, 0, 0, MT_THZTREEBRANCH)->angle = mobjangle + ANGLE_270; + } + break; case MT_CEZPOLE1: case MT_CEZPOLE2: - { // Spawn the banner - angle_t mobjangle = FixedAngle(mthing->angle<type == MT_CEZPOLE1) ? MT_CEZBANNER1 : MT_CEZBANNER2))->angle = mobjangle + ANGLE_90; - } - break; + { // Spawn the banner + angle_t mobjangle = FixedAngle(mthing->angle << FRACBITS); + P_SpawnMobjFromMobj(mobj, + P_ReturnThrustX(mobj, mobjangle, 4 << FRACBITS), + P_ReturnThrustY(mobj, mobjangle, 4 << FRACBITS), + 0, ((mobj->type == MT_CEZPOLE1) ? MT_CEZBANNER1 : MT_CEZBANNER2))->angle = mobjangle + ANGLE_90; + } + break; case MT_HHZTREE_TOP: - { // Spawn the branches - angle_t mobjangle = FixedAngle(mthing->angle<angle << FRACBITS) & (ANGLE_90 - 1); + mobj_t* leaf; #define doleaf(x, y) \ leaf = P_SpawnMobjFromMobj(mobj, x, y, 0, MT_HHZTREE_PART);\ leaf->angle = mobjangle;\ P_SetMobjState(leaf, leaf->info->seestate);\ mobjangle += ANGLE_90 - doleaf(1*FRACUNIT, 0); - doleaf(0, 1*FRACUNIT); - doleaf(-1*FRACUNIT, 0); - doleaf(0, -1*FRACUNIT); + doleaf(FRACUNIT, 0); + doleaf(0, FRACUNIT); + doleaf(-FRACUNIT, 0); + doleaf(0, -FRACUNIT); #undef doleaf - } - break; + } + break; case MT_SMASHINGSPIKEBALL: if (mthing->angle > 0) mobj->tics += mthing->angle; @@ -12736,94 +12751,27 @@ ML_EFFECT5 : Don't stop thinking when too far away angle_t fa = (angle >> ANGLETOFINESHIFT) & FINEMASK; fixed_t xoffs = FINECOSINE(fa); fixed_t yoffs = FINESINE(fa); - mobj_t *leaf = P_SpawnMobjFromMobj(mobj, xoffs, yoffs, 0, MT_BIGFERNLEAF); + mobj_t* leaf = P_SpawnMobjFromMobj(mobj, xoffs, yoffs, 0, MT_BIGFERNLEAF); leaf->angle = angle; angle += ANGLE_45; } break; } case MT_REDBOOSTER: - { - angle_t angle = FixedAngle(mthing->angle << FRACBITS); - fixed_t x1 = FINECOSINE((angle >> ANGLETOFINESHIFT) & FINEMASK); - fixed_t y1 = FINESINE((angle >> ANGLETOFINESHIFT) & FINEMASK); - fixed_t x2 = FINECOSINE(((angle+ANGLE_90) >> ANGLETOFINESHIFT) & FINEMASK); - fixed_t y2 = FINESINE(((angle+ANGLE_90) >> ANGLETOFINESHIFT) & FINEMASK); - - mobj_t *seg = P_SpawnMobjFromMobj(mobj, 26*x1, 26*y1, 0, MT_BOOSTERSEG); - seg->angle = angle-ANGLE_90; - P_SetMobjState(seg, S_REDBOOSTERSEG_FACE); - seg = P_SpawnMobjFromMobj(mobj, -26*x1, -26*y1, 0, MT_BOOSTERSEG); - seg->angle = angle+ANGLE_90; - P_SetMobjState(seg, S_REDBOOSTERSEG_FACE); - seg = P_SpawnMobjFromMobj(mobj, 21*x2, 21*y2, 0, MT_BOOSTERSEG); - seg->angle = angle; - P_SetMobjState(seg, S_REDBOOSTERSEG_LEFT); - seg = P_SpawnMobjFromMobj(mobj, -21*x2, -21*y2, 0, MT_BOOSTERSEG); - seg->angle = angle; - P_SetMobjState(seg, S_REDBOOSTERSEG_RIGHT); - - seg = P_SpawnMobjFromMobj(mobj, 13*(x1+x2), 13*(y1+y2), 0, MT_BOOSTERROLLER); - seg->angle = angle; - P_SetMobjState(seg, S_REDBOOSTERROLLER); - seg = P_SpawnMobjFromMobj(mobj, 13*(x1-x2), 13*(y1-y2), 0, MT_BOOSTERROLLER); - seg->angle = angle; - P_SetMobjState(seg, S_REDBOOSTERROLLER); - seg = P_SpawnMobjFromMobj(mobj, -13*(x1+x2), -13*(y1+y2), 0, MT_BOOSTERROLLER); - seg->angle = angle; - P_SetMobjState(seg, S_REDBOOSTERROLLER); - seg = P_SpawnMobjFromMobj(mobj, -13*(x1-x2), -13*(y1-y2), 0, MT_BOOSTERROLLER); - seg->angle = angle; - P_SetMobjState(seg, S_REDBOOSTERROLLER); - break; - } case MT_YELLOWBOOSTER: - { - angle_t angle = FixedAngle(mthing->angle << FRACBITS); - fixed_t x1 = FINECOSINE((angle >> ANGLETOFINESHIFT) & FINEMASK); - fixed_t y1 = FINESINE((angle >> ANGLETOFINESHIFT) & FINEMASK); - fixed_t x2 = FINECOSINE(((angle+ANGLE_90) >> ANGLETOFINESHIFT) & FINEMASK); - fixed_t y2 = FINESINE(((angle+ANGLE_90) >> ANGLETOFINESHIFT) & FINEMASK); - - mobj_t *seg = P_SpawnMobjFromMobj(mobj, 26*x1, 26*y1, 0, MT_BOOSTERSEG); - seg->angle = angle-ANGLE_90; - P_SetMobjState(seg, S_YELLOWBOOSTERSEG_FACE); - seg = P_SpawnMobjFromMobj(mobj, -26*x1, -26*y1, 0, MT_BOOSTERSEG); - seg->angle = angle+ANGLE_90; - P_SetMobjState(seg, S_YELLOWBOOSTERSEG_FACE); - seg = P_SpawnMobjFromMobj(mobj, 21*x2, 21*y2, 0, MT_BOOSTERSEG); - seg->angle = angle; - P_SetMobjState(seg, S_YELLOWBOOSTERSEG_LEFT); - seg = P_SpawnMobjFromMobj(mobj, -21*x2, -21*y2, 0, MT_BOOSTERSEG); - seg->angle = angle; - P_SetMobjState(seg, S_YELLOWBOOSTERSEG_RIGHT); - - seg = P_SpawnMobjFromMobj(mobj, 13*(x1+x2), 13*(y1+y2), 0, MT_BOOSTERROLLER); - seg->angle = angle; - P_SetMobjState(seg, S_YELLOWBOOSTERROLLER); - seg = P_SpawnMobjFromMobj(mobj, 13*(x1-x2), 13*(y1-y2), 0, MT_BOOSTERROLLER); - seg->angle = angle; - P_SetMobjState(seg, S_YELLOWBOOSTERROLLER); - seg = P_SpawnMobjFromMobj(mobj, -13*(x1+x2), -13*(y1+y2), 0, MT_BOOSTERROLLER); - seg->angle = angle; - P_SetMobjState(seg, S_YELLOWBOOSTERROLLER); - seg = P_SpawnMobjFromMobj(mobj, -13*(x1-x2), -13*(y1-y2), 0, MT_BOOSTERROLLER); - seg->angle = angle; - P_SetMobjState(seg, S_YELLOWBOOSTERROLLER); + if (!P_SetupBooster(mthing, mobj, mobj->type == MT_REDBOOSTER)) + return false; break; - } - default: - break; - } + case MT_AXIS: + // Inverted if uppermost bit is set + if (mthing->angle & 16384) + mobj->flags2 |= MF2_AMBUSH; - if (mobj->flags & MF_BOSS) - { - if (mthing->options & MTF_OBJECTSPECIAL) // No egg trap for this boss - mobj->flags2 |= MF2_BOSSNOTRAP; - } - - if (i == MT_AXIS || i == MT_AXISTRANSFER || i == MT_AXISTRANSFERLINE) // Axis Points - { + if (mthing->angle > 0) + mobj->radius = (mthing->angle & 16383) << FRACBITS; + // FALLTHRU + case MT_AXISTRANSFER: + case MT_AXISTRANSFERLINE: // Mare it belongs to mobj->threshold = min(mthing->extrainfo, 7); @@ -12831,38 +12779,29 @@ ML_EFFECT5 : Don't stop thinking when too far away mobj->health = mthing->options; mobj->flags2 |= MF2_AXIS; - - if (i == MT_AXIS) - { - // Inverted if uppermost bit is set - if (mthing->angle & 16384) - mobj->flags2 |= MF2_AMBUSH; - - if (mthing->angle > 0) - mobj->radius = (mthing->angle & 16383)*FRACUNIT; - } - } - else if (i == MT_TOKEN) - { + break; + case MT_TOKEN: // We advanced tokenbits earlier due to the return check. // Subtract 1 here for the correct value. mobj->health = 1 << (tokenbits - 1); - } - else if (i == MT_CYBRAKDEMON && mthing->options & MTF_AMBUSH) + break; + case MT_CYBRAKDEMON: + if (mthing->options & MTF_AMBUSH) + { + mobj_t* elecmobj; + elecmobj = P_SpawnMobj(mobj->x, mobj->y, mobj->z, MT_CYBRAKDEMON_ELECTRIC_BARRIER); + P_SetTarget(&elecmobj->target, mobj); + elecmobj->angle = FixedAngle(mthing->angle << FRACBITS); + elecmobj->destscale = mobj->scale*2; + P_SetScale(elecmobj, elecmobj->destscale); + } + break; + case MT_STARPOST: { - mobj_t *elecmobj; - elecmobj = P_SpawnMobj(x, y, z, MT_CYBRAKDEMON_ELECTRIC_BARRIER); - P_SetTarget(&elecmobj->target, mobj); - elecmobj->angle = FixedAngle(mthing->angle<destscale = mobj->scale*2; - P_SetScale(elecmobj, elecmobj->destscale); - } - else if (i == MT_STARPOST) - { - thinker_t *th; - mobj_t *mo2; + thinker_t* th; + mobj_t* mo2; boolean foundanother = false; - mobj->health = (mthing->angle / 360) + 1; + mobj->health = (mthing->angle/360) + 1; // See if other starposts exist in this level that have the same value. for (th = thlist[THINK_MOBJ].next; th != &thlist[THINK_MOBJ]; th = th->next) @@ -12870,7 +12809,7 @@ ML_EFFECT5 : Don't stop thinking when too far away if (th->function.acp1 == (actionf_p1)P_RemoveThinkerDelayed) continue; - mo2 = (mobj_t *)th; + mo2 = (mobj_t*)th; if (mo2 == mobj) continue; @@ -12884,14 +12823,14 @@ ML_EFFECT5 : Don't stop thinking when too far away if (!foundanother) numstarposts++; + break; } - else if (i == MT_SPIKE) - { + case MT_SPIKE: // Pop up spikes! if (mthing->options & MTF_OBJECTSPECIAL) { mobj->flags &= ~MF_SCENERY; - mobj->fuse = (16 - mthing->extrainfo) * (mthing->angle + mobj->info->speed) / 16; + mobj->fuse = (16 - mthing->extrainfo)*(mthing->angle + mobj->info->speed)/16; if (mthing->options & MTF_EXTRA) P_SetMobjState(mobj, mobj->info->meleestate); } @@ -12903,14 +12842,13 @@ ML_EFFECT5 : Don't stop thinking when too far away mobj->flags |= MF_SOLID; P_SetThingPosition(mobj); } - } - else if (i == MT_WALLSPIKE) - { + break; + case MT_WALLSPIKE: // Pop up spikes! if (mthing->options & MTF_OBJECTSPECIAL) { mobj->flags &= ~MF_SCENERY; - mobj->fuse = (16 - mthing->extrainfo) * ((mthing->angle/360) + mobj->info->speed) / 16; + mobj->fuse = (16 - mthing->extrainfo)*((mthing->angle/360) + mobj->info->speed)/16; if (mthing->options & MTF_EXTRA) P_SetMobjState(mobj, mobj->info->meleestate); } @@ -12918,64 +12856,51 @@ ML_EFFECT5 : Don't stop thinking when too far away if (!(mthing->options & MTF_AMBUSH) && !metalrecording) { P_UnsetThingPosition(mobj); - mobj->flags &= ~(MF_NOBLOCKMAP|MF_NOCLIPHEIGHT); + mobj->flags &= ~(MF_NOBLOCKMAP | MF_NOCLIPHEIGHT); mobj->flags |= MF_SOLID; P_SetThingPosition(mobj); } // spawn base { - const angle_t mobjangle = FixedAngle(mthing->angle<angle << FRACBITS); // the mobj's own angle hasn't been set quite yet so... const fixed_t baseradius = mobj->radius - mobj->scale; - mobj_t *base = P_SpawnMobj( - mobj->x - P_ReturnThrustX(mobj, mobjangle, baseradius), - mobj->y - P_ReturnThrustY(mobj, mobjangle, baseradius), - mobj->z, MT_WALLSPIKEBASE); + mobj_t* base = P_SpawnMobj( + mobj->x - P_ReturnThrustX(mobj, mobjangle, baseradius), + mobj->y - P_ReturnThrustY(mobj, mobjangle, baseradius), + mobj->z, MT_WALLSPIKEBASE); base->angle = mobjangle + ANGLE_90; base->destscale = mobj->destscale; P_SetScale(base, mobj->scale); P_SetTarget(&base->target, mobj); P_SetTarget(&mobj->tracer, base); } - } - - //count 10 ring boxes into the number of rings equation too. - if (i == MT_RING_BOX && nummaprings >= 0) - nummaprings += 10; - - if (i == MT_BIGTUMBLEWEED || i == MT_LITTLETUMBLEWEED) - { + break; + case MT_RING_BOX: + //count 10 ring boxes into the number of rings equation too. + if (nummaprings >= 0) + nummaprings += 10; + break; + case MT_BIGTUMBLEWEED: + case MT_LITTLETUMBLEWEED: if (mthing->options & MTF_AMBUSH) { - mobj->momz += FixedMul(16*FRACUNIT, mobj->scale); - - if (P_RandomChance(FRACUNIT/2)) - mobj->momx += FixedMul(16*FRACUNIT, mobj->scale); - else - mobj->momx -= FixedMul(16*FRACUNIT, mobj->scale); - - if (P_RandomChance(FRACUNIT/2)) - mobj->momy += FixedMul(16*FRACUNIT, mobj->scale); - else - mobj->momy -= FixedMul(16*FRACUNIT,mobj->scale); + fixed_t offset = FixedMul(16*FRACUNIT, mobj->scale); + mobj->momx += P_RandomChance(FRACUNIT/2) ? offset : -offset; + mobj->momy += P_RandomChance(FRACUNIT/2) ? offset : -offset; + mobj->momz += offset; } - } - - // CTF flag pointers - if (i == MT_REDFLAG) - { + break; + case MT_REDFLAG: redflag = mobj; rflagpoint = mobj->spawnpoint; - } - if (i == MT_BLUEFLAG) - { + break; + case MT_BLUEFLAG: blueflag = mobj; bflagpoint = mobj->spawnpoint; - } - - // special push/pull stuff - if (i == MT_PUSH || i == MT_PULL) - { + break; + case MT_PUSH: + case MT_PULL: mobj->health = 0; // Default behaviour: pushing uses XY, fading uses XYZ if (mthing->options & MTF_AMBUSH) @@ -12984,14 +12909,68 @@ ML_EFFECT5 : Don't stop thinking when too far away mobj->health |= 2; // If object special is set, fade using XY if (G_IsSpecialStage(gamemap)) - { - if (i == MT_PUSH) - P_SetMobjState(mobj, S_GRAVWELLGREEN); - if (i == MT_PULL) - P_SetMobjState(mobj, S_GRAVWELLRED); - } + P_SetMobjState(mobj, (mobj->type == MT_PUSH) ? S_GRAVWELLGREEN : S_GRAVWELLRED); + break; + default: + break; } + if (mobj->flags & MF_BOSS) + { + if (mthing->options & MTF_OBJECTSPECIAL) // No egg trap for this boss + mobj->flags2 |= MF2_BOSSNOTRAP; + } + + return true; +} + +// +// P_SpawnMapThing +// The fields of the mapthing should +// already be in host byte order. +// +void P_SpawnMapThing(mapthing_t *mthing) +{ + mobjtype_t i; + mobj_t *mobj; + fixed_t x, y, z; + boolean doangle = true; + + if (!mthing->type) + return; // Ignore type-0 things as NOPs + + if (mthing->type == 3328) // 3D Mode start Thing + return; + + if (!objectplacing && P_SpawnNonMobjMapThing(mthing)) + return; + + i = P_GetMobjtype(mthing->type); + if (i == MT_UNKNOWN) + CONS_Alert(CONS_WARNING, M_GetText("Unknown thing type %d placed at (%d, %d)\n"), mthing->type, mthing->x, mthing->y); + + // Skip all returning/substitution code in objectplace. + if (!objectplacing) + { + if (!P_AllowMobjSpawn(mthing, i)) + return; + + i = P_GetMobjtypeSubstitute(mthing, i); + if (i == MT_NULL) // Don't spawn mobj + return; + } + + // spawn it + x = mthing->x << FRACBITS; + y = mthing->y << FRACBITS; + z = P_GetMobjSpawnHeight(i, mthing, x, y); + + mobj = P_SpawnMobj(x, y, z, i); + mobj->spawnpoint = mthing; + + if (!P_SetupSpawnedMapThing(mthing, mobj, &doangle)) + return; + if (doangle) mobj->angle = FixedAngle(mthing->angle< Date: Mon, 23 Dec 2019 19:08:40 +0100 Subject: [PATCH 330/746] P_SpawnMapThing(): Separate handling of MTF_AMBUSH and MTF_OBJECTSPECIAL in its own functions --- src/p_mobj.c | 120 ++++++++++++++++++++++++++------------------------- 1 file changed, 61 insertions(+), 59 deletions(-) diff --git a/src/p_mobj.c b/src/p_mobj.c index 0397451d0..04411f585 100644 --- a/src/p_mobj.c +++ b/src/p_mobj.c @@ -11598,6 +11598,12 @@ static fixed_t P_GetMobjSpawnHeight(const mobjtype_t mobjtype, const mapthing_t* offset = 288*FRACUNIT; break; + // Horizontal springs, may float additional units with MTF_AMBUSH. + case MT_YELLOWHORIZ: + case MT_REDHORIZ: + case MT_BLUEHORIZ: + offset += mthing->options & MTF_AMBUSH ? 16*FRACUNIT : 0; + // Ring-like items, may float additional units with MTF_AMBUSH. case MT_SPIKEBALL: case MT_EMERALDSPAWN: @@ -12924,6 +12930,59 @@ static boolean P_SetupSpawnedMapThing(mapthing_t *mthing, mobj_t *mobj, boolean return true; } +static void P_SetAmbush(mobj_t *mobj) +{ + if (mobj->type == MT_YELLOWDIAG || mobj->type == MT_REDDIAG || mobj->type == MT_BLUEDIAG) + mobj->angle += ANGLE_22h; + + if (mobj->flags & MF_NIGHTSITEM) + { + // Spawn already displayed + mobj->flags |= MF_SPECIAL; + mobj->flags &= ~MF_NIGHTSITEM; + } + + if (mobj->flags & MF_PUSHABLE) + mobj->flags &= ~MF_PUSHABLE; + + if ((mobj->flags & MF_MONITOR) && mobj->info->speed != 0) + { + // flag for strong/weak random boxes + // any monitor with nonzero speed is allowed to respawn like this + mobj->flags2 |= MF2_AMBUSH; + } + + else if (mobj->type != MT_AXIS && + mobj->type != MT_AXISTRANSFER && + mobj->type != MT_AXISTRANSFERLINE && + mobj->type != MT_NIGHTSBUMPER && + mobj->type != MT_STARPOST) + mobj->flags2 |= MF2_AMBUSH; +} + +static void P_SetObjectSpecial(mobj_t *mobj) +{ + if (mobj->type == MT_YELLOWDIAG || mobj->type == MT_REDDIAG || mobj->type == MT_BLUEDIAG) + mobj->flags |= MF_NOGRAVITY; + + if ((mobj->flags & MF_MONITOR) && mobj->info->speed != 0) + { + // flag for strong/weak random boxes + // any monitor with nonzero speed is allowed to respawn like this + mobj->flags2 |= MF2_STRONGBOX; + } + + // Requires you to be in bonus time to activate + if (mobj->flags & MF_NIGHTSITEM) + mobj->flags2 |= MF2_STRONGBOX; + + // Pushables bounce and slide coolly with object special flag set + if (mobj->flags & MF_PUSHABLE) + { + mobj->flags2 |= MF2_SLIDEPUSH; + mobj->flags |= MF_BOUNCE; + } +} // // P_SpawnMapThing // The fields of the mapthing should @@ -12988,67 +13047,10 @@ void P_SpawnMapThing(mapthing_t *mthing) else { if (mthing->options & MTF_AMBUSH) - { - if (i == MT_YELLOWDIAG || i == MT_REDDIAG || i == MT_BLUEDIAG) - mobj->angle += ANGLE_22h; - - if (i == MT_YELLOWHORIZ || i == MT_REDHORIZ || i == MT_BLUEHORIZ) - { - if (mthing->options & MTF_OBJECTFLIP) - mobj->z -= 16*FRACUNIT; - else - mobj->z += 16*FRACUNIT; - } - - - if (mobj->flags & MF_NIGHTSITEM) - { - // Spawn already displayed - mobj->flags |= MF_SPECIAL; - mobj->flags &= ~MF_NIGHTSITEM; - } - - if (mobj->flags & MF_PUSHABLE) - mobj->flags &= ~MF_PUSHABLE; - - if ((mobj->flags & MF_MONITOR) && mobj->info->speed != 0) - { - // flag for strong/weak random boxes - // any monitor with nonzero speed is allowed to respawn like this - mobj->flags2 |= MF2_AMBUSH; - } - - else if (mthing->type != mobjinfo[MT_AXIS].doomednum && - mthing->type != mobjinfo[MT_AXISTRANSFER].doomednum && - mthing->type != mobjinfo[MT_AXISTRANSFERLINE].doomednum && - mthing->type != mobjinfo[MT_NIGHTSBUMPER].doomednum && - mthing->type != mobjinfo[MT_STARPOST].doomednum) - mobj->flags2 |= MF2_AMBUSH; - } + P_SetAmbush(mobj); if (mthing->options & MTF_OBJECTSPECIAL) - { - if (i == MT_YELLOWDIAG || i == MT_REDDIAG || i == MT_BLUEDIAG) - mobj->flags |= MF_NOGRAVITY; - - if ((mobj->flags & MF_MONITOR) && mobj->info->speed != 0) - { - // flag for strong/weak random boxes - // any monitor with nonzero speed is allowed to respawn like this - mobj->flags2 |= MF2_STRONGBOX; - } - - // Requires you to be in bonus time to activate - if (mobj->flags & MF_NIGHTSITEM) - mobj->flags2 |= MF2_STRONGBOX; - - // Pushables bounce and slide coolly with object special flag set - if (mobj->flags & MF_PUSHABLE) - { - mobj->flags2 |= MF2_SLIDEPUSH; - mobj->flags |= MF_BOUNCE; - } - } + P_SetObjectSpecial(mobj); } // Generic reverse gravity for individual objects flag. From 2b3922a8f3a4aefb316b508cfdaaa42eac57d269 Mon Sep 17 00:00:00 2001 From: MascaraSnake Date: Mon, 23 Dec 2019 20:12:45 +0100 Subject: [PATCH 331/746] Set mthing->mobj before the flags handling code, since at this point the setup can't fail anymore --- src/p_mobj.c | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/src/p_mobj.c b/src/p_mobj.c index 04411f585..1acecbb76 100644 --- a/src/p_mobj.c +++ b/src/p_mobj.c @@ -13033,12 +13033,11 @@ void P_SpawnMapThing(mapthing_t *mthing) if (doangle) mobj->angle = FixedAngle(mthing->angle<mobj = mobj; + // ignore MTF_ flags and return early if (i == MT_NIGHTSBUMPER) - { - mthing->mobj = mobj; return; - } if ((mthing->options & MTF_AMBUSH) && (mthing->options & MTF_OBJECTSPECIAL) @@ -13073,8 +13072,6 @@ void P_SpawnMapThing(mapthing_t *mthing) // Final set of not being able to draw nightsitems. if (mobj->flags & MF_NIGHTSITEM) mobj->flags2 |= MF2_DONTDRAW; - - mthing->mobj = mobj; } static void P_SpawnHoop(mapthing_t* mthing, fixed_t x, fixed_t y, fixed_t z, sector_t* sec, INT32 hoopsize, fixed_t sizefactor) From a5a8d0c77b6368a2247f8b673987105f23b35bd2 Mon Sep 17 00:00:00 2001 From: GoldenTails Date: Mon, 23 Dec 2019 14:01:37 -0600 Subject: [PATCH 332/746] 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 24f8d4ef519a8541e24df3b47a2c9293d053ff11 Mon Sep 17 00:00:00 2001 From: MascaraSnake Date: Mon, 23 Dec 2019 21:17:12 +0100 Subject: [PATCH 333/746] Made a mapthing-independent version of P_GetMobjSpawnHeight so P_SpawnHoopsAndRings subfunctions can use it instead of duplicating code. --- src/p_mobj.c | 144 +++++++++++++++++---------------------------------- 1 file changed, 48 insertions(+), 96 deletions(-) diff --git a/src/p_mobj.c b/src/p_mobj.c index 1acecbb76..54e603fe9 100644 --- a/src/p_mobj.c +++ b/src/p_mobj.c @@ -11559,10 +11559,39 @@ void P_MovePlayerToStarpost(INT32 playernum) mapthing_t *huntemeralds[MAXHUNTEMERALDS]; INT32 numhuntemeralds; - -static fixed_t P_GetMobjSpawnHeight(const mobjtype_t mobjtype, const mapthing_t* mthing, const fixed_t x, const fixed_t y) +static fixed_t P_GetMobjSpawnHeight(const mobjtype_t mobjtype, const fixed_t x, const fixed_t y, const fixed_t offset, const boolean flip) { const subsector_t *ss = R_PointInSubsector(x, y); + + // Axis objects snap to the floor. + if (mobjtype == MT_AXIS || mobjtype == MT_AXISTRANSFER || mobjtype == MT_AXISTRANSFERLINE) + return ONFLOORZ; + + if (!offset) // Snap to the surfaces when there's no offset set. + { + if (flip) + return ONCEILINGZ; + else + return ONFLOORZ; + } + + // Establish height. + if (flip) + return ( +#ifdef ESLOPE + ss->sector->c_slope ? P_GetZAt(ss->sector->c_slope, x, y) : +#endif + ss->sector->ceilingheight) - offset - mobjinfo[mobjtype].height; + else + return ( +#ifdef ESLOPE + ss->sector->f_slope ? P_GetZAt(ss->sector->f_slope, x, y) : +#endif + ss->sector->floorheight) + offset; +} + +static fixed_t P_GetMapThingSpawnHeight(const mobjtype_t mobjtype, const mapthing_t* mthing, const fixed_t x, const fixed_t y) +{ fixed_t offset = mthing->z << FRACBITS; boolean flip = (!!(mobjinfo[mobjtype].flags & MF_SPAWNCEILING) ^ !!(mthing->options & MTF_OBJECTFLIP)); @@ -11573,12 +11602,6 @@ static fixed_t P_GetMobjSpawnHeight(const mobjtype_t mobjtype, const mapthing_t* flip = false; break; - // Axis objects snap to the floor. - case MT_AXIS: - case MT_AXISTRANSFER: - case MT_AXISTRANSFERLINE: - return ONFLOORZ; - // Objects with a non-zero default height. case MT_CRAWLACOMMANDER: case MT_DETON: @@ -11626,27 +11649,7 @@ static fixed_t P_GetMobjSpawnHeight(const mobjtype_t mobjtype, const mapthing_t* offset += mthing->options & MTF_AMBUSH ? 24*FRACUNIT : 0; } - if (!offset) // Snap to the surfaces when there's no offset set. - { - if (flip) - return ONCEILINGZ; - else - return ONFLOORZ; - } - - // Establish height. - if (flip) - return ( -#ifdef ESLOPE - ss->sector->c_slope ? P_GetZAt(ss->sector->c_slope, x, y) : -#endif - ss->sector->ceilingheight) - offset - mobjinfo[mobjtype].height; - else - return ( -#ifdef ESLOPE - ss->sector->f_slope ? P_GetZAt(ss->sector->f_slope, x, y) : -#endif - ss->sector->floorheight) + offset; + return P_GetMobjSpawnHeight(mobjtype, x, y, offset, flip); } static boolean P_SpawnNonMobjMapThing(mapthing_t *mthing) @@ -13022,7 +13025,7 @@ void P_SpawnMapThing(mapthing_t *mthing) // spawn it x = mthing->x << FRACBITS; y = mthing->y << FRACBITS; - z = P_GetMobjSpawnHeight(i, mthing, x, y); + z = P_GetMapThingSpawnHeight(i, mthing, x, y); mobj = P_SpawnMobj(x, y, z, i); mobj->spawnpoint = mthing; @@ -13074,7 +13077,7 @@ void P_SpawnMapThing(mapthing_t *mthing) mobj->flags2 |= MF2_DONTDRAW; } -static void P_SpawnHoop(mapthing_t* mthing, fixed_t x, fixed_t y, fixed_t z, sector_t* sec, INT32 hoopsize, fixed_t sizefactor) +static void P_SpawnHoop(mapthing_t* mthing, fixed_t x, fixed_t y, fixed_t z, INT32 hoopsize, fixed_t sizefactor) { mobj_t *mobj = NULL; mobj_t *nextmobj = NULL; @@ -13085,11 +13088,7 @@ static void P_SpawnHoop(mapthing_t* mthing, fixed_t x, fixed_t y, fixed_t z, sec angle_t fa; TVector v, *res; - z += -#ifdef ESLOPE - sec->f_slope ? P_GetZAt(sec->f_slope, x, y) : -#endif - sec->floorheight; + z = P_GetMobjSpawnHeight(MT_HOOP, x, y, z, false); hoopcenter = P_SpawnMobj(x, y, z, MT_HOOPCENTER); hoopcenter->spawnpoint = mthing; @@ -13209,7 +13208,7 @@ static void P_SpawnRingItem(mapthing_t *mthing, fixed_t x, fixed_t y, boolean bo ringthing = (gametype == GT_CTF) ? MT_BLUETEAMRING : MT_RING; } - z = P_GetMobjSpawnHeight(ringthing, mthing, x, y); + z = P_GetMapThingSpawnHeight(ringthing, mthing, x, y); mobj = P_SpawnMobj(x, y, z, ringthing); mobj->spawnpoint = mthing; @@ -13230,11 +13229,10 @@ static void P_SpawnRingItem(mapthing_t *mthing, fixed_t x, fixed_t y, boolean bo P_SetMobjState(mobj, mobj->info->seestate); } -static void P_SpawnVerticalSpringRings(mapthing_t *mthing, fixed_t x, fixed_t y, sector_t* sec, boolean nightsreplace) +static void P_SpawnVerticalSpringRings(mapthing_t *mthing, fixed_t x, fixed_t y, fixed_t z, boolean nightsreplace) { mobjtype_t ringthing = MT_RING; mobj_t* mobj = NULL; - fixed_t z; INT32 r; INT32 dist = 64*FRACUNIT; @@ -13247,26 +13245,7 @@ static void P_SpawnVerticalSpringRings(mapthing_t *mthing, fixed_t x, fixed_t y, if (nightsreplace) ringthing = MT_NIGHTSSTAR; - if (mthing->options & MTF_OBJECTFLIP) - { - z = ( -#ifdef ESLOPE - sec->c_slope ? P_GetZAt(sec->c_slope, x, y) : -#endif - sec->ceilingheight) - mobjinfo[ringthing].height; - if (mthing->z) - z -= (mthing->z << FRACBITS); - } - else - { - z = ( -#ifdef ESLOPE - sec->f_slope ? P_GetZAt(sec->f_slope, x, y) : -#endif - sec->floorheight); - if (mthing->z) - z += (mthing->z << FRACBITS); - } + z = P_GetMobjSpawnHeight(ringthing, x, y, z, mthing->options & MTF_OBJECTFLIP); for (r = 1; r <= 5; r++) { @@ -13292,11 +13271,10 @@ static void P_SpawnVerticalSpringRings(mapthing_t *mthing, fixed_t x, fixed_t y, } } -static void P_SpawnDiagonalSpringRings(mapthing_t* mthing, fixed_t x, fixed_t y, sector_t* sec, boolean nightsreplace) +static void P_SpawnDiagonalSpringRings(mapthing_t* mthing, fixed_t x, fixed_t y, fixed_t z, boolean nightsreplace) { mobjtype_t ringthing = MT_RING; mobj_t *mobj = NULL; - fixed_t z; INT32 r; angle_t closestangle, fa; @@ -13313,26 +13291,7 @@ static void P_SpawnDiagonalSpringRings(mapthing_t* mthing, fixed_t x, fixed_t y, closestangle = FixedAngle(mthing->angle << FRACBITS); fa = (closestangle >> ANGLETOFINESHIFT); - if (mthing->options & MTF_OBJECTFLIP) - { - z = ( -#ifdef ESLOPE - sec->c_slope ? P_GetZAt(sec->c_slope, x, y) : -#endif - sec->ceilingheight) - mobjinfo[ringthing].height; - if (mthing->z) - z -= (mthing->z << FRACBITS); - } - else - { - z = ( -#ifdef ESLOPE - sec->f_slope ? P_GetZAt(sec->f_slope, x, y) : -#endif - sec->floorheight); - if (mthing->z) - z += (mthing->z << FRACBITS); - } + z = P_GetMobjSpawnHeight(ringthing, x, y, z, mthing->options & MTF_OBJECTFLIP); for (r = 1; r <= iterations; r++) { @@ -13361,11 +13320,11 @@ static void P_SpawnDiagonalSpringRings(mapthing_t* mthing, fixed_t x, fixed_t y, } } -static void P_SpawnItemCircle(mapthing_t* mthing, fixed_t x, fixed_t y, sector_t* sec, boolean bonustime, boolean nightsreplace) +static void P_SpawnItemCircle(mapthing_t* mthing, fixed_t x, fixed_t y, fixed_t z, boolean bonustime, boolean nightsreplace) { mobjtype_t ringthing = MT_RING; mobj_t *mobj = NULL; - fixed_t z, finalx, finaly, finalz; + fixed_t finalx, finaly, finalz; angle_t closestangle, fa; INT32 i; TVector v, *res; @@ -13378,13 +13337,7 @@ static void P_SpawnItemCircle(mapthing_t* mthing, fixed_t x, fixed_t y, sector_t size = 192*FRACUNIT; } - z = -#ifdef ESLOPE - sec->f_slope ? P_GetZAt(sec->f_slope, x, y) : -#endif - sec->floorheight; - if (mthing->z) - z += (mthing->z << FRACBITS); + z = P_GetMobjSpawnHeight(ringthing, x, y, z, false); closestangle = FixedAngle(mthing->angle << FRACBITS); @@ -13462,7 +13415,6 @@ void P_SpawnHoopsAndRings(mapthing_t *mthing, boolean bonustime) fixed_t x = mthing->x << FRACBITS; fixed_t y = mthing->y << FRACBITS; fixed_t z = mthing->z << FRACBITS; - sector_t *sec = R_PointInSubsector(x, y)->sector; boolean nightsreplace = ((maptol & TOL_NIGHTS) && !G_IsSpecialStage(gamemap)); switch (mthing->type) @@ -13470,11 +13422,11 @@ void P_SpawnHoopsAndRings(mapthing_t *mthing, boolean bonustime) // Special placement patterns case 600: // 5 vertical rings (yellow spring) case 601: // 5 vertical rings (red spring) - P_SpawnVerticalSpringRings(mthing, x, y, sec, nightsreplace); + P_SpawnVerticalSpringRings(mthing, x, y, z, nightsreplace); return; case 602: // 5 diagonal rings (yellow spring) case 603: // 10 diagonal rings (red spring) - P_SpawnDiagonalSpringRings(mthing, x, y, sec, nightsreplace); + P_SpawnDiagonalSpringRings(mthing, x, y, z, nightsreplace); return; case 604: // Circle of rings (8 items) case 605: // Circle of rings (16 bits) @@ -13482,16 +13434,16 @@ void P_SpawnHoopsAndRings(mapthing_t *mthing, boolean bonustime) case 607: // Circle of blue spheres (16 items) case 608: // Circle of rings and blue spheres (8 items) case 609: // Circle of rings and blue spheres (16 items) - P_SpawnItemCircle(mthing, x, y, sec, bonustime, nightsreplace); + P_SpawnItemCircle(mthing, x, y, z, bonustime, nightsreplace); return; // Hoops case 1705: // Generic NiGHTS hoop - P_SpawnHoop(mthing, x, y, z, sec, 24, 4*FRACUNIT); + P_SpawnHoop(mthing, x, y, z, 24, 4*FRACUNIT); return; case 1713: // Customizable NiGHTS hoop // For each flag add 16 fracunits to the size // Default (0 flags) is 32 fracunits - P_SpawnHoop(mthing, x, y, z, sec, 8 + (4*(mthing->options & 0xF)), 4*FRACUNIT); + P_SpawnHoop(mthing, x, y, z, 8 + (4*(mthing->options & 0xF)), 4*FRACUNIT); return; default: // All manners of rings and coins P_SpawnRingItem(mthing, x, y, bonustime, nightsreplace); From 6939da01641bc950f99b0080055d9729e16c2c3b Mon Sep 17 00:00:00 2001 From: MascaraSnake Date: Mon, 23 Dec 2019 21:35:03 +0100 Subject: [PATCH 334/746] Turned nightsreplace into a macro so we have don't have to keep dragging it along as a function parameter --- src/p_mobj.c | 19 ++++++++++--------- 1 file changed, 10 insertions(+), 9 deletions(-) diff --git a/src/p_mobj.c b/src/p_mobj.c index 54e603fe9..aa19716df 100644 --- a/src/p_mobj.c +++ b/src/p_mobj.c @@ -13182,7 +13182,9 @@ static void P_SpawnHoop(mapthing_t* mthing, fixed_t x, fixed_t y, fixed_t z, INT } while (hoopsize >= 8); } -static void P_SpawnRingItem(mapthing_t *mthing, fixed_t x, fixed_t y, boolean bonustime, boolean nightsreplace) +#define nightsreplace ((maptol & TOL_NIGHTS) && !G_IsSpecialStage(gamemap)) + +static void P_SpawnRingItem(mapthing_t *mthing, fixed_t x, fixed_t y, boolean bonustime) { mobjtype_t ringthing = MT_RING; mobj_t *mobj = NULL; @@ -13229,7 +13231,7 @@ static void P_SpawnRingItem(mapthing_t *mthing, fixed_t x, fixed_t y, boolean bo P_SetMobjState(mobj, mobj->info->seestate); } -static void P_SpawnVerticalSpringRings(mapthing_t *mthing, fixed_t x, fixed_t y, fixed_t z, boolean nightsreplace) +static void P_SpawnVerticalSpringRings(mapthing_t *mthing, fixed_t x, fixed_t y, fixed_t z) { mobjtype_t ringthing = MT_RING; mobj_t* mobj = NULL; @@ -13271,7 +13273,7 @@ static void P_SpawnVerticalSpringRings(mapthing_t *mthing, fixed_t x, fixed_t y, } } -static void P_SpawnDiagonalSpringRings(mapthing_t* mthing, fixed_t x, fixed_t y, fixed_t z, boolean nightsreplace) +static void P_SpawnDiagonalSpringRings(mapthing_t* mthing, fixed_t x, fixed_t y, fixed_t z) { mobjtype_t ringthing = MT_RING; mobj_t *mobj = NULL; @@ -13320,7 +13322,7 @@ static void P_SpawnDiagonalSpringRings(mapthing_t* mthing, fixed_t x, fixed_t y, } } -static void P_SpawnItemCircle(mapthing_t* mthing, fixed_t x, fixed_t y, fixed_t z, boolean bonustime, boolean nightsreplace) +static void P_SpawnItemCircle(mapthing_t* mthing, fixed_t x, fixed_t y, fixed_t z, boolean bonustime) { mobjtype_t ringthing = MT_RING; mobj_t *mobj = NULL; @@ -13415,18 +13417,17 @@ void P_SpawnHoopsAndRings(mapthing_t *mthing, boolean bonustime) fixed_t x = mthing->x << FRACBITS; fixed_t y = mthing->y << FRACBITS; fixed_t z = mthing->z << FRACBITS; - boolean nightsreplace = ((maptol & TOL_NIGHTS) && !G_IsSpecialStage(gamemap)); switch (mthing->type) { // Special placement patterns case 600: // 5 vertical rings (yellow spring) case 601: // 5 vertical rings (red spring) - P_SpawnVerticalSpringRings(mthing, x, y, z, nightsreplace); + P_SpawnVerticalSpringRings(mthing, x, y, z); return; case 602: // 5 diagonal rings (yellow spring) case 603: // 10 diagonal rings (red spring) - P_SpawnDiagonalSpringRings(mthing, x, y, z, nightsreplace); + P_SpawnDiagonalSpringRings(mthing, x, y, z); return; case 604: // Circle of rings (8 items) case 605: // Circle of rings (16 bits) @@ -13434,7 +13435,7 @@ void P_SpawnHoopsAndRings(mapthing_t *mthing, boolean bonustime) case 607: // Circle of blue spheres (16 items) case 608: // Circle of rings and blue spheres (8 items) case 609: // Circle of rings and blue spheres (16 items) - P_SpawnItemCircle(mthing, x, y, z, bonustime, nightsreplace); + P_SpawnItemCircle(mthing, x, y, z, bonustime); return; // Hoops case 1705: // Generic NiGHTS hoop @@ -13446,7 +13447,7 @@ void P_SpawnHoopsAndRings(mapthing_t *mthing, boolean bonustime) P_SpawnHoop(mthing, x, y, z, 8 + (4*(mthing->options & 0xF)), 4*FRACUNIT); return; default: // All manners of rings and coins - P_SpawnRingItem(mthing, x, y, bonustime, nightsreplace); + P_SpawnRingItem(mthing, x, y, bonustime); } } From d0f7877fd03c75c4a94528d8d9bfb6ce2c8ed09b Mon Sep 17 00:00:00 2001 From: Jaime Passos Date: Mon, 23 Dec 2019 18:33:39 -0300 Subject: [PATCH 335/746] Turn noglobals into setglobals, move the extra global variable handling to gamestateglobals. --- src/lua_script.c | 28 +++++++++++++++++----------- 1 file changed, 17 insertions(+), 11 deletions(-) diff --git a/src/lua_script.c b/src/lua_script.c index 13592815b..759f858a0 100644 --- a/src/lua_script.c +++ b/src/lua_script.c @@ -79,8 +79,22 @@ FUNCNORETURN static int LUA_Panic(lua_State *L) #endif } +// See lib_getenum in dehacked.c. +static boolean gamestateglobals(const char *csname, lua_State *L) +{ + if (fastcmp(csname,"redscore")) + redscore = (UINT32)luaL_checkinteger(L, 2); + else if (fastcmp(csname,"bluescore")) + bluescore = (UINT32)luaL_checkinteger(L, 2); + else + return false; + + // Global variable set, so return and don't error. + return true; +} + // This function decides which global variables you are allowed to set. -static int noglobals(lua_State *L) +static int setglobals(lua_State *L) { const char *csname; char *name; @@ -106,16 +120,8 @@ static int noglobals(lua_State *L) return 0; } - if (fastcmp(csname,"redscore")) - { - redscore = (UINT32)luaL_checkinteger(L, 2); + if (gamestateglobals(csname, L)) return 0; - } - else if (fastcmp(csname,"bluescore")) - { - bluescore = (UINT32)luaL_checkinteger(L, 2); - return 0; - } Z_Free(name); return luaL_error(L, "Implicit global " LUA_QS " prevented. Create a local variable instead.", csname); @@ -155,7 +161,7 @@ static void LUA_ClearState(void) // lock the global namespace lua_getmetatable(L, LUA_GLOBALSINDEX); - lua_pushcfunction(L, noglobals); + lua_pushcfunction(L, setglobals); lua_setfield(L, -2, "__newindex"); lua_newtable(L); lua_setfield(L, -2, "__metatable"); From 7425591815bb87a962196ab5da13f9398986c6e3 Mon Sep 17 00:00:00 2001 From: Jaime Passos Date: Mon, 23 Dec 2019 18:37:38 -0300 Subject: [PATCH 336/746] Add pointlimit and timelimit to Lua. --- src/dehacked.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/dehacked.c b/src/dehacked.c index e3fac0a4b..0d8f230e0 100644 --- a/src/dehacked.c +++ b/src/dehacked.c @@ -10828,6 +10828,12 @@ static inline int lib_getenum(lua_State *L) } else if (fastcmp(word,"redscore")) { lua_pushinteger(L, redscore); return 1; + } else if (fastcmp(word,"timelimit")) { + lua_pushinteger(L, cv_timelimit.value); + return 1; + } else if (fastcmp(word,"pointlimit")) { + lua_pushinteger(L, cv_pointlimit.value); + return 1; // begin map vars } else if (fastcmp(word,"spstage_start")) { lua_pushinteger(L, spstage_start); From 5ebd84c3e734feea8099b00ae864b98e6548a0ff Mon Sep 17 00:00:00 2001 From: Jaime Passos Date: Mon, 23 Dec 2019 18:49:23 -0300 Subject: [PATCH 337/746] Move ALL the Lua global variable stuff into lua_script.c. --- src/dehacked.c | 208 +----------------------------------------- src/lua_script.c | 228 +++++++++++++++++++++++++++++++++++++++++++++-- src/lua_script.h | 2 + 3 files changed, 224 insertions(+), 214 deletions(-) diff --git a/src/dehacked.c b/src/dehacked.c index 0d8f230e0..d1e18a1d7 100644 --- a/src/dehacked.c +++ b/src/dehacked.c @@ -10777,213 +10777,7 @@ static inline int lib_getenum(lua_State *L) // DYNAMIC variables too!! // Try not to add anything that would break netgames or timeattack replays here. // You know, like consoleplayer, displayplayer, secondarydisplayplayer, or gametime. - if (fastcmp(word,"gamemap")) { - lua_pushinteger(L, gamemap); - return 1; - } else if (fastcmp(word,"maptol")) { - lua_pushinteger(L, maptol); - return 1; - } else if (fastcmp(word,"ultimatemode")) { - lua_pushboolean(L, ultimatemode != 0); - return 1; - } else if (fastcmp(word,"mariomode")) { - lua_pushboolean(L, mariomode != 0); - return 1; - } else if (fastcmp(word,"twodlevel")) { - lua_pushboolean(L, twodlevel != 0); - return 1; - } else if (fastcmp(word,"circuitmap")) { - lua_pushboolean(L, circuitmap); - return 1; - } else if (fastcmp(word,"netgame")) { - lua_pushboolean(L, netgame); - return 1; - } else if (fastcmp(word,"multiplayer")) { - lua_pushboolean(L, multiplayer); - return 1; - } else if (fastcmp(word,"modeattacking")) { - lua_pushboolean(L, modeattacking); - return 1; - } else if (fastcmp(word,"splitscreen")) { - lua_pushboolean(L, splitscreen); - return 1; - } else if (fastcmp(word,"gamecomplete")) { - lua_pushboolean(L, gamecomplete); - return 1; - } else if (fastcmp(word,"devparm")) { - lua_pushboolean(L, devparm); - return 1; - } else if (fastcmp(word,"modifiedgame")) { - lua_pushboolean(L, modifiedgame && !savemoddata); - return 1; - } else if (fastcmp(word,"menuactive")) { - lua_pushboolean(L, menuactive); - return 1; - } else if (fastcmp(word,"paused")) { - lua_pushboolean(L, paused); - return 1; - } else if (fastcmp(word,"bluescore")) { - lua_pushinteger(L, bluescore); - return 1; - } else if (fastcmp(word,"redscore")) { - lua_pushinteger(L, redscore); - return 1; - } else if (fastcmp(word,"timelimit")) { - lua_pushinteger(L, cv_timelimit.value); - return 1; - } else if (fastcmp(word,"pointlimit")) { - lua_pushinteger(L, cv_pointlimit.value); - return 1; - // begin map vars - } else if (fastcmp(word,"spstage_start")) { - lua_pushinteger(L, spstage_start); - return 1; - } else if (fastcmp(word,"sstage_start")) { - lua_pushinteger(L, sstage_start); - return 1; - } else if (fastcmp(word,"sstage_end")) { - lua_pushinteger(L, sstage_end); - return 1; - } else if (fastcmp(word,"smpstage_start")) { - lua_pushinteger(L, smpstage_start); - return 1; - } else if (fastcmp(word,"smpstage_end")) { - lua_pushinteger(L, smpstage_end); - return 1; - } else if (fastcmp(word,"titlemap")) { - lua_pushinteger(L, titlemap); - return 1; - } else if (fastcmp(word,"titlemapinaction")) { - lua_pushboolean(L, (titlemapinaction != TITLEMAP_OFF)); - return 1; - } else if (fastcmp(word,"bootmap")) { - lua_pushinteger(L, bootmap); - return 1; - } else if (fastcmp(word,"tutorialmap")) { - lua_pushinteger(L, tutorialmap); - return 1; - } else if (fastcmp(word,"tutorialmode")) { - lua_pushboolean(L, tutorialmode); - return 1; - // end map vars - // begin CTF colors - } else if (fastcmp(word,"skincolor_redteam")) { - lua_pushinteger(L, skincolor_redteam); - return 1; - } else if (fastcmp(word,"skincolor_blueteam")) { - lua_pushinteger(L, skincolor_blueteam); - return 1; - } else if (fastcmp(word,"skincolor_redring")) { - lua_pushinteger(L, skincolor_redring); - return 1; - } else if (fastcmp(word,"skincolor_bluering")) { - lua_pushinteger(L, skincolor_bluering); - return 1; - // end CTF colors - // begin timers - } else if (fastcmp(word,"invulntics")) { - lua_pushinteger(L, invulntics); - return 1; - } else if (fastcmp(word,"sneakertics")) { - lua_pushinteger(L, sneakertics); - return 1; - } else if (fastcmp(word,"flashingtics")) { - lua_pushinteger(L, flashingtics); - return 1; - } else if (fastcmp(word,"tailsflytics")) { - lua_pushinteger(L, tailsflytics); - return 1; - } else if (fastcmp(word,"underwatertics")) { - lua_pushinteger(L, underwatertics); - return 1; - } else if (fastcmp(word,"spacetimetics")) { - lua_pushinteger(L, spacetimetics); - return 1; - } else if (fastcmp(word,"extralifetics")) { - lua_pushinteger(L, extralifetics); - return 1; - } else if (fastcmp(word,"nightslinktics")) { - lua_pushinteger(L, nightslinktics); - return 1; - } else if (fastcmp(word,"gameovertics")) { - lua_pushinteger(L, gameovertics); - return 1; - } else if (fastcmp(word,"ammoremovaltics")) { - lua_pushinteger(L, ammoremovaltics); - return 1; - // end timers - } else if (fastcmp(word,"gametype")) { - lua_pushinteger(L, gametype); - return 1; - } else if (fastcmp(word,"gametyperules")) { - lua_pushinteger(L, gametyperules); - return 1; - } else if (fastcmp(word,"leveltime")) { - lua_pushinteger(L, leveltime); - return 1; - } else if (fastcmp(word,"curWeather")) { - lua_pushinteger(L, curWeather); - return 1; - } else if (fastcmp(word,"globalweather")) { - lua_pushinteger(L, globalweather); - return 1; - } else if (fastcmp(word,"levelskynum")) { - lua_pushinteger(L, levelskynum); - return 1; - } else if (fastcmp(word,"globallevelskynum")) { - lua_pushinteger(L, globallevelskynum); - return 1; - } else if (fastcmp(word,"mapmusname")) { - lua_pushstring(L, mapmusname); - return 1; - } else if (fastcmp(word,"mapmusflags")) { - lua_pushinteger(L, mapmusflags); - return 1; - } else if (fastcmp(word,"mapmusposition")) { - lua_pushinteger(L, mapmusposition); - return 1; - // local player variables, by popular request - } else if (fastcmp(word,"consoleplayer")) { // player controlling console (aka local player 1) - if (consoleplayer < 0 || !playeringame[consoleplayer]) - return 0; - LUA_PushUserdata(L, &players[consoleplayer], META_PLAYER); - return 1; - } else if (fastcmp(word,"displayplayer")) { // player visible on screen (aka display player 1) - if (displayplayer < 0 || !playeringame[displayplayer]) - return 0; - LUA_PushUserdata(L, &players[displayplayer], META_PLAYER); - return 1; - } else if (fastcmp(word,"secondarydisplayplayer")) { // local/display player 2, for splitscreen - if (!splitscreen || secondarydisplayplayer < 0 || !playeringame[secondarydisplayplayer]) - return 0; - LUA_PushUserdata(L, &players[secondarydisplayplayer], META_PLAYER); - return 1; - // end local player variables - } else if (fastcmp(word,"server")) { - if ((!multiplayer || !netgame) && !playeringame[serverplayer]) - return 0; - LUA_PushUserdata(L, &players[serverplayer], META_PLAYER); - return 1; - } else if (fastcmp(word,"admin")) { // BACKWARDS COMPATIBILITY HACK: This was replaced with IsPlayerAdmin(), but some 2.1 Lua scripts still use the admin variable. It now points to the first admin player in the array. - LUA_Deprecated(L, "admin", "IsPlayerAdmin(player)"); - if (!playeringame[adminplayers[0]] || IsPlayerAdmin(serverplayer)) - return 0; - LUA_PushUserdata(L, &players[adminplayers[0]], META_PLAYER); - return 1; - } else if (fastcmp(word,"emeralds")) { - lua_pushinteger(L, emeralds); - return 1; - } else if (fastcmp(word,"gravity")) { - lua_pushinteger(L, gravity); - return 1; - } else if (fastcmp(word,"VERSIONSTRING")) { - lua_pushstring(L, VERSIONSTRING); - return 1; - } else if (fastcmp(word, "token")) { - lua_pushinteger(L, token); - return 1; - } - return 0; + return LUA_PushGlobals(L, word); } int LUA_EnumLib(lua_State *L) diff --git a/src/lua_script.c b/src/lua_script.c index 759f858a0..4b5e72938 100644 --- a/src/lua_script.c +++ b/src/lua_script.c @@ -18,7 +18,9 @@ #include "w_wad.h" #include "p_setup.h" #include "r_state.h" +#include "r_sky.h" #include "g_game.h" +#include "f_finale.h" #include "byteptr.h" #include "p_saveg.h" #include "p_local.h" @@ -79,18 +81,230 @@ FUNCNORETURN static int LUA_Panic(lua_State *L) #endif } -// See lib_getenum in dehacked.c. -static boolean gamestateglobals(const char *csname, lua_State *L) +// Moved here from lib_getenum. +int LUA_PushGlobals(lua_State *L, const char *word) { - if (fastcmp(csname,"redscore")) + if (fastcmp(word,"gamemap")) { + lua_pushinteger(L, gamemap); + return 1; + } else if (fastcmp(word,"maptol")) { + lua_pushinteger(L, maptol); + return 1; + } else if (fastcmp(word,"ultimatemode")) { + lua_pushboolean(L, ultimatemode != 0); + return 1; + } else if (fastcmp(word,"mariomode")) { + lua_pushboolean(L, mariomode != 0); + return 1; + } else if (fastcmp(word,"twodlevel")) { + lua_pushboolean(L, twodlevel != 0); + return 1; + } else if (fastcmp(word,"circuitmap")) { + lua_pushboolean(L, circuitmap); + return 1; + } else if (fastcmp(word,"netgame")) { + lua_pushboolean(L, netgame); + return 1; + } else if (fastcmp(word,"multiplayer")) { + lua_pushboolean(L, multiplayer); + return 1; + } else if (fastcmp(word,"modeattacking")) { + lua_pushboolean(L, modeattacking); + return 1; + } else if (fastcmp(word,"splitscreen")) { + lua_pushboolean(L, splitscreen); + return 1; + } else if (fastcmp(word,"gamecomplete")) { + lua_pushboolean(L, gamecomplete); + return 1; + } else if (fastcmp(word,"devparm")) { + lua_pushboolean(L, devparm); + return 1; + } else if (fastcmp(word,"modifiedgame")) { + lua_pushboolean(L, modifiedgame && !savemoddata); + return 1; + } else if (fastcmp(word,"menuactive")) { + lua_pushboolean(L, menuactive); + return 1; + } else if (fastcmp(word,"paused")) { + lua_pushboolean(L, paused); + return 1; + } else if (fastcmp(word,"bluescore")) { + lua_pushinteger(L, bluescore); + return 1; + } else if (fastcmp(word,"redscore")) { + lua_pushinteger(L, redscore); + return 1; + } else if (fastcmp(word,"timelimit")) { + lua_pushinteger(L, cv_timelimit.value); + return 1; + } else if (fastcmp(word,"pointlimit")) { + lua_pushinteger(L, cv_pointlimit.value); + return 1; + // begin map vars + } else if (fastcmp(word,"spstage_start")) { + lua_pushinteger(L, spstage_start); + return 1; + } else if (fastcmp(word,"sstage_start")) { + lua_pushinteger(L, sstage_start); + return 1; + } else if (fastcmp(word,"sstage_end")) { + lua_pushinteger(L, sstage_end); + return 1; + } else if (fastcmp(word,"smpstage_start")) { + lua_pushinteger(L, smpstage_start); + return 1; + } else if (fastcmp(word,"smpstage_end")) { + lua_pushinteger(L, smpstage_end); + return 1; + } else if (fastcmp(word,"titlemap")) { + lua_pushinteger(L, titlemap); + return 1; + } else if (fastcmp(word,"titlemapinaction")) { + lua_pushboolean(L, (titlemapinaction != TITLEMAP_OFF)); + return 1; + } else if (fastcmp(word,"bootmap")) { + lua_pushinteger(L, bootmap); + return 1; + } else if (fastcmp(word,"tutorialmap")) { + lua_pushinteger(L, tutorialmap); + return 1; + } else if (fastcmp(word,"tutorialmode")) { + lua_pushboolean(L, tutorialmode); + return 1; + // end map vars + // begin CTF colors + } else if (fastcmp(word,"skincolor_redteam")) { + lua_pushinteger(L, skincolor_redteam); + return 1; + } else if (fastcmp(word,"skincolor_blueteam")) { + lua_pushinteger(L, skincolor_blueteam); + return 1; + } else if (fastcmp(word,"skincolor_redring")) { + lua_pushinteger(L, skincolor_redring); + return 1; + } else if (fastcmp(word,"skincolor_bluering")) { + lua_pushinteger(L, skincolor_bluering); + return 1; + // end CTF colors + // begin timers + } else if (fastcmp(word,"invulntics")) { + lua_pushinteger(L, invulntics); + return 1; + } else if (fastcmp(word,"sneakertics")) { + lua_pushinteger(L, sneakertics); + return 1; + } else if (fastcmp(word,"flashingtics")) { + lua_pushinteger(L, flashingtics); + return 1; + } else if (fastcmp(word,"tailsflytics")) { + lua_pushinteger(L, tailsflytics); + return 1; + } else if (fastcmp(word,"underwatertics")) { + lua_pushinteger(L, underwatertics); + return 1; + } else if (fastcmp(word,"spacetimetics")) { + lua_pushinteger(L, spacetimetics); + return 1; + } else if (fastcmp(word,"extralifetics")) { + lua_pushinteger(L, extralifetics); + return 1; + } else if (fastcmp(word,"nightslinktics")) { + lua_pushinteger(L, nightslinktics); + return 1; + } else if (fastcmp(word,"gameovertics")) { + lua_pushinteger(L, gameovertics); + return 1; + } else if (fastcmp(word,"ammoremovaltics")) { + lua_pushinteger(L, ammoremovaltics); + return 1; + // end timers + } else if (fastcmp(word,"gametype")) { + lua_pushinteger(L, gametype); + return 1; + } else if (fastcmp(word,"gametyperules")) { + lua_pushinteger(L, gametyperules); + return 1; + } else if (fastcmp(word,"leveltime")) { + lua_pushinteger(L, leveltime); + return 1; + } else if (fastcmp(word,"curWeather")) { + lua_pushinteger(L, curWeather); + return 1; + } else if (fastcmp(word,"globalweather")) { + lua_pushinteger(L, globalweather); + return 1; + } else if (fastcmp(word,"levelskynum")) { + lua_pushinteger(L, levelskynum); + return 1; + } else if (fastcmp(word,"globallevelskynum")) { + lua_pushinteger(L, globallevelskynum); + return 1; + } else if (fastcmp(word,"mapmusname")) { + lua_pushstring(L, mapmusname); + return 1; + } else if (fastcmp(word,"mapmusflags")) { + lua_pushinteger(L, mapmusflags); + return 1; + } else if (fastcmp(word,"mapmusposition")) { + lua_pushinteger(L, mapmusposition); + return 1; + // local player variables, by popular request + } else if (fastcmp(word,"consoleplayer")) { // player controlling console (aka local player 1) + if (consoleplayer < 0 || !playeringame[consoleplayer]) + return 0; + LUA_PushUserdata(L, &players[consoleplayer], META_PLAYER); + return 1; + } else if (fastcmp(word,"displayplayer")) { // player visible on screen (aka display player 1) + if (displayplayer < 0 || !playeringame[displayplayer]) + return 0; + LUA_PushUserdata(L, &players[displayplayer], META_PLAYER); + return 1; + } else if (fastcmp(word,"secondarydisplayplayer")) { // local/display player 2, for splitscreen + if (!splitscreen || secondarydisplayplayer < 0 || !playeringame[secondarydisplayplayer]) + return 0; + LUA_PushUserdata(L, &players[secondarydisplayplayer], META_PLAYER); + return 1; + // end local player variables + } else if (fastcmp(word,"server")) { + if ((!multiplayer || !netgame) && !playeringame[serverplayer]) + return 0; + LUA_PushUserdata(L, &players[serverplayer], META_PLAYER); + return 1; + } else if (fastcmp(word,"admin")) { // BACKWARDS COMPATIBILITY HACK: This was replaced with IsPlayerAdmin(), but some 2.1 Lua scripts still use the admin variable. It now points to the first admin player in the array. + LUA_Deprecated(L, "admin", "IsPlayerAdmin(player)"); + if (!playeringame[adminplayers[0]] || IsPlayerAdmin(serverplayer)) + return 0; + LUA_PushUserdata(L, &players[adminplayers[0]], META_PLAYER); + return 1; + } else if (fastcmp(word,"emeralds")) { + lua_pushinteger(L, emeralds); + return 1; + } else if (fastcmp(word,"gravity")) { + lua_pushinteger(L, gravity); + return 1; + } else if (fastcmp(word,"VERSIONSTRING")) { + lua_pushstring(L, VERSIONSTRING); + return 1; + } else if (fastcmp(word, "token")) { + lua_pushinteger(L, token); + return 1; + } + return 0; +} + +// See the above. +int LUA_CheckGlobals(lua_State *L, const char *word) +{ + if (fastcmp(word, "redscore")) redscore = (UINT32)luaL_checkinteger(L, 2); - else if (fastcmp(csname,"bluescore")) + else if (fastcmp(word, "bluescore")) bluescore = (UINT32)luaL_checkinteger(L, 2); else - return false; + return 0; // Global variable set, so return and don't error. - return true; + return 1; } // This function decides which global variables you are allowed to set. @@ -120,7 +334,7 @@ static int setglobals(lua_State *L) return 0; } - if (gamestateglobals(csname, L)) + if (LUA_CheckGlobals(L, csname)) return 0; Z_Free(name); diff --git a/src/lua_script.h b/src/lua_script.h index 4f66d3f8a..8f27dcb4c 100644 --- a/src/lua_script.h +++ b/src/lua_script.h @@ -54,6 +54,8 @@ void LUA_InvalidatePlayer(player_t *player); void LUA_Step(void); void LUA_Archive(void); void LUA_UnArchive(void); +int LUA_PushGlobals(lua_State *L, const char *word); +int LUA_CheckGlobals(lua_State *L, const char *word); void Got_Luacmd(UINT8 **cp, INT32 playernum); // lua_consolelib.c void LUA_CVarChanged(const char *name); // lua_consolelib.c int Lua_optoption(lua_State *L, int narg, From edddc3e64e43351e99368605cc4c09edd6cbe289 Mon Sep 17 00:00:00 2001 From: Jaime Passos Date: Mon, 23 Dec 2019 18:54:25 -0300 Subject: [PATCH 338/746] Custom gametype constant support for Lua. --- src/lua_baselib.c | 27 +++++++++++++++++---------- 1 file changed, 17 insertions(+), 10 deletions(-) diff --git a/src/lua_baselib.c b/src/lua_baselib.c index 5f9d3dbf6..b0935983e 100644 --- a/src/lua_baselib.c +++ b/src/lua_baselib.c @@ -2642,6 +2642,7 @@ static int lib_gAddGametype(lua_State *L) lua_Integer i; const char *gtname = NULL; + const char *gtconst = NULL; const char *gtdescription = NULL; INT16 newgtidx = 0; UINT32 newgtrules = 0; @@ -2678,39 +2679,43 @@ static int lib_gAddGametype(lua_State *L) if (!lua_isstring(L, 3)) TYPEERROR("name", LUA_TSTRING) gtname = Z_StrDup(lua_tostring(L, 3)); - } else if (i == 2 || (k && fasticmp(k, "rules"))) { + } else if (i == 2 || (k && fasticmp(k, "identifier"))) { + if (!lua_isstring(L, 3)) + TYPEERROR("identifier", LUA_TSTRING) + gtconst = Z_StrDup(lua_tostring(L, 3)); + } else if (i == 3 || (k && fasticmp(k, "rules"))) { if (!lua_isnumber(L, 3)) TYPEERROR("rules", LUA_TNUMBER) newgtrules = (UINT32)lua_tointeger(L, 3); - } else if (i == 3 || (k && fasticmp(k, "typeoflevel"))) { + } else if (i == 4 || (k && fasticmp(k, "typeoflevel"))) { if (!lua_isnumber(L, 3)) TYPEERROR("typeoflevel", LUA_TNUMBER) newgttol = (UINT32)lua_tointeger(L, 3); - } else if (i == 4 || (k && fasticmp(k, "rankingtype"))) { + } else if (i == 5 || (k && fasticmp(k, "rankingtype"))) { if (!lua_isnumber(L, 3)) TYPEERROR("rankingtype", LUA_TNUMBER) newgtrankingstype = (INT16)lua_tointeger(L, 3); - } else if (i == 5 || (k && fasticmp(k, "intermissiontype"))) { + } else if (i == 6 || (k && fasticmp(k, "intermissiontype"))) { if (!lua_isnumber(L, 3)) TYPEERROR("intermissiontype", LUA_TNUMBER) newgtinttype = (int)lua_tointeger(L, 3); - } else if (i == 6 || (k && fasticmp(k, "defaultpointlimit"))) { + } else if (i == 7 || (k && fasticmp(k, "defaultpointlimit"))) { if (!lua_isnumber(L, 3)) TYPEERROR("defaultpointlimit", LUA_TNUMBER) newgtpointlimit = (INT32)lua_tointeger(L, 3); - } else if (i == 7 || (k && fasticmp(k, "defaulttimelimit"))) { + } else if (i == 8 || (k && fasticmp(k, "defaulttimelimit"))) { if (!lua_isnumber(L, 3)) TYPEERROR("defaulttimelimit", LUA_TNUMBER) newgttimelimit = (INT32)lua_tointeger(L, 3); - } else if (i == 8 || (k && fasticmp(k, "description"))) { + } else if (i == 9 || (k && fasticmp(k, "description"))) { if (!lua_isstring(L, 3)) TYPEERROR("description", LUA_TSTRING) gtdescription = Z_StrDup(lua_tostring(L, 3)); - } else if (i == 9 || (k && fasticmp(k, "headerleftcolor"))) { + } else if (i == 10 || (k && fasticmp(k, "headerleftcolor"))) { if (!lua_isnumber(L, 3)) TYPEERROR("headerleftcolor", LUA_TNUMBER) newgtleftcolor = (UINT8)lua_tointeger(L, 3); - } else if (i == 10 || (k && fasticmp(k, "headerrightcolor"))) { + } else if (i == 11 || (k && fasticmp(k, "headerrightcolor"))) { if (!lua_isnumber(L, 3)) TYPEERROR("headerrightcolor", LUA_TNUMBER) newgtrightcolor = (UINT8)lua_tointeger(L, 3); @@ -2753,7 +2758,9 @@ static int lib_gAddGametype(lua_State *L) Gametype_Names[newgtidx] = gtname; // Write the constant name. - G_AddGametypeConstant(newgtidx, gtname); + if (gtconst == NULL) + gtconst = gtname; + G_AddGametypeConstant(newgtidx, gtconst); // Update gametype_cons_t accordingly. G_UpdateGametypeSelections(); From d050e04dae61594149b2f029f2f872119b6d3f2e Mon Sep 17 00:00:00 2001 From: Jaime Passos Date: Mon, 23 Dec 2019 18:58:33 -0300 Subject: [PATCH 339/746] Bail out if there are no more free gametype slots. --- src/lua_baselib.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/lua_baselib.c b/src/lua_baselib.c index b0935983e..e5d477549 100644 --- a/src/lua_baselib.c +++ b/src/lua_baselib.c @@ -2734,6 +2734,10 @@ static int lib_gAddGametype(lua_State *L) // pop gametype table lua_pop(L, 1); + // Ran out of gametype slots + if (gametypecount == NUMGAMETYPEFREESLOTS) + return luaL_error(L, "Ran out of free gametype slots!"); + // Set defaults if (gtname == NULL) gtname = Z_StrDup("Unnamed gametype"); From 50dd0a71db5a38ad4ccb1d2c0bee3b112b0ca8bf Mon Sep 17 00:00:00 2001 From: MascaraSnake Date: Mon, 23 Dec 2019 22:58:58 +0100 Subject: [PATCH 340/746] Turn size and number of items for item circle into function parameters (in preparation for UDMF) --- src/p_mobj.c | 18 +++++++----------- 1 file changed, 7 insertions(+), 11 deletions(-) diff --git a/src/p_mobj.c b/src/p_mobj.c index aa19716df..b4ac43e21 100644 --- a/src/p_mobj.c +++ b/src/p_mobj.c @@ -13322,7 +13322,7 @@ static void P_SpawnDiagonalSpringRings(mapthing_t* mthing, fixed_t x, fixed_t y, } } -static void P_SpawnItemCircle(mapthing_t* mthing, fixed_t x, fixed_t y, fixed_t z, boolean bonustime) +static void P_SpawnItemCircle(mapthing_t* mthing, fixed_t x, fixed_t y, fixed_t z, INT32 numitems, fixed_t size, boolean bonustime) { mobjtype_t ringthing = MT_RING; mobj_t *mobj = NULL; @@ -13330,14 +13330,6 @@ static void P_SpawnItemCircle(mapthing_t* mthing, fixed_t x, fixed_t y, fixed_t angle_t closestangle, fa; INT32 i; TVector v, *res; - INT32 numitems = 8; - INT32 size = 96*FRACUNIT; - - if (mthing->type & 1) - { - numitems = 16; - size = 192*FRACUNIT; - } z = P_GetMobjSpawnHeight(ringthing, x, y, z, false); @@ -13430,13 +13422,17 @@ void P_SpawnHoopsAndRings(mapthing_t *mthing, boolean bonustime) P_SpawnDiagonalSpringRings(mthing, x, y, z); return; case 604: // Circle of rings (8 items) - case 605: // Circle of rings (16 bits) + case 605: // Circle of rings (16 items) case 606: // Circle of blue spheres (8 items) case 607: // Circle of blue spheres (16 items) case 608: // Circle of rings and blue spheres (8 items) case 609: // Circle of rings and blue spheres (16 items) - P_SpawnItemCircle(mthing, x, y, z, bonustime); + { + INT32 numitems = (mthing->type & 1) ? 16 : 8; + fixed_t size = (mthing->type & 1) ? 192*FRACUNIT : 96*FRACUNIT; + P_SpawnItemCircle(mthing, x, y, z, numitems, size, bonustime); return; + } // Hoops case 1705: // Generic NiGHTS hoop P_SpawnHoop(mthing, x, y, z, 24, 4*FRACUNIT); From bbe946ac1e8d741536d62224fa9c89651eaaa28e Mon Sep 17 00:00:00 2001 From: Jaime Passos Date: Mon, 23 Dec 2019 19:00:46 -0300 Subject: [PATCH 341/746] Bail out earlier. --- src/lua_baselib.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/lua_baselib.c b/src/lua_baselib.c index e5d477549..20eaa2048 100644 --- a/src/lua_baselib.c +++ b/src/lua_baselib.c @@ -2660,6 +2660,10 @@ static int lib_gAddGametype(lua_State *L) if (!lua_lumploading) return luaL_error(L, "This function cannot be called from within a hook or coroutine!"); + // Ran out of gametype slots + if (gametypecount == NUMGAMETYPEFREESLOTS) + return luaL_error(L, "Ran out of free gametype slots!"); + #define FIELDERROR(f, e) luaL_error(L, "bad value for " LUA_QL(f) " in table passed to " LUA_QL("G_AddGametype") " (%s)", e); #define TYPEERROR(f, t) FIELDERROR(f, va("%s expected, got %s", lua_typename(L, t), luaL_typename(L, -1))) @@ -2734,10 +2738,6 @@ static int lib_gAddGametype(lua_State *L) // pop gametype table lua_pop(L, 1); - // Ran out of gametype slots - if (gametypecount == NUMGAMETYPEFREESLOTS) - return luaL_error(L, "Ran out of free gametype slots!"); - // Set defaults if (gtname == NULL) gtname = Z_StrDup("Unnamed gametype"); From e9f69b9c6a07c3bbda1aec57def1f20cc2c457d9 Mon Sep 17 00:00:00 2001 From: Jaime Passos Date: Mon, 23 Dec 2019 19:08:57 -0300 Subject: [PATCH 342/746] Add sstimer to LUA_PushGlobals. --- src/lua_script.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/lua_script.c b/src/lua_script.c index 4b5e72938..eb1afaf09 100644 --- a/src/lua_script.c +++ b/src/lua_script.c @@ -228,6 +228,9 @@ int LUA_PushGlobals(lua_State *L, const char *word) } else if (fastcmp(word,"leveltime")) { lua_pushinteger(L, leveltime); return 1; + } else if (fastcmp(word,"sstimer")) { + lua_pushinteger(L, sstimer); + return 1; } else if (fastcmp(word,"curWeather")) { lua_pushinteger(L, curWeather); return 1; From bb1f43d37458ecb699c7860983f6cc7ea003a86b Mon Sep 17 00:00:00 2001 From: Jaime Passos Date: Mon, 23 Dec 2019 19:16:10 -0300 Subject: [PATCH 343/746] Add gametyperules to LUA_CheckGlobals. --- src/lua_script.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/lua_script.c b/src/lua_script.c index eb1afaf09..18d9a87c2 100644 --- a/src/lua_script.c +++ b/src/lua_script.c @@ -299,7 +299,9 @@ int LUA_PushGlobals(lua_State *L, const char *word) // See the above. int LUA_CheckGlobals(lua_State *L, const char *word) { - if (fastcmp(word, "redscore")) + if (fastcmp(word, "gametyperules")) + gametyperules = (UINT32)luaL_checkinteger(L, 2); + else if (fastcmp(word, "redscore")) redscore = (UINT32)luaL_checkinteger(L, 2); else if (fastcmp(word, "bluescore")) bluescore = (UINT32)luaL_checkinteger(L, 2); From 630c06b7b0a40b99d04d04f07903d78d41cab8a7 Mon Sep 17 00:00:00 2001 From: Jaime Passos Date: Mon, 23 Dec 2019 19:24:06 -0300 Subject: [PATCH 344/746] Turn GTR_CHASECAM into GTR_FIRSTPERSON. --- src/dehacked.c | 2 +- src/doomstat.h | 6 +++--- src/g_game.c | 16 ++++++++-------- src/p_setup.c | 2 +- 4 files changed, 13 insertions(+), 13 deletions(-) diff --git a/src/dehacked.c b/src/dehacked.c index d1e18a1d7..ee079aad1 100644 --- a/src/dehacked.c +++ b/src/dehacked.c @@ -8870,7 +8870,7 @@ static const char *const GAMETYPERULE_LIST[] = { "HIDETIME", "HIDEFROZEN", "BLINDFOLDED", - "CHASECAM", + "FIRSTPERSON", "MATCHEMERALDS", "TEAMFLAGS", "PITYSHIELD", diff --git a/src/doomstat.h b/src/doomstat.h index 0ab8c1bff..940d2d60c 100644 --- a/src/doomstat.h +++ b/src/doomstat.h @@ -389,7 +389,7 @@ enum GameType // Game type rules enum GameTypeRules { - GTR_CAMPAIGN = 1, // Linear Co-op map progression. Don't allow random maps. + 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 @@ -402,12 +402,12 @@ enum GameTypeRules GTR_HIDETIME = 1<<10, // Hide time (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_CHASECAM = 1<<13, // Prefer chasecam at map load (All platform gametypes) + GTR_FIRSTPERSON = 1<<13, // First person camera GTR_MATCHEMERALDS = 1<<14, // Ringslinger emeralds (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, // For use with GTR_SPECTATORS - spawn in the map instead of with the spectators + 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 diff --git a/src/g_game.c b/src/g_game.c index b29824b1c..34524c8f9 100644 --- a/src/g_game.c +++ b/src/g_game.c @@ -3167,24 +3167,24 @@ const char *Gametype_ConstantNames[NUMGAMETYPES] = UINT32 gametypedefaultrules[NUMGAMETYPES] = { // Co-op - GTR_CAMPAIGN|GTR_LIVES|GTR_CHASECAM|GTR_SPAWNENEMIES|GTR_ALLOWEXIT|GTR_EMERALDHUNT|GTR_EMERALDTOKENS|GTR_SPECIALSTAGES, + GTR_CAMPAIGN|GTR_LIVES|GTR_SPAWNENEMIES|GTR_ALLOWEXIT|GTR_EMERALDHUNT|GTR_EMERALDTOKENS|GTR_SPECIALSTAGES, // Competition - GTR_RACE|GTR_LIVES|GTR_CHASECAM|GTR_SPAWNENEMIES|GTR_EMERALDTOKENS|GTR_ALLOWEXIT, + GTR_RACE|GTR_LIVES|GTR_SPAWNENEMIES|GTR_EMERALDTOKENS|GTR_ALLOWEXIT, // Race - GTR_RACE|GTR_CHASECAM|GTR_SPAWNENEMIES|GTR_ALLOWEXIT, + GTR_RACE|GTR_SPAWNENEMIES|GTR_ALLOWEXIT, // Match - GTR_RINGSLINGER|GTR_SPECTATORS|GTR_POINTLIMIT|GTR_TIMELIMIT|GTR_MATCHEMERALDS|GTR_PITYSHIELD|GTR_DEATHPENALTY, + GTR_RINGSLINGER|GTR_FIRSTPERSON|GTR_SPECTATORS|GTR_POINTLIMIT|GTR_TIMELIMIT|GTR_MATCHEMERALDS|GTR_PITYSHIELD|GTR_DEATHPENALTY, // Team Match - GTR_RINGSLINGER|GTR_SPECTATORS|GTR_TEAMS|GTR_POINTLIMIT|GTR_TIMELIMIT|GTR_PITYSHIELD, + GTR_RINGSLINGER|GTR_FIRSTPERSON|GTR_SPECTATORS|GTR_TEAMS|GTR_POINTLIMIT|GTR_TIMELIMIT|GTR_PITYSHIELD, // Tag - GTR_RINGSLINGER|GTR_TAG|GTR_SPECTATORS|GTR_POINTLIMIT|GTR_TIMELIMIT|GTR_HIDETIME|GTR_BLINDFOLDED, + GTR_RINGSLINGER|GTR_FIRSTPERSON|GTR_TAG|GTR_SPECTATORS|GTR_POINTLIMIT|GTR_TIMELIMIT|GTR_HIDETIME|GTR_BLINDFOLDED, // Hide and Seek - GTR_RINGSLINGER|GTR_TAG|GTR_SPECTATORS|GTR_POINTLIMIT|GTR_TIMELIMIT|GTR_HIDETIME|GTR_BLINDFOLDED, + GTR_RINGSLINGER|GTR_FIRSTPERSON|GTR_TAG|GTR_SPECTATORS|GTR_POINTLIMIT|GTR_TIMELIMIT|GTR_HIDETIME|GTR_BLINDFOLDED, // CTF - GTR_RINGSLINGER|GTR_SPECTATORS|GTR_TEAMS|GTR_POINTLIMIT|GTR_TIMELIMIT|GTR_MATCHEMERALDS|GTR_TEAMFLAGS|GTR_PITYSHIELD, + GTR_RINGSLINGER|GTR_FIRSTPERSON|GTR_SPECTATORS|GTR_TEAMS|GTR_POINTLIMIT|GTR_TIMELIMIT|GTR_MATCHEMERALDS|GTR_TEAMFLAGS|GTR_PITYSHIELD, }; // diff --git a/src/p_setup.c b/src/p_setup.c index 821f8bcd5..34f0cf882 100644 --- a/src/p_setup.c +++ b/src/p_setup.c @@ -2673,7 +2673,7 @@ boolean P_SetupLevel(boolean skipprecip) // chasecam on in chaos, race, coop // chasecam off in match, tag, capture the flag - chase = (gametyperules & GTR_CHASECAM) || (maptol & TOL_2D); + chase = (!(gametyperules & GTR_FIRSTPERSON)) || (maptol & TOL_2D); if (!dedicated) { From ffd6cf4acad17ba5f1c60a42dcf19d56e2f75db3 Mon Sep 17 00:00:00 2001 From: MascaraSnake Date: Tue, 24 Dec 2019 00:10:29 +0100 Subject: [PATCH 345/746] Replaced functions for spawning premade rows of rings with a function for spawning a generic row of rings (groundwork for UDMF) --- src/p_mobj.c | 76 ++++++++++------------------------------------------ 1 file changed, 14 insertions(+), 62 deletions(-) diff --git a/src/p_mobj.c b/src/p_mobj.c index b4ac43e21..f25690ed8 100644 --- a/src/p_mobj.c +++ b/src/p_mobj.c @@ -13231,58 +13231,13 @@ static void P_SpawnRingItem(mapthing_t *mthing, fixed_t x, fixed_t y, boolean bo P_SetMobjState(mobj, mobj->info->seestate); } -static void P_SpawnVerticalSpringRings(mapthing_t *mthing, fixed_t x, fixed_t y, fixed_t z) -{ - mobjtype_t ringthing = MT_RING; - mobj_t* mobj = NULL; - INT32 r; - - INT32 dist = 64*FRACUNIT; - if (mthing->type == 601) - dist = 128*FRACUNIT; - - if (ultimatemode) - return; // No rings in Ultimate! - - if (nightsreplace) - ringthing = MT_NIGHTSSTAR; - - z = P_GetMobjSpawnHeight(ringthing, x, y, z, mthing->options & MTF_OBJECTFLIP); - - for (r = 1; r <= 5; r++) - { - if (mthing->options & MTF_OBJECTFLIP) - z -= dist; - else - z += dist; - - mobj = P_SpawnMobj(x, y, z, ringthing); - - if (mthing->options & MTF_OBJECTFLIP) - { - mobj->eflags |= MFE_VERTICALFLIP; - mobj->flags2 |= MF2_OBJECTFLIP; - } - - mobj->angle = FixedAngle(mthing->angle << FRACBITS); - if (mthing->options & MTF_AMBUSH) - mobj->flags2 |= MF2_AMBUSH; - - if ((maptol & TOL_XMAS) && (ringthing == MT_NIGHTSSTAR)) - P_SetMobjState(mobj, mobj->info->seestate); - } -} - -static void P_SpawnDiagonalSpringRings(mapthing_t* mthing, fixed_t x, fixed_t y, fixed_t z) +static void P_SpawnItemRow(mapthing_t* mthing, fixed_t x, fixed_t y, fixed_t z, INT32 numitems, fixed_t horizontalspacing, fixed_t verticalspacing, INT16 fixedangle) { mobjtype_t ringthing = MT_RING; mobj_t *mobj = NULL; INT32 r; - angle_t closestangle, fa; - - INT32 iterations = 5; - if (mthing->type == 603) - iterations = 10; + angle_t angle = FixedAngle(fixedangle << FRACBITS); + angle_t fineangle = (angle >> ANGLETOFINESHIFT) & FINEMASK; if (ultimatemode) return; // No rings in Ultimate! @@ -13290,20 +13245,13 @@ static void P_SpawnDiagonalSpringRings(mapthing_t* mthing, fixed_t x, fixed_t y, if (nightsreplace) ringthing = MT_NIGHTSSTAR; - closestangle = FixedAngle(mthing->angle << FRACBITS); - fa = (closestangle >> ANGLETOFINESHIFT); - z = P_GetMobjSpawnHeight(ringthing, x, y, z, mthing->options & MTF_OBJECTFLIP); - for (r = 1; r <= iterations; r++) + for (r = 0; r < numitems; r++) { - x += FixedMul(64*FRACUNIT, FINECOSINE(fa)); - y += FixedMul(64*FRACUNIT, FINESINE(fa)); - - if (mthing->options & MTF_OBJECTFLIP) - z -= 64*FRACUNIT; - else - z += 64*FRACUNIT; + x += FixedMul(horizontalspacing, FINECOSINE(fineangle)); + y += FixedMul(horizontalspacing, FINESINE(fineangle)); + z += (mthing->options & MTF_OBJECTFLIP) ? -verticalspacing : verticalspacing; mobj = P_SpawnMobj(x, y, z, ringthing); @@ -13313,7 +13261,7 @@ static void P_SpawnDiagonalSpringRings(mapthing_t* mthing, fixed_t x, fixed_t y, mobj->flags2 |= MF2_OBJECTFLIP; } - mobj->angle = closestangle; + mobj->angle = angle; if (mthing->options & MTF_AMBUSH) mobj->flags2 |= MF2_AMBUSH; @@ -13414,12 +13362,16 @@ void P_SpawnHoopsAndRings(mapthing_t *mthing, boolean bonustime) { // Special placement patterns case 600: // 5 vertical rings (yellow spring) + P_SpawnItemRow(mthing, x, y, z, 5, 0, 64*FRACUNIT, 0); + return; case 601: // 5 vertical rings (red spring) - P_SpawnVerticalSpringRings(mthing, x, y, z); + P_SpawnItemRow(mthing, x, y, z, 5, 0, 128*FRACUNIT, 0); return; case 602: // 5 diagonal rings (yellow spring) + P_SpawnItemRow(mthing, x, y, z, 5, 64*FRACUNIT, 64*FRACUNIT, mthing->angle); + return; case 603: // 10 diagonal rings (red spring) - P_SpawnDiagonalSpringRings(mthing, x, y, z); + P_SpawnItemRow(mthing, x, y, z, 10, 64*FRACUNIT, 64*FRACUNIT, mthing->angle); return; case 604: // Circle of rings (8 items) case 605: // Circle of rings (16 items) From a657392d397cb71af3851be3ae08788fd8c338e2 Mon Sep 17 00:00:00 2001 From: Jaime Passos Date: Mon, 23 Dec 2019 20:22:57 -0300 Subject: [PATCH 346/746] ViewpointSwitch improvements. --- src/d_clisrv.c | 14 +++++++++++--- src/d_netcmd.c | 8 ++++++++ src/g_game.c | 25 ++++++++++++++++++------- src/lua_hook.h | 2 +- src/lua_hooklib.c | 12 +++++++----- src/p_user.c | 14 ++++++++++++++ 6 files changed, 59 insertions(+), 16 deletions(-) diff --git a/src/d_clisrv.c b/src/d_clisrv.c index c0dec7ff7..cad27f52c 100644 --- a/src/d_clisrv.c +++ b/src/d_clisrv.c @@ -2486,6 +2486,17 @@ static void CL_RemovePlayer(INT32 playernum, INT32 reason) (void)reason; #endif + // don't look through someone's view who isn't there + if (playernum == displayplayer) + { +#ifdef HAVE_BLUA + // Call ViewpointSwitch hooks here. + // The viewpoint was forcibly changed. + LUAh_ViewpointSwitch(&players[consoleplayer], &players[displayplayer], true); +#endif + displayplayer = consoleplayer; + } + // Reset player data CL_ClearPlayer(playernum); @@ -2503,9 +2514,6 @@ static void CL_RemovePlayer(INT32 playernum, INT32 reason) RemoveAdminPlayer(playernum); // don't stay admin after you're gone } - if (playernum == displayplayer) - displayplayer = consoleplayer; // don't look through someone's view who isn't there - #ifdef HAVE_BLUA LUA_InvalidatePlayer(&players[playernum]); #endif diff --git a/src/d_netcmd.c b/src/d_netcmd.c index be8b90c78..4e14ca25f 100644 --- a/src/d_netcmd.c +++ b/src/d_netcmd.c @@ -2900,7 +2900,15 @@ static void Got_Teamchange(UINT8 **cp, INT32 playernum) //reset view if you are changed, or viewing someone who was changed. if (playernum == consoleplayer || displayplayer == playernum) + { +#ifdef HAVE_BLUA + // Call ViewpointSwitch hooks here. + // The viewpoint was forcibly changed. + if (displayplayer != consoleplayer) // You're already viewing yourself. No big deal. + LUAh_ViewpointSwitch(&players[playernum], &players[displayplayer], true); +#endif displayplayer = consoleplayer; + } if (G_GametypeHasTeams()) { diff --git a/src/g_game.c b/src/g_game.c index 34524c8f9..ead7e8c5c 100644 --- a/src/g_game.c +++ b/src/g_game.c @@ -1379,7 +1379,14 @@ void G_BuildTiccmd(ticcmd_t *cmd, INT32 realtics) //Reset away view if a command is given. if ((cmd->forwardmove || cmd->sidemove || cmd->buttons) && displayplayer != consoleplayer) + { +#ifdef HAVE_BLUA + // Call ViewpointSwitch hooks here. + // The viewpoint was forcibly changed. + LUAh_ViewpointSwitch(player, &players[displayplayer], true); +#endif displayplayer = consoleplayer; + } } // like the g_buildticcmd 1 but using mouse2, gamcontrolbis, ... @@ -2021,6 +2028,11 @@ boolean G_Responder(event_t *ev) if (gamestate == GS_LEVEL && ev->type == ev_keydown && (ev->data1 == KEY_F12 || ev->data1 == gamecontrol[gc_viewpoint][0] || ev->data1 == gamecontrol[gc_viewpoint][1])) { + // ViewpointSwitch Lua hook. +#ifdef HAVE_BLUA + UINT8 canSwitchView = 0; +#endif + if (splitscreen || !netgame) displayplayer = consoleplayer; else @@ -2036,13 +2048,12 @@ boolean G_Responder(event_t *ev) continue; #ifdef HAVE_BLUA - { - UINT8 canSwitchView = LUAh_ViewpointSwitch(&players[consoleplayer], &players[displayplayer]); - if (canSwitchView == 1) // Set viewpoint to this player - break; - else if (canSwitchView == 2) // Skip this player - continue; - } + // Call ViewpointSwitch hooks here. + canSwitchView = LUAh_ViewpointSwitch(&players[consoleplayer], &players[displayplayer], false); + if (canSwitchView == 1) // Set viewpoint to this player + break; + else if (canSwitchView == 2) // Skip this player + continue; #endif if (players[displayplayer].spectator) diff --git a/src/lua_hook.h b/src/lua_hook.h index 8d780490e..68efbce93 100644 --- a/src/lua_hook.h +++ b/src/lua_hook.h @@ -96,6 +96,6 @@ UINT8 LUAh_PlayerCanDamage(player_t *player, mobj_t *mobj); // Hook for P_Player 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); // Hook for spy mode in G_Responder +UINT8 LUAh_ViewpointSwitch(player_t *player, player_t *newdisplayplayer, boolean forced); // Hook for spy mode #endif diff --git a/src/lua_hooklib.c b/src/lua_hooklib.c index d213bd307..5383cbf0b 100644 --- a/src/lua_hooklib.c +++ b/src/lua_hooklib.c @@ -1397,8 +1397,8 @@ boolean LUAh_TeamSwitch(player_t *player, int newteam, boolean fromspectators, b return canSwitchTeam; } -// Hook for spy mode in G_Responder -UINT8 LUAh_ViewpointSwitch(player_t *player, player_t *newdisplayplayer) +// Hook for spy mode +UINT8 LUAh_ViewpointSwitch(player_t *player, player_t *newdisplayplayer, boolean forced) { hook_p hookp; UINT8 canSwitchView = 0; // 0 = default, 1 = force yes, 2 = force no. @@ -1417,12 +1417,14 @@ UINT8 LUAh_ViewpointSwitch(player_t *player, player_t *newdisplayplayer) { LUA_PushUserdata(gL, player, META_PLAYER); LUA_PushUserdata(gL, newdisplayplayer, META_PLAYER); + lua_pushboolean(gL, forced); } 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)) { + lua_pushvalue(gL, -4); + lua_pushvalue(gL, -4); + lua_pushvalue(gL, -4); + if (lua_pcall(gL, 3, 1, 0)) { if (!hookp->error || cv_debug & DBG_LUA) CONS_Alert(CONS_WARNING,"%s\n",lua_tostring(gL, -1)); lua_pop(gL, 1); diff --git a/src/p_user.c b/src/p_user.c index c8a329c35..4dbea87e3 100644 --- a/src/p_user.c +++ b/src/p_user.c @@ -10380,7 +10380,14 @@ boolean P_SpectatorJoinGame(player_t *player) //Reset away view if (P_IsLocalPlayer(player) && displayplayer != consoleplayer) + { +#ifdef HAVE_BLUA + // Call ViewpointSwitch hooks here. + // The viewpoint was forcibly changed. + LUAh_ViewpointSwitch(player, &players[displayplayer], true); +#endif displayplayer = consoleplayer; + } if (changeto == 1) CONS_Printf(M_GetText("%s switched to the %c%s%c.\n"), player_names[player-players], '\x85', M_GetText("Red team"), '\x80'); @@ -10422,7 +10429,14 @@ boolean P_SpectatorJoinGame(player_t *player) //Reset away view if (P_IsLocalPlayer(player) && displayplayer != consoleplayer) + { +#ifdef HAVE_BLUA + // Call ViewpointSwitch hooks here. + // The viewpoint was forcibly changed. + LUAh_ViewpointSwitch(player, &players[displayplayer], true); +#endif displayplayer = consoleplayer; + } if (gametype != GT_COOP) CONS_Printf(M_GetText("%s entered the game.\n"), player_names[player-players]); From d9d13764e6840e036c095c6d87838a4dfede80f4 Mon Sep 17 00:00:00 2001 From: James R Date: Mon, 23 Dec 2019 15:31:50 -0800 Subject: [PATCH 347/746] -logfile to let the user change the log file name --- src/sdl/i_main.c | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/src/sdl/i_main.c b/src/sdl/i_main.c index 029febc05..32cc16208 100644 --- a/src/sdl/i_main.c +++ b/src/sdl/i_main.c @@ -133,15 +133,19 @@ int main(int argc, char **argv) { time_t my_time; struct tm * timeinfo; - char buf[26]; + const char *format; logdir = D_Home(); my_time = time(NULL); timeinfo = localtime(&my_time); - strftime(buf, 26, "%Y-%m-%d %H-%M-%S", timeinfo); - strcpy(logfile, va("log-%s.txt", buf)); + if (M_CheckParm("-logfile") && M_IsNextParm()) + format = M_GetNextParm(); + else + format = "log-%Y-%m-%d %H-%M-%S.txt"; + + strftime(logfile, sizeof logfile, format, timeinfo); #ifdef DEFAULTDIR if (logdir) From c285000c5668ab82545ec9ee4989aabf65e2585e Mon Sep 17 00:00:00 2001 From: James R Date: Mon, 23 Dec 2019 15:34:27 -0800 Subject: [PATCH 348/746] Change default log filename to not use a space bleh --- src/sdl/i_main.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/sdl/i_main.c b/src/sdl/i_main.c index 32cc16208..326f1a929 100644 --- a/src/sdl/i_main.c +++ b/src/sdl/i_main.c @@ -143,7 +143,7 @@ int main(int argc, char **argv) if (M_CheckParm("-logfile") && M_IsNextParm()) format = M_GetNextParm(); else - format = "log-%Y-%m-%d %H-%M-%S.txt"; + format = "log-%Y-%m-%d_%H-%M-%S.txt"; strftime(logfile, sizeof logfile, format, timeinfo); From 1f93ab0e0ffe5c19dee2fa1c47f1dbe0c161d207 Mon Sep 17 00:00:00 2001 From: GoldenTails Date: Mon, 23 Dec 2019 18:53:41 -0600 Subject: [PATCH 349/746] Optimise further, play beep on cut/copy, play beep when paste is successful. --- src/m_menu.c | 23 ++++++++++++++++------- 1 file changed, 16 insertions(+), 7 deletions(-) diff --git a/src/m_menu.c b/src/m_menu.c index ad0f70eb2..fed0d65b1 100644 --- a/src/m_menu.c +++ b/src/m_menu.c @@ -10433,33 +10433,42 @@ static void M_HandleConnectIP(INT32 choice) default: l = strlen(setupm_ip); - if (l >= 28-1) - break; - - char *paste = (char *)I_ClipboardPaste(); // Paste clipboard into char if ( ctrldown ) { switch (choice) { case 118: // ctrl+v, pasting + ; + char *paste = (char *)I_ClipboardPaste(); // Paste clipboard into char + if (paste != NULL) { - if (strlen(paste) + strlen(setupm_ip) >= 28-1) - paste[28-1 - strlen(setupm_ip)] = 0; + if (strlen(paste) + l >= 28-1) + paste[28-1 - l] = 0; strcat(setupm_ip, paste); // Concat the ip field with clipboard + if (strlen(paste) != 0) // Don't play sound if nothing was pasted + S_StartSound(NULL,sfx_menu1); // Tails } break; + case 99: // ctrl+c, copying I_ClipboardCopy(setupm_ip, l); + S_StartSound(NULL,sfx_menu1); // Tails break; + case 120: // ctrl+x, cutting I_ClipboardCopy(setupm_ip, l); + S_StartSound(NULL,sfx_menu1); // Tails setupm_ip[0] = 0; break; + default: // otherwise do nothing break; } - break; // break + break; // don't check for typed keys } + if (l >= 28-1) + break; + // Rudimentary number and period enforcing - also allows letters so hostnames can be used instead if ((choice >= '-' && choice <= ':') || (choice >= 'A' && choice <= 'Z') || (choice >= 'a' && choice <= 'z')) { From 457e986b7514c0e9fa921c1961344012443ac164 Mon Sep 17 00:00:00 2001 From: James R Date: Mon, 23 Dec 2019 17:21:58 -0800 Subject: [PATCH 350/746] -logdir lets the user change the log directory --- src/m_misc.c | 73 ++++++++++++++++++++++++++++++++++++++++++++++++ src/m_misc.h | 4 +++ src/sdl/i_main.c | 34 ++++++++++++++++------ 3 files changed, 102 insertions(+), 9 deletions(-) diff --git a/src/m_misc.c b/src/m_misc.c index d97383385..69e554a2c 100644 --- a/src/m_misc.c +++ b/src/m_misc.c @@ -2453,3 +2453,76 @@ const char *M_FileError(FILE *fp) else return "end-of-file"; } + +/** Return the number of parts of this path. +*/ +int M_PathParts(const char *path) +{ + int n; + const char *p; + const char *t; + for (n = 0, p = path ;; ++n) + { + t = p; + if (( p = strchr(p, PATHSEP[0]) )) + p += strspn(p, PATHSEP); + else + { + if (*t)/* there is something after the final delimiter */ + n++; + break; + } + } + return n; +} + +/** Check whether a path is an absolute path. +*/ +boolean M_IsPathAbsolute(const char *path) +{ +#ifdef _WIN32 + return ( strncmp(&path[1], ":\\", 2) == 0 ); +#else + return ( path[0] == '/' ); +#endif +} + +/** I_mkdir for each part of the path. +*/ +void M_MkdirEach(const char *cpath, int start, int mode) +{ + char path[MAX_WADPATH]; + char *p; + char *t; + strlcpy(path, cpath, sizeof path); +#ifdef _WIN32 + if (strncmp(&path[1], ":\\", 2) == 0) + p = &path[3]; + else +#endif + p = path; + for (; start > 0; --start) + { + p += strspn(p, PATHSEP); + if (!( p = strchr(p, PATHSEP[0]) )) + return; + } + p += strspn(p, PATHSEP); + for (;;) + { + t = p; + if (( p = strchr(p, PATHSEP[0]) )) + { + *p = '\0'; + I_mkdir(path, mode); + *p = PATHSEP[0]; + p += strspn(p, PATHSEP); + } + else + { + if (*t) + I_mkdir(path, mode); + break; + } + } +} diff --git a/src/m_misc.h b/src/m_misc.h index 99ca8d0c9..9f570df20 100644 --- a/src/m_misc.h +++ b/src/m_misc.h @@ -96,6 +96,10 @@ void M_SetupMemcpy(void); const char *M_FileError(FILE *handle); +int M_PathParts (const char *path); +boolean M_IsPathAbsolute (const char *path); +void M_MkdirEach (const char *path, int start, int mode); + // counting bits, for weapon ammo code, usually FUNCMATH UINT8 M_CountBits(UINT32 num, UINT8 size); diff --git a/src/sdl/i_main.c b/src/sdl/i_main.c index 326f1a929..7a8ebcfd3 100644 --- a/src/sdl/i_main.c +++ b/src/sdl/i_main.c @@ -20,6 +20,7 @@ #include "../doomdef.h" #include "../m_argv.h" #include "../d_main.h" +#include "../m_misc.h"/* path shit */ #include "../i_system.h" #ifdef __GNUC__ @@ -134,6 +135,8 @@ int main(int argc, char **argv) time_t my_time; struct tm * timeinfo; const char *format; + const char *reldir; + int left; logdir = D_Home(); @@ -145,24 +148,37 @@ int main(int argc, char **argv) else format = "log-%Y-%m-%d_%H-%M-%S.txt"; - strftime(logfile, sizeof logfile, format, timeinfo); + if (M_CheckParm("-logdir") && M_IsNextParm()) + reldir = M_GetNextParm(); + else + reldir = "logs"; + if (M_IsPathAbsolute(reldir)) + { + left = snprintf(logfile, sizeof logfile, + "%s"PATHSEP, reldir); + } + else #ifdef DEFAULTDIR if (logdir) { - // Create dirs here because D_SRB2Main() is too late. - I_mkdir(va("%s%s"DEFAULTDIR, logdir, PATHSEP), 0755); - I_mkdir(va("%s%s"DEFAULTDIR"%slogs",logdir, PATHSEP, PATHSEP), 0755); - logstream = fopen(va("%s%s"DEFAULTDIR"%slogs%s%s",logdir, PATHSEP, PATHSEP, PATHSEP, logfile), "wt"); + left = snprintf(logfile, sizeof logfile, + "%s"PATHSEP DEFAULTDIR PATHSEP"%s"PATHSEP, logdir, reldir); } else -#endif +#endif/*DEFAULTDIR*/ { - I_mkdir("."PATHSEP"logs"PATHSEP, 0755); - logstream = fopen(va("."PATHSEP"logs"PATHSEP"%s", logfile), "wt"); + left = snprintf(logfile, sizeof logfile, + "."PATHSEP"%s"PATHSEP, reldir); } +#endif/*LOGMESSAGES*/ + + M_MkdirEach(logfile, M_PathParts(logdir) - 1, 0755); + + strftime(&logfile[left], sizeof logfile - left, format, timeinfo); + + logstream = fopen(logfile, "wt"); } -#endif //I_OutputMsg("I_StartupSystem() ...\n"); I_StartupSystem(); From 5fbe77cdda7ec52bc2ca10ab9253df8dc56d2317 Mon Sep 17 00:00:00 2001 From: James R Date: Mon, 23 Dec 2019 17:40:43 -0800 Subject: [PATCH 351/746] Let an asbolute path work with -logfile --- src/m_misc.c | 18 ++++++++++++++- src/m_misc.h | 1 + src/sdl/i_main.c | 58 +++++++++++++++++++++++++++++++----------------- 3 files changed, 56 insertions(+), 21 deletions(-) diff --git a/src/m_misc.c b/src/m_misc.c index 69e554a2c..9149c9cce 100644 --- a/src/m_misc.c +++ b/src/m_misc.c @@ -2489,11 +2489,15 @@ boolean M_IsPathAbsolute(const char *path) /** I_mkdir for each part of the path. */ -void M_MkdirEach(const char *cpath, int start, int mode) +void M_MkdirEachUntil(const char *cpath, int start, int end, int mode) { char path[MAX_WADPATH]; char *p; char *t; + + if (end > 0 && end <= start) + return; + strlcpy(path, cpath, sizeof path); #ifdef _WIN32 if (strncmp(&path[1], ":\\", 2) == 0) @@ -2501,6 +2505,10 @@ void M_MkdirEach(const char *cpath, int start, int mode) else #endif p = path; + + if (end > 0) + end -= start; + for (; start > 0; --start) { p += strspn(p, PATHSEP); @@ -2510,6 +2518,9 @@ void M_MkdirEach(const char *cpath, int start, int mode) p += strspn(p, PATHSEP); for (;;) { + if (end > 0 && !--end) + break; + t = p; if (( p = strchr(p, PATHSEP[0]) )) { @@ -2526,3 +2537,8 @@ void M_MkdirEach(const char *cpath, int start, int mode) } } } + +void M_MkdirEach(const char *path, int start, int mode) +{ + M_MkdirEachUntil(path, start, -1, mode); +} diff --git a/src/m_misc.h b/src/m_misc.h index 9f570df20..e0a73e0b7 100644 --- a/src/m_misc.h +++ b/src/m_misc.h @@ -99,6 +99,7 @@ const char *M_FileError(FILE *handle); int M_PathParts (const char *path); boolean M_IsPathAbsolute (const char *path); void M_MkdirEach (const char *path, int start, int mode); +void M_MkdirEachUntil (const char *path, int start, int end, int mode); // counting bits, for weapon ammo code, usually FUNCMATH UINT8 M_CountBits(UINT32 num, UINT8 size); diff --git a/src/sdl/i_main.c b/src/sdl/i_main.c index 7a8ebcfd3..71b38841a 100644 --- a/src/sdl/i_main.c +++ b/src/sdl/i_main.c @@ -137,6 +137,7 @@ int main(int argc, char **argv) const char *format; const char *reldir; int left; + boolean fileabs; logdir = D_Home(); @@ -144,38 +145,55 @@ int main(int argc, char **argv) timeinfo = localtime(&my_time); if (M_CheckParm("-logfile") && M_IsNextParm()) + { format = M_GetNextParm(); + fileabs = M_IsPathAbsolute(format); + } else + { format = "log-%Y-%m-%d_%H-%M-%S.txt"; + fileabs = false; + } - if (M_CheckParm("-logdir") && M_IsNextParm()) - reldir = M_GetNextParm(); - else - reldir = "logs"; - - if (M_IsPathAbsolute(reldir)) + if (fileabs) { - left = snprintf(logfile, sizeof logfile, - "%s"PATHSEP, reldir); + strftime(logfile, sizeof logfile, format, timeinfo); + + M_MkdirEachUntil(logfile, + M_PathParts(logdir) - 1, + M_PathParts(logfile) - 1, 0755); } else + { + if (M_CheckParm("-logdir") && M_IsNextParm()) + reldir = M_GetNextParm(); + else + reldir = "logs"; + + if (M_IsPathAbsolute(reldir)) + { + left = snprintf(logfile, sizeof logfile, + "%s"PATHSEP, reldir); + } + else #ifdef DEFAULTDIR - if (logdir) - { - left = snprintf(logfile, sizeof logfile, - "%s"PATHSEP DEFAULTDIR PATHSEP"%s"PATHSEP, logdir, reldir); - } - else + if (logdir) + { + left = snprintf(logfile, sizeof logfile, + "%s"PATHSEP DEFAULTDIR PATHSEP"%s"PATHSEP, logdir, reldir); + } + else #endif/*DEFAULTDIR*/ - { - left = snprintf(logfile, sizeof logfile, - "."PATHSEP"%s"PATHSEP, reldir); - } + { + left = snprintf(logfile, sizeof logfile, + "."PATHSEP"%s"PATHSEP, reldir); + } #endif/*LOGMESSAGES*/ - M_MkdirEach(logfile, M_PathParts(logdir) - 1, 0755); + M_MkdirEach(logfile, M_PathParts(logdir) - 1, 0755); - strftime(&logfile[left], sizeof logfile - left, format, timeinfo); + strftime(&logfile[left], sizeof logfile - left, format, timeinfo); + } logstream = fopen(logfile, "wt"); } From 98cb238d36e0f85d9d4b4d2cff59c720e1630bdd Mon Sep 17 00:00:00 2001 From: James R Date: Mon, 23 Dec 2019 17:43:42 -0800 Subject: [PATCH 352/746] Create directories from -logfile too --- src/sdl/i_main.c | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/src/sdl/i_main.c b/src/sdl/i_main.c index 71b38841a..70f582676 100644 --- a/src/sdl/i_main.c +++ b/src/sdl/i_main.c @@ -158,10 +158,6 @@ int main(int argc, char **argv) if (fileabs) { strftime(logfile, sizeof logfile, format, timeinfo); - - M_MkdirEachUntil(logfile, - M_PathParts(logdir) - 1, - M_PathParts(logfile) - 1, 0755); } else { @@ -190,11 +186,13 @@ int main(int argc, char **argv) } #endif/*LOGMESSAGES*/ - M_MkdirEach(logfile, M_PathParts(logdir) - 1, 0755); - strftime(&logfile[left], sizeof logfile - left, format, timeinfo); } + M_MkdirEachUntil(logfile, + M_PathParts(logdir) - 1, + M_PathParts(logfile) - 1, 0755); + logstream = fopen(logfile, "wt"); } From 40b0c853b7af09216df00fd1bd575c33b90ba6ab Mon Sep 17 00:00:00 2001 From: Jaime Passos Date: Mon, 23 Dec 2019 23:19:48 -0300 Subject: [PATCH 353/746] Add IDENTIFIER to gametype DeHackEd. --- src/dehacked.c | 17 ++++++++++++++++- 1 file changed, 16 insertions(+), 1 deletion(-) diff --git a/src/dehacked.c b/src/dehacked.c index ee079aad1..12aa8f970 100644 --- a/src/dehacked.c +++ b/src/dehacked.c @@ -1158,6 +1158,11 @@ static void readgametype(MYFILE *f, char *gtname) INT16 newgtrankingstype = -1; int newgtinttype = 0; char gtdescription[441]; + char gtconst[MAXLINELEN]; + + // Empty strings. + gtdescription[0] = '\0'; + gtconst[0] = '\0'; do { @@ -1231,6 +1236,12 @@ static void readgametype(MYFILE *f, char *gtname) // GTR_ newgtrules = (UINT32)get_number(word2); } + // Identifier + else if (fastcmp(word, "IDENTIFIER")) + { + // GT_ + strncpy(gtconst, word2, MAXLINELEN); + } // Point and time limits else if (fastcmp(word, "DEFAULTPOINTLIMIT")) newgtpointlimit = (INT32)i; @@ -1297,6 +1308,8 @@ static void readgametype(MYFILE *f, char *gtname) } } } while (!myfeof(f)); // finish when the line is empty + + // Free strings. Z_Free(s); if (word2lwr) Z_Free(word2lwr); @@ -1325,7 +1338,9 @@ static void readgametype(MYFILE *f, char *gtname) Gametype_Names[newgtidx] = Z_StrDup((const char *)gtname); // Write the constant name. - G_AddGametypeConstant(newgtidx, (const char *)gtname); + if (gtconst[0] == '\0') + strncpy(gtconst, gtname, MAXLINELEN); + G_AddGametypeConstant(newgtidx, (const char *)gtconst); // Update gametype_cons_t accordingly. G_UpdateGametypeSelections(); From 25525a6aae84581ac03ca3089950ad4ff25b8512 Mon Sep 17 00:00:00 2001 From: James R Date: Mon, 23 Dec 2019 18:20:04 -0800 Subject: [PATCH 354/746] symlink latest-log.txt on nix, copy to the real log file everywhere else --- src/doomdef.h | 1 + src/sdl/i_main.c | 40 +++++++++++++++++++++++++++++----------- src/sdl/i_system.c | 45 +++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 75 insertions(+), 11 deletions(-) diff --git a/src/doomdef.h b/src/doomdef.h index 6c4f1fef3..fe6a5faa3 100644 --- a/src/doomdef.h +++ b/src/doomdef.h @@ -127,6 +127,7 @@ #ifdef LOGMESSAGES extern FILE *logstream; +extern char logfilename[1024]; #endif //#define DEVELOP // Disable this for release builds to remove excessive cheat commands and enable MD5 checking and stuff, all in one go. :3 diff --git a/src/sdl/i_main.c b/src/sdl/i_main.c index 70f582676..af34da8d1 100644 --- a/src/sdl/i_main.c +++ b/src/sdl/i_main.c @@ -23,10 +23,14 @@ #include "../m_misc.h"/* path shit */ #include "../i_system.h" -#ifdef __GNUC__ +#if defined (__GNUC__) || defined (__unix__) #include #endif +#ifdef __unix__ +#include +#endif + #include "time.h" // For log timestamps #ifdef HAVE_SDL @@ -48,6 +52,7 @@ extern int SDL_main(int argc, char *argv[]); #ifdef LOGMESSAGES FILE *logstream = NULL; +char logfilename[1024]; #endif #ifndef DOXYGEN @@ -117,7 +122,6 @@ int main(int argc, char **argv) #endif { const char *logdir = NULL; - char logfile[MAX_WADPATH]; myargc = argc; myargv = argv; /// \todo pull out path to exe from this string @@ -157,7 +161,7 @@ int main(int argc, char **argv) if (fileabs) { - strftime(logfile, sizeof logfile, format, timeinfo); + strftime(logfilename, sizeof logfilename, format, timeinfo); } else { @@ -168,32 +172,46 @@ int main(int argc, char **argv) if (M_IsPathAbsolute(reldir)) { - left = snprintf(logfile, sizeof logfile, + left = snprintf(logfilename, sizeof logfilename, "%s"PATHSEP, reldir); } else #ifdef DEFAULTDIR if (logdir) { - left = snprintf(logfile, sizeof logfile, + left = snprintf(logfilename, sizeof logfilename, "%s"PATHSEP DEFAULTDIR PATHSEP"%s"PATHSEP, logdir, reldir); } else #endif/*DEFAULTDIR*/ { - left = snprintf(logfile, sizeof logfile, + left = snprintf(logfilename, sizeof logfilename, "."PATHSEP"%s"PATHSEP, reldir); } #endif/*LOGMESSAGES*/ - strftime(&logfile[left], sizeof logfile - left, format, timeinfo); + strftime(&logfilename[left], sizeof logfilename - left, + format, timeinfo); } - M_MkdirEachUntil(logfile, + M_MkdirEachUntil(logfilename, M_PathParts(logdir) - 1, - M_PathParts(logfile) - 1, 0755); + M_PathParts(logfilename) - 1, 0755); - logstream = fopen(logfile, "wt"); +#ifdef __unix__ + logstream = fopen(logfilename, "w"); +#ifdef DEFAULTDIR + if (symlink(logfilename, + va("%s/"DEFAULTDIR"/latest-log.txt", logdir)) == -1) +#else + if (symlink(logfilename, va("%s/latest-log.txt", logdir)) == -1) +#endif/*DEFAULTDIR*/ + { + I_OutputMsg("Error symlinking latest-log.txt: %s\n", strerror(errno)); + } +#else/*__unix__*/ + logstream = fopen("latest-log.txt", "wt+"); +#endif/*__unix__*/ } //I_OutputMsg("I_StartupSystem() ...\n"); @@ -222,7 +240,7 @@ int main(int argc, char **argv) D_SRB2Main(); #ifdef LOGMESSAGES if (!M_CheckParm("-nolog")) - CONS_Printf("Logfile: %s\n", logfile); + CONS_Printf("Logfile: %s\n", logfilename); #endif CONS_Printf("Entering main game loop...\n"); // never return diff --git a/src/sdl/i_system.c b/src/sdl/i_system.c index 13fb25bea..355131f3b 100644 --- a/src/sdl/i_system.c +++ b/src/sdl/i_system.c @@ -2377,6 +2377,48 @@ void I_RemoveExitFunc(void (*func)()) } } +#ifndef __unix__ +static void Shittycopyerror(const char *name) +{ + I_OutputMsg( + "Error copying log file: %s: %s\n", + name, + strerror(errno) + ); +} + +static void Shittylogcopy(void) +{ + char buf[8192]; + FILE *fp; + int n; + if (fseek(logstream, 0, SEEK_SET) == -1) + { + Shittycopyerror("fseek"); + } + else if (( fp = fopen(logfilename, "wt") )) + { + while (( n = fread(buf, 1, sizeof buf, logstream) )) + { + if (fwrite(buf, 1, n, fp) < n) + { + Shittycopyerror("fwrite"); + break; + } + } + if (ferror(logstream)) + { + Shittycopyerror("fread"); + } + fclose(fp); + } + else + { + Shittycopyerror(logfilename); + } +} +#endif/*__unix__*/ + // // Closes down everything. This includes restoring the initial // palette and video mode, and removing whatever mouse, keyboard, and @@ -2395,6 +2437,9 @@ void I_ShutdownSystem(void) if (logstream) { I_OutputMsg("I_ShutdownSystem(): end of logstream.\n"); +#ifndef __unix__ + Shittylogcopy(); +#endif fclose(logstream); logstream = NULL; } From d76c4eaba8680a9484ad6b8d2c339b073ea868d3 Mon Sep 17 00:00:00 2001 From: Jaime Passos Date: Tue, 24 Dec 2019 00:14:25 -0300 Subject: [PATCH 355/746] Fix Lua HUD library crashes. --- src/lua_hudlib.c | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/src/lua_hudlib.c b/src/lua_hudlib.c index 0c0e79261..12ae1b5fc 100644 --- a/src/lua_hudlib.c +++ b/src/lua_hudlib.c @@ -1056,13 +1056,16 @@ int LUA_HudLib(lua_State *L) lua_rawseti(L, -2, 2); // HUD[2] = game rendering functions array lua_newtable(L); - lua_rawseti(L, -2, 3); // HUD[2] = scores rendering functions array + lua_rawseti(L, -2, 3); // HUD[3] = scores rendering functions array lua_newtable(L); - lua_rawseti(L, -2, 4); // HUD[3] = title rendering functions array + lua_rawseti(L, -2, 4); // HUD[4] = intermission rendering functions array lua_newtable(L); - lua_rawseti(L, -2, 5); // HUD[4] = title card rendering functions array + lua_rawseti(L, -2, 5); // HUD[5] = title rendering functions array + + lua_newtable(L); + lua_rawseti(L, -2, 6); // HUD[6] = title card rendering functions array lua_setfield(L, LUA_REGISTRYINDEX, "HUD"); luaL_newmetatable(L, META_HUDINFO); From ce3f526a5e2a427b16945dbf93c88388504e9670 Mon Sep 17 00:00:00 2001 From: Nev3r Date: Tue, 24 Dec 2019 10:25:38 +0100 Subject: [PATCH 356/746] Ignore '=' and ';' when tokenizing, for textmap reading's sake. --- src/m_misc.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/m_misc.c b/src/m_misc.c index d97383385..847f24905 100644 --- a/src/m_misc.c +++ b/src/m_misc.c @@ -1784,6 +1784,7 @@ char *M_GetToken(const char *inputString) || stringToUse[startPos] == '\n' || stringToUse[startPos] == '\0' || stringToUse[startPos] == '"' // we're treating this as whitespace because SLADE likes adding it for no good reason + || stringToUse[startPos] == '=' || stringToUse[startPos] == ';' // UDMF TEXTMAP. || inComment != 0) && startPos < stringLength) { @@ -1852,6 +1853,7 @@ char *M_GetToken(const char *inputString) && stringToUse[endPos] != '{' && stringToUse[endPos] != '}' && stringToUse[endPos] != '"' // see above + && stringToUse[endPos] != '=' && stringToUse[endPos] != ';' // UDMF TEXTMAP. && inComment == 0) && endPos < stringLength) { From 36996c8c9124310fd4a86161a0d3c8238546698f Mon Sep 17 00:00:00 2001 From: Nev3r Date: Tue, 24 Dec 2019 10:27:23 +0100 Subject: [PATCH 357/746] Treat strings inside ""s as a single token. --- src/m_misc.c | 19 +++++++++++++++++-- 1 file changed, 17 insertions(+), 2 deletions(-) diff --git a/src/m_misc.c b/src/m_misc.c index 847f24905..b12e7371d 100644 --- a/src/m_misc.c +++ b/src/m_misc.c @@ -1783,7 +1783,6 @@ char *M_GetToken(const char *inputString) || stringToUse[startPos] == '\r' || stringToUse[startPos] == '\n' || stringToUse[startPos] == '\0' - || stringToUse[startPos] == '"' // we're treating this as whitespace because SLADE likes adding it for no good reason || stringToUse[startPos] == '=' || stringToUse[startPos] == ';' // UDMF TEXTMAP. || inComment != 0) && startPos < stringLength) @@ -1842,6 +1841,23 @@ char *M_GetToken(const char *inputString) texturesToken[1] = '\0'; return texturesToken; } + // Return entire string within quotes, except without the quotes. + else if (stringToUse[startPos] == '"') + { + endPos = ++startPos; + while (stringToUse[endPos] != '"' && endPos < stringLength) + endPos++; + + texturesTokenLength = endPos++ - startPos; + // Assign the memory. Don't forget an extra byte for the end of the string! + texturesToken = (char *)Z_Malloc((texturesTokenLength+1)*sizeof(char),PU_STATIC,NULL); + // Copy the string. + M_Memcpy(texturesToken, stringToUse+startPos, (size_t)texturesTokenLength); + // Make the final character NUL. + texturesToken[texturesTokenLength] = '\0'; + + return texturesToken; + } // Now find the end of the token. This includes several additional characters that are okay to capture as one character, but not trailing at the end of another token. endPos = startPos + 1; @@ -1852,7 +1868,6 @@ char *M_GetToken(const char *inputString) && stringToUse[endPos] != ',' && stringToUse[endPos] != '{' && stringToUse[endPos] != '}' - && stringToUse[endPos] != '"' // see above && stringToUse[endPos] != '=' && stringToUse[endPos] != ';' // UDMF TEXTMAP. && inComment == 0) && endPos < stringLength) From dd01fce1a84710a772a04521378dd6945fac991e Mon Sep 17 00:00:00 2001 From: MascaraSnake Date: Tue, 24 Dec 2019 10:50:49 +0100 Subject: [PATCH 358/746] Separate P_SpawnHoopsAndRings into different functions: -Hoops are spawned in P_SpawnHoop -Item patterns are spawned in P_SpawnItemPattern -Ring-like items are spawned normally via P_SpawnMapThing -Bonus time items are spawned via P_SpawnBonusTimeItem, which is a wrapper for P_SpawnMapThing --- src/m_cheat.c | 32 ++++------- src/p_mobj.c | 152 +++++++++++++++++++++++--------------------------- src/p_mobj.h | 6 +- src/p_saveg.c | 2 +- src/p_setup.c | 43 ++++++-------- 5 files changed, 102 insertions(+), 133 deletions(-) diff --git a/src/m_cheat.c b/src/m_cheat.c index 0451a5fb3..3d1fe5b7e 100644 --- a/src/m_cheat.c +++ b/src/m_cheat.c @@ -1186,7 +1186,7 @@ void OP_NightsObjectplace(player_t *player) mt->options = (mt->options & ~(UINT16)cv_opflags.value) | (UINT16)cv_ophoopflags.value; mt->angle = (INT16)(mt->angle+(INT16)((FixedInt(FixedDiv(temp*FRACUNIT, 360*(FRACUNIT/256))))<<8)); - P_SpawnHoopsAndRings(mt, false); + P_SpawnHoop(mt); } // This places a bumper! @@ -1249,7 +1249,7 @@ void OP_NightsObjectplace(player_t *player) return; mt = OP_CreateNewMapThing(player, (UINT16)mobjinfo[MT_BLUESPHERE].doomednum, false); - P_SpawnHoopsAndRings(mt, false); + P_SpawnMapThing(mt); } // This places a ring! @@ -1260,7 +1260,7 @@ void OP_NightsObjectplace(player_t *player) return; mt = OP_CreateNewMapThing(player, (UINT16)mobjinfo[MT_RING].doomednum, false); - P_SpawnHoopsAndRings(mt, false); + P_SpawnMapThing(mt); } // This places a custom object as defined in the console cv_mapthingnum. @@ -1292,15 +1292,10 @@ void OP_NightsObjectplace(player_t *player) mt = OP_CreateNewMapThing(player, (UINT16)cv_mapthingnum.value, false); mt->angle = angle; - if (mt->type == 300 // Ring - || mt->type == 308 || mt->type == 309 // Team Rings - || mt->type == 1706 // Sphere - || (mt->type >= 600 && mt->type <= 609) // Placement patterns - || mt->type == 1705 || mt->type == 1713 // NiGHTS Hoops - || mt->type == 1800) // Mario Coin - { - P_SpawnHoopsAndRings(mt, false); - } + if (mt->type >= 600 && mt->type <= 609) // Placement patterns + P_SpawnItemPattern(mt, false); + else if (mt->type == 1705 || mt->type == 1713) // NiGHTS Hoops + P_SpawnHoop(mt); else P_SpawnMapThing(mt); } @@ -1437,15 +1432,10 @@ void OP_ObjectplaceMovement(player_t *player) return; mt = OP_CreateNewMapThing(player, (UINT16)spawnthing, ceiling); - if (mt->type == 300 // Ring - || mt->type == 308 || mt->type == 309 // Team Rings - || mt->type == 1706 // Nights Wing - || (mt->type >= 600 && mt->type <= 609) // Placement patterns - || mt->type == 1705 || mt->type == 1713 // NiGHTS Hoops - || mt->type == 1800) // Mario Coin - { - P_SpawnHoopsAndRings(mt, false); - } + if (mt->type >= 600 && mt->type <= 609) // Placement patterns + P_SpawnItemPattern(mt, false); + else if (mt->type == 1705 || mt->type == 1713) // NiGHTS Hoops + P_SpawnHoop(mt); else P_SpawnMapThing(mt); diff --git a/src/p_mobj.c b/src/p_mobj.c index f25690ed8..606c65014 100644 --- a/src/p_mobj.c +++ b/src/p_mobj.c @@ -11711,15 +11711,6 @@ static boolean P_AllowMobjSpawn(mapthing_t* mthing, mobjtype_t i) { switch (i) { - case MT_RING: - case MT_COIN: - case MT_REDTEAMRING: - case MT_BLUETEAMRING: - case MT_BLUESPHERE: - case MT_BOMBSPHERE: - case MT_NIGHTSSTAR: - case MT_NIGHTSCHIP: - return false; // These are handled in P_SpawnHoopsAndRings(). case MT_EMERALD1: case MT_EMERALD2: case MT_EMERALD3: @@ -11786,8 +11777,12 @@ static boolean P_AllowMobjSpawn(mapthing_t* mthing, mobjtype_t i) } if (metalrecording) // Metal Sonic can't use these things. - if (mobjinfo[i].flags & (MF_ENEMY|MF_BOSS) || i == MT_TOKEN || i == MT_STARPOST) + { + if ((mobjinfo[i].flags & (MF_ENEMY|MF_BOSS)) || i == MT_TOKEN || i == MT_STARPOST + || i == MT_RING || i == MT_BLUETEAMRING || i == MT_REDTEAMRING || i == MT_COIN + || i == MT_BLUESPHERE || i == MT_BOMBSPHERE || i == MT_NIGHTSCHIP || i == MT_NIGHTSSTAR) return false; + } if (!G_PlatformGametype()) { @@ -11825,7 +11820,9 @@ static boolean P_AllowMobjSpawn(mapthing_t* mthing, mobjtype_t i) if (ultimatemode) { - if (i == MT_PITY_BOX || i == MT_ELEMENTAL_BOX || i == MT_ATTRACT_BOX + if (i == MT_RING || i == MT_REDTEAMRING || i == MT_BLUETEAMRING + || i == MT_COIN || i == MT_NIGHTSSTAR || i == MT_NIGHTSCHIP + || i == MT_PITY_BOX || i == MT_ELEMENTAL_BOX || i == MT_ATTRACT_BOX || i == MT_FORCE_BOX || i == MT_ARMAGEDDON_BOX || i == MT_WHIRLWIND_BOX || i == MT_FLAMEAURA_BOX || i == MT_BUBBLEWRAP_BOX || i == MT_THUNDERCOIN_BOX || i == MT_RING_BOX || i == MT_STARPOST) @@ -11838,6 +11835,8 @@ static boolean P_AllowMobjSpawn(mapthing_t* mthing, mobjtype_t i) return true; } +#define nightsreplace ((maptol & TOL_NIGHTS) && !G_IsSpecialStage(gamemap)) + static mobjtype_t P_GetMobjtypeSubstitute(mapthing_t *mthing, mobjtype_t i) { // Altering monitor spawns via cvars @@ -11881,8 +11880,23 @@ static mobjtype_t P_GetMobjtypeSubstitute(mapthing_t *mthing, mobjtype_t i) } } - if (gametype != GT_CTF && (i == MT_RING_BLUEBOX || i == MT_RING_REDBOX)) - return MT_RING_BOX; + if (nightsreplace) + { + if (i == MT_RING || i == MT_REDTEAMRING || i == MT_BLUETEAMRING || i == MT_COIN) + return MT_NIGHTSSTAR; + + if (i == MT_BLUESPHERE) + return MT_NIGHTSCHIP; + } + + if (gametype != GT_CTF) + { + if (i == MT_BLUETEAMRING || i == MT_REDTEAMRING) + return MT_RING; + + if (i == MT_RING_BLUEBOX || i == MT_RING_REDBOX) + return MT_RING_BOX; + } if (modeattacking && i == MT_1UP_BOX) // 1UPs -->> Score TVs { @@ -12920,6 +12934,10 @@ static boolean P_SetupSpawnedMapThing(mapthing_t *mthing, mobj_t *mobj, boolean if (G_IsSpecialStage(gamemap)) P_SetMobjState(mobj, (mobj->type == MT_PUSH) ? S_GRAVWELLGREEN : S_GRAVWELLRED); break; + case MT_NIGHTSSTAR: + if (maptol & TOL_XMAS) + P_SetMobjState(mobj, mobj->info->seestate); + break; default: break; } @@ -12991,21 +13009,21 @@ static void P_SetObjectSpecial(mobj_t *mobj) // The fields of the mapthing should // already be in host byte order. // -void P_SpawnMapThing(mapthing_t *mthing) +mobj_t *P_SpawnMapThing(mapthing_t *mthing) { mobjtype_t i; - mobj_t *mobj; + mobj_t *mobj = NULL; fixed_t x, y, z; boolean doangle = true; if (!mthing->type) - return; // Ignore type-0 things as NOPs + return mobj; // Ignore type-0 things as NOPs if (mthing->type == 3328) // 3D Mode start Thing - return; + return mobj; if (!objectplacing && P_SpawnNonMobjMapThing(mthing)) - return; + return mobj; i = P_GetMobjtype(mthing->type); if (i == MT_UNKNOWN) @@ -13015,11 +13033,11 @@ void P_SpawnMapThing(mapthing_t *mthing) if (!objectplacing) { if (!P_AllowMobjSpawn(mthing, i)) - return; + return mobj; i = P_GetMobjtypeSubstitute(mthing, i); if (i == MT_NULL) // Don't spawn mobj - return; + return mobj; } // spawn it @@ -13031,7 +13049,7 @@ void P_SpawnMapThing(mapthing_t *mthing) mobj->spawnpoint = mthing; if (!P_SetupSpawnedMapThing(mthing, mobj, &doangle)) - return; + return mobj; if (doangle) mobj->angle = FixedAngle(mthing->angle<options & MTF_AMBUSH) && (mthing->options & MTF_OBJECTSPECIAL) @@ -13075,9 +13093,11 @@ void P_SpawnMapThing(mapthing_t *mthing) // Final set of not being able to draw nightsitems. if (mobj->flags & MF_NIGHTSITEM) mobj->flags2 |= MF2_DONTDRAW; + + return mobj; } -static void P_SpawnHoop(mapthing_t* mthing, fixed_t x, fixed_t y, fixed_t z, INT32 hoopsize, fixed_t sizefactor) +static void P_SpawnHoopInternal(mapthing_t *mthing, INT32 hoopsize, fixed_t sizefactor) { mobj_t *mobj = NULL; mobj_t *nextmobj = NULL; @@ -13087,8 +13107,9 @@ static void P_SpawnHoop(mapthing_t* mthing, fixed_t x, fixed_t y, fixed_t z, INT INT32 i; angle_t fa; TVector v, *res; - - z = P_GetMobjSpawnHeight(MT_HOOP, x, y, z, false); + fixed_t x = mthing->x << FRACBITS; + fixed_t y = mthing->y << FRACBITS; + fixed_t z = P_GetMobjSpawnHeight(MT_HOOP, x, y, mthing->z << FRACBITS, false); hoopcenter = P_SpawnMobj(x, y, z, MT_HOOPCENTER); hoopcenter->spawnpoint = mthing; @@ -13182,56 +13203,27 @@ static void P_SpawnHoop(mapthing_t* mthing, fixed_t x, fixed_t y, fixed_t z, INT } while (hoopsize >= 8); } -#define nightsreplace ((maptol & TOL_NIGHTS) && !G_IsSpecialStage(gamemap)) - -static void P_SpawnRingItem(mapthing_t *mthing, fixed_t x, fixed_t y, boolean bonustime) +void P_SpawnHoop(mapthing_t *mthing) { - mobjtype_t ringthing = MT_RING; - mobj_t *mobj = NULL; - fixed_t z; + if (metalrecording) + return; - // Which ringthing to use - if (mthing->type == mobjinfo[MT_BLUESPHERE].doomednum) - ringthing = (nightsreplace) ? MT_NIGHTSCHIP : MT_BLUESPHERE; - else if (mthing->type == mobjinfo[MT_BOMBSPHERE].doomednum) - ringthing = MT_BOMBSPHERE; - else - { - if (ultimatemode) - return; // No rings in Ultimate! - - if (nightsreplace) - ringthing = MT_NIGHTSSTAR; - else if (mthing->type == mobjinfo[MT_COIN].doomednum) - ringthing = MT_COIN; - else if (mthing->type == mobjinfo[MT_REDTEAMRING].doomednum) // No team rings in non-CTF - ringthing = (gametype == GT_CTF) ? MT_REDTEAMRING : MT_RING; - else if (mthing->type == mobjinfo[MT_BLUETEAMRING].doomednum) // Ditto - ringthing = (gametype == GT_CTF) ? MT_BLUETEAMRING : MT_RING; - } - - z = P_GetMapThingSpawnHeight(ringthing, mthing, x, y); - mobj = P_SpawnMobj(x, y, z, ringthing); - mobj->spawnpoint = mthing; - - if (mthing->options & MTF_OBJECTFLIP) - { - mobj->eflags |= MFE_VERTICALFLIP; - mobj->flags2 |= MF2_OBJECTFLIP; - } - - mobj->angle = FixedAngle(mthing->angle << FRACBITS); - mthing->mobj = mobj; - if (mthing->options & MTF_AMBUSH) - mobj->flags2 |= MF2_AMBUSH; - - if (bonustime && (ringthing == MT_BLUESPHERE || ringthing == MT_NIGHTSCHIP)) - P_SetMobjState(mobj, mobj->info->raisestate); - else if ((maptol & TOL_XMAS) && (ringthing == MT_NIGHTSSTAR)) - P_SetMobjState(mobj, mobj->info->seestate); + if (mthing->type == 1705) // Generic hoop + P_SpawnHoopInternal(mthing, 24, 4*FRACUNIT); + else // Customizable hoop + // For each flag add 16 fracunits to the size + // Default (0 flags) is 32 fracunits + P_SpawnHoopInternal(mthing, 8 + (4*(mthing->options & 0xF)), 4*FRACUNIT); } -static void P_SpawnItemRow(mapthing_t* mthing, fixed_t x, fixed_t y, fixed_t z, INT32 numitems, fixed_t horizontalspacing, fixed_t verticalspacing, INT16 fixedangle) +void P_SpawnBonusTimeItem(mapthing_t *mthing) +{ + mobj_t *mobj = P_SpawnMapThing(mthing); + if (mobj && (mobj->type == MT_BLUESPHERE || mobj->type == MT_NIGHTSCHIP)) + P_SetMobjState(mobj, mobj->info->raisestate); +} + +static void P_SpawnItemRow(mapthing_t *mthing, fixed_t x, fixed_t y, fixed_t z, INT32 numitems, fixed_t horizontalspacing, fixed_t verticalspacing, INT16 fixedangle) { mobjtype_t ringthing = MT_RING; mobj_t *mobj = NULL; @@ -13270,7 +13262,7 @@ static void P_SpawnItemRow(mapthing_t* mthing, fixed_t x, fixed_t y, fixed_t z, } } -static void P_SpawnItemCircle(mapthing_t* mthing, fixed_t x, fixed_t y, fixed_t z, INT32 numitems, fixed_t size, boolean bonustime) +static void P_SpawnItemCircle(mapthing_t *mthing, fixed_t x, fixed_t y, fixed_t z, INT32 numitems, fixed_t size, boolean bonustime) { mobjtype_t ringthing = MT_RING; mobj_t *mobj = NULL; @@ -13352,12 +13344,15 @@ static void P_SpawnItemCircle(mapthing_t* mthing, fixed_t x, fixed_t y, fixed_t } } -void P_SpawnHoopsAndRings(mapthing_t *mthing, boolean bonustime) +void P_SpawnItemPattern(mapthing_t *mthing, boolean bonustime) { fixed_t x = mthing->x << FRACBITS; fixed_t y = mthing->y << FRACBITS; fixed_t z = mthing->z << FRACBITS; + if (metalrecording) + return; + switch (mthing->type) { // Special placement patterns @@ -13385,17 +13380,8 @@ void P_SpawnHoopsAndRings(mapthing_t *mthing, boolean bonustime) P_SpawnItemCircle(mthing, x, y, z, numitems, size, bonustime); return; } - // Hoops - case 1705: // Generic NiGHTS hoop - P_SpawnHoop(mthing, x, y, z, 24, 4*FRACUNIT); + default: return; - case 1713: // Customizable NiGHTS hoop - // For each flag add 16 fracunits to the size - // Default (0 flags) is 32 fracunits - P_SpawnHoop(mthing, x, y, z, 8 + (4*(mthing->options & 0xF)), 4*FRACUNIT); - return; - default: // All manners of rings and coins - P_SpawnRingItem(mthing, x, y, bonustime); } } diff --git a/src/p_mobj.h b/src/p_mobj.h index 40d850f16..9b015d23c 100644 --- a/src/p_mobj.h +++ b/src/p_mobj.h @@ -456,8 +456,10 @@ void P_MovePlayerToSpawn(INT32 playernum, mapthing_t *mthing); void P_MovePlayerToStarpost(INT32 playernum); void P_AfterPlayerSpawn(INT32 playernum); -void P_SpawnMapThing(mapthing_t *mthing); -void P_SpawnHoopsAndRings(mapthing_t *mthing, boolean bonustime); +mobj_t *P_SpawnMapThing(mapthing_t *mthing); +void P_SpawnHoop(mapthing_t *mthing); +void P_SpawnBonusTimeItem(mapthing_t *mthing); +void P_SpawnItemPattern(mapthing_t *mthing, boolean bonustime); void P_SpawnHoopOfSomething(fixed_t x, fixed_t y, fixed_t z, fixed_t radius, INT32 number, mobjtype_t type, angle_t rotangle); void P_SpawnPrecipitation(void); void P_SpawnParaloop(fixed_t x, fixed_t y, fixed_t z, fixed_t radius, INT32 number, mobjtype_t type, statenum_t nstate, angle_t rotangle, boolean spawncenter); diff --git a/src/p_saveg.c b/src/p_saveg.c index c876713e4..86224d936 100644 --- a/src/p_saveg.c +++ b/src/p_saveg.c @@ -2545,7 +2545,7 @@ static thinker_t* LoadMobjThinker(actionf_p1 thinker) if (mapthings[spawnpointnum].type == 1705 || mapthings[spawnpointnum].type == 1713) // NiGHTS Hoop special case { - P_SpawnHoopsAndRings(&mapthings[spawnpointnum], false); + P_SpawnHoop(&mapthings[spawnpointnum]); return NULL; } diff --git a/src/p_setup.c b/src/p_setup.c index bc736588e..46fe118c4 100644 --- a/src/p_setup.c +++ b/src/p_setup.c @@ -765,7 +765,7 @@ static void P_LoadRawNodes(UINT8 *data) // // P_ReloadRings -// Used by NiGHTS, clears all ring/wing/etc items and respawns them +// Used by NiGHTS, clears all ring/sphere/hoop/etc items and respawns them // void P_ReloadRings(void) { @@ -812,18 +812,21 @@ void P_ReloadRings(void) { // Notice an omission? We handle hoops differently. if (mt->type == mobjinfo[MT_RING].doomednum || mt->type == mobjinfo[MT_COIN].doomednum - || mt->type == mobjinfo[MT_REDTEAMRING].doomednum || mt->type == mobjinfo[MT_BLUETEAMRING].doomednum - || mt->type == mobjinfo[MT_BLUESPHERE].doomednum || mt->type == mobjinfo[MT_BOMBSPHERE].doomednum - || (mt->type >= 600 && mt->type <= 609)) // circles and diagonals + || mt->type == mobjinfo[MT_REDTEAMRING].doomednum || mt->type == mobjinfo[MT_BLUETEAMRING].doomednum + || mt->type == mobjinfo[MT_BLUESPHERE].doomednum || mt->type == mobjinfo[MT_BOMBSPHERE].doomednum) { mt->mobj = NULL; - - P_SpawnHoopsAndRings(mt, true); + P_SpawnBonusTimeItem(mt); + } + else if (mt->type >= 600 && mt->type <= 609) // Item patterns + { + mt->mobj = NULL; + P_SpawnItemPattern(mt, true); } } for (i = 0; i < numHoops; i++) { - P_SpawnHoopsAndRings(hoopsToRespawn[i], false); + P_SpawnHoop(hoopsToRespawn[i]); } } @@ -1017,30 +1020,18 @@ static void P_LoadThings(boolean loademblems) continue; mt->mobj = NULL; - P_SpawnMapThing(mt); + + if (mt->type >= 600 && mt->type <= 609) // item patterns + P_SpawnItemPattern(mt, false); + else if (mt->type == 1705 || mt->type == 1713) // hoops + P_SpawnHoop(mt); + else // Everything else + P_SpawnMapThing(mt); } // random emeralds for hunt if (numhuntemeralds) P_SpawnEmeraldHunt(); - - if (metalrecording) // Metal Sonic gets no rings to distract him. - return; - - // Run through the list of mapthings again to spawn hoops and rings - mt = mapthings; - for (i = 0; i < nummapthings; i++, mt++) - { - if (mt->type == mobjinfo[MT_RING].doomednum || mt->type == mobjinfo[MT_COIN].doomednum - || mt->type == mobjinfo[MT_REDTEAMRING].doomednum || mt->type == mobjinfo[MT_BLUETEAMRING].doomednum - || mt->type == mobjinfo[MT_BLUESPHERE].doomednum || mt->type == mobjinfo[MT_BOMBSPHERE].doomednum - || (mt->type >= 600 && mt->type <= 609) // circles and diagonals - || mt->type == 1705 || mt->type == 1713) // hoops - { - mt->mobj = NULL; - P_SpawnHoopsAndRings(mt, false); - } - } } // Experimental groovy write function! From f2c2836301d4dc59242d09f08a5473341c4d692c Mon Sep 17 00:00:00 2001 From: James R Date: Tue, 24 Dec 2019 01:55:47 -0800 Subject: [PATCH 359/746] Overwrite an already existing symlink --- src/sdl/i_main.c | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/src/sdl/i_main.c b/src/sdl/i_main.c index af34da8d1..f798ca6cd 100644 --- a/src/sdl/i_main.c +++ b/src/sdl/i_main.c @@ -142,6 +142,7 @@ int main(int argc, char **argv) const char *reldir; int left; boolean fileabs; + const char *link; logdir = D_Home(); @@ -201,11 +202,12 @@ int main(int argc, char **argv) #ifdef __unix__ logstream = fopen(logfilename, "w"); #ifdef DEFAULTDIR - if (symlink(logfilename, - va("%s/"DEFAULTDIR"/latest-log.txt", logdir)) == -1) + link = va("%s/"DEFAULTDIR"/latest-log.txt", logdir); #else - if (symlink(logfilename, va("%s/latest-log.txt", logdir)) == -1) + link = va("%s/latest-log.txt", logdir); #endif/*DEFAULTDIR*/ + unlink(link); + if (symlink(logfilename, link) == -1) { I_OutputMsg("Error symlinking latest-log.txt: %s\n", strerror(errno)); } From b7b4945c36fb95f406a365d64f109cfc83ad4d63 Mon Sep 17 00:00:00 2001 From: James R Date: Tue, 24 Dec 2019 01:58:39 -0800 Subject: [PATCH 360/746] Correct usage of logdir --- src/sdl/i_main.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/src/sdl/i_main.c b/src/sdl/i_main.c index f798ca6cd..0de96ad97 100644 --- a/src/sdl/i_main.c +++ b/src/sdl/i_main.c @@ -202,10 +202,11 @@ int main(int argc, char **argv) #ifdef __unix__ logstream = fopen(logfilename, "w"); #ifdef DEFAULTDIR - link = va("%s/"DEFAULTDIR"/latest-log.txt", logdir); -#else - link = va("%s/latest-log.txt", logdir); + if (logdir) + link = va("%s/"DEFAULTDIR"/latest-log.txt", logdir); + else #endif/*DEFAULTDIR*/ + link = "latest-log.txt"; unlink(link); if (symlink(logfilename, link) == -1) { From 75e18610bc8f71e96bdb8314bcea8425b0a4a9b0 Mon Sep 17 00:00:00 2001 From: Nev3r Date: Tue, 24 Dec 2019 11:58:25 +0100 Subject: [PATCH 361/746] Refactor existing configuration into ZDoom-styled format. --- extras/conf/Includes/Game_SRB222.cfg | 77 + extras/conf/Includes/SRB222_common.cfg | 309 ++ extras/conf/Includes/SRB222_linedefs.cfg | 2486 ++++++++++++++++ extras/conf/Includes/SRB222_misc.cfg | 726 +++++ extras/conf/Includes/SRB222_sectors.cfg | 109 + extras/conf/Includes/SRB222_things.cfg | 3398 ++++++++++++++++++++++ extras/conf/SRB2_22Doom.cfg | 38 + extras/conf/SRB2_22UDMF.cfg | 47 + 8 files changed, 7190 insertions(+) create mode 100644 extras/conf/Includes/Game_SRB222.cfg create mode 100644 extras/conf/Includes/SRB222_common.cfg create mode 100644 extras/conf/Includes/SRB222_linedefs.cfg create mode 100644 extras/conf/Includes/SRB222_misc.cfg create mode 100644 extras/conf/Includes/SRB222_sectors.cfg create mode 100644 extras/conf/Includes/SRB222_things.cfg create mode 100644 extras/conf/SRB2_22Doom.cfg create mode 100644 extras/conf/SRB2_22UDMF.cfg diff --git a/extras/conf/Includes/Game_SRB222.cfg b/extras/conf/Includes/Game_SRB222.cfg new file mode 100644 index 000000000..3c4b11e9f --- /dev/null +++ b/extras/conf/Includes/Game_SRB222.cfg @@ -0,0 +1,77 @@ +// Default lump name for new map +defaultlumpname = "MAP01"; +//GZDB specific. Don't try to load lumps that don't exist. +basegame = 0; + +//Sky textures for vanilla maps +defaultskytextures +{ + SKY1 = "MAP01,MAP02,MAP03,MAP33,MAP50,MAP60,MAPF0,MAPM0"; + SKY2 = "MAPM7,MAPMB"; + SKY4 = "MAP04,MAP06,MAP61,MAPF6,MAPM1"; + SKY6 = "MAP05,MAP51,MAPMA"; + SKY7 = "MAPM2,MAPM5"; + SKY8 = "MAP07,MAP08,MAP09,MAP52,MAP62,MAPF1"; + SKY10 = "MAP10,MAP12,MAP53,MAP63,MAPM3"; + SKY11 = "MAP11,MAPF7"; + SKY13 = "MAP13,MAP64"; + SKY14 = "MAP14"; + SKY15 = "MAP15,MAP54"; + SKY17 = "MAP70"; + SKY20 = "MAP32,MAP55,MAP65,MAPF2,MAPF5"; + SKY21 = "MAPM4"; + SKY22 = "MAP22,MAP23,MAP25,MAP26,MAP27,MAP56,MAP66,MAPF4,MAPM6"; + SKY30 = "MAP30"; + SKY31 = "MAP31"; + SKY35 = "MAP42"; + SKY40 = "MAP41,MAP71,MAPM9"; + SKY55 = "MAPF3,MAPM8"; + SKY68 = "MAPF8"; + SKY99 = "MAP57,MAPZ0"; + SKY159 = "MAP16"; + SKY172 = "MAP40"; + SKY300 = "MAP72"; + SKY301 = "MAP73"; +} + +// Skill levels +skills +{ + 1 = "Normal"; +} + +// Skins +skins +{ + Sonic; + Tails; + Knuckles; + Amy; + Fang; + Metalsonic; +} + +// Gametypes +gametypes +{ + -1 = "Single Player"; + 0 = "Co-op"; + 1 = "Competition"; + 2 = "Race"; + 3 = "Match"; + 4 = "Team Match"; + 5 = "Tag"; + 6 = "Hide and Seek"; + 7 = "CTF"; +} + +// Texture loading options +defaultwalltexture = "GFZROCK"; +defaultfloortexture = "GFZFLR01"; +defaultceilingtexture = "F_SKY1"; + +// Default texture sets +// (these are not required, but useful for new users) +texturesets +{ +} \ No newline at end of file diff --git a/extras/conf/Includes/SRB222_common.cfg b/extras/conf/Includes/SRB222_common.cfg new file mode 100644 index 000000000..a832e6cef --- /dev/null +++ b/extras/conf/Includes/SRB222_common.cfg @@ -0,0 +1,309 @@ +common +{ + // Some common settings + + + + // Default testing parameters + testparameters = "-file \"%AP\" \"%F\" -warp %L"; + testshortpaths = true; + + // Action special help (mxd) + actionspecialhelp = "https://wiki.srb2.org/wiki/Linedef_type_%K"; + + // Default nodebuilder configurations + defaultsavecompiler = "zennode_normal"; + defaulttestcompiler = "zennode_fast"; + + // Generalized actions + generalizedlinedefs = false; + generalizedsectors = true; + + mixtexturesflats = true; + defaulttexturescale = 1.0f; + defaultflatscale = 1.0f; + scaledtextureoffsets = true; + + // Thing number for start position in 3D Mode + start3dmode = 3328; + + // Texture sources + textures + { + include("SRB222_misc.cfg", "textures"); + } + + // Patch sources + patches + { + include("SRB222_misc.cfg", "patches"); + } + + // Sprite sources + sprites + { + include("SRB222_misc.cfg", "sprites"); + } + + // Flat sources + flats + { + include("SRB222_misc.cfg", "flats"); + } +} + +mapformat_doom +{ + // The format interface handles the map data format - DoomMapSetIO for SRB2DB2, SRB2MapSetIO for Zone Builder + formatinterface = "SRB2MapSetIO"; + + /* + GAME DETECT PATTERN + Used to guess the game for which a WAD file is made. + + 1 = One of these lumps must exist + 2 = None of these lumps must exist + 3 = All of these lumps must exist + */ + + gamedetect + { + EXTENDED = 2; + + + BEHAVIOR = 2; + + E#M# = 2; + + MAP?? = 1; + } + + /* + MAP LUMP NAMES + Map lumps are loaded with the map as long as they are right after each other. When the editor + meets a lump which is not defined in this list it will ignore the map if not satisfied. + The order of items defines the order in which lumps will be written to WAD file on save. + To indicate the map header lump, use ~MAP + + Legenda: + required = Lump is required to exist. + blindcopy = Lump will be copied along with the map blindly. (usefull for lumps Doom Builder doesn't use) + nodebuild = The nodebuilder generates this lump. + allowempty = The nodebuilder is allowed to leave this lump empty. + script = This lump is a text-based script. Specify the filename of the script configuration to use. + */ + + maplumpnames + { + include("SRB222_misc.cfg", "doommaplumpnames"); + } + + // When this is set to true, sectors with the same tag will light up when a line is highlighted + linetagindicatesectors = true; + + // Special linedefs + include("SRB222_misc.cfg", "speciallinedefs"); + + // Default flags for first new thing (As far as 2.2 goes, they're empty just like in 2.1) + defaultthingflags + { + } + + // DEFAULT SECTOR BRIGHTNESS LEVELS + sectorbrightness + { + include("SRB222_misc.cfg", "sectorbrightness"); + } + + // SECTOR TYPES----------------------------------------------------------------- + sectortypes + { + include("SRB222_sectors.cfg", "sectortypes"); + } + + // GENERALISED SECTOR TYPES----------------------------------------------------------------- + gen_sectortypes + { + include("SRB222_sectors.cfg", "gen_sectortypes"); + } + + // LINEDEF FLAGS + linedefflags + { + include("SRB222_misc.cfg", "linedefflags"); + } + + // Linedef flags UDMF translation table + // This is needed for copy/paste and prefabs to work properly + // When the UDMF field name is prefixed with ! it is inverted + linedefflagstranslation + { + include("SRB222_misc.cfg", "linedefflagstranslation"); + } + + // LINEDEF ACTIVATIONS + linedefactivations + { + } + + // LINEDEF TYPES + linedeftypes + { + include("SRB222_linedefs.cfg", "doom"); + } + + // THING FLAGS + thingflags + { + include("SRB222_misc.cfg", "thingflags"); + } + + // Thing flags UDMF translation table + // This is needed for copy/paste and prefabs to work properly + // When the UDMF field name is prefixed with ! it is inverted + thingflagstranslation + { + include("SRB222_misc.cfg", "thingflagstranslation"); + } + + // THING FLAGS ERROR MASK + // Mask for the thing flags which indicates the options + // that make the same thing appear in the same modes + thingflagsmask1 = 7; // 1 + 2 + 4 + thingflagsmask2 = 0; +} + +mapformat_udmf +{ + // The format interface handles the map data format + formatinterface = "UniversalMapSetIO"; + + // Enables support for long (> 8 chars) texture names + // WARNING: this should only be enabled for UDMF game configurations! + // WARNING: enabling this will make maps incompatible with Doom Builder 2 and can lead to problems in Slade 3! + longtexturenames = false; + + // Default nodebuilder configurations + defaultsavecompiler = "zdbsp_udmf_normal"; + defaulttestcompiler = "zdbsp_udmf_fast"; + + engine = "srb2"; // override that so that DB2 uses the correct namespace + + maplumpnames + { + include("UDMF_misc.cfg", "udmfmaplumpnames_begin"); + include("SRB222_misc.cfg", "udmfmaplumpnames"); + include("UDMF_misc.cfg", "udmfmaplumpnames_end"); + } + + universalfields + { +// include("SRB222_misc.cfg", "universalfields"); + } + + // When this is set to true, sectors with the same tag will light up when a line is highlighted + linetagindicatesectors = false; + + // Special linedefs + include("SRB222_misc.cfg", "speciallinedefs_udmf"); + + // Default flags for first new thing (As far as 2.2 goes, they're empty just like in 2.1) + defaultthingflags + { + } + + // Generalized actions + generalizedlinedefs = false; + + // SECTOR FLAGS + sectorflags + { +// include("SRB222_misc.cfg", "sectorflags"); + } + + // DEFAULT SECTOR BRIGHTNESS LEVELS + sectorbrightness + { + include("SRB222_misc.cfg", "sectorbrightness"); + } + + // SECTOR TYPES + sectortypes + { + include("SRB222_sectors.cfg", "sectortypes"); + } + + // SECTOR RENSERSTYLES +/* sectorrenderstyles + { + include("SRB222_misc.cfg", "sectorrenderstyles"); + }*/ + + // LINEDEF FLAGS + linedefflags + { + include("SRB222_misc.cfg", "linedefflags_udmf"); + } + + // LINEDEF ACTIVATIONS + linedefactivations + { + include("SRB222_misc.cfg", "linedefactivations_udmf"); + } + + linedefflagstranslation + { + } + + + // LINEDEF RENSERSTYLES + linedefrenderstyles + { + include("SRB222_misc.cfg", "linedefrenderstyles"); + } + + //SIDEDEF FLAGS +/* sidedefflags + { + include("UDMF_misc.cfg", "sidedefflags"); + }*/ + + // THING FLAGS + thingflags + { + include("SRB222_misc.cfg", "thingflags_udmf"); + } + + // Thing flags UDMF translation table + // This is needed for copy/paste and prefabs to work properly + // When the UDMF field name is prefixed with ! it is inverted + thingflagstranslation + { + include("SRB222_misc.cfg", "thingflagstranslation"); + } + + // THING RENSERSTYLES +/* thingrenderstyles + { + include("SRB222_misc.cfg", "thingrenderstyles"); + }*/ + + // How to compare thing flags (for the stuck things error checker) +/* thingflagscompare + { + include("UDMF_misc.cfg", "thingflagscompare"); + }*/ + + //mxd. Thing flags UDMF translation table + // This is needed for copy/paste and prefabs to work properly + // When the UDMF field name is prefixed with ! it is inverted + thingflagstranslation + { + } + + // LINEDEF TYPES + linedeftypes + { + include("SRB222_linedefs.cfg", "udmf"); + } +} \ No newline at end of file diff --git a/extras/conf/Includes/SRB222_linedefs.cfg b/extras/conf/Includes/SRB222_linedefs.cfg new file mode 100644 index 000000000..8bc761dfe --- /dev/null +++ b/extras/conf/Includes/SRB222_linedefs.cfg @@ -0,0 +1,2486 @@ +doom +{ + misc + { + title = "Miscellaneous"; + + 0 + { + title = "None"; + prefix = "(0)"; + } + + 1 + { + title = "Per-Sector Gravity"; + prefix = "(1)"; + flags64text = "[6] Flip in reverse gravity"; + } + + 5 + { + title = "Camera Scanner"; + prefix = "(5)"; + } + + 7 + { + title = "Sector Flat Alignment"; + prefix = "(7)"; + flags2048text = "[11] Don't align floor"; + flags4096text = "[12] Don't align ceiling"; + flags8192text = "[13] Use texture offsets"; + } + + 10 + { + title = "Culling Plane"; + prefix = "(10)"; + flags64text = "[6] Cull only while in sector"; + } + + 13 + { + title = "Heat Wave Effect"; + prefix = "(13)"; + } + + 40 + { + title = "Visual Portal Between Tagged Linedefs"; + prefix = "(40)"; + } + + 41 + { + title = "Horizon Effect"; + prefix = "(41)"; + } + + 50 + { + title = "Instantly Lower Floor on Level Load"; + prefix = "(50)"; + } + + 51 + { + title = "Instantly Raise Ceiling on Level Load"; + prefix = "(51)"; + } + + 63 + { + title = "Fake Floor/Ceiling Planes"; + prefix = "(63)"; + } + + 540 + { + title = "Floor Friction"; + prefix = "(540)"; + } + } + + parameters + { + title = "Parameters"; + + 2 + { + title = "Custom Exit"; + prefix = "(2)"; + flags2text = "[1] Check emeralds"; + flags64text = "[6] Skip score tally"; + } + + 3 + { + title = "Zoom Tube Parameters"; + prefix = "(3)"; + flags512text = "[9] Ignore player direction"; + } + + 4 + { + title = "Speed Pad Parameters"; + prefix = "(4)"; + flags512text = "[9] No teleport to center"; + flags1024text = "[10] Force spinning frames"; + } + + 8 + { + title = "Special Sector Properties"; + prefix = "(8)"; + flags32text = "[5] Invert precipitation"; + flags64text = "[6] Touch only ceiling"; + flags128text = "[7] Allow opposite gravity"; + flags256text = "[8] Touch sector edge"; + flags512text = "[9] Touch floor or ceiling"; + } + + 9 + { + title = "Chain Parameters"; + prefix = "(9)"; + flags32text = "[5] Swing instead of spin"; + flags64text = "[6] Player-turnable chain"; + flags128text = "[7] Make chain from maces"; + flags256text = "[8] Spawn mace at origin"; + flags512text = "[9] Don't clip inside ground"; + flags1024text = "[10] No distance check"; + } + + 11 + { + title = "Rope Hang Parameters"; + prefix = "(11)"; + flags32text = "[5] Don't loop"; + flags64text = "[6] Static"; + } + + 12 + { + title = "Rock Spawner Parameters"; + prefix = "(12)"; + flags64text = "[6] Randomize speed"; + } + + 14 + { + title = "Bustable Block Parameters"; + prefix = "(14)"; + flags32text = "[5] Particles launch from center"; + } + + 15 + { + title = "Fan Particle Spawner Parameters"; + prefix = "(15)"; + } + + 16 + { + title = "Minecart Parameters"; + prefix = "(16)"; + } + + 64 + { + title = "Continuously Appearing/Disappearing FOF"; + prefix = "(64)"; + flags2text = "[1] Use control sector tag"; + flags64text = "[6] No sound effect"; + } + + 65 + { + title = "Bridge Thinker "; + prefix = "(65)"; + } + } + + polyobject + { + title = "PolyObject"; + + 20 + { + title = "First Line"; + prefix = "(20)"; + } + + 21 + { + title = "Explicitly Include Line "; + prefix = "(21)"; + } + + 22 + { + title = "Parameters"; + prefix = "(22)"; + flags64text = "[6] Trigger linedef executor"; + flags128text = "[7] Intangible"; + flags256text = "[8] Stopped by pushables"; + flags512text = "[9] Render flats"; + } + + 30 + { + title = "Waving Flag"; + prefix = "(30)"; + } + + 31 + { + title = "Displacement by Front Sector"; + prefix = "(31)"; + } + + 32 + { + title = "Angular Displacement by Front Sector"; + prefix = "(32)"; + flags8text = "[3] Set delay by backside sector"; + flags64text = "[6] Don't turn players"; + flags512text = "[9] Turn all objects"; + } + } + + planemove + { + title = "Plane Movement"; + + 52 + { + title = "Continuously Falling Sector"; + prefix = "(52)"; + flags64text = "[6] Continuously rising"; + } + + 53 + { + title = "Continuous Floor/Ceiling Mover"; + prefix = "(53)"; + } + + 54 + { + title = "Continuous Floor Mover"; + prefix = "(54)"; + } + + 55 + { + title = "Continuous Ceiling Mover"; + prefix = "(55)"; + } + + 56 + { + title = "Continuous Two-Speed Floor/Ceiling Mover"; + prefix = "(56)"; + } + + 57 + { + title = "Continuous Two-Speed Floor Mover"; + prefix = "(57)"; + } + + 58 + { + title = "Continuous Two-Speed Ceiling Mover"; + prefix = "(58)"; + } + + 59 + { + title = "Activate Moving Platform"; + prefix = "(59)"; + flags64text = "[6] Move upwards at start"; + } + + 60 + { + title = "Activate Moving Platform (Adjustable Speed)"; + prefix = "(60)"; + flags64text = "[6] Move upwards at start"; + } + + 61 + { + title = "Crusher (Ceiling to Floor)"; + prefix = "(61)"; + flags512text = "[9] Double, constant speed"; + } + + 62 + { + title = "Crusher (Floor to Ceiling)"; + prefix = "(62)"; + flags512text = "[9] Double, constant speed"; + } + + 66 + { + title = "Move Floor by Displacement"; + prefix = "(66)"; + flags64text = "[6] Inverse movement"; + } + + 67 + { + title = "Move Ceiling by Displacement"; + prefix = "(67)"; + flags64text = "[6] Inverse movement"; + } + + 68 + { + title = "Move Floor and Ceiling by Displacement"; + prefix = "(68)"; + flags64text = "[6] Inverse movement"; + } + } + + fofsolid + { + title = "FOF (solid)"; + + 100 + { + title = "Solid, Opaque"; + prefix = "(100)"; + flags8text = "[3] Slope skew sides"; + flags32text = "[5] Only block player"; + flags128text = "[7] Only block non-players"; + 3dfloor = true; + 3dfloorflags = "19F"; + } + + 101 + { + title = "Solid, Opaque, No Shadow"; + prefix = "(101)"; + flags8text = "[3] Slope skew sides"; + flags32text = "[5] Only block player"; + flags128text = "[7] Only block non-players"; + 3dfloor = true; + 3dfloorflags = "1DF"; + } + + 102 + { + title = "Solid, Translucent"; + prefix = "(102)"; + flags8text = "[3] Slope skew sides"; + flags32text = "[5] Only block player"; + flags64text = "[6] Render insides"; + flags128text = "[7] Only block non-players"; + 3dfloor = true; + 3dfloorflags = "195F"; + flags643dfloorflagsadd = "7C80"; + } + + 103 + { + title = "Solid, Sides Only"; + prefix = "(103)"; + flags8text = "[3] Slope skew sides"; + flags32text = "[5] Only block player"; + flags128text = "[7] Only block non-players"; + 3dfloor = true; + 3dfloorflags = "1CF"; + } + + 104 + { + title = "Solid, No Sides"; + prefix = "(104)"; + flags32text = "[5] Only block player"; + flags64text = "[6] Cast shadow"; + flags128text = "[7] Only block non-players"; + 3dfloor = true; + 3dfloorflags = "1D7"; + flags643dfloorflagsremove = "40"; + } + + 105 + { + title = "Solid, Invisible"; + prefix = "(105)"; + flags32text = "[5] Only block player"; + flags128text = "[7] Only block non-players"; + 3dfloor = true; + 3dfloorflags = "47"; + } + + 140 + { + title = "Intangible from Bottom, Opaque"; + prefix = "(140)"; + flags8text = "[3] Slope skew sides"; + flags32text = "[5] Only block player"; + flags64text = "[6] Don't cast shadow"; + flags128text = "[7] Only block non-players"; + 3dfloor = true; + 3dfloorflags = "200841F"; + flags643dfloorflagsadd = "40"; + } + + 141 + { + title = "Intangible from Bottom, Translucent"; + prefix = "(141)"; + flags8text = "[3] Slope skew sides"; + flags32text = "[5] Only block player"; + flags64text = "[6] Don't cast shadow"; + flags128text = "[7] Render insides/block non-plr"; + 3dfloor = true; + 3dfloorflags = "200191F"; + flags1283dfloorflagsadd = "7C80"; + flags643dfloorflagsadd = "40"; + } + + 142 + { + title = "Intangible from Bottom, Translucent, No Sides"; + prefix = "(142)"; + flags32text = "[5] Only block player"; + flags64text = "[6] Don't cast shadow"; + flags128text = "[7] Render insides/block non-plr"; + 3dfloor = true; + 3dfloorflags = "2001917"; + flags1283dfloorflagsadd = "7C80"; + flags643dfloorflagsadd = "40"; + } + + 143 + { + title = "Intangible from Top, Opaque"; + prefix = "(143)"; + flags8text = "[3] Slope skew sides"; + flags32text = "[5] Only block player"; + flags64text = "[6] Don't cast shadow"; + flags128text = "[7] Only block non-players"; + 3dfloor = true; + 3dfloorflags = "400841F"; + flags643dfloorflagsadd = "40"; + } + + 144 + { + title = "Intangible from Top, Translucent"; + prefix = "(144)"; + flags8text = "[3] Slope skew sides"; + flags32text = "[5] Only block player"; + flags64text = "[6] Don't cast shadow"; + flags128text = "[7] Render insides/block non-plr"; + 3dfloor = true; + 3dfloorflags = "400191F"; + flags1283dfloorflagsadd = "7C80"; + flags643dfloorflagsadd = "40"; + } + + 145 + { + title = "Intangible from Top, Translucent, No Sides"; + prefix = "(145)"; + flags32text = "[5] Only block player"; + flags64text = "[6] Don't cast shadow"; + flags128text = "[7] Render insides/block non-plr"; + 3dfloor = true; + 3dfloorflags = "4001917"; + flags1283dfloorflagsadd = "7C80"; + flags643dfloorflagsadd = "40"; + } + + 146 + { + title = "Only Tangible from Sides"; + prefix = "(146)"; + flags8text = "[3] Slope skew sides"; + flags32text = "[5] Only block player"; + flags128text = "[7] Only block non-players"; + 3dfloor = true; + 3dfloorflags = "600800F"; + } + } + + fofintangible + { + title = "FOF (intangible)"; + + 120 + { + title = "Water, Opaque"; + prefix = "(120)"; + flags8text = "[3] Slope skew sides"; + flags64text = "[6] Use two light levels"; + flags512text = "[9] Use target light level"; + flags1024text = "[10] Ripple effect"; + 3dfloor = true; + 3dfloorflags = "8F39"; + flags643dfloorflagsadd = "20000"; + flags5123dfloorflagsadd = "80000000"; + flags10243dfloorflagsadd = "40000000"; + } + + 121 + { + title = "Water, Translucent"; + prefix = "(121)"; + flags8text = "[3] Slope skew sides"; + flags64text = "[6] Use two light levels"; + flags512text = "[9] Use target light level"; + flags1024text = "[10] Ripple effect"; + 3dfloor = true; + 3dfloorflags = "9F39"; + flags643dfloorflagsadd = "20000"; + flags5123dfloorflagsadd = "80000000"; + flags10243dfloorflagsadd = "40000000"; + } + + 122 + { + title = "Water, Opaque, No Sides"; + prefix = "(122)"; + flags64text = "[6] Use two light levels"; + flags512text = "[9] Use target light level"; + flags1024text = "[10] Ripple effect"; + 3dfloor = true; + 3dfloorflags = "F31"; + flags643dfloorflagsadd = "20000"; + flags5123dfloorflagsadd = "80000000"; + flags10243dfloorflagsadd = "40000000"; + } + + 123 + { + title = "Water, Translucent, No Sides"; + prefix = "(123)"; + flags64text = "[6] Use two light levels"; + flags512text = "[9] Use target light level"; + flags1024text = "[10] Ripple effect"; + 3dfloor = true; + 3dfloorflags = "1F31"; + flags643dfloorflagsadd = "20000"; + flags5123dfloorflagsadd = "80000000"; + flags10243dfloorflagsadd = "40000000"; + } + + 124 + { + title = "Goo Water, Translucent"; + prefix = "(124)"; + flags8text = "[3] Slope skew sides"; + flags64text = "[6] Use two light levels"; + flags512text = "[9] Use target light level"; + flags1024text = "[10] Ripple effect"; + 3dfloor = true; + 3dfloorflags = "209F39"; + flags643dfloorflagsadd = "20000"; + flags5123dfloorflagsadd = "80000000"; + flags10243dfloorflagsadd = "40000000"; + } + + 125 + { + title = "Goo Water, Translucent, No Sides"; + prefix = "(125)"; + flags8text = "[3] Slope skew sides"; + flags64text = "[6] Use two light levels"; + flags512text = "[9] Use target light level"; + flags1024text = "[10] Ripple effect"; + 3dfloor = true; + 3dfloorflags = "201F31"; + flags643dfloorflagsadd = "20000"; + flags5123dfloorflagsadd = "80000000"; + flags10243dfloorflagsadd = "40000000"; + } + + 220 + { + title = "Intangible, Opaque"; + prefix = "(220)"; + flags8text = "[3] Slope skew sides"; + 3dfloor = true; + 3dfloorflags = "8F19"; + } + + 221 + { + title = "Intangible, Translucent"; + prefix = "(221)"; + flags8text = "[3] Slope skew sides"; + flags64text = "[6] Cast shadow"; + 3dfloor = true; + 3dfloorflags = "1B59"; + flags643dfloorflagsremove = "40"; + } + + 222 + { + title = "Intangible, Sides Only"; + prefix = "(222)"; + flags8text = "[3] Slope skew sides"; + flags64text = "[6] Cast shadow"; + 3dfloor = true; + 3dfloorflags = "8249"; + flags643dfloorflagsremove = "240"; + } + + 223 + { + title = "Intangible, Invisible"; + prefix = "(223)"; + 3dfloor = true; + 3dfloorflags = "41"; + } + } + + fofmoving + { + title = "FOF (moving)"; + + 150 + { + title = "Air Bobbing"; + prefix = "(150)"; + flags8text = "[3] Slope skew sides"; + flags32text = "[5] Only block player"; + flags64text = "[6] Spindash to move"; + flags128text = "[7] Only block non-players"; + 3dfloor = true; + 3dfloorflags = "19F"; + } + + 151 + { + title = "Air Bobbing (Adjustable)"; + prefix = "(151)"; + flags8text = "[3] Slope skew sides"; + flags32text = "[5] Only block player"; + flags64text = "[6] Spindash to move"; + flags128text = "[7] Only block non-players"; + 3dfloor = true; + 3dfloorflags = "19F"; + } + + 152 + { + title = "Reverse Air Bobbing (Adjustable)"; + prefix = "(152)"; + flags8text = "[3] Slope skew sides"; + flags32text = "[5] Only block player"; + flags64text = "[6] Spindash to move"; + flags128text = "[7] Only block non-players"; + 3dfloor = true; + 3dfloorflags = "19F"; + } + + 160 + { + title = "Floating, Bobbing"; + prefix = "(160)"; + flags8text = "[3] Slope skew sides"; + flags32text = "[5] Only block player"; + flags128text = "[7] Only block non-players"; + 3dfloor = true; + 3dfloorflags = "4019F"; + } + + 190 + { + title = "Rising Platform, Solid, Opaque"; + prefix = "(190)"; + flags2text = "[1] Sink when stepped on"; + flags8text = "[3] Slope skew sides"; + flags32text = "[5] Only block player"; + flags64text = "[6] Spindash to move"; + flags128text = "[7] Only block non-players"; + 3dfloor = true; + 3dfloorflags = "19F"; + } + + 191 + { + title = "Rising Platform, Solid, Opaque, No Shadow"; + prefix = "(191)"; + flags2text = "[1] Sink when stepped on"; + flags8text = "[3] Slope skew sides"; + flags32text = "[5] Only block player"; + flags64text = "[6] Spindash to move"; + flags128text = "[7] Only block non-players"; + 3dfloor = true; + 3dfloorflags = "1DF"; + } + + 192 + { + title = "Rising Platform, Solid, Translucent"; + prefix = "(192)"; + flags2text = "[1] Sink when stepped on"; + flags8text = "[3] Slope skew sides"; + flags32text = "[5] Only block player"; + flags64text = "[6] Spindash to move"; + flags128text = "[7] Only block non-players"; + 3dfloor = true; + 3dfloorflags = "195F"; + } + + 193 + { + title = "Rising Platform, Solid, Invisible"; + prefix = "(193)"; + flags2text = "[1] Sink when stepped on"; + flags8text = "[3] Slope skew sides"; + flags32text = "[5] Only block player"; + flags64text = "[6] Spindash to move"; + flags128text = "[7] Only block non-players"; + 3dfloor = true; + 3dfloorflags = "47"; + } + + 194 + { + title = "Rising Platform, Intangible from Bottom, Opaque"; + prefix = "(194)"; + flags2text = "[1] Sink when stepped on"; + flags8text = "[3] Slope skew sides"; + flags32text = "[5] Only block player"; + flags64text = "[6] Spindash, no shadow"; + flags128text = "[7] Only block non-players"; + 3dfloor = true; + 3dfloorflags = "200841F"; + flags643dfloorflagsadd = "40"; + } + + 195 + { + title = "Rising Platform, Intangible from Bottom, Translucent"; + prefix = "(195)"; + flags2text = "[1] Sink when stepped on"; + flags8text = "[3] Slope skew sides"; + flags32text = "[5] Only block player"; + flags64text = "[6] Spindash, no shadow"; + flags128text = "[7] Only block non-players"; + 3dfloor = true; + 3dfloorflags = "2009D1F"; + flags643dfloorflagsadd = "40"; + } + } + + fofcrumbling + { + title = "FOF (crumbling)"; + + 170 + { + title = "Crumbling, Respawn"; + prefix = "(170)"; + flags8text = "[3] Slope skew sides"; + flags32text = "[5] Only block player"; + flags128text = "[7] Only block non-players"; + 3dfloor = true; + 3dfloorflags = "10019F"; + } + + 171 + { + title = "Crumbling, No Respawn"; + prefix = "(171)"; + flags8text = "[3] Slope skew sides"; + flags32text = "[5] Only block player"; + flags128text = "[7] Only block non-players"; + 3dfloor = true; + 3dfloorflags = "80019F"; + } + + 172 + { + title = "Crumbling, Respawn, Intangible from Bottom"; + prefix = "(172)"; + flags8text = "[3] Slope skew sides"; + flags32text = "[5] Only block player"; + flags64text = "[6] Don't cast shadow"; + flags128text = "[7] Only block non-players"; + 3dfloor = true; + 3dfloorflags = "210841F"; + flags643dfloorflagsadd = "40"; + } + + 173 + { + title = "Crumbling, No Respawn, Intangible from Bottom"; + prefix = "(173)"; + flags8text = "[3] Slope skew sides"; + flags32text = "[5] Only block player"; + flags64text = "[6] Don't cast shadow"; + flags128text = "[7] Only block non-players"; + 3dfloor = true; + 3dfloorflags = "218841F"; + flags643dfloorflagsadd = "40"; + } + + 174 + { + title = "Crumbling, Respawn, Int. from Bottom, Translucent"; + prefix = "(174)"; + flags8text = "[3] Slope skew sides"; + flags32text = "[5] Only block player"; + flags64text = "[6] Don't cast shadow"; + flags128text = "[7] Only block non-players"; + 3dfloor = true; + 3dfloorflags = "210959F"; + flags643dfloorflagsadd = "40"; + } + + 175 + { + title = "Crumbling, No Respawn, Int. from Bottom, Translucent"; + prefix = "(175)"; + flags8text = "[3] Slope skew sides"; + flags32text = "[5] Only block player"; + flags64text = "[6] Don't cast shadow"; + flags128text = "[7] Only block non-players"; + 3dfloor = true; + 3dfloorflags = "218959F"; + flags643dfloorflagsadd = "40"; + } + + 176 + { + title = "Crumbling, Respawn, Floating, Bobbing"; + prefix = "(176)"; + flags8text = "[3] Slope skew sides"; + flags32text = "[5] Only block player"; + flags64text = "[6] Spindash to move"; + flags128text = "[7] Only block non-players"; + 3dfloor = true; + 3dfloorflags = "14019F"; + } + + 177 + { + title = "Crumbling, No Respawn, Floating, Bobbing"; + prefix = "(177)"; + flags8text = "[3] Slope skew sides"; + flags32text = "[5] Only block player"; + flags64text = "[6] Spindash to move"; + flags128text = "[7] Only block non-players"; + 3dfloor = true; + 3dfloorflags = "1C019F"; + } + + 178 + { + title = "Crumbling, Respawn, Floating"; + prefix = "(178)"; + flags8text = "[3] Slope skew sides"; + flags32text = "[5] Only block player"; + flags128text = "[7] Only block non-players"; + 3dfloor = true; + 3dfloorflags = "14019F"; + } + + 179 + { + title = "Crumbling, No Respawn, Floating"; + prefix = "(179)"; + flags8text = "[3] Slope skew sides"; + flags32text = "[5] Only block player"; + flags128text = "[7] Only block non-players"; + 3dfloor = true; + 3dfloorflags = "1C019F"; + } + + 180 + { + title = "Crumbling, Respawn, Air Bobbing"; + prefix = "(180)"; + flags8text = "[3] Slope skew sides"; + flags32text = "[5] Only block player"; + flags64text = "[6] Spindash to move"; + flags128text = "[7] Only block non-players"; + 3dfloor = true; + 3dfloorflags = "10019F"; + } + } + + fofspecial + { + title = "FOF (special)"; + + 200 + { + title = "Light Block"; + prefix = "(200)"; + 3dfloor = true; + 3dfloorflags = "20201"; + } + + 201 + { + title = "Half Light Block"; + prefix = "(201)"; + 3dfloor = true; + 3dfloorflags = "201"; + } + + 202 + { + title = "Fog Block"; + prefix = "(202)"; + 3dfloor = true; + 3dfloorflags = "3EF19"; + } + + 250 + { + title = "Mario Block"; + prefix = "(250)"; + flags32text = "[5] Invisible block"; + flags64text = "[6] Brick block"; + 3dfloor = true; + 3dfloorflags = "40019F"; + } + + 251 + { + title = "Thwomp Block"; + prefix = "(251)"; + flags512text = "[9] Custom crushing sound"; + flags1024text = "[10] Custom speed"; + 3dfloor = true; + 3dfloorflags = "19F"; + } + + 252 + { + title = "Shatter Block"; + prefix = "(252)"; + flags8text = "[3] Slope skew sides"; + flags64text = "[6] Shatter only from below"; + flags512text = "[9] Shattered by pushables"; + flags1024text = "[10] Trigger linedef executor"; + 3dfloor = true; + 3dfloorflags = "8800019"; + flags643dfloorflagsadd = "200006"; + } + + 253 + { + title = "Shatter Block, Translucent"; + prefix = "(253)"; + flags8text = "[3] Slope skew sides"; + flags512text = "[9] Shattered by pushables"; + flags1024text = "[10] Trigger linedef executor"; + 3dfloor = true; + 3dfloorflags = "8801019"; + } + + 254 + { + title = "Bustable Block"; + prefix = "(254)"; + flags8text = "[3] Slope skew sides"; + flags64text = "[6] Strong characters only"; + flags128text = "[7] Only block non-players"; + flags512text = "[9] Shattered by pushables"; + flags1024text = "[10] Trigger linedef executor"; + 3dfloor = true; + 3dfloorflags = "80001F"; + flags643dfloorflagsadd = "20000000"; + } + + 255 + { + title = "Spin-Bustable Block"; + prefix = "(255)"; + flags8text = "[3] Slope skew sides"; + flags32text = "[5] Only block player"; + flags128text = "[7] Only block non-players"; + flags512text = "[9] Shattered by pushables"; + flags1024text = "[10] Trigger linedef executor"; + 3dfloor = true; + 3dfloorflags = "1080001F"; + } + + 256 + { + title = "Spin-Bustable Block, Translucent"; + prefix = "(256)"; + flags8text = "[3] Slope skew sides"; + flags32text = "[5] Only block player"; + flags128text = "[7] Only block non-players"; + flags512text = "[9] Shattered by pushables"; + flags1024text = "[10] Trigger linedef executor"; + 3dfloor = true; + 3dfloorflags = "1080101F"; + } + + 257 + { + title = "Quicksand"; + prefix = "(257)"; + flags8text = "[3] Slope skew sides"; + flags1024text = "[10] Ripple effect"; + 3dfloor = true; + 3dfloorflags = "1008219"; + flags10243dfloorflagsadd = "40000000"; + } + + 258 + { + title = "Laser"; + prefix = "(258)"; + flags8text = "[3] Slope skew sides"; + flags32text = "[5] Don't damage bosses"; + 3dfloor = true; + 3dfloorflags = "959"; + } + + 259 + { + title = "Custom FOF"; + prefix = "(259)"; + flags32text = "[5] Only block player"; + flags128text = "[7] Only block non-players"; + flags512text = "[9] Shattered by pushables"; + flags1024text = "[10] Trigger linedef executor"; + 3dfloor = true; + 3dfloorcustom = true; + } + } + + linedeftrigger + { + title = "Linedef Executor Trigger"; + + 300 + { + title = "Continuous"; + prefix = "(300)"; + } + + 301 + { + title = "Each Time"; + prefix = "(301)"; + flags16384text = "[14] Also trigger on exit"; + } + + 302 + { + title = "Once"; + prefix = "(302)"; + } + + 303 + { + title = "Ring Count - Continuous"; + prefix = "(303)"; + flags2text = "[1] Rings greater or equal"; + flags64text = "[6] Rings less or equal"; + flags512text = "[9] Consider all players"; + } + + 304 + { + title = "Ring Count - Once"; + prefix = "(304)"; + flags2text = "[1] Rings greater or equal"; + flags64text = "[6] Rings less or equal"; + flags512text = "[9] Consider all players"; + } + + 305 + { + title = "Character Ability - Continuous"; + prefix = "(305)"; + } + + 306 + { + title = "Character Ability - Each Time"; + prefix = "(306)"; + flags16384text = "[14] Also trigger on exit"; + } + + 307 + { + title = "Character Ability - Once"; + prefix = "(307)"; + } + + 308 + { + title = "Race Only - Once"; + prefix = "(308)"; + } + + 309 + { + title = "CTF Red Team - Continuous"; + prefix = "(309)"; + } + + 310 + { + title = "CTF Red Team - Each Time"; + prefix = "(310)"; + flags16384text = "[14] Also trigger on exit"; + } + + 311 + { + title = "CTF Blue Team - Continuous"; + prefix = "(311)"; + } + + 312 + { + title = "CTF Blue Team - Each Time"; + prefix = "(312)"; + flags16384text = "[14] Also trigger on exit"; + } + + 313 + { + title = "No More Enemies - Once"; + prefix = "(313)"; + } + + 314 + { + title = "Number of Pushables - Continuous"; + prefix = "(314)"; + flags64text = "[6] Number greater or equal"; + flags512text = "[9] Number less"; + } + + 315 + { + title = "Number of Pushables - Once"; + prefix = "(315)"; + flags64text = "[6] Number greater or equal"; + flags512text = "[9] Number less"; + } + + 317 + { + title = "Condition Set Trigger - Continuous"; + prefix = "(317)"; + } + + 318 + { + title = "Condition Set Trigger - Once"; + prefix = "(318)"; + } + + 319 + { + title = "Unlockable - Continuous"; + prefix = "(319)"; + } + + 320 + { + title = "Unlockable - Once"; + prefix = "(320)"; + } + + 321 + { + title = "Trigger After X Calls - Continuous"; + prefix = "(321)"; + flags64text = "[6] Trigger more than once"; + + } + + 322 + { + title = "Trigger After X Calls - Each Time"; + prefix = "(322)"; + flags64text = "[6] Trigger more than once"; + } + + 323 + { + title = "NiGHTSerize - Each Time"; + prefix = "(323)"; + flags2text = "[1] Mare >= Front X Offset"; + flags8text = "[3] Run only if player is NiGHTS"; + flags16text = "[4] Count from lowest of players"; + flags32text = "[5] Lap <= Front Y Offset"; + flags64text = "[6] Mare <= Front X Offset"; + flags128text = "[7] Lap >= Front Y Offset"; + flags256text = "[8] Count laps from Bonus Time"; + flags512text = "[9] Count from triggering player"; + flags16384text = "[14] Run if no more mares"; + flags32768text = "[15] Run if player is not NiGHTS"; + } + + 324 + { + title = "NiGHTSerize - Once"; + flags2text = "[1] Mare >= Front X Offset"; + flags8text = "[3] Run only if player is NiGHTS"; + flags16text = "[4] Count from lowest of players"; + flags32text = "[5] Lap <= Front Y Offset"; + flags64text = "[6] Mare <= Front X Offset"; + flags128text = "[7] Lap >= Front Y Offset"; + flags256text = "[8] Count laps from Bonus Time"; + flags512text = "[9] Count from triggering player"; + flags16384text = "[14] Run if no more mares"; + flags32768text = "[15] Run if player is not NiGHTS"; + prefix = "(324)"; + } + + 325 + { + title = "De-NiGHTSerize - Each Time"; + flags2text = "[1] Mare >= Front X Offset"; + flags8text = "[3] Run if anyone is NiGHTS"; + flags16text = "[4] Count from lowest of players"; + flags32text = "[5] Lap <= Front Y Offset"; + flags64text = "[6] Mare <= Front X Offset"; + flags128text = "[7] Lap >= Front Y Offset"; + flags256text = "[8] Count laps from Bonus Time"; + flags512text = "[9] Count from triggering player"; + flags32768text = "[15] Run if no one is NiGHTS"; + prefix = "(325)"; + } + + 326 + { + title = "De-NiGHTSerize - Once"; + flags2text = "[1] Mare >= Front X Offset"; + flags8text = "[3] Run if anyone is NiGHTS"; + flags16text = "[4] Count from lowest of players"; + flags32text = "[5] Lap <= Front Y Offset"; + flags64text = "[6] Mare <= Front X Offset"; + flags128text = "[7] Lap >= Front Y Offset"; + flags256text = "[8] Count laps from Bonus Time"; + flags512text = "[9] Count from triggering player"; + flags32768text = "[15] Run if no one is NiGHTS"; + prefix = "(326)"; + } + + 327 + { + title = "NiGHTS Lap - Each Time"; + flags2text = "[1] Mare >= Front X Offset"; + flags16text = "[4] Count from lowest of players"; + flags32text = "[5] Lap <= Front Y Offset"; + flags64text = "[6] Mare <= Front X Offset"; + flags128text = "[7] Lap >= Front Y Offset"; + flags256text = "[8] Count laps from Bonus Time"; + flags512text = "[9] Count from triggering player"; + prefix = "(327)"; + } + + 328 + { + title = "NiGHTS Lap - Once"; + flags2text = "[1] Mare >= Front X Offset"; + flags16text = "[4] Count from lowest of players"; + flags32text = "[5] Lap <= Front Y Offset"; + flags64text = "[6] Mare <= Front X Offset"; + flags128text = "[7] Lap >= Front Y Offset"; + flags256text = "[8] Count laps from Bonus Time"; + flags512text = "[9] Count from triggering player"; + prefix = "(328)"; + } + + 329 + { + title = "Ideya Capture Touch - Each Time"; + flags2text = "[1] Mare >= Front X Offset"; + flags8text = "[3] Run regardless of spheres"; + flags16text = "[4] Count from lowest of players"; + flags32text = "[5] Lap <= Front Y Offset"; + flags64text = "[6] Mare <= Front X Offset"; + flags128text = "[7] Lap >= Front Y Offset"; + flags256text = "[8] Count laps from Bonus Time"; + flags512text = "[9] Count from triggering player"; + flags16384text = "[14] Only if not enough spheres"; + flags32768text = "[15] Run when entering Capture"; + prefix = "(329)"; + } + + 330 + { + title = "Ideya Capture Touch - Once"; + flags2text = "[1] Mare >= Front X Offset"; + flags8text = "[3] Run regardless of spheres"; + flags16text = "[4] Count from lowest of players"; + flags32text = "[5] Lap <= Front Y Offset"; + flags64text = "[6] Mare <= Front X Offset"; + flags128text = "[7] Lap >= Front Y Offset"; + flags256text = "[8] Count laps from Bonus Time"; + flags512text = "[9] Count from triggering player"; + flags16384text = "[14] Only if not enough spheres"; + flags32768text = "[15] Run when entering Capture"; + prefix = "(330)"; + } + + 331 + { + title = "Player Skin - Continuous"; + flags64text = "[6] Disable for this skin"; + prefix = "(331)"; + } + + 332 + { + title = "Player Skin - Each Time"; + flags64text = "[6] Disable for this skin"; + prefix = "(332)"; + } + + 333 + { + title = "Player Skin - Once"; + flags64text = "[6] Disable for this skin"; + prefix = "(333)"; + } + + 399 + { + title = "Level Load"; + prefix = "(399)"; + } + } + + linedefexecsector + { + title = "Linedef Executor (sector)"; + + 400 + { + title = "Set Tagged Sector's Floor Height/Texture"; + prefix = "(400)"; + flags8text = "[3] Set delay by backside sector"; + flags64text = "[6] Keep floor flat"; + } + + 401 + { + title = "Set Tagged Sector's Ceiling Height/Texture"; + prefix = "(401)"; + flags8text = "[3] Set delay by backside sector"; + } + + 402 + { + title = "Set Tagged Sector's Light Level"; + prefix = "(402)"; + flags8text = "[3] Set delay by backside sector"; + } + + 409 + { + title = "Change Tagged Sector's Tag"; + prefix = "(409)"; + flags8text = "[3] Set delay by backside sector"; + } + + 410 + { + title = "Change Front Sector's Tag"; + prefix = "(410)"; + flags8text = "[3] Set delay by backside sector"; + } + + 416 + { + title = "Start Adjustable Flickering Light"; + prefix = "(416)"; + flags8text = "[3] Set delay by backside sector"; + flags64text = "[6] Second level from back"; + } + + 417 + { + title = "Start Adjustable Pulsating Light"; + prefix = "(417)"; + flags8text = "[3] Set delay by backside sector"; + flags64text = "[6] Second level from back"; + } + + 418 + { + title = "Start Adjustable Blinking Light (unsynchronized)"; + prefix = "(418)"; + flags8text = "[3] Set delay by backside sector"; + flags64text = "[6] Second level from back"; + } + + 419 + { + title = "Start Adjustable Blinking Light (synchronized)"; + prefix = "(419)"; + flags8text = "[3] Set delay by backside sector"; + flags64text = "[6] Second level from back"; + } + + 420 + { + title = "Fade Light Level"; + prefix = "(420)"; + flags8text = "[3] Set delay by backside sector"; + flags16text = "[4] Set params by X/Y offsets"; + flags512text = "[9] Speed = Tic Duration"; + flags1024text = "[10] Override existing fade"; + } + + 421 + { + title = "Stop Lighting Effect"; + prefix = "(421)"; + flags8text = "[3] Set delay by backside sector"; + } + + 435 + { + title = "Change Plane Scroller Direction"; + prefix = "(435)"; + flags8text = "[3] Set delay by backside sector"; + } + } + + linedefexecplane + { + title = "Linedef Executor (plane movement)"; + + 403 + { + title = "Move Tagged Sector's Floor"; + prefix = "(403)"; + flags2text = "[1] Trigger linedef executor"; + flags8text = "[3] Set delay by backside sector"; + flags64text = "[6] Change floor flat"; + } + + 404 + { + title = "Move Tagged Sector's Ceiling"; + prefix = "(404)"; + flags2text = "[1] Trigger linedef executor"; + flags8text = "[3] Set delay by backside sector"; + flags64text = "[6] Change ceiling flat"; + } + + 405 + { + title = "Move Floor According to Front Texture Offsets"; + prefix = "(405)"; + flags8text = "[3] Set delay by backside sector"; + flags64text = "[6] Move instantly"; + } + + 407 + { + title = "Move Ceiling According to Front Texture Offsets"; + prefix = "(407)"; + flags8text = "[3] Set delay by backside sector"; + flags64text = "[6] Move instantly"; + } + + 411 + { + title = "Stop Plane Movement"; + prefix = "(411)"; + flags8text = "[3] Set delay by backside sector"; + } + + 428 + { + title = "Start Platform Movement"; + prefix = "(428)"; + flags8text = "[3] Set delay by backside sector"; + flags64text = "[6] Move upwards at start"; + } + + 429 + { + title = "Crush Ceiling Once"; + prefix = "(429)"; + flags8text = "[3] Set delay by backside sector"; + flags512text = "[9] Double, constant speed"; + } + + 430 + { + title = "Crush Floor Once"; + prefix = "(430)"; + flags8text = "[3] Set delay by backside sector"; + } + + 431 + { + title = "Crush Floor and Ceiling Once"; + prefix = "(431)"; + flags8text = "[3] Set delay by backside sector"; + flags512text = "[9] Double, constant speed"; + } + } + + linedefexecplayer + { + title = "Linedef Executor (player/object)"; + + 412 + { + title = "Teleporter"; + prefix = "(412)"; + flags2text = "[1] Silent"; + flags8text = "[3] Set delay by backside sector"; + flags64text = "[6] Retain angle"; + flags256text = "[8] Relative, silent"; + flags512text = "[9] Retain momentum"; + } + + 425 + { + title = "Change Object State"; + prefix = "(425)"; + flags8text = "[3] Set delay by backside sector"; + } + + 426 + { + title = "Stop Object"; + prefix = "(426)"; + flags8text = "[3] Set delay by backside sector"; + flags64text = "[6] Teleport to sector center"; + } + + 427 + { + title = "Award Score"; + prefix = "(427)"; + flags8text = "[3] Set delay by backside sector"; + } + + 432 + { + title = "Enable/Disable 2D Mode"; + prefix = "(432)"; + flags8text = "[3] Set delay by backside sector"; + flags64text = "[6] Return to 3D"; + } + + 433 + { + title = "Enable/Disable Gravity Flip"; + prefix = "(433)"; + flags8text = "[3] Set delay by backside sector"; + flags64text = "[6] Return to normal"; + } + + 434 + { + title = "Award Power-Up"; + prefix = "(434)"; + flags2text = "[1] Use back upper texture"; + flags8text = "[3] Set delay by backside sector"; + flags64text = "[6] No time limit"; + } + + 437 + { + title = "Disable Player Control"; + prefix = "(437)"; + flags8text = "[3] Set delay by backside sector"; + flags64text = "[6] Allow jumping"; + } + + 438 + { + title = "Change Object Size"; + prefix = "(438)"; + flags8text = "[3] Set delay by backside sector"; + } + + 442 + { + title = "Change Object Type State"; + prefix = "(442)"; + flags8text = "[3] Set delay by backside sector"; + } + + 457 + { + title = "Track Object's Angle"; + prefix = "(457)"; + flags8text = "[3] Set delay by backside sector"; + flags128text = "[7] Don't stop after first fail"; + } + + 458 + { + title = "Stop Tracking Object's Angle"; + prefix = "(458)"; + flags8text = "[3] Set delay by backside sector"; + } + + 460 + { + title = "Award Rings"; + prefix = "(460)"; + } + + 461 + { + title = "Spawn Object"; + prefix = "(461)"; + flags64text = "[6] Spawn inside a range"; + } + + 462 + { + title = "Stop Timer/Exit Stage in Record Attack"; + prefix = "(462)"; + } + } + + linedefexecmisc + { + title = "Linedef Executor (misc.)"; + + 413 + { + title = "Change Music"; + prefix = "(413)"; + flags2text = "[1] Keep after death"; + flags8text = "[3] Set delay by backside sector"; + flags32text = "[5] Seek to current song position"; + flags64text = "[6] For everyone"; + flags128text = "[7] Fade to custom volume"; + flags512text = "[9] Don't loop"; + flags16384text = "[14] Force music reload"; + } + + 414 + { + title = "Play Sound Effect"; + prefix = "(414)"; + flags2text = "[1] From calling sector"; + flags8text = "[3] Set delay by backside sector"; + flags64text = "[6] From nowhere for triggerer"; + flags512text = "[9] For everyone"; + flags1024text = "[10] From tagged sectors"; + } + + 415 + { + title = "Run Script"; + prefix = "(415)"; + flags8text = "[3] Set delay by backside sector"; + } + + 422 + { + title = "Switch to Cut-Away View"; + prefix = "(422)"; + flags8text = "[3] Set delay by backside sector"; + flags64text = "[6] Adjust pitch"; + } + + 423 + { + title = "Change Sky"; + prefix = "(423)"; + flags8text = "[3] Set delay by backside sector"; + flags64text = "[6] For everyone"; + } + + 424 + { + title = "Change Weather"; + prefix = "(424)"; + flags8text = "[3] Set delay by backside sector"; + flags64text = "[6] For everyone"; + } + + 436 + { + title = "Shatter FOF"; + prefix = "(436)"; + flags8text = "[3] Set delay by backside sector"; + } + + 439 + { + title = "Change Tagged Linedef's Textures"; + prefix = "(439)"; + flags8text = "[3] Set delay by backside sector"; + flags64text = "[6] Only existing"; + } + + 440 + { + title = "Start Metal Sonic Race"; + prefix = "(440)"; + flags8text = "[3] Set delay by backside sector"; + } + + 441 + { + title = "Condition Set Trigger"; + prefix = "(441)"; + flags8text = "[3] Set delay by backside sector"; + } + + 443 + { + title = "Call Lua Function"; + prefix = "(443)"; + flags8text = "[3] Set delay by backside sector"; + } + + 444 + { + title = "Earthquake"; + prefix = "(444)"; + flags8text = "[3] Set delay by backside sector"; + } + + + 445 + { + title = "Make FOF Disappear/Reappear"; + prefix = "(445)"; + flags8text = "[3] Set delay by backside sector"; + flags64text = "[6] Reappear"; + } + + 446 + { + title = "Make FOF Crumble"; + prefix = "(446)"; + flags2text = "[1] Flags determine respawn"; + flags8text = "[3] Set delay by backside sector"; + flags64text = "[6] Don't respawn"; + } + + 447 + { + title = "Change Tagged Sector's Colormap"; + prefix = "(447)"; + flags8text = "[3] Set delay by backside sector"; + flags16text = "[4] Front X/Y = Alpha"; + flags32text = "[5] Subtract Red value"; + flags64text = "[6] Subtract Green value"; + flags128text = "[7] Subtract Blue value"; + flags256text = "[8] Calc relative values"; + flags32768text = "[15] Use back side colormap"; + } + + 448 + { + title = "Change Skybox"; + prefix = "(448)"; + flags2text = "[1] Change centerpoint"; + flags8text = "[3] Set delay by backside sector"; + flags64text = "[6] For everyone"; + flags512text = "[9] Don't change viewpoint"; + } + + 450 + { + title = "Execute Linedef Executor (specific tag)"; + prefix = "(450)"; + flags8text = "[3] Set delay by backside sector"; + } + + 451 + { + title = "Execute Linedef Executor (random tag in range)"; + prefix = "(451)"; + flags8text = "[3] Set delay by backside sector"; + } + + 452 + { + title = "Set FOF Translucency"; + prefix = "(452)"; + flags8text = "[3] Set delay by backside sector"; + flags64text = "[6] Do not handle FF_TRANS"; + flags256text = "[8] Set relative to current val"; + } + + 453 + { + title = "Fade FOF"; + prefix = "(453)"; + flags2text = "[1] Do not handle FF_EXISTS"; + flags8text = "[3] Set delay by backside sector"; + flags32text = "[5] No collision during fade"; + flags64text = "[6] Do not handle FF_TRANS"; + flags128text = "[7] Do not handle lighting"; + flags256text = "[8] Set relative to current val"; + flags512text = "[9] Speed = Tic Duration"; + flags1024text = "[10] Override existing fade"; + flags16384text = "[14] Do not handle collision"; + flags32768text = "[15] Use exact alpha in OGL"; + } + + 454 + { + title = "Stop Fading FOF"; + prefix = "(454)"; + flags2text = "[1] Do not finalize collision"; + flags8text = "[3] Set delay by backside sector"; + } + + 455 + { + title = "Fade Tagged Sector's Colormap"; + prefix = "(455)"; + flags8text = "[3] Set delay by backside sector"; + flags16text = "[4] Front X/Y = Alpha"; + flags32text = "[5] Subtract Red value"; + flags64text = "[6] Subtract Green value"; + flags128text = "[7] Subtract Blue value"; + flags256text = "[8] Calc relative values"; + flags512text = "[9] Speed = Tic Duration"; + flags1024text = "[10] Override existing fade"; + flags16384text = "[14] Fade from invisible black"; + flags32768text = "[15] Use back side colormap"; + } + + 456 + { + title = "Stop Fading Tagged Sector's Colormap"; + prefix = "(456)"; + flags8text = "[3] Set delay by backside sector"; + } + + 459 + { + title = "Control Text Prompt"; + prefix = "(459)"; + flags2text = "[1] Close text prompt"; + flags8text = "[3] Set delay by backside sector"; + flags32text = "[5] Run executor tag on close"; + flags64text = "[6] For everyone"; + flags128text = "[7] Do not block controls"; + flags256text = "[8] Do not freeze time"; + flags32768text = "[15] Find prompt by name"; + } + } + + linedefexecpoly + { + title = "Linedef Executor (polyobject)"; + + 480 + { + title = "Door Slide"; + prefix = "(480)"; + flags8text = "[3] Set delay by backside sector"; + } + + 481 + { + title = "Door Swing"; + prefix = "(481)"; + flags8text = "[3] Set delay by backside sector"; + } + + 482 + { + title = "Move"; + prefix = "(482)"; + flags8text = "[3] Set delay by backside sector"; + } + + 483 + { + title = "Move, Override"; + prefix = "(483)"; + flags8text = "[3] Set delay by backside sector"; + } + + 484 + { + title = "Rotate Right"; + prefix = "(484)"; + flags8text = "[3] Set delay by backside sector"; + flags64text = "[6] Don't turn players"; + flags512text = "[9] Turn all objects"; + } + + 485 + { + title = "Rotate Right, Override"; + prefix = "(485)"; + flags8text = "[3] Set delay by backside sector"; + flags64text = "[6] Don't turn players"; + flags512text = "[9] Turn all objects"; + } + + 486 + { + title = "Rotate Left"; + prefix = "(486)"; + flags8text = "[3] Set delay by backside sector"; + flags64text = "[6] Don't turn players"; + flags512text = "[9] Turn all objects"; + } + + 487 + { + title = "Rotate Left, Override"; + prefix = "(487)"; + flags8text = "[3] Set delay by backside sector"; + flags64text = "[6] Don't turn players"; + flags512text = "[9] Turn all objects"; + } + + 488 + { + title = "Move by Waypoints"; + prefix = "(488)"; + flags8text = "[3] Set delay by backside sector"; + flags32text = "[5] Reverse order"; + flags128text = "[7] There and back"; + flags256text = "[8] Return when done"; + flags512text = "[9] Loop movement"; + } + + 489 + { + title = "Turn Invisible, Intangible"; + prefix = "(489)"; + flags8text = "[3] Set delay by backside sector"; + flags64text = "[6] Only invisible"; + } + + 490 + { + title = "Turn Visible, Tangible"; + prefix = "(490)"; + flags8text = "[3] Set delay by backside sector"; + flags64text = "[6] Only visible"; + } + + 491 + { + title = "Set Translucency"; + prefix = "(491)"; + flags8text = "[3] Set delay by backside sector"; + flags16text = "[4] Set raw alpha by Front X"; + flags256text = "[8] Calc relative values"; + } + + 492 + { + title = "Fade Translucency"; + prefix = "(492)"; + flags8text = "[3] Set delay by backside sector"; + flags16text = "[4] Set raw alpha by Front X"; + flags32text = "[5] No collision during fade"; + flags256text = "[8] Calc relative values"; + flags512text = "[9] Speed = Tic Duration"; + flags1024text = "[10] Override existing fade"; + flags16384text = "[14] Do not handle collision"; + } + } + + wallscroll + { + title = "Wall Scrolling"; + + 500 + { + title = "Scroll Wall Front Side Left"; + prefix = "(500)"; + } + + 501 + { + title = "Scroll Wall Front Side Right"; + prefix = "(501)"; + } + + 502 + { + title = "Scroll Wall According to Linedef"; + prefix = "(502)"; + } + + 503 + { + title = "Scroll Wall According to Linedef (Accelerative)"; + prefix = "(503)"; + } + + 504 + { + title = "Scroll Wall According to Linedef (Displacement)"; + prefix = "(504)"; + } + + 505 + { + title = "Scroll Texture by Front Side Offsets"; + prefix = "(505)"; + } + + 506 + { + title = "Scroll Texture by Back Side Offsets"; + prefix = "(506)"; + } + } + + planescroll + { + title = "Plane Scrolling"; + + 510 + { + title = "Scroll Floor Texture"; + prefix = "(510)"; + } + + 511 + { + title = "Scroll Floor Texture (Accelerative)"; + prefix = "(511)"; + } + + 512 + { + title = "Scroll Floor Texture (Displacement)"; + prefix = "(512)"; + } + + 513 + { + title = "Scroll Ceiling Texture"; + prefix = "(513)"; + } + + 514 + { + title = "Scroll Ceiling Texture (Accelerative)"; + prefix = "(514)"; + } + + 515 + { + title = "Scroll Ceiling Texture (Displacement)"; + prefix = "(515)"; + } + + 520 + { + title = "Carry Objects on Floor"; + prefix = "(520)"; + } + + 521 + { + title = "Carry Objects on Floor (Accelerative)"; + prefix = "(521)"; + flags64text = "[6] Even across edges"; + } + + 522 + { + title = "Carry Objects on Floor (Displacement)"; + prefix = "(522)"; + } + + 523 + { + title = "Carry Objects on Ceiling"; + prefix = "(523)"; + flags64text = "[6] Even across edges"; + } + + 524 + { + title = "Carry Objects on Ceiling (Accelerative)"; + prefix = "(524)"; + } + + 525 + { + title = "Carry Objects on Ceiling (Displacement)"; + prefix = "(525)"; + } + + 530 + { + title = "Scroll Floor Texture and Carry Objects"; + prefix = "(530)"; + flags64text = "[6] Even across edges"; + } + + 531 + { + title = "Scroll Floor Texture and Carry Objects (Accelerative)"; + prefix = "(531)"; + } + + 532 + { + title = "Scroll Floor Texture and Carry Objects (Displacement)"; + prefix = "(532)"; + } + + 533 + { + title = "Scroll Ceiling Texture and Carry Objects"; + prefix = "(533)"; + flags64text = "[6] Even across edges"; + } + + 534 + { + title = "Scroll Ceiling Texture and Carry Objects (Accelerative)"; + prefix = "(534)"; + } + + 535 + { + title = "Scroll Ceiling Texture and Carry Objects (Displacement)"; + prefix = "(535)"; + } + } + + pusher + { + title = "Pusher"; + + 541 + { + title = "Wind"; + prefix = "(541)"; + flags512text = "[9] Player slides"; + flags64text = "[6] Even across edges"; + } + + 542 + { + title = "Upwards Wind"; + prefix = "(542)"; + flags512text = "[9] Player slides"; + flags64text = "[6] Even across edges"; + } + + 543 + { + title = "Downwards Wind"; + prefix = "(543)"; + flags512text = "[9] Player slides"; + flags64text = "[6] Even across edges"; + } + + 544 + { + title = "Current"; + prefix = "(544)"; + flags512text = "[9] Player slides"; + flags64text = "[6] Even across edges"; + } + + 545 + { + title = "Upwards Current"; + prefix = "(545)"; + flags512text = "[9] Player slides"; + flags64text = "[6] Even across edges"; + } + + 546 + { + title = "Downwards Current"; + prefix = "(546)"; + flags512text = "[9] Player slides"; + flags64text = "[6] Even across edges"; + } + + 547 + { + title = "Push/Pull"; + prefix = "(547)"; + } + } + + light + { + title = "Lighting"; + + 600 + { + title = "Floor Lighting"; + prefix = "(600)"; + } + + 601 + { + title = "Ceiling Lighting"; + prefix = "(601)"; + } + + 602 + { + title = "Adjustable Pulsating Light"; + prefix = "(602)"; + } + + 603 + { + title = "Adjustable Flickering Light"; + prefix = "(603)"; + } + + 604 + { + title = "Adjustable Blinking Light (unsynchronized)"; + prefix = "(604)"; + } + + 605 + { + title = "Adjustable Blinking Light (synchronized)"; + prefix = "(605)"; + } + + 606 + { + title = "Colormap"; + prefix = "(606)"; + } + } + + slope + { + title = "Slope"; + + 700 + { + title = "Slope Frontside Floor"; + prefix = "(700)"; + flags2048text = "[11] No physics"; + flags4096text = "[12] Dynamic"; + slope = "regular"; + slopeargs = 1; + } + + 701 + { + title = "Slope Frontside Ceiling"; + prefix = "(701)"; + flags2048text = "[11] No physics"; + flags4096text = "[12] Dynamic"; + slope = "regular"; + slopeargs = 2; + } + + 702 + { + title = "Slope Frontside Floor and Ceiling"; + prefix = "(702)"; + flags2048text = "[11] No physics"; + flags4096text = "[12] Dynamic"; + slope = "regular"; + slopeargs = 3; + } + + 703 + { + title = "Slope Frontside Floor and Backside Ceiling"; + prefix = "(703)"; + flags2048text = "[11] No physics"; + flags4096text = "[12] Dynamic"; + slope = "regular"; + slopeargs = 9; + } + + 704 + { + title = "Slope Frontside Floor by 3 Tagged Vertex Things"; + prefix = "(704)"; + flags2048text = "[11] No physics"; + flags4096text = "[12] Dynamic"; + flags8192text = "[13] Use tag and offsets"; + slope = "vertex"; + slopeargs = 0; + } + + 705 + { + title = "Slope Frontside Ceiling by 3 Tagged Vertex Things"; + prefix = "(705)"; + flags2048text = "[11] No physics"; + flags4096text = "[12] Dynamic"; + flags8192text = "[13] Use tag and offsets"; + slope = "vertex"; + slopeargs = 1; + } + + 710 + { + title = "Slope Backside Floor"; + prefix = "(710)"; + flags2048text = "[11] No physics"; + flags4096text = "[12] Dynamic"; + slope = "regular"; + slopeargs = 4; + } + + 711 + { + title = "Slope Backside Ceiling"; + prefix = "(711)"; + flags2048text = "[11] No physics"; + flags4096text = "[12] Dynamic"; + slope = "regular"; + slopeargs = 8; + } + + 712 + { + title = "Slope Backside Floor and Ceiling"; + prefix = "(712)"; + flags2048text = "[11] No physics"; + flags4096text = "[12] Dynamic"; + slope = "regular"; + slopeargs = 12; + } + + 713 + { + title = "Slope Backside Floor and Frontside Ceiling"; + prefix = "(713)"; + flags2048text = "[11] No physics"; + flags4096text = "[12] Dynamic"; + slope = "regular"; + slopeargs = 6; + } + + 714 + { + title = "Slope Backside Floor by 3 Tagged Vertex Things"; + prefix = "(714)"; + flags2048text = "[11] No physics"; + flags4096text = "[12] Dynamic"; + flags8192text = "[13] Use tag and offsets"; + slope = "vertex"; + slopeargs = 2; + } + + 715 + { + title = "Slope Backside Ceiling by 3 Tagged Vertex Things"; + prefix = "(715)"; + flags2048text = "[11] No physics"; + flags4096text = "[12] Dynamic"; + flags8192text = "[13] Use tag and offsets"; + slope = "vertex"; + slopeargs = 3; + } + + 720 + { + title = "Copy Frontside Floor Slope from Line Tag"; + prefix = "(720)"; + slope = "copy"; + slopeargs = 1; + } + + 721 + { + title = "Copy Frontside Ceiling Slope from Line Tag"; + prefix = "(721)"; + slope = "copy"; + slopeargs = 2; + } + + 722 + { + title = "Copy Frontside Floor and Ceiling Slope from Line Tag"; + prefix = "(722)"; + slope = "copy"; + slopeargs = 3; + } + + 799 + { + title = "Set Tagged Dynamic Slope Vertex to Front Sector Height"; + prefix = "(799)"; + } + } + + transwall + { + title = "Translucent Wall"; + + 900 + { + title = "90% Opaque"; + prefix = "(900)"; + } + + 901 + { + title = "80% Opaque"; + prefix = "(901)"; + } + + 902 + { + title = "70% Opaque"; + prefix = "(902)"; + } + + 903 + { + title = "60% Opaque"; + prefix = "(903)"; + } + + 904 + { + title = "50% Opaque"; + prefix = "(904)"; + } + + 905 + { + title = "40% Opaque"; + prefix = "(905)"; + } + + 906 + { + title = "30% Opaque"; + prefix = "(906)"; + } + + 907 + { + title = "20% Opaque"; + prefix = "(907)"; + } + + 908 + { + title = "10% Opaque"; + prefix = "(908)"; + } + + 909 + { + title = "Fog Wall"; + prefix = "(909)"; + } + } +} + +udmf +{ + misc + { + title = "Miscellaneous"; + + 0 + { + title = "None"; + prefix = "(0)"; + } + } +} \ No newline at end of file diff --git a/extras/conf/Includes/SRB222_misc.cfg b/extras/conf/Includes/SRB222_misc.cfg new file mode 100644 index 000000000..ce23388b2 --- /dev/null +++ b/extras/conf/Includes/SRB222_misc.cfg @@ -0,0 +1,726 @@ +linedefflags +{ + 1 = "[0] Impassable"; + 2 = "[1] Block Enemies"; + 4 = "[2] Double-Sided"; + 8 = "[3] Upper Unpegged"; + 16 = "[4] Lower Unpegged"; + 32 = "[5] Slope Skew (E1)"; + 64 = "[6] Not Climbable"; + 128 = "[7] No Midtexture Skew (E2)"; + 256 = "[8] Peg Midtexture (E3)"; + 512 = "[9] Solid Midtexture (E4)"; + 1024 = "[10] Repeat Midtexture (E5)"; + 2048 = "[11] Netgame Only"; + 4096 = "[12] No Netgame"; + 8192 = "[13] Effect 6"; + 16384 = "[14] Bouncy Wall"; + 32768 = "[15] Transfer Line"; +} + + +// LINEDEF ACTIVATIONS +// Make sure these are in order from lowest value to highest value +linedefactivations +{ +} + + +// Linedef flags UDMF translation table +// This is needed for copy/paste and prefabs to work properly +// When the UDMF field name is prefixed with ! it is inverted +linedefflagstranslation +{ + 1 = "blocking"; + 2 = "blockmonsters"; + 4 = "twosided"; + 8 = "dontpegtop"; + 16 = "dontpegbottom"; + 32 = "skewtd"; + 64 = "noclimb"; + 128 = "noskew"; + 256 = "midpeg"; + 512 = "midsolid"; + 1024 = "wrapmidtex"; + 2048 = "netonly"; + 4096 = "nonet"; + 8192 = "effect6"; + 16384 = "bouncy"; + 32768 = "transfer"; +} + + +linedefflags_udmf +{ + blocking = "Impassable"; + blockmonsters = "Block Enemies"; + twosided = "Double-Sided"; + dontpegtop = "Upper Unpegged"; + dontpegbottom = "Lower Unpegged"; + skewtd = "Slope Skew"; + noclimb = "Not Climbable"; + noskew = "No Midtexture Skew"; + midpeg = "Peg Midtexture"; + midsolid = "Solid Midtexture"; + wrapmidtex = "Repeat Midtexture"; +// netonly = "Netgame-Only special"; +// nonet = "No netgame special"; +// effect6 = "Effect 6"; + bouncy = "Bouncy Wall"; +// transfer = "Transfer Line"; +} + + +linedefactivations_udmf +{ + notriggerorder = "Out of Order"; + netonly = "Netgame-Only"; + nonet = "No netgame"; +} + +sidedefflags +{ + clipmidtex = "Clip middle texture"; + wrapmidtex = "Wrap middle texture"; + smoothlighting = "Smooth lighting"; + nofakecontrast = "Even lighting"; + nodecals = "No decals"; + lightfog = "Use sidedef brightness on fogged walls"; +} + +//RENDER STYLES +thingrenderstyles +{ +} + +linedefrenderstyles +{ + translucent = "Translucent"; + fog = "Fog"; +} + +sectorrenderstyles +{ +} + +thingflags +{ + 1 = "[1] Extra"; + 2 = "[2] Flip"; + 4 = "[4] Special"; + 8 = "[8] Ambush"; +} + +// THING FLAGS +thingflags_udmf +{ + extra = "Extra"; + flip = "Flip"; + special = "Special"; + ambush = "Ambush"; +} + + +// Thing flags UDMF translation table +// This is needed for copy/paste and prefabs to work properly +// When the UDMF field name is prefixed with ! it is inverted +thingflagstranslation +{ + 1 = "extra"; + 2 = "flip"; + 4 = "special"; + 8 = "ambush"; +} + + +// DEFAULT SECTOR BRIGHTNESS LEVELS +sectorbrightness +{ + 255; + 248; + 240; + 232; + 224; + 216; + 208; + 200; + 192; + 184; + 176; + 168; + 160; + 152; + 144; + 136; + 128; + 120; + 112; + 104; + 96; + 88; + 80; + 72; + 64; + 56; + 48; + 40; + 32; + 24; + 16; + 8; + 0; +} + +/* +TEXTURES AND FLAT SOURCES +This tells Doom Builder where to find the information for textures +and flats in the IWAD file, Addition WAD file and Map WAD file. + +Start and end lumps must be given in a structure (of which the +key name doesnt matter) and any textures or flats in between them +are loaded in either the textures category or flats category. + +For textures: PNAMES, TEXTURE1 and TEXTURE2 are loaded by default. +*/ +textures +{ + zdoom1 + { + start = "TX_START"; + end = "TX_END"; + } +} + +/* +ADDITIONAL UNIVERSAL DOOM MAP FORMAT FIELD DEFINITIONS +Only add fields here that Doom Builder does not edit with its own user-interface! +The "default" field must match the UDMF specifications! + +Field data types: +0 = integer * +1 = float +2 = string +3 = bool +4 = linedef action (integer) * +5 = sector effect (integer) * +6 = texture (string) +7 = flat (string) +8 = angle in degrees (integer) +9 = angle in radians (float) +10 = XXRRGGBB color (integer) +11 = enum option (integer) * +12 = enum bits (integer) * +13 = sector tag (integer) * +14 = thing tag (integer) * +15 = linedef tag (integer) * +16 = enum option (string) +17 = angle in degrees (float) +22 = byte angle (integer) +*/ +universalfields +{ + sector + { + friction + { + name = "Friction"; + type = 1; + default = 1; + } + + specialeffectplanes + { + type = 11; + enum = "floorceiling"; + default = 0; + } + + colormapbegin + { + type = 0; + default = 0; + } + + colormapend + { + type = 0; + default = 33; + } + + foglighting + { + type = 3; + default = false; + } + + teambase + { + type = 11; + enum = "ctfteam"; + default = 0; + } + + triggersector + { + type = 3; + default = false; + } + + triggerobject + { + type = 11; + enum = "triggerobjects"; + default = 0; + } + + triggersurface + { + type = 11; + enum = "triggersurfaces"; + default = 0; + } + + ringdrain + { + type = 1; + default = 0; + } + } + + linedef + { + executordelay + { + type = 0; + default = 0; + } + midtexrepetitions + { + type = 0; + default = 0; + } + arg5 + { + type = 0; + default = 0; + } + arg1str + { + type = 2; + default = ""; + } + } + + thing + { + } +} + +/* +MAP LUMP NAMES +Map lumps are loaded with the map as long as they are right after each other. When the editor +meets a lump which is not defined in this list it will ignore the map if not satisfied. +The order of items defines the order in which lumps will be written to WAD file on save. +To indicate the map header lump, use ~MAP + +Legenda: +required = Lump is required to exist. +blindcopy = Lump will be copied along with the map blindly. (useful for lumps Doom Builder doesn't use) +nodebuild = The nodebuilder generates this lump. +allowempty = The nodebuilder is allowed to leave this lump empty. +scriptbuild = This lump is a text-based script, which should be compiled using current script compiler; +script = This lump is a text-based script. Specify the filename of the script configuration to use. +*/ + +doommaplumpnames +{ + ~MAP + { + required = true; + blindcopy = true; + nodebuild = false; + } + + THINGS + { + required = true; + nodebuild = true; + allowempty = true; + } + + LINEDEFS + { + required = true; + nodebuild = true; + allowempty = false; + } + + SIDEDEFS + { + required = true; + nodebuild = true; + allowempty = false; + } + + VERTEXES + { + required = true; + nodebuild = true; + allowempty = false; + } + + SEGS + { + required = false; + nodebuild = true; + allowempty = false; + } + + SSECTORS + { + required = false; + nodebuild = true; + allowempty = false; + } + + NODES + { + required = false; + nodebuild = true; + allowempty = false; + } + + SECTORS + { + required = true; + nodebuild = true; + allowempty = false; + } + + REJECT + { + required = false; + nodebuild = true; + allowempty = false; + } + + BLOCKMAP + { + required = false; + nodebuild = true; + allowempty = true; + } +} + +udmfmaplumpnames +{ + ZNODES + { + required = false; + nodebuild = true; + allowempty = false; + } + + REJECT + { + required = false; + nodebuild = true; + allowempty = false; + } + + BLOCKMAP + { + required = false; + nodebuild = true; + allowempty = true; + } +} + +// ENUMERATIONS +// These are enumerated lists for linedef types and UDMF fields. +// Reserved names are: angledeg, anglerad, color, texture, flat +enums +{ + falsetrue + { + 0 = "False"; + 1 = "True"; + } + + yesno + { + 0 = "Yes"; + 1 = "No"; + } + + noyes + { + 0 = "No"; + 1 = "Yes"; + } + + onoff + { + 0 = "On"; + 1 = "Off"; + } + + offon + { + 0 = "Off"; + 1 = "On"; + } + + updown + { + 0 = "Up"; + 1 = "Down"; + } + + downup + { + 0 = "Down"; + 1 = "Up"; + } + + addset + { + 0 = "Add"; + 1 = "Set"; + } + + floorceiling + { + 0 = "Floor"; + 1 = "Ceiling"; + 2 = "Floor and ceiling"; + } + + triggertype + { + 0 = "Continuous"; + 1 = "Each Time (Enter)"; + 2 = "Each Time (Enter and leave)"; + 3 = "Once"; + } + + frontback + { + 0 = "None"; + 1 = "Front"; + 2 = "Back"; + } + + ctfteam + { + 0 = "None"; + 1 = "Red"; + 2 = "Blue"; + } + + triggerobjects + { + 0 = "Any player"; + 1 = "All players"; + 2 = "Pushable object"; + 3 = "Any object with thinker"; + } + + triggersurfaces + { + 0 = "Floor touch"; + 1 = "Ceiling touch"; + 2 = "Floor or ceiling touch"; + 3 = "Anywhere in sector"; + } + + tangibility + { + 1 = "Intangible from top"; + 2 = "Intangible from bottom"; + 4 = "Don't block players"; + 8 = "Don't block non-players"; + } +} + +//Default things filters +thingsfilters +{ + + filter0 + { + name = "Player starts"; + category = "starts"; + type = -1; + } + + + filter1 + { + name = "Enemies"; + category = "enemies"; + type = -1; + + } + + + filter2 + { + name = "NiGHTS Track"; + category = "nightstrk"; + type = -1; + + } + + + filter3 + { + name = "Normal Gravity"; + category = ""; + type = -1; + + fields + { + 2 = false; + } + + } + + + filter4 + { + name = "Reverse Gravity"; + category = ""; + type = -1; + + fields + { + 2 = true; + } + + } +} + +thingsfilters_udmf +{ +} + +// Special linedefs +speciallinedefs +{ + soundlinedefflag = 64; // See linedefflags + singlesidedflag = 1; // See linedefflags + doublesidedflag = 4; // See linedefflags + impassableflag = 1; + upperunpeggedflag = 8; + lowerunpeggedflag = 16; + repeatmidtextureflag = 1024; + pegmidtextureflag = 256; +} + +speciallinedefs_udmf +{ + soundlinedefflag = "noclimb"; + singlesidedflag = "blocking"; + doublesidedflag = "twosided"; + impassableflag = "blocking"; + upperunpeggedflag = "dontpegtop"; + lowerunpeggedflag = "dontpegbottom"; + repeatmidtextureflag = "wrapmidtex"; + pegmidtextureflag = "midpeg"; +} + +scriptlumpnames +{ + MAINCFG + { + script = "SOC.cfg"; + } + + OBJCTCFG + { + script = "SOC.cfg"; + } + + SOC_ + { + script = "SOC.cfg"; + isprefix = true; + } + + LUA_ + { + script = "Lua.cfg"; + isprefix = true; + } +} + +// Texture sources +textures +{ + zdoom1 + { + start = "TX_START"; + end = "TX_END"; + } +} + +// Patch sources +patches +{ + standard1 + { + start = "P_START"; + end = "P_END"; + } + + standard2 + { + start = "PP_START"; + end = "PP_END"; + } +} + +// Sprite sources +sprites +{ + standard1 + { + start = "S_START"; + end = "S_END"; + } + + standard2 + { + start = "SS_START"; + end = "SS_END"; + } +} + +// Flat sources +flats +{ + standard1 + { + start = "F_START"; + end = "F_END"; + } + + standard2 + { + start = "FF_START"; + end = "FF_END"; + } + + standard3 + { + start = "FF_START"; + end = "F_END"; + } + + standard4 + { + start = "F_START"; + end = "FF_END"; + } +} \ No newline at end of file diff --git a/extras/conf/Includes/SRB222_sectors.cfg b/extras/conf/Includes/SRB222_sectors.cfg new file mode 100644 index 000000000..3bcbeb1b1 --- /dev/null +++ b/extras/conf/Includes/SRB222_sectors.cfg @@ -0,0 +1,109 @@ +sectortypes +{ + 0 = "Normal"; + 1 = "Damage"; + 2 = "Damage (Water)"; + 3 = "Damage (Fire)"; + 4 = "Damage (Electrical)"; + 5 = "Spikes"; + 6 = "Death Pit (Camera Tilt)"; + 7 = "Death Pit (No Camera Tilt)"; + 8 = "Instant Kill"; + 9 = "Ring Drainer (Floor Touch)"; + 10 = "Ring Drainer (Anywhere in Sector)"; + 11 = "Special Stage Damage"; + 12 = "Space Countdown"; + 13 = "Ramp Sector (double step-up/down)"; + 14 = "Non-Ramp Sector (no step-down)"; + 15 = "Bouncy FOF"; + 16 = "Trigger Line Ex. (Pushable Objects)"; + 32 = "Trigger Line Ex. (Anywhere, All Players)"; + 48 = "Trigger Line Ex. (Floor Touch, All Players)"; + 64 = "Trigger Line Ex. (Anywhere in Sector)"; + 80 = "Trigger Line Ex. (Floor Touch)"; + 96 = "Trigger Line Ex. (Emerald Check)"; + 112 = "Trigger Line Ex. (NiGHTS Mare)"; + 128 = "Check for Linedef Executor on FOFs"; + 144 = "Egg Capsule"; + 160 = "Special Stage Time/Rings Parameters"; + 176 = "Custom Global Gravity"; + 512 = "Wind/Current"; + 1024 = "Conveyor Belt"; + 1280 = "Speed Pad"; + 4096 = "Star Post Activator"; + 8192 = "Exit/Special Stage Pit/Return Flag"; + 12288 = "CTF Red Team Base"; + 16384 = "CTF Blue Team Base"; + 20480 = "Fan Sector"; + 24576 = "Super Sonic Transform"; + 28672 = "Force Spin"; + 32768 = "Zoom Tube Start"; + 36864 = "Zoom Tube End"; + 40960 = "Circuit Finish Line"; + 45056 = "Rope Hang"; + 49152 = "Intangible to the Camera"; +} + +gen_sectortypes +{ + first + { + 0 = "Normal"; + 1 = "Damage"; + 2 = "Damage (Water)"; + 3 = "Damage (Fire)"; + 4 = "Damage (Electrical)"; + 5 = "Spikes"; + 6 = "Death Pit (Camera Tilt)"; + 7 = "Death Pit (No Camera Tilt)"; + 8 = "Instant Kill"; + 9 = "Ring Drainer (Floor Touch)"; + 10 = "Ring Drainer (Anywhere in Sector)"; + 11 = "Special Stage Damage"; + 12 = "Space Countdown"; + 13 = "Ramp Sector (double step-up/down)"; + 14 = "Non-Ramp Sector (no step-down)"; + 15 = "Bouncy FOF"; + } + + second + { + 0 = "Normal"; + 16 = "Trigger Line Ex. (Pushable Objects)"; + 32 = "Trigger Line Ex. (Anywhere, All Players)"; + 48 = "Trigger Line Ex. (Floor Touch, All Players)"; + 64 = "Trigger Line Ex. (Anywhere in Sector)"; + 80 = "Trigger Line Ex. (Floor Touch)"; + 96 = "Trigger Line Ex. (Emerald Check)"; + 112 = "Trigger Line Ex. (NiGHTS Mare)"; + 128 = "Check for Linedef Executor on FOFs"; + 144 = "Egg Capsule"; + 160 = "Special Stage Time/Rings Parameters"; + 176 = "Custom Global Gravity"; + } + + third + { + 0 = "Normal"; + 512 = "Wind/Current"; + 1024 = "Conveyor Belt"; + 1280 = "Speed Pad"; + } + + fourth + { + 0 = "Normal"; + 4096 = "Star Post Activator"; + 8192 = "Exit/Special Stage Pit/Return Flag"; + 12288 = "CTF Red Team Base"; + 16384 = "CTF Blue Team Base"; + 20480 = "Fan Sector"; + 24576 = "Super Sonic Transform"; + 28672 = "Force Spin"; + 32768 = "Zoom Tube Start"; + 36864 = "Zoom Tube End"; + 40960 = "Circuit Finish Line"; + 45056 = "Rope Hang"; + 49152 = "Intangible to the Camera"; + } +} \ No newline at end of file diff --git a/extras/conf/Includes/SRB222_things.cfg b/extras/conf/Includes/SRB222_things.cfg new file mode 100644 index 000000000..194e43630 --- /dev/null +++ b/extras/conf/Includes/SRB222_things.cfg @@ -0,0 +1,3398 @@ +// THING TYPES------------------------------------------------------------------ +// Color values: 1-Dark_Blue 2-Dark_Green 3-Turqoise 4-Dark_Red 5-Purple 6-Brown 7-Gray +// 8-Dark_Gray 9-Blue 10-Green 11-Cyan 12-Red 13-Magenta +// 14-Yellow 15-White 16-Pink 17-Orange 18-Gold 19-Cream + +editor +{ + color = 15; // White + arrow = 1; + title = ""; + error = -1; + width = 8; + height = 16; + sort = 1; + + 3328 = "3D Mode Start"; +} + +starts +{ + color = 1; // Blue + arrow = 1; + title = "Player Starts"; + width = 16; + height = 48; + flags8text = "[8] Spawn on ceiling"; + sprite = "PLAYA0"; + + 1 + { + title = "Player 01 Start"; + sprite = "PLAYA0"; + } + 2 + { + title = "Player 02 Start"; + sprite = "PLAYA0"; + } + 3 + { + title = "Player 03 Start"; + sprite = "PLAYA0"; + } + 4 + { + title = "Player 04 Start"; + sprite = "PLAYA0"; + } + 5 + { + title = "Player 05 Start"; + sprite = "PLAYA0"; + } + 6 + { + title = "Player 06 Start"; + sprite = "PLAYA0"; + } + 7 + { + title = "Player 07 Start"; + sprite = "PLAYA0"; + } + 8 + { + title = "Player 08 Start"; + sprite = "PLAYA0"; + } + 9 + { + title = "Player 09 Start"; + sprite = "PLAYA0"; + } + 10 + { + title = "Player 10 Start"; + sprite = "PLAYA0"; + } + 11 + { + title = "Player 11 Start"; + sprite = "PLAYA0"; + } + 12 + { + title = "Player 12 Start"; + sprite = "PLAYA0"; + } + 13 + { + title = "Player 13 Start"; + sprite = "PLAYA0"; + } + 14 + { + title = "Player 14 Start"; + sprite = "PLAYA0"; + } + 15 + { + title = "Player 15 Start"; + sprite = "PLAYA0"; + } + 16 + { + title = "Player 16 Start"; + sprite = "PLAYA0"; + } + 17 + { + title = "Player 17 Start"; + sprite = "PLAYA0"; + } + 18 + { + title = "Player 18 Start"; + sprite = "PLAYA0"; + } + 19 + { + title = "Player 19 Start"; + sprite = "PLAYA0"; + } + 20 + { + title = "Player 20 Start"; + sprite = "PLAYA0"; + } + 21 + { + title = "Player 21 Start"; + sprite = "PLAYA0"; + } + 22 + { + title = "Player 22 Start"; + sprite = "PLAYA0"; + } + 23 + { + title = "Player 23 Start"; + sprite = "PLAYA0"; + } + 24 + { + title = "Player 24 Start"; + sprite = "PLAYA0"; + } + 25 + { + title = "Player 25 Start"; + sprite = "PLAYA0"; + } + 26 + { + title = "Player 26 Start"; + sprite = "PLAYA0"; + } + 27 + { + title = "Player 27 Start"; + sprite = "PLAYA0"; + } + 28 + { + title = "Player 28 Start"; + sprite = "PLAYA0"; + } + 29 + { + title = "Player 29 Start"; + sprite = "PLAYA0"; + } + 30 + { + title = "Player 30 Start"; + sprite = "PLAYA0"; + } + 31 + { + title = "Player 31 Start"; + sprite = "PLAYA0"; + } + 32 + { + title = "Player 32 Start"; + sprite = "PLAYA0"; + } + 33 + { + title = "Match Start"; + sprite = "NDRNA2A8"; + } + 34 + { + title = "CTF Red Team Start"; + sprite = "SIGNG0"; + } + 35 + { + title = "CTF Blue Team Start"; + sprite = "SIGNE0"; + } +} + +enemies +{ + color = 9; // Light_Blue + arrow = 1; + title = "Enemies"; + + 100 + { + title = "Crawla (Blue)"; + sprite = "POSSA1"; + width = 24; + height = 32; + } + 101 + { + title = "Crawla (Red)"; + sprite = "SPOSA1"; + width = 24; + height = 32; + } + 102 + { + title = "Stupid Dumb Unnamed RoboFish"; + sprite = "FISHA0"; + width = 8; + height = 28; + angletext = "Jump strength"; + } + 103 + { + title = "Buzz (Gold)"; + sprite = "BUZZA1"; + width = 28; + height = 40; + flags8text = "[8] Cannot move"; + } + 104 + { + title = "Buzz (Red)"; + sprite = "RBUZA1"; + width = 28; + height = 40; + flags8text = "[8] Cannot move"; + } + 108 + { + title = "Deton"; + sprite = "DETNA1"; + width = 20; + height = 32; + } + 110 + { + title = "Turret"; + sprite = "TRETA1"; + width = 16; + height = 32; + } + 111 + { + title = "Pop-up Turret"; + sprite = "TURRI1"; + width = 12; + height = 64; + angletext = "Firing delay"; + } + 122 + { + title = "Spring Shell (Green)"; + sprite = "SSHLA1"; + width = 24; + height = 40; + } + 125 + { + title = "Spring Shell (Yellow)"; + sprite = "SSHLI1"; + width = 24; + height = 40; + } + 109 + { + title = "Skim"; + sprite = "SKIMA1"; + width = 16; + height = 24; + } + 113 + { + title = "Jet Jaw"; + sprite = "JJAWA3A7"; + width = 12; + height = 20; + } + 126 + { + title = "Crushstacean"; + sprite = "CRABA0"; + width = 24; + height = 32; + flags8text = "[8] Move left from spawn"; + } + 138 + { + title = "Banpyura"; + sprite = "CR2BA0"; + width = 24; + height = 32; + flags8text = "[8] Move left from spawn"; + } + 117 + { + title = "Robo-Hood"; + sprite = "ARCHA1"; + width = 24; + height = 32; + } + 118 + { + title = "Lance-a-Bot"; + sprite = "CBFSA1"; + width = 32; + height = 72; + } + 1113 + { + title = "Suspicious Lance-a-Bot Statue"; + sprite = "CBBSA1"; + width = 32; + height = 72; + } + 119 + { + title = "Egg Guard"; + sprite = "ESHIA1"; + width = 16; + height = 48; + flags1text = "[1] 90 degrees counter-clockwise"; + flags4text = "[4] 90 degrees clockwise"; + flags8text = "[8] Double speed"; + } + 115 + { + title = "Bird Aircraft Strike Hazard"; + sprite = "VLTRF1"; + width = 12; + height = 24; + } + 120 + { + title = "Green Snapper"; + sprite = "GSNPA1"; + width = 24; + height = 24; + } + 121 + { + title = "Minus"; + sprite = "MNUSA0"; + width = 24; + height = 32; + } + 134 + { + title = "Canarivore"; + sprite = "CANAA0"; + width = 12; + height = 80; + hangs = 1; + } + 123 + { + title = "Unidus"; + sprite = "UNIDA1"; + width = 18; + height = 36; + } + 135 + { + title = "Pterabyte Spawner"; + sprite = "PTERA2A8"; + width = 16; + height = 16; + parametertext = "No. Pterabytes"; + } + 136 + { + title = "Pyre Fly"; + sprite = "PYREA0"; + width = 24; + height = 34; + flags8text = "[8] Start on fire"; + } + 137 + { + title = "Dragonbomber"; + sprite = "DRABA1"; + width = 28; + height = 48; + } + 105 + { + title = "Jetty-Syn Bomber"; + sprite = "JETBB1"; + width = 20; + height = 50; + flags8text = "[8] Cannot move"; + } + 106 + { + title = "Jetty-Syn Gunner"; + sprite = "JETGB1"; + width = 20; + height = 48; + flags8text = "[8] Cannot move"; + } + 112 + { + title = "Spincushion"; + sprite = "SHRPA1"; + width = 16; + height = 24; + } + 114 + { + title = "Snailer"; + sprite = "SNLRA3A7"; + width = 24; + height = 48; + } + 129 + { + title = "Penguinator"; + sprite = "PENGA1"; + width = 24; + height = 32; + } + 130 + { + title = "Pophat"; + sprite = "POPHA1"; + width = 24; + height = 32; + } + 107 + { + title = "Crawla Commander"; + sprite = "CCOMA1"; + width = 16; + height = 32; + } + 131 + { + title = "Spinbobert"; + sprite = "SBOBB0"; + width = 32; + height = 32; + } + 132 + { + title = "Cacolantern"; + sprite = "CACOA0"; + width = 32; + height = 32; + flags8text = "[8] Cannot move"; + } + 133 + { + title = "Hangster"; + sprite = "HBATC1"; + width = 24; + height = 24; + hangs = 1; + } + 127 + { + title = "Hive Elemental"; + sprite = "HIVEA0"; + width = 32; + height = 80; + parametertext = "No. bees"; + } + 128 + { + title = "Bumblebore"; + sprite = "BUMBA1"; + width = 16; + height = 32; + } + 124 + { + title = "Buggle"; + sprite = "BBUZA1"; + width = 20; + height = 24; + } + 116 + { + title = "Pointy"; + sprite = "PNTYA1"; + width = 8; + height = 16; + } +} + +bosses +{ + color = 8; // Dark_Gray + arrow = 1; + title = "Bosses"; + + 200 + { + title = "Egg Mobile"; + sprite = "EGGMA1"; + width = 24; + height = 76; + flags4text = "[4] End level on death"; + flags8text = "[8] Alternate laser attack"; + } + 201 + { + title = "Egg Slimer"; + sprite = "EGGNA1"; + width = 24; + height = 76; + flags4text = "[4] End level on death"; + flags8text = "[8] Speed up when hit"; + } + 202 + { + title = "Sea Egg"; + sprite = "EGGOA1"; + width = 32; + height = 116; + flags4text = "[4] End level on death"; + } + 203 + { + title = "Egg Colosseum"; + sprite = "EGGPA1"; + width = 24; + height = 76; + flags4text = "[4] End level on death"; + } + 204 + { + title = "Fang"; + sprite = "FANGA1"; + width = 24; + height = 60; + flags1text = "[1] Grayscale mode"; + flags4text = "[4] End level on death"; + } + 206 + { + title = "Brak Eggman (Old)"; + sprite = "BRAKB1"; + width = 48; + height = 160; + flags4text = "[4] End level on death"; + } + 207 + { + title = "Metal Sonic (Race)"; + sprite = "METLI1"; + width = 16; + height = 48; + flags1text = "[1] Grayscale mode"; + } + 208 + { + title = "Metal Sonic (Battle)"; + sprite = "METLC1"; + width = 16; + height = 48; + flags1text = "[1] Grayscale mode"; + flags4text = "[4] End level on death"; + } + 209 + { + title = "Brak Eggman"; + sprite = "BRAK01"; + width = 48; + height = 160; + flags1text = "[1] No origin-fling death"; + flags4text = "[4] End level on death"; + flags8text = "[8] Electric barrier"; + } + 290 + { + arrow = 0; + title = "Boss Escape Point"; + width = 8; + height = 16; + sprite = "internal:eggmanend"; + } + 291 + { + arrow = 0; + title = "Egg Capsule Center"; + width = 8; + height = 16; + sprite = "internal:capsule"; + } + 292 + { + arrow = 0; + title = "Boss Waypoint"; + width = 8; + height = 16; + flags8text = "[8] Sea Egg shooting point"; + sprite = "internal:eggmanway"; + angletext = "No. (Sea Egg)"; + flagsvaluetext = "No. (Brak)"; + parametertext = "Next"; + } + 293 + { + title = "Metal Sonic Gather Point"; + sprite = "internal:metal"; + width = 8; + height = 16; + } + 294 + { + title = "Fang Waypoint"; + flags8text = "[8] Center waypoint"; + sprite = "internal:eggmanway"; + width = 8; + height = 16; + } +} + +rings +{ + color = 14; // Yellow + title = "Rings and Weapon Panels"; + width = 24; + height = 24; + flags8height = 24; + flags8text = "[8] Float"; + sprite = "RINGA0"; + + 300 + { + title = "Ring"; + sprite = "RINGA0"; + width = 16; + } + 301 + { + title = "Bounce Ring"; + sprite = "internal:RNGBA0"; + } + 302 + { + title = "Rail Ring"; + sprite = "internal:RNGRA0"; + } + 303 + { + title = "Infinity Ring"; + sprite = "internal:RNGIA0"; + } + 304 + { + title = "Automatic Ring"; + sprite = "internal:RNGAA0"; + } + 305 + { + title = "Explosion Ring"; + sprite = "internal:RNGEA0"; + } + 306 + { + title = "Scatter Ring"; + sprite = "internal:RNGSA0"; + } + 307 + { + title = "Grenade Ring"; + sprite = "internal:RNGGA0"; + } + 308 + { + title = "CTF Team Ring (Red)"; + sprite = "internal:RRNGA0"; + width = 16; + } + 309 + { + title = "CTF Team Ring (Blue)"; + sprite = "internal:BRNGA0"; + width = 16; + } + 330 + { + title = "Bounce Ring Panel"; + sprite = "internal:PIKBA0"; + } + 331 + { + title = "Rail Ring Panel"; + sprite = "internal:PIKRA0"; + } + 332 + { + title = "Automatic Ring Panel"; + sprite = "internal:PIKAA0"; + } + 333 + { + title = "Explosion Ring Panel"; + sprite = "internal:PIKEA0"; + } + 334 + { + title = "Scatter Ring Panel"; + sprite = "internal:PIKSA0"; + } + 335 + { + title = "Grenade Ring Panel"; + sprite = "internal:PIKGA0"; + } +} + +collectibles +{ + color = 10; // Light_Green + title = "Other Collectibles"; + width = 16; + height = 32; + sort = 1; + sprite = "CEMGA0"; + + 310 + { + title = "CTF Red Flag"; + sprite = "RFLGA0"; + width = 24; + height = 64; + } + 311 + { + title = "CTF Blue Flag"; + sprite = "BFLGA0"; + width = 24; + height = 64; + } + 312 + { + title = "Emerald Token"; + sprite = "TOKEA0"; + width = 16; + height = 32; + flags8height = 24; + flags8text = "[8] Float"; + } + 313 + { + title = "Chaos Emerald 1 (Green)"; + sprite = "CEMGA0"; + } + 314 + { + title = "Chaos Emerald 2 (Purple)"; + sprite = "CEMGB0"; + } + 315 + { + title = "Chaos Emerald 3 (Blue)"; + sprite = "CEMGC0"; + } + 316 + { + title = "Chaos Emerald 4 (Cyan)"; + sprite = "CEMGD0"; + } + 317 + { + title = "Chaos Emerald 5 (Orange)"; + sprite = "CEMGE0"; + } + 318 + { + title = "Chaos Emerald 6 (Red)"; + sprite = "CEMGF0"; + } + 319 + { + title = "Chaos Emerald 7 (Gray)"; + sprite = "CEMGG0"; + } + 320 + { + title = "Emerald Hunt Location"; + sprite = "SHRDA0"; + } + 321 + { + title = "Match Chaos Emerald Spawn"; + sprite = "CEMGA0"; + flags8height = 24; + flags8text = "[8] Float"; + } + 322 + { + title = "Emblem"; + sprite = "EMBMA0"; + width = 16; + height = 30; + flags8height = 24; + flags8text = "[8] Float"; + angletext = "Tag"; + } +} + +boxes +{ + color = 7; // Gray + blocking = 2; + title = "Monitors"; + width = 18; + height = 40; + flags1text = "[1] Run Linedef Executor on pop"; + flags4text = "[4] Random (Strong)"; + flags8text = "[8] Random (Weak)"; + + 400 + { + title = "Super Ring (10 Rings)"; + sprite = "TVRIA0"; + } + 401 + { + title = "Pity Shield"; + sprite = "TVPIA0"; + } + 402 + { + title = "Attraction Shield"; + sprite = "TVATA0"; + } + 403 + { + title = "Force Shield"; + sprite = "TVFOA0"; + } + 404 + { + title = "Armageddon Shield"; + sprite = "TVARA0"; + } + 405 + { + title = "Whirlwind Shield"; + sprite = "TVWWA0"; + } + 406 + { + title = "Elemental Shield"; + sprite = "TVELA0"; + } + 407 + { + title = "Super Sneakers"; + sprite = "TVSSA0"; + } + 408 + { + title = "Invincibility"; + sprite = "TVIVA0"; + } + 409 + { + title = "Extra Life"; + sprite = "TV1UA0"; + flags4text = "[4] Random (Strong) / 10k points"; + flags8text = "[8] Random (Weak) / 10k points"; + } + 410 + { + title = "Eggman"; + sprite = "TVEGA0"; + flags4text = "[4] Special"; + flags8text = "[8] Ambush"; + } + 411 + { + title = "Teleporter"; + sprite = "TVMXA0"; + } + 413 + { + title = "Gravity Boots"; + sprite = "TVGVA0"; + flags4text = "[4] Special"; + flags8text = "[8] Ambush"; + } + 414 + { + title = "CTF Team Ring Monitor (Red)"; + sprite = "TRRIA0"; + flags4text = "[4] Special"; + flags8text = "[8] Ambush"; + } + 415 + { + title = "CTF Team Ring Monitor (Blue)"; + sprite = "TBRIA0"; + flags4text = "[4] Special"; + flags8text = "[8] Ambush"; + } + 416 + { + title = "Recycler"; + sprite = "TVRCA0"; + } + 418 + { + title = "Score (1,000 Points)"; + sprite = "TV1KA0"; + flags4text = "[4] Special"; + flags8text = "[8] Ambush"; + } + 419 + { + title = "Score (10,000 Points)"; + sprite = "TVTKA0"; + flags4text = "[4] Special"; + flags8text = "[8] Ambush"; + } + 420 + { + title = "Flame Shield"; + sprite = "TVFLA0"; + } + 421 + { + title = "Water Shield"; + sprite = "TVBBA0"; + } + 422 + { + title = "Lightning Shield"; + sprite = "TVZPA0"; + } +} + +boxes2 +{ + color = 18; // Gold + blocking = 2; + title = "Monitors (Respawning)"; + width = 20; + height = 44; + flags1text = "[1] Run Linedef Executor on pop"; + + 431 + { + title = "Pity Shield (Respawn)"; + sprite = "TVPIB0"; + } + 432 + { + title = "Attraction Shield (Respawn)"; + sprite = "TVATB0"; + } + 433 + { + title = "Force Shield (Respawn)"; + sprite = "TVFOB0"; + } + 434 + { + title = "Armageddon Shield (Respawn)"; + sprite = "TVARB0"; + } + 435 + { + title = "Whirlwind Shield (Respawn)"; + sprite = "TVWWB0"; + } + 436 + { + title = "Elemental Shield (Respawn)"; + sprite = "TVELB0"; + } + 437 + { + title = "Super Sneakers (Respawn)"; + sprite = "TVSSB0"; + } + 438 + { + title = "Invincibility (Respawn)"; + sprite = "TVIVB0"; + } + 440 + { + title = "Eggman (Respawn)"; + sprite = "TVEGB0"; + } + 443 + { + title = "Gravity Boots (Respawn)"; + sprite = "TVGVB0"; + } + 450 + { + title = "Flame Shield (Respawn)"; + sprite = "TVFLB0"; + } + 451 + { + title = "Water Shield (Respawn)"; + sprite = "TVBBB0"; + } + 452 + { + title = "Lightning Shield (Respawn)"; + sprite = "TVZPB0"; + } +} + +generic +{ + color = 11; // Light_Cyan + title = "Generic Items & Hazards"; + + 500 + { + title = "Air Bubble Patch"; + sprite = "BUBLE0"; + width = 8; + height = 16; + flags8text = "[8] No distance check"; + } + 501 + { + title = "Signpost"; + sprite = "SIGND0"; + width = 8; + height = 32; + } + 502 + { + arrow = 1; + title = "Star Post"; + sprite = "STPTA0M0"; + width = 64; + height = 128; + angletext = "Angle/Order"; + } + 520 + { + title = "Bomb Sphere"; + sprite = "SPHRD0"; + width = 16; + height = 24; + flags8height = 24; + flags8text = "[8] Float"; + unflippable = true; + } + 521 + { + title = "Spikeball"; + sprite = "SPIKA0"; + width = 12; + height = 8; + flags8height = 24; + flags8text = "[8] Float"; + } + 522 + { + title = "Wall Spike"; + sprite = "WSPKALAR"; + width = 16; + height = 14; + flags1text = "[1] Start retracted"; + flags4text = "[4] Retractable"; + flags8text = "[8] Intangible"; + parametertext = "Initial delay"; + } + 523 + { + title = "Spike"; + sprite = "USPKA0"; + width = 8; + height = 32; + flags1text = "[1] Start retracted"; + flags4text = "[4] Retractable"; + flags8text = "[8] Intangible"; + angletext = "Retraction interval"; + parametertext = "Initial delay"; + } + 1130 + { + title = "Small Mace"; + sprite = "SMCEA0"; + width = 17; + height = 34; + } + 1131 + { + title = "Big Mace"; + sprite = "BMCEA0"; + width = 34; + height = 68; + } + 1136 + { + title = "Small Fireball"; + sprite = "SFBRA0"; + width = 17; + height = 34; + } + 1137 + { + title = "Large Fireball"; + sprite = "BFBRA0"; + width = 34; + height = 68; + } +} + +springs +{ + color = 12; // Light_Red + title = "Springs and Fans"; + width = 20; + height = 16; + sprite = "RSPRD2"; + + 540 + { + title = "Fan"; + sprite = "FANSA0D0"; + width = 16; + height = 8; + flags4text = "[4] Invisible"; + flags8text = "[8] No distance check"; + angletext = "Lift height"; + } + 541 + { + title = "Gas Jet"; + sprite = "STEMD0"; + flags8text = "[8] No sounds"; + width = 32; + } + 542 + { + title = "Bumper"; + sprite = "BUMPA0"; + width = 32; + height = 64; + angletext = "Strength"; + } + 543 + { + title = "Balloon"; + sprite = "BLONA0"; + width = 32; + height = 64; + flags8text = "[8] Respawn"; + angletext = "Color"; + } + 550 + { + title = "Yellow Spring"; + sprite = "SPRYA0"; + } + 551 + { + title = "Red Spring"; + sprite = "SPRRA0"; + } + 552 + { + title = "Blue Spring"; + sprite = "SPRBA0"; + } + 555 + { + arrow = 1; + title = "Diagonal Yellow Spring"; + sprite = "YSPRD2"; + width = 16; + flags4text = "[4] Ignore gravity"; + flags8text = "[8] Rotate 22.5° CCW"; + } + 556 + { + arrow = 1; + title = "Diagonal Red Spring"; + sprite = "RSPRD2"; + width = 16; + flags4text = "[4] Ignore gravity"; + flags8text = "[8] Rotate 22.5° CCW"; + } + 557 + { + arrow = 1; + title = "Diagonal Blue Spring"; + sprite = "BSPRD2"; + width = 16; + flags4text = "[4] Ignore gravity"; + flags8text = "[8] Rotate 22.5° CCW"; + } + 558 + { + arrow = 1; + title = "Horizontal Yellow Spring"; + sprite = "SSWYD2D8"; + flags8height = 16; + flags8text = "[8] Float"; + width = 16; + height = 32; + } + 559 + { + arrow = 1; + title = "Horizontal Red Spring"; + sprite = "SSWRD2D8"; + flags8height = 16; + flags8text = "[8] Float"; + width = 16; + height = 32; + } + 560 + { + arrow = 1; + title = "Horizontal Blue Spring"; + sprite = "SSWBD2D8"; + flags8height = 16; + flags8text = "[8] Float"; + width = 16; + height = 32; + } + 1134 + { + title = "Yellow Spring Ball"; + sprite = "YSPBA0"; + width = 17; + height = 34; + } + 1135 + { + title = "Red Spring Ball"; + sprite = "RSPBA0"; + width = 17; + height = 34; + } + 544 + { + arrow = 1; + title = "Yellow Boost Panel"; + sprite = "BSTYA0"; + flags8text = "[8] Force spin"; + width = 28; + height = 2; + } + 545 + { + arrow = 1; + title = "Red Boost Panel"; + sprite = "BSTRA0"; + flags8text = "[8] Force spin"; + width = 28; + height = 2; + } +} + +patterns +{ + color = 5; // Magenta + arrow = 1; + title = "Special Placement Patterns"; + width = 16; + height = 384; + sprite = "RINGA0"; + + 600 + { + arrow = 0; + title = "5 Vertical Rings (Yellow Spring)"; + sprite = "RINGA0"; + } + 601 + { + arrow = 0; + title = "5 Vertical Rings (Red Spring)"; + sprite = "RINGA0"; + height = 1024; + } + 602 + { + title = "5 Diagonal Rings (Yellow Spring)"; + sprite = "RINGA0"; + height = 32; + } + 603 + { + title = "10 Diagonal Rings (Red Spring)"; + sprite = "RINGA0"; + height = 32; + } + 604 + { + title = "Circle of Rings"; + sprite = "RINGA0"; + width = 96; + height = 192; + unflippable = true; + centerHitbox = true; + } + 605 + { + title = "Circle of Rings (Big)"; + sprite = "RINGA0"; + width = 192; + unflippable = true; + centerHitbox = true; + } + 606 + { + title = "Circle of Blue Spheres"; + sprite = "SPHRA0"; + width = 96; + height = 192; + unflippable = true; + centerHitbox = true; + } + 607 + { + title = "Circle of Blue Spheres (Big)"; + sprite = "SPHRA0"; + width = 192; + unflippable = true; + centerHitbox = true; + } + 608 + { + title = "Circle of Rings and Spheres"; + sprite = "SPHRA0"; + width = 96; + height = 192; + unflippable = true; + centerHitbox = true; + } + 609 + { + title = "Circle of Rings and Spheres (Big)"; + sprite = "SPHRA0"; + width = 192; + unflippable = true; + centerHitbox = true; + } +} + +invisible +{ + color = 15; // White + title = "Misc. Invisible"; + width = 0; + height = 0; + sprite = "UNKNA0"; + sort = 1; + fixedsize = true; + blocking = 0; + + 700 + { + title = "Water Ambience A (Large)"; + sprite = "internal:ambiance"; + } + + 701 + { + title = "Water Ambience B (Large)"; + sprite = "internal:ambiance"; + } + + 702 + { + title = "Water Ambience C (Medium)"; + sprite = "internal:ambiance"; + } + + 703 + { + title = "Water Ambience D (Medium)"; + sprite = "internal:ambiance"; + } + + 704 + { + title = "Water Ambience E (Small)"; + sprite = "internal:ambiance"; + } + + 705 + { + title = "Water Ambience F (Small)"; + sprite = "internal:ambiance"; + } + + 706 + { + title = "Water Ambience G (Extra Large)"; + sprite = "internal:ambiance"; + } + + 707 + { + title = "Water Ambience H (Extra Large)"; + sprite = "internal:ambiance"; + } + + 708 + { + title = "Disco Ambience"; + sprite = "internal:ambiance"; + } + + 709 + { + title = "Volcano Ambience"; + sprite = "internal:ambiance"; + } + + 710 + { + title = "Machine Ambience"; + sprite = "internal:ambiance"; + } + + 750 + { + title = "Slope Vertex"; + sprite = "internal:vertexslope"; + angletext = "Tag"; + } + + 751 + { + arrow = 1; + title = "Teleport Destination"; + sprite = "internal:tele"; + } + + 752 + { + arrow = 1; + title = "Alternate View Point"; + sprite = "internal:view"; + } + + 753 + { + title = "Zoom Tube Waypoint"; + sprite = "internal:zoom"; + angletext = "Order"; + } + + 754 + { + title = "Push Point"; + flags4text = "[4] Fades using XY"; + flags8text = "[8] Push using XYZ"; + sprite = "GWLGA0"; + angletext = "Radius"; + } + 755 + { + title = "Pull Point"; + flags4text = "[4] Fades using XY"; + flags8text = "[8] Pull using XYZ"; + sprite = "GWLRA0"; + angletext = "Radius"; + } + 756 + { + title = "Blast Linedef Executor"; + sprite = "TOADA0"; + width = 32; + height = 16; + } + 757 + { + title = "Fan Particle Generator"; + sprite = "PRTLA0"; + width = 8; + height = 16; + angletext = "Tag"; + } + 758 + { + title = "Object Angle Anchor"; + sprite = "internal:view"; + } + 760 + { + title = "PolyObject Anchor"; + sprite = "internal:polyanchor"; + angletext = "ID"; + } + + 761 + { + title = "PolyObject Spawn Point"; + sprite = "internal:polycenter"; + angletext = "ID"; + } + + 762 + { + title = "PolyObject Spawn Point (Crush)"; + sprite = "internal:polycentercrush"; + angletext = "ID"; + } + 780 + { + title = "Skybox View Point"; + sprite = "internal:skyb"; + flags4text = "[4] In-map centerpoint"; + parametertext = "ID"; + } +} + +greenflower +{ + color = 10; // Green + title = "Greenflower"; + + 800 + { + title = "GFZ Flower"; + sprite = "FWR1A0"; + width = 16; + height = 40; + } + 801 + { + title = "Sunflower"; + sprite = "FWR2A0"; + width = 16; + height = 96; + } + 802 + { + title = "Budding Flower"; + sprite = "FWR3A0"; + width = 8; + height = 32; + } + 803 + { + title = "Blueberry Bush"; + sprite = "BUS3A0"; + width = 16; + height = 32; + } + 804 + { + title = "Berry Bush"; + sprite = "BUS1A0"; + width = 16; + height = 32; + } + 805 + { + title = "Bush"; + sprite = "BUS2A0"; + width = 16; + height = 32; + } + 806 + { + title = "GFZ Tree"; + sprite = "TRE1A0"; + width = 20; + height = 128; + } + 807 + { + title = "GFZ Berry Tree"; + sprite = "TRE1B0"; + width = 20; + height = 128; + } + 808 + { + title = "GFZ Cherry Tree"; + sprite = "TRE1C0"; + width = 20; + height = 128; + } + 809 + { + title = "Checkered Tree"; + sprite = "TRE2A0"; + width = 20; + height = 200; + } + 810 + { + title = "Checkered Tree (Sunset)"; + sprite = "TRE2B0"; + width = 20; + height = 200; + } + 811 + { + title = "Polygon Tree"; + sprite = "TRE4A0"; + width = 20; + height = 200; + } + 812 + { + title = "Bush Tree"; + sprite = "TRE5A0"; + width = 20; + height = 200; + } + 813 + { + title = "Red Bush Tree"; + sprite = "TRE5B0"; + width = 20; + height = 200; + } +} + +technohill +{ + color = 10; // Green + title = "Techno Hill"; + + 900 + { + title = "THZ Steam Flower"; + sprite = "THZPA0"; + width = 8; + height = 32; + } + 901 + { + title = "Alarm"; + sprite = "ALRMA0"; + width = 8; + height = 16; + hangs = 1; + } + 902 + { + title = "THZ Spin Flower (Red)"; + sprite = "FWR5A0"; + width = 16; + height = 64; + } + 903 + { + title = "THZ Spin Flower (Yellow)"; + sprite = "FWR6A0"; + width = 16; + height = 64; + } + 904 + { + arrow = 1; + title = "Whistlebush"; + sprite = "THZTA0"; + width = 16; + height = 64; + } +} + +deepsea +{ + color = 10; // Green + title = "Deep Sea"; + + 1000 + { + arrow = 1; + blocking = 2; + title = "Gargoyle"; + sprite = "GARGA1"; + width = 16; + height = 40; + flags4text = "[4] Slides when pushed"; + flags8text = "[8] Not pushable"; + } + 1009 + { + arrow = 1; + blocking = 2; + title = "Gargoyle (Big)"; + sprite = "GARGB1"; + width = 32; + height = 80; + flags4text = "[4] Slides when pushed"; + flags8text = "[8] Not pushable"; + } + 1001 + { + title = "Seaweed"; + sprite = "SEWEA0"; + width = 24; + height = 56; + } + 1002 + { + title = "Dripping Water"; + sprite = "DRIPD0"; + width = 8; + height = 16; + hangs = 1; + angletext = "Dripping interval"; + } + 1003 + { + title = "Coral (Green)"; + sprite = "CORLA0"; + width = 29; + height = 40; + } + 1004 + { + title = "Coral (Red)"; + sprite = "CORLB0"; + width = 30; + height = 53; + } + 1005 + { + title = "Coral (Orange)"; + sprite = "CORLC0"; + width = 28; + height = 41; + } + 1006 + { + title = "Blue Crystal"; + sprite = "BCRYA1"; + width = 8; + height = 16; + } + 1007 + { + title = "Kelp"; + sprite = "KELPA0"; + width = 16; + height = 292; + flags4text = "[4] Double size"; + } + 1008 + { + title = "Stalagmite (DSZ1)"; + sprite = "DSTGA0"; + width = 8; + height = 116; + flags4text = "[4] Double size"; + } + 1010 + { + arrow = 1; + title = "Light Beam"; + sprite = "LIBEARAL"; + width = 16; + height = 16; + } + 1011 + { + title = "Stalagmite (DSZ2)"; + sprite = "DSTGA0"; + width = 8; + height = 116; + flags4text = "[4] Double size"; + } + 1012 + { + arrow = 1; + title = "Big Floating Mine"; + width = 28; + height = 56; + sprite = "BMNEA1"; + } + 1013 + { + title = "Animated Kelp"; + sprite = "ALGAA0"; + width = 48; + height = 120; + } + 1014 + { + title = "Large Coral (Brown)"; + sprite = "CORLD0"; + width = 56; + height = 112; + } + 1015 + { + title = "Large Coral (Beige)"; + sprite = "CORLE0"; + width = 56; + height = 112; + } +} + +castleeggman +{ + color = 10; // Green + title = "Castle Eggman"; + + 1100 + { + title = "Chain (Decorative)"; + sprite = "CHANA0"; + width = 4; + height = 128; + hangs = 1; + } + 1101 + { + title = "Torch"; + sprite = "FLAMA0E0"; + width = 8; + height = 32; + flags1text = "[1] Add corona"; + } + 1102 + { + arrow = 1; + blocking = 2; + title = "Eggman Statue"; + sprite = "ESTAA1"; + width = 32; + height = 240; + flags1text = "[1] Solid gold"; + flags4text = "[4] Slides when pushed"; + flags8text = "[8] Not pushable"; + } + 1103 + { + title = "CEZ Flower"; + sprite = "FWR4A0"; + width = 16; + height = 40; + } + 1104 + { + title = "Mace Spawnpoint"; + sprite = "SMCEA0"; + width = 17; + height = 34; + flags4text = "[4] No sounds"; + flags8text = "[8] Double size"; + angletext = "Tag"; + } + 1105 + { + title = "Chain with Maces Spawnpoint"; + sprite = "SMCEA0"; + width = 17; + height = 34; + flags4text = "[4] No sounds"; + flags8text = "[8] Double size"; + angletext = "Tag"; + } + 1106 + { + title = "Chained Spring Spawnpoint"; + sprite = "YSPBA0"; + width = 17; + height = 34; + flags4text = "[4] No sounds"; + flags8text = "[8] Red spring"; + angletext = "Tag"; + } + 1107 + { + title = "Chain Spawnpoint"; + sprite = "BMCHA0"; + width = 17; + height = 34; + flags8text = "[8] Double size"; + angletext = "Tag"; + } + 1108 + { + arrow = 1; + title = "Hidden Chain Spawnpoint"; + sprite = "internal:chain3"; + width = 17; + height = 34; + flags8text = "[8] Double size"; + } + 1109 + { + title = "Firebar Spawnpoint"; + sprite = "BFBRA0"; + width = 17; + height = 34; + flags4text = "[4] No sounds"; + flags8text = "[8] Double size"; + angletext = "Tag"; + } + 1110 + { + title = "Custom Mace Spawnpoint"; + sprite = "SMCEA0"; + width = 17; + height = 34; + flags4text = "[4] No sounds"; + angletext = "Tag"; + } + 1111 + { + arrow = 1; + blocking = 2; + title = "Crawla Statue"; + sprite = "CSTAA1"; + width = 16; + height = 40; + flags4text = "[4] Slides when pushed"; + flags8text = "[8] Not pushable"; + } + 1112 + { + arrow = 1; + blocking = 2; + title = "Lance-a-Bot Statue"; + sprite = "CBBSA1"; + width = 32; + height = 72; + flags4text = "[4] Slides when pushed"; + flags8text = "[8] Not pushable"; + } + 1114 + { + title = "Pine Tree"; + sprite = "PINEA0"; + width = 16; + height = 628; + } + 1115 + { + title = "CEZ Shrub (Small)"; + sprite = "CEZBA0"; + width = 16; + height = 24; + } + 1116 + { + title = "CEZ Shrub (Large)"; + sprite = "CEZBB0"; + width = 32; + height = 48; + } + 1117 + { + arrow = 1; + title = "Pole Banner (Red)"; + sprite = "BANRA0"; + width = 40; + height = 224; + } + 1118 + { + arrow = 1; + title = "Pole Banner (Blue)"; + sprite = "BANRA0"; + width = 40; + height = 224; + } + 1119 + { + title = "Candle"; + sprite = "CNDLA0"; + width = 8; + height = 48; + flags1text = "[1] Add corona"; + } + 1120 + { + title = "Candle Pricket"; + sprite = "CNDLB0"; + width = 8; + height = 176; + flags1text = "[1] Add corona"; + } + 1121 + { + title = "Flame Holder"; + sprite = "FLMHA0"; + width = 24; + height = 80; + flags1text = "[1] Add corona"; + flags4text = "[4] No flame"; + } + 1122 + { + title = "Fire Torch"; + sprite = "CTRCA0"; + width = 16; + height = 80; + } + 1123 + { + title = "Cannonball Launcher"; + sprite = "internal:cannonball"; + width = 8; + height = 16; + } + 1124 + { + blocking = 2; + title = "Cannonball"; + sprite = "CBLLA0"; + width = 20; + height = 40; + flags4text = "[4] Slides when pushed"; + flags8text = "[8] Not pushable"; + } + 1125 + { + title = "Brambles"; + sprite = "CABRALAR"; + width = 48; + height = 32; + } + 1126 + { + title = "Invisible Lockon Object"; + sprite = "LCKNC0"; + width = 16; + height = 32; + } + 1127 + { + title = "Spectator Eggrobo"; + sprite = "EGR1A1"; + width = 20; + height = 72; + } + 1128 + { + arrow = 1; + title = "Waving Flag (Red)"; + sprite = "CFLGA0"; + width = 8; + height = 208; + } + 1129 + { + arrow = 1; + title = "Waving Flag (Blue)"; + sprite = "CFLGA0"; + width = 8; + height = 208; + } +} + +aridcanyon +{ + color = 10; // Green + title = "Arid Canyon"; + + 1200 + { + title = "Tumbleweed (Big)"; + sprite = "BTBLA0"; + width = 24; + height = 48; + flags8text = "[8] Moves perpetually"; + } + 1201 + { + title = "Tumbleweed (Small)"; + sprite = "STBLA0"; + width = 12; + height = 24; + flags8text = "[8] Moves perpetually"; + } + 1202 + { + arrow = 1; + title = "Rock Spawner"; + sprite = "ROIAA0"; + width = 8; + height = 16; + angletext = "Tag"; + } + 1203 + { + title = "Tiny Red Flower Cactus"; + sprite = "CACTA0"; + width = 13; + height = 24; + } + 1204 + { + title = "Small Red Flower Cactus"; + sprite = "CACTB0"; + width = 15; + height = 52; + } + 1205 + { + title = "Tiny Blue Flower Cactus"; + sprite = "CACTC0"; + width = 13; + height = 24; + } + 1206 + { + title = "Small Blue Flower Cactus"; + sprite = "CACTD0"; + width = 15; + height = 52; + } + 1207 + { + title = "Prickly Pear"; + sprite = "CACTE0"; + width = 32; + height = 96; + } + 1208 + { + title = "Barrel Cactus"; + sprite = "CACTF0"; + width = 20; + height = 128; + } + 1209 + { + title = "Tall Barrel Cactus"; + sprite = "CACTG0"; + width = 24; + height = 224; + } + 1210 + { + title = "Armed Cactus"; + sprite = "CACTH0"; + width = 24; + height = 256; + } + 1211 + { + title = "Ball Cactus"; + sprite = "CACTI0"; + width = 48; + height = 96; + } + 1212 + { + title = "Caution Sign"; + sprite = "WWSGAR"; + width = 22; + height = 64; + } + 1213 + { + title = "Cacti Sign"; + sprite = "WWS2AR"; + width = 22; + height = 64; + } + 1214 + { + title = "Sharp Turn Sign"; + sprite = "WWS3ALAR"; + width = 16; + height = 192; + } + 1215 + { + title = "Mine Oil Lamp"; + sprite = "OILLA0"; + width = 22; + height = 64; + hangs = 1; + } + 1216 + { + title = "TNT Barrel"; + sprite = "BARRA1"; + width = 24; + height = 63; + } + 1217 + { + title = "TNT Proximity Shell"; + sprite = "REMTA0"; + width = 64; + height = 40; + } + 1218 + { + title = "Dust Devil"; + sprite = "TAZDCR"; + width = 80; + height = 416; + } + 1219 + { + title = "Minecart Spawner"; + sprite = "MCRTCLFR"; + width = 22; + height = 32; + } + 1220 + { + title = "Minecart Stopper"; + sprite = "MCRTIR"; + width = 32; + height = 32; + } + 1221 + { + title = "Minecart Saloon Door"; + sprite = "SALDARAL"; + width = 96; + height = 160; + flags8text = "[8] Allow non-minecart players"; + } + 1222 + { + title = "Train Cameo Spawner"; + sprite = "TRAEBRBL"; + width = 28; + height = 32; + } + 1223 + { + title = "Train Dust Spawner"; + sprite = "ADSTA0"; + width = 4; + height = 4; + } + 1224 + { + title = "Train Steam Spawner"; + sprite = "STEAA0"; + width = 4; + height = 4; + } + 1229 + { + title = "Minecart Switch Point"; + sprite = "internal:zoom"; + width = 8; + height = 16; + flags8text = "[8] Enable switching"; + } + 1230 + { + title = "Tiny Cactus"; + sprite = "CACTJ0"; + width = 13; + height = 28; + } + 1231 + { + title = "Small Cactus"; + sprite = "CACTK0"; + width = 15; + height = 60; + } +} + +redvolcano +{ + color = 10; // Green + title = "Red Volcano"; + + 1300 + { + arrow = 1; + title = "Flame Jet (Horizontal)"; + sprite = "internal:flameh"; + width = 16; + height = 40; + flags8text = "[8] Waves vertically"; + angletext = "On/Off time"; + parametertext = "Strength"; + } + 1301 + { + title = "Flame Jet (Vertical)"; + sprite = "internal:flamev"; + width = 16; + height = 40; + flags8text = "[8] Shoot downwards"; + angletext = "On/Off time"; + parametertext = "Strength"; + } + 1302 + { + title = "Spinning Flame Jet (Counter-Clockwise)"; + sprite = "internal:flame2"; + width = 16; + height = 24; + } + 1303 + { + title = "Spinning Flame Jet (Clockwise)"; + sprite = "internal:flame1"; + width = 16; + height = 24; + } + 1304 + { + title = "Lavafall"; + sprite = "LFALF0"; + width = 30; + height = 32; + angletext = "Initial delay"; + flags8text = "[8] Double size"; + } + 1305 + { + title = "Rollout Rock"; + sprite = "PUMIA1A5"; + width = 30; + height = 60; + flags8text = "[8] Non-buoyant"; + } + 1306 + { + title = "Big Fern"; + sprite = "JPLAB0"; + width = 32; + height = 48; + } + 1307 + { + title = "Jungle Palm"; + sprite = "JPLAC0"; + width = 32; + height = 48; + } + 1308 + { + title = "Torch Flower"; + sprite = "TFLOA0"; + width = 14; + height = 110; + } + 1309 + { + title = "RVZ1 Wall Vine (Long)"; + sprite = "WVINALAR"; + width = 1; + height = 288; + } + 1310 + { + title = "RVZ1 Wall Vine (Short)"; + sprite = "WVINBLBR"; + width = 1; + height = 288; + } +} + +botanicserenity +{ + color = 10; // Green + title = "Botanic Serenity"; + width = 16; + height = 32; + sprite = "BSZ1A0"; + 1400 + { + title = "Tall Flower (Red)"; + sprite = "BSZ1A0"; + } + 1401 + { + title = "Tall Flower (Purple)"; + sprite = "BSZ1B0"; + } + 1402 + { + title = "Tall Flower (Blue)"; + sprite = "BSZ1C0"; + } + 1403 + { + title = "Tall Flower (Cyan)"; + sprite = "BSZ1D0"; + } + 1404 + { + title = "Tall Flower (Yellow)"; + sprite = "BSZ1E0"; + } + 1405 + { + title = "Tall Flower (Orange)"; + sprite = "BSZ1F0"; + } + 1410 + { + title = "Medium Flower (Red)"; + sprite = "BSZ2A0"; + } + 1411 + { + title = "Medium Flower (Purple)"; + sprite = "BSZ2B0"; + } + 1412 + { + title = "Medium Flower (Blue)"; + sprite = "BSZ2C0"; + } + 1413 + { + title = "Medium Flower (Cyan)"; + sprite = "BSZ2D0"; + } + 1414 + { + title = "Medium Flower (Yellow)"; + sprite = "BSZ2E0"; + } + 1415 + { + title = "Medium Flower (Orange)"; + sprite = "BSZ2F0"; + } + 1420 + { + title = "Short Flower (Red)"; + sprite = "BSZ3A0"; + } + 1421 + { + title = "Short Flower (Purple)"; + sprite = "BSZ3B0"; + } + 1422 + { + title = "Short Flower (Blue)"; + sprite = "BSZ3C0"; + } + 1423 + { + title = "Short Flower (Cyan)"; + sprite = "BSZ3D0"; + } + 1424 + { + title = "Short Flower (Yellow)"; + sprite = "BSZ3E0"; + } + 1425 + { + title = "Short Flower (Orange)"; + sprite = "BSZ3F0"; + } + 1430 + { + title = "Tulip (Red)"; + sprite = "BST1A0"; + } + 1431 + { + title = "Tulip (Purple)"; + sprite = "BST2A0"; + } + 1432 + { + title = "Tulip (Blue)"; + sprite = "BST3A0"; + } + 1433 + { + title = "Tulip (Cyan)"; + sprite = "BST4A0"; + } + 1434 + { + title = "Tulip (Yellow)"; + sprite = "BST5A0"; + } + 1435 + { + title = "Tulip (Orange)"; + sprite = "BST6A0"; + } + 1440 + { + title = "Cluster (Red)"; + sprite = "BSZ5A0"; + } + 1441 + { + title = "Cluster (Purple)"; + sprite = "BSZ5B0"; + } + 1442 + { + title = "Cluster (Blue)"; + sprite = "BSZ5C0"; + } + 1443 + { + title = "Cluster (Cyan)"; + sprite = "BSZ5D0"; + } + 1444 + { + title = "Cluster (Yellow)"; + sprite = "BSZ5E0"; + } + 1445 + { + title = "Cluster (Orange)"; + sprite = "BSZ5F0"; + } + 1450 + { + title = "Bush (Red)"; + sprite = "BSZ6A0"; + } + 1451 + { + title = "Bush (Purple)"; + sprite = "BSZ6B0"; + } + 1452 + { + title = "Bush (Blue)"; + sprite = "BSZ6C0"; + } + 1453 + { + title = "Bush (Cyan)"; + sprite = "BSZ6D0"; + } + 1454 + { + title = "Bush (Yellow)"; + sprite = "BSZ6E0"; + } + 1455 + { + title = "Bush (Orange)"; + sprite = "BSZ6F0"; + } + 1460 + { + title = "Vine (Red)"; + sprite = "BSZ7A0"; + } + 1461 + { + title = "Vine (Purple)"; + sprite = "BSZ7B0"; + } + 1462 + { + title = "Vine (Blue)"; + sprite = "BSZ7C0"; + } + 1463 + { + title = "Vine (Cyan)"; + sprite = "BSZ7D0"; + } + 1464 + { + title = "Vine (Yellow)"; + sprite = "BSZ7E0"; + } + 1465 + { + title = "Vine (Orange)"; + sprite = "BSZ7F0"; + } + 1470 + { + title = "BSZ Shrub"; + sprite = "BSZ8A0"; + } + 1471 + { + title = "BSZ Clover"; + sprite = "BSZ8B0"; + } + 1473 + { + title = "Palm Tree (Big)"; + width = 16; + height = 160; + sprite = "BSZ8D0"; + } + 1475 + { + title = "Palm Tree (Small)"; + width = 16; + height = 80; + sprite = "BSZ8F0"; + } +} + +azuretemple +{ + color = 10; // Green + title = "Azure Temple"; + + 1500 + { + arrow = 1; + blocking = 2; + title = "Glaregoyle"; + sprite = "BGARA1"; + width = 16; + height = 40; + flags4text = "[4] Slides when pushed"; + flags8text = "[8] Not pushable"; + } + 1501 + { + arrow = 1; + blocking = 2; + title = "Glaregoyle (Up)"; + sprite = "BGARA1"; + width = 16; + height = 40; + flags4text = "[4] Slides when pushed"; + flags8text = "[8] Not pushable"; + } + 1502 + { + arrow = 1; + blocking = 2; + title = "Glaregoyle (Down)"; + sprite = "BGARA1"; + width = 16; + height = 40; + flags4text = "[4] Slides when pushed"; + flags8text = "[8] Not pushable"; + } + 1503 + { + arrow = 1; + blocking = 2; + title = "Glaregoyle (Long)"; + sprite = "BGARA1"; + width = 16; + height = 40; + flags4text = "[4] Slides when pushed"; + flags8text = "[8] Not pushable"; + } + 1504 + { + title = "ATZ Target"; + sprite = "RCRYB0"; + width = 24; + height = 32; + } + 1505 + { + title = "Green Flame"; + sprite = "CFLMA0E0"; + width = 8; + height = 32; + } + 1506 + { + arrow = 1; + blocking = 2; + title = "Blue Gargoyle"; + sprite = "BGARD1"; + width = 16; + height = 40; + flags4text = "[4] Slides when pushed"; + flags8text = "[8] Not pushable"; + } +} + +dreamhill +{ + color = 10; // Green + title = "Dream Hill"; + + 1600 + { + title = "Spring Tree"; + sprite = "TRE6A0"; + width = 16; + height = 32; + } + 1601 + { + title = "Shleep"; + sprite = "SHLPA0"; + width = 24; + height = 32; + } + 1602 + { + title = "Pian"; + sprite = "NTPNALAR"; + width = 16; + height = 32; + } +} + +nightstrk +{ + color = 13; // Pink + title = "NiGHTS Track"; + width = 8; + height = 4096; + sprite = "UNKNA0"; + + 1700 + { + title = "Axis"; + sprite = "internal:axis1"; + circle = 1; + unflippable = true; + ignoreZ = true; + flagsvaluetext = "Order"; + angletext = "Radius/Direction"; + parametertext = "Mare"; + } + 1701 + { + title = "Axis Transfer"; + sprite = "internal:axis2"; + unflippable = true; + ignoreZ = true; + flagsvaluetext = "Order"; + parametertext = "Mare"; + } + 1702 + { + title = "Axis Transfer Line"; + sprite = "internal:axis3"; + unflippable = true; + ignoreZ = true; + flagsvaluetext = "Order"; + parametertext = "Mare"; + } + 1710 + { + title = "Ideya Capture"; + sprite = "CAPSA0"; + width = 72; + height = 144; + angletext = "Rings"; + parametertext = "Mare"; + } +} + +nights +{ + color = 13; // Pink + title = "NiGHTS Items"; + width = 16; + height = 32; + + 1703 + { + title = "Ideya Drone"; + sprite = "NDRNA1"; + width = 16; + height = 56; + flags1text = "[1] Align player to middle"; + flags4text = "[4] Align player to top"; + flags8text = "[8] Die upon time up"; + angletext = "Time limit"; + parametertext = "Height"; + } + 1704 + { + arrow = 1; + title = "NiGHTS Bumper"; + sprite = "NBMPG3G7"; + width = 32; + height = 64; + unflippable = true; + flagsvaluetext = "Pitch"; + angletext = "Yaw"; + } + 1705 + { + arrow = 1; + title = "Hoop (Generic)"; + sprite = "HOOPA0"; + width = 80; + height = 160; + unflippable = true; + centerHitbox = true; + flagsvaluetext = "Height"; + angletext = "Pitch/Yaw"; + } + 1706 + { + title = "Blue Sphere"; + sprite = "SPHRA0"; + width = 16; + height = 24; + flags8height = 24; + flags8text = "[8] Float"; + unflippable = true; + } + 1707 + { + title = "Super Paraloop"; + sprite = "NPRUA0"; + flags4text = "[4] Bonus time only"; + flags8text = "[8] Spawn immediately"; + } + 1708 + { + title = "Drill Refill"; + sprite = "NPRUB0"; + flags4text = "[4] Bonus time only"; + flags8text = "[8] Spawn immediately"; + } + 1709 + { + title = "Nightopian Helper"; + sprite = "NPRUC0"; + flags4text = "[4] Bonus time only"; + flags8text = "[8] Spawn immediately"; + } + 1711 + { + title = "Extra Time"; + sprite = "NPRUD0"; + flags4text = "[4] Bonus time only"; + flags8text = "[8] Spawn immediately"; + } + 1712 + { + title = "Link Freeze"; + sprite = "NPRUE0"; + flags4text = "[4] Bonus time only"; + flags8text = "[8] Spawn immediately"; + } + 1713 + { + arrow = 1; + title = "Hoop (Customizable)"; + flags1text = "[1] Radius +16"; + flags2text = "[2] Radius +32"; + flags4text = "[4] Radius +64"; + flags8text = "[8] Radius +128"; + sprite = "HOOPA0"; + width = 80; + height = 160; + unflippable = true; + centerHitbox = true; + } + 1714 + { + title = "Ideya Anchor Point"; + sprite = "internal:axis1"; + width = 8; + height = 16; + parametertext = "Ideya"; + } +} + +mario +{ + color = 6; // Brown + title = "Mario"; + + 1800 + { + title = "Coin"; + sprite = "COINA0"; + width = 16; + height = 24; + flags8height = 24; + flags8text = "[8] Float"; + } + 1801 + { + arrow = 1; + title = "Goomba"; + sprite = "GOOMA0"; + width = 24; + height = 32; + } + 1802 + { + arrow = 1; + title = "Goomba (Blue)"; + sprite = "BGOMA0"; + width = 24; + height = 32; + } + 1803 + { + title = "Fire Flower"; + sprite = "FFWRB0"; + width = 16; + height = 32; + } + 1804 + { + title = "Koopa Shell"; + sprite = "SHLLA1"; + width = 16; + height = 20; + } + 1805 + { + title = "Puma (Jumping Fireball)"; + sprite = "PUMAA0"; + width = 8; + height = 16; + angletext = "Jump strength"; + } + 1806 + { + title = "King Bowser"; + sprite = "KOOPA0"; + width = 16; + height = 48; + } + 1807 + { + title = "Axe"; + sprite = "MAXEA0"; + width = 8; + height = 16; + } + 1808 + { + title = "Bush (Short)"; + sprite = "MUS1A0"; + width = 16; + height = 32; + } + 1809 + { + title = "Bush (Tall)"; + sprite = "MUS2A0"; + width = 16; + height = 32; + } + 1810 + { + title = "Toad"; + sprite = "TOADA0"; + width = 8; + height = 32; + } +} + +christmasdisco +{ + color = 10; // Green + title = "Christmas & Disco"; + + 1850 + { + title = "Christmas Pole"; + sprite = "XMS1A0"; + width = 16; + height = 40; + } + 1851 + { + title = "Candy Cane"; + sprite = "XMS2A0"; + width = 8; + height = 32; + } + 1852 + { + blocking = 2; + title = "Snowman"; + sprite = "XMS3A0"; + width = 16; + height = 64; + flags4text = "[4] Slides when pushed"; + flags8text = "[8] Not pushable"; + } + 1853 + { + blocking = 2; + title = "Snowman (With Hat)"; + sprite = "XMS3B0"; + width = 16; + height = 80; + flags4text = "[4] Slides when pushed"; + flags8text = "[8] Not pushable"; + } + 1854 + { + title = "Lamp Post"; + sprite = "XMS4A0"; + width = 8; + height = 120; + } + 1855 + { + title = "Lamp Post (Snow)"; + sprite = "XMS4B0"; + width = 8; + height = 120; + } + 1856 + { + title = "Hanging Star"; + sprite = "XMS5A0"; + width = 4; + height = 80; + hangs = 1; + } + 1857 + { + title = "Berry Bush (Snow)"; + sprite = "BUS1B0"; + width = 16; + height = 32; + } + 1858 + { + title = "Bush (Snow)"; + sprite = "BUS2B0"; + width = 16; + height = 32; + } + 1859 + { + title = "Blueberry Bush (Snow)"; + sprite = "BUS3B0"; + width = 16; + height = 32; + } + 1875 + { + title = "Disco Ball"; + sprite = "DBALA0"; + width = 16; + height = 54; + hangs = 1; + } + 1876 + { + arrow = 1; + blocking = 2; + title = "Eggman Disco Statue"; + sprite = "ESTAB1"; + width = 20; + height = 96; + flags4text = "[4] Slides when pushed"; + flags8text = "[8] Not pushable"; + } +} + +stalagmites +{ + color = 10; // Green + title = "Stalagmites"; + width = 16; + height = 40; + + 1900 + { + title = "Brown Stalagmite (Tall)"; + sprite = "STLGA0"; + width = 16; + height = 40; + } + 1901 + { + title = "Brown Stalagmite"; + sprite = "STLGB0"; + width = 16; + height = 40; + } + 1902 + { + title = "Orange Stalagmite (Tall)"; + sprite = "STLGC0"; + width = 16; + height = 40; + } + 1903 + { + title = "Orange Stalagmite"; + sprite = "STLGD0"; + width = 16; + height = 40; + } + 1904 + { + title = "Red Stalagmite (Tall)"; + sprite = "STLGE0"; + width = 16; + height = 40; + } + 1905 + { + title = "Red Stalagmite"; + sprite = "STLGF0"; + width = 16; + height = 40; + } + 1906 + { + title = "Gray Stalagmite (Tall)"; + sprite = "STLGG0"; + width = 24; + height = 96; + } + 1907 + { + title = "Gray Stalagmite"; + sprite = "STLGH0"; + width = 16; + height = 40; + } + 1908 + { + title = "Blue Stalagmite (Tall)"; + sprite = "STLGI0"; + width = 16; + height = 40; + } + 1909 + { + title = "Blue Stalagmite"; + sprite = "STLGJ0"; + width = 16; + height = 40; + } +} + +hauntedheights +{ + color = 10; // Green + title = "Haunted Heights"; + + 2000 + { + title = "Smashing Spikeball"; + sprite = "FMCEA0"; + width = 18; + height = 28; + angletext = "Initial delay"; + } + 2001 + { + title = "HHZ Grass"; + sprite = "HHZMA0"; + width = 16; + height = 40; + } + 2002 + { + title = "HHZ Tentacle 1"; + sprite = "HHZMB0"; + width = 16; + height = 40; + } + 2003 + { + title = "HHZ Tentacle 2"; + sprite = "HHZMC0"; + width = 16; + height = 40; + } + 2004 + { + title = "HHZ Stalagmite (Tall)"; + sprite = "HHZME0"; + width = 16; + height = 40; + } + 2005 + { + title = "HHZ Stalagmite (Short)"; + sprite = "HHZMF0"; + width = 16; + height = 40; + } + 2006 + { + title = "Jack-o'-lantern 1"; + sprite = "PUMKA0"; + width = 16; + height = 40; + flags1text = "Don't flicker"; + } + 2007 + { + title = "Jack-o'-lantern 2"; + sprite = "PUMKB0"; + width = 16; + height = 40; + flags1text = "Don't flicker"; + } + 2008 + { + title = "Jack-o'-lantern 3"; + sprite = "PUMKC0"; + width = 16; + height = 40; + flags1text = "Don't flicker"; + } + 2009 + { + title = "Purple Mushroom"; + sprite = "SHRMD0"; + width = 16; + height = 48; + } + 2010 + { + title = "HHZ Tree"; + sprite = "HHPLC0"; + width = 12; + height = 40; + } +} + +frozenhillside +{ + color = 10; // Green + title = "Frozen Hillside"; + + 2100 + { + title = "Ice Shard (Small)"; + sprite = "FHZIA0"; + width = 8; + height = 32; + } + 2101 + { + title = "Ice Shard (Large)"; + sprite = "FHZIB0"; + width = 8; + height = 32; + } + 2102 + { + title = "Crystal Tree (Aqua)"; + sprite = "TRE3A0"; + width = 20; + height = 200; + } + 2103 + { + title = "Crystal Tree (Pink)"; + sprite = "TRE3B0"; + width = 20; + height = 200; + } + 2104 + { + title = "Amy Cameo"; + sprite = "ROSYA1"; + width = 16; + height = 48; + flags1text = "[1] Grayscale mode"; + } + 2105 + { + title = "Mistletoe"; + sprite = "XMS6A0"; + width = 52; + height = 106; + } +} + +flickies +{ + color = 10; // Green + title = "Flickies"; + width = 8; + height = 20; + flags1text = "[1] Move aimlessly"; + flags4text = "[4] No movement"; + flags8text = "[8] Hop"; + angletext = "Radius"; + + 2200 + { + title = "Bluebird"; + sprite = "FL01A1"; + } + 2201 + { + title = "Rabbit"; + sprite = "FL02A1"; + } + 2202 + { + title = "Chicken"; + sprite = "FL03A1"; + } + 2203 + { + title = "Seal"; + sprite = "FL04A1"; + } + 2204 + { + title = "Pig"; + sprite = "FL05A1"; + } + 2205 + { + title = "Chipmunk"; + sprite = "FL06A1"; + } + 2206 + { + title = "Penguin"; + sprite = "FL07A1"; + } + 2207 + { + title = "Fish"; + sprite = "FL08A1"; + parametertext = "Color"; + } + 2208 + { + title = "Ram"; + sprite = "FL09A1"; + } + 2209 + { + title = "Puffin"; + sprite = "FL10A1"; + } + 2210 + { + title = "Cow"; + sprite = "FL11A1"; + } + 2211 + { + title = "Rat"; + sprite = "FL12A1"; + } + 2212 + { + title = "Bear"; + sprite = "FL13A1"; + } + 2213 + { + title = "Dove"; + sprite = "FL14A1"; + } + 2214 + { + title = "Cat"; + sprite = "FL15A1"; + } + 2215 + { + title = "Canary"; + sprite = "FL16A1"; + } + 2216 + { + title = "Spider"; + sprite = "FS01A1"; + } + 2217 + { + title = "Bat"; + sprite = "FS02A0"; + } +} \ No newline at end of file diff --git a/extras/conf/SRB2_22Doom.cfg b/extras/conf/SRB2_22Doom.cfg new file mode 100644 index 000000000..65e49d387 --- /dev/null +++ b/extras/conf/SRB2_22Doom.cfg @@ -0,0 +1,38 @@ +/************************************************************************\ + Zone Builder Game Configuration for Sonic Robo Blast 2 Version 2.2 +\************************************************************************/ + +// This is required to prevent accidental use of a different configuration +type = "Doom Builder 2 Game Configuration"; + +// This is the title to show for this game +game = "Sonic Robo Blast 2 - 2.2 (Doom format)"; + +// This is the simplified game engine/sourceport name +engine = "zdoom"; + +// Settings common to all games and all map formats +include("Includes\\SRB222_common.cfg", "common"); + +// Settings common to Doom map format +include("Includes\\SRB222_common.cfg", "mapformat_doom"); + +include("Includes\\Game_SRB222.cfg"); + +// Script lumps detection +scriptlumpnames +{ + include("Includes\\SRB222_misc.cfg", "scriptlumpnames"); +} + +// THING TYPES +thingtypes +{ + include("Includes\\SRB222_things.cfg"); +} + +//Default things filters +thingsfilters +{ + include("Includes\\SRB222_misc.cfg", "thingsfilters"); +} \ No newline at end of file diff --git a/extras/conf/SRB2_22UDMF.cfg b/extras/conf/SRB2_22UDMF.cfg new file mode 100644 index 000000000..52104ed09 --- /dev/null +++ b/extras/conf/SRB2_22UDMF.cfg @@ -0,0 +1,47 @@ +/************************************************************************\ + Zone Builder Game Configuration for Sonic Robo Blast 2 Version 2.2 +\************************************************************************/ + +// This is required to prevent accidental use of a different configuration +type = "Doom Builder 2 Game Configuration"; + +// This is the title to show for this game +game = "Sonic Robo Blast 2 - 2.2 (UDMF)"; + +// This is the simplified game engine/sourceport name +engine = "zdoom"; + +// Settings common to all games and all map formats +include("Includes\\SRB222_common.cfg", "common"); + +// Settings common to Doom map format +include("Includes\\SRB222_common.cfg", "mapformat_udmf"); + +include("Includes\\Game_SRB222.cfg"); + +// Script lumps detection +scriptlumpnames +{ + include("Includes\\SRB222_misc.cfg", "scriptlumpnames"); +} + +// THING TYPES +thingtypes +{ + include("Includes\\SRB222_things.cfg"); +} + +//Default things filters +thingsfilters +{ + include("Includes\\SRB222_misc.cfg", "thingsfilters"); +} + +// ENUMERATIONS +// Each engine has its own additional thing types +// These are enumerated lists for linedef types and UDMF fields. +enums +{ + // Basic game enums + include("Includes\\SRB222_misc.cfg", "enums"); +} \ No newline at end of file From 2cf94ea6aec88827d77e106aa53303276f2398a8 Mon Sep 17 00:00:00 2001 From: Nev3r Date: Tue, 24 Dec 2019 12:02:40 +0100 Subject: [PATCH 362/746] Delete the original configuration file. --- extras/conf/SRB2-22.cfg | 6521 --------------------------------------- 1 file changed, 6521 deletions(-) delete mode 100644 extras/conf/SRB2-22.cfg diff --git a/extras/conf/SRB2-22.cfg b/extras/conf/SRB2-22.cfg deleted file mode 100644 index 5bc48211c..000000000 --- a/extras/conf/SRB2-22.cfg +++ /dev/null @@ -1,6521 +0,0 @@ -/*********************************************************\ - Zone Builder Game Configuration - For Sonic Robo Blast 2 Version 2.2 - Contributors (alphabetical): - * Foxboy - * FuriousFox - * JJames19119 - * Kalaron - * Kristos - * MascaraSnake - * mazmazz - * Morpheus - * Neo Chaotikal - * Nev3r - * Oogaland - * Rob - * Shadow Hog - * Spherallic - * SRB2-Playah - * SSNTails - * SteelT - * ST218 - * toaster - * Viola -\*********************************************************/ - -// This is required to prevent accidental use of a different configuration -type = "Doom Builder 2 Game Configuration"; - -// This is the title to show for this game -game = "Sonic Robo Blast 2 - 2.2"; - -//GZDB specific. Don't try to load lumps that don't exist. -basegame = 0; - -// This is the simplified game engine/sourceport name -engine = "zdoom"; - -// When this is set to true, sectors with the same tag will light up when a line is highlighted -linetagindicatesectors = true; - -// The format interface handles the map data format - DoomMapSetIO for SRB2DB2, SRB2MapSetIO for Zone Builder -formatinterface = "SRB2MapSetIO"; - -//Sky textures for vanilla maps -defaultskytextures -{ - SKY1 = "MAP01,MAP02,MAP03,MAP33,MAP50,MAP60,MAPF0,MAPM0"; - SKY2 = "MAPM7,MAPMB"; - SKY4 = "MAP04,MAP06,MAP61,MAPF6,MAPM1"; - SKY6 = "MAP05,MAP51,MAPMA"; - SKY7 = "MAPM2,MAPM5"; - SKY8 = "MAP07,MAP08,MAP09,MAP52,MAP62,MAPF1"; - SKY10 = "MAP10,MAP12,MAP53,MAP63,MAPM3"; - SKY11 = "MAP11,MAPF7"; - SKY13 = "MAP13,MAP64"; - SKY14 = "MAP14"; - SKY15 = "MAP15,MAP54"; - SKY17 = "MAP70"; - SKY20 = "MAP32,MAP55,MAP65,MAPF2,MAPF5"; - SKY21 = "MAPM4"; - SKY22 = "MAP22,MAP23,MAP25,MAP26,MAP27,MAP56,MAP66,MAPF4,MAPM6"; - SKY30 = "MAP30"; - SKY31 = "MAP31"; - SKY35 = "MAP42"; - SKY40 = "MAP41,MAP71,MAPM9"; - SKY55 = "MAPF3,MAPM8"; - SKY68 = "MAPF8"; - SKY99 = "MAP57,MAPZ0"; - SKY159 = "MAP16"; - SKY172 = "MAP40"; - SKY300 = "MAP72"; - SKY301 = "MAP73"; -} - -// Default lump name for new map -defaultlumpname = "MAP01"; - -// Default testing parameters -testparameters = "-file \"%AP\" \"%F\" -warp %L"; -testshortpaths = true; - -// Default nodebuilder configurations -defaultsavecompiler = "zennode_normal"; -defaulttestcompiler = "zennode_fast"; - -// Skill levels -skills -{ - 1 = "Normal"; -} - -// Skins -skins -{ - Sonic; - Tails; - Knuckles; - Amy; - Fang; - Metalsonic; -} - -// Gametypes -gametypes -{ - -1 = "Single Player"; - 0 = "Co-op"; - 1 = "Competition"; - 2 = "Race"; - 3 = "Match"; - 4 = "Team Match"; - 5 = "Tag"; - 6 = "Hide and Seek"; - 7 = "CTF"; -} - -// Special linedefs -soundlinedefflag = 64; // See linedefflags -singlesidedflag = 1; // See linedefflags -doublesidedflag = 4; // See linedefflags -impassableflag = 1; -upperunpeggedflag = 8; -lowerunpeggedflag = 16; -repeatmidtextureflag = 1024; -pegmidtextureflag = 256; - -// Generalized actions -generalizedlinedefs = false; -generalizedsectors = true; - -// Texture loading options -defaultwalltexture = "GFZROCK"; -defaultfloortexture = "GFZFLR01"; -defaultceilingtexture = "F_SKY1"; -mixtexturesflats = true; -defaulttexturescale = 1.0f; -defaultflatscale = 1.0f; - -// Thing number for start position in 3D Mode -start3dmode = 3328; - - - - -/* -TEXTURES AND FLAT SOURCES -This tells Doom Builder where to find the information for textures -and flats in the IWAD file, Addition WAD file and Map WAD file. - -Start and end lumps must be given in a structure (of which the -key name doesnt matter) and any textures or flats in between them -are loaded in either the textures category or flats category. - -For textures: PNAMES, TEXTURE1 and TEXTURE2 are loaded by default. -Kalaron: and now TX_START -*/ - -// Texture sources -textures -{ - zdoom1 - { - start = "TX_START"; - end = "TX_END"; - } -} - -// Patch sources -patches -{ - standard1 - { - start = "P_START"; - end = "P_END"; - } - - standard2 - { - start = "PP_START"; - end = "PP_END"; - } -} - -// Sprite sources -sprites -{ - standard1 - { - start = "S_START"; - end = "S_END"; - } - - standard2 - { - start = "SS_START"; - end = "SS_END"; - } -} - -// Flat sources -flats -{ - standard1 - { - start = "F_START"; - end = "F_END"; - } - - standard2 - { - start = "FF_START"; - end = "FF_END"; - } - - standard3 - { - start = "FF_START"; - end = "F_END"; - } - - standard4 - { - start = "F_START"; - end = "FF_END"; - } -} - - -/* -GAME DETECT PATTERN -Used to guess the game for which a WAD file is made. - -1 = One of these lumps must exist -2 = None of these lumps must exist -3 = All of these lumps must exist -*/ - -gamedetect -{ - EXTENDED = 2; - - - BEHAVIOR = 2; - - E#M# = 2; - - MAP?? = 1; -} - - -/* -MAP LUMP NAMES -Map lumps are loaded with the map as long as they are right after each other. When the editor -meets a lump which is not defined in this list it will ignore the map if not satisfied. -The order of items defines the order in which lumps will be written to WAD file on save. -To indicate the map header lump, use ~MAP - -Legenda: -required = Lump is required to exist. -blindcopy = Lump will be copied along with the map blindly. (usefull for lumps Doom Builder doesn't use) -nodebuild = The nodebuilder generates this lump. -allowempty = The nodebuilder is allowed to leave this lump empty. -script = This lump is a text-based script. Specify the filename of the script configuration to use. -*/ - -maplumpnames -{ - ~MAP - { - required = true; - blindcopy = true; - nodebuild = false; - } - - THINGS - { - required = true; - nodebuild = true; - allowempty = true; - } - - LINEDEFS - { - required = true; - nodebuild = true; - allowempty = false; - } - - SIDEDEFS - { - required = true; - nodebuild = true; - allowempty = false; - } - - VERTEXES - { - required = true; - nodebuild = true; - allowempty = false; - } - - SEGS - { - required = false; - nodebuild = true; - allowempty = false; - } - - SSECTORS - { - required = false; - nodebuild = true; - allowempty = false; - } - - NODES - { - required = false; - nodebuild = true; - allowempty = false; - } - - SECTORS - { - required = true; - nodebuild = true; - allowempty = false; - } - - REJECT - { - required = false; - nodebuild = true; - allowempty = false; - } - - BLOCKMAP - { - required = false; - nodebuild = true; - allowempty = true; - } -} - -scriptlumpnames -{ - MAINCFG - { - script = "SOC.cfg"; - } - - OBJCTCFG - { - script = "SOC.cfg"; - } - - SOC_ - { - script = "SOC.cfg"; - isprefix = true; - } - - LUA_ - { - script = "Lua.cfg"; - isprefix = true; - } -} - -// DEFAULT SECTOR BRIGHTNESS LEVELS -sectorbrightness -{ - 255; - 248; - 240; - 232; - 224; - 216; - 208; - 200; - 192; - 184; - 176; - 168; - 160; - 152; - 144; - 136; - 128; - 120; - 112; - 104; - 96; - 88; - 80; - 72; - 64; - 56; - 48; - 40; - 32; - 24; - 16; - 8; - 0; -} - -// SECTOR TYPES----------------------------------------------------------------- -sectortypes -{ - 0 = "Normal"; - 1 = "Damage"; - 2 = "Damage (Water)"; - 3 = "Damage (Fire)"; - 4 = "Damage (Electrical)"; - 5 = "Spikes"; - 6 = "Death Pit (Camera Tilt)"; - 7 = "Death Pit (No Camera Tilt)"; - 8 = "Instant Kill"; - 9 = "Ring Drainer (Floor Touch)"; - 10 = "Ring Drainer (Anywhere in Sector)"; - 11 = "Special Stage Damage"; - 12 = "Space Countdown"; - 13 = "Ramp Sector (double step-up/down)"; - 14 = "Non-Ramp Sector (no step-down)"; - 15 = "Bouncy FOF"; - 16 = "Trigger Line Ex. (Pushable Objects)"; - 32 = "Trigger Line Ex. (Anywhere, All Players)"; - 48 = "Trigger Line Ex. (Floor Touch, All Players)"; - 64 = "Trigger Line Ex. (Anywhere in Sector)"; - 80 = "Trigger Line Ex. (Floor Touch)"; - 96 = "Trigger Line Ex. (Emerald Check)"; - 112 = "Trigger Line Ex. (NiGHTS Mare)"; - 128 = "Check for Linedef Executor on FOFs"; - 144 = "Egg Capsule"; - 160 = "Special Stage Time/Rings Parameters"; - 176 = "Custom Global Gravity"; - 512 = "Wind/Current"; - 1024 = "Conveyor Belt"; - 1280 = "Speed Pad"; - 4096 = "Star Post Activator"; - 8192 = "Exit/Special Stage Pit/Return Flag"; - 12288 = "CTF Red Team Base"; - 16384 = "CTF Blue Team Base"; - 20480 = "Fan Sector"; - 24576 = "Super Sonic Transform"; - 28672 = "Force Spin"; - 32768 = "Zoom Tube Start"; - 36864 = "Zoom Tube End"; - 40960 = "Circuit Finish Line"; - 45056 = "Rope Hang"; - 49152 = "Intangible to the Camera"; -} - - -// GENERALISED SECTOR TYPES----------------------------------------------------------------- -gen_sectortypes -{ - first - { - 0 = "Normal"; - 1 = "Damage"; - 2 = "Damage (Water)"; - 3 = "Damage (Fire)"; - 4 = "Damage (Electrical)"; - 5 = "Spikes"; - 6 = "Death Pit (Camera Tilt)"; - 7 = "Death Pit (No Camera Tilt)"; - 8 = "Instant Kill"; - 9 = "Ring Drainer (Floor Touch)"; - 10 = "Ring Drainer (Anywhere in Sector)"; - 11 = "Special Stage Damage"; - 12 = "Space Countdown"; - 13 = "Ramp Sector (double step-up/down)"; - 14 = "Non-Ramp Sector (no step-down)"; - 15 = "Bouncy FOF"; - } - - second - { - 0 = "Normal"; - 16 = "Trigger Line Ex. (Pushable Objects)"; - 32 = "Trigger Line Ex. (Anywhere, All Players)"; - 48 = "Trigger Line Ex. (Floor Touch, All Players)"; - 64 = "Trigger Line Ex. (Anywhere in Sector)"; - 80 = "Trigger Line Ex. (Floor Touch)"; - 96 = "Trigger Line Ex. (Emerald Check)"; - 112 = "Trigger Line Ex. (NiGHTS Mare)"; - 128 = "Check for Linedef Executor on FOFs"; - 144 = "Egg Capsule"; - 160 = "Special Stage Time/Rings Parameters"; - 176 = "Custom Global Gravity"; - } - - third - { - 0 = "Normal"; - 512 = "Wind/Current"; - 1024 = "Conveyor Belt"; - 1280 = "Speed Pad"; - } - - fourth - { - 0 = "Normal"; - 4096 = "Star Post Activator"; - 8192 = "Exit/Special Stage Pit/Return Flag"; - 12288 = "CTF Red Team Base"; - 16384 = "CTF Blue Team Base"; - 20480 = "Fan Sector"; - 24576 = "Super Sonic Transform"; - 28672 = "Force Spin"; - 32768 = "Zoom Tube Start"; - 36864 = "Zoom Tube End"; - 40960 = "Circuit Finish Line"; - 45056 = "Rope Hang"; - 49152 = "Intangible to the Camera"; - } -} - -// LINEDEF FLAGS -linedefflags -{ - 1 = "[0] Impassable"; - 2 = "[1] Block Enemies"; - 4 = "[2] Double-Sided"; - 8 = "[3] Upper Unpegged"; - 16 = "[4] Lower Unpegged"; - 32 = "[5] Slope Skew (E1)"; - 64 = "[6] Not Climbable"; - 128 = "[7] No Midtexture Skew (E2)"; - 256 = "[8] Peg Midtexture (E3)"; - 512 = "[9] Solid Midtexture (E4)"; - 1024 = "[10] Repeat Midtexture (E5)"; - 2048 = "[11] Netgame Only"; - 4096 = "[12] No Netgame"; - 8192 = "[13] Effect 6"; - 16384 = "[14] Bouncy Wall"; - 32768 = "[15] Transfer Line"; -} - -// Linedef flags UDMF translation table -// This is needed for copy/paste and prefabs to work properly -// When the UDMF field name is prefixed with ! it is inverted -linedefflagstranslation -{ - 1 = "blocking"; - 2 = "blockmonsters"; - 4 = "twosided"; - 8 = "dontpegtop"; - 16 = "dontpegbottom"; - 32 = "secret"; - 64 = "blocksound"; - 128 = "dontdraw"; - 256 = "mapped"; -} - -// LINEDEF ACTIVATIONS -linedefactivations -{ -} - -// LINEDEF TYPES -linedeftypes -{ - misc - { - title = "Miscellaneous"; - - 0 - { - title = "None"; - prefix = "(0)"; - } - - 1 - { - title = "Per-Sector Gravity"; - prefix = "(1)"; - flags64text = "[6] Flip in reverse gravity"; - } - - 5 - { - title = "Camera Scanner"; - prefix = "(5)"; - } - - 7 - { - title = "Sector Flat Alignment"; - prefix = "(7)"; - flags2048text = "[11] Don't align floor"; - flags4096text = "[12] Don't align ceiling"; - flags8192text = "[13] Use texture offsets"; - } - - 10 - { - title = "Culling Plane"; - prefix = "(10)"; - flags64text = "[6] Cull only while in sector"; - } - - 13 - { - title = "Heat Wave Effect"; - prefix = "(13)"; - } - - 40 - { - title = "Visual Portal Between Tagged Linedefs"; - prefix = "(40)"; - } - - 41 - { - title = "Horizon Effect"; - prefix = "(41)"; - } - - 50 - { - title = "Instantly Lower Floor on Level Load"; - prefix = "(50)"; - } - - 51 - { - title = "Instantly Raise Ceiling on Level Load"; - prefix = "(51)"; - } - - 63 - { - title = "Fake Floor/Ceiling Planes"; - prefix = "(63)"; - } - - 540 - { - title = "Floor Friction"; - prefix = "(540)"; - } - } - - parameters - { - title = "Parameters"; - - 2 - { - title = "Custom Exit"; - prefix = "(2)"; - flags2text = "[1] Check emeralds"; - flags64text = "[6] Skip score tally"; - } - - 3 - { - title = "Zoom Tube Parameters"; - prefix = "(3)"; - flags512text = "[9] Ignore player direction"; - } - - 4 - { - title = "Speed Pad Parameters"; - prefix = "(4)"; - flags512text = "[9] No teleport to center"; - flags1024text = "[10] Force spinning frames"; - } - - 8 - { - title = "Special Sector Properties"; - prefix = "(8)"; - flags32text = "[5] Invert precipitation"; - flags64text = "[6] Touch only ceiling"; - flags128text = "[7] Allow opposite gravity"; - flags256text = "[8] Touch sector edge"; - flags512text = "[9] Touch floor or ceiling"; - } - - 9 - { - title = "Chain Parameters"; - prefix = "(9)"; - flags32text = "[5] Swing instead of spin"; - flags64text = "[6] Player-turnable chain"; - flags128text = "[7] Make chain from maces"; - flags256text = "[8] Spawn mace at origin"; - flags512text = "[9] Don't clip inside ground"; - flags1024text = "[10] No distance check"; - } - - 11 - { - title = "Rope Hang Parameters"; - prefix = "(11)"; - flags32text = "[5] Don't loop"; - flags64text = "[6] Static"; - } - - 12 - { - title = "Rock Spawner Parameters"; - prefix = "(12)"; - flags64text = "[6] Randomize speed"; - } - - 14 - { - title = "Bustable Block Parameters"; - prefix = "(14)"; - flags32text = "[5] Particles launch from center"; - } - - 15 - { - title = "Fan Particle Spawner Parameters"; - prefix = "(15)"; - } - - 16 - { - title = "Minecart Parameters"; - prefix = "(16)"; - } - - 64 - { - title = "Continuously Appearing/Disappearing FOF"; - prefix = "(64)"; - flags2text = "[1] Use control sector tag"; - flags64text = "[6] No sound effect"; - } - - 65 - { - title = "Bridge Thinker "; - prefix = "(65)"; - } - } - - polyobject - { - title = "PolyObject"; - - 20 - { - title = "First Line"; - prefix = "(20)"; - } - - 21 - { - title = "Explicitly Include Line "; - prefix = "(21)"; - } - - 22 - { - title = "Parameters"; - prefix = "(22)"; - flags64text = "[6] Trigger linedef executor"; - flags128text = "[7] Intangible"; - flags256text = "[8] Stopped by pushables"; - flags512text = "[9] Render flats"; - } - - 30 - { - title = "Waving Flag"; - prefix = "(30)"; - } - - 31 - { - title = "Displacement by Front Sector"; - prefix = "(31)"; - } - - 32 - { - title = "Angular Displacement by Front Sector"; - prefix = "(32)"; - flags8text = "[3] Set delay by backside sector"; - flags64text = "[6] Don't turn players"; - flags512text = "[9] Turn all objects"; - } - } - - planemove - { - title = "Plane Movement"; - - 52 - { - title = "Continuously Falling Sector"; - prefix = "(52)"; - flags64text = "[6] Continuously rising"; - } - - 53 - { - title = "Continuous Floor/Ceiling Mover"; - prefix = "(53)"; - } - - 54 - { - title = "Continuous Floor Mover"; - prefix = "(54)"; - } - - 55 - { - title = "Continuous Ceiling Mover"; - prefix = "(55)"; - } - - 56 - { - title = "Continuous Two-Speed Floor/Ceiling Mover"; - prefix = "(56)"; - } - - 57 - { - title = "Continuous Two-Speed Floor Mover"; - prefix = "(57)"; - } - - 58 - { - title = "Continuous Two-Speed Ceiling Mover"; - prefix = "(58)"; - } - - 59 - { - title = "Activate Moving Platform"; - prefix = "(59)"; - flags64text = "[6] Move upwards at start"; - } - - 60 - { - title = "Activate Moving Platform (Adjustable Speed)"; - prefix = "(60)"; - flags64text = "[6] Move upwards at start"; - } - - 61 - { - title = "Crusher (Ceiling to Floor)"; - prefix = "(61)"; - flags512text = "[9] Double, constant speed"; - } - - 62 - { - title = "Crusher (Floor to Ceiling)"; - prefix = "(62)"; - flags512text = "[9] Double, constant speed"; - } - - 66 - { - title = "Move Floor by Displacement"; - prefix = "(66)"; - flags64text = "[6] Inverse movement"; - } - - 67 - { - title = "Move Ceiling by Displacement"; - prefix = "(67)"; - flags64text = "[6] Inverse movement"; - } - - 68 - { - title = "Move Floor and Ceiling by Displacement"; - prefix = "(68)"; - flags64text = "[6] Inverse movement"; - } - } - - fofsolid - { - title = "FOF (solid)"; - - 100 - { - title = "Solid, Opaque"; - prefix = "(100)"; - flags8text = "[3] Slope skew sides"; - flags32text = "[5] Only block player"; - flags128text = "[7] Only block non-players"; - 3dfloor = true; - 3dfloorflags = "19F"; - } - - 101 - { - title = "Solid, Opaque, No Shadow"; - prefix = "(101)"; - flags8text = "[3] Slope skew sides"; - flags32text = "[5] Only block player"; - flags128text = "[7] Only block non-players"; - 3dfloor = true; - 3dfloorflags = "1DF"; - } - - 102 - { - title = "Solid, Translucent"; - prefix = "(102)"; - flags8text = "[3] Slope skew sides"; - flags32text = "[5] Only block player"; - flags64text = "[6] Render insides"; - flags128text = "[7] Only block non-players"; - 3dfloor = true; - 3dfloorflags = "195F"; - flags643dfloorflagsadd = "7C80"; - } - - 103 - { - title = "Solid, Sides Only"; - prefix = "(103)"; - flags8text = "[3] Slope skew sides"; - flags32text = "[5] Only block player"; - flags128text = "[7] Only block non-players"; - 3dfloor = true; - 3dfloorflags = "1CF"; - } - - 104 - { - title = "Solid, No Sides"; - prefix = "(104)"; - flags32text = "[5] Only block player"; - flags64text = "[6] Cast shadow"; - flags128text = "[7] Only block non-players"; - 3dfloor = true; - 3dfloorflags = "1D7"; - flags643dfloorflagsremove = "40"; - } - - 105 - { - title = "Solid, Invisible"; - prefix = "(105)"; - flags32text = "[5] Only block player"; - flags128text = "[7] Only block non-players"; - 3dfloor = true; - 3dfloorflags = "47"; - } - - 140 - { - title = "Intangible from Bottom, Opaque"; - prefix = "(140)"; - flags8text = "[3] Slope skew sides"; - flags32text = "[5] Only block player"; - flags64text = "[6] Don't cast shadow"; - flags128text = "[7] Only block non-players"; - 3dfloor = true; - 3dfloorflags = "200841F"; - flags643dfloorflagsadd = "40"; - } - - 141 - { - title = "Intangible from Bottom, Translucent"; - prefix = "(141)"; - flags8text = "[3] Slope skew sides"; - flags32text = "[5] Only block player"; - flags64text = "[6] Don't cast shadow"; - flags128text = "[7] Render insides/block non-plr"; - 3dfloor = true; - 3dfloorflags = "200191F"; - flags1283dfloorflagsadd = "7C80"; - flags643dfloorflagsadd = "40"; - } - - 142 - { - title = "Intangible from Bottom, Translucent, No Sides"; - prefix = "(142)"; - flags32text = "[5] Only block player"; - flags64text = "[6] Don't cast shadow"; - flags128text = "[7] Render insides/block non-plr"; - 3dfloor = true; - 3dfloorflags = "2001917"; - flags1283dfloorflagsadd = "7C80"; - flags643dfloorflagsadd = "40"; - } - - 143 - { - title = "Intangible from Top, Opaque"; - prefix = "(143)"; - flags8text = "[3] Slope skew sides"; - flags32text = "[5] Only block player"; - flags64text = "[6] Don't cast shadow"; - flags128text = "[7] Only block non-players"; - 3dfloor = true; - 3dfloorflags = "400841F"; - flags643dfloorflagsadd = "40"; - } - - 144 - { - title = "Intangible from Top, Translucent"; - prefix = "(144)"; - flags8text = "[3] Slope skew sides"; - flags32text = "[5] Only block player"; - flags64text = "[6] Don't cast shadow"; - flags128text = "[7] Render insides/block non-plr"; - 3dfloor = true; - 3dfloorflags = "400191F"; - flags1283dfloorflagsadd = "7C80"; - flags643dfloorflagsadd = "40"; - } - - 145 - { - title = "Intangible from Top, Translucent, No Sides"; - prefix = "(145)"; - flags32text = "[5] Only block player"; - flags64text = "[6] Don't cast shadow"; - flags128text = "[7] Render insides/block non-plr"; - 3dfloor = true; - 3dfloorflags = "4001917"; - flags1283dfloorflagsadd = "7C80"; - flags643dfloorflagsadd = "40"; - } - - 146 - { - title = "Only Tangible from Sides"; - prefix = "(146)"; - flags8text = "[3] Slope skew sides"; - flags32text = "[5] Only block player"; - flags128text = "[7] Only block non-players"; - 3dfloor = true; - 3dfloorflags = "600800F"; - } - } - - fofintangible - { - title = "FOF (intangible)"; - - 120 - { - title = "Water, Opaque"; - prefix = "(120)"; - flags8text = "[3] Slope skew sides"; - flags64text = "[6] Use two light levels"; - flags512text = "[9] Use target light level"; - flags1024text = "[10] Ripple effect"; - 3dfloor = true; - 3dfloorflags = "8F39"; - flags643dfloorflagsadd = "20000"; - flags5123dfloorflagsadd = "80000000"; - flags10243dfloorflagsadd = "40000000"; - } - - 121 - { - title = "Water, Translucent"; - prefix = "(121)"; - flags8text = "[3] Slope skew sides"; - flags64text = "[6] Use two light levels"; - flags512text = "[9] Use target light level"; - flags1024text = "[10] Ripple effect"; - 3dfloor = true; - 3dfloorflags = "9F39"; - flags643dfloorflagsadd = "20000"; - flags5123dfloorflagsadd = "80000000"; - flags10243dfloorflagsadd = "40000000"; - } - - 122 - { - title = "Water, Opaque, No Sides"; - prefix = "(122)"; - flags64text = "[6] Use two light levels"; - flags512text = "[9] Use target light level"; - flags1024text = "[10] Ripple effect"; - 3dfloor = true; - 3dfloorflags = "F31"; - flags643dfloorflagsadd = "20000"; - flags5123dfloorflagsadd = "80000000"; - flags10243dfloorflagsadd = "40000000"; - } - - 123 - { - title = "Water, Translucent, No Sides"; - prefix = "(123)"; - flags64text = "[6] Use two light levels"; - flags512text = "[9] Use target light level"; - flags1024text = "[10] Ripple effect"; - 3dfloor = true; - 3dfloorflags = "1F31"; - flags643dfloorflagsadd = "20000"; - flags5123dfloorflagsadd = "80000000"; - flags10243dfloorflagsadd = "40000000"; - } - - 124 - { - title = "Goo Water, Translucent"; - prefix = "(124)"; - flags8text = "[3] Slope skew sides"; - flags64text = "[6] Use two light levels"; - flags512text = "[9] Use target light level"; - flags1024text = "[10] Ripple effect"; - 3dfloor = true; - 3dfloorflags = "209F39"; - flags643dfloorflagsadd = "20000"; - flags5123dfloorflagsadd = "80000000"; - flags10243dfloorflagsadd = "40000000"; - } - - 125 - { - title = "Goo Water, Translucent, No Sides"; - prefix = "(125)"; - flags8text = "[3] Slope skew sides"; - flags64text = "[6] Use two light levels"; - flags512text = "[9] Use target light level"; - flags1024text = "[10] Ripple effect"; - 3dfloor = true; - 3dfloorflags = "201F31"; - flags643dfloorflagsadd = "20000"; - flags5123dfloorflagsadd = "80000000"; - flags10243dfloorflagsadd = "40000000"; - } - - 220 - { - title = "Intangible, Opaque"; - prefix = "(220)"; - flags8text = "[3] Slope skew sides"; - 3dfloor = true; - 3dfloorflags = "8F19"; - } - - 221 - { - title = "Intangible, Translucent"; - prefix = "(221)"; - flags8text = "[3] Slope skew sides"; - flags64text = "[6] Cast shadow"; - 3dfloor = true; - 3dfloorflags = "1B59"; - flags643dfloorflagsremove = "40"; - } - - 222 - { - title = "Intangible, Sides Only"; - prefix = "(222)"; - flags8text = "[3] Slope skew sides"; - flags64text = "[6] Cast shadow"; - 3dfloor = true; - 3dfloorflags = "8249"; - flags643dfloorflagsremove = "240"; - } - - 223 - { - title = "Intangible, Invisible"; - prefix = "(223)"; - 3dfloor = true; - 3dfloorflags = "41"; - } - } - - fofmoving - { - title = "FOF (moving)"; - - 150 - { - title = "Air Bobbing"; - prefix = "(150)"; - flags8text = "[3] Slope skew sides"; - flags32text = "[5] Only block player"; - flags64text = "[6] Spindash to move"; - flags128text = "[7] Only block non-players"; - 3dfloor = true; - 3dfloorflags = "19F"; - } - - 151 - { - title = "Air Bobbing (Adjustable)"; - prefix = "(151)"; - flags8text = "[3] Slope skew sides"; - flags32text = "[5] Only block player"; - flags64text = "[6] Spindash to move"; - flags128text = "[7] Only block non-players"; - 3dfloor = true; - 3dfloorflags = "19F"; - } - - 152 - { - title = "Reverse Air Bobbing (Adjustable)"; - prefix = "(152)"; - flags8text = "[3] Slope skew sides"; - flags32text = "[5] Only block player"; - flags64text = "[6] Spindash to move"; - flags128text = "[7] Only block non-players"; - 3dfloor = true; - 3dfloorflags = "19F"; - } - - 160 - { - title = "Floating, Bobbing"; - prefix = "(160)"; - flags8text = "[3] Slope skew sides"; - flags32text = "[5] Only block player"; - flags128text = "[7] Only block non-players"; - 3dfloor = true; - 3dfloorflags = "4019F"; - } - - 190 - { - title = "Rising Platform, Solid, Opaque"; - prefix = "(190)"; - flags2text = "[1] Sink when stepped on"; - flags8text = "[3] Slope skew sides"; - flags32text = "[5] Only block player"; - flags64text = "[6] Spindash to move"; - flags128text = "[7] Only block non-players"; - 3dfloor = true; - 3dfloorflags = "19F"; - } - - 191 - { - title = "Rising Platform, Solid, Opaque, No Shadow"; - prefix = "(191)"; - flags2text = "[1] Sink when stepped on"; - flags8text = "[3] Slope skew sides"; - flags32text = "[5] Only block player"; - flags64text = "[6] Spindash to move"; - flags128text = "[7] Only block non-players"; - 3dfloor = true; - 3dfloorflags = "1DF"; - } - - 192 - { - title = "Rising Platform, Solid, Translucent"; - prefix = "(192)"; - flags2text = "[1] Sink when stepped on"; - flags8text = "[3] Slope skew sides"; - flags32text = "[5] Only block player"; - flags64text = "[6] Spindash to move"; - flags128text = "[7] Only block non-players"; - 3dfloor = true; - 3dfloorflags = "195F"; - } - - 193 - { - title = "Rising Platform, Solid, Invisible"; - prefix = "(193)"; - flags2text = "[1] Sink when stepped on"; - flags8text = "[3] Slope skew sides"; - flags32text = "[5] Only block player"; - flags64text = "[6] Spindash to move"; - flags128text = "[7] Only block non-players"; - 3dfloor = true; - 3dfloorflags = "47"; - } - - 194 - { - title = "Rising Platform, Intangible from Bottom, Opaque"; - prefix = "(194)"; - flags2text = "[1] Sink when stepped on"; - flags8text = "[3] Slope skew sides"; - flags32text = "[5] Only block player"; - flags64text = "[6] Spindash, no shadow"; - flags128text = "[7] Only block non-players"; - 3dfloor = true; - 3dfloorflags = "200841F"; - flags643dfloorflagsadd = "40"; - } - - 195 - { - title = "Rising Platform, Intangible from Bottom, Translucent"; - prefix = "(195)"; - flags2text = "[1] Sink when stepped on"; - flags8text = "[3] Slope skew sides"; - flags32text = "[5] Only block player"; - flags64text = "[6] Spindash, no shadow"; - flags128text = "[7] Only block non-players"; - 3dfloor = true; - 3dfloorflags = "2009D1F"; - flags643dfloorflagsadd = "40"; - } - } - - fofcrumbling - { - title = "FOF (crumbling)"; - - 170 - { - title = "Crumbling, Respawn"; - prefix = "(170)"; - flags8text = "[3] Slope skew sides"; - flags32text = "[5] Only block player"; - flags128text = "[7] Only block non-players"; - 3dfloor = true; - 3dfloorflags = "10019F"; - } - - 171 - { - title = "Crumbling, No Respawn"; - prefix = "(171)"; - flags8text = "[3] Slope skew sides"; - flags32text = "[5] Only block player"; - flags128text = "[7] Only block non-players"; - 3dfloor = true; - 3dfloorflags = "80019F"; - } - - 172 - { - title = "Crumbling, Respawn, Intangible from Bottom"; - prefix = "(172)"; - flags8text = "[3] Slope skew sides"; - flags32text = "[5] Only block player"; - flags64text = "[6] Don't cast shadow"; - flags128text = "[7] Only block non-players"; - 3dfloor = true; - 3dfloorflags = "210841F"; - flags643dfloorflagsadd = "40"; - } - - 173 - { - title = "Crumbling, No Respawn, Intangible from Bottom"; - prefix = "(173)"; - flags8text = "[3] Slope skew sides"; - flags32text = "[5] Only block player"; - flags64text = "[6] Don't cast shadow"; - flags128text = "[7] Only block non-players"; - 3dfloor = true; - 3dfloorflags = "218841F"; - flags643dfloorflagsadd = "40"; - } - - 174 - { - title = "Crumbling, Respawn, Int. from Bottom, Translucent"; - prefix = "(174)"; - flags8text = "[3] Slope skew sides"; - flags32text = "[5] Only block player"; - flags64text = "[6] Don't cast shadow"; - flags128text = "[7] Only block non-players"; - 3dfloor = true; - 3dfloorflags = "210959F"; - flags643dfloorflagsadd = "40"; - } - - 175 - { - title = "Crumbling, No Respawn, Int. from Bottom, Translucent"; - prefix = "(175)"; - flags8text = "[3] Slope skew sides"; - flags32text = "[5] Only block player"; - flags64text = "[6] Don't cast shadow"; - flags128text = "[7] Only block non-players"; - 3dfloor = true; - 3dfloorflags = "218959F"; - flags643dfloorflagsadd = "40"; - } - - 176 - { - title = "Crumbling, Respawn, Floating, Bobbing"; - prefix = "(176)"; - flags8text = "[3] Slope skew sides"; - flags32text = "[5] Only block player"; - flags64text = "[6] Spindash to move"; - flags128text = "[7] Only block non-players"; - 3dfloor = true; - 3dfloorflags = "14019F"; - } - - 177 - { - title = "Crumbling, No Respawn, Floating, Bobbing"; - prefix = "(177)"; - flags8text = "[3] Slope skew sides"; - flags32text = "[5] Only block player"; - flags64text = "[6] Spindash to move"; - flags128text = "[7] Only block non-players"; - 3dfloor = true; - 3dfloorflags = "1C019F"; - } - - 178 - { - title = "Crumbling, Respawn, Floating"; - prefix = "(178)"; - flags8text = "[3] Slope skew sides"; - flags32text = "[5] Only block player"; - flags128text = "[7] Only block non-players"; - 3dfloor = true; - 3dfloorflags = "14019F"; - } - - 179 - { - title = "Crumbling, No Respawn, Floating"; - prefix = "(179)"; - flags8text = "[3] Slope skew sides"; - flags32text = "[5] Only block player"; - flags128text = "[7] Only block non-players"; - 3dfloor = true; - 3dfloorflags = "1C019F"; - } - - 180 - { - title = "Crumbling, Respawn, Air Bobbing"; - prefix = "(180)"; - flags8text = "[3] Slope skew sides"; - flags32text = "[5] Only block player"; - flags64text = "[6] Spindash to move"; - flags128text = "[7] Only block non-players"; - 3dfloor = true; - 3dfloorflags = "10019F"; - } - } - - fofspecial - { - title = "FOF (special)"; - - 200 - { - title = "Light Block"; - prefix = "(200)"; - 3dfloor = true; - 3dfloorflags = "20201"; - } - - 201 - { - title = "Half Light Block"; - prefix = "(201)"; - 3dfloor = true; - 3dfloorflags = "201"; - } - - 202 - { - title = "Fog Block"; - prefix = "(202)"; - 3dfloor = true; - 3dfloorflags = "3EF19"; - } - - 250 - { - title = "Mario Block"; - prefix = "(250)"; - flags32text = "[5] Invisible block"; - flags64text = "[6] Brick block"; - 3dfloor = true; - 3dfloorflags = "40019F"; - } - - 251 - { - title = "Thwomp Block"; - prefix = "(251)"; - flags512text = "[9] Custom crushing sound"; - flags1024text = "[10] Custom speed"; - 3dfloor = true; - 3dfloorflags = "19F"; - } - - 252 - { - title = "Shatter Block"; - prefix = "(252)"; - flags8text = "[3] Slope skew sides"; - flags64text = "[6] Shatter only from below"; - flags512text = "[9] Shattered by pushables"; - flags1024text = "[10] Trigger linedef executor"; - 3dfloor = true; - 3dfloorflags = "8800019"; - flags643dfloorflagsadd = "200006"; - } - - 253 - { - title = "Shatter Block, Translucent"; - prefix = "(253)"; - flags8text = "[3] Slope skew sides"; - flags512text = "[9] Shattered by pushables"; - flags1024text = "[10] Trigger linedef executor"; - 3dfloor = true; - 3dfloorflags = "8801019"; - } - - 254 - { - title = "Bustable Block"; - prefix = "(254)"; - flags8text = "[3] Slope skew sides"; - flags64text = "[6] Strong characters only"; - flags128text = "[7] Only block non-players"; - flags512text = "[9] Shattered by pushables"; - flags1024text = "[10] Trigger linedef executor"; - 3dfloor = true; - 3dfloorflags = "80001F"; - flags643dfloorflagsadd = "20000000"; - } - - 255 - { - title = "Spin-Bustable Block"; - prefix = "(255)"; - flags8text = "[3] Slope skew sides"; - flags32text = "[5] Only block player"; - flags128text = "[7] Only block non-players"; - flags512text = "[9] Shattered by pushables"; - flags1024text = "[10] Trigger linedef executor"; - 3dfloor = true; - 3dfloorflags = "1080001F"; - } - - 256 - { - title = "Spin-Bustable Block, Translucent"; - prefix = "(256)"; - flags8text = "[3] Slope skew sides"; - flags32text = "[5] Only block player"; - flags128text = "[7] Only block non-players"; - flags512text = "[9] Shattered by pushables"; - flags1024text = "[10] Trigger linedef executor"; - 3dfloor = true; - 3dfloorflags = "1080101F"; - } - - 257 - { - title = "Quicksand"; - prefix = "(257)"; - flags8text = "[3] Slope skew sides"; - flags1024text = "[10] Ripple effect"; - 3dfloor = true; - 3dfloorflags = "1008219"; - flags10243dfloorflagsadd = "40000000"; - } - - 258 - { - title = "Laser"; - prefix = "(258)"; - flags8text = "[3] Slope skew sides"; - flags32text = "[5] Don't damage bosses"; - 3dfloor = true; - 3dfloorflags = "959"; - } - - 259 - { - title = "Custom FOF"; - prefix = "(259)"; - flags32text = "[5] Only block player"; - flags128text = "[7] Only block non-players"; - flags512text = "[9] Shattered by pushables"; - flags1024text = "[10] Trigger linedef executor"; - 3dfloor = true; - 3dfloorcustom = true; - } - } - - linedeftrigger - { - title = "Linedef Executor Trigger"; - - 300 - { - title = "Continuous"; - prefix = "(300)"; - } - - 301 - { - title = "Each Time"; - prefix = "(301)"; - flags16384text = "[14] Also trigger on exit"; - } - - 302 - { - title = "Once"; - prefix = "(302)"; - } - - 303 - { - title = "Ring Count - Continuous"; - prefix = "(303)"; - flags2text = "[1] Rings greater or equal"; - flags64text = "[6] Rings less or equal"; - flags512text = "[9] Consider all players"; - } - - 304 - { - title = "Ring Count - Once"; - prefix = "(304)"; - flags2text = "[1] Rings greater or equal"; - flags64text = "[6] Rings less or equal"; - flags512text = "[9] Consider all players"; - } - - 305 - { - title = "Character Ability - Continuous"; - prefix = "(305)"; - } - - 306 - { - title = "Character Ability - Each Time"; - prefix = "(306)"; - flags16384text = "[14] Also trigger on exit"; - } - - 307 - { - title = "Character Ability - Once"; - prefix = "(307)"; - } - - 308 - { - title = "Race Only - Once"; - prefix = "(308)"; - } - - 309 - { - title = "CTF Red Team - Continuous"; - prefix = "(309)"; - } - - 310 - { - title = "CTF Red Team - Each Time"; - prefix = "(310)"; - flags16384text = "[14] Also trigger on exit"; - } - - 311 - { - title = "CTF Blue Team - Continuous"; - prefix = "(311)"; - } - - 312 - { - title = "CTF Blue Team - Each Time"; - prefix = "(312)"; - flags16384text = "[14] Also trigger on exit"; - } - - 313 - { - title = "No More Enemies - Once"; - prefix = "(313)"; - } - - 314 - { - title = "Number of Pushables - Continuous"; - prefix = "(314)"; - flags64text = "[6] Number greater or equal"; - flags512text = "[9] Number less"; - } - - 315 - { - title = "Number of Pushables - Once"; - prefix = "(315)"; - flags64text = "[6] Number greater or equal"; - flags512text = "[9] Number less"; - } - - 317 - { - title = "Condition Set Trigger - Continuous"; - prefix = "(317)"; - } - - 318 - { - title = "Condition Set Trigger - Once"; - prefix = "(318)"; - } - - 319 - { - title = "Unlockable - Continuous"; - prefix = "(319)"; - } - - 320 - { - title = "Unlockable - Once"; - prefix = "(320)"; - } - - 321 - { - title = "Trigger After X Calls - Continuous"; - prefix = "(321)"; - flags64text = "[6] Trigger more than once"; - - } - - 322 - { - title = "Trigger After X Calls - Each Time"; - prefix = "(322)"; - flags64text = "[6] Trigger more than once"; - } - - 323 - { - title = "NiGHTSerize - Each Time"; - prefix = "(323)"; - flags2text = "[1] Mare >= Front X Offset"; - flags8text = "[3] Run only if player is NiGHTS"; - flags16text = "[4] Count from lowest of players"; - flags32text = "[5] Lap <= Front Y Offset"; - flags64text = "[6] Mare <= Front X Offset"; - flags128text = "[7] Lap >= Front Y Offset"; - flags256text = "[8] Count laps from Bonus Time"; - flags512text = "[9] Count from triggering player"; - flags16384text = "[14] Run if no more mares"; - flags32768text = "[15] Run if player is not NiGHTS"; - } - - 324 - { - title = "NiGHTSerize - Once"; - flags2text = "[1] Mare >= Front X Offset"; - flags8text = "[3] Run only if player is NiGHTS"; - flags16text = "[4] Count from lowest of players"; - flags32text = "[5] Lap <= Front Y Offset"; - flags64text = "[6] Mare <= Front X Offset"; - flags128text = "[7] Lap >= Front Y Offset"; - flags256text = "[8] Count laps from Bonus Time"; - flags512text = "[9] Count from triggering player"; - flags16384text = "[14] Run if no more mares"; - flags32768text = "[15] Run if player is not NiGHTS"; - prefix = "(324)"; - } - - 325 - { - title = "De-NiGHTSerize - Each Time"; - flags2text = "[1] Mare >= Front X Offset"; - flags8text = "[3] Run if anyone is NiGHTS"; - flags16text = "[4] Count from lowest of players"; - flags32text = "[5] Lap <= Front Y Offset"; - flags64text = "[6] Mare <= Front X Offset"; - flags128text = "[7] Lap >= Front Y Offset"; - flags256text = "[8] Count laps from Bonus Time"; - flags512text = "[9] Count from triggering player"; - flags32768text = "[15] Run if no one is NiGHTS"; - prefix = "(325)"; - } - - 326 - { - title = "De-NiGHTSerize - Once"; - flags2text = "[1] Mare >= Front X Offset"; - flags8text = "[3] Run if anyone is NiGHTS"; - flags16text = "[4] Count from lowest of players"; - flags32text = "[5] Lap <= Front Y Offset"; - flags64text = "[6] Mare <= Front X Offset"; - flags128text = "[7] Lap >= Front Y Offset"; - flags256text = "[8] Count laps from Bonus Time"; - flags512text = "[9] Count from triggering player"; - flags32768text = "[15] Run if no one is NiGHTS"; - prefix = "(326)"; - } - - 327 - { - title = "NiGHTS Lap - Each Time"; - flags2text = "[1] Mare >= Front X Offset"; - flags16text = "[4] Count from lowest of players"; - flags32text = "[5] Lap <= Front Y Offset"; - flags64text = "[6] Mare <= Front X Offset"; - flags128text = "[7] Lap >= Front Y Offset"; - flags256text = "[8] Count laps from Bonus Time"; - flags512text = "[9] Count from triggering player"; - prefix = "(327)"; - } - - 328 - { - title = "NiGHTS Lap - Once"; - flags2text = "[1] Mare >= Front X Offset"; - flags16text = "[4] Count from lowest of players"; - flags32text = "[5] Lap <= Front Y Offset"; - flags64text = "[6] Mare <= Front X Offset"; - flags128text = "[7] Lap >= Front Y Offset"; - flags256text = "[8] Count laps from Bonus Time"; - flags512text = "[9] Count from triggering player"; - prefix = "(328)"; - } - - 329 - { - title = "Ideya Capture Touch - Each Time"; - flags2text = "[1] Mare >= Front X Offset"; - flags8text = "[3] Run regardless of spheres"; - flags16text = "[4] Count from lowest of players"; - flags32text = "[5] Lap <= Front Y Offset"; - flags64text = "[6] Mare <= Front X Offset"; - flags128text = "[7] Lap >= Front Y Offset"; - flags256text = "[8] Count laps from Bonus Time"; - flags512text = "[9] Count from triggering player"; - flags16384text = "[14] Only if not enough spheres"; - flags32768text = "[15] Run when entering Capture"; - prefix = "(329)"; - } - - 330 - { - title = "Ideya Capture Touch - Once"; - flags2text = "[1] Mare >= Front X Offset"; - flags8text = "[3] Run regardless of spheres"; - flags16text = "[4] Count from lowest of players"; - flags32text = "[5] Lap <= Front Y Offset"; - flags64text = "[6] Mare <= Front X Offset"; - flags128text = "[7] Lap >= Front Y Offset"; - flags256text = "[8] Count laps from Bonus Time"; - flags512text = "[9] Count from triggering player"; - flags16384text = "[14] Only if not enough spheres"; - flags32768text = "[15] Run when entering Capture"; - prefix = "(330)"; - } - - 331 - { - title = "Player Skin - Continuous"; - flags64text = "[6] Disable for this skin"; - prefix = "(331)"; - } - - 332 - { - title = "Player Skin - Each Time"; - flags64text = "[6] Disable for this skin"; - prefix = "(332)"; - } - - 333 - { - title = "Player Skin - Once"; - flags64text = "[6] Disable for this skin"; - prefix = "(333)"; - } - - 399 - { - title = "Level Load"; - prefix = "(399)"; - } - } - - linedefexecsector - { - title = "Linedef Executor (sector)"; - - 400 - { - title = "Set Tagged Sector's Floor Height/Texture"; - prefix = "(400)"; - flags8text = "[3] Set delay by backside sector"; - flags64text = "[6] Keep floor flat"; - } - - 401 - { - title = "Set Tagged Sector's Ceiling Height/Texture"; - prefix = "(401)"; - flags8text = "[3] Set delay by backside sector"; - } - - 402 - { - title = "Set Tagged Sector's Light Level"; - prefix = "(402)"; - flags8text = "[3] Set delay by backside sector"; - } - - 409 - { - title = "Change Tagged Sector's Tag"; - prefix = "(409)"; - flags8text = "[3] Set delay by backside sector"; - } - - 410 - { - title = "Change Front Sector's Tag"; - prefix = "(410)"; - flags8text = "[3] Set delay by backside sector"; - } - - 416 - { - title = "Start Adjustable Flickering Light"; - prefix = "(416)"; - flags8text = "[3] Set delay by backside sector"; - flags64text = "[6] Second level from back"; - } - - 417 - { - title = "Start Adjustable Pulsating Light"; - prefix = "(417)"; - flags8text = "[3] Set delay by backside sector"; - flags64text = "[6] Second level from back"; - } - - 418 - { - title = "Start Adjustable Blinking Light (unsynchronized)"; - prefix = "(418)"; - flags8text = "[3] Set delay by backside sector"; - flags64text = "[6] Second level from back"; - } - - 419 - { - title = "Start Adjustable Blinking Light (synchronized)"; - prefix = "(419)"; - flags8text = "[3] Set delay by backside sector"; - flags64text = "[6] Second level from back"; - } - - 420 - { - title = "Fade Light Level"; - prefix = "(420)"; - flags8text = "[3] Set delay by backside sector"; - flags16text = "[4] Set params by X/Y offsets"; - flags512text = "[9] Speed = Tic Duration"; - flags1024text = "[10] Override existing fade"; - } - - 421 - { - title = "Stop Lighting Effect"; - prefix = "(421)"; - flags8text = "[3] Set delay by backside sector"; - } - - 435 - { - title = "Change Plane Scroller Direction"; - prefix = "(435)"; - flags8text = "[3] Set delay by backside sector"; - } - } - - linedefexecplane - { - title = "Linedef Executor (plane movement)"; - - 403 - { - title = "Move Tagged Sector's Floor"; - prefix = "(403)"; - flags2text = "[1] Trigger linedef executor"; - flags8text = "[3] Set delay by backside sector"; - flags64text = "[6] Change floor flat"; - } - - 404 - { - title = "Move Tagged Sector's Ceiling"; - prefix = "(404)"; - flags2text = "[1] Trigger linedef executor"; - flags8text = "[3] Set delay by backside sector"; - flags64text = "[6] Change ceiling flat"; - } - - 405 - { - title = "Move Floor According to Front Texture Offsets"; - prefix = "(405)"; - flags8text = "[3] Set delay by backside sector"; - flags64text = "[6] Move instantly"; - } - - 407 - { - title = "Move Ceiling According to Front Texture Offsets"; - prefix = "(407)"; - flags8text = "[3] Set delay by backside sector"; - flags64text = "[6] Move instantly"; - } - - 411 - { - title = "Stop Plane Movement"; - prefix = "(411)"; - flags8text = "[3] Set delay by backside sector"; - } - - 428 - { - title = "Start Platform Movement"; - prefix = "(428)"; - flags8text = "[3] Set delay by backside sector"; - flags64text = "[6] Move upwards at start"; - } - - 429 - { - title = "Crush Ceiling Once"; - prefix = "(429)"; - flags8text = "[3] Set delay by backside sector"; - flags512text = "[9] Double, constant speed"; - } - - 430 - { - title = "Crush Floor Once"; - prefix = "(430)"; - flags8text = "[3] Set delay by backside sector"; - } - - 431 - { - title = "Crush Floor and Ceiling Once"; - prefix = "(431)"; - flags8text = "[3] Set delay by backside sector"; - flags512text = "[9] Double, constant speed"; - } - } - - linedefexecplayer - { - title = "Linedef Executor (player/object)"; - - 412 - { - title = "Teleporter"; - prefix = "(412)"; - flags2text = "[1] Silent"; - flags8text = "[3] Set delay by backside sector"; - flags64text = "[6] Retain angle"; - flags256text = "[8] Relative, silent"; - flags512text = "[9] Retain momentum"; - } - - 425 - { - title = "Change Object State"; - prefix = "(425)"; - flags8text = "[3] Set delay by backside sector"; - } - - 426 - { - title = "Stop Object"; - prefix = "(426)"; - flags8text = "[3] Set delay by backside sector"; - flags64text = "[6] Teleport to sector center"; - } - - 427 - { - title = "Award Score"; - prefix = "(427)"; - flags8text = "[3] Set delay by backside sector"; - } - - 432 - { - title = "Enable/Disable 2D Mode"; - prefix = "(432)"; - flags8text = "[3] Set delay by backside sector"; - flags64text = "[6] Return to 3D"; - } - - 433 - { - title = "Enable/Disable Gravity Flip"; - prefix = "(433)"; - flags8text = "[3] Set delay by backside sector"; - flags64text = "[6] Return to normal"; - } - - 434 - { - title = "Award Power-Up"; - prefix = "(434)"; - flags2text = "[1] Use back upper texture"; - flags8text = "[3] Set delay by backside sector"; - flags64text = "[6] No time limit"; - } - - 437 - { - title = "Disable Player Control"; - prefix = "(437)"; - flags8text = "[3] Set delay by backside sector"; - flags64text = "[6] Allow jumping"; - } - - 438 - { - title = "Change Object Size"; - prefix = "(438)"; - flags8text = "[3] Set delay by backside sector"; - } - - 442 - { - title = "Change Object Type State"; - prefix = "(442)"; - flags8text = "[3] Set delay by backside sector"; - } - - 457 - { - title = "Track Object's Angle"; - prefix = "(457)"; - flags8text = "[3] Set delay by backside sector"; - flags128text = "[7] Don't stop after first fail"; - } - - 458 - { - title = "Stop Tracking Object's Angle"; - prefix = "(458)"; - flags8text = "[3] Set delay by backside sector"; - } - - 460 - { - title = "Award Rings"; - prefix = "(460)"; - } - - 461 - { - title = "Spawn Object"; - prefix = "(461)"; - flags64text = "[6] Spawn inside a range"; - } - - 462 - { - title = "Stop Timer/Exit Stage in Record Attack"; - prefix = "(462)"; - } - } - - linedefexecmisc - { - title = "Linedef Executor (misc.)"; - - 413 - { - title = "Change Music"; - prefix = "(413)"; - flags2text = "[1] Keep after death"; - flags8text = "[3] Set delay by backside sector"; - flags32text = "[5] Seek to current song position"; - flags64text = "[6] For everyone"; - flags128text = "[7] Fade to custom volume"; - flags512text = "[9] Don't loop"; - flags16384text = "[14] Force music reload"; - } - - 414 - { - title = "Play Sound Effect"; - prefix = "(414)"; - flags2text = "[1] From calling sector"; - flags8text = "[3] Set delay by backside sector"; - flags64text = "[6] From nowhere for triggerer"; - flags512text = "[9] For everyone"; - flags1024text = "[10] From tagged sectors"; - } - - 415 - { - title = "Run Script"; - prefix = "(415)"; - flags8text = "[3] Set delay by backside sector"; - } - - 422 - { - title = "Switch to Cut-Away View"; - prefix = "(422)"; - flags8text = "[3] Set delay by backside sector"; - flags64text = "[6] Adjust pitch"; - } - - 423 - { - title = "Change Sky"; - prefix = "(423)"; - flags8text = "[3] Set delay by backside sector"; - flags64text = "[6] For everyone"; - } - - 424 - { - title = "Change Weather"; - prefix = "(424)"; - flags8text = "[3] Set delay by backside sector"; - flags64text = "[6] For everyone"; - } - - 436 - { - title = "Shatter FOF"; - prefix = "(436)"; - flags8text = "[3] Set delay by backside sector"; - } - - 439 - { - title = "Change Tagged Linedef's Textures"; - prefix = "(439)"; - flags8text = "[3] Set delay by backside sector"; - flags64text = "[6] Only existing"; - } - - 440 - { - title = "Start Metal Sonic Race"; - prefix = "(440)"; - flags8text = "[3] Set delay by backside sector"; - } - - 441 - { - title = "Condition Set Trigger"; - prefix = "(441)"; - flags8text = "[3] Set delay by backside sector"; - } - - 443 - { - title = "Call Lua Function"; - prefix = "(443)"; - flags8text = "[3] Set delay by backside sector"; - } - - 444 - { - title = "Earthquake"; - prefix = "(444)"; - flags8text = "[3] Set delay by backside sector"; - } - - - 445 - { - title = "Make FOF Disappear/Reappear"; - prefix = "(445)"; - flags8text = "[3] Set delay by backside sector"; - flags64text = "[6] Reappear"; - } - - 446 - { - title = "Make FOF Crumble"; - prefix = "(446)"; - flags2text = "[1] Flags determine respawn"; - flags8text = "[3] Set delay by backside sector"; - flags64text = "[6] Don't respawn"; - } - - 447 - { - title = "Change Tagged Sector's Colormap"; - prefix = "(447)"; - flags8text = "[3] Set delay by backside sector"; - flags16text = "[4] Front X/Y = Alpha"; - flags32text = "[5] Subtract Red value"; - flags64text = "[6] Subtract Green value"; - flags128text = "[7] Subtract Blue value"; - flags256text = "[8] Calc relative values"; - flags32768text = "[15] Use back side colormap"; - } - - 448 - { - title = "Change Skybox"; - prefix = "(448)"; - flags2text = "[1] Change centerpoint"; - flags8text = "[3] Set delay by backside sector"; - flags64text = "[6] For everyone"; - flags512text = "[9] Don't change viewpoint"; - } - - 450 - { - title = "Execute Linedef Executor (specific tag)"; - prefix = "(450)"; - flags8text = "[3] Set delay by backside sector"; - } - - 451 - { - title = "Execute Linedef Executor (random tag in range)"; - prefix = "(451)"; - flags8text = "[3] Set delay by backside sector"; - } - - 452 - { - title = "Set FOF Translucency"; - prefix = "(452)"; - flags8text = "[3] Set delay by backside sector"; - flags64text = "[6] Do not handle FF_TRANS"; - flags256text = "[8] Set relative to current val"; - } - - 453 - { - title = "Fade FOF"; - prefix = "(453)"; - flags2text = "[1] Do not handle FF_EXISTS"; - flags8text = "[3] Set delay by backside sector"; - flags32text = "[5] No collision during fade"; - flags64text = "[6] Do not handle FF_TRANS"; - flags128text = "[7] Do not handle lighting"; - flags256text = "[8] Set relative to current val"; - flags512text = "[9] Speed = Tic Duration"; - flags1024text = "[10] Override existing fade"; - flags16384text = "[14] Do not handle collision"; - flags32768text = "[15] Use exact alpha in OGL"; - } - - 454 - { - title = "Stop Fading FOF"; - prefix = "(454)"; - flags2text = "[1] Do not finalize collision"; - flags8text = "[3] Set delay by backside sector"; - } - - 455 - { - title = "Fade Tagged Sector's Colormap"; - prefix = "(455)"; - flags8text = "[3] Set delay by backside sector"; - flags16text = "[4] Front X/Y = Alpha"; - flags32text = "[5] Subtract Red value"; - flags64text = "[6] Subtract Green value"; - flags128text = "[7] Subtract Blue value"; - flags256text = "[8] Calc relative values"; - flags512text = "[9] Speed = Tic Duration"; - flags1024text = "[10] Override existing fade"; - flags16384text = "[14] Fade from invisible black"; - flags32768text = "[15] Use back side colormap"; - } - - 456 - { - title = "Stop Fading Tagged Sector's Colormap"; - prefix = "(456)"; - flags8text = "[3] Set delay by backside sector"; - } - - 459 - { - title = "Control Text Prompt"; - prefix = "(459)"; - flags2text = "[1] Close text prompt"; - flags8text = "[3] Set delay by backside sector"; - flags32text = "[5] Run executor tag on close"; - flags64text = "[6] For everyone"; - flags128text = "[7] Do not block controls"; - flags256text = "[8] Do not freeze time"; - flags32768text = "[15] Find prompt by name"; - } - } - - linedefexecpoly - { - title = "Linedef Executor (polyobject)"; - - 480 - { - title = "Door Slide"; - prefix = "(480)"; - flags8text = "[3] Set delay by backside sector"; - } - - 481 - { - title = "Door Swing"; - prefix = "(481)"; - flags8text = "[3] Set delay by backside sector"; - } - - 482 - { - title = "Move"; - prefix = "(482)"; - flags8text = "[3] Set delay by backside sector"; - } - - 483 - { - title = "Move, Override"; - prefix = "(483)"; - flags8text = "[3] Set delay by backside sector"; - } - - 484 - { - title = "Rotate Right"; - prefix = "(484)"; - flags8text = "[3] Set delay by backside sector"; - flags64text = "[6] Don't turn players"; - flags512text = "[9] Turn all objects"; - } - - 485 - { - title = "Rotate Right, Override"; - prefix = "(485)"; - flags8text = "[3] Set delay by backside sector"; - flags64text = "[6] Don't turn players"; - flags512text = "[9] Turn all objects"; - } - - 486 - { - title = "Rotate Left"; - prefix = "(486)"; - flags8text = "[3] Set delay by backside sector"; - flags64text = "[6] Don't turn players"; - flags512text = "[9] Turn all objects"; - } - - 487 - { - title = "Rotate Left, Override"; - prefix = "(487)"; - flags8text = "[3] Set delay by backside sector"; - flags64text = "[6] Don't turn players"; - flags512text = "[9] Turn all objects"; - } - - 488 - { - title = "Move by Waypoints"; - prefix = "(488)"; - flags8text = "[3] Set delay by backside sector"; - flags32text = "[5] Reverse order"; - flags128text = "[7] There and back"; - flags256text = "[8] Return when done"; - flags512text = "[9] Loop movement"; - } - - 489 - { - title = "Turn Invisible, Intangible"; - prefix = "(489)"; - flags8text = "[3] Set delay by backside sector"; - flags64text = "[6] Only invisible"; - } - - 490 - { - title = "Turn Visible, Tangible"; - prefix = "(490)"; - flags8text = "[3] Set delay by backside sector"; - flags64text = "[6] Only visible"; - } - - 491 - { - title = "Set Translucency"; - prefix = "(491)"; - flags8text = "[3] Set delay by backside sector"; - flags16text = "[4] Set raw alpha by Front X"; - flags256text = "[8] Calc relative values"; - } - - 492 - { - title = "Fade Translucency"; - prefix = "(492)"; - flags8text = "[3] Set delay by backside sector"; - flags16text = "[4] Set raw alpha by Front X"; - flags32text = "[5] No collision during fade"; - flags256text = "[8] Calc relative values"; - flags512text = "[9] Speed = Tic Duration"; - flags1024text = "[10] Override existing fade"; - flags16384text = "[14] Do not handle collision"; - } - } - - wallscroll - { - title = "Wall Scrolling"; - - 500 - { - title = "Scroll Wall Front Side Left"; - prefix = "(500)"; - } - - 501 - { - title = "Scroll Wall Front Side Right"; - prefix = "(501)"; - } - - 502 - { - title = "Scroll Wall According to Linedef"; - prefix = "(502)"; - } - - 503 - { - title = "Scroll Wall According to Linedef (Accelerative)"; - prefix = "(503)"; - } - - 504 - { - title = "Scroll Wall According to Linedef (Displacement)"; - prefix = "(504)"; - } - - 505 - { - title = "Scroll Texture by Front Side Offsets"; - prefix = "(505)"; - } - - 506 - { - title = "Scroll Texture by Back Side Offsets"; - prefix = "(506)"; - } - } - - planescroll - { - title = "Plane Scrolling"; - - 510 - { - title = "Scroll Floor Texture"; - prefix = "(510)"; - } - - 511 - { - title = "Scroll Floor Texture (Accelerative)"; - prefix = "(511)"; - } - - 512 - { - title = "Scroll Floor Texture (Displacement)"; - prefix = "(512)"; - } - - 513 - { - title = "Scroll Ceiling Texture"; - prefix = "(513)"; - } - - 514 - { - title = "Scroll Ceiling Texture (Accelerative)"; - prefix = "(514)"; - } - - 515 - { - title = "Scroll Ceiling Texture (Displacement)"; - prefix = "(515)"; - } - - 520 - { - title = "Carry Objects on Floor"; - prefix = "(520)"; - } - - 521 - { - title = "Carry Objects on Floor (Accelerative)"; - prefix = "(521)"; - flags64text = "[6] Even across edges"; - } - - 522 - { - title = "Carry Objects on Floor (Displacement)"; - prefix = "(522)"; - } - - 523 - { - title = "Carry Objects on Ceiling"; - prefix = "(523)"; - flags64text = "[6] Even across edges"; - } - - 524 - { - title = "Carry Objects on Ceiling (Accelerative)"; - prefix = "(524)"; - } - - 525 - { - title = "Carry Objects on Ceiling (Displacement)"; - prefix = "(525)"; - } - - 530 - { - title = "Scroll Floor Texture and Carry Objects"; - prefix = "(530)"; - flags64text = "[6] Even across edges"; - } - - 531 - { - title = "Scroll Floor Texture and Carry Objects (Accelerative)"; - prefix = "(531)"; - } - - 532 - { - title = "Scroll Floor Texture and Carry Objects (Displacement)"; - prefix = "(532)"; - } - - 533 - { - title = "Scroll Ceiling Texture and Carry Objects"; - prefix = "(533)"; - flags64text = "[6] Even across edges"; - } - - 534 - { - title = "Scroll Ceiling Texture and Carry Objects (Accelerative)"; - prefix = "(534)"; - } - - 535 - { - title = "Scroll Ceiling Texture and Carry Objects (Displacement)"; - prefix = "(535)"; - } - } - - pusher - { - title = "Pusher"; - - 541 - { - title = "Wind"; - prefix = "(541)"; - flags512text = "[9] Player slides"; - flags64text = "[6] Even across edges"; - } - - 542 - { - title = "Upwards Wind"; - prefix = "(542)"; - flags512text = "[9] Player slides"; - flags64text = "[6] Even across edges"; - } - - 543 - { - title = "Downwards Wind"; - prefix = "(543)"; - flags512text = "[9] Player slides"; - flags64text = "[6] Even across edges"; - } - - 544 - { - title = "Current"; - prefix = "(544)"; - flags512text = "[9] Player slides"; - flags64text = "[6] Even across edges"; - } - - 545 - { - title = "Upwards Current"; - prefix = "(545)"; - flags512text = "[9] Player slides"; - flags64text = "[6] Even across edges"; - } - - 546 - { - title = "Downwards Current"; - prefix = "(546)"; - flags512text = "[9] Player slides"; - flags64text = "[6] Even across edges"; - } - - 547 - { - title = "Push/Pull"; - prefix = "(547)"; - } - } - - light - { - title = "Lighting"; - - 600 - { - title = "Floor Lighting"; - prefix = "(600)"; - } - - 601 - { - title = "Ceiling Lighting"; - prefix = "(601)"; - } - - 602 - { - title = "Adjustable Pulsating Light"; - prefix = "(602)"; - } - - 603 - { - title = "Adjustable Flickering Light"; - prefix = "(603)"; - } - - 604 - { - title = "Adjustable Blinking Light (unsynchronized)"; - prefix = "(604)"; - } - - 605 - { - title = "Adjustable Blinking Light (synchronized)"; - prefix = "(605)"; - } - - 606 - { - title = "Colormap"; - prefix = "(606)"; - } - } - - slope - { - title = "Slope"; - - 700 - { - title = "Slope Frontside Floor"; - prefix = "(700)"; - flags2048text = "[11] No physics"; - flags4096text = "[12] Dynamic"; - slope = "regular"; - slopeargs = 1; - } - - 701 - { - title = "Slope Frontside Ceiling"; - prefix = "(701)"; - flags2048text = "[11] No physics"; - flags4096text = "[12] Dynamic"; - slope = "regular"; - slopeargs = 2; - } - - 702 - { - title = "Slope Frontside Floor and Ceiling"; - prefix = "(702)"; - flags2048text = "[11] No physics"; - flags4096text = "[12] Dynamic"; - slope = "regular"; - slopeargs = 3; - } - - 703 - { - title = "Slope Frontside Floor and Backside Ceiling"; - prefix = "(703)"; - flags2048text = "[11] No physics"; - flags4096text = "[12] Dynamic"; - slope = "regular"; - slopeargs = 9; - } - - 704 - { - title = "Slope Frontside Floor by 3 Tagged Vertex Things"; - prefix = "(704)"; - flags2048text = "[11] No physics"; - flags4096text = "[12] Dynamic"; - flags8192text = "[13] Use tag and offsets"; - slope = "vertex"; - slopeargs = 0; - } - - 705 - { - title = "Slope Frontside Ceiling by 3 Tagged Vertex Things"; - prefix = "(705)"; - flags2048text = "[11] No physics"; - flags4096text = "[12] Dynamic"; - flags8192text = "[13] Use tag and offsets"; - slope = "vertex"; - slopeargs = 1; - } - - 710 - { - title = "Slope Backside Floor"; - prefix = "(710)"; - flags2048text = "[11] No physics"; - flags4096text = "[12] Dynamic"; - slope = "regular"; - slopeargs = 4; - } - - 711 - { - title = "Slope Backside Ceiling"; - prefix = "(711)"; - flags2048text = "[11] No physics"; - flags4096text = "[12] Dynamic"; - slope = "regular"; - slopeargs = 8; - } - - 712 - { - title = "Slope Backside Floor and Ceiling"; - prefix = "(712)"; - flags2048text = "[11] No physics"; - flags4096text = "[12] Dynamic"; - slope = "regular"; - slopeargs = 12; - } - - 713 - { - title = "Slope Backside Floor and Frontside Ceiling"; - prefix = "(713)"; - flags2048text = "[11] No physics"; - flags4096text = "[12] Dynamic"; - slope = "regular"; - slopeargs = 6; - } - - 714 - { - title = "Slope Backside Floor by 3 Tagged Vertex Things"; - prefix = "(714)"; - flags2048text = "[11] No physics"; - flags4096text = "[12] Dynamic"; - flags8192text = "[13] Use tag and offsets"; - slope = "vertex"; - slopeargs = 2; - } - - 715 - { - title = "Slope Backside Ceiling by 3 Tagged Vertex Things"; - prefix = "(715)"; - flags2048text = "[11] No physics"; - flags4096text = "[12] Dynamic"; - flags8192text = "[13] Use tag and offsets"; - slope = "vertex"; - slopeargs = 3; - } - - 720 - { - title = "Copy Frontside Floor Slope from Line Tag"; - prefix = "(720)"; - slope = "copy"; - slopeargs = 1; - } - - 721 - { - title = "Copy Frontside Ceiling Slope from Line Tag"; - prefix = "(721)"; - slope = "copy"; - slopeargs = 2; - } - - 722 - { - title = "Copy Frontside Floor and Ceiling Slope from Line Tag"; - prefix = "(722)"; - slope = "copy"; - slopeargs = 3; - } - - 799 - { - title = "Set Tagged Dynamic Slope Vertex to Front Sector Height"; - prefix = "(799)"; - } - } - - transwall - { - title = "Translucent Wall"; - - 900 - { - title = "90% Opaque"; - prefix = "(900)"; - } - - 901 - { - title = "80% Opaque"; - prefix = "(901)"; - } - - 902 - { - title = "70% Opaque"; - prefix = "(902)"; - } - - 903 - { - title = "60% Opaque"; - prefix = "(903)"; - } - - 904 - { - title = "50% Opaque"; - prefix = "(904)"; - } - - 905 - { - title = "40% Opaque"; - prefix = "(905)"; - } - - 906 - { - title = "30% Opaque"; - prefix = "(906)"; - } - - 907 - { - title = "20% Opaque"; - prefix = "(907)"; - } - - 908 - { - title = "10% Opaque"; - prefix = "(908)"; - } - - 909 - { - title = "Fog Wall"; - prefix = "(909)"; - } - } -} - - -// THING FLAGS -thingflags -{ - 1 = "[1] Extra"; - 2 = "[2] Flip"; - 4 = "[4] Special"; - 8 = "[8] Ambush"; -} - -// Thing flags UDMF translation table -// This is needed for copy/paste and prefabs to work properly -// When the UDMF field name is prefixed with ! it is inverted -thingflagstranslation -{ - 1 = "skill1"; - 2 = "skill2"; - 4 = "skill3"; - 8 = "ambush"; -} - -// THING FLAGS ERROR MASK -// Mask for the thing flags which indicates the options -// that make the same thing appear in the same modes -thingflagsmask1 = 7; // 1 + 2 + 4 -thingflagsmask2 = 0; - - -// THING TYPES------------------------------------------------------------------ -// Color values: 1-Dark_Blue 2-Dark_Green 3-Turqoise 4-Dark_Red 5-Purple 6-Brown 7-Gray -// 8-Dark_Gray 9-Blue 10-Green 11-Cyan 12-Red 13-Magenta -// 14-Yellow 15-White 16-Pink 17-Orange 18-Gold 19-Cream -thingtypes -{ - editor - { - color = 15; // White - arrow = 1; - title = ""; - error = -1; - width = 8; - height = 16; - sort = 1; - - 3328 = "3D Mode Start"; - } - - starts - { - color = 1; // Blue - arrow = 1; - title = "Player Starts"; - width = 16; - height = 48; - flags8text = "[8] Spawn on ceiling"; - sprite = "PLAYA0"; - - 1 - { - title = "Player 01 Start"; - sprite = "PLAYA0"; - } - 2 - { - title = "Player 02 Start"; - sprite = "PLAYA0"; - } - 3 - { - title = "Player 03 Start"; - sprite = "PLAYA0"; - } - 4 - { - title = "Player 04 Start"; - sprite = "PLAYA0"; - } - 5 - { - title = "Player 05 Start"; - sprite = "PLAYA0"; - } - 6 - { - title = "Player 06 Start"; - sprite = "PLAYA0"; - } - 7 - { - title = "Player 07 Start"; - sprite = "PLAYA0"; - } - 8 - { - title = "Player 08 Start"; - sprite = "PLAYA0"; - } - 9 - { - title = "Player 09 Start"; - sprite = "PLAYA0"; - } - 10 - { - title = "Player 10 Start"; - sprite = "PLAYA0"; - } - 11 - { - title = "Player 11 Start"; - sprite = "PLAYA0"; - } - 12 - { - title = "Player 12 Start"; - sprite = "PLAYA0"; - } - 13 - { - title = "Player 13 Start"; - sprite = "PLAYA0"; - } - 14 - { - title = "Player 14 Start"; - sprite = "PLAYA0"; - } - 15 - { - title = "Player 15 Start"; - sprite = "PLAYA0"; - } - 16 - { - title = "Player 16 Start"; - sprite = "PLAYA0"; - } - 17 - { - title = "Player 17 Start"; - sprite = "PLAYA0"; - } - 18 - { - title = "Player 18 Start"; - sprite = "PLAYA0"; - } - 19 - { - title = "Player 19 Start"; - sprite = "PLAYA0"; - } - 20 - { - title = "Player 20 Start"; - sprite = "PLAYA0"; - } - 21 - { - title = "Player 21 Start"; - sprite = "PLAYA0"; - } - 22 - { - title = "Player 22 Start"; - sprite = "PLAYA0"; - } - 23 - { - title = "Player 23 Start"; - sprite = "PLAYA0"; - } - 24 - { - title = "Player 24 Start"; - sprite = "PLAYA0"; - } - 25 - { - title = "Player 25 Start"; - sprite = "PLAYA0"; - } - 26 - { - title = "Player 26 Start"; - sprite = "PLAYA0"; - } - 27 - { - title = "Player 27 Start"; - sprite = "PLAYA0"; - } - 28 - { - title = "Player 28 Start"; - sprite = "PLAYA0"; - } - 29 - { - title = "Player 29 Start"; - sprite = "PLAYA0"; - } - 30 - { - title = "Player 30 Start"; - sprite = "PLAYA0"; - } - 31 - { - title = "Player 31 Start"; - sprite = "PLAYA0"; - } - 32 - { - title = "Player 32 Start"; - sprite = "PLAYA0"; - } - 33 - { - title = "Match Start"; - sprite = "NDRNA2A8"; - } - 34 - { - title = "CTF Red Team Start"; - sprite = "SIGNG0"; - } - 35 - { - title = "CTF Blue Team Start"; - sprite = "SIGNE0"; - } - } - - enemies - { - color = 9; // Light_Blue - arrow = 1; - title = "Enemies"; - - 100 - { - title = "Crawla (Blue)"; - sprite = "POSSA1"; - width = 24; - height = 32; - } - 101 - { - title = "Crawla (Red)"; - sprite = "SPOSA1"; - width = 24; - height = 32; - } - 102 - { - title = "Stupid Dumb Unnamed RoboFish"; - sprite = "FISHA0"; - width = 8; - height = 28; - angletext = "Jump strength"; - } - 103 - { - title = "Buzz (Gold)"; - sprite = "BUZZA1"; - width = 28; - height = 40; - flags8text = "[8] Cannot move"; - } - 104 - { - title = "Buzz (Red)"; - sprite = "RBUZA1"; - width = 28; - height = 40; - flags8text = "[8] Cannot move"; - } - 108 - { - title = "Deton"; - sprite = "DETNA1"; - width = 20; - height = 32; - } - 110 - { - title = "Turret"; - sprite = "TRETA1"; - width = 16; - height = 32; - } - 111 - { - title = "Pop-up Turret"; - sprite = "TURRI1"; - width = 12; - height = 64; - angletext = "Firing delay"; - } - 122 - { - title = "Spring Shell (Green)"; - sprite = "SSHLA1"; - width = 24; - height = 40; - } - 125 - { - title = "Spring Shell (Yellow)"; - sprite = "SSHLI1"; - width = 24; - height = 40; - } - 109 - { - title = "Skim"; - sprite = "SKIMA1"; - width = 16; - height = 24; - } - 113 - { - title = "Jet Jaw"; - sprite = "JJAWA3A7"; - width = 12; - height = 20; - } - 126 - { - title = "Crushstacean"; - sprite = "CRABA0"; - width = 24; - height = 32; - flags8text = "[8] Move left from spawn"; - } - 138 - { - title = "Banpyura"; - sprite = "CR2BA0"; - width = 24; - height = 32; - flags8text = "[8] Move left from spawn"; - } - 117 - { - title = "Robo-Hood"; - sprite = "ARCHA1"; - width = 24; - height = 32; - } - 118 - { - title = "Lance-a-Bot"; - sprite = "CBFSA1"; - width = 32; - height = 72; - } - 1113 - { - title = "Suspicious Lance-a-Bot Statue"; - sprite = "CBBSA1"; - width = 32; - height = 72; - } - 119 - { - title = "Egg Guard"; - sprite = "ESHIA1"; - width = 16; - height = 48; - flags1text = "[1] 90 degrees counter-clockwise"; - flags4text = "[4] 90 degrees clockwise"; - flags8text = "[8] Double speed"; - } - 115 - { - title = "Bird Aircraft Strike Hazard"; - sprite = "VLTRF1"; - width = 12; - height = 24; - } - 120 - { - title = "Green Snapper"; - sprite = "GSNPA1"; - width = 24; - height = 24; - } - 121 - { - title = "Minus"; - sprite = "MNUSA0"; - width = 24; - height = 32; - } - 134 - { - title = "Canarivore"; - sprite = "CANAA0"; - width = 12; - height = 80; - hangs = 1; - } - 123 - { - title = "Unidus"; - sprite = "UNIDA1"; - width = 18; - height = 36; - } - 135 - { - title = "Pterabyte Spawner"; - sprite = "PTERA2A8"; - width = 16; - height = 16; - parametertext = "No. Pterabytes"; - } - 136 - { - title = "Pyre Fly"; - sprite = "PYREA0"; - width = 24; - height = 34; - flags8text = "[8] Start on fire"; - } - 137 - { - title = "Dragonbomber"; - sprite = "DRABA1"; - width = 28; - height = 48; - } - 105 - { - title = "Jetty-Syn Bomber"; - sprite = "JETBB1"; - width = 20; - height = 50; - flags8text = "[8] Cannot move"; - } - 106 - { - title = "Jetty-Syn Gunner"; - sprite = "JETGB1"; - width = 20; - height = 48; - flags8text = "[8] Cannot move"; - } - 112 - { - title = "Spincushion"; - sprite = "SHRPA1"; - width = 16; - height = 24; - } - 114 - { - title = "Snailer"; - sprite = "SNLRA3A7"; - width = 24; - height = 48; - } - 129 - { - title = "Penguinator"; - sprite = "PENGA1"; - width = 24; - height = 32; - } - 130 - { - title = "Pophat"; - sprite = "POPHA1"; - width = 24; - height = 32; - } - 107 - { - title = "Crawla Commander"; - sprite = "CCOMA1"; - width = 16; - height = 32; - } - 131 - { - title = "Spinbobert"; - sprite = "SBOBB0"; - width = 32; - height = 32; - } - 132 - { - title = "Cacolantern"; - sprite = "CACOA0"; - width = 32; - height = 32; - flags8text = "[8] Cannot move"; - } - 133 - { - title = "Hangster"; - sprite = "HBATC1"; - width = 24; - height = 24; - hangs = 1; - } - 127 - { - title = "Hive Elemental"; - sprite = "HIVEA0"; - width = 32; - height = 80; - parametertext = "No. bees"; - } - 128 - { - title = "Bumblebore"; - sprite = "BUMBA1"; - width = 16; - height = 32; - } - 124 - { - title = "Buggle"; - sprite = "BBUZA1"; - width = 20; - height = 24; - } - 116 - { - title = "Pointy"; - sprite = "PNTYA1"; - width = 8; - height = 16; - } - } - - bosses - { - color = 8; // Dark_Gray - arrow = 1; - title = "Bosses"; - - 200 - { - title = "Egg Mobile"; - sprite = "EGGMA1"; - width = 24; - height = 76; - flags4text = "[4] End level on death"; - flags8text = "[8] Alternate laser attack"; - } - 201 - { - title = "Egg Slimer"; - sprite = "EGGNA1"; - width = 24; - height = 76; - flags4text = "[4] End level on death"; - flags8text = "[8] Speed up when hit"; - } - 202 - { - title = "Sea Egg"; - sprite = "EGGOA1"; - width = 32; - height = 116; - flags4text = "[4] End level on death"; - } - 203 - { - title = "Egg Colosseum"; - sprite = "EGGPA1"; - width = 24; - height = 76; - flags4text = "[4] End level on death"; - } - 204 - { - title = "Fang"; - sprite = "FANGA1"; - width = 24; - height = 60; - flags1text = "[1] Grayscale mode"; - flags4text = "[4] End level on death"; - } - 206 - { - title = "Brak Eggman (Old)"; - sprite = "BRAKB1"; - width = 48; - height = 160; - flags4text = "[4] End level on death"; - } - 207 - { - title = "Metal Sonic (Race)"; - sprite = "METLI1"; - width = 16; - height = 48; - flags1text = "[1] Grayscale mode"; - } - 208 - { - title = "Metal Sonic (Battle)"; - sprite = "METLC1"; - width = 16; - height = 48; - flags1text = "[1] Grayscale mode"; - flags4text = "[4] End level on death"; - } - 209 - { - title = "Brak Eggman"; - sprite = "BRAK01"; - width = 48; - height = 160; - flags1text = "[1] No origin-fling death"; - flags4text = "[4] End level on death"; - flags8text = "[8] Electric barrier"; - } - 290 - { - arrow = 0; - title = "Boss Escape Point"; - width = 8; - height = 16; - sprite = "internal:eggmanend"; - } - 291 - { - arrow = 0; - title = "Egg Capsule Center"; - width = 8; - height = 16; - sprite = "internal:capsule"; - } - 292 - { - arrow = 0; - title = "Boss Waypoint"; - width = 8; - height = 16; - flags8text = "[8] Sea Egg shooting point"; - sprite = "internal:eggmanway"; - angletext = "No. (Sea Egg)"; - flagsvaluetext = "No. (Brak)"; - parametertext = "Next"; - } - 293 - { - title = "Metal Sonic Gather Point"; - sprite = "internal:metal"; - width = 8; - height = 16; - } - 294 - { - title = "Fang Waypoint"; - flags8text = "[8] Center waypoint"; - sprite = "internal:eggmanway"; - width = 8; - height = 16; - } - } - - rings - { - color = 14; // Yellow - title = "Rings and Weapon Panels"; - width = 24; - height = 24; - flags8height = 24; - flags8text = "[8] Float"; - sprite = "RINGA0"; - - 300 - { - title = "Ring"; - sprite = "RINGA0"; - width = 16; - } - 301 - { - title = "Bounce Ring"; - sprite = "internal:RNGBA0"; - } - 302 - { - title = "Rail Ring"; - sprite = "internal:RNGRA0"; - } - 303 - { - title = "Infinity Ring"; - sprite = "internal:RNGIA0"; - } - 304 - { - title = "Automatic Ring"; - sprite = "internal:RNGAA0"; - } - 305 - { - title = "Explosion Ring"; - sprite = "internal:RNGEA0"; - } - 306 - { - title = "Scatter Ring"; - sprite = "internal:RNGSA0"; - } - 307 - { - title = "Grenade Ring"; - sprite = "internal:RNGGA0"; - } - 308 - { - title = "CTF Team Ring (Red)"; - sprite = "internal:RRNGA0"; - width = 16; - } - 309 - { - title = "CTF Team Ring (Blue)"; - sprite = "internal:BRNGA0"; - width = 16; - } - 330 - { - title = "Bounce Ring Panel"; - sprite = "internal:PIKBA0"; - } - 331 - { - title = "Rail Ring Panel"; - sprite = "internal:PIKRA0"; - } - 332 - { - title = "Automatic Ring Panel"; - sprite = "internal:PIKAA0"; - } - 333 - { - title = "Explosion Ring Panel"; - sprite = "internal:PIKEA0"; - } - 334 - { - title = "Scatter Ring Panel"; - sprite = "internal:PIKSA0"; - } - 335 - { - title = "Grenade Ring Panel"; - sprite = "internal:PIKGA0"; - } - } - - collectibles - { - color = 10; // Light_Green - title = "Other Collectibles"; - width = 16; - height = 32; - sort = 1; - sprite = "CEMGA0"; - - 310 - { - title = "CTF Red Flag"; - sprite = "RFLGA0"; - width = 24; - height = 64; - } - 311 - { - title = "CTF Blue Flag"; - sprite = "BFLGA0"; - width = 24; - height = 64; - } - 312 - { - title = "Emerald Token"; - sprite = "TOKEA0"; - width = 16; - height = 32; - flags8height = 24; - flags8text = "[8] Float"; - } - 313 - { - title = "Chaos Emerald 1 (Green)"; - sprite = "CEMGA0"; - } - 314 - { - title = "Chaos Emerald 2 (Purple)"; - sprite = "CEMGB0"; - } - 315 - { - title = "Chaos Emerald 3 (Blue)"; - sprite = "CEMGC0"; - } - 316 - { - title = "Chaos Emerald 4 (Cyan)"; - sprite = "CEMGD0"; - } - 317 - { - title = "Chaos Emerald 5 (Orange)"; - sprite = "CEMGE0"; - } - 318 - { - title = "Chaos Emerald 6 (Red)"; - sprite = "CEMGF0"; - } - 319 - { - title = "Chaos Emerald 7 (Gray)"; - sprite = "CEMGG0"; - } - 320 - { - title = "Emerald Hunt Location"; - sprite = "SHRDA0"; - } - 321 - { - title = "Match Chaos Emerald Spawn"; - sprite = "CEMGA0"; - flags8height = 24; - flags8text = "[8] Float"; - } - 322 - { - title = "Emblem"; - sprite = "EMBMA0"; - width = 16; - height = 30; - flags8height = 24; - flags8text = "[8] Float"; - angletext = "Tag"; - } - } - - boxes - { - color = 7; // Gray - blocking = 2; - title = "Monitors"; - width = 18; - height = 40; - flags1text = "[1] Run Linedef Executor on pop"; - flags4text = "[4] Random (Strong)"; - flags8text = "[8] Random (Weak)"; - - 400 - { - title = "Super Ring (10 Rings)"; - sprite = "TVRIA0"; - } - 401 - { - title = "Pity Shield"; - sprite = "TVPIA0"; - } - 402 - { - title = "Attraction Shield"; - sprite = "TVATA0"; - } - 403 - { - title = "Force Shield"; - sprite = "TVFOA0"; - } - 404 - { - title = "Armageddon Shield"; - sprite = "TVARA0"; - } - 405 - { - title = "Whirlwind Shield"; - sprite = "TVWWA0"; - } - 406 - { - title = "Elemental Shield"; - sprite = "TVELA0"; - } - 407 - { - title = "Super Sneakers"; - sprite = "TVSSA0"; - } - 408 - { - title = "Invincibility"; - sprite = "TVIVA0"; - } - 409 - { - title = "Extra Life"; - sprite = "TV1UA0"; - flags4text = "[4] Random (Strong) / 10k points"; - flags8text = "[8] Random (Weak) / 10k points"; - } - 410 - { - title = "Eggman"; - sprite = "TVEGA0"; - flags4text = "[4] Special"; - flags8text = "[8] Ambush"; - } - 411 - { - title = "Teleporter"; - sprite = "TVMXA0"; - } - 413 - { - title = "Gravity Boots"; - sprite = "TVGVA0"; - flags4text = "[4] Special"; - flags8text = "[8] Ambush"; - } - 414 - { - title = "CTF Team Ring Monitor (Red)"; - sprite = "TRRIA0"; - flags4text = "[4] Special"; - flags8text = "[8] Ambush"; - } - 415 - { - title = "CTF Team Ring Monitor (Blue)"; - sprite = "TBRIA0"; - flags4text = "[4] Special"; - flags8text = "[8] Ambush"; - } - 416 - { - title = "Recycler"; - sprite = "TVRCA0"; - } - 418 - { - title = "Score (1,000 Points)"; - sprite = "TV1KA0"; - flags4text = "[4] Special"; - flags8text = "[8] Ambush"; - } - 419 - { - title = "Score (10,000 Points)"; - sprite = "TVTKA0"; - flags4text = "[4] Special"; - flags8text = "[8] Ambush"; - } - 420 - { - title = "Flame Shield"; - sprite = "TVFLA0"; - } - 421 - { - title = "Water Shield"; - sprite = "TVBBA0"; - } - 422 - { - title = "Lightning Shield"; - sprite = "TVZPA0"; - } - } - - boxes2 - { - color = 18; // Gold - blocking = 2; - title = "Monitors (Respawning)"; - width = 20; - height = 44; - flags1text = "[1] Run Linedef Executor on pop"; - - 431 - { - title = "Pity Shield (Respawn)"; - sprite = "TVPIB0"; - } - 432 - { - title = "Attraction Shield (Respawn)"; - sprite = "TVATB0"; - } - 433 - { - title = "Force Shield (Respawn)"; - sprite = "TVFOB0"; - } - 434 - { - title = "Armageddon Shield (Respawn)"; - sprite = "TVARB0"; - } - 435 - { - title = "Whirlwind Shield (Respawn)"; - sprite = "TVWWB0"; - } - 436 - { - title = "Elemental Shield (Respawn)"; - sprite = "TVELB0"; - } - 437 - { - title = "Super Sneakers (Respawn)"; - sprite = "TVSSB0"; - } - 438 - { - title = "Invincibility (Respawn)"; - sprite = "TVIVB0"; - } - 440 - { - title = "Eggman (Respawn)"; - sprite = "TVEGB0"; - } - 443 - { - title = "Gravity Boots (Respawn)"; - sprite = "TVGVB0"; - } - 450 - { - title = "Flame Shield (Respawn)"; - sprite = "TVFLB0"; - } - 451 - { - title = "Water Shield (Respawn)"; - sprite = "TVBBB0"; - } - 452 - { - title = "Lightning Shield (Respawn)"; - sprite = "TVZPB0"; - } - } - - generic - { - color = 11; // Light_Cyan - title = "Generic Items & Hazards"; - - 500 - { - title = "Air Bubble Patch"; - sprite = "BUBLE0"; - width = 8; - height = 16; - flags8text = "[8] No distance check"; - } - 501 - { - title = "Signpost"; - sprite = "SIGND0"; - width = 8; - height = 32; - } - 502 - { - arrow = 1; - title = "Star Post"; - sprite = "STPTA0M0"; - width = 64; - height = 128; - angletext = "Angle/Order"; - } - 520 - { - title = "Bomb Sphere"; - sprite = "SPHRD0"; - width = 16; - height = 24; - flags8height = 24; - flags8text = "[8] Float"; - unflippable = true; - } - 521 - { - title = "Spikeball"; - sprite = "SPIKA0"; - width = 12; - height = 8; - flags8height = 24; - flags8text = "[8] Float"; - } - 522 - { - title = "Wall Spike"; - sprite = "WSPKALAR"; - width = 16; - height = 14; - flags1text = "[1] Start retracted"; - flags4text = "[4] Retractable"; - flags8text = "[8] Intangible"; - parametertext = "Initial delay"; - } - 523 - { - title = "Spike"; - sprite = "USPKA0"; - width = 8; - height = 32; - flags1text = "[1] Start retracted"; - flags4text = "[4] Retractable"; - flags8text = "[8] Intangible"; - angletext = "Retraction interval"; - parametertext = "Initial delay"; - } - 1130 - { - title = "Small Mace"; - sprite = "SMCEA0"; - width = 17; - height = 34; - } - 1131 - { - title = "Big Mace"; - sprite = "BMCEA0"; - width = 34; - height = 68; - } - 1136 - { - title = "Small Fireball"; - sprite = "SFBRA0"; - width = 17; - height = 34; - } - 1137 - { - title = "Large Fireball"; - sprite = "BFBRA0"; - width = 34; - height = 68; - } - } - - springs - { - color = 12; // Light_Red - title = "Springs and Fans"; - width = 20; - height = 16; - sprite = "RSPRD2"; - - 540 - { - title = "Fan"; - sprite = "FANSA0D0"; - width = 16; - height = 8; - flags4text = "[4] Invisible"; - flags8text = "[8] No distance check"; - angletext = "Lift height"; - } - 541 - { - title = "Gas Jet"; - sprite = "STEMD0"; - flags8text = "[8] No sounds"; - width = 32; - } - 542 - { - title = "Bumper"; - sprite = "BUMPA0"; - width = 32; - height = 64; - angletext = "Strength"; - } - 543 - { - title = "Balloon"; - sprite = "BLONA0"; - width = 32; - height = 64; - flags8text = "[8] Respawn"; - angletext = "Color"; - } - 550 - { - title = "Yellow Spring"; - sprite = "SPRYA0"; - } - 551 - { - title = "Red Spring"; - sprite = "SPRRA0"; - } - 552 - { - title = "Blue Spring"; - sprite = "SPRBA0"; - } - 555 - { - arrow = 1; - title = "Diagonal Yellow Spring"; - sprite = "YSPRD2"; - width = 16; - flags4text = "[4] Ignore gravity"; - flags8text = "[8] Rotate 22.5° CCW"; - } - 556 - { - arrow = 1; - title = "Diagonal Red Spring"; - sprite = "RSPRD2"; - width = 16; - flags4text = "[4] Ignore gravity"; - flags8text = "[8] Rotate 22.5° CCW"; - } - 557 - { - arrow = 1; - title = "Diagonal Blue Spring"; - sprite = "BSPRD2"; - width = 16; - flags4text = "[4] Ignore gravity"; - flags8text = "[8] Rotate 22.5° CCW"; - } - 558 - { - arrow = 1; - title = "Horizontal Yellow Spring"; - sprite = "SSWYD2D8"; - flags8height = 16; - flags8text = "[8] Float"; - width = 16; - height = 32; - } - 559 - { - arrow = 1; - title = "Horizontal Red Spring"; - sprite = "SSWRD2D8"; - flags8height = 16; - flags8text = "[8] Float"; - width = 16; - height = 32; - } - 560 - { - arrow = 1; - title = "Horizontal Blue Spring"; - sprite = "SSWBD2D8"; - flags8height = 16; - flags8text = "[8] Float"; - width = 16; - height = 32; - } - 1134 - { - title = "Yellow Spring Ball"; - sprite = "YSPBA0"; - width = 17; - height = 34; - } - 1135 - { - title = "Red Spring Ball"; - sprite = "RSPBA0"; - width = 17; - height = 34; - } - 544 - { - arrow = 1; - title = "Yellow Boost Panel"; - sprite = "BSTYA0"; - flags8text = "[8] Force spin"; - width = 28; - height = 2; - } - 545 - { - arrow = 1; - title = "Red Boost Panel"; - sprite = "BSTRA0"; - flags8text = "[8] Force spin"; - width = 28; - height = 2; - } - } - - patterns - { - color = 5; // Magenta - arrow = 1; - title = "Special Placement Patterns"; - width = 16; - height = 384; - sprite = "RINGA0"; - - 600 - { - arrow = 0; - title = "5 Vertical Rings (Yellow Spring)"; - sprite = "RINGA0"; - } - 601 - { - arrow = 0; - title = "5 Vertical Rings (Red Spring)"; - sprite = "RINGA0"; - height = 1024; - } - 602 - { - title = "5 Diagonal Rings (Yellow Spring)"; - sprite = "RINGA0"; - height = 32; - } - 603 - { - title = "10 Diagonal Rings (Red Spring)"; - sprite = "RINGA0"; - height = 32; - } - 604 - { - title = "Circle of Rings"; - sprite = "RINGA0"; - width = 96; - height = 192; - unflippable = true; - centerHitbox = true; - } - 605 - { - title = "Circle of Rings (Big)"; - sprite = "RINGA0"; - width = 192; - unflippable = true; - centerHitbox = true; - } - 606 - { - title = "Circle of Blue Spheres"; - sprite = "SPHRA0"; - width = 96; - height = 192; - unflippable = true; - centerHitbox = true; - } - 607 - { - title = "Circle of Blue Spheres (Big)"; - sprite = "SPHRA0"; - width = 192; - unflippable = true; - centerHitbox = true; - } - 608 - { - title = "Circle of Rings and Spheres"; - sprite = "SPHRA0"; - width = 96; - height = 192; - unflippable = true; - centerHitbox = true; - } - 609 - { - title = "Circle of Rings and Spheres (Big)"; - sprite = "SPHRA0"; - width = 192; - unflippable = true; - centerHitbox = true; - } - } - - invisible - { - color = 15; // White - title = "Misc. Invisible"; - width = 8; - height = 16; - sprite = "UNKNA0"; - - 700 - { - title = "Water Ambience A (Large)"; - sprite = "internal:ambiance"; - } - - 701 - { - title = "Water Ambience B (Large)"; - sprite = "internal:ambiance"; - } - - 702 - { - title = "Water Ambience C (Medium)"; - sprite = "internal:ambiance"; - } - - 703 - { - title = "Water Ambience D (Medium)"; - sprite = "internal:ambiance"; - } - - 704 - { - title = "Water Ambience E (Small)"; - sprite = "internal:ambiance"; - } - - 705 - { - title = "Water Ambience F (Small)"; - sprite = "internal:ambiance"; - } - - 706 - { - title = "Water Ambience G (Extra Large)"; - sprite = "internal:ambiance"; - } - - 707 - { - title = "Water Ambience H (Extra Large)"; - sprite = "internal:ambiance"; - } - - 708 - { - title = "Disco Ambience"; - sprite = "internal:ambiance"; - } - - 709 - { - title = "Volcano Ambience"; - sprite = "internal:ambiance"; - } - - 710 - { - title = "Machine Ambience"; - sprite = "internal:ambiance"; - } - - 750 - { - title = "Slope Vertex"; - sprite = "internal:vertexslope"; - angletext = "Tag"; - } - - 751 - { - arrow = 1; - title = "Teleport Destination"; - sprite = "internal:tele"; - } - - 752 - { - arrow = 1; - title = "Alternate View Point"; - sprite = "internal:view"; - } - - 753 - { - title = "Zoom Tube Waypoint"; - sprite = "internal:zoom"; - angletext = "Order"; - } - - 754 - { - title = "Push Point"; - flags4text = "[4] Fades using XY"; - flags8text = "[8] Push using XYZ"; - sprite = "GWLGA0"; - angletext = "Radius"; - } - 755 - { - title = "Pull Point"; - flags4text = "[4] Fades using XY"; - flags8text = "[8] Pull using XYZ"; - sprite = "GWLRA0"; - angletext = "Radius"; - } - 756 - { - title = "Blast Linedef Executor"; - sprite = "TOADA0"; - width = 32; - height = 16; - } - 757 - { - title = "Fan Particle Generator"; - sprite = "PRTLA0"; - width = 8; - height = 16; - angletext = "Tag"; - } - 758 - { - title = "Object Angle Anchor"; - sprite = "internal:view"; - } - 760 - { - title = "PolyObject Anchor"; - sprite = "internal:polyanchor"; - angletext = "ID"; - } - - 761 - { - title = "PolyObject Spawn Point"; - sprite = "internal:polycenter"; - angletext = "ID"; - } - - 762 - { - title = "PolyObject Spawn Point (Crush)"; - sprite = "internal:polycentercrush"; - angletext = "ID"; - } - 780 - { - title = "Skybox View Point"; - sprite = "internal:skyb"; - flags4text = "[4] In-map centerpoint"; - parametertext = "ID"; - } - } - - greenflower - { - color = 10; // Green - title = "Greenflower"; - - 800 - { - title = "GFZ Flower"; - sprite = "FWR1A0"; - width = 16; - height = 40; - } - 801 - { - title = "Sunflower"; - sprite = "FWR2A0"; - width = 16; - height = 96; - } - 802 - { - title = "Budding Flower"; - sprite = "FWR3A0"; - width = 8; - height = 32; - } - 803 - { - title = "Blueberry Bush"; - sprite = "BUS3A0"; - width = 16; - height = 32; - } - 804 - { - title = "Berry Bush"; - sprite = "BUS1A0"; - width = 16; - height = 32; - } - 805 - { - title = "Bush"; - sprite = "BUS2A0"; - width = 16; - height = 32; - } - 806 - { - title = "GFZ Tree"; - sprite = "TRE1A0"; - width = 20; - height = 128; - } - 807 - { - title = "GFZ Berry Tree"; - sprite = "TRE1B0"; - width = 20; - height = 128; - } - 808 - { - title = "GFZ Cherry Tree"; - sprite = "TRE1C0"; - width = 20; - height = 128; - } - 809 - { - title = "Checkered Tree"; - sprite = "TRE2A0"; - width = 20; - height = 200; - } - 810 - { - title = "Checkered Tree (Sunset)"; - sprite = "TRE2B0"; - width = 20; - height = 200; - } - 811 - { - title = "Polygon Tree"; - sprite = "TRE4A0"; - width = 20; - height = 200; - } - 812 - { - title = "Bush Tree"; - sprite = "TRE5A0"; - width = 20; - height = 200; - } - 813 - { - title = "Red Bush Tree"; - sprite = "TRE5B0"; - width = 20; - height = 200; - } - } - - technohill - { - color = 10; // Green - title = "Techno Hill"; - - 900 - { - title = "THZ Steam Flower"; - sprite = "THZPA0"; - width = 8; - height = 32; - } - 901 - { - title = "Alarm"; - sprite = "ALRMA0"; - width = 8; - height = 16; - hangs = 1; - } - 902 - { - title = "THZ Spin Flower (Red)"; - sprite = "FWR5A0"; - width = 16; - height = 64; - } - 903 - { - title = "THZ Spin Flower (Yellow)"; - sprite = "FWR6A0"; - width = 16; - height = 64; - } - 904 - { - arrow = 1; - title = "Whistlebush"; - sprite = "THZTA0"; - width = 16; - height = 64; - } - } - - deepsea - { - color = 10; // Green - title = "Deep Sea"; - - 1000 - { - arrow = 1; - blocking = 2; - title = "Gargoyle"; - sprite = "GARGA1"; - width = 16; - height = 40; - flags4text = "[4] Slides when pushed"; - flags8text = "[8] Not pushable"; - } - 1009 - { - arrow = 1; - blocking = 2; - title = "Gargoyle (Big)"; - sprite = "GARGB1"; - width = 32; - height = 80; - flags4text = "[4] Slides when pushed"; - flags8text = "[8] Not pushable"; - } - 1001 - { - title = "Seaweed"; - sprite = "SEWEA0"; - width = 24; - height = 56; - } - 1002 - { - title = "Dripping Water"; - sprite = "DRIPD0"; - width = 8; - height = 16; - hangs = 1; - angletext = "Dripping interval"; - } - 1003 - { - title = "Coral (Green)"; - sprite = "CORLA0"; - width = 29; - height = 40; - } - 1004 - { - title = "Coral (Red)"; - sprite = "CORLB0"; - width = 30; - height = 53; - } - 1005 - { - title = "Coral (Orange)"; - sprite = "CORLC0"; - width = 28; - height = 41; - } - 1006 - { - title = "Blue Crystal"; - sprite = "BCRYA1"; - width = 8; - height = 16; - } - 1007 - { - title = "Kelp"; - sprite = "KELPA0"; - width = 16; - height = 292; - flags4text = "[4] Double size"; - } - 1008 - { - title = "Stalagmite (DSZ1)"; - sprite = "DSTGA0"; - width = 8; - height = 116; - flags4text = "[4] Double size"; - } - 1010 - { - arrow = 1; - title = "Light Beam"; - sprite = "LIBEARAL"; - width = 16; - height = 16; - } - 1011 - { - title = "Stalagmite (DSZ2)"; - sprite = "DSTGA0"; - width = 8; - height = 116; - flags4text = "[4] Double size"; - } - 1012 - { - arrow = 1; - title = "Big Floating Mine"; - width = 28; - height = 56; - sprite = "BMNEA1"; - } - 1013 - { - title = "Animated Kelp"; - sprite = "ALGAA0"; - width = 48; - height = 120; - } - 1014 - { - title = "Large Coral (Brown)"; - sprite = "CORLD0"; - width = 56; - height = 112; - } - 1015 - { - title = "Large Coral (Beige)"; - sprite = "CORLE0"; - width = 56; - height = 112; - } - } - - castleeggman - { - color = 10; // Green - title = "Castle Eggman"; - - 1100 - { - title = "Chain (Decorative)"; - sprite = "CHANA0"; - width = 4; - height = 128; - hangs = 1; - } - 1101 - { - title = "Torch"; - sprite = "FLAMA0E0"; - width = 8; - height = 32; - flags1text = "[1] Add corona"; - } - 1102 - { - arrow = 1; - blocking = 2; - title = "Eggman Statue"; - sprite = "ESTAA1"; - width = 32; - height = 240; - flags1text = "[1] Solid gold"; - flags4text = "[4] Slides when pushed"; - flags8text = "[8] Not pushable"; - } - 1103 - { - title = "CEZ Flower"; - sprite = "FWR4A0"; - width = 16; - height = 40; - } - 1104 - { - title = "Mace Spawnpoint"; - sprite = "SMCEA0"; - width = 17; - height = 34; - flags4text = "[4] No sounds"; - flags8text = "[8] Double size"; - angletext = "Tag"; - } - 1105 - { - title = "Chain with Maces Spawnpoint"; - sprite = "SMCEA0"; - width = 17; - height = 34; - flags4text = "[4] No sounds"; - flags8text = "[8] Double size"; - angletext = "Tag"; - } - 1106 - { - title = "Chained Spring Spawnpoint"; - sprite = "YSPBA0"; - width = 17; - height = 34; - flags4text = "[4] No sounds"; - flags8text = "[8] Red spring"; - angletext = "Tag"; - } - 1107 - { - title = "Chain Spawnpoint"; - sprite = "BMCHA0"; - width = 17; - height = 34; - flags8text = "[8] Double size"; - angletext = "Tag"; - } - 1108 - { - arrow = 1; - title = "Hidden Chain Spawnpoint"; - sprite = "internal:chain3"; - width = 17; - height = 34; - flags8text = "[8] Double size"; - } - 1109 - { - title = "Firebar Spawnpoint"; - sprite = "BFBRA0"; - width = 17; - height = 34; - flags4text = "[4] No sounds"; - flags8text = "[8] Double size"; - angletext = "Tag"; - } - 1110 - { - title = "Custom Mace Spawnpoint"; - sprite = "SMCEA0"; - width = 17; - height = 34; - flags4text = "[4] No sounds"; - angletext = "Tag"; - } - 1111 - { - arrow = 1; - blocking = 2; - title = "Crawla Statue"; - sprite = "CSTAA1"; - width = 16; - height = 40; - flags4text = "[4] Slides when pushed"; - flags8text = "[8] Not pushable"; - } - 1112 - { - arrow = 1; - blocking = 2; - title = "Lance-a-Bot Statue"; - sprite = "CBBSA1"; - width = 32; - height = 72; - flags4text = "[4] Slides when pushed"; - flags8text = "[8] Not pushable"; - } - 1114 - { - title = "Pine Tree"; - sprite = "PINEA0"; - width = 16; - height = 628; - } - 1115 - { - title = "CEZ Shrub (Small)"; - sprite = "CEZBA0"; - width = 16; - height = 24; - } - 1116 - { - title = "CEZ Shrub (Large)"; - sprite = "CEZBB0"; - width = 32; - height = 48; - } - 1117 - { - arrow = 1; - title = "Pole Banner (Red)"; - sprite = "BANRA0"; - width = 40; - height = 224; - } - 1118 - { - arrow = 1; - title = "Pole Banner (Blue)"; - sprite = "BANRA0"; - width = 40; - height = 224; - } - 1119 - { - title = "Candle"; - sprite = "CNDLA0"; - width = 8; - height = 48; - flags1text = "[1] Add corona"; - } - 1120 - { - title = "Candle Pricket"; - sprite = "CNDLB0"; - width = 8; - height = 176; - flags1text = "[1] Add corona"; - } - 1121 - { - title = "Flame Holder"; - sprite = "FLMHA0"; - width = 24; - height = 80; - flags1text = "[1] Add corona"; - flags4text = "[4] No flame"; - } - 1122 - { - title = "Fire Torch"; - sprite = "CTRCA0"; - width = 16; - height = 80; - } - 1123 - { - title = "Cannonball Launcher"; - sprite = "internal:cannonball"; - width = 8; - height = 16; - } - 1124 - { - blocking = 2; - title = "Cannonball"; - sprite = "CBLLA0"; - width = 20; - height = 40; - flags4text = "[4] Slides when pushed"; - flags8text = "[8] Not pushable"; - } - 1125 - { - title = "Brambles"; - sprite = "CABRALAR"; - width = 48; - height = 32; - } - 1126 - { - title = "Invisible Lockon Object"; - sprite = "LCKNC0"; - width = 16; - height = 32; - } - 1127 - { - title = "Spectator Eggrobo"; - sprite = "EGR1A1"; - width = 20; - height = 72; - } - 1128 - { - arrow = 1; - title = "Waving Flag (Red)"; - sprite = "CFLGA0"; - width = 8; - height = 208; - } - 1129 - { - arrow = 1; - title = "Waving Flag (Blue)"; - sprite = "CFLGA0"; - width = 8; - height = 208; - } - } - - aridcanyon - { - color = 10; // Green - title = "Arid Canyon"; - - 1200 - { - title = "Tumbleweed (Big)"; - sprite = "BTBLA0"; - width = 24; - height = 48; - flags8text = "[8] Moves perpetually"; - } - 1201 - { - title = "Tumbleweed (Small)"; - sprite = "STBLA0"; - width = 12; - height = 24; - flags8text = "[8] Moves perpetually"; - } - 1202 - { - arrow = 1; - title = "Rock Spawner"; - sprite = "ROIAA0"; - width = 8; - height = 16; - angletext = "Tag"; - } - 1203 - { - title = "Tiny Red Flower Cactus"; - sprite = "CACTA0"; - width = 13; - height = 24; - } - 1204 - { - title = "Small Red Flower Cactus"; - sprite = "CACTB0"; - width = 15; - height = 52; - } - 1205 - { - title = "Tiny Blue Flower Cactus"; - sprite = "CACTC0"; - width = 13; - height = 24; - } - 1206 - { - title = "Small Blue Flower Cactus"; - sprite = "CACTD0"; - width = 15; - height = 52; - } - 1207 - { - title = "Prickly Pear"; - sprite = "CACTE0"; - width = 32; - height = 96; - } - 1208 - { - title = "Barrel Cactus"; - sprite = "CACTF0"; - width = 20; - height = 128; - } - 1209 - { - title = "Tall Barrel Cactus"; - sprite = "CACTG0"; - width = 24; - height = 224; - } - 1210 - { - title = "Armed Cactus"; - sprite = "CACTH0"; - width = 24; - height = 256; - } - 1211 - { - title = "Ball Cactus"; - sprite = "CACTI0"; - width = 48; - height = 96; - } - 1212 - { - title = "Caution Sign"; - sprite = "WWSGAR"; - width = 22; - height = 64; - } - 1213 - { - title = "Cacti Sign"; - sprite = "WWS2AR"; - width = 22; - height = 64; - } - 1214 - { - title = "Sharp Turn Sign"; - sprite = "WWS3ALAR"; - width = 16; - height = 192; - } - 1215 - { - title = "Mine Oil Lamp"; - sprite = "OILLA0"; - width = 22; - height = 64; - hangs = 1; - } - 1216 - { - title = "TNT Barrel"; - sprite = "BARRA1"; - width = 24; - height = 63; - } - 1217 - { - title = "TNT Proximity Shell"; - sprite = "REMTA0"; - width = 64; - height = 40; - } - 1218 - { - title = "Dust Devil"; - sprite = "TAZDCR"; - width = 80; - height = 416; - } - 1219 - { - title = "Minecart Spawner"; - sprite = "MCRTCLFR"; - width = 22; - height = 32; - } - 1220 - { - title = "Minecart Stopper"; - sprite = "MCRTIR"; - width = 32; - height = 32; - } - 1221 - { - title = "Minecart Saloon Door"; - sprite = "SALDARAL"; - width = 96; - height = 160; - flags8text = "[8] Allow non-minecart players"; - } - 1222 - { - title = "Train Cameo Spawner"; - sprite = "TRAEBRBL"; - width = 28; - height = 32; - } - 1223 - { - title = "Train Dust Spawner"; - sprite = "ADSTA0"; - width = 4; - height = 4; - } - 1224 - { - title = "Train Steam Spawner"; - sprite = "STEAA0"; - width = 4; - height = 4; - } - 1229 - { - title = "Minecart Switch Point"; - sprite = "internal:zoom"; - width = 8; - height = 16; - flags8text = "[8] Enable switching"; - } - 1230 - { - title = "Tiny Cactus"; - sprite = "CACTJ0"; - width = 13; - height = 28; - } - 1231 - { - title = "Small Cactus"; - sprite = "CACTK0"; - width = 15; - height = 60; - } - } - - redvolcano - { - color = 10; // Green - title = "Red Volcano"; - - 1300 - { - arrow = 1; - title = "Flame Jet (Horizontal)"; - sprite = "internal:flameh"; - width = 16; - height = 40; - flags8text = "[8] Waves vertically"; - angletext = "On/Off time"; - parametertext = "Strength"; - } - 1301 - { - title = "Flame Jet (Vertical)"; - sprite = "internal:flamev"; - width = 16; - height = 40; - flags8text = "[8] Shoot downwards"; - angletext = "On/Off time"; - parametertext = "Strength"; - } - 1302 - { - title = "Spinning Flame Jet (Counter-Clockwise)"; - sprite = "internal:flame2"; - width = 16; - height = 24; - } - 1303 - { - title = "Spinning Flame Jet (Clockwise)"; - sprite = "internal:flame1"; - width = 16; - height = 24; - } - 1304 - { - title = "Lavafall"; - sprite = "LFALF0"; - width = 30; - height = 32; - angletext = "Initial delay"; - flags8text = "[8] Double size"; - } - 1305 - { - title = "Rollout Rock"; - sprite = "PUMIA1A5"; - width = 30; - height = 60; - flags8text = "[8] Non-buoyant"; - } - 1306 - { - title = "Big Fern"; - sprite = "JPLAB0"; - width = 32; - height = 48; - } - 1307 - { - title = "Jungle Palm"; - sprite = "JPLAC0"; - width = 32; - height = 48; - } - 1308 - { - title = "Torch Flower"; - sprite = "TFLOA0"; - width = 14; - height = 110; - } - 1309 - { - title = "RVZ1 Wall Vine (Long)"; - sprite = "WVINALAR"; - width = 1; - height = 288; - } - 1310 - { - title = "RVZ1 Wall Vine (Short)"; - sprite = "WVINBLBR"; - width = 1; - height = 288; - } - } - - botanicserenity - { - color = 10; // Green - title = "Botanic Serenity"; - width = 16; - height = 32; - sprite = "BSZ1A0"; - 1400 - { - title = "Tall Flower (Red)"; - sprite = "BSZ1A0"; - } - 1401 - { - title = "Tall Flower (Purple)"; - sprite = "BSZ1B0"; - } - 1402 - { - title = "Tall Flower (Blue)"; - sprite = "BSZ1C0"; - } - 1403 - { - title = "Tall Flower (Cyan)"; - sprite = "BSZ1D0"; - } - 1404 - { - title = "Tall Flower (Yellow)"; - sprite = "BSZ1E0"; - } - 1405 - { - title = "Tall Flower (Orange)"; - sprite = "BSZ1F0"; - } - 1410 - { - title = "Medium Flower (Red)"; - sprite = "BSZ2A0"; - } - 1411 - { - title = "Medium Flower (Purple)"; - sprite = "BSZ2B0"; - } - 1412 - { - title = "Medium Flower (Blue)"; - sprite = "BSZ2C0"; - } - 1413 - { - title = "Medium Flower (Cyan)"; - sprite = "BSZ2D0"; - } - 1414 - { - title = "Medium Flower (Yellow)"; - sprite = "BSZ2E0"; - } - 1415 - { - title = "Medium Flower (Orange)"; - sprite = "BSZ2F0"; - } - 1420 - { - title = "Short Flower (Red)"; - sprite = "BSZ3A0"; - } - 1421 - { - title = "Short Flower (Purple)"; - sprite = "BSZ3B0"; - } - 1422 - { - title = "Short Flower (Blue)"; - sprite = "BSZ3C0"; - } - 1423 - { - title = "Short Flower (Cyan)"; - sprite = "BSZ3D0"; - } - 1424 - { - title = "Short Flower (Yellow)"; - sprite = "BSZ3E0"; - } - 1425 - { - title = "Short Flower (Orange)"; - sprite = "BSZ3F0"; - } - 1430 - { - title = "Tulip (Red)"; - sprite = "BST1A0"; - } - 1431 - { - title = "Tulip (Purple)"; - sprite = "BST2A0"; - } - 1432 - { - title = "Tulip (Blue)"; - sprite = "BST3A0"; - } - 1433 - { - title = "Tulip (Cyan)"; - sprite = "BST4A0"; - } - 1434 - { - title = "Tulip (Yellow)"; - sprite = "BST5A0"; - } - 1435 - { - title = "Tulip (Orange)"; - sprite = "BST6A0"; - } - 1440 - { - title = "Cluster (Red)"; - sprite = "BSZ5A0"; - } - 1441 - { - title = "Cluster (Purple)"; - sprite = "BSZ5B0"; - } - 1442 - { - title = "Cluster (Blue)"; - sprite = "BSZ5C0"; - } - 1443 - { - title = "Cluster (Cyan)"; - sprite = "BSZ5D0"; - } - 1444 - { - title = "Cluster (Yellow)"; - sprite = "BSZ5E0"; - } - 1445 - { - title = "Cluster (Orange)"; - sprite = "BSZ5F0"; - } - 1450 - { - title = "Bush (Red)"; - sprite = "BSZ6A0"; - } - 1451 - { - title = "Bush (Purple)"; - sprite = "BSZ6B0"; - } - 1452 - { - title = "Bush (Blue)"; - sprite = "BSZ6C0"; - } - 1453 - { - title = "Bush (Cyan)"; - sprite = "BSZ6D0"; - } - 1454 - { - title = "Bush (Yellow)"; - sprite = "BSZ6E0"; - } - 1455 - { - title = "Bush (Orange)"; - sprite = "BSZ6F0"; - } - 1460 - { - title = "Vine (Red)"; - sprite = "BSZ7A0"; - } - 1461 - { - title = "Vine (Purple)"; - sprite = "BSZ7B0"; - } - 1462 - { - title = "Vine (Blue)"; - sprite = "BSZ7C0"; - } - 1463 - { - title = "Vine (Cyan)"; - sprite = "BSZ7D0"; - } - 1464 - { - title = "Vine (Yellow)"; - sprite = "BSZ7E0"; - } - 1465 - { - title = "Vine (Orange)"; - sprite = "BSZ7F0"; - } - 1470 - { - title = "BSZ Shrub"; - sprite = "BSZ8A0"; - } - 1471 - { - title = "BSZ Clover"; - sprite = "BSZ8B0"; - } - 1473 - { - title = "Palm Tree (Big)"; - width = 16; - height = 160; - sprite = "BSZ8D0"; - } - 1475 - { - title = "Palm Tree (Small)"; - width = 16; - height = 80; - sprite = "BSZ8F0"; - } - } - - azuretemple - { - color = 10; // Green - title = "Azure Temple"; - - 1500 - { - arrow = 1; - blocking = 2; - title = "Glaregoyle"; - sprite = "BGARA1"; - width = 16; - height = 40; - flags4text = "[4] Slides when pushed"; - flags8text = "[8] Not pushable"; - } - 1501 - { - arrow = 1; - blocking = 2; - title = "Glaregoyle (Up)"; - sprite = "BGARA1"; - width = 16; - height = 40; - flags4text = "[4] Slides when pushed"; - flags8text = "[8] Not pushable"; - } - 1502 - { - arrow = 1; - blocking = 2; - title = "Glaregoyle (Down)"; - sprite = "BGARA1"; - width = 16; - height = 40; - flags4text = "[4] Slides when pushed"; - flags8text = "[8] Not pushable"; - } - 1503 - { - arrow = 1; - blocking = 2; - title = "Glaregoyle (Long)"; - sprite = "BGARA1"; - width = 16; - height = 40; - flags4text = "[4] Slides when pushed"; - flags8text = "[8] Not pushable"; - } - 1504 - { - title = "ATZ Target"; - sprite = "RCRYB0"; - width = 24; - height = 32; - } - 1505 - { - title = "Green Flame"; - sprite = "CFLMA0E0"; - width = 8; - height = 32; - } - 1506 - { - arrow = 1; - blocking = 2; - title = "Blue Gargoyle"; - sprite = "BGARD1"; - width = 16; - height = 40; - flags4text = "[4] Slides when pushed"; - flags8text = "[8] Not pushable"; - } - } - - dreamhill - { - color = 10; // Green - title = "Dream Hill"; - - 1600 - { - title = "Spring Tree"; - sprite = "TRE6A0"; - width = 16; - height = 32; - } - 1601 - { - title = "Shleep"; - sprite = "SHLPA0"; - width = 24; - height = 32; - } - 1602 - { - title = "Pian"; - sprite = "NTPNALAR"; - width = 16; - height = 32; - } - } - - nightstrk - { - color = 13; // Pink - title = "NiGHTS Track"; - width = 8; - height = 4096; - sprite = "UNKNA0"; - - 1700 - { - title = "Axis"; - sprite = "internal:axis1"; - circle = 1; - unflippable = true; - ignoreZ = true; - flagsvaluetext = "Order"; - angletext = "Radius/Direction"; - parametertext = "Mare"; - } - 1701 - { - title = "Axis Transfer"; - sprite = "internal:axis2"; - unflippable = true; - ignoreZ = true; - flagsvaluetext = "Order"; - parametertext = "Mare"; - } - 1702 - { - title = "Axis Transfer Line"; - sprite = "internal:axis3"; - unflippable = true; - ignoreZ = true; - flagsvaluetext = "Order"; - parametertext = "Mare"; - } - 1710 - { - title = "Ideya Capture"; - sprite = "CAPSA0"; - width = 72; - height = 144; - angletext = "Rings"; - parametertext = "Mare"; - } - } - - nights - { - color = 13; // Pink - title = "NiGHTS Items"; - width = 16; - height = 32; - - 1703 - { - title = "Ideya Drone"; - sprite = "NDRNA1"; - width = 16; - height = 56; - flags1text = "[1] Align player to middle"; - flags4text = "[4] Align player to top"; - flags8text = "[8] Die upon time up"; - angletext = "Time limit"; - parametertext = "Height"; - } - 1704 - { - arrow = 1; - title = "NiGHTS Bumper"; - sprite = "NBMPG3G7"; - width = 32; - height = 64; - unflippable = true; - flagsvaluetext = "Pitch"; - angletext = "Yaw"; - } - 1705 - { - arrow = 1; - title = "Hoop (Generic)"; - sprite = "HOOPA0"; - width = 80; - height = 160; - unflippable = true; - centerHitbox = true; - flagsvaluetext = "Height"; - angletext = "Pitch/Yaw"; - } - 1706 - { - title = "Blue Sphere"; - sprite = "SPHRA0"; - width = 16; - height = 24; - flags8height = 24; - flags8text = "[8] Float"; - unflippable = true; - } - 1707 - { - title = "Super Paraloop"; - sprite = "NPRUA0"; - flags4text = "[4] Bonus time only"; - flags8text = "[8] Spawn immediately"; - } - 1708 - { - title = "Drill Refill"; - sprite = "NPRUB0"; - flags4text = "[4] Bonus time only"; - flags8text = "[8] Spawn immediately"; - } - 1709 - { - title = "Nightopian Helper"; - sprite = "NPRUC0"; - flags4text = "[4] Bonus time only"; - flags8text = "[8] Spawn immediately"; - } - 1711 - { - title = "Extra Time"; - sprite = "NPRUD0"; - flags4text = "[4] Bonus time only"; - flags8text = "[8] Spawn immediately"; - } - 1712 - { - title = "Link Freeze"; - sprite = "NPRUE0"; - flags4text = "[4] Bonus time only"; - flags8text = "[8] Spawn immediately"; - } - 1713 - { - arrow = 1; - title = "Hoop (Customizable)"; - flags1text = "[1] Radius +16"; - flags2text = "[2] Radius +32"; - flags4text = "[4] Radius +64"; - flags8text = "[8] Radius +128"; - sprite = "HOOPA0"; - width = 80; - height = 160; - unflippable = true; - centerHitbox = true; - } - 1714 - { - title = "Ideya Anchor Point"; - sprite = "internal:axis1"; - width = 8; - height = 16; - parametertext = "Ideya"; - } - } - - mario - { - color = 6; // Brown - title = "Mario"; - - 1800 - { - title = "Coin"; - sprite = "COINA0"; - width = 16; - height = 24; - flags8height = 24; - flags8text = "[8] Float"; - } - 1801 - { - arrow = 1; - title = "Goomba"; - sprite = "GOOMA0"; - width = 24; - height = 32; - } - 1802 - { - arrow = 1; - title = "Goomba (Blue)"; - sprite = "BGOMA0"; - width = 24; - height = 32; - } - 1803 - { - title = "Fire Flower"; - sprite = "FFWRB0"; - width = 16; - height = 32; - } - 1804 - { - title = "Koopa Shell"; - sprite = "SHLLA1"; - width = 16; - height = 20; - } - 1805 - { - title = "Puma (Jumping Fireball)"; - sprite = "PUMAA0"; - width = 8; - height = 16; - angletext = "Jump strength"; - } - 1806 - { - title = "King Bowser"; - sprite = "KOOPA0"; - width = 16; - height = 48; - } - 1807 - { - title = "Axe"; - sprite = "MAXEA0"; - width = 8; - height = 16; - } - 1808 - { - title = "Bush (Short)"; - sprite = "MUS1A0"; - width = 16; - height = 32; - } - 1809 - { - title = "Bush (Tall)"; - sprite = "MUS2A0"; - width = 16; - height = 32; - } - 1810 - { - title = "Toad"; - sprite = "TOADA0"; - width = 8; - height = 32; - } - } - - christmasdisco - { - color = 10; // Green - title = "Christmas & Disco"; - - 1850 - { - title = "Christmas Pole"; - sprite = "XMS1A0"; - width = 16; - height = 40; - } - 1851 - { - title = "Candy Cane"; - sprite = "XMS2A0"; - width = 8; - height = 32; - } - 1852 - { - blocking = 2; - title = "Snowman"; - sprite = "XMS3A0"; - width = 16; - height = 64; - flags4text = "[4] Slides when pushed"; - flags8text = "[8] Not pushable"; - } - 1853 - { - blocking = 2; - title = "Snowman (With Hat)"; - sprite = "XMS3B0"; - width = 16; - height = 80; - flags4text = "[4] Slides when pushed"; - flags8text = "[8] Not pushable"; - } - 1854 - { - title = "Lamp Post"; - sprite = "XMS4A0"; - width = 8; - height = 120; - } - 1855 - { - title = "Lamp Post (Snow)"; - sprite = "XMS4B0"; - width = 8; - height = 120; - } - 1856 - { - title = "Hanging Star"; - sprite = "XMS5A0"; - width = 4; - height = 80; - hangs = 1; - } - 1857 - { - title = "Berry Bush (Snow)"; - sprite = "BUS1B0"; - width = 16; - height = 32; - } - 1858 - { - title = "Bush (Snow)"; - sprite = "BUS2B0"; - width = 16; - height = 32; - } - 1859 - { - title = "Blueberry Bush (Snow)"; - sprite = "BUS3B0"; - width = 16; - height = 32; - } - 1875 - { - title = "Disco Ball"; - sprite = "DBALA0"; - width = 16; - height = 54; - hangs = 1; - } - 1876 - { - arrow = 1; - blocking = 2; - title = "Eggman Disco Statue"; - sprite = "ESTAB1"; - width = 20; - height = 96; - flags4text = "[4] Slides when pushed"; - flags8text = "[8] Not pushable"; - } - } - - stalagmites - { - color = 10; // Green - title = "Stalagmites"; - width = 16; - height = 40; - - 1900 - { - title = "Brown Stalagmite (Tall)"; - sprite = "STLGA0"; - width = 16; - height = 40; - } - 1901 - { - title = "Brown Stalagmite"; - sprite = "STLGB0"; - width = 16; - height = 40; - } - 1902 - { - title = "Orange Stalagmite (Tall)"; - sprite = "STLGC0"; - width = 16; - height = 40; - } - 1903 - { - title = "Orange Stalagmite"; - sprite = "STLGD0"; - width = 16; - height = 40; - } - 1904 - { - title = "Red Stalagmite (Tall)"; - sprite = "STLGE0"; - width = 16; - height = 40; - } - 1905 - { - title = "Red Stalagmite"; - sprite = "STLGF0"; - width = 16; - height = 40; - } - 1906 - { - title = "Gray Stalagmite (Tall)"; - sprite = "STLGG0"; - width = 24; - height = 96; - } - 1907 - { - title = "Gray Stalagmite"; - sprite = "STLGH0"; - width = 16; - height = 40; - } - 1908 - { - title = "Blue Stalagmite (Tall)"; - sprite = "STLGI0"; - width = 16; - height = 40; - } - 1909 - { - title = "Blue Stalagmite"; - sprite = "STLGJ0"; - width = 16; - height = 40; - } - } - - hauntedheights - { - color = 10; // Green - title = "Haunted Heights"; - - 2000 - { - title = "Smashing Spikeball"; - sprite = "FMCEA0"; - width = 18; - height = 28; - angletext = "Initial delay"; - } - 2001 - { - title = "HHZ Grass"; - sprite = "HHZMA0"; - width = 16; - height = 40; - } - 2002 - { - title = "HHZ Tentacle 1"; - sprite = "HHZMB0"; - width = 16; - height = 40; - } - 2003 - { - title = "HHZ Tentacle 2"; - sprite = "HHZMC0"; - width = 16; - height = 40; - } - 2004 - { - title = "HHZ Stalagmite (Tall)"; - sprite = "HHZME0"; - width = 16; - height = 40; - } - 2005 - { - title = "HHZ Stalagmite (Short)"; - sprite = "HHZMF0"; - width = 16; - height = 40; - } - 2006 - { - title = "Jack-o'-lantern 1"; - sprite = "PUMKA0"; - width = 16; - height = 40; - flags1text = "Don't flicker"; - } - 2007 - { - title = "Jack-o'-lantern 2"; - sprite = "PUMKB0"; - width = 16; - height = 40; - flags1text = "Don't flicker"; - } - 2008 - { - title = "Jack-o'-lantern 3"; - sprite = "PUMKC0"; - width = 16; - height = 40; - flags1text = "Don't flicker"; - } - 2009 - { - title = "Purple Mushroom"; - sprite = "SHRMD0"; - width = 16; - height = 48; - } - 2010 - { - title = "HHZ Tree"; - sprite = "HHPLC0"; - width = 12; - height = 40; - } - } - - frozenhillside - { - color = 10; // Green - title = "Frozen Hillside"; - - 2100 - { - title = "Ice Shard (Small)"; - sprite = "FHZIA0"; - width = 8; - height = 32; - } - 2101 - { - title = "Ice Shard (Large)"; - sprite = "FHZIB0"; - width = 8; - height = 32; - } - 2102 - { - title = "Crystal Tree (Aqua)"; - sprite = "TRE3A0"; - width = 20; - height = 200; - } - 2103 - { - title = "Crystal Tree (Pink)"; - sprite = "TRE3B0"; - width = 20; - height = 200; - } - 2104 - { - title = "Amy Cameo"; - sprite = "ROSYA1"; - width = 16; - height = 48; - flags1text = "[1] Grayscale mode"; - } - 2105 - { - title = "Mistletoe"; - sprite = "XMS6A0"; - width = 52; - height = 106; - } - } - - flickies - { - color = 10; // Green - title = "Flickies"; - width = 8; - height = 20; - flags1text = "[1] Move aimlessly"; - flags4text = "[4] No movement"; - flags8text = "[8] Hop"; - angletext = "Radius"; - - 2200 - { - title = "Bluebird"; - sprite = "FL01A1"; - } - 2201 - { - title = "Rabbit"; - sprite = "FL02A1"; - } - 2202 - { - title = "Chicken"; - sprite = "FL03A1"; - } - 2203 - { - title = "Seal"; - sprite = "FL04A1"; - } - 2204 - { - title = "Pig"; - sprite = "FL05A1"; - } - 2205 - { - title = "Chipmunk"; - sprite = "FL06A1"; - } - 2206 - { - title = "Penguin"; - sprite = "FL07A1"; - } - 2207 - { - title = "Fish"; - sprite = "FL08A1"; - parametertext = "Color"; - } - 2208 - { - title = "Ram"; - sprite = "FL09A1"; - } - 2209 - { - title = "Puffin"; - sprite = "FL10A1"; - } - 2210 - { - title = "Cow"; - sprite = "FL11A1"; - } - 2211 - { - title = "Rat"; - sprite = "FL12A1"; - } - 2212 - { - title = "Bear"; - sprite = "FL13A1"; - } - 2213 - { - title = "Dove"; - sprite = "FL14A1"; - } - 2214 - { - title = "Cat"; - sprite = "FL15A1"; - } - 2215 - { - title = "Canary"; - sprite = "FL16A1"; - } - 2216 - { - title = "Spider"; - sprite = "FS01A1"; - } - 2217 - { - title = "Bat"; - sprite = "FS02A0"; - } - } -} - -//Default things filters -thingsfilters -{ - - filter0 - { - name = "Player starts"; - category = "starts"; - type = -1; - } - - - filter1 - { - name = "Enemies"; - category = "enemies"; - type = -1; - - } - - - filter2 - { - name = "NiGHTS Track"; - category = "nightstrk"; - type = -1; - - } - - - filter3 - { - name = "Normal Gravity"; - category = ""; - type = -1; - - fields - { - 2 = false; - } - - } - - - filter4 - { - name = "Reverse Gravity"; - category = ""; - type = -1; - - fields - { - 2 = true; - } - - } -} From 2dac47a54c4757871f5b8ee907ddd96b2daaf664 Mon Sep 17 00:00:00 2001 From: MascaraSnake Date: Tue, 24 Dec 2019 12:19:13 +0100 Subject: [PATCH 363/746] Allow P_SpawnItemRow to spawn arbitrary mobjtypes (will be used in UDMF) --- src/p_mobj.c | 173 +++++++++++++++++++++++++++------------------------ 1 file changed, 90 insertions(+), 83 deletions(-) diff --git a/src/p_mobj.c b/src/p_mobj.c index 606c65014..427f3526d 100644 --- a/src/p_mobj.c +++ b/src/p_mobj.c @@ -11567,14 +11567,6 @@ static fixed_t P_GetMobjSpawnHeight(const mobjtype_t mobjtype, const fixed_t x, if (mobjtype == MT_AXIS || mobjtype == MT_AXISTRANSFER || mobjtype == MT_AXISTRANSFERLINE) return ONFLOORZ; - if (!offset) // Snap to the surfaces when there's no offset set. - { - if (flip) - return ONCEILINGZ; - else - return ONFLOORZ; - } - // Establish height. if (flip) return ( @@ -11649,6 +11641,14 @@ static fixed_t P_GetMapThingSpawnHeight(const mobjtype_t mobjtype, const mapthin offset += mthing->options & MTF_AMBUSH ? 24*FRACUNIT : 0; } + if (!offset) // Snap to the surfaces when there's no offset set. + { + if (flip) + return ONCEILINGZ; + else + return ONFLOORZ; + } + return P_GetMobjSpawnHeight(mobjtype, x, y, offset, flip); } @@ -11703,6 +11703,13 @@ static boolean P_SpawnNonMobjMapThing(mapthing_t *mthing) || (mthing->type >= 600 && mthing->type <= 609) // Special placement patterns || mthing->type == 1705 || mthing->type == 1713) // Hoops return true; // These are handled elsewhere. + else if (mthing->type == mobjinfo[MT_EMERHUNT].doomednum) + { + // Emerald Hunt is Coop only. Don't spawn the emerald yet, but save the spawnpoint for later. + if (gametype == GT_COOP && numhuntemeralds < MAXHUNTEMERALDS) + huntemeralds[numhuntemeralds++] = mthing; + return true; + } return false; } @@ -11728,14 +11735,6 @@ static boolean P_AllowMobjSpawn(mapthing_t* mthing, mobjtype_t i) return false; break; - case MT_EMERHUNT: - // Emerald Hunt is Coop only. - if (gametype != GT_COOP) - return false; - - if (numhuntemeralds < MAXHUNTEMERALDS) - huntemeralds[numhuntemeralds++] = mthing; - return false; case MT_EMERALDSPAWN: if (!cv_powerstones.value) return false; @@ -13004,47 +13003,12 @@ static void P_SetObjectSpecial(mobj_t *mobj) mobj->flags |= MF_BOUNCE; } } -// -// P_SpawnMapThing -// The fields of the mapthing should -// already be in host byte order. -// -mobj_t *P_SpawnMapThing(mapthing_t *mthing) + +mobj_t *P_SpawnMobjFromMapThing(mapthing_t *mthing, fixed_t x, fixed_t y, fixed_t z, mobjtype_t i) { - mobjtype_t i; mobj_t *mobj = NULL; - fixed_t x, y, z; boolean doangle = true; - if (!mthing->type) - return mobj; // Ignore type-0 things as NOPs - - if (mthing->type == 3328) // 3D Mode start Thing - return mobj; - - if (!objectplacing && P_SpawnNonMobjMapThing(mthing)) - return mobj; - - i = P_GetMobjtype(mthing->type); - if (i == MT_UNKNOWN) - CONS_Alert(CONS_WARNING, M_GetText("Unknown thing type %d placed at (%d, %d)\n"), mthing->type, mthing->x, mthing->y); - - // Skip all returning/substitution code in objectplace. - if (!objectplacing) - { - if (!P_AllowMobjSpawn(mthing, i)) - return mobj; - - i = P_GetMobjtypeSubstitute(mthing, i); - if (i == MT_NULL) // Don't spawn mobj - return mobj; - } - - // spawn it - x = mthing->x << FRACBITS; - y = mthing->y << FRACBITS; - z = P_GetMapThingSpawnHeight(i, mthing, x, y); - mobj = P_SpawnMobj(x, y, z, i); mobj->spawnpoint = mthing; @@ -13052,7 +13016,7 @@ mobj_t *P_SpawnMapThing(mapthing_t *mthing) return mobj; if (doangle) - mobj->angle = FixedAngle(mthing->angle<angle = FixedAngle(mthing->angle << FRACBITS); mthing->mobj = mobj; @@ -13061,8 +13025,8 @@ mobj_t *P_SpawnMapThing(mapthing_t *mthing) return mobj; if ((mthing->options & MTF_AMBUSH) - && (mthing->options & MTF_OBJECTSPECIAL) - && (mobj->flags & MF_PUSHABLE)) + && (mthing->options & MTF_OBJECTSPECIAL) + && (mobj->flags & MF_PUSHABLE)) mobj->flags2 |= MF2_CLASSICPUSH; else { @@ -13097,6 +13061,47 @@ mobj_t *P_SpawnMapThing(mapthing_t *mthing) return mobj; } +// +// P_SpawnMapThing +// The fields of the mapthing should +// already be in host byte order. +// +mobj_t *P_SpawnMapThing(mapthing_t *mthing) +{ + mobjtype_t i; + mobj_t *mobj = NULL; + fixed_t x, y, z; + + if (!mthing->type) + return mobj; // Ignore type-0 things as NOPs + + if (mthing->type == 3328) // 3D Mode start Thing + return mobj; + + if (!objectplacing && P_SpawnNonMobjMapThing(mthing)) + return mobj; + + i = P_GetMobjtype(mthing->type); + if (i == MT_UNKNOWN) + CONS_Alert(CONS_WARNING, M_GetText("Unknown thing type %d placed at (%d, %d)\n"), mthing->type, mthing->x, mthing->y); + + // Skip all returning/substitution code in objectplace. + if (!objectplacing) + { + if (!P_AllowMobjSpawn(mthing, i)) + return mobj; + + i = P_GetMobjtypeSubstitute(mthing, i); + if (i == MT_NULL) // Don't spawn mobj + return mobj; + } + + x = mthing->x << FRACBITS; + y = mthing->y << FRACBITS; + z = P_GetMapThingSpawnHeight(i, mthing, x, y); + return P_SpawnMobjFromMapThing(mthing, x, y, z, i); +} + static void P_SpawnHoopInternal(mapthing_t *mthing, INT32 hoopsize, fixed_t sizefactor) { mobj_t *mobj = NULL; @@ -13223,21 +13228,29 @@ void P_SpawnBonusTimeItem(mapthing_t *mthing) P_SetMobjState(mobj, mobj->info->raisestate); } -static void P_SpawnItemRow(mapthing_t *mthing, fixed_t x, fixed_t y, fixed_t z, INT32 numitems, fixed_t horizontalspacing, fixed_t verticalspacing, INT16 fixedangle) +static void P_SpawnItemRow(mapthing_t *mthing, mobjtype_t itemtype, INT32 numitems, fixed_t horizontalspacing, fixed_t verticalspacing, INT16 fixedangle, boolean bonustime) { - mobjtype_t ringthing = MT_RING; + mapthing_t dummything = *mthing; mobj_t *mobj = NULL; + fixed_t x = mthing->x << FRACBITS; + fixed_t y = mthing->y << FRACBITS; + fixed_t z = mthing->z << FRACBITS; INT32 r; angle_t angle = FixedAngle(fixedangle << FRACBITS); angle_t fineangle = (angle >> ANGLETOFINESHIFT) & FINEMASK; - if (ultimatemode) - return; // No rings in Ultimate! + dummything.type = mobjinfo[itemtype].doomednum; + // Skip all returning/substitution code in objectplace. + if (!objectplacing) + { + if (!P_AllowMobjSpawn(&dummything, itemtype)) + return; - if (nightsreplace) - ringthing = MT_NIGHTSSTAR; - - z = P_GetMobjSpawnHeight(ringthing, x, y, z, mthing->options & MTF_OBJECTFLIP); + itemtype = P_GetMobjtypeSubstitute(&dummything, itemtype); + if (itemtype == MT_NULL) // Don't spawn + return; + } + z = P_GetMobjSpawnHeight(itemtype, x, y, z, mthing->options & MTF_OBJECTFLIP); for (r = 0; r < numitems; r++) { @@ -13245,20 +13258,14 @@ static void P_SpawnItemRow(mapthing_t *mthing, fixed_t x, fixed_t y, fixed_t z, y += FixedMul(horizontalspacing, FINESINE(fineangle)); z += (mthing->options & MTF_OBJECTFLIP) ? -verticalspacing : verticalspacing; - mobj = P_SpawnMobj(x, y, z, ringthing); + mobj = P_SpawnMobjFromMapThing(&dummything, x, y, z, itemtype); - if (mthing->options & MTF_OBJECTFLIP) - { - mobj->eflags |= MFE_VERTICALFLIP; - mobj->flags2 |= MF2_OBJECTFLIP; - } + if (!mobj) + continue; - mobj->angle = angle; - if (mthing->options & MTF_AMBUSH) - mobj->flags2 |= MF2_AMBUSH; - - if ((maptol & TOL_XMAS) && (ringthing == MT_NIGHTSSTAR)) - P_SetMobjState(mobj, mobj->info->seestate); + mobj->spawnpoint = NULL; + if (bonustime && (mobj->type == MT_BLUESPHERE || mobj->type == MT_NIGHTSCHIP)) + P_SetMobjState(mobj, mobj->info->raisestate); } } @@ -13271,6 +13278,9 @@ static void P_SpawnItemCircle(mapthing_t *mthing, fixed_t x, fixed_t y, fixed_t INT32 i; TVector v, *res; + if (metalrecording) + return; + z = P_GetMobjSpawnHeight(ringthing, x, y, z, false); closestangle = FixedAngle(mthing->angle << FRACBITS); @@ -13350,23 +13360,20 @@ void P_SpawnItemPattern(mapthing_t *mthing, boolean bonustime) fixed_t y = mthing->y << FRACBITS; fixed_t z = mthing->z << FRACBITS; - if (metalrecording) - return; - switch (mthing->type) { // Special placement patterns case 600: // 5 vertical rings (yellow spring) - P_SpawnItemRow(mthing, x, y, z, 5, 0, 64*FRACUNIT, 0); + P_SpawnItemRow(mthing, MT_RING, 5, 0, 64*FRACUNIT, 0, bonustime); return; case 601: // 5 vertical rings (red spring) - P_SpawnItemRow(mthing, x, y, z, 5, 0, 128*FRACUNIT, 0); + P_SpawnItemRow(mthing, MT_RING, 5, 0, 128*FRACUNIT, 0, bonustime); return; case 602: // 5 diagonal rings (yellow spring) - P_SpawnItemRow(mthing, x, y, z, 5, 64*FRACUNIT, 64*FRACUNIT, mthing->angle); + P_SpawnItemRow(mthing, MT_RING, 5, 64*FRACUNIT, 64*FRACUNIT, mthing->angle, bonustime); return; case 603: // 10 diagonal rings (red spring) - P_SpawnItemRow(mthing, x, y, z, 10, 64*FRACUNIT, 64*FRACUNIT, mthing->angle); + P_SpawnItemRow(mthing, MT_RING, 10, 64*FRACUNIT, 64*FRACUNIT, mthing->angle, bonustime); return; case 604: // Circle of rings (8 items) case 605: // Circle of rings (16 items) From 72a1571937a6c4e33fb80b23969018b241769c71 Mon Sep 17 00:00:00 2001 From: MascaraSnake Date: Tue, 24 Dec 2019 12:38:16 +0100 Subject: [PATCH 364/746] Allow P_SpawnItemCircle to spawn arbitrary mobjtypes (will be used in UDMF) --- src/p_mobj.c | 113 ++++++++++++++++++++------------------------------- 1 file changed, 45 insertions(+), 68 deletions(-) diff --git a/src/p_mobj.c b/src/p_mobj.c index 427f3526d..a72c59421 100644 --- a/src/p_mobj.c +++ b/src/p_mobj.c @@ -13269,97 +13269,66 @@ static void P_SpawnItemRow(mapthing_t *mthing, mobjtype_t itemtype, INT32 numite } } -static void P_SpawnItemCircle(mapthing_t *mthing, fixed_t x, fixed_t y, fixed_t z, INT32 numitems, fixed_t size, boolean bonustime) +static void P_SpawnItemCircle(mapthing_t *mthing, mobjtype_t *itemtypes, UINT8 numitemtypes, INT32 numitems, fixed_t size, boolean bonustime) { - mobjtype_t ringthing = MT_RING; - mobj_t *mobj = NULL; - fixed_t finalx, finaly, finalz; - angle_t closestangle, fa; + mapthing_t dummything; + mobj_t* mobj = NULL; + fixed_t x = mthing->x << FRACBITS; + fixed_t y = mthing->y << FRACBITS; + fixed_t z = mthing->z << FRACBITS; + angle_t angle = FixedAngle(mthing->angle << FRACBITS); + angle_t fa; INT32 i; TVector v, *res; - if (metalrecording) - return; - - z = P_GetMobjSpawnHeight(ringthing, x, y, z, false); - - closestangle = FixedAngle(mthing->angle << FRACBITS); - - switch (mthing->type) + for (i = 0; i < numitemtypes; i++) { - case 604: - case 605: - if (ultimatemode) - return; // No rings in Ultimate! - if (nightsreplace) - ringthing = MT_NIGHTSSTAR; - break; - case 608: - case 609: - /*ringthing = (i & 1) ? MT_RING : MT_BLUESPHERE; -- i == 0 is bluesphere - break;*/ - case 606: - case 607: - ringthing = (nightsreplace) ? MT_NIGHTSCHIP : MT_BLUESPHERE; - break; - default: - break; - } + dummything = *mthing; + dummything.type = mobjinfo[itemtypes[i]].doomednum; + // Skip all returning/substitution code in objectplace. + if (!objectplacing) + { + if (!P_AllowMobjSpawn(&dummything, itemtypes[i])) + { + itemtypes[i] = MT_NULL; + continue; + } + + itemtypes[i] = P_GetMobjtypeSubstitute(&dummything, itemtypes[i]); + } + } + z = P_GetMobjSpawnHeight(itemtypes[0], x, y, z, false); - // Create the hoop! for (i = 0; i < numitems; i++) { - if (mthing->type == 608 || mthing->type == 609) - { - if (i & 1) - { - if (ultimatemode) - continue; // No rings in Ultimate! - ringthing = (nightsreplace) ? MT_NIGHTSSTAR : MT_RING; - } - else - ringthing = (nightsreplace) ? MT_NIGHTSCHIP : MT_BLUESPHERE; - } + mobjtype_t itemtype = itemtypes[i % numitemtypes]; + if (itemtype == MT_NULL) + continue; + dummything.type = mobjinfo[itemtype].doomednum; - fa = i * FINEANGLES/numitems; + fa = i*FINEANGLES/numitems; v[0] = FixedMul(FINECOSINE(fa), size); v[1] = 0; v[2] = FixedMul(FINESINE(fa), size); v[3] = FRACUNIT; - res = VectorMatrixMultiply(v, *RotateZMatrix(closestangle)); + res = VectorMatrixMultiply(v, *RotateZMatrix(angle)); M_Memcpy(&v, res, sizeof(v)); - finalx = x + v[0]; - finaly = y + v[1]; - finalz = z + v[2]; + mobj = P_SpawnMobjFromMapThing(&dummything, x + v[0], y + v[1], z + v[2], itemtype); + + if (!mobj) + continue; - mobj = P_SpawnMobj(finalx, finaly, finalz, ringthing); mobj->z -= mobj->height/2; - - if (mthing->options & MTF_OBJECTFLIP) - { - mobj->eflags |= MFE_VERTICALFLIP; - mobj->flags2 |= MF2_OBJECTFLIP; - } - - mobj->angle = closestangle; - if (mthing->options & MTF_AMBUSH) - mobj->flags2 |= MF2_AMBUSH; - - if (bonustime && (ringthing == MT_BLUESPHERE || ringthing == MT_NIGHTSCHIP)) + mobj->spawnpoint = NULL; + if (bonustime && (mobj->type == MT_BLUESPHERE || mobj->type == MT_NIGHTSCHIP)) P_SetMobjState(mobj, mobj->info->raisestate); - else if ((maptol & TOL_XMAS) && (ringthing == MT_NIGHTSSTAR)) - P_SetMobjState(mobj, mobj->info->seestate); } } void P_SpawnItemPattern(mapthing_t *mthing, boolean bonustime) { - fixed_t x = mthing->x << FRACBITS; - fixed_t y = mthing->y << FRACBITS; - fixed_t z = mthing->z << FRACBITS; - switch (mthing->type) { // Special placement patterns @@ -13379,12 +13348,20 @@ void P_SpawnItemPattern(mapthing_t *mthing, boolean bonustime) case 605: // Circle of rings (16 items) case 606: // Circle of blue spheres (8 items) case 607: // Circle of blue spheres (16 items) + { + INT32 numitems = (mthing->type & 1) ? 16 : 8; + fixed_t size = (mthing->type & 1) ? 192*FRACUNIT : 96*FRACUNIT; + mobjtype_t itemtypes[1] = { (mthing->type & 1) ? MT_RING : MT_BLUESPHERE }; + P_SpawnItemCircle(mthing, itemtypes, 1, numitems, size, bonustime); + return; + } case 608: // Circle of rings and blue spheres (8 items) case 609: // Circle of rings and blue spheres (16 items) { INT32 numitems = (mthing->type & 1) ? 16 : 8; fixed_t size = (mthing->type & 1) ? 192*FRACUNIT : 96*FRACUNIT; - P_SpawnItemCircle(mthing, x, y, z, numitems, size, bonustime); + mobjtype_t itemtypes[2] = { MT_RING, MT_BLUESPHERE }; + P_SpawnItemCircle(mthing, itemtypes, 2, numitems, size, bonustime); return; } default: From ac3a57aaf54802b0942c4b4b9c97a940136fbb35 Mon Sep 17 00:00:00 2001 From: MascaraSnake Date: Tue, 24 Dec 2019 12:47:44 +0100 Subject: [PATCH 365/746] Allow P_SpawnItemRow to spawn different item types in the same row --- src/p_mobj.c | 46 +++++++++++++++++++++++++++++++--------------- 1 file changed, 31 insertions(+), 15 deletions(-) diff --git a/src/p_mobj.c b/src/p_mobj.c index a72c59421..88397e43b 100644 --- a/src/p_mobj.c +++ b/src/p_mobj.c @@ -13228,9 +13228,9 @@ void P_SpawnBonusTimeItem(mapthing_t *mthing) P_SetMobjState(mobj, mobj->info->raisestate); } -static void P_SpawnItemRow(mapthing_t *mthing, mobjtype_t itemtype, INT32 numitems, fixed_t horizontalspacing, fixed_t verticalspacing, INT16 fixedangle, boolean bonustime) +static void P_SpawnItemRow(mapthing_t *mthing, mobjtype_t* itemtypes, UINT8 numitemtypes, INT32 numitems, fixed_t horizontalspacing, fixed_t verticalspacing, INT16 fixedangle, boolean bonustime) { - mapthing_t dummything = *mthing; + mapthing_t dummything; mobj_t *mobj = NULL; fixed_t x = mthing->x << FRACBITS; fixed_t y = mthing->y << FRACBITS; @@ -13239,21 +13239,31 @@ static void P_SpawnItemRow(mapthing_t *mthing, mobjtype_t itemtype, INT32 numite angle_t angle = FixedAngle(fixedangle << FRACBITS); angle_t fineangle = (angle >> ANGLETOFINESHIFT) & FINEMASK; - dummything.type = mobjinfo[itemtype].doomednum; - // Skip all returning/substitution code in objectplace. - if (!objectplacing) + for (r = 0; r < numitemtypes; r++) { - if (!P_AllowMobjSpawn(&dummything, itemtype)) - return; + dummything = *mthing; + dummything.type = mobjinfo[itemtypes[r]].doomednum; + // Skip all returning/substitution code in objectplace. + if (!objectplacing) + { + if (!P_AllowMobjSpawn(&dummything, itemtypes[r])) + { + itemtypes[r] = MT_NULL; + continue; + } - itemtype = P_GetMobjtypeSubstitute(&dummything, itemtype); - if (itemtype == MT_NULL) // Don't spawn - return; + itemtypes[r] = P_GetMobjtypeSubstitute(&dummything, itemtypes[r]); + } } - z = P_GetMobjSpawnHeight(itemtype, x, y, z, mthing->options & MTF_OBJECTFLIP); + z = P_GetMobjSpawnHeight(itemtypes[0], x, y, z, mthing->options & MTF_OBJECTFLIP); for (r = 0; r < numitems; r++) { + mobjtype_t itemtype = itemtypes[r % numitemtypes]; + if (itemtype == MT_NULL) + continue; + dummything.type = mobjinfo[itemtype].doomednum; + x += FixedMul(horizontalspacing, FINECOSINE(fineangle)); y += FixedMul(horizontalspacing, FINESINE(fineangle)); z += (mthing->options & MTF_OBJECTFLIP) ? -verticalspacing : verticalspacing; @@ -13269,6 +13279,12 @@ static void P_SpawnItemRow(mapthing_t *mthing, mobjtype_t itemtype, INT32 numite } } +static void P_SpawnSingularItemRow(mapthing_t* mthing, mobjtype_t itemtype, INT32 numitems, fixed_t horizontalspacing, fixed_t verticalspacing, INT16 fixedangle, boolean bonustime) +{ + mobjtype_t itemtypes[1] = { itemtype }; + return P_SpawnItemRow(mthing, itemtypes, 1, numitems, horizontalspacing, verticalspacing, fixedangle, bonustime); +} + static void P_SpawnItemCircle(mapthing_t *mthing, mobjtype_t *itemtypes, UINT8 numitemtypes, INT32 numitems, fixed_t size, boolean bonustime) { mapthing_t dummything; @@ -13333,16 +13349,16 @@ void P_SpawnItemPattern(mapthing_t *mthing, boolean bonustime) { // Special placement patterns case 600: // 5 vertical rings (yellow spring) - P_SpawnItemRow(mthing, MT_RING, 5, 0, 64*FRACUNIT, 0, bonustime); + P_SpawnSingularItemRow(mthing, MT_RING, 5, 0, 64*FRACUNIT, 0, bonustime); return; case 601: // 5 vertical rings (red spring) - P_SpawnItemRow(mthing, MT_RING, 5, 0, 128*FRACUNIT, 0, bonustime); + P_SpawnSingularItemRow(mthing, MT_RING, 5, 0, 128*FRACUNIT, 0, bonustime); return; case 602: // 5 diagonal rings (yellow spring) - P_SpawnItemRow(mthing, MT_RING, 5, 64*FRACUNIT, 64*FRACUNIT, mthing->angle, bonustime); + P_SpawnSingularItemRow(mthing, MT_RING, 5, 64*FRACUNIT, 64*FRACUNIT, mthing->angle, bonustime); return; case 603: // 10 diagonal rings (red spring) - P_SpawnItemRow(mthing, MT_RING, 10, 64*FRACUNIT, 64*FRACUNIT, mthing->angle, bonustime); + P_SpawnSingularItemRow(mthing, MT_RING, 10, 64*FRACUNIT, 64*FRACUNIT, mthing->angle, bonustime); return; case 604: // Circle of rings (8 items) case 605: // Circle of rings (16 items) From a57f903933fd232dea79f3c3e02eaaa28e4ae355 Mon Sep 17 00:00:00 2001 From: MascaraSnake Date: Tue, 24 Dec 2019 12:52:43 +0100 Subject: [PATCH 366/746] Move bonus time handling into new function P_SetBonusTime() --- src/p_mobj.c | 20 ++++++++++++-------- src/p_mobj.h | 2 +- src/p_setup.c | 2 +- 3 files changed, 14 insertions(+), 10 deletions(-) diff --git a/src/p_mobj.c b/src/p_mobj.c index 88397e43b..866ffaf70 100644 --- a/src/p_mobj.c +++ b/src/p_mobj.c @@ -13221,11 +13221,15 @@ void P_SpawnHoop(mapthing_t *mthing) P_SpawnHoopInternal(mthing, 8 + (4*(mthing->options & 0xF)), 4*FRACUNIT); } -void P_SpawnBonusTimeItem(mapthing_t *mthing) +void P_SetBonusTime(mobj_t *mobj) { - mobj_t *mobj = P_SpawnMapThing(mthing); - if (mobj && (mobj->type == MT_BLUESPHERE || mobj->type == MT_NIGHTSCHIP)) - P_SetMobjState(mobj, mobj->info->raisestate); + if (!mobj) + return; + + if (mobj->type != MT_BLUESPHERE && mobj->type != MT_NIGHTSCHIP) + return; + + P_SetMobjState(mobj, mobj->info->raisestate); } static void P_SpawnItemRow(mapthing_t *mthing, mobjtype_t* itemtypes, UINT8 numitemtypes, INT32 numitems, fixed_t horizontalspacing, fixed_t verticalspacing, INT16 fixedangle, boolean bonustime) @@ -13274,8 +13278,8 @@ static void P_SpawnItemRow(mapthing_t *mthing, mobjtype_t* itemtypes, UINT8 numi continue; mobj->spawnpoint = NULL; - if (bonustime && (mobj->type == MT_BLUESPHERE || mobj->type == MT_NIGHTSCHIP)) - P_SetMobjState(mobj, mobj->info->raisestate); + if (bonustime) + P_SetBonusTime(mobj); } } @@ -13338,8 +13342,8 @@ static void P_SpawnItemCircle(mapthing_t *mthing, mobjtype_t *itemtypes, UINT8 n mobj->z -= mobj->height/2; mobj->spawnpoint = NULL; - if (bonustime && (mobj->type == MT_BLUESPHERE || mobj->type == MT_NIGHTSCHIP)) - P_SetMobjState(mobj, mobj->info->raisestate); + if (bonustime) + P_SetBonusTime(mobj); } } diff --git a/src/p_mobj.h b/src/p_mobj.h index 9b015d23c..a272003c1 100644 --- a/src/p_mobj.h +++ b/src/p_mobj.h @@ -458,7 +458,7 @@ void P_AfterPlayerSpawn(INT32 playernum); mobj_t *P_SpawnMapThing(mapthing_t *mthing); void P_SpawnHoop(mapthing_t *mthing); -void P_SpawnBonusTimeItem(mapthing_t *mthing); +void P_SetBonusTime(mobj_t *mobj); void P_SpawnItemPattern(mapthing_t *mthing, boolean bonustime); void P_SpawnHoopOfSomething(fixed_t x, fixed_t y, fixed_t z, fixed_t radius, INT32 number, mobjtype_t type, angle_t rotangle); void P_SpawnPrecipitation(void); diff --git a/src/p_setup.c b/src/p_setup.c index 46fe118c4..41d61704f 100644 --- a/src/p_setup.c +++ b/src/p_setup.c @@ -816,7 +816,7 @@ void P_ReloadRings(void) || mt->type == mobjinfo[MT_BLUESPHERE].doomednum || mt->type == mobjinfo[MT_BOMBSPHERE].doomednum) { mt->mobj = NULL; - P_SpawnBonusTimeItem(mt); + P_SetBonusTime(P_SpawnMapThing(mt)); } else if (mt->type >= 600 && mt->type <= 609) // Item patterns { From 13eb71e1ee5910f07eeae15931d2873f4ed9d576 Mon Sep 17 00:00:00 2001 From: MascaraSnake Date: Tue, 24 Dec 2019 12:58:12 +0100 Subject: [PATCH 367/746] Fixed missing break in offset handling for horizontal springs --- src/p_mobj.c | 1 + 1 file changed, 1 insertion(+) diff --git a/src/p_mobj.c b/src/p_mobj.c index 866ffaf70..13f75b94a 100644 --- a/src/p_mobj.c +++ b/src/p_mobj.c @@ -11618,6 +11618,7 @@ static fixed_t P_GetMapThingSpawnHeight(const mobjtype_t mobjtype, const mapthin case MT_REDHORIZ: case MT_BLUEHORIZ: offset += mthing->options & MTF_AMBUSH ? 16*FRACUNIT : 0; + break; // Ring-like items, may float additional units with MTF_AMBUSH. case MT_SPIKEBALL: From 0aa3c9b0a3655ae0ef86b435991a2fa0e9ed1f7d Mon Sep 17 00:00:00 2001 From: MascaraSnake Date: Tue, 24 Dec 2019 13:01:17 +0100 Subject: [PATCH 368/746] Fixed missing break in offset handling for horizontal springs --- src/p_mobj.c | 1 + 1 file changed, 1 insertion(+) diff --git a/src/p_mobj.c b/src/p_mobj.c index 1acecbb76..e8186b752 100644 --- a/src/p_mobj.c +++ b/src/p_mobj.c @@ -11603,6 +11603,7 @@ static fixed_t P_GetMobjSpawnHeight(const mobjtype_t mobjtype, const mapthing_t* case MT_REDHORIZ: case MT_BLUEHORIZ: offset += mthing->options & MTF_AMBUSH ? 16*FRACUNIT : 0; + break; // Ring-like items, may float additional units with MTF_AMBUSH. case MT_SPIKEBALL: From b740daf5bfc89b252ed2cf302af423323f77a44f Mon Sep 17 00:00:00 2001 From: Jaime Passos Date: Tue, 24 Dec 2019 16:09:00 -0300 Subject: [PATCH 369/746] GTR_HURTMESSAGES --- src/dehacked.c | 1 + src/doomstat.h | 1 + src/p_inter.c | 2 +- 3 files changed, 3 insertions(+), 1 deletion(-) diff --git a/src/dehacked.c b/src/dehacked.c index 12aa8f970..18c4077be 100644 --- a/src/dehacked.c +++ b/src/dehacked.c @@ -8899,6 +8899,7 @@ static const char *const GAMETYPERULE_LIST[] = { "ALLOWEXIT", "NOTITLECARD", "OVERTIME", + "HURTMESSAGES", NULL }; diff --git a/src/doomstat.h b/src/doomstat.h index 940d2d60c..6a708dc9b 100644 --- a/src/doomstat.h +++ b/src/doomstat.h @@ -416,6 +416,7 @@ enum GameTypeRules 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 }; // String names for gametypes diff --git a/src/p_inter.c b/src/p_inter.c index 08e8a62a1..8643b4275 100644 --- a/src/p_inter.c +++ b/src/p_inter.c @@ -1888,7 +1888,7 @@ static void P_HitDeathMessages(player_t *player, mobj_t *inflictor, mobj_t *sour char targetname[MAXPLAYERNAME+4]; char sourcename[MAXPLAYERNAME+4]; - if (G_PlatformGametype()) + if (!(gametyperules & (GTR_RINGSLINGER|GTR_HURTMESSAGES))) return; // Not in coop, etc. if (!player) From 5b4d587b1ae9df2e3aed431429ddb617b733b68c Mon Sep 17 00:00:00 2001 From: Jaime Passos Date: Tue, 24 Dec 2019 16:12:05 -0300 Subject: [PATCH 370/746] Don't warn about missing CTF starts if the gametype doesn't have team flags. --- 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 ead7e8c5c..91e788e1c 100644 --- a/src/g_game.c +++ b/src/g_game.c @@ -2720,7 +2720,7 @@ mapthing_t *G_FindCTFStart(INT32 playernum) if (!numredctfstarts && !numbluectfstarts) //why even bother, eh? { - if (playernum == consoleplayer || (splitscreen && playernum == secondarydisplayplayer)) + if ((gametyperules & GTR_TEAMFLAGS) && (playernum == consoleplayer || (splitscreen && playernum == secondarydisplayplayer))) CONS_Alert(CONS_WARNING, M_GetText("No CTF starts in this map!\n")); return NULL; } From 9d28351b5ce78cdc61cd22fe751062534e355384 Mon Sep 17 00:00:00 2001 From: James R Date: Tue, 24 Dec 2019 11:14:21 -0800 Subject: [PATCH 371/746] I'm an idiot --- src/sdl/i_system.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/sdl/i_system.c b/src/sdl/i_system.c index a5e536bf5..52186baae 100644 --- a/src/sdl/i_system.c +++ b/src/sdl/i_system.c @@ -675,7 +675,7 @@ static inline void I_ShutdownConsole(void){} // // StartupKeyboard // -void I_RegisterSignals (void) +static void I_RegisterSignals (void) { #ifdef SIGINT signal(SIGINT , quit_handler); From 9319014d8d5d80420dbcc926c8dfa349f5fc9e9d Mon Sep 17 00:00:00 2001 From: Jaime Passos Date: Tue, 24 Dec 2019 16:22:25 -0300 Subject: [PATCH 372/746] Title card fixes. --- src/g_game.c | 19 ++++++++++++++++++- src/g_game.h | 1 + src/st_stuff.c | 9 +++++++++ 3 files changed, 28 insertions(+), 1 deletion(-) diff --git a/src/g_game.c b/src/g_game.c index 91e788e1c..32d69b301 100644 --- a/src/g_game.c +++ b/src/g_game.c @@ -1895,7 +1895,7 @@ void G_StartTitleCard(void) // The title card has been disabled for this map. // Oh well. - if ((mapheaderinfo[gamemap-1]->levelflags & LF_NOTITLECARD) || (gametyperules & GTR_NOTITLECARD)) + if (!G_IsTitleCardAvailable()) { WipeStageTitle = false; return; @@ -1938,6 +1938,23 @@ void G_PreLevelTitleCard(void) } } +// +// Returns true if the current level has a title card. +// +boolean G_IsTitleCardAvailable(void) +{ + // The current level header explicitly disabled the title card. + if (mapheaderinfo[gamemap-1]->levelflags & LF_NOTITLECARD) + return false; + + // The current gametype doesn't have a title card. + if (gametyperules & GTR_NOTITLECARD) + return false; + + // The title card is available. + return true; +} + INT32 pausedelay = 0; boolean pausebreakkey = false; static INT32 camtoggledelay, camtoggledelay2 = 0; diff --git a/src/g_game.h b/src/g_game.h index 4e577f51a..238dd1964 100644 --- a/src/g_game.h +++ b/src/g_game.h @@ -143,6 +143,7 @@ void G_DeferedInitNew(boolean pultmode, const char *mapname, INT32 pickedchar, void G_DoLoadLevel(boolean resetplayer); void G_StartTitleCard(void); void G_PreLevelTitleCard(void); +boolean G_IsTitleCardAvailable(void); void G_DeferedPlayDemo(const char *demo); // Can be called by the startup code or M_Responder, calls P_SetupLevel. diff --git a/src/st_stuff.c b/src/st_stuff.c index 6ff73e03a..3299c9d39 100644 --- a/src/st_stuff.c +++ b/src/st_stuff.c @@ -1216,6 +1216,9 @@ void ST_startTitleCard(void) // void ST_preDrawTitleCard(void) { + if (!G_IsTitleCardAvailable()) + return; + if (lt_ticker >= (lt_endtime + TICRATE)) return; @@ -1231,6 +1234,9 @@ void ST_preDrawTitleCard(void) // void ST_runTitleCard(void) { + if (!G_IsTitleCardAvailable()) + return; + if (lt_ticker >= (lt_endtime + TICRATE)) return; @@ -1284,6 +1290,9 @@ void ST_drawTitleCard(void) INT32 zzticker; patch_t *actpat, *zigzag, *zztext; + if (!G_IsTitleCardAvailable()) + return; + #ifdef HAVE_BLUA if (!LUA_HudEnabled(hud_stagetitle)) goto luahook; From c61c1e2514588418d04c410784466cdae7ed9bdc Mon Sep 17 00:00:00 2001 From: Jaime Passos Date: Tue, 24 Dec 2019 16:30:18 -0300 Subject: [PATCH 373/746] Turn the babysitting deterrent into its own rule. --- src/dehacked.c | 1 + src/doomstat.h | 3 ++- src/g_game.c | 14 +++++++------- src/p_mobj.c | 2 +- 4 files changed, 11 insertions(+), 9 deletions(-) diff --git a/src/dehacked.c b/src/dehacked.c index 18c4077be..b598d40ac 100644 --- a/src/dehacked.c +++ b/src/dehacked.c @@ -8900,6 +8900,7 @@ static const char *const GAMETYPERULE_LIST[] = { "NOTITLECARD", "OVERTIME", "HURTMESSAGES", + "SPAWNINVUL", NULL }; diff --git a/src/doomstat.h b/src/doomstat.h index 6a708dc9b..2e3fe9b36 100644 --- a/src/doomstat.h +++ b/src/doomstat.h @@ -386,7 +386,7 @@ enum GameType }; // If you alter this list, update dehacked.c, MISC_ChangeGameTypeMenu in m_menu.c, and Gametype_Names in g_game.c -// Game type rules +// Gametype rules enum GameTypeRules { GTR_CAMPAIGN = 1, // Linear Co-op map progression, don't allow random maps @@ -417,6 +417,7 @@ enum GameTypeRules 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 }; // String names for gametypes diff --git a/src/g_game.c b/src/g_game.c index 32d69b301..b39205f50 100644 --- a/src/g_game.c +++ b/src/g_game.c @@ -3197,22 +3197,22 @@ UINT32 gametypedefaultrules[NUMGAMETYPES] = // Co-op GTR_CAMPAIGN|GTR_LIVES|GTR_SPAWNENEMIES|GTR_ALLOWEXIT|GTR_EMERALDHUNT|GTR_EMERALDTOKENS|GTR_SPECIALSTAGES, // Competition - GTR_RACE|GTR_LIVES|GTR_SPAWNENEMIES|GTR_EMERALDTOKENS|GTR_ALLOWEXIT, + GTR_RACE|GTR_LIVES|GTR_SPAWNENEMIES|GTR_EMERALDTOKENS|GTR_SPAWNINVUL|GTR_ALLOWEXIT, // Race - GTR_RACE|GTR_SPAWNENEMIES|GTR_ALLOWEXIT, + GTR_RACE|GTR_SPAWNENEMIES|GTR_SPAWNINVUL|GTR_ALLOWEXIT, // Match - GTR_RINGSLINGER|GTR_FIRSTPERSON|GTR_SPECTATORS|GTR_POINTLIMIT|GTR_TIMELIMIT|GTR_MATCHEMERALDS|GTR_PITYSHIELD|GTR_DEATHPENALTY, + GTR_RINGSLINGER|GTR_FIRSTPERSON|GTR_SPECTATORS|GTR_POINTLIMIT|GTR_TIMELIMIT|GTR_MATCHEMERALDS|GTR_SPAWNINVUL|GTR_PITYSHIELD|GTR_DEATHPENALTY, // Team Match - GTR_RINGSLINGER|GTR_FIRSTPERSON|GTR_SPECTATORS|GTR_TEAMS|GTR_POINTLIMIT|GTR_TIMELIMIT|GTR_PITYSHIELD, + GTR_RINGSLINGER|GTR_FIRSTPERSON|GTR_SPECTATORS|GTR_TEAMS|GTR_POINTLIMIT|GTR_TIMELIMIT|GTR_SPAWNINVUL|GTR_PITYSHIELD, // Tag - GTR_RINGSLINGER|GTR_FIRSTPERSON|GTR_TAG|GTR_SPECTATORS|GTR_POINTLIMIT|GTR_TIMELIMIT|GTR_HIDETIME|GTR_BLINDFOLDED, + GTR_RINGSLINGER|GTR_FIRSTPERSON|GTR_TAG|GTR_SPECTATORS|GTR_POINTLIMIT|GTR_TIMELIMIT|GTR_HIDETIME|GTR_BLINDFOLDED|GTR_SPAWNINVUL, // Hide and Seek - GTR_RINGSLINGER|GTR_FIRSTPERSON|GTR_TAG|GTR_SPECTATORS|GTR_POINTLIMIT|GTR_TIMELIMIT|GTR_HIDETIME|GTR_BLINDFOLDED, + GTR_RINGSLINGER|GTR_FIRSTPERSON|GTR_TAG|GTR_SPECTATORS|GTR_POINTLIMIT|GTR_TIMELIMIT|GTR_HIDETIME|GTR_BLINDFOLDED|GTR_SPAWNINVUL, // CTF - GTR_RINGSLINGER|GTR_FIRSTPERSON|GTR_SPECTATORS|GTR_TEAMS|GTR_POINTLIMIT|GTR_TIMELIMIT|GTR_MATCHEMERALDS|GTR_TEAMFLAGS|GTR_PITYSHIELD, + GTR_RINGSLINGER|GTR_FIRSTPERSON|GTR_SPECTATORS|GTR_TEAMS|GTR_POINTLIMIT|GTR_TIMELIMIT|GTR_MATCHEMERALDS|GTR_TEAMFLAGS|GTR_SPAWNINVUL|GTR_PITYSHIELD, }; // diff --git a/src/p_mobj.c b/src/p_mobj.c index a10e6b3ba..d841ede05 100644 --- a/src/p_mobj.c +++ b/src/p_mobj.c @@ -11297,7 +11297,7 @@ void P_SpawnPlayer(INT32 playernum) p->skincolor = skincolor_blueteam; } - if ((netgame || multiplayer) && (gametype != GT_COOP || leveltime) && !p->spectator && !(maptol & TOL_NIGHTS)) + if ((netgame || multiplayer) && ((gametyperules & GTR_SPAWNINVUL) || leveltime) && !p->spectator && !(maptol & TOL_NIGHTS)) p->powers[pw_flashing] = flashingtics-1; // Babysitting deterrent mobj = P_SpawnMobj(0, 0, 0, MT_PLAYER); From be063c454a7c8ecc4fbda2aa5079ea94c0c39500 Mon Sep 17 00:00:00 2001 From: James R Date: Tue, 24 Dec 2019 11:37:37 -0800 Subject: [PATCH 374/746] Fix NOPNG compiling --- src/r_data.c | 2 -- src/r_plane.c | 2 ++ src/sdl/mixer_sound.c | 38 ++++++++++++++++--------------- src/w_wad.c | 52 +++++++++++++++---------------------------- 4 files changed, 40 insertions(+), 54 deletions(-) diff --git a/src/r_data.c b/src/r_data.c index 12e0702c1..cecd4840c 100644 --- a/src/r_data.c +++ b/src/r_data.c @@ -536,9 +536,7 @@ static UINT8 *R_GenerateTexture(size_t texnum) } // multi-patch textures (or 'composite') -#ifndef NO_PNG_LUMPS multipatch: -#endif texture->holes = false; texture->flip = 0; blocksize = (texture->width * 4) + (texture->width * texture->height); diff --git a/src/r_plane.c b/src/r_plane.c index 3214fa23d..5d5e1f20d 100644 --- a/src/r_plane.c +++ b/src/r_plane.c @@ -788,6 +788,8 @@ static UINT8 *R_GetTextureFlat(levelflat_t *levelflat, boolean leveltexture, boo patch_t *patch = NULL; boolean texturechanged = (leveltexture ? (levelflat->u.texture.num != levelflat->u.texture.lastnum) : false); + (void)ispng; + // Check if the texture changed. if (leveltexture && (!texturechanged)) { diff --git a/src/sdl/mixer_sound.c b/src/sdl/mixer_sound.c index 369d04ced..b60dab14c 100644 --- a/src/sdl/mixer_sound.c +++ b/src/sdl/mixer_sound.c @@ -9,6 +9,26 @@ /// \file /// \brief SDL Mixer interface for sound +#ifdef HAVE_LIBGME +#ifdef HAVE_ZLIB +#ifndef _MSC_VER +#ifndef _LARGEFILE64_SOURCE +#define _LARGEFILE64_SOURCE +#endif +#endif + +#ifndef _LFS64_LARGEFILE +#define _LFS64_LARGEFILE +#endif + +#ifndef _FILE_OFFSET_BITS +#define _FILE_OFFSET_BITS 0 +#endif + +#include +#endif // HAVE_ZLIB +#endif // HAVE_LIBGME + #include "../doomdef.h" #include "../doomstat.h" // menuactive @@ -57,24 +77,6 @@ #include "gme/gme.h" #define GME_TREBLE 5.0f #define GME_BASS 1.0f - -#ifdef HAVE_ZLIB -#ifndef _MSC_VER -#ifndef _LARGEFILE64_SOURCE -#define _LARGEFILE64_SOURCE -#endif -#endif - -#ifndef _LFS64_LARGEFILE -#define _LFS64_LARGEFILE -#endif - -#ifndef _FILE_OFFSET_BITS -#define _FILE_OFFSET_BITS 0 -#endif - -#include "zlib.h" -#endif // HAVE_ZLIB #endif // HAVE_LIBGME static UINT16 BUFFERSIZE = 2048; diff --git a/src/w_wad.c b/src/w_wad.c index 950294b1f..86972118a 100644 --- a/src/w_wad.c +++ b/src/w_wad.c @@ -11,6 +11,24 @@ /// \file w_wad.c /// \brief Handles WAD file header, directory, lump I/O +#ifdef HAVE_ZLIB +#ifndef _MSC_VER +#ifndef _LARGEFILE64_SOURCE +#define _LARGEFILE64_SOURCE +#endif +#endif + +#ifndef _LFS64_LARGEFILE +#define _LFS64_LARGEFILE +#endif + +#ifndef _FILE_OFFSET_BITS +#define _FILE_OFFSET_BITS 0 +#endif + +#include +#endif + #ifdef __GNUC__ #include #endif @@ -22,22 +40,6 @@ #include "lzf.h" #endif -#ifndef _FILE_OFFSET_BITS -#define _FILE_OFFSET_BITS 0 -#endif - -#ifndef _LARGEFILE64_SOURCE -#define _LARGEFILE64_SOURCE -#endif - -#ifndef _LFS64_LARGEFILE -#define _LFS64_LARGEFILE -#endif - -//#ifdef HAVE_ZLIB -#include "zlib.h" -//#endif // HAVE_ZLIB - #include "doomdef.h" #include "doomstat.h" #include "doomtype.h" @@ -77,24 +79,6 @@ int snprintf(char *str, size_t n, const char *fmt, ...); #define O_BINARY 0 #endif -#ifdef HAVE_ZLIB -#ifndef _MSC_VER -#ifndef _LARGEFILE64_SOURCE -#define _LARGEFILE64_SOURCE -#endif -#endif - -#ifndef _LFS64_LARGEFILE -#define _LFS64_LARGEFILE -#endif - -#ifndef _FILE_OFFSET_BITS -#define _FILE_OFFSET_BITS 0 -#endif - -#include "zlib.h" -#endif - typedef struct { From 25f8f2706bc51a4d65abb4729d7ce44b8b73e8e2 Mon Sep 17 00:00:00 2001 From: GoldenTails Date: Tue, 24 Dec 2019 13:55:19 -0600 Subject: [PATCH 375/746] 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 ddccfbd73d58a73d3f35eaa53b09d25289ae402f Mon Sep 17 00:00:00 2001 From: MascaraSnake Date: Tue, 24 Dec 2019 21:07:55 +0100 Subject: [PATCH 376/746] P_MobjThinker(): Separate scale thinking and scenery thinking into their own functions --- src/p_mobj.c | 1714 ++++++++++++++++++++++++++------------------------ 1 file changed, 878 insertions(+), 836 deletions(-) diff --git a/src/p_mobj.c b/src/p_mobj.c index 13f75b94a..ab435afce 100644 --- a/src/p_mobj.c +++ b/src/p_mobj.c @@ -7143,6 +7143,881 @@ static void P_PyreFlyBurn(mobj_t *mobj, fixed_t hoffs, INT16 vrange, mobjtype_t particle->momz = momz; } +static void P_MobjScaleThink(mobj_t *mobj) +{ + fixed_t oldheight = mobj->height; + UINT8 correctionType = 0; // Don't correct Z position, just gain height + + if ((mobj->flags & MF_NOCLIPHEIGHT || (mobj->z > mobj->floorz && mobj->z + mobj->height < mobj->ceilingz)) + && mobj->type != MT_EGGMOBILE_FIRE) + correctionType = 1; // Correct Z position by centering + else if (mobj->eflags & MFE_VERTICALFLIP) + correctionType = 2; // Correct Z position by moving down + + if (abs(mobj->scale - mobj->destscale) < mobj->scalespeed) + P_SetScale(mobj, mobj->destscale); + else if (mobj->scale < mobj->destscale) + P_SetScale(mobj, mobj->scale + mobj->scalespeed); + else if (mobj->scale > mobj->destscale) + P_SetScale(mobj, mobj->scale - mobj->scalespeed); + + if (correctionType == 1) + mobj->z -= (mobj->height - oldheight)/2; + else if (correctionType == 2) + mobj->z -= mobj->height - oldheight; + + if (mobj->scale == mobj->destscale) + /// \todo Lua hook for "reached destscale"? + switch (mobj->type) + { + case MT_EGGMOBILE_FIRE: + mobj->destscale = FRACUNIT; + mobj->scalespeed = FRACUNIT>>4; + break; + default: + break; + } +} + +static void P_MaceSceneryThink(mobj_t *mobj) +{ + angle_t oldmovedir = mobj->movedir; + + // Always update movedir to prevent desyncing (in the traditional sense, not the netplay sense). + mobj->movedir = (mobj->movedir + mobj->lastlook) & FINEMASK; + + // If too far away and not deliberately spitting in the face of optimisation, don't think! + if (!(mobj->flags2 & MF2_BOSSNOTRAP)) + { + UINT8 i; + // Quick! Look through players! Don't move unless a player is relatively close by. + // The below is selected based on CEZ2's first room. I promise you it is a coincidence that it looks like the weed number. + for (i = 0; i < MAXPLAYERS; ++i) + if (playeringame[i] && players[i].mo + && P_AproxDistance(P_AproxDistance(mobj->x - players[i].mo->x, mobj->y - players[i].mo->y), mobj->z - players[i].mo->z) < (4200 << FRACBITS)) + break; // Stop looking. + if (i == MAXPLAYERS) + { + if (!(mobj->flags2 & MF2_BEYONDTHEGRAVE)) + { + mobj_t *ref = mobj; + + // stop/hide all your babies + while ((ref = ref->hnext)) + { + ref->eflags = (((ref->flags & MF_NOTHINK) ? 0 : 1) + | ((ref->flags & MF_NOCLIPTHING) ? 0 : 2) + | ((ref->flags2 & MF2_DONTDRAW) ? 0 : 4)); // oh my god this is nasty. + ref->flags |= MF_NOTHINK|MF_NOCLIPTHING; + ref->flags2 |= MF2_DONTDRAW; + ref->momx = ref->momy = ref->momz = 0; + } + + mobj->flags2 |= MF2_BEYONDTHEGRAVE; + } + return; // don't make bubble! + } + else if (mobj->flags2 & MF2_BEYONDTHEGRAVE) + { + mobj_t *ref = mobj; + + // start/show all your babies + while ((ref = ref->hnext)) + { + if (ref->eflags & 1) + ref->flags &= ~MF_NOTHINK; + if (ref->eflags & 2) + ref->flags &= ~MF_NOCLIPTHING; + if (ref->eflags & 4) + ref->flags2 &= ~MF2_DONTDRAW; + ref->eflags = 0; // le sign + } + + mobj->flags2 &= ~MF2_BEYONDTHEGRAVE; + } + } + + // Okay, time to MOVE + P_MaceRotate(mobj, mobj->movedir, oldmovedir); +} + +static boolean P_DrownNumbersSceneryThink(mobj_t *mobj) +{ + if (!mobj->target) + { + P_RemoveMobj(mobj); + return false; + } + if (!mobj->target->player || !(mobj->target->player->powers[pw_underwater] || mobj->target->player->powers[pw_spacetime])) + { + P_RemoveMobj(mobj); + return false; + } + mobj->x = mobj->target->x; + mobj->y = mobj->target->y; + + mobj->destscale = mobj->target->destscale; + P_SetScale(mobj, mobj->target->scale); + + if (mobj->target->eflags & MFE_VERTICALFLIP) + { + mobj->z = mobj->target->z - FixedMul(16*FRACUNIT, mobj->target->scale) - mobj->height; + if (mobj->target->player->pflags & PF_FLIPCAM) + mobj->eflags |= MFE_VERTICALFLIP; + } + else + mobj->z = mobj->target->z + (mobj->target->height) + FixedMul(8*FRACUNIT, mobj->target->scale); // Adjust height for height changes + + if (mobj->threshold <= 35) + mobj->flags2 |= MF2_DONTDRAW; + else + mobj->flags2 &= ~MF2_DONTDRAW; + if (mobj->threshold <= 30) + mobj->threshold = 40; + mobj->threshold--; + return true; +} + +static void P_FlameJetSceneryThink(mobj_t *mobj) +{ + mobj_t *flame; + fixed_t strength; + + if (!(mobj->flags2 & MF2_FIRING)) + return; + + if ((leveltime & 3) == 0) + return; + + // Wave the flames back and forth. Reactiontime determines which direction it's going. + if (mobj->fuse <= -16) + mobj->reactiontime = 1; + else if (mobj->fuse >= 16) + mobj->reactiontime = 0; + + if (mobj->reactiontime) + mobj->fuse += 2; + else + mobj->fuse -= 2; + + flame = P_SpawnMobj(mobj->x, mobj->y, mobj->z, MT_FLAMEJETFLAME); + P_SetMobjState(flame, S_FLAMEJETFLAME4); + + flame->angle = mobj->angle; + + if (mobj->flags2 & MF2_AMBUSH) // Wave up and down instead of side-to-side + flame->momz = mobj->fuse << (FRACBITS - 2); + else + flame->angle += FixedAngle(mobj->fuse<movedir; + + P_InstaThrust(flame, flame->angle, strength); + S_StartSound(flame, sfx_fire); +} + +static void P_VerticalFlameJetSceneryThink(mobj_t *mobj) +{ + mobj_t *flame; + fixed_t strength; + + if (!(mobj->flags2 & MF2_FIRING)) + return; + + if ((leveltime & 3) == 0) + return; + + // Wave the flames back and forth. Reactiontime determines which direction it's going. + if (mobj->fuse <= -16) + mobj->reactiontime = 1; + else if (mobj->fuse >= 16) + mobj->reactiontime = 0; + + if (mobj->reactiontime) + mobj->fuse++; + else + mobj->fuse--; + + flame = P_SpawnMobj(mobj->x, mobj->y, mobj->z, MT_FLAMEJETFLAME); + + strength = 20*FRACUNIT; + strength -= ((20*FRACUNIT)/16)*mobj->movedir; + + // If deaf'd, the object spawns on the ceiling. + if (mobj->flags2 & MF2_AMBUSH) + { + mobj->z = mobj->ceilingz - mobj->height; + flame->momz = -strength; + } + else + { + flame->momz = strength; + P_SetMobjState(flame, S_FLAMEJETFLAME7); + } + P_InstaThrust(flame, mobj->angle, FixedDiv(mobj->fuse*FRACUNIT, 3*FRACUNIT)); + S_StartSound(flame, sfx_fire); +} + +static boolean P_ParticleGenSceneryThink(mobj_t *mobj) +{ + if (!mobj->lastlook) + return false; + + if (!mobj->threshold) + return false; + + if (--mobj->fuse <= 0) + { + INT32 i = 0; + mobj_t *spawn; + fixed_t bottomheight, topheight; + INT32 type = mobj->threshold, line = mobj->cvmem; + + mobj->fuse = (tic_t)mobj->reactiontime; + + bottomheight = lines[line].frontsector->floorheight; + topheight = lines[line].frontsector->ceilingheight - mobjinfo[(mobjtype_t)type].height; + + if (mobj->waterbottom != bottomheight || mobj->watertop != topheight) + { + if (mobj->movefactor && (topheight > bottomheight)) + mobj->health = (tic_t)(FixedDiv((topheight - bottomheight), abs(mobj->movefactor)) >> FRACBITS); + else + mobj->health = 0; + + mobj->z = ((mobj->flags2 & MF2_OBJECTFLIP) ? topheight : bottomheight); + } + + if (!mobj->health) + return false; + + for (i = 0; i < mobj->lastlook; i++) + { + spawn = P_SpawnMobj( + mobj->x + FixedMul(FixedMul(mobj->friction, mobj->scale), FINECOSINE(mobj->angle >> ANGLETOFINESHIFT)), + mobj->y + FixedMul(FixedMul(mobj->friction, mobj->scale), FINESINE(mobj->angle >> ANGLETOFINESHIFT)), + mobj->z, + (mobjtype_t)mobj->threshold); + P_SetScale(spawn, mobj->scale); + spawn->momz = FixedMul(mobj->movefactor, spawn->scale); + spawn->destscale = spawn->scale/100; + spawn->scalespeed = spawn->scale/mobj->health; + spawn->tics = (tic_t)mobj->health; + spawn->flags2 |= (mobj->flags2 & MF2_OBJECTFLIP); + spawn->angle += P_RandomKey(36)*ANG10; // irrelevant for default objects but might make sense for some custom ones + + mobj->angle += mobj->movedir; + } + + mobj->angle += (angle_t)mobj->movecount; + } + + return true; +} + +static void P_RosySceneryThink(mobj_t *mobj) +{ + UINT8 i; + fixed_t pdist = 1700*mobj->scale, work, actualwork; + player_t *player = NULL; + statenum_t stat = (mobj->state - states); + for (i = 0; i < MAXPLAYERS; i++) + { + if (!playeringame[i]) + continue; + if (!players[i].mo) + continue; + if (players[i].bot) + continue; + if (!players[i].mo->health) + continue; + actualwork = work = FixedHypot(mobj->x - players[i].mo->x, mobj->y - players[i].mo->y); + if (player) + { + if (players[i].skin == 0 || players[i].skin == 5) + work = (2*work)/3; + if (work >= pdist) + continue; + } + pdist = actualwork; + player = &players[i]; + } + + if (stat == S_ROSY_JUMP || stat == S_ROSY_PAIN) + { + if (P_IsObjectOnGround(mobj)) + { + mobj->momx = mobj->momy = 0; + if (player && mobj->cvmem < (-2*TICRATE)) + stat = S_ROSY_UNHAPPY; + else + stat = S_ROSY_WALK; + P_SetMobjState(mobj, stat); + } + else if (P_MobjFlip(mobj)*mobj->momz < 0) + mobj->frame = mobj->state->frame + mobj->state->var1; + } + + if (!player) + { + if ((stat < S_ROSY_IDLE1 || stat > S_ROSY_IDLE4) && stat != S_ROSY_JUMP) + { + mobj->momx = mobj->momy = 0; + P_SetMobjState(mobj, S_ROSY_IDLE1); + } + } + else + { + boolean dojump = false, targonground, love, makeheart = false; + if (mobj->target != player->mo) + P_SetTarget(&mobj->target, player->mo); + // Tatsuru: Don't try to hug them if they're above or below you! + targonground = (P_IsObjectOnGround(mobj->target) && (player->panim == PA_IDLE || player->panim == PA_WALK || player->panim == PA_RUN) && player->mo->z == mobj->z); + love = (player->skin == 0 || player->skin == 5); + + switch (stat) + { + case S_ROSY_IDLE1: + case S_ROSY_IDLE2: + case S_ROSY_IDLE3: + case S_ROSY_IDLE4: + dojump = true; + break; + case S_ROSY_JUMP: + case S_ROSY_PAIN: + // handled above + break; + case S_ROSY_WALK: + { + fixed_t x = mobj->x, y = mobj->y, z = mobj->z; + angle_t angletoplayer = R_PointToAngle2(x, y, mobj->target->x, mobj->target->y); + boolean allowed = P_TryMove(mobj, mobj->target->x, mobj->target->y, false); + + P_UnsetThingPosition(mobj); + mobj->x = x; + mobj->y = y; + mobj->z = z; + P_SetThingPosition(mobj); + + if (allowed) + { + fixed_t mom, max; + P_Thrust(mobj, angletoplayer, (3*FRACUNIT) >> 1); + mom = FixedHypot(mobj->momx, mobj->momy); + max = pdist; + if ((--mobj->extravalue1) <= 0) + { + if (++mobj->frame > mobj->state->frame + mobj->state->var1) + mobj->frame = mobj->state->frame; + if (mom > 12*mobj->scale) + mobj->extravalue1 = 2; + else if (mom > 6*mobj->scale) + mobj->extravalue1 = 3; + else + mobj->extravalue1 = 4; + } + if (max < (mobj->radius + mobj->target->radius)) + { + mobj->momx = mobj->target->player->cmomx; + mobj->momy = mobj->target->player->cmomy; + if ((mobj->cvmem > TICRATE && !player->exiting) || !targonground) + P_SetMobjState(mobj, (stat = S_ROSY_STND)); + else + { + mobj->target->momx = mobj->momx; + mobj->target->momy = mobj->momy; + P_SetMobjState(mobj, (stat = S_ROSY_HUG)); + S_StartSound(mobj, sfx_cdpcm6); + mobj->angle = angletoplayer; + } + } + else + { + max /= 3; + if (max > 30*mobj->scale) + max = 30*mobj->scale; + if (mom > max && max > mobj->scale) + { + max = FixedDiv(max, mom); + mobj->momx = FixedMul(mobj->momx, max); + mobj->momy = FixedMul(mobj->momy, max); + } + if (abs(mobj->momx) > mobj->scale || abs(mobj->momy) > mobj->scale) + mobj->angle = R_PointToAngle2(0, 0, mobj->momx, mobj->momy); + } + } + else + dojump = true; + } + break; + case S_ROSY_HUG: + if (targonground) + { + player->pflags |= PF_STASIS; + if (mobj->cvmem < 5*TICRATE) + mobj->cvmem++; + if (love && !(leveltime & 7)) + makeheart = true; + } + else + { + if (mobj->cvmem < (love ? 5*TICRATE : 0)) + { + P_SetMobjState(mobj, (stat = S_ROSY_PAIN)); + S_StartSound(mobj, sfx_cdpcm7); + } + else + P_SetMobjState(mobj, (stat = S_ROSY_JUMP)); + var1 = var2 = 0; + A_DoNPCPain(mobj); + mobj->cvmem -= TICRATE; + } + break; + case S_ROSY_STND: + if ((pdist > (mobj->radius + mobj->target->radius + 3*(mobj->scale + mobj->target->scale)))) + P_SetMobjState(mobj, (stat = S_ROSY_WALK)); + else if (!targonground) + ; + else + { + if (love && !(leveltime & 15)) + makeheart = true; + if (player->exiting || --mobj->cvmem < TICRATE) + { + P_SetMobjState(mobj, (stat = S_ROSY_HUG)); + S_StartSound(mobj, sfx_cdpcm6); + mobj->angle = R_PointToAngle2(mobj->x, mobj->y, mobj->target->x, mobj->target->y); + mobj->target->momx = mobj->momx; + mobj->target->momy = mobj->momy; + } + } + break; + case S_ROSY_UNHAPPY: + default: + break; + } + + if (stat == S_ROSY_HUG) + { + if (player->panim != PA_IDLE) + P_SetPlayerMobjState(mobj->target, S_PLAY_STND); + player->pflags |= PF_STASIS; + } + + if (dojump) + { + P_SetMobjState(mobj, S_ROSY_JUMP); + mobj->z += P_MobjFlip(mobj); + mobj->momx = mobj->momy = 0; + P_SetObjectMomZ(mobj, 6 << FRACBITS, false); + S_StartSound(mobj, sfx_cdfm02); + } + + if (makeheart) + { + mobj_t *cdlhrt = P_SpawnMobjFromMobj(mobj, 0, 0, mobj->height, MT_CDLHRT); + cdlhrt->destscale = (5*mobj->scale) >> 4; + P_SetScale(cdlhrt, cdlhrt->destscale); + cdlhrt->fuse = (5*TICRATE) >> 1; + cdlhrt->momz = mobj->scale; + P_SetTarget(&cdlhrt->target, mobj); + cdlhrt->extravalue1 = mobj->x; + cdlhrt->extravalue2 = mobj->y; + } + } +} + +static void P_MobjSceneryThink(mobj_t *mobj) +{ +#ifdef HAVE_BLUA + if (LUAh_MobjThinker(mobj)) + return; + if (P_MobjWasRemoved(mobj)) + return; +#endif + + if ((mobj->flags2 & MF2_SHIELD) && !P_AddShield(mobj)) + return; + + switch (mobj->type) + { + case MT_BOSSJUNK: + mobj->flags2 ^= MF2_DONTDRAW; + break; + case MT_MACEPOINT: + case MT_CHAINMACEPOINT: + case MT_SPRINGBALLPOINT: + case MT_CHAINPOINT: + case MT_FIREBARPOINT: + case MT_CUSTOMMACEPOINT: + case MT_HIDDEN_SLING: + P_MaceSceneryThink(mobj); + break; + case MT_HOOP: + if (mobj->fuse > 1) + P_MoveHoop(mobj); + else if (mobj->fuse == 1) + mobj->movecount = 1; + + if (mobj->movecount) + { + mobj->fuse++; + + if (mobj->fuse > 32) + { + // Don't kill the hoop center. For the sake of respawning. + //if (mobj->target) + // P_RemoveMobj(mobj->target); + + P_RemoveMobj(mobj); + } + } + else + mobj->fuse--; + return; + case MT_NIGHTSPARKLE: + if (mobj->tics != -1) + { + mobj->tics--; + + // you can cycle through multiple states in a tic + if (!mobj->tics) + if (!P_SetMobjState(mobj, mobj->state->nextstate)) + return; // freed itself + } + + P_UnsetThingPosition(mobj); + mobj->x += mobj->momx; + mobj->y += mobj->momy; + mobj->z += mobj->momz; + P_SetThingPosition(mobj); + return; + case MT_NIGHTSLOOPHELPER: + if (--mobj->tics <= 0) + P_RemoveMobj(mobj); + + // Don't touch my fuse! + return; + case MT_OVERLAY: + if (!mobj->target) + { + P_RemoveMobj(mobj); + return; + } + else + P_AddOverlay(mobj); + break; + case MT_PITY_ORB: + case MT_WHIRLWIND_ORB: + case MT_ARMAGEDDON_ORB: + if (!(mobj->flags2 & MF2_SHIELD)) + return; + break; + case MT_ATTRACT_ORB: + if (!(mobj->flags2 & MF2_SHIELD)) + return; + if (/*(mobj->target) -- the following is implicit by P_AddShield + && (mobj->target->player) + && */ (mobj->target->player->homing) && (mobj->target->player->pflags & PF_SHIELDABILITY)) + { + P_SetMobjState(mobj, mobj->info->painstate); + mobj->tics++; + } + break; + case MT_ELEMENTAL_ORB: + if (!(mobj->flags2 & MF2_SHIELD)) + return; + if (mobj->tracer + /* && mobj->target -- the following is implicit by P_AddShield + && mobj->target->player + && (mobj->target->player->powers[pw_shield] & SH_NOSTACK) == SH_ELEMENTAL */ + && mobj->target->player->pflags & PF_SHIELDABILITY + && ((statenum_t)(mobj->tracer->state - states) < mobj->info->raisestate + || (mobj->tracer->state->nextstate < mobj->info->raisestate && mobj->tracer->tics == 1))) + { + P_SetMobjState(mobj, mobj->info->painstate); + mobj->tics++; + P_SetMobjState(mobj->tracer, mobj->info->raisestate); + mobj->tracer->tics++; + } + break; + case MT_FORCE_ORB: + if (!(mobj->flags2 & MF2_SHIELD)) + return; + if (/* + && mobj->target -- the following is implicit by P_AddShield + && mobj->target->player + && (mobj->target->player->powers[pw_shield] & SH_FORCE) + && */ (mobj->target->player->pflags & PF_SHIELDABILITY)) + { + mobj_t *whoosh = P_SpawnMobjFromMobj(mobj, 0, 0, 0, MT_GHOST); // done here so the offset is correct + P_SetMobjState(whoosh, mobj->info->raisestate); + whoosh->destscale = whoosh->scale << 1; + whoosh->scalespeed = FixedMul(whoosh->scalespeed, whoosh->scale); + whoosh->height = 38*whoosh->scale; + whoosh->fuse = 10; + whoosh->flags |= MF_NOCLIPHEIGHT; + whoosh->momz = mobj->target->momz; // Stay reasonably centered for a few frames + mobj->target->player->pflags &= ~PF_SHIELDABILITY; // prevent eternal whoosh + } + /* FALLTHRU */ + case MT_FLAMEAURA_ORB: + if (!(mobj->flags2 & MF2_SHIELD)) + return; + if ((statenum_t)(mobj->state - states) < mobj->info->painstate) + mobj->angle = mobj->target->angle; // implicitly okay because of P_AddShield + if (mobj->tracer + /* && mobj->target -- the following is implicit by P_AddShield + && mobj->target->player + && (mobj->target->player->powers[pw_shield] & SH_NOSTACK) == SH_FLAMEAURA */ + && mobj->target->player->pflags & PF_SHIELDABILITY + && ((statenum_t)(mobj->tracer->state - states) < mobj->info->raisestate + || (mobj->tracer->state->nextstate < mobj->info->raisestate && mobj->tracer->tics == 1))) + { + P_SetMobjState(mobj, mobj->info->painstate); + mobj->tics++; + P_SetMobjState(mobj->tracer, mobj->info->raisestate); + mobj->tracer->tics++; + } + break; + case MT_BUBBLEWRAP_ORB: + if (!(mobj->flags2 & MF2_SHIELD)) + return; + if (mobj->tracer + /* && mobj->target -- the following is implicit by P_AddShield + && mobj->target->player + && (mobj->target->player->powers[pw_shield] & SH_NOSTACK) == SH_BUBBLEWRAP */ + ) + { + if (mobj->target->player->pflags & PF_SHIELDABILITY + && ((statenum_t)(mobj->state - states) < mobj->info->painstate + || (mobj->state->nextstate < mobj->info->painstate && mobj->tics == 1))) + { + P_SetMobjState(mobj, mobj->info->painstate); + mobj->tics++; + P_SetMobjState(mobj->tracer, mobj->info->raisestate); + mobj->tracer->tics++; + } + else if (mobj->target->eflags & MFE_JUSTHITFLOOR + && (statenum_t)(mobj->state - states) == mobj->info->painstate) + { + P_SetMobjState(mobj, mobj->info->painstate + 1); + mobj->tics++; + P_SetMobjState(mobj->tracer, mobj->info->raisestate + 1); + mobj->tracer->tics++; + } + } + break; + case MT_THUNDERCOIN_ORB: + if (!(mobj->flags2 & MF2_SHIELD)) + return; + if (mobj->tracer + /* && mobj->target -- the following is implicit by P_AddShield + && mobj->target->player + && (mobj->target->player->powers[pw_shield] & SH_NOSTACK) == SH_THUNDERCOIN */ + && (mobj->target->player->pflags & PF_SHIELDABILITY)) + { + P_SetMobjState(mobj, mobj->info->painstate); + mobj->tics++; + P_SetMobjState(mobj->tracer, mobj->info->raisestate); + mobj->tracer->tics++; + mobj->target->player->pflags &= ~PF_SHIELDABILITY; // prevent eternal spark + } + break; + case MT_WATERDROP: + P_SceneryCheckWater(mobj); + if ((mobj->z <= mobj->floorz || mobj->z <= mobj->watertop) + && mobj->health > 0) + { + mobj->health = 0; + P_SetMobjState(mobj, mobj->info->deathstate); + S_StartSound(mobj, mobj->info->deathsound + P_RandomKey(mobj->info->mass)); + return; + } + break; + case MT_BUBBLES: + P_SceneryCheckWater(mobj); + break; + case MT_SMALLBUBBLE: + case MT_MEDIUMBUBBLE: + case MT_EXTRALARGEBUBBLE: // start bubble dissipate + P_SceneryCheckWater(mobj); + if (P_MobjWasRemoved(mobj)) // bubble was removed by not being in water + return; + if (!(mobj->eflags & MFE_UNDERWATER) + || (!(mobj->eflags & MFE_VERTICALFLIP) && mobj->z + mobj->height >= mobj->ceilingz) + || (mobj->eflags & MFE_VERTICALFLIP && mobj->z <= mobj->floorz) + || (P_CheckDeathPitCollide(mobj)) + || --mobj->fuse <= 0) // Bubbles eventually dissipate if they can't reach the surface. + { + // no playing sound: no point; the object is being removed + P_RemoveMobj(mobj); + return; + } + break; + case MT_LOCKON: + if (!mobj->target) + { + P_RemoveMobj(mobj); + return; + } + + mobj->flags2 &= ~MF2_DONTDRAW; + + mobj->x = mobj->target->x; + mobj->y = mobj->target->y; + + mobj->eflags |= (mobj->target->eflags & MFE_VERTICALFLIP); + + mobj->destscale = mobj->target->destscale; + P_SetScale(mobj, mobj->target->scale); + + if (!(mobj->eflags & MFE_VERTICALFLIP)) + mobj->z = mobj->target->z + mobj->target->height + FixedMul((16 + abs((signed)(leveltime % TICRATE) - TICRATE/2))*FRACUNIT, mobj->target->scale); + else + mobj->z = mobj->target->z - FixedMul((16 + abs((signed)(leveltime % TICRATE) - TICRATE/2))*FRACUNIT, mobj->target->scale) - mobj->height; + break; + case MT_LOCKONINF: + if (!(mobj->flags2 & MF2_STRONGBOX)) + { + mobj->threshold = mobj->z; + mobj->flags2 |= MF2_STRONGBOX; + } + if (!(mobj->eflags & MFE_VERTICALFLIP)) + mobj->z = mobj->threshold + FixedMul((16 + abs((signed)(leveltime % TICRATE) - TICRATE/2))*FRACUNIT, mobj->scale); + else + mobj->z = mobj->threshold - FixedMul((16 + abs((signed)(leveltime % TICRATE) - TICRATE/2))*FRACUNIT, mobj->scale); + break; + case MT_DROWNNUMBERS: + if (!P_DrownNumbersSceneryThink(mobj)) + return; + break; + case MT_FLAMEJET: + P_FlameJetSceneryThink(mobj); + break; + case MT_VERTICALFLAMEJET: + P_VerticalFlameJetSceneryThink(mobj); + break; + case MT_FLICKY_01_CENTER: + case MT_FLICKY_02_CENTER: + case MT_FLICKY_03_CENTER: + case MT_FLICKY_04_CENTER: + case MT_FLICKY_05_CENTER: + case MT_FLICKY_06_CENTER: + case MT_FLICKY_07_CENTER: + case MT_FLICKY_08_CENTER: + case MT_FLICKY_09_CENTER: + case MT_FLICKY_10_CENTER: + case MT_FLICKY_11_CENTER: + case MT_FLICKY_12_CENTER: + case MT_FLICKY_13_CENTER: + case MT_FLICKY_14_CENTER: + case MT_FLICKY_15_CENTER: + case MT_FLICKY_16_CENTER: + case MT_SECRETFLICKY_01_CENTER: + case MT_SECRETFLICKY_02_CENTER: + if (mobj->tracer && (mobj->flags & MF_NOCLIPTHING) + && (mobj->flags & MF_GRENADEBOUNCE)) + // for now: only do this bounce routine if flicky is in-place. \todo allow in all movements + { + if (!(mobj->tracer->flags2 & MF2_OBJECTFLIP) && mobj->tracer->z <= mobj->tracer->floorz) + mobj->tracer->momz = 7*FRACUNIT; + else if ((mobj->tracer->flags2 & MF2_OBJECTFLIP) && mobj->tracer->z >= mobj->tracer->ceilingz - mobj->tracer->height) + mobj->tracer->momz = -7*FRACUNIT; + } + break; + case MT_SEED: + if (P_MobjFlip(mobj)*mobj->momz < mobj->info->speed) + mobj->momz = P_MobjFlip(mobj)*mobj->info->speed; + break; + case MT_ROCKCRUMBLE1: + case MT_ROCKCRUMBLE2: + case MT_ROCKCRUMBLE3: + case MT_ROCKCRUMBLE4: + case MT_ROCKCRUMBLE5: + case MT_ROCKCRUMBLE6: + case MT_ROCKCRUMBLE7: + case MT_ROCKCRUMBLE8: + case MT_ROCKCRUMBLE9: + case MT_ROCKCRUMBLE10: + case MT_ROCKCRUMBLE11: + case MT_ROCKCRUMBLE12: + case MT_ROCKCRUMBLE13: + case MT_ROCKCRUMBLE14: + case MT_ROCKCRUMBLE15: + case MT_ROCKCRUMBLE16: + case MT_WOODDEBRIS: + case MT_BRICKDEBRIS: + case MT_BROKENROBOT: + if (mobj->z <= P_FloorzAtPos(mobj->x, mobj->y, mobj->z, mobj->height) + && mobj->state != &states[mobj->info->deathstate]) + { + P_SetMobjState(mobj, mobj->info->deathstate); + return; + } + break; + case MT_PARTICLEGEN: + if (!P_ParticleGenSceneryThink(mobj)) + return; + break; + case MT_FSGNA: + if (mobj->movedir) + mobj->angle += mobj->movedir; + break; + case MT_ROSY: + P_RosySceneryThink(mobj); + break; + case MT_CDLHRT: + { + if (mobj->cvmem < 24) + mobj->cvmem++; + mobj->movedir += ANG10; + P_UnsetThingPosition(mobj); + mobj->x = mobj->extravalue1 + P_ReturnThrustX(mobj, mobj->movedir, mobj->cvmem*mobj->scale); + mobj->y = mobj->extravalue2 + P_ReturnThrustY(mobj, mobj->movedir, mobj->cvmem*mobj->scale); + P_SetThingPosition(mobj); + if ((--mobj->fuse) < 6) + { + if (!mobj->fuse) + { + P_RemoveMobj(mobj); + return; + } + mobj->frame = (mobj->frame & ~FF_TRANSMASK) | ((10 - (mobj->fuse*2)) << (FF_TRANSSHIFT)); + } + } + break; + case MT_VWREF: + case MT_VWREB: + { + INT32 strength; + ++mobj->movedir; + mobj->frame &= ~FF_TRANSMASK; + strength = min(mobj->fuse, (INT32)mobj->movedir)*3; + if (strength < 10) + mobj->frame |= ((10 - strength) << (FF_TRANSSHIFT)); + } + /* FALLTHRU */ + default: + if (mobj->fuse) + { // Scenery object fuse! Very basic! + mobj->fuse--; + if (!mobj->fuse) + { +#ifdef HAVE_BLUA + if (!LUAh_MobjFuse(mobj)) +#endif + P_RemoveMobj(mobj); + return; + } + } + break; + } + + P_SceneryThinker(mobj); +} + // // P_MobjThinker // @@ -7171,7 +8046,7 @@ void P_MobjThinker(mobj_t *mobj) tmfloorthing = tmhitthing = NULL; - // 970 allows ANY mobj to trigger a linedef exec + // Sector special (2,8) allows ANY mobj to trigger a linedef exec if (mobj->subsector && GETSECSPECIAL(mobj->subsector->sector->special, 2) == 8) { sector_t *sec2; @@ -7181,42 +8056,8 @@ void P_MobjThinker(mobj_t *mobj) P_LinedefExecute(sec2->tag, mobj, sec2); } - // Slowly scale up/down to reach your destscale. if (mobj->scale != mobj->destscale) - { - fixed_t oldheight = mobj->height; - UINT8 correctionType = 0; // Don't correct Z position, just gain height - - if ((mobj->flags & MF_NOCLIPHEIGHT || (mobj->z > mobj->floorz && mobj->z + mobj->height < mobj->ceilingz)) - && mobj->type != MT_EGGMOBILE_FIRE) - correctionType = 1; // Correct Z position by centering - else if (mobj->eflags & MFE_VERTICALFLIP) - correctionType = 2; // Correct Z position by moving down - - if (abs(mobj->scale - mobj->destscale) < mobj->scalespeed) - P_SetScale(mobj, mobj->destscale); - else if (mobj->scale < mobj->destscale) - P_SetScale(mobj, mobj->scale + mobj->scalespeed); - else if (mobj->scale > mobj->destscale) - P_SetScale(mobj, mobj->scale - mobj->scalespeed); - - if (correctionType == 1) - mobj->z -= (mobj->height - oldheight)/2; - else if (correctionType == 2) - mobj->z -= mobj->height - oldheight; - - if (mobj->scale == mobj->destscale) - /// \todo Lua hook for "reached destscale"? - switch(mobj->type) - { - case MT_EGGMOBILE_FIRE: - mobj->destscale = FRACUNIT; - mobj->scalespeed = FRACUNIT>>4; - break; - default: - break; - } - } + P_MobjScaleThink(mobj); // Slowly scale up/down to reach your destscale. if ((mobj->type == MT_GHOST || mobj->type == MT_THOK) && mobj->fuse > 0) // Not guaranteed to be MF_SCENERY or not MF_SCENERY! { @@ -7237,806 +8078,7 @@ void P_MobjThinker(mobj_t *mobj) // Special thinker for scenery objects if (mobj->flags & MF_SCENERY) { -#ifdef HAVE_BLUA - if (LUAh_MobjThinker(mobj)) - return; - if (P_MobjWasRemoved(mobj)) - return; -#endif - - if (mobj->flags2 & MF2_SHIELD) - if (!P_AddShield(mobj)) - return; - - switch (mobj->type) - { - case MT_BOSSJUNK: - mobj->flags2 ^= MF2_DONTDRAW; - break; - case MT_MACEPOINT: - case MT_CHAINMACEPOINT: - case MT_SPRINGBALLPOINT: - case MT_CHAINPOINT: - case MT_FIREBARPOINT: - case MT_CUSTOMMACEPOINT: - case MT_HIDDEN_SLING: - { - angle_t oldmovedir = mobj->movedir; - - // Always update movedir to prevent desyncing (in the traditional sense, not the netplay sense). - mobj->movedir = (mobj->movedir + mobj->lastlook) & FINEMASK; - - // If too far away and not deliberately spitting in the face of optimisation, don't think! - if (!(mobj->flags2 & MF2_BOSSNOTRAP)) - { - UINT8 i; - // Quick! Look through players! Don't move unless a player is relatively close by. - // The below is selected based on CEZ2's first room. I promise you it is a coincidence that it looks like the weed number. - for (i = 0; i < MAXPLAYERS; ++i) - if (playeringame[i] && players[i].mo - && P_AproxDistance(P_AproxDistance(mobj->x - players[i].mo->x, mobj->y - players[i].mo->y), mobj->z - players[i].mo->z) < (4200<flags2 & MF2_BEYONDTHEGRAVE)) - { - mobj_t *ref = mobj; - - // stop/hide all your babies - while ((ref = ref->hnext)) - { - ref->eflags = (((ref->flags & MF_NOTHINK) ? 0 : 1) - | ((ref->flags & MF_NOCLIPTHING) ? 0 : 2) - | ((ref->flags2 & MF2_DONTDRAW) ? 0 : 4)); // oh my god this is nasty. - ref->flags |= MF_NOTHINK|MF_NOCLIPTHING; - ref->flags2 |= MF2_DONTDRAW; - ref->momx = ref->momy = ref->momz = 0; - } - - mobj->flags2 |= MF2_BEYONDTHEGRAVE; - } - - break; // don't make bubble! - } - else if (mobj->flags2 & MF2_BEYONDTHEGRAVE) - { - mobj_t *ref = mobj; - - // start/show all your babies - while ((ref = ref->hnext)) - { - if (ref->eflags & 1) - ref->flags &= ~MF_NOTHINK; - if (ref->eflags & 2) - ref->flags &= ~MF_NOCLIPTHING; - if (ref->eflags & 4) - ref->flags2 &= ~MF2_DONTDRAW; - ref->eflags = 0; // le sign - } - - mobj->flags2 &= ~MF2_BEYONDTHEGRAVE; - } - } - - // Okay, time to MOVE - P_MaceRotate(mobj, mobj->movedir, oldmovedir); - } - break; - case MT_HOOP: - if (mobj->fuse > 1) - P_MoveHoop(mobj); - else if (mobj->fuse == 1) - mobj->movecount = 1; - - if (mobj->movecount) - { - mobj->fuse++; - - if (mobj->fuse > 32) - { - // Don't kill the hoop center. For the sake of respawning. - //if (mobj->target) - // P_RemoveMobj(mobj->target); - - P_RemoveMobj(mobj); - } - } - else - mobj->fuse--; - return; - case MT_NIGHTSPARKLE: - if (mobj->tics != -1) - { - mobj->tics--; - - // you can cycle through multiple states in a tic - if (!mobj->tics) - if (!P_SetMobjState(mobj, mobj->state->nextstate)) - return; // freed itself - } - - P_UnsetThingPosition(mobj); - mobj->x += mobj->momx; - mobj->y += mobj->momy; - mobj->z += mobj->momz; - P_SetThingPosition(mobj); - return; - case MT_NIGHTSLOOPHELPER: - if (--mobj->tics <= 0) - P_RemoveMobj(mobj); - - // Don't touch my fuse! - return; - case MT_OVERLAY: - if (!mobj->target) - { - P_RemoveMobj(mobj); - return; - } - else - P_AddOverlay(mobj); - break; - case MT_PITY_ORB: - case MT_WHIRLWIND_ORB: - case MT_ARMAGEDDON_ORB: - if (!(mobj->flags2 & MF2_SHIELD)) - return; - break; - case MT_ATTRACT_ORB: - if (!(mobj->flags2 & MF2_SHIELD)) - return; - if (/*(mobj->target) -- the following is implicit by P_AddShield - && (mobj->target->player) - && */ (mobj->target->player->homing) && (mobj->target->player->pflags & PF_SHIELDABILITY)) - { - P_SetMobjState(mobj, mobj->info->painstate); - mobj->tics++; - } - break; - case MT_ELEMENTAL_ORB: - if (!(mobj->flags2 & MF2_SHIELD)) - return; - if (mobj->tracer - /* && mobj->target -- the following is implicit by P_AddShield - && mobj->target->player - && (mobj->target->player->powers[pw_shield] & SH_NOSTACK) == SH_ELEMENTAL */ - && mobj->target->player->pflags & PF_SHIELDABILITY - && ((statenum_t)(mobj->tracer->state-states) < mobj->info->raisestate - || (mobj->tracer->state->nextstate < mobj->info->raisestate && mobj->tracer->tics == 1))) - { - P_SetMobjState(mobj, mobj->info->painstate); - mobj->tics++; - P_SetMobjState(mobj->tracer, mobj->info->raisestate); - mobj->tracer->tics++; - } - break; - case MT_FORCE_ORB: - if (!(mobj->flags2 & MF2_SHIELD)) - return; - if (/* - && mobj->target -- the following is implicit by P_AddShield - && mobj->target->player - && (mobj->target->player->powers[pw_shield] & SH_FORCE) - && */ (mobj->target->player->pflags & PF_SHIELDABILITY)) - { - mobj_t *whoosh = P_SpawnMobjFromMobj(mobj, 0, 0, 0, MT_GHOST); // done here so the offset is correct - P_SetMobjState(whoosh, mobj->info->raisestate); - whoosh->destscale = whoosh->scale<<1; - whoosh->scalespeed = FixedMul(whoosh->scalespeed, whoosh->scale); - whoosh->height = 38*whoosh->scale; - whoosh->fuse = 10; - whoosh->flags |= MF_NOCLIPHEIGHT; - whoosh->momz = mobj->target->momz; // Stay reasonably centered for a few frames - mobj->target->player->pflags &= ~PF_SHIELDABILITY; // prevent eternal whoosh - } - /* FALLTHRU */ - case MT_FLAMEAURA_ORB: - if (!(mobj->flags2 & MF2_SHIELD)) - return; - if ((statenum_t)(mobj->state-states) < mobj->info->painstate) - mobj->angle = mobj->target->angle; // implicitly okay because of P_AddShield - if (mobj->tracer - /* && mobj->target -- the following is implicit by P_AddShield - && mobj->target->player - && (mobj->target->player->powers[pw_shield] & SH_NOSTACK) == SH_FLAMEAURA */ - && mobj->target->player->pflags & PF_SHIELDABILITY - && ((statenum_t)(mobj->tracer->state-states) < mobj->info->raisestate - || (mobj->tracer->state->nextstate < mobj->info->raisestate && mobj->tracer->tics == 1))) - { - P_SetMobjState(mobj, mobj->info->painstate); - mobj->tics++; - P_SetMobjState(mobj->tracer, mobj->info->raisestate); - mobj->tracer->tics++; - } - break; - case MT_BUBBLEWRAP_ORB: - if (!(mobj->flags2 & MF2_SHIELD)) - return; - if (mobj->tracer - /* && mobj->target -- the following is implicit by P_AddShield - && mobj->target->player - && (mobj->target->player->powers[pw_shield] & SH_NOSTACK) == SH_BUBBLEWRAP */ - ) - { - if (mobj->target->player->pflags & PF_SHIELDABILITY - && ((statenum_t)(mobj->state-states) < mobj->info->painstate - || (mobj->state->nextstate < mobj->info->painstate && mobj->tics == 1))) - { - P_SetMobjState(mobj, mobj->info->painstate); - mobj->tics++; - P_SetMobjState(mobj->tracer, mobj->info->raisestate); - mobj->tracer->tics++; - } - else if (mobj->target->eflags & MFE_JUSTHITFLOOR - && (statenum_t)(mobj->state-states) == mobj->info->painstate) - { - P_SetMobjState(mobj, mobj->info->painstate+1); - mobj->tics++; - P_SetMobjState(mobj->tracer, mobj->info->raisestate+1); - mobj->tracer->tics++; - } - } - break; - case MT_THUNDERCOIN_ORB: - if (!(mobj->flags2 & MF2_SHIELD)) - return; - if (mobj->tracer - /* && mobj->target -- the following is implicit by P_AddShield - && mobj->target->player - && (mobj->target->player->powers[pw_shield] & SH_NOSTACK) == SH_THUNDERCOIN */ - && (mobj->target->player->pflags & PF_SHIELDABILITY)) - { - P_SetMobjState(mobj, mobj->info->painstate); - mobj->tics++; - P_SetMobjState(mobj->tracer, mobj->info->raisestate); - mobj->tracer->tics++; - mobj->target->player->pflags &= ~PF_SHIELDABILITY; // prevent eternal spark - } - break; - case MT_WATERDROP: - P_SceneryCheckWater(mobj); - if ((mobj->z <= mobj->floorz || mobj->z <= mobj->watertop) - && mobj->health > 0) - { - mobj->health = 0; - P_SetMobjState(mobj, mobj->info->deathstate); - S_StartSound(mobj, mobj->info->deathsound+P_RandomKey(mobj->info->mass)); - return; - } - break; - case MT_BUBBLES: - P_SceneryCheckWater(mobj); - break; - case MT_SMALLBUBBLE: - case MT_MEDIUMBUBBLE: - case MT_EXTRALARGEBUBBLE: // start bubble dissipate - P_SceneryCheckWater(mobj); - if (P_MobjWasRemoved(mobj)) // bubble was removed by not being in water - return; - if (!(mobj->eflags & MFE_UNDERWATER) - || (!(mobj->eflags & MFE_VERTICALFLIP) && mobj->z + mobj->height >= mobj->ceilingz) - || (mobj->eflags & MFE_VERTICALFLIP && mobj->z <= mobj->floorz) - || (P_CheckDeathPitCollide(mobj)) - || --mobj->fuse <= 0) // Bubbles eventually dissipate if they can't reach the surface. - { - // no playing sound: no point; the object is being removed - P_RemoveMobj(mobj); - return; - } - break; - case MT_LOCKON: - if (!mobj->target) - { - P_RemoveMobj(mobj); - return; - } - - mobj->flags2 &= ~MF2_DONTDRAW; - - mobj->x = mobj->target->x; - mobj->y = mobj->target->y; - - mobj->eflags |= (mobj->target->eflags & MFE_VERTICALFLIP); - - mobj->destscale = mobj->target->destscale; - P_SetScale(mobj, mobj->target->scale); - - if (!(mobj->eflags & MFE_VERTICALFLIP)) - mobj->z = mobj->target->z + mobj->target->height + FixedMul((16 + abs((signed)(leveltime % TICRATE) - TICRATE/2))*FRACUNIT, mobj->target->scale); - else - mobj->z = mobj->target->z - FixedMul((16 + abs((signed)(leveltime % TICRATE) - TICRATE/2))*FRACUNIT, mobj->target->scale) - mobj->height; - break; - case MT_LOCKONINF: - if (!(mobj->flags2 & MF2_STRONGBOX)) - { - mobj->threshold = mobj->z; - mobj->flags2 |= MF2_STRONGBOX; - } - if (!(mobj->eflags & MFE_VERTICALFLIP)) - mobj->z = mobj->threshold + FixedMul((16 + abs((signed)(leveltime % TICRATE) - TICRATE/2))*FRACUNIT, mobj->scale); - else - mobj->z = mobj->threshold - FixedMul((16 + abs((signed)(leveltime % TICRATE) - TICRATE/2))*FRACUNIT, mobj->scale); - break; - case MT_DROWNNUMBERS: - if (!mobj->target) - { - P_RemoveMobj(mobj); - return; - } - if (!mobj->target->player || !(mobj->target->player->powers[pw_underwater] || mobj->target->player->powers[pw_spacetime])) - { - P_RemoveMobj(mobj); - return; - } - mobj->x = mobj->target->x; - mobj->y = mobj->target->y; - - mobj->destscale = mobj->target->destscale; - P_SetScale(mobj, mobj->target->scale); - - if (mobj->target->eflags & MFE_VERTICALFLIP) - { - mobj->z = mobj->target->z - FixedMul(16*FRACUNIT, mobj->target->scale) - mobj->height; - if (mobj->target->player->pflags & PF_FLIPCAM) - mobj->eflags |= MFE_VERTICALFLIP; - } - else - mobj->z = mobj->target->z + (mobj->target->height) + FixedMul(8*FRACUNIT, mobj->target->scale); // Adjust height for height changes - - if (mobj->threshold <= 35) - mobj->flags2 |= MF2_DONTDRAW; - else - mobj->flags2 &= ~MF2_DONTDRAW; - if (mobj->threshold <= 30) - mobj->threshold = 40; - mobj->threshold--; - break; - case MT_FLAMEJET: - if ((mobj->flags2 & MF2_FIRING) && (leveltime & 3) == 0) - { - mobj_t *flame; - fixed_t strength; - - // Wave the flames back and forth. Reactiontime determines which direction it's going. - if (mobj->fuse <= -16) - mobj->reactiontime = 1; - else if (mobj->fuse >= 16) - mobj->reactiontime = 0; - - if (mobj->reactiontime) - mobj->fuse += 2; - else - mobj->fuse -= 2; - - flame = P_SpawnMobj(mobj->x, mobj->y, mobj->z, MT_FLAMEJETFLAME); - P_SetMobjState(flame, S_FLAMEJETFLAME4); - - flame->angle = mobj->angle; - - if (mobj->flags2 & MF2_AMBUSH) // Wave up and down instead of side-to-side - flame->momz = mobj->fuse << (FRACBITS-2); - else - flame->angle += FixedAngle(mobj->fuse*FRACUNIT); - - strength = 20*FRACUNIT; - strength -= ((20*FRACUNIT)/16)*mobj->movedir; - - P_InstaThrust(flame, flame->angle, strength); - S_StartSound(flame, sfx_fire); - } - break; - case MT_VERTICALFLAMEJET: - if ((mobj->flags2 & MF2_FIRING) && (leveltime & 3) == 0) - { - mobj_t *flame; - fixed_t strength; - - // Wave the flames back and forth. Reactiontime determines which direction it's going. - if (mobj->fuse <= -16) - mobj->reactiontime = 1; - else if (mobj->fuse >= 16) - mobj->reactiontime = 0; - - if (mobj->reactiontime) - mobj->fuse++; - else - mobj->fuse--; - - flame = P_SpawnMobj(mobj->x, mobj->y, mobj->z, MT_FLAMEJETFLAME); - - strength = 20*FRACUNIT; - strength -= ((20*FRACUNIT)/16)*mobj->movedir; - - // If deaf'd, the object spawns on the ceiling. - if (mobj->flags2 & MF2_AMBUSH) - { - mobj->z = mobj->ceilingz-mobj->height; - flame->momz = -strength; - } - else - { - flame->momz = strength; - P_SetMobjState(flame, S_FLAMEJETFLAME7); - } - P_InstaThrust(flame, mobj->angle, FixedDiv(mobj->fuse*FRACUNIT,3*FRACUNIT)); - S_StartSound(flame, sfx_fire); - } - break; - case MT_FLICKY_01_CENTER: - case MT_FLICKY_02_CENTER: - case MT_FLICKY_03_CENTER: - case MT_FLICKY_04_CENTER: - case MT_FLICKY_05_CENTER: - case MT_FLICKY_06_CENTER: - case MT_FLICKY_07_CENTER: - case MT_FLICKY_08_CENTER: - case MT_FLICKY_09_CENTER: - case MT_FLICKY_10_CENTER: - case MT_FLICKY_11_CENTER: - case MT_FLICKY_12_CENTER: - case MT_FLICKY_13_CENTER: - case MT_FLICKY_14_CENTER: - case MT_FLICKY_15_CENTER: - case MT_FLICKY_16_CENTER: - case MT_SECRETFLICKY_01_CENTER: - case MT_SECRETFLICKY_02_CENTER: - if (mobj->tracer && (mobj->flags & MF_NOCLIPTHING) - && (mobj->flags & MF_GRENADEBOUNCE)) - // for now: only do this bounce routine if flicky is in-place. \todo allow in all movements - { - if (!(mobj->tracer->flags2 & MF2_OBJECTFLIP) && mobj->tracer->z <= mobj->tracer->floorz) - mobj->tracer->momz = 7*FRACUNIT; - else if ((mobj->tracer->flags2 & MF2_OBJECTFLIP) && mobj->tracer->z >= mobj->tracer->ceilingz - mobj->tracer->height) - mobj->tracer->momz = -7*FRACUNIT; - } - break; - case MT_SEED: - if (P_MobjFlip(mobj)*mobj->momz < mobj->info->speed) - mobj->momz = P_MobjFlip(mobj)*mobj->info->speed; - break; - case MT_ROCKCRUMBLE1: - case MT_ROCKCRUMBLE2: - case MT_ROCKCRUMBLE3: - case MT_ROCKCRUMBLE4: - case MT_ROCKCRUMBLE5: - case MT_ROCKCRUMBLE6: - case MT_ROCKCRUMBLE7: - case MT_ROCKCRUMBLE8: - case MT_ROCKCRUMBLE9: - case MT_ROCKCRUMBLE10: - case MT_ROCKCRUMBLE11: - case MT_ROCKCRUMBLE12: - case MT_ROCKCRUMBLE13: - case MT_ROCKCRUMBLE14: - case MT_ROCKCRUMBLE15: - case MT_ROCKCRUMBLE16: - case MT_WOODDEBRIS: - case MT_BRICKDEBRIS: - case MT_BROKENROBOT: - if (mobj->z <= P_FloorzAtPos(mobj->x, mobj->y, mobj->z, mobj->height) - && mobj->state != &states[mobj->info->deathstate]) - { - P_SetMobjState(mobj, mobj->info->deathstate); - return; - } - break; - case MT_PARTICLEGEN: - if (!mobj->lastlook) - return; - - if (!mobj->threshold) - return; - - if (--mobj->fuse <= 0) - { - INT32 i = 0; - mobj_t *spawn; - fixed_t bottomheight, topheight; - INT32 type = mobj->threshold, line = mobj->cvmem; - - mobj->fuse = (tic_t)mobj->reactiontime; - - bottomheight = lines[line].frontsector->floorheight; - topheight = lines[line].frontsector->ceilingheight - mobjinfo[(mobjtype_t)type].height; - - if (mobj->waterbottom != bottomheight || mobj->watertop != topheight) - { - if (mobj->movefactor && (topheight > bottomheight)) - mobj->health = (tic_t)(FixedDiv((topheight - bottomheight), abs(mobj->movefactor)) >> FRACBITS); - else - mobj->health = 0; - - mobj->z = ((mobj->flags2 & MF2_OBJECTFLIP) ? topheight : bottomheight); - } - - if (!mobj->health) - return; - - for (i = 0; i < mobj->lastlook; i++) - { - spawn = P_SpawnMobj( - mobj->x + FixedMul(FixedMul(mobj->friction, mobj->scale), FINECOSINE(mobj->angle>>ANGLETOFINESHIFT)), - mobj->y + FixedMul(FixedMul(mobj->friction, mobj->scale), FINESINE(mobj->angle>>ANGLETOFINESHIFT)), - mobj->z, - (mobjtype_t)mobj->threshold); - P_SetScale(spawn, mobj->scale); - spawn->momz = FixedMul(mobj->movefactor, spawn->scale); - spawn->destscale = spawn->scale/100; - spawn->scalespeed = spawn->scale/mobj->health; - spawn->tics = (tic_t)mobj->health; - spawn->flags2 |= (mobj->flags2 & MF2_OBJECTFLIP); - spawn->angle += P_RandomKey(36)*ANG10; // irrelevant for default objects but might make sense for some custom ones - - mobj->angle += mobj->movedir; - } - - mobj->angle += (angle_t)mobj->movecount; - } - break; - case MT_FSGNA: - if (mobj->movedir) - mobj->angle += mobj->movedir; - break; - case MT_ROSY: - { - UINT8 i; - fixed_t pdist = 1700*mobj->scale, work, actualwork; - player_t *player = NULL; - statenum_t stat = (mobj->state-states); - for (i = 0; i < MAXPLAYERS; i++) - { - if (!playeringame[i]) - continue; - if (!players[i].mo) - continue; - if (players[i].bot) - continue; - if (!players[i].mo->health) - continue; - actualwork = work = FixedHypot(mobj->x-players[i].mo->x, mobj->y-players[i].mo->y); - if (player) - { - if (players[i].skin == 0 || players[i].skin == 5) - work = (2*work)/3; - if (work >= pdist) - continue; - } - pdist = actualwork; - player = &players[i]; - } - - if (stat == S_ROSY_JUMP || stat == S_ROSY_PAIN) - { - if (P_IsObjectOnGround(mobj)) - { - mobj->momx = mobj->momy = 0; - if (player && mobj->cvmem < (-2*TICRATE)) - stat = S_ROSY_UNHAPPY; - else - stat = S_ROSY_WALK; - P_SetMobjState(mobj, stat); - } - else if (P_MobjFlip(mobj)*mobj->momz < 0) - mobj->frame = mobj->state->frame+mobj->state->var1; - } - - if (!player) - { - if ((stat < S_ROSY_IDLE1 || stat > S_ROSY_IDLE4) && stat != S_ROSY_JUMP) - { - mobj->momx = mobj->momy = 0; - P_SetMobjState(mobj, S_ROSY_IDLE1); - } - } - else - { - boolean dojump = false, targonground, love, makeheart = false; - if (mobj->target != player->mo) - P_SetTarget(&mobj->target, player->mo); - // Tatsuru: Don't try to hug them if they're above or below you! - targonground = (P_IsObjectOnGround(mobj->target) && (player->panim == PA_IDLE || player->panim == PA_WALK || player->panim == PA_RUN) && player->mo->z == mobj->z); - love = (player->skin == 0 || player->skin == 5); - - switch (stat) - { - case S_ROSY_IDLE1: - case S_ROSY_IDLE2: - case S_ROSY_IDLE3: - case S_ROSY_IDLE4: - dojump = true; - break; - case S_ROSY_JUMP: - case S_ROSY_PAIN: - // handled above - break; - case S_ROSY_WALK: - { - fixed_t x = mobj->x, y = mobj->y, z = mobj->z; - angle_t angletoplayer = R_PointToAngle2(x, y, mobj->target->x, mobj->target->y); - boolean allowed = P_TryMove(mobj, mobj->target->x, mobj->target->y, false); - - P_UnsetThingPosition(mobj); - mobj->x = x; - mobj->y = y; - mobj->z = z; - P_SetThingPosition(mobj); - - if (allowed) - { - fixed_t mom, max; - P_Thrust(mobj, angletoplayer, (3*FRACUNIT)>>1); - mom = FixedHypot(mobj->momx, mobj->momy); - max = pdist; - if ((--mobj->extravalue1) <= 0) - { - if (++mobj->frame > mobj->state->frame+mobj->state->var1) - mobj->frame = mobj->state->frame; - if (mom > 12*mobj->scale) - mobj->extravalue1 = 2; - else if (mom > 6*mobj->scale) - mobj->extravalue1 = 3; - else - mobj->extravalue1 = 4; - } - if (max < (mobj->radius + mobj->target->radius)) - { - mobj->momx = mobj->target->player->cmomx; - mobj->momy = mobj->target->player->cmomy; - if ((mobj->cvmem > TICRATE && !player->exiting) || !targonground) - P_SetMobjState(mobj, (stat = S_ROSY_STND)); - else - { - mobj->target->momx = mobj->momx; - mobj->target->momy = mobj->momy; - P_SetMobjState(mobj, (stat = S_ROSY_HUG)); - S_StartSound(mobj, sfx_cdpcm6); - mobj->angle = angletoplayer; - } - } - else - { - max /= 3; - if (max > 30*mobj->scale) - max = 30*mobj->scale; - if (mom > max && max > mobj->scale) - { - max = FixedDiv(max, mom); - mobj->momx = FixedMul(mobj->momx, max); - mobj->momy = FixedMul(mobj->momy, max); - } - if (abs(mobj->momx) > mobj->scale || abs(mobj->momy) > mobj->scale) - mobj->angle = R_PointToAngle2(0, 0, mobj->momx, mobj->momy); - } - } - else - dojump = true; - } - break; - case S_ROSY_HUG: - if (targonground) - { - player->pflags |= PF_STASIS; - if (mobj->cvmem < 5*TICRATE) - mobj->cvmem++; - if (love && !(leveltime & 7)) - makeheart = true; - } - else - { - if (mobj->cvmem < (love ? 5*TICRATE : 0)) - { - P_SetMobjState(mobj, (stat = S_ROSY_PAIN)); - S_StartSound(mobj, sfx_cdpcm7); - } - else - P_SetMobjState(mobj, (stat = S_ROSY_JUMP)); - var1 = var2 = 0; - A_DoNPCPain(mobj); - mobj->cvmem -= TICRATE; - } - break; - case S_ROSY_STND: - if ((pdist > (mobj->radius + mobj->target->radius + 3*(mobj->scale + mobj->target->scale)))) - P_SetMobjState(mobj, (stat = S_ROSY_WALK)); - else if (!targonground) - ; - else - { - if (love && !(leveltime & 15)) - makeheart = true; - if (player->exiting || --mobj->cvmem < TICRATE) - { - P_SetMobjState(mobj, (stat = S_ROSY_HUG)); - S_StartSound(mobj, sfx_cdpcm6); - mobj->angle = R_PointToAngle2(mobj->x, mobj->y, mobj->target->x, mobj->target->y); - mobj->target->momx = mobj->momx; - mobj->target->momy = mobj->momy; - } - } - break; - case S_ROSY_UNHAPPY: - default: - break; - } - - if (stat == S_ROSY_HUG) - { - if (player->panim != PA_IDLE) - P_SetPlayerMobjState(mobj->target, S_PLAY_STND); - player->pflags |= PF_STASIS; - } - - if (dojump) - { - P_SetMobjState(mobj, S_ROSY_JUMP); - mobj->z += P_MobjFlip(mobj); - mobj->momx = mobj->momy = 0; - P_SetObjectMomZ(mobj, 6<height, MT_CDLHRT); - cdlhrt->destscale = (5*mobj->scale)>>4; - P_SetScale(cdlhrt, cdlhrt->destscale); - cdlhrt->fuse = (5*TICRATE)>>1; - cdlhrt->momz = mobj->scale; - P_SetTarget(&cdlhrt->target, mobj); - cdlhrt->extravalue1 = mobj->x; - cdlhrt->extravalue2 = mobj->y; - } - } - } - break; - case MT_CDLHRT: - { - if (mobj->cvmem < 24) - mobj->cvmem++; - mobj->movedir += ANG10; - P_UnsetThingPosition(mobj); - mobj->x = mobj->extravalue1 + P_ReturnThrustX(mobj, mobj->movedir, mobj->cvmem*mobj->scale); - mobj->y = mobj->extravalue2 + P_ReturnThrustY(mobj, mobj->movedir, mobj->cvmem*mobj->scale); - P_SetThingPosition(mobj); - if ((--mobj->fuse) < 6) - { - if (!mobj->fuse) - { - P_RemoveMobj(mobj); - return; - } - mobj->frame = (mobj->frame & ~FF_TRANSMASK)|((10-(mobj->fuse*2))<<(FF_TRANSSHIFT)); - } - } - break; - case MT_VWREF: - case MT_VWREB: - { - INT32 strength; - ++mobj->movedir; - mobj->frame &= ~FF_TRANSMASK; - strength = min(mobj->fuse, (INT32)mobj->movedir)*3; - if (strength < 10) - mobj->frame |= ((10-strength)<<(FF_TRANSSHIFT)); - } - /* FALLTHRU */ - default: - if (mobj->fuse) - { // Scenery object fuse! Very basic! - mobj->fuse--; - if (!mobj->fuse) - { -#ifdef HAVE_BLUA - if (!LUAh_MobjFuse(mobj)) -#endif - P_RemoveMobj(mobj); - return; - } - } - break; - } - - P_SceneryThinker(mobj); + P_MobjSceneryThink(mobj); return; } From b49672e3f91da252ca1cd882e0fb1dc75f1b5ccc Mon Sep 17 00:00:00 2001 From: Steel Titanium Date: Tue, 24 Dec 2019 17:44:06 -0500 Subject: [PATCH 377/746] Change this condition a bit --- src/p_inter.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/p_inter.c b/src/p_inter.c index 5ec1161ea..52b84059f 100644 --- a/src/p_inter.c +++ b/src/p_inter.c @@ -3439,13 +3439,13 @@ void P_SpecialStageDamage(player_t *player, mobj_t *inflictor, mobj_t *source) } } - if (inflictor->type == MT_LHRT) - return; - if (source->player->ctfteam == player->ctfteam) return; } + if (inflictor->type == MT_LHRT) + return; + if (player->powers[pw_shield] || player->bot) //If One-Hit Shield { P_RemoveShield(player); From 8d8e0ca22c79df5cfee65622e78ca1645ed0cddd Mon Sep 17 00:00:00 2001 From: Steel Titanium Date: Tue, 24 Dec 2019 17:45:57 -0500 Subject: [PATCH 378/746] Clean up comment --- src/p_inter.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/p_inter.c b/src/p_inter.c index 52b84059f..064551c8c 100644 --- a/src/p_inter.c +++ b/src/p_inter.c @@ -3426,8 +3426,6 @@ void P_SpecialStageDamage(player_t *player, mobj_t *inflictor, mobj_t *source) if (player->powers[pw_invulnerability] || player->powers[pw_flashing] || player->powers[pw_super]) return; - // Don't allow players to hurt one another, - // unless cv_friendlyfire is on. if (!cv_friendlyfire.value) { if (inflictor->type == MT_LHRT && !(player->powers[pw_shield] & SH_NOSTACK)) From 5d89e915c6099ec20034ef37212c2dde034b122d Mon Sep 17 00:00:00 2001 From: MascaraSnake Date: Wed, 25 Dec 2019 00:14:53 +0100 Subject: [PATCH 379/746] Continue cutting up P_MobjThinker into multiple functions --- src/p_mobj.c | 3500 ++++++++++++++++++++++++++------------------------ 1 file changed, 1793 insertions(+), 1707 deletions(-) diff --git a/src/p_mobj.c b/src/p_mobj.c index ab435afce..84592dcaa 100644 --- a/src/p_mobj.c +++ b/src/p_mobj.c @@ -8018,6 +8018,1791 @@ static void P_MobjSceneryThink(mobj_t *mobj) P_SceneryThinker(mobj); } +static boolean P_MobjPushableThink(mobj_t *mobj) +{ + P_MobjCheckWater(mobj); + P_PushableThinker(mobj); + + // Extinguish fire objects in water. (Yes, it's extraordinarily rare to have a pushable flame object, but Brak uses such a case.) + if (mobj->flags & MF_FIRE && mobj->type != MT_PUMA && mobj->type != MT_FIREBALL + && (mobj->eflags & (MFE_UNDERWATER | MFE_TOUCHWATER))) + { + P_KillMobj(mobj, NULL, NULL, 0); + return false; + } + + return true; +} + +static boolean P_MobjBossThink(mobj_t *mobj) +{ +#ifdef HAVE_BLUA + if (LUAh_BossThinker(mobj)) + { + if (P_MobjWasRemoved(mobj)) + return false; + } + else if (P_MobjWasRemoved(mobj)) + return false; + else +#endif + switch (mobj->type) + { + case MT_EGGMOBILE: + if (mobj->health < mobj->info->damage + 1 && leveltime & 2) + { + fixed_t rad = mobj->radius >> FRACBITS; + fixed_t hei = mobj->height >> FRACBITS; + mobj_t *particle = P_SpawnMobjFromMobj(mobj, + P_RandomRange(rad, -rad) << FRACBITS, + P_RandomRange(rad, -rad) << FRACBITS, + P_RandomRange(hei / 2, hei) << FRACBITS, + MT_SMOKE); + P_SetObjectMomZ(particle, 2 << FRACBITS, false); + particle->momz += mobj->momz; + } + if (mobj->flags2 & MF2_SKULLFLY) +#if 1 + P_SpawnGhostMobj(mobj); +#else // all the way back from final demo... MT_THOK isn't even the same size anymore! + { + mobj_t *spawnmobj; + spawnmobj = P_SpawnMobj(mobj->x, mobj->y, mobj->z, mobj->info->painchance); + P_SetTarget(&spawnmobj->target, mobj); + spawnmobj->color = SKINCOLOR_GREY; + } +#endif + P_Boss1Thinker(mobj); + break; + case MT_EGGMOBILE2: + if (mobj->health < mobj->info->damage + 1 && leveltime & 2) + { + fixed_t rad = mobj->radius >> FRACBITS; + fixed_t hei = mobj->height >> FRACBITS; + mobj_t *particle = P_SpawnMobjFromMobj(mobj, + P_RandomRange(rad, -rad) << FRACBITS, + P_RandomRange(rad, -rad) << FRACBITS, + P_RandomRange(hei/2, hei) << FRACBITS, + MT_SMOKE); + P_SetObjectMomZ(particle, 2 << FRACBITS, false); + particle->momz += mobj->momz; + } + P_Boss2Thinker(mobj); + break; + case MT_EGGMOBILE3: + if (mobj->health < mobj->info->damage + 1 && leveltime & 2) + { + fixed_t rad = mobj->radius >> FRACBITS; + fixed_t hei = mobj->height >> FRACBITS; + mobj_t *particle = P_SpawnMobjFromMobj(mobj, + P_RandomRange(rad, -rad) << FRACBITS, + P_RandomRange(rad, -rad) << FRACBITS, + P_RandomRange(hei/2, hei) << FRACBITS, + MT_SMOKE); + P_SetObjectMomZ(particle, 2 << FRACBITS, false); + particle->momz += mobj->momz; + } + P_Boss3Thinker(mobj); + break; + case MT_EGGMOBILE4: + if (mobj->health < mobj->info->damage + 1 && leveltime & 2) + { + fixed_t rad = mobj->radius >> FRACBITS; + fixed_t hei = mobj->height >> FRACBITS; + mobj_t* particle = P_SpawnMobjFromMobj(mobj, + P_RandomRange(rad, -rad) << FRACBITS, + P_RandomRange(rad, -rad) << FRACBITS, + P_RandomRange(hei/2, hei) << FRACBITS, + MT_SMOKE); + P_SetObjectMomZ(particle, 2 << FRACBITS, false); + particle->momz += mobj->momz; + } + P_Boss4Thinker(mobj); + break; + case MT_FANG: + P_Boss5Thinker(mobj); + break; + case MT_BLACKEGGMAN: + P_Boss7Thinker(mobj); + break; + case MT_METALSONIC_BATTLE: + P_Boss9Thinker(mobj); + break; + default: // Generic SOC-made boss + if (mobj->flags2 & MF2_SKULLFLY) + P_SpawnGhostMobj(mobj); + P_GenericBossThinker(mobj); + break; + } + if (mobj->flags2 & MF2_BOSSFLEE) + { + if (mobj->extravalue1) + { + if (!(--mobj->extravalue1)) + { + if (mobj->target) + { + mobj->momz = FixedMul(FixedDiv(mobj->target->z - mobj->z, P_AproxDistance(mobj->x - mobj->target->x, mobj->y - mobj->target->y)), mobj->scale << 1); + mobj->angle = R_PointToAngle2(mobj->x, mobj->y, mobj->target->x, mobj->target->y); + } + else + mobj->momz = 8*mobj->scale; + } + else + mobj->angle += mobj->movedir; + } + else if (mobj->target) + P_InstaThrust(mobj, mobj->angle, FixedMul(12*FRACUNIT, mobj->scale)); + } + if (mobj->type == MT_CYBRAKDEMON && !mobj->health) + { + if (!(mobj->tics & 1)) + { + var1 = 2; + var2 = 0; + A_BossScream(mobj); + } + if (P_CheckDeathPitCollide(mobj)) + { + P_RemoveMobj(mobj); + return false; + } + if (mobj->momz && mobj->z + mobj->momz <= mobj->floorz) + { + S_StartSound(mobj, sfx_befall); + if (mobj->state != states + S_CYBRAKDEMON_DIE8) + P_SetMobjState(mobj, S_CYBRAKDEMON_DIE8); + } + } + return true; +} + +static boolean P_MobjDeadThink(mobj_t *mobj) +{ + switch (mobj->type) + { + case MT_BLUESPHERE: + if ((mobj->tics >> 2) + 1 > 0 && (mobj->tics >> 2) + 1 <= tr_trans60) // tr_trans50 through tr_trans90, shifting once every second frame + mobj->frame = (NUMTRANSMAPS - ((mobj->tics >> 2) + 1)) << FF_TRANSSHIFT; + else // tr_trans60 otherwise + mobj->frame = tr_trans60 << FF_TRANSSHIFT; + break; + case MT_EGGCAPSULE: + if (mobj->z <= mobj->floorz) + { + P_RemoveMobj(mobj); + return false; + } + break; + case MT_FAKEMOBILE: + if (mobj->scale == mobj->destscale) + { + if (!mobj->fuse) + { + S_StartSound(mobj, sfx_s3k77); + mobj->flags2 |= MF2_DONTDRAW; + mobj->fuse = TICRATE; + } + return false; + } + if (!mobj->reactiontime) + { + if (P_RandomChance(FRACUNIT/2)) + mobj->movefactor = FRACUNIT; + else + mobj->movefactor = -FRACUNIT; + if (P_RandomChance(FRACUNIT/2)) + mobj->movedir = ANG20; + else + mobj->movedir = -ANG20; + mobj->reactiontime = 5; + } + mobj->momz += mobj->movefactor; + mobj->angle += mobj->movedir; + P_InstaThrust(mobj, mobj->angle, -mobj->info->speed); + mobj->reactiontime--; + break; + case MT_EGGSHIELD: + mobj->flags2 ^= MF2_DONTDRAW; + break; + case MT_EGGTRAP: // Egg Capsule animal release + if (mobj->fuse > 0)// && mobj->fuse < TICRATE-(TICRATE/7)) + { + INT32 i; + fixed_t x, y, z; + fixed_t ns; + mobj_t* mo2; + mobj_t* flicky; + + z = mobj->subsector->sector->floorheight + FRACUNIT + (P_RandomKey(64) << FRACBITS); + for (i = 0; i < 3; i++) + { + const angle_t fa = P_RandomKey(FINEANGLES) & FINEMASK; + ns = 64*FRACUNIT; + x = mobj->x + FixedMul(FINESINE(fa), ns); + y = mobj->y + FixedMul(FINECOSINE(fa), ns); + + mo2 = P_SpawnMobj(x, y, z, MT_EXPLODE); + P_SetMobjStateNF(mo2, S_XPLD_EGGTRAP); // so the flickies don't lose their target if they spawn + ns = 4*FRACUNIT; + mo2->momx = FixedMul(FINESINE(fa), ns); + mo2->momy = FixedMul(FINECOSINE(fa), ns); + mo2->angle = fa << ANGLETOFINESHIFT; + + if (!i && !(mobj->fuse & 2)) + S_StartSound(mo2, mobj->info->deathsound); + + flicky = P_InternalFlickySpawn(mo2, 0, 8*FRACUNIT, false, -1); + if (!flicky) + break; + + P_SetTarget(&flicky->target, mo2); + flicky->momx = mo2->momx; + flicky->momy = mo2->momy; + } + + mobj->fuse--; + } + break; + case MT_PLAYER: + /// \todo Have the player's dead body completely finish its animation even if they've already respawned. + if (!mobj->fuse) + { // Go away. + /// \todo Actually go ahead and remove mobj completely, and fix any bugs and crashes doing this creates. Chasecam should stop moving, and F12 should never return to it. + mobj->momz = 0; + if (mobj->player) + mobj->flags2 |= MF2_DONTDRAW; + else // safe to remove, nobody's going to complain! + { + P_RemoveMobj(mobj); + return false; + } + } + else // Apply gravity to fall downwards. + { + if (mobj->player && !(mobj->fuse % 8) && (mobj->player->charflags & SF_MACHINE)) + { + fixed_t r = mobj->radius >> FRACBITS; + mobj_t *explosion = P_SpawnMobj( + mobj->x + (P_RandomRange(r, -r) << FRACBITS), + mobj->y + (P_RandomRange(r, -r) << FRACBITS), + mobj->z + (P_RandomKey(mobj->height >> FRACBITS) << FRACBITS), + MT_SONIC3KBOSSEXPLODE); + S_StartSound(explosion, sfx_s3kb4); + } + if (mobj->movedir == DMG_DROWNED) + P_SetObjectMomZ(mobj, -FRACUNIT/2, true); // slower fall from drowning + else + P_SetObjectMomZ(mobj, -2*FRACUNIT/3, true); + } + break; + case MT_METALSONIC_RACE: + { + if (!(mobj->fuse % 8)) + { + fixed_t r = mobj->radius >> FRACBITS; + mobj_t *explosion = P_SpawnMobj( + mobj->x + (P_RandomRange(r, -r) << FRACBITS), + mobj->y + (P_RandomRange(r, -r) << FRACBITS), + mobj->z + (P_RandomKey(mobj->height >> FRACBITS) << FRACBITS), + MT_SONIC3KBOSSEXPLODE); + S_StartSound(explosion, sfx_s3kb4); + } + P_SetObjectMomZ(mobj, -2*FRACUNIT/3, true); + } + break; + default: + break; + } + return true; +} + +// Angle-to-tracer to trigger a linedef exec +// See Linedef Exec 457 (Track mobj angle to point) +static void P_TracerAngleThink(mobj_t *mobj) +{ + if (!mobj->tracer) + return; + + if (!mobj->extravalue2) + return; + + // mobj->lastlook - Don't disable behavior after first failure + // mobj->extravalue1 - Angle tolerance + // mobj->extravalue2 - Exec tag upon failure + // mobj->cvval - Allowable failure delay + // mobj->cvmem - Failure timer + + angle_t ang = mobj->angle - R_PointToAngle2(mobj->x, mobj->y, mobj->tracer->x, mobj->tracer->y); + + // \todo account for distance between mobj and tracer + // Because closer mobjs can be facing beyond the angle tolerance + // yet tracer is still in the camera view + + // failure state: mobj is not facing tracer + // Reasaonable defaults: ANGLE_67h, ANGLE_292h + if (ang >= (angle_t)mobj->extravalue1 && ang <= ANGLE_MAX - (angle_t)mobj->extravalue1) + { + if (mobj->cvmem) + mobj->cvmem--; + else + { + INT32 exectag = mobj->extravalue2; // remember this before we erase the values + + if (mobj->lastlook) + mobj->cvmem = mobj->cusval; // reset timer for next failure + else + { + // disable after first failure + mobj->eflags &= ~MFE_TRACERANGLE; + mobj->lastlook = mobj->extravalue1 = mobj->extravalue2 = mobj->cvmem = mobj->cusval = 0; + } + + P_LinedefExecute(exectag, mobj, NULL); + } + } + else + mobj->cvmem = mobj->cusval; // reset failure timer +} + +static void P_ArrowThink(mobj_t *mobj) +{ + if (mobj->flags & MF_MISSILE) + { + // Calculate the angle of movement. + /* + momz + / | + / | + / | + 0------dist(momx,momy) + */ + + fixed_t dist = P_AproxDistance(mobj->momx, mobj->momy); + angle_t angle = R_PointToAngle2(0, 0, dist, mobj->momz); + + if (angle > ANG20 && angle <= ANGLE_180) + mobj->frame = 2; + else if (angle < ANG340 && angle > ANGLE_180) + mobj->frame = 0; + else + mobj->frame = 1; + + if (!(mobj->extravalue1) && (mobj->momz < 0)) + { + mobj->extravalue1 = 1; + S_StartSound(mobj, mobj->info->activesound); + } + if (leveltime & 1) + { + mobj_t *dust = P_SpawnMobjFromMobj(mobj, 0, 0, 0, MT_PARTICLE); + dust->tics = 18; + dust->scalespeed = 4096; + dust->destscale = FRACUNIT/32; + } + } + else + mobj->flags2 ^= MF2_DONTDRAW; +} + +static void P_BumbleboreThink(mobj_t *mobj) +{ + statenum_t st = mobj->state - states; + if (st == S_BUMBLEBORE_FLY1 || st == S_BUMBLEBORE_FLY2) + { + if (!mobj->target) + P_SetMobjState(mobj, mobj->info->spawnstate); + else if (P_MobjFlip(mobj)*((mobj->z + (mobj->height >> 1)) - (mobj->target->z + (mobj->target->height >> 1))) > 0 + && R_PointToDist2(mobj->x, mobj->y, mobj->target->x, mobj->target->y) <= 32*FRACUNIT) + { + mobj->momx >>= 1; + mobj->momy >>= 1; + if (++mobj->movefactor == 4) + { + S_StartSound(mobj, mobj->info->seesound); + mobj->momx = mobj->momy = mobj->momz = 0; + mobj->flags = (mobj->flags|MF_PAIN) & ~MF_NOGRAVITY; + P_SetMobjState(mobj, mobj->info->meleestate); + } + } + else + mobj->movefactor = 0; + } + else if (st == S_BUMBLEBORE_RAISE || st == S_BUMBLEBORE_FALL2) // no _FALL1 because it's an 0-tic + { + if (P_IsObjectOnGround(mobj)) + { + S_StopSound(mobj); + S_StartSound(mobj, mobj->info->attacksound); + mobj->flags = (mobj->flags | MF_NOGRAVITY) & ~MF_PAIN; + mobj->momx = mobj->momy = mobj->momz = 0; + P_SetMobjState(mobj, mobj->info->painstate); + } + else + { + mobj->angle += ANGLE_22h; + mobj->frame = mobj->state->frame + ((mobj->tics & 2) >> 1); + } + } + else if (st == S_BUMBLEBORE_STUCK2 && mobj->tics < TICRATE) + mobj->frame = mobj->state->frame + ((mobj->tics & 2) >> 1); +} + +static boolean P_HangsterThink(mobj_t *mobj) +{ + statenum_t st = mobj->state - states; + //ghost image trail when flying down + if (st == S_HANGSTER_SWOOP1 || st == S_HANGSTER_SWOOP2) + { + P_SpawnGhostMobj(mobj); + //curve when in line with target, otherwise curve to avoid crashing into floor + if ((mobj->z - mobj->floorz <= 80*FRACUNIT) || (mobj->target && (mobj->z - mobj->target->z <= 80*FRACUNIT))) + P_SetMobjState(mobj, (st = S_HANGSTER_ARC1)); + } + + //swoop arc movement stuff + if (st == S_HANGSTER_ARC1) + { + A_FaceTarget(mobj); + P_Thrust(mobj, mobj->angle, 1*FRACUNIT); + } + else if (st == S_HANGSTER_ARC2) + P_Thrust(mobj, mobj->angle, 2*FRACUNIT); + else if (st == S_HANGSTER_ARC3) + P_Thrust(mobj, mobj->angle, 4*FRACUNIT); + //if movement has stopped while flying (like hitting a wall), fly up immediately + else if (st == S_HANGSTER_FLY1 && !mobj->momx && !mobj->momy) + { + mobj->extravalue1 = 0; + P_SetMobjState(mobj, S_HANGSTER_ARCUP1); + } + //after swooping back up, check for ceiling + else if ((st == S_HANGSTER_RETURN1 || st == S_HANGSTER_RETURN2) && mobj->momz == 0 && mobj->ceilingz == (mobj->z + mobj->height)) + P_SetMobjState(mobj, (st = S_HANGSTER_RETURN3)); + + //should you roost on a ceiling with F_SKY1 as its flat, disappear forever + if (st == S_HANGSTER_RETURN3 && mobj->momz == 0 && mobj->ceilingz == (mobj->z + mobj->height) + && mobj->subsector->sector->ceilingpic == skyflatnum + && mobj->subsector->sector->ceilingheight == mobj->ceilingz) + { + P_RemoveMobj(mobj); + return false; + } + + return true; +} + +static boolean P_JetFume1Think(mobj_t *mobj) +{ + fixed_t jetx, jety; + + if (!mobj->target // if you have no target + || (!(mobj->target->flags & MF_BOSS) && mobj->target->health <= 0)) // or your target isn't a boss and it's popped now + { // then remove yourself as well! + P_RemoveMobj(mobj); + return false; + } + + jetx = mobj->target->x + P_ReturnThrustX(mobj->target, mobj->target->angle, FixedMul(-64*FRACUNIT, mobj->target->scale)); + jety = mobj->target->y + P_ReturnThrustY(mobj->target, mobj->target->angle, FixedMul(-64*FRACUNIT, mobj->target->scale)); + + if (mobj->fuse == 56) // First one + { + P_UnsetThingPosition(mobj); + mobj->x = jetx; + mobj->y = jety; + if (mobj->target->eflags & MFE_VERTICALFLIP) + mobj->z = mobj->target->z + mobj->target->height - mobj->height - FixedMul(38*FRACUNIT, mobj->target->scale); + else + mobj->z = mobj->target->z + FixedMul(38*FRACUNIT, mobj->target->scale); + mobj->floorz = mobj->z; + mobj->ceilingz = mobj->z + mobj->height; + P_SetThingPosition(mobj); + } + else if (mobj->fuse == 57) + { + P_UnsetThingPosition(mobj); + mobj->x = jetx + P_ReturnThrustX(mobj->target, mobj->target->angle - ANGLE_90, FixedMul(24*FRACUNIT, mobj->target->scale)); + mobj->y = jety + P_ReturnThrustY(mobj->target, mobj->target->angle - ANGLE_90, FixedMul(24*FRACUNIT, mobj->target->scale)); + if (mobj->target->eflags & MFE_VERTICALFLIP) + mobj->z = mobj->target->z + mobj->target->height - mobj->height - FixedMul(12*FRACUNIT, mobj->target->scale); + else + mobj->z = mobj->target->z + FixedMul(12*FRACUNIT, mobj->target->scale); + mobj->floorz = mobj->z; + mobj->ceilingz = mobj->z + mobj->height; + P_SetThingPosition(mobj); + } + else if (mobj->fuse == 58) + { + P_UnsetThingPosition(mobj); + mobj->x = jetx + P_ReturnThrustX(mobj->target, mobj->target->angle + ANGLE_90, FixedMul(24*FRACUNIT, mobj->target->scale)); + mobj->y = jety + P_ReturnThrustY(mobj->target, mobj->target->angle + ANGLE_90, FixedMul(24*FRACUNIT, mobj->target->scale)); + if (mobj->target->eflags & MFE_VERTICALFLIP) + mobj->z = mobj->target->z + mobj->target->height - mobj->height - FixedMul(12*FRACUNIT, mobj->target->scale); + else + mobj->z = mobj->target->z + FixedMul(12*FRACUNIT, mobj->target->scale); + mobj->floorz = mobj->z; + mobj->ceilingz = mobj->z + mobj->height; + P_SetThingPosition(mobj); + } + else if (mobj->fuse == 59) + { + boolean dashmod = ((mobj->target->flags & MF_PAIN) && (mobj->target->health <= mobj->target->info->damage)); + jetx = mobj->target->x + P_ReturnThrustX(mobj->target, mobj->target->angle, -mobj->target->radius); + jety = mobj->target->y + P_ReturnThrustY(mobj->target, mobj->target->angle, -mobj->target->radius); + P_UnsetThingPosition(mobj); + mobj->x = jetx; + mobj->y = jety; + mobj->destscale = mobj->target->scale; + if (!(dashmod && mobj->target->state == states + S_METALSONIC_BOUNCE)) + { + mobj->destscale = (mobj->destscale + FixedDiv(R_PointToDist2(0, 0, mobj->target->momx, mobj->target->momy), 36*mobj->target->scale))/3; + } + if (mobj->target->eflags & MFE_VERTICALFLIP) + mobj->z = mobj->target->z + mobj->target->height/2 + mobj->height/2; + else + mobj->z = mobj->target->z + mobj->target->height/2 - mobj->height/2; + mobj->floorz = mobj->z; + mobj->ceilingz = mobj->z + mobj->height; + P_SetThingPosition(mobj); + if (dashmod) + { + mobj->color = SKINCOLOR_SUNSET; + if (mobj->target->movecount == 3 && !mobj->target->reactiontime && (mobj->target->movedir == 0 || mobj->target->movedir == 2)) + P_SpawnGhostMobj(mobj); + } + else + mobj->color = SKINCOLOR_ICY; + } + mobj->fuse++; + return true; +} + +static boolean P_EggRobo1Think(mobj_t *mobj) +{ +#define SPECTATORRADIUS (96*mobj->scale) + if (!(mobj->flags2 & MF2_STRONGBOX)) + { + mobj->cusval = mobj->x; // eat my SOCs, p_mobj.h warning, we have lua now + mobj->cvmem = mobj->y; // ditto + mobj->movedir = mobj->angle; + mobj->threshold = P_MobjFlip(mobj)*10*mobj->scale; + if (mobj->threshold < 0) + mobj->threshold += (mobj->ceilingz - mobj->height); + else + mobj->threshold += mobj->floorz; + var1 = 4; + A_BossJetFume(mobj); + mobj->flags2 |= MF2_STRONGBOX; + } + + if (mobj->state == &states[mobj->info->deathstate]) // todo: make map actually set health to 0 for these + { + if (mobj->movecount) + { + if (!(--mobj->movecount)) + S_StartSound(mobj, mobj->info->deathsound); + } + else + { + mobj->momz += P_MobjFlip(mobj)*mobj->scale; + if (mobj->momz > 0) + { + if (mobj->z + mobj->momz > mobj->ceilingz + (1000 << FRACBITS)) + { + P_RemoveMobj(mobj); + return false; + } + } + else if (mobj->z + mobj->height + mobj->momz < mobj->floorz - (1000 << FRACBITS)) + { + P_RemoveMobj(mobj); + return false; + } + } + } + else + { + fixed_t basex = mobj->cusval, basey = mobj->cvmem; + + if (mobj->spawnpoint && mobj->spawnpoint->options & (MTF_AMBUSH|MTF_OBJECTSPECIAL)) + { + angle_t sideang = mobj->movedir + ((mobj->spawnpoint->options & MTF_AMBUSH) ? ANGLE_90 : -ANGLE_90); + fixed_t oscillate = FixedMul(FINESINE(((leveltime * ANG1) >> (ANGLETOFINESHIFT + 2)) & FINEMASK), 250*mobj->scale); + basex += P_ReturnThrustX(mobj, sideang, oscillate); + basey += P_ReturnThrustY(mobj, sideang, oscillate); + } + + mobj->z = mobj->threshold + FixedMul(FINESINE(((leveltime + mobj->movecount)*ANG2 >> (ANGLETOFINESHIFT - 2)) & FINEMASK), 8*mobj->scale); + if (mobj->state != &states[mobj->info->meleestate]) + { + boolean didmove = false; + + if (mobj->state == &states[mobj->info->spawnstate]) + { + UINT8 i; + fixed_t dist = INT32_MAX; + + for (i = 0; i < MAXPLAYERS; i++) + { + fixed_t compdist; + if (!playeringame[i]) + continue; + if (players[i].spectator) + continue; + if (!players[i].mo) + continue; + if (!players[i].mo->health) + continue; + if (P_PlayerInPain(&players[i])) + continue; + if (players[i].mo->z > mobj->z + mobj->height + 8*mobj->scale) + continue; + if (players[i].mo->z + players[i].mo->height < mobj->z - 8*mobj->scale) + continue; + compdist = P_AproxDistance( + players[i].mo->x + players[i].mo->momx - basex, + players[i].mo->y + players[i].mo->momy - basey); + if (compdist >= dist) + continue; + dist = compdist; + P_SetTarget(&mobj->target, players[i].mo); + } + + if (dist < (SPECTATORRADIUS << 1)) + { + didmove = true; + mobj->frame = 3 + ((leveltime & 2) >> 1); + mobj->angle = R_PointToAngle2(mobj->x, mobj->y, mobj->target->x, mobj->target->y); + + if (P_AproxDistance( + mobj->x - basex, + mobj->y - basey) + < mobj->scale) + S_StartSound(mobj, mobj->info->seesound); + + P_TeleportMove(mobj, + (15*(mobj->x >> 4)) + (basex >> 4) + P_ReturnThrustX(mobj, mobj->angle, SPECTATORRADIUS >> 4), + (15*(mobj->y >> 4)) + (basey >> 4) + P_ReturnThrustY(mobj, mobj->angle, SPECTATORRADIUS >> 4), + mobj->z); + } + else + { + angle_t diff = (mobj->movedir - mobj->angle); + if (diff > ANGLE_180) + diff = InvAngle(InvAngle(diff)/8); + else + diff /= 8; + mobj->angle += diff; + + dist = FINECOSINE(((leveltime + mobj->movecount)*ANG2 >> (ANGLETOFINESHIFT - 2)) & FINEMASK); + + if (abs(dist) < FRACUNIT/2) + mobj->frame = 0; + else + mobj->frame = (dist > 0) ? 1 : 2; + } + } + + if (!didmove) + { + if (P_AproxDistance(mobj->x - basex, mobj->y - basey) < mobj->scale) + P_TeleportMove(mobj, basex, basey, mobj->z); + else + P_TeleportMove(mobj, + (15*(mobj->x >> 4)) + (basex >> 4), + (15*(mobj->y >> 4)) + (basey >> 4), + mobj->z); + } + } + } + return true; +#undef SPECTATORRADIUS +} + +static void P_NiGHTSDroneThink(mobj_t *mobj) +{ + { + // variable setup + mobj_t *goalpost = NULL; + mobj_t *sparkle = NULL; + mobj_t *droneman = NULL; + + boolean flip = mobj->flags2 & MF2_OBJECTFLIP; + boolean topaligned = (mobj->flags & MF_SLIDEME) && !(mobj->flags & MF_GRENADEBOUNCE); + boolean middlealigned = (mobj->flags & MF_GRENADEBOUNCE) && !(mobj->flags & MF_SLIDEME); + boolean bottomoffsetted = !(mobj->flags & MF_SLIDEME) && !(mobj->flags & MF_GRENADEBOUNCE); + boolean flipchanged = false; + + fixed_t dronemanoffset, goaloffset, sparkleoffset, droneboxmandiff, dronemangoaldiff; + + if (mobj->target && mobj->target->type == MT_NIGHTSDRONE_GOAL) + { + goalpost = mobj->target; + if (goalpost->target && goalpost->target->type == MT_NIGHTSDRONE_SPARKLING) + sparkle = goalpost->target; + if (goalpost->tracer && goalpost->tracer->type == MT_NIGHTSDRONE_MAN) + droneman = goalpost->tracer; + } + + if (!goalpost || !sparkle || !droneman) + return; + + // did NIGHTSDRONE position, scale, flip, or flags change? all elements need to be synced + droneboxmandiff = max(mobj->height - droneman->height, 0); + dronemangoaldiff = max(droneman->height - goalpost->height, 0); + + if (!(goalpost->flags2 & MF2_OBJECTFLIP) && (mobj->flags2 & MF2_OBJECTFLIP)) + { + goalpost->eflags |= MFE_VERTICALFLIP; + goalpost->flags2 |= MF2_OBJECTFLIP; + sparkle->eflags |= MFE_VERTICALFLIP; + sparkle->flags2 |= MF2_OBJECTFLIP; + droneman->eflags |= MFE_VERTICALFLIP; + droneman->flags2 |= MF2_OBJECTFLIP; + flipchanged = true; + } + else if ((goalpost->flags2 & MF2_OBJECTFLIP) && !(mobj->flags2 & MF2_OBJECTFLIP)) + { + goalpost->eflags &= ~MFE_VERTICALFLIP; + goalpost->flags2 &= ~MF2_OBJECTFLIP; + sparkle->eflags &= ~MFE_VERTICALFLIP; + sparkle->flags2 &= ~MF2_OBJECTFLIP; + droneman->eflags &= ~MFE_VERTICALFLIP; + droneman->flags2 &= ~MF2_OBJECTFLIP; + flipchanged = true; + } + + if (goalpost->destscale != mobj->destscale + || goalpost->movefactor != mobj->z + || goalpost->friction != mobj->height + || flipchanged + || goalpost->threshold != (INT32)(mobj->flags & (MF_SLIDEME|MF_GRENADEBOUNCE))) + { + goalpost->destscale = sparkle->destscale = droneman->destscale = mobj->destscale; + + // straight copy-pasta from P_SpawnMapThing, case MT_NIGHTSDRONE + if (!flip) + { + if (topaligned) // Align droneman to top of hitbox + { + dronemanoffset = droneboxmandiff; + goaloffset = dronemangoaldiff/2 + dronemanoffset; + } + else if (middlealigned) // Align droneman to center of hitbox + { + dronemanoffset = droneboxmandiff/2; + goaloffset = dronemangoaldiff/2 + dronemanoffset; + } + else if (bottomoffsetted) + { + dronemanoffset = 24*FRACUNIT; + goaloffset = dronemangoaldiff + dronemanoffset; + } + else + { + dronemanoffset = 0; + goaloffset = dronemangoaldiff/2 + dronemanoffset; + } + + sparkleoffset = goaloffset - FixedMul(15*FRACUNIT, mobj->scale); + } + else + { + if (topaligned) // Align droneman to top of hitbox + { + dronemanoffset = 0; + goaloffset = dronemangoaldiff/2 + dronemanoffset; + } + else if (middlealigned) // Align droneman to center of hitbox + { + dronemanoffset = droneboxmandiff/2; + goaloffset = dronemangoaldiff/2 + dronemanoffset; + } + else if (bottomoffsetted) + { + dronemanoffset = droneboxmandiff - FixedMul(24*FRACUNIT, mobj->scale); + goaloffset = dronemangoaldiff + dronemanoffset; + } + else + { + dronemanoffset = droneboxmandiff; + goaloffset = dronemangoaldiff/2 + dronemanoffset; + } + + sparkleoffset = goaloffset + FixedMul(15*FRACUNIT, mobj->scale); + } + + P_TeleportMove(goalpost, mobj->x, mobj->y, mobj->z + goaloffset); + P_TeleportMove(sparkle, mobj->x, mobj->y, mobj->z + sparkleoffset); + if (goalpost->movefactor != mobj->z || goalpost->friction != mobj->height) + { + P_TeleportMove(droneman, mobj->x, mobj->y, mobj->z + dronemanoffset); + goalpost->movefactor = mobj->z; + goalpost->friction = mobj->height; + } + goalpost->threshold = mobj->flags & (MF_SLIDEME|MF_GRENADEBOUNCE); + } + else + { + if (goalpost->x != mobj->x || goalpost->y != mobj->y) + { + P_TeleportMove(goalpost, mobj->x, mobj->y, goalpost->z); + P_TeleportMove(sparkle, mobj->x, mobj->y, sparkle->z); + } + + if (droneman->x != mobj->x || droneman->y != mobj->y) + P_TeleportMove(droneman, mobj->x, mobj->y, + droneman->z >= mobj->floorz && droneman->z <= mobj->ceilingz ? droneman->z : mobj->z); + } + + // now toggle states! + // GOAL mode? + if (sparkle->state >= &states[S_NIGHTSDRONE_SPARKLING1] && sparkle->state <= &states[S_NIGHTSDRONE_SPARKLING16]) + { + INT32 i; + boolean bonustime = false; + + for (i = 0; i < MAXPLAYERS; i++) + if (playeringame[i] && players[i].bonustime && players[i].powers[pw_carry] == CR_NIGHTSMODE) + { + bonustime = true; + break; + } + + if (!bonustime) + { + CONS_Debug(DBG_NIGHTSBASIC, "Removing goal post\n"); + if (goalpost && goalpost->state != &states[S_INVISIBLE]) + P_SetMobjState(goalpost, S_INVISIBLE); + if (sparkle && sparkle->state != &states[S_INVISIBLE]) + P_SetMobjState(sparkle, S_INVISIBLE); + } + } + // Invisible/bouncing mode. + else + { + INT32 i; + boolean bonustime = false; + fixed_t zcomp; + + // Bouncy bouncy! + if (!flip) + { + if (topaligned) + zcomp = droneboxmandiff + mobj->z; + else if (middlealigned) + zcomp = (droneboxmandiff/2) + mobj->z; + else if (bottomoffsetted) + zcomp = mobj->z + FixedMul(24*FRACUNIT, mobj->scale); + else + zcomp = mobj->z; + } + else + { + if (topaligned) + zcomp = mobj->z; + else if (middlealigned) + zcomp = (droneboxmandiff/2) + mobj->z; + else if (bottomoffsetted) + zcomp = mobj->z + droneboxmandiff - FixedMul(24*FRACUNIT, mobj->scale); + else + zcomp = mobj->z + droneboxmandiff; + } + + droneman->angle += ANG10; + if (!flip && droneman->z <= zcomp) + droneman->momz = FixedMul(5*FRACUNIT, droneman->scale); + else if (flip && droneman->z >= zcomp) + droneman->momz = FixedMul(-5*FRACUNIT, droneman->scale); + + // state switching logic + for (i = 0; i < MAXPLAYERS; i++) + if (playeringame[i] && players[i].bonustime && players[i].powers[pw_carry] == CR_NIGHTSMODE) + { + bonustime = true; + break; + } + + if (bonustime) + { + CONS_Debug(DBG_NIGHTSBASIC, "Adding goal post\n"); + if (!(droneman->flags2 & MF2_DONTDRAW)) + droneman->flags2 |= MF2_DONTDRAW; + if (goalpost->state == &states[S_INVISIBLE]) + P_SetMobjState(goalpost, mobjinfo[goalpost->type].meleestate); + if (sparkle->state == &states[S_INVISIBLE]) + P_SetMobjState(sparkle, mobjinfo[sparkle->type].meleestate); + } + else if (!G_IsSpecialStage(gamemap)) + { + for (i = 0; i < MAXPLAYERS; i++) + if (playeringame[i] && players[i].powers[pw_carry] != CR_NIGHTSMODE) + { + bonustime = true; // variable reuse + break; + } + + if (bonustime) + { + // show droneman if at least one player is non-nights + if (goalpost->state != &states[S_INVISIBLE]) + P_SetMobjState(goalpost, S_INVISIBLE); + if (sparkle->state != &states[S_INVISIBLE]) + P_SetMobjState(sparkle, S_INVISIBLE); + if (droneman->state != &states[mobjinfo[droneman->type].meleestate]) + P_SetMobjState(droneman, mobjinfo[droneman->type].meleestate); + if (droneman->flags2 & MF2_DONTDRAW) + droneman->flags2 &= ~MF2_DONTDRAW; + } + else + { + // else, hide it + if (!(droneman->flags2 & MF2_DONTDRAW)) + droneman->flags2 |= MF2_DONTDRAW; + } + } + } + } +} + +static boolean P_TurretThink(mobj_t *mobj) +{ + P_MobjCheckWater(mobj); + P_CheckPosition(mobj, mobj->x, mobj->y); + if (P_MobjWasRemoved(mobj)) + return false; + mobj->floorz = tmfloorz; + mobj->ceilingz = tmceilingz; + mobj->floorrover = tmfloorrover; + mobj->ceilingrover = tmceilingrover; + + if ((mobj->eflags & MFE_UNDERWATER) && mobj->health > 0) + { + P_SetMobjState(mobj, mobj->info->deathstate); + mobj->health = 0; + mobj->flags2 &= ~MF2_FIRING; + } + else if (mobj->health > 0 && mobj->z + mobj->height > mobj->ceilingz) // Crushed + { + INT32 i, j; + fixed_t ns; + fixed_t x, y, z; + mobj_t* mo2; + + z = mobj->subsector->sector->floorheight + FixedMul(64*FRACUNIT, mobj->scale); + for (j = 0; j < 2; j++) + { + for (i = 0; i < 32; i++) + { + const angle_t fa = (i*FINEANGLES/16) & FINEMASK; + ns = FixedMul(64*FRACUNIT, mobj->scale); + x = mobj->x + FixedMul(FINESINE(fa), ns); + y = mobj->y + FixedMul(FINECOSINE(fa), ns); + + mo2 = P_SpawnMobj(x, y, z, MT_EXPLODE); + ns = FixedMul(16*FRACUNIT, mobj->scale); + mo2->momx = FixedMul(FINESINE(fa), ns); + mo2->momy = FixedMul(FINECOSINE(fa), ns); + } + z -= FixedMul(32*FRACUNIT, mobj->scale); + } + P_SetMobjState(mobj, mobj->info->deathstate); + mobj->health = 0; + mobj->flags2 &= ~MF2_FIRING; + } + return true; +} + +static void P_SaloonDoorThink(mobj_t *mobj) +{ + fixed_t x = mobj->tracer->x; + fixed_t y = mobj->tracer->y; + fixed_t z = mobj->tracer->z; + angle_t oang = FixedAngle(mobj->extravalue1); + angle_t fa = (oang >> ANGLETOFINESHIFT) & FINEMASK; + fixed_t c0 = -96*FINECOSINE(fa); + fixed_t s0 = -96*FINESINE(fa); + angle_t fma; + fixed_t c, s; + angle_t angdiff; + + // Adjust angular speed + fixed_t da = AngleFixed(mobj->angle - oang); + if (da > 180*FRACUNIT) + da -= 360*FRACUNIT; + mobj->extravalue2 = 8*(mobj->extravalue2 - da/32)/9; + + // Update angle + mobj->angle += FixedAngle(mobj->extravalue2); + + angdiff = mobj->angle - FixedAngle(mobj->extravalue1); + if (angdiff > (ANGLE_90 - ANG2) && angdiff < ANGLE_180) + { + mobj->angle = FixedAngle(mobj->extravalue1) + (ANGLE_90 - ANG2); + mobj->extravalue2 /= 2; + } + else if (angdiff < (ANGLE_270 + ANG2) && angdiff >= ANGLE_180) + { + mobj->angle = FixedAngle(mobj->extravalue1) + (ANGLE_270 + ANG2); + mobj->extravalue2 /= 2; + } + + // Update position + fma = (mobj->angle >> ANGLETOFINESHIFT) & FINEMASK; + c = 48*FINECOSINE(fma); + s = 48*FINESINE(fma); + P_TeleportMove(mobj, x + c0 + c, y + s0 + s, z); +} + +static void P_PyreFlyThink(mobj_t *mobj) +{ + fixed_t hdist; + + mobj->extravalue1 = (mobj->extravalue1 + 3) % 360; + mobj->z += FINESINE(((mobj->extravalue1 * ANG1) >> ANGLETOFINESHIFT) & FINEMASK); + + if (!(mobj->flags2 & MF2_BOSSNOTRAP)) + P_LookForPlayers(mobj, true, false, 1500*FRACUNIT); + + if (!mobj->target) + return; + + if (mobj->extravalue2 == 1) + P_PyreFlyBurn(mobj, 0, 20, MT_SMOKE, 4*FRACUNIT); + else if (mobj->extravalue2 == 2) + { + INT32 fireradius = min(100 - mobj->fuse, 52); + P_PyreFlyBurn(mobj, P_RandomRange(0, fireradius) << FRACBITS, 20, MT_FLAMEPARTICLE, 4*FRACUNIT); + P_PyreFlyBurn(mobj, fireradius*FRACUNIT, 40, MT_PYREFLY_FIRE, 0); + } + + hdist = R_PointToDist2(mobj->x, mobj->y, mobj->target->x, mobj->target->y); + + if (hdist > 1500*FRACUNIT) + { + mobj->flags2 &= ~MF2_BOSSNOTRAP; + P_SetTarget(&mobj->target, NULL); + return; + } + + if (!(mobj->flags2 & MF2_BOSSNOTRAP) && hdist <= 450*FRACUNIT) + mobj->flags2 |= MF2_BOSSNOTRAP; + + if (!(mobj->flags2 & MF2_BOSSNOTRAP)) + return; + + if (hdist < 1000*FRACUNIT) + { + //Aim for player z position. If too close to floor/ceiling, aim just above/below them. + fixed_t destz = min(max(mobj->target->z, mobj->target->floorz + 70*FRACUNIT), mobj->target->ceilingz - 80*FRACUNIT - mobj->height); + fixed_t dist = P_AproxDistance(hdist, destz - mobj->z); + P_InstaThrust(mobj, R_PointToAngle2(mobj->x, mobj->y, mobj->target->x, mobj->target->y), 2*FRACUNIT); + mobj->momz = FixedMul(FixedDiv(destz - mobj->z, dist), 2*FRACUNIT); + } + else + { + mobj->momx = 0; + mobj->momy = 0; + mobj->momz = 0; + } +} + +static void P_PterabyteThink(mobj_t *mobj) +{ + if (mobj->extravalue1 & 4) // Cooldown after grabbing + { + if (mobj->movefactor) + mobj->movefactor--; + else + { + P_SetTarget(&mobj->target, NULL); + mobj->extravalue1 &= 3; + } + } + + if ((mobj->extravalue1 & 3) == 0) // Hovering + { + fixed_t vdist, hdist, time; + fixed_t hspeed = 3*mobj->info->speed; + angle_t fa; + + var1 = 1; + var2 = 0; + A_CapeChase(mobj); + + if (mobj->target) + return; // Still carrying a player or in cooldown + + P_LookForPlayers(mobj, true, false, 256*FRACUNIT); + + if (!mobj->target) + return; + + if (mobj->target->player->powers[pw_flashing]) + { + P_SetTarget(&mobj->target, NULL); + return; + } + + vdist = mobj->z - mobj->target->z - mobj->target->height; + if (P_MobjFlip(mobj)*vdist <= 0) + { + P_SetTarget(&mobj->target, NULL); + return; + } + + hdist = R_PointToDist2(mobj->x, mobj->y, mobj->target->x, mobj->target->y); + if (hdist > 450*FRACUNIT) + { + P_SetTarget(&mobj->target, NULL); + return; + } + + P_SetMobjState(mobj, S_PTERABYTE_SWOOPDOWN); + mobj->extravalue1++; + S_StartSound(mobj, mobj->info->attacksound); + time = FixedDiv(hdist, hspeed); + mobj->angle = R_PointToAngle2(mobj->x, mobj->y, mobj->target->x, mobj->target->y); + fa = (mobj->angle >> ANGLETOFINESHIFT) & FINEMASK; + mobj->momx = FixedMul(FINECOSINE(fa), hspeed); + mobj->momy = FixedMul(FINESINE(fa), hspeed); + mobj->momz = -2*FixedDiv(vdist, time); + mobj->extravalue2 = -FixedDiv(mobj->momz, time); //Z accel + mobj->movecount = time >> FRACBITS; + mobj->reactiontime = mobj->movecount; + } + else if ((mobj->extravalue1 & 3) == 1) // Swooping + { + mobj->reactiontime--; + mobj->momz += mobj->extravalue2; + if (mobj->reactiontime) + return; + + if (mobj->state - states == S_PTERABYTE_SWOOPDOWN) + { + P_SetMobjState(mobj, S_PTERABYTE_SWOOPUP); + mobj->reactiontime = mobj->movecount; + } + else if (mobj->state - states == S_PTERABYTE_SWOOPUP) + { + P_SetMobjState(mobj, S_PTERABYTE_FLY1); + mobj->extravalue1++; + if (mobj->target && mobj->target->tracer != mobj) + P_SetTarget(&mobj->target, NULL); // Failed to grab the target + mobj->momx = mobj->momy = mobj->momz = 0; + } + } + else // Returning + { + var1 = 2*mobj->info->speed; + var2 = 1; + A_HomingChase(mobj); + if (P_AproxDistance(mobj->x - mobj->tracer->x, mobj->y - mobj->tracer->y) <= mobj->info->speed) + { + mobj->extravalue1 -= 2; + mobj->momx = mobj->momy = mobj->momz = 0; + } + } +} + +static void P_DragonbomberThink(mobj_t *mobj) +{ +#define DRAGONTURNSPEED ANG2 + mobj->movecount = (mobj->movecount + 9) % 360; + P_SetObjectMomZ(mobj, 4*FINESINE(((mobj->movecount*ANG1) >> ANGLETOFINESHIFT) & FINEMASK), false); + if (mobj->threshold > 0) // are we dropping mines? + { + mobj->threshold--; + if (mobj->threshold == 0) // if the timer hits 0, look for a mine to drop! + { + mobj_t *segment = mobj; + while (segment->tracer != NULL && !P_MobjWasRemoved(segment->tracer) && segment->tracer->state == &states[segment->tracer->info->spawnstate]) + segment = segment->tracer; + if (segment != mobj) // found an unactivated segment? + { + mobj_t *mine = P_SpawnMobjFromMobj(segment, 0, 0, 0, segment->info->painchance); + mine->angle = segment->angle; + P_InstaThrust(mine, mobj->angle, P_AproxDistance(mobj->momx, mobj->momy) >> 1); + P_SetObjectMomZ(mine, -2*FRACUNIT, true); + S_StartSound(mine, mine->info->seesound); + P_SetMobjState(segment, segment->info->raisestate); + mobj->threshold = mobj->info->painchance; + } + } + } + if (mobj->target) // Are we chasing a player? + { + fixed_t dist = P_AproxDistance(mobj->x - mobj->target->x, mobj->y - mobj->target->y); + if (dist > 2000*mobj->scale) // Not anymore! + P_SetTarget(&mobj->target, NULL); + else + { + fixed_t vspeed = FixedMul(mobj->info->speed >> 3, mobj->scale); + fixed_t z = mobj->target->z + (mobj->height >> 1) + (mobj->flags & MFE_VERTICALFLIP ? -128*mobj->scale : 128*mobj->scale + mobj->target->height); + angle_t diff = R_PointToAngle2(mobj->x, mobj->y, mobj->target->x, mobj->target->y) - mobj->angle; + if (diff > ANGLE_180) + mobj->angle -= DRAGONTURNSPEED; + else + mobj->angle += DRAGONTURNSPEED; + if (!mobj->threshold && dist < 512*mobj->scale) // Close enough to drop bombs + { + mobj->threshold = mobj->info->painchance; + } + mobj->momz += max(min(z - mobj->z, vspeed), -vspeed); + } + } + else // Can we find a player to chase? + { + if (mobj->tracer == NULL || mobj->tracer->state != &states[mobj->tracer->info->spawnstate] + || !P_LookForPlayers(mobj, true, false, 2000*mobj->scale)) // if not, circle around the spawnpoint + { + if (!mobj->spawnpoint) // unless we don't have one, in which case uhhh just circle around wherever we currently are I guess?? + mobj->angle += DRAGONTURNSPEED; + else + { + fixed_t vspeed = FixedMul(mobj->info->speed >> 3, mobj->scale); + fixed_t x = mobj->spawnpoint->x << FRACBITS; + fixed_t y = mobj->spawnpoint->y << FRACBITS; + fixed_t z = mobj->spawnpoint->z << FRACBITS; + angle_t diff = R_PointToAngle2(mobj->x, mobj->y, x, y) - mobj->angle; + if (diff > ANGLE_180) + mobj->angle -= DRAGONTURNSPEED; + else + mobj->angle += DRAGONTURNSPEED; + mobj->momz += max(min(z - mobj->z, vspeed), -vspeed); + } + } + } + P_InstaThrust(mobj, mobj->angle, FixedMul(mobj->info->speed, mobj->scale)); +#undef DRAGONTURNSPEED +} + +static boolean P_MobjRegularThink(mobj_t *mobj) +{ + if ((mobj->flags & MF_ENEMY) && (mobj->state->nextstate == mobj->info->spawnstate && mobj->tics == 1)) + mobj->flags2 &= ~MF2_FRET; + + if (mobj->eflags & MFE_TRACERANGLE) + P_TracerAngleThink(mobj); + + switch (mobj->type) + { + case MT_WALLSPIKEBASE: + if (!mobj->target) { + P_RemoveMobj(mobj); + return false; + } + mobj->frame = (mobj->frame & ~FF_FRAMEMASK)|(mobj->target->frame & FF_FRAMEMASK); +#if 0 + if (mobj->angle != mobj->target->angle + ANGLE_90) // reposition if not the correct angle + { + mobj_t* target = mobj->target; // shortcut + const fixed_t baseradius = target->radius - (target->scale/2); //FixedMul(FRACUNIT/2, target->scale); + P_UnsetThingPosition(mobj); + mobj->x = target->x - P_ReturnThrustX(target, target->angle, baseradius); + mobj->y = target->y - P_ReturnThrustY(target, target->angle, baseradius); + P_SetThingPosition(mobj); + mobj->angle = target->angle + ANGLE_90; + } +#endif + break; + case MT_FALLINGROCK: + // Despawn rocks here in case zmovement code can't do so (blame slopes) + if (!mobj->momx && !mobj->momy && !mobj->momz + && ((mobj->eflags & MFE_VERTICALFLIP) ? + mobj->z + mobj->height >= mobj->ceilingz + : mobj->z <= mobj->floorz)) + { + P_RemoveMobj(mobj); + return false; + } + P_MobjCheckWater(mobj); + break; + case MT_ARROW: + P_ArrowThink(mobj); + break; + case MT_EMERALDSPAWN: + if (mobj->threshold) + { + mobj->threshold--; + + if (!mobj->threshold && !mobj->target && mobj->reactiontime) + { + mobj_t *emerald = P_SpawnMobj(mobj->x, mobj->y, mobj->z, mobj->reactiontime); + emerald->threshold = 42; + P_SetTarget(&mobj->target, emerald); + P_SetTarget(&emerald->target, mobj); + } + } + break; + case MT_BUGGLE: + mobj->eflags |= MFE_UNDERWATER; //P_MobjCheckWater(mobj); // solely for MFE_UNDERWATER for A_FlickySpawn + { + if (mobj->tracer && mobj->tracer->player && mobj->tracer->health > 0 + && P_AproxDistance(P_AproxDistance(mobj->tracer->x - mobj->x, mobj->tracer->y - mobj->y), mobj->tracer->z - mobj->z) <= mobj->radius*16) + { + // Home in on the target. + P_HomingAttack(mobj, mobj->tracer); + + if (mobj->z < mobj->floorz) + mobj->z = mobj->floorz; + + if (leveltime % mobj->info->painchance == 0) + S_StartSound(mobj, mobj->info->activesound); + + if ((statenum_t)(mobj->state - states) != mobj->info->seestate) + P_SetMobjState(mobj, mobj->info->seestate); + } + else + { + // Try to find a player + P_LookForPlayers(mobj, true, true, mobj->radius*16); + mobj->momx >>= 1; + mobj->momy >>= 1; + mobj->momz >>= 1; + if ((statenum_t)(mobj->state - states) != mobj->info->spawnstate) + P_SetMobjState(mobj, mobj->info->spawnstate); + } + } + break; + case MT_BUMBLEBORE: + P_BumbleboreThink(mobj); + break; + case MT_BIGMINE: + mobj->extravalue1 += 3; + mobj->extravalue1 %= 360; + P_UnsetThingPosition(mobj); + mobj->z += FINESINE(mobj->extravalue1*(FINEMASK + 1)/360); + P_SetThingPosition(mobj); + break; + case MT_FLAME: + if (mobj->flags2 & MF2_BOSSNOTRAP) + { + if (!mobj->target || P_MobjWasRemoved(mobj->target)) + { + if (mobj->tracer && !P_MobjWasRemoved(mobj->tracer)) + P_RemoveMobj(mobj->tracer); + P_RemoveMobj(mobj); + return false; + } + mobj->z = mobj->target->z + mobj->target->momz; + if (!(mobj->eflags & MFE_VERTICALFLIP)) + mobj->z += mobj->target->height; + } + if (mobj->tracer && !P_MobjWasRemoved(mobj->tracer)) + { + mobj->tracer->z = mobj->z + P_MobjFlip(mobj)*20*mobj->scale; + if (mobj->eflags & MFE_VERTICALFLIP) + mobj->tracer->z += mobj->height; + } + break; + case MT_WAVINGFLAG1: + case MT_WAVINGFLAG2: + { + fixed_t base = (leveltime << (FRACBITS + 1)); + mobj_t *seg = mobj->tracer, *prev = mobj; + mobj->movedir = mobj->angle + + ((((FINESINE((FixedAngle(base << 1) >> ANGLETOFINESHIFT) & FINEMASK) + + FINESINE((FixedAngle(base << 4) >> ANGLETOFINESHIFT) & FINEMASK)) >> 1) + + FINESINE((FixedAngle(base*9) >> ANGLETOFINESHIFT) & FINEMASK) + + FINECOSINE(((FixedAngle(base*9)) >> ANGLETOFINESHIFT) & FINEMASK)) << 12); //*2^12 + while (seg) + { + seg->movedir = seg->angle; + seg->angle = prev->movedir; + P_UnsetThingPosition(seg); + seg->x = prev->x + P_ReturnThrustX(prev, prev->angle, prev->radius); + seg->y = prev->y + P_ReturnThrustY(prev, prev->angle, prev->radius); + seg->z = prev->z + prev->height - (seg->scale >> 1); + P_SetThingPosition(seg); + prev = seg; + seg = seg->tracer; + } + } + break; + case MT_SPINCUSHION: + if (mobj->target && mobj->state - states >= S_SPINCUSHION_AIM1 && mobj->state - states <= S_SPINCUSHION_AIM5) + mobj->angle = R_PointToAngle2(mobj->x, mobj->y, mobj->target->x, mobj->target->y); + break; + case MT_CRUSHCLAW: + if (mobj->state - states == S_CRUSHCLAW_STAY && mobj->target) + { + mobj_t *chain = mobj->target->target; + SINT8 sign = ((mobj->tics & 1) ? mobj->tics : -(SINT8)(mobj->tics)); + while (chain) + { + chain->z = chain->watertop + sign*mobj->scale; + sign = -sign; + chain = chain->target; + } + } + break; + case MT_SMASHINGSPIKEBALL: + mobj->momx = mobj->momy = 0; + if (mobj->state - states == S_SMASHSPIKE_FALL && P_IsObjectOnGround(mobj)) + { + P_SetMobjState(mobj, S_SMASHSPIKE_STOMP1); + S_StartSound(mobj, sfx_spsmsh); + } + else if (mobj->state - states == S_SMASHSPIKE_RISE2 && P_MobjFlip(mobj)*(mobj->z - mobj->movecount) >= 0) + { + mobj->momz = 0; + P_SetMobjState(mobj, S_SMASHSPIKE_FLOAT); + } + break; + case MT_HANGSTER: + if (!P_HangsterThink(mobj)) + return false; + break; + case MT_LHRT: + mobj->momx = FixedMul(mobj->momx, mobj->extravalue2); + mobj->momy = FixedMul(mobj->momy, mobj->extravalue2); + break; + case MT_EGGCAPSULE: + if (!mobj->reactiontime) + { + // Target nearest player on your mare. + // (You can make it float up/down by adding MF_FLOAT, + // but beware level design pitfalls.) + fixed_t shortest = 1024*FRACUNIT; + INT32 i; + P_SetTarget(&mobj->target, NULL); + for (i = 0; i < MAXPLAYERS; i++) + if (playeringame[i] && players[i].mo + && players[i].mare == mobj->threshold && players[i].spheres > 0) + { + fixed_t dist = P_AproxDistance(players[i].mo->x - mobj->x, players[i].mo->y - mobj->y); + if (dist < shortest) + { + P_SetTarget(&mobj->target, players[i].mo); + shortest = dist; + } + } + } + break; + case MT_EGGMOBILE2_POGO: + if (!mobj->target + || !mobj->target->health + || mobj->target->state == &states[mobj->target->info->spawnstate] + || mobj->target->state == &states[mobj->target->info->raisestate]) + { + P_RemoveMobj(mobj); + return false; + } + P_TeleportMove(mobj, mobj->target->x, mobj->target->y, mobj->target->z - mobj->height); + break; + case MT_HAMMER: + if (mobj->z <= mobj->floorz) + { + P_RemoveMobj(mobj); + return false; + } + break; + case MT_KOOPA: + P_KoopaThinker(mobj); + break; + case MT_FIREBALL: + if (P_AproxDistance(mobj->momx, mobj->momy) <= 16*FRACUNIT) // Once fireballs lose enough speed, kill them + { + P_KillMobj(mobj, NULL, NULL, 0); + return false; + } + break; + case MT_REDRING: + if (((mobj->z < mobj->floorz) || (mobj->z + mobj->height > mobj->ceilingz)) + && mobj->flags & MF_MISSILE) + { + P_ExplodeMissile(mobj); + return false; + } + break; + case MT_BOSSFLYPOINT: + return false; + case MT_NIGHTSCORE: + mobj->color = (UINT8)(leveltime % SKINCOLOR_WHITE); + break; + case MT_JETFUME1: + if (!P_JetFume1Think(mobj)) + return false; + break; + case MT_JETFLAME: + { + if (!mobj->target // if you have no target + || (!(mobj->target->flags & MF_BOSS) && mobj->target->health <= 0)) // or your target isn't a boss and it's popped now + { // then remove yourself as well! + P_RemoveMobj(mobj); + return false; + } + + P_UnsetThingPosition(mobj); + mobj->x = mobj->target->x; + mobj->y = mobj->target->y; + mobj->z = mobj->target->z - 50*mobj->target->scale; + mobj->floorz = mobj->z; + mobj->ceilingz = mobj->z + mobj->height; + P_SetThingPosition(mobj); + } + break; + case MT_EGGROBO1: + if (!P_EggRobo1Think(mobj)) + return false; + break; + case MT_EGGROBO1JET: + { + if (!mobj->target || P_MobjWasRemoved(mobj->target) // if you have no target + || (mobj->target->health <= 0)) // or your target isn't a boss and it's popped now + { // then remove yourself as well! + P_RemoveMobj(mobj); + return false; + } + + mobj->flags2 ^= MF2_DONTDRAW; + + P_UnsetThingPosition(mobj); + mobj->x = mobj->target->x + P_ReturnThrustX(mobj, mobj->target->angle + ANGLE_90, mobj->movefactor*mobj->target->scale) - P_ReturnThrustX(mobj, mobj->target->angle, 19*mobj->target->scale); + mobj->y = mobj->target->y + P_ReturnThrustY(mobj, mobj->target->angle + ANGLE_90, mobj->movefactor*mobj->target->scale) - P_ReturnThrustY(mobj, mobj->target->angle, 19*mobj->target->scale); + mobj->z = mobj->target->z; + if (mobj->target->eflags & MFE_VERTICALFLIP) + mobj->z += (mobj->target->height - mobj->height); + mobj->floorz = mobj->z; + mobj->ceilingz = mobj->z + mobj->height; + P_SetThingPosition(mobj); + } + break; + case MT_NIGHTSDRONE: + P_NiGHTSDroneThink(mobj); + break; + case MT_PLAYER: + if (mobj->player) + P_PlayerMobjThinker(mobj); + return false; + case MT_SKIM: + // check mobj against possible water content, before movement code + P_MobjCheckWater(mobj); + + // Keep Skim at water surface + if (mobj->z <= mobj->watertop) + { + mobj->flags |= MF_NOGRAVITY; + if (mobj->z < mobj->watertop) + { + if (mobj->watertop - mobj->z <= FixedMul(mobj->info->speed*FRACUNIT, mobj->scale)) + mobj->z = mobj->watertop; + else + mobj->momz = FixedMul(mobj->info->speed*FRACUNIT, mobj->scale); + } + } + else + { + mobj->flags &= ~MF_NOGRAVITY; + if (mobj->z > mobj->watertop && mobj->z - mobj->watertop < FixedMul(MAXSTEPMOVE, mobj->scale)) + mobj->z = mobj->watertop; + } + break; + case MT_RING: + case MT_REDTEAMRING: + case MT_BLUETEAMRING: + P_KillRingsInLava(mobj); + if (P_MobjWasRemoved(mobj)) + return false; + /* FALLTHRU */ + case MT_COIN: + case MT_BLUESPHERE: + case MT_BOMBSPHERE: + case MT_NIGHTSCHIP: + case MT_NIGHTSSTAR: + // No need to check water. Who cares? + P_RingThinker(mobj); + if (mobj->flags2 & MF2_NIGHTSPULL) + P_NightsItemChase(mobj); + else + A_AttractChase(mobj); + return false; + // Flung items + case MT_FLINGRING: + P_KillRingsInLava(mobj); + if (P_MobjWasRemoved(mobj)) + return false; + /* FALLTHRU */ + case MT_FLINGCOIN: + case MT_FLINGBLUESPHERE: + case MT_FLINGNIGHTSCHIP: + if (mobj->flags2 & MF2_NIGHTSPULL) + P_NightsItemChase(mobj); + else + A_AttractChase(mobj); + break; + case MT_EMBLEM: + if (mobj->flags2 & MF2_NIGHTSPULL) + P_NightsItemChase(mobj); + break; + case MT_SHELL: + if (mobj->threshold && mobj->threshold != TICRATE) + mobj->threshold--; + + if (mobj->threshold >= TICRATE) + { + mobj->angle += ((mobj->movedir == 1) ? ANGLE_22h : ANGLE_337h); + P_InstaThrust(mobj, R_PointToAngle2(0, 0, mobj->momx, mobj->momy), (mobj->info->speed*mobj->scale)); + } + break; + case MT_TURRET: + if (!P_TurretThink(mobj)) + return false; + break; + case MT_BLUEFLAG: + case MT_REDFLAG: + { + sector_t* sec2; + sec2 = P_ThingOnSpecial3DFloor(mobj); + if ((sec2 && GETSECSPECIAL(sec2->special, 4) == 2) || (GETSECSPECIAL(mobj->subsector->sector->special, 4) == 2)) + mobj->fuse = 1; // Return to base. + break; + } + case MT_CANNONBALL: +#ifdef FLOORSPLATS + R_AddFloorSplat(mobj->tracer->subsector, mobj->tracer, "TARGET", mobj->tracer->x, + mobj->tracer->y, mobj->tracer->floorz, SPLATDRAWMODE_SHADE); +#endif + break; + case MT_SPINDUST: // Spindash dust + mobj->momx = FixedMul(mobj->momx, (3*FRACUNIT)/4); // originally 50000 + mobj->momy = FixedMul(mobj->momy, (3*FRACUNIT)/4); // same + //mobj->momz = mobj->momz+P_MobjFlip(mobj)/3; // no meaningful change in value to be frank + if (mobj->state >= &states[S_SPINDUST_BUBBLE1] && mobj->state <= &states[S_SPINDUST_BUBBLE4]) // bubble dust! + { + P_MobjCheckWater(mobj); + if (mobj->watertop != mobj->subsector->sector->floorheight - 1000*FRACUNIT + && mobj->z + mobj->height >= mobj->watertop - 5*FRACUNIT) + mobj->flags2 |= MF2_DONTDRAW; + } + break; + case MT_TRAINDUSTSPAWNER: + if (leveltime % 5 == 0) { + mobj_t* traindust = P_SpawnMobj(mobj->x, mobj->y, mobj->z, MT_PARTICLE); + traindust->flags = MF_SCENERY; + P_SetMobjState(traindust, S_TRAINDUST); + traindust->frame = P_RandomRange(0, 8)|FF_TRANS90; + traindust->angle = mobj->angle; + traindust->tics = TICRATE*4; + traindust->destscale = FRACUNIT*64; + traindust->scalespeed = FRACUNIT/24; + P_SetScale(traindust, FRACUNIT*6); + } + break; + case MT_TRAINSTEAMSPAWNER: + if (leveltime % 5 == 0) { + mobj_t *steam = P_SpawnMobj(mobj->x + FRACUNIT*P_SignedRandom()/2, mobj->y + FRACUNIT*P_SignedRandom()/2, mobj->z, MT_PARTICLE); + P_SetMobjState(steam, S_TRAINSTEAM); + steam->frame = P_RandomRange(0, 1)|FF_TRANS90; + steam->tics = TICRATE*8; + steam->destscale = FRACUNIT*64; + steam->scalespeed = FRACUNIT/8; + P_SetScale(steam, FRACUNIT*16); + steam->momx = P_SignedRandom()*32; + steam->momy = -64*FRACUNIT; + steam->momz = 2*FRACUNIT; + } + break; + case MT_CANARIVORE_GAS: + { + fixed_t momz; + + if (mobj->flags2 & MF2_AMBUSH) + { + mobj->momx = FixedMul(mobj->momx, 50*FRACUNIT/51); + mobj->momy = FixedMul(mobj->momy, 50*FRACUNIT/51); + break; + } + + if (mobj->eflags & MFE_VERTICALFLIP) + { + if ((mobj->z + mobj->height + mobj->momz) <= mobj->ceilingz) + break; + } + else + { + if ((mobj->z + mobj->momz) >= mobj->floorz) + break; + } + + momz = abs(mobj->momz); + if (R_PointToDist2(0, 0, mobj->momx, mobj->momy) < momz) + P_InstaThrust(mobj, R_PointToAngle2(0, 0, mobj->momx, mobj->momy), momz); + mobj->flags2 |= MF2_AMBUSH; + break; + } + case MT_SALOONDOOR: + P_SaloonDoorThink(mobj); + break; + case MT_MINECARTSPAWNER: + P_HandleMinecartSegments(mobj); + if (!mobj->fuse || mobj->fuse > TICRATE) + break; + if (mobj->fuse == 2) + { + mobj->fuse = 0; + break; + } + mobj->flags2 ^= MF2_DONTDRAW; + break; + case MT_LAVAFALLROCK: + if (P_IsObjectOnGround(mobj)) + P_RemoveMobj(mobj); + break; + case MT_PYREFLY: + P_PyreFlyThink(mobj); + break; + case MT_PTERABYTE: + P_PterabyteThink(mobj); + break; + case MT_DRAGONBOMBER: + P_DragonbomberThink(mobj); + break; + case MT_MINUS: +#ifdef ROTSPRITE + { + if (P_IsObjectOnGround(mobj)) + mobj->rollangle = 0; + else + mobj->rollangle = R_PointToAngle2(0, 0, mobj->momz, (mobj->scale << 1) - min(abs(mobj->momz), mobj->scale << 1)); + } +#endif + break; + case MT_SPINFIRE: + if (mobj->flags & MF_NOGRAVITY) + { + if (mobj->eflags & MFE_VERTICALFLIP) + mobj->z = mobj->ceilingz - mobj->height; + else + mobj->z = mobj->floorz; + } + else if ((!(mobj->eflags & MFE_VERTICALFLIP) && mobj->z <= mobj->floorz) + || ((mobj->eflags & MFE_VERTICALFLIP) && mobj->z + mobj->height >= mobj->ceilingz)) + { + mobj->flags |= MF_NOGRAVITY; + mobj->momx = 8; // this is a hack which is used to ensure it still behaves as a missile and can damage others + mobj->momy = mobj->momz = 0; + mobj->z = ((mobj->eflags & MFE_VERTICALFLIP) ? mobj->ceilingz - mobj->height : mobj->floorz); + } + /* FALLTHRU */ + default: + // check mobj against possible water content, before movement code + P_MobjCheckWater(mobj); + + // Extinguish fire objects in water + if (mobj->flags & MF_FIRE && mobj->type != MT_PUMA && mobj->type != MT_FIREBALL + && (mobj->eflags & (MFE_UNDERWATER|MFE_TOUCHWATER))) + { + P_KillMobj(mobj, NULL, NULL, 0); + return false; + } + break; + } + return true; +} + // // P_MobjThinker // @@ -8101,1722 +9886,23 @@ void P_MobjThinker(mobj_t *mobj) // separate thinker if (mobj->flags & MF_PUSHABLE || (mobj->info->flags & MF_PUSHABLE && mobj->fuse)) { - P_MobjCheckWater(mobj); - P_PushableThinker(mobj); - - // Extinguish fire objects in water. (Yes, it's extraordinarily rare to have a pushable flame object, but Brak uses such a case.) - if (mobj->flags & MF_FIRE && mobj->type != MT_PUMA && mobj->type != MT_FIREBALL - && (mobj->eflags & (MFE_UNDERWATER|MFE_TOUCHWATER))) - { - P_KillMobj(mobj, NULL, NULL, 0); + if (!P_MobjPushableThink(mobj)) return; - } } else if (mobj->flags & MF_BOSS) { -#ifdef HAVE_BLUA - if (LUAh_BossThinker(mobj)) - { - if (P_MobjWasRemoved(mobj)) - return; - } - else if (P_MobjWasRemoved(mobj)) + if (!P_MobjBossThink(mobj)) return; - else -#endif - switch (mobj->type) - { - case MT_EGGMOBILE: - if (mobj->health < mobj->info->damage+1 && leveltime & 2) - { - fixed_t rad = mobj->radius>>FRACBITS; - fixed_t hei = mobj->height>>FRACBITS; - mobj_t *particle = P_SpawnMobjFromMobj(mobj, - P_RandomRange(rad, -rad)<momz += mobj->momz; - } - if (mobj->flags2 & MF2_SKULLFLY) -#if 1 - P_SpawnGhostMobj(mobj); -#else // all the way back from final demo... MT_THOK isn't even the same size anymore! - { - mobj_t *spawnmobj; - spawnmobj = P_SpawnMobj(mobj->x, mobj->y, mobj->z, mobj->info->painchance); - P_SetTarget(&spawnmobj->target, mobj); - spawnmobj->color = SKINCOLOR_GREY; - } -#endif - P_Boss1Thinker(mobj); - break; - case MT_EGGMOBILE2: - if (mobj->health < mobj->info->damage+1 && leveltime & 2) - { - fixed_t rad = mobj->radius>>FRACBITS; - fixed_t hei = mobj->height>>FRACBITS; - mobj_t *particle = P_SpawnMobjFromMobj(mobj, - P_RandomRange(rad, -rad)<momz += mobj->momz; - } - P_Boss2Thinker(mobj); - break; - case MT_EGGMOBILE3: - if (mobj->health < mobj->info->damage+1 && leveltime & 2) - { - fixed_t rad = mobj->radius>>FRACBITS; - fixed_t hei = mobj->height>>FRACBITS; - mobj_t *particle = P_SpawnMobjFromMobj(mobj, - P_RandomRange(rad, -rad)<momz += mobj->momz; - } - P_Boss3Thinker(mobj); - break; - case MT_EGGMOBILE4: - if (mobj->health < mobj->info->damage+1 && leveltime & 2) - { - fixed_t rad = mobj->radius>>FRACBITS; - fixed_t hei = mobj->height>>FRACBITS; - mobj_t *particle = P_SpawnMobjFromMobj(mobj, - P_RandomRange(rad, -rad)<momz += mobj->momz; - } - P_Boss4Thinker(mobj); - break; - case MT_FANG: - P_Boss5Thinker(mobj); - break; - case MT_BLACKEGGMAN: - P_Boss7Thinker(mobj); - break; - case MT_METALSONIC_BATTLE: - P_Boss9Thinker(mobj); - break; - default: // Generic SOC-made boss - if (mobj->flags2 & MF2_SKULLFLY) - P_SpawnGhostMobj(mobj); - P_GenericBossThinker(mobj); - break; - } - if (mobj->flags2 & MF2_BOSSFLEE) - { - if (mobj->extravalue1) - { - if (!(--mobj->extravalue1)) - { - if (mobj->target) - { - mobj->momz = FixedMul(FixedDiv(mobj->target->z - mobj->z, P_AproxDistance(mobj->x-mobj->target->x,mobj->y-mobj->target->y)), mobj->scale<<1); - mobj->angle = R_PointToAngle2(mobj->x, mobj->y, mobj->target->x, mobj->target->y); - } - else - mobj->momz = 8*mobj->scale; - } - else - mobj->angle += mobj->movedir; - } - else if (mobj->target) - P_InstaThrust(mobj, mobj->angle, FixedMul(12*FRACUNIT, mobj->scale)); - } - if (mobj->type == MT_CYBRAKDEMON && !mobj->health) - { - if (!(mobj->tics & 1)) - { - var1 = 2; - var2 = 0; - A_BossScream(mobj); - } - if (P_CheckDeathPitCollide(mobj)) - { - P_RemoveMobj(mobj); - return; - } - if (mobj->momz && mobj->z+mobj->momz <= mobj->floorz) - { - S_StartSound(mobj, sfx_befall); - if (mobj->state != states+S_CYBRAKDEMON_DIE8) - P_SetMobjState(mobj, S_CYBRAKDEMON_DIE8); - } - } } else if (mobj->health <= 0) // Dead things think differently than the living. - switch (mobj->type) - { - case MT_BLUESPHERE: - if ((mobj->tics>>2)+1 > 0 && (mobj->tics>>2)+1 <= tr_trans60) // tr_trans50 through tr_trans90, shifting once every second frame - mobj->frame = (NUMTRANSMAPS-((mobj->tics>>2)+1))<frame = tr_trans60<z <= mobj->floorz) - { - P_RemoveMobj(mobj); - return; - } - break; - case MT_FAKEMOBILE: - if (mobj->scale == mobj->destscale) - { - if (!mobj->fuse) - { - S_StartSound(mobj, sfx_s3k77); - mobj->flags2 |= MF2_DONTDRAW; - mobj->fuse = TICRATE; - } - return; - } - if (!mobj->reactiontime) - { - if (P_RandomChance(FRACUNIT/2)) - mobj->movefactor = FRACUNIT; - else - mobj->movefactor = -FRACUNIT; - if (P_RandomChance(FRACUNIT/2)) - mobj->movedir = ANG20; - else - mobj->movedir = -ANG20; - mobj->reactiontime = 5; - } - mobj->momz += mobj->movefactor; - mobj->angle += mobj->movedir; - P_InstaThrust(mobj, mobj->angle, -mobj->info->speed); - mobj->reactiontime--; - break; - case MT_EGGSHIELD: - mobj->flags2 ^= MF2_DONTDRAW; - break; - case MT_EGGTRAP: // Egg Capsule animal release - if (mobj->fuse > 0)// && mobj->fuse < TICRATE-(TICRATE/7)) - { - INT32 i; - fixed_t x,y,z; - fixed_t ns; - mobj_t *mo2; - mobj_t *flicky; - - z = mobj->subsector->sector->floorheight + FRACUNIT + (P_RandomKey(64)<x + FixedMul(FINESINE(fa),ns); - y = mobj->y + FixedMul(FINECOSINE(fa),ns); - - mo2 = P_SpawnMobj(x, y, z, MT_EXPLODE); - P_SetMobjStateNF(mo2, S_XPLD_EGGTRAP); // so the flickies don't lose their target if they spawn - ns = 4 * FRACUNIT; - mo2->momx = FixedMul(FINESINE(fa),ns); - mo2->momy = FixedMul(FINECOSINE(fa),ns); - mo2->angle = fa << ANGLETOFINESHIFT; - - if (!i && !(mobj->fuse & 2)) - S_StartSound(mo2, mobj->info->deathsound); - - flicky = P_InternalFlickySpawn(mo2, 0, 8*FRACUNIT, false, -1); - if (!flicky) - break; - - P_SetTarget(&flicky->target, mo2); - flicky->momx = mo2->momx; - flicky->momy = mo2->momy; - } - - mobj->fuse--; - } - break; - case MT_PLAYER: - /// \todo Have the player's dead body completely finish its animation even if they've already respawned. - if (!mobj->fuse) - { // Go away. - /// \todo Actually go ahead and remove mobj completely, and fix any bugs and crashes doing this creates. Chasecam should stop moving, and F12 should never return to it. - mobj->momz = 0; - if (mobj->player) - mobj->flags2 |= MF2_DONTDRAW; - else // safe to remove, nobody's going to complain! - { - P_RemoveMobj(mobj); - return; - } - } - else // Apply gravity to fall downwards. - { - if (mobj->player && !(mobj->fuse % 8) && (mobj->player->charflags & SF_MACHINE)) - { - fixed_t r = mobj->radius >> FRACBITS; - mobj_t *explosion = P_SpawnMobj( - mobj->x + (P_RandomRange(r, -r) << FRACBITS), - mobj->y + (P_RandomRange(r, -r) << FRACBITS), - mobj->z + (P_RandomKey(mobj->height >> FRACBITS) << FRACBITS), - MT_SONIC3KBOSSEXPLODE); - S_StartSound(explosion, sfx_s3kb4); - } - if (mobj->movedir == DMG_DROWNED) - P_SetObjectMomZ(mobj, -FRACUNIT / 2, true); // slower fall from drowning - else - P_SetObjectMomZ(mobj, -2 * FRACUNIT / 3, true); - } - break; - case MT_METALSONIC_RACE: - { - if (!(mobj->fuse % 8)) - { - fixed_t r = mobj->radius >> FRACBITS; - mobj_t *explosion = P_SpawnMobj( - mobj->x + (P_RandomRange(r, -r) << FRACBITS), - mobj->y + (P_RandomRange(r, -r) << FRACBITS), - mobj->z + (P_RandomKey(mobj->height >> FRACBITS) << FRACBITS), - MT_SONIC3KBOSSEXPLODE); - S_StartSound(explosion, sfx_s3kb4); - } - P_SetObjectMomZ(mobj, -2 * FRACUNIT / 3, true); - } - default: - break; - } + { + if (!P_MobjDeadThink(mobj)) + return; + } else { - if ((mobj->flags & MF_ENEMY) && (mobj->state->nextstate == mobj->info->spawnstate && mobj->tics == 1)) - mobj->flags2 &= ~MF2_FRET; - - // Angle-to-tracer to trigger a linedef exec - // See Linedef Exec 457 (Track mobj angle to point) - if ((mobj->eflags & MFE_TRACERANGLE) && mobj->tracer && mobj->extravalue2) - { - // mobj->lastlook - Don't disable behavior after first failure - // mobj->extravalue1 - Angle tolerance - // mobj->extravalue2 - Exec tag upon failure - // mobj->cvval - Allowable failure delay - // mobj->cvmem - Failure timer - - angle_t ang = mobj->angle - R_PointToAngle2(mobj->x, mobj->y, mobj->tracer->x, mobj->tracer->y); - - // \todo account for distance between mobj and tracer - // Because closer mobjs can be facing beyond the angle tolerance - // yet tracer is still in the camera view - - // failure state: mobj is not facing tracer - // Reasaonable defaults: ANGLE_67h, ANGLE_292h - if (ang >= (angle_t)mobj->extravalue1 && ang <= ANGLE_MAX - (angle_t)mobj->extravalue1) - { - if (mobj->cvmem) - mobj->cvmem--; - else - { - INT32 exectag = mobj->extravalue2; // remember this before we erase the values - - if (mobj->lastlook) - mobj->cvmem = mobj->cusval; // reset timer for next failure - else - { - // disable after first failure - mobj->eflags &= ~MFE_TRACERANGLE; - mobj->lastlook = mobj->extravalue1 = mobj->extravalue2 = mobj->cvmem = mobj->cusval = 0; - } - - P_LinedefExecute(exectag, mobj, NULL); - } - } - else - mobj->cvmem = mobj->cusval; // reset failure timer - } - - switch (mobj->type) - { - case MT_WALLSPIKEBASE: - if (!mobj->target) { - P_RemoveMobj(mobj); - return; - } - mobj->frame = (mobj->frame & ~FF_FRAMEMASK)|(mobj->target->frame & FF_FRAMEMASK); -#if 0 - if (mobj->angle != mobj->target->angle + ANGLE_90) // reposition if not the correct angle - { - mobj_t *target = mobj->target; // shortcut - const fixed_t baseradius = target->radius - (target->scale/2); //FixedMul(FRACUNIT/2, target->scale); - P_UnsetThingPosition(mobj); - mobj->x = target->x - P_ReturnThrustX(target, target->angle, baseradius); - mobj->y = target->y - P_ReturnThrustY(target, target->angle, baseradius); - P_SetThingPosition(mobj); - mobj->angle = target->angle + ANGLE_90; - } -#endif - break; - case MT_FALLINGROCK: - // Despawn rocks here in case zmovement code can't do so (blame slopes) - if (!mobj->momx && !mobj->momy && !mobj->momz - && ((mobj->eflags & MFE_VERTICALFLIP) ? - mobj->z + mobj->height >= mobj->ceilingz - : mobj->z <= mobj->floorz)) - { - P_RemoveMobj(mobj); - return; - } - P_MobjCheckWater(mobj); - break; - case MT_ARROW: - if (mobj->flags & MF_MISSILE) - { - // Calculate the angle of movement. - /* - momz - / | - / | - / | - 0------dist(momx,momy) - */ - - fixed_t dist = P_AproxDistance(mobj->momx, mobj->momy); - angle_t angle = R_PointToAngle2(0, 0, dist, mobj->momz); - - if (angle > ANG20 && angle <= ANGLE_180) - mobj->frame = 2; - else if (angle < ANG340 && angle > ANGLE_180) - mobj->frame = 0; - else - mobj->frame = 1; - - if (!(mobj->extravalue1) && (mobj->momz < 0)) - { - mobj->extravalue1 = 1; - S_StartSound(mobj, mobj->info->activesound); - } - if (leveltime & 1) - { - mobj_t *dust = P_SpawnMobjFromMobj(mobj, 0, 0, 0, MT_PARTICLE); - dust->tics = 18; - dust->scalespeed = 4096; - dust->destscale = FRACUNIT/32; - } - } - else - mobj->flags2 ^= MF2_DONTDRAW; - break; - case MT_EMERALDSPAWN: - if (mobj->threshold) - { - mobj->threshold--; - - if (!mobj->threshold && !mobj->target && mobj->reactiontime) - { - mobj_t *emerald = P_SpawnMobj(mobj->x, mobj->y, mobj->z, mobj->reactiontime); - emerald->threshold = 42; - P_SetTarget(&mobj->target, emerald); - P_SetTarget(&emerald->target, mobj); - } - } - break; - case MT_BUGGLE: - mobj->eflags |= MFE_UNDERWATER; //P_MobjCheckWater(mobj); // solely for MFE_UNDERWATER for A_FlickySpawn - { - if (mobj->tracer && mobj->tracer->player && mobj->tracer->health > 0 - && P_AproxDistance(P_AproxDistance(mobj->tracer->x - mobj->x, mobj->tracer->y - mobj->y), mobj->tracer->z - mobj->z) <= mobj->radius * 16) - { - // Home in on the target. - P_HomingAttack(mobj, mobj->tracer); - - if (mobj->z < mobj->floorz) - mobj->z = mobj->floorz; - - if (leveltime % mobj->info->painchance == 0) - S_StartSound(mobj, mobj->info->activesound); - - if ((statenum_t)(mobj->state-states) != mobj->info->seestate) - P_SetMobjState(mobj, mobj->info->seestate); - } - else - { - // Try to find a player - P_LookForPlayers(mobj, true, true, mobj->radius * 16); - mobj->momx >>= 1; - mobj->momy >>= 1; - mobj->momz >>= 1; - if ((statenum_t)(mobj->state-states) != mobj->info->spawnstate) - P_SetMobjState(mobj, mobj->info->spawnstate); - } - } - break; - case MT_BUMBLEBORE: - { - statenum_t st = mobj->state-states; - if (st == S_BUMBLEBORE_FLY1 || st == S_BUMBLEBORE_FLY2) - { - if (!mobj->target) - P_SetMobjState(mobj, mobj->info->spawnstate); - else if (P_MobjFlip(mobj)*((mobj->z + (mobj->height>>1)) - (mobj->target->z + (mobj->target->height>>1))) > 0 - && R_PointToDist2(mobj->x, mobj->y, mobj->target->x, mobj->target->y) <= 32*FRACUNIT) - { - mobj->momx >>= 1; - mobj->momy >>= 1; - if (++mobj->movefactor == 4) - { - S_StartSound(mobj, mobj->info->seesound); - mobj->momx = mobj->momy = mobj->momz = 0; - mobj->flags = (mobj->flags|MF_PAIN) & ~MF_NOGRAVITY; - P_SetMobjState(mobj, mobj->info->meleestate); - } - } - else - mobj->movefactor = 0; - } - else if (st == S_BUMBLEBORE_RAISE || st == S_BUMBLEBORE_FALL2) // no _FALL1 because it's an 0-tic - { - if (P_IsObjectOnGround(mobj)) - { - S_StopSound(mobj); - S_StartSound(mobj, mobj->info->attacksound); - mobj->flags = (mobj->flags|MF_NOGRAVITY) & ~MF_PAIN; - mobj->momx = mobj->momy = mobj->momz = 0; - P_SetMobjState(mobj, mobj->info->painstate); - } - else - { - mobj->angle += ANGLE_22h; - mobj->frame = mobj->state->frame + ((mobj->tics & 2)>>1); - } - } - else if (st == S_BUMBLEBORE_STUCK2 && mobj->tics < TICRATE) - mobj->frame = mobj->state->frame + ((mobj->tics & 2)>>1); - } - break; - case MT_BIGMINE: - mobj->extravalue1 += 3; - mobj->extravalue1 %= 360; - P_UnsetThingPosition(mobj); - mobj->z += FINESINE(mobj->extravalue1*(FINEMASK+1)/360); - P_SetThingPosition(mobj); - break; - case MT_FLAME: - if (mobj->flags2 & MF2_BOSSNOTRAP) - { - if (!mobj->target || P_MobjWasRemoved(mobj->target)) - { - if (mobj->tracer && !P_MobjWasRemoved(mobj->tracer)) - P_RemoveMobj(mobj->tracer); - P_RemoveMobj(mobj); - return; - } - mobj->z = mobj->target->z + mobj->target->momz; - if (!(mobj->eflags & MFE_VERTICALFLIP)) - mobj->z += mobj->target->height; - } - if (mobj->tracer && !P_MobjWasRemoved(mobj->tracer)) - { - mobj->tracer->z = mobj->z + P_MobjFlip(mobj)*20*mobj->scale; - if (mobj->eflags & MFE_VERTICALFLIP) - mobj->tracer->z += mobj->height; - } - break; - case MT_WAVINGFLAG1: - case MT_WAVINGFLAG2: - { - fixed_t base = (leveltime<<(FRACBITS+1)); - mobj_t *seg = mobj->tracer, *prev = mobj; - mobj->movedir = mobj->angle - + ((((FINESINE((FixedAngle(base<<1)>>ANGLETOFINESHIFT) & FINEMASK) - + FINESINE((FixedAngle(base<<4)>>ANGLETOFINESHIFT) & FINEMASK))>>1) - + FINESINE((FixedAngle(base*9)>>ANGLETOFINESHIFT) & FINEMASK) - + FINECOSINE(((FixedAngle(base*9))>>ANGLETOFINESHIFT) & FINEMASK))<<12); //*2^12 - while (seg) - { - seg->movedir = seg->angle; - seg->angle = prev->movedir; - P_UnsetThingPosition(seg); - seg->x = prev->x + P_ReturnThrustX(prev, prev->angle, prev->radius); - seg->y = prev->y + P_ReturnThrustY(prev, prev->angle, prev->radius); - seg->z = prev->z + prev->height - (seg->scale>>1); - P_SetThingPosition(seg); - prev = seg; - seg = seg->tracer; - } - } - break; - case MT_SPINCUSHION: - if (mobj->target && mobj->state-states >= S_SPINCUSHION_AIM1 && mobj->state-states <= S_SPINCUSHION_AIM5) - mobj->angle = R_PointToAngle2(mobj->x, mobj->y, mobj->target->x, mobj->target->y); - break; - case MT_CRUSHCLAW: - if (mobj->state-states == S_CRUSHCLAW_STAY && mobj->target) - { - mobj_t *chain = mobj->target->target; - SINT8 sign = ((mobj->tics & 1) ? mobj->tics : -(SINT8)(mobj->tics)); - while (chain) - { - chain->z = chain->watertop + sign*mobj->scale; - sign = -sign; - chain = chain->target; - } - } - break; - case MT_SMASHINGSPIKEBALL: - mobj->momx = mobj->momy = 0; - if (mobj->state-states == S_SMASHSPIKE_FALL && P_IsObjectOnGround(mobj)) - { - P_SetMobjState(mobj, S_SMASHSPIKE_STOMP1); - S_StartSound(mobj, sfx_spsmsh); - } - else if (mobj->state-states == S_SMASHSPIKE_RISE2 && P_MobjFlip(mobj)*(mobj->z - mobj->movecount) >= 0) - { - mobj->momz = 0; - P_SetMobjState(mobj, S_SMASHSPIKE_FLOAT); - } - break; - case MT_HANGSTER: - { - statenum_t st = mobj->state-states; - //ghost image trail when flying down - if (st == S_HANGSTER_SWOOP1 || st == S_HANGSTER_SWOOP2) - { - P_SpawnGhostMobj(mobj); - //curve when in line with target, otherwise curve to avoid crashing into floor - if ((mobj->z - mobj->floorz <= 80*FRACUNIT) || (mobj->target && (mobj->z - mobj->target->z <= 80*FRACUNIT))) - P_SetMobjState(mobj, (st = S_HANGSTER_ARC1)); - } - - //swoop arc movement stuff - if (st == S_HANGSTER_ARC1) - { - A_FaceTarget(mobj); - P_Thrust(mobj, mobj->angle, 1*FRACUNIT); - } - else if (st == S_HANGSTER_ARC2) - P_Thrust(mobj, mobj->angle, 2*FRACUNIT); - else if (st == S_HANGSTER_ARC3) - P_Thrust(mobj, mobj->angle, 4*FRACUNIT); - //if movement has stopped while flying (like hitting a wall), fly up immediately - else if (st == S_HANGSTER_FLY1 && !mobj->momx && !mobj->momy) - { - mobj->extravalue1 = 0; - P_SetMobjState(mobj, S_HANGSTER_ARCUP1); - } - //after swooping back up, check for ceiling - else if ((st == S_HANGSTER_RETURN1 || st == S_HANGSTER_RETURN2) && mobj->momz == 0 && mobj->ceilingz == (mobj->z + mobj->height)) - P_SetMobjState(mobj, (st = S_HANGSTER_RETURN3)); - - //should you roost on a ceiling with F_SKY1 as its flat, disappear forever - if (st == S_HANGSTER_RETURN3 && mobj->momz == 0 && mobj->ceilingz == (mobj->z + mobj->height) - && mobj->subsector->sector->ceilingpic == skyflatnum - && mobj->subsector->sector->ceilingheight == mobj->ceilingz) - { - P_RemoveMobj(mobj); - return; - } - } - break; - case MT_LHRT: - mobj->momx = FixedMul(mobj->momx, mobj->extravalue2); - mobj->momy = FixedMul(mobj->momy, mobj->extravalue2); - break; - case MT_EGGCAPSULE: - if (!mobj->reactiontime) - { - // Target nearest player on your mare. - // (You can make it float up/down by adding MF_FLOAT, - // but beware level design pitfalls.) - fixed_t shortest = 1024*FRACUNIT; - INT32 i; - P_SetTarget(&mobj->target, NULL); - for (i = 0; i < MAXPLAYERS; i++) - if (playeringame[i] && players[i].mo - && players[i].mare == mobj->threshold && players[i].spheres > 0) - { - fixed_t dist = P_AproxDistance(players[i].mo->x - mobj->x, players[i].mo->y - mobj->y); - if (dist < shortest) - { - P_SetTarget(&mobj->target, players[i].mo); - shortest = dist; - } - } - } - break; - case MT_EGGMOBILE2_POGO: - if (!mobj->target - || !mobj->target->health - || mobj->target->state == &states[mobj->target->info->spawnstate] - || mobj->target->state == &states[mobj->target->info->raisestate]) - { - P_RemoveMobj(mobj); - return; - } - P_TeleportMove(mobj, mobj->target->x, mobj->target->y, mobj->target->z - mobj->height); - break; - case MT_HAMMER: - if (mobj->z <= mobj->floorz) - { - P_RemoveMobj(mobj); - return; - } - break; - case MT_KOOPA: - P_KoopaThinker(mobj); - break; - case MT_FIREBALL: - if (P_AproxDistance(mobj->momx, mobj->momy) <= 16*FRACUNIT) // Once fireballs lose enough speed, kill them - { - P_KillMobj(mobj, NULL, NULL, 0); - return; - } - break; - case MT_REDRING: - if (((mobj->z < mobj->floorz) || (mobj->z + mobj->height > mobj->ceilingz)) - && mobj->flags & MF_MISSILE) - { - P_ExplodeMissile(mobj); - return; - } - break; - case MT_BOSSFLYPOINT: - return; - case MT_NIGHTSCORE: - mobj->color = (UINT8)(leveltime % SKINCOLOR_WHITE); - break; - case MT_JETFUME1: - { - fixed_t jetx, jety; - - if (!mobj->target // if you have no target - || (!(mobj->target->flags & MF_BOSS) && mobj->target->health <= 0)) // or your target isn't a boss and it's popped now - { // then remove yourself as well! - P_RemoveMobj(mobj); - return; - } - - jetx = mobj->target->x + P_ReturnThrustX(mobj->target, mobj->target->angle, FixedMul(-64*FRACUNIT, mobj->target->scale)); - jety = mobj->target->y + P_ReturnThrustY(mobj->target, mobj->target->angle, FixedMul(-64*FRACUNIT, mobj->target->scale)); - - if (mobj->fuse == 56) // First one - { - P_UnsetThingPosition(mobj); - mobj->x = jetx; - mobj->y = jety; - if (mobj->target->eflags & MFE_VERTICALFLIP) - mobj->z = mobj->target->z + mobj->target->height - mobj->height - FixedMul(38*FRACUNIT, mobj->target->scale); - else - mobj->z = mobj->target->z + FixedMul(38*FRACUNIT, mobj->target->scale); - mobj->floorz = mobj->z; - mobj->ceilingz = mobj->z+mobj->height; - P_SetThingPosition(mobj); - } - else if (mobj->fuse == 57) - { - P_UnsetThingPosition(mobj); - mobj->x = jetx + P_ReturnThrustX(mobj->target, mobj->target->angle-ANGLE_90, FixedMul(24*FRACUNIT, mobj->target->scale)); - mobj->y = jety + P_ReturnThrustY(mobj->target, mobj->target->angle-ANGLE_90, FixedMul(24*FRACUNIT, mobj->target->scale)); - if (mobj->target->eflags & MFE_VERTICALFLIP) - mobj->z = mobj->target->z + mobj->target->height - mobj->height - FixedMul(12*FRACUNIT, mobj->target->scale); - else - mobj->z = mobj->target->z + FixedMul(12*FRACUNIT, mobj->target->scale); - mobj->floorz = mobj->z; - mobj->ceilingz = mobj->z+mobj->height; - P_SetThingPosition(mobj); - } - else if (mobj->fuse == 58) - { - P_UnsetThingPosition(mobj); - mobj->x = jetx + P_ReturnThrustX(mobj->target, mobj->target->angle+ANGLE_90, FixedMul(24*FRACUNIT, mobj->target->scale)); - mobj->y = jety + P_ReturnThrustY(mobj->target, mobj->target->angle+ANGLE_90, FixedMul(24*FRACUNIT, mobj->target->scale)); - if (mobj->target->eflags & MFE_VERTICALFLIP) - mobj->z = mobj->target->z + mobj->target->height - mobj->height - FixedMul(12*FRACUNIT, mobj->target->scale); - else - mobj->z = mobj->target->z + FixedMul(12*FRACUNIT, mobj->target->scale); - mobj->floorz = mobj->z; - mobj->ceilingz = mobj->z+mobj->height; - P_SetThingPosition(mobj); - } - else if (mobj->fuse == 59) - { - boolean dashmod = ((mobj->target->flags & MF_PAIN) && (mobj->target->health <= mobj->target->info->damage)); - jetx = mobj->target->x + P_ReturnThrustX(mobj->target, mobj->target->angle, -mobj->target->radius); - jety = mobj->target->y + P_ReturnThrustY(mobj->target, mobj->target->angle, -mobj->target->radius); - P_UnsetThingPosition(mobj); - mobj->x = jetx; - mobj->y = jety; - mobj->destscale = mobj->target->scale; - if (!(dashmod && mobj->target->state == states+S_METALSONIC_BOUNCE)) - { - mobj->destscale = (mobj->destscale + FixedDiv(R_PointToDist2(0, 0, mobj->target->momx, mobj->target->momy), 36*mobj->target->scale))/3; - } - if (mobj->target->eflags & MFE_VERTICALFLIP) - mobj->z = mobj->target->z + mobj->target->height/2 + mobj->height/2; - else - mobj->z = mobj->target->z + mobj->target->height/2 - mobj->height/2; - mobj->floorz = mobj->z; - mobj->ceilingz = mobj->z+mobj->height; - P_SetThingPosition(mobj); - if (dashmod) - { - mobj->color = SKINCOLOR_SUNSET; - if (mobj->target->movecount == 3 && !mobj->target->reactiontime && (mobj->target->movedir == 0 || mobj->target->movedir == 2)) - P_SpawnGhostMobj(mobj); - } - else - mobj->color = SKINCOLOR_ICY; - } - mobj->fuse++; - } - break; - case MT_JETFLAME: - { - if (!mobj->target // if you have no target - || (!(mobj->target->flags & MF_BOSS) && mobj->target->health <= 0)) // or your target isn't a boss and it's popped now - { // then remove yourself as well! - P_RemoveMobj(mobj); - return; - } - - P_UnsetThingPosition(mobj); - mobj->x = mobj->target->x; - mobj->y = mobj->target->y; - mobj->z = mobj->target->z - 50*mobj->target->scale; - mobj->floorz = mobj->z; - mobj->ceilingz = mobj->z+mobj->height; - P_SetThingPosition(mobj); - } - break; - case MT_EGGROBO1: -#define SPECTATORRADIUS (96*mobj->scale) - { - if (!(mobj->flags2 & MF2_STRONGBOX)) - { - mobj->cusval = mobj->x; // eat my SOCs, p_mobj.h warning, we have lua now - mobj->cvmem = mobj->y; // ditto - mobj->movedir = mobj->angle; - mobj->threshold = P_MobjFlip(mobj)*10*mobj->scale; - if (mobj->threshold < 0) - mobj->threshold += (mobj->ceilingz - mobj->height); - else - mobj->threshold += mobj->floorz; - var1 = 4; - A_BossJetFume(mobj); - mobj->flags2 |= MF2_STRONGBOX; - } - - if (mobj->state == &states[mobj->info->deathstate]) // todo: make map actually set health to 0 for these - { - if (mobj->movecount) - { - if (!(--mobj->movecount)) - S_StartSound(mobj, mobj->info->deathsound); - } - else - { - mobj->momz += P_MobjFlip(mobj)*mobj->scale; - if (mobj->momz > 0) - { - if (mobj->z + mobj->momz > mobj->ceilingz + (1000<z + mobj->height + mobj->momz < mobj->floorz - (1000<cusval, basey = mobj->cvmem; - - if (mobj->spawnpoint && mobj->spawnpoint->options & (MTF_AMBUSH|MTF_OBJECTSPECIAL)) - { - angle_t sideang = mobj->movedir + ((mobj->spawnpoint->options & MTF_AMBUSH) ? ANGLE_90 : -ANGLE_90); - fixed_t oscillate = FixedMul(FINESINE(((leveltime*ANG1)>>(ANGLETOFINESHIFT+2)) & FINEMASK), 250*mobj->scale); - basex += P_ReturnThrustX(mobj, sideang, oscillate); - basey += P_ReturnThrustY(mobj, sideang, oscillate); - } - - mobj->z = mobj->threshold + FixedMul(FINESINE(((leveltime + mobj->movecount)*ANG2>>(ANGLETOFINESHIFT-2)) & FINEMASK), 8*mobj->scale); - if (mobj->state != &states[mobj->info->meleestate]) - { - boolean didmove = false; - - if (mobj->state == &states[mobj->info->spawnstate]) - { - UINT8 i; - fixed_t dist = INT32_MAX; - - for (i = 0; i < MAXPLAYERS; i++) - { - fixed_t compdist; - if (!playeringame[i]) - continue; - if (players[i].spectator) - continue; - if (!players[i].mo) - continue; - if (!players[i].mo->health) - continue; - if (P_PlayerInPain(&players[i])) - continue; - if (players[i].mo->z > mobj->z + mobj->height + 8*mobj->scale) - continue; - if (players[i].mo->z + players[i].mo->height < mobj->z - 8*mobj->scale) - continue; - compdist = P_AproxDistance( - players[i].mo->x + players[i].mo->momx - basex, - players[i].mo->y + players[i].mo->momy - basey); - if (compdist >= dist) - continue; - dist = compdist; - P_SetTarget(&mobj->target, players[i].mo); - } - - if (dist < (SPECTATORRADIUS<<1)) - { - didmove = true; - mobj->frame = 3 + ((leveltime & 2)>>1); - mobj->angle = R_PointToAngle2(mobj->x, mobj->y, mobj->target->x, mobj->target->y); - - if (P_AproxDistance( - mobj->x - basex, - mobj->y - basey) - < mobj->scale) - S_StartSound(mobj, mobj->info->seesound); - - P_TeleportMove(mobj, - (15*(mobj->x>>4)) + (basex>>4) + P_ReturnThrustX(mobj, mobj->angle, SPECTATORRADIUS>>4), - (15*(mobj->y>>4)) + (basey>>4) + P_ReturnThrustY(mobj, mobj->angle, SPECTATORRADIUS>>4), - mobj->z); - } - else - { - angle_t diff = (mobj->movedir - mobj->angle); - if (diff > ANGLE_180) - diff = InvAngle(InvAngle(diff)/8); - else - diff /= 8; - mobj->angle += diff; - - dist = FINECOSINE(((leveltime + mobj->movecount)*ANG2>>(ANGLETOFINESHIFT-2)) & FINEMASK); - - if (abs(dist) < FRACUNIT/2) - mobj->frame = 0; - else - mobj->frame = (dist > 0) ? 1 : 2; - } - } - - if (!didmove) - { - if (P_AproxDistance(mobj->x - basex, mobj->y - basey) < mobj->scale) - P_TeleportMove(mobj, basex, basey, mobj->z); - else - P_TeleportMove(mobj, - (15*(mobj->x>>4)) + (basex>>4), - (15*(mobj->y>>4)) + (basey>>4), - mobj->z); - } - } - } - } - break; -#undef SPECTATORRADIUS - case MT_EGGROBO1JET: - { - if (!mobj->target || P_MobjWasRemoved(mobj->target) // if you have no target - || (mobj->target->health <= 0)) // or your target isn't a boss and it's popped now - { // then remove yourself as well! - P_RemoveMobj(mobj); - return; - } - - mobj->flags2 ^= MF2_DONTDRAW; - - P_UnsetThingPosition(mobj); - mobj->x = mobj->target->x + P_ReturnThrustX(mobj, mobj->target->angle+ANGLE_90, mobj->movefactor*mobj->target->scale) - P_ReturnThrustX(mobj, mobj->target->angle, 19*mobj->target->scale); - mobj->y = mobj->target->y + P_ReturnThrustY(mobj, mobj->target->angle+ANGLE_90, mobj->movefactor*mobj->target->scale) - P_ReturnThrustY(mobj, mobj->target->angle, 19*mobj->target->scale); - mobj->z = mobj->target->z; - if (mobj->target->eflags & MFE_VERTICALFLIP) - mobj->z += (mobj->target->height - mobj->height); - mobj->floorz = mobj->z; - mobj->ceilingz = mobj->z+mobj->height; - P_SetThingPosition(mobj); - } - break; - case MT_NIGHTSDRONE: - { - // variable setup - mobj_t *goalpost = NULL; - mobj_t *sparkle = NULL; - mobj_t *droneman = NULL; - - boolean flip = mobj->flags2 & MF2_OBJECTFLIP; - boolean topaligned = (mobj->flags & MF_SLIDEME) && !(mobj->flags & MF_GRENADEBOUNCE); - boolean middlealigned = (mobj->flags & MF_GRENADEBOUNCE) && !(mobj->flags & MF_SLIDEME); - boolean bottomoffsetted = !(mobj->flags & MF_SLIDEME) && !(mobj->flags & MF_GRENADEBOUNCE); - boolean flipchanged = false; - - fixed_t dronemanoffset, goaloffset, sparkleoffset, droneboxmandiff, dronemangoaldiff; - - if (mobj->target && mobj->target->type == MT_NIGHTSDRONE_GOAL) - { - goalpost = mobj->target; - if (goalpost->target && goalpost->target->type == MT_NIGHTSDRONE_SPARKLING) - sparkle = goalpost->target; - if (goalpost->tracer && goalpost->tracer->type == MT_NIGHTSDRONE_MAN) - droneman = goalpost->tracer; - } - - if (!goalpost || !sparkle || !droneman) - break; - - // did NIGHTSDRONE position, scale, flip, or flags change? all elements need to be synced - droneboxmandiff = max(mobj->height - droneman->height, 0); - dronemangoaldiff = max(droneman->height - goalpost->height, 0); - - if (!(goalpost->flags2 & MF2_OBJECTFLIP) && (mobj->flags2 & MF2_OBJECTFLIP)) - { - goalpost->eflags |= MFE_VERTICALFLIP; - goalpost->flags2 |= MF2_OBJECTFLIP; - sparkle->eflags |= MFE_VERTICALFLIP; - sparkle->flags2 |= MF2_OBJECTFLIP; - droneman->eflags |= MFE_VERTICALFLIP; - droneman->flags2 |= MF2_OBJECTFLIP; - flipchanged = true; - } - else if ((goalpost->flags2 & MF2_OBJECTFLIP) && !(mobj->flags2 & MF2_OBJECTFLIP)) - { - goalpost->eflags &= ~MFE_VERTICALFLIP; - goalpost->flags2 &= ~MF2_OBJECTFLIP; - sparkle->eflags &= ~MFE_VERTICALFLIP; - sparkle->flags2 &= ~MF2_OBJECTFLIP; - droneman->eflags &= ~MFE_VERTICALFLIP; - droneman->flags2 &= ~MF2_OBJECTFLIP; - flipchanged = true; - } - - if (goalpost->destscale != mobj->destscale - || goalpost->movefactor != mobj->z - || goalpost->friction != mobj->height - || flipchanged - || goalpost->threshold != (INT32)(mobj->flags & (MF_SLIDEME | MF_GRENADEBOUNCE))) - { - goalpost->destscale = sparkle->destscale = droneman->destscale = mobj->destscale; - - // straight copy-pasta from P_SpawnMapThing, case MT_NIGHTSDRONE - if (!flip) - { - if (topaligned) // Align droneman to top of hitbox - { - dronemanoffset = droneboxmandiff; - goaloffset = dronemangoaldiff / 2 + dronemanoffset; - } - else if (middlealigned) // Align droneman to center of hitbox - { - dronemanoffset = droneboxmandiff / 2; - goaloffset = dronemangoaldiff / 2 + dronemanoffset; - } - else if (bottomoffsetted) - { - dronemanoffset = 24*FRACUNIT; - goaloffset = dronemangoaldiff + dronemanoffset; - } - else - { - dronemanoffset = 0; - goaloffset = dronemangoaldiff / 2 + dronemanoffset; - } - - sparkleoffset = goaloffset - FixedMul(15*FRACUNIT, mobj->scale); - } - else - { - if (topaligned) // Align droneman to top of hitbox - { - dronemanoffset = 0; - goaloffset = dronemangoaldiff / 2 + dronemanoffset; - } - else if (middlealigned) // Align droneman to center of hitbox - { - dronemanoffset = droneboxmandiff / 2; - goaloffset = dronemangoaldiff / 2 + dronemanoffset; - } - else if (bottomoffsetted) - { - dronemanoffset = droneboxmandiff - FixedMul(24*FRACUNIT, mobj->scale); - goaloffset = dronemangoaldiff + dronemanoffset; - } - else - { - dronemanoffset = droneboxmandiff; - goaloffset = dronemangoaldiff / 2 + dronemanoffset; - } - - sparkleoffset = goaloffset + FixedMul(15*FRACUNIT, mobj->scale); - } - - P_TeleportMove(goalpost, mobj->x, mobj->y, mobj->z + goaloffset); - P_TeleportMove(sparkle, mobj->x, mobj->y, mobj->z + sparkleoffset); - if (goalpost->movefactor != mobj->z || goalpost->friction != mobj->height) - { - P_TeleportMove(droneman, mobj->x, mobj->y, mobj->z + dronemanoffset); - goalpost->movefactor = mobj->z; - goalpost->friction = mobj->height; - } - goalpost->threshold = mobj->flags & (MF_SLIDEME | MF_GRENADEBOUNCE); - } - else - { - if (goalpost->x != mobj->x || goalpost->y != mobj->y) - { - P_TeleportMove(goalpost, mobj->x, mobj->y, goalpost->z); - P_TeleportMove(sparkle, mobj->x, mobj->y, sparkle->z); - } - - if (droneman->x != mobj->x || droneman->y != mobj->y) - P_TeleportMove(droneman, mobj->x, mobj->y, - droneman->z >= mobj->floorz && droneman->z <= mobj->ceilingz ? droneman->z : mobj->z); - } - - // now toggle states! - // GOAL mode? - if (sparkle->state >= &states[S_NIGHTSDRONE_SPARKLING1] && sparkle->state <= &states[S_NIGHTSDRONE_SPARKLING16]) - { - INT32 i; - boolean bonustime = false; - - for (i = 0; i < MAXPLAYERS; i++) - if (playeringame[i] && players[i].bonustime && players[i].powers[pw_carry] == CR_NIGHTSMODE) - { - bonustime = true; - break; - } - - if (!bonustime) - { - CONS_Debug(DBG_NIGHTSBASIC, "Removing goal post\n"); - if (goalpost && goalpost->state != &states[S_INVISIBLE]) - P_SetMobjState(goalpost, S_INVISIBLE); - if (sparkle && sparkle->state != &states[S_INVISIBLE]) - P_SetMobjState(sparkle, S_INVISIBLE); - } - } - // Invisible/bouncing mode. - else - { - INT32 i; - boolean bonustime = false; - fixed_t zcomp; - - // Bouncy bouncy! - if (!flip) - { - if (topaligned) - zcomp = droneboxmandiff + mobj->z; - else if (middlealigned) - zcomp = (droneboxmandiff / 2) + mobj->z; - else if (bottomoffsetted) - zcomp = mobj->z + FixedMul(24*FRACUNIT, mobj->scale); - else - zcomp = mobj->z; - } - else - { - if (topaligned) - zcomp = mobj->z; - else if (middlealigned) - zcomp = (droneboxmandiff / 2) + mobj->z; - else if (bottomoffsetted) - zcomp = mobj->z + droneboxmandiff - FixedMul(24*FRACUNIT, mobj->scale); - else - zcomp = mobj->z + droneboxmandiff; - } - - droneman->angle += ANG10; - if (!flip && droneman->z <= zcomp) - droneman->momz = FixedMul(5*FRACUNIT, droneman->scale); - else if (flip && droneman->z >= zcomp) - droneman->momz = FixedMul(-5*FRACUNIT, droneman->scale); - - // state switching logic - for (i = 0; i < MAXPLAYERS; i++) - if (playeringame[i] && players[i].bonustime && players[i].powers[pw_carry] == CR_NIGHTSMODE) - { - bonustime = true; - break; - } - - if (bonustime) - { - CONS_Debug(DBG_NIGHTSBASIC, "Adding goal post\n"); - if (!(droneman->flags2 & MF2_DONTDRAW)) - droneman->flags2 |= MF2_DONTDRAW; - if (goalpost->state == &states[S_INVISIBLE]) - P_SetMobjState(goalpost, mobjinfo[goalpost->type].meleestate); - if (sparkle->state == &states[S_INVISIBLE]) - P_SetMobjState(sparkle, mobjinfo[sparkle->type].meleestate); - } - else if (!G_IsSpecialStage(gamemap)) - { - for (i = 0; i < MAXPLAYERS; i++) - if (playeringame[i] && players[i].powers[pw_carry] != CR_NIGHTSMODE) - { - bonustime = true; // variable reuse - break; - } - - if (bonustime) - { - // show droneman if at least one player is non-nights - if (goalpost->state != &states[S_INVISIBLE]) - P_SetMobjState(goalpost, S_INVISIBLE); - if (sparkle->state != &states[S_INVISIBLE]) - P_SetMobjState(sparkle, S_INVISIBLE); - if (droneman->state != &states[mobjinfo[droneman->type].meleestate]) - P_SetMobjState(droneman, mobjinfo[droneman->type].meleestate); - if (droneman->flags2 & MF2_DONTDRAW) - droneman->flags2 &= ~MF2_DONTDRAW; - } - else - { - // else, hide it - if (!(droneman->flags2 & MF2_DONTDRAW)) - droneman->flags2 |= MF2_DONTDRAW; - } - } - } - } - break; - case MT_PLAYER: - if (mobj->player) - P_PlayerMobjThinker(mobj); - return; - case MT_SKIM: - // check mobj against possible water content, before movement code - P_MobjCheckWater(mobj); - - // Keep Skim at water surface - if (mobj->z <= mobj->watertop) - { - mobj->flags |= MF_NOGRAVITY; - if (mobj->z < mobj->watertop) - { - if (mobj->watertop - mobj->z <= FixedMul(mobj->info->speed*FRACUNIT, mobj->scale)) - mobj->z = mobj->watertop; - else - mobj->momz = FixedMul(mobj->info->speed*FRACUNIT, mobj->scale); - } - } - else - { - mobj->flags &= ~MF_NOGRAVITY; - if (mobj->z > mobj->watertop && mobj->z - mobj->watertop < FixedMul(MAXSTEPMOVE, mobj->scale)) - mobj->z = mobj->watertop; - } - break; - case MT_RING: - case MT_REDTEAMRING: - case MT_BLUETEAMRING: - P_KillRingsInLava(mobj); - if (P_MobjWasRemoved(mobj)) - return; - /* FALLTHRU */ - case MT_COIN: - case MT_BLUESPHERE: - case MT_BOMBSPHERE: - case MT_NIGHTSCHIP: - case MT_NIGHTSSTAR: - // No need to check water. Who cares? - P_RingThinker(mobj); - if (mobj->flags2 & MF2_NIGHTSPULL) - P_NightsItemChase(mobj); - else - A_AttractChase(mobj); - return; - // Flung items - case MT_FLINGRING: - P_KillRingsInLava(mobj); - if (P_MobjWasRemoved(mobj)) - return; - /* FALLTHRU */ - case MT_FLINGCOIN: - case MT_FLINGBLUESPHERE: - case MT_FLINGNIGHTSCHIP: - if (mobj->flags2 & MF2_NIGHTSPULL) - P_NightsItemChase(mobj); - else - A_AttractChase(mobj); - break; - case MT_EMBLEM: - if (mobj->flags2 & MF2_NIGHTSPULL) - P_NightsItemChase(mobj); - break; - case MT_SHELL: - if (mobj->threshold && mobj->threshold != TICRATE) - mobj->threshold--; - - if (mobj->threshold >= TICRATE) - { - mobj->angle += ((mobj->movedir == 1) ? ANGLE_22h : ANGLE_337h); - P_InstaThrust(mobj, R_PointToAngle2(0, 0, mobj->momx, mobj->momy), (mobj->info->speed*mobj->scale)); - } - break; - case MT_TURRET: - P_MobjCheckWater(mobj); - P_CheckPosition(mobj, mobj->x, mobj->y); - if (P_MobjWasRemoved(mobj)) - return; - mobj->floorz = tmfloorz; - mobj->ceilingz = tmceilingz; - mobj->floorrover = tmfloorrover; - mobj->ceilingrover = tmceilingrover; - - if ((mobj->eflags & MFE_UNDERWATER) && mobj->health > 0) - { - P_SetMobjState(mobj, mobj->info->deathstate); - mobj->health = 0; - mobj->flags2 &= ~MF2_FIRING; - } - else if (mobj->health > 0 && mobj->z + mobj->height > mobj->ceilingz) // Crushed - { - INT32 i,j; - fixed_t ns; - fixed_t x,y,z; - mobj_t *mo2; - - z = mobj->subsector->sector->floorheight + FixedMul(64*FRACUNIT, mobj->scale); - for (j = 0; j < 2; j++) - { - for (i = 0; i < 32; i++) - { - const angle_t fa = (i*FINEANGLES/16) & FINEMASK; - ns = FixedMul(64 * FRACUNIT, mobj->scale); - x = mobj->x + FixedMul(FINESINE(fa),ns); - y = mobj->y + FixedMul(FINECOSINE(fa),ns); - - mo2 = P_SpawnMobj(x, y, z, MT_EXPLODE); - ns = FixedMul(16 * FRACUNIT, mobj->scale); - mo2->momx = FixedMul(FINESINE(fa),ns); - mo2->momy = FixedMul(FINECOSINE(fa),ns); - } - z -= FixedMul(32*FRACUNIT, mobj->scale); - } - P_SetMobjState(mobj, mobj->info->deathstate); - mobj->health = 0; - mobj->flags2 &= ~MF2_FIRING; - } - break; - case MT_BLUEFLAG: - case MT_REDFLAG: - { - sector_t *sec2; - sec2 = P_ThingOnSpecial3DFloor(mobj); - if ((sec2 && GETSECSPECIAL(sec2->special, 4) == 2) || (GETSECSPECIAL(mobj->subsector->sector->special, 4) == 2)) - mobj->fuse = 1; // Return to base. - break; - } - case MT_CANNONBALL: -#ifdef FLOORSPLATS - R_AddFloorSplat(mobj->tracer->subsector, mobj->tracer, "TARGET", mobj->tracer->x, - mobj->tracer->y, mobj->tracer->floorz, SPLATDRAWMODE_SHADE); -#endif - break; - case MT_SPINDUST: // Spindash dust - mobj->momx = FixedMul(mobj->momx, (3*FRACUNIT)/4); // originally 50000 - mobj->momy = FixedMul(mobj->momy, (3*FRACUNIT)/4); // same - //mobj->momz = mobj->momz+P_MobjFlip(mobj)/3; // no meaningful change in value to be frank - if (mobj->state >= &states[S_SPINDUST_BUBBLE1] && mobj->state <= &states[S_SPINDUST_BUBBLE4]) // bubble dust! - { - P_MobjCheckWater(mobj); - if (mobj->watertop != mobj->subsector->sector->floorheight - 1000*FRACUNIT - && mobj->z+mobj->height >= mobj->watertop - 5*FRACUNIT) - mobj->flags2 |= MF2_DONTDRAW; - } - break; - case MT_TRAINDUSTSPAWNER: - if (leveltime % 5 == 0) { - mobj_t *traindust = P_SpawnMobj(mobj->x, mobj->y, mobj->z, MT_PARTICLE); - traindust->flags = MF_SCENERY; - P_SetMobjState(traindust, S_TRAINDUST); - traindust->frame = P_RandomRange(0, 8) | FF_TRANS90; - traindust->angle = mobj->angle; - traindust->tics = TICRATE * 4; - traindust->destscale = FRACUNIT * 64; - traindust->scalespeed = FRACUNIT / 24; - P_SetScale(traindust, FRACUNIT * 6); - } - break; - case MT_TRAINSTEAMSPAWNER: - if (leveltime % 5 == 0) { - mobj_t *steam = P_SpawnMobj(mobj->x + FRACUNIT*P_SignedRandom() / 2, mobj->y + FRACUNIT*P_SignedRandom() / 2, mobj->z, MT_PARTICLE); - P_SetMobjState(steam, S_TRAINSTEAM); - steam->frame = P_RandomRange(0, 1) | FF_TRANS90; - steam->tics = TICRATE * 8; - steam->destscale = FRACUNIT * 64; - steam->scalespeed = FRACUNIT / 8; - P_SetScale(steam, FRACUNIT * 16); - steam->momx = P_SignedRandom() * 32; - steam->momy = -64 * FRACUNIT; - steam->momz = 2 * FRACUNIT; - } - break; - case MT_CANARIVORE_GAS: - { - fixed_t momz; - - if (mobj->flags2 & MF2_AMBUSH) - { - mobj->momx = FixedMul(mobj->momx, 50 * FRACUNIT / 51); - mobj->momy = FixedMul(mobj->momy, 50 * FRACUNIT / 51); - break; - } - - if (mobj->eflags & MFE_VERTICALFLIP) - { - if ((mobj->z + mobj->height + mobj->momz) <= mobj->ceilingz) - break; - } - else - { - if ((mobj->z + mobj->momz) >= mobj->floorz) - break; - } - - momz = abs(mobj->momz); - if (R_PointToDist2(0, 0, mobj->momx, mobj->momy) < momz) - P_InstaThrust(mobj, R_PointToAngle2(0, 0, mobj->momx, mobj->momy), momz); - mobj->flags2 |= MF2_AMBUSH; - break; - } - case MT_SALOONDOOR: - { - fixed_t x = mobj->tracer->x; - fixed_t y = mobj->tracer->y; - fixed_t z = mobj->tracer->z; - angle_t oang = FixedAngle(mobj->extravalue1); - angle_t fa = (oang >> ANGLETOFINESHIFT) & FINEMASK; - fixed_t c0 = -96*FINECOSINE(fa); - fixed_t s0 = -96*FINESINE(fa); - angle_t fma; - fixed_t c, s; - angle_t angdiff; - - // Adjust angular speed - fixed_t da = AngleFixed(mobj->angle - oang); - if (da > 180*FRACUNIT) - da -= 360*FRACUNIT; - mobj->extravalue2 = 8*(mobj->extravalue2 - da/32)/9; - - // Update angle - mobj->angle += FixedAngle(mobj->extravalue2); - - angdiff = mobj->angle - FixedAngle(mobj->extravalue1); - if (angdiff > (ANGLE_90 - ANG2) && angdiff < ANGLE_180) - { - mobj->angle = FixedAngle(mobj->extravalue1) + (ANGLE_90 - ANG2); - mobj->extravalue2 /= 2; - } - else if (angdiff < (ANGLE_270 + ANG2) && angdiff >= ANGLE_180) - { - mobj->angle = FixedAngle(mobj->extravalue1) + (ANGLE_270 + ANG2); - mobj->extravalue2 /= 2; - } - - // Update position - fma = (mobj->angle >> ANGLETOFINESHIFT) & FINEMASK; - c = 48*FINECOSINE(fma); - s = 48*FINESINE(fma); - P_TeleportMove(mobj, x + c0 + c, y + s0 + s, z); - break; - } - case MT_MINECARTSPAWNER: - P_HandleMinecartSegments(mobj); - if (!mobj->fuse || mobj->fuse > TICRATE) - break; - if (mobj->fuse == 2) - { - mobj->fuse = 0; - break; - } - mobj->flags2 ^= MF2_DONTDRAW; - break; - case MT_LAVAFALLROCK: - if (P_IsObjectOnGround(mobj)) - P_RemoveMobj(mobj); - break; - case MT_PYREFLY: - { - fixed_t hdist; - - mobj->extravalue1 = (mobj->extravalue1 + 3) % 360; - mobj->z += FINESINE(((mobj->extravalue1*ANG1) >> ANGLETOFINESHIFT) & FINEMASK); - - if (!(mobj->flags2 & MF2_BOSSNOTRAP)) - P_LookForPlayers(mobj, true, false, 1500*FRACUNIT); - - if (!mobj->target) - break; - - if (mobj->extravalue2 == 1) - P_PyreFlyBurn(mobj, 0, 20, MT_SMOKE, 4*FRACUNIT); - else if (mobj->extravalue2 == 2) - { - INT32 fireradius = min(100 - mobj->fuse, 52); - P_PyreFlyBurn(mobj, P_RandomRange(0, fireradius)*FRACUNIT, 20, MT_FLAMEPARTICLE, 4*FRACUNIT); - P_PyreFlyBurn(mobj, fireradius*FRACUNIT, 40, MT_PYREFLY_FIRE, 0); - } - - hdist = R_PointToDist2(mobj->x, mobj->y, mobj->target->x, mobj->target->y); - - if (hdist > 1500*FRACUNIT) - { - mobj->flags2 &= ~MF2_BOSSNOTRAP; - P_SetTarget(&mobj->target, NULL); - break; - } - - if (!(mobj->flags2 & MF2_BOSSNOTRAP) && hdist <= 450*FRACUNIT) - mobj->flags2 |= MF2_BOSSNOTRAP; - - if (!(mobj->flags2 & MF2_BOSSNOTRAP)) - break; - - if (hdist < 1000*FRACUNIT) - { - //Aim for player z position. If too close to floor/ceiling, aim just above/below them. - fixed_t destz = min(max(mobj->target->z, mobj->target->floorz + 70*FRACUNIT), mobj->target->ceilingz - 80*FRACUNIT - mobj->height); - fixed_t dist = P_AproxDistance(hdist, destz - mobj->z); - P_InstaThrust(mobj, R_PointToAngle2(mobj->x, mobj->y, mobj->target->x, mobj->target->y), 2*FRACUNIT); - mobj->momz = FixedMul(FixedDiv(destz - mobj->z, dist), 2*FRACUNIT); - } - else - { - mobj->momx = 0; - mobj->momy = 0; - mobj->momz = 0; - } - break; - } - case MT_PTERABYTE: - { - if (mobj->extravalue1 & 4) // Cooldown after grabbing - { - if (mobj->movefactor) - mobj->movefactor--; - else - { - P_SetTarget(&mobj->target, NULL); - mobj->extravalue1 &= 3; - } - } - - if ((mobj->extravalue1 & 3) == 0) // Hovering - { - fixed_t vdist, hdist, time; - fixed_t hspeed = 3*mobj->info->speed; - angle_t fa; - - var1 = 1; - var2 = 0; - A_CapeChase(mobj); - - if (mobj->target) - break; // Still carrying a player or in cooldown - - P_LookForPlayers(mobj, true, false, 256*FRACUNIT); - - if (!mobj->target) - break; - - if (mobj->target->player->powers[pw_flashing]) - { - P_SetTarget(&mobj->target, NULL); - break; - } - - vdist = mobj->z - mobj->target->z - mobj->target->height; - if (P_MobjFlip(mobj)*vdist <= 0) - { - P_SetTarget(&mobj->target, NULL); - break; - } - - hdist = R_PointToDist2(mobj->x, mobj->y, mobj->target->x, mobj->target->y); - if (hdist > 450*FRACUNIT) - { - P_SetTarget(&mobj->target, NULL); - break; - } - - P_SetMobjState(mobj, S_PTERABYTE_SWOOPDOWN); - mobj->extravalue1++; - S_StartSound(mobj, mobj->info->attacksound); - time = FixedDiv(hdist, hspeed); - mobj->angle = R_PointToAngle2(mobj->x, mobj->y, mobj->target->x, mobj->target->y); - fa = (mobj->angle >> ANGLETOFINESHIFT) & FINEMASK; - mobj->momx = FixedMul(FINECOSINE(fa), hspeed); - mobj->momy = FixedMul(FINESINE(fa), hspeed); - mobj->momz = -2*FixedDiv(vdist, time); - mobj->extravalue2 = -FixedDiv(mobj->momz, time); //Z accel - mobj->movecount = time >> FRACBITS; - mobj->reactiontime = mobj->movecount; - } - else if ((mobj->extravalue1 & 3) == 1) // Swooping - { - mobj->reactiontime--; - mobj->momz += mobj->extravalue2; - if (mobj->reactiontime) - break; - - if (mobj->state - states == S_PTERABYTE_SWOOPDOWN) - { - P_SetMobjState(mobj, S_PTERABYTE_SWOOPUP); - mobj->reactiontime = mobj->movecount; - } - else if (mobj->state - states == S_PTERABYTE_SWOOPUP) - { - P_SetMobjState(mobj, S_PTERABYTE_FLY1); - mobj->extravalue1++; - if (mobj->target && mobj->target->tracer != mobj) - P_SetTarget(&mobj->target, NULL); // Failed to grab the target - mobj->momx = mobj->momy = mobj->momz = 0; - } - } - else // Returning - { - var1 = 2*mobj->info->speed; - var2 = 1; - A_HomingChase(mobj); - if (P_AproxDistance(mobj->x - mobj->tracer->x, mobj->y - mobj->tracer->y) <= mobj->info->speed) - { - mobj->extravalue1 -= 2; - mobj->momx = mobj->momy = mobj->momz = 0; - } - } - break; - } - case MT_DRAGONBOMBER: - { -#define DRAGONTURNSPEED ANG2 - mobj->movecount = (mobj->movecount + 9) % 360; - P_SetObjectMomZ(mobj, 4*FINESINE(((mobj->movecount*ANG1) >> ANGLETOFINESHIFT) & FINEMASK), false); - if (mobj->threshold > 0) // are we dropping mines? - { - mobj->threshold--; - if (mobj->threshold == 0) // if the timer hits 0, look for a mine to drop! - { - mobj_t *segment = mobj; - while (segment->tracer != NULL && !P_MobjWasRemoved(segment->tracer) && segment->tracer->state == &states[segment->tracer->info->spawnstate]) - { - segment = segment->tracer; - } - if (segment != mobj) // found an unactivated segment? - { - mobj_t *mine = P_SpawnMobjFromMobj(segment, 0, 0, 0, segment->info->painchance); - mine->angle = segment->angle; - P_InstaThrust(mine, mobj->angle, P_AproxDistance(mobj->momx, mobj->momy) >> 1); - P_SetObjectMomZ(mine, -2*FRACUNIT, true); - S_StartSound(mine, mine->info->seesound); - P_SetMobjState(segment, segment->info->raisestate); - mobj->threshold = mobj->info->painchance; - } - } - } - if (mobj->target != NULL) // Are we chasing a player? - { - fixed_t dist = P_AproxDistance(mobj->x - mobj->target->x, mobj->y - mobj->target->y); - if (dist > 2000 * mobj->scale) // Not anymore! - P_SetTarget(&mobj->target, NULL); - else - { - fixed_t vspeed = FixedMul(mobj->info->speed >> 3, mobj->scale); - fixed_t z = mobj->target->z + (mobj->height >> 1) + (mobj->flags & MFE_VERTICALFLIP ? -128*mobj->scale : 128*mobj->scale + mobj->target->height); - angle_t diff = R_PointToAngle2(mobj->x, mobj->y, mobj->target->x, mobj->target->y) - mobj->angle; - if (diff > ANGLE_180) - mobj->angle -= DRAGONTURNSPEED; - else - mobj->angle += DRAGONTURNSPEED; - if (!mobj->threshold && dist < 512 * mobj->scale) // Close enough to drop bombs - { - mobj->threshold = mobj->info->painchance; - } - mobj->momz += max(min(z - mobj->z, vspeed), -vspeed); - } - } - else // Can we find a player to chase? - { - if (mobj->tracer == NULL || mobj->tracer->state != &states[mobj->tracer->info->spawnstate] - || !P_LookForPlayers(mobj, true, false, 2000*mobj->scale)) // if not, circle around the spawnpoint - { - if (!mobj->spawnpoint) // unless we don't have one, in which case uhhh just circle around wherever we currently are I guess?? - mobj->angle += DRAGONTURNSPEED; - else - { - fixed_t vspeed = FixedMul(mobj->info->speed >> 3, mobj->scale); - fixed_t x = mobj->spawnpoint->x << FRACBITS; - fixed_t y = mobj->spawnpoint->y << FRACBITS; - fixed_t z = mobj->spawnpoint->z << FRACBITS; - angle_t diff = R_PointToAngle2(mobj->x, mobj->y, x, y) - mobj->angle; - if (diff > ANGLE_180) - mobj->angle -= DRAGONTURNSPEED; - else - mobj->angle += DRAGONTURNSPEED; - mobj->momz += max(min(z - mobj->z, vspeed), -vspeed); - } - } - } - P_InstaThrust(mobj, mobj->angle, FixedMul(mobj->info->speed, mobj->scale)); -#undef DRAGONTURNSPEED - } - break; - case MT_MINUS: -#ifdef ROTSPRITE - { - if (P_IsObjectOnGround(mobj)) - mobj->rollangle = 0; - else - mobj->rollangle = R_PointToAngle2(0, 0, mobj->momz, (mobj->scale << 1) - min(abs(mobj->momz), mobj->scale << 1)); - } -#endif - break; - case MT_SPINFIRE: - if (mobj->flags & MF_NOGRAVITY) - { - if (mobj->eflags & MFE_VERTICALFLIP) - mobj->z = mobj->ceilingz - mobj->height; - else - mobj->z = mobj->floorz; - } - else if ((!(mobj->eflags & MFE_VERTICALFLIP) && mobj->z <= mobj->floorz) - || ((mobj->eflags & MFE_VERTICALFLIP) && mobj->z+mobj->height >= mobj->ceilingz)) - { - mobj->flags |= MF_NOGRAVITY; - mobj->momx = 8; // this is a hack which is used to ensure it still behaves as a missile and can damage others - mobj->momy = mobj->momz = 0; - mobj->z = ((mobj->eflags & MFE_VERTICALFLIP) ? mobj->ceilingz-mobj->height : mobj->floorz); - } - /* FALLTHRU */ - default: - // check mobj against possible water content, before movement code - P_MobjCheckWater(mobj); - - // Extinguish fire objects in water - if (mobj->flags & MF_FIRE && mobj->type != MT_PUMA && mobj->type != MT_FIREBALL - && (mobj->eflags & (MFE_UNDERWATER|MFE_TOUCHWATER))) - { - P_KillMobj(mobj, NULL, NULL, 0); - return; - } - break; - } + if (!P_MobjRegularThink(mobj)) + return; } if (P_MobjWasRemoved(mobj)) return; From 6032aa3cd1c2d55053971fb2738f6f4753306aa6 Mon Sep 17 00:00:00 2001 From: MascaraSnake Date: Wed, 25 Dec 2019 00:18:12 +0100 Subject: [PATCH 380/746] P_MobjThinker: Separate MF2_FIRING handling into its own function --- src/p_mobj.c | 93 ++++++++++++++++++++++++++++------------------------ 1 file changed, 51 insertions(+), 42 deletions(-) diff --git a/src/p_mobj.c b/src/p_mobj.c index 84592dcaa..10ca92a2d 100644 --- a/src/p_mobj.c +++ b/src/p_mobj.c @@ -9803,6 +9803,55 @@ static boolean P_MobjRegularThink(mobj_t *mobj) return true; } +static void P_FiringThink(mobj_t* mobj) +{ + if (!mobj->target) + return; + + if (mobj->health <= 0) + return; + + if (mobj->state->action.acp1 == (actionf_p1)A_Boss1Laser) + { + if (mobj->state->tics > 1) + { + var1 = mobj->state->var1; + var2 = mobj->state->var2 & 65535; + mobj->state->action.acp1(mobj); + } + } + else if (leveltime & 1) // Fire mode + { + mobj_t *missile; + + if (mobj->target->player && mobj->target->player->powers[pw_carry] == CR_NIGHTSMODE) + { + fixed_t oldval = mobjinfo[mobj->extravalue1].speed; + + mobj->angle = R_PointToAngle2(mobj->x, mobj->y, mobj->target->x + mobj->target->momx, mobj->target->y + mobj->target->momy); + mobjinfo[mobj->extravalue1].speed = FixedMul(60*FRACUNIT, mobj->scale); + missile = P_SpawnMissile(mobj, mobj->target, mobj->extravalue1); + mobjinfo[mobj->extravalue1].speed = oldval; + } + else + { + mobj->angle = R_PointToAngle2(mobj->x, mobj->y, mobj->target->x, mobj->target->y); + missile = P_SpawnMissile(mobj, mobj->target, mobj->extravalue1); + } + + if (missile) + { + if (mobj->flags2 & MF2_SUPERFIRE) + missile->flags2 |= MF2_SUPERFIRE; + + if (mobj->info->attacksound) + S_StartSound(missile, mobj->info->attacksound); + } + } + else + mobj->angle = R_PointToAngle2(mobj->x, mobj->y, mobj->target->x, mobj->target->y); +} + // // P_MobjThinker // @@ -9907,48 +9956,8 @@ void P_MobjThinker(mobj_t *mobj) if (P_MobjWasRemoved(mobj)) return; - if (mobj->flags2 & MF2_FIRING && mobj->target && mobj->health > 0) - { - if (mobj->state->action.acp1 == (actionf_p1)A_Boss1Laser) - { - if (mobj->state->tics > 1) - { - var1 = mobj->state->var1; - var2 = mobj->state->var2 & 65535; - mobj->state->action.acp1(mobj); - } - } - else if (leveltime & 1) // Fire mode - { - mobj_t *missile; - - if (mobj->target->player && mobj->target->player->powers[pw_carry] == CR_NIGHTSMODE) - { - fixed_t oldval = mobjinfo[mobj->extravalue1].speed; - - mobj->angle = R_PointToAngle2(mobj->x, mobj->y, mobj->target->x+mobj->target->momx, mobj->target->y+mobj->target->momy); - mobjinfo[mobj->extravalue1].speed = FixedMul(60*FRACUNIT, mobj->scale); - missile = P_SpawnMissile(mobj, mobj->target, mobj->extravalue1); - mobjinfo[mobj->extravalue1].speed = oldval; - } - else - { - mobj->angle = R_PointToAngle2(mobj->x, mobj->y, mobj->target->x, mobj->target->y); - missile = P_SpawnMissile(mobj, mobj->target, mobj->extravalue1); - } - - if (missile) - { - if (mobj->flags2 & MF2_SUPERFIRE) - missile->flags2 |= MF2_SUPERFIRE; - - if (mobj->info->attacksound) - S_StartSound(missile, mobj->info->attacksound); - } - } - else - mobj->angle = R_PointToAngle2(mobj->x, mobj->y, mobj->target->x, mobj->target->y); - } + if (mobj->flags2 & MF2_FIRING) + P_FiringThink(mobj); if (mobj->flags & MF_AMBIENT) { From f0ef4e3193b94553eebbc8158b43cfebbc51c24e Mon Sep 17 00:00:00 2001 From: Steel Titanium Date: Tue, 24 Dec 2019 18:31:47 -0500 Subject: [PATCH 381/746] Fix edge case with R_SkinUsable --- 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 aa2a73515..a4bc14c02 100644 --- a/src/r_things.c +++ b/src/r_things.c @@ -2839,7 +2839,7 @@ boolean R_SkinUsable(INT32 playernum, INT32 skinnum) { return ((skinnum == -1) // Simplifies things elsewhere, since there's already plenty of checks for less-than-0... || (!skins[skinnum].availability) - || ((playernum != -1) ? (players[playernum].availabilities & (1 << skinnum)) : (unlockables[skins[skinnum].availability - 1].unlocked)) + || (((netgame || multiplayer) && playernum != -1) ? (players[playernum].availabilities & (1 << skinnum)) : (unlockables[skins[skinnum].availability - 1].unlocked)) || (modeattacking) // If you have someone else's run you might as well take a look || (Playing() && (R_SkinAvailable(mapheaderinfo[gamemap-1]->forcecharacter) == skinnum)) // Force 1. || (netgame && (cv_forceskin.value == skinnum)) // Force 2. From 64df10f7bee74f221fd2a70978948911613a9822 Mon Sep 17 00:00:00 2001 From: MascaraSnake Date: Wed, 25 Dec 2019 00:36:24 +0100 Subject: [PATCH 382/746] P_MobjThinker: Separate fuse handling into its own function --- src/p_mobj.c | 437 ++++++++++++++++++++++++++------------------------- 1 file changed, 226 insertions(+), 211 deletions(-) diff --git a/src/p_mobj.c b/src/p_mobj.c index 10ca92a2d..292545328 100644 --- a/src/p_mobj.c +++ b/src/p_mobj.c @@ -9803,7 +9803,7 @@ static boolean P_MobjRegularThink(mobj_t *mobj) return true; } -static void P_FiringThink(mobj_t* mobj) +static void P_FiringThink(mobj_t *mobj) { if (!mobj->target) return; @@ -9852,6 +9852,229 @@ static void P_FiringThink(mobj_t* mobj) mobj->angle = R_PointToAngle2(mobj->x, mobj->y, mobj->target->x, mobj->target->y); } +static void P_MonitorFuseThink(mobj_t *mobj) +{ + mobj_t *newmobj; + + // Special case for ALL monitors. + // If a box's speed is nonzero, it's allowed to respawn as a WRM/SRM. + if (mobj->info->speed != 0 && (mobj->flags2 & (MF2_AMBUSH|MF2_STRONGBOX))) + { + mobjtype_t spawnchance[64]; + INT32 numchoices = 0, i = 0; + + // This define should make it a lot easier to organize and change monitor weights +#define SETMONITORCHANCES(type, strongboxamt, weakboxamt) \ +for (i = ((mobj->flags2 & MF2_STRONGBOX) ? strongboxamt : weakboxamt); i; --i) spawnchance[numchoices++] = type + + // Type SRM WRM + SETMONITORCHANCES(MT_SNEAKERS_BOX, 0, 10); // Super Sneakers + SETMONITORCHANCES(MT_INVULN_BOX, 2, 0); // Invincibility + SETMONITORCHANCES(MT_WHIRLWIND_BOX, 3, 8); // Whirlwind Shield + SETMONITORCHANCES(MT_ELEMENTAL_BOX, 3, 8); // Elemental Shield + SETMONITORCHANCES(MT_ATTRACT_BOX, 2, 0); // Attraction Shield + SETMONITORCHANCES(MT_FORCE_BOX, 3, 3); // Force Shield + SETMONITORCHANCES(MT_ARMAGEDDON_BOX, 2, 0); // Armageddon Shield + SETMONITORCHANCES(MT_MIXUP_BOX, 0, 1); // Teleporters + SETMONITORCHANCES(MT_RECYCLER_BOX, 0, 1); // Recycler + SETMONITORCHANCES(MT_1UP_BOX, 1, 1); // 1-Up + // ======================================= + // Total 16 32 + +#undef SETMONITORCHANCES + + i = P_RandomKey(numchoices); // Gotta love those random numbers! + newmobj = P_SpawnMobj(mobj->x, mobj->y, mobj->z, spawnchance[i]); + } + else + newmobj = P_SpawnMobj(mobj->x, mobj->y, mobj->z, mobj->type); + + // Transfer flags2 (ambush, strongbox, objectflip) + newmobj->flags2 = mobj->flags2; + P_RemoveMobj(mobj); // make sure they disappear +} + +static void P_FlagFuseThink(mobj_t *mobj) +{ + subsector_t *ss; + fixed_t x, y, z; + mobj_t* flagmo; + + if (!mobj->spawnpoint) + return; + + x = mobj->spawnpoint->x << FRACBITS; + y = mobj->spawnpoint->y << FRACBITS; + ss = R_PointInSubsector(x, y); + if (mobj->spawnpoint->options & MTF_OBJECTFLIP) + { + z = ss->sector->ceilingheight - mobjinfo[mobj->type].height; + if (mobj->spawnpoint->options >> ZSHIFT) + z -= (mobj->spawnpoint->options >> ZSHIFT) << FRACBITS; + } + else + { + z = ss->sector->floorheight; + if (mobj->spawnpoint->options >> ZSHIFT) + z += (mobj->spawnpoint->options >> ZSHIFT) << FRACBITS; + } + flagmo = P_SpawnMobj(x, y, z, mobj->type); + flagmo->spawnpoint = mobj->spawnpoint; + if (mobj->spawnpoint->options & MTF_OBJECTFLIP) + { + flagmo->eflags |= MFE_VERTICALFLIP; + flagmo->flags2 |= MF2_OBJECTFLIP; + } + + if (mobj->type == MT_REDFLAG) + { + if (!(mobj->flags2 & MF2_JUSTATTACKED)) + CONS_Printf(M_GetText("The %c%s%c has returned to base.\n"), 0x85, M_GetText("Red flag"), 0x80); + + // Assumedly in splitscreen players will be on opposing teams + if (players[consoleplayer].ctfteam == 1 || splitscreen) + S_StartSound(NULL, sfx_hoop1); + else if (players[consoleplayer].ctfteam == 2) + S_StartSound(NULL, sfx_hoop3); + + redflag = flagmo; + } + else // MT_BLUEFLAG + { + if (!(mobj->flags2 & MF2_JUSTATTACKED)) + CONS_Printf(M_GetText("The %c%s%c has returned to base.\n"), 0x84, M_GetText("Blue flag"), 0x80); + + // Assumedly in splitscreen players will be on opposing teams + if (players[consoleplayer].ctfteam == 2 || splitscreen) + S_StartSound(NULL, sfx_hoop1); + else if (players[consoleplayer].ctfteam == 1) + S_StartSound(NULL, sfx_hoop3); + + blueflag = flagmo; + } +} + +static boolean P_FuseThink(mobj_t *mobj) +{ + if (mobj->type == MT_SNAPPER_HEAD || mobj->type == MT_SNAPPER_LEG || mobj->type == MT_MINECARTSEG) + mobj->flags2 ^= MF2_DONTDRAW; + + mobj->fuse--; + + if (mobj->fuse) + return true; + +#ifdef HAVE_BLUA + if (LUAh_MobjFuse(mobj) || P_MobjWasRemoved(mobj)) + ; + else +#endif + if (mobj->info->flags & MF_MONITOR) + { + P_MonitorFuseThink(mobj); + return false; + } + else switch (mobj->type) + { + // gargoyle and snowman handled in P_PushableThinker, not here + case MT_THROWNGRENADE: + case MT_CYBRAKDEMON_NAPALM_BOMB_LARGE: + P_SetMobjState(mobj, mobj->info->deathstate); + break; + case MT_LHRT: + P_KillMobj(mobj, NULL, NULL, 0); + break; + case MT_BLUEFLAG: + case MT_REDFLAG: + P_FlagFuseThink(mobj); + P_RemoveMobj(mobj); + return false; + case MT_FANG: + if (mobj->flags2 & MF2_SLIDEPUSH) + { + var1 = 0; + var2 = 0; + A_BossDeath(mobj); + return false; + } + P_SetMobjState(mobj, mobj->state->nextstate); + if (P_MobjWasRemoved(mobj)) + return false; + break; + case MT_METALSONIC_BATTLE: + break; // don't remove + case MT_SPIKE: + P_SetMobjState(mobj, mobj->state->nextstate); + mobj->fuse = mobj->info->speed; + if (mobj->spawnpoint) + mobj->fuse += mobj->spawnpoint->angle; + break; + case MT_WALLSPIKE: + P_SetMobjState(mobj, mobj->state->nextstate); + mobj->fuse = mobj->info->speed; + if (mobj->spawnpoint) + mobj->fuse += (mobj->spawnpoint->angle / 360); + break; + case MT_NIGHTSCORE: + P_RemoveMobj(mobj); + return false; + case MT_LAVAFALL: + if (mobj->state - states == S_LAVAFALL_DORMANT) + { + mobj->fuse = 30; + P_SetMobjState(mobj, S_LAVAFALL_TELL); + S_StartSound(mobj, mobj->info->seesound); + } + else if (mobj->state - states == S_LAVAFALL_TELL) + { + mobj->fuse = 40; + P_SetMobjState(mobj, S_LAVAFALL_SHOOT); + S_StopSound(mobj); + S_StartSound(mobj, mobj->info->attacksound); + } + else + { + mobj->fuse = 30; + P_SetMobjState(mobj, S_LAVAFALL_DORMANT); + S_StopSound(mobj); + } + return false; + case MT_PYREFLY: + if (mobj->health <= 0) + break; + + mobj->extravalue2 = (mobj->extravalue2 + 1) % 3; + if (mobj->extravalue2 == 0) + { + P_SetMobjState(mobj, mobj->info->spawnstate); + mobj->fuse = 100; + S_StopSound(mobj); + S_StartSound(mobj, sfx_s3k8c); + } + else if (mobj->extravalue2 == 1) + { + mobj->fuse = 50; + S_StartSound(mobj, sfx_s3ka3); + } + else + { + P_SetMobjState(mobj, mobj->info->meleestate); + mobj->fuse = 100; + S_StopSound(mobj); + S_StartSound(mobj, sfx_s3kc2l); + } + return false; + case MT_PLAYER: + break; // don't remove + default: + P_SetMobjState(mobj, mobj->info->xdeathstate); // will remove the mobj if S_NULL. + break; + // Looking for monitors? They moved to a special condition above. + } + + return !P_MobjWasRemoved(mobj); +} + // // P_MobjThinker // @@ -9967,216 +10190,8 @@ void P_MobjThinker(mobj_t *mobj) } // Check fuse - if (mobj->fuse) - { - - if (mobj->type == MT_SNAPPER_HEAD || mobj->type == MT_SNAPPER_LEG || mobj->type == MT_MINECARTSEG) - mobj->flags2 ^= MF2_DONTDRAW; - - mobj->fuse--; - if (!mobj->fuse) - { - subsector_t *ss; - fixed_t x, y, z; - mobj_t *flagmo, *newmobj; - -#ifdef HAVE_BLUA - if (LUAh_MobjFuse(mobj) || P_MobjWasRemoved(mobj)) - ; - else -#endif - if (mobj->info->flags & MF_MONITOR) - { - // Special case for ALL monitors. - // If a box's speed is nonzero, it's allowed to respawn as a WRM/SRM. - if (mobj->info->speed != 0 && (mobj->flags2 & (MF2_AMBUSH|MF2_STRONGBOX))) - { - mobjtype_t spawnchance[64]; - INT32 numchoices = 0, i = 0; - -// This define should make it a lot easier to organize and change monitor weights -#define SETMONITORCHANCES(type, strongboxamt, weakboxamt) \ -for (i = ((mobj->flags2 & MF2_STRONGBOX) ? strongboxamt : weakboxamt); i; --i) spawnchance[numchoices++] = type - - // Type SRM WRM - SETMONITORCHANCES(MT_SNEAKERS_BOX, 0, 10); // Super Sneakers - SETMONITORCHANCES(MT_INVULN_BOX, 2, 0); // Invincibility - SETMONITORCHANCES(MT_WHIRLWIND_BOX, 3, 8); // Whirlwind Shield - SETMONITORCHANCES(MT_ELEMENTAL_BOX, 3, 8); // Elemental Shield - SETMONITORCHANCES(MT_ATTRACT_BOX, 2, 0); // Attraction Shield - SETMONITORCHANCES(MT_FORCE_BOX, 3, 3); // Force Shield - SETMONITORCHANCES(MT_ARMAGEDDON_BOX, 2, 0); // Armageddon Shield - SETMONITORCHANCES(MT_MIXUP_BOX, 0, 1); // Teleporters - SETMONITORCHANCES(MT_RECYCLER_BOX, 0, 1); // Recycler - SETMONITORCHANCES(MT_1UP_BOX, 1, 1); // 1-Up - // ======================================= - // Total 16 32 - -#undef SETMONITORCHANCES - - i = P_RandomKey(numchoices); // Gotta love those random numbers! - newmobj = P_SpawnMobj(mobj->x, mobj->y, mobj->z, spawnchance[i]); - } - else - newmobj = P_SpawnMobj(mobj->x, mobj->y, mobj->z, mobj->type); - - // Transfer flags2 (ambush, strongbox, objectflip) - newmobj->flags2 = mobj->flags2; - P_RemoveMobj(mobj); // make sure they disappear - return; - } - else switch (mobj->type) - { - // gargoyle and snowman handled in P_PushableThinker, not here - case MT_THROWNGRENADE: - case MT_CYBRAKDEMON_NAPALM_BOMB_LARGE: - P_SetMobjState(mobj, mobj->info->deathstate); - break; - case MT_LHRT: - P_KillMobj(mobj, NULL, NULL, 0); - break; - case MT_BLUEFLAG: - case MT_REDFLAG: - if (mobj->spawnpoint) - { - x = mobj->spawnpoint->x << FRACBITS; - y = mobj->spawnpoint->y << FRACBITS; - ss = R_PointInSubsector(x, y); - if (mobj->spawnpoint->options & MTF_OBJECTFLIP) - { - z = ss->sector->ceilingheight - mobjinfo[mobj->type].height; - if (mobj->spawnpoint->options >> ZSHIFT) - z -= (mobj->spawnpoint->options >> ZSHIFT) << FRACBITS; - } - else - { - z = ss->sector->floorheight; - if (mobj->spawnpoint->options >> ZSHIFT) - z += (mobj->spawnpoint->options >> ZSHIFT) << FRACBITS; - } - flagmo = P_SpawnMobj(x, y, z, mobj->type); - flagmo->spawnpoint = mobj->spawnpoint; - if (mobj->spawnpoint->options & MTF_OBJECTFLIP) - { - flagmo->eflags |= MFE_VERTICALFLIP; - flagmo->flags2 |= MF2_OBJECTFLIP; - } - - if (mobj->type == MT_REDFLAG) - { - if (!(mobj->flags2 & MF2_JUSTATTACKED)) - CONS_Printf(M_GetText("The %c%s%c has returned to base.\n"), 0x85, M_GetText("Red flag"), 0x80); - - // Assumedly in splitscreen players will be on opposing teams - if (players[consoleplayer].ctfteam == 1 || splitscreen) - S_StartSound(NULL, sfx_hoop1); - else if (players[consoleplayer].ctfteam == 2) - S_StartSound(NULL, sfx_hoop3); - - redflag = flagmo; - } - else // MT_BLUEFLAG - { - if (!(mobj->flags2 & MF2_JUSTATTACKED)) - CONS_Printf(M_GetText("The %c%s%c has returned to base.\n"), 0x84, M_GetText("Blue flag"), 0x80); - - // Assumedly in splitscreen players will be on opposing teams - if (players[consoleplayer].ctfteam == 2 || splitscreen) - S_StartSound(NULL, sfx_hoop1); - else if (players[consoleplayer].ctfteam == 1) - S_StartSound(NULL, sfx_hoop3); - - blueflag = flagmo; - } - } - P_RemoveMobj(mobj); - return; - case MT_FANG: - if (mobj->flags2 & MF2_SLIDEPUSH) - { - var1 = 0; - var2 = 0; - A_BossDeath(mobj); - return; - } - P_SetMobjState(mobj, mobj->state->nextstate); - if (P_MobjWasRemoved(mobj)) - return; - break; - case MT_METALSONIC_BATTLE: - break; // don't remove - case MT_SPIKE: - P_SetMobjState(mobj, mobj->state->nextstate); - mobj->fuse = mobj->info->speed; - if (mobj->spawnpoint) - mobj->fuse += mobj->spawnpoint->angle; - break; - case MT_WALLSPIKE: - P_SetMobjState(mobj, mobj->state->nextstate); - mobj->fuse = mobj->info->speed; - if (mobj->spawnpoint) - mobj->fuse += (mobj->spawnpoint->angle/360); - break; - case MT_NIGHTSCORE: - P_RemoveMobj(mobj); - return; - case MT_LAVAFALL: - if (mobj->state - states == S_LAVAFALL_DORMANT) - { - mobj->fuse = 30; - P_SetMobjState(mobj, S_LAVAFALL_TELL); - S_StartSound(mobj, mobj->info->seesound); - } - else if (mobj->state - states == S_LAVAFALL_TELL) - { - mobj->fuse = 40; - P_SetMobjState(mobj, S_LAVAFALL_SHOOT); - S_StopSound(mobj); - S_StartSound(mobj, mobj->info->attacksound); - } - else - { - mobj->fuse = 30; - P_SetMobjState(mobj, S_LAVAFALL_DORMANT); - S_StopSound(mobj); - } - return; - case MT_PYREFLY: - if (mobj->health <= 0) - break; - - mobj->extravalue2 = (mobj->extravalue2 + 1) % 3; - if (mobj->extravalue2 == 0) - { - P_SetMobjState(mobj, mobj->info->spawnstate); - mobj->fuse = 100; - S_StopSound(mobj); - S_StartSound(mobj, sfx_s3k8c); - } - else if (mobj->extravalue2 == 1) - { - mobj->fuse = 50; - S_StartSound(mobj, sfx_s3ka3); - } - else - { - P_SetMobjState(mobj, mobj->info->meleestate); - mobj->fuse = 100; - S_StopSound(mobj); - S_StartSound(mobj, sfx_s3kc2l); - } - return; - case MT_PLAYER: - break; // don't remove - default: - P_SetMobjState(mobj, mobj->info->xdeathstate); // will remove the mobj if S_NULL. - break; - // Looking for monitors? They moved to a special condition above. - } - if (P_MobjWasRemoved(mobj)) - return; - } - } + if (mobj->fuse && !P_FuseThink(mobj)) + return; I_Assert(mobj != NULL); I_Assert(!P_MobjWasRemoved(mobj)); From b9a276f5aaa918bb2cabc54246e259bd7a70c784 Mon Sep 17 00:00:00 2001 From: MascaraSnake Date: Wed, 25 Dec 2019 09:10:20 +0100 Subject: [PATCH 383/746] Make slope vertices use mt->z directly instead of mt->options >> ZSHIFT --- src/p_slopes.c | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/src/p_slopes.c b/src/p_slopes.c index 89d265fa4..1dc4f9819 100644 --- a/src/p_slopes.c +++ b/src/p_slopes.c @@ -445,10 +445,9 @@ static pslope_t *MakeViaMapthings(INT16 tag1, INT16 tag2, INT16 tag3, UINT8 flag I_Error("MakeViaMapthings: Slope vertex %s (for linedef tag %d) not found!", sizeu1(i), tag1); vx[i].x = mt->x << FRACBITS; vx[i].y = mt->y << FRACBITS; - if (mt->extrainfo) - vx[i].z = mt->options << FRACBITS; - else - vx[i].z = (R_PointInSubsector(mt->x << FRACBITS, mt->y << FRACBITS)->sector->floorheight) + ((mt->options >> ZSHIFT) << FRACBITS); + vx[i].z = mt->z << FRACBITS; + if (!mt->extrainfo) + vx[i].z += R_PointInSubsector(vx[i].x, vx[i].y)->sector->floorheight; } ReconfigureViaVertexes(ret, vx[0], vx[1], vx[2]); From 32ef930c04d6a0bd9437ad0a34c2cd23c14e16d8 Mon Sep 17 00:00:00 2001 From: MascaraSnake Date: Wed, 25 Dec 2019 09:40:08 +0100 Subject: [PATCH 384/746] Get rid of a few mt->options >> ZSHIFT usages in objectplace --- src/m_cheat.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/m_cheat.c b/src/m_cheat.c index 3d1fe5b7e..52b79f930 100644 --- a/src/m_cheat.c +++ b/src/m_cheat.c @@ -1193,14 +1193,14 @@ void OP_NightsObjectplace(player_t *player) if (cmd->buttons & BT_TOSSFLAG) { UINT16 vertangle = (UINT16)(player->anotherflyangle % 360); - UINT16 newflags, newz; + UINT16 newflags; player->pflags |= PF_ATTACKDOWN; if (!OP_HeightOkay(player, false)) return; mt = OP_CreateNewMapThing(player, (UINT16)mobjinfo[MT_NIGHTSBUMPER].doomednum, false); - newz = min((mt->options >> ZSHIFT) - (mobjinfo[MT_NIGHTSBUMPER].height/4), 0); + mt->z = min(mt->z - (mobjinfo[MT_NIGHTSBUMPER].height/4), 0); // height offset: from P_TouchSpecialThing case MT_NIGHTSBUMPER // clockwise @@ -1231,7 +1231,7 @@ void OP_NightsObjectplace(player_t *player) else // forward newflags = 0; - mt->options = (newz << ZSHIFT) | newflags; + mt->options = (mt->z << ZSHIFT) | newflags; // if NiGHTS is facing backwards, orient the Thing angle forwards so that the sprite angle // displays correctly. Backwards movement via the Thing flags is unaffected. @@ -1439,7 +1439,7 @@ void OP_ObjectplaceMovement(player_t *player) else P_SpawnMapThing(mt); - CONS_Printf(M_GetText("Placed object type %d at %d, %d, %d, %d\n"), mt->type, mt->x, mt->y, mt->options>>ZSHIFT, mt->angle); + CONS_Printf(M_GetText("Placed object type %d at %d, %d, %d, %d\n"), mt->type, mt->x, mt->y, mt->z, mt->angle); } } From 12d30b7acc537aa520ff825e266342c872752007 Mon Sep 17 00:00:00 2001 From: MascaraSnake Date: Wed, 25 Dec 2019 09:46:09 +0100 Subject: [PATCH 385/746] Use mthing->z instead of mthing->options >> ZSHIFT in particle generator setup --- src/p_mobj.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/p_mobj.c b/src/p_mobj.c index 292545328..4be20a81b 100644 --- a/src/p_mobj.c +++ b/src/p_mobj.c @@ -12464,7 +12464,7 @@ static boolean P_SetupParticleGen(mapthing_t *mthing, mobj_t *mobj) || (ticcount = (sides[lines[line].sidenum[1]].textureoffset >> FRACBITS)) < 1) ticcount = 3; - numdivisions = (mthing->options >> ZSHIFT); + numdivisions = mthing->z; if (numdivisions) { From f4c6068ab1b92d48be8ba73b038b755abc863700 Mon Sep 17 00:00:00 2001 From: MascaraSnake Date: Wed, 25 Dec 2019 10:59:12 +0100 Subject: [PATCH 386/746] P_MovePlayerToSpawn: Use mthing->z instead of mthing->options >> ZSHIFT --- src/p_mobj.c | 21 ++++++++------------- 1 file changed, 8 insertions(+), 13 deletions(-) diff --git a/src/p_mobj.c b/src/p_mobj.c index 4be20a81b..bc5121318 100644 --- a/src/p_mobj.c +++ b/src/p_mobj.c @@ -11562,7 +11562,7 @@ void P_MovePlayerToSpawn(INT32 playernum, mapthing_t *mthing) fixed_t z; sector_t *sector; - fixed_t floor, ceiling; + fixed_t floor, ceiling, ceilingspawn; player_t *p = &players[playernum]; mobj_t *mobj = p->mo; @@ -11589,23 +11589,18 @@ void P_MovePlayerToSpawn(INT32 playernum, mapthing_t *mthing) sector->c_slope ? P_GetZAt(sector->c_slope, x, y) : #endif sector->ceilingheight; + ceilingspawn = ceiling - mobjinfo[MT_PLAYER].height; if (mthing) { + fixed_t offset = mthing->z << FRACBITS; + // Flagging a player's ambush will make them start on the ceiling // Objectflip inverts if (!!(mthing->options & MTF_AMBUSH) ^ !!(mthing->options & MTF_OBJECTFLIP)) - { - z = ceiling - mobjinfo[MT_PLAYER].height; - if (mthing->options >> ZSHIFT) - z -= ((mthing->options >> ZSHIFT) << FRACBITS); - } + z = ceilingspawn - offset; else - { - z = floor; - if (mthing->options >> ZSHIFT) - z += ((mthing->options >> ZSHIFT) << FRACBITS); - } + z = floor + offset; if (mthing->options & MTF_OBJECTFLIP) // flip the player! { @@ -11622,8 +11617,8 @@ void P_MovePlayerToSpawn(INT32 playernum, mapthing_t *mthing) if (z < floor) z = floor; - else if (z > ceiling - mobjinfo[MT_PLAYER].height) - z = ceiling - mobjinfo[MT_PLAYER].height; + else if (z > ceilingspawn) + z = ceilingspawn; mobj->floorz = floor; mobj->ceilingz = ceiling; From de7575416acf6830a0c0858b46e94b38bf632ae1 Mon Sep 17 00:00:00 2001 From: MascaraSnake Date: Wed, 25 Dec 2019 11:17:57 +0100 Subject: [PATCH 387/746] P_FlagFuseThink: Use mt->z instead of mt->options >> ZSHIFT --- src/p_mobj.c | 13 +++---------- 1 file changed, 3 insertions(+), 10 deletions(-) diff --git a/src/p_mobj.c b/src/p_mobj.c index bc5121318..83ab50b35 100644 --- a/src/p_mobj.c +++ b/src/p_mobj.c @@ -9905,19 +9905,12 @@ static void P_FlagFuseThink(mobj_t *mobj) x = mobj->spawnpoint->x << FRACBITS; y = mobj->spawnpoint->y << FRACBITS; + z = mobj->spawnpoint->z << FRACBITS; ss = R_PointInSubsector(x, y); if (mobj->spawnpoint->options & MTF_OBJECTFLIP) - { - z = ss->sector->ceilingheight - mobjinfo[mobj->type].height; - if (mobj->spawnpoint->options >> ZSHIFT) - z -= (mobj->spawnpoint->options >> ZSHIFT) << FRACBITS; - } + z = ss->sector->ceilingheight - mobjinfo[mobj->type].height - z; else - { - z = ss->sector->floorheight; - if (mobj->spawnpoint->options >> ZSHIFT) - z += (mobj->spawnpoint->options >> ZSHIFT) << FRACBITS; - } + z = ss->sector->floorheight + z; flagmo = P_SpawnMobj(x, y, z, mobj->type); flagmo->spawnpoint = mobj->spawnpoint; if (mobj->spawnpoint->options & MTF_OBJECTFLIP) From c4a017ddf01e6c529df0369bb28e66d9aa0cdf20 Mon Sep 17 00:00:00 2001 From: Nev3r Date: Wed, 25 Dec 2019 12:05:40 +0100 Subject: [PATCH 388/746] Move flat caching code to the map data load function. --- src/p_setup.c | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/src/p_setup.c b/src/p_setup.c index f5d4c26e2..3ae17cc23 100644 --- a/src/p_setup.c +++ b/src/p_setup.c @@ -651,14 +651,6 @@ static void P_LoadRawSectors(UINT8 *data) sector_t *ss = sectors; size_t i; - // Allocate a big chunk of memory as big as our MAXLEVELFLATS limit. - //Fab : FIXME: allocate for whatever number of flats - 512 different flats per level should be plenty - foundflats = calloc(MAXLEVELFLATS, sizeof (*foundflats)); - if (foundflats == NULL) - I_Error("Ran out of memory while loading sectors\n"); - - numlevelflats = 0; - // For each counted sector, copy the sector raw data from our cache pointer ms, to the global table pointer ss. for (i = 0; i < numsectors; i++, ss++, ms++) { @@ -1982,6 +1974,14 @@ static void P_LoadMapData(const virtres_t* virt) lines = Z_Calloc(numlines * sizeof (*lines), PU_LEVEL, NULL); mapthings = Z_Calloc(nummapthings * sizeof (*mapthings), PU_LEVEL, NULL); + // Allocate a big chunk of memory as big as our MAXLEVELFLATS limit. + //Fab : FIXME: allocate for whatever number of flats - 512 different flats per level should be plenty + foundflats = calloc(MAXLEVELFLATS, sizeof (*foundflats)); + if (foundflats == NULL) + I_Error("Ran out of memory while loading sectors\n"); + + numlevelflats = 0; + #ifdef UDMF if (textmap) { From 5241030012cf53746192d8004f21e0118297853f Mon Sep 17 00:00:00 2001 From: Monster Iestyn Date: Wed, 25 Dec 2019 21:48:59 +0000 Subject: [PATCH 389/746] Fix ShouldDamage, MobjDamage and MobjDeath hooks all messing up the pushing of variables to Lua as function args, by adding damagetype support where it was missing! The above issue occured only if you had both a generic hook and a type specific hook for a particular hook type. This way, the stack is never updated to include damagetype at the start, and all pushes of the variables get offsetted by 1 compared to what they should be, once the code *expects* damagetype to be included in it. --- src/lua_hooklib.c | 34 ++++++++++++++++++++-------------- 1 file changed, 20 insertions(+), 14 deletions(-) diff --git a/src/lua_hooklib.c b/src/lua_hooklib.c index ef87d0b6f..aadba6aba 100644 --- a/src/lua_hooklib.c +++ b/src/lua_hooklib.c @@ -657,14 +657,16 @@ UINT8 LUAh_ShouldDamage(mobj_t *target, mobj_t *inflictor, mobj_t *source, INT32 LUA_PushUserdata(gL, inflictor, META_MOBJ); LUA_PushUserdata(gL, source, META_MOBJ); lua_pushinteger(gL, damage); + lua_pushinteger(gL, damagetype); } lua_pushfstring(gL, FMT_HOOKID, hookp->id); lua_gettable(gL, LUA_REGISTRYINDEX); - lua_pushvalue(gL, -5); - lua_pushvalue(gL, -5); - lua_pushvalue(gL, -5); - lua_pushvalue(gL, -5); - if (lua_pcall(gL, 4, 1, 0)) { + lua_pushvalue(gL, -6); + lua_pushvalue(gL, -6); + lua_pushvalue(gL, -6); + lua_pushvalue(gL, -6); + lua_pushvalue(gL, -6); + if (lua_pcall(gL, 5, 1, 0)) { if (!hookp->error || cv_debug & DBG_LUA) CONS_Alert(CONS_WARNING,"%s\n",lua_tostring(gL, -1)); lua_pop(gL, 1); @@ -745,14 +747,16 @@ boolean LUAh_MobjDamage(mobj_t *target, mobj_t *inflictor, mobj_t *source, INT32 LUA_PushUserdata(gL, inflictor, META_MOBJ); LUA_PushUserdata(gL, source, META_MOBJ); lua_pushinteger(gL, damage); + lua_pushinteger(gL, damagetype); } lua_pushfstring(gL, FMT_HOOKID, hookp->id); lua_gettable(gL, LUA_REGISTRYINDEX); - lua_pushvalue(gL, -5); - lua_pushvalue(gL, -5); - lua_pushvalue(gL, -5); - lua_pushvalue(gL, -5); - if (lua_pcall(gL, 4, 1, 0)) { + lua_pushvalue(gL, -6); + lua_pushvalue(gL, -6); + lua_pushvalue(gL, -6); + lua_pushvalue(gL, -6); + lua_pushvalue(gL, -6); + if (lua_pcall(gL, 5, 1, 0)) { if (!hookp->error || cv_debug & DBG_LUA) CONS_Alert(CONS_WARNING,"%s\n",lua_tostring(gL, -1)); lua_pop(gL, 1); @@ -823,13 +827,15 @@ boolean LUAh_MobjDeath(mobj_t *target, mobj_t *inflictor, mobj_t *source, UINT8 LUA_PushUserdata(gL, target, META_MOBJ); LUA_PushUserdata(gL, inflictor, META_MOBJ); LUA_PushUserdata(gL, source, META_MOBJ); + lua_pushinteger(gL, damagetype); } lua_pushfstring(gL, FMT_HOOKID, hookp->id); lua_gettable(gL, LUA_REGISTRYINDEX); - lua_pushvalue(gL, -4); - lua_pushvalue(gL, -4); - lua_pushvalue(gL, -4); - if (lua_pcall(gL, 3, 1, 0)) { + lua_pushvalue(gL, -5); + lua_pushvalue(gL, -5); + lua_pushvalue(gL, -5); + lua_pushvalue(gL, -5); + if (lua_pcall(gL, 4, 1, 0)) { if (!hookp->error || cv_debug & DBG_LUA) CONS_Alert(CONS_WARNING,"%s\n",lua_tostring(gL, -1)); lua_pop(gL, 1); From 70f08007ebff21a97b10f5978d2765d002ace6d4 Mon Sep 17 00:00:00 2001 From: James R Date: Wed, 25 Dec 2019 15:23:19 -0800 Subject: [PATCH 390/746] Correct the check for rings on thing 604 - 607 The original code used a switch case, not AND 1. :V --- src/p_mobj.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/p_mobj.c b/src/p_mobj.c index 13f75b94a..1882a4e3c 100644 --- a/src/p_mobj.c +++ b/src/p_mobj.c @@ -13372,7 +13372,7 @@ void P_SpawnItemPattern(mapthing_t *mthing, boolean bonustime) { INT32 numitems = (mthing->type & 1) ? 16 : 8; fixed_t size = (mthing->type & 1) ? 192*FRACUNIT : 96*FRACUNIT; - mobjtype_t itemtypes[1] = { (mthing->type & 1) ? MT_RING : MT_BLUESPHERE }; + mobjtype_t itemtypes[1] = { (mthing->type < 606) ? MT_RING : MT_BLUESPHERE }; P_SpawnItemCircle(mthing, itemtypes, 1, numitems, size, bonustime); return; } From 6f5a259983d9d8e97769cec83ac4a54ac518342c Mon Sep 17 00:00:00 2001 From: Jaime Passos Date: Thu, 26 Dec 2019 00:07:04 -0300 Subject: [PATCH 391/746] Tame R_StoreWallRange --- src/r_segs.c | 1933 +++++++++++++++++++++++++++----------------------- 1 file changed, 1040 insertions(+), 893 deletions(-) diff --git a/src/r_segs.c b/src/r_segs.c index 29120ebb8..c131af9ed 100644 --- a/src/r_segs.c +++ b/src/r_segs.c @@ -37,6 +37,14 @@ static boolean maskedtexture; static INT32 toptexture, bottomtexture, midtexture; static INT32 numthicksides, numbackffloors; +static boolean bothceilingssky; +static boolean bothfloorssky; + +#ifdef ESLOPE +static vertex_t segleft, segright; +static fixed_t ceilingfrontslide, floorfrontslide, ceilingbackslide, floorbackslide; +#endif + angle_t rw_normalangle; // angle to line origin angle_t rw_angle1; @@ -1687,8 +1695,20 @@ static void R_RenderSegLoop (void) } } -// Uses precalculated seg->length -static INT64 R_CalcSegDist(seg_t* seg, INT64 x2, INT64 y2) +// Macro for slope bullshit +#define SLOPEPARAMS(slope, end1, end2, normalheight) \ + if (slope) { \ + end1 = P_GetZAt(slope, segleft.x, segleft.y); \ + end2 = P_GetZAt(slope, segright.x, segright.y); \ + } else \ + end1 = end2 = normalheight; + +// +// R_CalculateSegDistance +// Calculate the distance from a seg. +// Uses precalculated seg->length. +// +static INT64 R_CalculateSegDistance(seg_t* seg, INT64 x2, INT64 y2) { if (!seg->linedef->dy) return llabs(y2 - seg->v1->y); @@ -1705,112 +1725,13 @@ static INT64 R_CalcSegDist(seg_t* seg, INT64 x2, INT64 y2) } // -// R_StoreWallRange -// A wall segment will be drawn -// between start and stop pixels (inclusive). +// R_CalculateWallScale +// Calculate scale at both ends and step. // -void R_StoreWallRange(INT32 start, INT32 stop) +static INT32 R_CalculateWallScale(INT32 start, INT32 stop) { - fixed_t hyp; - fixed_t sineval; - angle_t distangle, offsetangle; - boolean longboi; -#ifndef ESLOPE - fixed_t vtop; -#endif - INT32 lightnum; - INT32 i, p; - lightlist_t *light; - r_lightlist_t *rlight; - INT32 range; -#ifdef ESLOPE - vertex_t segleft, segright; - fixed_t ceilingfrontslide, floorfrontslide, ceilingbackslide, floorbackslide; -#endif - static size_t maxdrawsegs = 0; + INT32 range = 1; -#ifdef ESLOPE - maskedtextureheight = NULL; - //initialize segleft and segright - memset(&segleft, 0x00, sizeof(segleft)); - memset(&segright, 0x00, sizeof(segright)); -#endif - - colfunc = colfuncs[BASEDRAWFUNC]; - - if (ds_p == drawsegs+maxdrawsegs) - { - size_t curpos = curdrawsegs - drawsegs; - size_t pos = ds_p - drawsegs; - size_t newmax = maxdrawsegs ? maxdrawsegs*2 : 128; - if (firstseg) - firstseg = (drawseg_t *)(firstseg - drawsegs); - drawsegs = Z_Realloc(drawsegs, newmax*sizeof (*drawsegs), PU_STATIC, NULL); - ds_p = drawsegs + pos; - maxdrawsegs = newmax; - curdrawsegs = drawsegs + curpos; - if (firstseg) - firstseg = drawsegs + (size_t)firstseg; - } - - sidedef = curline->sidedef; - linedef = curline->linedef; - - // calculate rw_distance for scale calculation - rw_normalangle = curline->angle + ANGLE_90; - offsetangle = abs((INT32)(rw_normalangle-rw_angle1)); - - if (offsetangle > ANGLE_90) - offsetangle = ANGLE_90; - - distangle = ANGLE_90 - offsetangle; - sineval = FINESINE(distangle>>ANGLETOFINESHIFT); - - hyp = R_PointToDist(curline->v1->x, curline->v1->y); - rw_distance = FixedMul(hyp, sineval); - longboi = (hyp >= INT32_MAX); - - // big room fix - if (longboi) - rw_distance = (fixed_t)R_CalcSegDist(curline,viewx,viewy); - - ds_p->x1 = rw_x = start; - ds_p->x2 = stop; - ds_p->curline = curline; - rw_stopx = stop+1; - - //SoM: Code to remove limits on openings. - { - size_t pos = lastopening - openings; - size_t need = (rw_stopx - start)*4 + pos; - if (need > maxopenings) - { - drawseg_t *ds; //needed for fix from *cough* zdoom *cough* - INT16 *oldopenings = openings; - INT16 *oldlast = lastopening; - - do - maxopenings = maxopenings ? maxopenings*2 : 16384; - while (need > maxopenings); - openings = Z_Realloc(openings, maxopenings * sizeof (*openings), PU_STATIC, NULL); - lastopening = openings + pos; - - // borrowed fix from *cough* zdoom *cough* - // [RH] We also need to adjust the openings pointers that - // were already stored in drawsegs. - for (ds = drawsegs; ds < ds_p; ds++) - { -#define ADJUST(p) if (ds->p + ds->x1 >= oldopenings && ds->p + ds->x1 <= oldlast) ds->p = ds->p - oldopenings + openings; - ADJUST(maskedtexturecol); - ADJUST(sprtopclip); - ADJUST(sprbottomclip); - ADJUST(thicksidecol); -#undef ADJUST - } - } - } // end of code to remove limits on openings - - // calculate scale at both ends and step ds_p->scale1 = rw_scale = R_ScaleFromGlobalAngle(viewangle + xtoviewangle[start]); if (stop > start) @@ -1837,13 +1758,20 @@ void R_StoreWallRange(INT32 start, INT32 stop) } #endif ds_p->scale2 = ds_p->scale1; - range = 1; } ds_p->scalestep = rw_scalestep = (ds_p->scale2 - rw_scale) / (range); - // calculate texture boundaries - // and decide if floor / ceiling marks are needed + return range; +} + +// +// R_WorldTopAndBottom +// Calculate texture boundaries +// and decide if floor or ceiling marks are needed. +// +static void R_WorldTopAndBottom(INT32 start, INT32 stop) +{ #ifdef ESLOPE // Figure out map coordinates of where start and end are mapping to on seg, so we can clip right for slope bullshit if (frontsector->hasslope || (backsector && backsector->hasslope)) // Commenting this out for FOFslop. -Red @@ -1895,14 +1823,6 @@ void R_StoreWallRange(INT32 start, INT32 stop) } } - -#define SLOPEPARAMS(slope, end1, end2, normalheight) \ - if (slope) { \ - end1 = P_GetZAt(slope, segleft.x, segleft.y); \ - end2 = P_GetZAt(slope, segright.x, segright.y); \ - } else \ - end1 = end2 = normalheight; - SLOPEPARAMS(frontsector->c_slope, worldtop, worldtopslope, frontsector->ceilingheight) SLOPEPARAMS(frontsector->f_slope, worldbottom, worldbottomslope, frontsector->floorheight) // subtract viewz from these to turn them into @@ -1915,60 +1835,350 @@ void R_StoreWallRange(INT32 start, INT32 stop) worldtop = frontsector->ceilingheight - viewz; worldbottom = frontsector->floorheight - viewz; #endif +} - midtexture = toptexture = bottomtexture = maskedtexture = 0; - ds_p->maskedtexturecol = NULL; - ds_p->numthicksides = numthicksides = 0; - ds_p->thicksidecol = NULL; - ds_p->tsilheight = 0; +// +// R_WorldSegTextured +// Calculate rw_offset. +// Only needed for textured lines. +// +static void R_WorldSegTextured(fixed_t hyp, boolean longboi) +{ + INT32 lightnum; + fixed_t sineval; + angle_t offsetangle = rw_normalangle-rw_angle1; - numbackffloors = 0; + if (offsetangle > ANGLE_180) + offsetangle = -(signed)offsetangle; + if (offsetangle > ANGLE_90) + offsetangle = ANGLE_90; - for (i = 0; i < MAXFFLOORS; i++) - ds_p->thicksides[i] = NULL; + sineval = FINESINE(offsetangle>>ANGLETOFINESHIFT); + rw_offset = FixedMul(hyp, sineval); - if (numffloors) + // big room fix + if (longboi) { - for (i = 0; i < numffloors; i++) + INT64 dx = (curline->v2->x)-(curline->v1->x); + INT64 dy = (curline->v2->y)-(curline->v1->y); + INT64 vdx = viewx-(curline->v1->x); + INT64 vdy = viewy-(curline->v1->y); + rw_offset = ((dx*vdx-dy*vdy))/(curline->length); + } + + if (rw_normalangle-rw_angle1 < ANGLE_180) + rw_offset = -rw_offset; + + /// don't use texture offset for splats + rw_offset2 = rw_offset + curline->offset; + rw_offset += sidedef->textureoffset + curline->offset; + rw_centerangle = ANGLE_90 + viewangle - rw_normalangle; + + // calculate light table + // use different light tables + // for horizontal / vertical / diagonal + // OPTIMIZE: get rid of LIGHTSEGSHIFT globally + lightnum = (frontsector->lightlevel >> LIGHTSEGSHIFT); + + if (curline->v1->y == curline->v2->y) + lightnum--; + else if (curline->v1->x == curline->v2->x) + lightnum++; + + if (lightnum < 0) + walllights = scalelight[0]; + else if (lightnum >= LIGHTLEVELS) + walllights = scalelight[LIGHTLEVELS - 1]; + else + walllights = scalelight[lightnum]; +} + +// +// R_CheckMaskedTextures +// Midtexture stuff, presumably. +// +static void R_CheckMaskedTextures(void) +{ + INT32 i = 0; + // allocate space for masked texture tables + if (frontsector && backsector && frontsector->tag != backsector->tag && (backsector->ffloors || frontsector->ffloors)) + { + ffloor_t *rover; + ffloor_t *r2; + fixed_t lowcut, highcut; +#ifdef ESLOPE + fixed_t lowcutslope, highcutslope; + + // Used for height comparisons and etc across FOFs and slopes + fixed_t high1, highslope1, low1, lowslope1, high2, highslope2, low2, lowslope2; +#endif + + //markceiling = markfloor = true; + maskedtexture = true; + + ds_p->thicksidecol = maskedtexturecol = lastopening - rw_x; + lastopening += rw_stopx - rw_x; + + lowcut = max(worldbottom, worldlow) + viewz; + highcut = min(worldtop, worldhigh) + viewz; +#ifdef ESLOPE + lowcutslope = max(worldbottomslope, worldlowslope) + viewz; + highcutslope = min(worldtopslope, worldhighslope) + viewz; +#endif + + if (frontsector->ffloors && backsector->ffloors) { -#ifdef POLYOBJECTS_PLANES - if (ffloor[i].polyobj && (!ds_p->curline->polyseg || ffloor[i].polyobj != ds_p->curline->polyseg)) - continue; -#endif + i = 0; + for (rover = backsector->ffloors; rover && i < MAXFFLOORS; rover = rover->next) + { + if (!(rover->flags & FF_RENDERSIDES) || !(rover->flags & FF_EXISTS)) + continue; + if (rover->flags & FF_INVERTSIDES) + continue; + + if (rover->norender == leveltime) + continue; #ifdef ESLOPE - if (ffloor[i].slope) { - ffloor[i].f_pos = P_GetZAt(ffloor[i].slope, segleft.x, segleft.y) - viewz; - ffloor[i].f_pos_slope = P_GetZAt(ffloor[i].slope, segright.x, segright.y) - viewz; - } else - ffloor[i].f_pos_slope = + SLOPEPARAMS(*rover->t_slope, high1, highslope1, *rover->topheight) + SLOPEPARAMS(*rover->b_slope, low1, lowslope1, *rover->bottomheight) + + if ((high1 < lowcut && highslope1 < lowcutslope) || (low1 > highcut && lowslope1 > highcutslope)) + continue; +#else + if (*rover->topheight < lowcut || *rover->bottomheight > highcut) + continue; #endif - ffloor[i].f_pos = ffloor[i].height - viewz; + + for (r2 = frontsector->ffloors; r2; r2 = r2->next) + { + if (!(r2->flags & FF_EXISTS) || !(r2->flags & FF_RENDERSIDES)) + continue; + + if (r2->norender == leveltime) + continue; + + if (rover->flags & FF_EXTRA) + { + if (!(r2->flags & FF_CUTEXTRA)) + continue; + + if (r2->flags & FF_EXTRA && (r2->flags & (FF_TRANSLUCENT|FF_FOG)) != (rover->flags & (FF_TRANSLUCENT|FF_FOG))) + continue; + } + else + { + if (!(r2->flags & FF_CUTSOLIDS)) + continue; + } + +#ifdef ESLOPE + SLOPEPARAMS(*r2->t_slope, high2, highslope2, *r2->topheight) + SLOPEPARAMS(*r2->b_slope, low2, lowslope2, *r2->bottomheight) + + if ((high2 < lowcut || highslope2 < lowcutslope) || (low2 > highcut || lowslope2 > highcutslope)) + continue; + if ((high1 > high2 || highslope1 > highslope2) || (low1 < low2 || lowslope1 < lowslope2)) + continue; +#else + if (*r2->topheight < lowcut || *r2->bottomheight > highcut) + continue; + if (*rover->topheight > *r2->topheight || *rover->bottomheight < *r2->bottomheight) + continue; +#endif + + break; + } + if (r2) + continue; + + ds_p->thicksides[i] = rover; + i++; + } + + for (rover = frontsector->ffloors; rover && i < MAXFFLOORS; rover = rover->next) + { + if (!(rover->flags & FF_RENDERSIDES) || !(rover->flags & FF_EXISTS)) + continue; + if (!(rover->flags & FF_ALLSIDES)) + continue; + + if (rover->norender == leveltime) + continue; + +#ifdef ESLOPE + SLOPEPARAMS(*rover->t_slope, high1, highslope1, *rover->topheight) + SLOPEPARAMS(*rover->b_slope, low1, lowslope1, *rover->bottomheight) + + if ((high1 < lowcut && highslope1 < lowcutslope) || (low1 > highcut && lowslope1 > highcutslope)) + continue; +#else + if (*rover->topheight < lowcut || *rover->bottomheight > highcut) + continue; +#endif + + for (r2 = backsector->ffloors; r2; r2 = r2->next) + { + if (!(r2->flags & FF_EXISTS) || !(r2->flags & FF_RENDERSIDES)) + continue; + + if (r2->norender == leveltime) + continue; + + if (rover->flags & FF_EXTRA) + { + if (!(r2->flags & FF_CUTEXTRA)) + continue; + + if (r2->flags & FF_EXTRA && (r2->flags & (FF_TRANSLUCENT|FF_FOG)) != (rover->flags & (FF_TRANSLUCENT|FF_FOG))) + continue; + } + else + { + if (!(r2->flags & FF_CUTSOLIDS)) + continue; + } + +#ifdef ESLOPE + SLOPEPARAMS(*r2->t_slope, high2, highslope2, *r2->topheight) + SLOPEPARAMS(*r2->b_slope, low2, lowslope2, *r2->bottomheight) + if ((high2 < lowcut || highslope2 < lowcutslope) || (low2 > highcut || lowslope2 > highcutslope)) + continue; + if ((high1 > high2 || highslope1 > highslope2) || (low1 < low2 || lowslope1 < lowslope2)) + continue; +#else + if (*r2->topheight < lowcut || *r2->bottomheight > highcut) + continue; + if (*rover->topheight > *r2->topheight || *rover->bottomheight < *r2->bottomheight) + continue; +#endif + + break; + } + if (r2) + continue; + + ds_p->thicksides[i] = rover; + i++; + } } - } + else if (backsector->ffloors) + { + for (rover = backsector->ffloors, i = 0; rover && i < MAXFFLOORS; rover = rover->next) + { + if (!(rover->flags & FF_RENDERSIDES) || !(rover->flags & FF_EXISTS) || rover->flags & FF_INVERTSIDES) + continue; + if (rover->norender == leveltime) + continue; #ifdef ESLOPE - // Set up texture Y offset slides for sloped walls - rw_toptextureslide = rw_midtextureslide = rw_bottomtextureslide = 0; - ceilingfrontslide = floorfrontslide = ceilingbackslide = floorbackslide = 0; - - { - angle_t lineangle = R_PointToAngle2(curline->v1->x, curline->v1->y, curline->v2->x, curline->v2->y); - - if (frontsector->f_slope) - floorfrontslide = FixedMul(frontsector->f_slope->zdelta, FINECOSINE((lineangle-frontsector->f_slope->xydirection)>>ANGLETOFINESHIFT)); - - if (frontsector->c_slope) - ceilingfrontslide = FixedMul(frontsector->c_slope->zdelta, FINECOSINE((lineangle-frontsector->c_slope->xydirection)>>ANGLETOFINESHIFT)); - - if (backsector && backsector->f_slope) - floorbackslide = FixedMul(backsector->f_slope->zdelta, FINECOSINE((lineangle-backsector->f_slope->xydirection)>>ANGLETOFINESHIFT)); - - if (backsector && backsector->c_slope) - ceilingbackslide = FixedMul(backsector->c_slope->zdelta, FINECOSINE((lineangle-backsector->c_slope->xydirection)>>ANGLETOFINESHIFT)); - } + // Oy vey. + if (( (*rover->t_slope ? P_GetZAt(*rover->t_slope, segleft.x, segleft.y) : *rover->topheight) <= worldbottom+viewz + && (*rover->t_slope ? P_GetZAt(*rover->t_slope, segright.x, segright.y) : *rover->topheight) <= worldbottomslope+viewz) + ||((*rover->b_slope ? P_GetZAt(*rover->b_slope, segleft.x, segleft.y) : *rover->bottomheight) >= worldtop+viewz + && (*rover->b_slope ? P_GetZAt(*rover->b_slope, segright.x, segright.y) : *rover->bottomheight) >= worldtopslope+viewz)) + continue; +#else + if (*rover->topheight <= frontsector->floorheight || *rover->bottomheight >= frontsector->ceilingheight) + continue; #endif + ds_p->thicksides[i] = rover; + i++; + } + } + else if (frontsector->ffloors) + { + for (rover = frontsector->ffloors, i = 0; rover && i < MAXFFLOORS; rover = rover->next) + { + if (!(rover->flags & FF_RENDERSIDES) || !(rover->flags & FF_EXISTS) || !(rover->flags & FF_ALLSIDES)) + continue; + if (rover->norender == leveltime) + continue; +#ifdef ESLOPE + // Oy vey. + if (( (*rover->t_slope ? P_GetZAt(*rover->t_slope, segleft.x, segleft.y) : *rover->topheight) <= worldbottom+viewz + && (*rover->t_slope ? P_GetZAt(*rover->t_slope, segright.x, segright.y) : *rover->topheight) <= worldbottomslope+viewz) + ||((*rover->b_slope ? P_GetZAt(*rover->b_slope, segleft.x, segleft.y) : *rover->bottomheight) >= worldtop+viewz + && (*rover->b_slope ? P_GetZAt(*rover->b_slope, segright.x, segright.y) : *rover->bottomheight) >= worldtopslope+viewz)) + continue; + + if (( (*rover->t_slope ? P_GetZAt(*rover->t_slope, segleft.x, segleft.y) : *rover->topheight) <= worldlow+viewz + && (*rover->t_slope ? P_GetZAt(*rover->t_slope, segright.x, segright.y) : *rover->topheight) <= worldlowslope+viewz) + ||((*rover->b_slope ? P_GetZAt(*rover->b_slope, segleft.x, segleft.y) : *rover->bottomheight) >= worldhigh+viewz + && (*rover->b_slope ? P_GetZAt(*rover->b_slope, segright.x, segright.y) : *rover->bottomheight) >= worldhighslope+viewz)) + continue; +#else + if (*rover->topheight <= frontsector->floorheight || *rover->bottomheight >= frontsector->ceilingheight) + continue; + if (*rover->topheight <= backsector->floorheight || *rover->bottomheight >= backsector->ceilingheight) + continue; +#endif + + ds_p->thicksides[i] = rover; + i++; + } + } + + ds_p->numthicksides = numthicksides = i; + } + + if (sidedef->midtexture > 0 && sidedef->midtexture < numtextures) + { + // masked midtexture + if (!ds_p->thicksidecol) + { + ds_p->maskedtexturecol = maskedtexturecol = lastopening - rw_x; + lastopening += rw_stopx - rw_x; + } + else + ds_p->maskedtexturecol = ds_p->thicksidecol; + +#ifdef ESLOPE + maskedtextureheight = ds_p->maskedtextureheight; // note to red, this == &(ds_p->maskedtextureheight[0]) + +#ifdef POLYOBJECTS + if (curline->polyseg) { // use REAL front and back floors please, so midtexture rendering isn't mucked up + rw_midtextureslide = rw_midtexturebackslide = 0; + if (!!(linedef->flags & ML_DONTPEGBOTTOM) ^ !!(linedef->flags & ML_EFFECT3)) + rw_midtexturemid = rw_midtextureback = max(curline->frontsector->floorheight, curline->backsector->floorheight) - viewz; + else + rw_midtexturemid = rw_midtextureback = min(curline->frontsector->ceilingheight, curline->backsector->ceilingheight) - viewz; + } else +#endif + // Set midtexture starting height + if (linedef->flags & ML_EFFECT2) { // Ignore slopes when texturing + rw_midtextureslide = rw_midtexturebackslide = 0; + if (!!(linedef->flags & ML_DONTPEGBOTTOM) ^ !!(linedef->flags & ML_EFFECT3)) + rw_midtexturemid = rw_midtextureback = max(frontsector->floorheight, backsector->floorheight) - viewz; + else + rw_midtexturemid = rw_midtextureback = min(frontsector->ceilingheight, backsector->ceilingheight) - viewz; + + } else if (!!(linedef->flags & ML_DONTPEGBOTTOM) ^ !!(linedef->flags & ML_EFFECT3)) { + rw_midtexturemid = worldbottom; + rw_midtextureslide = floorfrontslide; + rw_midtextureback = worldlow; + rw_midtexturebackslide = floorbackslide; + } else { + rw_midtexturemid = worldtop; + rw_midtextureslide = ceilingfrontslide; + rw_midtextureback = worldhigh; + rw_midtexturebackslide = ceilingbackslide; + } + rw_midtexturemid += sidedef->rowoffset; + rw_midtextureback += sidedef->rowoffset; +#endif + + maskedtexture = true; + } +} + +// +// R_CheckWallTextures +// Self-explanatory, I hope?! +// +static void R_CheckWallTextures(void) +{ if (!backsector) { fixed_t texheight; @@ -2006,7 +2216,113 @@ void R_StoreWallRange(INT32 start, INT32 stop) #endif } rw_midtexturemid += sidedef->rowoffset; + } + else + { + // check TOP TEXTURE + if (!bothceilingssky // never draw the top texture if on + && (worldhigh < worldtop +#ifdef ESLOPE + || worldhighslope < worldtopslope +#endif + )) + { + fixed_t texheight; + // top texture + if ((linedef->flags & (ML_DONTPEGTOP) && (linedef->flags & ML_DONTPEGBOTTOM)) + && linedef->sidenum[1] != 0xffff) + { + // Special case... use offsets from 2nd side but only if it has a texture. + side_t *def = &sides[linedef->sidenum[1]]; + toptexture = R_GetTextureNum(def->toptexture); + if (!toptexture) //Second side has no texture, use the first side's instead. + toptexture = R_GetTextureNum(sidedef->toptexture); + texheight = textureheight[toptexture]; + } + else + { + toptexture = R_GetTextureNum(sidedef->toptexture); + texheight = textureheight[toptexture]; + } +#ifdef ESLOPE + if (!(linedef->flags & ML_EFFECT1)) { // Ignore slopes for lower/upper textures unless flag is checked + if (linedef->flags & ML_DONTPEGTOP) + rw_toptexturemid = frontsector->ceilingheight - viewz; + else + rw_toptexturemid = backsector->ceilingheight - viewz; + } else +#endif + if (linedef->flags & ML_DONTPEGTOP) + { + // top of texture at top + rw_toptexturemid = worldtop; +#ifdef ESLOPE + rw_toptextureslide = ceilingfrontslide; +#endif + } + else + { +#ifdef ESLOPE + rw_toptexturemid = worldhigh + texheight; + rw_toptextureslide = ceilingbackslide; +#else + vtop = backsector->ceilingheight + texheight; + // bottom of texture + rw_toptexturemid = vtop - viewz; +#endif + } + } + // check BOTTOM TEXTURE + if (!bothfloorssky // never draw the bottom texture if on + && (worldlow > worldbottom +#ifdef ESLOPE + || worldlowslope > worldbottomslope +#endif + )) //seulement si VISIBLE!!! + { + // bottom texture + bottomtexture = R_GetTextureNum(sidedef->bottomtexture); + +#ifdef ESLOPE + if (!(linedef->flags & ML_EFFECT1)) { // Ignore slopes for lower/upper textures unless flag is checked + if (linedef->flags & ML_DONTPEGBOTTOM) + rw_bottomtexturemid = frontsector->floorheight - viewz; + else + rw_bottomtexturemid = backsector->floorheight - viewz; + } else +#endif + if (linedef->flags & ML_DONTPEGBOTTOM) + { + // bottom of texture at bottom + // top of texture at top + rw_bottomtexturemid = worldbottom; +#ifdef ESLOPE + rw_bottomtextureslide = floorfrontslide; +#endif + } + else { // top of texture at top + rw_bottomtexturemid = worldlow; +#ifdef ESLOPE + rw_bottomtextureslide = floorbackslide; +#endif + } + } + + rw_toptexturemid += sidedef->rowoffset; + rw_bottomtexturemid += sidedef->rowoffset; + } +} + +// +// R_StoreWallSilhouette +// Sets the silhouette for the current seg. +// Also checks if any floors or ceilings have to be marked. +// +static void R_StoreWallSilhouette(void) +{ + if (!backsector) + { ds_p->silhouette = SIL_BOTH; ds_p->sprtopclip = screenheightarray; ds_p->sprbottomclip = negonearray; @@ -2016,8 +2332,8 @@ void R_StoreWallRange(INT32 start, INT32 stop) else { // two sided line - boolean bothceilingssky = false; // turned on if both back and front ceilings are sky - boolean bothfloorssky = false; // likewise, but for floors + bothceilingssky = false; // turned on if both back and front ceilings are sky + bothfloorssky = false; // likewise, but for floors #ifdef ESLOPE SLOPEPARAMS(backsector->c_slope, worldhigh, worldhighslope, backsector->ceilingheight) @@ -2240,460 +2556,22 @@ void R_StoreWallRange(INT32 start, INT32 stop) markceiling = markfloor = true; } } - - // check TOP TEXTURE - if (!bothceilingssky // never draw the top texture if on - && (worldhigh < worldtop -#ifdef ESLOPE - || worldhighslope < worldtopslope -#endif - )) - { - fixed_t texheight; - // top texture - if ((linedef->flags & (ML_DONTPEGTOP) && (linedef->flags & ML_DONTPEGBOTTOM)) - && linedef->sidenum[1] != 0xffff) - { - // Special case... use offsets from 2nd side but only if it has a texture. - side_t *def = &sides[linedef->sidenum[1]]; - toptexture = R_GetTextureNum(def->toptexture); - - if (!toptexture) //Second side has no texture, use the first side's instead. - toptexture = R_GetTextureNum(sidedef->toptexture); - texheight = textureheight[toptexture]; - } - else - { - toptexture = R_GetTextureNum(sidedef->toptexture); - texheight = textureheight[toptexture]; - } -#ifdef ESLOPE - if (!(linedef->flags & ML_EFFECT1)) { // Ignore slopes for lower/upper textures unless flag is checked - if (linedef->flags & ML_DONTPEGTOP) - rw_toptexturemid = frontsector->ceilingheight - viewz; - else - rw_toptexturemid = backsector->ceilingheight - viewz; - } else -#endif - if (linedef->flags & ML_DONTPEGTOP) - { - // top of texture at top - rw_toptexturemid = worldtop; -#ifdef ESLOPE - rw_toptextureslide = ceilingfrontslide; -#endif - } - else - { -#ifdef ESLOPE - rw_toptexturemid = worldhigh + texheight; - rw_toptextureslide = ceilingbackslide; -#else - vtop = backsector->ceilingheight + texheight; - // bottom of texture - rw_toptexturemid = vtop - viewz; -#endif - } - } - // check BOTTOM TEXTURE - if (!bothfloorssky // never draw the bottom texture if on - && (worldlow > worldbottom -#ifdef ESLOPE - || worldlowslope > worldbottomslope -#endif - )) //seulement si VISIBLE!!! - { - // bottom texture - bottomtexture = R_GetTextureNum(sidedef->bottomtexture); - -#ifdef ESLOPE - if (!(linedef->flags & ML_EFFECT1)) { // Ignore slopes for lower/upper textures unless flag is checked - if (linedef->flags & ML_DONTPEGBOTTOM) - rw_bottomtexturemid = frontsector->floorheight - viewz; - else - rw_bottomtexturemid = backsector->floorheight - viewz; - } else -#endif - if (linedef->flags & ML_DONTPEGBOTTOM) - { - // bottom of texture at bottom - // top of texture at top - rw_bottomtexturemid = worldbottom; -#ifdef ESLOPE - rw_bottomtextureslide = floorfrontslide; -#endif - } - else { // top of texture at top - rw_bottomtexturemid = worldlow; -#ifdef ESLOPE - rw_bottomtextureslide = floorbackslide; -#endif - } - } - - rw_toptexturemid += sidedef->rowoffset; - rw_bottomtexturemid += sidedef->rowoffset; - - // allocate space for masked texture tables - if (frontsector && backsector && frontsector->tag != backsector->tag && (backsector->ffloors || frontsector->ffloors)) - { - ffloor_t *rover; - ffloor_t *r2; - fixed_t lowcut, highcut; -#ifdef ESLOPE - fixed_t lowcutslope, highcutslope; - - // Used for height comparisons and etc across FOFs and slopes - fixed_t high1, highslope1, low1, lowslope1, high2, highslope2, low2, lowslope2; -#endif - - //markceiling = markfloor = true; - maskedtexture = true; - - ds_p->thicksidecol = maskedtexturecol = lastopening - rw_x; - lastopening += rw_stopx - rw_x; - - lowcut = max(worldbottom, worldlow) + viewz; - highcut = min(worldtop, worldhigh) + viewz; -#ifdef ESLOPE - lowcutslope = max(worldbottomslope, worldlowslope) + viewz; - highcutslope = min(worldtopslope, worldhighslope) + viewz; -#endif - - if (frontsector->ffloors && backsector->ffloors) - { - i = 0; - for (rover = backsector->ffloors; rover && i < MAXFFLOORS; rover = rover->next) - { - if (!(rover->flags & FF_RENDERSIDES) || !(rover->flags & FF_EXISTS)) - continue; - if (rover->flags & FF_INVERTSIDES) - continue; - - if (rover->norender == leveltime) - continue; - -#ifdef ESLOPE - SLOPEPARAMS(*rover->t_slope, high1, highslope1, *rover->topheight) - SLOPEPARAMS(*rover->b_slope, low1, lowslope1, *rover->bottomheight) - - if ((high1 < lowcut && highslope1 < lowcutslope) || (low1 > highcut && lowslope1 > highcutslope)) - continue; -#else - if (*rover->topheight < lowcut || *rover->bottomheight > highcut) - continue; -#endif - - for (r2 = frontsector->ffloors; r2; r2 = r2->next) - { - if (!(r2->flags & FF_EXISTS) || !(r2->flags & FF_RENDERSIDES)) - continue; - - if (r2->norender == leveltime) - continue; - - if (rover->flags & FF_EXTRA) - { - if (!(r2->flags & FF_CUTEXTRA)) - continue; - - if (r2->flags & FF_EXTRA && (r2->flags & (FF_TRANSLUCENT|FF_FOG)) != (rover->flags & (FF_TRANSLUCENT|FF_FOG))) - continue; - } - else - { - if (!(r2->flags & FF_CUTSOLIDS)) - continue; - } - -#ifdef ESLOPE - SLOPEPARAMS(*r2->t_slope, high2, highslope2, *r2->topheight) - SLOPEPARAMS(*r2->b_slope, low2, lowslope2, *r2->bottomheight) - - if ((high2 < lowcut || highslope2 < lowcutslope) || (low2 > highcut || lowslope2 > highcutslope)) - continue; - if ((high1 > high2 || highslope1 > highslope2) || (low1 < low2 || lowslope1 < lowslope2)) - continue; -#else - if (*r2->topheight < lowcut || *r2->bottomheight > highcut) - continue; - if (*rover->topheight > *r2->topheight || *rover->bottomheight < *r2->bottomheight) - continue; -#endif - - break; - } - if (r2) - continue; - - ds_p->thicksides[i] = rover; - i++; - } - - for (rover = frontsector->ffloors; rover && i < MAXFFLOORS; rover = rover->next) - { - if (!(rover->flags & FF_RENDERSIDES) || !(rover->flags & FF_EXISTS)) - continue; - if (!(rover->flags & FF_ALLSIDES)) - continue; - - if (rover->norender == leveltime) - continue; - -#ifdef ESLOPE - SLOPEPARAMS(*rover->t_slope, high1, highslope1, *rover->topheight) - SLOPEPARAMS(*rover->b_slope, low1, lowslope1, *rover->bottomheight) - - if ((high1 < lowcut && highslope1 < lowcutslope) || (low1 > highcut && lowslope1 > highcutslope)) - continue; -#else - if (*rover->topheight < lowcut || *rover->bottomheight > highcut) - continue; -#endif - - for (r2 = backsector->ffloors; r2; r2 = r2->next) - { - if (!(r2->flags & FF_EXISTS) || !(r2->flags & FF_RENDERSIDES)) - continue; - - if (r2->norender == leveltime) - continue; - - if (rover->flags & FF_EXTRA) - { - if (!(r2->flags & FF_CUTEXTRA)) - continue; - - if (r2->flags & FF_EXTRA && (r2->flags & (FF_TRANSLUCENT|FF_FOG)) != (rover->flags & (FF_TRANSLUCENT|FF_FOG))) - continue; - } - else - { - if (!(r2->flags & FF_CUTSOLIDS)) - continue; - } - -#ifdef ESLOPE - SLOPEPARAMS(*r2->t_slope, high2, highslope2, *r2->topheight) - SLOPEPARAMS(*r2->b_slope, low2, lowslope2, *r2->bottomheight) -#undef SLOPEPARAMS - if ((high2 < lowcut || highslope2 < lowcutslope) || (low2 > highcut || lowslope2 > highcutslope)) - continue; - if ((high1 > high2 || highslope1 > highslope2) || (low1 < low2 || lowslope1 < lowslope2)) - continue; -#else - if (*r2->topheight < lowcut || *r2->bottomheight > highcut) - continue; - if (*rover->topheight > *r2->topheight || *rover->bottomheight < *r2->bottomheight) - continue; -#endif - - break; - } - if (r2) - continue; - - ds_p->thicksides[i] = rover; - i++; - } - } - else if (backsector->ffloors) - { - for (rover = backsector->ffloors, i = 0; rover && i < MAXFFLOORS; rover = rover->next) - { - if (!(rover->flags & FF_RENDERSIDES) || !(rover->flags & FF_EXISTS) || rover->flags & FF_INVERTSIDES) - continue; - if (rover->norender == leveltime) - continue; - -#ifdef ESLOPE - // Oy vey. - if (( (*rover->t_slope ? P_GetZAt(*rover->t_slope, segleft.x, segleft.y) : *rover->topheight) <= worldbottom+viewz - && (*rover->t_slope ? P_GetZAt(*rover->t_slope, segright.x, segright.y) : *rover->topheight) <= worldbottomslope+viewz) - ||((*rover->b_slope ? P_GetZAt(*rover->b_slope, segleft.x, segleft.y) : *rover->bottomheight) >= worldtop+viewz - && (*rover->b_slope ? P_GetZAt(*rover->b_slope, segright.x, segright.y) : *rover->bottomheight) >= worldtopslope+viewz)) - continue; -#else - if (*rover->topheight <= frontsector->floorheight || *rover->bottomheight >= frontsector->ceilingheight) - continue; -#endif - - ds_p->thicksides[i] = rover; - i++; - } - } - else if (frontsector->ffloors) - { - for (rover = frontsector->ffloors, i = 0; rover && i < MAXFFLOORS; rover = rover->next) - { - if (!(rover->flags & FF_RENDERSIDES) || !(rover->flags & FF_EXISTS) || !(rover->flags & FF_ALLSIDES)) - continue; - if (rover->norender == leveltime) - continue; -#ifdef ESLOPE - // Oy vey. - if (( (*rover->t_slope ? P_GetZAt(*rover->t_slope, segleft.x, segleft.y) : *rover->topheight) <= worldbottom+viewz - && (*rover->t_slope ? P_GetZAt(*rover->t_slope, segright.x, segright.y) : *rover->topheight) <= worldbottomslope+viewz) - ||((*rover->b_slope ? P_GetZAt(*rover->b_slope, segleft.x, segleft.y) : *rover->bottomheight) >= worldtop+viewz - && (*rover->b_slope ? P_GetZAt(*rover->b_slope, segright.x, segright.y) : *rover->bottomheight) >= worldtopslope+viewz)) - continue; - - if (( (*rover->t_slope ? P_GetZAt(*rover->t_slope, segleft.x, segleft.y) : *rover->topheight) <= worldlow+viewz - && (*rover->t_slope ? P_GetZAt(*rover->t_slope, segright.x, segright.y) : *rover->topheight) <= worldlowslope+viewz) - ||((*rover->b_slope ? P_GetZAt(*rover->b_slope, segleft.x, segleft.y) : *rover->bottomheight) >= worldhigh+viewz - && (*rover->b_slope ? P_GetZAt(*rover->b_slope, segright.x, segright.y) : *rover->bottomheight) >= worldhighslope+viewz)) - continue; -#else - if (*rover->topheight <= frontsector->floorheight || *rover->bottomheight >= frontsector->ceilingheight) - continue; - if (*rover->topheight <= backsector->floorheight || *rover->bottomheight >= backsector->ceilingheight) - continue; -#endif - - ds_p->thicksides[i] = rover; - i++; - } - } - - ds_p->numthicksides = numthicksides = i; - } - if (sidedef->midtexture > 0 && sidedef->midtexture < numtextures) - { - // masked midtexture - if (!ds_p->thicksidecol) - { - ds_p->maskedtexturecol = maskedtexturecol = lastopening - rw_x; - lastopening += rw_stopx - rw_x; - } - else - ds_p->maskedtexturecol = ds_p->thicksidecol; - -#ifdef ESLOPE - maskedtextureheight = ds_p->maskedtextureheight; // note to red, this == &(ds_p->maskedtextureheight[0]) - -#ifdef POLYOBJECTS - if (curline->polyseg) { // use REAL front and back floors please, so midtexture rendering isn't mucked up - rw_midtextureslide = rw_midtexturebackslide = 0; - if (!!(linedef->flags & ML_DONTPEGBOTTOM) ^ !!(linedef->flags & ML_EFFECT3)) - rw_midtexturemid = rw_midtextureback = max(curline->frontsector->floorheight, curline->backsector->floorheight) - viewz; - else - rw_midtexturemid = rw_midtextureback = min(curline->frontsector->ceilingheight, curline->backsector->ceilingheight) - viewz; - } else -#endif - // Set midtexture starting height - if (linedef->flags & ML_EFFECT2) { // Ignore slopes when texturing - rw_midtextureslide = rw_midtexturebackslide = 0; - if (!!(linedef->flags & ML_DONTPEGBOTTOM) ^ !!(linedef->flags & ML_EFFECT3)) - rw_midtexturemid = rw_midtextureback = max(frontsector->floorheight, backsector->floorheight) - viewz; - else - rw_midtexturemid = rw_midtextureback = min(frontsector->ceilingheight, backsector->ceilingheight) - viewz; - - } else if (!!(linedef->flags & ML_DONTPEGBOTTOM) ^ !!(linedef->flags & ML_EFFECT3)) { - rw_midtexturemid = worldbottom; - rw_midtextureslide = floorfrontslide; - rw_midtextureback = worldlow; - rw_midtexturebackslide = floorbackslide; - } else { - rw_midtexturemid = worldtop; - rw_midtextureslide = ceilingfrontslide; - rw_midtextureback = worldhigh; - rw_midtexturebackslide = ceilingbackslide; - } - rw_midtexturemid += sidedef->rowoffset; - rw_midtextureback += sidedef->rowoffset; -#endif - - maskedtexture = true; - } } +} - // calculate rw_offset (only needed for textured lines) - segtextured = midtexture || toptexture || bottomtexture || maskedtexture || (numthicksides > 0); - - if (segtextured) - { - offsetangle = rw_normalangle-rw_angle1; - - if (offsetangle > ANGLE_180) - offsetangle = -(signed)offsetangle; - - if (offsetangle > ANGLE_90) - offsetangle = ANGLE_90; - - sineval = FINESINE(offsetangle>>ANGLETOFINESHIFT); - rw_offset = FixedMul(hyp, sineval); - - // big room fix - if (longboi) - { - INT64 dx = (curline->v2->x)-(curline->v1->x); - INT64 dy = (curline->v2->y)-(curline->v1->y); - INT64 vdx = viewx-(curline->v1->x); - INT64 vdy = viewy-(curline->v1->y); - rw_offset = ((dx*vdx-dy*vdy))/(curline->length); - } - - if (rw_normalangle-rw_angle1 < ANGLE_180) - rw_offset = -rw_offset; - - /// don't use texture offset for splats - rw_offset2 = rw_offset + curline->offset; - rw_offset += sidedef->textureoffset + curline->offset; - rw_centerangle = ANGLE_90 + viewangle - rw_normalangle; - - // calculate light table - // use different light tables - // for horizontal / vertical / diagonal - // OPTIMIZE: get rid of LIGHTSEGSHIFT globally - lightnum = (frontsector->lightlevel >> LIGHTSEGSHIFT); - - if (curline->v1->y == curline->v2->y) - lightnum--; - else if (curline->v1->x == curline->v2->x) - lightnum++; - - if (lightnum < 0) - walllights = scalelight[0]; - else if (lightnum >= LIGHTLEVELS) - walllights = scalelight[LIGHTLEVELS - 1]; - else - walllights = scalelight[lightnum]; - } - - // if a floor / ceiling plane is on the wrong side - // of the view plane, it is definitely invisible - // and doesn't need to be marked. - if (frontsector->heightsec == -1) - { - if (frontsector->floorpic != skyflatnum - && ( -#ifdef ESLOPE - frontsector->f_slope ? P_GetZAt(frontsector->f_slope, viewx, viewy) : -#endif - frontsector->floorheight) >= viewz) - { - // above view plane - markfloor = false; - } - - if (frontsector->ceilingpic != skyflatnum - && ( -#ifdef ESLOPE - frontsector->c_slope ? P_GetZAt(frontsector->c_slope, viewx, viewy) : -#endif - frontsector->ceilingheight) <= viewz) - { - // below view plane - markceiling = false; - } - } - - // calculate incremental stepping values for texture edges +// +// R_WorldStep +// Does... stepping... stuff? +// +static void R_WorldStep(INT32 range) +{ worldtop >>= 4; worldbottom >>= 4; #ifdef ESLOPE worldtopslope >>= 4; worldbottomslope >>= 4; +#else + (void)range; #endif if (linedef->special == HORIZONSPECIAL) { // HORIZON LINES @@ -2718,6 +2596,329 @@ void R_StoreWallRange(INT32 start, INT32 stop) } #endif } +} + +// +// R_WorldBackStep +// Does... stepping... stuff? For backsides?!?!?!?!?!?! +// +static void R_WorldBackStep(INT32 range) +{ + INT32 i; + + worldhigh >>= 4; + worldlow >>= 4; +#ifdef ESLOPE + worldhighslope >>= 4; + worldlowslope >>= 4; +#else + (void)range; +#endif + + if (toptexture) + { + pixhigh = (centeryfrac>>4) - FixedMul (worldhigh, rw_scale); + pixhighstep = -FixedMul (rw_scalestep,worldhigh); + +#ifdef ESLOPE + if (backsector->c_slope) { + fixed_t topfracend = (centeryfrac>>4) - FixedMul (worldhighslope, ds_p->scale2); + pixhighstep = (topfracend-pixhigh)/(range); + } +#endif + } + + if (bottomtexture) + { + pixlow = (centeryfrac>>4) - FixedMul (worldlow, rw_scale); + pixlowstep = -FixedMul (rw_scalestep,worldlow); +#ifdef ESLOPE + if (backsector->f_slope) { + fixed_t bottomfracend = (centeryfrac>>4) - FixedMul (worldlowslope, ds_p->scale2); + pixlowstep = (bottomfracend-pixlow)/(range); + } +#endif + } + + { + ffloor_t * rover; +#ifdef ESLOPE + fixed_t roverleft, roverright; + fixed_t planevistest; +#endif + i = 0; + + if (backsector->ffloors) + { + for (rover = backsector->ffloors; rover && i < MAXFFLOORS; rover = rover->next) + { + if (!(rover->flags & FF_EXISTS) || !(rover->flags & FF_RENDERPLANES)) + continue; + if (rover->norender == leveltime) + continue; + +#ifdef ESLOPE + // Let the renderer know this sector is sloped. + if (*rover->b_slope || *rover->t_slope) + backsector->hasslope = true; + + roverleft = (*rover->b_slope ? P_GetZAt(*rover->b_slope, segleft.x, segleft.y) : *rover->bottomheight) - viewz; + roverright = (*rover->b_slope ? P_GetZAt(*rover->b_slope, segright.x, segright.y) : *rover->bottomheight) - viewz; + planevistest = (*rover->b_slope ? P_GetZAt(*rover->b_slope, viewx, viewy) : *rover->bottomheight); + + if ((roverleft>>4 <= worldhigh || roverright>>4 <= worldhighslope) && + (roverleft>>4 >= worldlow || roverright>>4 >= worldlowslope) && + ((viewz < planevistest && !(rover->flags & FF_INVERTPLANES)) || + (viewz > planevistest && (rover->flags & FF_BOTHPLANES)))) + { + //ffloor[i].slope = *rover->b_slope; + ffloor[i].b_pos = roverleft; + ffloor[i].b_pos_slope = roverright; + ffloor[i].b_pos >>= 4; + ffloor[i].b_pos_slope >>= 4; + ffloor[i].b_frac = (centeryfrac >> 4) - FixedMul(ffloor[i].b_pos, rw_scale); + ffloor[i].b_step = (centeryfrac >> 4) - FixedMul(ffloor[i].b_pos_slope, ds_p->scale2); + ffloor[i].b_step = (ffloor[i].b_step-ffloor[i].b_frac)/(range); + i++; + } + + if (i >= MAXFFLOORS) + break; + + roverleft = (*rover->t_slope ? P_GetZAt(*rover->t_slope, segleft.x, segleft.y) : *rover->topheight) - viewz; + roverright = (*rover->t_slope ? P_GetZAt(*rover->t_slope, segright.x, segright.y) : *rover->topheight) - viewz; + planevistest = (*rover->t_slope ? P_GetZAt(*rover->t_slope, viewx, viewy) : *rover->topheight); + + if ((roverleft>>4 <= worldhigh || roverright>>4 <= worldhighslope) && + (roverleft>>4 >= worldlow || roverright>>4 >= worldlowslope) && + ((viewz > planevistest && !(rover->flags & FF_INVERTPLANES)) || + (viewz < planevistest && (rover->flags & FF_BOTHPLANES)))) + { + //ffloor[i].slope = *rover->t_slope; + ffloor[i].b_pos = roverleft; + ffloor[i].b_pos_slope = roverright; + ffloor[i].b_pos >>= 4; + ffloor[i].b_pos_slope >>= 4; + ffloor[i].b_frac = (centeryfrac >> 4) - FixedMul(ffloor[i].b_pos, rw_scale); + ffloor[i].b_step = (centeryfrac >> 4) - FixedMul(ffloor[i].b_pos_slope, ds_p->scale2); + ffloor[i].b_step = (ffloor[i].b_step-ffloor[i].b_frac)/(range); + i++; + } +#else + if (*rover->bottomheight <= backsector->ceilingheight && + *rover->bottomheight >= backsector->floorheight && + ((viewz < *rover->bottomheight && !(rover->flags & FF_INVERTPLANES)) || + (viewz > *rover->bottomheight && (rover->flags & FF_BOTHPLANES)))) + { + ffloor[i].b_pos = *rover->bottomheight; + ffloor[i].b_pos = (ffloor[i].b_pos - viewz) >> 4; + ffloor[i].b_step = FixedMul(-rw_scalestep, ffloor[i].b_pos); + ffloor[i].b_frac = (centeryfrac >> 4) - FixedMul(ffloor[i].b_pos, rw_scale); + i++; + } + + if (i >= MAXFFLOORS) + break; + + if (*rover->topheight >= backsector->floorheight && + *rover->topheight <= backsector->ceilingheight && + ((viewz > *rover->topheight && !(rover->flags & FF_INVERTPLANES)) || + (viewz < *rover->topheight && (rover->flags & FF_BOTHPLANES)))) + { + ffloor[i].b_pos = *rover->topheight; + ffloor[i].b_pos = (ffloor[i].b_pos - viewz) >> 4; + ffloor[i].b_step = FixedMul(-rw_scalestep, ffloor[i].b_pos); + ffloor[i].b_frac = (centeryfrac >> 4) - FixedMul(ffloor[i].b_pos, rw_scale); + i++; + } +#endif + } + } + else if (frontsector && frontsector->ffloors) + { + for (rover = frontsector->ffloors; rover && i < MAXFFLOORS; rover = rover->next) + { + if (!(rover->flags & FF_EXISTS) || !(rover->flags & FF_RENDERPLANES)) + continue; + if (rover->norender == leveltime) + continue; + + +#ifdef ESLOPE + // Let the renderer know this sector is sloped. + if (*rover->b_slope || *rover->t_slope) + frontsector->hasslope = true; + + roverleft = (*rover->b_slope ? P_GetZAt(*rover->b_slope, segleft.x, segleft.y) : *rover->bottomheight) - viewz; + roverright = (*rover->b_slope ? P_GetZAt(*rover->b_slope, segright.x, segright.y) : *rover->bottomheight) - viewz; + planevistest = (*rover->b_slope ? P_GetZAt(*rover->b_slope, viewx, viewy) : *rover->bottomheight); + + if ((roverleft>>4 <= worldhigh || roverright>>4 <= worldhighslope) && + (roverleft>>4 >= worldlow || roverright>>4 >= worldlowslope) && + ((viewz < planevistest && !(rover->flags & FF_INVERTPLANES)) || + (viewz > planevistest && (rover->flags & FF_BOTHPLANES)))) + { + //ffloor[i].slope = *rover->b_slope; + ffloor[i].b_pos = roverleft; + ffloor[i].b_pos_slope = roverright; + ffloor[i].b_pos >>= 4; + ffloor[i].b_pos_slope >>= 4; + ffloor[i].b_frac = (centeryfrac >> 4) - FixedMul(ffloor[i].b_pos, rw_scale); + ffloor[i].b_step = (centeryfrac >> 4) - FixedMul(ffloor[i].b_pos_slope, ds_p->scale2); + ffloor[i].b_step = (ffloor[i].b_step-ffloor[i].b_frac)/(range); + i++; + } + + if (i >= MAXFFLOORS) + break; + + roverleft = (*rover->t_slope ? P_GetZAt(*rover->t_slope, segleft.x, segleft.y) : *rover->topheight) - viewz; + roverright = (*rover->t_slope ? P_GetZAt(*rover->t_slope, segright.x, segright.y) : *rover->topheight) - viewz; + planevistest = (*rover->t_slope ? P_GetZAt(*rover->t_slope, viewx, viewy) : *rover->topheight); + + if ((roverleft>>4 <= worldhigh || roverright>>4 <= worldhighslope) && + (roverleft>>4 >= worldlow || roverright>>4 >= worldlowslope) && + ((viewz > planevistest && !(rover->flags & FF_INVERTPLANES)) || + (viewz < planevistest && (rover->flags & FF_BOTHPLANES)))) + { + //ffloor[i].slope = *rover->t_slope; + ffloor[i].b_pos = roverleft; + ffloor[i].b_pos_slope = roverright; + ffloor[i].b_pos >>= 4; + ffloor[i].b_pos_slope >>= 4; + ffloor[i].b_frac = (centeryfrac >> 4) - FixedMul(ffloor[i].b_pos, rw_scale); + ffloor[i].b_step = (centeryfrac >> 4) - FixedMul(ffloor[i].b_pos_slope, ds_p->scale2); + ffloor[i].b_step = (ffloor[i].b_step-ffloor[i].b_frac)/(range); + i++; + } +#else + if (*rover->bottomheight <= frontsector->ceilingheight && + *rover->bottomheight >= frontsector->floorheight && + ((viewz < *rover->bottomheight && !(rover->flags & FF_INVERTPLANES)) || + (viewz > *rover->bottomheight && (rover->flags & FF_BOTHPLANES)))) + { + ffloor[i].b_pos = *rover->bottomheight; + ffloor[i].b_pos = (ffloor[i].b_pos - viewz) >> 4; + ffloor[i].b_step = FixedMul(-rw_scalestep, ffloor[i].b_pos); + ffloor[i].b_frac = (centeryfrac >> 4) - FixedMul(ffloor[i].b_pos, rw_scale); + i++; + } + if (i >= MAXFFLOORS) + break; + if (*rover->topheight >= frontsector->floorheight && + *rover->topheight <= frontsector->ceilingheight && + ((viewz > *rover->topheight && !(rover->flags & FF_INVERTPLANES)) || + (viewz < *rover->topheight && (rover->flags & FF_BOTHPLANES)))) + { + ffloor[i].b_pos = *rover->topheight; + ffloor[i].b_pos = (ffloor[i].b_pos - viewz) >> 4; + ffloor[i].b_step = FixedMul(-rw_scalestep, ffloor[i].b_pos); + ffloor[i].b_frac = (centeryfrac >> 4) - FixedMul(ffloor[i].b_pos, rw_scale); + i++; + } +#endif + } + } + +#ifdef POLYOBJECTS_PLANES + if (curline->polyseg && frontsector && (curline->polyseg->flags & POF_RENDERPLANES)) + { + while (i < numffloors && ffloor[i].polyobj != curline->polyseg) i++; + if (i < numffloors && backsector->floorheight <= frontsector->ceilingheight && + backsector->floorheight >= frontsector->floorheight && + (viewz < backsector->floorheight)) + { + if (ffloor[i].plane->minx > ds_p->x1) + ffloor[i].plane->minx = ds_p->x1; + + if (ffloor[i].plane->maxx < ds_p->x2) + ffloor[i].plane->maxx = ds_p->x2; + +#ifdef ESLOPE + ffloor[i].slope = NULL; +#endif + ffloor[i].b_pos = backsector->floorheight; + ffloor[i].b_pos = (ffloor[i].b_pos - viewz) >> 4; + ffloor[i].b_step = FixedMul(-rw_scalestep, ffloor[i].b_pos); + ffloor[i].b_frac = (centeryfrac >> 4) - FixedMul(ffloor[i].b_pos, rw_scale); + i++; + } + if (i < numffloors && backsector->ceilingheight >= frontsector->floorheight && + backsector->ceilingheight <= frontsector->ceilingheight && + (viewz > backsector->ceilingheight)) + { + if (ffloor[i].plane->minx > ds_p->x1) + ffloor[i].plane->minx = ds_p->x1; + + if (ffloor[i].plane->maxx < ds_p->x2) + ffloor[i].plane->maxx = ds_p->x2; + +#ifdef ESLOPE + ffloor[i].slope = NULL; +#endif + ffloor[i].b_pos = backsector->ceilingheight; + ffloor[i].b_pos = (ffloor[i].b_pos - viewz) >> 4; + ffloor[i].b_step = FixedMul(-rw_scalestep, ffloor[i].b_pos); + ffloor[i].b_frac = (centeryfrac >> 4) - FixedMul(ffloor[i].b_pos, rw_scale); + i++; + } + } +#endif + + numbackffloors = i; + } +} + +// +// R_WorldFFloorStep +// Does... stepping... stuff? For FOFs?! +// +static void R_WorldFFloorStep(INT32 range) +{ + INT32 i; + +#ifndef ESLOPE + (void)range; // Not needed! +#endif + + for (i = 0; i < numffloors; i++) + { + ffloor[i].f_pos >>= 4; +#ifdef ESLOPE + ffloor[i].f_pos_slope >>= 4; +#endif + if (linedef->special == HORIZONSPECIAL) // Horizon lines extend FOFs in contact with them too. + { + ffloor[i].f_step = 0; + ffloor[i].f_frac = (centeryfrac>>4); + topfrac++; // Prevent 1px HOM + } + else + { +#ifdef ESLOPE + ffloor[i].f_frac = (centeryfrac>>4) - FixedMul(ffloor[i].f_pos, rw_scale); + ffloor[i].f_step = ((centeryfrac>>4) - FixedMul(ffloor[i].f_pos_slope, ds_p->scale2) - ffloor[i].f_frac)/(range); +#else + ffloor[i].f_step = FixedMul(-rw_scalestep, ffloor[i].f_pos); + ffloor[i].f_frac = (centeryfrac>>4) - FixedMul(ffloor[i].f_pos, rw_scale); +#endif + } + } +} + +// +// R_WorldLightLists +// Creates light lists. +// +static void R_WorldLightLists(INT32 range) +{ + INT32 i, p; + lightlist_t *light; + r_lightlist_t *rlight; + +#ifndef ESLOPE + (void)range; // Not needed! +#endif dc_numlights = 0; @@ -2818,295 +3019,15 @@ void R_StoreWallRange(INT32 start, INT32 stop) dc_numlights = p; } +} - if (numffloors) - { - for (i = 0; i < numffloors; i++) - { - ffloor[i].f_pos >>= 4; -#ifdef ESLOPE - ffloor[i].f_pos_slope >>= 4; -#endif - if (linedef->special == HORIZONSPECIAL) // Horizon lines extend FOFs in contact with them too. - { - ffloor[i].f_step = 0; - ffloor[i].f_frac = (centeryfrac>>4); - topfrac++; // Prevent 1px HOM - } - else - { -#ifdef ESLOPE - ffloor[i].f_frac = (centeryfrac>>4) - FixedMul(ffloor[i].f_pos, rw_scale); - ffloor[i].f_step = ((centeryfrac>>4) - FixedMul(ffloor[i].f_pos_slope, ds_p->scale2) - ffloor[i].f_frac)/(range); -#else - ffloor[i].f_step = FixedMul(-rw_scalestep, ffloor[i].f_pos); - ffloor[i].f_frac = (centeryfrac>>4) - FixedMul(ffloor[i].f_pos, rw_scale); -#endif - } - } - } - - if (backsector) - { - worldhigh >>= 4; - worldlow >>= 4; -#ifdef ESLOPE - worldhighslope >>= 4; - worldlowslope >>= 4; -#endif - - if (toptexture) - { - pixhigh = (centeryfrac>>4) - FixedMul (worldhigh, rw_scale); - pixhighstep = -FixedMul (rw_scalestep,worldhigh); - -#ifdef ESLOPE - if (backsector->c_slope) { - fixed_t topfracend = (centeryfrac>>4) - FixedMul (worldhighslope, ds_p->scale2); - pixhighstep = (topfracend-pixhigh)/(range); - } -#endif - } - - if (bottomtexture) - { - pixlow = (centeryfrac>>4) - FixedMul (worldlow, rw_scale); - pixlowstep = -FixedMul (rw_scalestep,worldlow); -#ifdef ESLOPE - if (backsector->f_slope) { - fixed_t bottomfracend = (centeryfrac>>4) - FixedMul (worldlowslope, ds_p->scale2); - pixlowstep = (bottomfracend-pixlow)/(range); - } -#endif - } - - { - ffloor_t * rover; -#ifdef ESLOPE - fixed_t roverleft, roverright; - fixed_t planevistest; -#endif - i = 0; - - if (backsector->ffloors) - { - for (rover = backsector->ffloors; rover && i < MAXFFLOORS; rover = rover->next) - { - if (!(rover->flags & FF_EXISTS) || !(rover->flags & FF_RENDERPLANES)) - continue; - if (rover->norender == leveltime) - continue; - -#ifdef ESLOPE - // Let the renderer know this sector is sloped. - if (*rover->b_slope || *rover->t_slope) - backsector->hasslope = true; - - roverleft = (*rover->b_slope ? P_GetZAt(*rover->b_slope, segleft.x, segleft.y) : *rover->bottomheight) - viewz; - roverright = (*rover->b_slope ? P_GetZAt(*rover->b_slope, segright.x, segright.y) : *rover->bottomheight) - viewz; - planevistest = (*rover->b_slope ? P_GetZAt(*rover->b_slope, viewx, viewy) : *rover->bottomheight); - - if ((roverleft>>4 <= worldhigh || roverright>>4 <= worldhighslope) && - (roverleft>>4 >= worldlow || roverright>>4 >= worldlowslope) && - ((viewz < planevistest && !(rover->flags & FF_INVERTPLANES)) || - (viewz > planevistest && (rover->flags & FF_BOTHPLANES)))) - { - //ffloor[i].slope = *rover->b_slope; - ffloor[i].b_pos = roverleft; - ffloor[i].b_pos_slope = roverright; - ffloor[i].b_pos >>= 4; - ffloor[i].b_pos_slope >>= 4; - ffloor[i].b_frac = (centeryfrac >> 4) - FixedMul(ffloor[i].b_pos, rw_scale); - ffloor[i].b_step = (centeryfrac >> 4) - FixedMul(ffloor[i].b_pos_slope, ds_p->scale2); - ffloor[i].b_step = (ffloor[i].b_step-ffloor[i].b_frac)/(range); - i++; - } - - if (i >= MAXFFLOORS) - break; - - roverleft = (*rover->t_slope ? P_GetZAt(*rover->t_slope, segleft.x, segleft.y) : *rover->topheight) - viewz; - roverright = (*rover->t_slope ? P_GetZAt(*rover->t_slope, segright.x, segright.y) : *rover->topheight) - viewz; - planevistest = (*rover->t_slope ? P_GetZAt(*rover->t_slope, viewx, viewy) : *rover->topheight); - - if ((roverleft>>4 <= worldhigh || roverright>>4 <= worldhighslope) && - (roverleft>>4 >= worldlow || roverright>>4 >= worldlowslope) && - ((viewz > planevistest && !(rover->flags & FF_INVERTPLANES)) || - (viewz < planevistest && (rover->flags & FF_BOTHPLANES)))) - { - //ffloor[i].slope = *rover->t_slope; - ffloor[i].b_pos = roverleft; - ffloor[i].b_pos_slope = roverright; - ffloor[i].b_pos >>= 4; - ffloor[i].b_pos_slope >>= 4; - ffloor[i].b_frac = (centeryfrac >> 4) - FixedMul(ffloor[i].b_pos, rw_scale); - ffloor[i].b_step = (centeryfrac >> 4) - FixedMul(ffloor[i].b_pos_slope, ds_p->scale2); - ffloor[i].b_step = (ffloor[i].b_step-ffloor[i].b_frac)/(range); - i++; - } -#else - if (*rover->bottomheight <= backsector->ceilingheight && - *rover->bottomheight >= backsector->floorheight && - ((viewz < *rover->bottomheight && !(rover->flags & FF_INVERTPLANES)) || - (viewz > *rover->bottomheight && (rover->flags & FF_BOTHPLANES)))) - { - ffloor[i].b_pos = *rover->bottomheight; - ffloor[i].b_pos = (ffloor[i].b_pos - viewz) >> 4; - ffloor[i].b_step = FixedMul(-rw_scalestep, ffloor[i].b_pos); - ffloor[i].b_frac = (centeryfrac >> 4) - FixedMul(ffloor[i].b_pos, rw_scale); - i++; - } - - if (i >= MAXFFLOORS) - break; - - if (*rover->topheight >= backsector->floorheight && - *rover->topheight <= backsector->ceilingheight && - ((viewz > *rover->topheight && !(rover->flags & FF_INVERTPLANES)) || - (viewz < *rover->topheight && (rover->flags & FF_BOTHPLANES)))) - { - ffloor[i].b_pos = *rover->topheight; - ffloor[i].b_pos = (ffloor[i].b_pos - viewz) >> 4; - ffloor[i].b_step = FixedMul(-rw_scalestep, ffloor[i].b_pos); - ffloor[i].b_frac = (centeryfrac >> 4) - FixedMul(ffloor[i].b_pos, rw_scale); - i++; - } -#endif - } - } - else if (frontsector && frontsector->ffloors) - { - for (rover = frontsector->ffloors; rover && i < MAXFFLOORS; rover = rover->next) - { - if (!(rover->flags & FF_EXISTS) || !(rover->flags & FF_RENDERPLANES)) - continue; - if (rover->norender == leveltime) - continue; - - -#ifdef ESLOPE - // Let the renderer know this sector is sloped. - if (*rover->b_slope || *rover->t_slope) - frontsector->hasslope = true; - - roverleft = (*rover->b_slope ? P_GetZAt(*rover->b_slope, segleft.x, segleft.y) : *rover->bottomheight) - viewz; - roverright = (*rover->b_slope ? P_GetZAt(*rover->b_slope, segright.x, segright.y) : *rover->bottomheight) - viewz; - planevistest = (*rover->b_slope ? P_GetZAt(*rover->b_slope, viewx, viewy) : *rover->bottomheight); - - if ((roverleft>>4 <= worldhigh || roverright>>4 <= worldhighslope) && - (roverleft>>4 >= worldlow || roverright>>4 >= worldlowslope) && - ((viewz < planevistest && !(rover->flags & FF_INVERTPLANES)) || - (viewz > planevistest && (rover->flags & FF_BOTHPLANES)))) - { - //ffloor[i].slope = *rover->b_slope; - ffloor[i].b_pos = roverleft; - ffloor[i].b_pos_slope = roverright; - ffloor[i].b_pos >>= 4; - ffloor[i].b_pos_slope >>= 4; - ffloor[i].b_frac = (centeryfrac >> 4) - FixedMul(ffloor[i].b_pos, rw_scale); - ffloor[i].b_step = (centeryfrac >> 4) - FixedMul(ffloor[i].b_pos_slope, ds_p->scale2); - ffloor[i].b_step = (ffloor[i].b_step-ffloor[i].b_frac)/(range); - i++; - } - - if (i >= MAXFFLOORS) - break; - - roverleft = (*rover->t_slope ? P_GetZAt(*rover->t_slope, segleft.x, segleft.y) : *rover->topheight) - viewz; - roverright = (*rover->t_slope ? P_GetZAt(*rover->t_slope, segright.x, segright.y) : *rover->topheight) - viewz; - planevistest = (*rover->t_slope ? P_GetZAt(*rover->t_slope, viewx, viewy) : *rover->topheight); - - if ((roverleft>>4 <= worldhigh || roverright>>4 <= worldhighslope) && - (roverleft>>4 >= worldlow || roverright>>4 >= worldlowslope) && - ((viewz > planevistest && !(rover->flags & FF_INVERTPLANES)) || - (viewz < planevistest && (rover->flags & FF_BOTHPLANES)))) - { - //ffloor[i].slope = *rover->t_slope; - ffloor[i].b_pos = roverleft; - ffloor[i].b_pos_slope = roverright; - ffloor[i].b_pos >>= 4; - ffloor[i].b_pos_slope >>= 4; - ffloor[i].b_frac = (centeryfrac >> 4) - FixedMul(ffloor[i].b_pos, rw_scale); - ffloor[i].b_step = (centeryfrac >> 4) - FixedMul(ffloor[i].b_pos_slope, ds_p->scale2); - ffloor[i].b_step = (ffloor[i].b_step-ffloor[i].b_frac)/(range); - i++; - } -#else - if (*rover->bottomheight <= frontsector->ceilingheight && - *rover->bottomheight >= frontsector->floorheight && - ((viewz < *rover->bottomheight && !(rover->flags & FF_INVERTPLANES)) || - (viewz > *rover->bottomheight && (rover->flags & FF_BOTHPLANES)))) - { - ffloor[i].b_pos = *rover->bottomheight; - ffloor[i].b_pos = (ffloor[i].b_pos - viewz) >> 4; - ffloor[i].b_step = FixedMul(-rw_scalestep, ffloor[i].b_pos); - ffloor[i].b_frac = (centeryfrac >> 4) - FixedMul(ffloor[i].b_pos, rw_scale); - i++; - } - if (i >= MAXFFLOORS) - break; - if (*rover->topheight >= frontsector->floorheight && - *rover->topheight <= frontsector->ceilingheight && - ((viewz > *rover->topheight && !(rover->flags & FF_INVERTPLANES)) || - (viewz < *rover->topheight && (rover->flags & FF_BOTHPLANES)))) - { - ffloor[i].b_pos = *rover->topheight; - ffloor[i].b_pos = (ffloor[i].b_pos - viewz) >> 4; - ffloor[i].b_step = FixedMul(-rw_scalestep, ffloor[i].b_pos); - ffloor[i].b_frac = (centeryfrac >> 4) - FixedMul(ffloor[i].b_pos, rw_scale); - i++; - } -#endif - } - } -#ifdef POLYOBJECTS_PLANES - if (curline->polyseg && frontsector && (curline->polyseg->flags & POF_RENDERPLANES)) - { - while (i < numffloors && ffloor[i].polyobj != curline->polyseg) i++; - if (i < numffloors && backsector->floorheight <= frontsector->ceilingheight && - backsector->floorheight >= frontsector->floorheight && - (viewz < backsector->floorheight)) - { - if (ffloor[i].plane->minx > ds_p->x1) - ffloor[i].plane->minx = ds_p->x1; - - if (ffloor[i].plane->maxx < ds_p->x2) - ffloor[i].plane->maxx = ds_p->x2; - -#ifdef ESLOPE - ffloor[i].slope = NULL; -#endif - ffloor[i].b_pos = backsector->floorheight; - ffloor[i].b_pos = (ffloor[i].b_pos - viewz) >> 4; - ffloor[i].b_step = FixedMul(-rw_scalestep, ffloor[i].b_pos); - ffloor[i].b_frac = (centeryfrac >> 4) - FixedMul(ffloor[i].b_pos, rw_scale); - i++; - } - if (i < numffloors && backsector->ceilingheight >= frontsector->floorheight && - backsector->ceilingheight <= frontsector->ceilingheight && - (viewz > backsector->ceilingheight)) - { - if (ffloor[i].plane->minx > ds_p->x1) - ffloor[i].plane->minx = ds_p->x1; - - if (ffloor[i].plane->maxx < ds_p->x2) - ffloor[i].plane->maxx = ds_p->x2; - -#ifdef ESLOPE - ffloor[i].slope = NULL; -#endif - ffloor[i].b_pos = backsector->ceilingheight; - ffloor[i].b_pos = (ffloor[i].b_pos - viewz) >> 4; - ffloor[i].b_step = FixedMul(-rw_scalestep, ffloor[i].b_pos); - ffloor[i].b_frac = (centeryfrac >> 4) - FixedMul(ffloor[i].b_pos, rw_scale); - i++; - } - } -#endif - - numbackffloors = i; - } - } +// +// R_MarkPlanes +// Creates visplanes. +// +static void R_MarkPlanes(void) +{ + INT32 i; // get a new or use the same visplane if (markceiling) @@ -3173,6 +3094,231 @@ void R_StoreWallRange(INT32 start, INT32 stop) } #endif } +} + +// +// R_RemoveOpeningLimits +// Code to remove limits on openings. +// +static void R_RemoveOpeningLimits(INT32 start) +{ + size_t pos = lastopening - openings; + size_t need = (rw_stopx - start)*4 + pos; + if (need > maxopenings) + { + drawseg_t *ds; //needed for fix from *cough* zdoom *cough* + INT16 *oldopenings = openings; + INT16 *oldlast = lastopening; + + do + maxopenings = maxopenings ? maxopenings*2 : 16384; + while (need > maxopenings); + openings = Z_Realloc(openings, maxopenings * sizeof (*openings), PU_STATIC, NULL); + lastopening = openings + pos; + + // borrowed fix from *cough* zdoom *cough* + // [RH] We also need to adjust the openings pointers that + // were already stored in drawsegs. + for (ds = drawsegs; ds < ds_p; ds++) + { +#define ADJUST(p) if (ds->p + ds->x1 >= oldopenings && ds->p + ds->x1 <= oldlast) ds->p = ds->p - oldopenings + openings; + ADJUST(maskedtexturecol); + ADJUST(sprtopclip); + ADJUST(sprbottomclip); + ADJUST(thicksidecol); +#undef ADJUST + } + } +} + +// +// R_StoreWallRange +// A wall segment will be drawn +// between start and stop pixels (inclusive). +// +void R_StoreWallRange(INT32 start, INT32 stop) +{ + fixed_t hyp; + fixed_t sineval; + angle_t distangle, offsetangle; + boolean longboi; +#ifndef ESLOPE + fixed_t vtop; +#endif + INT32 i; + INT32 range; + static size_t maxdrawsegs = 0; + +#ifdef ESLOPE + maskedtextureheight = NULL; + //initialize segleft and segright + memset(&segleft, 0x00, sizeof(segleft)); + memset(&segright, 0x00, sizeof(segright)); +#endif + + colfunc = colfuncs[BASEDRAWFUNC]; + + if (ds_p == drawsegs+maxdrawsegs) + { + size_t curpos = curdrawsegs - drawsegs; + size_t pos = ds_p - drawsegs; + size_t newmax = maxdrawsegs ? maxdrawsegs*2 : 128; + if (firstseg) + firstseg = (drawseg_t *)(firstseg - drawsegs); + drawsegs = Z_Realloc(drawsegs, newmax*sizeof (*drawsegs), PU_STATIC, NULL); + ds_p = drawsegs + pos; + maxdrawsegs = newmax; + curdrawsegs = drawsegs + curpos; + if (firstseg) + firstseg = drawsegs + (size_t)firstseg; + } + + sidedef = curline->sidedef; + linedef = curline->linedef; + + // calculate rw_distance for scale calculation + rw_normalangle = curline->angle + ANGLE_90; + offsetangle = abs((INT32)(rw_normalangle-rw_angle1)); + + if (offsetangle > ANGLE_90) + offsetangle = ANGLE_90; + + distangle = ANGLE_90 - offsetangle; + sineval = FINESINE(distangle>>ANGLETOFINESHIFT); + + hyp = R_PointToDist(curline->v1->x, curline->v1->y); + rw_distance = FixedMul(hyp, sineval); + longboi = (hyp >= INT32_MAX); + + // big room fix + if (longboi) + rw_distance = (fixed_t)R_CalculateSegDistance(curline,viewx,viewy); + + ds_p->x1 = rw_x = start; + ds_p->x2 = stop; + ds_p->curline = curline; + rw_stopx = stop+1; + + //SoM: Code to remove limits on openings. + R_RemoveOpeningLimits(start); + + // calculate scale at both ends and step + range = R_CalculateWallScale(start, stop); + + // calculate texture boundaries + // and decide if floor / ceiling marks are needed + R_WorldTopAndBottom(start, stop); + + midtexture = toptexture = bottomtexture = maskedtexture = 0; + ds_p->maskedtexturecol = NULL; + ds_p->numthicksides = numthicksides = 0; + ds_p->thicksidecol = NULL; + ds_p->tsilheight = 0; + + numbackffloors = 0; + + for (i = 0; i < MAXFFLOORS; i++) + ds_p->thicksides[i] = NULL; + + if (numffloors) + { + for (i = 0; i < numffloors; i++) + { +#ifdef POLYOBJECTS_PLANES + if (ffloor[i].polyobj && (!ds_p->curline->polyseg || ffloor[i].polyobj != ds_p->curline->polyseg)) + continue; +#endif + +#ifdef ESLOPE + if (ffloor[i].slope) { + ffloor[i].f_pos = P_GetZAt(ffloor[i].slope, segleft.x, segleft.y) - viewz; + ffloor[i].f_pos_slope = P_GetZAt(ffloor[i].slope, segright.x, segright.y) - viewz; + } else + ffloor[i].f_pos_slope = +#endif + ffloor[i].f_pos = ffloor[i].height - viewz; + } + } + +#ifdef ESLOPE + // Set up texture Y offset slides for sloped walls + rw_toptextureslide = rw_midtextureslide = rw_bottomtextureslide = 0; + ceilingfrontslide = floorfrontslide = ceilingbackslide = floorbackslide = 0; + + { + angle_t lineangle = R_PointToAngle2(curline->v1->x, curline->v1->y, curline->v2->x, curline->v2->y); + + if (frontsector->f_slope) + floorfrontslide = FixedMul(frontsector->f_slope->zdelta, FINECOSINE((lineangle-frontsector->f_slope->xydirection)>>ANGLETOFINESHIFT)); + + if (frontsector->c_slope) + ceilingfrontslide = FixedMul(frontsector->c_slope->zdelta, FINECOSINE((lineangle-frontsector->c_slope->xydirection)>>ANGLETOFINESHIFT)); + + if (backsector && backsector->f_slope) + floorbackslide = FixedMul(backsector->f_slope->zdelta, FINECOSINE((lineangle-backsector->f_slope->xydirection)>>ANGLETOFINESHIFT)); + + if (backsector && backsector->c_slope) + ceilingbackslide = FixedMul(backsector->c_slope->zdelta, FINECOSINE((lineangle-backsector->c_slope->xydirection)>>ANGLETOFINESHIFT)); + } +#endif + + // Check for textures + R_StoreWallSilhouette(); + R_CheckWallTextures(); + if (backsector) + R_CheckMaskedTextures(); + +#undef SLOPEPARAMS + + // Calculate rw_offset (only needed for textured lines) + segtextured = midtexture || toptexture || bottomtexture || maskedtexture || (numthicksides > 0); + if (segtextured) + R_WorldSegTextured(hyp, longboi); + + // if a floor / ceiling plane is on the wrong side + // of the view plane, it is definitely invisible + // and doesn't need to be marked. + if (frontsector->heightsec == -1) + { + if (frontsector->floorpic != skyflatnum + && ( +#ifdef ESLOPE + frontsector->f_slope ? P_GetZAt(frontsector->f_slope, viewx, viewy) : +#endif + frontsector->floorheight) >= viewz) + { + // above view plane + markfloor = false; + } + + if (frontsector->ceilingpic != skyflatnum + && ( +#ifdef ESLOPE + frontsector->c_slope ? P_GetZAt(frontsector->c_slope, viewx, viewy) : +#endif + frontsector->ceilingheight) <= viewz) + { + // below view plane + markceiling = false; + } + } + + // Calculate incremental stepping values for texture edges + R_WorldStep(range); + + // Create light lists + R_WorldLightLists(range); + + // Step FOFs + if (numffloors) + R_WorldFFloorStep(range); + + // Step world back + if (backsector) + R_WorldBackStep(range); + + // Mark floor and or ceiling visplanes + R_MarkPlanes(); #ifdef WALLSPLATS if (linedef->splats && cv_splats.value) @@ -3220,5 +3366,6 @@ void R_StoreWallRange(INT32 start, INT32 stop) ds_p->silhouette |= SIL_BOTTOM; ds_p->bsilheight = (sidedef->midtexture > 0 && sidedef->midtexture < numtextures) ? INT32_MAX: INT32_MIN; } + ds_p++; } From 69e97840856423abfc25f0636e1649f11dd75be1 Mon Sep 17 00:00:00 2001 From: Jaime Passos Date: Thu, 26 Dec 2019 00:55:34 -0300 Subject: [PATCH 392/746] 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 6bd383621eee92b215f86c9c4b483934d7e60daa Mon Sep 17 00:00:00 2001 From: James R Date: Wed, 25 Dec 2019 20:44:25 -0800 Subject: [PATCH 393/746] 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 649455c2d0890770e02922776368749c70e18063 Mon Sep 17 00:00:00 2001 From: Jaime Passos Date: Thu, 26 Dec 2019 01:58:38 -0300 Subject: [PATCH 394/746] 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 50379dac858f60057c474806bad160e558c34cb2 Mon Sep 17 00:00:00 2001 From: Alam Ed Arias Date: Thu, 26 Dec 2019 12:27:15 -0500 Subject: [PATCH 395/746] cleanup buildbot error --- src/p_mobj.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/p_mobj.c b/src/p_mobj.c index 1882a4e3c..bd0927355 100644 --- a/src/p_mobj.c +++ b/src/p_mobj.c @@ -13005,7 +13005,7 @@ static void P_SetObjectSpecial(mobj_t *mobj) } } -mobj_t *P_SpawnMobjFromMapThing(mapthing_t *mthing, fixed_t x, fixed_t y, fixed_t z, mobjtype_t i) +static mobj_t *P_SpawnMobjFromMapThing(mapthing_t *mthing, fixed_t x, fixed_t y, fixed_t z, mobjtype_t i) { mobj_t *mobj = NULL; boolean doangle = true; From 4906cd4331f9697e71b6e01949e9e296dd557476 Mon Sep 17 00:00:00 2001 From: Alam Ed Arias Date: Thu, 26 Dec 2019 12:44:47 -0500 Subject: [PATCH 396/746] ISO C90 fixup --- src/p_mobj.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/p_mobj.c b/src/p_mobj.c index 83ab50b35..88ab45a12 100644 --- a/src/p_mobj.c +++ b/src/p_mobj.c @@ -8321,6 +8321,7 @@ static boolean P_MobjDeadThink(mobj_t *mobj) // See Linedef Exec 457 (Track mobj angle to point) static void P_TracerAngleThink(mobj_t *mobj) { + angle_t ang; if (!mobj->tracer) return; @@ -8333,7 +8334,7 @@ static void P_TracerAngleThink(mobj_t *mobj) // mobj->cvval - Allowable failure delay // mobj->cvmem - Failure timer - angle_t ang = mobj->angle - R_PointToAngle2(mobj->x, mobj->y, mobj->tracer->x, mobj->tracer->y); + ang = mobj->angle - R_PointToAngle2(mobj->x, mobj->y, mobj->tracer->x, mobj->tracer->y); // \todo account for distance between mobj and tracer // Because closer mobjs can be facing beyond the angle tolerance From e09838224e6ff998327a8d6de9e5a6eb791e54d5 Mon Sep 17 00:00:00 2001 From: Jaime Passos Date: Thu, 26 Dec 2019 15:27:16 -0300 Subject: [PATCH 397/746] 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 398/746] 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 a1d944fc4d13b1f749e2bdc9288d730aa88c136b Mon Sep 17 00:00:00 2001 From: Sally Cochenour Date: Thu, 26 Dec 2019 14:02:02 -0500 Subject: [PATCH 399/746] 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 855f5da6c9673daa051b387661bee64b0a4f53f1 Mon Sep 17 00:00:00 2001 From: MascaraSnake Date: Thu, 26 Dec 2019 20:13:56 +0100 Subject: [PATCH 400/746] Make P_RespawnSpecials call P_SpawnMapThing instead of trying to do everything itself --- src/p_mobj.c | 60 +--------------------------------------------------- 1 file changed, 1 insertion(+), 59 deletions(-) diff --git a/src/p_mobj.c b/src/p_mobj.c index 83ab50b35..dde2476a4 100644 --- a/src/p_mobj.c +++ b/src/p_mobj.c @@ -11284,9 +11284,6 @@ static mobjtype_t P_GetMobjtype(UINT16 mthingtype) // void P_RespawnSpecials(void) { - fixed_t x, y, z; - subsector_t *ss; - mobj_t *mo = NULL; mapthing_t *mthing = NULL; // only respawn items when cv_itemrespawn is on @@ -11316,63 +11313,8 @@ void P_RespawnSpecials(void) #endif if (mthing) - { - mobjtype_t i = P_GetMobjtype(mthing->type); - x = mthing->x << FRACBITS; - y = mthing->y << FRACBITS; - ss = R_PointInSubsector(x, y); + P_SpawnMapThing(mthing); - if (i == MT_UNKNOWN) // prevent creation of objects with this type -- Monster Iestyn 17/12/17 - { - // 3D Mode start Thing is unlikely to be added to the que, - // so don't bother checking for that specific type - CONS_Alert(CONS_WARNING, M_GetText("P_RespawnSpecials: Unknown thing type %d attempted to respawn at (%d, %d)\n"), mthing->type, mthing->x, mthing->y); - // pull it from the que - iquetail = (iquetail+1)&(ITEMQUESIZE-1); - return; - } - - //CTF rings should continue to respawn as normal rings outside of CTF. - if (gametype != GT_CTF) - { - if (i == MT_REDTEAMRING || i == MT_BLUETEAMRING) - i = MT_RING; - } - - if (mthing->options & MTF_OBJECTFLIP) - { - z = ( -#ifdef ESLOPE - ss->sector->c_slope ? P_GetZAt(ss->sector->c_slope, x, y) : -#endif - ss->sector->ceilingheight) - (mthing->options >> ZSHIFT) * FRACUNIT; - if (mthing->options & MTF_AMBUSH - && (i == MT_RING || i == MT_REDTEAMRING || i == MT_BLUETEAMRING || i == MT_COIN || i == MT_NIGHTSSTAR || P_WeaponOrPanel(i))) - z -= 24*FRACUNIT; - z -= mobjinfo[i].height; // Don't forget the height! - } - else - { - z = ( -#ifdef ESLOPE - ss->sector->f_slope ? P_GetZAt(ss->sector->f_slope, x, y) : -#endif - ss->sector->floorheight) + (mthing->options >> ZSHIFT) * FRACUNIT; - if (mthing->options & MTF_AMBUSH - && (i == MT_RING || i == MT_REDTEAMRING || i == MT_BLUETEAMRING || i == MT_COIN || i == MT_NIGHTSSTAR || P_WeaponOrPanel(i))) - z += 24*FRACUNIT; - } - - mo = P_SpawnMobj(x, y, z, i); - mo->spawnpoint = mthing; - mo->angle = ANGLE_45 * (mthing->angle/45); - - if (mthing->options & MTF_OBJECTFLIP) - { - mo->eflags |= MFE_VERTICALFLIP; - mo->flags2 |= MF2_OBJECTFLIP; - } - } // pull it from the que iquetail = (iquetail+1)&(ITEMQUESIZE-1); } From 5f1e3bab718f2c278c00ef0da39bc62ea1a66dae Mon Sep 17 00:00:00 2001 From: Jaime Passos Date: Thu, 26 Dec 2019 16:25:04 -0300 Subject: [PATCH 401/746] 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 f86c5f13ced5398a63ce2f74f639feb4a4a1565e Mon Sep 17 00:00:00 2001 From: MascaraSnake Date: Thu, 26 Dec 2019 20:48:52 +0100 Subject: [PATCH 402/746] Use mt->z instead of mt->options >> ZSHIFT in Command_Teleport_f --- src/m_cheat.c | 14 ++++---------- 1 file changed, 4 insertions(+), 10 deletions(-) diff --git a/src/m_cheat.c b/src/m_cheat.c index 52b79f930..f4042eba9 100644 --- a/src/m_cheat.c +++ b/src/m_cheat.c @@ -517,6 +517,7 @@ void Command_Teleport_f(void) if (!starpostnum) // spawnpoints... { mapthing_t *mt; + fixed_t offset; if (starpostpath >= numcoopstarts) { @@ -527,6 +528,7 @@ void Command_Teleport_f(void) mt = playerstarts[starpostpath]; // Given above check, should never be NULL. intx = mt->x<y<z<sector->ceilingheight - ss->sector->floorheight < p->mo->height) @@ -538,17 +540,9 @@ void Command_Teleport_f(void) // Flagging a player's ambush will make them start on the ceiling // Objectflip inverts if (!!(mt->options & MTF_AMBUSH) ^ !!(mt->options & MTF_OBJECTFLIP)) - { - intz = ss->sector->ceilingheight - p->mo->height; - if (mt->options >> ZSHIFT) - intz -= ((mt->options >> ZSHIFT) << FRACBITS); - } + intz = ss->sector->ceilingheight - p->mo->height - offset; else - { - intz = ss->sector->floorheight; - if (mt->options >> ZSHIFT) - intz += ((mt->options >> ZSHIFT) << FRACBITS); - } + intz = ss->sector->floorheight + offset; if (mt->options & MTF_OBJECTFLIP) // flip the player! { From 7ccb695fa16eb550c6fc4e7221162635283bf862 Mon Sep 17 00:00:00 2001 From: MascaraSnake Date: Thu, 26 Dec 2019 20:54:06 +0100 Subject: [PATCH 403/746] Use mthing->z instead of mthing->options >> ZSHIFT in G_AddGhost --- src/g_game.c | 11 ++++------- 1 file changed, 4 insertions(+), 7 deletions(-) diff --git a/src/g_game.c b/src/g_game.c index cf9b4367d..67424f02a 100644 --- a/src/g_game.c +++ b/src/g_game.c @@ -6629,23 +6629,20 @@ void G_AddGhost(char *defdemoname) I_Assert(mthing); { // A bit more complex than P_SpawnPlayer because ghosts aren't solid and won't just push themselves out of the ceiling. fixed_t z,f,c; + fixed_t offset = mthing->z << FRACBITS; gh->mo = P_SpawnMobj(mthing->x << FRACBITS, mthing->y << FRACBITS, 0, MT_GHOST); - gh->mo->angle = FixedAngle(mthing->angle*FRACUNIT); + gh->mo->angle = FixedAngle(mthing->angle << FRACBITS); f = gh->mo->floorz; c = gh->mo->ceilingz - mobjinfo[MT_PLAYER].height; if (!!(mthing->options & MTF_AMBUSH) ^ !!(mthing->options & MTF_OBJECTFLIP)) { - z = c; - if (mthing->options >> ZSHIFT) - z -= ((mthing->options >> ZSHIFT) << FRACBITS); + z = c - offset; if (z < f) z = f; } else { - z = f; - if (mthing->options >> ZSHIFT) - z += ((mthing->options >> ZSHIFT) << FRACBITS); + z = f + offset; if (z > c) z = c; } From 2d90098b6a981761da87739d3dd41fcc2cdfc1f1 Mon Sep 17 00:00:00 2001 From: MascaraSnake Date: Thu, 26 Dec 2019 20:55:29 +0100 Subject: [PATCH 404/746] Use startpos->z instead of startpos->options >> ZSHIFT in F_StartTitleScreen --- src/f_finale.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/f_finale.c b/src/f_finale.c index 1436a159b..124fedc28 100644 --- a/src/f_finale.c +++ b/src/f_finale.c @@ -2493,7 +2493,7 @@ void F_StartTitleScreen(void) camera.x = startpos->x << FRACBITS; camera.y = startpos->y << FRACBITS; camera.subsector = R_PointInSubsector(camera.x, camera.y); - camera.z = camera.subsector->sector->floorheight + ((startpos->options >> ZSHIFT) << FRACBITS); + camera.z = camera.subsector->sector->floorheight + (startpos->z << FRACBITS); camera.angle = (startpos->angle % 360)*ANG1; camera.aiming = 0; } From 919864d0f39688616d25cc3636d1ab48ae8334b3 Mon Sep 17 00:00:00 2001 From: Jaime Passos Date: Thu, 26 Dec 2019 17:15:30 -0300 Subject: [PATCH 405/746] Thick stuff. Hoping I didn't break anything. --- src/r_segs.c | 702 ++++++++++++++++++++++++++------------------------ src/r_state.h | 15 ++ 2 files changed, 386 insertions(+), 331 deletions(-) diff --git a/src/r_segs.c b/src/r_segs.c index 63c9799e0..1b78a22dd 100644 --- a/src/r_segs.c +++ b/src/r_segs.c @@ -2360,14 +2360,13 @@ static void R_DrawWallSplats(void) // way we don't have to store extra post_t info with each column for // multi-patch textures. They are not normally needed as multi-patch // textures don't have holes in it. At least not for now. -static INT32 column2s_length; // column->length : for multi-patch on 2sided wall = texture->height static void R_Render2sidedMultiPatchColumn(column_t *column) { INT32 topscreen, bottomscreen; topscreen = sprtopscreen; // + spryscale*column->topdelta; topdelta is 0 for the wall - bottomscreen = topscreen + spryscale * column2s_length; + bottomscreen = topscreen + spryscale * rw.column2s_length; dc_yl = (sprtopscreen+FRACUNIT-1)>>FRACBITS; dc_yh = (bottomscreen-1)>>FRACBITS; @@ -2403,7 +2402,7 @@ static void R_Render2sidedMultiPatchColumn(column_t *column) // uses column2s_length for texture->height as above static void R_DrawFlippedMaskedSegColumn(column_t *column) { - R_DrawFlippedMaskedColumn(column, column2s_length); + R_DrawFlippedMaskedColumn(column, rw.column2s_length); } void R_RenderMaskedSegRange(drawseg_t *ds, INT32 x1, INT32 x2) @@ -2414,7 +2413,6 @@ void R_RenderMaskedSegRange(drawseg_t *ds, INT32 x1, INT32 x2) fixed_t height, realbot; lightlist_t *light; r_lightlist_t *rlight; - void (*colfunc_2s)(column_t *); line_t *ldef; sector_t *front, *back; INT32 times, repeats; @@ -2483,16 +2481,16 @@ void R_RenderMaskedSegRange(drawseg_t *ds, INT32 x1, INT32 x2) { if (textures[texnum]->flip & 2) // vertically flipped? { - colfunc_2s = R_DrawFlippedMaskedSegColumn; - column2s_length = textures[texnum]->height; + rw.colfunc_2s = R_DrawFlippedMaskedSegColumn; + rw.column2s_length = textures[texnum]->height; } else - colfunc_2s = R_DrawMaskedColumn; // render the usual 2sided single-patch packed texture + rw.colfunc_2s = R_DrawMaskedColumn; // render the usual 2sided single-patch packed texture } else { - colfunc_2s = R_Render2sidedMultiPatchColumn; // render multipatch with no holes (no post_t info) - column2s_length = textures[texnum]->height; + rw.colfunc_2s = R_Render2sidedMultiPatchColumn; // render multipatch with no holes (no post_t info) + rw.column2s_length = textures[texnum]->height; } // Setup lighting based on the presence/lack-of 3D floors. @@ -2741,7 +2739,7 @@ void R_RenderMaskedSegRange(drawseg_t *ds, INT32 x1, INT32 x2) if (windowbottom >= realbot) { windowbottom = realbot; - colfunc_2s(col); + rw.colfunc_2s(col); for (i++; i < dc_numlights; i++) { rlight = &dc_lightlist[i]; @@ -2750,13 +2748,13 @@ void R_RenderMaskedSegRange(drawseg_t *ds, INT32 x1, INT32 x2) continue; } - colfunc_2s(col); + rw.colfunc_2s(col); windowtop = windowbottom + 1; dc_colormap = rlight->rcolormap; } windowbottom = realbot; if (windowtop < windowbottom) - colfunc_2s(col); + rw.colfunc_2s(col); spryscale += rw.scalestep; continue; @@ -2833,7 +2831,7 @@ void R_RenderMaskedSegRange(drawseg_t *ds, INT32 x1, INT32 x2) } else #endif - colfunc_2s(col); + rw.colfunc_2s(col); } spryscale += rw.scalestep; } @@ -2856,110 +2854,238 @@ static void R_DrawRepeatMaskedColumn(column_t *col) static void R_DrawRepeatFlippedMaskedColumn(column_t *col) { do { - R_DrawFlippedMaskedColumn(col, column2s_length); + R_DrawFlippedMaskedColumn(col, rw.column2s_length); sprtopscreen += dc_texheight*spryscale; } while (sprtopscreen < sprbotscreen); } // -// R_RenderThickSideRange -// Renders all the thick sides in the given range. -void R_RenderThickSideRange(drawseg_t *ds, INT32 x1, INT32 x2, ffloor_t *pfloor) +// R_RenderThickSegLoop +// Like R_RenderSegLoop, but for thick sides. +// +void R_RenderThickSegLoop(void) { - size_t pindex; - column_t * col; - INT32 lightnum; - INT32 texnum; - sector_t tempsec; - INT32 templight; - INT32 i, p; - fixed_t bottombounds = viewheight << FRACBITS; - fixed_t topbounds = (con_clipviewtop - 1) << FRACBITS; - fixed_t offsetvalue = 0; - lightlist_t *light; - r_lightlist_t *rlight; + column_t *col; + size_t pindex; + INT32 i; + INT32 lightnum; + r_lightlist_t *rlight; + + ffloor_t *pfloor = rw.pfloor; + fixed_t bottombounds = viewheight << FRACBITS; + fixed_t topbounds = (con_clipviewtop - 1) << FRACBITS; + #ifdef ESLOPE - INT32 range; -#endif -#ifndef ESLOPE - fixed_t lheight; -#endif - line_t *newline = NULL; -#ifdef ESLOPE - // Render FOF sides kinda like normal sides, with the frac and step and everything - // NOTE: INT64 instead of fixed_t because overflow concerns - INT64 top_frac, top_step, bottom_frac, bottom_step; - // skew FOF walls with slopes? - boolean slopeskew = false; - fixed_t ffloortextureslide = 0; - INT32 oldx = -1; - fixed_t left_top, left_bottom; // needed here for slope skewing - pslope_t *skewslope = NULL; + INT32 oldx = -1; #endif - void (*colfunc_2s) (column_t *); - - // Calculate light table. - // Use different light tables - // for horizontal / vertical / diagonal. Diagonal? - // OPTIMIZE: get rid of LIGHTSEGSHIFT globally - - curline = ds->curline; - backsector = pfloor->target; - frontsector = curline->frontsector == pfloor->target ? curline->backsector : curline->frontsector; - texnum = R_GetTextureNum(sides[pfloor->master->sidenum[0]].midtexture); - - colfunc = colfuncs[BASEDRAWFUNC]; - - if (pfloor->master->flags & ML_TFERLINE) + for (dc_x = rw.x; dc_x <= rw.stopx; dc_x++) { - size_t linenum = curline->linedef-backsector->lines[0]; - newline = pfloor->master->frontsector->lines[0] + linenum; - texnum = R_GetTextureNum(sides[newline->sidenum[0]].midtexture); - } - - if (pfloor->flags & FF_TRANSLUCENT) - { - boolean fuzzy = true; - - // Hacked up support for alpha value in software mode Tails 09-24-2002 - if (pfloor->alpha < 12) - return; // Don't even draw it - else if (pfloor->alpha < 38) - dc_transmap = transtables + ((tr_trans90-1)<alpha < 64) - dc_transmap = transtables + ((tr_trans80-1)<alpha < 89) - dc_transmap = transtables + ((tr_trans70-1)<alpha < 115) - dc_transmap = transtables + ((tr_trans60-1)<alpha < 140) - dc_transmap = transtables + ((tr_trans50-1)<alpha < 166) - dc_transmap = transtables + ((tr_trans40-1)<alpha < 192) - dc_transmap = transtables + ((tr_trans30-1)<alpha < 217) - dc_transmap = transtables + ((tr_trans20-1)<alpha < 243) - dc_transmap = transtables + ((tr_trans10-1)<flags & FF_FOG) - colfunc = colfuncs[COLDRAWFUNC_FOG]; - + if (maskedtexturecol[dc_x] != INT16_MAX) + { #ifdef ESLOPE - range = max(ds->x2-ds->x1, 1); + if (rw.ffloortextureslide) { // skew FOF walls + if (oldx != -1) + dc_texturemid += FixedMul(rw.ffloortextureslide, (maskedtexturecol[oldx]-maskedtexturecol[dc_x])<scalestep; - spryscale = ds->scale1 + (x1 - ds->x1)*rw.scalestep; + // Calculate bounds + // clamp the values if necessary to avoid overflows and rendering glitches caused by them +#ifdef ESLOPE + #define CLAMPMAX INT32_MAX + #define CLAMPMIN (-INT32_MAX) // This is not INT32_MIN on purpose! INT32_MIN makes the drawers freak out. + if (rw.top_frac > (INT64)CLAMPMAX) sprtopscreen = windowtop = CLAMPMAX; + else if (rw.top_frac > (INT64)CLAMPMIN) sprtopscreen = windowtop = (fixed_t)rw.top_frac; + else sprtopscreen = windowtop = CLAMPMIN; + if (rw.bottom_frac > (INT64)CLAMPMAX) sprbotscreen = windowbottom = CLAMPMAX; + else if (rw.bottom_frac > (INT64)CLAMPMIN) sprbotscreen = windowbottom = (fixed_t)rw.bottom_frac; + else sprbotscreen = windowbottom = CLAMPMIN; + + rw.top_frac += rw.top_step; + rw.bottom_frac += rw.bottom_step; +#else + sprtopscreen = windowtop = (centeryfrac - FixedMul((dc_texturemid - offsetvalue), spryscale)); + sprbotscreen = windowbottom = FixedMul(*pfloor->topheight - *pfloor->bottomheight, spryscale) + sprtopscreen; +#endif + + // SoM: If column is out of range, why bother with it?? + if (windowbottom < topbounds || windowtop > bottombounds) + { + if (dc_numlights) + { + for (i = 0; i < dc_numlights; i++) + { + rlight = &dc_lightlist[i]; + rlight->height += rlight->heightstep; + if (rlight->flags & FF_CUTLEVEL) + rlight->botheight += rlight->botheightstep; + } + } + spryscale += rw.scalestep; + continue; + } + + dc_iscale = 0xffffffffu / (unsigned)spryscale; + + // Get data for the column + col = (column_t *)((UINT8 *)R_GetColumn(rw.texnum,maskedtexturecol[dc_x]) - 3); + + // SoM: New code does not rely on R_DrawColumnShadowed_8 which + // will (hopefully) put less strain on the stack. + if (dc_numlights) + { + lighttable_t **xwalllights; + fixed_t height; + fixed_t bheight = 0; + INT32 solid = 0; + INT32 lighteffect = 0; + + for (i = 0; i < dc_numlights; i++) + { + // Check if the current light effects the colormap/lightlevel + rlight = &dc_lightlist[i]; + lighteffect = !(dc_lightlist[i].flags & FF_NOSHADE); + if (lighteffect) + { + lightnum = rlight->lightnum; + + if (lightnum < 0) + xwalllights = scalelight[0]; + else if (lightnum >= LIGHTLEVELS) + xwalllights = scalelight[LIGHTLEVELS-1]; + else + xwalllights = scalelight[lightnum]; + + pindex = FixedMul(spryscale, FixedDiv(640, vid.width))>>LIGHTSCALESHIFT; + + if (pindex >= MAXLIGHTSCALE) + pindex = MAXLIGHTSCALE-1; + + if (pfloor->flags & FF_FOG) + { + if (pfloor->master->frontsector->extra_colormap) + rlight->rcolormap = pfloor->master->frontsector->extra_colormap->colormap + (xwalllights[pindex] - colormaps); + else + rlight->rcolormap = xwalllights[pindex]; + } + else + { + if (rlight->extra_colormap) + rlight->rcolormap = rlight->extra_colormap->colormap + (xwalllights[pindex] - colormaps); + else + rlight->rcolormap = xwalllights[pindex]; + } + } + + solid = 0; // don't carry over solid-cutting flag from the previous light + + // Check if the current light can cut the current 3D floor. + if (rlight->flags & FF_CUTSOLIDS && !(pfloor->flags & FF_EXTRA)) + solid = 1; + else if (rlight->flags & FF_CUTEXTRA && pfloor->flags & FF_EXTRA) + { + if (rlight->flags & FF_EXTRA) + { + // The light is from an extra 3D floor... Check the flags so + // there are no undesired cuts. + if ((rlight->flags & (FF_FOG|FF_SWIMMABLE)) == (pfloor->flags & (FF_FOG|FF_SWIMMABLE))) + solid = 1; + } + else + solid = 1; + } + else + solid = 0; + + height = rlight->height; + rlight->height += rlight->heightstep; + + if (solid) + { + bheight = rlight->botheight - (FRACUNIT >> 1); + rlight->botheight += rlight->botheightstep; + } + + if (height <= windowtop) + { + if (lighteffect) + dc_colormap = rlight->rcolormap; + if (solid && windowtop < bheight) + windowtop = bheight; + continue; + } + + windowbottom = height; + if (windowbottom >= sprbotscreen) + { + windowbottom = sprbotscreen; + // draw the texture + rw.colfunc_2s (col); + for (i++; i < dc_numlights; i++) + { + rlight = &dc_lightlist[i]; + rlight->height += rlight->heightstep; + if (rlight->flags & FF_CUTLEVEL) + rlight->botheight += rlight->botheightstep; + } + continue; + } + // draw the texture + rw.colfunc_2s (col); + if (solid) + windowtop = bheight; + else + windowtop = windowbottom + 1; + if (lighteffect) + dc_colormap = rlight->rcolormap; + } + windowbottom = sprbotscreen; + // draw the texture, if there is any space left + if (windowtop < windowbottom) + rw.colfunc_2s (col); + + spryscale += rw.scalestep; + continue; + } + + // calculate lighting + pindex = FixedMul(spryscale, FixedDiv(640, vid.width))>>LIGHTSCALESHIFT; + + if (pindex >= MAXLIGHTSCALE) + pindex = MAXLIGHTSCALE - 1; + + dc_colormap = walllights[pindex]; + + if (pfloor->flags & FF_FOG && pfloor->master->frontsector->extra_colormap) + dc_colormap = pfloor->master->frontsector->extra_colormap->colormap + (dc_colormap - colormaps); + else if (frontsector->extra_colormap) + dc_colormap = frontsector->extra_colormap->colormap + (dc_colormap - colormaps); + + // draw the texture + rw.colfunc_2s (col); + spryscale += rw.scalestep; + } + } +} + +// +// R_ThickLightLists +// Creates light lists, but for thick sides. +// +static void R_ThickLightLists(drawseg_t *ds, INT32 range) +{ + INT32 lightnum; + sector_t tempsec; + INT32 templight; + INT32 i, p; + + lightlist_t *light; + r_lightlist_t *rlight; + ffloor_t *pfloor = rw.pfloor; dc_numlights = 0; + if (frontsector->numlights) { dc_numlights = frontsector->numlights; @@ -2975,6 +3101,8 @@ void R_RenderThickSideRange(drawseg_t *ds, INT32 x1, INT32 x2, ffloor_t *pfloor) fixed_t leftheight, rightheight; fixed_t pfloorleft, pfloorright; INT64 overflow_test; +#else + (void)range; #endif light = &frontsector->lightlist[i]; rlight = &dc_lightlist[p]; @@ -3006,8 +3134,6 @@ void R_RenderThickSideRange(drawseg_t *ds, INT32 x1, INT32 x2, ffloor_t *pfloor) leftheight -= viewz; rightheight -= viewz; -#define CLAMPMAX INT32_MAX -#define CLAMPMIN (-INT32_MAX) // This is not INT32_MIN on purpose! INT32_MIN makes the drawers freak out. // Monster Iestyn (25/03/18): do not skip these lights if they fail overflow test, just clamp them instead so they behave. overflow_test = (INT64)centeryfrac - (((INT64)leftheight*ds->scale1)>>FRACBITS); if (overflow_test > (INT64)CLAMPMAX) rlight->height = CLAMPMAX; @@ -3104,6 +3230,130 @@ void R_RenderThickSideRange(drawseg_t *ds, INT32 x1, INT32 x2, ffloor_t *pfloor) else walllights = scalelight[lightnum]; } +} + +// +// R_ThickStepping +// Set stepping values for thick sides. +// +#ifdef ESLOPE +static void R_ThickStepping(drawseg_t *ds, INT32 range) +{ + fixed_t right_top, right_bottom; + ffloor_t *pfloor = rw.pfloor; + + // calculate right ends now + if (*pfloor->t_slope) + right_top = P_GetZAt(*pfloor->t_slope, ds->rightpos.x, ds->rightpos.y) - viewz; + else + right_top = *pfloor->topheight - viewz; + + if (*pfloor->b_slope) + right_bottom = P_GetZAt(*pfloor->b_slope, ds->rightpos.x, ds->rightpos.y) - viewz; + else + right_bottom = *pfloor->bottomheight - viewz; + + // using INT64 to avoid 32bit overflow + rw.top_frac = (INT64)centeryfrac - (((INT64)rw.left_top * ds->scale1) >> FRACBITS); + rw.bottom_frac = (INT64)centeryfrac - (((INT64)rw.left_bottom * ds->scale1) >> FRACBITS); + rw.top_step = (INT64)centeryfrac - (((INT64)right_top * ds->scale2) >> FRACBITS); + rw.bottom_step = (INT64)centeryfrac - (((INT64)right_bottom * ds->scale2) >> FRACBITS); + + rw.top_step = (rw.top_step-rw.top_frac)/(range); + rw.bottom_step = (rw.bottom_step-rw.bottom_frac)/(range); + + rw.top_frac += rw.top_step * (rw.x - ds->x1); + rw.bottom_frac += rw.bottom_step * (rw.x - ds->x1); +} +#endif + +// +// R_RenderThickSideRange +// Renders all the thick sides in the given range. +// +void R_RenderThickSideRange(drawseg_t *ds, INT32 x1, INT32 x2, ffloor_t *pfloor) +{ + INT32 texnum; + + fixed_t offsetvalue = 0; +#ifdef ESLOPE + INT32 range; +#endif +#ifndef ESLOPE + fixed_t lheight; +#endif + line_t *newline = NULL; +#ifdef ESLOPE + // skew FOF walls with slopes? + boolean slopeskew = false; + pslope_t *skewslope = NULL; +#endif + + rw.x = x1; + rw.stopx = x2; + rw.pfloor = pfloor; + + // Calculate light table. + // Use different light tables + // for horizontal / vertical / diagonal. Diagonal? + // OPTIMIZE: get rid of LIGHTSEGSHIFT globally + + curline = ds->curline; + backsector = pfloor->target; + frontsector = curline->frontsector == pfloor->target ? curline->backsector : curline->frontsector; + texnum = R_GetTextureNum(sides[pfloor->master->sidenum[0]].midtexture); + + colfunc = colfuncs[BASEDRAWFUNC]; + + if (pfloor->master->flags & ML_TFERLINE) + { + size_t linenum = curline->linedef-backsector->lines[0]; + newline = pfloor->master->frontsector->lines[0] + linenum; + texnum = R_GetTextureNum(sides[newline->sidenum[0]].midtexture); + } + + if (pfloor->flags & FF_TRANSLUCENT) + { + boolean fuzzy = true; + + // Hacked up support for alpha value in software mode Tails 09-24-2002 + if (pfloor->alpha < 12) + return; // Don't even draw it + else if (pfloor->alpha < 38) + dc_transmap = transtables + ((tr_trans90-1)<alpha < 64) + dc_transmap = transtables + ((tr_trans80-1)<alpha < 89) + dc_transmap = transtables + ((tr_trans70-1)<alpha < 115) + dc_transmap = transtables + ((tr_trans60-1)<alpha < 140) + dc_transmap = transtables + ((tr_trans50-1)<alpha < 166) + dc_transmap = transtables + ((tr_trans40-1)<alpha < 192) + dc_transmap = transtables + ((tr_trans30-1)<alpha < 217) + dc_transmap = transtables + ((tr_trans20-1)<alpha < 243) + dc_transmap = transtables + ((tr_trans10-1)<flags & FF_FOG) + colfunc = colfuncs[COLDRAWFUNC_FOG]; + +#ifdef ESLOPE + range = max(ds->x2-ds->x1, 1); +#endif + //SoM: Moved these up here so they are available for my lightlist calculations + rw.scalestep = ds->scalestep; + spryscale = ds->scale1 + (x1 - ds->x1)*rw.scalestep; + + R_ThickLightLists(ds, range); maskedtexturecol = ds->thicksidecol; @@ -3114,14 +3364,14 @@ void R_RenderThickSideRange(drawseg_t *ds, INT32 x1, INT32 x2, ffloor_t *pfloor) #ifdef ESLOPE // calculate both left ends if (*pfloor->t_slope) - left_top = P_GetZAt(*pfloor->t_slope, ds->leftpos.x, ds->leftpos.y) - viewz; + rw.left_top = P_GetZAt(*pfloor->t_slope, ds->leftpos.x, ds->leftpos.y) - viewz; else - left_top = *pfloor->topheight - viewz; + rw.left_top = *pfloor->topheight - viewz; if (*pfloor->b_slope) - left_bottom = P_GetZAt(*pfloor->b_slope, ds->leftpos.x, ds->leftpos.y) - viewz; + rw.left_bottom = P_GetZAt(*pfloor->b_slope, ds->leftpos.x, ds->leftpos.y) - viewz; else - left_bottom = *pfloor->bottomheight - viewz; + rw.left_bottom = *pfloor->bottomheight - viewz; skewslope = *pfloor->t_slope; // skew using top slope by default if (newline) { @@ -3132,7 +3382,7 @@ void R_RenderThickSideRange(drawseg_t *ds, INT32 x1, INT32 x2, ffloor_t *pfloor) slopeskew = true; if (slopeskew) - dc_texturemid = left_top; + dc_texturemid = rw.left_top; else #endif dc_texturemid = *pfloor->topheight - viewz; @@ -3145,7 +3395,7 @@ void R_RenderThickSideRange(drawseg_t *ds, INT32 x1, INT32 x2, ffloor_t *pfloor) #ifdef ESLOPE skewslope = *pfloor->b_slope; // skew using bottom slope if (slopeskew) - dc_texturemid = left_bottom; + dc_texturemid = rw.left_bottom; else #endif offsetvalue -= *pfloor->topheight - *pfloor->bottomheight; @@ -3159,7 +3409,7 @@ void R_RenderThickSideRange(drawseg_t *ds, INT32 x1, INT32 x2, ffloor_t *pfloor) #ifdef ESLOPE skewslope = *pfloor->b_slope; // skew using bottom slope if (slopeskew) - dc_texturemid = left_bottom; + dc_texturemid = rw.left_bottom; else #endif offsetvalue -= *pfloor->topheight - *pfloor->bottomheight; @@ -3172,7 +3422,7 @@ void R_RenderThickSideRange(drawseg_t *ds, INT32 x1, INT32 x2, ffloor_t *pfloor) angle_t lineangle = R_PointToAngle2(curline->v1->x, curline->v1->y, curline->v2->x, curline->v2->y); if (skewslope) - ffloortextureslide = FixedMul(skewslope->zdelta, FINECOSINE((lineangle-skewslope->xydirection)>>ANGLETOFINESHIFT)); + rw.ffloortextureslide = FixedMul(skewslope->zdelta, FINECOSINE((lineangle-skewslope->xydirection)>>ANGLETOFINESHIFT)); } #endif @@ -3187,236 +3437,26 @@ void R_RenderThickSideRange(drawseg_t *ds, INT32 x1, INT32 x2, ffloor_t *pfloor) { if (textures[texnum]->flip & 2) // vertically flipped? { - colfunc_2s = R_DrawRepeatFlippedMaskedColumn; - column2s_length = textures[texnum]->height; + rw.colfunc_2s = R_DrawRepeatFlippedMaskedColumn; + rw.column2s_length = textures[texnum]->height; } else - colfunc_2s = R_DrawRepeatMaskedColumn; // render the usual 2sided single-patch packed texture + rw.colfunc_2s = R_DrawRepeatMaskedColumn; // render the usual 2sided single-patch packed texture } else { - colfunc_2s = R_Render2sidedMultiPatchColumn; //render multipatch with no holes (no post_t info) - column2s_length = textures[texnum]->height; + rw.colfunc_2s = R_Render2sidedMultiPatchColumn; //render multipatch with no holes (no post_t info) + rw.column2s_length = textures[texnum]->height; } #ifdef ESLOPE // Set heights according to plane, or slope, whichever - { - fixed_t right_top, right_bottom; - - // calculate right ends now - if (*pfloor->t_slope) - right_top = P_GetZAt(*pfloor->t_slope, ds->rightpos.x, ds->rightpos.y) - viewz; - else - right_top = *pfloor->topheight - viewz; - - if (*pfloor->b_slope) - right_bottom = P_GetZAt(*pfloor->b_slope, ds->rightpos.x, ds->rightpos.y) - viewz; - else - right_bottom = *pfloor->bottomheight - viewz; - - // using INT64 to avoid 32bit overflow - top_frac = (INT64)centeryfrac - (((INT64)left_top * ds->scale1) >> FRACBITS); - bottom_frac = (INT64)centeryfrac - (((INT64)left_bottom * ds->scale1) >> FRACBITS); - top_step = (INT64)centeryfrac - (((INT64)right_top * ds->scale2) >> FRACBITS); - bottom_step = (INT64)centeryfrac - (((INT64)right_bottom * ds->scale2) >> FRACBITS); - - top_step = (top_step-top_frac)/(range); - bottom_step = (bottom_step-bottom_frac)/(range); - - top_frac += top_step * (x1 - ds->x1); - bottom_frac += bottom_step * (x1 - ds->x1); - } + R_ThickStepping(ds, range); #endif // draw the columns - for (dc_x = x1; dc_x <= x2; dc_x++) - { - if (maskedtexturecol[dc_x] != INT16_MAX) - { -#ifdef ESLOPE - if (ffloortextureslide) { // skew FOF walls - if (oldx != -1) - dc_texturemid += FixedMul(ffloortextureslide, (maskedtexturecol[oldx]-maskedtexturecol[dc_x])< (INT64)CLAMPMAX) sprtopscreen = windowtop = CLAMPMAX; - else if (top_frac > (INT64)CLAMPMIN) sprtopscreen = windowtop = (fixed_t)top_frac; - else sprtopscreen = windowtop = CLAMPMIN; - if (bottom_frac > (INT64)CLAMPMAX) sprbotscreen = windowbottom = CLAMPMAX; - else if (bottom_frac > (INT64)CLAMPMIN) sprbotscreen = windowbottom = (fixed_t)bottom_frac; - else sprbotscreen = windowbottom = CLAMPMIN; - - top_frac += top_step; - bottom_frac += bottom_step; -#else - sprtopscreen = windowtop = (centeryfrac - FixedMul((dc_texturemid - offsetvalue), spryscale)); - sprbotscreen = windowbottom = FixedMul(*pfloor->topheight - *pfloor->bottomheight, spryscale) + sprtopscreen; -#endif - - // SoM: If column is out of range, why bother with it?? - if (windowbottom < topbounds || windowtop > bottombounds) - { - if (dc_numlights) - { - for (i = 0; i < dc_numlights; i++) - { - rlight = &dc_lightlist[i]; - rlight->height += rlight->heightstep; - if (rlight->flags & FF_CUTLEVEL) - rlight->botheight += rlight->botheightstep; - } - } - spryscale += rw.scalestep; - continue; - } - - dc_iscale = 0xffffffffu / (unsigned)spryscale; - - // Get data for the column - col = (column_t *)((UINT8 *)R_GetColumn(texnum,maskedtexturecol[dc_x]) - 3); - - // SoM: New code does not rely on R_DrawColumnShadowed_8 which - // will (hopefully) put less strain on the stack. - if (dc_numlights) - { - lighttable_t **xwalllights; - fixed_t height; - fixed_t bheight = 0; - INT32 solid = 0; - INT32 lighteffect = 0; - - for (i = 0; i < dc_numlights; i++) - { - // Check if the current light effects the colormap/lightlevel - rlight = &dc_lightlist[i]; - lighteffect = !(dc_lightlist[i].flags & FF_NOSHADE); - if (lighteffect) - { - lightnum = rlight->lightnum; - - if (lightnum < 0) - xwalllights = scalelight[0]; - else if (lightnum >= LIGHTLEVELS) - xwalllights = scalelight[LIGHTLEVELS-1]; - else - xwalllights = scalelight[lightnum]; - - pindex = FixedMul(spryscale, FixedDiv(640, vid.width))>>LIGHTSCALESHIFT; - - if (pindex >= MAXLIGHTSCALE) - pindex = MAXLIGHTSCALE-1; - - if (pfloor->flags & FF_FOG) - { - if (pfloor->master->frontsector->extra_colormap) - rlight->rcolormap = pfloor->master->frontsector->extra_colormap->colormap + (xwalllights[pindex] - colormaps); - else - rlight->rcolormap = xwalllights[pindex]; - } - else - { - if (rlight->extra_colormap) - rlight->rcolormap = rlight->extra_colormap->colormap + (xwalllights[pindex] - colormaps); - else - rlight->rcolormap = xwalllights[pindex]; - } - } - - solid = 0; // don't carry over solid-cutting flag from the previous light - - // Check if the current light can cut the current 3D floor. - if (rlight->flags & FF_CUTSOLIDS && !(pfloor->flags & FF_EXTRA)) - solid = 1; - else if (rlight->flags & FF_CUTEXTRA && pfloor->flags & FF_EXTRA) - { - if (rlight->flags & FF_EXTRA) - { - // The light is from an extra 3D floor... Check the flags so - // there are no undesired cuts. - if ((rlight->flags & (FF_FOG|FF_SWIMMABLE)) == (pfloor->flags & (FF_FOG|FF_SWIMMABLE))) - solid = 1; - } - else - solid = 1; - } - else - solid = 0; - - height = rlight->height; - rlight->height += rlight->heightstep; - - if (solid) - { - bheight = rlight->botheight - (FRACUNIT >> 1); - rlight->botheight += rlight->botheightstep; - } - - if (height <= windowtop) - { - if (lighteffect) - dc_colormap = rlight->rcolormap; - if (solid && windowtop < bheight) - windowtop = bheight; - continue; - } - - windowbottom = height; - if (windowbottom >= sprbotscreen) - { - windowbottom = sprbotscreen; - // draw the texture - colfunc_2s (col); - for (i++; i < dc_numlights; i++) - { - rlight = &dc_lightlist[i]; - rlight->height += rlight->heightstep; - if (rlight->flags & FF_CUTLEVEL) - rlight->botheight += rlight->botheightstep; - } - continue; - } - // draw the texture - colfunc_2s (col); - if (solid) - windowtop = bheight; - else - windowtop = windowbottom + 1; - if (lighteffect) - dc_colormap = rlight->rcolormap; - } - windowbottom = sprbotscreen; - // draw the texture, if there is any space left - if (windowtop < windowbottom) - colfunc_2s (col); - - spryscale += rw.scalestep; - continue; - } - - // calculate lighting - pindex = FixedMul(spryscale, FixedDiv(640, vid.width))>>LIGHTSCALESHIFT; - - if (pindex >= MAXLIGHTSCALE) - pindex = MAXLIGHTSCALE - 1; - - dc_colormap = walllights[pindex]; - - if (pfloor->flags & FF_FOG && pfloor->master->frontsector->extra_colormap) - dc_colormap = pfloor->master->frontsector->extra_colormap->colormap + (dc_colormap - colormaps); - else if (frontsector->extra_colormap) - dc_colormap = frontsector->extra_colormap->colormap + (dc_colormap - colormaps); - - // draw the texture - colfunc_2s (col); - spryscale += rw.scalestep; - } - } + rw.texnum = texnum; + R_RenderThickSegLoop(); colfunc = colfuncs[BASEDRAWFUNC]; #undef CLAMPMAX diff --git a/src/r_state.h b/src/r_state.h index 8211ac75a..cecdb8f4d 100644 --- a/src/r_state.h +++ b/src/r_state.h @@ -109,6 +109,21 @@ typedef struct fixed_t distance; angle_t normalangle; angle_t angle1; // angle to line origin + + // for masked segs and thick sides + INT32 texnum; + void (*colfunc_2s) (column_t *); + INT32 column2s_length; // column->length : for multi-patch on 2sided wall = texture->height + + // thick sides + ffloor_t *pfloor; +#ifdef ESLOPE + // Render FOF sides kinda like normal sides, with the frac and step and everything + // NOTE: INT64 instead of fixed_t because overflow concerns + INT64 top_frac, top_step, bottom_frac, bottom_step; + fixed_t ffloortextureslide; + fixed_t left_top, left_bottom; // needed here for slope skewing +#endif } renderwall_t; extern renderwall_t rw; From 0ec800b266bc22c06874789c02a7084bd9ec9938 Mon Sep 17 00:00:00 2001 From: Jaime Passos Date: Thu, 26 Dec 2019 17:20:17 -0300 Subject: [PATCH 406/746] I forgot a ``static`` --- src/r_segs.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/r_segs.c b/src/r_segs.c index 1b78a22dd..1d44d9f84 100644 --- a/src/r_segs.c +++ b/src/r_segs.c @@ -2863,7 +2863,7 @@ static void R_DrawRepeatFlippedMaskedColumn(column_t *col) // R_RenderThickSegLoop // Like R_RenderSegLoop, but for thick sides. // -void R_RenderThickSegLoop(void) +static void R_RenderThickSegLoop(void) { column_t *col; size_t pindex; From ad6cda7c53ec01748754b8fd883003017cce448f Mon Sep 17 00:00:00 2001 From: Jaime Passos Date: Thu, 26 Dec 2019 17:39:18 -0300 Subject: [PATCH 407/746] Masked stuff --- src/r_segs.c | 554 ++++++++++++++++++++++++++------------------------ src/r_state.h | 3 + 2 files changed, 296 insertions(+), 261 deletions(-) diff --git a/src/r_segs.c b/src/r_segs.c index 1d44d9f84..fa26420a8 100644 --- a/src/r_segs.c +++ b/src/r_segs.c @@ -2405,96 +2405,210 @@ static void R_DrawFlippedMaskedSegColumn(column_t *column) R_DrawFlippedMaskedColumn(column, rw.column2s_length); } -void R_RenderMaskedSegRange(drawseg_t *ds, INT32 x1, INT32 x2) +// +// R_RenderMaskedSegLoop +// Like R_RenderSegLoop, but for masked segs. +// +static void R_RenderMaskedSegLoop(drawseg_t *ds) { size_t pindex; column_t *col; - INT32 lightnum, texnum, i; + INT32 i; fixed_t height, realbot; + r_lightlist_t *rlight; + INT64 overflow_test; + + for (dc_x = rw.x; dc_x <= rw.stopx; dc_x++) + { +#ifdef ESLOPE + dc_texturemid = ds->maskedtextureheight[dc_x]; + + if (!!(curline->linedef->flags & ML_DONTPEGBOTTOM) ^ !!(curline->linedef->flags & ML_EFFECT3)) + dc_texturemid += (textureheight[rw.texnum])*rw.maskedrepeat + textureheight[rw.texnum]; + else + dc_texturemid -= (textureheight[rw.texnum])*rw.maskedrepeat; +#endif + // calculate lighting + if (maskedtexturecol[dc_x] != INT16_MAX) + { + // Check for overflows first + overflow_test = (INT64)centeryfrac - (((INT64)dc_texturemid*spryscale)>>FRACBITS); + if (overflow_test < 0) overflow_test = -overflow_test; + if ((UINT64)overflow_test&0xFFFFFFFF80000000ULL) + { + // Eh, no, go away, don't waste our time + if (dc_numlights) + { + for (i = 0; i < dc_numlights; i++) + { + rlight = &dc_lightlist[i]; + rlight->height += rlight->heightstep; + } + } + spryscale += rw.scalestep; + continue; + } + + if (dc_numlights) + { + lighttable_t **xwalllights; + + sprbotscreen = INT32_MAX; + sprtopscreen = windowtop = (centeryfrac - FixedMul(dc_texturemid, spryscale)); + + realbot = windowbottom = FixedMul(textureheight[rw.texnum], spryscale) + sprtopscreen; + dc_iscale = 0xffffffffu / (unsigned)spryscale; + + // draw the texture + col = (column_t *)((UINT8 *)R_GetColumn(rw.texnum, maskedtexturecol[dc_x]) - 3); + + for (i = 0; i < dc_numlights; i++) + { + rlight = &dc_lightlist[i]; + + if ((rlight->flags & FF_NOSHADE)) + continue; + + if (rlight->lightnum < 0) + xwalllights = scalelight[0]; + else if (rlight->lightnum >= LIGHTLEVELS) + xwalllights = scalelight[LIGHTLEVELS-1]; + else + xwalllights = scalelight[rlight->lightnum]; + + pindex = FixedMul(spryscale, FixedDiv(640, vid.width))>>LIGHTSCALESHIFT; + + if (pindex >= MAXLIGHTSCALE) + pindex = MAXLIGHTSCALE - 1; + + if (rlight->extra_colormap) + rlight->rcolormap = rlight->extra_colormap->colormap + (xwalllights[pindex] - colormaps); + else + rlight->rcolormap = xwalllights[pindex]; + + height = rlight->height; + rlight->height += rlight->heightstep; + + if (height <= windowtop) + { + dc_colormap = rlight->rcolormap; + continue; + } + + windowbottom = height; + if (windowbottom >= realbot) + { + windowbottom = realbot; + rw.colfunc_2s(col); + for (i++; i < dc_numlights; i++) + { + rlight = &dc_lightlist[i]; + rlight->height += rlight->heightstep; + } + + continue; + } + rw.colfunc_2s(col); + windowtop = windowbottom + 1; + dc_colormap = rlight->rcolormap; + } + windowbottom = realbot; + if (windowtop < windowbottom) + rw.colfunc_2s(col); + + spryscale += rw.scalestep; + continue; + } + + // calculate lighting + pindex = FixedMul(spryscale, FixedDiv(640, vid.width))>>LIGHTSCALESHIFT; + + if (pindex >= MAXLIGHTSCALE) + pindex = MAXLIGHTSCALE - 1; + + dc_colormap = walllights[pindex]; + + if (frontsector->extra_colormap) + dc_colormap = frontsector->extra_colormap->colormap + (dc_colormap - colormaps); + + sprtopscreen = centeryfrac - FixedMul(dc_texturemid, spryscale); + dc_iscale = 0xffffffffu / (unsigned)spryscale; + + // draw the texture + col = (column_t *)((UINT8 *)R_GetColumn(rw.texnum, maskedtexturecol[dc_x]) - 3); + +//#ifdef POLYOBJECTS_PLANES +#if 0 // Disabling this allows inside edges to render below the planes, for until the clipping is fixed to work right when POs are near the camera. -Red + if (curline->dontrenderme && curline->polyseg && (curline->polyseg->flags & POF_RENDERPLANES)) + { + fixed_t my_topscreen; + fixed_t my_bottomscreen; + fixed_t my_yl, my_yh; + + my_topscreen = sprtopscreen + spryscale*col->topdelta; + my_bottomscreen = sprbotscreen == INT32_MAX ? my_topscreen + spryscale*col->length + : sprbotscreen + spryscale*col->length; + + my_yl = (my_topscreen+FRACUNIT-1)>>FRACBITS; + my_yh = (my_bottomscreen-1)>>FRACBITS; +// CONS_Debug(DBG_RENDER, "my_topscreen: %d\nmy_bottomscreen: %d\nmy_yl: %d\nmy_yh: %d\n", my_topscreen, my_bottomscreen, my_yl, my_yh); + + if (numffloors) + { + INT32 top = my_yl; + INT32 bottom = my_yh; + + for (i = 0; i < numffloors; i++) + { + if (!ffloor[i].polyobj || ffloor[i].polyobj != curline->polyseg) + continue; + + if (ffloor[i].height < viewz) + { + INT32 top_w = ffloor[i].plane->top[dc_x]; + +// CONS_Debug(DBG_RENDER, "Leveltime : %d\n", leveltime); +// CONS_Debug(DBG_RENDER, "Top is %d, top_w is %d\n", top, top_w); + if (top_w < top) + { + ffloor[i].plane->top[dc_x] = (INT16)top; + ffloor[i].plane->picnum = 0; + } +// CONS_Debug(DBG_RENDER, "top_w is now %d\n", ffloor[i].plane->top[dc_x]); + } + else if (ffloor[i].height > viewz) + { + INT32 bottom_w = ffloor[i].plane->bottom[dc_x]; + + if (bottom_w > bottom) + { + ffloor[i].plane->bottom[dc_x] = (INT16)bottom; + ffloor[i].plane->picnum = 0; + } + } + } + } + } + else +#endif + rw.colfunc_2s(col); + } + spryscale += rw.scalestep; + } +} + +// +// R_MaskedLightLists +// Creates light lists, but for masked segs. +// +static void R_MaskedLightLists(drawseg_t *ds, INT32 range) +{ lightlist_t *light; r_lightlist_t *rlight; - line_t *ldef; - sector_t *front, *back; - INT32 times, repeats; - INT64 overflow_test; -#ifdef ESLOPE - INT32 range; -#endif + INT32 lightnum, i; - // Calculate light table. - // Use different light tables - // for horizontal / vertical / diagonal. Diagonal? - // OPTIMIZE: get rid of LIGHTSEGSHIFT globally - curline = ds->curline; - frontsector = curline->frontsector; - backsector = curline->backsector; - texnum = R_GetTextureNum(curline->sidedef->midtexture); - windowbottom = windowtop = sprbotscreen = INT32_MAX; - - // hack translucent linedef types (900-909 for transtables 1-9) - ldef = curline->linedef; - switch (ldef->special) - { - case 900: - case 901: - case 902: - case 903: - case 904: - case 905: - case 906: - case 907: - case 908: - dc_transmap = transtables + ((ldef->special-900)<ceilingheight; - windowbottom = frontsector->floorheight; - break; - default: - colfunc = colfuncs[BASEDRAWFUNC]; - break; - } - - if (curline->polyseg && curline->polyseg->translucency > 0) - { - if (curline->polyseg->translucency >= NUMTRANSMAPS) - return; - - dc_transmap = transtables + ((curline->polyseg->translucency-1)<x2-ds->x1, 1); -#endif - rw.scalestep = ds->scalestep; - spryscale = ds->scale1 + (x1 - ds->x1)*rw.scalestep; - - // Texture must be cached before setting colfunc_2s, - // otherwise texture[texnum]->holes may be false when it shouldn't be - R_CheckTextureCache(texnum); - // handle case where multipatch texture is drawn on a 2sided wall, multi-patch textures - // are not stored per-column with post info in SRB2 - if (textures[texnum]->holes) - { - if (textures[texnum]->flip & 2) // vertically flipped? - { - rw.colfunc_2s = R_DrawFlippedMaskedSegColumn; - rw.column2s_length = textures[texnum]->height; - } - else - rw.colfunc_2s = R_DrawMaskedColumn; // render the usual 2sided single-patch packed texture - } - else - { - rw.colfunc_2s = R_Render2sidedMultiPatchColumn; // render multipatch with no holes (no post_t info) - rw.column2s_length = textures[texnum]->height; - } - - // Setup lighting based on the presence/lack-of 3D floors. dc_numlights = 0; + if (frontsector->numlights) { dc_numlights = frontsector->numlights; @@ -2508,6 +2622,8 @@ void R_RenderMaskedSegRange(drawseg_t *ds, INT32 x1, INT32 x2) { #ifdef ESLOPE fixed_t leftheight, rightheight; +#else + (void)range; #endif light = &frontsector->lightlist[i]; rlight = &dc_lightlist[i]; @@ -2579,6 +2695,99 @@ void R_RenderMaskedSegRange(drawseg_t *ds, INT32 x1, INT32 x2) else walllights = scalelight[lightnum]; } +} + +// +// R_RenderMaskedSegRange +// Renders all the masked segs in the given range. +// +void R_RenderMaskedSegRange(drawseg_t *ds, INT32 x1, INT32 x2) +{ + INT32 texnum, i; + r_lightlist_t *rlight; + line_t *ldef; + sector_t *front, *back; + INT32 times, repeats; + INT32 range; + + // Calculate light table. + // Use different light tables + // for horizontal / vertical / diagonal. Diagonal? + // OPTIMIZE: get rid of LIGHTSEGSHIFT globally + curline = ds->curline; + frontsector = curline->frontsector; + backsector = curline->backsector; + texnum = R_GetTextureNum(curline->sidedef->midtexture); + windowbottom = windowtop = sprbotscreen = INT32_MAX; + + rw.x = x1; + rw.stopx = x2; + rw.texnum = texnum; + + // hack translucent linedef types (900-909 for transtables 1-9) + ldef = curline->linedef; + switch (ldef->special) + { + case 900: + case 901: + case 902: + case 903: + case 904: + case 905: + case 906: + case 907: + case 908: + dc_transmap = transtables + ((ldef->special-900)<ceilingheight; + windowbottom = frontsector->floorheight; + break; + default: + colfunc = colfuncs[BASEDRAWFUNC]; + break; + } + + if (curline->polyseg && curline->polyseg->translucency > 0) + { + if (curline->polyseg->translucency >= NUMTRANSMAPS) + return; + + dc_transmap = transtables + ((curline->polyseg->translucency-1)<x2-ds->x1, 1); +#endif + rw.scalestep = ds->scalestep; + spryscale = ds->scale1 + (x1 - ds->x1)*rw.scalestep; + + // Texture must be cached before setting colfunc_2s, + // otherwise texture[texnum]->holes may be false when it shouldn't be + R_CheckTextureCache(texnum); + // handle case where multipatch texture is drawn on a 2sided wall, multi-patch textures + // are not stored per-column with post info in SRB2 + if (textures[texnum]->holes) + { + if (textures[texnum]->flip & 2) // vertically flipped? + { + rw.colfunc_2s = R_DrawFlippedMaskedSegColumn; + rw.column2s_length = textures[texnum]->height; + } + else + rw.colfunc_2s = R_DrawMaskedColumn; // render the usual 2sided single-patch packed texture + } + else + { + rw.colfunc_2s = R_Render2sidedMultiPatchColumn; // render multipatch with no holes (no post_t info) + rw.column2s_length = textures[texnum]->height; + } + + // Setup lighting based on the presence/lack-of 3D floors. + R_MaskedLightLists(ds, range); maskedtexturecol = ds->maskedtexturecol; @@ -2658,183 +2867,8 @@ void R_RenderMaskedSegRange(drawseg_t *ds, INT32 x1, INT32 x2) dc_texheight = textureheight[texnum]>>FRACBITS; // draw the columns - for (dc_x = x1; dc_x <= x2; dc_x++) - { -#ifdef ESLOPE - dc_texturemid = ds->maskedtextureheight[dc_x]; - - if (!!(curline->linedef->flags & ML_DONTPEGBOTTOM) ^ !!(curline->linedef->flags & ML_EFFECT3)) - dc_texturemid += (textureheight[texnum])*times + textureheight[texnum]; - else - dc_texturemid -= (textureheight[texnum])*times; -#endif - // calculate lighting - if (maskedtexturecol[dc_x] != INT16_MAX) - { - // Check for overflows first - overflow_test = (INT64)centeryfrac - (((INT64)dc_texturemid*spryscale)>>FRACBITS); - if (overflow_test < 0) overflow_test = -overflow_test; - if ((UINT64)overflow_test&0xFFFFFFFF80000000ULL) - { - // Eh, no, go away, don't waste our time - if (dc_numlights) - { - for (i = 0; i < dc_numlights; i++) - { - rlight = &dc_lightlist[i]; - rlight->height += rlight->heightstep; - } - } - spryscale += rw.scalestep; - continue; - } - - if (dc_numlights) - { - lighttable_t **xwalllights; - - sprbotscreen = INT32_MAX; - sprtopscreen = windowtop = (centeryfrac - FixedMul(dc_texturemid, spryscale)); - - realbot = windowbottom = FixedMul(textureheight[texnum], spryscale) + sprtopscreen; - dc_iscale = 0xffffffffu / (unsigned)spryscale; - - // draw the texture - col = (column_t *)((UINT8 *)R_GetColumn(texnum, maskedtexturecol[dc_x]) - 3); - - for (i = 0; i < dc_numlights; i++) - { - rlight = &dc_lightlist[i]; - - if ((rlight->flags & FF_NOSHADE)) - continue; - - if (rlight->lightnum < 0) - xwalllights = scalelight[0]; - else if (rlight->lightnum >= LIGHTLEVELS) - xwalllights = scalelight[LIGHTLEVELS-1]; - else - xwalllights = scalelight[rlight->lightnum]; - - pindex = FixedMul(spryscale, FixedDiv(640, vid.width))>>LIGHTSCALESHIFT; - - if (pindex >= MAXLIGHTSCALE) - pindex = MAXLIGHTSCALE - 1; - - if (rlight->extra_colormap) - rlight->rcolormap = rlight->extra_colormap->colormap + (xwalllights[pindex] - colormaps); - else - rlight->rcolormap = xwalllights[pindex]; - - height = rlight->height; - rlight->height += rlight->heightstep; - - if (height <= windowtop) - { - dc_colormap = rlight->rcolormap; - continue; - } - - windowbottom = height; - if (windowbottom >= realbot) - { - windowbottom = realbot; - rw.colfunc_2s(col); - for (i++; i < dc_numlights; i++) - { - rlight = &dc_lightlist[i]; - rlight->height += rlight->heightstep; - } - - continue; - } - rw.colfunc_2s(col); - windowtop = windowbottom + 1; - dc_colormap = rlight->rcolormap; - } - windowbottom = realbot; - if (windowtop < windowbottom) - rw.colfunc_2s(col); - - spryscale += rw.scalestep; - continue; - } - - // calculate lighting - pindex = FixedMul(spryscale, FixedDiv(640, vid.width))>>LIGHTSCALESHIFT; - - if (pindex >= MAXLIGHTSCALE) - pindex = MAXLIGHTSCALE - 1; - - dc_colormap = walllights[pindex]; - - if (frontsector->extra_colormap) - dc_colormap = frontsector->extra_colormap->colormap + (dc_colormap - colormaps); - - sprtopscreen = centeryfrac - FixedMul(dc_texturemid, spryscale); - dc_iscale = 0xffffffffu / (unsigned)spryscale; - - // draw the texture - col = (column_t *)((UINT8 *)R_GetColumn(texnum, maskedtexturecol[dc_x]) - 3); - -//#ifdef POLYOBJECTS_PLANES -#if 0 // Disabling this allows inside edges to render below the planes, for until the clipping is fixed to work right when POs are near the camera. -Red - if (curline->dontrenderme && curline->polyseg && (curline->polyseg->flags & POF_RENDERPLANES)) - { - fixed_t my_topscreen; - fixed_t my_bottomscreen; - fixed_t my_yl, my_yh; - - my_topscreen = sprtopscreen + spryscale*col->topdelta; - my_bottomscreen = sprbotscreen == INT32_MAX ? my_topscreen + spryscale*col->length - : sprbotscreen + spryscale*col->length; - - my_yl = (my_topscreen+FRACUNIT-1)>>FRACBITS; - my_yh = (my_bottomscreen-1)>>FRACBITS; - // CONS_Debug(DBG_RENDER, "my_topscreen: %d\nmy_bottomscreen: %d\nmy_yl: %d\nmy_yh: %d\n", my_topscreen, my_bottomscreen, my_yl, my_yh); - - if (numffloors) - { - INT32 top = my_yl; - INT32 bottom = my_yh; - - for (i = 0; i < numffloors; i++) - { - if (!ffloor[i].polyobj || ffloor[i].polyobj != curline->polyseg) - continue; - - if (ffloor[i].height < viewz) - { - INT32 top_w = ffloor[i].plane->top[dc_x]; - - // CONS_Debug(DBG_RENDER, "Leveltime : %d\n", leveltime); - // CONS_Debug(DBG_RENDER, "Top is %d, top_w is %d\n", top, top_w); - if (top_w < top) - { - ffloor[i].plane->top[dc_x] = (INT16)top; - ffloor[i].plane->picnum = 0; - } - // CONS_Debug(DBG_RENDER, "top_w is now %d\n", ffloor[i].plane->top[dc_x]); - } - else if (ffloor[i].height > viewz) - { - INT32 bottom_w = ffloor[i].plane->bottom[dc_x]; - - if (bottom_w > bottom) - { - ffloor[i].plane->bottom[dc_x] = (INT16)bottom; - ffloor[i].plane->picnum = 0; - } - } - } - } - } - else -#endif - rw.colfunc_2s(col); - } - spryscale += rw.scalestep; - } + rw.maskedrepeat = times; + R_RenderMaskedSegLoop(ds); } colfunc = colfuncs[BASEDRAWFUNC]; } @@ -3276,9 +3310,7 @@ void R_RenderThickSideRange(drawseg_t *ds, INT32 x1, INT32 x2, ffloor_t *pfloor) INT32 texnum; fixed_t offsetvalue = 0; -#ifdef ESLOPE INT32 range; -#endif #ifndef ESLOPE fixed_t lheight; #endif diff --git a/src/r_state.h b/src/r_state.h index cecdb8f4d..2c5e5fcf7 100644 --- a/src/r_state.h +++ b/src/r_state.h @@ -115,6 +115,9 @@ typedef struct void (*colfunc_2s) (column_t *); INT32 column2s_length; // column->length : for multi-patch on 2sided wall = texture->height + // masked segs + INT32 maskedrepeat; + // thick sides ffloor_t *pfloor; #ifdef ESLOPE From 69b4efb57966eacd62da24e43fedbaf99d29fd46 Mon Sep 17 00:00:00 2001 From: Jaime Passos Date: Thu, 26 Dec 2019 18:13:03 -0300 Subject: [PATCH 408/746] 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 ca5a4d90e0e3445df560a6adc7884eb22df02f3b Mon Sep 17 00:00:00 2001 From: Monster Iestyn Date: Thu, 26 Dec 2019 21:59:09 +0000 Subject: [PATCH 409/746] Fix mixed declaration-and-code compiling error --- src/p_mobj.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/p_mobj.c b/src/p_mobj.c index b3705ee44..9ecd1d32a 100644 --- a/src/p_mobj.c +++ b/src/p_mobj.c @@ -8321,6 +8321,8 @@ static boolean P_MobjDeadThink(mobj_t *mobj) // See Linedef Exec 457 (Track mobj angle to point) static void P_TracerAngleThink(mobj_t *mobj) { + angle_t ang; + if (!mobj->tracer) return; @@ -8333,7 +8335,7 @@ static void P_TracerAngleThink(mobj_t *mobj) // mobj->cvval - Allowable failure delay // mobj->cvmem - Failure timer - angle_t ang = mobj->angle - R_PointToAngle2(mobj->x, mobj->y, mobj->tracer->x, mobj->tracer->y); + ang = mobj->angle - R_PointToAngle2(mobj->x, mobj->y, mobj->tracer->x, mobj->tracer->y); // \todo account for distance between mobj and tracer // Because closer mobjs can be facing beyond the angle tolerance From dd1ca69f54b3816f8042f81be0ee7ac44091594c Mon Sep 17 00:00:00 2001 From: James R Date: Thu, 26 Dec 2019 14:59:31 -0800 Subject: [PATCH 410/746] P_PlayerHitsPlayer is too big for inline, and these other functions are getting there --- src/p_inter.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/p_inter.c b/src/p_inter.c index 70fb01fd0..1acbad085 100644 --- a/src/p_inter.c +++ b/src/p_inter.c @@ -2962,7 +2962,7 @@ void P_KillMobj(mobj_t *target, mobj_t *inflictor, mobj_t *source, UINT8 damaget Graue 12-22-2003 */ } -static inline void P_NiGHTSDamage(mobj_t *target, mobj_t *source) +static void P_NiGHTSDamage(mobj_t *target, mobj_t *source) { player_t *player = target->player; tic_t oldnightstime = player->nightstime; @@ -3028,7 +3028,7 @@ static inline void P_NiGHTSDamage(mobj_t *target, mobj_t *source) } } -static inline boolean P_TagDamage(mobj_t *target, mobj_t *inflictor, mobj_t *source, INT32 damage, UINT8 damagetype) +static boolean P_TagDamage(mobj_t *target, mobj_t *inflictor, mobj_t *source, INT32 damage, UINT8 damagetype) { player_t *player = target->player; (void)damage; //unused parm @@ -3132,7 +3132,7 @@ static inline boolean P_TagDamage(mobj_t *target, mobj_t *inflictor, mobj_t *sou return true; } -static inline boolean P_PlayerHitsPlayer(mobj_t *target, mobj_t *inflictor, mobj_t *source, INT32 damage, UINT8 damagetype) +static boolean P_PlayerHitsPlayer(mobj_t *target, mobj_t *inflictor, mobj_t *source, INT32 damage, UINT8 damagetype) { player_t *player = target->player; From 56fd29a42a5f9042611255da92df764e57a84632 Mon Sep 17 00:00:00 2001 From: Jaime Passos Date: Thu, 26 Dec 2019 21:27:30 -0300 Subject: [PATCH 411/746] stuff --- src/hardware/hw_main.c | 11 +++-------- src/r_patch.c | 25 ++++++++++++++++++++----- src/r_patch.h | 5 +++-- src/r_things.c | 20 ++++++++------------ 4 files changed, 34 insertions(+), 27 deletions(-) diff --git a/src/hardware/hw_main.c b/src/hardware/hw_main.c index 6ef48f222..41e2c5693 100644 --- a/src/hardware/hw_main.c +++ b/src/hardware/hw_main.c @@ -5501,17 +5501,12 @@ static void HWR_ProjectSprite(mobj_t *thing) fixed_t spr_offset, spr_topoffset; #ifdef ROTSPRITE patch_t *rotsprite = NULL; - angle_t arollangle; - UINT32 rollangle; + INT32 rollangle = 0; #endif if (!thing) return; -#ifdef ROTSPRITE - arollangle = thing->rollangle; - rollangle = AngleFixed(arollangle)>>FRACBITS; -#endif this_scale = FIXED_TO_FLOAT(thing->scale); // transform the origin point @@ -5618,11 +5613,11 @@ static void HWR_ProjectSprite(mobj_t *thing) spr_topoffset = spritecachedinfo[lumpoff].topoffset; #ifdef ROTSPRITE - if (rollangle > 0) + if (thing->rollangle) { + rollangle = R_GetRollAngle(thing->rollangle); if (!sprframe->rotsprite.cached[rot]) R_CacheRotSprite(thing->sprite, (thing->frame & FF_FRAMEMASK), sprinfo, sprframe, rot, flip); - rollangle /= ROTANGDIFF; rotsprite = sprframe->rotsprite.patch[rot][rollangle]; if (rotsprite != NULL) { diff --git a/src/r_patch.c b/src/r_patch.c index 69d5ad1a2..9803d01f0 100644 --- a/src/r_patch.c +++ b/src/r_patch.c @@ -49,8 +49,6 @@ #endif static unsigned char imgbuf[1<<26]; -fixed_t cosang2rad[ROTANGLES]; -fixed_t sinang2rad[ROTANGLES]; // // R_CheckIfPatch @@ -1123,6 +1121,23 @@ static UINT16 GetPatchPixel(patch_t *patch, INT32 x, INT32 y, boolean flip) } #ifdef ROTSPRITE +// +// R_GetRollAngle +// +// Angles precalculated in R_InitSprites. +// +fixed_t rollcosang[ROTANGLES]; +fixed_t rollsinang[ROTANGLES]; +INT32 R_GetRollAngle(angle_t rollangle) +{ + INT32 ra = AngleFixed(rollangle)>>FRACBITS; +#if (ROTANGDIFF > 1) + ra += (ROTANGDIFF/2); +#endif + ra /= ROTANGDIFF; + return max(0, min(ra, ROTANGLES)); +} + // // R_CacheRotSprite // @@ -1180,12 +1195,12 @@ void R_CacheRotSprite(spritenum_t sprnum, UINT8 frame, spriteinfo_t *sprinfo, sp leftoffset = width - leftoffset; } - for (angle = 0; angle < ROTANGLES; angle++) + for (angle = 1; angle < ROTANGLES; angle++) { INT32 newwidth, newheight; - ca = cosang2rad[angle]; - sa = sinang2rad[angle]; + ca = rollcosang[angle]; + sa = rollsinang[angle]; // Find the dimensions of the rotated patch. { diff --git a/src/r_patch.h b/src/r_patch.h index c534debdb..72371f253 100644 --- a/src/r_patch.h +++ b/src/r_patch.h @@ -62,11 +62,12 @@ void R_ParseSPRTINFOLump(UINT16 wadNum, UINT16 lumpNum); // Sprite rotation #ifdef ROTSPRITE +INT32 R_GetRollAngle(angle_t rollangle); 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); -extern fixed_t cosang2rad[ROTANGLES]; -extern fixed_t sinang2rad[ROTANGLES]; +extern fixed_t rollcosang[ROTANGLES]; +extern fixed_t rollsinang[ROTANGLES]; #endif #endif // __R_PATCH__ diff --git a/src/r_things.c b/src/r_things.c index d29baa711..465430017 100644 --- a/src/r_things.c +++ b/src/r_things.c @@ -500,7 +500,7 @@ void R_InitSprites(void) { size_t i; #ifdef ROTSPRITE - INT32 angle, ra; + INT32 angle; float fa; #endif @@ -508,14 +508,11 @@ void R_InitSprites(void) negonearray[i] = -1; #ifdef ROTSPRITE - for (angle = 0; angle < ROTANGLES; angle++) + for (angle = 1; angle < ROTANGLES; angle++) { - ra = (ROTANGDIFF * angle); - if (!ra) - ra = (ROTANGDIFF / 2) + 1; - fa = ANG2RAD(FixedAngle(ra<rollangle; - UINT32 rollangle = AngleFixed(arollangle)>>FRACBITS; + INT32 rollangle = 0; #endif #ifndef PROPERPAPER @@ -1262,11 +1258,11 @@ static void R_ProjectSprite(mobj_t *thing) spr_topoffset = spritecachedinfo[lump].topoffset; #ifdef ROTSPRITE - if (rollangle > 0) + if (thing->rollangle) { + rollangle = R_GetRollAngle(thing->rollangle); if (!sprframe->rotsprite.cached[rot]) R_CacheRotSprite(thing->sprite, (thing->frame & FF_FRAMEMASK), sprinfo, sprframe, rot, flip); - rollangle /= ROTANGDIFF; rotsprite = sprframe->rotsprite.patch[rot][rollangle]; if (rotsprite != NULL) { From 4b653a0b12c9f5c6657f7be161690fc797e295ad Mon Sep 17 00:00:00 2001 From: Jaime Passos Date: Thu, 26 Dec 2019 21:36:35 -0300 Subject: [PATCH 412/746] Remove the min() and max() calls. --- src/r_patch.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/r_patch.c b/src/r_patch.c index 9803d01f0..83593d295 100644 --- a/src/r_patch.c +++ b/src/r_patch.c @@ -1135,7 +1135,7 @@ INT32 R_GetRollAngle(angle_t rollangle) ra += (ROTANGDIFF/2); #endif ra /= ROTANGDIFF; - return max(0, min(ra, ROTANGLES)); + return ra; } // From da1718f93c0298575d93dbf6e763d6630806dd50 Mon Sep 17 00:00:00 2001 From: Jaime Passos Date: Thu, 26 Dec 2019 21:49:36 -0300 Subject: [PATCH 413/746] Avoid possible overflows in the rotsprite arrays. --- src/r_patch.c | 1 + 1 file changed, 1 insertion(+) diff --git a/src/r_patch.c b/src/r_patch.c index 83593d295..0519d6dc9 100644 --- a/src/r_patch.c +++ b/src/r_patch.c @@ -1135,6 +1135,7 @@ INT32 R_GetRollAngle(angle_t rollangle) ra += (ROTANGDIFF/2); #endif ra /= ROTANGDIFF; + ra %= ROTANGLES; return ra; } From f26bdf00fe6d02ea092554bc72135d015a752a4c Mon Sep 17 00:00:00 2001 From: James R Date: Thu, 26 Dec 2019 18:12:10 -0800 Subject: [PATCH 414/746] A system to encode flags in the command buffer --- src/command.c | 67 ++++++++++++++++++++++++++++++++++++++++++++------- src/command.h | 7 ++++-- 2 files changed, 63 insertions(+), 11 deletions(-) diff --git a/src/command.c b/src/command.c index 33d8ead96..3aa22b62f 100644 --- a/src/command.c +++ b/src/command.c @@ -61,6 +61,8 @@ static consvar_t *consvar_vars; // list of registered console variables static char com_token[1024]; static char *COM_Parse(char *data); +static char * COM_Purge (char *text, int *lenp); + CV_PossibleValue_t CV_OnOff[] = {{0, "Off"}, {1, "On"}, {0, NULL}}; CV_PossibleValue_t CV_YesNo[] = {{0, "No"}, {1, "Yes"}, {0, NULL}}; CV_PossibleValue_t CV_Unsigned[] = {{0, "MIN"}, {999999999, "MAX"}, {0, NULL}}; @@ -100,31 +102,61 @@ static cmdalias_t *com_alias; // aliases list static vsbuf_t com_text; // variable sized buffer +/** Purges control characters out of some text. + * + * \param s The text. + * \param np Optionally a pointer to fill with the new string length. + * \return The new length. + * \sa COM_ExecuteString + */ +static char * +COM_Purge (char *s, int *np) +{ + char *t; + char *p; + int n; + n = strlen(s); + t = s + n + 1; + p = s; + while (( p = strchr(p, '\033') )) + { + memmove(p, &p[1], t - p - 1); + n--; + } + if (np) + (*np) = n; + return s; +} + /** Adds text into the command buffer for later execution. * * \param ptext The text to add. - * \sa COM_BufInsertText + * \sa COM_BufInsertTextEx */ -void COM_BufAddText(const char *ptext) +void COM_BufAddTextEx(const char *ptext, int flags) { - size_t l; + int l; + char *text; - l = strlen(ptext); + text = COM_Purge(Z_StrDup(ptext), &l); - if (com_text.cursize + l >= com_text.maxsize) + if (com_text.cursize + 2 + l >= com_text.maxsize) { CONS_Alert(CONS_WARNING, M_GetText("Command buffer full!\n")); return; } - VS_Write(&com_text, ptext, l); + + VS_WriteEx(&com_text, text, l, flags); + + Z_Free(text); } /** Adds command text and executes it immediately. * * \param ptext The text to execute. A newline is automatically added. - * \sa COM_BufAddText + * \sa COM_BufAddTextEx */ -void COM_BufInsertText(const char *ptext) +void COM_BufInsertTextEx(const char *ptext, int flags) { char *temp = NULL; size_t templen; @@ -138,7 +170,7 @@ void COM_BufInsertText(const char *ptext) } // add the entire text of the file (or alias) - COM_BufAddText(ptext); + COM_BufAddTextEx(ptext, flags); COM_BufExecute(); // do it right away // add the copied off data @@ -272,6 +304,7 @@ static size_t com_argc; static char *com_argv[MAX_ARGS]; static const char *com_null_string = ""; static char *com_args = NULL; // current command args or NULL +static int com_flags; static void Got_NetVar(UINT8 **p, INT32 playernum); @@ -394,9 +427,16 @@ static void COM_TokenizeString(char *ptext) com_argc = 0; com_args = NULL; + com_flags = 0; while (com_argc < MAX_ARGS) { + if (ptext[0] == '\033') + { + com_flags = (unsigned)ptext[1]; + ptext += 2; + } + // Skip whitespace up to a newline. while (*ptext != '\0' && *ptext <= ' ' && *ptext != '\n') ptext++; @@ -1016,6 +1056,15 @@ void VS_Write(vsbuf_t *buf, const void *data, size_t length) M_Memcpy(VS_GetSpace(buf, length), data, length); } +void VS_WriteEx(vsbuf_t *buf, const void *data, size_t length, int flags) +{ + char *p; + p = VS_GetSpace(buf, 2 + length); + p[0] = '\033'; + p[1] = flags; + M_Memcpy(&p[2], data, length); +} + /** Prints text in a variable buffer. Like VS_Write() plus a * trailing NUL. * diff --git a/src/command.h b/src/command.h index 51e161cd0..af9d08ae1 100644 --- a/src/command.h +++ b/src/command.h @@ -36,10 +36,12 @@ size_t COM_FirstOption(void); const char *COM_CompleteCommand(const char *partial, INT32 skips); // insert at queu (at end of other command) -void COM_BufAddText(const char *btext); +#define COM_BufAddText(s) COM_BufAddTextEx(s, 0) +void COM_BufAddTextEx(const char *btext, int flags); // insert in head (before other command) -void COM_BufInsertText(const char *btext); +#define COM_BufInsertText(s) COM_BufInsertTextEx(s, 0) +void COM_BufInsertTextEx(const char *btext, int flags); // don't bother inserting, just do immediately void COM_ImmedExecute(const char *ptext); @@ -71,6 +73,7 @@ void VS_Free(vsbuf_t *buf); void VS_Clear(vsbuf_t *buf); void *VS_GetSpace(vsbuf_t *buf, size_t length); void VS_Write(vsbuf_t *buf, const void *data, size_t length); +void VS_WriteEx(vsbuf_t *buf, const void *data, size_t length, int flags); void VS_Print(vsbuf_t *buf, const char *data); // strcats onto the sizebuf //================== From cb29a9dd0aeb28f3293f03f9810b46b70027545d Mon Sep 17 00:00:00 2001 From: James R Date: Thu, 26 Dec 2019 18:15:19 -0800 Subject: [PATCH 415/746] CV_NOLUA for when a cvar should not be changed via Lua --- src/command.c | 3 +++ src/command.h | 8 +++++++- src/dehacked.c | 1 + src/lua_consolelib.c | 4 ++-- 4 files changed, 13 insertions(+), 3 deletions(-) diff --git a/src/command.c b/src/command.c index 3aa22b62f..861a1f828 100644 --- a/src/command.c +++ b/src/command.c @@ -2064,6 +2064,9 @@ static boolean CV_Command(void) if (!v) return false; + if (( com_flags & COM_SAFE ) && ( v->flags & CV_NOLUA )) + return false; + // perform a variable print or set if (COM_Argc() == 1) { diff --git a/src/command.h b/src/command.h index af9d08ae1..b1026437f 100644 --- a/src/command.h +++ b/src/command.h @@ -20,6 +20,11 @@ // Command buffer & command execution //=================================== +enum +{ + COM_SAFE = 1, +}; + typedef void (*com_func_t)(void); void COM_AddCommand(const char *name, com_func_t func); @@ -103,7 +108,8 @@ typedef enum CV_HIDEN = 1024, // variable is not part of the cvar list so cannot be accessed by the console // can only be set when we have the pointer to it // used on menus - CV_CHEAT = 2048 // Don't let this be used in multiplayer unless cheats are on. + CV_CHEAT = 2048, // Don't let this be used in multiplayer unless cheats are on. + CV_NOLUA = 4096,/* don't let this be called from Lua */ } cvflags_t; typedef struct CV_PossibleValue_s diff --git a/src/dehacked.c b/src/dehacked.c index 9abb708a9..c9e10c064 100644 --- a/src/dehacked.c +++ b/src/dehacked.c @@ -9462,6 +9462,7 @@ struct { {"CV_HIDEN",CV_HIDEN}, {"CV_HIDDEN",CV_HIDEN}, {"CV_CHEAT",CV_CHEAT}, + {"CV_NOLUA",CV_NOLUA}, // v_video flags {"V_NOSCALEPATCH",V_NOSCALEPATCH}, diff --git a/src/lua_consolelib.c b/src/lua_consolelib.c index 58e720c85..837612e52 100644 --- a/src/lua_consolelib.c +++ b/src/lua_consolelib.c @@ -245,7 +245,7 @@ static int lib_comBufAddText(lua_State *L) return LUA_ErrInvalid(L, "player_t"); if (plr != &players[consoleplayer]) return 0; - COM_BufAddText(va("%s\n", luaL_checkstring(L, 2))); + COM_BufAddTextEx(va("%s\n", luaL_checkstring(L, 2)), COM_SAFE); return 0; } @@ -262,7 +262,7 @@ static int lib_comBufInsertText(lua_State *L) return LUA_ErrInvalid(L, "player_t"); if (plr != &players[consoleplayer]) return 0; - COM_BufInsertText(va("%s\n", luaL_checkstring(L, 2))); + COM_BufInsertTextEx(va("%s\n", luaL_checkstring(L, 2)), COM_SAFE); return 0; } From 4959d52ae0b33e7db90afb7db2cedd4a42108079 Mon Sep 17 00:00:00 2001 From: James R Date: Thu, 26 Dec 2019 18:15:52 -0800 Subject: [PATCH 416/746] Make cv_renderer CV_NOLUA instead of hidden!!! --- src/screen.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/screen.c b/src/screen.c index b21b6815a..4aac27c01 100644 --- a/src/screen.c +++ b/src/screen.c @@ -65,7 +65,7 @@ consvar_t cv_renderview = {"renderview", "On", 0, CV_OnOff, NULL, 0, NULL, NULL, static void SCR_ActuallyChangeRenderer(void); static CV_PossibleValue_t cv_renderer_t[] = {{1, "Software"}, {2, "OpenGL"}, {0, NULL}}; -consvar_t cv_renderer = {"renderer", "Software", CV_HIDEN|CV_CALL, cv_renderer_t, SCR_ChangeRenderer, 0, NULL, NULL, 0, 0, NULL}; +consvar_t cv_renderer = {"renderer", "Software", CV_NOLUA|CV_CALL, cv_renderer_t, SCR_ChangeRenderer, 0, NULL, NULL, 0, 0, NULL}; static void SCR_ChangeFullscreen(void); From 967343962869852bc626e26a278cce1640253a09 Mon Sep 17 00:00:00 2001 From: James R Date: Thu, 26 Dec 2019 18:20:48 -0800 Subject: [PATCH 417/746] e --- src/command.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/command.c b/src/command.c index 861a1f828..5e9453b16 100644 --- a/src/command.c +++ b/src/command.c @@ -106,7 +106,7 @@ static vsbuf_t com_text; // variable sized buffer * * \param s The text. * \param np Optionally a pointer to fill with the new string length. - * \return The new length. + * \return The text. * \sa COM_ExecuteString */ static char * From 4865a190578b900b48571e74e0bd97bef88ea71b Mon Sep 17 00:00:00 2001 From: James R Date: Thu, 26 Dec 2019 18:23:01 -0800 Subject: [PATCH 418/746] One more optimization --- src/command.c | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/src/command.c b/src/command.c index 5e9453b16..40efa1eee 100644 --- a/src/command.c +++ b/src/command.c @@ -427,16 +427,17 @@ static void COM_TokenizeString(char *ptext) com_argc = 0; com_args = NULL; - com_flags = 0; + + if (ptext[0] == '\033') + { + com_flags = (unsigned)ptext[1]; + ptext += 2; + } + else + com_flags = 0; while (com_argc < MAX_ARGS) { - if (ptext[0] == '\033') - { - com_flags = (unsigned)ptext[1]; - ptext += 2; - } - // Skip whitespace up to a newline. while (*ptext != '\0' && *ptext <= ' ' && *ptext != '\n') ptext++; From e617f3518241621719780e97eb2248671b81ca35 Mon Sep 17 00:00:00 2001 From: Jaime Passos Date: Thu, 26 Dec 2019 23:26:43 -0300 Subject: [PATCH 419/746] 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 e49d12b7310ec4f1a9e6ec415a85be1f6143d28f Mon Sep 17 00:00:00 2001 From: James R Date: Mon, 5 Aug 2019 15:00:09 -0700 Subject: [PATCH 420/746] 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 7df6a3090a41c585bbc9752b3447b9922b5da26f Mon Sep 17 00:00:00 2001 From: James R Date: Mon, 5 Aug 2019 15:00:21 -0700 Subject: [PATCH 421/746] 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 644e41d90cffb211e80c3bf38b0f22bb2619989d Mon Sep 17 00:00:00 2001 From: Jaime Passos Date: Thu, 26 Dec 2019 23:39:40 -0300 Subject: [PATCH 422/746] Handle character select screen correctly after a renderer switch --- src/m_menu.c | 63 ++++++++++++++++++++++++++++++++++------------------ 1 file changed, 42 insertions(+), 21 deletions(-) diff --git a/src/m_menu.c b/src/m_menu.c index 7049b00c4..fccffed8e 100644 --- a/src/m_menu.c +++ b/src/m_menu.c @@ -8296,6 +8296,43 @@ void M_ForceSaveSlotSelected(INT32 sslot) // CHARACTER SELECT // ================ +// lactozilla: sometimes the renderer changes and these patches don't exist anymore +static void M_CacheCharacterSelectEntry(INT32 i, INT32 skinnum) +{ + if (!(description[i].picname[0])) + { + if (skins[skinnum].sprites[SPR2_XTRA].numframes > XTRA_CHARSEL) + { + spritedef_t *sprdef = &skins[skinnum].sprites[SPR2_XTRA]; + spriteframe_t *sprframe = &sprdef->spriteframes[XTRA_CHARSEL]; + description[i].charpic = W_CachePatchNum(sprframe->lumppat[0], PU_PATCH); + } + else + description[i].charpic = W_CachePatchName("MISSING", PU_PATCH); + } + else + description[i].charpic = W_CachePatchName(description[i].picname, PU_PATCH); + + if (description[i].nametag[0]) + description[i].namepic = W_CachePatchName(description[i].nametag, PU_PATCH); +} + +static void M_CacheCharacterSelect(void) +{ + INT32 i, skinnum; + + for (i = 0; i < 32; i++) + { + if (!description[i].used) + continue; + + // Already set in M_SetupChoosePlayer + skinnum = description[i].skinnum[0]; + if ((skinnum != -1) && (R_SkinUsable(-1, skinnum))) + M_CacheCharacterSelectEntry(i, skinnum); + } +} + static void M_SetupChoosePlayer(INT32 choice) { INT32 skinnum; @@ -8343,27 +8380,7 @@ static void M_SetupChoosePlayer(INT32 choice) if (i == char_on) allowed = true; - if (!(description[i].picname[0])) - { - if (skins[skinnum].sprites[SPR2_XTRA].numframes > XTRA_CHARSEL) - { - spritedef_t *sprdef = &skins[skinnum].sprites[SPR2_XTRA]; - spriteframe_t *sprframe = &sprdef->spriteframes[XTRA_CHARSEL]; - description[i].charpic = W_CachePatchNum(sprframe->lumppat[0], PU_PATCH); - } - else - description[i].charpic = W_CachePatchName("MISSING", PU_PATCH); - } - else - description[i].charpic = W_CachePatchName(description[i].picname, PU_PATCH); - - if (description[i].nametag[0]) - { - const char *nametag = description[i].nametag; - description[i].namepic = NULL; - if (W_LumpExists(nametag)) - description[i].namepic = W_CachePatchName(nametag, PU_PATCH); - } + M_CacheCharacterSelectEntry(i, skinnum); } // else -- Technically, character select icons without corresponding skins get bundled away behind this too. Sucks to be them. } @@ -8511,6 +8528,10 @@ static void M_DrawSetupChoosePlayerMenu(void) INT32 x, y; INT32 w = (vid.width/vid.dupx); + // lactozilla: the renderer changed so recache patches + if (needpatchrecache) + M_CacheCharacterSelect(); + if (abs(char_scroll) > FRACUNIT) char_scroll -= (char_scroll>>2); else // close enough. From 76a1a80d711c1a4e393e3dfdd3ed8c09b50e89db Mon Sep 17 00:00:00 2001 From: James R Date: Thu, 26 Dec 2019 18:44:02 -0800 Subject: [PATCH 423/746] Save the renderer --- src/screen.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/screen.c b/src/screen.c index 4aac27c01..94b6c2454 100644 --- a/src/screen.c +++ b/src/screen.c @@ -65,7 +65,7 @@ consvar_t cv_renderview = {"renderview", "On", 0, CV_OnOff, NULL, 0, NULL, NULL, static void SCR_ActuallyChangeRenderer(void); static CV_PossibleValue_t cv_renderer_t[] = {{1, "Software"}, {2, "OpenGL"}, {0, NULL}}; -consvar_t cv_renderer = {"renderer", "Software", CV_NOLUA|CV_CALL, cv_renderer_t, SCR_ChangeRenderer, 0, NULL, NULL, 0, 0, NULL}; +consvar_t cv_renderer = {"renderer", "Software", CV_SAVE|CV_NOLUA|CV_CALL, cv_renderer_t, SCR_ChangeRenderer, 0, NULL, NULL, 0, 0, NULL}; static void SCR_ChangeFullscreen(void); From 956905c8f4395c196068a3e83f65feb09f4a9833 Mon Sep 17 00:00:00 2001 From: Jaime Passos Date: Thu, 26 Dec 2019 23:49:31 -0300 Subject: [PATCH 424/746] Same deal, but for the level platter and save select screen --- src/m_menu.c | 52 ++++++++++++++++++++++++++++++++++++++-------------- 1 file changed, 38 insertions(+), 14 deletions(-) diff --git a/src/m_menu.c b/src/m_menu.c index fccffed8e..9fbcd55d7 100644 --- a/src/m_menu.c +++ b/src/m_menu.c @@ -4784,6 +4784,22 @@ static INT32 M_CountRowsToShowOnPlatter(INT32 gt) return rows; } +// +// M_CacheLevelPlatter +// +// Cache every patch used by the level platter. +// +static void M_CacheLevelPlatter(void) +{ + levselp[0][0] = W_CachePatchName("SLCT1LVL", PU_PATCH); + levselp[0][1] = W_CachePatchName("SLCT2LVL", PU_PATCH); + levselp[0][2] = W_CachePatchName("BLANKLVL", PU_PATCH); + + levselp[1][0] = W_CachePatchName("SLCT1LVW", PU_PATCH); + levselp[1][1] = W_CachePatchName("SLCT2LVW", PU_PATCH); + levselp[1][2] = W_CachePatchName("BLANKLVW", PU_PATCH); +} + // // M_PrepareLevelPlatter // @@ -4933,13 +4949,7 @@ static boolean M_PrepareLevelPlatter(INT32 gt, boolean nextmappick) } #endif - levselp[0][0] = W_CachePatchName("SLCT1LVL", PU_PATCH); - levselp[0][1] = W_CachePatchName("SLCT2LVL", PU_PATCH); - levselp[0][2] = W_CachePatchName("BLANKLVL", PU_PATCH); - - levselp[1][0] = W_CachePatchName("SLCT1LVW", PU_PATCH); - levselp[1][1] = W_CachePatchName("SLCT2LVW", PU_PATCH); - levselp[1][2] = W_CachePatchName("BLANKLVW", PU_PATCH); + M_CacheLevelPlatter(); return true; } @@ -5160,6 +5170,9 @@ static void M_DrawLevelPlatterWideMap(UINT8 row, UINT8 col, INT32 x, INT32 y, bo if (map <= 0) return; + if (needpatchrecache) + M_CacheLevelPlatter(); + // A 564x100 image of the level as entry MAPxxW if (!(levelselect.rows[row].mapavailable[col])) { @@ -5191,6 +5204,9 @@ static void M_DrawLevelPlatterMap(UINT8 row, UINT8 col, INT32 x, INT32 y, boolea if (map <= 0) return; + if (needpatchrecache) + M_CacheLevelPlatter(); + // A 160x100 image of the level as entry MAPxxP if (!(levelselect.rows[row].mapavailable[col])) { @@ -7626,6 +7642,17 @@ static INT32 saveSlotSelected = 1; static INT32 loadgamescroll = 0; static UINT8 loadgameoffset = 0; +static void M_CacheLoadGameData(void) +{ + savselp[0] = W_CachePatchName("SAVEBACK", PU_PATCH); + savselp[1] = W_CachePatchName("SAVENONE", PU_PATCH); + savselp[2] = W_CachePatchName("ULTIMATE", PU_PATCH); + + savselp[3] = W_CachePatchName("GAMEDONE", PU_PATCH); + savselp[4] = W_CachePatchName("BLACXLVL", PU_PATCH); + savselp[5] = W_CachePatchName("BLANKLVL", PU_PATCH); +} + static void M_DrawLoadGameData(void) { INT32 i, savetodraw, x, y, hsep = 90; @@ -7634,6 +7661,9 @@ static void M_DrawLoadGameData(void) if (vid.width != BASEVIDWIDTH*vid.dupx) hsep = (hsep*vid.width)/(BASEVIDWIDTH*vid.dupx); + if (needpatchrecache) + M_CacheLoadGameData(); + for (i = -2; i <= 2; i++) { savetodraw = (saveSlotSelected + i + numsaves)%numsaves; @@ -8110,13 +8140,7 @@ static void M_ReadSaveStrings(void) M_ReadSavegameInfo(i); } - savselp[0] = W_CachePatchName("SAVEBACK", PU_PATCH); - savselp[1] = W_CachePatchName("SAVENONE", PU_PATCH); - savselp[2] = W_CachePatchName("ULTIMATE", PU_PATCH); - - savselp[3] = W_CachePatchName("GAMEDONE", PU_PATCH); - savselp[4] = W_CachePatchName("BLACXLVL", PU_PATCH); - savselp[5] = W_CachePatchName("BLANKLVL", PU_PATCH); + M_CacheLoadGameData(); } // From eca5be52b28613319173241b04b22191736fa561 Mon Sep 17 00:00:00 2001 From: Jaime Passos Date: Thu, 26 Dec 2019 23:52:42 -0300 Subject: [PATCH 425/746] And the sound test --- src/m_menu.c | 39 ++++++++++++++++++++++++--------------- 1 file changed, 24 insertions(+), 15 deletions(-) diff --git a/src/m_menu.c b/src/m_menu.c index 9fbcd55d7..e2451de6a 100644 --- a/src/m_menu.c +++ b/src/m_menu.c @@ -7023,11 +7023,29 @@ static tic_t st_time = 0; static patch_t* st_radio[9]; static patch_t* st_launchpad[4]; +static void M_CacheSoundTest(void) +{ + UINT8 i; + char buf[8]; + + STRBUFCPY(buf, "M_RADIOn"); + for (i = 0; i < 9; i++) + { + buf[7] = (char)('0'+i); + st_radio[i] = W_CachePatchName(buf, PU_PATCH); + } + + STRBUFCPY(buf, "M_LPADn"); + for (i = 0; i < 4; i++) + { + buf[6] = (char)('0'+i); + st_launchpad[i] = W_CachePatchName(buf, PU_PATCH); + } +} + static void M_SoundTest(INT32 choice) { INT32 ul = skyRoomMenuTranslations[choice-1]; - UINT8 i; - char buf[8]; soundtestpage = (UINT8)(unlockables[ul].variable); if (!soundtestpage) @@ -7039,19 +7057,7 @@ static void M_SoundTest(INT32 choice) return; } - STRBUFCPY(buf, "M_RADIOn"); - for (i = 0; i < 9; i++) - { - buf[7] = (char)('0'+i); - st_radio[i] = W_CachePatchName(buf, PU_STATIC); - } - - STRBUFCPY(buf, "M_LPADn"); - for (i = 0; i < 4; i++) - { - buf[6] = (char)('0'+i); - st_launchpad[i] = W_CachePatchName(buf, PU_STATIC); - } + M_CacheSoundTest(); curplaying = NULL; st_time = 0; @@ -7070,6 +7076,9 @@ static void M_DrawSoundTest(void) fixed_t hscale = FRACUNIT/2, vscale = FRACUNIT/2, bounce = 0; UINT8 frame[4] = {0, 0, -1, SKINCOLOR_RUBY}; + if (needpatchrecache) + M_CacheSoundTest(); + // let's handle the ticker first. ideally we'd tick this somewhere else, BUT... if (curplaying) { From 96609e45aeaf7baf05c6ad5bab665cd3f66a0ec9 Mon Sep 17 00:00:00 2001 From: Jaime Passos Date: Fri, 27 Dec 2019 00:02:30 -0300 Subject: [PATCH 426/746] 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 855e61f59e858b70631d5b178d0772ffd669efbc Mon Sep 17 00:00:00 2001 From: James R Date: Thu, 26 Dec 2019 19:27:25 -0800 Subject: [PATCH 427/746] 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 5ea43aa023aaf35c0ba39e483823f59f03a501dc Mon Sep 17 00:00:00 2001 From: Jaime Passos Date: Fri, 27 Dec 2019 00:37:40 -0300 Subject: [PATCH 428/746] 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 51404130af736868d7474beaf388bcdef706e6d1 Mon Sep 17 00:00:00 2001 From: Jaime Passos Date: Fri, 27 Dec 2019 01:44:27 -0300 Subject: [PATCH 429/746] 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 56e94182d5de9d497307cb12e886275a4edf8eb6 Mon Sep 17 00:00:00 2001 From: Jaime Passos Date: Fri, 27 Dec 2019 02:07:13 -0300 Subject: [PATCH 430/746] 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 9613bdeca69bde37ecd452ec3649c5798b02f6c0 Mon Sep 17 00:00:00 2001 From: Jaime Passos Date: Fri, 27 Dec 2019 12:14:33 -0300 Subject: [PATCH 431/746] 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 1d0d40492272db90d9f0a12278c247e78a5a5c0c Mon Sep 17 00:00:00 2001 From: Jaime Passos Date: Fri, 27 Dec 2019 12:17:38 -0300 Subject: [PATCH 432/746] 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 5c023739e6e80cc6f1faeac5ecaa39ceb89d5b6f Mon Sep 17 00:00:00 2001 From: Jaime Passos Date: Fri, 27 Dec 2019 12:23:50 -0300 Subject: [PATCH 433/746] 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 f8eed7171a8d63176bf2e43b8662d58befbf0758 Mon Sep 17 00:00:00 2001 From: Jaime Passos Date: Fri, 27 Dec 2019 12:28:00 -0300 Subject: [PATCH 434/746] 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 f0d58368f912941c9a46edf29cab87fc76be8a1b Mon Sep 17 00:00:00 2001 From: Jaime Passos Date: Fri, 27 Dec 2019 12:29:21 -0300 Subject: [PATCH 435/746] 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 6b8839d5aaee3212b3c0a7f6976504fb235759f7 Mon Sep 17 00:00:00 2001 From: Jaime Passos Date: Fri, 27 Dec 2019 12:34:35 -0300 Subject: [PATCH 436/746] 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 ff004c4cf6c0481e3b4897bbe9a4e2040c59d0fc Mon Sep 17 00:00:00 2001 From: Alam Ed Arias Date: Fri, 27 Dec 2019 13:05:15 -0500 Subject: [PATCH 437/746] we only need link on unix systems --- src/sdl/i_main.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/sdl/i_main.c b/src/sdl/i_main.c index dcfe73c72..5d0009927 100644 --- a/src/sdl/i_main.c +++ b/src/sdl/i_main.c @@ -142,7 +142,9 @@ int main(int argc, char **argv) const char *reldir; int left; boolean fileabs; +#ifdef __unix__ const char *link; +#endif logdir = D_Home(); From 0caa08defd1aad04c12b36ee9f40c84e7885170c Mon Sep 17 00:00:00 2001 From: Alam Ed Arias Date: Fri, 27 Dec 2019 13:08:26 -0500 Subject: [PATCH 438/746] fread and fwrite use size_t, not int --- src/sdl/i_system.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/sdl/i_system.c b/src/sdl/i_system.c index f57dc5c71..81420e757 100644 --- a/src/sdl/i_system.c +++ b/src/sdl/i_system.c @@ -2498,16 +2498,16 @@ static void Shittylogcopy(void) { char buf[8192]; FILE *fp; - int n; + size_t r; if (fseek(logstream, 0, SEEK_SET) == -1) { Shittycopyerror("fseek"); } else if (( fp = fopen(logfilename, "wt") )) { - while (( n = fread(buf, 1, sizeof buf, logstream) )) + while (( r = fread(buf, 1, sizeof buf, logstream) )) { - if (fwrite(buf, 1, n, fp) < n) + if (fwrite(buf, 1, r, fp) < r) { Shittycopyerror("fwrite"); break; From c394ad056c9756c7f8fc96e5a248188c183fa6d4 Mon Sep 17 00:00:00 2001 From: Alam Ed Arias Date: Fri, 27 Dec 2019 13:20:58 -0500 Subject: [PATCH 439/746] 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 282fe7667ccd831e41a2d7f18599deba6457b833 Mon Sep 17 00:00:00 2001 From: Monster Iestyn Date: Fri, 27 Dec 2019 19:10:14 +0000 Subject: [PATCH 440/746] 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 1d04001fdfcdb434082395036476c4c10b37ec5d Mon Sep 17 00:00:00 2001 From: Monster Iestyn Date: Fri, 27 Dec 2019 19:24:00 +0000 Subject: [PATCH 441/746] 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 ed29efd9ebf1ccd90ded05742dcdad5a5de04249 Mon Sep 17 00:00:00 2001 From: Jaime Passos Date: Fri, 27 Dec 2019 16:58:55 -0300 Subject: [PATCH 442/746] 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 1f96f701730ab80348097852523b9b7d94e22892 Mon Sep 17 00:00:00 2001 From: Jaime Passos Date: Fri, 27 Dec 2019 17:08:20 -0300 Subject: [PATCH 443/746] 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 3b341245f13cdf2a5e3ef425e2b73aaea6cf5d27 Mon Sep 17 00:00:00 2001 From: Jaime Passos Date: Fri, 27 Dec 2019 17:14:56 -0300 Subject: [PATCH 444/746] 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 4b2c88fab8bc2645b744385c6b827006a48801ab Mon Sep 17 00:00:00 2001 From: Jaime Passos Date: Fri, 27 Dec 2019 17:15:23 -0300 Subject: [PATCH 445/746] 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 e03eaa554bff41f31538be11b66e9b36a9a3989e Mon Sep 17 00:00:00 2001 From: Jaime Passos Date: Fri, 27 Dec 2019 17:22:55 -0300 Subject: [PATCH 446/746] 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 1fb244d87fde7662f5808d6450eb146d58f56680 Mon Sep 17 00:00:00 2001 From: Jaime Passos Date: Fri, 27 Dec 2019 18:24:08 -0300 Subject: [PATCH 447/746] 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 afc78fb56a7efff53fbd55a1edeff8c2f3fcd859 Mon Sep 17 00:00:00 2001 From: James R Date: Fri, 27 Dec 2019 14:48:55 -0800 Subject: [PATCH 448/746] 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 f62579811bdab4f9b1ca6388c5c0603cd2a66867 Mon Sep 17 00:00:00 2001 From: GoldenTails Date: Fri, 27 Dec 2019 23:51:13 -0600 Subject: [PATCH 449/746] 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 f83d0fe3a1a804fadd0ec93ccf5aecc576813b22 Mon Sep 17 00:00:00 2001 From: MascaraSnake Date: Sat, 28 Dec 2019 08:42:16 +0100 Subject: [PATCH 450/746] Fixed/clarified some flag descriptions in the ZB config --- extras/conf/SRB2-22.cfg | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/extras/conf/SRB2-22.cfg b/extras/conf/SRB2-22.cfg index 5bc48211c..ec318321d 100644 --- a/extras/conf/SRB2-22.cfg +++ b/extras/conf/SRB2-22.cfg @@ -690,9 +690,9 @@ linedeftypes title = "Chain Parameters"; prefix = "(9)"; flags32text = "[5] Swing instead of spin"; + flags128text = "[7] Make chain from end item"; flags64text = "[6] Player-turnable chain"; - flags128text = "[7] Make chain from maces"; - flags256text = "[8] Spawn mace at origin"; + flags256text = "[8] Spawn link at origin"; flags512text = "[9] Don't clip inside ground"; flags1024text = "[10] No distance check"; } From 08895ef751049b7110a2b0d58d862c8d915c4f75 Mon Sep 17 00:00:00 2001 From: MascaraSnake Date: Sat, 28 Dec 2019 08:43:27 +0100 Subject: [PATCH 451/746] Fixed/clarified some flag descriptions in the ZB config --- extras/conf/Includes/SRB222_linedefs.cfg | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/extras/conf/Includes/SRB222_linedefs.cfg b/extras/conf/Includes/SRB222_linedefs.cfg index 8bc761dfe..fdf191850 100644 --- a/extras/conf/Includes/SRB222_linedefs.cfg +++ b/extras/conf/Includes/SRB222_linedefs.cfg @@ -126,8 +126,8 @@ doom prefix = "(9)"; flags32text = "[5] Swing instead of spin"; flags64text = "[6] Player-turnable chain"; - flags128text = "[7] Make chain from maces"; - flags256text = "[8] Spawn mace at origin"; + flags128text = "[7] Make chain from end item"; + flags256text = "[8] Spawn link at origin"; flags512text = "[9] Don't clip inside ground"; flags1024text = "[10] No distance check"; } From 319ed09c0021bac170e559209d7add5609279f9f Mon Sep 17 00:00:00 2001 From: MascaraSnake Date: Sat, 28 Dec 2019 11:30:39 +0100 Subject: [PATCH 452/746] Rename P_SetupLevel to the more accurate P_LoadLevel and separate out some of its content into subfunctions --- src/d_main.c | 2 +- src/g_game.c | 2 +- src/p_saveg.c | 2 +- src/p_setup.c | 557 +++++++++++++++++++++++++++----------------------- src/p_setup.h | 2 +- 5 files changed, 306 insertions(+), 259 deletions(-) diff --git a/src/d_main.c b/src/d_main.c index e25ef998e..0654e0927 100644 --- a/src/d_main.c +++ b/src/d_main.c @@ -1462,7 +1462,7 @@ void D_SRB2Main(void) { levelstarttic = gametic; G_SetGamestate(GS_LEVEL); - if (!P_SetupLevel(false)) + if (!P_LoadLevel(false)) I_Quit(); // fail so reset game stuff } } diff --git a/src/g_game.c b/src/g_game.c index 19b18ef8c..e6a28aa41 100644 --- a/src/g_game.c +++ b/src/g_game.c @@ -1847,7 +1847,7 @@ void G_DoLoadLevel(boolean resetplayer) } // Setup the level. - if (!P_SetupLevel(false)) // this never returns false? + if (!P_LoadLevel(false)) // this never returns false? { // fail so reset game stuff Command_ExitGame_f(); diff --git a/src/p_saveg.c b/src/p_saveg.c index 85efacf88..4cfeab6f8 100644 --- a/src/p_saveg.c +++ b/src/p_saveg.c @@ -4064,7 +4064,7 @@ static inline boolean P_NetUnArchiveMisc(void) tokenlist = READUINT32(save_p); - if (!P_SetupLevel(true)) + if (!P_LoadLevel(true)) return false; // get the time diff --git a/src/p_setup.c b/src/p_setup.c index 9acc4adb3..1ec811e62 100644 --- a/src/p_setup.c +++ b/src/p_setup.c @@ -970,7 +970,7 @@ static void P_SpawnEmeraldHunt(void) mobjinfo[MT_EMERHUNT].spawnstate+2); } -static void P_LoadThings(boolean loademblems) +static void P_SpawnMapThings(boolean spawnemblems) { size_t i; mapthing_t *mt; @@ -1000,7 +1000,7 @@ static void P_LoadThings(boolean loademblems) || mt->type == 1702) // MT_AXISTRANSFERLINE continue; // These were already spawned - if (!loademblems && mt->type == mobjinfo[MT_EMBLEM].doomednum) + if (!spawnemblems && mt->type == mobjinfo[MT_EMBLEM].doomednum) continue; mt->mobj = NULL; @@ -2015,6 +2015,75 @@ static void P_LoadMapData(const virtres_t* virt) memcpy(spawnsides, sides, numsides * sizeof (*sides)); } +/** Compute MD5 message digest for bytes read from memory source + * + * The resulting message digest number will be written into the 16 bytes + * beginning at RESBLOCK. + * + * \param filename path of file + * \param resblock resulting MD5 checksum + * \return 0 if MD5 checksum was made, and is at resblock, 1 if error was found + */ +static INT32 P_MakeBufferMD5(const char* buffer, size_t len, void* resblock) +{ +#ifdef NOMD5 + (void)buffer; + (void)len; + memset(resblock, 0x00, 16); + return 1; +#else + tic_t t = I_GetTime(); + CONS_Debug(DBG_SETUP, "Making MD5\n"); + if (md5_buffer(buffer, len, resblock) == NULL) + return 1; + CONS_Debug(DBG_SETUP, "MD5 calc took %f seconds\n", (float)(I_GetTime() - t)/NEWTICRATE); + return 0; +#endif +} + +static void P_MakeMapMD5(virtres_t* virt, void* dest) +{ + unsigned char linemd5[16]; + unsigned char sectormd5[16]; + unsigned char thingmd5[16]; + unsigned char sidedefmd5[16]; + unsigned char resmd5[16]; + UINT8 i; + + // Create a hash for the current map + // get the actual lumps! + virtlump_t *virtlines = vres_Find(virt, "LINEDEFS"); + virtlump_t *virtsectors = vres_Find(virt, "SECTORS"); + virtlump_t *virtmthings = vres_Find(virt, "THINGS"); + virtlump_t *virtsides = vres_Find(virt, "SIDEDEFS"); + + P_MakeBufferMD5((char*)virtlines->data, virtlines->size, linemd5); + P_MakeBufferMD5((char*)virtsectors->data, virtsectors->size, sectormd5); + P_MakeBufferMD5((char*)virtmthings->data, virtmthings->size, thingmd5); + P_MakeBufferMD5((char*)virtsides->data, virtsides->size, sidedefmd5); + + for (i = 0; i < 16; i++) + resmd5[i] = (linemd5[i] + sectormd5[i] + thingmd5[i] + sidedefmd5[i]) & 0xFF; + + M_Memcpy(dest, &resmd5, 16); +} + +static void P_LoadMapFromFile(void) +{ + virtres_t *virt = vres_GetMap(lastloadedmaplumpnum); + + P_LoadMapData(virt); + P_LoadMapBSP(virt); + P_LoadMapLUT(virt); + + P_LoadLineDefs2(); + P_GroupLines(); + + P_MakeMapMD5(virt, &mapmd5); + + vres_Free(virt); +} + #if 0 static char *levellumps[] = { @@ -2210,66 +2279,13 @@ void P_LoadThingsOnly(void) P_LevelInitStuff(); - P_LoadThings(true); + P_SpawnMapThings(true); // restore skybox viewpoint/centerpoint if necessary, set them to defaults if we can't do that skyboxmo[0] = skyboxviewpnts[(viewid >= 0) ? viewid : 0]; skyboxmo[1] = skyboxcenterpnts[(centerid >= 0) ? centerid : 0]; } -/** Compute MD5 message digest for bytes read from memory source - * - * The resulting message digest number will be written into the 16 bytes - * beginning at RESBLOCK. - * - * \param filename path of file - * \param resblock resulting MD5 checksum - * \return 0 if MD5 checksum was made, and is at resblock, 1 if error was found - */ -static INT32 P_MakeBufferMD5(const char *buffer, size_t len, void *resblock) -{ -#ifdef NOMD5 - (void)buffer; - (void)len; - memset(resblock, 0x00, 16); - return 1; -#else - tic_t t = I_GetTime(); - CONS_Debug(DBG_SETUP, "Making MD5\n"); - if (md5_buffer(buffer, len, resblock) == NULL) - return 1; - CONS_Debug(DBG_SETUP, "MD5 calc took %f seconds\n", (float)(I_GetTime() - t)/NEWTICRATE); - return 0; -#endif -} - -static void P_MakeMapMD5(virtres_t* virt, void *dest) -{ - unsigned char linemd5[16]; - unsigned char sectormd5[16]; - unsigned char thingmd5[16]; - unsigned char sidedefmd5[16]; - unsigned char resmd5[16]; - UINT8 i; - - // Create a hash for the current map - // get the actual lumps! - virtlump_t* virtlines = vres_Find(virt, "LINEDEFS"); - virtlump_t* virtsectors = vres_Find(virt, "SECTORS"); - virtlump_t* virtmthings = vres_Find(virt, "THINGS"); - virtlump_t* virtsides = vres_Find(virt, "SIDEDEFS"); - - P_MakeBufferMD5((char*)virtlines->data, virtlines->size, linemd5); - P_MakeBufferMD5((char*)virtsectors->data, virtsectors->size, sectormd5); - P_MakeBufferMD5((char*)virtmthings->data, virtmthings->size, thingmd5); - P_MakeBufferMD5((char*)virtsides->data, virtsides->size, sidedefmd5); - - for (i = 0; i < 16; i++) - resmd5[i] = (linemd5[i] + sectormd5[i] + thingmd5[i] + sidedefmd5[i]) & 0xFF; - - M_Memcpy(dest, &resmd5, 16); -} - static void P_RunLevelScript(const char *scriptname) { if (!(mapheaderinfo[gamemap-1]->levelflags & LF_SCRIPTISFILE)) @@ -2433,6 +2449,45 @@ static void P_LoadNightsGhosts(void) free(gpath); } +static void P_InitTagGametype(void) +{ + UINT8 i; + INT32 realnumplayers = 0; + INT32 playersactive[MAXPLAYERS]; + + //I just realized how problematic this code can be. + //D_NumPlayers() will not always cover the scope of the netgame. + //What if one player is node 0 and the other node 31? + //The solution? Make a temp array of all players that are currently playing and pick from them. + //Future todo? When a player leaves, shift all nodes down so D_NumPlayers() can be used as intended? + //Also, you'd never have to loop through all 32 players slots to find anything ever again. + for (i = 0; i < MAXPLAYERS; i++) + { + if (playeringame[i] && !players[i].spectator) + { + playersactive[realnumplayers] = i; //stores the player's node in the array. + realnumplayers++; + } + } + + if (!realnumplayers) //this should also fix the dedicated crash bug. You only pick a player if one exists to be picked. + { + CONS_Printf(M_GetText("No player currently available to become IT. Awaiting available players.\n")); + return; + } + + i = P_RandomKey(realnumplayers); + players[playersactive[i]].pflags |= PF_TAGIT; //choose our initial tagger before map starts. + + // Taken and modified from G_DoReborn() + // Remove the player so he can respawn elsewhere. + // first disassociate the corpse + if (players[playersactive[i]].mo) + P_RemoveMobj(players[playersactive[i]].mo); + + G_SpawnPlayer(playersactive[i], false); //respawn the lucky player in his dedicated spawn location. +} + static void P_SetupCamera(void) { if (players[displayplayer].mo && (server || addedtogame)) @@ -2470,6 +2525,52 @@ static void P_SetupCamera(void) } } +static void P_InitCamera(void) +{ + if (!dedicated) + { + P_SetupCamera(); + + // Salt: CV_ClearChangedFlags() messes with your settings :( + /*if (!cv_cam_height.changed) + CV_Set(&cv_cam_height, cv_cam_height.defaultvalue); + if (!cv_cam2_height.changed) + CV_Set(&cv_cam2_height, cv_cam2_height.defaultvalue); + + if (!cv_cam_dist.changed) + CV_Set(&cv_cam_dist, cv_cam_dist.defaultvalue); + if (!cv_cam2_dist.changed) + CV_Set(&cv_cam2_dist, cv_cam2_dist.defaultvalue);*/ + + // Though, I don't think anyone would care about cam_rotate being reset back to the only value that makes sense :P + if (!cv_cam_rotate.changed) + CV_Set(&cv_cam_rotate, cv_cam_rotate.defaultvalue); + if (!cv_cam2_rotate.changed) + CV_Set(&cv_cam2_rotate, cv_cam2_rotate.defaultvalue); + + if (!cv_analog.changed) + CV_SetValue(&cv_analog, 0); + if (!cv_analog2.changed) + CV_SetValue(&cv_analog2, 0); + + displayplayer = consoleplayer; // Start with your OWN view, please! + } + + if (twodlevel) + { + CV_SetValue(&cv_analog, false); + CV_SetValue(&cv_analog2, false); + } + else + { + if (cv_useranalog.value) + CV_SetValue(&cv_analog, true); + + if ((splitscreen && cv_useranalog2.value) || botingame) + CV_SetValue(&cv_analog2, true); + } +} + static boolean CanSaveLevel(INT32 mapnum) { if (ultimatemode) // never save in ultimate (probably redundant with cursaveslot also being checked) @@ -2485,18 +2586,152 @@ static boolean CanSaveLevel(INT32 mapnum) return (mapheaderinfo[mapnum-1]->levelflags & LF_SAVEGAME || gamecomplete || !lastmaploaded); } +static void P_RunSpecialStageWipe(void) +{ + tic_t starttime = I_GetTime(); + tic_t endtime = starttime + (3*TICRATE)/2; + tic_t nowtime; + + S_StartSound(NULL, sfx_s3kaf); + + // Fade music! Time it to S3KAF: 0.25 seconds is snappy. + if (RESETMUSIC || + strnicmp(S_MusicName(), + (mapmusflags & MUSIC_RELOADRESET) ? mapheaderinfo[gamemap - 1]->musname : mapmusname, 7)) + S_FadeOutStopMusic(MUSICRATE/4); //FixedMul(FixedDiv(F_GetWipeLength(wipedefs[wipe_speclevel_towhite])*NEWTICRATERATIO, NEWTICRATE), MUSICRATE) + + F_WipeStartScreen(); + wipestyleflags |= (WSF_FADEOUT|WSF_TOWHITE); + +#ifdef HWRENDER + // uh.......... + if (rendermode == render_opengl) + F_WipeColorFill(0); +#endif + + F_WipeEndScreen(); + F_RunWipe(wipedefs[wipe_speclevel_towhite], false); + + I_OsPolling(); + I_FinishUpdate(); // page flip or blit buffer + if (moviemode) + M_SaveFrame(); + + nowtime = lastwipetic; + + // Hold on white for extra effect. + while (nowtime < endtime) + { + // wait loop + while (!((nowtime = I_GetTime()) - lastwipetic)) + I_Sleep(); + lastwipetic = nowtime; + if (moviemode) // make sure we save frames for the white hold too + M_SaveFrame(); + } +} + +static void P_RunLevelWipe(void) +{ + F_WipeStartScreen(); + wipestyleflags |= WSF_FADEOUT; + +#ifdef HWRENDER + // uh.......... + if (rendermode == render_opengl) + F_WipeColorFill(31); +#endif + + F_WipeEndScreen(); + // for titlemap: run a specific wipe if specified + // needed for exiting time attack + if (wipetypepre != INT16_MAX) + F_RunWipe( + (wipetypepre >= 0 && F_WipeExists(wipetypepre)) ? wipetypepre : wipedefs[wipe_level_toblack], + false); + wipetypepre = -1; +} + +static void P_InitPlayers(void) +{ + UINT8 i; + + for (i = 0; i < MAXPLAYERS; i++) + { + if (!playeringame[i]) + continue; + + // Start players with pity shields if possible + players[i].pity = -1; + + players[i].mo = NULL; + + if (!G_PlatformGametype()) + G_DoReborn(i); + else // gametype is GT_COOP or GT_RACE + { + G_SpawnPlayer(i, players[i].starposttime); + if (players[i].starposttime) + P_ClearStarPost(players[i].starpostnum); + } + } +} + +static void P_WriteLetter(void) +{ + char *buf, *b; + + if (!unlockables[27].unlocked) // pandora's box + return; + + if (modeattacking) + return; + +#ifndef DEVELOP + if (modifiedgame) + return; +#endif + + if (netgame || multiplayer) + return; + + if (gamemap != 0x1d35 - 016464) + return; + + P_SpawnMobj(0640370000, 0x11000000, 0x3180000, MT_LETTER)->angle = ANGLE_90; + + if (textprompts[199]->page[1].backcolor == 259) + return; + + buf = W_CacheLumpName("WATERMAP", PU_STATIC); + b = buf; + + while ((*b != 65) && (b - buf < 256)) + { + *b = (*b - 65) & 255; + b++; + } + *b = '\0'; + + Z_Free(textprompts[199]->page[1].text); + textprompts[199]->page[1].text = Z_StrDup(buf); + textprompts[199]->page[1].lines = 4; + textprompts[199]->page[1].backcolor = 259; + Z_Free(buf); +} + /** Loads a level from a lump or external wad. * * \param skipprecip If true, don't spawn precipitation. * \todo Clean up, refactor, split up; get rid of the bloat. */ -boolean P_SetupLevel(boolean skipprecip) +boolean P_LoadLevel(boolean skipprecip) { // use gamemap to get map number. // 99% of the things already did, so. // Map header should always be in place at this point INT32 i, loadprecip = 1, ranspecialwipe = 0; - INT32 loademblems = 1; + boolean spawnemblems = true; INT32 fromnetsave = 0; sector_t *ss; boolean chase; @@ -2569,48 +2804,7 @@ boolean P_SetupLevel(boolean skipprecip) ranspecialwipe = 2; else if (rendermode != render_none && G_IsSpecialStage(gamemap)) { - tic_t starttime = I_GetTime(); - tic_t endtime = starttime + (3*TICRATE)/2; - tic_t nowtime; - - S_StartSound(NULL, sfx_s3kaf); - - // Fade music! Time it to S3KAF: 0.25 seconds is snappy. - if (RESETMUSIC || - strnicmp(S_MusicName(), - (mapmusflags & MUSIC_RELOADRESET) ? mapheaderinfo[gamemap-1]->musname : mapmusname, 7)) - S_FadeOutStopMusic(MUSICRATE/4); //FixedMul(FixedDiv(F_GetWipeLength(wipedefs[wipe_speclevel_towhite])*NEWTICRATERATIO, NEWTICRATE), MUSICRATE) - - F_WipeStartScreen(); - wipestyleflags |= (WSF_FADEOUT|WSF_TOWHITE); - -#ifdef HWRENDER - // uh.......... - if (rendermode == render_opengl) - F_WipeColorFill(0); -#endif - - F_WipeEndScreen(); - F_RunWipe(wipedefs[wipe_speclevel_towhite], false); - - I_OsPolling(); - I_FinishUpdate(); // page flip or blit buffer - if (moviemode) - M_SaveFrame(); - - nowtime = lastwipetic; - - // Hold on white for extra effect. - while (nowtime < endtime) - { - // wait loop - while (!((nowtime = I_GetTime()) - lastwipetic)) - I_Sleep(); - lastwipetic = nowtime; - if (moviemode) // make sure we save frames for the white hold too - M_SaveFrame(); - } - + P_RunSpecialStageWipe(); ranspecialwipe = 1; } @@ -2636,25 +2830,7 @@ boolean P_SetupLevel(boolean skipprecip) // Let's fade to black here // But only if we didn't do the special stage wipe if (rendermode != render_none && !ranspecialwipe) - { - F_WipeStartScreen(); - wipestyleflags |= WSF_FADEOUT; - -#ifdef HWRENDER - // uh.......... - if (rendermode == render_opengl) - F_WipeColorFill(31); -#endif - - F_WipeEndScreen(); - // for titlemap: run a specific wipe if specified - // needed for exiting time attack - if (wipetypepre != INT16_MAX) - F_RunWipe( - (wipetypepre >= 0 && F_WipeExists(wipetypepre)) ? wipetypepre : wipedefs[wipe_level_toblack], - false); - wipetypepre = -1; - } + P_RunLevelWipe(); if (!titlemapinaction) { @@ -2717,7 +2893,7 @@ boolean P_SetupLevel(boolean skipprecip) { fromnetsave = 1; loadprecip = 0; - loademblems = 0; + spawnemblems = false; } else if (savedata.lives > 0) { @@ -2763,20 +2939,7 @@ boolean P_SetupLevel(boolean skipprecip) P_MapStart(); if (lastloadedmaplumpnum) - { - virtres_t* virt = vres_GetMap(lastloadedmaplumpnum); - - P_LoadMapData(virt); - P_LoadMapBSP(virt); - P_LoadMapLUT(virt); - - P_LoadLineDefs2(); - P_GroupLines(); - - P_MakeMapMD5(virt, &mapmd5); - - vres_Free(virt); - } + P_LoadMapFromFile(); // init gravity, tag lists, // anything that P_ResetDynamicSlopes/P_LoadThings needs to know @@ -2786,7 +2949,7 @@ boolean P_SetupLevel(boolean skipprecip) P_ResetDynamicSlopes(fromnetsave); #endif - P_LoadThings(loademblems); + P_SpawnMapThings(spawnemblems); skyboxmo[0] = skyboxviewpnts[0]; skyboxmo[1] = skyboxcenterpnts[0]; @@ -2829,30 +2992,7 @@ boolean P_SetupLevel(boolean skipprecip) goto netgameskip; // ========== - for (i = 0; i < MAXPLAYERS; i++) - if (playeringame[i]) - { - // Start players with pity shields if possible - players[i].pity = -1; - - if (!G_PlatformGametype()) - { - players[i].mo = NULL; - G_DoReborn(i); - } - else // gametype is GT_COOP or GT_RACE - { - players[i].mo = NULL; - - if (players[i].starposttime) - { - G_SpawnPlayer(i, true); - P_ClearStarPost(players[i].starpostnum); - } - else - G_SpawnPlayer(i, false); - } - } + P_InitPlayers(); // restore time in netgame (see also g_game.c) if ((netgame || multiplayer) && gametype == GT_COOP && cv_coopstarposts.value == 2) @@ -2867,24 +3007,7 @@ boolean P_SetupLevel(boolean skipprecip) leveltime = maxstarposttime; } - if (unlockables[27].unlocked && !modeattacking // pandora's box -#ifndef DEVELOP - && !modifiedgame -#endif - && !(netgame || multiplayer) && gamemap == 0x1d35-016464) - { - P_SpawnMobj(0640370000, 0x11000000, 0x3180000, MT_LETTER)->angle = ANGLE_90; - if (textprompts[199]->page[1].backcolor != 259) - { - char *buf = W_CacheLumpName("WATERMAP", PU_STATIC), *b = buf; - while ((*b != 65) && (b-buf < 256)) { *b = (*b - 65)&255; b++; } *b = '\0'; - Z_Free(textprompts[199]->page[1].text); - textprompts[199]->page[1].text = Z_StrDup(buf); - textprompts[199]->page[1].lines = 4; - textprompts[199]->page[1].backcolor = 259; - Z_Free(buf); - } - } + P_WriteLetter(); if (modeattacking == ATTACKING_RECORD && !demoplayback) P_LoadRecordGhosts(); @@ -2892,42 +3015,7 @@ boolean P_SetupLevel(boolean skipprecip) P_LoadNightsGhosts(); if (G_TagGametype()) - { - INT32 realnumplayers = 0; - INT32 playersactive[MAXPLAYERS]; - - //I just realized how problematic this code can be. - //D_NumPlayers() will not always cover the scope of the netgame. - //What if one player is node 0 and the other node 31? - //The solution? Make a temp array of all players that are currently playing and pick from them. - //Future todo? When a player leaves, shift all nodes down so D_NumPlayers() can be used as intended? - //Also, you'd never have to loop through all 32 players slots to find anything ever again. - for (i = 0; i < MAXPLAYERS; i++) - { - if (playeringame[i] && !players[i].spectator) - { - playersactive[realnumplayers] = i; //stores the player's node in the array. - realnumplayers++; - } - } - - if (realnumplayers) //this should also fix the dedicated crash bug. You only pick a player if one exists to be picked. - { - i = P_RandomKey(realnumplayers); - players[playersactive[i]].pflags |= PF_TAGIT; //choose our initial tagger before map starts. - - // Taken and modified from G_DoReborn() - // Remove the player so he can respawn elsewhere. - // first dissasociate the corpse - if (players[playersactive[i]].mo) - P_RemoveMobj(players[playersactive[i]].mo); - - G_SpawnPlayer(playersactive[i], false); //respawn the lucky player in his dedicated spawn location. - } - else - CONS_Printf(M_GetText("No player currently available to become IT. Awaiting available players.\n")); - - } + P_InitTagGametype(); else if (gametype == GT_RACE && server) CV_StealthSetValue(&cv_numlaps, (cv_basenumlaps.value) @@ -2938,48 +3026,7 @@ boolean P_SetupLevel(boolean skipprecip) // landing point for netgames. netgameskip: - if (!dedicated) - { - P_SetupCamera(); - - // Salt: CV_ClearChangedFlags() messes with your settings :( - /*if (!cv_cam_height.changed) - CV_Set(&cv_cam_height, cv_cam_height.defaultvalue); - if (!cv_cam2_height.changed) - CV_Set(&cv_cam2_height, cv_cam2_height.defaultvalue); - - if (!cv_cam_dist.changed) - CV_Set(&cv_cam_dist, cv_cam_dist.defaultvalue); - if (!cv_cam2_dist.changed) - CV_Set(&cv_cam2_dist, cv_cam2_dist.defaultvalue);*/ - - // Though, I don't think anyone would care about cam_rotate being reset back to the only value that makes sense :P - if (!cv_cam_rotate.changed) - CV_Set(&cv_cam_rotate, cv_cam_rotate.defaultvalue); - if (!cv_cam2_rotate.changed) - CV_Set(&cv_cam2_rotate, cv_cam2_rotate.defaultvalue); - - if (!cv_analog.changed) - CV_SetValue(&cv_analog, 0); - if (!cv_analog2.changed) - CV_SetValue(&cv_analog2, 0); - - displayplayer = consoleplayer; // Start with your OWN view, please! - } - - if (cv_useranalog.value) - CV_SetValue(&cv_analog, true); - - if (splitscreen && cv_useranalog2.value) - CV_SetValue(&cv_analog2, true); - else if (botingame) - CV_SetValue(&cv_analog2, true); - - if (twodlevel) - { - CV_SetValue(&cv_analog2, false); - CV_SetValue(&cv_analog, false); - } + P_InitCamera(); // clear special respawning que iquehead = iquetail = 0; diff --git a/src/p_setup.h b/src/p_setup.h index c95dd0f63..0751cf7b9 100644 --- a/src/p_setup.h +++ b/src/p_setup.h @@ -97,7 +97,7 @@ void P_SetupLevelSky(INT32 skynum, boolean global); void P_ScanThings(INT16 mapnum, INT16 wadnum, INT16 lumpnum); #endif void P_LoadThingsOnly(void); -boolean P_SetupLevel(boolean skipprecip); +boolean P_LoadLevel(boolean skipprecip); boolean P_AddWadFile(const char *wadfilename); boolean P_RunSOC(const char *socfilename); void P_LoadSoundsRange(UINT16 wadnum, UINT16 first, UINT16 num); From c0591469370a1943753bb07356412398d4e58a91 Mon Sep 17 00:00:00 2001 From: MascaraSnake Date: Sat, 28 Dec 2019 11:37:56 +0100 Subject: [PATCH 453/746] Move more P_LoadLevel parts into subfunctions --- src/p_setup.c | 109 +++++++++++++++++++++++++++----------------------- 1 file changed, 58 insertions(+), 51 deletions(-) diff --git a/src/p_setup.c b/src/p_setup.c index 1ec811e62..0b443c939 100644 --- a/src/p_setup.c +++ b/src/p_setup.c @@ -2350,6 +2350,26 @@ static void P_ForceCharacter(const char *forcecharskin) } } +static void P_ResetSpawnpoints(void) +{ + UINT8 i; + + numdmstarts = numredctfstarts = numbluectfstarts = 0; + + // reset the player starts + for (i = 0; i < MAXPLAYERS; i++) + playerstarts[i] = bluectfstarts[i] = redctfstarts[i] = NULL; + + for (i = 0; i < MAX_DM_STARTS; i++) + deathmatchstarts[i] = NULL; + + for (i = 0; i < 2; i++) + skyboxmo[i] = NULL; + + for (i = 0; i < 16; i++) + skyboxviewpnts[i] = skyboxcenterpnts[i] = NULL; +} + static void P_LoadRecordGhosts(void) { const size_t glen = strlen(srb2home)+1+strlen("replay")+1+strlen(timeattackfolder)+1+strlen("MAPXX")+1; @@ -2720,6 +2740,41 @@ static void P_WriteLetter(void) Z_Free(buf); } +static void P_InitGametype(void) +{ + UINT8 i; + + P_InitPlayers(); + + // restore time in netgame (see also g_game.c) + if ((netgame || multiplayer) && gametype == GT_COOP && cv_coopstarposts.value == 2) + { + // is this a hack? maybe + tic_t maxstarposttime = 0; + for (i = 0; i < MAXPLAYERS; i++) + { + if (playeringame[i] && players[i].starposttime > maxstarposttime) + maxstarposttime = players[i].starposttime; + } + leveltime = maxstarposttime; + } + + P_WriteLetter(); + + if (modeattacking == ATTACKING_RECORD && !demoplayback) + P_LoadRecordGhosts(); + else if (modeattacking == ATTACKING_NIGHTS && !demoplayback) + P_LoadNightsGhosts(); + + if (G_TagGametype()) + P_InitTagGametype(); + else if (gametype == GT_RACE && server) + CV_StealthSetValue(&cv_numlaps, + (cv_basenumlaps.value) + ? cv_basenumlaps.value + : mapheaderinfo[gamemap - 1]->numlaps); +} + /** Loads a level from a lump or external wad. * * \param skipprecip If true, don't spawn precipitation. @@ -2921,20 +2976,7 @@ boolean P_LoadLevel(boolean skipprecip) // SRB2 determines the sky texture to be used depending on the map header. P_SetupLevelSky(mapheaderinfo[gamemap-1]->skynum, true); - numdmstarts = numredctfstarts = numbluectfstarts = 0; - - // reset the player starts - for (i = 0; i < MAXPLAYERS; i++) - playerstarts[i] = bluectfstarts[i] = redctfstarts[i] = NULL; - - for (i = 0; i < MAX_DM_STARTS; i++) - deathmatchstarts[i] = NULL; - - for (i = 0; i < 2; i++) - skyboxmo[i] = NULL; - - for (i = 0; i < 16; i++) - skyboxviewpnts[i] = skyboxcenterpnts[i] = NULL; + P_ResetSpawnpoints(); P_MapStart(); @@ -2988,43 +3030,8 @@ boolean P_LoadLevel(boolean skipprecip) // none of this needs to be done because it's not the beginning of the map when // a netgame save is being loaded, and could actively be harmful by messing with // the client's view of the data.) - if (fromnetsave) - goto netgameskip; - // ========== - - P_InitPlayers(); - - // restore time in netgame (see also g_game.c) - if ((netgame || multiplayer) && gametype == GT_COOP && cv_coopstarposts.value == 2) - { - // is this a hack? maybe - tic_t maxstarposttime = 0; - for (i = 0; i < MAXPLAYERS; i++) - { - if (playeringame[i] && players[i].starposttime > maxstarposttime) - maxstarposttime = players[i].starposttime; - } - leveltime = maxstarposttime; - } - - P_WriteLetter(); - - if (modeattacking == ATTACKING_RECORD && !demoplayback) - P_LoadRecordGhosts(); - else if (modeattacking == ATTACKING_NIGHTS && !demoplayback) - P_LoadNightsGhosts(); - - if (G_TagGametype()) - P_InitTagGametype(); - else if (gametype == GT_RACE && server) - CV_StealthSetValue(&cv_numlaps, - (cv_basenumlaps.value) - ? cv_basenumlaps.value - : mapheaderinfo[gamemap - 1]->numlaps); - - // =========== - // landing point for netgames. - netgameskip: + if (!fromnetsave) + P_InitGametype(); P_InitCamera(); From e9376a8353c69c25938914a2f54d190eaa809098 Mon Sep 17 00:00:00 2001 From: MascaraSnake Date: Sat, 28 Dec 2019 12:48:32 +0100 Subject: [PATCH 454/746] Cleaned up some more stuff in P_LoadLevel() --- src/p_setup.c | 39 +++++++++++++-------------------------- src/p_setup.h | 2 +- src/p_slopes.c | 9 +++------ src/p_slopes.h | 2 +- src/p_spec.c | 2 +- src/p_spec.h | 2 +- 6 files changed, 20 insertions(+), 36 deletions(-) diff --git a/src/p_setup.c b/src/p_setup.c index 0b443c939..9dba341b7 100644 --- a/src/p_setup.c +++ b/src/p_setup.c @@ -2152,7 +2152,7 @@ lumpnum_t lastloadedmaplumpnum; // for comparative savegame // // Some player initialization for map start. // -static void P_LevelInitStuff(void) +static void P_InitLevelSettings(void) { INT32 i; boolean canresetlives = true; @@ -2277,7 +2277,7 @@ void P_LoadThingsOnly(void) P_RemoveMobj((mobj_t *)think); } - P_LevelInitStuff(); + P_InitLevelSettings(); P_SpawnMapThings(true); @@ -2777,19 +2777,16 @@ static void P_InitGametype(void) /** Loads a level from a lump or external wad. * - * \param skipprecip If true, don't spawn precipitation. + * \param fromnetsave If true, skip some stuff because we're loading a netgame snapshot. * \todo Clean up, refactor, split up; get rid of the bloat. */ -boolean P_LoadLevel(boolean skipprecip) +boolean P_LoadLevel(boolean fromnetsave) { // use gamemap to get map number. // 99% of the things already did, so. // Map header should always be in place at this point - INT32 i, loadprecip = 1, ranspecialwipe = 0; - boolean spawnemblems = true; - INT32 fromnetsave = 0; + INT32 i, ranspecialwipe = 0; sector_t *ss; - boolean chase; levelloading = true; // This is needed. Don't touch. @@ -2820,19 +2817,18 @@ boolean P_LoadLevel(boolean skipprecip) if (cv_runscripts.value && mapheaderinfo[gamemap-1]->scriptname[0] != '#') P_RunLevelScript(mapheaderinfo[gamemap-1]->scriptname); - P_LevelInitStuff(); + P_InitLevelSettings(); postimgtype = postimgtype2 = postimg_none; if (mapheaderinfo[gamemap-1]->forcecharacter[0] != '\0') P_ForceCharacter(mapheaderinfo[gamemap-1]->forcecharacter); - // chasecam on in chaos, race, coop - // chasecam off in match, tag, capture the flag - chase = (!(gametyperules & GTR_FIRSTPERSON)) || (maptol & TOL_2D); - if (!dedicated) { + // chasecam on in first-person gametypes and 2D + boolean chase = (!(gametyperules & GTR_FIRSTPERSON)) || (maptol & TOL_2D); + // Salt: CV_ClearChangedFlags() messes with your settings :( /*if (!cv_cam_speed.changed) CV_Set(&cv_cam_speed, cv_cam_speed.defaultvalue);*/ @@ -2943,14 +2939,7 @@ boolean P_LoadLevel(boolean skipprecip) P_InitThinkers(); P_InitCachedActions(); - /// \note for not spawning precipitation, etc. when loading netgame snapshots - if (skipprecip) - { - fromnetsave = 1; - loadprecip = 0; - spawnemblems = false; - } - else if (savedata.lives > 0) + if (!fromnetsave && savedata.lives > 0) { numgameovers = savedata.numgameovers; players[consoleplayer].continues = savedata.continues; @@ -2964,9 +2953,7 @@ boolean P_LoadLevel(boolean skipprecip) // internal game map maplumpname = G_BuildMapName(gamemap); - //lastloadedmaplumpnum = LUMPERROR; lastloadedmaplumpnum = W_CheckNumForName(maplumpname); - if (lastloadedmaplumpnum == INT16_MAX) I_Error("Map %s not found.\n", maplumpname); @@ -2991,7 +2978,7 @@ boolean P_LoadLevel(boolean skipprecip) P_ResetDynamicSlopes(fromnetsave); #endif - P_SpawnMapThings(spawnemblems); + P_SpawnMapThings(!fromnetsave); skyboxmo[0] = skyboxviewpnts[0]; skyboxmo[1] = skyboxcenterpnts[0]; @@ -3002,7 +2989,7 @@ boolean P_LoadLevel(boolean skipprecip) // set up world state P_SpawnSpecials(fromnetsave); - if (loadprecip) // ugly hack for P_NetUnArchiveMisc (and P_LoadNetGame) + if (!fromnetsave) // ugly hack for P_NetUnArchiveMisc (and P_LoadNetGame) P_SpawnPrecipitation(); #ifdef HWRENDER // not win32 only 19990829 by Kin @@ -3068,7 +3055,7 @@ boolean P_LoadLevel(boolean skipprecip) lastmaploaded = gamemap; // HAS to be set after saving!! - if (loadprecip) // uglier hack + if (!fromnetsave) // uglier hack { // to make a newly loaded level start on the second frame. INT32 buf = gametic % BACKUPTICS; for (i = 0; i < MAXPLAYERS; i++) diff --git a/src/p_setup.h b/src/p_setup.h index 0751cf7b9..de791677c 100644 --- a/src/p_setup.h +++ b/src/p_setup.h @@ -97,7 +97,7 @@ void P_SetupLevelSky(INT32 skynum, boolean global); void P_ScanThings(INT16 mapnum, INT16 wadnum, INT16 lumpnum); #endif void P_LoadThingsOnly(void); -boolean P_LoadLevel(boolean skipprecip); +boolean P_LoadLevel(boolean fromnetsave); 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/p_slopes.c b/src/p_slopes.c index 89d265fa4..f35e7d732 100644 --- a/src/p_slopes.c +++ b/src/p_slopes.c @@ -553,11 +553,8 @@ pslope_t *P_SlopeById(UINT16 id) } /// Reset slopes and read them from special lines. -void P_ResetDynamicSlopes(const UINT32 fromsave) { +void P_ResetDynamicSlopes(const boolean fromsave) { size_t i; - - boolean spawnthinkers = !(boolean)fromsave; - slopelist = NULL; slopecount = 0; @@ -574,14 +571,14 @@ void P_ResetDynamicSlopes(const UINT32 fromsave) { case 711: case 712: case 713: - line_SpawnViaLine(i, spawnthinkers); + line_SpawnViaLine(i, !fromsave); break; case 704: case 705: case 714: case 715: - line_SpawnViaVertexes(i, spawnthinkers); + line_SpawnViaVertexes(i, !fromsave); break; default: diff --git a/src/p_slopes.h b/src/p_slopes.h index 076fd8796..96764051b 100644 --- a/src/p_slopes.h +++ b/src/p_slopes.h @@ -23,7 +23,7 @@ extern UINT16 slopecount; void P_LinkSlopeThinkers (void); void P_CalculateSlopeNormal(pslope_t *slope); -void P_ResetDynamicSlopes(const UINT32 fromsave); +void P_ResetDynamicSlopes(const boolean fromsave); // // P_CopySectorSlope diff --git a/src/p_spec.c b/src/p_spec.c index 0b0ba940d..20f1c8278 100644 --- a/src/p_spec.c +++ b/src/p_spec.c @@ -6426,7 +6426,7 @@ static void P_ApplyFlatAlignment(line_t *master, sector_t *sector, angle_t flata * as they'll just be erased by UnArchiveThinkers. * \sa P_SpawnPrecipitation, P_SpawnFriction, P_SpawnPushers, P_SpawnScrollers */ -void P_SpawnSpecials(INT32 fromnetsave) +void P_SpawnSpecials(boolean fromnetsave) { sector_t *sector; size_t i; diff --git a/src/p_spec.h b/src/p_spec.h index 14d3ebb59..630bcb3de 100644 --- a/src/p_spec.h +++ b/src/p_spec.h @@ -35,7 +35,7 @@ void P_SetupLevelFlatAnims(void); // at map load void P_InitSpecials(void); -void P_SpawnSpecials(INT32 fromnetsave); +void P_SpawnSpecials(boolean fromnetsave); // every tic void P_UpdateSpecials(void); From ceca99e3c5bdc0a1dfcb378af70b1f99b0feb02c Mon Sep 17 00:00:00 2001 From: MascaraSnake Date: Sat, 28 Dec 2019 13:58:23 +0100 Subject: [PATCH 455/746] Fix accidental removal of sector_t's spawn_lightlevel initialization --- src/p_setup.c | 1 + 1 file changed, 1 insertion(+) diff --git a/src/p_setup.c b/src/p_setup.c index 9acc4adb3..ce6027c4e 100644 --- a/src/p_setup.c +++ b/src/p_setup.c @@ -664,6 +664,7 @@ static void P_LoadRawSectors(UINT8 *data) ss->ceilingpic = P_AddLevelFlat(ms->ceilingpic, foundflats); ss->lightlevel = SHORT(ms->lightlevel); + ss->spawn_lightlevel = ss->lightlevel; ss->special = SHORT(ms->special); ss->tag = SHORT(ms->tag); ss->nexttag = ss->firsttag = -1; From 3971067cf3c8c41c53416f9f26df158f6b61d0ac Mon Sep 17 00:00:00 2001 From: MascaraSnake Date: Sat, 28 Dec 2019 14:03:48 +0100 Subject: [PATCH 456/746] Remove some old #if 0'd code --- src/p_setup.c | 44 -------------------------------------------- 1 file changed, 44 deletions(-) diff --git a/src/p_setup.c b/src/p_setup.c index 2605faa0d..0e298a954 100644 --- a/src/p_setup.c +++ b/src/p_setup.c @@ -1719,13 +1719,6 @@ static void P_ReadBlockMapLump(INT16 *wadblockmaplump, size_t count) // -- Monster Iestyn 09/01/18 static boolean P_LoadRawBlockMap(UINT8 *data, size_t count) { -#if 0 - (void)data; - (void)count; - (void)lumpname; - return false; -#else - if (!count || count >= 0x20000) return false; @@ -2085,43 +2078,6 @@ static void P_LoadMapFromFile(void) vres_Free(virt); } -#if 0 -static char *levellumps[] = -{ - "label", // ML_LABEL, A separator, name, MAPxx - "THINGS", // ML_THINGS, Enemies, items.. - "LINEDEFS", // ML_LINEDEFS, Linedefs, from editing - "SIDEDEFS", // ML_SIDEDEFS, Sidedefs, from editing - "VERTEXES", // ML_VERTEXES, Vertices, edited and BSP splits generated - "SEGS", // ML_SEGS, Linesegs, from linedefs split by BSP - "SSECTORS", // ML_SSECTORS, Subsectors, list of linesegs - "NODES", // ML_NODES, BSP nodes - "SECTORS", // ML_SECTORS, Sectors, from editing - "REJECT", // ML_REJECT, LUT, sector-sector visibility -}; - -/** Checks a lump and returns whether it is a valid start-of-level marker. - * - * \param lumpnum Lump number to check. - * \return True if the lump is a valid level marker, false if not. - */ -static inline boolean P_CheckLevel(lumpnum_t lumpnum) -{ - UINT16 file, lump; - size_t i; - - for (i = ML_THINGS; i <= ML_REJECT; i++) - { - file = WADFILENUM(lumpnum); - lump = LUMPNUM(lumpnum+1); - if (file > numwadfiles || lump < LUMPNUM(lumpnum) || lump > wadfiles[file]->numlumps || - memcmp(wadfiles[file]->lumpinfo[lump].name, levellumps[i], 8) != 0) - return false; - } - return true; // all right -} -#endif - /** Sets up a sky texture to use for the level. * The sky texture is used instead of F_SKY1. */ From 559034304310f1bf89c868655d918228b6e5d04d Mon Sep 17 00:00:00 2001 From: MascaraSnake Date: Sat, 28 Dec 2019 14:13:26 +0100 Subject: [PATCH 457/746] Rename P_LoadThingsOnly to P_RespawnThings to make it clearer that it doesn't actually reload the things from the file, it just respawns them. --- src/g_game.c | 2 +- src/p_setup.c | 8 ++------ src/p_setup.h | 2 +- 3 files changed, 4 insertions(+), 8 deletions(-) diff --git a/src/g_game.c b/src/g_game.c index e6a28aa41..7ce68b497 100644 --- a/src/g_game.c +++ b/src/g_game.c @@ -2965,7 +2965,7 @@ void G_DoReborn(INT32 playernum) } if (!countdowntimeup && (mapheaderinfo[gamemap-1]->levelflags & LF_NORELOAD)) { - P_LoadThingsOnly(); + P_RespawnThings(); for (i = 0; i < MAXPLAYERS; i++) { diff --git a/src/p_setup.c b/src/p_setup.c index 0e298a954..ad1ae12ae 100644 --- a/src/p_setup.c +++ b/src/p_setup.c @@ -2206,12 +2206,8 @@ static void P_InitLevelSettings(void) CV_SetValue(&cv_analog2, true); } -// -// P_LoadThingsOnly -// -// "Reloads" a level, but only reloads all of the mobjs. -// -void P_LoadThingsOnly(void) +// Respawns all the mapthings and mobjs in the map from the already loaded map data. +void P_RespawnThings(void) { // Search through all the thinkers. thinker_t *think; diff --git a/src/p_setup.h b/src/p_setup.h index de791677c..be3d220d8 100644 --- a/src/p_setup.h +++ b/src/p_setup.h @@ -96,7 +96,7 @@ void P_SetupLevelSky(INT32 skynum, boolean global); #ifdef SCANTHINGS void P_ScanThings(INT16 mapnum, INT16 wadnum, INT16 lumpnum); #endif -void P_LoadThingsOnly(void); +void P_RespawnThings(void); boolean P_LoadLevel(boolean fromnetsave); boolean P_AddWadFile(const char *wadfilename); boolean P_RunSOC(const char *socfilename); From b1854b5c96301fc182ce12a53ba1265fcd179372 Mon Sep 17 00:00:00 2001 From: MascaraSnake Date: Sat, 28 Dec 2019 14:50:00 +0100 Subject: [PATCH 458/746] Remove stray #endif --- src/p_setup.c | 1 - 1 file changed, 1 deletion(-) diff --git a/src/p_setup.c b/src/p_setup.c index ad1ae12ae..6abbd9576 100644 --- a/src/p_setup.c +++ b/src/p_setup.c @@ -1744,7 +1744,6 @@ static boolean P_LoadRawBlockMap(UINT8 *data, size_t count) polyblocklinks = Z_Calloc(count, PU_LEVEL, NULL); #endif return true; -#endif } // From 21b7507aee1540a15d27a0e68c957e19238b7253 Mon Sep 17 00:00:00 2001 From: MascaraSnake Date: Sat, 28 Dec 2019 16:40:35 +0100 Subject: [PATCH 459/746] Reorganize and partially rename map loading functions --- src/p_setup.c | 1107 +++++++++++++++++++++++++------------------------ 1 file changed, 554 insertions(+), 553 deletions(-) diff --git a/src/p_setup.c b/src/p_setup.c index 6abbd9576..1884b6de3 100644 --- a/src/p_setup.c +++ b/src/p_setup.c @@ -373,114 +373,6 @@ UINT32 P_GetScoreForGrade(INT16 map, UINT8 mare, UINT8 grade) return mapheaderinfo[map-1]->grades[mare].grade[grade-1]; } -// Loads the vertexes for a level. -static inline void P_LoadRawVertexes(UINT8 *data) -{ - mapvertex_t *ml = (mapvertex_t *)data; - vertex_t *li = vertexes; - size_t i; - - // Copy and convert vertex coordinates, internal representation as fixed. - for (i = 0; i < numvertexes; i++, li++, ml++) - { - li->x = SHORT(ml->x)<y = SHORT(ml->y)<v2->x - seg->v1->x)>>1; - INT64 dy = (seg->v2->y - seg->v1->y)>>1; - 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. - */ -static inline float P_SegLengthFloat(seg_t *seg) -{ - float dx, dy; - - // make a vector (start at origin) - dx = FIXED_TO_FLOAT(seg->v2->x - seg->v1->x); - dy = FIXED_TO_FLOAT(seg->v2->y - seg->v1->y); - - return (float)hypot(dx, dy); -} -#endif - -// Loads the SEGS resource from a level. -static void P_LoadRawSegs(UINT8 *data) -{ - INT32 linedef, side; - mapseg_t *ml = (mapseg_t*)data; - seg_t *li = segs; - line_t *ldef; - size_t i; - - for (i = 0; i < numsegs; i++, li++, ml++) - { - li->v1 = &vertexes[SHORT(ml->v1)]; - li->v2 = &vertexes[SHORT(ml->v2)]; - - li->length = P_SegLength(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 - } - li->pv1 = li->pv2 = NULL; -#endif - - li->angle = (SHORT(ml->angle))<offset = (SHORT(ml->offset))<linedef); - ldef = &lines[linedef]; - li->linedef = ldef; - li->side = side = SHORT(ml->side); - li->sidedef = &sides[ldef->sidenum[side]]; - li->frontsector = sides[ldef->sidenum[side]].sector; - if (ldef->flags & ML_TWOSIDED) - li->backsector = sides[ldef->sidenum[side^1]].sector; - else - li->backsector = 0; - - li->numlights = 0; - li->rlights = NULL; - } -} - -// Loads the SSECTORS resource from a level. -static inline void P_LoadRawSubsectors(void *data) -{ - mapsubsector_t *ms = (mapsubsector_t*)data; - subsector_t *ss = subsectors; - size_t i; - - for (i = 0; i < numsubsectors; i++, ss++, ms++) - { - ss->sector = NULL; - ss->numlines = SHORT(ms->numsegs); - ss->firstline = SHORT(ms->firstseg); -#ifdef FLOORSPLATS - ss->splats = NULL; -#endif - ss->validcount = 0; - } -} - // // levelflats // @@ -647,107 +539,6 @@ INT32 P_CheckLevelFlat(const char *flatname) return (INT32)i; } -// Sets up the ingame sectors structures. -static void P_LoadRawSectors(UINT8 *data) -{ - mapsector_t *ms = (mapsector_t *)data; - sector_t *ss = sectors; - size_t i; - - // For each counted sector, copy the sector raw data from our cache pointer ms, to the global table pointer ss. - for (i = 0; i < numsectors; i++, ss++, ms++) - { - ss->floorheight = SHORT(ms->floorheight)<ceilingheight = SHORT(ms->ceilingheight)<floorpic = P_AddLevelFlat(ms->floorpic, foundflats); - ss->ceilingpic = P_AddLevelFlat(ms->ceilingpic, foundflats); - - ss->lightlevel = SHORT(ms->lightlevel); - ss->spawn_lightlevel = ss->lightlevel; - ss->special = SHORT(ms->special); - ss->tag = SHORT(ms->tag); - ss->nexttag = ss->firsttag = -1; - - memset(&ss->soundorg, 0, sizeof(ss->soundorg)); - ss->validcount = 0; - - ss->thinglist = NULL; - ss->touching_thinglist = NULL; - ss->preciplist = NULL; - ss->touching_preciplist = NULL; - - ss->floordata = NULL; - ss->ceilingdata = NULL; - ss->lightingdata = NULL; - - ss->linecount = 0; - ss->lines = NULL; - - ss->heightsec = -1; - ss->camsec = -1; - ss->floorlightsec = -1; - ss->ceilinglightsec = -1; - ss->crumblestate = 0; - ss->ffloors = NULL; - ss->lightlist = NULL; - ss->numlights = 0; - ss->attached = NULL; - ss->attachedsolid = NULL; - ss->numattached = 0; - ss->maxattached = 1; - ss->moved = true; - - ss->extra_colormap = NULL; - ss->spawn_extra_colormap = NULL; - - ss->floor_xoffs = ss->ceiling_xoffs = ss->floor_yoffs = ss->ceiling_yoffs = 0; - ss->floorpic_angle = ss->ceilingpic_angle = 0; - ss->gravity = NULL; - ss->cullheight = NULL; - ss->verticalflip = false; - ss->flags = 0; - ss->flags |= SF_FLIPSPECIAL_FLOOR; - - ss->floorspeed = 0; - ss->ceilspeed = 0; - -#ifdef HWRENDER // ----- for special tricks with HW renderer ----- - ss->pseudoSector = false; - ss->virtualFloor = false; - ss->virtualCeiling = false; - ss->sectorLines = NULL; - ss->stackList = NULL; - ss->lineoutLength = -1.0l; -#endif // ----- end special tricks ----- - } -} - -// -// P_LoadNodes -// -static void P_LoadRawNodes(UINT8 *data) -{ - UINT8 j, k; - mapnode_t *mn = (mapnode_t*)data; - node_t *no = nodes; - size_t i; - - for (i = 0; i < numnodes; i++, no++, mn++) - { - no->x = SHORT(mn->x)<y = SHORT(mn->y)<dx = SHORT(mn->dx)<dy = SHORT(mn->dy)<children[j] = SHORT(mn->children[j]); - for (k = 0; k < 4; k++) - no->bbox[j][k] = SHORT(mn->bbox[j][k])<x = READINT16(data); - mt->y = READINT16(data); - - mt->angle = READINT16(data); - mt->type = READUINT16(data); - mt->options = READUINT16(data); - mt->extrainfo = (UINT8)(mt->type >> 12); - - mt->type &= 4095; - - if (mt->type == 1705 || (mt->type == 750 && mt->extrainfo)) - mt->z = mt->options; // NiGHTS Hoops use the full flags bits to set the height. - else - mt->z = mt->options >> ZSHIFT; - } -} - static void P_SpawnEmeraldHunt(void) { INT32 emer1, emer2, emer3; @@ -1062,7 +829,100 @@ void P_WriteThings(lumpnum_t lumpnum) CONS_Printf(M_GetText("newthings%d.lmp saved.\n"), gamemap); } -static void P_LoadRawLineDefs(UINT8 *data) +// +// MAP LOADING FUNCTIONS +// + +static void P_LoadVertices(UINT8 *data) +{ + mapvertex_t *ml = (mapvertex_t *)data; + vertex_t *li = vertexes; + size_t i; + + // Copy and convert vertex coordinates, internal representation as fixed. + for (i = 0; i < numvertexes; i++, li++, ml++) + { + li->x = SHORT(ml->x)<y = SHORT(ml->y)<floorheight = SHORT(ms->floorheight)<ceilingheight = SHORT(ms->ceilingheight)<floorpic = P_AddLevelFlat(ms->floorpic, foundflats); + ss->ceilingpic = P_AddLevelFlat(ms->ceilingpic, foundflats); + + ss->lightlevel = SHORT(ms->lightlevel); + ss->spawn_lightlevel = ss->lightlevel; + ss->special = SHORT(ms->special); + ss->tag = SHORT(ms->tag); + ss->nexttag = ss->firsttag = -1; + + memset(&ss->soundorg, 0, sizeof(ss->soundorg)); + ss->validcount = 0; + + ss->thinglist = NULL; + ss->touching_thinglist = NULL; + ss->preciplist = NULL; + ss->touching_preciplist = NULL; + + ss->floordata = NULL; + ss->ceilingdata = NULL; + ss->lightingdata = NULL; + + ss->linecount = 0; + ss->lines = NULL; + + ss->heightsec = -1; + ss->camsec = -1; + ss->floorlightsec = -1; + ss->ceilinglightsec = -1; + ss->crumblestate = 0; + ss->ffloors = NULL; + ss->lightlist = NULL; + ss->numlights = 0; + ss->attached = NULL; + ss->attachedsolid = NULL; + ss->numattached = 0; + ss->maxattached = 1; + ss->moved = true; + + ss->extra_colormap = NULL; + ss->spawn_extra_colormap = NULL; + + ss->floor_xoffs = ss->ceiling_xoffs = ss->floor_yoffs = ss->ceiling_yoffs = 0; + ss->floorpic_angle = ss->ceilingpic_angle = 0; + ss->gravity = NULL; + ss->cullheight = NULL; + ss->verticalflip = false; + ss->flags = 0; + ss->flags |= SF_FLIPSPECIAL_FLOOR; + + ss->floorspeed = 0; + ss->ceilspeed = 0; + +#ifdef HWRENDER // ----- for special tricks with HW renderer ----- + ss->pseudoSector = false; + ss->virtualFloor = false; + ss->virtualCeiling = false; + ss->sectorLines = NULL; + ss->stackList = NULL; + ss->lineoutLength = -1.0l; +#endif // ----- end special tricks ----- + } +} + +static void P_LoadLinedefs(UINT8 *data) { maplinedef_t *mld = (maplinedef_t *)data; line_t *ld = lines; @@ -1142,7 +1002,7 @@ static void P_SetupLines(void) if (ld->sidenum[j] != 0xffff && ld->sidenum[j] >= (UINT16)numsides) { ld->sidenum[j] = 0xffff; - CONS_Debug(DBG_SETUP, "P_LoadRawLineDefs: linedef %s has out-of-range sidedef number\n", sizeu1(numlines-i-1)); + CONS_Debug(DBG_SETUP, "P_SetupLines: Linedef %s has out-of-range sidedef number\n", sizeu1(numlines-i-1)); } } @@ -1156,14 +1016,14 @@ static void P_SetupLines(void) { ld->sidenum[0] = 0; // Substitute dummy sidedef for missing right side // cph - print a warning about the bug - CONS_Debug(DBG_SETUP, "Linedef %s missing first sidedef\n", sizeu1(numlines-i-1)); + CONS_Debug(DBG_SETUP, "P_SetupLines: Linedef %s missing first sidedef\n", sizeu1(numlines-i-1)); } if ((ld->sidenum[1] == 0xffff) && (ld->flags & ML_TWOSIDED)) { ld->flags &= ~ML_TWOSIDED; // Clear 2s flag for missing left side // cph - print a warning about the bug - CONS_Debug(DBG_SETUP, "Linedef %s has two-sided flag set, but no second sidedef\n", sizeu1(numlines-i-1)); + CONS_Debug(DBG_SETUP, "P_SetupLines: Linedef %s has two-sided flag set, but no second sidedef\n", sizeu1(numlines-i-1)); } if (ld->sidenum[0] != 0xffff && ld->special) @@ -1173,109 +1033,7 @@ static void P_SetupLines(void) } } -static void P_LoadLineDefs2(void) -{ - size_t i = numlines; - register line_t *ld = lines; - for (;i--;ld++) - { - ld->frontsector = sides[ld->sidenum[0]].sector; //e6y: Can't be -1 here - ld->backsector = ld->sidenum[1] != 0xffff ? sides[ld->sidenum[1]].sector : 0; - - // Repeat count for midtexture - if ((ld->flags & ML_EFFECT5) && (ld->sidenum[1] != 0xffff) - && !(ld->special >= 300 && ld->special < 500)) // exempt linedef exec specials - { - sides[ld->sidenum[0]].repeatcnt = (INT16)(((unsigned)sides[ld->sidenum[0]].textureoffset >> FRACBITS) >> 12); - sides[ld->sidenum[0]].textureoffset = (((unsigned)sides[ld->sidenum[0]].textureoffset >> FRACBITS) & 2047) << FRACBITS; - sides[ld->sidenum[1]].repeatcnt = (INT16)(((unsigned)sides[ld->sidenum[1]].textureoffset >> FRACBITS) >> 12); - sides[ld->sidenum[1]].textureoffset = (((unsigned)sides[ld->sidenum[1]].textureoffset >> FRACBITS) & 2047) << FRACBITS; - } - - // Compile linedef 'text' from both sidedefs 'text' for appropriate specials. - switch(ld->special) - { - case 331: // Trigger linedef executor: Skin - Continuous - case 332: // Trigger linedef executor: Skin - Each time - case 333: // Trigger linedef executor: Skin - Once - case 443: // Calls a named Lua function - if (sides[ld->sidenum[0]].text) - { - size_t len = strlen(sides[ld->sidenum[0]].text)+1; - if (ld->sidenum[1] != 0xffff && sides[ld->sidenum[1]].text) - len += strlen(sides[ld->sidenum[1]].text); - ld->text = Z_Malloc(len, PU_LEVEL, NULL); - M_Memcpy(ld->text, sides[ld->sidenum[0]].text, strlen(sides[ld->sidenum[0]].text)+1); - if (ld->sidenum[1] != 0xffff && sides[ld->sidenum[1]].text) - M_Memcpy(ld->text+strlen(ld->text)+1, sides[ld->sidenum[1]].text, strlen(sides[ld->sidenum[1]].text)+1); - } - break; - } - } - - // Optimize sidedefs - if (M_CheckParm("-compress")) - { - side_t *newsides; - size_t numnewsides = 0; - size_t z; - - for (i = 0; i < numsides; i++) - { - size_t j, k; - if (sides[i].sector == NULL) - 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 == NULL) - 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 != NULL) - M_Memcpy(&newsides[z++], &sides[i], sizeof(side_t)); - } - - CONS_Debug(DBG_SETUP, "Old sides is %s, new sides is %s\n", sizeu1(numsides), sizeu1(numnewsides)); - - Z_Free(sides); - sides = newsides; - numsides = numnewsides; - } -} - -static void P_LoadRawSideDefs2(void *data) +static void P_LoadSidedefs(UINT8 *data) { UINT16 i; @@ -1293,7 +1051,7 @@ static void P_LoadRawSideDefs2(void *data) if (sector_num >= numsectors) { - CONS_Debug(DBG_SETUP, "P_LoadRawSideDefs2: sidedef %u has out-of-range sector num %u\n", i, sector_num); + CONS_Debug(DBG_SETUP, "P_LoadSidedefs: sidedef %u has out-of-range sector num %u\n", i, sector_num); sector_num = 0; } sd->sector = sec = §ors[sector_num]; @@ -1434,6 +1192,335 @@ static void P_LoadRawSideDefs2(void *data) } } +static void P_LoadThings(UINT8 *data) +{ + mapthing_t *mt; + size_t i; + + for (i = 0, mt = mapthings; i < nummapthings; i++, mt++) + { + mt->x = READINT16(data); + mt->y = READINT16(data); + + mt->angle = READINT16(data); + mt->type = READUINT16(data); + mt->options = READUINT16(data); + mt->extrainfo = (UINT8)(mt->type >> 12); + + mt->type &= 4095; + + if (mt->type == 1705 || (mt->type == 750 && mt->extrainfo)) + mt->z = mt->options; // NiGHTS Hoops use the full flags bits to set the height. + else + mt->z = mt->options >> ZSHIFT; + } +} + +static void P_LoadMapData(const virtres_t *virt) +{ + virtlump_t* virtvertexes = NULL, * virtsectors = NULL, * virtsidedefs = NULL, * virtlinedefs = NULL, * virtthings = NULL; +#ifdef UDMF + virtlump_t* textmap = vres_Find(virt, "TEXTMAP"); + + // Count map data. + if (textmap) + { + nummapthings = 0; + numlines = 0; + numsides = 0; + numvertexes = 0; + numsectors = 0; + + // Count how many entries for each type we got in textmap. + //TextmapCount(vtextmap->data, vtextmap->size); + } + else +#endif + { + virtthings = vres_Find(virt, "THINGS"); + virtvertexes = vres_Find(virt, "VERTEXES"); + virtsectors = vres_Find(virt, "SECTORS"); + virtsidedefs = vres_Find(virt, "SIDEDEFS"); + virtlinedefs = vres_Find(virt, "LINEDEFS"); + + if (!virtthings) + I_Error("THINGS lump not found"); + if (!virtvertexes) + I_Error("VERTEXES lump not found"); + if (!virtsectors) + I_Error("SECTORS lump not found"); + if (!virtsidedefs) + I_Error("SIDEDEFS lump not found"); + if (!virtlinedefs) + I_Error("LINEDEFS lump not found"); + + // Traditional doom map format just assumes the number of elements from the lump sizes. + numvertexes = virtvertexes->size / sizeof (mapvertex_t); + numsectors = virtsectors->size / sizeof (mapsector_t); + numsides = virtsidedefs->size / sizeof (mapsidedef_t); + numlines = virtlinedefs->size / sizeof (maplinedef_t); + nummapthings = virtthings->size / (5 * sizeof (INT16)); + } + + if (numvertexes <= 0) + I_Error("Level has no vertices"); + if (numsectors <= 0) + I_Error("Level has no sectors"); + if (numsides <= 0) + I_Error("Level has no sidedefs"); + if (numlines <= 0) + I_Error("Level has no linedefs"); + + vertexes = Z_Calloc(numvertexes * sizeof (*vertexes), PU_LEVEL, NULL); + sectors = Z_Calloc(numsectors * sizeof (*sectors), PU_LEVEL, NULL); + sides = Z_Calloc(numsides * sizeof (*sides), PU_LEVEL, NULL); + lines = Z_Calloc(numlines * sizeof (*lines), PU_LEVEL, NULL); + mapthings = Z_Calloc(nummapthings * sizeof (*mapthings), PU_LEVEL, NULL); + + // Allocate a big chunk of memory as big as our MAXLEVELFLATS limit. + //Fab : FIXME: allocate for whatever number of flats - 512 different flats per level should be plenty + foundflats = calloc(MAXLEVELFLATS, sizeof (*foundflats)); + if (foundflats == NULL) + I_Error("Ran out of memory while loading sectors\n"); + + numlevelflats = 0; + +#ifdef UDMF + if (textmap) + { + + } + else +#endif + { + // Strict map data + P_LoadVertices(virtvertexes->data); + P_LoadSectors(virtsectors->data); + P_LoadLinedefs(virtlinedefs->data); + P_SetupLines(); + P_LoadSidedefs(virtsidedefs->data); + P_LoadThings(virtthings->data); + } + + R_ClearTextureNumCache(true); + + // set the sky flat num + skyflatnum = P_AddLevelFlat(SKYFLATNAME, foundflats); + + // copy table for global usage + levelflats = M_Memcpy(Z_Calloc(numlevelflats * sizeof (*levelflats), PU_LEVEL, NULL), foundflats, numlevelflats * sizeof (levelflat_t)); + free(foundflats); + + // search for animated flats and set up + P_SetupLevelFlatAnims(); + + // Copy relevant map data for NetArchive purposes. + spawnsectors = Z_Calloc(numsectors * sizeof (*sectors), PU_LEVEL, NULL); + spawnlines = Z_Calloc(numlines * sizeof (*lines), PU_LEVEL, NULL); + spawnsides = Z_Calloc(numsides * sizeof (*sides), PU_LEVEL, NULL); + + memcpy(spawnsectors, sectors, numsectors * sizeof (*sectors)); + memcpy(spawnlines, lines, numlines * sizeof (*lines)); + memcpy(spawnsides, sides, numsides * sizeof (*sides)); +} + +static inline void P_LoadSubsectors(UINT8 *data) +{ + mapsubsector_t *ms = (mapsubsector_t*)data; + subsector_t *ss = subsectors; + size_t i; + + for (i = 0; i < numsubsectors; i++, ss++, ms++) + { + ss->sector = NULL; + ss->numlines = SHORT(ms->numsegs); + ss->firstline = SHORT(ms->firstseg); +#ifdef FLOORSPLATS + ss->splats = NULL; +#endif + ss->validcount = 0; + } +} + +static void P_LoadNodes(UINT8 *data) +{ + UINT8 j, k; + mapnode_t *mn = (mapnode_t*)data; + node_t *no = nodes; + size_t i; + + for (i = 0; i < numnodes; i++, no++, mn++) + { + no->x = SHORT(mn->x)<y = SHORT(mn->y)<dx = SHORT(mn->dx)<dy = SHORT(mn->dy)<children[j] = SHORT(mn->children[j]); + for (k = 0; k < 4; k++) + no->bbox[j][k] = SHORT(mn->bbox[j][k])<v2->x - seg->v1->x)>>1; + INT64 dy = (seg->v2->y - seg->v1->y)>>1; + 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. + */ +static inline float P_SegLengthFloat(seg_t *seg) +{ + float dx, dy; + + // make a vector (start at origin) + dx = FIXED_TO_FLOAT(seg->v2->x - seg->v1->x); + dy = FIXED_TO_FLOAT(seg->v2->y - seg->v1->y); + + return (float)hypot(dx, dy); +} +#endif + +static void P_LoadSegs(UINT8 *data) +{ + INT32 linedef, side; + mapseg_t *ml = (mapseg_t*)data; + seg_t *li = segs; + line_t *ldef; + size_t i; + + for (i = 0; i < numsegs; i++, li++, ml++) + { + li->v1 = &vertexes[SHORT(ml->v1)]; + li->v2 = &vertexes[SHORT(ml->v2)]; + + li->length = P_SegLength(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 + } + li->pv1 = li->pv2 = NULL; +#endif + + li->angle = (SHORT(ml->angle))<offset = (SHORT(ml->offset))<linedef); + ldef = &lines[linedef]; + li->linedef = ldef; + li->side = side = SHORT(ml->side); + li->sidedef = &sides[ldef->sidenum[side]]; + li->frontsector = sides[ldef->sidenum[side]].sector; + if (ldef->flags & ML_TWOSIDED) + li->backsector = sides[ldef->sidenum[side^1]].sector; + else + li->backsector = 0; + + li->numlights = 0; + li->rlights = NULL; + } +} + +static void P_LoadMapBSP(const virtres_t *virt) +{ + virtlump_t* virtssectors = vres_Find(virt, "SSECTORS"); + virtlump_t* virtsegs = vres_Find(virt, "SEGS"); + virtlump_t* virtnodes = vres_Find(virt, "NODES"); + + numsubsectors = virtssectors->size / sizeof(mapsubsector_t); + numnodes = virtnodes->size / sizeof(mapnode_t); + numsegs = virtsegs->size / sizeof(mapseg_t); + + if (numsubsectors <= 0) + I_Error("Level has no subsectors (did you forget to run it through a nodesbuilder?)"); + if (numnodes <= 0) + I_Error("Level has no nodes"); + if (numsegs <= 0) + I_Error("Level has no segs"); + + subsectors = Z_Calloc(numsubsectors * sizeof(*subsectors), PU_LEVEL, NULL); + nodes = Z_Calloc(numnodes * sizeof(*nodes), PU_LEVEL, NULL); + segs = Z_Calloc(numsegs * sizeof(*segs), PU_LEVEL, NULL); + + // Nodes + P_LoadSubsectors(virtssectors->data); + P_LoadNodes(virtnodes->data); + P_LoadSegs(virtsegs->data); +} + +// Split from P_LoadBlockMap for convenience +// -- Monster Iestyn 08/01/18 +static void P_ReadBlockMapLump(INT16 *wadblockmaplump, size_t count) +{ + size_t i; + blockmaplump = Z_Calloc(sizeof (*blockmaplump) * count, PU_LEVEL, NULL); + + // killough 3/1/98: Expand wad blockmap into larger internal one, + // by treating all offsets except -1 as unsigned and zero-extending + // them. This potentially doubles the size of blockmaps allowed, + // because Doom originally considered the offsets as always signed. + + blockmaplump[0] = SHORT(wadblockmaplump[0]); + blockmaplump[1] = SHORT(wadblockmaplump[1]); + blockmaplump[2] = (INT32)(SHORT(wadblockmaplump[2])) & 0xffff; + blockmaplump[3] = (INT32)(SHORT(wadblockmaplump[3])) & 0xffff; + + for (i = 4; i < count; i++) + { + INT16 t = SHORT(wadblockmaplump[i]); // killough 3/1/98 + blockmaplump[i] = t == -1 ? (INT32)-1 : (INT32) t & 0xffff; + } +} + +// This needs to be a separate function +// because making both the WAD and PK3 loading code use +// the same functions is trickier than it looks for blockmap +// -- Monster Iestyn 09/01/18 +static boolean P_LoadBlockMap(UINT8 *data, size_t count) +{ + if (!count || count >= 0x20000) + return false; + + //CONS_Printf("Reading blockmap lump for pk3...\n"); + + // no need to malloc anything, assume the data is uncompressed for now + count /= 2; + P_ReadBlockMapLump((INT16 *)data, count); + + bmaporgx = blockmaplump[0]<= 0x20000) - return false; + virtlump_t* virtblockmap = vres_Find(virt, "BLOCKMAP"); + virtlump_t* virtreject = vres_Find(virt, "REJECT"); - //CONS_Printf("Reading blockmap lump for pk3...\n"); + // Lookup tables + if (virtreject) + P_LoadReject(virtreject->data, virtreject->size); + else + rejectmatrix = NULL; - // no need to malloc anything, assume the data is uncompressed for now - count /= 2; - P_ReadBlockMapLump((INT16 *)data, count); + if (!(virtblockmap && P_LoadBlockMap(virtblockmap->data, virtblockmap->size))) + P_CreateBlockMap(); +} - bmaporgx = blockmaplump[0]<frontsector = sides[ld->sidenum[0]].sector; //e6y: Can't be -1 here + ld->backsector = ld->sidenum[1] != 0xffff ? sides[ld->sidenum[1]].sector : 0; - // clear out mobj chains - count = sizeof (*blocklinks)* bmapwidth*bmapheight; - blocklinks = Z_Calloc(count, PU_LEVEL, NULL); - blockmap = blockmaplump+4; + // Repeat count for midtexture + if ((ld->flags & ML_EFFECT5) && (ld->sidenum[1] != 0xffff) + && !(ld->special >= 300 && ld->special < 500)) // exempt linedef exec specials + { + sides[ld->sidenum[0]].repeatcnt = (INT16)(((unsigned)sides[ld->sidenum[0]].textureoffset >> FRACBITS) >> 12); + sides[ld->sidenum[0]].textureoffset = (((unsigned)sides[ld->sidenum[0]].textureoffset >> FRACBITS) & 2047) << FRACBITS; + sides[ld->sidenum[1]].repeatcnt = (INT16)(((unsigned)sides[ld->sidenum[1]].textureoffset >> FRACBITS) >> 12); + sides[ld->sidenum[1]].textureoffset = (((unsigned)sides[ld->sidenum[1]].textureoffset >> FRACBITS) & 2047) << FRACBITS; + } -#ifdef POLYOBJECTS - // haleyjd 2/22/06: setup polyobject blockmap - count = sizeof(*polyblocklinks) * bmapwidth * bmapheight; - polyblocklinks = Z_Calloc(count, PU_LEVEL, NULL); -#endif - return true; + // Compile linedef 'text' from both sidedefs 'text' for appropriate specials. + switch(ld->special) + { + case 331: // Trigger linedef executor: Skin - Continuous + case 332: // Trigger linedef executor: Skin - Each time + case 333: // Trigger linedef executor: Skin - Once + case 443: // Calls a named Lua function + if (sides[ld->sidenum[0]].text) + { + size_t len = strlen(sides[ld->sidenum[0]].text)+1; + if (ld->sidenum[1] != 0xffff && sides[ld->sidenum[1]].text) + len += strlen(sides[ld->sidenum[1]].text); + ld->text = Z_Malloc(len, PU_LEVEL, NULL); + M_Memcpy(ld->text, sides[ld->sidenum[0]].text, strlen(sides[ld->sidenum[0]].text)+1); + if (ld->sidenum[1] != 0xffff && sides[ld->sidenum[1]].text) + M_Memcpy(ld->text+strlen(ld->text)+1, sides[ld->sidenum[1]].text, strlen(sides[ld->sidenum[1]].text)+1); + } + break; + } + } + + // Optimize sidedefs + if (M_CheckParm("-compress")) + { + side_t *newsides; + size_t numnewsides = 0; + size_t z; + + for (i = 0; i < numsides; i++) + { + size_t j, k; + if (sides[i].sector == NULL) + 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 == NULL) + 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 != NULL) + M_Memcpy(&newsides[z++], &sides[i], sizeof(side_t)); + } + + CONS_Debug(DBG_SETUP, "Old sides is %s, new sides is %s\n", sizeu1(numsides), sizeu1(numnewsides)); + + Z_Free(sides); + sides = newsides; + numsides = numnewsides; + } } // @@ -1842,172 +2005,6 @@ static void P_GroupLines(void) } } -// PK3 version -// -- Monster Iestyn 09/01/18 -static void P_LoadRawReject(UINT8 *data, size_t count) -{ - if (!count) // zero length, someone probably used ZDBSP - { - rejectmatrix = NULL; - CONS_Debug(DBG_SETUP, "P_LoadRawReject: REJECT lump has size 0, will not be loaded\n"); - } - else - { - rejectmatrix = Z_Malloc(count, PU_LEVEL, NULL); // allocate memory for the reject matrix - M_Memcpy(rejectmatrix, data, count); // copy the data into it - } -} - -static void P_LoadMapBSP(const virtres_t* virt) -{ - virtlump_t* virtssectors = vres_Find(virt, "SSECTORS"); - virtlump_t* virtsegs = vres_Find(virt, "SEGS"); - virtlump_t* virtnodes = vres_Find(virt, "NODES"); - - numsubsectors = virtssectors->size / sizeof(mapsubsector_t); - numnodes = virtnodes->size / sizeof(mapnode_t); - numsegs = virtsegs->size / sizeof(mapseg_t); - - if (numsubsectors <= 0) - I_Error("Level has no subsectors (did you forget to run it through a nodesbuilder?)"); - if (numnodes <= 0) - I_Error("Level has no nodes"); - if (numsegs <= 0) - I_Error("Level has no segs"); - - subsectors = Z_Calloc(numsubsectors * sizeof(*subsectors), PU_LEVEL, NULL); - nodes = Z_Calloc(numnodes * sizeof(*nodes), PU_LEVEL, NULL); - segs = Z_Calloc(numsegs * sizeof(*segs), PU_LEVEL, NULL); - - // Nodes - P_LoadRawSubsectors(virtssectors->data); - P_LoadRawNodes(virtnodes->data); - P_LoadRawSegs(virtsegs->data); -} - -static void P_LoadMapLUT(const virtres_t* virt) -{ - virtlump_t* virtblockmap = vres_Find(virt, "BLOCKMAP"); - virtlump_t* virtreject = vres_Find(virt, "REJECT"); - - // Lookup tables - if (virtreject) - P_LoadRawReject(virtreject->data, virtreject->size); - else - rejectmatrix = NULL; - - if (!(virtblockmap && P_LoadRawBlockMap(virtblockmap->data, virtblockmap->size))) - P_CreateBlockMap(); -} - -static void P_LoadMapData(const virtres_t* virt) -{ - virtlump_t* virtvertexes = NULL, * virtsectors = NULL, * virtsidedefs = NULL, * virtlinedefs = NULL, * virtthings = NULL; -#ifdef UDMF - virtlump_t* textmap = vres_Find(virt, "TEXTMAP"); - - // Count map data. - if (textmap) - { - nummapthings = 0; - numlines = 0; - numsides = 0; - numvertexes = 0; - numsectors = 0; - - // Count how many entries for each type we got in textmap. - //TextmapCount(vtextmap->data, vtextmap->size); - } - else -#endif - { - virtthings = vres_Find(virt, "THINGS"); - virtvertexes = vres_Find(virt, "VERTEXES"); - virtsectors = vres_Find(virt, "SECTORS"); - virtsidedefs = vres_Find(virt, "SIDEDEFS"); - virtlinedefs = vres_Find(virt, "LINEDEFS"); - - if (!virtthings) - I_Error("THINGS lump not found"); - if (!virtvertexes) - I_Error("VERTEXES lump not found"); - if (!virtsectors) - I_Error("SECTORS lump not found"); - if (!virtsidedefs) - I_Error("SIDEDEFS lump not found"); - if (!virtlinedefs) - I_Error("LINEDEFS lump not found"); - - // Traditional doom map format just assumes the number of elements from the lump sizes. - numvertexes = virtvertexes->size / sizeof (mapvertex_t); - numsectors = virtsectors->size / sizeof (mapsector_t); - numsides = virtsidedefs->size / sizeof (mapsidedef_t); - numlines = virtlinedefs->size / sizeof (maplinedef_t); - nummapthings = virtthings->size / (5 * sizeof (INT16)); - } - - if (numvertexes <= 0) - I_Error("Level has no vertices"); - if (numsectors <= 0) - I_Error("Level has no sectors"); - if (numsides <= 0) - I_Error("Level has no sidedefs"); - if (numlines <= 0) - I_Error("Level has no linedefs"); - - vertexes = Z_Calloc(numvertexes * sizeof (*vertexes), PU_LEVEL, NULL); - sectors = Z_Calloc(numsectors * sizeof (*sectors), PU_LEVEL, NULL); - sides = Z_Calloc(numsides * sizeof (*sides), PU_LEVEL, NULL); - lines = Z_Calloc(numlines * sizeof (*lines), PU_LEVEL, NULL); - mapthings = Z_Calloc(nummapthings * sizeof (*mapthings), PU_LEVEL, NULL); - - // Allocate a big chunk of memory as big as our MAXLEVELFLATS limit. - //Fab : FIXME: allocate for whatever number of flats - 512 different flats per level should be plenty - foundflats = calloc(MAXLEVELFLATS, sizeof (*foundflats)); - if (foundflats == NULL) - I_Error("Ran out of memory while loading sectors\n"); - - numlevelflats = 0; - -#ifdef UDMF - if (textmap) - { - - } - else -#endif - { - // Strict map data - P_LoadRawVertexes(virtvertexes->data); - P_LoadRawSectors(virtsectors->data); - P_LoadRawLineDefs(virtlinedefs->data); - P_SetupLines(); - P_LoadRawSideDefs2(virtsidedefs->data); - P_PrepareRawThings(virtthings->data); - } - - R_ClearTextureNumCache(true); - - // set the sky flat num - skyflatnum = P_AddLevelFlat(SKYFLATNAME, foundflats); - - // copy table for global usage - levelflats = M_Memcpy(Z_Calloc(numlevelflats * sizeof (*levelflats), PU_LEVEL, NULL), foundflats, numlevelflats * sizeof (levelflat_t)); - free(foundflats); - - // search for animated flats and set up - P_SetupLevelFlatAnims(); - - // Copy relevant map data for NetArchive purposes. - spawnsectors = Z_Calloc(numsectors * sizeof (*sectors), PU_LEVEL, NULL); - spawnlines = Z_Calloc(numlines * sizeof (*lines), PU_LEVEL, NULL); - spawnsides = Z_Calloc(numsides * sizeof (*sides), PU_LEVEL, NULL); - - memcpy(spawnsectors, sectors, numsectors * sizeof (*sectors)); - memcpy(spawnlines, lines, numlines * sizeof (*lines)); - memcpy(spawnsides, sides, numsides * sizeof (*sides)); -} - /** Compute MD5 message digest for bytes read from memory source * * The resulting message digest number will be written into the 16 bytes @@ -2017,7 +2014,7 @@ static void P_LoadMapData(const virtres_t* virt) * \param resblock resulting MD5 checksum * \return 0 if MD5 checksum was made, and is at resblock, 1 if error was found */ -static INT32 P_MakeBufferMD5(const char* buffer, size_t len, void* resblock) +static INT32 P_MakeBufferMD5(const char *buffer, size_t len, void *resblock) { #ifdef NOMD5 (void)buffer; @@ -2034,7 +2031,7 @@ static INT32 P_MakeBufferMD5(const char* buffer, size_t len, void* resblock) #endif } -static void P_MakeMapMD5(virtres_t* virt, void* dest) +static void P_MakeMapMD5(virtres_t *virt, void *dest) { unsigned char linemd5[16]; unsigned char sectormd5[16]; @@ -2077,6 +2074,10 @@ static void P_LoadMapFromFile(void) vres_Free(virt); } +// +// LEVEL INITIALIZATION FUNCTIONS +// + /** Sets up a sky texture to use for the level. * The sky texture is used instead of F_SKY1. */ From 86d1fb73f4336ecaa691d8fa09d496499571479d Mon Sep 17 00:00:00 2001 From: MascaraSnake Date: Sat, 28 Dec 2019 16:49:56 +0100 Subject: [PATCH 460/746] Split P_LoadLineDefs2 into P_ProcessLinedefsWithSidedefs and P_CompressSidedefs --- src/p_setup.c | 104 ++++++++++++++++++++++++++------------------------ 1 file changed, 54 insertions(+), 50 deletions(-) diff --git a/src/p_setup.c b/src/p_setup.c index 1884b6de3..b581e16d3 100644 --- a/src/p_setup.c +++ b/src/p_setup.c @@ -1807,7 +1807,7 @@ static void P_LoadMapLUT(const virtres_t *virt) P_CreateBlockMap(); } -static void P_LoadLineDefs2(void) +static void P_ProcessLinedefsWithSidedefs(void) { size_t i = numlines; register line_t *ld = lines; @@ -1846,67 +1846,69 @@ static void P_LoadLineDefs2(void) break; } } +} - // Optimize sidedefs - if (M_CheckParm("-compress")) +static void P_CompressSidedefs(void) +{ + side_t *newsides; + size_t numnewsides = 0; + size_t z; + size_t i; + + for (i = 0; i < numsides; i++) { - side_t *newsides; - size_t numnewsides = 0; - size_t z; + size_t j, k; + line_t *ld; - for (i = 0; i < numsides; i++) + if (!sides[i].sector) + continue; + + for (k = numlines, ld = lines; k--; ld++) { - size_t j, k; - if (sides[i].sector == NULL) + 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; - for (k = numlines, ld = lines; k--; ld++) + if (!memcmp(&sides[i], &sides[j], sizeof(side_t))) { - 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 == NULL) - 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++) { - // 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[0] == j) + ld->sidenum[0] = (UINT16)numnewsides; - if (ld->sidenum[1] == j) - ld->sidenum[1] = (UINT16)numnewsides; - } - sides[j].sector = NULL; // Flag for deletion + 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 != NULL) - M_Memcpy(&newsides[z++], &sides[i], sizeof(side_t)); - } - - CONS_Debug(DBG_SETUP, "Old sides is %s, new sides is %s\n", sizeu1(numsides), sizeu1(numnewsides)); - - Z_Free(sides); - sides = newsides; - numsides = numnewsides; + 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; } // @@ -2066,7 +2068,9 @@ static void P_LoadMapFromFile(void) P_LoadMapBSP(virt); P_LoadMapLUT(virt); - P_LoadLineDefs2(); + P_ProcessLinedefsWithSidedefs(); + if (M_CheckParm("-compress")) + P_CompressSidedefs(); P_GroupLines(); P_MakeMapMD5(virt, &mapmd5); From 85de3614cb71c6f9fdab4fbab3d7e38a4b08e3bd Mon Sep 17 00:00:00 2001 From: MascaraSnake Date: Sat, 28 Dec 2019 16:58:48 +0100 Subject: [PATCH 461/746] Standardize P_LoadVertices and P_LoadSidedefs --- src/p_setup.c | 42 +++++++++++++++++++----------------------- 1 file changed, 19 insertions(+), 23 deletions(-) diff --git a/src/p_setup.c b/src/p_setup.c index b581e16d3..a3d186ba6 100644 --- a/src/p_setup.c +++ b/src/p_setup.c @@ -835,15 +835,15 @@ void P_WriteThings(lumpnum_t lumpnum) static void P_LoadVertices(UINT8 *data) { - mapvertex_t *ml = (mapvertex_t *)data; - vertex_t *li = vertexes; + mapvertex_t *mv = (mapvertex_t *)data; + vertex_t *v = vertexes; size_t i; // Copy and convert vertex coordinates, internal representation as fixed. - for (i = 0; i < numvertexes; i++, li++, ml++) + for (i = 0; i < numvertexes; i++, v++, mv++) { - li->x = SHORT(ml->x)<y = SHORT(ml->y)<x = SHORT(mv->x)<y = SHORT(mv->y)<textureoffset = SHORT(msd->textureoffset)<rowoffset = SHORT(msd->rowoffset)<sector); - - if (sector_num >= numsectors) - { - CONS_Debug(DBG_SETUP, "P_LoadSidedefs: sidedef %u has out-of-range sector num %u\n", i, sector_num); - sector_num = 0; - } - sd->sector = sec = §ors[sector_num]; + // cph 2006/09/30 - catch out-of-range sector numbers; use sector 0 instead + sector_num = SHORT(msd->sector); + if (sector_num >= numsectors) + { + CONS_Debug(DBG_SETUP, "P_LoadSidedefs: sidedef %u has out-of-range sector num %u\n", i, sector_num); + sector_num = 0; } - - sd->sector = sec = §ors[SHORT(msd->sector)]; + sd->sector = §ors[sector_num]; sd->colormap_data = NULL; - // Colormaps! + // Special info stored in texture fields! switch (sd->special) { - case 63: // variable colormap via 242 linedef + case 63: // Fake floor/ceiling planes case 606: //SoM: 4/4/2000: Just colormap transfer case 447: // Change colormap of tagged sectors! -- Monster Iestyn 14/06/18 case 455: // Fade colormaps! mazmazz 9/12/2018 (:flag_us:) From 1ca25224c26581b94c1b1f4562de5627b2bcde08 Mon Sep 17 00:00:00 2001 From: MascaraSnake Date: Sat, 28 Dec 2019 17:05:04 +0100 Subject: [PATCH 462/746] Fix P_SetupLines printing the wrong line number --- src/p_setup.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/p_setup.c b/src/p_setup.c index a3d186ba6..4cb20d453 100644 --- a/src/p_setup.c +++ b/src/p_setup.c @@ -1002,7 +1002,7 @@ static void P_SetupLines(void) if (ld->sidenum[j] != 0xffff && ld->sidenum[j] >= (UINT16)numsides) { ld->sidenum[j] = 0xffff; - CONS_Debug(DBG_SETUP, "P_SetupLines: Linedef %s has out-of-range sidedef number\n", sizeu1(numlines-i-1)); + CONS_Debug(DBG_SETUP, "P_SetupLines: Linedef %s has out-of-range sidedef number\n", sizeu1(i)); } } @@ -1016,14 +1016,14 @@ static void P_SetupLines(void) { ld->sidenum[0] = 0; // Substitute dummy sidedef for missing right side // cph - print a warning about the bug - CONS_Debug(DBG_SETUP, "P_SetupLines: Linedef %s missing first sidedef\n", sizeu1(numlines-i-1)); + CONS_Debug(DBG_SETUP, "P_SetupLines: Linedef %s missing first sidedef\n", sizeu1(i)); } if ((ld->sidenum[1] == 0xffff) && (ld->flags & ML_TWOSIDED)) { ld->flags &= ~ML_TWOSIDED; // Clear 2s flag for missing left side // cph - print a warning about the bug - CONS_Debug(DBG_SETUP, "P_SetupLines: Linedef %s has two-sided flag set, but no second sidedef\n", sizeu1(numlines-i-1)); + CONS_Debug(DBG_SETUP, "P_SetupLines: Linedef %s has two-sided flag set, but no second sidedef\n", sizeu1(i)); } if (ld->sidenum[0] != 0xffff && ld->special) From 54fe91b1cc0e48737d74f6183f8d3a1ddaa03f36 Mon Sep 17 00:00:00 2001 From: MascaraSnake Date: Sat, 28 Dec 2019 17:21:31 +0100 Subject: [PATCH 463/746] Refactor P_SetupLines into P_InitializeLinedef --- src/p_setup.c | 160 +++++++++++++++++++++----------------------------- 1 file changed, 68 insertions(+), 92 deletions(-) diff --git a/src/p_setup.c b/src/p_setup.c index 4cb20d453..05386a96b 100644 --- a/src/p_setup.c +++ b/src/p_setup.c @@ -922,6 +922,73 @@ static void P_LoadSectors(UINT8 *data) } } +static void P_InitializeLinedef(line_t *ld) +{ + vertex_t *v1 = ld->v1; + vertex_t *v2 = ld->v2; + UINT8 j; + + ld->dx = v2->x - v1->x; + ld->dy = v2->y - v1->y; + + ld->bbox[BOXLEFT] = min(v1->x, v2->x); + ld->bbox[BOXRIGHT] = max(v1->x, v2->x); + ld->bbox[BOXBOTTOM] = min(v1->y, v2->y); + ld->bbox[BOXTOP] = max(v1->y, v2->y); + + if (!ld->dx) + ld->slopetype = ST_VERTICAL; + else if (!ld->dy) + ld->slopetype = ST_HORIZONTAL; + else if ((ld->dy > 0) == (ld->dx > 0)) + ld->slopetype = ST_POSITIVE; + else + ld->slopetype = ST_NEGATIVE; + + ld->frontsector = ld->backsector = NULL; + + ld->validcount = 0; +#ifdef WALLSPLATS + ld->splats = NULL; +#endif + ld->firsttag = ld->nexttag = -1; +#ifdef POLYOBJECTS + ld->polyobj = NULL; +#endif + + ld->text = NULL; + ld->callcount = 0; + + // cph 2006/09/30 - fix sidedef errors right away. + // cph 2002/07/20 - these errors are fatal if not fixed, so apply them + for (j = 0; j < 2; j++) + if (ld->sidenum[j] != 0xffff && ld->sidenum[j] >= (UINT16)numsides) + { + ld->sidenum[j] = 0xffff; + CONS_Debug(DBG_SETUP, "P_SetupLines: Linedef %s has out-of-range sidedef number\n", sizeu1((size_t)(ld - lines))); + } + + // killough 11/98: fix common wad errors (missing sidedefs): + if (ld->sidenum[0] == 0xffff) + { + ld->sidenum[0] = 0; // Substitute dummy sidedef for missing right side + // cph - print a warning about the bug + CONS_Debug(DBG_SETUP, "P_SetupLines: Linedef %s missing first sidedef\n", sizeu1((size_t)(ld - lines))); + } + + if ((ld->sidenum[1] == 0xffff) && (ld->flags & ML_TWOSIDED)) + { + ld->flags &= ~ML_TWOSIDED; // Clear 2s flag for missing left side + // cph - print a warning about the bug + CONS_Debug(DBG_SETUP, "P_SetupLines: Linedef %s has two-sided flag set, but no second sidedef\n", sizeu1((size_t)(ld - lines))); + } + + if (ld->sidenum[0] != 0xffff && ld->special) + sides[ld->sidenum[0]].special = ld->special; + if (ld->sidenum[1] != 0xffff && ld->special) + sides[ld->sidenum[1]].special = ld->special; +} + static void P_LoadLinedefs(UINT8 *data) { maplinedef_t *mld = (maplinedef_t *)data; @@ -938,98 +1005,8 @@ static void P_LoadLinedefs(UINT8 *data) ld->sidenum[0] = SHORT(mld->sidenum[0]); ld->sidenum[1] = SHORT(mld->sidenum[1]); - } -} -static void P_SetupLines(void) -{ - line_t *ld = lines; - size_t i; - - for (i = 0; i < numlines; i++, ld++) - { - vertex_t *v1 = ld->v1; - vertex_t *v2 = ld->v2; - -#ifdef WALLSPLATS - ld->splats = NULL; -#endif - -#ifdef POLYOBJECTS - ld->polyobj = NULL; -#endif - - ld->dx = v2->x - v1->x; - ld->dy = v2->y - v1->y; - - if (!ld->dx) - ld->slopetype = ST_VERTICAL; - else if (!ld->dy) - ld->slopetype = ST_HORIZONTAL; - else if ((ld->dy > 0) == (ld->dx > 0)) - ld->slopetype = ST_POSITIVE; - else - ld->slopetype = ST_NEGATIVE; - - if (v1->x < v2->x) - { - ld->bbox[BOXLEFT] = v1->x; - ld->bbox[BOXRIGHT] = v2->x; - } - else - { - ld->bbox[BOXLEFT] = v2->x; - ld->bbox[BOXRIGHT] = v1->x; - } - - if (v1->y < v2->y) - { - ld->bbox[BOXBOTTOM] = v1->y; - ld->bbox[BOXTOP] = v2->y; - } - else - { - ld->bbox[BOXBOTTOM] = v2->y; - ld->bbox[BOXTOP] = v1->y; - } - - { - // cph 2006/09/30 - fix sidedef errors right away. - // cph 2002/07/20 - these errors are fatal if not fixed, so apply them - UINT8 j; - - for (j=0; j < 2; j++) - if (ld->sidenum[j] != 0xffff && ld->sidenum[j] >= (UINT16)numsides) - { - ld->sidenum[j] = 0xffff; - CONS_Debug(DBG_SETUP, "P_SetupLines: Linedef %s has out-of-range sidedef number\n", sizeu1(i)); - } - } - - ld->frontsector = ld->backsector = NULL; - ld->validcount = 0; - ld->firsttag = ld->nexttag = -1; - ld->callcount = 0; - - // killough 11/98: fix common wad errors (missing sidedefs): - if (ld->sidenum[0] == 0xffff) - { - ld->sidenum[0] = 0; // Substitute dummy sidedef for missing right side - // cph - print a warning about the bug - CONS_Debug(DBG_SETUP, "P_SetupLines: Linedef %s missing first sidedef\n", sizeu1(i)); - } - - if ((ld->sidenum[1] == 0xffff) && (ld->flags & ML_TWOSIDED)) - { - ld->flags &= ~ML_TWOSIDED; // Clear 2s flag for missing left side - // cph - print a warning about the bug - CONS_Debug(DBG_SETUP, "P_SetupLines: Linedef %s has two-sided flag set, but no second sidedef\n", sizeu1(i)); - } - - if (ld->sidenum[0] != 0xffff && ld->special) - sides[ld->sidenum[0]].special = ld->special; - if (ld->sidenum[1] != 0xffff && ld->special) - sides[ld->sidenum[1]].special = ld->special; + P_InitializeLinedef(ld); } } @@ -1293,7 +1270,6 @@ static void P_LoadMapData(const virtres_t *virt) P_LoadVertices(virtvertexes->data); P_LoadSectors(virtsectors->data); P_LoadLinedefs(virtlinedefs->data); - P_SetupLines(); P_LoadSidedefs(virtsidedefs->data); P_LoadThings(virtthings->data); } From d38ee51d494142cd88e1eb99f14bf79714d9cebf Mon Sep 17 00:00:00 2001 From: MascaraSnake Date: Sat, 28 Dec 2019 17:29:58 +0100 Subject: [PATCH 464/746] Separate setting of sector field defaults into P_InitializeSector --- src/p_setup.c | 131 ++++++++++++++++++++++++++++++-------------------- 1 file changed, 78 insertions(+), 53 deletions(-) diff --git a/src/p_setup.c b/src/p_setup.c index 05386a96b..6c126b1e8 100644 --- a/src/p_setup.c +++ b/src/p_setup.c @@ -844,9 +844,86 @@ static void P_LoadVertices(UINT8 *data) { v->x = SHORT(mv->x)<y = SHORT(mv->y)<z = 0; } } +static void P_InitializeSector(sector_t *ss) +{ + ss->nexttag = ss->firsttag = -1; + + memset(&ss->soundorg, 0, sizeof(ss->soundorg)); + + ss->validcount = 0; + + ss->thinglist = NULL; + + ss->floordata = NULL; + ss->ceilingdata = NULL; + ss->lightingdata = NULL; + ss->fadecolormapdata = NULL; + + ss->floor_xoffs = ss->floor_yoffs = 0; + ss->ceiling_xoffs = ss->ceiling_yoffs = 0; + + ss->floorpic_angle = ss->ceilingpic_angle = 0; + + ss->heightsec = -1; + ss->camsec = -1; + + ss->floorlightsec = ss->ceilinglightsec = -1; + ss->crumblestate = 0; + + ss->touching_thinglist = NULL; + + ss->linecount = 0; + ss->lines = NULL; + ss->tagline = NULL; + + ss->ffloors = NULL; + ss->attached = NULL; + ss->attachedsolid = NULL; + ss->numattached = 0; + ss->maxattached = 1; + ss->lightlist = NULL; + ss->numlights = 0; + ss->moved = true; + + ss->extra_colormap = NULL; + +#ifdef HWRENDER // ----- for special tricks with HW renderer ----- + ss->pseudoSector = false; + ss->virtualFloor = false; + ss->virtualFloorheight = 0; + ss->virtualCeiling = false; + ss->virtualCeilingheight = 0; + ss->sectorLines = NULL; + ss->stackList = NULL; + ss->lineoutLength = -1.0l; +#endif // ----- end special tricks ----- + + ss->gravity = NULL; + ss->verticalflip = false; + ss->flags = SF_FLIPSPECIAL_FLOOR; + + ss->cullheight = NULL; + + ss->floorspeed = ss->ceilspeed = 0; + + ss->preciplist = NULL; + ss->touching_preciplist = NULL; + +#ifdef ESLOPE + ss->f_slope = NULL; + ss->c_slope = NULL; + ss->hasslope = false; +#endif + + ss->spawn_lightlevel = ss->lightlevel; + + ss->spawn_extra_colormap = NULL; +} + static void P_LoadSectors(UINT8 *data) { mapsector_t *ms = (mapsector_t *)data; @@ -863,62 +940,10 @@ static void P_LoadSectors(UINT8 *data) ss->ceilingpic = P_AddLevelFlat(ms->ceilingpic, foundflats); ss->lightlevel = SHORT(ms->lightlevel); - ss->spawn_lightlevel = ss->lightlevel; ss->special = SHORT(ms->special); ss->tag = SHORT(ms->tag); - ss->nexttag = ss->firsttag = -1; - memset(&ss->soundorg, 0, sizeof(ss->soundorg)); - ss->validcount = 0; - - ss->thinglist = NULL; - ss->touching_thinglist = NULL; - ss->preciplist = NULL; - ss->touching_preciplist = NULL; - - ss->floordata = NULL; - ss->ceilingdata = NULL; - ss->lightingdata = NULL; - - ss->linecount = 0; - ss->lines = NULL; - - ss->heightsec = -1; - ss->camsec = -1; - ss->floorlightsec = -1; - ss->ceilinglightsec = -1; - ss->crumblestate = 0; - ss->ffloors = NULL; - ss->lightlist = NULL; - ss->numlights = 0; - ss->attached = NULL; - ss->attachedsolid = NULL; - ss->numattached = 0; - ss->maxattached = 1; - ss->moved = true; - - ss->extra_colormap = NULL; - ss->spawn_extra_colormap = NULL; - - ss->floor_xoffs = ss->ceiling_xoffs = ss->floor_yoffs = ss->ceiling_yoffs = 0; - ss->floorpic_angle = ss->ceilingpic_angle = 0; - ss->gravity = NULL; - ss->cullheight = NULL; - ss->verticalflip = false; - ss->flags = 0; - ss->flags |= SF_FLIPSPECIAL_FLOOR; - - ss->floorspeed = 0; - ss->ceilspeed = 0; - -#ifdef HWRENDER // ----- for special tricks with HW renderer ----- - ss->pseudoSector = false; - ss->virtualFloor = false; - ss->virtualCeiling = false; - ss->sectorLines = NULL; - ss->stackList = NULL; - ss->lineoutLength = -1.0l; -#endif // ----- end special tricks ----- + P_InitializeSector(ss); } } From 7e5b87ce42b8ca45b1a5dc4835a3dc30b92743e8 Mon Sep 17 00:00:00 2001 From: MascaraSnake Date: Sat, 28 Dec 2019 17:37:32 +0100 Subject: [PATCH 465/746] Fix debug prints --- src/p_setup.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/p_setup.c b/src/p_setup.c index 6c126b1e8..ed22a56a8 100644 --- a/src/p_setup.c +++ b/src/p_setup.c @@ -990,7 +990,7 @@ static void P_InitializeLinedef(line_t *ld) if (ld->sidenum[j] != 0xffff && ld->sidenum[j] >= (UINT16)numsides) { ld->sidenum[j] = 0xffff; - CONS_Debug(DBG_SETUP, "P_SetupLines: Linedef %s has out-of-range sidedef number\n", sizeu1((size_t)(ld - lines))); + CONS_Debug(DBG_SETUP, "P_InitializeLinedef: Linedef %s has out-of-range sidedef number\n", sizeu1((size_t)(ld - lines))); } // killough 11/98: fix common wad errors (missing sidedefs): @@ -998,14 +998,14 @@ static void P_InitializeLinedef(line_t *ld) { ld->sidenum[0] = 0; // Substitute dummy sidedef for missing right side // cph - print a warning about the bug - CONS_Debug(DBG_SETUP, "P_SetupLines: Linedef %s missing first sidedef\n", sizeu1((size_t)(ld - lines))); + CONS_Debug(DBG_SETUP, "P_InitializeLinedef: Linedef %s missing first sidedef\n", sizeu1((size_t)(ld - lines))); } if ((ld->sidenum[1] == 0xffff) && (ld->flags & ML_TWOSIDED)) { ld->flags &= ~ML_TWOSIDED; // Clear 2s flag for missing left side // cph - print a warning about the bug - CONS_Debug(DBG_SETUP, "P_SetupLines: Linedef %s has two-sided flag set, but no second sidedef\n", sizeu1((size_t)(ld - lines))); + CONS_Debug(DBG_SETUP, "P_InitializeLinedef: Linedef %s has two-sided flag set, but no second sidedef\n", sizeu1((size_t)(ld - lines))); } if (ld->sidenum[0] != 0xffff && ld->special) @@ -1052,7 +1052,7 @@ static void P_LoadSidedefs(UINT8 *data) sector_num = SHORT(msd->sector); if (sector_num >= numsectors) { - CONS_Debug(DBG_SETUP, "P_LoadSidedefs: sidedef %u has out-of-range sector num %u\n", i, sector_num); + CONS_Debug(DBG_SETUP, "P_LoadSidedefs: sidedef %s has out-of-range sector num %u\n", sizeu1(i), sector_num); sector_num = 0; } sd->sector = §ors[sector_num]; From bd7765227eebc29c03c9218bb4832c5af02d07b7 Mon Sep 17 00:00:00 2001 From: MascaraSnake Date: Sat, 28 Dec 2019 17:40:08 +0100 Subject: [PATCH 466/746] Rename P_GroupLines to the more apt P_LinkMapData --- src/p_setup.c | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/src/p_setup.c b/src/p_setup.c index ed22a56a8..8d92c3e87 100644 --- a/src/p_setup.c +++ b/src/p_setup.c @@ -1909,11 +1909,11 @@ static void P_CompressSidedefs(void) } // -// P_GroupLines +// P_LinkMapData // Builds sector line lists and subsector sector numbers. // Finds block bounding boxes for sectors. // -static void P_GroupLines(void) +static void P_LinkMapData(void) { size_t i, j; line_t *li; @@ -1927,20 +1927,20 @@ static void P_GroupLines(void) for (i = 0; i < numsubsectors; i++, ss++) { if (ss->firstline >= numsegs) - CorruptMapError(va("P_GroupLines: ss->firstline invalid " + CorruptMapError(va("P_LinkMapData: ss->firstline invalid " "(subsector %s, firstline refers to %d of %s)", sizeu1(i), ss->firstline, sizeu2(numsegs))); seg = &segs[ss->firstline]; sidei = (size_t)(seg->sidedef - sides); if (!seg->sidedef) - CorruptMapError(va("P_GroupLines: seg->sidedef is NULL " + CorruptMapError(va("P_LinkMapData: seg->sidedef is NULL " "(subsector %s, firstline is %d)", sizeu1(i), ss->firstline)); if (seg->sidedef - sides < 0 || seg->sidedef - sides > (UINT16)numsides) - CorruptMapError(va("P_GroupLines: seg->sidedef refers to sidedef %s of %s " + CorruptMapError(va("P_LinkMapData: seg->sidedef refers to sidedef %s of %s " "(subsector %s, firstline is %d)", sizeu1(sidei), sizeu2(numsides), sizeu3(i), ss->firstline)); if (!seg->sidedef->sector) - CorruptMapError(va("P_GroupLines: seg->sidedef->sector is NULL " + CorruptMapError(va("P_LinkMapData: seg->sidedef->sector is NULL " "(subsector %s, firstline is %d, sidedef is %s)", sizeu1(i), ss->firstline, sizeu1(sidei))); ss->sector = seg->sidedef->sector; @@ -1961,7 +1961,7 @@ static void P_GroupLines(void) if (sector->linecount == 0) // no lines found? { sector->lines = NULL; - CONS_Debug(DBG_SETUP, "P_GroupLines: sector %s has no lines\n", sizeu1(i)); + CONS_Debug(DBG_SETUP, "P_LinkMapData: sector %s has no lines\n", sizeu1(i)); } else { @@ -2068,7 +2068,7 @@ static void P_LoadMapFromFile(void) P_ProcessLinedefsWithSidedefs(); if (M_CheckParm("-compress")) P_CompressSidedefs(); - P_GroupLines(); + P_LinkMapData(); P_MakeMapMD5(virt, &mapmd5); From 5ed1dc5410158fc3086797d7dada645c7c1de4e5 Mon Sep 17 00:00:00 2001 From: lachwright Date: Sun, 29 Dec 2019 03:01:09 +0800 Subject: [PATCH 467/746] Remove MF_NOTHINK from join-breaking referenced objects --- src/info.c | 8 ++++---- src/p_enemy.c | 2 +- src/p_mobj.c | 2 +- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/src/info.c b/src/info.c index dd808349e..30f3e96d0 100644 --- a/src/info.c +++ b/src/info.c @@ -4492,7 +4492,7 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] = 0, // mass 0, // damage sfx_None, // activesound - MF_NOTHINK|MF_NOBLOCKMAP|MF_NOCLIP|MF_NOCLIPHEIGHT|MF_NOGRAVITY, // flags + MF_SCENERY|MF_NOBLOCKMAP|MF_NOCLIP|MF_NOCLIPHEIGHT|MF_NOGRAVITY, // flags S_NULL // raisestate }, @@ -6273,7 +6273,7 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] = 0, // mass 0, // damage sfx_None, // activesound - MF_NOGRAVITY|MF_NOBLOCKMAP|MF_NOTHINK, // flags + MF_NOGRAVITY|MF_NOBLOCKMAP|MF_SCENERY, // flags S_NULL // raisestate }, @@ -11992,7 +11992,7 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] = 100, // mass 0, // damage sfx_None, // activesound - MF_NOTHINK|MF_NOBLOCKMAP|MF_NOCLIP|MF_NOCLIPHEIGHT|MF_NOGRAVITY|MF_SCENERY, // flags + MF_NOBLOCKMAP|MF_NOCLIP|MF_NOCLIPHEIGHT|MF_NOGRAVITY|MF_SCENERY, // flags S_NULL // raisestate }, @@ -12019,7 +12019,7 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] = 100, // mass 0, // damage sfx_None, // activesound - MF_NOTHINK|MF_NOBLOCKMAP|MF_NOCLIP|MF_NOCLIPHEIGHT|MF_NOGRAVITY|MF_SCENERY, // flags + MF_NOBLOCKMAP|MF_NOCLIP|MF_NOCLIPHEIGHT|MF_NOGRAVITY|MF_SCENERY, // flags S_NULL // raisestate }, diff --git a/src/p_enemy.c b/src/p_enemy.c index f15ad86ae..31c1f76c7 100644 --- a/src/p_enemy.c +++ b/src/p_enemy.c @@ -2261,7 +2261,7 @@ void A_CrushclawLaunch(mobj_t *actor) while (chain) { P_TeleportMove(chain, actor->target->x + idx, actor->target->y + idy, actor->target->z + idz); - chain->watertop = chain->z; + chain->movefactor = chain->z; idx += dx; idy += dy; idz += dz; diff --git a/src/p_mobj.c b/src/p_mobj.c index 75bc174a5..8880e5827 100644 --- a/src/p_mobj.c +++ b/src/p_mobj.c @@ -9434,7 +9434,7 @@ static boolean P_MobjRegularThink(mobj_t *mobj) SINT8 sign = ((mobj->tics & 1) ? mobj->tics : -(SINT8)(mobj->tics)); while (chain) { - chain->z = chain->watertop + sign*mobj->scale; + chain->z = chain->movefactor + sign*mobj->scale; sign = -sign; chain = chain->target; } From 4b604328d56af04201c1e3edfef9147705bf041c Mon Sep 17 00:00:00 2001 From: Jaime Passos Date: Sat, 28 Dec 2019 19:47:03 -0300 Subject: [PATCH 468/746] 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 45af6d889906401067abe72fc73ae338934995ab Mon Sep 17 00:00:00 2001 From: Jaime Passos Date: Sat, 28 Dec 2019 19:49:34 -0300 Subject: [PATCH 469/746] 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 093a1baf1d134ddac3fec5724552dc75f9390cb1 Mon Sep 17 00:00:00 2001 From: Jaime Passos Date: Sat, 28 Dec 2019 19:50:14 -0300 Subject: [PATCH 470/746] 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 7a00b3a331d86a06c6a27999999623c1308bc088 Mon Sep 17 00:00:00 2001 From: Jaime Passos Date: Sat, 28 Dec 2019 19:56:18 -0300 Subject: [PATCH 471/746] 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 ae0acfba0feeba6aaed4dd1ca247c0e9a3bd2774 Mon Sep 17 00:00:00 2001 From: Jaime Passos Date: Sat, 28 Dec 2019 20:18:21 -0300 Subject: [PATCH 472/746] 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 216657192002bcfc74de14b1251ff52f25b8b3b1 Mon Sep 17 00:00:00 2001 From: Jaime Passos Date: Sat, 28 Dec 2019 20:33:28 -0300 Subject: [PATCH 473/746] 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 745cced08e560475da66795bc119b65f4128a60a Mon Sep 17 00:00:00 2001 From: Zachary McAlpin Date: Sat, 28 Dec 2019 17:40:47 -0600 Subject: [PATCH 474/746] Execute LUAh_PlayerThink(player) at the end if the player has a valid mobj_t object --- src/p_user.c | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/src/p_user.c b/src/p_user.c index 1c9d1c051..b26615b46 100644 --- a/src/p_user.c +++ b/src/p_user.c @@ -11700,12 +11700,13 @@ void P_PlayerThink(player_t *player) P_MovePlayer(player); } -#ifdef HAVE_BLUA - LUAh_PlayerThink(player); -#endif - if (!player->mo) + { +#ifdef HAVE_BLUA + LUAh_PlayerThink(player); +#endif return; // P_MovePlayer removed player->mo. + } // deez New User eXperiences. { @@ -12137,6 +12138,11 @@ void P_PlayerThink(player_t *player) dashmode = 0; } #undef dashmode + +#ifdef HAVE_BLUA + LUAh_PlayerThink(player); +#endif + /* // Colormap verification { From 5b1b5569469e0cf30ae9297342e6f873217dcc89 Mon Sep 17 00:00:00 2001 From: Jaime Passos Date: Sat, 28 Dec 2019 20:54:22 -0300 Subject: [PATCH 475/746] 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 dede51fc4c86343efb031ec67e6e09def5fb0fd6 Mon Sep 17 00:00:00 2001 From: Jaime Passos Date: Sat, 28 Dec 2019 21:05:42 -0300 Subject: [PATCH 476/746] 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 3bb7fd4cbf2bb92f5548cafad00b80cb366395a4 Mon Sep 17 00:00:00 2001 From: Jaime Passos Date: Sat, 28 Dec 2019 22:14:23 -0300 Subject: [PATCH 477/746] Fix logfiles crashing Windoze --- src/sdl/i_main.c | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/src/sdl/i_main.c b/src/sdl/i_main.c index 5d0009927..8a4fa06b5 100644 --- a/src/sdl/i_main.c +++ b/src/sdl/i_main.c @@ -197,9 +197,12 @@ int main(int argc, char **argv) format, timeinfo); } - M_MkdirEachUntil(logfilename, - M_PathParts(logdir) - 1, - M_PathParts(logfilename) - 1, 0755); + if (logdir) + { + M_MkdirEachUntil(logfilename, + M_PathParts(logdir) - 1, + M_PathParts(logfilename) - 1, 0755); + } #ifdef __unix__ logstream = fopen(logfilename, "w"); From 244f0b228fefb69fb59c1f7f70d4815c0388a634 Mon Sep 17 00:00:00 2001 From: Jaime Passos Date: Sat, 28 Dec 2019 22:18:41 -0300 Subject: [PATCH 478/746] Fix M_PathParts instead --- src/m_misc.c | 2 ++ src/sdl/i_main.c | 9 +++------ 2 files changed, 5 insertions(+), 6 deletions(-) diff --git a/src/m_misc.c b/src/m_misc.c index 5f75aae92..83c0c7bec 100644 --- a/src/m_misc.c +++ b/src/m_misc.c @@ -2457,6 +2457,8 @@ int M_PathParts(const char *path) int n; const char *p; const char *t; + if (path == NULL) + return 0; for (n = 0, p = path ;; ++n) { t = p; diff --git a/src/sdl/i_main.c b/src/sdl/i_main.c index 8a4fa06b5..5d0009927 100644 --- a/src/sdl/i_main.c +++ b/src/sdl/i_main.c @@ -197,12 +197,9 @@ int main(int argc, char **argv) format, timeinfo); } - if (logdir) - { - M_MkdirEachUntil(logfilename, - M_PathParts(logdir) - 1, - M_PathParts(logfilename) - 1, 0755); - } + M_MkdirEachUntil(logfilename, + M_PathParts(logdir) - 1, + M_PathParts(logfilename) - 1, 0755); #ifdef __unix__ logstream = fopen(logfilename, "w"); From 0237dc8ca27569616cc06eb8d085cf1735654231 Mon Sep 17 00:00:00 2001 From: James R Date: Sat, 28 Dec 2019 17:52:22 -0800 Subject: [PATCH 479/746] Add MFE_TOUCHLAVA and MFE_TRACERANGLE to Lua and SOC --- src/dehacked.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/dehacked.c b/src/dehacked.c index b77939c2a..4c90211cc 100644 --- a/src/dehacked.c +++ b/src/dehacked.c @@ -8824,9 +8824,11 @@ static const char *const MOBJEFLAG_LIST[] = { "JUSTSTEPPEDDOWN", // used for ramp sectors "VERTICALFLIP", // Vertically flip sprite/allow upside-down physics "GOOWATER", // Goo water + "TOUCHLAVA", // The mobj is touching a lava block "PUSHED", // Mobj was already pushed this tic "SPRUNG", // Mobj was already sprung this tic "APPLYPMOMZ", // Platform movement + "TRACERANGLE", // Compute and trigger on mobj angle relative to tracer NULL }; From f997866b4d3f9d2f4c6177e708529657359520d2 Mon Sep 17 00:00:00 2001 From: Jaime Passos Date: Sat, 28 Dec 2019 22:57:37 -0300 Subject: [PATCH 480/746] 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 2acb4f9840bce85ac49b0e96485d8b30c1d6dde1 Mon Sep 17 00:00:00 2001 From: Alam Ed Arias Date: Sat, 28 Dec 2019 21:43:10 -0500 Subject: [PATCH 481/746] Revert "Delete the original configuration file." This reverts commit 2cf94ea6aec88827d77e106aa53303276f2398a8. --- extras/conf/SRB2-22.cfg | 6521 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 6521 insertions(+) create mode 100644 extras/conf/SRB2-22.cfg diff --git a/extras/conf/SRB2-22.cfg b/extras/conf/SRB2-22.cfg new file mode 100644 index 000000000..5bc48211c --- /dev/null +++ b/extras/conf/SRB2-22.cfg @@ -0,0 +1,6521 @@ +/*********************************************************\ + Zone Builder Game Configuration + For Sonic Robo Blast 2 Version 2.2 + Contributors (alphabetical): + * Foxboy + * FuriousFox + * JJames19119 + * Kalaron + * Kristos + * MascaraSnake + * mazmazz + * Morpheus + * Neo Chaotikal + * Nev3r + * Oogaland + * Rob + * Shadow Hog + * Spherallic + * SRB2-Playah + * SSNTails + * SteelT + * ST218 + * toaster + * Viola +\*********************************************************/ + +// This is required to prevent accidental use of a different configuration +type = "Doom Builder 2 Game Configuration"; + +// This is the title to show for this game +game = "Sonic Robo Blast 2 - 2.2"; + +//GZDB specific. Don't try to load lumps that don't exist. +basegame = 0; + +// This is the simplified game engine/sourceport name +engine = "zdoom"; + +// When this is set to true, sectors with the same tag will light up when a line is highlighted +linetagindicatesectors = true; + +// The format interface handles the map data format - DoomMapSetIO for SRB2DB2, SRB2MapSetIO for Zone Builder +formatinterface = "SRB2MapSetIO"; + +//Sky textures for vanilla maps +defaultskytextures +{ + SKY1 = "MAP01,MAP02,MAP03,MAP33,MAP50,MAP60,MAPF0,MAPM0"; + SKY2 = "MAPM7,MAPMB"; + SKY4 = "MAP04,MAP06,MAP61,MAPF6,MAPM1"; + SKY6 = "MAP05,MAP51,MAPMA"; + SKY7 = "MAPM2,MAPM5"; + SKY8 = "MAP07,MAP08,MAP09,MAP52,MAP62,MAPF1"; + SKY10 = "MAP10,MAP12,MAP53,MAP63,MAPM3"; + SKY11 = "MAP11,MAPF7"; + SKY13 = "MAP13,MAP64"; + SKY14 = "MAP14"; + SKY15 = "MAP15,MAP54"; + SKY17 = "MAP70"; + SKY20 = "MAP32,MAP55,MAP65,MAPF2,MAPF5"; + SKY21 = "MAPM4"; + SKY22 = "MAP22,MAP23,MAP25,MAP26,MAP27,MAP56,MAP66,MAPF4,MAPM6"; + SKY30 = "MAP30"; + SKY31 = "MAP31"; + SKY35 = "MAP42"; + SKY40 = "MAP41,MAP71,MAPM9"; + SKY55 = "MAPF3,MAPM8"; + SKY68 = "MAPF8"; + SKY99 = "MAP57,MAPZ0"; + SKY159 = "MAP16"; + SKY172 = "MAP40"; + SKY300 = "MAP72"; + SKY301 = "MAP73"; +} + +// Default lump name for new map +defaultlumpname = "MAP01"; + +// Default testing parameters +testparameters = "-file \"%AP\" \"%F\" -warp %L"; +testshortpaths = true; + +// Default nodebuilder configurations +defaultsavecompiler = "zennode_normal"; +defaulttestcompiler = "zennode_fast"; + +// Skill levels +skills +{ + 1 = "Normal"; +} + +// Skins +skins +{ + Sonic; + Tails; + Knuckles; + Amy; + Fang; + Metalsonic; +} + +// Gametypes +gametypes +{ + -1 = "Single Player"; + 0 = "Co-op"; + 1 = "Competition"; + 2 = "Race"; + 3 = "Match"; + 4 = "Team Match"; + 5 = "Tag"; + 6 = "Hide and Seek"; + 7 = "CTF"; +} + +// Special linedefs +soundlinedefflag = 64; // See linedefflags +singlesidedflag = 1; // See linedefflags +doublesidedflag = 4; // See linedefflags +impassableflag = 1; +upperunpeggedflag = 8; +lowerunpeggedflag = 16; +repeatmidtextureflag = 1024; +pegmidtextureflag = 256; + +// Generalized actions +generalizedlinedefs = false; +generalizedsectors = true; + +// Texture loading options +defaultwalltexture = "GFZROCK"; +defaultfloortexture = "GFZFLR01"; +defaultceilingtexture = "F_SKY1"; +mixtexturesflats = true; +defaulttexturescale = 1.0f; +defaultflatscale = 1.0f; + +// Thing number for start position in 3D Mode +start3dmode = 3328; + + + + +/* +TEXTURES AND FLAT SOURCES +This tells Doom Builder where to find the information for textures +and flats in the IWAD file, Addition WAD file and Map WAD file. + +Start and end lumps must be given in a structure (of which the +key name doesnt matter) and any textures or flats in between them +are loaded in either the textures category or flats category. + +For textures: PNAMES, TEXTURE1 and TEXTURE2 are loaded by default. +Kalaron: and now TX_START +*/ + +// Texture sources +textures +{ + zdoom1 + { + start = "TX_START"; + end = "TX_END"; + } +} + +// Patch sources +patches +{ + standard1 + { + start = "P_START"; + end = "P_END"; + } + + standard2 + { + start = "PP_START"; + end = "PP_END"; + } +} + +// Sprite sources +sprites +{ + standard1 + { + start = "S_START"; + end = "S_END"; + } + + standard2 + { + start = "SS_START"; + end = "SS_END"; + } +} + +// Flat sources +flats +{ + standard1 + { + start = "F_START"; + end = "F_END"; + } + + standard2 + { + start = "FF_START"; + end = "FF_END"; + } + + standard3 + { + start = "FF_START"; + end = "F_END"; + } + + standard4 + { + start = "F_START"; + end = "FF_END"; + } +} + + +/* +GAME DETECT PATTERN +Used to guess the game for which a WAD file is made. + +1 = One of these lumps must exist +2 = None of these lumps must exist +3 = All of these lumps must exist +*/ + +gamedetect +{ + EXTENDED = 2; + + + BEHAVIOR = 2; + + E#M# = 2; + + MAP?? = 1; +} + + +/* +MAP LUMP NAMES +Map lumps are loaded with the map as long as they are right after each other. When the editor +meets a lump which is not defined in this list it will ignore the map if not satisfied. +The order of items defines the order in which lumps will be written to WAD file on save. +To indicate the map header lump, use ~MAP + +Legenda: +required = Lump is required to exist. +blindcopy = Lump will be copied along with the map blindly. (usefull for lumps Doom Builder doesn't use) +nodebuild = The nodebuilder generates this lump. +allowempty = The nodebuilder is allowed to leave this lump empty. +script = This lump is a text-based script. Specify the filename of the script configuration to use. +*/ + +maplumpnames +{ + ~MAP + { + required = true; + blindcopy = true; + nodebuild = false; + } + + THINGS + { + required = true; + nodebuild = true; + allowempty = true; + } + + LINEDEFS + { + required = true; + nodebuild = true; + allowempty = false; + } + + SIDEDEFS + { + required = true; + nodebuild = true; + allowempty = false; + } + + VERTEXES + { + required = true; + nodebuild = true; + allowempty = false; + } + + SEGS + { + required = false; + nodebuild = true; + allowempty = false; + } + + SSECTORS + { + required = false; + nodebuild = true; + allowempty = false; + } + + NODES + { + required = false; + nodebuild = true; + allowempty = false; + } + + SECTORS + { + required = true; + nodebuild = true; + allowempty = false; + } + + REJECT + { + required = false; + nodebuild = true; + allowempty = false; + } + + BLOCKMAP + { + required = false; + nodebuild = true; + allowempty = true; + } +} + +scriptlumpnames +{ + MAINCFG + { + script = "SOC.cfg"; + } + + OBJCTCFG + { + script = "SOC.cfg"; + } + + SOC_ + { + script = "SOC.cfg"; + isprefix = true; + } + + LUA_ + { + script = "Lua.cfg"; + isprefix = true; + } +} + +// DEFAULT SECTOR BRIGHTNESS LEVELS +sectorbrightness +{ + 255; + 248; + 240; + 232; + 224; + 216; + 208; + 200; + 192; + 184; + 176; + 168; + 160; + 152; + 144; + 136; + 128; + 120; + 112; + 104; + 96; + 88; + 80; + 72; + 64; + 56; + 48; + 40; + 32; + 24; + 16; + 8; + 0; +} + +// SECTOR TYPES----------------------------------------------------------------- +sectortypes +{ + 0 = "Normal"; + 1 = "Damage"; + 2 = "Damage (Water)"; + 3 = "Damage (Fire)"; + 4 = "Damage (Electrical)"; + 5 = "Spikes"; + 6 = "Death Pit (Camera Tilt)"; + 7 = "Death Pit (No Camera Tilt)"; + 8 = "Instant Kill"; + 9 = "Ring Drainer (Floor Touch)"; + 10 = "Ring Drainer (Anywhere in Sector)"; + 11 = "Special Stage Damage"; + 12 = "Space Countdown"; + 13 = "Ramp Sector (double step-up/down)"; + 14 = "Non-Ramp Sector (no step-down)"; + 15 = "Bouncy FOF"; + 16 = "Trigger Line Ex. (Pushable Objects)"; + 32 = "Trigger Line Ex. (Anywhere, All Players)"; + 48 = "Trigger Line Ex. (Floor Touch, All Players)"; + 64 = "Trigger Line Ex. (Anywhere in Sector)"; + 80 = "Trigger Line Ex. (Floor Touch)"; + 96 = "Trigger Line Ex. (Emerald Check)"; + 112 = "Trigger Line Ex. (NiGHTS Mare)"; + 128 = "Check for Linedef Executor on FOFs"; + 144 = "Egg Capsule"; + 160 = "Special Stage Time/Rings Parameters"; + 176 = "Custom Global Gravity"; + 512 = "Wind/Current"; + 1024 = "Conveyor Belt"; + 1280 = "Speed Pad"; + 4096 = "Star Post Activator"; + 8192 = "Exit/Special Stage Pit/Return Flag"; + 12288 = "CTF Red Team Base"; + 16384 = "CTF Blue Team Base"; + 20480 = "Fan Sector"; + 24576 = "Super Sonic Transform"; + 28672 = "Force Spin"; + 32768 = "Zoom Tube Start"; + 36864 = "Zoom Tube End"; + 40960 = "Circuit Finish Line"; + 45056 = "Rope Hang"; + 49152 = "Intangible to the Camera"; +} + + +// GENERALISED SECTOR TYPES----------------------------------------------------------------- +gen_sectortypes +{ + first + { + 0 = "Normal"; + 1 = "Damage"; + 2 = "Damage (Water)"; + 3 = "Damage (Fire)"; + 4 = "Damage (Electrical)"; + 5 = "Spikes"; + 6 = "Death Pit (Camera Tilt)"; + 7 = "Death Pit (No Camera Tilt)"; + 8 = "Instant Kill"; + 9 = "Ring Drainer (Floor Touch)"; + 10 = "Ring Drainer (Anywhere in Sector)"; + 11 = "Special Stage Damage"; + 12 = "Space Countdown"; + 13 = "Ramp Sector (double step-up/down)"; + 14 = "Non-Ramp Sector (no step-down)"; + 15 = "Bouncy FOF"; + } + + second + { + 0 = "Normal"; + 16 = "Trigger Line Ex. (Pushable Objects)"; + 32 = "Trigger Line Ex. (Anywhere, All Players)"; + 48 = "Trigger Line Ex. (Floor Touch, All Players)"; + 64 = "Trigger Line Ex. (Anywhere in Sector)"; + 80 = "Trigger Line Ex. (Floor Touch)"; + 96 = "Trigger Line Ex. (Emerald Check)"; + 112 = "Trigger Line Ex. (NiGHTS Mare)"; + 128 = "Check for Linedef Executor on FOFs"; + 144 = "Egg Capsule"; + 160 = "Special Stage Time/Rings Parameters"; + 176 = "Custom Global Gravity"; + } + + third + { + 0 = "Normal"; + 512 = "Wind/Current"; + 1024 = "Conveyor Belt"; + 1280 = "Speed Pad"; + } + + fourth + { + 0 = "Normal"; + 4096 = "Star Post Activator"; + 8192 = "Exit/Special Stage Pit/Return Flag"; + 12288 = "CTF Red Team Base"; + 16384 = "CTF Blue Team Base"; + 20480 = "Fan Sector"; + 24576 = "Super Sonic Transform"; + 28672 = "Force Spin"; + 32768 = "Zoom Tube Start"; + 36864 = "Zoom Tube End"; + 40960 = "Circuit Finish Line"; + 45056 = "Rope Hang"; + 49152 = "Intangible to the Camera"; + } +} + +// LINEDEF FLAGS +linedefflags +{ + 1 = "[0] Impassable"; + 2 = "[1] Block Enemies"; + 4 = "[2] Double-Sided"; + 8 = "[3] Upper Unpegged"; + 16 = "[4] Lower Unpegged"; + 32 = "[5] Slope Skew (E1)"; + 64 = "[6] Not Climbable"; + 128 = "[7] No Midtexture Skew (E2)"; + 256 = "[8] Peg Midtexture (E3)"; + 512 = "[9] Solid Midtexture (E4)"; + 1024 = "[10] Repeat Midtexture (E5)"; + 2048 = "[11] Netgame Only"; + 4096 = "[12] No Netgame"; + 8192 = "[13] Effect 6"; + 16384 = "[14] Bouncy Wall"; + 32768 = "[15] Transfer Line"; +} + +// Linedef flags UDMF translation table +// This is needed for copy/paste and prefabs to work properly +// When the UDMF field name is prefixed with ! it is inverted +linedefflagstranslation +{ + 1 = "blocking"; + 2 = "blockmonsters"; + 4 = "twosided"; + 8 = "dontpegtop"; + 16 = "dontpegbottom"; + 32 = "secret"; + 64 = "blocksound"; + 128 = "dontdraw"; + 256 = "mapped"; +} + +// LINEDEF ACTIVATIONS +linedefactivations +{ +} + +// LINEDEF TYPES +linedeftypes +{ + misc + { + title = "Miscellaneous"; + + 0 + { + title = "None"; + prefix = "(0)"; + } + + 1 + { + title = "Per-Sector Gravity"; + prefix = "(1)"; + flags64text = "[6] Flip in reverse gravity"; + } + + 5 + { + title = "Camera Scanner"; + prefix = "(5)"; + } + + 7 + { + title = "Sector Flat Alignment"; + prefix = "(7)"; + flags2048text = "[11] Don't align floor"; + flags4096text = "[12] Don't align ceiling"; + flags8192text = "[13] Use texture offsets"; + } + + 10 + { + title = "Culling Plane"; + prefix = "(10)"; + flags64text = "[6] Cull only while in sector"; + } + + 13 + { + title = "Heat Wave Effect"; + prefix = "(13)"; + } + + 40 + { + title = "Visual Portal Between Tagged Linedefs"; + prefix = "(40)"; + } + + 41 + { + title = "Horizon Effect"; + prefix = "(41)"; + } + + 50 + { + title = "Instantly Lower Floor on Level Load"; + prefix = "(50)"; + } + + 51 + { + title = "Instantly Raise Ceiling on Level Load"; + prefix = "(51)"; + } + + 63 + { + title = "Fake Floor/Ceiling Planes"; + prefix = "(63)"; + } + + 540 + { + title = "Floor Friction"; + prefix = "(540)"; + } + } + + parameters + { + title = "Parameters"; + + 2 + { + title = "Custom Exit"; + prefix = "(2)"; + flags2text = "[1] Check emeralds"; + flags64text = "[6] Skip score tally"; + } + + 3 + { + title = "Zoom Tube Parameters"; + prefix = "(3)"; + flags512text = "[9] Ignore player direction"; + } + + 4 + { + title = "Speed Pad Parameters"; + prefix = "(4)"; + flags512text = "[9] No teleport to center"; + flags1024text = "[10] Force spinning frames"; + } + + 8 + { + title = "Special Sector Properties"; + prefix = "(8)"; + flags32text = "[5] Invert precipitation"; + flags64text = "[6] Touch only ceiling"; + flags128text = "[7] Allow opposite gravity"; + flags256text = "[8] Touch sector edge"; + flags512text = "[9] Touch floor or ceiling"; + } + + 9 + { + title = "Chain Parameters"; + prefix = "(9)"; + flags32text = "[5] Swing instead of spin"; + flags64text = "[6] Player-turnable chain"; + flags128text = "[7] Make chain from maces"; + flags256text = "[8] Spawn mace at origin"; + flags512text = "[9] Don't clip inside ground"; + flags1024text = "[10] No distance check"; + } + + 11 + { + title = "Rope Hang Parameters"; + prefix = "(11)"; + flags32text = "[5] Don't loop"; + flags64text = "[6] Static"; + } + + 12 + { + title = "Rock Spawner Parameters"; + prefix = "(12)"; + flags64text = "[6] Randomize speed"; + } + + 14 + { + title = "Bustable Block Parameters"; + prefix = "(14)"; + flags32text = "[5] Particles launch from center"; + } + + 15 + { + title = "Fan Particle Spawner Parameters"; + prefix = "(15)"; + } + + 16 + { + title = "Minecart Parameters"; + prefix = "(16)"; + } + + 64 + { + title = "Continuously Appearing/Disappearing FOF"; + prefix = "(64)"; + flags2text = "[1] Use control sector tag"; + flags64text = "[6] No sound effect"; + } + + 65 + { + title = "Bridge Thinker "; + prefix = "(65)"; + } + } + + polyobject + { + title = "PolyObject"; + + 20 + { + title = "First Line"; + prefix = "(20)"; + } + + 21 + { + title = "Explicitly Include Line "; + prefix = "(21)"; + } + + 22 + { + title = "Parameters"; + prefix = "(22)"; + flags64text = "[6] Trigger linedef executor"; + flags128text = "[7] Intangible"; + flags256text = "[8] Stopped by pushables"; + flags512text = "[9] Render flats"; + } + + 30 + { + title = "Waving Flag"; + prefix = "(30)"; + } + + 31 + { + title = "Displacement by Front Sector"; + prefix = "(31)"; + } + + 32 + { + title = "Angular Displacement by Front Sector"; + prefix = "(32)"; + flags8text = "[3] Set delay by backside sector"; + flags64text = "[6] Don't turn players"; + flags512text = "[9] Turn all objects"; + } + } + + planemove + { + title = "Plane Movement"; + + 52 + { + title = "Continuously Falling Sector"; + prefix = "(52)"; + flags64text = "[6] Continuously rising"; + } + + 53 + { + title = "Continuous Floor/Ceiling Mover"; + prefix = "(53)"; + } + + 54 + { + title = "Continuous Floor Mover"; + prefix = "(54)"; + } + + 55 + { + title = "Continuous Ceiling Mover"; + prefix = "(55)"; + } + + 56 + { + title = "Continuous Two-Speed Floor/Ceiling Mover"; + prefix = "(56)"; + } + + 57 + { + title = "Continuous Two-Speed Floor Mover"; + prefix = "(57)"; + } + + 58 + { + title = "Continuous Two-Speed Ceiling Mover"; + prefix = "(58)"; + } + + 59 + { + title = "Activate Moving Platform"; + prefix = "(59)"; + flags64text = "[6] Move upwards at start"; + } + + 60 + { + title = "Activate Moving Platform (Adjustable Speed)"; + prefix = "(60)"; + flags64text = "[6] Move upwards at start"; + } + + 61 + { + title = "Crusher (Ceiling to Floor)"; + prefix = "(61)"; + flags512text = "[9] Double, constant speed"; + } + + 62 + { + title = "Crusher (Floor to Ceiling)"; + prefix = "(62)"; + flags512text = "[9] Double, constant speed"; + } + + 66 + { + title = "Move Floor by Displacement"; + prefix = "(66)"; + flags64text = "[6] Inverse movement"; + } + + 67 + { + title = "Move Ceiling by Displacement"; + prefix = "(67)"; + flags64text = "[6] Inverse movement"; + } + + 68 + { + title = "Move Floor and Ceiling by Displacement"; + prefix = "(68)"; + flags64text = "[6] Inverse movement"; + } + } + + fofsolid + { + title = "FOF (solid)"; + + 100 + { + title = "Solid, Opaque"; + prefix = "(100)"; + flags8text = "[3] Slope skew sides"; + flags32text = "[5] Only block player"; + flags128text = "[7] Only block non-players"; + 3dfloor = true; + 3dfloorflags = "19F"; + } + + 101 + { + title = "Solid, Opaque, No Shadow"; + prefix = "(101)"; + flags8text = "[3] Slope skew sides"; + flags32text = "[5] Only block player"; + flags128text = "[7] Only block non-players"; + 3dfloor = true; + 3dfloorflags = "1DF"; + } + + 102 + { + title = "Solid, Translucent"; + prefix = "(102)"; + flags8text = "[3] Slope skew sides"; + flags32text = "[5] Only block player"; + flags64text = "[6] Render insides"; + flags128text = "[7] Only block non-players"; + 3dfloor = true; + 3dfloorflags = "195F"; + flags643dfloorflagsadd = "7C80"; + } + + 103 + { + title = "Solid, Sides Only"; + prefix = "(103)"; + flags8text = "[3] Slope skew sides"; + flags32text = "[5] Only block player"; + flags128text = "[7] Only block non-players"; + 3dfloor = true; + 3dfloorflags = "1CF"; + } + + 104 + { + title = "Solid, No Sides"; + prefix = "(104)"; + flags32text = "[5] Only block player"; + flags64text = "[6] Cast shadow"; + flags128text = "[7] Only block non-players"; + 3dfloor = true; + 3dfloorflags = "1D7"; + flags643dfloorflagsremove = "40"; + } + + 105 + { + title = "Solid, Invisible"; + prefix = "(105)"; + flags32text = "[5] Only block player"; + flags128text = "[7] Only block non-players"; + 3dfloor = true; + 3dfloorflags = "47"; + } + + 140 + { + title = "Intangible from Bottom, Opaque"; + prefix = "(140)"; + flags8text = "[3] Slope skew sides"; + flags32text = "[5] Only block player"; + flags64text = "[6] Don't cast shadow"; + flags128text = "[7] Only block non-players"; + 3dfloor = true; + 3dfloorflags = "200841F"; + flags643dfloorflagsadd = "40"; + } + + 141 + { + title = "Intangible from Bottom, Translucent"; + prefix = "(141)"; + flags8text = "[3] Slope skew sides"; + flags32text = "[5] Only block player"; + flags64text = "[6] Don't cast shadow"; + flags128text = "[7] Render insides/block non-plr"; + 3dfloor = true; + 3dfloorflags = "200191F"; + flags1283dfloorflagsadd = "7C80"; + flags643dfloorflagsadd = "40"; + } + + 142 + { + title = "Intangible from Bottom, Translucent, No Sides"; + prefix = "(142)"; + flags32text = "[5] Only block player"; + flags64text = "[6] Don't cast shadow"; + flags128text = "[7] Render insides/block non-plr"; + 3dfloor = true; + 3dfloorflags = "2001917"; + flags1283dfloorflagsadd = "7C80"; + flags643dfloorflagsadd = "40"; + } + + 143 + { + title = "Intangible from Top, Opaque"; + prefix = "(143)"; + flags8text = "[3] Slope skew sides"; + flags32text = "[5] Only block player"; + flags64text = "[6] Don't cast shadow"; + flags128text = "[7] Only block non-players"; + 3dfloor = true; + 3dfloorflags = "400841F"; + flags643dfloorflagsadd = "40"; + } + + 144 + { + title = "Intangible from Top, Translucent"; + prefix = "(144)"; + flags8text = "[3] Slope skew sides"; + flags32text = "[5] Only block player"; + flags64text = "[6] Don't cast shadow"; + flags128text = "[7] Render insides/block non-plr"; + 3dfloor = true; + 3dfloorflags = "400191F"; + flags1283dfloorflagsadd = "7C80"; + flags643dfloorflagsadd = "40"; + } + + 145 + { + title = "Intangible from Top, Translucent, No Sides"; + prefix = "(145)"; + flags32text = "[5] Only block player"; + flags64text = "[6] Don't cast shadow"; + flags128text = "[7] Render insides/block non-plr"; + 3dfloor = true; + 3dfloorflags = "4001917"; + flags1283dfloorflagsadd = "7C80"; + flags643dfloorflagsadd = "40"; + } + + 146 + { + title = "Only Tangible from Sides"; + prefix = "(146)"; + flags8text = "[3] Slope skew sides"; + flags32text = "[5] Only block player"; + flags128text = "[7] Only block non-players"; + 3dfloor = true; + 3dfloorflags = "600800F"; + } + } + + fofintangible + { + title = "FOF (intangible)"; + + 120 + { + title = "Water, Opaque"; + prefix = "(120)"; + flags8text = "[3] Slope skew sides"; + flags64text = "[6] Use two light levels"; + flags512text = "[9] Use target light level"; + flags1024text = "[10] Ripple effect"; + 3dfloor = true; + 3dfloorflags = "8F39"; + flags643dfloorflagsadd = "20000"; + flags5123dfloorflagsadd = "80000000"; + flags10243dfloorflagsadd = "40000000"; + } + + 121 + { + title = "Water, Translucent"; + prefix = "(121)"; + flags8text = "[3] Slope skew sides"; + flags64text = "[6] Use two light levels"; + flags512text = "[9] Use target light level"; + flags1024text = "[10] Ripple effect"; + 3dfloor = true; + 3dfloorflags = "9F39"; + flags643dfloorflagsadd = "20000"; + flags5123dfloorflagsadd = "80000000"; + flags10243dfloorflagsadd = "40000000"; + } + + 122 + { + title = "Water, Opaque, No Sides"; + prefix = "(122)"; + flags64text = "[6] Use two light levels"; + flags512text = "[9] Use target light level"; + flags1024text = "[10] Ripple effect"; + 3dfloor = true; + 3dfloorflags = "F31"; + flags643dfloorflagsadd = "20000"; + flags5123dfloorflagsadd = "80000000"; + flags10243dfloorflagsadd = "40000000"; + } + + 123 + { + title = "Water, Translucent, No Sides"; + prefix = "(123)"; + flags64text = "[6] Use two light levels"; + flags512text = "[9] Use target light level"; + flags1024text = "[10] Ripple effect"; + 3dfloor = true; + 3dfloorflags = "1F31"; + flags643dfloorflagsadd = "20000"; + flags5123dfloorflagsadd = "80000000"; + flags10243dfloorflagsadd = "40000000"; + } + + 124 + { + title = "Goo Water, Translucent"; + prefix = "(124)"; + flags8text = "[3] Slope skew sides"; + flags64text = "[6] Use two light levels"; + flags512text = "[9] Use target light level"; + flags1024text = "[10] Ripple effect"; + 3dfloor = true; + 3dfloorflags = "209F39"; + flags643dfloorflagsadd = "20000"; + flags5123dfloorflagsadd = "80000000"; + flags10243dfloorflagsadd = "40000000"; + } + + 125 + { + title = "Goo Water, Translucent, No Sides"; + prefix = "(125)"; + flags8text = "[3] Slope skew sides"; + flags64text = "[6] Use two light levels"; + flags512text = "[9] Use target light level"; + flags1024text = "[10] Ripple effect"; + 3dfloor = true; + 3dfloorflags = "201F31"; + flags643dfloorflagsadd = "20000"; + flags5123dfloorflagsadd = "80000000"; + flags10243dfloorflagsadd = "40000000"; + } + + 220 + { + title = "Intangible, Opaque"; + prefix = "(220)"; + flags8text = "[3] Slope skew sides"; + 3dfloor = true; + 3dfloorflags = "8F19"; + } + + 221 + { + title = "Intangible, Translucent"; + prefix = "(221)"; + flags8text = "[3] Slope skew sides"; + flags64text = "[6] Cast shadow"; + 3dfloor = true; + 3dfloorflags = "1B59"; + flags643dfloorflagsremove = "40"; + } + + 222 + { + title = "Intangible, Sides Only"; + prefix = "(222)"; + flags8text = "[3] Slope skew sides"; + flags64text = "[6] Cast shadow"; + 3dfloor = true; + 3dfloorflags = "8249"; + flags643dfloorflagsremove = "240"; + } + + 223 + { + title = "Intangible, Invisible"; + prefix = "(223)"; + 3dfloor = true; + 3dfloorflags = "41"; + } + } + + fofmoving + { + title = "FOF (moving)"; + + 150 + { + title = "Air Bobbing"; + prefix = "(150)"; + flags8text = "[3] Slope skew sides"; + flags32text = "[5] Only block player"; + flags64text = "[6] Spindash to move"; + flags128text = "[7] Only block non-players"; + 3dfloor = true; + 3dfloorflags = "19F"; + } + + 151 + { + title = "Air Bobbing (Adjustable)"; + prefix = "(151)"; + flags8text = "[3] Slope skew sides"; + flags32text = "[5] Only block player"; + flags64text = "[6] Spindash to move"; + flags128text = "[7] Only block non-players"; + 3dfloor = true; + 3dfloorflags = "19F"; + } + + 152 + { + title = "Reverse Air Bobbing (Adjustable)"; + prefix = "(152)"; + flags8text = "[3] Slope skew sides"; + flags32text = "[5] Only block player"; + flags64text = "[6] Spindash to move"; + flags128text = "[7] Only block non-players"; + 3dfloor = true; + 3dfloorflags = "19F"; + } + + 160 + { + title = "Floating, Bobbing"; + prefix = "(160)"; + flags8text = "[3] Slope skew sides"; + flags32text = "[5] Only block player"; + flags128text = "[7] Only block non-players"; + 3dfloor = true; + 3dfloorflags = "4019F"; + } + + 190 + { + title = "Rising Platform, Solid, Opaque"; + prefix = "(190)"; + flags2text = "[1] Sink when stepped on"; + flags8text = "[3] Slope skew sides"; + flags32text = "[5] Only block player"; + flags64text = "[6] Spindash to move"; + flags128text = "[7] Only block non-players"; + 3dfloor = true; + 3dfloorflags = "19F"; + } + + 191 + { + title = "Rising Platform, Solid, Opaque, No Shadow"; + prefix = "(191)"; + flags2text = "[1] Sink when stepped on"; + flags8text = "[3] Slope skew sides"; + flags32text = "[5] Only block player"; + flags64text = "[6] Spindash to move"; + flags128text = "[7] Only block non-players"; + 3dfloor = true; + 3dfloorflags = "1DF"; + } + + 192 + { + title = "Rising Platform, Solid, Translucent"; + prefix = "(192)"; + flags2text = "[1] Sink when stepped on"; + flags8text = "[3] Slope skew sides"; + flags32text = "[5] Only block player"; + flags64text = "[6] Spindash to move"; + flags128text = "[7] Only block non-players"; + 3dfloor = true; + 3dfloorflags = "195F"; + } + + 193 + { + title = "Rising Platform, Solid, Invisible"; + prefix = "(193)"; + flags2text = "[1] Sink when stepped on"; + flags8text = "[3] Slope skew sides"; + flags32text = "[5] Only block player"; + flags64text = "[6] Spindash to move"; + flags128text = "[7] Only block non-players"; + 3dfloor = true; + 3dfloorflags = "47"; + } + + 194 + { + title = "Rising Platform, Intangible from Bottom, Opaque"; + prefix = "(194)"; + flags2text = "[1] Sink when stepped on"; + flags8text = "[3] Slope skew sides"; + flags32text = "[5] Only block player"; + flags64text = "[6] Spindash, no shadow"; + flags128text = "[7] Only block non-players"; + 3dfloor = true; + 3dfloorflags = "200841F"; + flags643dfloorflagsadd = "40"; + } + + 195 + { + title = "Rising Platform, Intangible from Bottom, Translucent"; + prefix = "(195)"; + flags2text = "[1] Sink when stepped on"; + flags8text = "[3] Slope skew sides"; + flags32text = "[5] Only block player"; + flags64text = "[6] Spindash, no shadow"; + flags128text = "[7] Only block non-players"; + 3dfloor = true; + 3dfloorflags = "2009D1F"; + flags643dfloorflagsadd = "40"; + } + } + + fofcrumbling + { + title = "FOF (crumbling)"; + + 170 + { + title = "Crumbling, Respawn"; + prefix = "(170)"; + flags8text = "[3] Slope skew sides"; + flags32text = "[5] Only block player"; + flags128text = "[7] Only block non-players"; + 3dfloor = true; + 3dfloorflags = "10019F"; + } + + 171 + { + title = "Crumbling, No Respawn"; + prefix = "(171)"; + flags8text = "[3] Slope skew sides"; + flags32text = "[5] Only block player"; + flags128text = "[7] Only block non-players"; + 3dfloor = true; + 3dfloorflags = "80019F"; + } + + 172 + { + title = "Crumbling, Respawn, Intangible from Bottom"; + prefix = "(172)"; + flags8text = "[3] Slope skew sides"; + flags32text = "[5] Only block player"; + flags64text = "[6] Don't cast shadow"; + flags128text = "[7] Only block non-players"; + 3dfloor = true; + 3dfloorflags = "210841F"; + flags643dfloorflagsadd = "40"; + } + + 173 + { + title = "Crumbling, No Respawn, Intangible from Bottom"; + prefix = "(173)"; + flags8text = "[3] Slope skew sides"; + flags32text = "[5] Only block player"; + flags64text = "[6] Don't cast shadow"; + flags128text = "[7] Only block non-players"; + 3dfloor = true; + 3dfloorflags = "218841F"; + flags643dfloorflagsadd = "40"; + } + + 174 + { + title = "Crumbling, Respawn, Int. from Bottom, Translucent"; + prefix = "(174)"; + flags8text = "[3] Slope skew sides"; + flags32text = "[5] Only block player"; + flags64text = "[6] Don't cast shadow"; + flags128text = "[7] Only block non-players"; + 3dfloor = true; + 3dfloorflags = "210959F"; + flags643dfloorflagsadd = "40"; + } + + 175 + { + title = "Crumbling, No Respawn, Int. from Bottom, Translucent"; + prefix = "(175)"; + flags8text = "[3] Slope skew sides"; + flags32text = "[5] Only block player"; + flags64text = "[6] Don't cast shadow"; + flags128text = "[7] Only block non-players"; + 3dfloor = true; + 3dfloorflags = "218959F"; + flags643dfloorflagsadd = "40"; + } + + 176 + { + title = "Crumbling, Respawn, Floating, Bobbing"; + prefix = "(176)"; + flags8text = "[3] Slope skew sides"; + flags32text = "[5] Only block player"; + flags64text = "[6] Spindash to move"; + flags128text = "[7] Only block non-players"; + 3dfloor = true; + 3dfloorflags = "14019F"; + } + + 177 + { + title = "Crumbling, No Respawn, Floating, Bobbing"; + prefix = "(177)"; + flags8text = "[3] Slope skew sides"; + flags32text = "[5] Only block player"; + flags64text = "[6] Spindash to move"; + flags128text = "[7] Only block non-players"; + 3dfloor = true; + 3dfloorflags = "1C019F"; + } + + 178 + { + title = "Crumbling, Respawn, Floating"; + prefix = "(178)"; + flags8text = "[3] Slope skew sides"; + flags32text = "[5] Only block player"; + flags128text = "[7] Only block non-players"; + 3dfloor = true; + 3dfloorflags = "14019F"; + } + + 179 + { + title = "Crumbling, No Respawn, Floating"; + prefix = "(179)"; + flags8text = "[3] Slope skew sides"; + flags32text = "[5] Only block player"; + flags128text = "[7] Only block non-players"; + 3dfloor = true; + 3dfloorflags = "1C019F"; + } + + 180 + { + title = "Crumbling, Respawn, Air Bobbing"; + prefix = "(180)"; + flags8text = "[3] Slope skew sides"; + flags32text = "[5] Only block player"; + flags64text = "[6] Spindash to move"; + flags128text = "[7] Only block non-players"; + 3dfloor = true; + 3dfloorflags = "10019F"; + } + } + + fofspecial + { + title = "FOF (special)"; + + 200 + { + title = "Light Block"; + prefix = "(200)"; + 3dfloor = true; + 3dfloorflags = "20201"; + } + + 201 + { + title = "Half Light Block"; + prefix = "(201)"; + 3dfloor = true; + 3dfloorflags = "201"; + } + + 202 + { + title = "Fog Block"; + prefix = "(202)"; + 3dfloor = true; + 3dfloorflags = "3EF19"; + } + + 250 + { + title = "Mario Block"; + prefix = "(250)"; + flags32text = "[5] Invisible block"; + flags64text = "[6] Brick block"; + 3dfloor = true; + 3dfloorflags = "40019F"; + } + + 251 + { + title = "Thwomp Block"; + prefix = "(251)"; + flags512text = "[9] Custom crushing sound"; + flags1024text = "[10] Custom speed"; + 3dfloor = true; + 3dfloorflags = "19F"; + } + + 252 + { + title = "Shatter Block"; + prefix = "(252)"; + flags8text = "[3] Slope skew sides"; + flags64text = "[6] Shatter only from below"; + flags512text = "[9] Shattered by pushables"; + flags1024text = "[10] Trigger linedef executor"; + 3dfloor = true; + 3dfloorflags = "8800019"; + flags643dfloorflagsadd = "200006"; + } + + 253 + { + title = "Shatter Block, Translucent"; + prefix = "(253)"; + flags8text = "[3] Slope skew sides"; + flags512text = "[9] Shattered by pushables"; + flags1024text = "[10] Trigger linedef executor"; + 3dfloor = true; + 3dfloorflags = "8801019"; + } + + 254 + { + title = "Bustable Block"; + prefix = "(254)"; + flags8text = "[3] Slope skew sides"; + flags64text = "[6] Strong characters only"; + flags128text = "[7] Only block non-players"; + flags512text = "[9] Shattered by pushables"; + flags1024text = "[10] Trigger linedef executor"; + 3dfloor = true; + 3dfloorflags = "80001F"; + flags643dfloorflagsadd = "20000000"; + } + + 255 + { + title = "Spin-Bustable Block"; + prefix = "(255)"; + flags8text = "[3] Slope skew sides"; + flags32text = "[5] Only block player"; + flags128text = "[7] Only block non-players"; + flags512text = "[9] Shattered by pushables"; + flags1024text = "[10] Trigger linedef executor"; + 3dfloor = true; + 3dfloorflags = "1080001F"; + } + + 256 + { + title = "Spin-Bustable Block, Translucent"; + prefix = "(256)"; + flags8text = "[3] Slope skew sides"; + flags32text = "[5] Only block player"; + flags128text = "[7] Only block non-players"; + flags512text = "[9] Shattered by pushables"; + flags1024text = "[10] Trigger linedef executor"; + 3dfloor = true; + 3dfloorflags = "1080101F"; + } + + 257 + { + title = "Quicksand"; + prefix = "(257)"; + flags8text = "[3] Slope skew sides"; + flags1024text = "[10] Ripple effect"; + 3dfloor = true; + 3dfloorflags = "1008219"; + flags10243dfloorflagsadd = "40000000"; + } + + 258 + { + title = "Laser"; + prefix = "(258)"; + flags8text = "[3] Slope skew sides"; + flags32text = "[5] Don't damage bosses"; + 3dfloor = true; + 3dfloorflags = "959"; + } + + 259 + { + title = "Custom FOF"; + prefix = "(259)"; + flags32text = "[5] Only block player"; + flags128text = "[7] Only block non-players"; + flags512text = "[9] Shattered by pushables"; + flags1024text = "[10] Trigger linedef executor"; + 3dfloor = true; + 3dfloorcustom = true; + } + } + + linedeftrigger + { + title = "Linedef Executor Trigger"; + + 300 + { + title = "Continuous"; + prefix = "(300)"; + } + + 301 + { + title = "Each Time"; + prefix = "(301)"; + flags16384text = "[14] Also trigger on exit"; + } + + 302 + { + title = "Once"; + prefix = "(302)"; + } + + 303 + { + title = "Ring Count - Continuous"; + prefix = "(303)"; + flags2text = "[1] Rings greater or equal"; + flags64text = "[6] Rings less or equal"; + flags512text = "[9] Consider all players"; + } + + 304 + { + title = "Ring Count - Once"; + prefix = "(304)"; + flags2text = "[1] Rings greater or equal"; + flags64text = "[6] Rings less or equal"; + flags512text = "[9] Consider all players"; + } + + 305 + { + title = "Character Ability - Continuous"; + prefix = "(305)"; + } + + 306 + { + title = "Character Ability - Each Time"; + prefix = "(306)"; + flags16384text = "[14] Also trigger on exit"; + } + + 307 + { + title = "Character Ability - Once"; + prefix = "(307)"; + } + + 308 + { + title = "Race Only - Once"; + prefix = "(308)"; + } + + 309 + { + title = "CTF Red Team - Continuous"; + prefix = "(309)"; + } + + 310 + { + title = "CTF Red Team - Each Time"; + prefix = "(310)"; + flags16384text = "[14] Also trigger on exit"; + } + + 311 + { + title = "CTF Blue Team - Continuous"; + prefix = "(311)"; + } + + 312 + { + title = "CTF Blue Team - Each Time"; + prefix = "(312)"; + flags16384text = "[14] Also trigger on exit"; + } + + 313 + { + title = "No More Enemies - Once"; + prefix = "(313)"; + } + + 314 + { + title = "Number of Pushables - Continuous"; + prefix = "(314)"; + flags64text = "[6] Number greater or equal"; + flags512text = "[9] Number less"; + } + + 315 + { + title = "Number of Pushables - Once"; + prefix = "(315)"; + flags64text = "[6] Number greater or equal"; + flags512text = "[9] Number less"; + } + + 317 + { + title = "Condition Set Trigger - Continuous"; + prefix = "(317)"; + } + + 318 + { + title = "Condition Set Trigger - Once"; + prefix = "(318)"; + } + + 319 + { + title = "Unlockable - Continuous"; + prefix = "(319)"; + } + + 320 + { + title = "Unlockable - Once"; + prefix = "(320)"; + } + + 321 + { + title = "Trigger After X Calls - Continuous"; + prefix = "(321)"; + flags64text = "[6] Trigger more than once"; + + } + + 322 + { + title = "Trigger After X Calls - Each Time"; + prefix = "(322)"; + flags64text = "[6] Trigger more than once"; + } + + 323 + { + title = "NiGHTSerize - Each Time"; + prefix = "(323)"; + flags2text = "[1] Mare >= Front X Offset"; + flags8text = "[3] Run only if player is NiGHTS"; + flags16text = "[4] Count from lowest of players"; + flags32text = "[5] Lap <= Front Y Offset"; + flags64text = "[6] Mare <= Front X Offset"; + flags128text = "[7] Lap >= Front Y Offset"; + flags256text = "[8] Count laps from Bonus Time"; + flags512text = "[9] Count from triggering player"; + flags16384text = "[14] Run if no more mares"; + flags32768text = "[15] Run if player is not NiGHTS"; + } + + 324 + { + title = "NiGHTSerize - Once"; + flags2text = "[1] Mare >= Front X Offset"; + flags8text = "[3] Run only if player is NiGHTS"; + flags16text = "[4] Count from lowest of players"; + flags32text = "[5] Lap <= Front Y Offset"; + flags64text = "[6] Mare <= Front X Offset"; + flags128text = "[7] Lap >= Front Y Offset"; + flags256text = "[8] Count laps from Bonus Time"; + flags512text = "[9] Count from triggering player"; + flags16384text = "[14] Run if no more mares"; + flags32768text = "[15] Run if player is not NiGHTS"; + prefix = "(324)"; + } + + 325 + { + title = "De-NiGHTSerize - Each Time"; + flags2text = "[1] Mare >= Front X Offset"; + flags8text = "[3] Run if anyone is NiGHTS"; + flags16text = "[4] Count from lowest of players"; + flags32text = "[5] Lap <= Front Y Offset"; + flags64text = "[6] Mare <= Front X Offset"; + flags128text = "[7] Lap >= Front Y Offset"; + flags256text = "[8] Count laps from Bonus Time"; + flags512text = "[9] Count from triggering player"; + flags32768text = "[15] Run if no one is NiGHTS"; + prefix = "(325)"; + } + + 326 + { + title = "De-NiGHTSerize - Once"; + flags2text = "[1] Mare >= Front X Offset"; + flags8text = "[3] Run if anyone is NiGHTS"; + flags16text = "[4] Count from lowest of players"; + flags32text = "[5] Lap <= Front Y Offset"; + flags64text = "[6] Mare <= Front X Offset"; + flags128text = "[7] Lap >= Front Y Offset"; + flags256text = "[8] Count laps from Bonus Time"; + flags512text = "[9] Count from triggering player"; + flags32768text = "[15] Run if no one is NiGHTS"; + prefix = "(326)"; + } + + 327 + { + title = "NiGHTS Lap - Each Time"; + flags2text = "[1] Mare >= Front X Offset"; + flags16text = "[4] Count from lowest of players"; + flags32text = "[5] Lap <= Front Y Offset"; + flags64text = "[6] Mare <= Front X Offset"; + flags128text = "[7] Lap >= Front Y Offset"; + flags256text = "[8] Count laps from Bonus Time"; + flags512text = "[9] Count from triggering player"; + prefix = "(327)"; + } + + 328 + { + title = "NiGHTS Lap - Once"; + flags2text = "[1] Mare >= Front X Offset"; + flags16text = "[4] Count from lowest of players"; + flags32text = "[5] Lap <= Front Y Offset"; + flags64text = "[6] Mare <= Front X Offset"; + flags128text = "[7] Lap >= Front Y Offset"; + flags256text = "[8] Count laps from Bonus Time"; + flags512text = "[9] Count from triggering player"; + prefix = "(328)"; + } + + 329 + { + title = "Ideya Capture Touch - Each Time"; + flags2text = "[1] Mare >= Front X Offset"; + flags8text = "[3] Run regardless of spheres"; + flags16text = "[4] Count from lowest of players"; + flags32text = "[5] Lap <= Front Y Offset"; + flags64text = "[6] Mare <= Front X Offset"; + flags128text = "[7] Lap >= Front Y Offset"; + flags256text = "[8] Count laps from Bonus Time"; + flags512text = "[9] Count from triggering player"; + flags16384text = "[14] Only if not enough spheres"; + flags32768text = "[15] Run when entering Capture"; + prefix = "(329)"; + } + + 330 + { + title = "Ideya Capture Touch - Once"; + flags2text = "[1] Mare >= Front X Offset"; + flags8text = "[3] Run regardless of spheres"; + flags16text = "[4] Count from lowest of players"; + flags32text = "[5] Lap <= Front Y Offset"; + flags64text = "[6] Mare <= Front X Offset"; + flags128text = "[7] Lap >= Front Y Offset"; + flags256text = "[8] Count laps from Bonus Time"; + flags512text = "[9] Count from triggering player"; + flags16384text = "[14] Only if not enough spheres"; + flags32768text = "[15] Run when entering Capture"; + prefix = "(330)"; + } + + 331 + { + title = "Player Skin - Continuous"; + flags64text = "[6] Disable for this skin"; + prefix = "(331)"; + } + + 332 + { + title = "Player Skin - Each Time"; + flags64text = "[6] Disable for this skin"; + prefix = "(332)"; + } + + 333 + { + title = "Player Skin - Once"; + flags64text = "[6] Disable for this skin"; + prefix = "(333)"; + } + + 399 + { + title = "Level Load"; + prefix = "(399)"; + } + } + + linedefexecsector + { + title = "Linedef Executor (sector)"; + + 400 + { + title = "Set Tagged Sector's Floor Height/Texture"; + prefix = "(400)"; + flags8text = "[3] Set delay by backside sector"; + flags64text = "[6] Keep floor flat"; + } + + 401 + { + title = "Set Tagged Sector's Ceiling Height/Texture"; + prefix = "(401)"; + flags8text = "[3] Set delay by backside sector"; + } + + 402 + { + title = "Set Tagged Sector's Light Level"; + prefix = "(402)"; + flags8text = "[3] Set delay by backside sector"; + } + + 409 + { + title = "Change Tagged Sector's Tag"; + prefix = "(409)"; + flags8text = "[3] Set delay by backside sector"; + } + + 410 + { + title = "Change Front Sector's Tag"; + prefix = "(410)"; + flags8text = "[3] Set delay by backside sector"; + } + + 416 + { + title = "Start Adjustable Flickering Light"; + prefix = "(416)"; + flags8text = "[3] Set delay by backside sector"; + flags64text = "[6] Second level from back"; + } + + 417 + { + title = "Start Adjustable Pulsating Light"; + prefix = "(417)"; + flags8text = "[3] Set delay by backside sector"; + flags64text = "[6] Second level from back"; + } + + 418 + { + title = "Start Adjustable Blinking Light (unsynchronized)"; + prefix = "(418)"; + flags8text = "[3] Set delay by backside sector"; + flags64text = "[6] Second level from back"; + } + + 419 + { + title = "Start Adjustable Blinking Light (synchronized)"; + prefix = "(419)"; + flags8text = "[3] Set delay by backside sector"; + flags64text = "[6] Second level from back"; + } + + 420 + { + title = "Fade Light Level"; + prefix = "(420)"; + flags8text = "[3] Set delay by backside sector"; + flags16text = "[4] Set params by X/Y offsets"; + flags512text = "[9] Speed = Tic Duration"; + flags1024text = "[10] Override existing fade"; + } + + 421 + { + title = "Stop Lighting Effect"; + prefix = "(421)"; + flags8text = "[3] Set delay by backside sector"; + } + + 435 + { + title = "Change Plane Scroller Direction"; + prefix = "(435)"; + flags8text = "[3] Set delay by backside sector"; + } + } + + linedefexecplane + { + title = "Linedef Executor (plane movement)"; + + 403 + { + title = "Move Tagged Sector's Floor"; + prefix = "(403)"; + flags2text = "[1] Trigger linedef executor"; + flags8text = "[3] Set delay by backside sector"; + flags64text = "[6] Change floor flat"; + } + + 404 + { + title = "Move Tagged Sector's Ceiling"; + prefix = "(404)"; + flags2text = "[1] Trigger linedef executor"; + flags8text = "[3] Set delay by backside sector"; + flags64text = "[6] Change ceiling flat"; + } + + 405 + { + title = "Move Floor According to Front Texture Offsets"; + prefix = "(405)"; + flags8text = "[3] Set delay by backside sector"; + flags64text = "[6] Move instantly"; + } + + 407 + { + title = "Move Ceiling According to Front Texture Offsets"; + prefix = "(407)"; + flags8text = "[3] Set delay by backside sector"; + flags64text = "[6] Move instantly"; + } + + 411 + { + title = "Stop Plane Movement"; + prefix = "(411)"; + flags8text = "[3] Set delay by backside sector"; + } + + 428 + { + title = "Start Platform Movement"; + prefix = "(428)"; + flags8text = "[3] Set delay by backside sector"; + flags64text = "[6] Move upwards at start"; + } + + 429 + { + title = "Crush Ceiling Once"; + prefix = "(429)"; + flags8text = "[3] Set delay by backside sector"; + flags512text = "[9] Double, constant speed"; + } + + 430 + { + title = "Crush Floor Once"; + prefix = "(430)"; + flags8text = "[3] Set delay by backside sector"; + } + + 431 + { + title = "Crush Floor and Ceiling Once"; + prefix = "(431)"; + flags8text = "[3] Set delay by backside sector"; + flags512text = "[9] Double, constant speed"; + } + } + + linedefexecplayer + { + title = "Linedef Executor (player/object)"; + + 412 + { + title = "Teleporter"; + prefix = "(412)"; + flags2text = "[1] Silent"; + flags8text = "[3] Set delay by backside sector"; + flags64text = "[6] Retain angle"; + flags256text = "[8] Relative, silent"; + flags512text = "[9] Retain momentum"; + } + + 425 + { + title = "Change Object State"; + prefix = "(425)"; + flags8text = "[3] Set delay by backside sector"; + } + + 426 + { + title = "Stop Object"; + prefix = "(426)"; + flags8text = "[3] Set delay by backside sector"; + flags64text = "[6] Teleport to sector center"; + } + + 427 + { + title = "Award Score"; + prefix = "(427)"; + flags8text = "[3] Set delay by backside sector"; + } + + 432 + { + title = "Enable/Disable 2D Mode"; + prefix = "(432)"; + flags8text = "[3] Set delay by backside sector"; + flags64text = "[6] Return to 3D"; + } + + 433 + { + title = "Enable/Disable Gravity Flip"; + prefix = "(433)"; + flags8text = "[3] Set delay by backside sector"; + flags64text = "[6] Return to normal"; + } + + 434 + { + title = "Award Power-Up"; + prefix = "(434)"; + flags2text = "[1] Use back upper texture"; + flags8text = "[3] Set delay by backside sector"; + flags64text = "[6] No time limit"; + } + + 437 + { + title = "Disable Player Control"; + prefix = "(437)"; + flags8text = "[3] Set delay by backside sector"; + flags64text = "[6] Allow jumping"; + } + + 438 + { + title = "Change Object Size"; + prefix = "(438)"; + flags8text = "[3] Set delay by backside sector"; + } + + 442 + { + title = "Change Object Type State"; + prefix = "(442)"; + flags8text = "[3] Set delay by backside sector"; + } + + 457 + { + title = "Track Object's Angle"; + prefix = "(457)"; + flags8text = "[3] Set delay by backside sector"; + flags128text = "[7] Don't stop after first fail"; + } + + 458 + { + title = "Stop Tracking Object's Angle"; + prefix = "(458)"; + flags8text = "[3] Set delay by backside sector"; + } + + 460 + { + title = "Award Rings"; + prefix = "(460)"; + } + + 461 + { + title = "Spawn Object"; + prefix = "(461)"; + flags64text = "[6] Spawn inside a range"; + } + + 462 + { + title = "Stop Timer/Exit Stage in Record Attack"; + prefix = "(462)"; + } + } + + linedefexecmisc + { + title = "Linedef Executor (misc.)"; + + 413 + { + title = "Change Music"; + prefix = "(413)"; + flags2text = "[1] Keep after death"; + flags8text = "[3] Set delay by backside sector"; + flags32text = "[5] Seek to current song position"; + flags64text = "[6] For everyone"; + flags128text = "[7] Fade to custom volume"; + flags512text = "[9] Don't loop"; + flags16384text = "[14] Force music reload"; + } + + 414 + { + title = "Play Sound Effect"; + prefix = "(414)"; + flags2text = "[1] From calling sector"; + flags8text = "[3] Set delay by backside sector"; + flags64text = "[6] From nowhere for triggerer"; + flags512text = "[9] For everyone"; + flags1024text = "[10] From tagged sectors"; + } + + 415 + { + title = "Run Script"; + prefix = "(415)"; + flags8text = "[3] Set delay by backside sector"; + } + + 422 + { + title = "Switch to Cut-Away View"; + prefix = "(422)"; + flags8text = "[3] Set delay by backside sector"; + flags64text = "[6] Adjust pitch"; + } + + 423 + { + title = "Change Sky"; + prefix = "(423)"; + flags8text = "[3] Set delay by backside sector"; + flags64text = "[6] For everyone"; + } + + 424 + { + title = "Change Weather"; + prefix = "(424)"; + flags8text = "[3] Set delay by backside sector"; + flags64text = "[6] For everyone"; + } + + 436 + { + title = "Shatter FOF"; + prefix = "(436)"; + flags8text = "[3] Set delay by backside sector"; + } + + 439 + { + title = "Change Tagged Linedef's Textures"; + prefix = "(439)"; + flags8text = "[3] Set delay by backside sector"; + flags64text = "[6] Only existing"; + } + + 440 + { + title = "Start Metal Sonic Race"; + prefix = "(440)"; + flags8text = "[3] Set delay by backside sector"; + } + + 441 + { + title = "Condition Set Trigger"; + prefix = "(441)"; + flags8text = "[3] Set delay by backside sector"; + } + + 443 + { + title = "Call Lua Function"; + prefix = "(443)"; + flags8text = "[3] Set delay by backside sector"; + } + + 444 + { + title = "Earthquake"; + prefix = "(444)"; + flags8text = "[3] Set delay by backside sector"; + } + + + 445 + { + title = "Make FOF Disappear/Reappear"; + prefix = "(445)"; + flags8text = "[3] Set delay by backside sector"; + flags64text = "[6] Reappear"; + } + + 446 + { + title = "Make FOF Crumble"; + prefix = "(446)"; + flags2text = "[1] Flags determine respawn"; + flags8text = "[3] Set delay by backside sector"; + flags64text = "[6] Don't respawn"; + } + + 447 + { + title = "Change Tagged Sector's Colormap"; + prefix = "(447)"; + flags8text = "[3] Set delay by backside sector"; + flags16text = "[4] Front X/Y = Alpha"; + flags32text = "[5] Subtract Red value"; + flags64text = "[6] Subtract Green value"; + flags128text = "[7] Subtract Blue value"; + flags256text = "[8] Calc relative values"; + flags32768text = "[15] Use back side colormap"; + } + + 448 + { + title = "Change Skybox"; + prefix = "(448)"; + flags2text = "[1] Change centerpoint"; + flags8text = "[3] Set delay by backside sector"; + flags64text = "[6] For everyone"; + flags512text = "[9] Don't change viewpoint"; + } + + 450 + { + title = "Execute Linedef Executor (specific tag)"; + prefix = "(450)"; + flags8text = "[3] Set delay by backside sector"; + } + + 451 + { + title = "Execute Linedef Executor (random tag in range)"; + prefix = "(451)"; + flags8text = "[3] Set delay by backside sector"; + } + + 452 + { + title = "Set FOF Translucency"; + prefix = "(452)"; + flags8text = "[3] Set delay by backside sector"; + flags64text = "[6] Do not handle FF_TRANS"; + flags256text = "[8] Set relative to current val"; + } + + 453 + { + title = "Fade FOF"; + prefix = "(453)"; + flags2text = "[1] Do not handle FF_EXISTS"; + flags8text = "[3] Set delay by backside sector"; + flags32text = "[5] No collision during fade"; + flags64text = "[6] Do not handle FF_TRANS"; + flags128text = "[7] Do not handle lighting"; + flags256text = "[8] Set relative to current val"; + flags512text = "[9] Speed = Tic Duration"; + flags1024text = "[10] Override existing fade"; + flags16384text = "[14] Do not handle collision"; + flags32768text = "[15] Use exact alpha in OGL"; + } + + 454 + { + title = "Stop Fading FOF"; + prefix = "(454)"; + flags2text = "[1] Do not finalize collision"; + flags8text = "[3] Set delay by backside sector"; + } + + 455 + { + title = "Fade Tagged Sector's Colormap"; + prefix = "(455)"; + flags8text = "[3] Set delay by backside sector"; + flags16text = "[4] Front X/Y = Alpha"; + flags32text = "[5] Subtract Red value"; + flags64text = "[6] Subtract Green value"; + flags128text = "[7] Subtract Blue value"; + flags256text = "[8] Calc relative values"; + flags512text = "[9] Speed = Tic Duration"; + flags1024text = "[10] Override existing fade"; + flags16384text = "[14] Fade from invisible black"; + flags32768text = "[15] Use back side colormap"; + } + + 456 + { + title = "Stop Fading Tagged Sector's Colormap"; + prefix = "(456)"; + flags8text = "[3] Set delay by backside sector"; + } + + 459 + { + title = "Control Text Prompt"; + prefix = "(459)"; + flags2text = "[1] Close text prompt"; + flags8text = "[3] Set delay by backside sector"; + flags32text = "[5] Run executor tag on close"; + flags64text = "[6] For everyone"; + flags128text = "[7] Do not block controls"; + flags256text = "[8] Do not freeze time"; + flags32768text = "[15] Find prompt by name"; + } + } + + linedefexecpoly + { + title = "Linedef Executor (polyobject)"; + + 480 + { + title = "Door Slide"; + prefix = "(480)"; + flags8text = "[3] Set delay by backside sector"; + } + + 481 + { + title = "Door Swing"; + prefix = "(481)"; + flags8text = "[3] Set delay by backside sector"; + } + + 482 + { + title = "Move"; + prefix = "(482)"; + flags8text = "[3] Set delay by backside sector"; + } + + 483 + { + title = "Move, Override"; + prefix = "(483)"; + flags8text = "[3] Set delay by backside sector"; + } + + 484 + { + title = "Rotate Right"; + prefix = "(484)"; + flags8text = "[3] Set delay by backside sector"; + flags64text = "[6] Don't turn players"; + flags512text = "[9] Turn all objects"; + } + + 485 + { + title = "Rotate Right, Override"; + prefix = "(485)"; + flags8text = "[3] Set delay by backside sector"; + flags64text = "[6] Don't turn players"; + flags512text = "[9] Turn all objects"; + } + + 486 + { + title = "Rotate Left"; + prefix = "(486)"; + flags8text = "[3] Set delay by backside sector"; + flags64text = "[6] Don't turn players"; + flags512text = "[9] Turn all objects"; + } + + 487 + { + title = "Rotate Left, Override"; + prefix = "(487)"; + flags8text = "[3] Set delay by backside sector"; + flags64text = "[6] Don't turn players"; + flags512text = "[9] Turn all objects"; + } + + 488 + { + title = "Move by Waypoints"; + prefix = "(488)"; + flags8text = "[3] Set delay by backside sector"; + flags32text = "[5] Reverse order"; + flags128text = "[7] There and back"; + flags256text = "[8] Return when done"; + flags512text = "[9] Loop movement"; + } + + 489 + { + title = "Turn Invisible, Intangible"; + prefix = "(489)"; + flags8text = "[3] Set delay by backside sector"; + flags64text = "[6] Only invisible"; + } + + 490 + { + title = "Turn Visible, Tangible"; + prefix = "(490)"; + flags8text = "[3] Set delay by backside sector"; + flags64text = "[6] Only visible"; + } + + 491 + { + title = "Set Translucency"; + prefix = "(491)"; + flags8text = "[3] Set delay by backside sector"; + flags16text = "[4] Set raw alpha by Front X"; + flags256text = "[8] Calc relative values"; + } + + 492 + { + title = "Fade Translucency"; + prefix = "(492)"; + flags8text = "[3] Set delay by backside sector"; + flags16text = "[4] Set raw alpha by Front X"; + flags32text = "[5] No collision during fade"; + flags256text = "[8] Calc relative values"; + flags512text = "[9] Speed = Tic Duration"; + flags1024text = "[10] Override existing fade"; + flags16384text = "[14] Do not handle collision"; + } + } + + wallscroll + { + title = "Wall Scrolling"; + + 500 + { + title = "Scroll Wall Front Side Left"; + prefix = "(500)"; + } + + 501 + { + title = "Scroll Wall Front Side Right"; + prefix = "(501)"; + } + + 502 + { + title = "Scroll Wall According to Linedef"; + prefix = "(502)"; + } + + 503 + { + title = "Scroll Wall According to Linedef (Accelerative)"; + prefix = "(503)"; + } + + 504 + { + title = "Scroll Wall According to Linedef (Displacement)"; + prefix = "(504)"; + } + + 505 + { + title = "Scroll Texture by Front Side Offsets"; + prefix = "(505)"; + } + + 506 + { + title = "Scroll Texture by Back Side Offsets"; + prefix = "(506)"; + } + } + + planescroll + { + title = "Plane Scrolling"; + + 510 + { + title = "Scroll Floor Texture"; + prefix = "(510)"; + } + + 511 + { + title = "Scroll Floor Texture (Accelerative)"; + prefix = "(511)"; + } + + 512 + { + title = "Scroll Floor Texture (Displacement)"; + prefix = "(512)"; + } + + 513 + { + title = "Scroll Ceiling Texture"; + prefix = "(513)"; + } + + 514 + { + title = "Scroll Ceiling Texture (Accelerative)"; + prefix = "(514)"; + } + + 515 + { + title = "Scroll Ceiling Texture (Displacement)"; + prefix = "(515)"; + } + + 520 + { + title = "Carry Objects on Floor"; + prefix = "(520)"; + } + + 521 + { + title = "Carry Objects on Floor (Accelerative)"; + prefix = "(521)"; + flags64text = "[6] Even across edges"; + } + + 522 + { + title = "Carry Objects on Floor (Displacement)"; + prefix = "(522)"; + } + + 523 + { + title = "Carry Objects on Ceiling"; + prefix = "(523)"; + flags64text = "[6] Even across edges"; + } + + 524 + { + title = "Carry Objects on Ceiling (Accelerative)"; + prefix = "(524)"; + } + + 525 + { + title = "Carry Objects on Ceiling (Displacement)"; + prefix = "(525)"; + } + + 530 + { + title = "Scroll Floor Texture and Carry Objects"; + prefix = "(530)"; + flags64text = "[6] Even across edges"; + } + + 531 + { + title = "Scroll Floor Texture and Carry Objects (Accelerative)"; + prefix = "(531)"; + } + + 532 + { + title = "Scroll Floor Texture and Carry Objects (Displacement)"; + prefix = "(532)"; + } + + 533 + { + title = "Scroll Ceiling Texture and Carry Objects"; + prefix = "(533)"; + flags64text = "[6] Even across edges"; + } + + 534 + { + title = "Scroll Ceiling Texture and Carry Objects (Accelerative)"; + prefix = "(534)"; + } + + 535 + { + title = "Scroll Ceiling Texture and Carry Objects (Displacement)"; + prefix = "(535)"; + } + } + + pusher + { + title = "Pusher"; + + 541 + { + title = "Wind"; + prefix = "(541)"; + flags512text = "[9] Player slides"; + flags64text = "[6] Even across edges"; + } + + 542 + { + title = "Upwards Wind"; + prefix = "(542)"; + flags512text = "[9] Player slides"; + flags64text = "[6] Even across edges"; + } + + 543 + { + title = "Downwards Wind"; + prefix = "(543)"; + flags512text = "[9] Player slides"; + flags64text = "[6] Even across edges"; + } + + 544 + { + title = "Current"; + prefix = "(544)"; + flags512text = "[9] Player slides"; + flags64text = "[6] Even across edges"; + } + + 545 + { + title = "Upwards Current"; + prefix = "(545)"; + flags512text = "[9] Player slides"; + flags64text = "[6] Even across edges"; + } + + 546 + { + title = "Downwards Current"; + prefix = "(546)"; + flags512text = "[9] Player slides"; + flags64text = "[6] Even across edges"; + } + + 547 + { + title = "Push/Pull"; + prefix = "(547)"; + } + } + + light + { + title = "Lighting"; + + 600 + { + title = "Floor Lighting"; + prefix = "(600)"; + } + + 601 + { + title = "Ceiling Lighting"; + prefix = "(601)"; + } + + 602 + { + title = "Adjustable Pulsating Light"; + prefix = "(602)"; + } + + 603 + { + title = "Adjustable Flickering Light"; + prefix = "(603)"; + } + + 604 + { + title = "Adjustable Blinking Light (unsynchronized)"; + prefix = "(604)"; + } + + 605 + { + title = "Adjustable Blinking Light (synchronized)"; + prefix = "(605)"; + } + + 606 + { + title = "Colormap"; + prefix = "(606)"; + } + } + + slope + { + title = "Slope"; + + 700 + { + title = "Slope Frontside Floor"; + prefix = "(700)"; + flags2048text = "[11] No physics"; + flags4096text = "[12] Dynamic"; + slope = "regular"; + slopeargs = 1; + } + + 701 + { + title = "Slope Frontside Ceiling"; + prefix = "(701)"; + flags2048text = "[11] No physics"; + flags4096text = "[12] Dynamic"; + slope = "regular"; + slopeargs = 2; + } + + 702 + { + title = "Slope Frontside Floor and Ceiling"; + prefix = "(702)"; + flags2048text = "[11] No physics"; + flags4096text = "[12] Dynamic"; + slope = "regular"; + slopeargs = 3; + } + + 703 + { + title = "Slope Frontside Floor and Backside Ceiling"; + prefix = "(703)"; + flags2048text = "[11] No physics"; + flags4096text = "[12] Dynamic"; + slope = "regular"; + slopeargs = 9; + } + + 704 + { + title = "Slope Frontside Floor by 3 Tagged Vertex Things"; + prefix = "(704)"; + flags2048text = "[11] No physics"; + flags4096text = "[12] Dynamic"; + flags8192text = "[13] Use tag and offsets"; + slope = "vertex"; + slopeargs = 0; + } + + 705 + { + title = "Slope Frontside Ceiling by 3 Tagged Vertex Things"; + prefix = "(705)"; + flags2048text = "[11] No physics"; + flags4096text = "[12] Dynamic"; + flags8192text = "[13] Use tag and offsets"; + slope = "vertex"; + slopeargs = 1; + } + + 710 + { + title = "Slope Backside Floor"; + prefix = "(710)"; + flags2048text = "[11] No physics"; + flags4096text = "[12] Dynamic"; + slope = "regular"; + slopeargs = 4; + } + + 711 + { + title = "Slope Backside Ceiling"; + prefix = "(711)"; + flags2048text = "[11] No physics"; + flags4096text = "[12] Dynamic"; + slope = "regular"; + slopeargs = 8; + } + + 712 + { + title = "Slope Backside Floor and Ceiling"; + prefix = "(712)"; + flags2048text = "[11] No physics"; + flags4096text = "[12] Dynamic"; + slope = "regular"; + slopeargs = 12; + } + + 713 + { + title = "Slope Backside Floor and Frontside Ceiling"; + prefix = "(713)"; + flags2048text = "[11] No physics"; + flags4096text = "[12] Dynamic"; + slope = "regular"; + slopeargs = 6; + } + + 714 + { + title = "Slope Backside Floor by 3 Tagged Vertex Things"; + prefix = "(714)"; + flags2048text = "[11] No physics"; + flags4096text = "[12] Dynamic"; + flags8192text = "[13] Use tag and offsets"; + slope = "vertex"; + slopeargs = 2; + } + + 715 + { + title = "Slope Backside Ceiling by 3 Tagged Vertex Things"; + prefix = "(715)"; + flags2048text = "[11] No physics"; + flags4096text = "[12] Dynamic"; + flags8192text = "[13] Use tag and offsets"; + slope = "vertex"; + slopeargs = 3; + } + + 720 + { + title = "Copy Frontside Floor Slope from Line Tag"; + prefix = "(720)"; + slope = "copy"; + slopeargs = 1; + } + + 721 + { + title = "Copy Frontside Ceiling Slope from Line Tag"; + prefix = "(721)"; + slope = "copy"; + slopeargs = 2; + } + + 722 + { + title = "Copy Frontside Floor and Ceiling Slope from Line Tag"; + prefix = "(722)"; + slope = "copy"; + slopeargs = 3; + } + + 799 + { + title = "Set Tagged Dynamic Slope Vertex to Front Sector Height"; + prefix = "(799)"; + } + } + + transwall + { + title = "Translucent Wall"; + + 900 + { + title = "90% Opaque"; + prefix = "(900)"; + } + + 901 + { + title = "80% Opaque"; + prefix = "(901)"; + } + + 902 + { + title = "70% Opaque"; + prefix = "(902)"; + } + + 903 + { + title = "60% Opaque"; + prefix = "(903)"; + } + + 904 + { + title = "50% Opaque"; + prefix = "(904)"; + } + + 905 + { + title = "40% Opaque"; + prefix = "(905)"; + } + + 906 + { + title = "30% Opaque"; + prefix = "(906)"; + } + + 907 + { + title = "20% Opaque"; + prefix = "(907)"; + } + + 908 + { + title = "10% Opaque"; + prefix = "(908)"; + } + + 909 + { + title = "Fog Wall"; + prefix = "(909)"; + } + } +} + + +// THING FLAGS +thingflags +{ + 1 = "[1] Extra"; + 2 = "[2] Flip"; + 4 = "[4] Special"; + 8 = "[8] Ambush"; +} + +// Thing flags UDMF translation table +// This is needed for copy/paste and prefabs to work properly +// When the UDMF field name is prefixed with ! it is inverted +thingflagstranslation +{ + 1 = "skill1"; + 2 = "skill2"; + 4 = "skill3"; + 8 = "ambush"; +} + +// THING FLAGS ERROR MASK +// Mask for the thing flags which indicates the options +// that make the same thing appear in the same modes +thingflagsmask1 = 7; // 1 + 2 + 4 +thingflagsmask2 = 0; + + +// THING TYPES------------------------------------------------------------------ +// Color values: 1-Dark_Blue 2-Dark_Green 3-Turqoise 4-Dark_Red 5-Purple 6-Brown 7-Gray +// 8-Dark_Gray 9-Blue 10-Green 11-Cyan 12-Red 13-Magenta +// 14-Yellow 15-White 16-Pink 17-Orange 18-Gold 19-Cream +thingtypes +{ + editor + { + color = 15; // White + arrow = 1; + title = ""; + error = -1; + width = 8; + height = 16; + sort = 1; + + 3328 = "3D Mode Start"; + } + + starts + { + color = 1; // Blue + arrow = 1; + title = "Player Starts"; + width = 16; + height = 48; + flags8text = "[8] Spawn on ceiling"; + sprite = "PLAYA0"; + + 1 + { + title = "Player 01 Start"; + sprite = "PLAYA0"; + } + 2 + { + title = "Player 02 Start"; + sprite = "PLAYA0"; + } + 3 + { + title = "Player 03 Start"; + sprite = "PLAYA0"; + } + 4 + { + title = "Player 04 Start"; + sprite = "PLAYA0"; + } + 5 + { + title = "Player 05 Start"; + sprite = "PLAYA0"; + } + 6 + { + title = "Player 06 Start"; + sprite = "PLAYA0"; + } + 7 + { + title = "Player 07 Start"; + sprite = "PLAYA0"; + } + 8 + { + title = "Player 08 Start"; + sprite = "PLAYA0"; + } + 9 + { + title = "Player 09 Start"; + sprite = "PLAYA0"; + } + 10 + { + title = "Player 10 Start"; + sprite = "PLAYA0"; + } + 11 + { + title = "Player 11 Start"; + sprite = "PLAYA0"; + } + 12 + { + title = "Player 12 Start"; + sprite = "PLAYA0"; + } + 13 + { + title = "Player 13 Start"; + sprite = "PLAYA0"; + } + 14 + { + title = "Player 14 Start"; + sprite = "PLAYA0"; + } + 15 + { + title = "Player 15 Start"; + sprite = "PLAYA0"; + } + 16 + { + title = "Player 16 Start"; + sprite = "PLAYA0"; + } + 17 + { + title = "Player 17 Start"; + sprite = "PLAYA0"; + } + 18 + { + title = "Player 18 Start"; + sprite = "PLAYA0"; + } + 19 + { + title = "Player 19 Start"; + sprite = "PLAYA0"; + } + 20 + { + title = "Player 20 Start"; + sprite = "PLAYA0"; + } + 21 + { + title = "Player 21 Start"; + sprite = "PLAYA0"; + } + 22 + { + title = "Player 22 Start"; + sprite = "PLAYA0"; + } + 23 + { + title = "Player 23 Start"; + sprite = "PLAYA0"; + } + 24 + { + title = "Player 24 Start"; + sprite = "PLAYA0"; + } + 25 + { + title = "Player 25 Start"; + sprite = "PLAYA0"; + } + 26 + { + title = "Player 26 Start"; + sprite = "PLAYA0"; + } + 27 + { + title = "Player 27 Start"; + sprite = "PLAYA0"; + } + 28 + { + title = "Player 28 Start"; + sprite = "PLAYA0"; + } + 29 + { + title = "Player 29 Start"; + sprite = "PLAYA0"; + } + 30 + { + title = "Player 30 Start"; + sprite = "PLAYA0"; + } + 31 + { + title = "Player 31 Start"; + sprite = "PLAYA0"; + } + 32 + { + title = "Player 32 Start"; + sprite = "PLAYA0"; + } + 33 + { + title = "Match Start"; + sprite = "NDRNA2A8"; + } + 34 + { + title = "CTF Red Team Start"; + sprite = "SIGNG0"; + } + 35 + { + title = "CTF Blue Team Start"; + sprite = "SIGNE0"; + } + } + + enemies + { + color = 9; // Light_Blue + arrow = 1; + title = "Enemies"; + + 100 + { + title = "Crawla (Blue)"; + sprite = "POSSA1"; + width = 24; + height = 32; + } + 101 + { + title = "Crawla (Red)"; + sprite = "SPOSA1"; + width = 24; + height = 32; + } + 102 + { + title = "Stupid Dumb Unnamed RoboFish"; + sprite = "FISHA0"; + width = 8; + height = 28; + angletext = "Jump strength"; + } + 103 + { + title = "Buzz (Gold)"; + sprite = "BUZZA1"; + width = 28; + height = 40; + flags8text = "[8] Cannot move"; + } + 104 + { + title = "Buzz (Red)"; + sprite = "RBUZA1"; + width = 28; + height = 40; + flags8text = "[8] Cannot move"; + } + 108 + { + title = "Deton"; + sprite = "DETNA1"; + width = 20; + height = 32; + } + 110 + { + title = "Turret"; + sprite = "TRETA1"; + width = 16; + height = 32; + } + 111 + { + title = "Pop-up Turret"; + sprite = "TURRI1"; + width = 12; + height = 64; + angletext = "Firing delay"; + } + 122 + { + title = "Spring Shell (Green)"; + sprite = "SSHLA1"; + width = 24; + height = 40; + } + 125 + { + title = "Spring Shell (Yellow)"; + sprite = "SSHLI1"; + width = 24; + height = 40; + } + 109 + { + title = "Skim"; + sprite = "SKIMA1"; + width = 16; + height = 24; + } + 113 + { + title = "Jet Jaw"; + sprite = "JJAWA3A7"; + width = 12; + height = 20; + } + 126 + { + title = "Crushstacean"; + sprite = "CRABA0"; + width = 24; + height = 32; + flags8text = "[8] Move left from spawn"; + } + 138 + { + title = "Banpyura"; + sprite = "CR2BA0"; + width = 24; + height = 32; + flags8text = "[8] Move left from spawn"; + } + 117 + { + title = "Robo-Hood"; + sprite = "ARCHA1"; + width = 24; + height = 32; + } + 118 + { + title = "Lance-a-Bot"; + sprite = "CBFSA1"; + width = 32; + height = 72; + } + 1113 + { + title = "Suspicious Lance-a-Bot Statue"; + sprite = "CBBSA1"; + width = 32; + height = 72; + } + 119 + { + title = "Egg Guard"; + sprite = "ESHIA1"; + width = 16; + height = 48; + flags1text = "[1] 90 degrees counter-clockwise"; + flags4text = "[4] 90 degrees clockwise"; + flags8text = "[8] Double speed"; + } + 115 + { + title = "Bird Aircraft Strike Hazard"; + sprite = "VLTRF1"; + width = 12; + height = 24; + } + 120 + { + title = "Green Snapper"; + sprite = "GSNPA1"; + width = 24; + height = 24; + } + 121 + { + title = "Minus"; + sprite = "MNUSA0"; + width = 24; + height = 32; + } + 134 + { + title = "Canarivore"; + sprite = "CANAA0"; + width = 12; + height = 80; + hangs = 1; + } + 123 + { + title = "Unidus"; + sprite = "UNIDA1"; + width = 18; + height = 36; + } + 135 + { + title = "Pterabyte Spawner"; + sprite = "PTERA2A8"; + width = 16; + height = 16; + parametertext = "No. Pterabytes"; + } + 136 + { + title = "Pyre Fly"; + sprite = "PYREA0"; + width = 24; + height = 34; + flags8text = "[8] Start on fire"; + } + 137 + { + title = "Dragonbomber"; + sprite = "DRABA1"; + width = 28; + height = 48; + } + 105 + { + title = "Jetty-Syn Bomber"; + sprite = "JETBB1"; + width = 20; + height = 50; + flags8text = "[8] Cannot move"; + } + 106 + { + title = "Jetty-Syn Gunner"; + sprite = "JETGB1"; + width = 20; + height = 48; + flags8text = "[8] Cannot move"; + } + 112 + { + title = "Spincushion"; + sprite = "SHRPA1"; + width = 16; + height = 24; + } + 114 + { + title = "Snailer"; + sprite = "SNLRA3A7"; + width = 24; + height = 48; + } + 129 + { + title = "Penguinator"; + sprite = "PENGA1"; + width = 24; + height = 32; + } + 130 + { + title = "Pophat"; + sprite = "POPHA1"; + width = 24; + height = 32; + } + 107 + { + title = "Crawla Commander"; + sprite = "CCOMA1"; + width = 16; + height = 32; + } + 131 + { + title = "Spinbobert"; + sprite = "SBOBB0"; + width = 32; + height = 32; + } + 132 + { + title = "Cacolantern"; + sprite = "CACOA0"; + width = 32; + height = 32; + flags8text = "[8] Cannot move"; + } + 133 + { + title = "Hangster"; + sprite = "HBATC1"; + width = 24; + height = 24; + hangs = 1; + } + 127 + { + title = "Hive Elemental"; + sprite = "HIVEA0"; + width = 32; + height = 80; + parametertext = "No. bees"; + } + 128 + { + title = "Bumblebore"; + sprite = "BUMBA1"; + width = 16; + height = 32; + } + 124 + { + title = "Buggle"; + sprite = "BBUZA1"; + width = 20; + height = 24; + } + 116 + { + title = "Pointy"; + sprite = "PNTYA1"; + width = 8; + height = 16; + } + } + + bosses + { + color = 8; // Dark_Gray + arrow = 1; + title = "Bosses"; + + 200 + { + title = "Egg Mobile"; + sprite = "EGGMA1"; + width = 24; + height = 76; + flags4text = "[4] End level on death"; + flags8text = "[8] Alternate laser attack"; + } + 201 + { + title = "Egg Slimer"; + sprite = "EGGNA1"; + width = 24; + height = 76; + flags4text = "[4] End level on death"; + flags8text = "[8] Speed up when hit"; + } + 202 + { + title = "Sea Egg"; + sprite = "EGGOA1"; + width = 32; + height = 116; + flags4text = "[4] End level on death"; + } + 203 + { + title = "Egg Colosseum"; + sprite = "EGGPA1"; + width = 24; + height = 76; + flags4text = "[4] End level on death"; + } + 204 + { + title = "Fang"; + sprite = "FANGA1"; + width = 24; + height = 60; + flags1text = "[1] Grayscale mode"; + flags4text = "[4] End level on death"; + } + 206 + { + title = "Brak Eggman (Old)"; + sprite = "BRAKB1"; + width = 48; + height = 160; + flags4text = "[4] End level on death"; + } + 207 + { + title = "Metal Sonic (Race)"; + sprite = "METLI1"; + width = 16; + height = 48; + flags1text = "[1] Grayscale mode"; + } + 208 + { + title = "Metal Sonic (Battle)"; + sprite = "METLC1"; + width = 16; + height = 48; + flags1text = "[1] Grayscale mode"; + flags4text = "[4] End level on death"; + } + 209 + { + title = "Brak Eggman"; + sprite = "BRAK01"; + width = 48; + height = 160; + flags1text = "[1] No origin-fling death"; + flags4text = "[4] End level on death"; + flags8text = "[8] Electric barrier"; + } + 290 + { + arrow = 0; + title = "Boss Escape Point"; + width = 8; + height = 16; + sprite = "internal:eggmanend"; + } + 291 + { + arrow = 0; + title = "Egg Capsule Center"; + width = 8; + height = 16; + sprite = "internal:capsule"; + } + 292 + { + arrow = 0; + title = "Boss Waypoint"; + width = 8; + height = 16; + flags8text = "[8] Sea Egg shooting point"; + sprite = "internal:eggmanway"; + angletext = "No. (Sea Egg)"; + flagsvaluetext = "No. (Brak)"; + parametertext = "Next"; + } + 293 + { + title = "Metal Sonic Gather Point"; + sprite = "internal:metal"; + width = 8; + height = 16; + } + 294 + { + title = "Fang Waypoint"; + flags8text = "[8] Center waypoint"; + sprite = "internal:eggmanway"; + width = 8; + height = 16; + } + } + + rings + { + color = 14; // Yellow + title = "Rings and Weapon Panels"; + width = 24; + height = 24; + flags8height = 24; + flags8text = "[8] Float"; + sprite = "RINGA0"; + + 300 + { + title = "Ring"; + sprite = "RINGA0"; + width = 16; + } + 301 + { + title = "Bounce Ring"; + sprite = "internal:RNGBA0"; + } + 302 + { + title = "Rail Ring"; + sprite = "internal:RNGRA0"; + } + 303 + { + title = "Infinity Ring"; + sprite = "internal:RNGIA0"; + } + 304 + { + title = "Automatic Ring"; + sprite = "internal:RNGAA0"; + } + 305 + { + title = "Explosion Ring"; + sprite = "internal:RNGEA0"; + } + 306 + { + title = "Scatter Ring"; + sprite = "internal:RNGSA0"; + } + 307 + { + title = "Grenade Ring"; + sprite = "internal:RNGGA0"; + } + 308 + { + title = "CTF Team Ring (Red)"; + sprite = "internal:RRNGA0"; + width = 16; + } + 309 + { + title = "CTF Team Ring (Blue)"; + sprite = "internal:BRNGA0"; + width = 16; + } + 330 + { + title = "Bounce Ring Panel"; + sprite = "internal:PIKBA0"; + } + 331 + { + title = "Rail Ring Panel"; + sprite = "internal:PIKRA0"; + } + 332 + { + title = "Automatic Ring Panel"; + sprite = "internal:PIKAA0"; + } + 333 + { + title = "Explosion Ring Panel"; + sprite = "internal:PIKEA0"; + } + 334 + { + title = "Scatter Ring Panel"; + sprite = "internal:PIKSA0"; + } + 335 + { + title = "Grenade Ring Panel"; + sprite = "internal:PIKGA0"; + } + } + + collectibles + { + color = 10; // Light_Green + title = "Other Collectibles"; + width = 16; + height = 32; + sort = 1; + sprite = "CEMGA0"; + + 310 + { + title = "CTF Red Flag"; + sprite = "RFLGA0"; + width = 24; + height = 64; + } + 311 + { + title = "CTF Blue Flag"; + sprite = "BFLGA0"; + width = 24; + height = 64; + } + 312 + { + title = "Emerald Token"; + sprite = "TOKEA0"; + width = 16; + height = 32; + flags8height = 24; + flags8text = "[8] Float"; + } + 313 + { + title = "Chaos Emerald 1 (Green)"; + sprite = "CEMGA0"; + } + 314 + { + title = "Chaos Emerald 2 (Purple)"; + sprite = "CEMGB0"; + } + 315 + { + title = "Chaos Emerald 3 (Blue)"; + sprite = "CEMGC0"; + } + 316 + { + title = "Chaos Emerald 4 (Cyan)"; + sprite = "CEMGD0"; + } + 317 + { + title = "Chaos Emerald 5 (Orange)"; + sprite = "CEMGE0"; + } + 318 + { + title = "Chaos Emerald 6 (Red)"; + sprite = "CEMGF0"; + } + 319 + { + title = "Chaos Emerald 7 (Gray)"; + sprite = "CEMGG0"; + } + 320 + { + title = "Emerald Hunt Location"; + sprite = "SHRDA0"; + } + 321 + { + title = "Match Chaos Emerald Spawn"; + sprite = "CEMGA0"; + flags8height = 24; + flags8text = "[8] Float"; + } + 322 + { + title = "Emblem"; + sprite = "EMBMA0"; + width = 16; + height = 30; + flags8height = 24; + flags8text = "[8] Float"; + angletext = "Tag"; + } + } + + boxes + { + color = 7; // Gray + blocking = 2; + title = "Monitors"; + width = 18; + height = 40; + flags1text = "[1] Run Linedef Executor on pop"; + flags4text = "[4] Random (Strong)"; + flags8text = "[8] Random (Weak)"; + + 400 + { + title = "Super Ring (10 Rings)"; + sprite = "TVRIA0"; + } + 401 + { + title = "Pity Shield"; + sprite = "TVPIA0"; + } + 402 + { + title = "Attraction Shield"; + sprite = "TVATA0"; + } + 403 + { + title = "Force Shield"; + sprite = "TVFOA0"; + } + 404 + { + title = "Armageddon Shield"; + sprite = "TVARA0"; + } + 405 + { + title = "Whirlwind Shield"; + sprite = "TVWWA0"; + } + 406 + { + title = "Elemental Shield"; + sprite = "TVELA0"; + } + 407 + { + title = "Super Sneakers"; + sprite = "TVSSA0"; + } + 408 + { + title = "Invincibility"; + sprite = "TVIVA0"; + } + 409 + { + title = "Extra Life"; + sprite = "TV1UA0"; + flags4text = "[4] Random (Strong) / 10k points"; + flags8text = "[8] Random (Weak) / 10k points"; + } + 410 + { + title = "Eggman"; + sprite = "TVEGA0"; + flags4text = "[4] Special"; + flags8text = "[8] Ambush"; + } + 411 + { + title = "Teleporter"; + sprite = "TVMXA0"; + } + 413 + { + title = "Gravity Boots"; + sprite = "TVGVA0"; + flags4text = "[4] Special"; + flags8text = "[8] Ambush"; + } + 414 + { + title = "CTF Team Ring Monitor (Red)"; + sprite = "TRRIA0"; + flags4text = "[4] Special"; + flags8text = "[8] Ambush"; + } + 415 + { + title = "CTF Team Ring Monitor (Blue)"; + sprite = "TBRIA0"; + flags4text = "[4] Special"; + flags8text = "[8] Ambush"; + } + 416 + { + title = "Recycler"; + sprite = "TVRCA0"; + } + 418 + { + title = "Score (1,000 Points)"; + sprite = "TV1KA0"; + flags4text = "[4] Special"; + flags8text = "[8] Ambush"; + } + 419 + { + title = "Score (10,000 Points)"; + sprite = "TVTKA0"; + flags4text = "[4] Special"; + flags8text = "[8] Ambush"; + } + 420 + { + title = "Flame Shield"; + sprite = "TVFLA0"; + } + 421 + { + title = "Water Shield"; + sprite = "TVBBA0"; + } + 422 + { + title = "Lightning Shield"; + sprite = "TVZPA0"; + } + } + + boxes2 + { + color = 18; // Gold + blocking = 2; + title = "Monitors (Respawning)"; + width = 20; + height = 44; + flags1text = "[1] Run Linedef Executor on pop"; + + 431 + { + title = "Pity Shield (Respawn)"; + sprite = "TVPIB0"; + } + 432 + { + title = "Attraction Shield (Respawn)"; + sprite = "TVATB0"; + } + 433 + { + title = "Force Shield (Respawn)"; + sprite = "TVFOB0"; + } + 434 + { + title = "Armageddon Shield (Respawn)"; + sprite = "TVARB0"; + } + 435 + { + title = "Whirlwind Shield (Respawn)"; + sprite = "TVWWB0"; + } + 436 + { + title = "Elemental Shield (Respawn)"; + sprite = "TVELB0"; + } + 437 + { + title = "Super Sneakers (Respawn)"; + sprite = "TVSSB0"; + } + 438 + { + title = "Invincibility (Respawn)"; + sprite = "TVIVB0"; + } + 440 + { + title = "Eggman (Respawn)"; + sprite = "TVEGB0"; + } + 443 + { + title = "Gravity Boots (Respawn)"; + sprite = "TVGVB0"; + } + 450 + { + title = "Flame Shield (Respawn)"; + sprite = "TVFLB0"; + } + 451 + { + title = "Water Shield (Respawn)"; + sprite = "TVBBB0"; + } + 452 + { + title = "Lightning Shield (Respawn)"; + sprite = "TVZPB0"; + } + } + + generic + { + color = 11; // Light_Cyan + title = "Generic Items & Hazards"; + + 500 + { + title = "Air Bubble Patch"; + sprite = "BUBLE0"; + width = 8; + height = 16; + flags8text = "[8] No distance check"; + } + 501 + { + title = "Signpost"; + sprite = "SIGND0"; + width = 8; + height = 32; + } + 502 + { + arrow = 1; + title = "Star Post"; + sprite = "STPTA0M0"; + width = 64; + height = 128; + angletext = "Angle/Order"; + } + 520 + { + title = "Bomb Sphere"; + sprite = "SPHRD0"; + width = 16; + height = 24; + flags8height = 24; + flags8text = "[8] Float"; + unflippable = true; + } + 521 + { + title = "Spikeball"; + sprite = "SPIKA0"; + width = 12; + height = 8; + flags8height = 24; + flags8text = "[8] Float"; + } + 522 + { + title = "Wall Spike"; + sprite = "WSPKALAR"; + width = 16; + height = 14; + flags1text = "[1] Start retracted"; + flags4text = "[4] Retractable"; + flags8text = "[8] Intangible"; + parametertext = "Initial delay"; + } + 523 + { + title = "Spike"; + sprite = "USPKA0"; + width = 8; + height = 32; + flags1text = "[1] Start retracted"; + flags4text = "[4] Retractable"; + flags8text = "[8] Intangible"; + angletext = "Retraction interval"; + parametertext = "Initial delay"; + } + 1130 + { + title = "Small Mace"; + sprite = "SMCEA0"; + width = 17; + height = 34; + } + 1131 + { + title = "Big Mace"; + sprite = "BMCEA0"; + width = 34; + height = 68; + } + 1136 + { + title = "Small Fireball"; + sprite = "SFBRA0"; + width = 17; + height = 34; + } + 1137 + { + title = "Large Fireball"; + sprite = "BFBRA0"; + width = 34; + height = 68; + } + } + + springs + { + color = 12; // Light_Red + title = "Springs and Fans"; + width = 20; + height = 16; + sprite = "RSPRD2"; + + 540 + { + title = "Fan"; + sprite = "FANSA0D0"; + width = 16; + height = 8; + flags4text = "[4] Invisible"; + flags8text = "[8] No distance check"; + angletext = "Lift height"; + } + 541 + { + title = "Gas Jet"; + sprite = "STEMD0"; + flags8text = "[8] No sounds"; + width = 32; + } + 542 + { + title = "Bumper"; + sprite = "BUMPA0"; + width = 32; + height = 64; + angletext = "Strength"; + } + 543 + { + title = "Balloon"; + sprite = "BLONA0"; + width = 32; + height = 64; + flags8text = "[8] Respawn"; + angletext = "Color"; + } + 550 + { + title = "Yellow Spring"; + sprite = "SPRYA0"; + } + 551 + { + title = "Red Spring"; + sprite = "SPRRA0"; + } + 552 + { + title = "Blue Spring"; + sprite = "SPRBA0"; + } + 555 + { + arrow = 1; + title = "Diagonal Yellow Spring"; + sprite = "YSPRD2"; + width = 16; + flags4text = "[4] Ignore gravity"; + flags8text = "[8] Rotate 22.5° CCW"; + } + 556 + { + arrow = 1; + title = "Diagonal Red Spring"; + sprite = "RSPRD2"; + width = 16; + flags4text = "[4] Ignore gravity"; + flags8text = "[8] Rotate 22.5° CCW"; + } + 557 + { + arrow = 1; + title = "Diagonal Blue Spring"; + sprite = "BSPRD2"; + width = 16; + flags4text = "[4] Ignore gravity"; + flags8text = "[8] Rotate 22.5° CCW"; + } + 558 + { + arrow = 1; + title = "Horizontal Yellow Spring"; + sprite = "SSWYD2D8"; + flags8height = 16; + flags8text = "[8] Float"; + width = 16; + height = 32; + } + 559 + { + arrow = 1; + title = "Horizontal Red Spring"; + sprite = "SSWRD2D8"; + flags8height = 16; + flags8text = "[8] Float"; + width = 16; + height = 32; + } + 560 + { + arrow = 1; + title = "Horizontal Blue Spring"; + sprite = "SSWBD2D8"; + flags8height = 16; + flags8text = "[8] Float"; + width = 16; + height = 32; + } + 1134 + { + title = "Yellow Spring Ball"; + sprite = "YSPBA0"; + width = 17; + height = 34; + } + 1135 + { + title = "Red Spring Ball"; + sprite = "RSPBA0"; + width = 17; + height = 34; + } + 544 + { + arrow = 1; + title = "Yellow Boost Panel"; + sprite = "BSTYA0"; + flags8text = "[8] Force spin"; + width = 28; + height = 2; + } + 545 + { + arrow = 1; + title = "Red Boost Panel"; + sprite = "BSTRA0"; + flags8text = "[8] Force spin"; + width = 28; + height = 2; + } + } + + patterns + { + color = 5; // Magenta + arrow = 1; + title = "Special Placement Patterns"; + width = 16; + height = 384; + sprite = "RINGA0"; + + 600 + { + arrow = 0; + title = "5 Vertical Rings (Yellow Spring)"; + sprite = "RINGA0"; + } + 601 + { + arrow = 0; + title = "5 Vertical Rings (Red Spring)"; + sprite = "RINGA0"; + height = 1024; + } + 602 + { + title = "5 Diagonal Rings (Yellow Spring)"; + sprite = "RINGA0"; + height = 32; + } + 603 + { + title = "10 Diagonal Rings (Red Spring)"; + sprite = "RINGA0"; + height = 32; + } + 604 + { + title = "Circle of Rings"; + sprite = "RINGA0"; + width = 96; + height = 192; + unflippable = true; + centerHitbox = true; + } + 605 + { + title = "Circle of Rings (Big)"; + sprite = "RINGA0"; + width = 192; + unflippable = true; + centerHitbox = true; + } + 606 + { + title = "Circle of Blue Spheres"; + sprite = "SPHRA0"; + width = 96; + height = 192; + unflippable = true; + centerHitbox = true; + } + 607 + { + title = "Circle of Blue Spheres (Big)"; + sprite = "SPHRA0"; + width = 192; + unflippable = true; + centerHitbox = true; + } + 608 + { + title = "Circle of Rings and Spheres"; + sprite = "SPHRA0"; + width = 96; + height = 192; + unflippable = true; + centerHitbox = true; + } + 609 + { + title = "Circle of Rings and Spheres (Big)"; + sprite = "SPHRA0"; + width = 192; + unflippable = true; + centerHitbox = true; + } + } + + invisible + { + color = 15; // White + title = "Misc. Invisible"; + width = 8; + height = 16; + sprite = "UNKNA0"; + + 700 + { + title = "Water Ambience A (Large)"; + sprite = "internal:ambiance"; + } + + 701 + { + title = "Water Ambience B (Large)"; + sprite = "internal:ambiance"; + } + + 702 + { + title = "Water Ambience C (Medium)"; + sprite = "internal:ambiance"; + } + + 703 + { + title = "Water Ambience D (Medium)"; + sprite = "internal:ambiance"; + } + + 704 + { + title = "Water Ambience E (Small)"; + sprite = "internal:ambiance"; + } + + 705 + { + title = "Water Ambience F (Small)"; + sprite = "internal:ambiance"; + } + + 706 + { + title = "Water Ambience G (Extra Large)"; + sprite = "internal:ambiance"; + } + + 707 + { + title = "Water Ambience H (Extra Large)"; + sprite = "internal:ambiance"; + } + + 708 + { + title = "Disco Ambience"; + sprite = "internal:ambiance"; + } + + 709 + { + title = "Volcano Ambience"; + sprite = "internal:ambiance"; + } + + 710 + { + title = "Machine Ambience"; + sprite = "internal:ambiance"; + } + + 750 + { + title = "Slope Vertex"; + sprite = "internal:vertexslope"; + angletext = "Tag"; + } + + 751 + { + arrow = 1; + title = "Teleport Destination"; + sprite = "internal:tele"; + } + + 752 + { + arrow = 1; + title = "Alternate View Point"; + sprite = "internal:view"; + } + + 753 + { + title = "Zoom Tube Waypoint"; + sprite = "internal:zoom"; + angletext = "Order"; + } + + 754 + { + title = "Push Point"; + flags4text = "[4] Fades using XY"; + flags8text = "[8] Push using XYZ"; + sprite = "GWLGA0"; + angletext = "Radius"; + } + 755 + { + title = "Pull Point"; + flags4text = "[4] Fades using XY"; + flags8text = "[8] Pull using XYZ"; + sprite = "GWLRA0"; + angletext = "Radius"; + } + 756 + { + title = "Blast Linedef Executor"; + sprite = "TOADA0"; + width = 32; + height = 16; + } + 757 + { + title = "Fan Particle Generator"; + sprite = "PRTLA0"; + width = 8; + height = 16; + angletext = "Tag"; + } + 758 + { + title = "Object Angle Anchor"; + sprite = "internal:view"; + } + 760 + { + title = "PolyObject Anchor"; + sprite = "internal:polyanchor"; + angletext = "ID"; + } + + 761 + { + title = "PolyObject Spawn Point"; + sprite = "internal:polycenter"; + angletext = "ID"; + } + + 762 + { + title = "PolyObject Spawn Point (Crush)"; + sprite = "internal:polycentercrush"; + angletext = "ID"; + } + 780 + { + title = "Skybox View Point"; + sprite = "internal:skyb"; + flags4text = "[4] In-map centerpoint"; + parametertext = "ID"; + } + } + + greenflower + { + color = 10; // Green + title = "Greenflower"; + + 800 + { + title = "GFZ Flower"; + sprite = "FWR1A0"; + width = 16; + height = 40; + } + 801 + { + title = "Sunflower"; + sprite = "FWR2A0"; + width = 16; + height = 96; + } + 802 + { + title = "Budding Flower"; + sprite = "FWR3A0"; + width = 8; + height = 32; + } + 803 + { + title = "Blueberry Bush"; + sprite = "BUS3A0"; + width = 16; + height = 32; + } + 804 + { + title = "Berry Bush"; + sprite = "BUS1A0"; + width = 16; + height = 32; + } + 805 + { + title = "Bush"; + sprite = "BUS2A0"; + width = 16; + height = 32; + } + 806 + { + title = "GFZ Tree"; + sprite = "TRE1A0"; + width = 20; + height = 128; + } + 807 + { + title = "GFZ Berry Tree"; + sprite = "TRE1B0"; + width = 20; + height = 128; + } + 808 + { + title = "GFZ Cherry Tree"; + sprite = "TRE1C0"; + width = 20; + height = 128; + } + 809 + { + title = "Checkered Tree"; + sprite = "TRE2A0"; + width = 20; + height = 200; + } + 810 + { + title = "Checkered Tree (Sunset)"; + sprite = "TRE2B0"; + width = 20; + height = 200; + } + 811 + { + title = "Polygon Tree"; + sprite = "TRE4A0"; + width = 20; + height = 200; + } + 812 + { + title = "Bush Tree"; + sprite = "TRE5A0"; + width = 20; + height = 200; + } + 813 + { + title = "Red Bush Tree"; + sprite = "TRE5B0"; + width = 20; + height = 200; + } + } + + technohill + { + color = 10; // Green + title = "Techno Hill"; + + 900 + { + title = "THZ Steam Flower"; + sprite = "THZPA0"; + width = 8; + height = 32; + } + 901 + { + title = "Alarm"; + sprite = "ALRMA0"; + width = 8; + height = 16; + hangs = 1; + } + 902 + { + title = "THZ Spin Flower (Red)"; + sprite = "FWR5A0"; + width = 16; + height = 64; + } + 903 + { + title = "THZ Spin Flower (Yellow)"; + sprite = "FWR6A0"; + width = 16; + height = 64; + } + 904 + { + arrow = 1; + title = "Whistlebush"; + sprite = "THZTA0"; + width = 16; + height = 64; + } + } + + deepsea + { + color = 10; // Green + title = "Deep Sea"; + + 1000 + { + arrow = 1; + blocking = 2; + title = "Gargoyle"; + sprite = "GARGA1"; + width = 16; + height = 40; + flags4text = "[4] Slides when pushed"; + flags8text = "[8] Not pushable"; + } + 1009 + { + arrow = 1; + blocking = 2; + title = "Gargoyle (Big)"; + sprite = "GARGB1"; + width = 32; + height = 80; + flags4text = "[4] Slides when pushed"; + flags8text = "[8] Not pushable"; + } + 1001 + { + title = "Seaweed"; + sprite = "SEWEA0"; + width = 24; + height = 56; + } + 1002 + { + title = "Dripping Water"; + sprite = "DRIPD0"; + width = 8; + height = 16; + hangs = 1; + angletext = "Dripping interval"; + } + 1003 + { + title = "Coral (Green)"; + sprite = "CORLA0"; + width = 29; + height = 40; + } + 1004 + { + title = "Coral (Red)"; + sprite = "CORLB0"; + width = 30; + height = 53; + } + 1005 + { + title = "Coral (Orange)"; + sprite = "CORLC0"; + width = 28; + height = 41; + } + 1006 + { + title = "Blue Crystal"; + sprite = "BCRYA1"; + width = 8; + height = 16; + } + 1007 + { + title = "Kelp"; + sprite = "KELPA0"; + width = 16; + height = 292; + flags4text = "[4] Double size"; + } + 1008 + { + title = "Stalagmite (DSZ1)"; + sprite = "DSTGA0"; + width = 8; + height = 116; + flags4text = "[4] Double size"; + } + 1010 + { + arrow = 1; + title = "Light Beam"; + sprite = "LIBEARAL"; + width = 16; + height = 16; + } + 1011 + { + title = "Stalagmite (DSZ2)"; + sprite = "DSTGA0"; + width = 8; + height = 116; + flags4text = "[4] Double size"; + } + 1012 + { + arrow = 1; + title = "Big Floating Mine"; + width = 28; + height = 56; + sprite = "BMNEA1"; + } + 1013 + { + title = "Animated Kelp"; + sprite = "ALGAA0"; + width = 48; + height = 120; + } + 1014 + { + title = "Large Coral (Brown)"; + sprite = "CORLD0"; + width = 56; + height = 112; + } + 1015 + { + title = "Large Coral (Beige)"; + sprite = "CORLE0"; + width = 56; + height = 112; + } + } + + castleeggman + { + color = 10; // Green + title = "Castle Eggman"; + + 1100 + { + title = "Chain (Decorative)"; + sprite = "CHANA0"; + width = 4; + height = 128; + hangs = 1; + } + 1101 + { + title = "Torch"; + sprite = "FLAMA0E0"; + width = 8; + height = 32; + flags1text = "[1] Add corona"; + } + 1102 + { + arrow = 1; + blocking = 2; + title = "Eggman Statue"; + sprite = "ESTAA1"; + width = 32; + height = 240; + flags1text = "[1] Solid gold"; + flags4text = "[4] Slides when pushed"; + flags8text = "[8] Not pushable"; + } + 1103 + { + title = "CEZ Flower"; + sprite = "FWR4A0"; + width = 16; + height = 40; + } + 1104 + { + title = "Mace Spawnpoint"; + sprite = "SMCEA0"; + width = 17; + height = 34; + flags4text = "[4] No sounds"; + flags8text = "[8] Double size"; + angletext = "Tag"; + } + 1105 + { + title = "Chain with Maces Spawnpoint"; + sprite = "SMCEA0"; + width = 17; + height = 34; + flags4text = "[4] No sounds"; + flags8text = "[8] Double size"; + angletext = "Tag"; + } + 1106 + { + title = "Chained Spring Spawnpoint"; + sprite = "YSPBA0"; + width = 17; + height = 34; + flags4text = "[4] No sounds"; + flags8text = "[8] Red spring"; + angletext = "Tag"; + } + 1107 + { + title = "Chain Spawnpoint"; + sprite = "BMCHA0"; + width = 17; + height = 34; + flags8text = "[8] Double size"; + angletext = "Tag"; + } + 1108 + { + arrow = 1; + title = "Hidden Chain Spawnpoint"; + sprite = "internal:chain3"; + width = 17; + height = 34; + flags8text = "[8] Double size"; + } + 1109 + { + title = "Firebar Spawnpoint"; + sprite = "BFBRA0"; + width = 17; + height = 34; + flags4text = "[4] No sounds"; + flags8text = "[8] Double size"; + angletext = "Tag"; + } + 1110 + { + title = "Custom Mace Spawnpoint"; + sprite = "SMCEA0"; + width = 17; + height = 34; + flags4text = "[4] No sounds"; + angletext = "Tag"; + } + 1111 + { + arrow = 1; + blocking = 2; + title = "Crawla Statue"; + sprite = "CSTAA1"; + width = 16; + height = 40; + flags4text = "[4] Slides when pushed"; + flags8text = "[8] Not pushable"; + } + 1112 + { + arrow = 1; + blocking = 2; + title = "Lance-a-Bot Statue"; + sprite = "CBBSA1"; + width = 32; + height = 72; + flags4text = "[4] Slides when pushed"; + flags8text = "[8] Not pushable"; + } + 1114 + { + title = "Pine Tree"; + sprite = "PINEA0"; + width = 16; + height = 628; + } + 1115 + { + title = "CEZ Shrub (Small)"; + sprite = "CEZBA0"; + width = 16; + height = 24; + } + 1116 + { + title = "CEZ Shrub (Large)"; + sprite = "CEZBB0"; + width = 32; + height = 48; + } + 1117 + { + arrow = 1; + title = "Pole Banner (Red)"; + sprite = "BANRA0"; + width = 40; + height = 224; + } + 1118 + { + arrow = 1; + title = "Pole Banner (Blue)"; + sprite = "BANRA0"; + width = 40; + height = 224; + } + 1119 + { + title = "Candle"; + sprite = "CNDLA0"; + width = 8; + height = 48; + flags1text = "[1] Add corona"; + } + 1120 + { + title = "Candle Pricket"; + sprite = "CNDLB0"; + width = 8; + height = 176; + flags1text = "[1] Add corona"; + } + 1121 + { + title = "Flame Holder"; + sprite = "FLMHA0"; + width = 24; + height = 80; + flags1text = "[1] Add corona"; + flags4text = "[4] No flame"; + } + 1122 + { + title = "Fire Torch"; + sprite = "CTRCA0"; + width = 16; + height = 80; + } + 1123 + { + title = "Cannonball Launcher"; + sprite = "internal:cannonball"; + width = 8; + height = 16; + } + 1124 + { + blocking = 2; + title = "Cannonball"; + sprite = "CBLLA0"; + width = 20; + height = 40; + flags4text = "[4] Slides when pushed"; + flags8text = "[8] Not pushable"; + } + 1125 + { + title = "Brambles"; + sprite = "CABRALAR"; + width = 48; + height = 32; + } + 1126 + { + title = "Invisible Lockon Object"; + sprite = "LCKNC0"; + width = 16; + height = 32; + } + 1127 + { + title = "Spectator Eggrobo"; + sprite = "EGR1A1"; + width = 20; + height = 72; + } + 1128 + { + arrow = 1; + title = "Waving Flag (Red)"; + sprite = "CFLGA0"; + width = 8; + height = 208; + } + 1129 + { + arrow = 1; + title = "Waving Flag (Blue)"; + sprite = "CFLGA0"; + width = 8; + height = 208; + } + } + + aridcanyon + { + color = 10; // Green + title = "Arid Canyon"; + + 1200 + { + title = "Tumbleweed (Big)"; + sprite = "BTBLA0"; + width = 24; + height = 48; + flags8text = "[8] Moves perpetually"; + } + 1201 + { + title = "Tumbleweed (Small)"; + sprite = "STBLA0"; + width = 12; + height = 24; + flags8text = "[8] Moves perpetually"; + } + 1202 + { + arrow = 1; + title = "Rock Spawner"; + sprite = "ROIAA0"; + width = 8; + height = 16; + angletext = "Tag"; + } + 1203 + { + title = "Tiny Red Flower Cactus"; + sprite = "CACTA0"; + width = 13; + height = 24; + } + 1204 + { + title = "Small Red Flower Cactus"; + sprite = "CACTB0"; + width = 15; + height = 52; + } + 1205 + { + title = "Tiny Blue Flower Cactus"; + sprite = "CACTC0"; + width = 13; + height = 24; + } + 1206 + { + title = "Small Blue Flower Cactus"; + sprite = "CACTD0"; + width = 15; + height = 52; + } + 1207 + { + title = "Prickly Pear"; + sprite = "CACTE0"; + width = 32; + height = 96; + } + 1208 + { + title = "Barrel Cactus"; + sprite = "CACTF0"; + width = 20; + height = 128; + } + 1209 + { + title = "Tall Barrel Cactus"; + sprite = "CACTG0"; + width = 24; + height = 224; + } + 1210 + { + title = "Armed Cactus"; + sprite = "CACTH0"; + width = 24; + height = 256; + } + 1211 + { + title = "Ball Cactus"; + sprite = "CACTI0"; + width = 48; + height = 96; + } + 1212 + { + title = "Caution Sign"; + sprite = "WWSGAR"; + width = 22; + height = 64; + } + 1213 + { + title = "Cacti Sign"; + sprite = "WWS2AR"; + width = 22; + height = 64; + } + 1214 + { + title = "Sharp Turn Sign"; + sprite = "WWS3ALAR"; + width = 16; + height = 192; + } + 1215 + { + title = "Mine Oil Lamp"; + sprite = "OILLA0"; + width = 22; + height = 64; + hangs = 1; + } + 1216 + { + title = "TNT Barrel"; + sprite = "BARRA1"; + width = 24; + height = 63; + } + 1217 + { + title = "TNT Proximity Shell"; + sprite = "REMTA0"; + width = 64; + height = 40; + } + 1218 + { + title = "Dust Devil"; + sprite = "TAZDCR"; + width = 80; + height = 416; + } + 1219 + { + title = "Minecart Spawner"; + sprite = "MCRTCLFR"; + width = 22; + height = 32; + } + 1220 + { + title = "Minecart Stopper"; + sprite = "MCRTIR"; + width = 32; + height = 32; + } + 1221 + { + title = "Minecart Saloon Door"; + sprite = "SALDARAL"; + width = 96; + height = 160; + flags8text = "[8] Allow non-minecart players"; + } + 1222 + { + title = "Train Cameo Spawner"; + sprite = "TRAEBRBL"; + width = 28; + height = 32; + } + 1223 + { + title = "Train Dust Spawner"; + sprite = "ADSTA0"; + width = 4; + height = 4; + } + 1224 + { + title = "Train Steam Spawner"; + sprite = "STEAA0"; + width = 4; + height = 4; + } + 1229 + { + title = "Minecart Switch Point"; + sprite = "internal:zoom"; + width = 8; + height = 16; + flags8text = "[8] Enable switching"; + } + 1230 + { + title = "Tiny Cactus"; + sprite = "CACTJ0"; + width = 13; + height = 28; + } + 1231 + { + title = "Small Cactus"; + sprite = "CACTK0"; + width = 15; + height = 60; + } + } + + redvolcano + { + color = 10; // Green + title = "Red Volcano"; + + 1300 + { + arrow = 1; + title = "Flame Jet (Horizontal)"; + sprite = "internal:flameh"; + width = 16; + height = 40; + flags8text = "[8] Waves vertically"; + angletext = "On/Off time"; + parametertext = "Strength"; + } + 1301 + { + title = "Flame Jet (Vertical)"; + sprite = "internal:flamev"; + width = 16; + height = 40; + flags8text = "[8] Shoot downwards"; + angletext = "On/Off time"; + parametertext = "Strength"; + } + 1302 + { + title = "Spinning Flame Jet (Counter-Clockwise)"; + sprite = "internal:flame2"; + width = 16; + height = 24; + } + 1303 + { + title = "Spinning Flame Jet (Clockwise)"; + sprite = "internal:flame1"; + width = 16; + height = 24; + } + 1304 + { + title = "Lavafall"; + sprite = "LFALF0"; + width = 30; + height = 32; + angletext = "Initial delay"; + flags8text = "[8] Double size"; + } + 1305 + { + title = "Rollout Rock"; + sprite = "PUMIA1A5"; + width = 30; + height = 60; + flags8text = "[8] Non-buoyant"; + } + 1306 + { + title = "Big Fern"; + sprite = "JPLAB0"; + width = 32; + height = 48; + } + 1307 + { + title = "Jungle Palm"; + sprite = "JPLAC0"; + width = 32; + height = 48; + } + 1308 + { + title = "Torch Flower"; + sprite = "TFLOA0"; + width = 14; + height = 110; + } + 1309 + { + title = "RVZ1 Wall Vine (Long)"; + sprite = "WVINALAR"; + width = 1; + height = 288; + } + 1310 + { + title = "RVZ1 Wall Vine (Short)"; + sprite = "WVINBLBR"; + width = 1; + height = 288; + } + } + + botanicserenity + { + color = 10; // Green + title = "Botanic Serenity"; + width = 16; + height = 32; + sprite = "BSZ1A0"; + 1400 + { + title = "Tall Flower (Red)"; + sprite = "BSZ1A0"; + } + 1401 + { + title = "Tall Flower (Purple)"; + sprite = "BSZ1B0"; + } + 1402 + { + title = "Tall Flower (Blue)"; + sprite = "BSZ1C0"; + } + 1403 + { + title = "Tall Flower (Cyan)"; + sprite = "BSZ1D0"; + } + 1404 + { + title = "Tall Flower (Yellow)"; + sprite = "BSZ1E0"; + } + 1405 + { + title = "Tall Flower (Orange)"; + sprite = "BSZ1F0"; + } + 1410 + { + title = "Medium Flower (Red)"; + sprite = "BSZ2A0"; + } + 1411 + { + title = "Medium Flower (Purple)"; + sprite = "BSZ2B0"; + } + 1412 + { + title = "Medium Flower (Blue)"; + sprite = "BSZ2C0"; + } + 1413 + { + title = "Medium Flower (Cyan)"; + sprite = "BSZ2D0"; + } + 1414 + { + title = "Medium Flower (Yellow)"; + sprite = "BSZ2E0"; + } + 1415 + { + title = "Medium Flower (Orange)"; + sprite = "BSZ2F0"; + } + 1420 + { + title = "Short Flower (Red)"; + sprite = "BSZ3A0"; + } + 1421 + { + title = "Short Flower (Purple)"; + sprite = "BSZ3B0"; + } + 1422 + { + title = "Short Flower (Blue)"; + sprite = "BSZ3C0"; + } + 1423 + { + title = "Short Flower (Cyan)"; + sprite = "BSZ3D0"; + } + 1424 + { + title = "Short Flower (Yellow)"; + sprite = "BSZ3E0"; + } + 1425 + { + title = "Short Flower (Orange)"; + sprite = "BSZ3F0"; + } + 1430 + { + title = "Tulip (Red)"; + sprite = "BST1A0"; + } + 1431 + { + title = "Tulip (Purple)"; + sprite = "BST2A0"; + } + 1432 + { + title = "Tulip (Blue)"; + sprite = "BST3A0"; + } + 1433 + { + title = "Tulip (Cyan)"; + sprite = "BST4A0"; + } + 1434 + { + title = "Tulip (Yellow)"; + sprite = "BST5A0"; + } + 1435 + { + title = "Tulip (Orange)"; + sprite = "BST6A0"; + } + 1440 + { + title = "Cluster (Red)"; + sprite = "BSZ5A0"; + } + 1441 + { + title = "Cluster (Purple)"; + sprite = "BSZ5B0"; + } + 1442 + { + title = "Cluster (Blue)"; + sprite = "BSZ5C0"; + } + 1443 + { + title = "Cluster (Cyan)"; + sprite = "BSZ5D0"; + } + 1444 + { + title = "Cluster (Yellow)"; + sprite = "BSZ5E0"; + } + 1445 + { + title = "Cluster (Orange)"; + sprite = "BSZ5F0"; + } + 1450 + { + title = "Bush (Red)"; + sprite = "BSZ6A0"; + } + 1451 + { + title = "Bush (Purple)"; + sprite = "BSZ6B0"; + } + 1452 + { + title = "Bush (Blue)"; + sprite = "BSZ6C0"; + } + 1453 + { + title = "Bush (Cyan)"; + sprite = "BSZ6D0"; + } + 1454 + { + title = "Bush (Yellow)"; + sprite = "BSZ6E0"; + } + 1455 + { + title = "Bush (Orange)"; + sprite = "BSZ6F0"; + } + 1460 + { + title = "Vine (Red)"; + sprite = "BSZ7A0"; + } + 1461 + { + title = "Vine (Purple)"; + sprite = "BSZ7B0"; + } + 1462 + { + title = "Vine (Blue)"; + sprite = "BSZ7C0"; + } + 1463 + { + title = "Vine (Cyan)"; + sprite = "BSZ7D0"; + } + 1464 + { + title = "Vine (Yellow)"; + sprite = "BSZ7E0"; + } + 1465 + { + title = "Vine (Orange)"; + sprite = "BSZ7F0"; + } + 1470 + { + title = "BSZ Shrub"; + sprite = "BSZ8A0"; + } + 1471 + { + title = "BSZ Clover"; + sprite = "BSZ8B0"; + } + 1473 + { + title = "Palm Tree (Big)"; + width = 16; + height = 160; + sprite = "BSZ8D0"; + } + 1475 + { + title = "Palm Tree (Small)"; + width = 16; + height = 80; + sprite = "BSZ8F0"; + } + } + + azuretemple + { + color = 10; // Green + title = "Azure Temple"; + + 1500 + { + arrow = 1; + blocking = 2; + title = "Glaregoyle"; + sprite = "BGARA1"; + width = 16; + height = 40; + flags4text = "[4] Slides when pushed"; + flags8text = "[8] Not pushable"; + } + 1501 + { + arrow = 1; + blocking = 2; + title = "Glaregoyle (Up)"; + sprite = "BGARA1"; + width = 16; + height = 40; + flags4text = "[4] Slides when pushed"; + flags8text = "[8] Not pushable"; + } + 1502 + { + arrow = 1; + blocking = 2; + title = "Glaregoyle (Down)"; + sprite = "BGARA1"; + width = 16; + height = 40; + flags4text = "[4] Slides when pushed"; + flags8text = "[8] Not pushable"; + } + 1503 + { + arrow = 1; + blocking = 2; + title = "Glaregoyle (Long)"; + sprite = "BGARA1"; + width = 16; + height = 40; + flags4text = "[4] Slides when pushed"; + flags8text = "[8] Not pushable"; + } + 1504 + { + title = "ATZ Target"; + sprite = "RCRYB0"; + width = 24; + height = 32; + } + 1505 + { + title = "Green Flame"; + sprite = "CFLMA0E0"; + width = 8; + height = 32; + } + 1506 + { + arrow = 1; + blocking = 2; + title = "Blue Gargoyle"; + sprite = "BGARD1"; + width = 16; + height = 40; + flags4text = "[4] Slides when pushed"; + flags8text = "[8] Not pushable"; + } + } + + dreamhill + { + color = 10; // Green + title = "Dream Hill"; + + 1600 + { + title = "Spring Tree"; + sprite = "TRE6A0"; + width = 16; + height = 32; + } + 1601 + { + title = "Shleep"; + sprite = "SHLPA0"; + width = 24; + height = 32; + } + 1602 + { + title = "Pian"; + sprite = "NTPNALAR"; + width = 16; + height = 32; + } + } + + nightstrk + { + color = 13; // Pink + title = "NiGHTS Track"; + width = 8; + height = 4096; + sprite = "UNKNA0"; + + 1700 + { + title = "Axis"; + sprite = "internal:axis1"; + circle = 1; + unflippable = true; + ignoreZ = true; + flagsvaluetext = "Order"; + angletext = "Radius/Direction"; + parametertext = "Mare"; + } + 1701 + { + title = "Axis Transfer"; + sprite = "internal:axis2"; + unflippable = true; + ignoreZ = true; + flagsvaluetext = "Order"; + parametertext = "Mare"; + } + 1702 + { + title = "Axis Transfer Line"; + sprite = "internal:axis3"; + unflippable = true; + ignoreZ = true; + flagsvaluetext = "Order"; + parametertext = "Mare"; + } + 1710 + { + title = "Ideya Capture"; + sprite = "CAPSA0"; + width = 72; + height = 144; + angletext = "Rings"; + parametertext = "Mare"; + } + } + + nights + { + color = 13; // Pink + title = "NiGHTS Items"; + width = 16; + height = 32; + + 1703 + { + title = "Ideya Drone"; + sprite = "NDRNA1"; + width = 16; + height = 56; + flags1text = "[1] Align player to middle"; + flags4text = "[4] Align player to top"; + flags8text = "[8] Die upon time up"; + angletext = "Time limit"; + parametertext = "Height"; + } + 1704 + { + arrow = 1; + title = "NiGHTS Bumper"; + sprite = "NBMPG3G7"; + width = 32; + height = 64; + unflippable = true; + flagsvaluetext = "Pitch"; + angletext = "Yaw"; + } + 1705 + { + arrow = 1; + title = "Hoop (Generic)"; + sprite = "HOOPA0"; + width = 80; + height = 160; + unflippable = true; + centerHitbox = true; + flagsvaluetext = "Height"; + angletext = "Pitch/Yaw"; + } + 1706 + { + title = "Blue Sphere"; + sprite = "SPHRA0"; + width = 16; + height = 24; + flags8height = 24; + flags8text = "[8] Float"; + unflippable = true; + } + 1707 + { + title = "Super Paraloop"; + sprite = "NPRUA0"; + flags4text = "[4] Bonus time only"; + flags8text = "[8] Spawn immediately"; + } + 1708 + { + title = "Drill Refill"; + sprite = "NPRUB0"; + flags4text = "[4] Bonus time only"; + flags8text = "[8] Spawn immediately"; + } + 1709 + { + title = "Nightopian Helper"; + sprite = "NPRUC0"; + flags4text = "[4] Bonus time only"; + flags8text = "[8] Spawn immediately"; + } + 1711 + { + title = "Extra Time"; + sprite = "NPRUD0"; + flags4text = "[4] Bonus time only"; + flags8text = "[8] Spawn immediately"; + } + 1712 + { + title = "Link Freeze"; + sprite = "NPRUE0"; + flags4text = "[4] Bonus time only"; + flags8text = "[8] Spawn immediately"; + } + 1713 + { + arrow = 1; + title = "Hoop (Customizable)"; + flags1text = "[1] Radius +16"; + flags2text = "[2] Radius +32"; + flags4text = "[4] Radius +64"; + flags8text = "[8] Radius +128"; + sprite = "HOOPA0"; + width = 80; + height = 160; + unflippable = true; + centerHitbox = true; + } + 1714 + { + title = "Ideya Anchor Point"; + sprite = "internal:axis1"; + width = 8; + height = 16; + parametertext = "Ideya"; + } + } + + mario + { + color = 6; // Brown + title = "Mario"; + + 1800 + { + title = "Coin"; + sprite = "COINA0"; + width = 16; + height = 24; + flags8height = 24; + flags8text = "[8] Float"; + } + 1801 + { + arrow = 1; + title = "Goomba"; + sprite = "GOOMA0"; + width = 24; + height = 32; + } + 1802 + { + arrow = 1; + title = "Goomba (Blue)"; + sprite = "BGOMA0"; + width = 24; + height = 32; + } + 1803 + { + title = "Fire Flower"; + sprite = "FFWRB0"; + width = 16; + height = 32; + } + 1804 + { + title = "Koopa Shell"; + sprite = "SHLLA1"; + width = 16; + height = 20; + } + 1805 + { + title = "Puma (Jumping Fireball)"; + sprite = "PUMAA0"; + width = 8; + height = 16; + angletext = "Jump strength"; + } + 1806 + { + title = "King Bowser"; + sprite = "KOOPA0"; + width = 16; + height = 48; + } + 1807 + { + title = "Axe"; + sprite = "MAXEA0"; + width = 8; + height = 16; + } + 1808 + { + title = "Bush (Short)"; + sprite = "MUS1A0"; + width = 16; + height = 32; + } + 1809 + { + title = "Bush (Tall)"; + sprite = "MUS2A0"; + width = 16; + height = 32; + } + 1810 + { + title = "Toad"; + sprite = "TOADA0"; + width = 8; + height = 32; + } + } + + christmasdisco + { + color = 10; // Green + title = "Christmas & Disco"; + + 1850 + { + title = "Christmas Pole"; + sprite = "XMS1A0"; + width = 16; + height = 40; + } + 1851 + { + title = "Candy Cane"; + sprite = "XMS2A0"; + width = 8; + height = 32; + } + 1852 + { + blocking = 2; + title = "Snowman"; + sprite = "XMS3A0"; + width = 16; + height = 64; + flags4text = "[4] Slides when pushed"; + flags8text = "[8] Not pushable"; + } + 1853 + { + blocking = 2; + title = "Snowman (With Hat)"; + sprite = "XMS3B0"; + width = 16; + height = 80; + flags4text = "[4] Slides when pushed"; + flags8text = "[8] Not pushable"; + } + 1854 + { + title = "Lamp Post"; + sprite = "XMS4A0"; + width = 8; + height = 120; + } + 1855 + { + title = "Lamp Post (Snow)"; + sprite = "XMS4B0"; + width = 8; + height = 120; + } + 1856 + { + title = "Hanging Star"; + sprite = "XMS5A0"; + width = 4; + height = 80; + hangs = 1; + } + 1857 + { + title = "Berry Bush (Snow)"; + sprite = "BUS1B0"; + width = 16; + height = 32; + } + 1858 + { + title = "Bush (Snow)"; + sprite = "BUS2B0"; + width = 16; + height = 32; + } + 1859 + { + title = "Blueberry Bush (Snow)"; + sprite = "BUS3B0"; + width = 16; + height = 32; + } + 1875 + { + title = "Disco Ball"; + sprite = "DBALA0"; + width = 16; + height = 54; + hangs = 1; + } + 1876 + { + arrow = 1; + blocking = 2; + title = "Eggman Disco Statue"; + sprite = "ESTAB1"; + width = 20; + height = 96; + flags4text = "[4] Slides when pushed"; + flags8text = "[8] Not pushable"; + } + } + + stalagmites + { + color = 10; // Green + title = "Stalagmites"; + width = 16; + height = 40; + + 1900 + { + title = "Brown Stalagmite (Tall)"; + sprite = "STLGA0"; + width = 16; + height = 40; + } + 1901 + { + title = "Brown Stalagmite"; + sprite = "STLGB0"; + width = 16; + height = 40; + } + 1902 + { + title = "Orange Stalagmite (Tall)"; + sprite = "STLGC0"; + width = 16; + height = 40; + } + 1903 + { + title = "Orange Stalagmite"; + sprite = "STLGD0"; + width = 16; + height = 40; + } + 1904 + { + title = "Red Stalagmite (Tall)"; + sprite = "STLGE0"; + width = 16; + height = 40; + } + 1905 + { + title = "Red Stalagmite"; + sprite = "STLGF0"; + width = 16; + height = 40; + } + 1906 + { + title = "Gray Stalagmite (Tall)"; + sprite = "STLGG0"; + width = 24; + height = 96; + } + 1907 + { + title = "Gray Stalagmite"; + sprite = "STLGH0"; + width = 16; + height = 40; + } + 1908 + { + title = "Blue Stalagmite (Tall)"; + sprite = "STLGI0"; + width = 16; + height = 40; + } + 1909 + { + title = "Blue Stalagmite"; + sprite = "STLGJ0"; + width = 16; + height = 40; + } + } + + hauntedheights + { + color = 10; // Green + title = "Haunted Heights"; + + 2000 + { + title = "Smashing Spikeball"; + sprite = "FMCEA0"; + width = 18; + height = 28; + angletext = "Initial delay"; + } + 2001 + { + title = "HHZ Grass"; + sprite = "HHZMA0"; + width = 16; + height = 40; + } + 2002 + { + title = "HHZ Tentacle 1"; + sprite = "HHZMB0"; + width = 16; + height = 40; + } + 2003 + { + title = "HHZ Tentacle 2"; + sprite = "HHZMC0"; + width = 16; + height = 40; + } + 2004 + { + title = "HHZ Stalagmite (Tall)"; + sprite = "HHZME0"; + width = 16; + height = 40; + } + 2005 + { + title = "HHZ Stalagmite (Short)"; + sprite = "HHZMF0"; + width = 16; + height = 40; + } + 2006 + { + title = "Jack-o'-lantern 1"; + sprite = "PUMKA0"; + width = 16; + height = 40; + flags1text = "Don't flicker"; + } + 2007 + { + title = "Jack-o'-lantern 2"; + sprite = "PUMKB0"; + width = 16; + height = 40; + flags1text = "Don't flicker"; + } + 2008 + { + title = "Jack-o'-lantern 3"; + sprite = "PUMKC0"; + width = 16; + height = 40; + flags1text = "Don't flicker"; + } + 2009 + { + title = "Purple Mushroom"; + sprite = "SHRMD0"; + width = 16; + height = 48; + } + 2010 + { + title = "HHZ Tree"; + sprite = "HHPLC0"; + width = 12; + height = 40; + } + } + + frozenhillside + { + color = 10; // Green + title = "Frozen Hillside"; + + 2100 + { + title = "Ice Shard (Small)"; + sprite = "FHZIA0"; + width = 8; + height = 32; + } + 2101 + { + title = "Ice Shard (Large)"; + sprite = "FHZIB0"; + width = 8; + height = 32; + } + 2102 + { + title = "Crystal Tree (Aqua)"; + sprite = "TRE3A0"; + width = 20; + height = 200; + } + 2103 + { + title = "Crystal Tree (Pink)"; + sprite = "TRE3B0"; + width = 20; + height = 200; + } + 2104 + { + title = "Amy Cameo"; + sprite = "ROSYA1"; + width = 16; + height = 48; + flags1text = "[1] Grayscale mode"; + } + 2105 + { + title = "Mistletoe"; + sprite = "XMS6A0"; + width = 52; + height = 106; + } + } + + flickies + { + color = 10; // Green + title = "Flickies"; + width = 8; + height = 20; + flags1text = "[1] Move aimlessly"; + flags4text = "[4] No movement"; + flags8text = "[8] Hop"; + angletext = "Radius"; + + 2200 + { + title = "Bluebird"; + sprite = "FL01A1"; + } + 2201 + { + title = "Rabbit"; + sprite = "FL02A1"; + } + 2202 + { + title = "Chicken"; + sprite = "FL03A1"; + } + 2203 + { + title = "Seal"; + sprite = "FL04A1"; + } + 2204 + { + title = "Pig"; + sprite = "FL05A1"; + } + 2205 + { + title = "Chipmunk"; + sprite = "FL06A1"; + } + 2206 + { + title = "Penguin"; + sprite = "FL07A1"; + } + 2207 + { + title = "Fish"; + sprite = "FL08A1"; + parametertext = "Color"; + } + 2208 + { + title = "Ram"; + sprite = "FL09A1"; + } + 2209 + { + title = "Puffin"; + sprite = "FL10A1"; + } + 2210 + { + title = "Cow"; + sprite = "FL11A1"; + } + 2211 + { + title = "Rat"; + sprite = "FL12A1"; + } + 2212 + { + title = "Bear"; + sprite = "FL13A1"; + } + 2213 + { + title = "Dove"; + sprite = "FL14A1"; + } + 2214 + { + title = "Cat"; + sprite = "FL15A1"; + } + 2215 + { + title = "Canary"; + sprite = "FL16A1"; + } + 2216 + { + title = "Spider"; + sprite = "FS01A1"; + } + 2217 + { + title = "Bat"; + sprite = "FS02A0"; + } + } +} + +//Default things filters +thingsfilters +{ + + filter0 + { + name = "Player starts"; + category = "starts"; + type = -1; + } + + + filter1 + { + name = "Enemies"; + category = "enemies"; + type = -1; + + } + + + filter2 + { + name = "NiGHTS Track"; + category = "nightstrk"; + type = -1; + + } + + + filter3 + { + name = "Normal Gravity"; + category = ""; + type = -1; + + fields + { + 2 = false; + } + + } + + + filter4 + { + name = "Reverse Gravity"; + category = ""; + type = -1; + + fields + { + 2 = true; + } + + } +} From 0d15f27026291644f1cfcf99e098d2d4346e450c Mon Sep 17 00:00:00 2001 From: Steel Titanium Date: Sat, 28 Dec 2019 21:57:29 -0500 Subject: [PATCH 482/746] 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 cfadbb0f360034ca5cbbd06cf491219251dd55d8 Mon Sep 17 00:00:00 2001 From: MascaraSnake Date: Sun, 29 Dec 2019 09:39:50 +0100 Subject: [PATCH 483/746] -Add linedef pointer to side_t, so sidedefs are able to tell if they're a front or back sidedef during setup -Fix a broken condition during setup of texture fields for the change music linedef --- src/lua_maplib.c | 5 +++++ src/p_setup.c | 16 ++++++++++++---- src/r_defs.h | 13 ++++++------- 3 files changed, 23 insertions(+), 11 deletions(-) diff --git a/src/lua_maplib.c b/src/lua_maplib.c index 8ad66d04f..8ce6551f7 100644 --- a/src/lua_maplib.c +++ b/src/lua_maplib.c @@ -134,6 +134,7 @@ enum side_e { side_toptexture, side_bottomtexture, side_midtexture, + side_line, side_sector, side_special, side_repeatcnt, @@ -869,6 +870,9 @@ static int side_get(lua_State *L) case side_midtexture: lua_pushinteger(L, side->midtexture); return 1; + case side_line: + LUA_PushUserdata(L, side->line, META_LINE); + return 1; case side_sector: LUA_PushUserdata(L, side->sector, META_SECTOR); return 1; @@ -902,6 +906,7 @@ static int side_set(lua_State *L) switch(field) { case side_valid: // valid + case side_line: case side_sector: case side_special: case side_text: diff --git a/src/p_setup.c b/src/p_setup.c index 8d92c3e87..52c79e1ce 100644 --- a/src/p_setup.c +++ b/src/p_setup.c @@ -1008,10 +1008,18 @@ static void P_InitializeLinedef(line_t *ld) CONS_Debug(DBG_SETUP, "P_InitializeLinedef: Linedef %s has two-sided flag set, but no second sidedef\n", sizeu1((size_t)(ld - lines))); } - if (ld->sidenum[0] != 0xffff && ld->special) + if (ld->sidenum[0] != 0xffff) + { sides[ld->sidenum[0]].special = ld->special; - if (ld->sidenum[1] != 0xffff && ld->special) + sides[ld->sidenum[0]].line = ld; + + } + if (ld->sidenum[1] != 0xffff) + { sides[ld->sidenum[1]].special = ld->special; + sides[ld->sidenum[1]].line = ld; + + } } static void P_LoadLinedefs(UINT8 *data) @@ -1044,6 +1052,7 @@ static void P_LoadSidedefs(UINT8 *data) for (i = 0; i < numsides; i++, sd++, msd++) { UINT16 sector_num; + boolean isfrontside = !sd->line || sd->line->sidenum[0] == i; sd->textureoffset = SHORT(msd->textureoffset)<rowoffset = SHORT(msd->rowoffset)<midtexture = get_number(process); } - // always process if back sidedef, because we need that - symbol sd->text = Z_Malloc(7, PU_LEVEL, NULL); - if (i == 1 || msd->toptexture[0] != '-' || msd->toptexture[1] != '\0') + if (isfrontside && !(msd->toptexture[0] == '-' && msd->toptexture[1] == '\0')) { M_Memcpy(process,msd->toptexture,8); process[8] = '\0'; diff --git a/src/r_defs.h b/src/r_defs.h index 353dc572b..4cb02f4f5 100644 --- a/src/r_defs.h +++ b/src/r_defs.h @@ -436,14 +436,10 @@ typedef struct line_s polyobj_t *polyobj; // Belongs to a polyobject? #endif - char *text; // a concatination of all front and back texture names, for linedef specials that require a string. + char *text; // a concatenation of all front and back texture names, for linedef specials that require a string. INT16 callcount; // no. of calls left before triggering, for the "X calls" linedef specials, defaults to 0 } line_t; -// -// The SideDef. -// - typedef struct { // add this to the calculated texture column @@ -456,13 +452,16 @@ typedef struct // We do not maintain names here. INT32 toptexture, bottomtexture, midtexture; - // Sector the SideDef is facing. + // Linedef the sidedef belongs to + line_t *line; + + // Sector the sidedef is facing. sector_t *sector; INT16 special; // the special of the linedef this side belongs to INT16 repeatcnt; // # of times to repeat midtexture - char *text; // a concatination of all top, bottom, and mid texture names, for linedef specials that require a string. + char *text; // a concatenation of all top, bottom, and mid texture names, for linedef specials that require a string. extracolormap_t *colormap_data; // storage for colormaps; not applied to sectors. } side_t; From 19aafbfd0b9bde40809ca91195d4636899504708 Mon Sep 17 00:00:00 2001 From: James R Date: Sun, 29 Dec 2019 02:14:02 -0800 Subject: [PATCH 484/746] Split map code checking from Command_Map_f --- src/d_netcmd.c | 45 +---------------------------------------- src/g_game.c | 54 ++++++++++++++++++++++++++++++++++++++++++++++++++ src/g_game.h | 3 +++ 3 files changed, 58 insertions(+), 44 deletions(-) diff --git a/src/d_netcmd.c b/src/d_netcmd.c index 262d0d1bc..80359db54 100644 --- a/src/d_netcmd.c +++ b/src/d_netcmd.c @@ -1802,18 +1802,15 @@ static void Command_Map_f(void) boolean newresetplayers; boolean mustmodifygame; - boolean usemapcode = false; INT32 newmapnum; char * mapname; - size_t mapnamelen; char *realmapname = NULL; INT32 newgametype = gametype; INT32 d; - char *p; if (client && !IsPlayerAdmin(consoleplayer)) { @@ -1873,43 +1870,8 @@ static void Command_Map_f(void) } mapname = ConcatCommandArgv(1, first_option); - mapnamelen = strlen(mapname); - if (mapnamelen == 2)/* maybe two digit code */ - { - if (( newmapnum = M_MapNumber(mapname[0], mapname[1]) )) - usemapcode = true; - } - else if (mapnamelen == 5 && strnicmp(mapname, "MAP", 3) == 0) - { - if (( newmapnum = M_MapNumber(mapname[3], mapname[4]) ) == 0) - { - CONS_Alert(CONS_ERROR, M_GetText("Invalid map code '%s'.\n"), mapname); - Z_Free(mapname); - return; - } - usemapcode = true; - } - - if (!usemapcode) - { - /* Now detect map number in base 10, which no one asked for. */ - newmapnum = strtol(mapname, &p, 10); - if (*p == '\0')/* we got it */ - { - if (newmapnum < 1 || newmapnum > NUMMAPS) - { - CONS_Alert(CONS_ERROR, M_GetText("Invalid map number %d.\n"), newmapnum); - Z_Free(mapname); - return; - } - usemapcode = true; - } - else - { - newmapnum = G_FindMap(mapname, &realmapname, NULL, NULL); - } - } + newmapnum = G_FindMapByNameOrCode(mapname, &realmapname); if (newmapnum == 0) { @@ -1918,11 +1880,6 @@ static void Command_Map_f(void) return; } - if (usemapcode) - { - realmapname = G_BuildMapTitle(newmapnum); - } - if (mustmodifygame && option_force) { G_SetGameModified(false); diff --git a/src/g_game.c b/src/g_game.c index e4caa3a36..e1a90eb71 100644 --- a/src/g_game.c +++ b/src/g_game.c @@ -4536,6 +4536,60 @@ void G_FreeMapSearch(mapsearchfreq_t *freq, INT32 freqc) Z_Free(freq); } +INT32 G_FindMapByNameOrCode(const char *mapname, char **realmapnamep) +{ + boolean usemapcode = false; + + INT32 newmapnum; + + size_t mapnamelen; + + char *p; + + mapnamelen = strlen(mapname); + + if (mapnamelen == 2)/* maybe two digit code */ + { + if (( newmapnum = M_MapNumber(mapname[0], mapname[1]) )) + usemapcode = true; + } + else if (mapnamelen == 5 && strnicmp(mapname, "MAP", 3) == 0) + { + if (( newmapnum = M_MapNumber(mapname[3], mapname[4]) ) == 0) + { + CONS_Alert(CONS_ERROR, M_GetText("Invalid map code '%s'.\n"), mapname); + return 0; + } + usemapcode = true; + } + + if (!usemapcode) + { + /* Now detect map number in base 10, which no one asked for. */ + newmapnum = strtol(mapname, &p, 10); + if (*p == '\0')/* we got it */ + { + if (newmapnum < 1 || newmapnum > NUMMAPS) + { + CONS_Alert(CONS_ERROR, M_GetText("Invalid map number %d.\n"), newmapnum); + return 0; + } + usemapcode = true; + } + else + { + newmapnum = G_FindMap(mapname, realmapnamep, NULL, NULL); + } + } + + if (usemapcode) + { + (*realmapnamep) = G_BuildMapTitle(newmapnum); + } + + return newmapnum; +} + // // DEMO RECORDING // diff --git a/src/g_game.h b/src/g_game.h index c19faebe4..596555071 100644 --- a/src/g_game.h +++ b/src/g_game.h @@ -130,6 +130,9 @@ INT32 G_FindMap(const char *query, char **foundmapnamep, mapsearchfreq_t **freqp, INT32 *freqc); void G_FreeMapSearch(mapsearchfreq_t *freq, INT32 freqc); +/* Match map name by search + 2 digit map code or map number. */ +INT32 G_FindMapByNameOrCode(const char *query, char **foundmapnamep); + // XMOD spawning mapthing_t *G_FindCTFStart(INT32 playernum); mapthing_t *G_FindMatchStart(INT32 playernum); From 2ffff56b391235257c65eb23e539926c4da6ac62 Mon Sep 17 00:00:00 2001 From: James R Date: Sun, 29 Dec 2019 02:15:48 -0800 Subject: [PATCH 485/746] Who cares? --- src/g_game.c | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/src/g_game.c b/src/g_game.c index e1a90eb71..0adedf3dc 100644 --- a/src/g_game.c +++ b/src/g_game.c @@ -4555,12 +4555,8 @@ INT32 G_FindMapByNameOrCode(const char *mapname, char **realmapnamep) } else if (mapnamelen == 5 && strnicmp(mapname, "MAP", 3) == 0) { - if (( newmapnum = M_MapNumber(mapname[3], mapname[4]) ) == 0) - { - CONS_Alert(CONS_ERROR, M_GetText("Invalid map code '%s'.\n"), mapname); - return 0; - } - usemapcode = true; + if (( newmapnum = M_MapNumber(mapname[3], mapname[4]) )) + usemapcode = true; } if (!usemapcode) From 0a014755b98fb909aed4a12feba00744bc2af225 Mon Sep 17 00:00:00 2001 From: James R Date: Sun, 29 Dec 2019 02:16:37 -0800 Subject: [PATCH 486/746] I'm still an idiot --- src/g_game.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/g_game.c b/src/g_game.c index 0adedf3dc..e5bbf9d5d 100644 --- a/src/g_game.c +++ b/src/g_game.c @@ -4580,7 +4580,8 @@ INT32 G_FindMapByNameOrCode(const char *mapname, char **realmapnamep) if (usemapcode) { - (*realmapnamep) = G_BuildMapTitle(newmapnum); + if (realmapnamep) + (*realmapnamep) = G_BuildMapTitle(newmapnum); } return newmapnum; From 404f3c13e4ed1d9e1a375bba1c2ae59b4f694e0e Mon Sep 17 00:00:00 2001 From: James R Date: Sun, 29 Dec 2019 02:31:14 -0800 Subject: [PATCH 487/746] If we move the -warp code down, map searching can be used --- src/d_main.c | 34 ++++++++++++++-------------------- 1 file changed, 14 insertions(+), 20 deletions(-) diff --git a/src/d_main.c b/src/d_main.c index c4b0d7117..c83c4ccc8 100644 --- a/src/d_main.c +++ b/src/d_main.c @@ -1118,26 +1118,6 @@ void D_SRB2Main(void) if (M_CheckParm("-server") || dedicated) netgame = server = true; - if (M_CheckParm("-warp") && M_IsNextParm()) - { - const char *word = M_GetNextParm(); - char ch; // use this with sscanf to catch non-digits with - if (fastncmp(word, "MAP", 3)) // MAPxx name - pstartmap = M_MapNumber(word[3], word[4]); - else if (sscanf(word, "%d%c", &pstartmap, &ch) != 1) // a plain number - I_Error("Cannot warp to map %s (invalid map name)\n", word); - // Don't check if lump exists just yet because the wads haven't been loaded! - // Just do a basic range check here. - if (pstartmap < 1 || pstartmap > NUMMAPS) - I_Error("Cannot warp to map %d (out of range)\n", pstartmap); - else - { - if (!M_CheckParm("-server")) - G_SetGameModified(true); - autostart = true; - } - } - CONS_Printf("Z_Init(): Init zone memory allocation daemon. \n"); Z_Init(); @@ -1194,6 +1174,20 @@ void D_SRB2Main(void) mainwadstally = packetsizetally; // technically not accurate atm, remember to port the two-stage -file process from kart in 2.2.x + if (M_CheckParm("-warp") && M_IsNextParm()) + { + const char *word = M_GetNextParm(); + pstartmap = G_FindMapByNameOrCode(word, 0); + if (! pstartmap) + I_Error("Cannot find a map remotely named '%s'\n", word); + else + { + if (!M_CheckParm("-server")) + G_SetGameModified(true); + autostart = true; + } + } + cht_Init(); //---------------------------------------------------- READY SCREEN From 566b4a1626399b1c1621bf8b4ab1f8426c789c36 Mon Sep 17 00:00:00 2001 From: James R Date: Sun, 29 Dec 2019 02:44:27 -0800 Subject: [PATCH 488/746] Don't let us warp to a map that doesn't exist (really!) Okay so 6464df9876e472d1210aabce4237d02af38377e1, I WAS mistaken! Except that's not how you check for a map's existence, at least not how the old map command did it. --- src/g_game.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/g_game.c b/src/g_game.c index e5bbf9d5d..95aa1ae00 100644 --- a/src/g_game.c +++ b/src/g_game.c @@ -4580,6 +4580,10 @@ INT32 G_FindMapByNameOrCode(const char *mapname, char **realmapnamep) if (usemapcode) { + /* we can't check mapheaderinfo for this hahahaha */ + if (W_CheckNumForName(G_BuildMapName(newmapnum)) == LUMPERROR) + return 0; + if (realmapnamep) (*realmapnamep) = G_BuildMapTitle(newmapnum); } From abdfe60aa7a05297cc7f4c325c37b4a35913267f Mon Sep 17 00:00:00 2001 From: MascaraSnake Date: Sun, 29 Dec 2019 12:01:41 +0100 Subject: [PATCH 489/746] Store custom FOF flags directly in back toptexture field at map load instead of re-reading the sidedefs data later on --- src/p_setup.c | 14 ++++++++++++++ src/p_spec.c | 32 ++++---------------------------- 2 files changed, 18 insertions(+), 28 deletions(-) diff --git a/src/p_setup.c b/src/p_setup.c index 52c79e1ce..ea61a2ec7 100644 --- a/src/p_setup.c +++ b/src/p_setup.c @@ -1179,6 +1179,20 @@ static void P_LoadSidedefs(UINT8 *data) break; } + case 259: // Custom FOF + if (!isfrontside) + { + if ((msd->toptexture[0] >= '0' && msd->toptexture[0] <= '9') + || (msd->toptexture[0] >= 'A' && msd->toptexture[0] <= 'F')) + sd->toptexture = axtoi(msd->toptexture); + else + I_Error("Custom FOF (tag %d) needs a value in the linedef's back side upper texture field.", sd->line->tag); + + sd->midtexture = R_TextureNumForName(msd->midtexture); + sd->bottomtexture = R_TextureNumForName(msd->bottomtexture); + break; + } + // FALLTHRU default: // normal cases if (msd->toptexture[0] == '#') { diff --git a/src/p_spec.c b/src/p_spec.c index 20f1c8278..7915956c8 100644 --- a/src/p_spec.c +++ b/src/p_spec.c @@ -7179,38 +7179,14 @@ void P_SpawnSpecials(boolean fromnetsave) EV_AddLaserThinker(§ors[s], §ors[sec], lines + i, secthinkers); break; - case 259: // Make-Your-Own FOF! + case 259: // Custom FOF if (lines[i].sidenum[1] != 0xffff) { - UINT8 *data; - UINT16 b; - - if (!virt) - virt = vres_GetMap(lastloadedmaplumpnum); - - data = (UINT8*) vres_Find(virt, "SIDEDEFS")->data; - - for (b = 0; b < (INT16)numsides; b++) - { - register mapsidedef_t *msd = (mapsidedef_t *)data + b; - - if (b == lines[i].sidenum[1]) - { - if ((msd->toptexture[0] >= '0' && msd->toptexture[0] <= '9') - || (msd->toptexture[0] >= 'A' && msd->toptexture[0] <= 'F')) - { - ffloortype_e FOF_Flags = axtoi(msd->toptexture); - - P_AddFakeFloorsByLine(i, FOF_Flags, secthinkers); - break; - } - else - I_Error("Make-Your-Own-FOF (tag %d) needs a value in the linedef's second side upper texture field.", lines[i].tag); - } - } + ffloortype_e fofflags = sides[lines[i].sidenum[1]].toptexture; + P_AddFakeFloorsByLine(i, fofflags, secthinkers); } else - I_Error("Make-Your-Own FOF (tag %d) found without a 2nd linedef side!", lines[i].tag); + I_Error("Custom FOF (tag %d) found without a linedef back side!", lines[i].tag); break; case 300: // Linedef executor (combines with sector special 974/975) and commands From c43a83dc04e2457ab017b8dc5b813c5f9f5824e8 Mon Sep 17 00:00:00 2001 From: MascaraSnake Date: Sun, 29 Dec 2019 12:26:02 +0100 Subject: [PATCH 490/746] Remove virtres_t pointer in P_SpawnSpecials that's no longer needed --- src/p_spec.c | 4 ---- 1 file changed, 4 deletions(-) diff --git a/src/p_spec.c b/src/p_spec.c index 7915956c8..4de488654 100644 --- a/src/p_spec.c +++ b/src/p_spec.c @@ -6433,7 +6433,6 @@ void P_SpawnSpecials(boolean fromnetsave) INT32 j; thinkerlist_t *secthinkers; thinker_t *th; - virtres_t* virt = NULL; // This used to be used, and *should* be used in the future, // but currently isn't. (void)fromnetsave; @@ -7409,9 +7408,6 @@ void P_SpawnSpecials(boolean fromnetsave) } } - if (virt) - vres_Free(virt); - // Allocate each list for (i = 0; i < numsectors; i++) if(secthinkers[i].thinkers) From 389b9e35c481a9c26e1f968e6b1d8d28e89284d9 Mon Sep 17 00:00:00 2001 From: Nev3r Date: Sun, 29 Dec 2019 14:17:51 +0100 Subject: [PATCH 491/746] Add XNOD, XGLN and XGL3 BSP formats recognition and support. --- src/hardware/hw_main.c | 2 + src/p_polyobj.c | 10 ++ src/p_setup.c | 313 ++++++++++++++++++++++++++++++++++++++--- src/r_bsp.c | 4 +- src/r_defs.h | 1 + src/r_segs.c | 4 + 6 files changed, 317 insertions(+), 17 deletions(-) diff --git a/src/hardware/hw_main.c b/src/hardware/hw_main.c index 41e2c5693..48e66e114 100644 --- a/src/hardware/hw_main.c +++ b/src/hardware/hw_main.c @@ -2714,6 +2714,8 @@ static void HWR_AddLine(seg_t * line) static sector_t tempsec; fixed_t v1x, v1y, v2x, v2y; // the seg's vertexes as fixed_t + if (line->glseg) + return; #ifdef POLYOBJECTS if (line->polyseg && !(line->polyseg->flags & POF_RENDERSIDES)) return; diff --git a/src/p_polyobj.c b/src/p_polyobj.c index c37926adf..4709e5e6f 100644 --- a/src/p_polyobj.c +++ b/src/p_polyobj.c @@ -400,6 +400,8 @@ static void Polyobj_findSegs(polyobj_t *po, seg_t *seg) // Find backfacings for (s = 0; s < numsegs; s++) { + if (segs[s].glseg) + continue; if (segs[s].linedef == seg->linedef && segs[s].side == 1) { @@ -436,6 +438,8 @@ newseg: // seg's ending vertex. for (i = 0; i < numsegs; ++i) { + if (segs[i].glseg) + continue; if (segs[i].side != 0) // needs to be frontfacing continue; if (segs[i].v1->x == seg->v2->x && segs[i].v1->y == seg->v2->y) @@ -460,6 +464,9 @@ newseg: // Find backfacings for (q = 0; q < numsegs; q++) { + if (segs[q].glseg) + continue; + if (segs[q].linedef == segs[i].linedef && segs[q].side == 1) { @@ -606,6 +613,9 @@ static void Polyobj_spawnPolyObj(INT32 num, mobj_t *spawnSpot, INT32 id) INT32 poflags = POF_SOLID|POF_TESTHEIGHT|POF_RENDERSIDES; INT32 parentID = 0, potrans = 0; + if (seg->glseg) + continue; + if (seg->side != 0) // needs to be frontfacing continue; diff --git a/src/p_setup.c b/src/p_setup.c index ea61a2ec7..b74bf83a2 100644 --- a/src/p_setup.c +++ b/src/p_setup.c @@ -1456,31 +1456,312 @@ static void P_LoadSegs(UINT8 *data) } } +// Auxiliary function: Shrink node ID from 32-bit to 16-bit. +static UINT16 ShrinkNodeID(UINT32 x) { + UINT16 mask = (x >> 16) & 0xC000; + UINT16 result = x; + return result | mask; +} + +typedef enum { + NT_DOOM, + NT_XNOD, + NT_ZNOD, + NT_XGLN, + NT_ZGLN, + NT_XGL2, + NT_ZGL2, + NT_XGL3, + NT_ZGL3, + NT_UNSUPPORTED +} nodetype_t; + static void P_LoadMapBSP(const virtres_t *virt) { virtlump_t* virtssectors = vres_Find(virt, "SSECTORS"); virtlump_t* virtsegs = vres_Find(virt, "SEGS"); virtlump_t* virtnodes = vres_Find(virt, "NODES"); - numsubsectors = virtssectors->size / sizeof(mapsubsector_t); - numnodes = virtnodes->size / sizeof(mapnode_t); - numsegs = virtsegs->size / sizeof(mapseg_t); + nodetype_t nodetype = NT_UNSUPPORTED; - if (numsubsectors <= 0) - I_Error("Level has no subsectors (did you forget to run it through a nodesbuilder?)"); - if (numnodes <= 0) - I_Error("Level has no nodes"); - if (numsegs <= 0) - I_Error("Level has no segs"); + // Find out the BSP format. + if (vres_Find(virt, "TEXTMAP")) + { + virtnodes = vres_Find(virt, "ZNODES"); + if (!memcmp(virtnodes->data, "XGLN", 4)) + nodetype = NT_XGLN; + else if (!memcmp(virtnodes->data, "XGL3", 4)) + nodetype = NT_XGL3; + } + else + { + if (!virtsegs || !virtsegs->size) + { + // Possibly ZDoom extended nodes: SSECTORS is empty, NODES has a signature. + if (!virtssectors || !virtssectors->size) + { + if (!memcmp(virtnodes->data, "XNOD", 4)) + nodetype = NT_XNOD; + else if (!memcmp(virtnodes->data, "ZNOD", 4)) // Compressed variant. + nodetype = NT_ZNOD; + } + // Possibly GL nodes: NODES ignored, SSECTORS takes precedence as nodes lump, (It is confusing yeah) and has a signature. + else + { + if (!memcmp(virtssectors->data, "XGLN", 4)) + { + virtnodes = virtssectors; + nodetype = NT_XGLN; + } + else if (!memcmp(virtssectors->data, "ZGLN", 4)) // Compressed variant. + { + virtnodes = virtssectors; + nodetype = NT_ZGLN; + } + else if (!memcmp(virtssectors->data, "XGL3", 4)) // Compressed variant. + { + virtnodes = virtssectors; + nodetype = NT_XGL3; + } + } + } + else // Traditional map format BSP tree. + nodetype = NT_DOOM; + } - subsectors = Z_Calloc(numsubsectors * sizeof(*subsectors), PU_LEVEL, NULL); - nodes = Z_Calloc(numnodes * sizeof(*nodes), PU_LEVEL, NULL); - segs = Z_Calloc(numsegs * sizeof(*segs), PU_LEVEL, NULL); + switch (nodetype) + { + case NT_DOOM: + numsubsectors = virtssectors->size / sizeof(mapsubsector_t); + numnodes = virtnodes->size / sizeof(mapnode_t); + numsegs = virtsegs->size / sizeof(mapseg_t); - // Nodes - P_LoadSubsectors(virtssectors->data); - P_LoadNodes(virtnodes->data); - P_LoadSegs(virtsegs->data); + if (numsubsectors <= 0) + I_Error("Level has no subsectors (did you forget to run it through a nodesbuilder?)"); + if (numnodes <= 0) + I_Error("Level has no nodes"); + if (numsegs <= 0) + I_Error("Level has no segs"); + + subsectors = Z_Calloc(numsubsectors * sizeof(*subsectors), PU_LEVEL, NULL); + nodes = Z_Calloc(numnodes * sizeof(*nodes), PU_LEVEL, NULL); + segs = Z_Calloc(numsegs * sizeof(*segs), PU_LEVEL, NULL); + + P_LoadSubsectors(virtssectors->data); + P_LoadNodes(virtnodes->data); + P_LoadSegs(virtsegs->data); + break; + + case NT_XNOD: + case NT_XGLN: + case NT_XGL3: + { + size_t i, j, k; + INT16 m; + UINT8* data = virtnodes->data + 4; + + /// Extended node formats feature additional vertexes; useful for OpenGL, but totally useless in gamelogic. + UINT32 orivtx, xtrvtx; + orivtx = READUINT32(data); + xtrvtx = READUINT32(data); + + if (numvertexes != orivtx) /// If native vertex count doesn't match node original vertex count, bail out (broken data?). + { + CONS_Alert(CONS_WARNING, "Vertex count in map data and nodes differ!\n"); + return; + } + + if (xtrvtx) /// If extra vertexes were generated, reallocate the vertex array and fix the pointers. + { + line_t* ld = lines; + size_t oldpos = (size_t) vertexes; + ssize_t offset; + numvertexes+= xtrvtx; + vertexes = Z_Realloc(vertexes, numvertexes * sizeof (*vertexes), PU_LEVEL, NULL); + offset = ((size_t) vertexes) - oldpos; + + for (i = 0, ld = lines; i < numlines; i++, ld++) + { + ld->v1 = (vertex_t*) ((size_t) ld->v1 + offset); + ld->v2 = (vertex_t*) ((size_t) ld->v2 + offset); + } + } + + // Read vertex data. + for (i = orivtx; i < numvertexes; i++) + { + vertexes[i].x = READFIXED(data); + vertexes[i].y = READFIXED(data); + } + + // Subsectors + numsubsectors = READUINT32(data); + subsectors = Z_Calloc(numsubsectors * sizeof (*subsectors), PU_LEVEL, NULL); + + for (i = 0; i < numsubsectors; i++) + subsectors[i].numlines = READUINT32(data); + + // Segs + numsegs = READUINT32(data); + segs = Z_Calloc(numsegs * sizeof (*segs), PU_LEVEL, NULL); + + for (i = 0, k = 0; i < numsubsectors; i++) + { + subsectors[i].firstline = k; + + switch (nodetype) + { + case NT_XGLN: + for (m = 0; m < subsectors[i].numlines; m++, k++) + { + UINT16 linenum; + UINT32 vert; + vert = READUINT32(data); + segs[k].v1 = &vertexes[vert]; + if (m == 0) + segs[k + subsectors[i].numlines - 1].v2 = &vertexes[vert]; + else + segs[k - 1].v2 = segs[k].v1; + data += 4;// partner; can be ignored by software renderer; + linenum = READUINT16(data); + if (linenum == 0xFFFF) + { + segs[k].glseg = true; + segs[k].linedef = NULL; + } + else + { + segs[k].glseg = false; + segs[k].linedef = &lines[linenum]; + } + segs[k].side = READUINT8(data); + } + break; + + case NT_XGL3: + for (m = 0; m < subsectors[i].numlines; m++, k++) + { + UINT32 linenum; + UINT32 vert; + vert = READUINT32(data); + segs[k].v1 = &vertexes[vert]; + if (m == 0) + segs[k + subsectors[i].numlines - 1].v2 = &vertexes[vert]; + else + segs[k - 1].v2 = segs[k].v1; + data += 4;// partner; can be ignored by software renderer; + linenum = READUINT32(data); + if (linenum == 0xFFFFFFFF) + { + segs[k].glseg = true; + segs[k].linedef = NULL; + } + else + { + segs[k].glseg = false; + segs[k].linedef = NULL; + } + segs[k].side = READUINT8(data); + } + break; + + case NT_XNOD: + for (m = 0; m < subsectors[i].numlines; m++, k++) + { + segs[k].v1 = &vertexes[READUINT32(data)]; + segs[k].v2 = &vertexes[READUINT32(data)]; + segs[k].linedef = &lines[READUINT16(data)]; + segs[k].side = READUINT8(data); + } + break; + + default: + return; + } + } + + { + INT32 side; + seg_t *li; + + for (i = 0, li = segs; i < numsegs; i++, li++) + { + vertex_t *v1 = li->v1; + vertex_t *v2 = li->v2; + li->angle = R_PointToAngle2(v1->x, v1->y, v2->x, v2->y); + li->offset = FixedHypot(v1->x - li->linedef->v1->x, v1->y - li->linedef->v1->y); + side = li->side; + li->sidedef = &sides[li->linedef->sidenum[side]]; + + li->frontsector = sides[li->linedef->sidenum[side]].sector; + if (li->linedef->flags & ML_TWOSIDED) + li->backsector = sides[li->linedef->sidenum[side^1]].sector; + else + li->backsector = 0; + + segs[i].numlights = 0; + segs[i].rlights = NULL; + } + } + + // Nodes + numnodes = READINT32(data); + nodes = Z_Calloc(numnodes * sizeof (*nodes), PU_LEVEL, NULL); + if (nodetype == NT_XGL3) + { + UINT32 x, y, dx, dy; + UINT32 c0, c1; + node_t *mn; + for (i = 0, mn = nodes; i < numnodes; i++, mn++) + { + // Splitter. + x = READINT32(data); + y = READINT32(data); + dx = READINT32(data); + dy = READINT32(data); + mn->x = x; + mn->y = y; + mn->dx = dx; + mn->dy = dy; + + // Bounding boxes and children. + for (j = 0; j < 2; j++) + for (k = 0; k < 4; k++) + mn->bbox[j][k] = READINT16(data)<children[0] = ShrinkNodeID(c0); /// \todo Use UINT32 for node children in a future, instead? + mn->children[1] = ShrinkNodeID(c1); + } + } + else + { + UINT32 c0, c1; + node_t *mn; + for (i = 0, mn = nodes; i < numnodes; i++, mn++) + { + // Splitter. + mn->x = READINT16(data)<y = READINT16(data)<dx = READINT16(data)<dy = READINT16(data)<bbox[j][k] = READINT16(data)<children[0] = ShrinkNodeID(c0); /// \todo Use UINT32 for node children in a future, instead? + mn->children[1] = ShrinkNodeID(c1); + } + } + } + break; + default: + CONS_Alert(CONS_WARNING, "Unsupported BSP format detected.\n"); + return; + } + return; } // Split from P_LoadBlockMap for convenience diff --git a/src/r_bsp.c b/src/r_bsp.c index 51d9bd3fd..6b4667aee 100644 --- a/src/r_bsp.c +++ b/src/r_bsp.c @@ -1169,9 +1169,11 @@ static void R_Subsector(size_t num) while (count--) { // CONS_Debug(DBG_GAMELOGIC, "Adding normal line %d...(%d)\n", line->linedef-lines, leveltime); + if (!line->glseg #ifdef POLYOBJECTS - if (!line->polyseg) // ignore segs that belong to polyobjects + && !line->polyseg // ignore segs that belong to polyobjects #endif + ) R_AddLine(line); line++; curline = NULL; /* cph 2001/11/18 - must clear curline now we're done with it, so stuff doesn't try using it for other things */ diff --git a/src/r_defs.h b/src/r_defs.h index 4cb02f4f5..ceb694c57 100644 --- a/src/r_defs.h +++ b/src/r_defs.h @@ -586,6 +586,7 @@ typedef struct seg_s polyobj_t *polyseg; boolean dontrenderme; #endif + boolean glseg; } seg_t; // diff --git a/src/r_segs.c b/src/r_segs.c index 29120ebb8..0fc91a823 100644 --- a/src/r_segs.c +++ b/src/r_segs.c @@ -308,6 +308,10 @@ void R_RenderMaskedSegRange(drawseg_t *ds, INT32 x1, INT32 x2) // for horizontal / vertical / diagonal. Diagonal? // OPTIMIZE: get rid of LIGHTSEGSHIFT globally curline = ds->curline; + + if (curline->glseg) + return; + frontsector = curline->frontsector; backsector = curline->backsector; texnum = R_GetTextureNum(curline->sidedef->midtexture); From 8032054a47bcb41d17e25870eb2c671525c0ad90 Mon Sep 17 00:00:00 2001 From: MascaraSnake Date: Sun, 29 Dec 2019 15:15:32 +0100 Subject: [PATCH 492/746] Separate loading of extended nodes into its own file --- src/p_setup.c | 404 +++++++++++++++++++++++++------------------------- 1 file changed, 203 insertions(+), 201 deletions(-) diff --git a/src/p_setup.c b/src/p_setup.c index b74bf83a2..a0eb52bc8 100644 --- a/src/p_setup.c +++ b/src/p_setup.c @@ -1476,6 +1476,208 @@ typedef enum { NT_UNSUPPORTED } nodetype_t; +static void P_LoadExtendedNodes(UINT8 *data, nodetype_t nodetype) +{ + size_t i, j, k; + INT16 m; + + /// Extended node formats feature additional vertexes; useful for OpenGL, but totally useless in gamelogic. + UINT32 orivtx, xtrvtx; + orivtx = READUINT32(data); + xtrvtx = READUINT32(data); + + if (numvertexes != orivtx) /// If native vertex count doesn't match node original vertex count, bail out (broken data?). + { + CONS_Alert(CONS_WARNING, "Vertex count in map data and nodes differ!\n"); + return; + } + + if (xtrvtx) /// If extra vertexes were generated, reallocate the vertex array and fix the pointers. + { + line_t *ld = lines; + size_t oldpos = (size_t)vertexes; + ssize_t offset; + numvertexes += xtrvtx; + vertexes = Z_Realloc(vertexes, numvertexes*sizeof(*vertexes), PU_LEVEL, NULL); + offset = ((size_t)vertexes) - oldpos; + + for (i = 0, ld = lines; i < numlines; i++, ld++) + { + ld->v1 = (vertex_t*)((size_t)ld->v1 + offset); + ld->v2 = (vertex_t*)((size_t)ld->v2 + offset); + } + } + + // Read vertex data. + for (i = orivtx; i < numvertexes; i++) + { + vertexes[i].x = READFIXED(data); + vertexes[i].y = READFIXED(data); + } + + // Subsectors + numsubsectors = READUINT32(data); + subsectors = Z_Calloc(numsubsectors*sizeof(*subsectors), PU_LEVEL, NULL); + + for (i = 0; i < numsubsectors; i++) + subsectors[i].numlines = READUINT32(data); + + // Segs + numsegs = READUINT32(data); + segs = Z_Calloc(numsegs*sizeof(*segs), PU_LEVEL, NULL); + + for (i = 0, k = 0; i < numsubsectors; i++) + { + subsectors[i].firstline = k; + + switch (nodetype) + { + case NT_XGLN: + for (m = 0; m < subsectors[i].numlines; m++, k++) + { + UINT16 linenum; + UINT32 vert; + vert = READUINT32(data); + segs[k].v1 = &vertexes[vert]; + if (m == 0) + segs[k + subsectors[i].numlines - 1].v2 = &vertexes[vert]; + else + segs[k - 1].v2 = segs[k].v1; + data += 4;// partner; can be ignored by software renderer; + linenum = READUINT16(data); + if (linenum == 0xFFFF) + { + segs[k].glseg = true; + segs[k].linedef = NULL; + } + else + { + segs[k].glseg = false; + segs[k].linedef = &lines[linenum]; + } + segs[k].side = READUINT8(data); + } + break; + + case NT_XGL3: + for (m = 0; m < subsectors[i].numlines; m++, k++) + { + UINT32 linenum; + UINT32 vert; + vert = READUINT32(data); + segs[k].v1 = &vertexes[vert]; + if (m == 0) + segs[k + subsectors[i].numlines - 1].v2 = &vertexes[vert]; + else + segs[k - 1].v2 = segs[k].v1; + data += 4;// partner; can be ignored by software renderer; + linenum = READUINT32(data); + if (linenum == 0xFFFFFFFF) + { + segs[k].glseg = true; + segs[k].linedef = NULL; + } + else + { + segs[k].glseg = false; + segs[k].linedef = NULL; + } + segs[k].side = READUINT8(data); + } + break; + + case NT_XNOD: + for (m = 0; m < subsectors[i].numlines; m++, k++) + { + segs[k].v1 = &vertexes[READUINT32(data)]; + segs[k].v2 = &vertexes[READUINT32(data)]; + segs[k].linedef = &lines[READUINT16(data)]; + segs[k].side = READUINT8(data); + } + break; + + default: + return; + } + } + + { + INT32 side; + seg_t *li; + + for (i = 0, li = segs; i < numsegs; i++, li++) + { + vertex_t *v1 = li->v1; + vertex_t *v2 = li->v2; + li->angle = R_PointToAngle2(v1->x, v1->y, v2->x, v2->y); + li->offset = FixedHypot(v1->x - li->linedef->v1->x, v1->y - li->linedef->v1->y); + side = li->side; + li->sidedef = &sides[li->linedef->sidenum[side]]; + + li->frontsector = sides[li->linedef->sidenum[side]].sector; + if (li->linedef->flags & ML_TWOSIDED) + li->backsector = sides[li->linedef->sidenum[side ^ 1]].sector; + else + li->backsector = 0; + + segs[i].numlights = 0; + segs[i].rlights = NULL; + } + } + + // Nodes + numnodes = READINT32(data); + nodes = Z_Calloc(numnodes*sizeof(*nodes), PU_LEVEL, NULL); + if (nodetype == NT_XGL3) + { + UINT32 x, y, dx, dy; + UINT32 c0, c1; + node_t *mn; + for (i = 0, mn = nodes; i < numnodes; i++, mn++) + { + // Splitter. + x = READINT32(data); + y = READINT32(data); + dx = READINT32(data); + dy = READINT32(data); + mn->x = x; + mn->y = y; + mn->dx = dx; + mn->dy = dy; + + // Bounding boxes and children. + for (j = 0; j < 2; j++) + for (k = 0; k < 4; k++) + mn->bbox[j][k] = READINT16(data) << FRACBITS; + c0 = READUINT32(data); + c1 = READUINT32(data); + mn->children[0] = ShrinkNodeID(c0); /// \todo Use UINT32 for node children in a future, instead? + mn->children[1] = ShrinkNodeID(c1); + } + } + else + { + UINT32 c0, c1; + node_t *mn; + for (i = 0, mn = nodes; i < numnodes; i++, mn++) + { + // Splitter. + mn->x = READINT16(data) << FRACBITS; + mn->y = READINT16(data) << FRACBITS; + mn->dx = READINT16(data) << FRACBITS; + mn->dy = READINT16(data) << FRACBITS; + // Bounding boxes and children. + for (j = 0; j < 2; j++) + for (k = 0; k < 4; k++) + mn->bbox[j][k] = READINT16(data) << FRACBITS; + c0 = READUINT32(data); + c1 = READUINT32(data); + mn->children[0] = ShrinkNodeID(c0); /// \todo Use UINT32 for node children in a future, instead? + mn->children[1] = ShrinkNodeID(c1); + } + } +} + static void P_LoadMapBSP(const virtres_t *virt) { virtlump_t* virtssectors = vres_Find(virt, "SSECTORS"); @@ -1555,207 +1757,7 @@ static void P_LoadMapBSP(const virtres_t *virt) case NT_XNOD: case NT_XGLN: case NT_XGL3: - { - size_t i, j, k; - INT16 m; - UINT8* data = virtnodes->data + 4; - - /// Extended node formats feature additional vertexes; useful for OpenGL, but totally useless in gamelogic. - UINT32 orivtx, xtrvtx; - orivtx = READUINT32(data); - xtrvtx = READUINT32(data); - - if (numvertexes != orivtx) /// If native vertex count doesn't match node original vertex count, bail out (broken data?). - { - CONS_Alert(CONS_WARNING, "Vertex count in map data and nodes differ!\n"); - return; - } - - if (xtrvtx) /// If extra vertexes were generated, reallocate the vertex array and fix the pointers. - { - line_t* ld = lines; - size_t oldpos = (size_t) vertexes; - ssize_t offset; - numvertexes+= xtrvtx; - vertexes = Z_Realloc(vertexes, numvertexes * sizeof (*vertexes), PU_LEVEL, NULL); - offset = ((size_t) vertexes) - oldpos; - - for (i = 0, ld = lines; i < numlines; i++, ld++) - { - ld->v1 = (vertex_t*) ((size_t) ld->v1 + offset); - ld->v2 = (vertex_t*) ((size_t) ld->v2 + offset); - } - } - - // Read vertex data. - for (i = orivtx; i < numvertexes; i++) - { - vertexes[i].x = READFIXED(data); - vertexes[i].y = READFIXED(data); - } - - // Subsectors - numsubsectors = READUINT32(data); - subsectors = Z_Calloc(numsubsectors * sizeof (*subsectors), PU_LEVEL, NULL); - - for (i = 0; i < numsubsectors; i++) - subsectors[i].numlines = READUINT32(data); - - // Segs - numsegs = READUINT32(data); - segs = Z_Calloc(numsegs * sizeof (*segs), PU_LEVEL, NULL); - - for (i = 0, k = 0; i < numsubsectors; i++) - { - subsectors[i].firstline = k; - - switch (nodetype) - { - case NT_XGLN: - for (m = 0; m < subsectors[i].numlines; m++, k++) - { - UINT16 linenum; - UINT32 vert; - vert = READUINT32(data); - segs[k].v1 = &vertexes[vert]; - if (m == 0) - segs[k + subsectors[i].numlines - 1].v2 = &vertexes[vert]; - else - segs[k - 1].v2 = segs[k].v1; - data += 4;// partner; can be ignored by software renderer; - linenum = READUINT16(data); - if (linenum == 0xFFFF) - { - segs[k].glseg = true; - segs[k].linedef = NULL; - } - else - { - segs[k].glseg = false; - segs[k].linedef = &lines[linenum]; - } - segs[k].side = READUINT8(data); - } - break; - - case NT_XGL3: - for (m = 0; m < subsectors[i].numlines; m++, k++) - { - UINT32 linenum; - UINT32 vert; - vert = READUINT32(data); - segs[k].v1 = &vertexes[vert]; - if (m == 0) - segs[k + subsectors[i].numlines - 1].v2 = &vertexes[vert]; - else - segs[k - 1].v2 = segs[k].v1; - data += 4;// partner; can be ignored by software renderer; - linenum = READUINT32(data); - if (linenum == 0xFFFFFFFF) - { - segs[k].glseg = true; - segs[k].linedef = NULL; - } - else - { - segs[k].glseg = false; - segs[k].linedef = NULL; - } - segs[k].side = READUINT8(data); - } - break; - - case NT_XNOD: - for (m = 0; m < subsectors[i].numlines; m++, k++) - { - segs[k].v1 = &vertexes[READUINT32(data)]; - segs[k].v2 = &vertexes[READUINT32(data)]; - segs[k].linedef = &lines[READUINT16(data)]; - segs[k].side = READUINT8(data); - } - break; - - default: - return; - } - } - - { - INT32 side; - seg_t *li; - - for (i = 0, li = segs; i < numsegs; i++, li++) - { - vertex_t *v1 = li->v1; - vertex_t *v2 = li->v2; - li->angle = R_PointToAngle2(v1->x, v1->y, v2->x, v2->y); - li->offset = FixedHypot(v1->x - li->linedef->v1->x, v1->y - li->linedef->v1->y); - side = li->side; - li->sidedef = &sides[li->linedef->sidenum[side]]; - - li->frontsector = sides[li->linedef->sidenum[side]].sector; - if (li->linedef->flags & ML_TWOSIDED) - li->backsector = sides[li->linedef->sidenum[side^1]].sector; - else - li->backsector = 0; - - segs[i].numlights = 0; - segs[i].rlights = NULL; - } - } - - // Nodes - numnodes = READINT32(data); - nodes = Z_Calloc(numnodes * sizeof (*nodes), PU_LEVEL, NULL); - if (nodetype == NT_XGL3) - { - UINT32 x, y, dx, dy; - UINT32 c0, c1; - node_t *mn; - for (i = 0, mn = nodes; i < numnodes; i++, mn++) - { - // Splitter. - x = READINT32(data); - y = READINT32(data); - dx = READINT32(data); - dy = READINT32(data); - mn->x = x; - mn->y = y; - mn->dx = dx; - mn->dy = dy; - - // Bounding boxes and children. - for (j = 0; j < 2; j++) - for (k = 0; k < 4; k++) - mn->bbox[j][k] = READINT16(data)<children[0] = ShrinkNodeID(c0); /// \todo Use UINT32 for node children in a future, instead? - mn->children[1] = ShrinkNodeID(c1); - } - } - else - { - UINT32 c0, c1; - node_t *mn; - for (i = 0, mn = nodes; i < numnodes; i++, mn++) - { - // Splitter. - mn->x = READINT16(data)<y = READINT16(data)<dx = READINT16(data)<dy = READINT16(data)<bbox[j][k] = READINT16(data)<children[0] = ShrinkNodeID(c0); /// \todo Use UINT32 for node children in a future, instead? - mn->children[1] = ShrinkNodeID(c1); - } - } - } + P_LoadExtendedNodes(virtnodes->data + 4, nodetype); break; default: CONS_Alert(CONS_WARNING, "Unsupported BSP format detected.\n"); From 0aed60f4de10349e6f746eb1d89ecea6677efca1 Mon Sep 17 00:00:00 2001 From: MascaraSnake Date: Sun, 29 Dec 2019 15:50:53 +0100 Subject: [PATCH 493/746] Separate retrieval of nodetype and nodes lump into its own function (Function. Not file. Sorry.) --- src/p_setup.c | 115 +++++++++++++++++++++++++++----------------------- 1 file changed, 62 insertions(+), 53 deletions(-) diff --git a/src/p_setup.c b/src/p_setup.c index a0eb52bc8..4f9b89c5c 100644 --- a/src/p_setup.c +++ b/src/p_setup.c @@ -1473,9 +1473,62 @@ typedef enum { NT_ZGL2, NT_XGL3, NT_ZGL3, - NT_UNSUPPORTED + NT_UNSUPPORTED, + NUMNODETYPES } nodetype_t; +// Find out the BSP format. +static nodetype_t P_GetNodetype(const virtres_t *virt, virtlump_t *virtnodes) +{ + boolean supported[NUMNODETYPES]; + nodetype_t nodetype = NT_UNSUPPORTED; + char signature[4 + 1]; + + if (vres_Find(virt, "TEXTMAP")) + { + virtnodes = vres_Find(virt, "ZNODES"); + supported[NT_XGLN] = supported[NT_XGL3] = true; + } + else + { + virtlump_t *virtsegs = vres_Find(virt, "SEGS"); + virtlump_t *virtssectors; + + if (virtsegs && virtsegs->size) + return NT_DOOM; // Traditional map format BSP tree. + + virtssectors = vres_Find(virt, "SSECTORS"); + + if (virtssectors && virtssectors->size) + { // Possibly GL nodes: NODES ignored, SSECTORS takes precedence as nodes lump, (It is confusing yeah) and has a signature. + virtnodes = virtssectors; + supported[NT_XGLN] = supported[NT_ZGLN] = supported[NT_XGL3] = true; + } + else + { // Possibly ZDoom extended nodes: SSECTORS is empty, NODES has a signature. + virtnodes = vres_Find(virt, "NODES"); + supported[NT_XNOD] = supported[NT_ZNOD] = true; + } + + M_Memcpy(signature, virtnodes->data, 4); + signature[4] = '\0'; + virtnodes->data += 4; + } + + if (!strcmp(signature, "XNOD")) + nodetype = NT_XNOD; + else if (!strcmp(signature, "ZNOD")) + nodetype = NT_ZNOD; + else if (!strcmp(signature, "XGLN")) + nodetype = NT_XGLN; + else if (!strcmp(signature, "ZGLN")) + nodetype = NT_ZGLN; + else if (!strcmp(signature, "XGL3")) + nodetype = NT_XGL3; + + return supported[nodetype] ? nodetype : NT_UNSUPPORTED; +} + static void P_LoadExtendedNodes(UINT8 *data, nodetype_t nodetype) { size_t i, j, k; @@ -1680,60 +1733,16 @@ static void P_LoadExtendedNodes(UINT8 *data, nodetype_t nodetype) static void P_LoadMapBSP(const virtres_t *virt) { - virtlump_t* virtssectors = vres_Find(virt, "SSECTORS"); - virtlump_t* virtsegs = vres_Find(virt, "SEGS"); - virtlump_t* virtnodes = vres_Find(virt, "NODES"); - - nodetype_t nodetype = NT_UNSUPPORTED; - - // Find out the BSP format. - if (vres_Find(virt, "TEXTMAP")) - { - virtnodes = vres_Find(virt, "ZNODES"); - if (!memcmp(virtnodes->data, "XGLN", 4)) - nodetype = NT_XGLN; - else if (!memcmp(virtnodes->data, "XGL3", 4)) - nodetype = NT_XGL3; - } - else - { - if (!virtsegs || !virtsegs->size) - { - // Possibly ZDoom extended nodes: SSECTORS is empty, NODES has a signature. - if (!virtssectors || !virtssectors->size) - { - if (!memcmp(virtnodes->data, "XNOD", 4)) - nodetype = NT_XNOD; - else if (!memcmp(virtnodes->data, "ZNOD", 4)) // Compressed variant. - nodetype = NT_ZNOD; - } - // Possibly GL nodes: NODES ignored, SSECTORS takes precedence as nodes lump, (It is confusing yeah) and has a signature. - else - { - if (!memcmp(virtssectors->data, "XGLN", 4)) - { - virtnodes = virtssectors; - nodetype = NT_XGLN; - } - else if (!memcmp(virtssectors->data, "ZGLN", 4)) // Compressed variant. - { - virtnodes = virtssectors; - nodetype = NT_ZGLN; - } - else if (!memcmp(virtssectors->data, "XGL3", 4)) // Compressed variant. - { - virtnodes = virtssectors; - nodetype = NT_XGL3; - } - } - } - else // Traditional map format BSP tree. - nodetype = NT_DOOM; - } + virtlump_t *virtnodes = NULL; + nodetype_t nodetype = P_GetNodetype(virt, virtnodes); switch (nodetype) { case NT_DOOM: + { + virtlump_t *virtssectors = vres_Find(virt, "SSECTORS"); + virtlump_t *virtsegs = vres_Find(virt, "SEGS"); + numsubsectors = virtssectors->size / sizeof(mapsubsector_t); numnodes = virtnodes->size / sizeof(mapnode_t); numsegs = virtsegs->size / sizeof(mapseg_t); @@ -1753,11 +1762,11 @@ static void P_LoadMapBSP(const virtres_t *virt) P_LoadNodes(virtnodes->data); P_LoadSegs(virtsegs->data); break; - + } case NT_XNOD: case NT_XGLN: case NT_XGL3: - P_LoadExtendedNodes(virtnodes->data + 4, nodetype); + P_LoadExtendedNodes(virtnodes->data, nodetype); break; default: CONS_Alert(CONS_WARNING, "Unsupported BSP format detected.\n"); From 9d009edfc800e87934abf919091bd2a9bf5eec4c Mon Sep 17 00:00:00 2001 From: MascaraSnake Date: Sun, 29 Dec 2019 15:59:15 +0100 Subject: [PATCH 494/746] Move copying of the nodes signature out of the else case --- src/p_setup.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/p_setup.c b/src/p_setup.c index 4f9b89c5c..5725c6db1 100644 --- a/src/p_setup.c +++ b/src/p_setup.c @@ -1509,12 +1509,12 @@ static nodetype_t P_GetNodetype(const virtres_t *virt, virtlump_t *virtnodes) virtnodes = vres_Find(virt, "NODES"); supported[NT_XNOD] = supported[NT_ZNOD] = true; } - - M_Memcpy(signature, virtnodes->data, 4); - signature[4] = '\0'; - virtnodes->data += 4; } + M_Memcpy(signature, virtnodes->data, 4); + signature[4] = '\0'; + virtnodes->data += 4; + if (!strcmp(signature, "XNOD")) nodetype = NT_XNOD; else if (!strcmp(signature, "ZNOD")) From 45ca959f97a7becbfef0ce3fdaa300d8296ce1fa Mon Sep 17 00:00:00 2001 From: MascaraSnake Date: Sun, 29 Dec 2019 17:52:49 +0100 Subject: [PATCH 495/746] -Move reading of actual extended nodes into separate function, cutting down on code duplication in the process -Fix a typo in the segs reading --- src/p_setup.c | 112 ++++++++++++++++++++------------------------------ 1 file changed, 44 insertions(+), 68 deletions(-) diff --git a/src/p_setup.c b/src/p_setup.c index 5725c6db1..74ba5c5bd 100644 --- a/src/p_setup.c +++ b/src/p_setup.c @@ -1456,13 +1456,6 @@ static void P_LoadSegs(UINT8 *data) } } -// Auxiliary function: Shrink node ID from 32-bit to 16-bit. -static UINT16 ShrinkNodeID(UINT32 x) { - UINT16 mask = (x >> 16) & 0xC000; - UINT16 result = x; - return result | mask; -} - typedef enum { NT_DOOM, NT_XNOD, @@ -1529,28 +1522,58 @@ static nodetype_t P_GetNodetype(const virtres_t *virt, virtlump_t *virtnodes) return supported[nodetype] ? nodetype : NT_UNSUPPORTED; } -static void P_LoadExtendedNodes(UINT8 *data, nodetype_t nodetype) +// Auxiliary function: Shrink node ID from 32-bit to 16-bit. +static UINT16 ShrinkNodeID(UINT32 x) { + UINT16 mask = (x >> 16) & 0xC000; + UINT16 result = x; + return result | mask; +} + +static void P_LoadExtendedNodes(UINT8 *data, boolean xgl3) +{ + node_t *mn; + size_t i, j, k; + + for (i = 0, mn = nodes; i < numnodes; i++, mn++) + { + // Splitter + mn->x = xgl3 ? READINT32(data) : (READINT16(data) << FRACBITS); + mn->y = xgl3 ? READINT32(data) : (READINT16(data) << FRACBITS); + mn->dx = xgl3 ? READINT32(data) : (READINT16(data) << FRACBITS); + mn->dy = xgl3 ? READINT32(data) : (READINT16(data) << FRACBITS); + + // Bounding boxes + for (j = 0; j < 2; j++) + for (k = 0; k < 4; k++) + mn->bbox[j][k] = READINT16(data) << FRACBITS; + + //Children + mn->children[0] = ShrinkNodeID(READUINT32(data)); /// \todo Use UINT32 for node children in a future, instead? + mn->children[1] = ShrinkNodeID(READUINT32(data)); + } +} + +static void P_LoadExtendedBSP(UINT8 *data, nodetype_t nodetype) { size_t i, j, k; INT16 m; - /// Extended node formats feature additional vertexes; useful for OpenGL, but totally useless in gamelogic. - UINT32 orivtx, xtrvtx; - orivtx = READUINT32(data); - xtrvtx = READUINT32(data); + // Extended node formats feature additional vertexes; useful for OpenGL, but totally useless in gamelogic. + UINT32 origvrtx = READUINT32(data); + UINT32 xtrvrtx = READUINT32(data); - if (numvertexes != orivtx) /// If native vertex count doesn't match node original vertex count, bail out (broken data?). + if (numvertexes != origvrtx) // If native vertex count doesn't match node original vertex count, bail out (broken data?). { CONS_Alert(CONS_WARNING, "Vertex count in map data and nodes differ!\n"); return; } - if (xtrvtx) /// If extra vertexes were generated, reallocate the vertex array and fix the pointers. + if (xtrvrtx) // If extra vertexes were generated, reallocate the vertex array and fix the pointers. { line_t *ld = lines; size_t oldpos = (size_t)vertexes; ssize_t offset; - numvertexes += xtrvtx; + numvertexes += xtrvrtx; vertexes = Z_Realloc(vertexes, numvertexes*sizeof(*vertexes), PU_LEVEL, NULL); offset = ((size_t)vertexes) - oldpos; @@ -1562,7 +1585,7 @@ static void P_LoadExtendedNodes(UINT8 *data, nodetype_t nodetype) } // Read vertex data. - for (i = orivtx; i < numvertexes; i++) + for (i = origvrtx; i < numvertexes; i++) { vertexes[i].x = READFIXED(data); vertexes[i].y = READFIXED(data); @@ -1596,7 +1619,7 @@ static void P_LoadExtendedNodes(UINT8 *data, nodetype_t nodetype) segs[k + subsectors[i].numlines - 1].v2 = &vertexes[vert]; else segs[k - 1].v2 = segs[k].v1; - data += 4;// partner; can be ignored by software renderer; + data += 4; // partner; can be ignored by software renderer; linenum = READUINT16(data); if (linenum == 0xFFFF) { @@ -1623,7 +1646,7 @@ static void P_LoadExtendedNodes(UINT8 *data, nodetype_t nodetype) segs[k + subsectors[i].numlines - 1].v2 = &vertexes[vert]; else segs[k - 1].v2 = segs[k].v1; - data += 4;// partner; can be ignored by software renderer; + data += 4; // partner; can be ignored by software renderer; linenum = READUINT32(data); if (linenum == 0xFFFFFFFF) { @@ -1633,7 +1656,7 @@ static void P_LoadExtendedNodes(UINT8 *data, nodetype_t nodetype) else { segs[k].glseg = false; - segs[k].linedef = NULL; + segs[k].linedef = &lines[linenum]; } segs[k].side = READUINT8(data); } @@ -1681,54 +1704,7 @@ static void P_LoadExtendedNodes(UINT8 *data, nodetype_t nodetype) // Nodes numnodes = READINT32(data); nodes = Z_Calloc(numnodes*sizeof(*nodes), PU_LEVEL, NULL); - if (nodetype == NT_XGL3) - { - UINT32 x, y, dx, dy; - UINT32 c0, c1; - node_t *mn; - for (i = 0, mn = nodes; i < numnodes; i++, mn++) - { - // Splitter. - x = READINT32(data); - y = READINT32(data); - dx = READINT32(data); - dy = READINT32(data); - mn->x = x; - mn->y = y; - mn->dx = dx; - mn->dy = dy; - - // Bounding boxes and children. - for (j = 0; j < 2; j++) - for (k = 0; k < 4; k++) - mn->bbox[j][k] = READINT16(data) << FRACBITS; - c0 = READUINT32(data); - c1 = READUINT32(data); - mn->children[0] = ShrinkNodeID(c0); /// \todo Use UINT32 for node children in a future, instead? - mn->children[1] = ShrinkNodeID(c1); - } - } - else - { - UINT32 c0, c1; - node_t *mn; - for (i = 0, mn = nodes; i < numnodes; i++, mn++) - { - // Splitter. - mn->x = READINT16(data) << FRACBITS; - mn->y = READINT16(data) << FRACBITS; - mn->dx = READINT16(data) << FRACBITS; - mn->dy = READINT16(data) << FRACBITS; - // Bounding boxes and children. - for (j = 0; j < 2; j++) - for (k = 0; k < 4; k++) - mn->bbox[j][k] = READINT16(data) << FRACBITS; - c0 = READUINT32(data); - c1 = READUINT32(data); - mn->children[0] = ShrinkNodeID(c0); /// \todo Use UINT32 for node children in a future, instead? - mn->children[1] = ShrinkNodeID(c1); - } - } + P_LoadExtendedNodes(data, nodetype == NT_XGL3); } static void P_LoadMapBSP(const virtres_t *virt) @@ -1766,7 +1742,7 @@ static void P_LoadMapBSP(const virtres_t *virt) case NT_XNOD: case NT_XGLN: case NT_XGL3: - P_LoadExtendedNodes(virtnodes->data, nodetype); + P_LoadExtendedBSP(virtnodes->data, nodetype); break; default: CONS_Alert(CONS_WARNING, "Unsupported BSP format detected.\n"); From 3839e95d633704ff52179a6cf98cb2a3deba9901 Mon Sep 17 00:00:00 2001 From: MascaraSnake Date: Sun, 29 Dec 2019 18:07:44 +0100 Subject: [PATCH 496/746] Move reading of extra vertices into separate function --- src/p_setup.c | 74 +++++++++++++++++++++++++++++---------------------- 1 file changed, 42 insertions(+), 32 deletions(-) diff --git a/src/p_setup.c b/src/p_setup.c index 74ba5c5bd..bd68d72cc 100644 --- a/src/p_setup.c +++ b/src/p_setup.c @@ -1522,6 +1522,46 @@ static nodetype_t P_GetNodetype(const virtres_t *virt, virtlump_t *virtnodes) return supported[nodetype] ? nodetype : NT_UNSUPPORTED; } +// Extended node formats feature additional vertices; useful for OpenGL, but totally useless in gamelogic. +static boolean P_LoadExtraVertices(UINT8 *data) +{ + UINT32 origvrtx = READUINT32(data); + UINT32 xtrvrtx = READUINT32(data); + line_t* ld = lines; + vertex_t *oldpos = vertexes; + ssize_t offset; + size_t i; + + if (numvertexes != origvrtx) // If native vertex count doesn't match node original vertex count, bail out (broken data?). + { + CONS_Alert(CONS_WARNING, "Vertex count in map data and nodes differ!\n"); + return false; + } + + if (!xtrvrtx) + return true; + + // If extra vertexes were generated, reallocate the vertex array and fix the pointers. + numvertexes += xtrvrtx; + vertexes = Z_Realloc(vertexes, numvertexes*sizeof(*vertexes), PU_LEVEL, NULL); + offset = (size_t)(vertexes - oldpos); + + for (i = 0, ld = lines; i < numlines; i++, ld++) + { + ld->v1 += offset; + ld->v2 += offset; + } + + // Read extra vertex data. + for (i = origvrtx; i < numvertexes; i++) + { + vertexes[i].x = READFIXED(data); + vertexes[i].y = READFIXED(data); + } + + return true; +} + // Auxiliary function: Shrink node ID from 32-bit to 16-bit. static UINT16 ShrinkNodeID(UINT32 x) { UINT16 mask = (x >> 16) & 0xC000; @@ -1555,41 +1595,11 @@ static void P_LoadExtendedNodes(UINT8 *data, boolean xgl3) static void P_LoadExtendedBSP(UINT8 *data, nodetype_t nodetype) { - size_t i, j, k; + size_t i, k; INT16 m; - // Extended node formats feature additional vertexes; useful for OpenGL, but totally useless in gamelogic. - UINT32 origvrtx = READUINT32(data); - UINT32 xtrvrtx = READUINT32(data); - - if (numvertexes != origvrtx) // If native vertex count doesn't match node original vertex count, bail out (broken data?). - { - CONS_Alert(CONS_WARNING, "Vertex count in map data and nodes differ!\n"); + if (!P_LoadExtraVertices(data)) return; - } - - if (xtrvrtx) // If extra vertexes were generated, reallocate the vertex array and fix the pointers. - { - line_t *ld = lines; - size_t oldpos = (size_t)vertexes; - ssize_t offset; - numvertexes += xtrvrtx; - vertexes = Z_Realloc(vertexes, numvertexes*sizeof(*vertexes), PU_LEVEL, NULL); - offset = ((size_t)vertexes) - oldpos; - - for (i = 0, ld = lines; i < numlines; i++, ld++) - { - ld->v1 = (vertex_t*)((size_t)ld->v1 + offset); - ld->v2 = (vertex_t*)((size_t)ld->v2 + offset); - } - } - - // Read vertex data. - for (i = origvrtx; i < numvertexes; i++) - { - vertexes[i].x = READFIXED(data); - vertexes[i].y = READFIXED(data); - } // Subsectors numsubsectors = READUINT32(data); From c287b86fabf7098f19eea92d717dd289b1744cff Mon Sep 17 00:00:00 2001 From: MascaraSnake Date: Sun, 29 Dec 2019 19:04:50 +0100 Subject: [PATCH 497/746] Get rid of duplicated code in the extended seg parsing --- src/p_setup.c | 42 +++++------------------------------------- 1 file changed, 5 insertions(+), 37 deletions(-) diff --git a/src/p_setup.c b/src/p_setup.c index bd68d72cc..c11f216b1 100644 --- a/src/p_setup.c +++ b/src/p_setup.c @@ -1619,6 +1619,7 @@ static void P_LoadExtendedBSP(UINT8 *data, nodetype_t nodetype) switch (nodetype) { case NT_XGLN: + case NT_XGL3: for (m = 0; m < subsectors[i].numlines; m++, k++) { UINT16 linenum; @@ -1630,44 +1631,11 @@ static void P_LoadExtendedBSP(UINT8 *data, nodetype_t nodetype) else segs[k - 1].v2 = segs[k].v1; data += 4; // partner; can be ignored by software renderer; + if (nodetype == NT_XGL3) + data += 2; // Line number is 32-bit in XGL3, but we're limited to 16 bits. linenum = READUINT16(data); - if (linenum == 0xFFFF) - { - segs[k].glseg = true; - segs[k].linedef = NULL; - } - else - { - segs[k].glseg = false; - segs[k].linedef = &lines[linenum]; - } - segs[k].side = READUINT8(data); - } - break; - - case NT_XGL3: - for (m = 0; m < subsectors[i].numlines; m++, k++) - { - UINT32 linenum; - UINT32 vert; - vert = READUINT32(data); - segs[k].v1 = &vertexes[vert]; - if (m == 0) - segs[k + subsectors[i].numlines - 1].v2 = &vertexes[vert]; - else - segs[k - 1].v2 = segs[k].v1; - data += 4; // partner; can be ignored by software renderer; - linenum = READUINT32(data); - if (linenum == 0xFFFFFFFF) - { - segs[k].glseg = true; - segs[k].linedef = NULL; - } - else - { - segs[k].glseg = false; - segs[k].linedef = &lines[linenum]; - } + segs[k].glseg = (linenum == 0xFFFF); + segs[k].linedef = (linenum == 0xFFFF) ? NULL : &lines[linenum]; segs[k].side = READUINT8(data); } break; From 36f86077da25fcd1a66e5e70bc7a1ce3828aebcf Mon Sep 17 00:00:00 2001 From: MascaraSnake Date: Sun, 29 Dec 2019 19:54:04 +0100 Subject: [PATCH 498/746] Move loading of extended subsectors and segs into its own function --- src/p_setup.c | 126 +++++++++++++++++++++++++------------------------- 1 file changed, 63 insertions(+), 63 deletions(-) diff --git a/src/p_setup.c b/src/p_setup.c index c11f216b1..6315ea859 100644 --- a/src/p_setup.c +++ b/src/p_setup.c @@ -1343,6 +1343,15 @@ static void P_LoadMapData(const virtres_t *virt) memcpy(spawnsides, sides, numsides * sizeof (*sides)); } +static void P_InitializeSubsector(subsector_t *ss) +{ + ss->sector = NULL; +#ifdef FLOORSPLATS + ss->splats = NULL; +#endif + ss->validcount = 0; +} + static inline void P_LoadSubsectors(UINT8 *data) { mapsubsector_t *ms = (mapsubsector_t*)data; @@ -1351,13 +1360,9 @@ static inline void P_LoadSubsectors(UINT8 *data) for (i = 0; i < numsubsectors; i++, ss++, ms++) { - ss->sector = NULL; ss->numlines = SHORT(ms->numsegs); ss->firstline = SHORT(ms->firstseg); -#ifdef FLOORSPLATS - ss->splats = NULL; -#endif - ss->validcount = 0; + P_InitializeSubsector(ss); } } @@ -1562,44 +1567,11 @@ static boolean P_LoadExtraVertices(UINT8 *data) return true; } -// Auxiliary function: Shrink node ID from 32-bit to 16-bit. -static UINT16 ShrinkNodeID(UINT32 x) { - UINT16 mask = (x >> 16) & 0xC000; - UINT16 result = x; - return result | mask; -} - -static void P_LoadExtendedNodes(UINT8 *data, boolean xgl3) -{ - node_t *mn; - size_t i, j, k; - - for (i = 0, mn = nodes; i < numnodes; i++, mn++) - { - // Splitter - mn->x = xgl3 ? READINT32(data) : (READINT16(data) << FRACBITS); - mn->y = xgl3 ? READINT32(data) : (READINT16(data) << FRACBITS); - mn->dx = xgl3 ? READINT32(data) : (READINT16(data) << FRACBITS); - mn->dy = xgl3 ? READINT32(data) : (READINT16(data) << FRACBITS); - - // Bounding boxes - for (j = 0; j < 2; j++) - for (k = 0; k < 4; k++) - mn->bbox[j][k] = READINT16(data) << FRACBITS; - - //Children - mn->children[0] = ShrinkNodeID(READUINT32(data)); /// \todo Use UINT32 for node children in a future, instead? - mn->children[1] = ShrinkNodeID(READUINT32(data)); - } -} - -static void P_LoadExtendedBSP(UINT8 *data, nodetype_t nodetype) +static boolean P_LoadExtendedSubsectorsAndSegs(UINT8 *data, nodetype_t nodetype) { size_t i, k; INT16 m; - - if (!P_LoadExtraVertices(data)) - return; + seg_t *seg; // Subsectors numsubsectors = READUINT32(data); @@ -1615,6 +1587,7 @@ static void P_LoadExtendedBSP(UINT8 *data, nodetype_t nodetype) for (i = 0, k = 0; i < numsubsectors; i++) { subsectors[i].firstline = k; + P_InitializeSubsector(&subsectors[i]); switch (nodetype) { @@ -1655,34 +1628,57 @@ static void P_LoadExtendedBSP(UINT8 *data, nodetype_t nodetype) } } + for (i = 0, seg = segs; i < numsegs; i++, seg++) { - INT32 side; - seg_t *li; + vertex_t *v1 = seg->v1; + vertex_t *v2 = seg->v2; + seg->angle = R_PointToAngle2(v1->x, v1->y, v2->x, v2->y); + seg->offset = FixedHypot(v1->x - seg->linedef->v1->x, v1->y - seg->linedef->v1->y); + seg->sidedef = &sides[seg->linedef->sidenum[seg->side]]; + seg->frontsector = seg->sidedef->sector; + if (seg->linedef->flags & ML_TWOSIDED) + seg->backsector = sides[seg->linedef->sidenum[seg->side ^ 1]].sector; + else + seg->backsector = 0; - for (i = 0, li = segs; i < numsegs; i++, li++) - { - vertex_t *v1 = li->v1; - vertex_t *v2 = li->v2; - li->angle = R_PointToAngle2(v1->x, v1->y, v2->x, v2->y); - li->offset = FixedHypot(v1->x - li->linedef->v1->x, v1->y - li->linedef->v1->y); - side = li->side; - li->sidedef = &sides[li->linedef->sidenum[side]]; - - li->frontsector = sides[li->linedef->sidenum[side]].sector; - if (li->linedef->flags & ML_TWOSIDED) - li->backsector = sides[li->linedef->sidenum[side ^ 1]].sector; - else - li->backsector = 0; - - segs[i].numlights = 0; - segs[i].rlights = NULL; - } + seg->numlights = 0; + seg->rlights = NULL; } +} + +// Auxiliary function: Shrink node ID from 32-bit to 16-bit. +static UINT16 ShrinkNodeID(UINT32 x) { + UINT16 mask = (x >> 16) & 0xC000; + UINT16 result = x; + return result | mask; +} + +static void P_LoadExtendedNodes(UINT8 *data, nodetype_t nodetype) +{ + node_t *mn; + size_t i, j, k; + boolean xgl3 = (nodetype == NT_XGL3); - // Nodes numnodes = READINT32(data); nodes = Z_Calloc(numnodes*sizeof(*nodes), PU_LEVEL, NULL); - P_LoadExtendedNodes(data, nodetype == NT_XGL3); + + for (i = 0, mn = nodes; i < numnodes; i++, mn++) + { + // Splitter + mn->x = xgl3 ? READINT32(data) : (READINT16(data) << FRACBITS); + mn->y = xgl3 ? READINT32(data) : (READINT16(data) << FRACBITS); + mn->dx = xgl3 ? READINT32(data) : (READINT16(data) << FRACBITS); + mn->dy = xgl3 ? READINT32(data) : (READINT16(data) << FRACBITS); + + // Bounding boxes + for (j = 0; j < 2; j++) + for (k = 0; k < 4; k++) + mn->bbox[j][k] = READINT16(data) << FRACBITS; + + //Children + mn->children[0] = ShrinkNodeID(READUINT32(data)); /// \todo Use UINT32 for node children in a future, instead? + mn->children[1] = ShrinkNodeID(READUINT32(data)); + } } static void P_LoadMapBSP(const virtres_t *virt) @@ -1720,7 +1716,11 @@ static void P_LoadMapBSP(const virtres_t *virt) case NT_XNOD: case NT_XGLN: case NT_XGL3: - P_LoadExtendedBSP(virtnodes->data, nodetype); + if (!P_LoadExtraVertices(virtnodes->data)) + return; + if (!P_LoadExtendedSubsectorsAndSegs(virtnodes->data, nodetype)) + return; + P_LoadExtendedNodes(virtnodes->data, nodetype); break; default: CONS_Alert(CONS_WARNING, "Unsupported BSP format detected.\n"); From 882e8ef7b89e9f9300c616d53cd386b199d87bc7 Mon Sep 17 00:00:00 2001 From: MascaraSnake Date: Sun, 29 Dec 2019 20:24:14 +0100 Subject: [PATCH 499/746] Separate shared parts of seg initialization into P_InitializeSeg --- src/p_setup.c | 96 +++++++++++++++++++++++++++------------------------ 1 file changed, 51 insertions(+), 45 deletions(-) diff --git a/src/p_setup.c b/src/p_setup.c index 6315ea859..0e2f1faa3 100644 --- a/src/p_setup.c +++ b/src/p_setup.c @@ -1419,45 +1419,54 @@ static inline float P_SegLengthFloat(seg_t *seg) } #endif -static void P_LoadSegs(UINT8 *data) +static void P_InitializeSeg(seg_t *seg) { - INT32 linedef, side; - mapseg_t *ml = (mapseg_t*)data; - seg_t *li = segs; - line_t *ldef; - size_t i; + seg->sidedef = &sides[seg->linedef->sidenum[seg->side]]; - for (i = 0; i < numsegs; i++, li++, ml++) - { - li->v1 = &vertexes[SHORT(ml->v1)]; - li->v2 = &vertexes[SHORT(ml->v2)]; + seg->frontsector = seg->sidedef->sector; + seg->backsector = (seg->linedef->flags & ML_TWOSIDED) ? sides[seg->linedef->sidenum[seg->side ^ 1]].sector : NULL; - li->length = P_SegLength(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 - } - li->pv1 = li->pv2 = NULL; + seg->pv1 = seg->pv2 = NULL; + + //Hurdler: 04/12/2000: for now, only used in hardware mode + seg->lightmaps = NULL; // list of static lightmap for this seg #endif - li->angle = (SHORT(ml->angle))<offset = (SHORT(ml->offset))<linedef); - ldef = &lines[linedef]; - li->linedef = ldef; - li->side = side = SHORT(ml->side); - li->sidedef = &sides[ldef->sidenum[side]]; - li->frontsector = sides[ldef->sidenum[side]].sector; - if (ldef->flags & ML_TWOSIDED) - li->backsector = sides[ldef->sidenum[side^1]].sector; - else - li->backsector = 0; + seg->numlights = 0; + seg->rlights = NULL; +#ifdef POLYOBJECTS + seg->polyseg = NULL; + seg->dontrenderme = false; +#endif +} - li->numlights = 0; - li->rlights = NULL; +static void P_LoadSegs(UINT8 *data) +{ + mapseg_t *ms = (mapseg_t*)data; + seg_t *seg = segs; + size_t i; + + for (i = 0; i < numsegs; i++, seg++, ms++) + { + seg->v1 = &vertexes[SHORT(ms->v1)]; + seg->v2 = &vertexes[SHORT(ms->v2)]; + + seg->side = SHORT(ms->side); + + seg->offset = (SHORT(ms->offset)) << FRACBITS; + + seg->angle = (SHORT(ms->angle)) << FRACBITS; + + seg->linedef = &lines[SHORT(ms->linedef)]; + + seg->length = P_SegLength(seg); +#ifdef HWRENDER + seg->flength = (rendermode == render_opengl) ? P_SegLengthFloat(seg) : 0; +#endif + + seg->glseg = false; + P_InitializeSeg(seg); } } @@ -1596,16 +1605,18 @@ static boolean P_LoadExtendedSubsectorsAndSegs(UINT8 *data, nodetype_t nodetype) for (m = 0; m < subsectors[i].numlines; m++, k++) { UINT16 linenum; - UINT32 vert; - vert = READUINT32(data); + UINT32 vert = READUINT32(data); + segs[k].v1 = &vertexes[vert]; if (m == 0) segs[k + subsectors[i].numlines - 1].v2 = &vertexes[vert]; else segs[k - 1].v2 = segs[k].v1; - data += 4; // partner; can be ignored by software renderer; + + data += 4; // partner, can be ignored by software renderer if (nodetype == NT_XGL3) data += 2; // Line number is 32-bit in XGL3, but we're limited to 16 bits. + linenum = READUINT16(data); segs[k].glseg = (linenum == 0xFFFF); segs[k].linedef = (linenum == 0xFFFF) ? NULL : &lines[linenum]; @@ -1620,11 +1631,12 @@ static boolean P_LoadExtendedSubsectorsAndSegs(UINT8 *data, nodetype_t nodetype) segs[k].v2 = &vertexes[READUINT32(data)]; segs[k].linedef = &lines[READUINT16(data)]; segs[k].side = READUINT8(data); + segs[k].glseg = false; } break; default: - return; + return false; } } @@ -1632,18 +1644,12 @@ static boolean P_LoadExtendedSubsectorsAndSegs(UINT8 *data, nodetype_t nodetype) { vertex_t *v1 = seg->v1; vertex_t *v2 = seg->v2; + P_InitializeSeg(seg); seg->angle = R_PointToAngle2(v1->x, v1->y, v2->x, v2->y); seg->offset = FixedHypot(v1->x - seg->linedef->v1->x, v1->y - seg->linedef->v1->y); - seg->sidedef = &sides[seg->linedef->sidenum[seg->side]]; - seg->frontsector = seg->sidedef->sector; - if (seg->linedef->flags & ML_TWOSIDED) - seg->backsector = sides[seg->linedef->sidenum[seg->side ^ 1]].sector; - else - seg->backsector = 0; - - seg->numlights = 0; - seg->rlights = NULL; } + + return true; } // Auxiliary function: Shrink node ID from 32-bit to 16-bit. From dd02fe0d78371ef72705ea279734c48c9795fd97 Mon Sep 17 00:00:00 2001 From: MascaraSnake Date: Sun, 29 Dec 2019 20:43:41 +0100 Subject: [PATCH 500/746] P_GetNodetype: Set virtnodes for traditional Doom format --- src/p_setup.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/p_setup.c b/src/p_setup.c index 0e2f1faa3..7b5cfc4c8 100644 --- a/src/p_setup.c +++ b/src/p_setup.c @@ -1502,7 +1502,10 @@ static nodetype_t P_GetNodetype(const virtres_t *virt, virtlump_t *virtnodes) virtlump_t *virtssectors; if (virtsegs && virtsegs->size) + { + virtnodes = vres_Find(virt, "NODES"); return NT_DOOM; // Traditional map format BSP tree. + } virtssectors = vres_Find(virt, "SSECTORS"); From e88556efe13ab4818abfc0d2dd19173d06e49164 Mon Sep 17 00:00:00 2001 From: MascaraSnake Date: Sun, 29 Dec 2019 21:00:20 +0100 Subject: [PATCH 501/746] P_GetNodetype: The virtnodes pointer is supposed to be the output parameter, so we have to pass a pointer to that pointer --- src/p_setup.c | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/src/p_setup.c b/src/p_setup.c index 7b5cfc4c8..16a192c36 100644 --- a/src/p_setup.c +++ b/src/p_setup.c @@ -1485,7 +1485,7 @@ typedef enum { } nodetype_t; // Find out the BSP format. -static nodetype_t P_GetNodetype(const virtres_t *virt, virtlump_t *virtnodes) +static nodetype_t P_GetNodetype(const virtres_t *virt, virtlump_t **virtnodes) { boolean supported[NUMNODETYPES]; nodetype_t nodetype = NT_UNSUPPORTED; @@ -1493,7 +1493,7 @@ static nodetype_t P_GetNodetype(const virtres_t *virt, virtlump_t *virtnodes) if (vres_Find(virt, "TEXTMAP")) { - virtnodes = vres_Find(virt, "ZNODES"); + *virtnodes = vres_Find(virt, "ZNODES"); supported[NT_XGLN] = supported[NT_XGL3] = true; } else @@ -1503,7 +1503,7 @@ static nodetype_t P_GetNodetype(const virtres_t *virt, virtlump_t *virtnodes) if (virtsegs && virtsegs->size) { - virtnodes = vres_Find(virt, "NODES"); + *virtnodes = vres_Find(virt, "NODES"); return NT_DOOM; // Traditional map format BSP tree. } @@ -1511,19 +1511,19 @@ static nodetype_t P_GetNodetype(const virtres_t *virt, virtlump_t *virtnodes) if (virtssectors && virtssectors->size) { // Possibly GL nodes: NODES ignored, SSECTORS takes precedence as nodes lump, (It is confusing yeah) and has a signature. - virtnodes = virtssectors; + *virtnodes = virtssectors; supported[NT_XGLN] = supported[NT_ZGLN] = supported[NT_XGL3] = true; } else { // Possibly ZDoom extended nodes: SSECTORS is empty, NODES has a signature. - virtnodes = vres_Find(virt, "NODES"); + *virtnodes = vres_Find(virt, "NODES"); supported[NT_XNOD] = supported[NT_ZNOD] = true; } } - M_Memcpy(signature, virtnodes->data, 4); + M_Memcpy(signature, (*virtnodes)->data, 4); signature[4] = '\0'; - virtnodes->data += 4; + (*virtnodes)->data += 4; if (!strcmp(signature, "XNOD")) nodetype = NT_XNOD; @@ -1693,7 +1693,7 @@ static void P_LoadExtendedNodes(UINT8 *data, nodetype_t nodetype) static void P_LoadMapBSP(const virtres_t *virt) { virtlump_t *virtnodes = NULL; - nodetype_t nodetype = P_GetNodetype(virt, virtnodes); + nodetype_t nodetype = P_GetNodetype(virt, &virtnodes); switch (nodetype) { From cfc6428569b0d397e21b9554e7fc969abf00276f Mon Sep 17 00:00:00 2001 From: MascaraSnake Date: Sun, 29 Dec 2019 21:42:16 +0100 Subject: [PATCH 502/746] Pass along virtnodes to extended nodes loading functions to make sure virtnodes->data is moved correctly --- src/p_setup.c | 60 +++++++++++++++++++++++++-------------------------- 1 file changed, 30 insertions(+), 30 deletions(-) diff --git a/src/p_setup.c b/src/p_setup.c index 16a192c36..597a03232 100644 --- a/src/p_setup.c +++ b/src/p_setup.c @@ -1540,10 +1540,10 @@ static nodetype_t P_GetNodetype(const virtres_t *virt, virtlump_t **virtnodes) } // Extended node formats feature additional vertices; useful for OpenGL, but totally useless in gamelogic. -static boolean P_LoadExtraVertices(UINT8 *data) +static boolean P_LoadExtraVertices(virtlump_t *virtnodes) { - UINT32 origvrtx = READUINT32(data); - UINT32 xtrvrtx = READUINT32(data); + UINT32 origvrtx = READUINT32(virtnodes->data); + UINT32 xtrvrtx = READUINT32(virtnodes->data); line_t* ld = lines; vertex_t *oldpos = vertexes; ssize_t offset; @@ -1572,28 +1572,28 @@ static boolean P_LoadExtraVertices(UINT8 *data) // Read extra vertex data. for (i = origvrtx; i < numvertexes; i++) { - vertexes[i].x = READFIXED(data); - vertexes[i].y = READFIXED(data); + vertexes[i].x = READFIXED(virtnodes->data); + vertexes[i].y = READFIXED(virtnodes->data); } return true; } -static boolean P_LoadExtendedSubsectorsAndSegs(UINT8 *data, nodetype_t nodetype) +static boolean P_LoadExtendedSubsectorsAndSegs(virtlump_t *virtnodes, nodetype_t nodetype) { size_t i, k; INT16 m; seg_t *seg; // Subsectors - numsubsectors = READUINT32(data); + numsubsectors = READUINT32(virtnodes->data); subsectors = Z_Calloc(numsubsectors*sizeof(*subsectors), PU_LEVEL, NULL); for (i = 0; i < numsubsectors; i++) - subsectors[i].numlines = READUINT32(data); + subsectors[i].numlines = READUINT32(virtnodes->data); // Segs - numsegs = READUINT32(data); + numsegs = READUINT32(virtnodes->data); segs = Z_Calloc(numsegs*sizeof(*segs), PU_LEVEL, NULL); for (i = 0, k = 0; i < numsubsectors; i++) @@ -1608,7 +1608,7 @@ static boolean P_LoadExtendedSubsectorsAndSegs(UINT8 *data, nodetype_t nodetype) for (m = 0; m < subsectors[i].numlines; m++, k++) { UINT16 linenum; - UINT32 vert = READUINT32(data); + UINT32 vert = READUINT32(virtnodes->data); segs[k].v1 = &vertexes[vert]; if (m == 0) @@ -1616,24 +1616,24 @@ static boolean P_LoadExtendedSubsectorsAndSegs(UINT8 *data, nodetype_t nodetype) else segs[k - 1].v2 = segs[k].v1; - data += 4; // partner, can be ignored by software renderer + virtnodes->data += 4; // partner, can be ignored by software renderer if (nodetype == NT_XGL3) - data += 2; // Line number is 32-bit in XGL3, but we're limited to 16 bits. + virtnodes->data += 2; // Line number is 32-bit in XGL3, but we're limited to 16 bits. - linenum = READUINT16(data); + linenum = READUINT16(virtnodes->data); segs[k].glseg = (linenum == 0xFFFF); segs[k].linedef = (linenum == 0xFFFF) ? NULL : &lines[linenum]; - segs[k].side = READUINT8(data); + segs[k].side = READUINT8(virtnodes->data); } break; case NT_XNOD: for (m = 0; m < subsectors[i].numlines; m++, k++) { - segs[k].v1 = &vertexes[READUINT32(data)]; - segs[k].v2 = &vertexes[READUINT32(data)]; - segs[k].linedef = &lines[READUINT16(data)]; - segs[k].side = READUINT8(data); + segs[k].v1 = &vertexes[READUINT32(virtnodes->data)]; + segs[k].v2 = &vertexes[READUINT32(virtnodes->data)]; + segs[k].linedef = &lines[READUINT16(virtnodes->data)]; + segs[k].side = READUINT8(virtnodes->data); segs[k].glseg = false; } break; @@ -1662,31 +1662,31 @@ static UINT16 ShrinkNodeID(UINT32 x) { return result | mask; } -static void P_LoadExtendedNodes(UINT8 *data, nodetype_t nodetype) +static void P_LoadExtendedNodes(virtlump_t *virtnodes, nodetype_t nodetype) { node_t *mn; size_t i, j, k; boolean xgl3 = (nodetype == NT_XGL3); - numnodes = READINT32(data); + numnodes = READINT32(virtnodes->data); nodes = Z_Calloc(numnodes*sizeof(*nodes), PU_LEVEL, NULL); for (i = 0, mn = nodes; i < numnodes; i++, mn++) { // Splitter - mn->x = xgl3 ? READINT32(data) : (READINT16(data) << FRACBITS); - mn->y = xgl3 ? READINT32(data) : (READINT16(data) << FRACBITS); - mn->dx = xgl3 ? READINT32(data) : (READINT16(data) << FRACBITS); - mn->dy = xgl3 ? READINT32(data) : (READINT16(data) << FRACBITS); + mn->x = xgl3 ? READINT32(virtnodes->data) : (READINT16(virtnodes->data) << FRACBITS); + mn->y = xgl3 ? READINT32(virtnodes->data) : (READINT16(virtnodes->data) << FRACBITS); + mn->dx = xgl3 ? READINT32(virtnodes->data) : (READINT16(virtnodes->data) << FRACBITS); + mn->dy = xgl3 ? READINT32(virtnodes->data) : (READINT16(virtnodes->data) << FRACBITS); // Bounding boxes for (j = 0; j < 2; j++) for (k = 0; k < 4; k++) - mn->bbox[j][k] = READINT16(data) << FRACBITS; + mn->bbox[j][k] = READINT16(virtnodes->data) << FRACBITS; //Children - mn->children[0] = ShrinkNodeID(READUINT32(data)); /// \todo Use UINT32 for node children in a future, instead? - mn->children[1] = ShrinkNodeID(READUINT32(data)); + mn->children[0] = ShrinkNodeID(READUINT32(virtnodes->data)); /// \todo Use UINT32 for node children in a future, instead? + mn->children[1] = ShrinkNodeID(READUINT32(virtnodes->data)); } } @@ -1725,11 +1725,11 @@ static void P_LoadMapBSP(const virtres_t *virt) case NT_XNOD: case NT_XGLN: case NT_XGL3: - if (!P_LoadExtraVertices(virtnodes->data)) + if (!P_LoadExtraVertices(virtnodes)) return; - if (!P_LoadExtendedSubsectorsAndSegs(virtnodes->data, nodetype)) + if (!P_LoadExtendedSubsectorsAndSegs(virtnodes, nodetype)) return; - P_LoadExtendedNodes(virtnodes->data, nodetype); + P_LoadExtendedNodes(virtnodes, nodetype); break; default: CONS_Alert(CONS_WARNING, "Unsupported BSP format detected.\n"); From 81422c4e6d9ec7beef6b03da77bd5875b4103f97 Mon Sep 17 00:00:00 2001 From: MascaraSnake Date: Sun, 29 Dec 2019 21:57:47 +0100 Subject: [PATCH 503/746] Revert "Pass along virtnodes to extended nodes loading functions to make sure virtnodes->data is moved correctly" This reverts commit cfc6428569b0d397e21b9554e7fc969abf00276f. --- src/p_setup.c | 60 +++++++++++++++++++++++++-------------------------- 1 file changed, 30 insertions(+), 30 deletions(-) diff --git a/src/p_setup.c b/src/p_setup.c index 597a03232..16a192c36 100644 --- a/src/p_setup.c +++ b/src/p_setup.c @@ -1540,10 +1540,10 @@ static nodetype_t P_GetNodetype(const virtres_t *virt, virtlump_t **virtnodes) } // Extended node formats feature additional vertices; useful for OpenGL, but totally useless in gamelogic. -static boolean P_LoadExtraVertices(virtlump_t *virtnodes) +static boolean P_LoadExtraVertices(UINT8 *data) { - UINT32 origvrtx = READUINT32(virtnodes->data); - UINT32 xtrvrtx = READUINT32(virtnodes->data); + UINT32 origvrtx = READUINT32(data); + UINT32 xtrvrtx = READUINT32(data); line_t* ld = lines; vertex_t *oldpos = vertexes; ssize_t offset; @@ -1572,28 +1572,28 @@ static boolean P_LoadExtraVertices(virtlump_t *virtnodes) // Read extra vertex data. for (i = origvrtx; i < numvertexes; i++) { - vertexes[i].x = READFIXED(virtnodes->data); - vertexes[i].y = READFIXED(virtnodes->data); + vertexes[i].x = READFIXED(data); + vertexes[i].y = READFIXED(data); } return true; } -static boolean P_LoadExtendedSubsectorsAndSegs(virtlump_t *virtnodes, nodetype_t nodetype) +static boolean P_LoadExtendedSubsectorsAndSegs(UINT8 *data, nodetype_t nodetype) { size_t i, k; INT16 m; seg_t *seg; // Subsectors - numsubsectors = READUINT32(virtnodes->data); + numsubsectors = READUINT32(data); subsectors = Z_Calloc(numsubsectors*sizeof(*subsectors), PU_LEVEL, NULL); for (i = 0; i < numsubsectors; i++) - subsectors[i].numlines = READUINT32(virtnodes->data); + subsectors[i].numlines = READUINT32(data); // Segs - numsegs = READUINT32(virtnodes->data); + numsegs = READUINT32(data); segs = Z_Calloc(numsegs*sizeof(*segs), PU_LEVEL, NULL); for (i = 0, k = 0; i < numsubsectors; i++) @@ -1608,7 +1608,7 @@ static boolean P_LoadExtendedSubsectorsAndSegs(virtlump_t *virtnodes, nodetype_t for (m = 0; m < subsectors[i].numlines; m++, k++) { UINT16 linenum; - UINT32 vert = READUINT32(virtnodes->data); + UINT32 vert = READUINT32(data); segs[k].v1 = &vertexes[vert]; if (m == 0) @@ -1616,24 +1616,24 @@ static boolean P_LoadExtendedSubsectorsAndSegs(virtlump_t *virtnodes, nodetype_t else segs[k - 1].v2 = segs[k].v1; - virtnodes->data += 4; // partner, can be ignored by software renderer + data += 4; // partner, can be ignored by software renderer if (nodetype == NT_XGL3) - virtnodes->data += 2; // Line number is 32-bit in XGL3, but we're limited to 16 bits. + data += 2; // Line number is 32-bit in XGL3, but we're limited to 16 bits. - linenum = READUINT16(virtnodes->data); + linenum = READUINT16(data); segs[k].glseg = (linenum == 0xFFFF); segs[k].linedef = (linenum == 0xFFFF) ? NULL : &lines[linenum]; - segs[k].side = READUINT8(virtnodes->data); + segs[k].side = READUINT8(data); } break; case NT_XNOD: for (m = 0; m < subsectors[i].numlines; m++, k++) { - segs[k].v1 = &vertexes[READUINT32(virtnodes->data)]; - segs[k].v2 = &vertexes[READUINT32(virtnodes->data)]; - segs[k].linedef = &lines[READUINT16(virtnodes->data)]; - segs[k].side = READUINT8(virtnodes->data); + segs[k].v1 = &vertexes[READUINT32(data)]; + segs[k].v2 = &vertexes[READUINT32(data)]; + segs[k].linedef = &lines[READUINT16(data)]; + segs[k].side = READUINT8(data); segs[k].glseg = false; } break; @@ -1662,31 +1662,31 @@ static UINT16 ShrinkNodeID(UINT32 x) { return result | mask; } -static void P_LoadExtendedNodes(virtlump_t *virtnodes, nodetype_t nodetype) +static void P_LoadExtendedNodes(UINT8 *data, nodetype_t nodetype) { node_t *mn; size_t i, j, k; boolean xgl3 = (nodetype == NT_XGL3); - numnodes = READINT32(virtnodes->data); + numnodes = READINT32(data); nodes = Z_Calloc(numnodes*sizeof(*nodes), PU_LEVEL, NULL); for (i = 0, mn = nodes; i < numnodes; i++, mn++) { // Splitter - mn->x = xgl3 ? READINT32(virtnodes->data) : (READINT16(virtnodes->data) << FRACBITS); - mn->y = xgl3 ? READINT32(virtnodes->data) : (READINT16(virtnodes->data) << FRACBITS); - mn->dx = xgl3 ? READINT32(virtnodes->data) : (READINT16(virtnodes->data) << FRACBITS); - mn->dy = xgl3 ? READINT32(virtnodes->data) : (READINT16(virtnodes->data) << FRACBITS); + mn->x = xgl3 ? READINT32(data) : (READINT16(data) << FRACBITS); + mn->y = xgl3 ? READINT32(data) : (READINT16(data) << FRACBITS); + mn->dx = xgl3 ? READINT32(data) : (READINT16(data) << FRACBITS); + mn->dy = xgl3 ? READINT32(data) : (READINT16(data) << FRACBITS); // Bounding boxes for (j = 0; j < 2; j++) for (k = 0; k < 4; k++) - mn->bbox[j][k] = READINT16(virtnodes->data) << FRACBITS; + mn->bbox[j][k] = READINT16(data) << FRACBITS; //Children - mn->children[0] = ShrinkNodeID(READUINT32(virtnodes->data)); /// \todo Use UINT32 for node children in a future, instead? - mn->children[1] = ShrinkNodeID(READUINT32(virtnodes->data)); + mn->children[0] = ShrinkNodeID(READUINT32(data)); /// \todo Use UINT32 for node children in a future, instead? + mn->children[1] = ShrinkNodeID(READUINT32(data)); } } @@ -1725,11 +1725,11 @@ static void P_LoadMapBSP(const virtres_t *virt) case NT_XNOD: case NT_XGLN: case NT_XGL3: - if (!P_LoadExtraVertices(virtnodes)) + if (!P_LoadExtraVertices(virtnodes->data)) return; - if (!P_LoadExtendedSubsectorsAndSegs(virtnodes, nodetype)) + if (!P_LoadExtendedSubsectorsAndSegs(virtnodes->data, nodetype)) return; - P_LoadExtendedNodes(virtnodes, nodetype); + P_LoadExtendedNodes(virtnodes->data, nodetype); break; default: CONS_Alert(CONS_WARNING, "Unsupported BSP format detected.\n"); From 136c656cc09fa3ac27d6a3fe56dbd5d8b6dfc718 Mon Sep 17 00:00:00 2001 From: MascaraSnake Date: Sun, 29 Dec 2019 22:11:15 +0100 Subject: [PATCH 504/746] Properly pass nodes data along to functions that need it without breaking the original data pointer --- src/p_setup.c | 79 ++++++++++++++++++++++++++------------------------- 1 file changed, 40 insertions(+), 39 deletions(-) diff --git a/src/p_setup.c b/src/p_setup.c index 16a192c36..a043c1e51 100644 --- a/src/p_setup.c +++ b/src/p_setup.c @@ -1485,7 +1485,7 @@ typedef enum { } nodetype_t; // Find out the BSP format. -static nodetype_t P_GetNodetype(const virtres_t *virt, virtlump_t **virtnodes) +static nodetype_t P_GetNodetype(const virtres_t *virt, UINT8 **nodedata) { boolean supported[NUMNODETYPES]; nodetype_t nodetype = NT_UNSUPPORTED; @@ -1493,7 +1493,7 @@ static nodetype_t P_GetNodetype(const virtres_t *virt, virtlump_t **virtnodes) if (vres_Find(virt, "TEXTMAP")) { - *virtnodes = vres_Find(virt, "ZNODES"); + *nodedata = vres_Find(virt, "ZNODES")->data; supported[NT_XGLN] = supported[NT_XGL3] = true; } else @@ -1503,7 +1503,7 @@ static nodetype_t P_GetNodetype(const virtres_t *virt, virtlump_t **virtnodes) if (virtsegs && virtsegs->size) { - *virtnodes = vres_Find(virt, "NODES"); + *nodedata = vres_Find(virt, "NODES")->data; return NT_DOOM; // Traditional map format BSP tree. } @@ -1511,19 +1511,19 @@ static nodetype_t P_GetNodetype(const virtres_t *virt, virtlump_t **virtnodes) if (virtssectors && virtssectors->size) { // Possibly GL nodes: NODES ignored, SSECTORS takes precedence as nodes lump, (It is confusing yeah) and has a signature. - *virtnodes = virtssectors; + *nodedata = virtssectors->data; supported[NT_XGLN] = supported[NT_ZGLN] = supported[NT_XGL3] = true; } else { // Possibly ZDoom extended nodes: SSECTORS is empty, NODES has a signature. - *virtnodes = vres_Find(virt, "NODES"); + *nodedata = vres_Find(virt, "NODES")->data; supported[NT_XNOD] = supported[NT_ZNOD] = true; } } - M_Memcpy(signature, (*virtnodes)->data, 4); + M_Memcpy(signature, *nodedata, 4); signature[4] = '\0'; - (*virtnodes)->data += 4; + (*nodedata) += 4; if (!strcmp(signature, "XNOD")) nodetype = NT_XNOD; @@ -1540,10 +1540,10 @@ static nodetype_t P_GetNodetype(const virtres_t *virt, virtlump_t **virtnodes) } // Extended node formats feature additional vertices; useful for OpenGL, but totally useless in gamelogic. -static boolean P_LoadExtraVertices(UINT8 *data) +static boolean P_LoadExtraVertices(UINT8 **data) { - UINT32 origvrtx = READUINT32(data); - UINT32 xtrvrtx = READUINT32(data); + UINT32 origvrtx = READUINT32((*data)); + UINT32 xtrvrtx = READUINT32((*data)); line_t* ld = lines; vertex_t *oldpos = vertexes; ssize_t offset; @@ -1572,28 +1572,28 @@ static boolean P_LoadExtraVertices(UINT8 *data) // Read extra vertex data. for (i = origvrtx; i < numvertexes; i++) { - vertexes[i].x = READFIXED(data); - vertexes[i].y = READFIXED(data); + vertexes[i].x = READFIXED((*data)); + vertexes[i].y = READFIXED((*data)); } return true; } -static boolean P_LoadExtendedSubsectorsAndSegs(UINT8 *data, nodetype_t nodetype) +static boolean P_LoadExtendedSubsectorsAndSegs(UINT8 **data, nodetype_t nodetype) { size_t i, k; INT16 m; seg_t *seg; // Subsectors - numsubsectors = READUINT32(data); + numsubsectors = READUINT32((*data)); subsectors = Z_Calloc(numsubsectors*sizeof(*subsectors), PU_LEVEL, NULL); for (i = 0; i < numsubsectors; i++) - subsectors[i].numlines = READUINT32(data); + subsectors[i].numlines = READUINT32((*data)); // Segs - numsegs = READUINT32(data); + numsegs = READUINT32((*data)); segs = Z_Calloc(numsegs*sizeof(*segs), PU_LEVEL, NULL); for (i = 0, k = 0; i < numsubsectors; i++) @@ -1608,7 +1608,7 @@ static boolean P_LoadExtendedSubsectorsAndSegs(UINT8 *data, nodetype_t nodetype) for (m = 0; m < subsectors[i].numlines; m++, k++) { UINT16 linenum; - UINT32 vert = READUINT32(data); + UINT32 vert = READUINT32((*data)); segs[k].v1 = &vertexes[vert]; if (m == 0) @@ -1616,24 +1616,24 @@ static boolean P_LoadExtendedSubsectorsAndSegs(UINT8 *data, nodetype_t nodetype) else segs[k - 1].v2 = segs[k].v1; - data += 4; // partner, can be ignored by software renderer + (*data) += 4; // partner, can be ignored by software renderer if (nodetype == NT_XGL3) - data += 2; // Line number is 32-bit in XGL3, but we're limited to 16 bits. + (*data) += 2; // Line number is 32-bit in XGL3, but we're limited to 16 bits. - linenum = READUINT16(data); + linenum = READUINT16((*data)); segs[k].glseg = (linenum == 0xFFFF); segs[k].linedef = (linenum == 0xFFFF) ? NULL : &lines[linenum]; - segs[k].side = READUINT8(data); + segs[k].side = READUINT8((*data)); } break; case NT_XNOD: for (m = 0; m < subsectors[i].numlines; m++, k++) { - segs[k].v1 = &vertexes[READUINT32(data)]; - segs[k].v2 = &vertexes[READUINT32(data)]; - segs[k].linedef = &lines[READUINT16(data)]; - segs[k].side = READUINT8(data); + segs[k].v1 = &vertexes[READUINT32((*data))]; + segs[k].v2 = &vertexes[READUINT32((*data))]; + segs[k].linedef = &lines[READUINT16((*data))]; + segs[k].side = READUINT8((*data)); segs[k].glseg = false; } break; @@ -1662,44 +1662,45 @@ static UINT16 ShrinkNodeID(UINT32 x) { return result | mask; } -static void P_LoadExtendedNodes(UINT8 *data, nodetype_t nodetype) +static void P_LoadExtendedNodes(UINT8 **data, nodetype_t nodetype) { node_t *mn; size_t i, j, k; boolean xgl3 = (nodetype == NT_XGL3); - numnodes = READINT32(data); + numnodes = READINT32((*data)); nodes = Z_Calloc(numnodes*sizeof(*nodes), PU_LEVEL, NULL); for (i = 0, mn = nodes; i < numnodes; i++, mn++) { // Splitter - mn->x = xgl3 ? READINT32(data) : (READINT16(data) << FRACBITS); - mn->y = xgl3 ? READINT32(data) : (READINT16(data) << FRACBITS); - mn->dx = xgl3 ? READINT32(data) : (READINT16(data) << FRACBITS); - mn->dy = xgl3 ? READINT32(data) : (READINT16(data) << FRACBITS); + mn->x = xgl3 ? READINT32((*data)) : (READINT16((*data)) << FRACBITS); + mn->y = xgl3 ? READINT32((*data)) : (READINT16((*data)) << FRACBITS); + mn->dx = xgl3 ? READINT32((*data)) : (READINT16((*data)) << FRACBITS); + mn->dy = xgl3 ? READINT32((*data)) : (READINT16((*data)) << FRACBITS); // Bounding boxes for (j = 0; j < 2; j++) for (k = 0; k < 4; k++) - mn->bbox[j][k] = READINT16(data) << FRACBITS; + mn->bbox[j][k] = READINT16((*data)) << FRACBITS; //Children - mn->children[0] = ShrinkNodeID(READUINT32(data)); /// \todo Use UINT32 for node children in a future, instead? - mn->children[1] = ShrinkNodeID(READUINT32(data)); + mn->children[0] = ShrinkNodeID(READUINT32((*data))); /// \todo Use UINT32 for node children in a future, instead? + mn->children[1] = ShrinkNodeID(READUINT32((*data))); } } static void P_LoadMapBSP(const virtres_t *virt) { - virtlump_t *virtnodes = NULL; - nodetype_t nodetype = P_GetNodetype(virt, &virtnodes); + UINT8 *nodedata = NULL; + nodetype_t nodetype = P_GetNodetype(virt, &nodedata); switch (nodetype) { case NT_DOOM: { virtlump_t *virtssectors = vres_Find(virt, "SSECTORS"); + virtlump_t* virtnodes = vres_Find(virt, "NODES"); virtlump_t *virtsegs = vres_Find(virt, "SEGS"); numsubsectors = virtssectors->size / sizeof(mapsubsector_t); @@ -1725,11 +1726,11 @@ static void P_LoadMapBSP(const virtres_t *virt) case NT_XNOD: case NT_XGLN: case NT_XGL3: - if (!P_LoadExtraVertices(virtnodes->data)) + if (!P_LoadExtraVertices(&nodedata)) return; - if (!P_LoadExtendedSubsectorsAndSegs(virtnodes->data, nodetype)) + if (!P_LoadExtendedSubsectorsAndSegs(&nodedata, nodetype)) return; - P_LoadExtendedNodes(virtnodes->data, nodetype); + P_LoadExtendedNodes(&nodedata, nodetype); break; default: CONS_Alert(CONS_WARNING, "Unsupported BSP format detected.\n"); From 2f4c270a7bd322e7c67f8d2cf64f9022dce2e879 Mon Sep 17 00:00:00 2001 From: Jaime Passos Date: Sun, 29 Dec 2019 19:43:38 -0300 Subject: [PATCH 505/746] 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 ae9adce873cbb4938a34657d783286fa14469c8a Mon Sep 17 00:00:00 2001 From: GoldenTails Date: Sun, 29 Dec 2019 18:26:56 -0600 Subject: [PATCH 506/746] Replace magic numbers with less magic and more readable chars. --- src/m_menu.c | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/src/m_menu.c b/src/m_menu.c index fed0d65b1..e1e28b671 100644 --- a/src/m_menu.c +++ b/src/m_menu.c @@ -10436,7 +10436,8 @@ static void M_HandleConnectIP(INT32 choice) if ( ctrldown ) { switch (choice) { - case 118: // ctrl+v, pasting + case 'v': + case 'V': // ctrl+v, pasting ; char *paste = (char *)I_ClipboardPaste(); // Paste clipboard into char @@ -10448,13 +10449,15 @@ static void M_HandleConnectIP(INT32 choice) S_StartSound(NULL,sfx_menu1); // Tails } break; - - case 99: // ctrl+c, copying + + case 'c': + case 'C': // ctrl+c, copying I_ClipboardCopy(setupm_ip, l); S_StartSound(NULL,sfx_menu1); // Tails break; - case 120: // ctrl+x, cutting + case 'x': + case 'X': // ctrl+x, cutting I_ClipboardCopy(setupm_ip, l); S_StartSound(NULL,sfx_menu1); // Tails setupm_ip[0] = 0; From 97c5e63dc331f838e951bd10fed7fb8d69ea420f Mon Sep 17 00:00:00 2001 From: James R Date: Sun, 29 Dec 2019 16:52:39 -0800 Subject: [PATCH 507/746] Initialize 'supported' array --- src/p_setup.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/p_setup.c b/src/p_setup.c index a043c1e51..99da5ccee 100644 --- a/src/p_setup.c +++ b/src/p_setup.c @@ -1487,7 +1487,7 @@ typedef enum { // Find out the BSP format. static nodetype_t P_GetNodetype(const virtres_t *virt, UINT8 **nodedata) { - boolean supported[NUMNODETYPES]; + boolean supported[NUMNODETYPES] = {0}; nodetype_t nodetype = NT_UNSUPPORTED; char signature[4 + 1]; From 9d701d722ebd08d4939ea43e195a5f0325338e0a Mon Sep 17 00:00:00 2001 From: GoldenTails Date: Sun, 29 Dec 2019 20:15:18 -0600 Subject: [PATCH 508/746] Reverted to better, less complex system, and added support for Shift+Insert and Shift+Delete. Major thanks to James for helping me. Turns out that strncpy thwarts the memory leaks for me. Silly, me! --- src/m_menu.c | 46 ++++++++++++++++++++++++++++++++++++---------- 1 file changed, 36 insertions(+), 10 deletions(-) diff --git a/src/m_menu.c b/src/m_menu.c index e1e28b671..ef9335907 100644 --- a/src/m_menu.c +++ b/src/m_menu.c @@ -10424,13 +10424,15 @@ static void M_HandleConnectIP(INT32 choice) break; case KEY_DEL: - if (setupm_ip[0]) + if (setupm_ip[0] && !shiftdown) // Shift+Delete is used for something else. { S_StartSound(NULL,sfx_menu1); // Tails setupm_ip[0] = 0; } - break; - + if (!shiftdown) // Shift+Delete is used for something else. + break; + + /* FALLTHRU */ default: l = strlen(setupm_ip); @@ -10438,18 +10440,17 @@ static void M_HandleConnectIP(INT32 choice) switch (choice) { case 'v': case 'V': // ctrl+v, pasting - ; - char *paste = (char *)I_ClipboardPaste(); // Paste clipboard into char - + { + const char *paste = I_ClipboardPaste(); + if (paste != NULL) { - if (strlen(paste) + l >= 28-1) - paste[28-1 - l] = 0; - strcat(setupm_ip, paste); // Concat the ip field with clipboard + strncat(setupm_ip, paste, 28-1 - l); // Concat the ip field with clipboard if (strlen(paste) != 0) // Don't play sound if nothing was pasted S_StartSound(NULL,sfx_menu1); // Tails } + break; - + } case 'c': case 'C': // ctrl+c, copying I_ClipboardCopy(setupm_ip, l); @@ -10469,6 +10470,31 @@ static void M_HandleConnectIP(INT32 choice) break; // don't check for typed keys } + if ( shiftdown ) { + switch (choice) { + case KEY_INS: + { + const char *paste = I_ClipboardPaste(); + + if (paste != NULL) { + strncat(setupm_ip, paste, 28-1 - l); // Concat the ip field with clipboard + if (strlen(paste) != 0) // Don't play sound if nothing was pasted + S_StartSound(NULL,sfx_menu1); // Tails + } + + break; + } + case KEY_DEL: // shift+delete, cutting + I_ClipboardCopy(setupm_ip, l); + S_StartSound(NULL,sfx_menu1); // Tails + setupm_ip[0] = 0; + break; + default: // otherwise do nothing. + break; + } + break; // don't check for typed keys + } + if (l >= 28-1) break; From bc88def2254afd6d24f6503fddf49f008b811bc9 Mon Sep 17 00:00:00 2001 From: GoldenTails Date: Sun, 29 Dec 2019 20:22:58 -0600 Subject: [PATCH 509/746] Slap in some Ctrl+Insert (copy) support too while I'm at it. Also added a comment but you didn't see that. --- src/m_menu.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/src/m_menu.c b/src/m_menu.c index ef9335907..e9cbe9980 100644 --- a/src/m_menu.c +++ b/src/m_menu.c @@ -10431,7 +10431,7 @@ static void M_HandleConnectIP(INT32 choice) } if (!shiftdown) // Shift+Delete is used for something else. break; - + /* FALLTHRU */ default: l = strlen(setupm_ip); @@ -10451,8 +10451,9 @@ static void M_HandleConnectIP(INT32 choice) break; } + case KEY_INS: case 'c': - case 'C': // ctrl+c, copying + case 'C': // ctrl+c, ctrl+insert, copying I_ClipboardCopy(setupm_ip, l); S_StartSound(NULL,sfx_menu1); // Tails break; @@ -10472,7 +10473,7 @@ static void M_HandleConnectIP(INT32 choice) if ( shiftdown ) { switch (choice) { - case KEY_INS: + case KEY_INS: // shift+insert, pasting { const char *paste = I_ClipboardPaste(); From 569453ee93d26fa3840915ac0307c2ba3d1a02c6 Mon Sep 17 00:00:00 2001 From: James R Date: Sun, 29 Dec 2019 18:37:22 -0800 Subject: [PATCH 510/746] Warn when going to OpenGL from the menu --- src/d_netcmd.c | 1 + src/m_menu.c | 43 ++++++++++++++++++++++++++++++++++++++++++- src/screen.c | 3 ++- src/screen.h | 4 ++++ 4 files changed, 49 insertions(+), 2 deletions(-) diff --git a/src/d_netcmd.c b/src/d_netcmd.c index f619f666a..28843c0d7 100644 --- a/src/d_netcmd.c +++ b/src/d_netcmd.c @@ -842,6 +842,7 @@ void D_RegisterClientCommands(void) CV_RegisterVar(&cv_fullscreen); CV_RegisterVar(&cv_renderview); CV_RegisterVar(&cv_renderer); + CV_RegisterVar(&cv_newrenderer); CV_RegisterVar(&cv_scr_depth); CV_RegisterVar(&cv_scr_width); CV_RegisterVar(&cv_scr_height); diff --git a/src/m_menu.c b/src/m_menu.c index e2451de6a..cbc65f86f 100644 --- a/src/m_menu.c +++ b/src/m_menu.c @@ -389,6 +389,7 @@ static void M_ResetCvars(void); // Consvar onchange functions static void Newgametype_OnChange(void); +static void Newrenderer_OnChange(void); static void Dummymares_OnChange(void); // ========================================================================== @@ -413,6 +414,9 @@ CV_PossibleValue_t gametype_cons_t[NUMGAMETYPES+1]; consvar_t cv_newgametype = {"newgametype", "Co-op", CV_HIDEN|CV_CALL, gametype_cons_t, Newgametype_OnChange, 0, NULL, NULL, 0, 0, NULL}; +consvar_t cv_newrenderer = {"newrenderer", "Software", CV_HIDEN|CV_CALL, cv_renderer_t, Newrenderer_OnChange, 0, NULL, NULL, 0, 0, NULL}; +static int newrenderer_set = 1;/* Software doesn't need confirmation! */ + static CV_PossibleValue_t serversort_cons_t[] = { {0,"Ping"}, {1,"Modified State"}, @@ -1210,7 +1214,7 @@ static menuitem_t OP_VideoOptionsMenu[] = {IT_STRING|IT_CVAR, NULL, "Fullscreen", &cv_fullscreen, 11}, #endif {IT_STRING | IT_CVAR, NULL, "Vertical Sync", &cv_vidwait, 16}, - {IT_STRING | IT_CVAR, NULL, "Renderer", &cv_renderer, 21}, + {IT_STRING | IT_CVAR, NULL, "Renderer", &cv_newrenderer, 21}, {IT_HEADER, NULL, "Color Profile", NULL, 30}, {IT_STRING | IT_CVAR | IT_CV_SLIDER, NULL, "Brightness (F11)", &cv_globalgamma,36}, @@ -2223,6 +2227,43 @@ static void Newgametype_OnChange(void) } } +static void Newrenderer_AREYOUSURE(INT32 c) +{ + int n; + switch (c) + { + case 'y': + case KEY_ENTER: + n = cv_newrenderer.value; + newrenderer_set |= n; + CV_SetValue(&cv_renderer, n); + break; + default: + CV_StealthSetValue(&cv_newrenderer, cv_renderer.value); + } +} + +static void Newrenderer_OnChange(void) +{ + /* Well this works for now because there's only two options. */ + int n; + n = cv_newrenderer.value; + if (( newrenderer_set & n )) + CV_SetValue(&cv_renderer, n); + else + { + M_StartMessage( + "The OpenGL renderer is incomplete.\n" + "Some visuals may fail to appear, or\n" + "appear incorrectly.\n" + "Do you still want to switch to it?\n" + "\n" + "(Press 'y' or 'n')", + Newrenderer_AREYOUSURE, MM_YESNO + ); + } +} + void Screenshot_option_Onchange(void) { OP_ScreenshotOptionsMenu[op_screenshot_folder].status = diff --git a/src/screen.c b/src/screen.c index 16ba13087..f9d81f8af 100644 --- a/src/screen.c +++ b/src/screen.c @@ -64,7 +64,7 @@ consvar_t cv_scr_depth = {"scr_depth", "16 bits", CV_SAVE, scr_depth_cons_t, NUL consvar_t cv_renderview = {"renderview", "On", 0, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL}; static void SCR_ActuallyChangeRenderer(void); -static CV_PossibleValue_t cv_renderer_t[] = {{1, "Software"}, {2, "OpenGL"}, {0, NULL}}; +CV_PossibleValue_t cv_renderer_t[] = {{1, "Software"}, {2, "OpenGL"}, {0, NULL}}; consvar_t cv_renderer = {"renderer", "Software", CV_SAVE|CV_NOLUA|CV_CALL, cv_renderer_t, SCR_ChangeRenderer, 0, NULL, NULL, 0, 0, NULL}; static void SCR_ChangeFullscreen(void); @@ -477,6 +477,7 @@ void SCR_ChangeRendererCVars(INT32 mode) CV_StealthSetValue(&cv_renderer, 1); else if (mode == render_opengl) CV_StealthSetValue(&cv_renderer, 2); + CV_StealthSetValue(&cv_newrenderer, cv_renderer.value); } boolean SCR_IsAspectCorrect(INT32 width, INT32 height) diff --git a/src/screen.h b/src/screen.h index 884ee303b..d47cdff9a 100644 --- a/src/screen.h +++ b/src/screen.h @@ -170,6 +170,7 @@ extern boolean R_SSE2; // ---------------- // screen variables // ---------------- + extern viddef_t vid; extern INT32 setmodeneeded; // mode number to set if needed, or 0 @@ -180,7 +181,10 @@ extern UINT8 setrenderneeded; extern INT32 scr_bpp; extern UINT8 *scr_borderpatch; // patch used to fill the view borders +extern CV_PossibleValue_t cv_renderer_t[]; + extern consvar_t cv_scr_width, cv_scr_height, cv_scr_depth, cv_renderview, cv_renderer, cv_fullscreen; +extern consvar_t cv_newrenderer; // wait for page flipping to end or not extern consvar_t cv_vidwait; From 7886a4bbee28c61dc6f877f5c6af8474a1453ac2 Mon Sep 17 00:00:00 2001 From: James R Date: Sun, 29 Dec 2019 18:37:44 -0800 Subject: [PATCH 511/746] 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 773d564d6adb336808c119b23ce8f2e2a43bb529 Mon Sep 17 00:00:00 2001 From: Jaime Passos Date: Mon, 30 Dec 2019 00:22:27 -0300 Subject: [PATCH 512/746] MUSICDEF parser changes. --- src/s_sound.c | 91 +++++++++++++++++++++++++++++++++++++++------------ 1 file changed, 70 insertions(+), 21 deletions(-) diff --git a/src/s_sound.c b/src/s_sound.c index a49499040..1b7c7c8c5 100644 --- a/src/s_sound.c +++ b/src/s_sound.c @@ -1469,6 +1469,7 @@ void S_LoadMusicDefs(UINT16 wadnum) char *buf2; char *stoken; char *value; + char *textline; size_t size; INT32 i; musicdef_t *def = NULL; @@ -1560,9 +1561,63 @@ skip_lump: } else { - value = strtok(NULL, "\r\n= "); + // If this is set true, the line was invalid. + boolean brokenline = false; + // Delimit only by line break. + value = strtok(NULL, "\r\n"); + + // Find the equals sign. + value = strchr(value, '='); + + // It's not there?! if (!value) + brokenline = true; + else + { + // Skip the equals sign. + value++; + + // Now skip funny whitespace. + for (;;) + { + char c = value[0]; + if (c == '\0') // :NOTHING: + { + brokenline = true; + break; + } + else if (c == ' ' || c == '\t') + value++; + else + break; + } + } + + // If the line is valid, copy the text line from the lump data. + if (!brokenline) + { + // strtok returns memory that already belongs to the input string. + value = buf + (value - buf2); + + // Find the length of the line. + size = 0; + for (;;) + { + char c = value[size]; + if (c == '\n' || c == '\r' || c == '\0') + break; + size++; + } + + // Copy the line. + textline = malloc(size+1); + if (!textline) + I_Error("S_LoadMusicDefs: No more free memory for text line\n"); + M_Memcpy(textline, value, size); + textline[size] = '\0'; + } + else { CONS_Alert(CONS_WARNING, "MUSICDEF: Field '%s' is missing value. (file %s, line %d)\n", stoken, wadfiles[wadnum]->filename, line); stoken = strtok(NULL, "\r\n"); // skip end of line @@ -1572,53 +1627,44 @@ skip_lump: if (!def) { CONS_Alert(CONS_ERROR, "MUSICDEF: No music definition before field '%s'. (file %s, line %d)\n", stoken, wadfiles[wadnum]->filename, line); + free(textline); free(buf2); return; } - i = atoi(value); + i = atoi(textline); if (!stricmp(stoken, "usage")) { #if 0 // Ignore for now - STRBUFCPY(def->usage, value); - for (value = def->usage; *value; value++) - if (*value == '_') *value = ' '; // turn _ into spaces. + STRBUFCPY(def->usage, textline); //CONS_Printf("S_LoadMusicDefs: Set usage to '%s'\n", def->usage); #endif } else if (!stricmp(stoken, "source")) { #if 0 // Ignore for now - STRBUFCPY(def->source, value); - for (value = def->source; *value; value++) - if (*value == '_') *value = ' '; // turn _ into spaces. + STRBUFCPY(def->source, textline); //CONS_Printf("S_LoadMusicDefs: Set source to '%s'\n", def->usage); #endif } else if (!stricmp(stoken, "title")) { - STRBUFCPY(def->title, value); - for (value = def->title; *value; value++) - if (*value == '_') *value = ' '; // turn _ into spaces. + STRBUFCPY(def->title, textline); //CONS_Printf("S_LoadMusicDefs: Set title to '%s'\n", def->source); } else if (!stricmp(stoken, "alttitle")) { - STRBUFCPY(def->alttitle, value); - for (value = def->alttitle; *value; value++) - if (*value == '_') *value = ' '; // turn _ into spaces. + STRBUFCPY(def->alttitle, textline); //CONS_Printf("S_LoadMusicDefs: Set alttitle to '%s'\n", def->source); } else if (!stricmp(stoken, "authors")) { - STRBUFCPY(def->authors, value); - for (value = def->authors; *value; value++) - if (*value == '_') *value = ' '; // turn _ into spaces. + STRBUFCPY(def->authors, textline); //CONS_Printf("S_LoadMusicDefs: Set authors to '%s'\n", def->source); } else if (!stricmp(stoken, "soundtestpage")) { def->soundtestpage = (UINT8)i; } else if (!stricmp(stoken, "soundtestcond")) { // Convert to map number - if (value[0] >= 'A' && value[0] <= 'Z' && value[2] == '\0') - i = M_MapNumber(value[0], value[1]); + if (textline[0] >= 'A' && textline[0] <= 'Z' && textline[2] == '\0') + i = M_MapNumber(textline[0], textline[1]); def->soundtestcond = (INT16)i; } else if (!stricmp(stoken, "stoppingtime")) { - double stoppingtime = atof(value)*TICRATE; + double stoppingtime = atof(textline)*TICRATE; def->stoppingtics = (tic_t)stoppingtime; } else if (!stricmp(stoken, "bpm")) { - double bpm = atof(value); + double bpm = atof(textline); fixed_t bpmf = FLOAT_TO_FIXED(bpm); if (bpmf > 0) def->bpm = FixedDiv((60*TICRATE)<filename, line); } + // Free the temporary line from memory. + free(textline); + skip_field: stoken = strtok(NULL, "\r\n= "); line++; From 3d724f302df688f26e6e4c0ce180a5fa23633721 Mon Sep 17 00:00:00 2001 From: Tatsuru <44866610+Ikkarin@users.noreply.github.com> Date: Mon, 30 Dec 2019 01:16:50 -0300 Subject: [PATCH 513/746] Fix saloon doors not letting players through when marked with the Ambush flag --- src/p_enemy.c | 2 +- src/p_map.c | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/p_enemy.c b/src/p_enemy.c index 74a11fe67..08aeac383 100644 --- a/src/p_enemy.c +++ b/src/p_enemy.c @@ -14248,7 +14248,7 @@ void A_SaloonDoorSpawn(mobj_t *actor) fixed_t c = FINECOSINE(fa)*locvar2; fixed_t s = FINESINE(fa)*locvar2; mobj_t *door; - mobjflag2_t ambush = (actor->flags & MF2_AMBUSH); + mobjflag2_t ambush = (actor->flags2 & MF2_AMBUSH); #ifdef HAVE_BLUA if (LUA_CallAction("A_SaloonDoorSpawn", actor)) diff --git a/src/p_map.c b/src/p_map.c index 2d36f747c..462694fe2 100644 --- a/src/p_map.c +++ b/src/p_map.c @@ -995,7 +995,7 @@ static boolean PIT_CheckThing(mobj_t *thing) if (thing->type == MT_SALOONDOOR && tmthing->player) { mobj_t *ref = (tmthing->player->powers[pw_carry] == CR_MINECART && tmthing->tracer && !P_MobjWasRemoved(tmthing->tracer)) ? tmthing->tracer : tmthing; - if ((thing->flags & MF2_AMBUSH) || ref != tmthing) + if ((thing->flags2 & MF2_AMBUSH) || ref != tmthing) { fixed_t dm = min(FixedHypot(ref->momx, ref->momy), 16*FRACUNIT); angle_t ang = R_PointToAngle2(0, 0, ref->momx, ref->momy) - thing->angle; @@ -1008,7 +1008,7 @@ static boolean PIT_CheckThing(mobj_t *thing) if (thing->type == MT_SALOONDOORCENTER && tmthing->player) { - if ((thing->flags & MF2_AMBUSH) || (tmthing->player->powers[pw_carry] == CR_MINECART && tmthing->tracer && !P_MobjWasRemoved(tmthing->tracer))) + if ((thing->flags2 & MF2_AMBUSH) || (tmthing->player->powers[pw_carry] == CR_MINECART && tmthing->tracer && !P_MobjWasRemoved(tmthing->tracer))) return true; } From 58dd578b094639405d452593562e0f8cb2b482ce Mon Sep 17 00:00:00 2001 From: Nami <50415197+namishere@users.noreply.github.com> Date: Sun, 29 Dec 2019 20:36:24 -0800 Subject: [PATCH 514/746] Let's try this again! --- src/dehacked.c | 3 +++ src/lua_blockmaplib.c | 40 ++++++++++++++++++---------------------- src/lua_hook.h | 6 ++++-- src/lua_hooklib.c | 34 +++++++++++++++++++++++++++++----- src/p_tick.c | 8 ++++++-- 5 files changed, 60 insertions(+), 31 deletions(-) diff --git a/src/dehacked.c b/src/dehacked.c index 4c90211cc..450e33c16 100644 --- a/src/dehacked.c +++ b/src/dehacked.c @@ -9824,6 +9824,9 @@ struct { {"TC_RAINBOW",TC_RAINBOW}, {"TC_BLINK",TC_BLINK}, {"TC_DASHMODE",TC_DASHMODE}, + + {"OPT_LINES", 1}, + {"OPT_MOBJS", 1<<1}, #endif {NULL,0} diff --git a/src/lua_blockmaplib.c b/src/lua_blockmaplib.c index 7f7dc9560..2130e9333 100644 --- a/src/lua_blockmaplib.c +++ b/src/lua_blockmaplib.c @@ -18,11 +18,6 @@ #include "lua_libs.h" //#include "lua_hud.h" // hud_running errors -static const char *const search_opt[] = { - "objects", - "lines", - NULL}; - // a quickly-made function pointer typedef used by lib_searchBlockmap... // return values: // 0 - normal, no interruptions @@ -179,29 +174,18 @@ static UINT8 lib_searchBlockmap_Lines(lua_State *L, INT32 x, INT32 y, mobj_t *th // false = searching of at least one block stopped mid-way (including if the whole search was stopped) static int lib_searchBlockmap(lua_State *L) { - int searchtype = luaL_checkoption(L, 1, "objects", search_opt); int n; mobj_t *mobj; INT32 xl, xh, yl, yh, bx, by; fixed_t x1, x2, y1, y2; boolean retval = true; + boolean repeat = false; UINT8 funcret = 0; - blockmap_func searchFunc; - lua_remove(L, 1); // remove searchtype, stack is now function, mobj, [x1, x2, y1, y2] + UINT32 flags = luaL_checkinteger(L, 1); + lua_remove(L, 1); // remove flags, stack is now function, mobj, [x1, x2, y1, y2] luaL_checktype(L, 1, LUA_TFUNCTION); - switch (searchtype) - { - case 0: // "objects" - default: - searchFunc = lib_searchBlockmap_Objects; - break; - case 1: // "lines" - searchFunc = lib_searchBlockmap_Lines; - break; - } - // the mobj we are searching around, the "calling" mobj we could say mobj = *((mobj_t **)luaL_checkudata(L, 2, META_MOBJ)); if (!mobj) @@ -240,8 +224,14 @@ static int lib_searchBlockmap(lua_State *L) validcount++; for (bx = xl; bx <= xh; bx++) for (by = yl; by <= yh; by++) - { - funcret = searchFunc(L, bx, by, mobj); + { + if (flags & (OPT_LINES|OPT_MOBJS)) + repeat = true; + if (flags & OPT_LINES) + funcret = lib_searchBlockmap_Lines(L, bx, by, mobj); + else + funcret = lib_searchBlockmap_Objects(L, bx, by, mobj); + doitagain: // return value of searchFunc determines searchFunc's return value and/or when to stop if (funcret == 2){ // stop whole search lua_pushboolean(L, false); // return false @@ -254,6 +244,12 @@ static int lib_searchBlockmap(lua_State *L) lua_pushboolean(L, false); // in which case we have to stop now regardless return 1; } + if (repeat) + { + funcret = lib_searchBlockmap_Objects(L, bx, by, mobj); + repeat = false; + goto doitagain; + } } lua_pushboolean(L, retval); return 1; @@ -265,4 +261,4 @@ int LUA_BlockmapLib(lua_State *L) return 0; } -#endif +#endif \ No newline at end of file diff --git a/src/lua_hook.h b/src/lua_hook.h index 68efbce93..620a7b307 100644 --- a/src/lua_hook.h +++ b/src/lua_hook.h @@ -20,7 +20,8 @@ enum hook { hook_MapChange, hook_MapLoad, hook_PlayerJoin, - hook_ThinkFrame, + hook_PreThinkFrame, + hook_PostThinkFrame, hook_MobjSpawn, hook_MobjCollide, hook_MobjMoveCollide, @@ -61,7 +62,8 @@ extern const char *const hookNames[]; void LUAh_MapChange(INT16 mapnumber); // Hook for map change (before load) void LUAh_MapLoad(void); // Hook for map load void LUAh_PlayerJoin(int playernum); // Hook for Got_AddPlayer -void LUAh_ThinkFrame(void); // Hook for frame (after mobj and player thinkers) +void LUAh_PreThinkFrame(void); // Hook for frame (before mobj and player thinkers) +void LUAh_PostThinkFrame(void); // Hook for frame (after mobj and player thinkers) boolean LUAh_MobjHook(mobj_t *mo, enum hook which); boolean LUAh_PlayerHook(player_t *plr, enum hook which); #define LUAh_MobjSpawn(mo) LUAh_MobjHook(mo, hook_MobjSpawn) // Hook for P_SpawnMobj by mobj type diff --git a/src/lua_hooklib.c b/src/lua_hooklib.c index 91b4c6992..ace0f14d5 100644 --- a/src/lua_hooklib.c +++ b/src/lua_hooklib.c @@ -31,7 +31,8 @@ const char *const hookNames[hook_MAX+1] = { "MapChange", "MapLoad", "PlayerJoin", - "ThinkFrame", + "PreThinkFrame", + "PostThinkFrame", "MobjSpawn", "MobjCollide", "MobjMoveCollide", @@ -411,16 +412,39 @@ void LUAh_PlayerJoin(int playernum) lua_settop(gL, 0); } -// Hook for frame (after mobj and player thinkers) -void LUAh_ThinkFrame(void) +// Hook for frame (before mobj and player thinkers) +void LUAh_PreThinkFrame(void) { hook_p hookp; - if (!gL || !(hooksAvailable[hook_ThinkFrame/8] & (1<<(hook_ThinkFrame%8)))) + if (!gL || !(hooksAvailable[hook_PreThinkFrame/8] & (1<<(hook_PreThinkFrame%8)))) return; for (hookp = roothook; hookp; hookp = hookp->next) { - if (hookp->type != hook_ThinkFrame) + if (hookp->type != hook_PreThinkFrame) + continue; + + lua_pushfstring(gL, FMT_HOOKID, hookp->id); + lua_gettable(gL, LUA_REGISTRYINDEX); + if (lua_pcall(gL, 0, 0, 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; + } + } +} + +// Hook for frame (after mobj and player thinkers) +void LUAh_PostThinkFrame(void) +{ + hook_p hookp; + if (!gL || !(hooksAvailable[hook_PostThinkFrame/8] & (1<<(hook_PostThinkFrame%8)))) + return; + + for (hookp = roothook; hookp; hookp = hookp->next) + { + if (hookp->type != hook_PostThinkFrame) continue; lua_pushfstring(gL, FMT_HOOKID, hookp->id); diff --git a/src/p_tick.c b/src/p_tick.c index e0f60bd22..b92465fe4 100644 --- a/src/p_tick.c +++ b/src/p_tick.c @@ -646,6 +646,10 @@ void P_Ticker(boolean run) if (run) { + #ifdef HAVE_BLUA + LUAh_PreThinkFrame(); + #endif + P_RunThinkers(); // Run any "after all the other thinkers" stuff @@ -654,7 +658,7 @@ void P_Ticker(boolean run) P_PlayerAfterThink(&players[i]); #ifdef HAVE_BLUA - LUAh_ThinkFrame(); + LUAh_PostThinkFrame(); #endif } @@ -769,7 +773,7 @@ void P_PreTicker(INT32 frames) P_PlayerAfterThink(&players[i]); #ifdef HAVE_BLUA - LUAh_ThinkFrame(); + LUAh_PostThinkFrame(); #endif // Run shield positioning From c303b1a435c61ea46e98a4ceee8c002921b00e3b Mon Sep 17 00:00:00 2001 From: Jaime Passos Date: Mon, 30 Dec 2019 01:39:34 -0300 Subject: [PATCH 515/746] Use strspn here. --- src/s_sound.c | 17 ++++------------- 1 file changed, 4 insertions(+), 13 deletions(-) diff --git a/src/s_sound.c b/src/s_sound.c index 1b7c7c8c5..11774b5ba 100644 --- a/src/s_sound.c +++ b/src/s_sound.c @@ -1579,19 +1579,10 @@ skip_lump: value++; // Now skip funny whitespace. - for (;;) - { - char c = value[0]; - if (c == '\0') // :NOTHING: - { - brokenline = true; - break; - } - else if (c == ' ' || c == '\t') - value++; - else - break; - } + if (value[0] == '\0') // :NOTHING: + brokenline = true; + else + value += strspn(value, "\t "); } // If the line is valid, copy the text line from the lump data. From 8a15e9abc4b36a9c5af0e0f81c7aeea8096ee666 Mon Sep 17 00:00:00 2001 From: James R Date: Sun, 29 Dec 2019 20:46:43 -0800 Subject: [PATCH 516/746] Bro player 2 can't use the console --- src/lua_consolelib.c | 1 - 1 file changed, 1 deletion(-) diff --git a/src/lua_consolelib.c b/src/lua_consolelib.c index 58e720c85..d6c532b65 100644 --- a/src/lua_consolelib.c +++ b/src/lua_consolelib.c @@ -130,7 +130,6 @@ void COM_Lua_f(void) lua_pop(gL, 1); // pop command info table return; // can't execute splitscreen command without player 2! } - playernum = secondarydisplayplayer; } if (netgame) From dc757f3086591729e24772cb213cd33c631fc432 Mon Sep 17 00:00:00 2001 From: James R Date: Sun, 29 Dec 2019 20:59:48 -0800 Subject: [PATCH 517/746] Fuck magic numbers; COM_ flags for Lua commands! --- src/command.h | 7 +++++++ src/dehacked.c | 4 ++++ src/lua_consolelib.c | 15 +++++++++++---- 3 files changed, 22 insertions(+), 4 deletions(-) diff --git a/src/command.h b/src/command.h index 51e161cd0..7078c333a 100644 --- a/src/command.h +++ b/src/command.h @@ -20,6 +20,13 @@ // Command buffer & command execution //=================================== +/* Lua command registration flags. */ +enum +{ + COM_ADMIN = 1, + COM_SPLITSCREEN = 2, +}; + typedef void (*com_func_t)(void); void COM_AddCommand(const char *name, com_func_t func); diff --git a/src/dehacked.c b/src/dehacked.c index 4c90211cc..7d473bd51 100644 --- a/src/dehacked.c +++ b/src/dehacked.c @@ -9732,6 +9732,10 @@ struct { {"BT_CUSTOM2",BT_CUSTOM2}, // Lua customizable {"BT_CUSTOM3",BT_CUSTOM3}, // Lua customizable + // Lua command registration flags + {"COM_ADMIN",COM_ADMIN}, + {"COM_SPLITSCREEN",COM_SPLITSCREEN}, + // cvflags_t {"CV_SAVE",CV_SAVE}, {"CV_CALL",CV_CALL}, diff --git a/src/lua_consolelib.c b/src/lua_consolelib.c index d6c532b65..b861a4ad7 100644 --- a/src/lua_consolelib.c +++ b/src/lua_consolelib.c @@ -118,12 +118,12 @@ void COM_Lua_f(void) lua_rawgeti(gL, -1, 2); // push flags from command info table if (lua_isboolean(gL, -1)) - flags = (lua_toboolean(gL, -1) ? 1 : 0); + flags = (lua_toboolean(gL, -1) ? COM_ADMIN : 0); else flags = (UINT8)lua_tointeger(gL, -1); lua_pop(gL, 1); // pop flags - if (flags & 2) // flag 2: splitscreen player command. + if (flags & COM_SPLITSCREEN) // flag 2: splitscreen player command. { if (!splitscreen) { @@ -137,7 +137,7 @@ void COM_Lua_f(void) UINT8 argc; lua_pop(gL, 1); // pop command info table - if (flags & 1 && !server && !IsPlayerAdmin(playernum)) // flag 1: only server/admin can use this command. + if (flags & COM_ADMIN && !server && !IsPlayerAdmin(playernum)) // flag 1: only server/admin can use this command. { CONS_Printf(M_GetText("Only the server or a remote admin can use this.\n")); return; @@ -191,7 +191,14 @@ static int lib_comAddCommand(lua_State *L) if (lua_gettop(L) >= 3) { // For the third argument, only take a boolean or a number. lua_settop(L, 3); - if (lua_type(L, 3) != LUA_TBOOLEAN) + if (lua_type(L, 3) == LUA_TBOOLEAN) + { + CONS_Alert(CONS_WARNING, + "Using a boolean is deprecated and will be removed.\n" + "Use \"COM_\" flags instead.\n" + ); + } + else luaL_checktype(L, 3, LUA_TNUMBER); } else From 6546e3c3bc38415150bd3a2c405a465fe67509a0 Mon Sep 17 00:00:00 2001 From: James R Date: Sun, 29 Dec 2019 21:02:42 -0800 Subject: [PATCH 518/746] No. --- src/lua_consolelib.c | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/src/lua_consolelib.c b/src/lua_consolelib.c index b861a4ad7..cbfa42f87 100644 --- a/src/lua_consolelib.c +++ b/src/lua_consolelib.c @@ -157,10 +157,7 @@ void COM_Lua_f(void) WRITEUINT8(p, argc); for (i = 0; i < argc; i++) WRITESTRINGN(p, COM_Argv(i), 255); - if (flags & 2) - SendNetXCmd2(XD_LUACMD, buf, p-buf); - else - SendNetXCmd(XD_LUACMD, buf, p-buf); + SendNetXCmd(XD_LUACMD, buf, p-buf); free(buf); return; } From 802ef0aba1ff9c5dab5b826b5393566b3b5ac40e Mon Sep 17 00:00:00 2001 From: James R Date: Sun, 29 Dec 2019 21:07:28 -0800 Subject: [PATCH 519/746] COM_LOCAL makes your commands NetXCmd free, FUCK NetXCmd --- src/command.h | 1 + src/dehacked.c | 1 + src/lua_consolelib.c | 2 +- 3 files changed, 3 insertions(+), 1 deletion(-) diff --git a/src/command.h b/src/command.h index 7078c333a..554c1131b 100644 --- a/src/command.h +++ b/src/command.h @@ -25,6 +25,7 @@ enum { COM_ADMIN = 1, COM_SPLITSCREEN = 2, + COM_LOCAL = 4, }; typedef void (*com_func_t)(void); diff --git a/src/dehacked.c b/src/dehacked.c index 7d473bd51..b3a8ed1dd 100644 --- a/src/dehacked.c +++ b/src/dehacked.c @@ -9735,6 +9735,7 @@ struct { // Lua command registration flags {"COM_ADMIN",COM_ADMIN}, {"COM_SPLITSCREEN",COM_SPLITSCREEN}, + {"COM_LOCAL",COM_LOCAL}, // cvflags_t {"CV_SAVE",CV_SAVE}, diff --git a/src/lua_consolelib.c b/src/lua_consolelib.c index cbfa42f87..f40b63ac6 100644 --- a/src/lua_consolelib.c +++ b/src/lua_consolelib.c @@ -132,7 +132,7 @@ void COM_Lua_f(void) } } - if (netgame) + if (netgame && !( flags & COM_LOCAL ))/* don't send local commands */ { // Send the command through the network UINT8 argc; lua_pop(gL, 1); // pop command info table From 757480f21940e9acfe3759d68d01c69404c12de0 Mon Sep 17 00:00:00 2001 From: Jaime Passos Date: Mon, 30 Dec 2019 02:07:39 -0300 Subject: [PATCH 520/746] Some cleanup in general. --- src/s_sound.c | 51 ++++++++++++++++++++++++++------------------------- 1 file changed, 26 insertions(+), 25 deletions(-) diff --git a/src/s_sound.c b/src/s_sound.c index 11774b5ba..b1d80f43b 100644 --- a/src/s_sound.c +++ b/src/s_sound.c @@ -1464,9 +1464,9 @@ static UINT16 W_CheckForMusicDefInPwad(UINT16 wadid) void S_LoadMusicDefs(UINT16 wadnum) { - UINT16 lump; - char *buf; - char *buf2; + UINT16 lumpnum; + char *lump, *buf; + char *musdeftext; char *stoken; char *value; char *textline; @@ -1475,21 +1475,27 @@ void S_LoadMusicDefs(UINT16 wadnum) musicdef_t *def = NULL; UINT16 line = 1; // for better error msgs - lump = W_CheckForMusicDefInPwad(wadnum); - if (lump == INT16_MAX) + lumpnum = W_CheckForMusicDefInPwad(wadnum); + if (lumpnum == INT16_MAX) return; - buf = W_CacheLumpNumPwad(wadnum, lump, PU_CACHE); - size = W_LumpLengthPwad(wadnum, lump); + lump = W_CacheLumpNumPwad(wadnum, lumpnum, PU_CACHE); + size = W_LumpLengthPwad(wadnum, lumpnum); + + // Null-terminated MUSICDEF lump. + musdeftext = malloc(size+1); + if (!musdeftext) + I_Error("S_LoadMusicDefs: No more free memory for the parser\n"); + M_Memcpy(musdeftext, lump, size); + musdeftext[size] = '\0'; // for strtok - buf2 = malloc(size+1); - if (!buf2) - I_Error("S_LoadMusicDefs: No more free memory\n"); - M_Memcpy(buf2,buf,size); - buf2[size] = '\0'; + buf = malloc(size+1); + if (!buf) + I_Error("S_LoadMusicDefs: No more free memory for the parser\n"); + M_Memcpy(buf, musdeftext, size+1); - stoken = strtok (buf2, "\r\n "); + stoken = strtok(buf, "\r\n "); // Find music def while (stoken) { @@ -1589,17 +1595,10 @@ skip_lump: if (!brokenline) { // strtok returns memory that already belongs to the input string. - value = buf + (value - buf2); + value = musdeftext + (value - buf); // Find the length of the line. - size = 0; - for (;;) - { - char c = value[size]; - if (c == '\n' || c == '\r' || c == '\0') - break; - size++; - } + size = strcspn(value, "\r\n"); // Copy the line. textline = malloc(size+1); @@ -1619,7 +1618,8 @@ skip_lump: { CONS_Alert(CONS_ERROR, "MUSICDEF: No music definition before field '%s'. (file %s, line %d)\n", stoken, wadfiles[wadnum]->filename, line); free(textline); - free(buf2); + free(buf); + free(musdeftext); return; } @@ -1663,7 +1663,7 @@ skip_lump: CONS_Alert(CONS_WARNING, "MUSICDEF: Invalid field '%s'. (file %s, line %d)\n", stoken, wadfiles[wadnum]->filename, line); } - // Free the temporary line from memory. + // Free the temporary text line from memory. free(textline); skip_field: @@ -1672,7 +1672,8 @@ skip_field: } } - free(buf2); + free(buf); + free(musdeftext); return; } From 65921c170207d2e4be1bd2bbfd43f7225d1e0fe9 Mon Sep 17 00:00:00 2001 From: James R Date: Sun, 29 Dec 2019 21:09:07 -0800 Subject: [PATCH 521/746] Improve COM_AddCommand boolean deprecated warning --- src/lua_consolelib.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/lua_consolelib.c b/src/lua_consolelib.c index f40b63ac6..4e397fb32 100644 --- a/src/lua_consolelib.c +++ b/src/lua_consolelib.c @@ -191,8 +191,9 @@ static int lib_comAddCommand(lua_State *L) if (lua_type(L, 3) == LUA_TBOOLEAN) { CONS_Alert(CONS_WARNING, - "Using a boolean is deprecated and will be removed.\n" - "Use \"COM_\" flags instead.\n" + "Using a boolean for admin commands is " + "deprecated and will be removed.\n" + "Use \"COM_ADMIN\" instead.\n" ); } else From aaef412823945719c30231d4c41d3fb9053dc0fb Mon Sep 17 00:00:00 2001 From: Nev3r Date: Mon, 30 Dec 2019 11:33:22 +0100 Subject: [PATCH 522/746] Add basic textmap support; currently crashes when trying to free the virtres, at vres_free(). --- src/doomdef.h | 2 + src/m_misc.c | 14 ++ src/p_setup.c | 371 +++++++++++++++++++++++++++++++++++++++++++++++++- src/w_wad.c | 2 + 4 files changed, 382 insertions(+), 7 deletions(-) diff --git a/src/doomdef.h b/src/doomdef.h index 51a15bd64..0d673a426 100644 --- a/src/doomdef.h +++ b/src/doomdef.h @@ -461,6 +461,8 @@ extern void *(*M_Memcpy)(void* dest, const void* src, size_t n) FUNCNONNULL; char *va(const char *format, ...) FUNCPRINTF; char *M_GetToken(const char *inputString); void M_UnGetToken(void); +UINT32 M_GetTokenPos(void); +void M_SetTokenPos(UINT32 newPos); char *sizeu1(size_t num); char *sizeu2(size_t num); char *sizeu3(size_t num); diff --git a/src/m_misc.c b/src/m_misc.c index b0a1fb8c5..edb24ab1e 100644 --- a/src/m_misc.c +++ b/src/m_misc.c @@ -1908,6 +1908,20 @@ void M_UnGetToken(void) endPos = oldendPos; } +/** Returns the current token's position. + */ +UINT32 M_GetTokenPos(void) +{ + return endPos; +} + +/** Sets the current token's position. + */ +void M_SetTokenPos(UINT32 newPos) +{ + endPos = newPos; +} + /** Count bits in a number. */ UINT8 M_CountBits(UINT32 num, UINT8 size) diff --git a/src/p_setup.c b/src/p_setup.c index 99da5ccee..c7eb50382 100644 --- a/src/p_setup.c +++ b/src/p_setup.c @@ -83,6 +83,8 @@ #include "p_slopes.h" #endif +#include "fastcmp.h" // textmap parsing + // // Map MD5, calculated on level load. // Sent to clients in PT_SERVERINFO. @@ -1236,10 +1238,367 @@ static void P_LoadThings(UINT8 *data) } } +// Stores positions for relevant map data spread through a TEXTMAP. +UINT32 mapthingsPos[UINT16_MAX]; +UINT32 linesPos[UINT16_MAX]; +UINT32 sidesPos[UINT16_MAX]; +UINT32 vertexesPos[UINT16_MAX]; +UINT32 sectorsPos[UINT16_MAX]; + +static boolean TextmapCount (UINT8 *data, size_t size) +{ + char *nsp1 = M_GetToken((char *)data); + boolean ret = true; + + // Determine total amount of map data in TEXTMAP. + // Look for namespace at the beginning. + if (fastcmp(nsp1, "namespace")) + { + char *nsp2 = M_GetToken(NULL); + char *tkn = M_GetToken(NULL); + + // Check if namespace is valid. + if (!fastcmp(nsp2, "srb2")) + CONS_Alert(CONS_WARNING, "Invalid namespace '%s', only 'srb2' is supported.\n", nsp2); + Z_Free(nsp2); + + while (tkn != NULL && M_GetTokenPos() < size) + { + // Avoid anything inside bracketed stuff, only look for external keywords. + // Assuming there's only one level of bracket nesting. + if (fastcmp(tkn, "{")) + { + Z_Free(tkn); + while (!fastcmp(tkn, "}")) + { + Z_Free(tkn); + tkn = M_GetToken(NULL); + } + } + // Check for valid fields. + else if (fastcmp(tkn, "thing")) + mapthingsPos[nummapthings++] = M_GetTokenPos(); + else if (fastcmp(tkn, "linedef")) + linesPos[numlines++] = M_GetTokenPos(); + else if (fastcmp(tkn, "sidedef")) + sidesPos[numsides++] = M_GetTokenPos(); + else if (fastcmp(tkn, "vertex")) + vertexesPos[numvertexes++] = M_GetTokenPos(); + else if (fastcmp(tkn, "sector")) + sectorsPos[numsectors++] = M_GetTokenPos(); + else + CONS_Alert(CONS_NOTICE, "Unknown field '%s'.\n", tkn); + + Z_Free(tkn); + tkn = M_GetToken(NULL); + } + } + else + { + CONS_Alert(CONS_WARNING, "No namespace at beginning of lump!\n"); + ret = false; + } + + Z_Free(nsp1); + return ret; +} + +static char* dat; + +/** Auxiliary function for TextmapParse. + * + * \param Vertex number. + * \param Parameter string. + */ +static void TextmapVertex(UINT32 i, char *param) +{ + if (fastcmp(param, "x")) + vertexes[i].x = FLOAT_TO_FIXED(atof(dat = M_GetToken(NULL))); + else if (fastcmp(param, "y")) + vertexes[i].y = FLOAT_TO_FIXED(atof(dat = M_GetToken(NULL))); +} + +/** Auxiliary function for TextmapParse. + * + * \param Sector number. + * \param Parameter string. + */ +static void TextmapSector(UINT32 i, char *param) +{ + if (fastcmp(param, "heightfloor")) + sectors[i].floorheight = atol(dat = M_GetToken(NULL)) << FRACBITS; + else if (fastcmp(param, "heightceiling")) + sectors[i].ceilingheight = atol(dat = M_GetToken(NULL)) << FRACBITS; + if (fastcmp(param, "texturefloor")) + sectors[i].floorpic = P_AddLevelFlat(dat = M_GetToken(NULL), foundflats); + else if (fastcmp(param, "textureceiling")) + sectors[i].ceilingpic = P_AddLevelFlat(dat = M_GetToken(NULL), foundflats); + else if (fastcmp(param, "lightlevel")) + sectors[i].lightlevel = atol(dat = M_GetToken(NULL)); + else if (fastcmp(param, "special")) + sectors[i].special = atol(dat = M_GetToken(NULL)); + else if (fastcmp(param, "id")) + sectors[i].tag = atol(dat = M_GetToken(NULL)); +} + +/** Auxiliary function for TextmapParse. + * + * \param Side number. + * \param Parameter string. + */ +static void TextmapSide(UINT32 i, char *param) +{ + if (fastcmp(param, "offsetx")) + sides[i].textureoffset = atol(dat = M_GetToken(NULL))<z = 0; + + TextmapParse(vertexesPos[i], i, TextmapVertex); + } + + for (i = 0, sc = sectors; i < numsectors; i++, sc++) + { + // Defaults. + sc->floorheight = 0; + sc->ceilingheight = 0; + + sc->floorpic = 0; + sc->ceilingpic = 0; + + sc->lightlevel = 255; + + sc->special = 0; + sc->tag = 0; + + sc->floor_xoffs = sc->floor_yoffs = sc->ceiling_xoffs = sc->ceiling_yoffs = 0; + sc->floorpic_angle = sc->ceilingpic_angle = 0; + + TextmapParse(sectorsPos[i], i, TextmapSector); + + P_InitializeSector(sc); + } + + for (i = 0, ld = lines; i < numlines; i++, ld++) + { + // Defaults. + ld->tag = 0; + ld->special = 0; + ld->sidenum[1] = 0xffff; + + TextmapParse(linesPos[i], i, TextmapLine); + + P_InitializeLinedef(ld); + } + + for (i = 0, sd = sides; i < numsides; i++, sd++) + { + // Defaults. + sd->rowoffset = 0; + sd->textureoffset = 0; + + sd->toptexture = R_TextureNumForName("-"); + sd->midtexture = R_TextureNumForName("-"); + sd->bottomtexture = R_TextureNumForName("-"); + sd->repeatcnt = 0; + + TextmapParse(sidesPos[i], i, TextmapSide); + } + + for (i = 0, mt = mapthings; i < nummapthings; i++, mt++) + { + // Defaults. + mt->z = 0; + mt->angle = 0; + + TextmapParse(mapthingsPos[i], i, TextmapThing); + } +} + +/** Provides a fix to the flat alignment coordinate transform from standard Textmaps. + */ +static void TextmapFixFlatOffsets (void) +{ + fixed_t pc, ps; + fixed_t xoffs, yoffs; + size_t i; + sector_t* sec = sectors; + for (i = 0; i < numsectors; i++, sec++) + { + if (sec->floorpic_angle) + { + pc = FINECOSINE(sec->floorpic_angle>>ANGLETOFINESHIFT); + ps = FINESINE (sec->floorpic_angle>>ANGLETOFINESHIFT); + xoffs = sec->floor_xoffs; + yoffs = sec->floor_yoffs; + #define MAXFLATSIZE (2048<floor_xoffs = (FixedMul(xoffs, pc) % MAXFLATSIZE) - (FixedMul(yoffs, ps) % MAXFLATSIZE); + sec->floor_yoffs = (FixedMul(xoffs, ps) % MAXFLATSIZE) + (FixedMul(yoffs, pc) % MAXFLATSIZE); + #undef MAXFLATSIZE + } + + if (sec->ceilingpic_angle) + { + pc = FINECOSINE(sec->ceilingpic_angle>>ANGLETOFINESHIFT); + ps = FINESINE (sec->ceilingpic_angle>>ANGLETOFINESHIFT); + xoffs = sec->ceiling_xoffs; + yoffs = sec->ceiling_yoffs; + #define MAXFLATSIZE (2048<ceiling_xoffs = (FixedMul(xoffs, pc) % MAXFLATSIZE) - (FixedMul(yoffs, ps) % MAXFLATSIZE); + sec->ceiling_yoffs = (FixedMul(xoffs, ps) % MAXFLATSIZE) + (FixedMul(yoffs, pc) % MAXFLATSIZE); + #undef MAXFLATSIZE + } + } +} + static void P_LoadMapData(const virtres_t *virt) { virtlump_t* virtvertexes = NULL, * virtsectors = NULL, * virtsidedefs = NULL, * virtlinedefs = NULL, * virtthings = NULL; -#ifdef UDMF virtlump_t* textmap = vres_Find(virt, "TEXTMAP"); // Count map data. @@ -1252,10 +1611,9 @@ static void P_LoadMapData(const virtres_t *virt) numsectors = 0; // Count how many entries for each type we got in textmap. - //TextmapCount(vtextmap->data, vtextmap->size); + TextmapCount(textmap->data, textmap->size); } else -#endif { virtthings = vres_Find(virt, "THINGS"); virtvertexes = vres_Find(virt, "VERTEXES"); @@ -1305,15 +1663,14 @@ static void P_LoadMapData(const virtres_t *virt) numlevelflats = 0; -#ifdef UDMF + // Load map data. if (textmap) { - + P_LoadTextmap(); + TextmapFixFlatOffsets(); } else -#endif { - // Strict map data P_LoadVertices(virtvertexes->data); P_LoadSectors(virtsectors->data); P_LoadLinedefs(virtlinedefs->data); diff --git a/src/w_wad.c b/src/w_wad.c index 62992441a..47c3f42d0 100644 --- a/src/w_wad.c +++ b/src/w_wad.c @@ -1942,6 +1942,8 @@ void vres_Free(virtres_t* vres) Z_Free(vres->vlumps[vres->numlumps].data); Z_Free(vres->vlumps); Z_Free(vres); + + CONS_Printf("A A A\n"); } /** (Debug) Prints lumps from a virtual resource into console. From 0839287609c3639e7f35057743c48175130a64eb Mon Sep 17 00:00:00 2001 From: lachwright Date: Mon, 30 Dec 2019 19:00:45 +0800 Subject: [PATCH 523/746] 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 ed114f655bd84576d8f3eea314921b9cc611b49e Mon Sep 17 00:00:00 2001 From: Nev3r Date: Mon, 30 Dec 2019 12:07:02 +0100 Subject: [PATCH 524/746] Fixed missing M_GetToken(NULL); --- src/p_setup.c | 1 + 1 file changed, 1 insertion(+) diff --git a/src/p_setup.c b/src/p_setup.c index c7eb50382..71d1ca880 100644 --- a/src/p_setup.c +++ b/src/p_setup.c @@ -1269,6 +1269,7 @@ static boolean TextmapCount (UINT8 *data, size_t size) if (fastcmp(tkn, "{")) { Z_Free(tkn); + tkn = M_GetToken(NULL); while (!fastcmp(tkn, "}")) { Z_Free(tkn); From f49b8de5fd8999965f28bc7fcec5ff666ac1b3d3 Mon Sep 17 00:00:00 2001 From: Nev3r Date: Mon, 30 Dec 2019 12:07:54 +0100 Subject: [PATCH 525/746] Adapt P_MakeMapMD5() for textmaps. --- src/p_setup.c | 41 ++++++++++++++++++++++++----------------- 1 file changed, 24 insertions(+), 17 deletions(-) diff --git a/src/p_setup.c b/src/p_setup.c index 71d1ca880..198b8ae6a 100644 --- a/src/p_setup.c +++ b/src/p_setup.c @@ -2668,27 +2668,34 @@ static INT32 P_MakeBufferMD5(const char *buffer, size_t len, void *resblock) static void P_MakeMapMD5(virtres_t *virt, void *dest) { - unsigned char linemd5[16]; - unsigned char sectormd5[16]; - unsigned char thingmd5[16]; - unsigned char sidedefmd5[16]; + virtlump_t* textmap = vres_Find(virt, "TEXTMAP"); unsigned char resmd5[16]; - UINT8 i; - // Create a hash for the current map - // get the actual lumps! - virtlump_t *virtlines = vres_Find(virt, "LINEDEFS"); - virtlump_t *virtsectors = vres_Find(virt, "SECTORS"); - virtlump_t *virtmthings = vres_Find(virt, "THINGS"); - virtlump_t *virtsides = vres_Find(virt, "SIDEDEFS"); + if (textmap) + P_MakeBufferMD5((char*)textmap->data, textmap->size, resmd5); + else + { + unsigned char linemd5[16]; + unsigned char sectormd5[16]; + unsigned char thingmd5[16]; + unsigned char sidedefmd5[16]; + UINT8 i; - P_MakeBufferMD5((char*)virtlines->data, virtlines->size, linemd5); - P_MakeBufferMD5((char*)virtsectors->data, virtsectors->size, sectormd5); - P_MakeBufferMD5((char*)virtmthings->data, virtmthings->size, thingmd5); - P_MakeBufferMD5((char*)virtsides->data, virtsides->size, sidedefmd5); + // Create a hash for the current map + // get the actual lumps! + virtlump_t* virtlines = vres_Find(virt, "LINEDEFS"); + virtlump_t* virtsectors = vres_Find(virt, "SECTORS"); + virtlump_t* virtmthings = vres_Find(virt, "THINGS"); + virtlump_t* virtsides = vres_Find(virt, "SIDEDEFS"); - for (i = 0; i < 16; i++) - resmd5[i] = (linemd5[i] + sectormd5[i] + thingmd5[i] + sidedefmd5[i]) & 0xFF; + P_MakeBufferMD5((char*)virtlines->data, virtlines->size, linemd5); + P_MakeBufferMD5((char*)virtsectors->data, virtsectors->size, sectormd5); + P_MakeBufferMD5((char*)virtmthings->data, virtmthings->size, thingmd5); + P_MakeBufferMD5((char*)virtsides->data, virtsides->size, sidedefmd5); + + for (i = 0; i < 16; i++) + resmd5[i] = (linemd5[i] + sectormd5[i] + thingmd5[i] + sidedefmd5[i]) & 0xFF; + } M_Memcpy(dest, &resmd5, 16); } From 493c6c8ae2e725870ceded26f97ed5b936ff4bea Mon Sep 17 00:00:00 2001 From: Nev3r Date: Mon, 30 Dec 2019 12:23:31 +0100 Subject: [PATCH 526/746] AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA --- src/w_wad.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/w_wad.c b/src/w_wad.c index 47c3f42d0..62992441a 100644 --- a/src/w_wad.c +++ b/src/w_wad.c @@ -1942,8 +1942,6 @@ void vres_Free(virtres_t* vres) Z_Free(vres->vlumps[vres->numlumps].data); Z_Free(vres->vlumps); Z_Free(vres); - - CONS_Printf("A A A\n"); } /** (Debug) Prints lumps from a virtual resource into console. From f9aabe753e76bb028746251b7ab867b297285c23 Mon Sep 17 00:00:00 2001 From: Nev3r Date: Mon, 30 Dec 2019 12:31:55 +0100 Subject: [PATCH 527/746] Refactor TextmapFixFlatOffsets(). --- src/p_setup.c | 53 +++++++++++++++++++++------------------------------ 1 file changed, 22 insertions(+), 31 deletions(-) diff --git a/src/p_setup.c b/src/p_setup.c index 198b8ae6a..2334a9a03 100644 --- a/src/p_setup.c +++ b/src/p_setup.c @@ -1523,6 +1523,7 @@ static void P_LoadTextmap (void) TextmapParse(sectorsPos[i], i, TextmapSector); P_InitializeSector(sc); + TextmapFixFlatOffsets(sc); } for (i = 0, ld = lines; i < numlines; i++, ld++) @@ -1563,37 +1564,30 @@ static void P_LoadTextmap (void) /** Provides a fix to the flat alignment coordinate transform from standard Textmaps. */ -static void TextmapFixFlatOffsets (void) +static void TextmapFixFlatOffsets (sector_t* sec) { - fixed_t pc, ps; - fixed_t xoffs, yoffs; - size_t i; - sector_t* sec = sectors; - for (i = 0; i < numsectors; i++, sec++) + if (sec->floorpic_angle) { - if (sec->floorpic_angle) - { - pc = FINECOSINE(sec->floorpic_angle>>ANGLETOFINESHIFT); - ps = FINESINE (sec->floorpic_angle>>ANGLETOFINESHIFT); - xoffs = sec->floor_xoffs; - yoffs = sec->floor_yoffs; - #define MAXFLATSIZE (2048<floor_xoffs = (FixedMul(xoffs, pc) % MAXFLATSIZE) - (FixedMul(yoffs, ps) % MAXFLATSIZE); - sec->floor_yoffs = (FixedMul(xoffs, ps) % MAXFLATSIZE) + (FixedMul(yoffs, pc) % MAXFLATSIZE); - #undef MAXFLATSIZE - } + fixed_t pc = FINECOSINE(sec->floorpic_angle>>ANGLETOFINESHIFT); + fixed_t ps = FINESINE (sec->floorpic_angle>>ANGLETOFINESHIFT); + fixed_t xoffs = sec->floor_xoffs; + fixed_t yoffs = sec->floor_yoffs; + #define MAXFLATSIZE (2048<floor_xoffs = (FixedMul(xoffs, pc) % MAXFLATSIZE) - (FixedMul(yoffs, ps) % MAXFLATSIZE); + sec->floor_yoffs = (FixedMul(xoffs, ps) % MAXFLATSIZE) + (FixedMul(yoffs, pc) % MAXFLATSIZE); + #undef MAXFLATSIZE + } - if (sec->ceilingpic_angle) - { - pc = FINECOSINE(sec->ceilingpic_angle>>ANGLETOFINESHIFT); - ps = FINESINE (sec->ceilingpic_angle>>ANGLETOFINESHIFT); - xoffs = sec->ceiling_xoffs; - yoffs = sec->ceiling_yoffs; - #define MAXFLATSIZE (2048<ceiling_xoffs = (FixedMul(xoffs, pc) % MAXFLATSIZE) - (FixedMul(yoffs, ps) % MAXFLATSIZE); - sec->ceiling_yoffs = (FixedMul(xoffs, ps) % MAXFLATSIZE) + (FixedMul(yoffs, pc) % MAXFLATSIZE); - #undef MAXFLATSIZE - } + if (sec->ceilingpic_angle) + { + fixed_t pc = FINECOSINE(sec->ceilingpic_angle>>ANGLETOFINESHIFT); + fixed_t ps = FINESINE (sec->ceilingpic_angle>>ANGLETOFINESHIFT); + fixed_t xoffs = sec->ceiling_xoffs; + fixed_t yoffs = sec->ceiling_yoffs; + #define MAXFLATSIZE (2048<ceiling_xoffs = (FixedMul(xoffs, pc) % MAXFLATSIZE) - (FixedMul(yoffs, ps) % MAXFLATSIZE); + sec->ceiling_yoffs = (FixedMul(xoffs, ps) % MAXFLATSIZE) + (FixedMul(yoffs, pc) % MAXFLATSIZE); + #undef MAXFLATSIZE } } @@ -1666,10 +1660,7 @@ static void P_LoadMapData(const virtres_t *virt) // Load map data. if (textmap) - { P_LoadTextmap(); - TextmapFixFlatOffsets(); - } else { P_LoadVertices(virtvertexes->data); From e43df2993fd06e7e3acefdb58a08a8f47b7b4e68 Mon Sep 17 00:00:00 2001 From: Nev3r Date: Mon, 30 Dec 2019 12:33:24 +0100 Subject: [PATCH 528/746] Move TextmapFixFlatOffsets() above P_LoadTextmap() so that it can compile. --- src/p_setup.c | 58 +++++++++++++++++++++++++-------------------------- 1 file changed, 29 insertions(+), 29 deletions(-) diff --git a/src/p_setup.c b/src/p_setup.c index 2334a9a03..09ef07c1a 100644 --- a/src/p_setup.c +++ b/src/p_setup.c @@ -1478,6 +1478,35 @@ static void TextmapParse(UINT32 dataPos, size_t num, void (*parser)(UINT32, char Z_Free(open); } +/** Provides a fix to the flat alignment coordinate transform from standard Textmaps. + */ +static void TextmapFixFlatOffsets (sector_t* sec) +{ + if (sec->floorpic_angle) + { + fixed_t pc = FINECOSINE(sec->floorpic_angle>>ANGLETOFINESHIFT); + fixed_t ps = FINESINE (sec->floorpic_angle>>ANGLETOFINESHIFT); + fixed_t xoffs = sec->floor_xoffs; + fixed_t yoffs = sec->floor_yoffs; + #define MAXFLATSIZE (2048<floor_xoffs = (FixedMul(xoffs, pc) % MAXFLATSIZE) - (FixedMul(yoffs, ps) % MAXFLATSIZE); + sec->floor_yoffs = (FixedMul(xoffs, ps) % MAXFLATSIZE) + (FixedMul(yoffs, pc) % MAXFLATSIZE); + #undef MAXFLATSIZE + } + + if (sec->ceilingpic_angle) + { + fixed_t pc = FINECOSINE(sec->ceilingpic_angle>>ANGLETOFINESHIFT); + fixed_t ps = FINESINE (sec->ceilingpic_angle>>ANGLETOFINESHIFT); + fixed_t xoffs = sec->ceiling_xoffs; + fixed_t yoffs = sec->ceiling_yoffs; + #define MAXFLATSIZE (2048<ceiling_xoffs = (FixedMul(xoffs, pc) % MAXFLATSIZE) - (FixedMul(yoffs, ps) % MAXFLATSIZE); + sec->ceiling_yoffs = (FixedMul(xoffs, ps) % MAXFLATSIZE) + (FixedMul(yoffs, pc) % MAXFLATSIZE); + #undef MAXFLATSIZE + } +} + /** Loads the textmap data, after obtaining the elements count and allocating their respective space. */ static void P_LoadTextmap (void) @@ -1562,35 +1591,6 @@ static void P_LoadTextmap (void) } } -/** Provides a fix to the flat alignment coordinate transform from standard Textmaps. - */ -static void TextmapFixFlatOffsets (sector_t* sec) -{ - if (sec->floorpic_angle) - { - fixed_t pc = FINECOSINE(sec->floorpic_angle>>ANGLETOFINESHIFT); - fixed_t ps = FINESINE (sec->floorpic_angle>>ANGLETOFINESHIFT); - fixed_t xoffs = sec->floor_xoffs; - fixed_t yoffs = sec->floor_yoffs; - #define MAXFLATSIZE (2048<floor_xoffs = (FixedMul(xoffs, pc) % MAXFLATSIZE) - (FixedMul(yoffs, ps) % MAXFLATSIZE); - sec->floor_yoffs = (FixedMul(xoffs, ps) % MAXFLATSIZE) + (FixedMul(yoffs, pc) % MAXFLATSIZE); - #undef MAXFLATSIZE - } - - if (sec->ceilingpic_angle) - { - fixed_t pc = FINECOSINE(sec->ceilingpic_angle>>ANGLETOFINESHIFT); - fixed_t ps = FINESINE (sec->ceilingpic_angle>>ANGLETOFINESHIFT); - fixed_t xoffs = sec->ceiling_xoffs; - fixed_t yoffs = sec->ceiling_yoffs; - #define MAXFLATSIZE (2048<ceiling_xoffs = (FixedMul(xoffs, pc) % MAXFLATSIZE) - (FixedMul(yoffs, ps) % MAXFLATSIZE); - sec->ceiling_yoffs = (FixedMul(xoffs, ps) % MAXFLATSIZE) + (FixedMul(yoffs, pc) % MAXFLATSIZE); - #undef MAXFLATSIZE - } -} - static void P_LoadMapData(const virtres_t *virt) { virtlump_t* virtvertexes = NULL, * virtsectors = NULL, * virtsidedefs = NULL, * virtlinedefs = NULL, * virtthings = NULL; From 7c9b1ee2cbc8fc528d53f37e98d940afd600a3c4 Mon Sep 17 00:00:00 2001 From: Monster Iestyn Date: Mon, 30 Dec 2019 11:49:01 +0000 Subject: [PATCH 529/746] 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 4aee4e3684ce3f70e6a6e60fc427eb998ddb0b9c Mon Sep 17 00:00:00 2001 From: MascaraSnake Date: Mon, 30 Dec 2019 13:27:05 +0100 Subject: [PATCH 530/746] Refactor TextmapCount --- src/p_setup.c | 107 +++++++++++++++++++++++++------------------------- 1 file changed, 53 insertions(+), 54 deletions(-) diff --git a/src/p_setup.c b/src/p_setup.c index 09ef07c1a..ccb528687 100644 --- a/src/p_setup.c +++ b/src/p_setup.c @@ -1245,63 +1245,71 @@ UINT32 sidesPos[UINT16_MAX]; UINT32 vertexesPos[UINT16_MAX]; UINT32 sectorsPos[UINT16_MAX]; -static boolean TextmapCount (UINT8 *data, size_t size) +// Determine total amount of map data in TEXTMAP. +static boolean TextmapCount(UINT8 *data, size_t size) { - char *nsp1 = M_GetToken((char *)data); - boolean ret = true; + char *tkn = M_GetToken((char *)data); + + nummapthings = 0; + numlines = 0; + numsides = 0; + numvertexes = 0; + numsectors = 0; - // Determine total amount of map data in TEXTMAP. // Look for namespace at the beginning. - if (fastcmp(nsp1, "namespace")) + if (!fastcmp(tkn, "namespace")) { - char *nsp2 = M_GetToken(NULL); - char *tkn = M_GetToken(NULL); + Z_Free(tkn); + CONS_Alert(CONS_WARNING, "No namespace at beginning of lump!\n"); + return false; + } + Z_Free(tkn); - // Check if namespace is valid. - if (!fastcmp(nsp2, "srb2")) - CONS_Alert(CONS_WARNING, "Invalid namespace '%s', only 'srb2' is supported.\n", nsp2); - Z_Free(nsp2); + // Check if namespace is valid. + tkn = M_GetToken(NULL); + if (!fastcmp(tkn, "srb2")) + CONS_Alert(CONS_WARNING, "Invalid namespace '%s', only 'srb2' is supported.\n", tkn); + Z_Free(tkn); - while (tkn != NULL && M_GetTokenPos() < size) + tkn = M_GetToken(NULL); + while (tkn && M_GetTokenPos() < size) + { + // Avoid anything inside bracketed stuff, only look for external keywords. + // Assuming there's only one level of bracket nesting. + if (fastcmp(tkn, "{")) { - // Avoid anything inside bracketed stuff, only look for external keywords. - // Assuming there's only one level of bracket nesting. - if (fastcmp(tkn, "{")) + do { Z_Free(tkn); tkn = M_GetToken(NULL); - while (!fastcmp(tkn, "}")) + if (!tkn || M_GetTokenPos() >= size) { Z_Free(tkn); - tkn = M_GetToken(NULL); + CONS_Alert(CONS_WARNING, "Opening bracket not closed!\n"); + return false; } - } - // Check for valid fields. - else if (fastcmp(tkn, "thing")) - mapthingsPos[nummapthings++] = M_GetTokenPos(); - else if (fastcmp(tkn, "linedef")) - linesPos[numlines++] = M_GetTokenPos(); - else if (fastcmp(tkn, "sidedef")) - sidesPos[numsides++] = M_GetTokenPos(); - else if (fastcmp(tkn, "vertex")) - vertexesPos[numvertexes++] = M_GetTokenPos(); - else if (fastcmp(tkn, "sector")) - sectorsPos[numsectors++] = M_GetTokenPos(); - else - CONS_Alert(CONS_NOTICE, "Unknown field '%s'.\n", tkn); - - Z_Free(tkn); - tkn = M_GetToken(NULL); + } while (!fastcmp(tkn, "}")); } - } - else - { - CONS_Alert(CONS_WARNING, "No namespace at beginning of lump!\n"); - ret = false; + // Check for valid fields. + else if (fastcmp(tkn, "thing")) + mapthingsPos[nummapthings++] = M_GetTokenPos(); + else if (fastcmp(tkn, "linedef")) + linesPos[numlines++] = M_GetTokenPos(); + else if (fastcmp(tkn, "sidedef")) + sidesPos[numsides++] = M_GetTokenPos(); + else if (fastcmp(tkn, "vertex")) + vertexesPos[numvertexes++] = M_GetTokenPos(); + else if (fastcmp(tkn, "sector")) + sectorsPos[numsectors++] = M_GetTokenPos(); + else + CONS_Alert(CONS_NOTICE, "Unknown field '%s'.\n", tkn); + + Z_Free(tkn); + tkn = M_GetToken(NULL); } - Z_Free(nsp1); - return ret; + Z_Free(tkn); + return true; } static char* dat; @@ -1593,21 +1601,12 @@ static void P_LoadTextmap (void) static void P_LoadMapData(const virtres_t *virt) { - virtlump_t* virtvertexes = NULL, * virtsectors = NULL, * virtsidedefs = NULL, * virtlinedefs = NULL, * virtthings = NULL; - virtlump_t* textmap = vres_Find(virt, "TEXTMAP"); + virtlump_t *virtvertexes = NULL, *virtsectors = NULL, *virtsidedefs = NULL, *virtlinedefs = NULL, *virtthings = NULL; + virtlump_t *textmap = vres_Find(virt, "TEXTMAP"); // Count map data. - if (textmap) - { - nummapthings = 0; - numlines = 0; - numsides = 0; - numvertexes = 0; - numsectors = 0; - - // Count how many entries for each type we got in textmap. + if (textmap) // Count how many entries for each type we got in textmap. TextmapCount(textmap->data, textmap->size); - } else { virtthings = vres_Find(virt, "THINGS"); @@ -2659,7 +2658,7 @@ static INT32 P_MakeBufferMD5(const char *buffer, size_t len, void *resblock) static void P_MakeMapMD5(virtres_t *virt, void *dest) { - virtlump_t* textmap = vres_Find(virt, "TEXTMAP"); + virtlump_t *textmap = vres_Find(virt, "TEXTMAP"); unsigned char resmd5[16]; if (textmap) From c6c00aa7d5e5ba923b28c3fa8ad53fb5eed501ad Mon Sep 17 00:00:00 2001 From: Nev3r Date: Mon, 30 Dec 2019 13:38:52 +0100 Subject: [PATCH 531/746] Tweak TextmapCount()'s bracket detection to account for multiple levels, if that ever happens. --- src/p_setup.c | 19 ++++++------------- 1 file changed, 6 insertions(+), 13 deletions(-) diff --git a/src/p_setup.c b/src/p_setup.c index ccb528687..55f0b4f3e 100644 --- a/src/p_setup.c +++ b/src/p_setup.c @@ -1249,6 +1249,7 @@ UINT32 sectorsPos[UINT16_MAX]; static boolean TextmapCount(UINT8 *data, size_t size) { char *tkn = M_GetToken((char *)data); + UINT8 brackets = 0; nummapthings = 0; numlines = 0; @@ -1275,21 +1276,13 @@ static boolean TextmapCount(UINT8 *data, size_t size) while (tkn && M_GetTokenPos() < size) { // Avoid anything inside bracketed stuff, only look for external keywords. - // Assuming there's only one level of bracket nesting. - if (fastcmp(tkn, "{")) + if (brackets) { - do - { - Z_Free(tkn); - tkn = M_GetToken(NULL); - if (!tkn || M_GetTokenPos() >= size) - { - Z_Free(tkn); - CONS_Alert(CONS_WARNING, "Opening bracket not closed!\n"); - return false; - } - } while (!fastcmp(tkn, "}")); + if (fastcmp(tkn, "}")) + brackets--; } + else if (fastcmp(tkn, "{")) + brackets++; // Check for valid fields. else if (fastcmp(tkn, "thing")) mapthingsPos[nummapthings++] = M_GetTokenPos(); From ea87af007678a8ca516437b4bd713d9242240eaa Mon Sep 17 00:00:00 2001 From: MascaraSnake Date: Mon, 30 Dec 2019 14:33:41 +0100 Subject: [PATCH 532/746] Refactor TextmapParse --- src/p_setup.c | 40 +++++++++++++++++++++------------------- 1 file changed, 21 insertions(+), 19 deletions(-) diff --git a/src/p_setup.c b/src/p_setup.c index 55f0b4f3e..16cb785ab 100644 --- a/src/p_setup.c +++ b/src/p_setup.c @@ -1455,33 +1455,35 @@ static void TextmapThing(UINT32 i, char *param) */ static void TextmapParse(UINT32 dataPos, size_t num, void (*parser)(UINT32, char *)) { - char *open; + char *tkn; M_SetTokenPos(dataPos); - open = M_GetToken(NULL); - if (fastcmp(open, "{")) + tkn = M_GetToken(NULL); + if (!fastcmp(tkn, "{")) { - char *tkn = M_GetToken(NULL); - while (!fastcmp(tkn, "}")) - { - dat = NULL; - parser(num, tkn); - if (dat) - Z_Free(dat); - - Z_Free(tkn); - tkn = M_GetToken(NULL); - } Z_Free(tkn); - } - else CONS_Alert(CONS_WARNING, "Invalid UDMF data capsule!\n"); - Z_Free(open); + return; + } + + Z_Free(tkn); + tkn = M_GetToken(NULL); + while (!fastcmp(tkn, "}")) + { + dat = NULL; + parser(num, tkn); + if (dat) + Z_Free(dat); + + Z_Free(tkn); + tkn = M_GetToken(NULL); + } + Z_Free(tkn); } /** Provides a fix to the flat alignment coordinate transform from standard Textmaps. */ -static void TextmapFixFlatOffsets (sector_t* sec) +static void TextmapFixFlatOffsets(sector_t *sec) { if (sec->floorpic_angle) { @@ -1510,7 +1512,7 @@ static void TextmapFixFlatOffsets (sector_t* sec) /** Loads the textmap data, after obtaining the elements count and allocating their respective space. */ -static void P_LoadTextmap (void) +static void P_LoadTextmap(void) { UINT32 i; From 7ae2143c9102c798c7db9d2583aadbc3b77f2631 Mon Sep 17 00:00:00 2001 From: Nev3r Date: Mon, 30 Dec 2019 14:42:41 +0100 Subject: [PATCH 533/746] Add a disclaimer when loading textmaps/UDMF. --- src/p_setup.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/p_setup.c b/src/p_setup.c index 55f0b4f3e..839e583c8 100644 --- a/src/p_setup.c +++ b/src/p_setup.c @@ -1520,6 +1520,8 @@ static void P_LoadTextmap (void) side_t *sd; mapthing_t *mt; + CONS_Alert(CONS_NOTICE, "UDMF support is still a work-in-progress; its specs and features are prone to change until it is fully implemented.\n"); + /// Given the UDMF specs, some fields are given a default value. /// If an element's field has a default value set, it is ommited /// from the textmap, and therefore we have to account for it by From f9d6e26558aa6fd4439edfcb5380691b0074c495 Mon Sep 17 00:00:00 2001 From: Nev3r Date: Mon, 30 Dec 2019 14:45:39 +0100 Subject: [PATCH 534/746] Replace INT16_MAX with LUMPERROR in lump check. --- src/p_setup.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/p_setup.c b/src/p_setup.c index 839e583c8..73c3b44f6 100644 --- a/src/p_setup.c +++ b/src/p_setup.c @@ -3536,7 +3536,7 @@ boolean P_LoadLevel(boolean fromnetsave) // internal game map maplumpname = G_BuildMapName(gamemap); lastloadedmaplumpnum = W_CheckNumForName(maplumpname); - if (lastloadedmaplumpnum == INT16_MAX) + if (lastloadedmaplumpnum == LUMPERROR) I_Error("Map %s not found.\n", maplumpname); R_ReInitColormaps(mapheaderinfo[gamemap-1]->palette); From 4a5498473c3ff07feb45006943e59ec0b504282a Mon Sep 17 00:00:00 2001 From: Nev3r Date: Mon, 30 Dec 2019 14:47:48 +0100 Subject: [PATCH 535/746] Make P_LoadMapData() a return a boolean as well as P_LoadMapFromFile(); if they fail to load, they return false, and thus P_SetupLevel() will also return false. TextmapCount() also now returns false if brackets are left open inside a textmap. --- src/p_setup.c | 28 +++++++++++++++++++++------- 1 file changed, 21 insertions(+), 7 deletions(-) diff --git a/src/p_setup.c b/src/p_setup.c index 73c3b44f6..f9ca4dcf0 100644 --- a/src/p_setup.c +++ b/src/p_setup.c @@ -1261,7 +1261,7 @@ static boolean TextmapCount(UINT8 *data, size_t size) if (!fastcmp(tkn, "namespace")) { Z_Free(tkn); - CONS_Alert(CONS_WARNING, "No namespace at beginning of lump!\n"); + CONS_Alert(CONS_ERROR, "No namespace at beginning of lump!\n"); return false; } Z_Free(tkn); @@ -1302,6 +1302,13 @@ static boolean TextmapCount(UINT8 *data, size_t size) } Z_Free(tkn); + + if (brackets) + { + CONS_Alert(CONS_ERROR, "Unclosed brackets detected in textmap lump.\n"); + return false; + } + return true; } @@ -1594,14 +1601,17 @@ static void P_LoadTextmap (void) } } -static void P_LoadMapData(const virtres_t *virt) +static boolean P_LoadMapData(const virtres_t *virt) { virtlump_t *virtvertexes = NULL, *virtsectors = NULL, *virtsidedefs = NULL, *virtlinedefs = NULL, *virtthings = NULL; virtlump_t *textmap = vres_Find(virt, "TEXTMAP"); // Count map data. if (textmap) // Count how many entries for each type we got in textmap. - TextmapCount(textmap->data, textmap->size); + { + if (!TextmapCount(textmap->data, textmap->size)) + return false; + } else { virtthings = vres_Find(virt, "THINGS"); @@ -1684,6 +1694,8 @@ static void P_LoadMapData(const virtres_t *virt) memcpy(spawnsectors, sectors, numsectors * sizeof (*sectors)); memcpy(spawnlines, lines, numlines * sizeof (*lines)); memcpy(spawnsides, sides, numsides * sizeof (*sides)); + + return true; } static void P_InitializeSubsector(subsector_t *ss) @@ -2685,11 +2697,12 @@ static void P_MakeMapMD5(virtres_t *virt, void *dest) M_Memcpy(dest, &resmd5, 16); } -static void P_LoadMapFromFile(void) +static boolean P_LoadMapFromFile(void) { virtres_t *virt = vres_GetMap(lastloadedmaplumpnum); - P_LoadMapData(virt); + if (!P_LoadMapData(virt)) + return false; P_LoadMapBSP(virt); P_LoadMapLUT(virt); @@ -2701,6 +2714,7 @@ static void P_LoadMapFromFile(void) P_MakeMapMD5(virt, &mapmd5); vres_Free(virt); + return true; } // @@ -3549,8 +3563,8 @@ boolean P_LoadLevel(boolean fromnetsave) P_MapStart(); - if (lastloadedmaplumpnum) - P_LoadMapFromFile(); + if (!P_LoadMapFromFile()) + return false; // init gravity, tag lists, // anything that P_ResetDynamicSlopes/P_LoadThings needs to know From a04834d1aa1dc361b2fbed81ad7cd81e005a1bdb Mon Sep 17 00:00:00 2001 From: Jaime Passos Date: Mon, 30 Dec 2019 12:02:09 -0300 Subject: [PATCH 536/746] 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 72bb67320969b17d116c18392a2781751d19af58 Mon Sep 17 00:00:00 2001 From: MascaraSnake Date: Mon, 30 Dec 2019 16:28:22 +0100 Subject: [PATCH 537/746] Some minor refactoring of textmap loading code --- src/p_setup.c | 54 +++++++++++++++------------------------------------ 1 file changed, 16 insertions(+), 38 deletions(-) diff --git a/src/p_setup.c b/src/p_setup.c index 78792f306..4d4eaff6d 100644 --- a/src/p_setup.c +++ b/src/p_setup.c @@ -1314,12 +1314,7 @@ static boolean TextmapCount(UINT8 *data, size_t size) static char* dat; -/** Auxiliary function for TextmapParse. - * - * \param Vertex number. - * \param Parameter string. - */ -static void TextmapVertex(UINT32 i, char *param) +static void ParseTextmapVertexParameter(UINT32 i, char *param) { if (fastcmp(param, "x")) vertexes[i].x = FLOAT_TO_FIXED(atof(dat = M_GetToken(NULL))); @@ -1327,12 +1322,7 @@ static void TextmapVertex(UINT32 i, char *param) vertexes[i].y = FLOAT_TO_FIXED(atof(dat = M_GetToken(NULL))); } -/** Auxiliary function for TextmapParse. - * - * \param Sector number. - * \param Parameter string. - */ -static void TextmapSector(UINT32 i, char *param) +static void ParseTextmapSectorParameter(UINT32 i, char *param) { if (fastcmp(param, "heightfloor")) sectors[i].floorheight = atol(dat = M_GetToken(NULL)) << FRACBITS; @@ -1350,12 +1340,7 @@ static void TextmapSector(UINT32 i, char *param) sectors[i].tag = atol(dat = M_GetToken(NULL)); } -/** Auxiliary function for TextmapParse. - * - * \param Side number. - * \param Parameter string. - */ -static void TextmapSide(UINT32 i, char *param) +static void ParseTextmapSidedefParameter(UINT32 i, char *param) { if (fastcmp(param, "offsetx")) sides[i].textureoffset = atol(dat = M_GetToken(NULL))<floorpic_angle>>ANGLETOFINESHIFT); fixed_t xoffs = sec->floor_xoffs; fixed_t yoffs = sec->floor_yoffs; - #define MAXFLATSIZE (2048<floor_xoffs = (FixedMul(xoffs, pc) % MAXFLATSIZE) - (FixedMul(yoffs, ps) % MAXFLATSIZE); sec->floor_yoffs = (FixedMul(xoffs, ps) % MAXFLATSIZE) + (FixedMul(yoffs, pc) % MAXFLATSIZE); - #undef MAXFLATSIZE } if (sec->ceilingpic_angle) @@ -1510,13 +1488,13 @@ static void TextmapFixFlatOffsets(sector_t *sec) fixed_t ps = FINESINE (sec->ceilingpic_angle>>ANGLETOFINESHIFT); fixed_t xoffs = sec->ceiling_xoffs; fixed_t yoffs = sec->ceiling_yoffs; - #define MAXFLATSIZE (2048<ceiling_xoffs = (FixedMul(xoffs, pc) % MAXFLATSIZE) - (FixedMul(yoffs, ps) % MAXFLATSIZE); sec->ceiling_yoffs = (FixedMul(xoffs, ps) % MAXFLATSIZE) + (FixedMul(yoffs, pc) % MAXFLATSIZE); - #undef MAXFLATSIZE } } +#undef MAXFLATSIZE + /** Loads the textmap data, after obtaining the elements count and allocating their respective space. */ static void P_LoadTextmap(void) @@ -1532,7 +1510,7 @@ static void P_LoadTextmap(void) CONS_Alert(CONS_NOTICE, "UDMF support is still a work-in-progress; its specs and features are prone to change until it is fully implemented.\n"); /// Given the UDMF specs, some fields are given a default value. - /// If an element's field has a default value set, it is ommited + /// If an element's field has a default value set, it is omitted /// from the textmap, and therefore we have to account for it by /// preemptively setting that value beforehand. @@ -1541,7 +1519,7 @@ static void P_LoadTextmap(void) // Defaults. vt->z = 0; - TextmapParse(vertexesPos[i], i, TextmapVertex); + TextmapParse(vertexesPos[i], i, ParseTextmapVertexParameter); } for (i = 0, sc = sectors; i < numsectors; i++, sc++) @@ -1561,7 +1539,7 @@ static void P_LoadTextmap(void) sc->floor_xoffs = sc->floor_yoffs = sc->ceiling_xoffs = sc->ceiling_yoffs = 0; sc->floorpic_angle = sc->ceilingpic_angle = 0; - TextmapParse(sectorsPos[i], i, TextmapSector); + TextmapParse(sectorsPos[i], i, ParseTextmapSectorParameter); P_InitializeSector(sc); TextmapFixFlatOffsets(sc); @@ -1574,7 +1552,7 @@ static void P_LoadTextmap(void) ld->special = 0; ld->sidenum[1] = 0xffff; - TextmapParse(linesPos[i], i, TextmapLine); + TextmapParse(linesPos[i], i, ParseTextmapLinedefParameter); P_InitializeLinedef(ld); } @@ -1590,7 +1568,7 @@ static void P_LoadTextmap(void) sd->bottomtexture = R_TextureNumForName("-"); sd->repeatcnt = 0; - TextmapParse(sidesPos[i], i, TextmapSide); + TextmapParse(sidesPos[i], i, ParseTextmapSidedefParameter); } for (i = 0, mt = mapthings; i < nummapthings; i++, mt++) @@ -1599,7 +1577,7 @@ static void P_LoadTextmap(void) mt->z = 0; mt->angle = 0; - TextmapParse(mapthingsPos[i], i, TextmapThing); + TextmapParse(mapthingsPos[i], i, ParseTextmapThingParameter); } } From 05a97530c18a5f8e87fc47d27187b6a3a3542eb5 Mon Sep 17 00:00:00 2001 From: MascaraSnake Date: Mon, 30 Dec 2019 17:28:10 +0100 Subject: [PATCH 538/746] Add support for flat offset and rotation fields in UDMF --- src/p_setup.c | 18 +++++++++++++----- 1 file changed, 13 insertions(+), 5 deletions(-) diff --git a/src/p_setup.c b/src/p_setup.c index 4d4eaff6d..e4b73570f 100644 --- a/src/p_setup.c +++ b/src/p_setup.c @@ -1338,6 +1338,18 @@ static void ParseTextmapSectorParameter(UINT32 i, char *param) sectors[i].special = atol(dat = M_GetToken(NULL)); else if (fastcmp(param, "id")) sectors[i].tag = atol(dat = M_GetToken(NULL)); + else if (fastcmp(param, "xpanningfloor")) + sectors[i].floor_xoffs = FLOAT_TO_FIXED(atof(dat = M_GetToken(NULL))); + else if (fastcmp(param, "ypanningfloor")) + sectors[i].floor_yoffs = FLOAT_TO_FIXED(atof(dat = M_GetToken(NULL))); + else if (fastcmp(param, "xpanningceiling")) + sectors[i].ceiling_xoffs = FLOAT_TO_FIXED(atof(dat = M_GetToken(NULL))); + else if (fastcmp(param, "ypanningceiling")) + sectors[i].ceiling_yoffs = FLOAT_TO_FIXED(atof(dat = M_GetToken(NULL))); + else if (fastcmp(param, "rotationfloor")) + sectors[i].floorpic_angle = FixedAngle(FLOAT_TO_FIXED(atof(dat = M_GetToken(NULL)))); + else if (fastcmp(param, "rotationceiling")) + sectors[i].ceilingpic_angle = FixedAngle(FLOAT_TO_FIXED(atof(dat = M_GetToken(NULL)))); } static void ParseTextmapSidedefParameter(UINT32 i, char *param) @@ -1536,12 +1548,8 @@ static void P_LoadTextmap(void) sc->special = 0; sc->tag = 0; - sc->floor_xoffs = sc->floor_yoffs = sc->ceiling_xoffs = sc->ceiling_yoffs = 0; - sc->floorpic_angle = sc->ceilingpic_angle = 0; - - TextmapParse(sectorsPos[i], i, ParseTextmapSectorParameter); - P_InitializeSector(sc); + TextmapParse(sectorsPos[i], i, ParseTextmapSectorParameter); TextmapFixFlatOffsets(sc); } From f4e7227e112af4b9d896b6a383c03faf16fd8a6e Mon Sep 17 00:00:00 2001 From: fickleheart Date: Mon, 30 Dec 2019 11:01:56 -0600 Subject: [PATCH 539/746] Fix compilation errors --- src/g_game.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/g_game.c b/src/g_game.c index 46495ecd6..008fc7f1b 100644 --- a/src/g_game.c +++ b/src/g_game.c @@ -459,6 +459,9 @@ typedef enum AXISMOVE, AXISLOOK, AXISSTRAFE, + + AXISDIGITAL, // axes below this use digital deadzone + AXISJUMP, AXISSPIN, AXISFIRE, @@ -1222,7 +1225,7 @@ void G_BuildTiccmd(ticcmd_t *cmd, INT32 realtics, UINT8 ssplayer) *myaiming = 0; joyaiming[forplayer] = thisjoyaiming; - turnaxis = JPlayerJoyAxis(ssplayer, AXISTURN); + turnaxis = PlayerJoyAxis(ssplayer, AXISTURN); if (strafeisturn) turnaxis += PlayerJoyAxis(ssplayer, AXISSTRAFE); lookaxis = PlayerJoyAxis(ssplayer, AXISLOOK); @@ -1301,9 +1304,6 @@ void G_BuildTiccmd(ticcmd_t *cmd, INT32 realtics, UINT8 ssplayer) if (turnright || turnleft || abs(cmd->angleturn) > angleturn[2]) tta_factor[forplayer] = 0; // suspend turn to angle - - // Make rotspeed affect turning speed :) - cmd->angleturn = (cmd->angleturn * (ssplayer == 1 ? cv_cam_rotspeed.value : cv_cam2_rotspeed.value)) / 10; } strafeaxis = strafeisturn ? 0 : PlayerJoyAxis(ssplayer, AXISSTRAFE); From ebbe5938a8bc5ecb75b4179acacee7e28c149b2c Mon Sep 17 00:00:00 2001 From: fickleheart Date: Mon, 30 Dec 2019 11:07:29 -0600 Subject: [PATCH 540/746] Fix tailsbot flying weird with P1=standard P2=simple controls --- 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 008fc7f1b..2a4e67d7b 100644 --- a/src/g_game.c +++ b/src/g_game.c @@ -1181,7 +1181,7 @@ void G_BuildTiccmd(ticcmd_t *cmd, INT32 realtics, UINT8 ssplayer) mly = &mlook2y; G_CopyTiccmd(cmd, I_BaseTiccmd2(), 1); // empty, or external driver } - abilitydirection = cv_abilitydirection[forplayer].value; + abilitydirection = cv_abilitydirection[player->bot ? 0 : forplayer].value; strafeisturn = abilitydirection && ticcmd_centerviewdown[forplayer] && ((cv_cam_lockedinput[forplayer].value && !ticcmd_ztargetfocus[forplayer]) || (player->pflags & PF_STARTDASH)) && @@ -1608,6 +1608,7 @@ void G_BuildTiccmd(ticcmd_t *cmd, INT32 realtics, UINT8 ssplayer) { G_CopyTiccmd(cmd, I_BaseTiccmd2(), 1); // empty, or external driver B_BuildTiccmd(player, cmd); + } } From 7fa9eed5735b9192fe9f1036c2b2da62277c14ab Mon Sep 17 00:00:00 2001 From: fickleheart Date: Mon, 30 Dec 2019 11:22:54 -0600 Subject: [PATCH 541/746] Fix camera reset snap in simple controls --- src/p_user.c | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/src/p_user.c b/src/p_user.c index f5a8208a3..7c7f94863 100644 --- a/src/p_user.c +++ b/src/p_user.c @@ -9781,7 +9781,13 @@ void P_ResetCamera(player_t *player, camera_t *thiscam) thiscam->y = y; thiscam->z = z; - if (!(thiscam == &camera && (cv_cam_still.value || cv_analog.value)) + if ((thiscam == &camera && cv_abilitydirection[0].value) + || (thiscam == &camera2 && cv_abilitydirection[1].value)) + { + thiscam->angle = (thiscam == &camera) ? localangle : localangle2; + thiscam->aiming = (thiscam == &camera) ? localaiming : localaiming2; + } + else if (!(thiscam == &camera && (cv_cam_still.value || cv_analog.value)) && !(thiscam == &camera2 && (cv_cam2_still.value || cv_analog2.value))) { thiscam->angle = player->mo->angle; From d980d526c89f416e7ffe8db42b8aeb7aae8c21de Mon Sep 17 00:00:00 2001 From: fickleheart Date: Mon, 30 Dec 2019 11:36:40 -0600 Subject: [PATCH 542/746] Change defaults to match my personal settings --- src/g_game.c | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/src/g_game.c b/src/g_game.c index 2a4e67d7b..aaac4cbc2 100644 --- a/src/g_game.c +++ b/src/g_game.c @@ -411,23 +411,23 @@ consvar_t cv_cam_shiftfacing[2] = { {"cam2_shiftfacingchar", "0.33", CV_FLOAT|CV_SAVE, zerotoone_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL}, }; consvar_t cv_cam_turnfacing[2] = { - {"cam_turnfacingchar", "0.0", CV_FLOAT|CV_SAVE, zerotoone_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL}, - {"cam2_turnfacingchar", "0.0", CV_FLOAT|CV_SAVE, zerotoone_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL}, + {"cam_turnfacingchar", "0.25", CV_FLOAT|CV_SAVE, zerotoone_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL}, + {"cam2_turnfacingchar", "0.25", CV_FLOAT|CV_SAVE, zerotoone_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL}, }; consvar_t cv_cam_turnfacingability[2] = { - {"cam_turnfacingability", "0.0", CV_FLOAT|CV_SAVE, zerotoone_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL}, - {"cam2_turnfacingability", "0.0", CV_FLOAT|CV_SAVE, zerotoone_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL}, + {"cam_turnfacingability", "0.125", CV_FLOAT|CV_SAVE, zerotoone_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL}, + {"cam2_turnfacingability", "0.125", CV_FLOAT|CV_SAVE, zerotoone_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL}, }; consvar_t cv_cam_turnfacingspindash[2] = { - {"cam_turnfacingspindash", "0.25", CV_FLOAT|CV_SAVE, zerotoone_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL}, - {"cam2_turnfacingspindash", "0.25", CV_FLOAT|CV_SAVE, zerotoone_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL}, + {"cam_turnfacingspindash", "0.5", CV_FLOAT|CV_SAVE, zerotoone_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL}, + {"cam2_turnfacingspindash", "0.5", CV_FLOAT|CV_SAVE, zerotoone_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL}, }; consvar_t cv_cam_turnfacinginput[2] = { {"cam_turnfacinginput", "0.25", CV_FLOAT|CV_SAVE, zerotoone_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL}, {"cam2_turnfacinginput", "0.25", CV_FLOAT|CV_SAVE, zerotoone_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL}, }; -static CV_PossibleValue_t centertoggle_cons_t[] = {{0, "Hold"}, {1, "Toggle"}, {0, NULL}}; +static CV_PossibleValue_t centertoggle_cons_t[] = {{0, "Hold"}, {1, "Toggle"}, {2, "Sticky Hold"}, {0, NULL}}; consvar_t cv_cam_centertoggle[2] = { {"cam_centertoggle", "Hold", CV_SAVE, centertoggle_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL}, {"cam2_centertoggle", "Hold", CV_SAVE, centertoggle_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL}, From b46cbe76d6fffc06341421524110ba94766b2f37 Mon Sep 17 00:00:00 2001 From: fickleheart Date: Mon, 30 Dec 2019 11:36:59 -0600 Subject: [PATCH 543/746] Somehow miss committing the ACTUAL stickyhold part --- src/g_game.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/g_game.c b/src/g_game.c index aaac4cbc2..3ffe8839b 100644 --- a/src/g_game.c +++ b/src/g_game.c @@ -1400,6 +1400,10 @@ void G_BuildTiccmd(ticcmd_t *cmd, INT32 realtics, UINT8 ssplayer) if (down && !last_centerviewdown[forplayer]) centerviewhold[forplayer] = !centerviewhold[forplayer]; last_centerviewdown[forplayer] = down; + + if (cv_cam_centertoggle[forplayer].value == 2 && !down && !ticcmd_ztargetfocus[forplayer]) + centerviewhold[forplayer] = false; + centerviewdown = centerviewhold[forplayer]; } } From 085c39128f1128b6493ad02ffbf89c6b3c851d75 Mon Sep 17 00:00:00 2001 From: fickleheart Date: Mon, 30 Dec 2019 12:10:38 -0600 Subject: [PATCH 544/746] Save separate camera settings for standard/simple modes --- src/m_menu.c | 31 ++++++++++++------------------- src/p_local.h | 4 ++++ src/p_setup.c | 3 +++ src/p_user.c | 44 ++++++++++++++++++++++++++++++++++++++++---- src/r_main.c | 10 ++++++++++ 5 files changed, 69 insertions(+), 23 deletions(-) diff --git a/src/m_menu.c b/src/m_menu.c index 3fb7eee7a..0675dceb9 100644 --- a/src/m_menu.c +++ b/src/m_menu.c @@ -1190,8 +1190,8 @@ static menuitem_t OP_CameraOptionsMenu[] = {IT_STRING | IT_CVAR, NULL, "Downhill Slope Adjustment", &cv_cam_adjust, 21}, {IT_HEADER, NULL, "Camera Positioning", NULL, 30}, - {IT_STRING | IT_CVAR | IT_CV_INTEGERSTEP, NULL, "Camera Distance", &cv_cam_dist, 36}, - {IT_STRING | IT_CVAR | IT_CV_INTEGERSTEP, NULL, "Camera Height", &cv_cam_height, 41}, + {IT_STRING | IT_CVAR | IT_CV_INTEGERSTEP, NULL, "Camera Distance", &cv_cam_savedist[0][0], 36}, + {IT_STRING | IT_CVAR | IT_CV_INTEGERSTEP, NULL, "Camera Height", &cv_cam_saveheight[0][0], 41}, {IT_STRING | IT_CVAR | IT_CV_FLOATSLIDER, NULL, "Camera Spacial Speed", &cv_cam_speed, 46}, {IT_STRING | IT_CVAR | IT_CV_FLOATSLIDER, NULL, "Rotation Speed", &cv_cam_turnmultiplier, 51}, @@ -1208,8 +1208,8 @@ static menuitem_t OP_Camera2OptionsMenu[] = {IT_STRING | IT_CVAR, NULL, "Downhill Slope Adjustment", &cv_cam2_adjust, 21}, {IT_HEADER, NULL, "Camera Positioning", NULL, 30}, - {IT_STRING | IT_CVAR | IT_CV_INTEGERSTEP, NULL, "Camera Distance", &cv_cam2_dist, 36}, - {IT_STRING | IT_CVAR | IT_CV_INTEGERSTEP, NULL, "Camera Height", &cv_cam2_height, 41}, + {IT_STRING | IT_CVAR | IT_CV_INTEGERSTEP, NULL, "Camera Distance", &cv_cam_savedist[0][1], 36}, + {IT_STRING | IT_CVAR | IT_CV_INTEGERSTEP, NULL, "Camera Height", &cv_cam_saveheight[0][1], 41}, {IT_STRING | IT_CVAR | IT_CV_FLOATSLIDER, NULL, "Camera Spacial Speed", &cv_cam2_speed, 46}, {IT_STRING | IT_CVAR | IT_CV_FLOATSLIDER, NULL, "Rotation Speed", &cv_cam2_turnmultiplier, 51}, @@ -1226,8 +1226,8 @@ static menuitem_t OP_CameraExtendedOptionsMenu[] = {IT_STRING | IT_CVAR, NULL, "Downhill Slope Adjustment", &cv_cam_adjust, 21}, {IT_HEADER, NULL, "Camera Positioning", NULL, 30}, - {IT_STRING | IT_CVAR | IT_CV_INTEGERSTEP, NULL, "Camera Distance", &cv_cam_dist, 36}, - {IT_STRING | IT_CVAR | IT_CV_INTEGERSTEP, NULL, "Camera Height", &cv_cam_height, 41}, + {IT_STRING | IT_CVAR | IT_CV_INTEGERSTEP, NULL, "Camera Distance", &cv_cam_savedist[1][0], 36}, + {IT_STRING | IT_CVAR | IT_CV_INTEGERSTEP, NULL, "Camera Height", &cv_cam_saveheight[1][0], 41}, {IT_STRING | IT_CVAR | IT_CV_FLOATSLIDER, NULL, "Camera Spacial Speed", &cv_cam_speed, 46}, {IT_STRING | IT_CVAR | IT_CV_FLOATSLIDER, NULL, "Rotation Speed", &cv_cam_turnmultiplier, 51}, @@ -1256,8 +1256,8 @@ static menuitem_t OP_Camera2ExtendedOptionsMenu[] = {IT_STRING | IT_CVAR, NULL, "Downhill Slope Adjustment", &cv_cam2_adjust, 21}, {IT_HEADER, NULL, "Camera Positioning", NULL, 30}, - {IT_STRING | IT_CVAR | IT_CV_INTEGERSTEP, NULL, "Camera Distance", &cv_cam2_dist, 36}, - {IT_STRING | IT_CVAR | IT_CV_INTEGERSTEP, NULL, "Camera Height", &cv_cam2_height, 41}, + {IT_STRING | IT_CVAR | IT_CV_INTEGERSTEP, NULL, "Camera Distance", &cv_cam_savedist[1][1], 36}, + {IT_STRING | IT_CVAR | IT_CV_INTEGERSTEP, NULL, "Camera Height", &cv_cam_saveheight[1][1], 41}, {IT_STRING | IT_CVAR | IT_CV_FLOATSLIDER, NULL, "Camera Spacial Speed", &cv_cam2_speed, 46}, {IT_STRING | IT_CVAR | IT_CV_FLOATSLIDER, NULL, "Rotation Speed", &cv_cam2_turnmultiplier, 51}, @@ -11664,18 +11664,11 @@ static void M_HandlePlaystyleMenu(INT32 choice) S_StartSound(NULL, sfx_menu1); if (cv_abilitydirection[playstyle_activeplayer].value != (playstyle_currentchoice/2)) { - if (cv_abilitydirection[playstyle_activeplayer].value) - { - CV_Set((playstyle_activeplayer ? &cv_cam2_dist : &cv_cam_dist), cv_cam_dist.defaultvalue); - CV_Set((playstyle_activeplayer ? &cv_cam2_height : &cv_cam_height), cv_cam_height.defaultvalue); - } - else - { - CV_SetValue((playstyle_activeplayer ? &cv_cam2_dist : &cv_cam_dist), 224); - CV_SetValue((playstyle_activeplayer ? &cv_cam2_height : &cv_cam_height), 50); - } - CV_SetValue(&cv_abilitydirection[playstyle_activeplayer], playstyle_currentchoice/2); + if (playstyle_activeplayer) + CV_UpdateCam2Dist(); + else + CV_UpdateCamDist(); } CV_SetValue((playstyle_activeplayer ? &cv_directionchar2 : &cv_directionchar), playstyle_currentchoice ? 1 : 0); CV_SetValue((playstyle_activeplayer ? &cv_useranalog2 : &cv_useranalog), 0); diff --git a/src/p_local.h b/src/p_local.h index 19213959d..687af23e5 100644 --- a/src/p_local.h +++ b/src/p_local.h @@ -120,6 +120,10 @@ extern consvar_t cv_cam_speed, cv_cam_rotate, cv_cam_rotspeed, cv_cam_turnmultip extern consvar_t cv_cam2_dist, cv_cam2_still, cv_cam2_height; extern consvar_t cv_cam2_speed, cv_cam2_rotate, cv_cam2_rotspeed, cv_cam2_turnmultiplier, cv_cam2_orbit, cv_cam2_adjust; +extern consvar_t cv_cam_savedist[2][2], cv_cam_saveheight[2][2]; +void CV_UpdateCamDist(void); +void CV_UpdateCam2Dist(void); + extern fixed_t t_cam_dist, t_cam_height, t_cam_rotate; extern fixed_t t_cam2_dist, t_cam2_height, t_cam2_rotate; diff --git a/src/p_setup.c b/src/p_setup.c index bf3493d8c..e6bf684d7 100644 --- a/src/p_setup.c +++ b/src/p_setup.c @@ -2692,6 +2692,9 @@ boolean P_SetupLevel(boolean skipprecip) /*if (!cv_cam_speed.changed) CV_Set(&cv_cam_speed, cv_cam_speed.defaultvalue);*/ + CV_UpdateCamDist(); + CV_UpdateCam2Dist(); + if (!cv_chasecam.changed) CV_SetValue(&cv_chasecam, chase); diff --git a/src/p_user.c b/src/p_user.c index 7c7f94863..bf6651a72 100644 --- a/src/p_user.c +++ b/src/p_user.c @@ -9729,8 +9729,8 @@ static CV_PossibleValue_t rotation_cons_t[] = {{1, "MIN"}, {25, "MAX"}, {0, NULL static CV_PossibleValue_t CV_CamRotate[] = {{-720, "MIN"}, {720, "MAX"}, {0, NULL}}; static CV_PossibleValue_t multiplier_cons_t[] = {{0, "MIN"}, {3*FRACUNIT, "MAX"}, {0, NULL}}; -consvar_t cv_cam_dist = {"cam_dist", "160", CV_FLOAT|CV_SAVE, NULL, NULL, 0, NULL, NULL, 0, 0, NULL}; -consvar_t cv_cam_height = {"cam_height", "25", CV_FLOAT|CV_SAVE, NULL, NULL, 0, NULL, NULL, 0, 0, NULL}; +consvar_t cv_cam_dist = {"cam_curdist", "160", CV_FLOAT, NULL, NULL, 0, NULL, NULL, 0, 0, NULL}; +consvar_t cv_cam_height = {"cam_curheight", "25", CV_FLOAT, NULL, NULL, 0, NULL, NULL, 0, 0, NULL}; consvar_t cv_cam_still = {"cam_still", "Off", 0, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL}; consvar_t cv_cam_speed = {"cam_speed", "0.3", CV_FLOAT|CV_SAVE, CV_CamSpeed, NULL, 0, NULL, NULL, 0, 0, NULL}; consvar_t cv_cam_rotate = {"cam_rotate", "0", CV_CALL|CV_NOINIT, CV_CamRotate, CV_CamRotate_OnChange, 0, NULL, NULL, 0, 0, NULL}; @@ -9738,8 +9738,8 @@ consvar_t cv_cam_rotspeed = {"cam_rotspeed", "10", CV_SAVE, rotation_cons_t, NUL consvar_t cv_cam_turnmultiplier = {"cam_turnmultiplier", "1.0", CV_FLOAT|CV_SAVE, multiplier_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL}; consvar_t cv_cam_orbit = {"cam_orbit", "Off", CV_SAVE, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL}; consvar_t cv_cam_adjust = {"cam_adjust", "On", CV_SAVE, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL}; -consvar_t cv_cam2_dist = {"cam2_dist", "160", CV_FLOAT|CV_SAVE, NULL, NULL, 0, NULL, NULL, 0, 0, NULL}; -consvar_t cv_cam2_height = {"cam2_height", "25", CV_FLOAT|CV_SAVE, NULL, NULL, 0, NULL, NULL, 0, 0, NULL}; +consvar_t cv_cam2_dist = {"cam2_curdist", "160", CV_FLOAT, NULL, NULL, 0, NULL, NULL, 0, 0, NULL}; +consvar_t cv_cam2_height = {"cam2_curheight", "25", CV_FLOAT, NULL, NULL, 0, NULL, NULL, 0, 0, NULL}; consvar_t cv_cam2_still = {"cam2_still", "Off", 0, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL}; consvar_t cv_cam2_speed = {"cam2_speed", "0.3", CV_FLOAT|CV_SAVE, CV_CamSpeed, NULL, 0, NULL, NULL, 0, 0, NULL}; consvar_t cv_cam2_rotate = {"cam2_rotate", "0", CV_CALL|CV_NOINIT, CV_CamRotate, CV_CamRotate2_OnChange, 0, NULL, NULL, 0, 0, NULL}; @@ -9748,6 +9748,42 @@ consvar_t cv_cam2_turnmultiplier = {"cam2_turnmultiplier", "1.0", CV_FLOAT|CV_SA consvar_t cv_cam2_orbit = {"cam2_orbit", "Off", CV_SAVE, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL}; consvar_t cv_cam2_adjust = {"cam2_adjust", "On", CV_SAVE, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL}; +// [standard vs simple][p1 or p2] +consvar_t cv_cam_savedist[2][2] = { + { // standard + {"cam_dist", "160", CV_FLOAT|CV_SAVE|CV_CALL, NULL, CV_UpdateCamDist, 0, NULL, NULL, 0, 0, NULL}, + {"cam2_dist", "160", CV_FLOAT|CV_SAVE|CV_CALL, NULL, CV_UpdateCam2Dist, 0, NULL, NULL, 0, 0, NULL} + }, + { // simple + {"cam_simpledist", "224", CV_FLOAT|CV_SAVE|CV_CALL, NULL, CV_UpdateCamDist, 0, NULL, NULL, 0, 0, NULL}, + {"cam2_simpledist", "224", CV_FLOAT|CV_SAVE|CV_CALL, NULL, CV_UpdateCam2Dist, 0, NULL, NULL, 0, 0, NULL} + + } +}; +consvar_t cv_cam_saveheight[2][2] = { + { // standard + {"cam_height", "25", CV_FLOAT|CV_SAVE|CV_CALL, NULL, CV_UpdateCamDist, 0, NULL, NULL, 0, 0, NULL}, + {"cam2_height", "25", CV_FLOAT|CV_SAVE|CV_CALL, NULL, CV_UpdateCam2Dist, 0, NULL, NULL, 0, 0, NULL} + }, + { // simple + {"cam_simpleheight", "48", CV_FLOAT|CV_SAVE|CV_CALL, NULL, CV_UpdateCamDist, 0, NULL, NULL, 0, 0, NULL}, + {"cam2_simpleheight", "48", CV_FLOAT|CV_SAVE|CV_CALL, NULL, CV_UpdateCam2Dist, 0, NULL, NULL, 0, 0, NULL} + + } +}; + +void CV_UpdateCamDist(void) +{ + CV_Set(&cv_cam_dist, va("%f", FIXED_TO_FLOAT(cv_cam_savedist[cv_abilitydirection[0].value][0].value))); + CV_Set(&cv_cam_height, va("%f", FIXED_TO_FLOAT(cv_cam_saveheight[cv_abilitydirection[0].value][0].value))); +} + +void CV_UpdateCam2Dist(void) +{ + CV_Set(&cv_cam2_dist, va("%f", FIXED_TO_FLOAT(cv_cam_savedist[cv_abilitydirection[1].value][1].value))); + CV_Set(&cv_cam2_height, va("%f", FIXED_TO_FLOAT(cv_cam_saveheight[cv_abilitydirection[1].value][1].value))); +} + fixed_t t_cam_dist = -42; fixed_t t_cam_height = -42; fixed_t t_cam_rotate = -42; diff --git a/src/r_main.c b/src/r_main.c index 115db8cb5..efea00af8 100644 --- a/src/r_main.c +++ b/src/r_main.c @@ -1206,6 +1206,16 @@ void R_RegisterEngineStuff(void) CV_RegisterVar(&cv_cam2_orbit); CV_RegisterVar(&cv_cam2_adjust); + CV_RegisterVar(&cv_cam_savedist[0][0]); + CV_RegisterVar(&cv_cam_savedist[0][1]); + CV_RegisterVar(&cv_cam_savedist[1][0]); + CV_RegisterVar(&cv_cam_savedist[1][1]); + + CV_RegisterVar(&cv_cam_saveheight[0][0]); + CV_RegisterVar(&cv_cam_saveheight[0][1]); + CV_RegisterVar(&cv_cam_saveheight[1][0]); + CV_RegisterVar(&cv_cam_saveheight[1][1]); + CV_RegisterVar(&cv_showhud); CV_RegisterVar(&cv_translucenthud); From 631b5ff883a3f557e6c582793b68caf003e79de7 Mon Sep 17 00:00:00 2001 From: fickleheart Date: Mon, 30 Dec 2019 12:13:41 -0600 Subject: [PATCH 545/746] Disable lock-on in Ringslinger --- 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 3ffe8839b..471c6db6c 100644 --- a/src/g_game.c +++ b/src/g_game.c @@ -1410,7 +1410,7 @@ void G_BuildTiccmd(ticcmd_t *cmd, INT32 realtics, UINT8 ssplayer) if (centerviewdown) { - if (abilitydirection && !ticcmd_centerviewdown[forplayer]) + if (abilitydirection && !ticcmd_centerviewdown[forplayer] && !G_RingSlingerGametype()) { CV_SetValue((ssplayer == 1 ? &cv_directionchar : &cv_directionchar2), 0); *myangle = player->mo->angle; From e0f35d207ff12eee1e183d367b057842ee038fd0 Mon Sep 17 00:00:00 2001 From: fickleheart Date: Mon, 30 Dec 2019 14:01:14 -0600 Subject: [PATCH 546/746] Convert analog/directionchar cvars into 2-long arrays --- src/b_bot.c | 2 +- src/d_main.c | 2 +- src/d_netcmd.c | 22 ++++++++++---------- src/doomstat.h | 2 +- src/g_game.c | 54 ++++++++++++++++++++++++++++---------------------- src/g_game.h | 5 ++--- src/m_cheat.c | 2 +- src/m_menu.c | 22 ++++++++++---------- src/m_misc.c | 4 ++-- src/p_map.c | 6 +++--- src/p_setup.c | 24 +++++++++++----------- src/p_user.c | 14 ++++++------- src/r_main.c | 12 +++++------ 13 files changed, 88 insertions(+), 83 deletions(-) diff --git a/src/b_bot.c b/src/b_bot.c index dfb5ee1cf..cd5edf990 100644 --- a/src/b_bot.c +++ b/src/b_bot.c @@ -379,7 +379,7 @@ void B_BuildTiccmd(player_t *player, ticcmd_t *cmd) } // Bot AI isn't programmed in analog. - CV_SetValue(&cv_analog2, false); + CV_SetValue(&cv_analog[1], false); #ifdef HAVE_BLUA // Let Lua scripts build ticcmds diff --git a/src/d_main.c b/src/d_main.c index c4b0d7117..f3e84985a 100644 --- a/src/d_main.c +++ b/src/d_main.c @@ -781,7 +781,7 @@ void D_StartTitle(void) CV_SetValue(&cv_usemouse, tutorialusemouse); CV_SetValue(&cv_alwaysfreelook, tutorialfreelook); CV_SetValue(&cv_mousemove, tutorialmousemove); - CV_SetValue(&cv_analog, tutorialanalog); + CV_SetValue(&cv_analog[0], tutorialanalog); M_StartMessage("Do you want to \x82save the recommended \x82movement controls?\x80\n\nPress 'Y' or 'Enter' to confirm\nPress 'N' or any key to keep \nyour current controls", M_TutorialSaveControlResponse, MM_YESNO); } diff --git a/src/d_netcmd.c b/src/d_netcmd.c index ffb5b90ca..df6d70446 100644 --- a/src/d_netcmd.c +++ b/src/d_netcmd.c @@ -816,14 +816,14 @@ void D_RegisterClientCommands(void) CV_RegisterVar(&cv_joyscale2); // Analog Control - CV_RegisterVar(&cv_analog); - CV_RegisterVar(&cv_analog2); - CV_RegisterVar(&cv_useranalog); - CV_RegisterVar(&cv_useranalog2); + CV_RegisterVar(&cv_analog[0]); + CV_RegisterVar(&cv_analog[1]); + CV_RegisterVar(&cv_useranalog[0]); + CV_RegisterVar(&cv_useranalog[1]); // deez New User eXperiences - CV_RegisterVar(&cv_directionchar); - CV_RegisterVar(&cv_directionchar2); + CV_RegisterVar(&cv_directionchar[0]); + CV_RegisterVar(&cv_directionchar[1]); CV_RegisterVar(&cv_autobrake); CV_RegisterVar(&cv_autobrake2); @@ -1510,9 +1510,9 @@ void SendWeaponPref(void) buf[0] = 0; if (cv_flipcam.value) buf[0] |= 1; - if (cv_analog.value) + if (cv_analog[0].value) buf[0] |= 2; - if (cv_directionchar.value) + if (cv_directionchar[0].value) buf[0] |= 4; if (cv_autobrake.value) buf[0] |= 8; @@ -1526,9 +1526,9 @@ void SendWeaponPref2(void) buf[0] = 0; if (cv_flipcam2.value) buf[0] |= 1; - if (cv_analog2.value) + if (cv_analog[1].value) buf[0] |= 2; - if (cv_directionchar2.value) + if (cv_directionchar[1].value) buf[0] |= 4; if (cv_autobrake2.value) buf[0] |= 8; @@ -2036,7 +2036,7 @@ static void Command_Map_f(void) CV_SetValue(&cv_usemouse, tutorialusemouse); CV_SetValue(&cv_alwaysfreelook, tutorialfreelook); CV_SetValue(&cv_mousemove, tutorialmousemove); - CV_SetValue(&cv_analog, tutorialanalog); + CV_SetValue(&cv_analog[0], tutorialanalog); } tutorialmode = false; // warping takes us out of tutorial mode diff --git a/src/doomstat.h b/src/doomstat.h index 3c0b4773a..cc4e0ca98 100644 --- a/src/doomstat.h +++ b/src/doomstat.h @@ -137,7 +137,7 @@ extern INT32 tutorialgcs; // which control scheme is loaded? extern INT32 tutorialusemouse; // store cv_usemouse user value extern INT32 tutorialfreelook; // store cv_alwaysfreelook user value extern INT32 tutorialmousemove; // store cv_mousemove user value -extern INT32 tutorialanalog; // store cv_analog user value +extern INT32 tutorialanalog; // store cv_analog[0] user value extern boolean looptitle; diff --git a/src/g_game.c b/src/g_game.c index 471c6db6c..df5e2afd1 100644 --- a/src/g_game.c +++ b/src/g_game.c @@ -139,7 +139,7 @@ INT32 tutorialgcs = gcs_custom; // which control scheme is loaded? INT32 tutorialusemouse = 0; // store cv_usemouse user value INT32 tutorialfreelook = 0; // store cv_alwaysfreelook user value INT32 tutorialmousemove = 0; // store cv_mousemove user value -INT32 tutorialanalog = 0; // store cv_analog user value +INT32 tutorialanalog = 0; // store cv_analog[0] user value boolean looptitle = false; @@ -388,15 +388,21 @@ consvar_t cv_mousemove2 = {"mousemove2", "Off", CV_SAVE, CV_OnOff, NULL, 0, NULL // previously "analog", "analog2", "useranalog", and "useranalog2", invalidating 2.1-era copies of config.cfg // changed because it'd be nice to see people try out our actually good controls with gamepads now autobrake exists -consvar_t cv_analog = {"sessionanalog", "Off", CV_CALL|CV_NOSHOWHELP, CV_OnOff, Analog_OnChange, 0, NULL, NULL, 0, 0, NULL}; -consvar_t cv_analog2 = {"sessionanalog2", "Off", CV_CALL|CV_NOSHOWHELP, CV_OnOff, Analog2_OnChange, 0, NULL, NULL, 0, 0, NULL}; -consvar_t cv_useranalog = {"configanalog", "Off", CV_SAVE|CV_CALL|CV_NOSHOWHELP, CV_OnOff, UserAnalog_OnChange, 0, NULL, NULL, 0, 0, NULL}; -consvar_t cv_useranalog2 = {"configanalog2", "Off", CV_SAVE|CV_CALL|CV_NOSHOWHELP, CV_OnOff, UserAnalog2_OnChange, 0, NULL, NULL, 0, 0, NULL}; +consvar_t cv_analog[2] = { + {"sessionanalog", "Off", CV_CALL|CV_NOSHOWHELP, CV_OnOff, Analog_OnChange, 0, NULL, NULL, 0, 0, NULL}, + {"sessionanalog2", "Off", CV_CALL|CV_NOSHOWHELP, CV_OnOff, Analog2_OnChange, 0, NULL, NULL, 0, 0, NULL} +}; +consvar_t cv_useranalog[2] = { + {"configanalog", "Off", CV_SAVE|CV_CALL|CV_NOSHOWHELP, CV_OnOff, UserAnalog_OnChange, 0, NULL, NULL, 0, 0, NULL}, + {"configanalog2", "Off", CV_SAVE|CV_CALL|CV_NOSHOWHELP, CV_OnOff, UserAnalog2_OnChange, 0, NULL, NULL, 0, 0, NULL} +}; // deez New User eXperiences static CV_PossibleValue_t directionchar_cons_t[] = {{0, "Camera"}, {1, "Movement"}, {0, NULL}}; -consvar_t cv_directionchar = {"directionchar", "Movement", CV_SAVE|CV_CALL, directionchar_cons_t, DirectionChar_OnChange, 0, NULL, NULL, 0, 0, NULL}; -consvar_t cv_directionchar2 = {"directionchar2", "Movement", CV_SAVE|CV_CALL, directionchar_cons_t, DirectionChar2_OnChange, 0, NULL, NULL, 0, 0, NULL}; +consvar_t cv_directionchar[2] = { + {"directionchar", "Movement", CV_SAVE|CV_CALL, directionchar_cons_t, DirectionChar_OnChange, 0, NULL, NULL, 0, 0, NULL}, + {"directionchar2", "Movement", CV_SAVE|CV_CALL, directionchar_cons_t, DirectionChar2_OnChange, 0, NULL, NULL, 0, 0, NULL} +}; consvar_t cv_autobrake = {"autobrake", "On", CV_SAVE|CV_CALL, CV_OnOff, AutoBrake_OnChange, 0, NULL, NULL, 0, 0, NULL}; consvar_t cv_autobrake2 = {"autobrake2", "On", CV_SAVE|CV_CALL, CV_OnOff, AutoBrake2_OnChange, 0, NULL, NULL, 0, 0, NULL}; @@ -1159,7 +1165,7 @@ void G_BuildTiccmd(ticcmd_t *cmd, INT32 realtics, UINT8 ssplayer) chasefreelook = cv_chasefreelook.value; alwaysfreelook = cv_alwaysfreelook.value; usejoystick = cv_usejoystick.value; - analog = cv_analog.value; + analog = cv_analog[0].value; invertmouse = cv_invertmouse.value; mousemove = cv_mousemove.value; mx = &mousex; @@ -1173,7 +1179,7 @@ void G_BuildTiccmd(ticcmd_t *cmd, INT32 realtics, UINT8 ssplayer) chasefreelook = cv_chasefreelook2.value; alwaysfreelook = cv_alwaysfreelook2.value; usejoystick = cv_usejoystick2.value; - analog = cv_analog2.value; + analog = cv_analog[1].value; invertmouse = cv_invertmouse2.value; mousemove = cv_mousemove2.value; mx = &mouse2x; @@ -1412,7 +1418,7 @@ void G_BuildTiccmd(ticcmd_t *cmd, INT32 realtics, UINT8 ssplayer) { if (abilitydirection && !ticcmd_centerviewdown[forplayer] && !G_RingSlingerGametype()) { - CV_SetValue((ssplayer == 1 ? &cv_directionchar : &cv_directionchar2), 0); + CV_SetValue((ssplayer == 1 ? &cv_directionchar[0] : &cv_directionchar[1]), 0); *myangle = player->mo->angle; *myaiming = 0; @@ -1427,7 +1433,7 @@ void G_BuildTiccmd(ticcmd_t *cmd, INT32 realtics, UINT8 ssplayer) if (abilitydirection) { P_SetTarget(&ticcmd_ztargetfocus[forplayer], NULL); - CV_SetValue((ssplayer == 1 ? &cv_directionchar : &cv_directionchar2), 1); + CV_SetValue((ssplayer == 1 ? &cv_directionchar[0] : &cv_directionchar[1]), 1); } ticcmd_centerviewdown[forplayer] = false; @@ -1606,7 +1612,7 @@ void G_BuildTiccmd(ticcmd_t *cmd, INT32 realtics, UINT8 ssplayer) if (!player->powers[pw_tailsfly] && (cmd->forwardmove || cmd->sidemove || cmd->buttons)) { player->bot = 2; // A player-controlled bot. Returns to AI when it respawns. - CV_SetValue(&cv_analog2, true); + CV_SetValue(&cv_analog[1], true); } else { @@ -1726,20 +1732,20 @@ void G_BuildTiccmd(ticcmd_t *cmd, INT32 realtics, UINT8 ssplayer) // fudging with it. static void UserAnalog_OnChange(void) { - if (cv_useranalog.value) - CV_SetValue(&cv_analog, 1); + if (cv_useranalog[0].value) + CV_SetValue(&cv_analog[0], 1); else - CV_SetValue(&cv_analog, 0); + CV_SetValue(&cv_analog[0], 0); } static void UserAnalog2_OnChange(void) { if (botingame) return; - if (cv_useranalog2.value) - CV_SetValue(&cv_analog2, 1); + if (cv_useranalog[1].value) + CV_SetValue(&cv_analog[1], 1); else - CV_SetValue(&cv_analog2, 0); + CV_SetValue(&cv_analog[1], 0); } static void Analog_OnChange(void) @@ -1749,8 +1755,8 @@ static void Analog_OnChange(void) // cameras are not initialized at this point - if (!cv_chasecam.value && cv_analog.value) { - CV_SetValue(&cv_analog, 0); + if (!cv_chasecam.value && cv_analog[0].value) { + CV_SetValue(&cv_analog[0], 0); return; } @@ -1764,8 +1770,8 @@ static void Analog2_OnChange(void) // cameras are not initialized at this point - if (!cv_chasecam2.value && cv_analog2.value) { - CV_SetValue(&cv_analog2, 0); + if (!cv_chasecam2.value && cv_analog[1].value) { + CV_SetValue(&cv_analog[1], 0); return; } @@ -5956,12 +5962,12 @@ void G_BeginRecording(void) buf |= 0x01; pflags |= PF_FLIPCAM; } - if (cv_analog.value) + if (cv_analog[0].value) { buf |= 0x02; pflags |= PF_ANALOGMODE; } - if (cv_directionchar.value) + if (cv_directionchar[0].value) { buf |= 0x04; pflags |= PF_DIRECTIONCHAR; diff --git a/src/g_game.h b/src/g_game.h index 5f094fbda..b2a237d7e 100644 --- a/src/g_game.h +++ b/src/g_game.h @@ -68,9 +68,8 @@ extern consvar_t cv_chatwidth, cv_chatnotifications, cv_chatheight, cv_chattime, extern consvar_t cv_crosshair, cv_crosshair2; extern consvar_t cv_invertmouse, cv_alwaysfreelook, cv_chasefreelook, cv_mousemove; extern consvar_t cv_invertmouse2, cv_alwaysfreelook2, cv_chasefreelook2, cv_mousemove2; -extern consvar_t cv_useranalog, cv_useranalog2; -extern consvar_t cv_analog, cv_analog2; -extern consvar_t cv_directionchar, cv_directionchar2; +extern consvar_t cv_useranalog[2], cv_analog[2]; +extern consvar_t cv_directionchar[2]; extern consvar_t cv_autobrake, cv_autobrake2; extern consvar_t cv_sideaxis,cv_turnaxis,cv_moveaxis,cv_lookaxis,cv_jumpaxis,cv_spinaxis,cv_fireaxis,cv_firenaxis,cv_deadzone,cv_digitaldeadzone; extern consvar_t cv_sideaxis2,cv_turnaxis2,cv_moveaxis2,cv_lookaxis2,cv_jumpaxis2,cv_spinaxis2,cv_fireaxis2,cv_firenaxis2,cv_deadzone2,cv_digitaldeadzone2; diff --git a/src/m_cheat.c b/src/m_cheat.c index e31ce7869..66d09faba 100644 --- a/src/m_cheat.c +++ b/src/m_cheat.c @@ -1316,7 +1316,7 @@ void OP_ObjectplaceMovement(player_t *player) { ticcmd_t *cmd = &player->cmd; - if (!player->climbing && (netgame || !cv_analog.value || (player->pflags & PF_SPINNING))) + if (!player->climbing && (netgame || !cv_analog[0].value || (player->pflags & PF_SPINNING))) player->drawangle = player->mo->angle = (cmd->angleturn<<16 /* not FRACBITS */); ticruned++; diff --git a/src/m_menu.c b/src/m_menu.c index 0675dceb9..c5691a7c3 100644 --- a/src/m_menu.c +++ b/src/m_menu.c @@ -1038,7 +1038,7 @@ static menuitem_t OP_P1ControlsMenu[] = {IT_SUBMENU | IT_STRING, NULL, "Camera Options...", &OP_CameraOptionsDef, 50}, - //{IT_STRING | IT_CVAR, NULL, "Character angle", &cv_directionchar, 70}, + //{IT_STRING | IT_CVAR, NULL, "Character angle", &cv_directionchar[0], 70}, {IT_STRING | IT_CVAR, NULL, "Automatic braking", &cv_autobrake, 70}, {IT_CALL | IT_STRING, NULL, "Play Style...", M_Setup1PPlaystyleMenu, 80}, //{IT_STRING | IT_CVAR, NULL, "Ability angle", &cv_abilitydirection[0], 90}, @@ -1052,7 +1052,7 @@ static menuitem_t OP_P2ControlsMenu[] = {IT_SUBMENU | IT_STRING, NULL, "Camera Options...", &OP_Camera2OptionsDef, 50}, - //{IT_STRING | IT_CVAR, NULL, "Character angle", &cv_directionchar2, 70}, + //{IT_STRING | IT_CVAR, NULL, "Character angle", &cv_directionchar[1], 70}, {IT_STRING | IT_CVAR, NULL, "Automatic braking", &cv_autobrake2, 70}, {IT_CALL | IT_STRING, NULL, "Play Style...", M_Setup2PPlaystyleMenu, 80}, //{IT_STRING | IT_CVAR, NULL, "Ability angle", &cv_abilitydirection[1], 90}, @@ -4318,7 +4318,7 @@ static void M_DrawControlsDefMenu(void) if (currentMenu == &OP_P1ControlsDef) { - opt = cv_useranalog.value ? 3 : (cv_abilitydirection[0].value ? 2 : cv_directionchar.value); + opt = cv_useranalog[0].value ? 3 : (cv_abilitydirection[0].value ? 2 : cv_directionchar[0].value); if (opt == 2) { @@ -4333,7 +4333,7 @@ static void M_DrawControlsDefMenu(void) } else { - opt = cv_useranalog2.value ? 3 : (cv_abilitydirection[1].value ? 2 : cv_directionchar2.value); + opt = cv_useranalog[1].value ? 3 : (cv_abilitydirection[1].value ? 2 : cv_directionchar[1].value); if (opt == 2) { @@ -7773,7 +7773,7 @@ void M_TutorialSaveControlResponse(INT32 ch) CV_Set(&cv_usemouse, cv_usemouse.defaultvalue); CV_Set(&cv_alwaysfreelook, cv_alwaysfreelook.defaultvalue); CV_Set(&cv_mousemove, cv_mousemove.defaultvalue); - CV_Set(&cv_analog, cv_analog.defaultvalue); + CV_Set(&cv_analog[0], cv_analog[0].defaultvalue); S_StartSound(NULL, sfx_itemup); } else @@ -7791,13 +7791,13 @@ static void M_TutorialControlResponse(INT32 ch) tutorialusemouse = cv_usemouse.value; tutorialfreelook = cv_alwaysfreelook.value; tutorialmousemove = cv_mousemove.value; - tutorialanalog = cv_analog.value; + tutorialanalog = cv_analog[0].value; G_CopyControls(gamecontrol, gamecontroldefault[tutorialgcs], gcl_tutorial_full, num_gcl_tutorial_full); CV_Set(&cv_usemouse, cv_usemouse.defaultvalue); CV_Set(&cv_alwaysfreelook, cv_alwaysfreelook.defaultvalue); CV_Set(&cv_mousemove, cv_mousemove.defaultvalue); - CV_Set(&cv_analog, cv_analog.defaultvalue); + CV_Set(&cv_analog[0], cv_analog[0].defaultvalue); //S_StartSound(NULL, sfx_itemup); } @@ -11619,7 +11619,7 @@ static void M_Setup1PPlaystyleMenu(INT32 choice) (void)choice; playstyle_activeplayer = 0; - playstyle_currentchoice = cv_useranalog.value ? 3 : (cv_abilitydirection[0].value ? 2 : cv_directionchar.value); + playstyle_currentchoice = cv_useranalog[0].value ? 3 : (cv_abilitydirection[0].value ? 2 : cv_directionchar[0].value); OP_PlaystyleDef.prevMenu = &OP_P1ControlsDef; M_SetupNextMenu(&OP_PlaystyleDef); } @@ -11629,7 +11629,7 @@ static void M_Setup2PPlaystyleMenu(INT32 choice) (void)choice; playstyle_activeplayer = 1; - playstyle_currentchoice = cv_useranalog2.value ? 3 : (cv_abilitydirection[1].value ? 2 : cv_directionchar2.value); + playstyle_currentchoice = cv_useranalog[1].value ? 3 : (cv_abilitydirection[1].value ? 2 : cv_directionchar[1].value); OP_PlaystyleDef.prevMenu = &OP_P2ControlsDef; M_SetupNextMenu(&OP_PlaystyleDef); } @@ -11670,8 +11670,8 @@ static void M_HandlePlaystyleMenu(INT32 choice) else CV_UpdateCamDist(); } - CV_SetValue((playstyle_activeplayer ? &cv_directionchar2 : &cv_directionchar), playstyle_currentchoice ? 1 : 0); - CV_SetValue((playstyle_activeplayer ? &cv_useranalog2 : &cv_useranalog), 0); + CV_SetValue((playstyle_activeplayer ? &cv_directionchar[1] : &cv_directionchar[0]), playstyle_currentchoice ? 1 : 0); + CV_SetValue((playstyle_activeplayer ? &cv_useranalog[1] : &cv_useranalog[0]), 0); M_SetupNextMenu(currentMenu->prevMenu); break; diff --git a/src/m_misc.c b/src/m_misc.c index 83c0c7bec..0fe1b6087 100644 --- a/src/m_misc.c +++ b/src/m_misc.c @@ -600,12 +600,12 @@ void M_SaveConfig(const char *filename) CV_SetValue(&cv_usemouse, tutorialusemouse); CV_SetValue(&cv_alwaysfreelook, tutorialfreelook); CV_SetValue(&cv_mousemove, tutorialmousemove); - CV_SetValue(&cv_analog, tutorialanalog); + CV_SetValue(&cv_analog[0], tutorialanalog); CV_SaveVariables(f); CV_Set(&cv_usemouse, cv_usemouse.defaultvalue); CV_Set(&cv_alwaysfreelook, cv_alwaysfreelook.defaultvalue); CV_Set(&cv_mousemove, cv_mousemove.defaultvalue); - CV_Set(&cv_analog, cv_analog.defaultvalue); + CV_Set(&cv_analog[0], cv_analog[0].defaultvalue); } else CV_SaveVariables(f); diff --git a/src/p_map.c b/src/p_map.c index 2d36f747c..20b0eae05 100644 --- a/src/p_map.c +++ b/src/p_map.c @@ -632,7 +632,7 @@ static void P_DoTailsCarry(player_t *sonic, player_t *tails) && P_MobjFlip(tails->mo)*sonic->mo->momz <= 0) { if (sonic-players == consoleplayer && botingame) - CV_SetValue(&cv_analog2, false); + CV_SetValue(&cv_analog[1], false); P_ResetPlayer(sonic); P_SetTarget(&sonic->mo->tracer, tails->mo); sonic->powers[pw_carry] = CR_PLAYER; @@ -644,7 +644,7 @@ static void P_DoTailsCarry(player_t *sonic, player_t *tails) } else { if (sonic-players == consoleplayer && botingame) - CV_SetValue(&cv_analog2, true); + CV_SetValue(&cv_analog[1], true); P_SetTarget(&sonic->mo->tracer, NULL); sonic->powers[pw_carry] = CR_NONE; } @@ -1621,7 +1621,7 @@ static boolean PIT_CheckThing(mobj_t *thing) } else if (thing->player) { if (thing->player-players == consoleplayer && botingame) - CV_SetValue(&cv_analog2, true); + CV_SetValue(&cv_analog[1], true); if (thing->player->powers[pw_carry] == CR_PLAYER) { P_SetTarget(&thing->tracer, NULL); diff --git a/src/p_setup.c b/src/p_setup.c index e6bf684d7..babe0265e 100644 --- a/src/p_setup.c +++ b/src/p_setup.c @@ -2304,7 +2304,7 @@ static void P_LevelInitStuff(void) } if (botingame) - CV_SetValue(&cv_analog2, true); + CV_SetValue(&cv_analog[1], true); } // @@ -3180,26 +3180,26 @@ boolean P_SetupLevel(boolean skipprecip) if (!cv_cam2_rotate.changed) CV_Set(&cv_cam2_rotate, cv_cam2_rotate.defaultvalue); - if (!cv_analog.changed) - CV_SetValue(&cv_analog, 0); - if (!cv_analog2.changed) - CV_SetValue(&cv_analog2, 0); + if (!cv_analog[0].changed) + CV_SetValue(&cv_analog[0], 0); + if (!cv_analog[1].changed) + CV_SetValue(&cv_analog[1], 0); displayplayer = consoleplayer; // Start with your OWN view, please! } - if (cv_useranalog.value) - CV_SetValue(&cv_analog, true); + if (cv_useranalog[0].value) + CV_SetValue(&cv_analog[0], true); - if (splitscreen && cv_useranalog2.value) - CV_SetValue(&cv_analog2, true); + if (splitscreen && cv_useranalog[1].value) + CV_SetValue(&cv_analog[1], true); else if (botingame) - CV_SetValue(&cv_analog2, true); + CV_SetValue(&cv_analog[1], true); if (twodlevel) { - CV_SetValue(&cv_analog2, false); - CV_SetValue(&cv_analog, false); + CV_SetValue(&cv_analog[1], false); + CV_SetValue(&cv_analog[0], false); } // clear special respawning que diff --git a/src/p_user.c b/src/p_user.c index bf6651a72..215cd88ee 100644 --- a/src/p_user.c +++ b/src/p_user.c @@ -1064,7 +1064,7 @@ void P_ResetPlayer(player_t *player) player->onconveyor = 0; player->skidtime = 0; if (player-players == consoleplayer && botingame) - CV_SetValue(&cv_analog2, true); + CV_SetValue(&cv_analog[1], true); } // P_PlayerCanDamage @@ -4438,7 +4438,7 @@ void P_DoJump(player_t *player, boolean soundandstate) player->powers[pw_carry] = CR_NONE; P_SetTarget(&player->mo->tracer, NULL); if (player-players == consoleplayer && botingame) - CV_SetValue(&cv_analog2, true); + CV_SetValue(&cv_analog[1], true); } else if (player->powers[pw_carry] == CR_GENERIC) { @@ -9823,8 +9823,8 @@ void P_ResetCamera(player_t *player, camera_t *thiscam) thiscam->angle = (thiscam == &camera) ? localangle : localangle2; thiscam->aiming = (thiscam == &camera) ? localaiming : localaiming2; } - else if (!(thiscam == &camera && (cv_cam_still.value || cv_analog.value)) - && !(thiscam == &camera2 && (cv_cam2_still.value || cv_analog2.value))) + else if (!(thiscam == &camera && (cv_cam_still.value || cv_analog[0].value)) + && !(thiscam == &camera2 && (cv_cam2_still.value || cv_analog[1].value))) { thiscam->angle = player->mo->angle; thiscam->aiming = 0; @@ -10029,14 +10029,14 @@ boolean P_MoveChaseCamera(player_t *player, camera_t *thiscam, boolean resetcall else angle = focusangle + FixedAngle(camrotate*FRACUNIT); - if (!resetcalled && (cv_analog.value || demoplayback) && ((thiscam == &camera && t_cam_rotate != -42) || (thiscam == &camera2 + if (!resetcalled && (cv_analog[0].value || demoplayback) && ((thiscam == &camera && t_cam_rotate != -42) || (thiscam == &camera2 && t_cam2_rotate != -42))) { angle = FixedAngle(camrotate*FRACUNIT); thiscam->angle = angle; } - if ((((thiscam == &camera) && cv_analog.value) || ((thiscam != &camera) && cv_analog2.value) || demoplayback) && !sign && !objectplacing && !(twodlevel || (mo->flags2 & MF2_TWOD)) && (player->powers[pw_carry] != CR_NIGHTSMODE) && displayplayer == consoleplayer) + if ((((thiscam == &camera) && cv_analog[0].value) || ((thiscam != &camera) && cv_analog[1].value) || demoplayback) && !sign && !objectplacing && !(twodlevel || (mo->flags2 & MF2_TWOD)) && (player->powers[pw_carry] != CR_NIGHTSMODE) && displayplayer == consoleplayer) { #ifdef REDSANALOG if ((player->cmd.buttons & (BT_CAMLEFT|BT_CAMRIGHT)) == (BT_CAMLEFT|BT_CAMRIGHT)); else @@ -12625,7 +12625,7 @@ void P_PlayerAfterThink(player_t *player) P_SetTarget(&player->mo->tracer, NULL); if (player-players == consoleplayer && botingame) - CV_SetValue(&cv_analog2, (player->powers[pw_carry] != CR_PLAYER)); + CV_SetValue(&cv_analog[1], (player->powers[pw_carry] != CR_PLAYER)); break; } case CR_GENERIC: // being carried by some generic item diff --git a/src/r_main.c b/src/r_main.c index efea00af8..9cb0f3edb 100644 --- a/src/r_main.c +++ b/src/r_main.c @@ -185,20 +185,20 @@ void SplitScreen_OnChange(void) static void ChaseCam_OnChange(void) { - if (!cv_chasecam.value || !cv_useranalog.value) - CV_SetValue(&cv_analog, 0); + if (!cv_chasecam.value || !cv_useranalog[0].value) + CV_SetValue(&cv_analog[0], 0); else - CV_SetValue(&cv_analog, 1); + CV_SetValue(&cv_analog[0], 1); } static void ChaseCam2_OnChange(void) { if (botingame) return; - if (!cv_chasecam2.value || !cv_useranalog2.value) - CV_SetValue(&cv_analog2, 0); + if (!cv_chasecam2.value || !cv_useranalog[1].value) + CV_SetValue(&cv_analog[1], 0); else - CV_SetValue(&cv_analog2, 1); + CV_SetValue(&cv_analog[1], 1); } static void FlipCam_OnChange(void) From 013f1f70d91dff68e496e481357dfa1d9f9b426f Mon Sep 17 00:00:00 2001 From: MascaraSnake Date: Mon, 30 Dec 2019 21:23:00 +0100 Subject: [PATCH 547/746] -Set defaults for vertex and mapthing fields in textmap -Fix P_InitializeSector being called too early (band-aid fix for now, will reorganize this properly later) --- src/p_setup.c | 28 ++++++++++++++++++++-------- 1 file changed, 20 insertions(+), 8 deletions(-) diff --git a/src/p_setup.c b/src/p_setup.c index e4b73570f..a48cfe909 100644 --- a/src/p_setup.c +++ b/src/p_setup.c @@ -865,11 +865,6 @@ static void P_InitializeSector(sector_t *ss) ss->lightingdata = NULL; ss->fadecolormapdata = NULL; - ss->floor_xoffs = ss->floor_yoffs = 0; - ss->ceiling_xoffs = ss->ceiling_yoffs = 0; - - ss->floorpic_angle = ss->ceilingpic_angle = 0; - ss->heightsec = -1; ss->camsec = -1; @@ -945,6 +940,11 @@ static void P_LoadSectors(UINT8 *data) ss->special = SHORT(ms->special); ss->tag = SHORT(ms->tag); + ss->floor_xoffs = ss->floor_yoffs = 0; + ss->ceiling_xoffs = ss->ceiling_yoffs = 0; + + ss->floorpic_angle = ss->ceilingpic_angle = 0; + P_InitializeSector(ss); } } @@ -1235,6 +1235,8 @@ static void P_LoadThings(UINT8 *data) mt->z = mt->options; // NiGHTS Hoops use the full flags bits to set the height. else mt->z = mt->options >> ZSHIFT; + + mt->mobj = NULL; } } @@ -1529,7 +1531,7 @@ static void P_LoadTextmap(void) for (i = 0, vt = vertexes; i < numvertexes; i++, vt++) { // Defaults. - vt->z = 0; + vt->x = vt->y = vt->z = 0; TextmapParse(vertexesPos[i], i, ParseTextmapVertexParameter); } @@ -1548,8 +1550,13 @@ static void P_LoadTextmap(void) sc->special = 0; sc->tag = 0; - P_InitializeSector(sc); + sc->floor_xoffs = sc->floor_yoffs = 0; + sc->ceiling_xoffs = sc->ceiling_yoffs = 0; + + sc->floorpic_angle = sc->ceilingpic_angle = 0; + TextmapParse(sectorsPos[i], i, ParseTextmapSectorParameter); + P_InitializeSector(sc); TextmapFixFlatOffsets(sc); } @@ -1582,8 +1589,13 @@ static void P_LoadTextmap(void) for (i = 0, mt = mapthings; i < nummapthings; i++, mt++) { // Defaults. - mt->z = 0; + mt->x = mt->y = 0; mt->angle = 0; + mt->type = 0; + mt->options = 0; + mt->z = 0; + mt->extrainfo = 0; + mt->mobj = NULL; TextmapParse(mapthingsPos[i], i, ParseTextmapThingParameter); } From d670139404831a32fc57c477223cd286fe2a4cc5 Mon Sep 17 00:00:00 2001 From: James R Date: Mon, 30 Dec 2019 12:30:35 -0800 Subject: [PATCH 548/746] Revert revert revert This reverts commit 6546e3c3bc38415150bd3a2c405a465fe67509a0. This reverts commit 8a15e9abc4b36a9c5af0e0f81c7aeea8096ee666. --- src/lua_consolelib.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/lua_consolelib.c b/src/lua_consolelib.c index 4e397fb32..06a3b3388 100644 --- a/src/lua_consolelib.c +++ b/src/lua_consolelib.c @@ -130,6 +130,7 @@ void COM_Lua_f(void) lua_pop(gL, 1); // pop command info table return; // can't execute splitscreen command without player 2! } + playernum = secondarydisplayplayer; } if (netgame && !( flags & COM_LOCAL ))/* don't send local commands */ @@ -157,7 +158,10 @@ void COM_Lua_f(void) WRITEUINT8(p, argc); for (i = 0; i < argc; i++) WRITESTRINGN(p, COM_Argv(i), 255); - SendNetXCmd(XD_LUACMD, buf, p-buf); + if (flags & COM_SPLITSCREEN) + SendNetXCmd2(XD_LUACMD, buf, p-buf); + else + SendNetXCmd(XD_LUACMD, buf, p-buf); free(buf); return; } From c3d14064e2538e1fc968fcb6a8ba5dc87f7b5118 Mon Sep 17 00:00:00 2001 From: fickleheart Date: Mon, 30 Dec 2019 15:05:24 -0600 Subject: [PATCH 549/746] Convert simple movement to directionchar+analog Analog + no directionchar is old analog (now known as CS_LMAOGALOG because lmao if you still use it). --- src/g_game.c | 61 ++++++++++++++---------------------- src/g_game.h | 11 +++++++ src/p_local.h | 6 +--- src/p_map.c | 6 ++-- src/p_spec.c | 4 +-- src/p_user.c | 84 ++++++++++++++++++++++++++++++-------------------- src/st_stuff.c | 12 +++++++- 7 files changed, 102 insertions(+), 82 deletions(-) diff --git a/src/g_game.c b/src/g_game.c index df5e2afd1..7234add65 100644 --- a/src/g_game.c +++ b/src/g_game.c @@ -1144,7 +1144,8 @@ void G_BuildTiccmd(ticcmd_t *cmd, INT32 realtics, UINT8 ssplayer) INT32 *myaiming = (ssplayer == 1 ? &localaiming : &localaiming2); angle_t drawangleoffset = (player->powers[pw_carry] == CR_ROLLOUT) ? ANGLE_180 : 0; - INT32 chasecam, chasefreelook, alwaysfreelook, usejoystick, analog, invertmouse, mousemove, abilitydirection; + INT32 chasecam, chasefreelook, alwaysfreelook, usejoystick, invertmouse, mousemove; + controlstyle_e controlstyle = G_ControlStyle(ssplayer); INT32 *mx; INT32 *my; INT32 *mly; static INT32 turnheld[2]; // for accelerative turning @@ -1165,7 +1166,6 @@ void G_BuildTiccmd(ticcmd_t *cmd, INT32 realtics, UINT8 ssplayer) chasefreelook = cv_chasefreelook.value; alwaysfreelook = cv_alwaysfreelook.value; usejoystick = cv_usejoystick.value; - analog = cv_analog[0].value; invertmouse = cv_invertmouse.value; mousemove = cv_mousemove.value; mx = &mousex; @@ -1179,7 +1179,6 @@ void G_BuildTiccmd(ticcmd_t *cmd, INT32 realtics, UINT8 ssplayer) chasefreelook = cv_chasefreelook2.value; alwaysfreelook = cv_alwaysfreelook2.value; usejoystick = cv_usejoystick2.value; - analog = cv_analog[1].value; invertmouse = cv_invertmouse2.value; mousemove = cv_mousemove2.value; mx = &mouse2x; @@ -1187,9 +1186,8 @@ void G_BuildTiccmd(ticcmd_t *cmd, INT32 realtics, UINT8 ssplayer) mly = &mlook2y; G_CopyTiccmd(cmd, I_BaseTiccmd2(), 1); // empty, or external driver } - abilitydirection = cv_abilitydirection[player->bot ? 0 : forplayer].value; - strafeisturn = abilitydirection && ticcmd_centerviewdown[forplayer] && + strafeisturn = controlstyle == CS_SIMPLE && ticcmd_centerviewdown[forplayer] && ((cv_cam_lockedinput[forplayer].value && !ticcmd_ztargetfocus[forplayer]) || (player->pflags & PF_STARTDASH)) && !player->climbing && player->powers[pw_carry] != CR_MINECART; @@ -1259,7 +1257,7 @@ void G_BuildTiccmd(ticcmd_t *cmd, INT32 realtics, UINT8 ssplayer) tspeed = speed; // let movement keys cancel each other out - if (analog) // Analog + if (controlstyle == CS_LMAOGALOG) // Analog { if (turnright) cmd->angleturn = (INT16)(cmd->angleturn - angleturn[tspeed]); @@ -1288,7 +1286,7 @@ void G_BuildTiccmd(ticcmd_t *cmd, INT32 realtics, UINT8 ssplayer) side += ((lookjoystickvector.xaxis * sidemove[1]) >> 10); } } - else if (analog) // Analog + else if (controlstyle == CS_LMAOGALOG) // Analog { if (turnright) cmd->buttons |= BT_CAMRIGHT; @@ -1399,7 +1397,7 @@ void G_BuildTiccmd(ticcmd_t *cmd, INT32 realtics, UINT8 ssplayer) static boolean last_centerviewdown[2], centerviewhold[2]; // detect taps for toggle behavior boolean down = PLAYERINPUTDOWN(ssplayer, gc_centerview); - if (!(abilitydirection && cv_cam_centertoggle[forplayer].value)) + if (!(controlstyle == CS_SIMPLE && cv_cam_centertoggle[forplayer].value)) centerviewdown = down; else { @@ -1416,9 +1414,9 @@ void G_BuildTiccmd(ticcmd_t *cmd, INT32 realtics, UINT8 ssplayer) if (centerviewdown) { - if (abilitydirection && !ticcmd_centerviewdown[forplayer] && !G_RingSlingerGametype()) + if (controlstyle == CS_SIMPLE && !ticcmd_centerviewdown[forplayer] && !G_RingSlingerGametype()) { - CV_SetValue((ssplayer == 1 ? &cv_directionchar[0] : &cv_directionchar[1]), 0); + CV_SetValue(&cv_directionchar[forplayer], 0); ///@TODO will break things *myangle = player->mo->angle; *myaiming = 0; @@ -1430,10 +1428,10 @@ void G_BuildTiccmd(ticcmd_t *cmd, INT32 realtics, UINT8 ssplayer) } else if (ticcmd_centerviewdown[forplayer]) { - if (abilitydirection) + if (controlstyle == CS_SIMPLE) { P_SetTarget(&ticcmd_ztargetfocus[forplayer], NULL); - CV_SetValue((ssplayer == 1 ? &cv_directionchar[0] : &cv_directionchar[1]), 1); + CV_SetValue(&cv_directionchar[forplayer], 1); } ticcmd_centerviewdown[forplayer] = false; @@ -1562,7 +1560,7 @@ void G_BuildTiccmd(ticcmd_t *cmd, INT32 realtics, UINT8 ssplayer) if ((!demoplayback && (player->pflags & PF_SLIDING))) // Analog for mouse side += *mx*2; - else if (analog) + else if (controlstyle == CS_LMAOGALOG) { if (*mx) { @@ -1622,7 +1620,7 @@ void G_BuildTiccmd(ticcmd_t *cmd, INT32 realtics, UINT8 ssplayer) } } - if (analog) { + if (controlstyle == CS_LMAOGALOG) { if (player->awayviewtics) cmd->angleturn = (INT16)(player->awayviewmobj->angle >> 16); else @@ -1634,7 +1632,7 @@ void G_BuildTiccmd(ticcmd_t *cmd, INT32 realtics, UINT8 ssplayer) cmd->angleturn = (INT16)(*myangle >> 16); // Adjust camera angle by player input - if (abilitydirection && !forcestrafe && camera.chase && !turnheld[forplayer] && !ticcmd_centerviewdown[forplayer] && !player->climbing && player->powers[pw_carry] != CR_MINECART) + if (controlstyle == CS_SIMPLE && !forcestrafe && camera.chase && !turnheld[forplayer] && !ticcmd_centerviewdown[forplayer] && !player->climbing && player->powers[pw_carry] != CR_MINECART) { fixed_t camadjustfactor = cv_cam_turnfacinginput[forplayer].value; @@ -1654,30 +1652,9 @@ void G_BuildTiccmd(ticcmd_t *cmd, INT32 realtics, UINT8 ssplayer) cmd->sidemove = 0; } - if (abilitydirection && camera.chase && !ticcmd_centerviewdown[forplayer] && !player->climbing && !forcestrafe && (player->pflags & PF_DIRECTIONCHAR) && player->powers[pw_carry] != CR_MINECART) - { - ///@TODO This block of code is a hack to get the desired abilitydirection and player angle behaviors while remaining netplay-compatible with EXEs without those features. - // This has side effects like making F12 spectate look kind of weird, and making the input viewer inaccurate. - // In a perfect world, this will be removed and player behavior would use facing direction in a way that mimics this. - // But that's a lot more work and I want to A) have this out quickly B) be netplay-compatible. - - if (cmd->forwardmove || cmd->sidemove) - { - angle_t controlangle = R_PointToAngle2(0, 0, cmd->forwardmove << FRACBITS, -cmd->sidemove << FRACBITS); - cmd->angleturn += (controlangle>>16); - - cmd->forwardmove = R_PointToDist2(0, 0, cmd->forwardmove, cmd->sidemove); - if (cmd->forwardmove > MAXPLMOVE) - cmd->forwardmove = MAXPLMOVE; - cmd->sidemove = 0; - } - else - cmd->angleturn = (player->drawangle+drawangleoffset)>>16; - } - // Adjust camera angle to face player direction, depending on circumstances // Nothing happens if cam left/right are held, so you can hold both to lock the camera in one direction - if (abilitydirection && !forcestrafe && camera.chase && !turnheld[forplayer] && !ticcmd_centerviewdown[forplayer] && player->powers[pw_carry] != CR_MINECART) + if (controlstyle == CS_SIMPLE && !forcestrafe && camera.chase && !turnheld[forplayer] && !ticcmd_centerviewdown[forplayer] && player->powers[pw_carry] != CR_MINECART) { fixed_t camadjustfactor; boolean alt = false; // Reduce intensity on diagonals and prevent backwards movement from turning the camera @@ -1703,7 +1680,15 @@ void G_BuildTiccmd(ticcmd_t *cmd, INT32 realtics, UINT8 ssplayer) if (camadjustfactor) { - INT32 anglediff = ((player->pflags & PF_SPINNING) ? player->drawangle + drawangleoffset : (cmd->angleturn<<16)) - *myangle; + angle_t controlangle; + INT32 anglediff; + + if ((cmd->forwardmove || cmd->sidemove) && !(player->pflags & PF_SPINNING)) + controlangle = (cmd->angleturn<<16) + R_PointToAngle2(0, 0, cmd->forwardmove << FRACBITS, -cmd->sidemove << FRACBITS); + else + controlangle = player->drawangle + drawangleoffset; + + anglediff = controlangle - *myangle; if (alt) { diff --git a/src/g_game.h b/src/g_game.h index b2a237d7e..1aac2ddb9 100644 --- a/src/g_game.h +++ b/src/g_game.h @@ -68,8 +68,19 @@ extern consvar_t cv_chatwidth, cv_chatnotifications, cv_chatheight, cv_chattime, extern consvar_t cv_crosshair, cv_crosshair2; extern consvar_t cv_invertmouse, cv_alwaysfreelook, cv_chasefreelook, cv_mousemove; extern consvar_t cv_invertmouse2, cv_alwaysfreelook2, cv_chasefreelook2, cv_mousemove2; + extern consvar_t cv_useranalog[2], cv_analog[2]; extern consvar_t cv_directionchar[2]; + +typedef enum { + CS_LEGACY, + CS_LMAOGALOG, + CS_STANDARD, + CS_SIMPLE = CS_LMAOGALOG|CS_STANDARD, +} controlstyle_e; +#define G_ControlStyle(ssplayer) ((cv_analog[(ssplayer)-1].value ? CS_LMAOGALOG : 0) | (cv_directionchar[(ssplayer)-1].value ? CS_STANDARD : 0)) +#define P_ControlStyle(player) ((((player)->pflags & PF_ANALOGMODE) ? CS_LMAOGALOG : 0) | (((player)->pflags & PF_DIRECTIONCHAR) ? CS_STANDARD : 0)) + extern consvar_t cv_autobrake, cv_autobrake2; extern consvar_t cv_sideaxis,cv_turnaxis,cv_moveaxis,cv_lookaxis,cv_jumpaxis,cv_spinaxis,cv_fireaxis,cv_firenaxis,cv_deadzone,cv_digitaldeadzone; extern consvar_t cv_sideaxis2,cv_turnaxis2,cv_moveaxis2,cv_lookaxis2,cv_jumpaxis2,cv_spinaxis2,cv_fireaxis2,cv_firenaxis2,cv_deadzone2,cv_digitaldeadzone2; diff --git a/src/p_local.h b/src/p_local.h index 687af23e5..a5f3d313c 100644 --- a/src/p_local.h +++ b/src/p_local.h @@ -192,11 +192,7 @@ void P_NukeEnemies(mobj_t *inflictor, mobj_t *source, fixed_t radius); boolean P_HomingAttack(mobj_t *source, mobj_t *enemy); /// \todo doesn't belong in p_user boolean P_SuperReady(player_t *player); void P_DoJump(player_t *player, boolean soundandstate); -#if 0 -boolean P_AnalogMove(player_t *player); -#else -#define P_AnalogMove(player) (player->pflags & PF_ANALOGMODE) -#endif +#define P_AnalogMove(player) (P_ControlStyle(player) == CS_LMAOGALOG) boolean P_TransferToNextMare(player_t *player); UINT8 P_FindLowestMare(void); void P_FindEmerald(void); diff --git a/src/p_map.c b/src/p_map.c index 20b0eae05..b6519ffca 100644 --- a/src/p_map.c +++ b/src/p_map.c @@ -377,7 +377,7 @@ boolean P_DoSpring(mobj_t *spring, mobj_t *object) { object->angle = object->player->drawangle = spring->angle; - if (!demoplayback || P_AnalogMove(object->player)) + if (!demoplayback || P_ControlStyle(object->player) == CS_LMAOGALOG) { if (object->player == &players[consoleplayer]) localangle = spring->angle; @@ -1322,7 +1322,7 @@ static boolean PIT_CheckThing(mobj_t *thing) thing->angle = tmthing->angle; - if (!demoplayback || P_AnalogMove(thing->player)) + if (!demoplayback || P_ControlStyle(thing->player) == CS_LMAOGALOG) { if (thing->player == &players[consoleplayer]) localangle = thing->angle; @@ -3491,7 +3491,7 @@ isblocking: && canclimb) { slidemo->angle = climbangle; - /*if (!demoplayback || P_AnalogMove(slidemo->player)) + /*if (!demoplayback || P_ControlStyle(slidemo->player) == CS_LMAOGALOG) { if (slidemo->player == &players[consoleplayer]) localangle = slidemo->angle; diff --git a/src/p_spec.c b/src/p_spec.c index d7a2133c8..d0890f3c9 100644 --- a/src/p_spec.c +++ b/src/p_spec.c @@ -4619,7 +4619,7 @@ DoneSection2: player->mo->angle = player->drawangle = lineangle; - if (!demoplayback || P_AnalogMove(player)) + if (!demoplayback || P_ControlStyle(player) == CS_LMAOGALOG) { if (player == &players[consoleplayer]) localangle = player->mo->angle; @@ -9176,7 +9176,7 @@ void T_Pusher(pusher_t *p) thing->player->pflags |= PF_SLIDING; thing->angle = R_PointToAngle2 (0, 0, xspeed<<(FRACBITS-PUSH_FACTOR), yspeed<<(FRACBITS-PUSH_FACTOR)); - if (!demoplayback || P_AnalogMove(thing->player)) + if (!demoplayback || P_ControlStyle(thing->player) == CS_LMAOGALOG) { if (thing->player == &players[consoleplayer]) { diff --git a/src/p_user.c b/src/p_user.c index 215cd88ee..3a6425478 100644 --- a/src/p_user.c +++ b/src/p_user.c @@ -3579,7 +3579,7 @@ static void P_DoClimbing(player_t *player) } #define CLIMBCONEMAX FixedAngle(90*FRACUNIT) - if (!demoplayback || P_AnalogMove(player)) + if (!demoplayback || P_ControlStyle(player) == CS_LMAOGALOG) { if (player == &players[consoleplayer]) { @@ -4394,7 +4394,7 @@ void P_DoJump(player_t *player, boolean soundandstate) player->drawangle = player->mo->angle = player->mo->angle - ANGLE_180; // Turn around from the wall you were climbing. - if (!demoplayback || P_AnalogMove(player)) + if (!demoplayback || P_ControlStyle(player) == CS_LMAOGALOG) { if (player == &players[consoleplayer]) localangle = player->mo->angle; // Adjust the local control angle. @@ -4719,7 +4719,7 @@ static void P_DoSpinAbility(player_t *player, ticcmd_t *cmd) { player->mo->angle = R_PointToAngle2(player->mo->x, player->mo->y, lockon->x, lockon->y); bullet = P_SpawnPointMissile(player->mo, lockon->x, lockon->y, zpos(lockon), player->revitem, player->mo->x, player->mo->y, zpos(player->mo)); - if (!demoplayback || P_AnalogMove(player)) + if (!demoplayback || P_ControlStyle(player) == CS_LMAOGALOG) { if (player == &players[consoleplayer]) localangle = player->mo->angle; @@ -5616,13 +5616,6 @@ static void P_DoJumpStuff(player_t *player, ticcmd_t *cmd) } } -#if 0 -boolean P_AnalogMove(player_t *player) -{ - return player->pflags & PF_ANALOGMODE; -} -#endif - // // P_GetPlayerControlDirection // @@ -5661,7 +5654,7 @@ INT32 P_GetPlayerControlDirection(player_t *player) origtempangle = tempangle = 0; // relative to the axis rather than the player! controlplayerdirection = R_PointToAngle2(0, 0, player->mo->momx, player->mo->momy); } - else if (P_AnalogMove(player) && thiscam->chase) + else if ((P_ControlStyle(player) & CS_LMAOGALOG) && thiscam->chase) { if (player->awayviewtics) origtempangle = tempangle = player->awayviewmobj->angle; @@ -5887,7 +5880,7 @@ static void P_3dMovement(player_t *player) INT32 mforward = 0, mbackward = 0; angle_t dangle; // replaces old quadrants bits fixed_t normalspd = FixedMul(player->normalspeed, player->mo->scale); - boolean analogmove = false; + controlstyle_e controlstyle; boolean spin = ((onground = P_IsObjectOnGround(player->mo)) && (player->pflags & (PF_SPINNING|PF_THOKKED)) == PF_SPINNING && (player->rmomx || player->rmomy) && !(player->pflags & PF_STARTDASH)); fixed_t oldMagnitude, newMagnitude; #ifdef ESLOPE @@ -5900,7 +5893,7 @@ static void P_3dMovement(player_t *player) // Get the old momentum; this will be needed at the end of the function! -SH oldMagnitude = R_PointToDist2(player->mo->momx - player->cmomx, player->mo->momy - player->cmomy, 0, 0); - analogmove = P_AnalogMove(player); + controlstyle = P_ControlStyle(player); cmd = &player->cmd; @@ -5927,7 +5920,7 @@ static void P_3dMovement(player_t *player) } } - if (analogmove) + if (controlstyle & CS_LMAOGALOG) { movepushangle = (cmd->angleturn<<16 /* not FRACBITS */); } @@ -6073,7 +6066,7 @@ static void P_3dMovement(player_t *player) P_SetObjectMomZ(player->mo, FixedDiv(cmd->forwardmove*FRACUNIT, 15*FRACUNIT>>1), false); } } - else if (!analogmove + else if (!(controlstyle == CS_LMAOGALOG) && cmd->forwardmove != 0 && !(player->pflags & PF_GLIDING || player->exiting || (P_PlayerInPain(player) && !onground))) { @@ -6112,7 +6105,7 @@ static void P_3dMovement(player_t *player) P_InstaThrust(player->mo, player->mo->angle-ANGLE_90, FixedDiv(cmd->sidemove*player->mo->scale, 15*FRACUNIT>>1)); } // Analog movement control - else if (analogmove) + else if (controlstyle == CS_LMAOGALOG) { if (!(player->pflags & PF_GLIDING || player->exiting || P_PlayerInPain(player))) { @@ -8132,8 +8125,33 @@ static void P_MovePlayer(player_t *player) P_2dMovement(player); else { - if (!player->climbing && (!P_AnalogMove(player))) - player->mo->angle = (cmd->angleturn<<16 /* not FRACBITS */); + if (!player->climbing) + { + switch (P_ControlStyle(player)) + { + case CS_LEGACY: + case CS_STANDARD: + player->mo->angle = (cmd->angleturn<<16 /* not FRACBITS */); + break; + + case CS_LMAOGALOG: + break; // handled elsewhere + + case CS_SIMPLE: + if (cmd->forwardmove || cmd->sidemove) + { + angle_t controlangle = R_PointToAngle2(0, 0, cmd->forwardmove << FRACBITS, -cmd->sidemove << FRACBITS); + player->mo->angle = (cmd->angleturn<<16 /* not FRACBITS */) + controlangle; + } + else + { + angle_t drawangleoffset = (player->powers[pw_carry] == CR_ROLLOUT) ? ANGLE_180 : 0; + player->mo->angle = player->drawangle + drawangleoffset; + } + + break; + } + } ticruned++; if ((cmd->angleturn & TICCMD_RECEIVED) == 0) @@ -8259,7 +8277,7 @@ static void P_MovePlayer(player_t *player) if (player->pflags & PF_GLIDING) { mobj_t *mo = player->mo; // seriously why isn't this at the top of the function hngngngng - fixed_t leeway = !P_AnalogMove(player) ? FixedAngle(cmd->sidemove*(FRACUNIT)) : 0; + fixed_t leeway = (P_ControlStyle(player) != CS_LMAOGALOG) ? FixedAngle(cmd->sidemove*(FRACUNIT)) : 0; fixed_t glidespeed = player->actionspd; fixed_t momx = mo->momx - player->cmomx, momy = mo->momy - player->cmomy; angle_t angle, moveangle = R_PointToAngle2(0, 0, momx, momy); @@ -8531,7 +8549,7 @@ static void P_MovePlayer(player_t *player) ////////////////// // This really looks like it should be moved to P_3dMovement. -Red - if (P_AnalogMove(player) + if (P_ControlStyle(player) == CS_LMAOGALOG && (cmd->forwardmove != 0 || cmd->sidemove != 0) && !player->climbing && !twodlevel && !(player->mo->flags2 & MF2_TWOD)) { // If travelling slow enough, face the way the controls @@ -9376,7 +9394,7 @@ boolean P_HomingAttack(mobj_t *source, mobj_t *enemy) // Home in on your target if (source->player) { source->player->drawangle = source->angle; - if (!demoplayback || P_AnalogMove(source->player)) + if (!demoplayback || P_ControlStyle(source->player) == CS_LMAOGALOG) { if (source->player == &players[consoleplayer]) localangle = source->angle; @@ -9982,7 +10000,7 @@ boolean P_MoveChaseCamera(player_t *player, camera_t *thiscam, boolean resetcall camheight = FixedMul(camheight, player->camerascale); #ifdef REDSANALOG - if (P_AnalogMove(player) && (player->cmd.buttons & (BT_CAMLEFT|BT_CAMRIGHT)) == (BT_CAMLEFT|BT_CAMRIGHT)) { + if (P_ControlStyle(player) == CS_LMAOGALOG && (player->cmd.buttons & (BT_CAMLEFT|BT_CAMRIGHT)) == (BT_CAMLEFT|BT_CAMRIGHT)) { camstill = true; if (camspeed < 4*FRACUNIT/5) @@ -10012,7 +10030,7 @@ boolean P_MoveChaseCamera(player_t *player, camera_t *thiscam, boolean resetcall angle = R_PointToAngle2(mo->x, mo->y, mo->target->x, mo->target->y); } } - else if (P_AnalogMove(player) && !sign) // Analog + else if (P_ControlStyle(player) == CS_LMAOGALOG && !sign) // Analog angle = R_PointToAngle2(thiscam->x, thiscam->y, mo->x, mo->y); else if (demoplayback) { @@ -10102,7 +10120,7 @@ boolean P_MoveChaseCamera(player_t *player, camera_t *thiscam, boolean resetcall camheight = mo->scale << 7; camspeed = FRACUNIT/12; } - else if (P_AnalogMove(player)) // x1.2 dist for analog + else if (P_ControlStyle(player) == CS_LMAOGALOG) // x1.2 dist for analog { dist = FixedMul(dist, 6*FRACUNIT/5); camheight = FixedMul(camheight, 6*FRACUNIT/5); @@ -10995,7 +11013,7 @@ static void P_MinecartThink(player_t *player) else if (angdiff > ANGLE_180 && angdiff < InvAngle(MINECARTCONEMAX)) player->mo->angle = minecart->angle - MINECARTCONEMAX; - if (angdiff + minecart->angle != player->mo->angle && (!demoplayback || P_AnalogMove(player))) + if (angdiff + minecart->angle != player->mo->angle && (!demoplayback || P_ControlStyle(player) == CS_LMAOGALOG)) { if (player == &players[consoleplayer]) localangle = player->mo->angle; @@ -11074,7 +11092,7 @@ static void P_MinecartThink(player_t *player) else minecart->angle = targetangle + ANGLE_180; angdiff = (minecart->angle - prevangle); - if (angdiff && (!demoplayback || P_AnalogMove(player))) // maintain relative angle on turns + if (angdiff && (!demoplayback || P_ControlStyle(player) == CS_LMAOGALOG)) // maintain relative angle on turns { player->mo->angle += angdiff; if (player == &players[consoleplayer]) @@ -11840,7 +11858,7 @@ void P_PlayerThink(player_t *player) player->mo->reactiontime--; else if (player->powers[pw_carry] == CR_MINECART) { - if (!P_AnalogMove(player)) + if (P_ControlStyle(player) != CS_LMAOGALOG) player->mo->angle = (cmd->angleturn << 16 /* not FRACBITS */); ticruned++; @@ -11853,7 +11871,7 @@ void P_PlayerThink(player_t *player) { if (player->powers[pw_carry] == CR_ROPEHANG) { - if (!P_AnalogMove(player)) + if (P_ControlStyle(player) != CS_LMAOGALOG) player->mo->angle = (cmd->angleturn<<16 /* not FRACBITS */); ticruned++; @@ -11901,7 +11919,7 @@ void P_PlayerThink(player_t *player) ; else if (!(player->pflags & PF_DIRECTIONCHAR) || (player->climbing) // stuff where the direction is forced at all times - || (P_AnalogMove(player) || twodlevel || player->mo->flags2 & MF2_TWOD) // keep things synchronised up there, since the camera IS seperate from player motion when that happens + || (twodlevel || player->mo->flags2 & MF2_TWOD) // keep things synchronised up there, since the camera IS seperate from player motion when that happens || G_RingSlingerGametype()) // no firing rings in directions your player isn't aiming player->drawangle = player->mo->angle; else if (P_PlayerInPain(player)) @@ -11932,7 +11950,7 @@ void P_PlayerThink(player_t *player) case CR_ROLLOUT: if (cmd->forwardmove || cmd->sidemove) // only when you're pressing movement keys { // inverse direction! - diff = ((player->mo->angle + R_PointToAngle2(0, 0, -cmd->forwardmove<sidemove<drawangle); + diff = (((player->cmd.angleturn<<16) + R_PointToAngle2(0, 0, -cmd->forwardmove<sidemove<drawangle); factor = 4; } break; @@ -11989,7 +12007,7 @@ void P_PlayerThink(player_t *player) } else if (cmd->forwardmove || cmd->sidemove) // only when you're pressing movement keys { - diff = ((player->mo->angle + R_PointToAngle2(0, 0, cmd->forwardmove<sidemove<drawangle); + diff = ((player->mo->angle + ((player->pflags & PF_ANALOGMODE) ? 0 : R_PointToAngle2(0, 0, cmd->forwardmove<sidemove<drawangle); factor = 4; } else if (player->rmomx || player->rmomy) @@ -12602,7 +12620,7 @@ void P_PlayerAfterThink(player_t *player) { player->mo->angle = tails->angle; - if (!demoplayback || P_AnalogMove(player)) + if (!demoplayback || P_ControlStyle(player) == CS_LMAOGALOG) { if (player == &players[consoleplayer]) localangle = player->mo->angle; @@ -12691,7 +12709,7 @@ void P_PlayerAfterThink(player_t *player) macecenter->angle += cmd->sidemove<mo->angle += cmd->sidemove< ANGLE_MAX - if (!demoplayback || P_AnalogMove(player)) + if (!demoplayback || P_ControlStyle(player) == CS_LMAOGALOG) { if (player == &players[consoleplayer]) localangle = player->mo->angle; // Adjust the local control angle. diff --git a/src/st_stuff.c b/src/st_stuff.c index 1b8107edb..03b32285d 100644 --- a/src/st_stuff.c +++ b/src/st_stuff.c @@ -1157,10 +1157,20 @@ static void ST_drawInput(void) "AUTOBRAKE"); y -= 8; } - if (stplyr->pflags & PF_ANALOGMODE) + switch (P_ControlStyle(stplyr)) { + case CS_LMAOGALOG: V_DrawThinString(x, y, hudinfo[HUD_LIVES].f, "ANALOG"); y -= 8; + break; + + case CS_SIMPLE: + V_DrawThinString(x, y, hudinfo[HUD_LIVES].f, "SIMPLE"); + y -= 8; + break; + + default: + break; } } if (!demosynced) // should always be last, so it doesn't push anything else around From a51f2500e09db67e27319fef11515e83339f8f80 Mon Sep 17 00:00:00 2001 From: fickleheart Date: Mon, 30 Dec 2019 15:15:37 -0600 Subject: [PATCH 550/746] Update playstyle menu handling to use analog/directionchar combo --- src/d_netcmd.c | 2 -- src/g_game.c | 4 ---- src/g_game.h | 2 +- src/hu_stuff.c | 4 ++-- src/m_menu.c | 27 ++++++++++----------------- src/p_user.c | 14 +++++++------- 6 files changed, 20 insertions(+), 33 deletions(-) diff --git a/src/d_netcmd.c b/src/d_netcmd.c index df6d70446..12a62a6b8 100644 --- a/src/d_netcmd.c +++ b/src/d_netcmd.c @@ -828,8 +828,6 @@ void D_RegisterClientCommands(void) CV_RegisterVar(&cv_autobrake2); // hi here's some new controls - CV_RegisterVar(&cv_abilitydirection[0]); - CV_RegisterVar(&cv_abilitydirection[1]); CV_RegisterVar(&cv_cam_shiftfacing[0]); CV_RegisterVar(&cv_cam_shiftfacing[1]); CV_RegisterVar(&cv_cam_turnfacing[0]); diff --git a/src/g_game.c b/src/g_game.c index 7234add65..ce661cc97 100644 --- a/src/g_game.c +++ b/src/g_game.c @@ -407,10 +407,6 @@ consvar_t cv_autobrake = {"autobrake", "On", CV_SAVE|CV_CALL, CV_OnOff, AutoBrak consvar_t cv_autobrake2 = {"autobrake2", "On", CV_SAVE|CV_CALL, CV_OnOff, AutoBrake2_OnChange, 0, NULL, NULL, 0, 0, NULL}; // hi here's some new controls -consvar_t cv_abilitydirection[2] = { - {"abilitydirection", "Movement", CV_SAVE, directionchar_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL}, - {"abilitydirection2", "Movement", CV_SAVE, directionchar_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL}, -}; static CV_PossibleValue_t zerotoone_cons_t[] = {{0, "MIN"}, {FRACUNIT, "MAX"}, {0, NULL}}; consvar_t cv_cam_shiftfacing[2] = { {"cam_shiftfacingchar", "0.33", CV_FLOAT|CV_SAVE, zerotoone_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL}, diff --git a/src/g_game.h b/src/g_game.h index 1aac2ddb9..27cb8bc00 100644 --- a/src/g_game.h +++ b/src/g_game.h @@ -87,7 +87,7 @@ extern consvar_t cv_sideaxis2,cv_turnaxis2,cv_moveaxis2,cv_lookaxis2,cv_jumpaxis extern consvar_t cv_ghost_bestscore, cv_ghost_besttime, cv_ghost_bestrings, cv_ghost_last, cv_ghost_guest; // hi here's some new controls -extern consvar_t cv_abilitydirection[2], cv_cam_shiftfacing[2], cv_cam_turnfacing[2], +extern consvar_t cv_cam_shiftfacing[2], cv_cam_turnfacing[2], cv_cam_turnfacingability[2], cv_cam_turnfacingspindash[2], cv_cam_turnfacinginput[2], cv_cam_centertoggle[2], cv_cam_lockedinput[2], cv_cam_lockonboss[2]; diff --git a/src/hu_stuff.c b/src/hu_stuff.c index c1818bd4b..ccfeed4f1 100644 --- a/src/hu_stuff.c +++ b/src/hu_stuff.c @@ -2195,12 +2195,12 @@ void HU_Drawer(void) // draw the crosshair, not when viewing demos nor with chasecam if (!automapactive && cv_crosshair.value && !demoplayback && - (!camera.chase || (cv_abilitydirection[0].value && ticcmd_centerviewdown[0] && ticcmd_ztargetfocus[0])) + (!camera.chase || ticcmd_ztargetfocus[0]) && !players[displayplayer].spectator) HU_DrawCrosshair(); if (!automapactive && cv_crosshair2.value && !demoplayback && - (!camera2.chase || (cv_abilitydirection[1].value && ticcmd_centerviewdown[1] && ticcmd_ztargetfocus[1])) + (!camera2.chase || ticcmd_ztargetfocus[1]) && !players[secondarydisplayplayer].spectator) HU_DrawCrosshair2(); diff --git a/src/m_menu.c b/src/m_menu.c index c5691a7c3..ead0fe544 100644 --- a/src/m_menu.c +++ b/src/m_menu.c @@ -1038,10 +1038,8 @@ static menuitem_t OP_P1ControlsMenu[] = {IT_SUBMENU | IT_STRING, NULL, "Camera Options...", &OP_CameraOptionsDef, 50}, - //{IT_STRING | IT_CVAR, NULL, "Character angle", &cv_directionchar[0], 70}, {IT_STRING | IT_CVAR, NULL, "Automatic braking", &cv_autobrake, 70}, {IT_CALL | IT_STRING, NULL, "Play Style...", M_Setup1PPlaystyleMenu, 80}, - //{IT_STRING | IT_CVAR, NULL, "Ability angle", &cv_abilitydirection[0], 90}, }; static menuitem_t OP_P2ControlsMenu[] = @@ -1052,10 +1050,8 @@ static menuitem_t OP_P2ControlsMenu[] = {IT_SUBMENU | IT_STRING, NULL, "Camera Options...", &OP_Camera2OptionsDef, 50}, - //{IT_STRING | IT_CVAR, NULL, "Character angle", &cv_directionchar[1], 70}, {IT_STRING | IT_CVAR, NULL, "Automatic braking", &cv_autobrake2, 70}, {IT_CALL | IT_STRING, NULL, "Play Style...", M_Setup2PPlaystyleMenu, 80}, - //{IT_STRING | IT_CVAR, NULL, "Ability angle", &cv_abilitydirection[1], 90}, }; static menuitem_t OP_ChangeControlsMenu[] = @@ -4318,7 +4314,7 @@ static void M_DrawControlsDefMenu(void) if (currentMenu == &OP_P1ControlsDef) { - opt = cv_useranalog[0].value ? 3 : (cv_abilitydirection[0].value ? 2 : cv_directionchar[0].value); + opt = cv_useranalog[0].value ? 3 - cv_directionchar[0].value : cv_directionchar[0].value; if (opt == 2) { @@ -4333,7 +4329,7 @@ static void M_DrawControlsDefMenu(void) } else { - opt = cv_useranalog[1].value ? 3 : (cv_abilitydirection[1].value ? 2 : cv_directionchar[1].value); + opt = cv_useranalog[1].value ? 3 - cv_directionchar[1].value : cv_directionchar[1].value; if (opt == 2) { @@ -11619,7 +11615,7 @@ static void M_Setup1PPlaystyleMenu(INT32 choice) (void)choice; playstyle_activeplayer = 0; - playstyle_currentchoice = cv_useranalog[0].value ? 3 : (cv_abilitydirection[0].value ? 2 : cv_directionchar[0].value); + playstyle_currentchoice = cv_useranalog[0].value ? 3 - cv_directionchar[0].value : cv_directionchar[0].value; OP_PlaystyleDef.prevMenu = &OP_P1ControlsDef; M_SetupNextMenu(&OP_PlaystyleDef); } @@ -11629,7 +11625,7 @@ static void M_Setup2PPlaystyleMenu(INT32 choice) (void)choice; playstyle_activeplayer = 1; - playstyle_currentchoice = cv_useranalog[1].value ? 3 : (cv_abilitydirection[1].value ? 2 : cv_directionchar[1].value); + playstyle_currentchoice = cv_useranalog[1].value ? 3 - cv_directionchar[1].value : cv_directionchar[1].value; OP_PlaystyleDef.prevMenu = &OP_P2ControlsDef; M_SetupNextMenu(&OP_PlaystyleDef); } @@ -11662,16 +11658,13 @@ static void M_HandlePlaystyleMenu(INT32 choice) case KEY_ENTER: S_StartSound(NULL, sfx_menu1); - if (cv_abilitydirection[playstyle_activeplayer].value != (playstyle_currentchoice/2)) - { - CV_SetValue(&cv_abilitydirection[playstyle_activeplayer], playstyle_currentchoice/2); - if (playstyle_activeplayer) - CV_UpdateCam2Dist(); - else - CV_UpdateCamDist(); - } CV_SetValue((playstyle_activeplayer ? &cv_directionchar[1] : &cv_directionchar[0]), playstyle_currentchoice ? 1 : 0); - CV_SetValue((playstyle_activeplayer ? &cv_useranalog[1] : &cv_useranalog[0]), 0); + CV_SetValue((playstyle_activeplayer ? &cv_useranalog[1] : &cv_useranalog[0]), playstyle_currentchoice/2); + + if (playstyle_activeplayer) + CV_UpdateCam2Dist(); + else + CV_UpdateCamDist(); M_SetupNextMenu(currentMenu->prevMenu); break; diff --git a/src/p_user.c b/src/p_user.c index 3a6425478..25448ffb3 100644 --- a/src/p_user.c +++ b/src/p_user.c @@ -9792,14 +9792,14 @@ consvar_t cv_cam_saveheight[2][2] = { void CV_UpdateCamDist(void) { - CV_Set(&cv_cam_dist, va("%f", FIXED_TO_FLOAT(cv_cam_savedist[cv_abilitydirection[0].value][0].value))); - CV_Set(&cv_cam_height, va("%f", FIXED_TO_FLOAT(cv_cam_saveheight[cv_abilitydirection[0].value][0].value))); + CV_Set(&cv_cam_dist, va("%f", FIXED_TO_FLOAT(cv_cam_savedist[cv_useranalog[0].value][0].value))); + CV_Set(&cv_cam_height, va("%f", FIXED_TO_FLOAT(cv_cam_saveheight[cv_useranalog[0].value][0].value))); } void CV_UpdateCam2Dist(void) { - CV_Set(&cv_cam2_dist, va("%f", FIXED_TO_FLOAT(cv_cam_savedist[cv_abilitydirection[1].value][1].value))); - CV_Set(&cv_cam2_height, va("%f", FIXED_TO_FLOAT(cv_cam_saveheight[cv_abilitydirection[1].value][1].value))); + CV_Set(&cv_cam2_dist, va("%f", FIXED_TO_FLOAT(cv_cam_savedist[cv_useranalog[1].value][1].value))); + CV_Set(&cv_cam2_height, va("%f", FIXED_TO_FLOAT(cv_cam_saveheight[cv_useranalog[1].value][1].value))); } fixed_t t_cam_dist = -42; @@ -9835,8 +9835,8 @@ void P_ResetCamera(player_t *player, camera_t *thiscam) thiscam->y = y; thiscam->z = z; - if ((thiscam == &camera && cv_abilitydirection[0].value) - || (thiscam == &camera2 && cv_abilitydirection[1].value)) + if ((thiscam == &camera && G_ControlStyle(1) == CS_SIMPLE) + || (thiscam == &camera2 && G_ControlStyle(2) == CS_SIMPLE)) { thiscam->angle = (thiscam == &camera) ? localangle : localangle2; thiscam->aiming = (thiscam == &camera) ? localaiming : localaiming2; @@ -10075,7 +10075,7 @@ boolean P_MoveChaseCamera(player_t *player, camera_t *thiscam, boolean resetcall } } - if (cv_abilitydirection[(thiscam == &camera) ? 0 : 1].value && !sign) + if (G_ControlStyle((thiscam == &camera) ? 1 : 2) == CS_SIMPLE && !sign) { // Shift the camera slightly to the sides depending on the player facing direction UINT8 forplayer = (thiscam == &camera) ? 0 : 1; From 2c45ecbaa5f21c1940446e4817a783ef41b921f9 Mon Sep 17 00:00:00 2001 From: fickleheart Date: Mon, 30 Dec 2019 15:34:43 -0600 Subject: [PATCH 551/746] Fix camera reset button --- src/d_netcmd.c | 8 ++++---- src/g_game.c | 7 +++++-- src/m_menu.c | 12 ++++++------ 3 files changed, 15 insertions(+), 12 deletions(-) diff --git a/src/d_netcmd.c b/src/d_netcmd.c index 12a62a6b8..c7f1b765d 100644 --- a/src/d_netcmd.c +++ b/src/d_netcmd.c @@ -1508,9 +1508,9 @@ void SendWeaponPref(void) buf[0] = 0; if (cv_flipcam.value) buf[0] |= 1; - if (cv_analog[0].value) + if (cv_analog[0].value && cv_directionchar[0].value != 2) buf[0] |= 2; - if (cv_directionchar[0].value) + if (cv_directionchar[0].value == 1) buf[0] |= 4; if (cv_autobrake.value) buf[0] |= 8; @@ -1524,9 +1524,9 @@ void SendWeaponPref2(void) buf[0] = 0; if (cv_flipcam2.value) buf[0] |= 1; - if (cv_analog[1].value) + if (cv_analog[1].value && cv_directionchar[1].value != 2) buf[0] |= 2; - if (cv_directionchar[1].value) + if (cv_directionchar[1].value == 1) buf[0] |= 4; if (cv_autobrake2.value) buf[0] |= 8; diff --git a/src/g_game.c b/src/g_game.c index ce661cc97..86e0491cf 100644 --- a/src/g_game.c +++ b/src/g_game.c @@ -398,7 +398,7 @@ consvar_t cv_useranalog[2] = { }; // deez New User eXperiences -static CV_PossibleValue_t directionchar_cons_t[] = {{0, "Camera"}, {1, "Movement"}, {0, NULL}}; +static CV_PossibleValue_t directionchar_cons_t[] = {{0, "Camera"}, {1, "Movement"}, {2, "Simple Locked"}, {0, NULL}}; consvar_t cv_directionchar[2] = { {"directionchar", "Movement", CV_SAVE|CV_CALL, directionchar_cons_t, DirectionChar_OnChange, 0, NULL, NULL, 0, 0, NULL}, {"directionchar2", "Movement", CV_SAVE|CV_CALL, directionchar_cons_t, DirectionChar2_OnChange, 0, NULL, NULL, 0, 0, NULL} @@ -1412,7 +1412,7 @@ void G_BuildTiccmd(ticcmd_t *cmd, INT32 realtics, UINT8 ssplayer) { if (controlstyle == CS_SIMPLE && !ticcmd_centerviewdown[forplayer] && !G_RingSlingerGametype()) { - CV_SetValue(&cv_directionchar[forplayer], 0); ///@TODO will break things + CV_SetValue(&cv_directionchar[forplayer], 2); *myangle = player->mo->angle; *myaiming = 0; @@ -1487,6 +1487,9 @@ void G_BuildTiccmd(ticcmd_t *cmd, INT32 realtics, UINT8 ssplayer) } } + if (ticcmd_centerviewdown[forplayer] && controlstyle == CS_SIMPLE) + controlstyle = CS_LEGACY; + if (PLAYERINPUTDOWN(ssplayer, gc_camreset)) { if (camera.chase && !resetdown[forplayer]) diff --git a/src/m_menu.c b/src/m_menu.c index ead0fe544..01baa9963 100644 --- a/src/m_menu.c +++ b/src/m_menu.c @@ -4306,6 +4306,8 @@ const char *PlaystyleDesc[4] = { "instead!" }; +static UINT8 playstyle_activeplayer = 0, playstyle_currentchoice = 0; + static void M_DrawControlsDefMenu(void) { UINT8 opt = 0; @@ -4314,7 +4316,8 @@ static void M_DrawControlsDefMenu(void) if (currentMenu == &OP_P1ControlsDef) { - opt = cv_useranalog[0].value ? 3 - cv_directionchar[0].value : cv_directionchar[0].value; + opt = cv_directionchar[0].value ? 1 : 0; + opt = playstyle_currentchoice = cv_useranalog[0].value ? 3 - opt : opt; if (opt == 2) { @@ -4329,7 +4332,8 @@ static void M_DrawControlsDefMenu(void) } else { - opt = cv_useranalog[1].value ? 3 - cv_directionchar[1].value : cv_directionchar[1].value; + opt = cv_directionchar[1].value ? 1 : 0; + opt = playstyle_currentchoice = cv_useranalog[1].value ? 3 - opt : opt; if (opt == 2) { @@ -11608,14 +11612,11 @@ static void M_ChangeControl(INT32 choice) M_StartMessage(tmp, M_ChangecontrolResponse, MM_EVENTHANDLER); } -static UINT8 playstyle_activeplayer = 0, playstyle_currentchoice = 0; - static void M_Setup1PPlaystyleMenu(INT32 choice) { (void)choice; playstyle_activeplayer = 0; - playstyle_currentchoice = cv_useranalog[0].value ? 3 - cv_directionchar[0].value : cv_directionchar[0].value; OP_PlaystyleDef.prevMenu = &OP_P1ControlsDef; M_SetupNextMenu(&OP_PlaystyleDef); } @@ -11625,7 +11626,6 @@ static void M_Setup2PPlaystyleMenu(INT32 choice) (void)choice; playstyle_activeplayer = 1; - playstyle_currentchoice = cv_useranalog[1].value ? 3 - cv_directionchar[1].value : cv_directionchar[1].value; OP_PlaystyleDef.prevMenu = &OP_P2ControlsDef; M_SetupNextMenu(&OP_PlaystyleDef); } From 85e2e92ee09ed84fea54767681893234ffcbf967 Mon Sep 17 00:00:00 2001 From: fickleheart Date: Mon, 30 Dec 2019 15:44:52 -0600 Subject: [PATCH 552/746] Fix spying on simple mode players having dumb camera angles --- 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 25448ffb3..c88566f4d 100644 --- a/src/p_user.c +++ b/src/p_user.c @@ -9960,7 +9960,7 @@ boolean P_MoveChaseCamera(player_t *player, camera_t *thiscam, boolean resetcall } else { - focusangle = mo->angle; + focusangle = player->cmd.angleturn << 16; focusaiming = player->aiming; } From 5e94ca07bcd8e8ce652601d01ecbbc497dc1f44b Mon Sep 17 00:00:00 2001 From: James R Date: Mon, 30 Dec 2019 17:57:18 -0800 Subject: [PATCH 553/746] 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 ab410652aeeb79b0ff6fc655db938bd406006ad4 Mon Sep 17 00:00:00 2001 From: James R Date: Mon, 30 Dec 2019 18:44:13 -0800 Subject: [PATCH 554/746] Fix unclosed quotes leaving the escape character in --- src/command.c | 29 +++++++++++++++++++++++------ 1 file changed, 23 insertions(+), 6 deletions(-) diff --git a/src/command.c b/src/command.c index 40efa1eee..efa56a825 100644 --- a/src/command.c +++ b/src/command.c @@ -2169,8 +2169,13 @@ skipwhite: com_token[len] = 0; return data; } - com_token[len] = c; - len++; + if (c == '\033') + data += 2; + else + { + com_token[len] = c; + len++; + } } } @@ -2186,10 +2191,22 @@ skipwhite: // parse a regular word do { - com_token[len] = c; - data++; - len++; - c = *data; + if (c == '\033') + { + do + { + data += 2; + c = *data; + } + while (c == '\033') ; + } + else + { + com_token[len] = c; + data++; + len++; + c = *data; + } if (c == '{' || c == '}' || c == ')'|| c == '(' || c == '\'') break; } while (c > 32); From ff47f911dc8e4a53d81328670de557ff264f1b1f Mon Sep 17 00:00:00 2001 From: James R Date: Mon, 30 Dec 2019 18:46:38 -0800 Subject: [PATCH 555/746] Fix command not running if it was split by COM_BufAddText (Looks at 4865a190578b900b48571e74e0bd97bef88ea71b...) --- src/command.c | 19 ++++++++++--------- 1 file changed, 10 insertions(+), 9 deletions(-) diff --git a/src/command.c b/src/command.c index efa56a825..0a6b34fc8 100644 --- a/src/command.c +++ b/src/command.c @@ -427,20 +427,21 @@ static void COM_TokenizeString(char *ptext) com_argc = 0; com_args = NULL; - - if (ptext[0] == '\033') - { - com_flags = (unsigned)ptext[1]; - ptext += 2; - } - else - com_flags = 0; + com_flags = 0; while (com_argc < MAX_ARGS) { // Skip whitespace up to a newline. while (*ptext != '\0' && *ptext <= ' ' && *ptext != '\n') - ptext++; + { + if (ptext[0] == '\033') + { + com_flags = (unsigned)ptext[1]; + ptext += 2; + } + else + ptext++; + } // A newline means end of command in buffer, // thus end of this command's args too. From a36920808b74e068d582dda5a3b75bdf64246463 Mon Sep 17 00:00:00 2001 From: Nami <50415197+namishere@users.noreply.github.com> Date: Mon, 30 Dec 2019 19:04:27 -0800 Subject: [PATCH 556/746] Revert changes to searchBlockmap because on reflection, the benefits didn't outweigh breaking every current usage of it Readd ThinkFrame in its original position PostThinkFrame now runs at the end of P_Ticker, only MapEnd runs after it --- src/dehacked.c | 3 --- src/lua_blockmaplib.c | 40 ++++++++++++++++++++++------------------ src/lua_hook.h | 4 +++- src/lua_hooklib.c | 25 +++++++++++++++++++++++++ src/p_tick.c | 20 +++++++++++++++----- 5 files changed, 65 insertions(+), 27 deletions(-) diff --git a/src/dehacked.c b/src/dehacked.c index 450e33c16..4c90211cc 100644 --- a/src/dehacked.c +++ b/src/dehacked.c @@ -9824,9 +9824,6 @@ struct { {"TC_RAINBOW",TC_RAINBOW}, {"TC_BLINK",TC_BLINK}, {"TC_DASHMODE",TC_DASHMODE}, - - {"OPT_LINES", 1}, - {"OPT_MOBJS", 1<<1}, #endif {NULL,0} diff --git a/src/lua_blockmaplib.c b/src/lua_blockmaplib.c index 2130e9333..7f7dc9560 100644 --- a/src/lua_blockmaplib.c +++ b/src/lua_blockmaplib.c @@ -18,6 +18,11 @@ #include "lua_libs.h" //#include "lua_hud.h" // hud_running errors +static const char *const search_opt[] = { + "objects", + "lines", + NULL}; + // a quickly-made function pointer typedef used by lib_searchBlockmap... // return values: // 0 - normal, no interruptions @@ -174,18 +179,29 @@ static UINT8 lib_searchBlockmap_Lines(lua_State *L, INT32 x, INT32 y, mobj_t *th // false = searching of at least one block stopped mid-way (including if the whole search was stopped) static int lib_searchBlockmap(lua_State *L) { + int searchtype = luaL_checkoption(L, 1, "objects", search_opt); int n; mobj_t *mobj; INT32 xl, xh, yl, yh, bx, by; fixed_t x1, x2, y1, y2; boolean retval = true; - boolean repeat = false; UINT8 funcret = 0; + blockmap_func searchFunc; - UINT32 flags = luaL_checkinteger(L, 1); - lua_remove(L, 1); // remove flags, stack is now function, mobj, [x1, x2, y1, y2] + lua_remove(L, 1); // remove searchtype, stack is now function, mobj, [x1, x2, y1, y2] luaL_checktype(L, 1, LUA_TFUNCTION); + switch (searchtype) + { + case 0: // "objects" + default: + searchFunc = lib_searchBlockmap_Objects; + break; + case 1: // "lines" + searchFunc = lib_searchBlockmap_Lines; + break; + } + // the mobj we are searching around, the "calling" mobj we could say mobj = *((mobj_t **)luaL_checkudata(L, 2, META_MOBJ)); if (!mobj) @@ -224,14 +240,8 @@ static int lib_searchBlockmap(lua_State *L) validcount++; for (bx = xl; bx <= xh; bx++) for (by = yl; by <= yh; by++) - { - if (flags & (OPT_LINES|OPT_MOBJS)) - repeat = true; - if (flags & OPT_LINES) - funcret = lib_searchBlockmap_Lines(L, bx, by, mobj); - else - funcret = lib_searchBlockmap_Objects(L, bx, by, mobj); - doitagain: + { + funcret = searchFunc(L, bx, by, mobj); // return value of searchFunc determines searchFunc's return value and/or when to stop if (funcret == 2){ // stop whole search lua_pushboolean(L, false); // return false @@ -244,12 +254,6 @@ static int lib_searchBlockmap(lua_State *L) lua_pushboolean(L, false); // in which case we have to stop now regardless return 1; } - if (repeat) - { - funcret = lib_searchBlockmap_Objects(L, bx, by, mobj); - repeat = false; - goto doitagain; - } } lua_pushboolean(L, retval); return 1; @@ -261,4 +265,4 @@ int LUA_BlockmapLib(lua_State *L) return 0; } -#endif \ No newline at end of file +#endif diff --git a/src/lua_hook.h b/src/lua_hook.h index 620a7b307..d035be097 100644 --- a/src/lua_hook.h +++ b/src/lua_hook.h @@ -21,6 +21,7 @@ enum hook { hook_MapLoad, hook_PlayerJoin, hook_PreThinkFrame, + hook_ThinkFrame, hook_PostThinkFrame, hook_MobjSpawn, hook_MobjCollide, @@ -63,7 +64,8 @@ void LUAh_MapChange(INT16 mapnumber); // Hook for map change (before load) void LUAh_MapLoad(void); // Hook for map load void LUAh_PlayerJoin(int playernum); // Hook for Got_AddPlayer void LUAh_PreThinkFrame(void); // Hook for frame (before mobj and player thinkers) -void LUAh_PostThinkFrame(void); // Hook for frame (after mobj and player thinkers) +void LUAh_ThinkFrame(void); // Hook for frame (after mobj and player thinkers) +void LUAh_PostThinkFrame(void); // Hook for frame (at end of tick, ie after overlays, precipitation, specials) boolean LUAh_MobjHook(mobj_t *mo, enum hook which); boolean LUAh_PlayerHook(player_t *plr, enum hook which); #define LUAh_MobjSpawn(mo) LUAh_MobjHook(mo, hook_MobjSpawn) // Hook for P_SpawnMobj by mobj type diff --git a/src/lua_hooklib.c b/src/lua_hooklib.c index ace0f14d5..d548f6a65 100644 --- a/src/lua_hooklib.c +++ b/src/lua_hooklib.c @@ -32,6 +32,7 @@ const char *const hookNames[hook_MAX+1] = { "MapLoad", "PlayerJoin", "PreThinkFrame", + "ThinkFrame", "PostThinkFrame", "MobjSpawn", "MobjCollide", @@ -436,6 +437,30 @@ void LUAh_PreThinkFrame(void) } // Hook for frame (after mobj and player thinkers) +void LUAh_ThinkFrame(void) +{ + hook_p hookp; + if (!gL || !(hooksAvailable[hook_ThinkFrame/8] & (1<<(hook_ThinkFrame%8)))) + return; + + for (hookp = roothook; hookp; hookp = hookp->next) + { + if (hookp->type != hook_ThinkFrame) + continue; + + lua_pushfstring(gL, FMT_HOOKID, hookp->id); + lua_gettable(gL, LUA_REGISTRYINDEX); + if (lua_pcall(gL, 0, 0, 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; + } + } +} + + +// Hook for frame (at end of tick, ie after overlays, precipitation, specials) void LUAh_PostThinkFrame(void) { hook_p hookp; diff --git a/src/p_tick.c b/src/p_tick.c index b92465fe4..e266f7013 100644 --- a/src/p_tick.c +++ b/src/p_tick.c @@ -646,9 +646,9 @@ void P_Ticker(boolean run) if (run) { - #ifdef HAVE_BLUA +#ifdef HAVE_BLUA LUAh_PreThinkFrame(); - #endif +#endif P_RunThinkers(); @@ -658,7 +658,7 @@ void P_Ticker(boolean run) P_PlayerAfterThink(&players[i]); #ifdef HAVE_BLUA - LUAh_PostThinkFrame(); + LUAh_ThinkFrame(); #endif } @@ -730,6 +730,10 @@ void P_Ticker(boolean run) G_ConsGhostTic(); if (modeattacking) G_GhostTicker(); + +#ifdef HAVE_BLUA + LUAh_PostThinkFrame(); +#endif } P_MapEnd(); @@ -764,7 +768,9 @@ void P_PreTicker(INT32 frames) memcpy(&players[i].cmd, &temptic, sizeof(ticcmd_t)); } - +#ifdef HAVE_BLUA + LUAh_PreThinkFrame(); +#endif P_RunThinkers(); // Run any "after all the other thinkers" stuff @@ -773,7 +779,7 @@ void P_PreTicker(INT32 frames) P_PlayerAfterThink(&players[i]); #ifdef HAVE_BLUA - LUAh_PostThinkFrame(); + LUAh_ThinkFrame(); #endif // Run shield positioning @@ -783,6 +789,10 @@ void P_PreTicker(INT32 frames) P_UpdateSpecials(); P_RespawnSpecials(); +#ifdef HAVE_BLUA + LUAh_PostThinkFrame(); +#endif + P_MapEnd(); } } From 41c902b819ac8fdef173c4ba76a8c50ad8107190 Mon Sep 17 00:00:00 2001 From: Nami <50415197+namishere@users.noreply.github.com> Date: Mon, 30 Dec 2019 19:11:49 -0800 Subject: [PATCH 557/746] Move PreThinkFrame hook back a bit, now runs before PlayerThink --- src/p_tick.c | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/src/p_tick.c b/src/p_tick.c index e266f7013..13209c3f9 100644 --- a/src/p_tick.c +++ b/src/p_tick.c @@ -629,6 +629,10 @@ void P_Ticker(boolean run) if (demoplayback) G_ReadDemoTiccmd(&players[consoleplayer].cmd, 0); + #ifdef HAVE_BLUA + LUAh_PreThinkFrame(); + #endif + for (i = 0; i < MAXPLAYERS; i++) if (playeringame[i] && players[i].mo && !P_MobjWasRemoved(players[i].mo)) P_PlayerThink(&players[i]); @@ -753,6 +757,9 @@ void P_PreTicker(INT32 frames) { P_MapStart(); +#ifdef HAVE_BLUA + LUAh_PreThinkFrame(); +#endif for (i = 0; i < MAXPLAYERS; i++) if (playeringame[i] && players[i].mo && !P_MobjWasRemoved(players[i].mo)) { @@ -768,9 +775,7 @@ void P_PreTicker(INT32 frames) memcpy(&players[i].cmd, &temptic, sizeof(ticcmd_t)); } -#ifdef HAVE_BLUA - LUAh_PreThinkFrame(); -#endif + P_RunThinkers(); // Run any "after all the other thinkers" stuff From 4bf35971168a5fa2b5759dc0c3d05a3767f30f95 Mon Sep 17 00:00:00 2001 From: James R Date: Mon, 30 Dec 2019 19:19:17 -0800 Subject: [PATCH 558/746] 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 60928db0e0b08fee7ceddd5515adf2246bb655c3 Mon Sep 17 00:00:00 2001 From: Nami <50415197+namishere@users.noreply.github.com> Date: Mon, 30 Dec 2019 19:22:12 -0800 Subject: [PATCH 559/746] I removed a hook I left behind and forgot to save the change before committing :upside_down: --- src/p_tick.c | 4 ---- 1 file changed, 4 deletions(-) diff --git a/src/p_tick.c b/src/p_tick.c index 13209c3f9..9b56ee1c2 100644 --- a/src/p_tick.c +++ b/src/p_tick.c @@ -650,10 +650,6 @@ void P_Ticker(boolean run) if (run) { -#ifdef HAVE_BLUA - LUAh_PreThinkFrame(); -#endif - P_RunThinkers(); // Run any "after all the other thinkers" stuff From 47b096a35748cc0ef20819daabdf561c011c9c25 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 560/746] 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 782bf8d31ed486679011a1c4b57f823e3e53c5d2 Mon Sep 17 00:00:00 2001 From: James R Date: Mon, 30 Dec 2019 20:08:29 -0800 Subject: [PATCH 561/746] Fix NOMIXER compiling --- src/sdl/sdl_sound.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/sdl/sdl_sound.c b/src/sdl/sdl_sound.c index 33b366bf6..b8991293c 100644 --- a/src/sdl/sdl_sound.c +++ b/src/sdl/sdl_sound.c @@ -1432,6 +1432,8 @@ static void I_ResumeGME(void) boolean I_LoadSong(char *data, size_t len) { + (void)data; + (void)len; return false; } @@ -1493,6 +1495,7 @@ boolean I_FadeSongFromVolume(UINT8 target_volume, UINT8 source_volume, UINT32 ms (void)target_volume; (void)source_volume; (void)ms; + (void)callback; return false; } @@ -1500,6 +1503,7 @@ boolean I_FadeSong(UINT8 target_volume, UINT32 ms, void (*callback)(void)) { (void)target_volume; (void)ms; + (void)callback; return false; } From 36c5bb7b0d32cd14c7b6ddc17f64c62c65965eb9 Mon Sep 17 00:00:00 2001 From: James R Date: Mon, 30 Dec 2019 20:18:08 -0800 Subject: [PATCH 562/746] 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 2d0cdbe34f5cdccc1395df84a66085f4b7e6bbe2 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 563/746] 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 e8db39229c0afe967e571340362412853ee4749c Mon Sep 17 00:00:00 2001 From: James R Date: Mon, 30 Dec 2019 20:29:41 -0800 Subject: [PATCH 564/746] 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 b68a629a7118cfeb39caea8c10443933c16dcd7e 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 565/746] 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 38492073fa9a240fe90606c3e79fd42a6a14bff5 Mon Sep 17 00:00:00 2001 From: James R Date: Mon, 30 Dec 2019 21:40:13 -0800 Subject: [PATCH 566/746] IT_PAIR for when you want to define both sides of a menu item --- src/m_menu.c | 21 ++++++++++++++++----- src/m_menu.h | 5 +++-- 2 files changed, 19 insertions(+), 7 deletions(-) diff --git a/src/m_menu.c b/src/m_menu.c index ae00c8062..c6206a572 100644 --- a/src/m_menu.c +++ b/src/m_menu.c @@ -2973,7 +2973,7 @@ static void M_NextOpt(void) itemOn = 0; else itemOn++; - } while (oldItemOn != itemOn && (currentMenu->menuitems[itemOn].status & IT_TYPE) == IT_SPACE); + } while (oldItemOn != itemOn && ( (currentMenu->menuitems[itemOn].status & IT_TYPE) & IT_SPACE )); } static void M_PrevOpt(void) @@ -2985,7 +2985,7 @@ static void M_PrevOpt(void) itemOn = currentMenu->numitems - 1; else itemOn--; - } while (oldItemOn != itemOn && (currentMenu->menuitems[itemOn].status & IT_TYPE) == IT_SPACE); + } while (oldItemOn != itemOn && ( (currentMenu->menuitems[itemOn].status & IT_TYPE) & IT_SPACE )); } // lock out further input in a tic when important buttons are pressed @@ -3619,11 +3619,11 @@ void M_SetupNextMenu(menu_t *menudef) // the curent item can be disabled, // this code go up until an enabled item found - if ((currentMenu->menuitems[itemOn].status & IT_TYPE) == IT_SPACE) + if (( (currentMenu->menuitems[itemOn].status & IT_TYPE) & IT_SPACE )) { for (i = 0; i < currentMenu->numitems; i++) { - if ((currentMenu->menuitems[i].status & IT_TYPE) != IT_SPACE) + if (!( (currentMenu->menuitems[i].status & IT_TYPE) & IT_SPACE )) { itemOn = i; break; @@ -4306,7 +4306,18 @@ static void M_DrawGenericScrollMenu(void) } break; case IT_TRANSTEXT: - V_DrawString(x, y, V_TRANSLUCENT, currentMenu->menuitems[i].text); + switch (currentMenu->menuitems[i].status & IT_TYPE) + { + case IT_PAIR: + V_DrawString(x, y, + V_TRANSLUCENT, currentMenu->menuitems[i].patch); + V_DrawRightAlignedString(BASEVIDWIDTH - x, y, + V_TRANSLUCENT, currentMenu->menuitems[i].text); + break; + default: + V_DrawString(x, y, + V_TRANSLUCENT, currentMenu->menuitems[i].text); + } break; case IT_QUESTIONMARKS: V_DrawString(x, y, V_TRANSLUCENT|V_OLDSPACING, M_CreateSecretMenuOption(currentMenu->menuitems[i].text)); diff --git a/src/m_menu.h b/src/m_menu.h index ce9b422dc..00c258fe8 100644 --- a/src/m_menu.h +++ b/src/m_menu.h @@ -222,13 +222,14 @@ boolean M_CanShowLevelInList(INT32 mapnum, INT32 gt); // flags for items in the menu // menu handle (what we do when key is pressed -#define IT_TYPE 14 // (2+4+8) +#define IT_TYPE 15 // (1+2+4+8) #define IT_CALL 0 // call the function +#define IT_SPACE 1 // no handling #define IT_ARROWS 2 // call function with 0 for left arrow and 1 for right arrow in param #define IT_KEYHANDLER 4 // call with the key in param #define IT_SUBMENU 6 // go to sub menu #define IT_CVAR 8 // handle as a cvar -#define IT_SPACE 10 // no handling +#define IT_PAIR 11 // no handling, define both sides of text #define IT_MSGHANDLER 12 // same as key but with event and sometime can handle y/n key (special for message) #define IT_DISPLAY (48+64+128) // 16+32+64+128 From 7af2533d237831ec0ffac516d2b4c358f564d73c Mon Sep 17 00:00:00 2001 From: James R Date: Mon, 30 Dec 2019 21:45:19 -0800 Subject: [PATCH 567/746] 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 0eb65d0fa75c998c2282e1fdc1f47c140d43d516 Mon Sep 17 00:00:00 2001 From: fickleheart Date: Mon, 30 Dec 2019 23:58:58 -0600 Subject: [PATCH 568/746] Fix tailsbot behavior that broke with Simple mode --- src/b_bot.c | 18 +++++++++++------- src/g_game.c | 3 ++- src/g_game.h | 2 +- 3 files changed, 14 insertions(+), 9 deletions(-) diff --git a/src/b_bot.c b/src/b_bot.c index cd5edf990..c300466ad 100644 --- a/src/b_bot.c +++ b/src/b_bot.c @@ -127,13 +127,17 @@ static void B_BuildTailsTiccmd(mobj_t *sonic, mobj_t *tails, ticcmd_t *cmd) } // Orientation - if ((bot->pflags & (PF_SPINNING|PF_STARTDASH)) || flymode == 2) + if (bot->pflags & (PF_SPINNING|PF_STARTDASH)) { - cmd->angleturn = (sonic->angle - tails->angle) >> FRACBITS; + cmd->angleturn = (sonic->angle - tails->angle) >> 16; // NOT FRACBITS DAMNIT + } + else if (flymode == 2) + { + cmd->angleturn = sonic->player->cmd.angleturn - (tails->angle >> 16); } else { - cmd->angleturn = (ang - tails->angle) >> FRACBITS; + cmd->angleturn = (ang - tails->angle) >> 16; // NOT FRACBITS DAMNIT } // ******** @@ -222,7 +226,7 @@ static void B_BuildTailsTiccmd(mobj_t *sonic, mobj_t *tails, ticcmd_t *cmd) { if (dist < followthres && dist > touchdist) // Do positioning { - cmd->angleturn = (ang - tails->angle) >> FRACBITS; + cmd->angleturn = (ang - tails->angle) >> 16; // NOT FRACBITS DAMNIT cmd->forwardmove = 50; spinmode = true; } @@ -230,7 +234,7 @@ static void B_BuildTailsTiccmd(mobj_t *sonic, mobj_t *tails, ticcmd_t *cmd) { if (!bmom && (!(bot->pflags & PF_SPINNING) || (bot->dashspeed && bot->pflags & PF_SPINNING))) { - cmd->angleturn = (sonic->angle - tails->angle) >> FRACBITS; + cmd->angleturn = (sonic->angle - tails->angle) >> 16; // NOT FRACBITS DAMNIT spin = true; } spinmode = true; @@ -244,7 +248,7 @@ static void B_BuildTailsTiccmd(mobj_t *sonic, mobj_t *tails, ticcmd_t *cmd) if (bot->pflags & PF_SPINNING || !spin_last) { spin = true; - cmd->angleturn = (sonic->angle - tails->angle) >> FRACBITS; + cmd->angleturn = (sonic->angle - tails->angle) >> 16; // NOT FRACBITS DAMNIT cmd->forwardmove = MAXPLMOVE; spinmode = true; } @@ -290,7 +294,7 @@ static void B_BuildTailsTiccmd(mobj_t *sonic, mobj_t *tails, ticcmd_t *cmd) else if (dist < followmin) { // Copy inputs - cmd->angleturn = (sonic->angle - tails->angle) >> FRACBITS; + cmd->angleturn = (sonic->angle - tails->angle) >> 16; // NOT FRACBITS DAMNIT bot->drawangle = ang; cmd->forwardmove = 8 * pcmd->forwardmove / 10; cmd->sidemove = 8 * pcmd->sidemove / 10; diff --git a/src/g_game.c b/src/g_game.c index 86e0491cf..f73b6cffd 100644 --- a/src/g_game.c +++ b/src/g_game.c @@ -1615,9 +1615,10 @@ void G_BuildTiccmd(ticcmd_t *cmd, INT32 realtics, UINT8 ssplayer) { G_CopyTiccmd(cmd, I_BaseTiccmd2(), 1); // empty, or external driver B_BuildTiccmd(player, cmd); - } } + else if (player->bot == 2) + *myangle = localangle; // Fix offset angle for P2-controlled Tailsbot when P2's controls are set to non-Legacy if (controlstyle == CS_LMAOGALOG) { if (player->awayviewtics) diff --git a/src/g_game.h b/src/g_game.h index 27cb8bc00..de814109e 100644 --- a/src/g_game.h +++ b/src/g_game.h @@ -78,7 +78,7 @@ typedef enum { CS_STANDARD, CS_SIMPLE = CS_LMAOGALOG|CS_STANDARD, } controlstyle_e; -#define G_ControlStyle(ssplayer) ((cv_analog[(ssplayer)-1].value ? CS_LMAOGALOG : 0) | (cv_directionchar[(ssplayer)-1].value ? CS_STANDARD : 0)) +#define G_ControlStyle(ssplayer) (cv_directionchar[(ssplayer)-1].value == 3 ? CS_LMAOGALOG : ((cv_analog[(ssplayer)-1].value ? CS_LMAOGALOG : 0) | (cv_directionchar[(ssplayer)-1].value ? CS_STANDARD : 0))) #define P_ControlStyle(player) ((((player)->pflags & PF_ANALOGMODE) ? CS_LMAOGALOG : 0) | (((player)->pflags & PF_DIRECTIONCHAR) ? CS_STANDARD : 0)) extern consvar_t cv_autobrake, cv_autobrake2; From 281f30c4fd8f6ae2630df8570d81a6780666a714 Mon Sep 17 00:00:00 2001 From: James R Date: Mon, 30 Dec 2019 22:18:55 -0800 Subject: [PATCH 569/746] 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 b4ebb01e2d9d080f66416bb36588c5b377495e41 Mon Sep 17 00:00:00 2001 From: James R Date: Mon, 30 Dec 2019 22:23:19 -0800 Subject: [PATCH 570/746] 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 d3c56cd80754ea289c0c9ce6f25179388e05656a Mon Sep 17 00:00:00 2001 From: lachwright Date: Tue, 31 Dec 2019 16:48:29 +0800 Subject: [PATCH 571/746] 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 1a78b3548c29b1814c48c4538b20f71e8379087b Mon Sep 17 00:00:00 2001 From: lachwright Date: Tue, 31 Dec 2019 16:54:52 +0800 Subject: [PATCH 572/746] 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 342d80198c20717863268ae7754f15abbc8b0961 Mon Sep 17 00:00:00 2001 From: lachwright Date: Tue, 31 Dec 2019 16:55:36 +0800 Subject: [PATCH 573/746] 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 10b71d40b8fb8c3220ef0b1f0e6ff05f718a8ba5 Mon Sep 17 00:00:00 2001 From: lachwright Date: Tue, 31 Dec 2019 17:26:35 +0800 Subject: [PATCH 574/746] 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 e5e96cb2717ca470e969e24f5d576c4f420a8e18 Mon Sep 17 00:00:00 2001 From: lachwright Date: Tue, 31 Dec 2019 18:06:40 +0800 Subject: [PATCH 575/746] 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 79f18a3c19232c4b6e231adcbb8d38c14f1a6bef 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 576/746] 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 cd1cc9a222efee42628976136173f09af7f88357 Mon Sep 17 00:00:00 2001 From: Jaime Passos Date: Tue, 31 Dec 2019 14:00:25 -0300 Subject: [PATCH 577/746] 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 8bc58807aaba8668670aaf4ba25d3b932de041cc Mon Sep 17 00:00:00 2001 From: fickleheart Date: Tue, 31 Dec 2019 11:21:46 -0600 Subject: [PATCH 578/746] Software FOV ported from kart also fixes high software FOVs having buggy walls --- src/hardware/hw_clip.c | 3 ++- src/hardware/hw_main.c | 24 ++++++------------- src/hardware/hw_main.h | 3 +-- src/hardware/r_opengl/r_opengl.c | 40 ++++++++++++++------------------ src/m_menu.c | 2 +- src/p_user.c | 9 +------ src/r_main.c | 35 +++++++++++++++++++++------- src/r_main.h | 1 + 8 files changed, 57 insertions(+), 60 deletions(-) diff --git a/src/hardware/hw_clip.c b/src/hardware/hw_clip.c index 4bdc753ec..a63527083 100644 --- a/src/hardware/hw_clip.c +++ b/src/hardware/hw_clip.c @@ -72,6 +72,7 @@ #include "../v_video.h" #include "hw_clip.h" #include "hw_glob.h" +#include "../r_main.h" #include "../r_state.h" #include "../tables.h" #include "r_opengl/r_opengl.h" @@ -328,7 +329,7 @@ angle_t gld_FrustumAngle(void) // NEWCLIP TODO: SRB2CBTODO: make a global render_fov for this function - float render_fov = FIXED_TO_FLOAT(cv_grfov.value); + float render_fov = FIXED_TO_FLOAT(cv_fov.value); float render_fovratio = (float)BASEVIDWIDTH / (float)BASEVIDHEIGHT; // SRB2CBTODO: NEWCLIPTODO: Is this right? float render_multiplier = 64.0f / render_fovratio / RMUL; diff --git a/src/hardware/hw_main.c b/src/hardware/hw_main.c index 6ef48f222..4ebc168cc 100644 --- a/src/hardware/hw_main.c +++ b/src/hardware/hw_main.c @@ -5896,7 +5896,7 @@ static void HWR_DrawSkyBackground(player_t *player) if (cv_grskydome.value) { FTransform dometransform; - const float fpov = FIXED_TO_FLOAT(cv_grfov.value+player->fovadd); + const float fpov = FIXED_TO_FLOAT(cv_fov.value+player->fovadd); postimg_t *type; if (splitscreen && player == &players[secondarydisplayplayer]) @@ -6074,7 +6074,7 @@ void HWR_SetViewSize(void) // ========================================================================== void HWR_RenderSkyboxView(INT32 viewnumber, player_t *player) { - const float fpov = FIXED_TO_FLOAT(cv_grfov.value+player->fovadd); + const float fpov = FIXED_TO_FLOAT(cv_fov.value+player->fovadd); postimg_t *type; if (splitscreen && player == &players[secondarydisplayplayer]) @@ -6200,7 +6200,7 @@ if (0) viewangle = localaiming2; // Handle stuff when you are looking farther up or down. - if ((aimingangle || cv_grfov.value+player->fovadd > 90*FRACUNIT)) + if ((aimingangle || cv_fov.value+player->fovadd > 90*FRACUNIT)) { dup_viewangle += ANGLE_90; HWR_ClearClipSegs(); @@ -6278,7 +6278,7 @@ if (0) // ========================================================================== void HWR_RenderPlayerView(INT32 viewnumber, player_t *player) { - const float fpov = FIXED_TO_FLOAT(cv_grfov.value+player->fovadd); + const float fpov = FIXED_TO_FLOAT(cv_fov.value+player->fovadd); postimg_t *type; const boolean skybox = (skyboxmo[0] && cv_skybox.value); // True if there's a skybox object and skyboxes are on @@ -6420,7 +6420,7 @@ if (0) viewangle = localaiming2; // Handle stuff when you are looking farther up or down. - if ((aimingangle || cv_grfov.value+player->fovadd > 90*FRACUNIT)) + if ((aimingangle || cv_fov.value+player->fovadd > 90*FRACUNIT)) { dup_viewangle += ANGLE_90; HWR_ClearClipSegs(); @@ -6549,9 +6549,7 @@ static void CV_grmodellighting_OnChange(void); static void CV_grfiltermode_OnChange(void); static void CV_granisotropic_OnChange(void); static void CV_grfogdensity_OnChange(void); -static void CV_grfov_OnChange(void); -static CV_PossibleValue_t grfov_cons_t[] = {{0, "MIN"}, {179*FRACUNIT, "MAX"}, {0, NULL}}; static CV_PossibleValue_t grfiltermode_cons_t[]= {{HWD_SET_TEXTUREFILTER_POINTSAMPLED, "Nearest"}, {HWD_SET_TEXTUREFILTER_BILINEAR, "Bilinear"}, {HWD_SET_TEXTUREFILTER_TRILINEAR, "Trilinear"}, {HWD_SET_TEXTUREFILTER_MIXED1, "Linear_Nearest"}, @@ -6560,7 +6558,7 @@ static CV_PossibleValue_t grfiltermode_cons_t[]= {{HWD_SET_TEXTUREFILTER_POINTSA {0, NULL}}; CV_PossibleValue_t granisotropicmode_cons_t[] = {{1, "MIN"}, {16, "MAX"}, {0, NULL}}; -consvar_t cv_grfovchange = {"gr_fovchange", "Off", CV_SAVE, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL}; +consvar_t cv_fovchange = {"gr_fovchange", "Off", CV_SAVE, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL}; consvar_t cv_grfog = {"gr_fog", "On", CV_SAVE, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL}; consvar_t cv_grfogcolor = {"gr_fogcolor", "AAAAAA", CV_SAVE, NULL, NULL, 0, NULL, NULL, 0, 0, NULL}; consvar_t cv_grsoftwarefog = {"gr_softwarefog", "Off", CV_SAVE, grsoftwarefog_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL}; @@ -6580,7 +6578,6 @@ consvar_t cv_grspritebillboarding = {"gr_spritebillboarding", "Off", CV_SAVE, CV consvar_t cv_grskydome = {"gr_skydome", "On", CV_SAVE, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL}; consvar_t cv_grrounddown = {"gr_rounddown", "Off", 0, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL}; -consvar_t cv_grfov = {"gr_fov", "90", CV_FLOAT|CV_CALL, grfov_cons_t, CV_grfov_OnChange, 0, NULL, NULL, 0, 0, NULL}; consvar_t cv_grfogdensity = {"gr_fogdensity", "150", CV_CALL|CV_NOINIT, CV_Unsigned, CV_grfogdensity_OnChange, 0, NULL, NULL, 0, 0, NULL}; @@ -6616,17 +6613,10 @@ static void CV_granisotropic_OnChange(void) HWD.pfnSetSpecialState(HWD_SET_TEXTUREANISOTROPICMODE, cv_granisotropicmode.value); } -static void CV_grfov_OnChange(void) -{ - if ((netgame || multiplayer) && !cv_debug && cv_grfov.value != 90*FRACUNIT) - CV_Set(&cv_grfov, cv_grfov.defaultvalue); -} - //added by Hurdler: console varibale that are saved void HWR_AddCommands(void) { - CV_RegisterVar(&cv_grfovchange); - CV_RegisterVar(&cv_grfov); + CV_RegisterVar(&cv_fovchange); CV_RegisterVar(&cv_grfogdensity); CV_RegisterVar(&cv_grfogcolor); diff --git a/src/hardware/hw_main.h b/src/hardware/hw_main.h index e46aa9801..1314577cc 100644 --- a/src/hardware/hw_main.h +++ b/src/hardware/hw_main.h @@ -83,7 +83,6 @@ extern consvar_t cv_grstaticlighting; extern consvar_t cv_grcoronas; extern consvar_t cv_grcoronasize; #endif -extern consvar_t cv_grfov; extern consvar_t cv_grmodels; extern consvar_t cv_grmodelinterpolation; extern consvar_t cv_grmodellighting; @@ -94,7 +93,7 @@ extern consvar_t cv_grsoftwarefog; extern consvar_t cv_grfiltermode; extern consvar_t cv_granisotropicmode; extern consvar_t cv_grcorrecttricks; -extern consvar_t cv_grfovchange; +extern consvar_t cv_fovchange; extern consvar_t cv_grsolvetjoin; extern consvar_t cv_grspritebillboarding; extern consvar_t cv_grskydome; diff --git a/src/hardware/r_opengl/r_opengl.c b/src/hardware/r_opengl/r_opengl.c index 129bf5678..612d06c6d 100644 --- a/src/hardware/r_opengl/r_opengl.c +++ b/src/hardware/r_opengl/r_opengl.c @@ -2224,11 +2224,11 @@ EXPORT void HWRAPI(DrawModel) (model_t *model, INT32 frameIndex, INT32 duration, EXPORT void HWRAPI(SetTransform) (FTransform *stransform) { static boolean special_splitscreen; + float used_fov; pglLoadIdentity(); if (stransform) { - boolean fovx90; - + used_fov = stransform->fovxangle; #ifdef USE_FTRANSFORM_MIRROR // mirroring from Kart if (stransform->mirror) @@ -2244,32 +2244,28 @@ EXPORT void HWRAPI(SetTransform) (FTransform *stransform) pglRotatef(stransform->angley+270.0f, 0.0f, 1.0f, 0.0f); pglTranslatef(-stransform->x, -stransform->z, -stransform->y); - pglMatrixMode(GL_PROJECTION); - pglLoadIdentity(); - fovx90 = stransform->fovxangle > 0.0f && fabsf(stransform->fovxangle - 90.0f) < 0.5f; - special_splitscreen = (stransform->splitscreen && fovx90); - if (special_splitscreen) - GLPerspective(53.13f, 2*ASPECT_RATIO); // 53.13 = 2*atan(0.5) - else - GLPerspective(stransform->fovxangle, ASPECT_RATIO); - pglGetFloatv(GL_PROJECTION_MATRIX, projMatrix); // added for new coronas' code (without depth buffer) - pglMatrixMode(GL_MODELVIEW); + special_splitscreen = stransform->splitscreen; } else { + used_fov = fov; pglScalef(1.0f, 1.0f, -1.0f); - - pglMatrixMode(GL_PROJECTION); - pglLoadIdentity(); - if (special_splitscreen) - GLPerspective(53.13f, 2*ASPECT_RATIO); // 53.13 = 2*atan(0.5) - else - //Hurdler: is "fov" correct? - GLPerspective(fov, ASPECT_RATIO); - pglGetFloatv(GL_PROJECTION_MATRIX, projMatrix); // added for new coronas' code (without depth buffer) - pglMatrixMode(GL_MODELVIEW); } + pglMatrixMode(GL_PROJECTION); + pglLoadIdentity(); + + if (special_splitscreen) + { + used_fov = atan(tan(used_fov*M_PI/360)*0.8)*360/M_PI; + GLPerspective(used_fov, 2*ASPECT_RATIO); + } + else + GLPerspective(used_fov, ASPECT_RATIO); + + pglGetFloatv(GL_PROJECTION_MATRIX, projMatrix); // added for new coronas' code (without depth buffer) + pglMatrixMode(GL_MODELVIEW); + pglGetFloatv(GL_MODELVIEW_MATRIX, modelMatrix); // added for new coronas' code (without depth buffer) } diff --git a/src/m_menu.c b/src/m_menu.c index 630f0c643..12624abb7 100644 --- a/src/m_menu.c +++ b/src/m_menu.c @@ -1311,7 +1311,7 @@ static menuitem_t OP_OpenGLOptionsMenu[] = {IT_STRING|IT_CVAR, NULL, "Model lighting", &cv_grmodellighting, 32}, {IT_HEADER, NULL, "General", NULL, 51}, - {IT_STRING|IT_CVAR, NULL, "Field of view", &cv_grfov, 63}, + {IT_STRING|IT_CVAR, NULL, "Field of view", &cv_fov, 63}, {IT_STRING|IT_CVAR, NULL, "Quality", &cv_scr_depth, 73}, {IT_STRING|IT_CVAR, NULL, "Texture Filter", &cv_grfiltermode, 83}, {IT_STRING|IT_CVAR, NULL, "Anisotropic", &cv_granisotropicmode,93}, diff --git a/src/p_user.c b/src/p_user.c index 20fbc99f4..a97e62052 100644 --- a/src/p_user.c +++ b/src/p_user.c @@ -8648,7 +8648,7 @@ static void P_MovePlayer(player_t *player) } #ifdef HWRENDER - if (rendermode != render_soft && rendermode != render_none && cv_grfovchange.value) + if (rendermode != render_soft && rendermode != render_none && cv_fovchange.value) { fixed_t speed; const fixed_t runnyspeed = 20*FRACUNIT; @@ -9884,13 +9884,6 @@ boolean P_MoveChaseCamera(player_t *player, camera_t *thiscam, boolean resetcall { dist = camdist; - // x1.5 dist for splitscreen - if (splitscreen) - { - dist = FixedMul(dist, 3*FRACUNIT/2); - camheight = FixedMul(camheight, 3*FRACUNIT/2); - } - if (sign) // signpost camera has specific placement { camheight = mo->scale << 7; diff --git a/src/r_main.c b/src/r_main.c index 115db8cb5..8ee7858f9 100644 --- a/src/r_main.c +++ b/src/r_main.c @@ -57,6 +57,7 @@ INT32 centerx, centery; fixed_t centerxfrac, centeryfrac; fixed_t projection; fixed_t projectiony; // aspect ratio +fixed_t fovtan; // field of view // just for profiling purposes size_t framecount; @@ -106,10 +107,12 @@ static CV_PossibleValue_t drawdist_precip_cons_t[] = { {1024, "1024"}, {1536, "1536"}, {2048, "2048"}, {0, "None"}, {0, NULL}}; +static CV_PossibleValue_t fov_cons_t[] = {{60*FRACUNIT, "MIN"}, {179*FRACUNIT, "MAX"}, {0, NULL}}; static CV_PossibleValue_t translucenthud_cons_t[] = {{0, "MIN"}, {10, "MAX"}, {0, NULL}}; static CV_PossibleValue_t maxportals_cons_t[] = {{0, "MIN"}, {12, "MAX"}, {0, NULL}}; // lmao rendering 32 portals, you're a card static CV_PossibleValue_t homremoval_cons_t[] = {{0, "No"}, {1, "Yes"}, {2, "Flash"}, {0, NULL}}; +static void Fov_OnChange(void); static void ChaseCam_OnChange(void); static void ChaseCam2_OnChange(void); static void FlipCam_OnChange(void); @@ -139,6 +142,7 @@ consvar_t cv_drawdist = {"drawdist", "Infinite", CV_SAVE, drawdist_cons_t, NULL, consvar_t cv_drawdist_nights = {"drawdist_nights", "2048", CV_SAVE, drawdist_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL}; consvar_t cv_drawdist_precip = {"drawdist_precip", "1024", CV_SAVE, drawdist_precip_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL}; //consvar_t cv_precipdensity = {"precipdensity", "Moderate", CV_SAVE, precipdensity_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL}; +consvar_t cv_fov = {"fov", "90", CV_FLOAT|CV_CALL, fov_cons_t, Fov_OnChange, 0, NULL, NULL, 0, 0, NULL}; // Okay, whoever said homremoval causes a performance hit should be shot. consvar_t cv_homremoval = {"homremoval", "No", CV_SAVE, homremoval_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL}; @@ -182,6 +186,14 @@ void SplitScreen_OnChange(void) } } } +static void Fov_OnChange(void) +{ + // Shouldn't be needed with render parity? + //if ((netgame || multiplayer) && !cv_debug && cv_fov.value != 90*FRACUNIT) + // CV_Set(&cv_fov, cv_fov.defaultvalue); + + R_SetViewSize(); +} static void ChaseCam_OnChange(void) { @@ -446,8 +458,8 @@ static void R_InitTextureMapping(void) // // Calc focallength // so FIELDOFVIEW angles covers SCREENWIDTH. - focallength = FixedDiv(centerxfrac, - FINETANGENT(FINEANGLES/4+/*cv_fov.value*/ FIELDOFVIEW/2)); + focallength = FixedDiv(projection, + FINETANGENT(FINEANGLES/4+FIELDOFVIEW/2)); #ifdef ESLOPE focallengthf = FIXED_TO_FLOAT(focallength); @@ -455,9 +467,9 @@ static void R_InitTextureMapping(void) for (i = 0; i < FINEANGLES/2; i++) { - if (FINETANGENT(i) > FRACUNIT*2) + if (FINETANGENT(i) > fovtan*2) t = -1; - else if (FINETANGENT(i) < -FRACUNIT*2) + else if (FINETANGENT(i) < -fovtan*2) t = viewwidth+1; else { @@ -561,6 +573,7 @@ void R_ExecuteSetViewSize(void) INT32 j; INT32 level; INT32 startmapl; + angle_t fov; setsizeneeded = false; @@ -583,9 +596,12 @@ void R_ExecuteSetViewSize(void) centerxfrac = centerx<> ANGLETOFINESHIFT); + if (splitscreen == 1) // Splitscreen FOV should be adjusted to maintain expected vertical view + fovtan = 17*fovtan/10; + + projection = projectiony = FixedDiv(centerxfrac, fovtan); R_InitViewBuffer(scaledviewwidth, viewheight); @@ -611,7 +627,7 @@ void R_ExecuteSetViewSize(void) for (i = 0; i < j; i++) { dy = ((i - viewheight*8)<>ANGLETOFINESHIFT)) & FINEMASK)*160)>>FRACBITS) +#define AIMINGTODY(a) FixedDiv((FINETANGENT((2048+(((INT32)a)>>ANGLETOFINESHIFT)) & FINEMASK)*160)>>FRACBITS, fovtan) // recalc necessary stuff for mouseaiming // slopes are already calculated for the full possible view (which is 4*viewheight). @@ -1175,6 +1191,7 @@ void R_RegisterEngineStuff(void) CV_RegisterVar(&cv_drawdist); CV_RegisterVar(&cv_drawdist_nights); CV_RegisterVar(&cv_drawdist_precip); + CV_RegisterVar(&cv_fov); CV_RegisterVar(&cv_chasecam); CV_RegisterVar(&cv_chasecam2); diff --git a/src/r_main.h b/src/r_main.h index 58c23cd81..c1bb0861a 100644 --- a/src/r_main.h +++ b/src/r_main.h @@ -84,6 +84,7 @@ extern conscar_t cv_shadowoffs; #endif //#ifdef GLBADSHADOWS extern consvar_t cv_translucency; extern consvar_t cv_drawdist, cv_drawdist_nights, cv_drawdist_precip; +extern consvar_t cv_fov; extern consvar_t cv_skybox; extern consvar_t cv_tailspickup; From 1c048275da96aa07b244e6295485fe4ac0b9d558 Mon Sep 17 00:00:00 2001 From: Jaime Passos Date: Tue, 31 Dec 2019 14:37:45 -0300 Subject: [PATCH 579/746] **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 6e330348bcc0ec895ca32e70d6d9a1d3c4d4948c 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 580/746] 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 83467a7b3d584b72329e57d23638e61f6019bbbb 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 581/746] 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 ef4840555e2c52a781e69ade5c56a88f70963af9 Mon Sep 17 00:00:00 2001 From: Nami <50415197+namishere@users.noreply.github.com> Date: Tue, 31 Dec 2019 15:17:02 -0800 Subject: [PATCH 582/746] Add MobjLineCollide hook --- src/lua_hook.h | 3 ++ src/lua_hooklib.c | 81 +++++++++++++++++++++++++++++++++++++++++++++++ src/p_map.c | 11 +++++++ 3 files changed, 95 insertions(+) diff --git a/src/lua_hook.h b/src/lua_hook.h index d035be097..6f8805708 100644 --- a/src/lua_hook.h +++ b/src/lua_hook.h @@ -25,6 +25,7 @@ enum hook { hook_PostThinkFrame, hook_MobjSpawn, hook_MobjCollide, + hook_MobjLineCollide, hook_MobjMoveCollide, hook_TouchSpecial, hook_MobjFuse, @@ -70,7 +71,9 @@ boolean LUAh_MobjHook(mobj_t *mo, enum hook which); boolean LUAh_PlayerHook(player_t *plr, enum hook which); #define LUAh_MobjSpawn(mo) LUAh_MobjHook(mo, hook_MobjSpawn) // Hook for P_SpawnMobj by mobj type UINT8 LUAh_MobjCollideHook(mobj_t *thing1, mobj_t *thing2, enum hook which); +UINT8 LUAh_MobjLineCollideHook(mobj_t *thing, line_t *line, enum hook which); #define LUAh_MobjCollide(thing1, thing2) LUAh_MobjCollideHook(thing1, thing2, hook_MobjCollide) // Hook for PIT_CheckThing by (thing) mobj type +#define LUAh_MobjLineCollide(thing, line) LUAh_MobjLineCollideHook(thing, line, hook_MobjLineCollide) // Hook for PIT_CheckThing by (thing) mobj type #define LUAh_MobjMoveCollide(thing1, thing2) LUAh_MobjCollideHook(thing1, thing2, hook_MobjMoveCollide) // Hook for PIT_CheckThing by (tmthing) mobj type boolean LUAh_TouchSpecial(mobj_t *special, mobj_t *toucher); // Hook for P_TouchSpecialThing by mobj type #define LUAh_MobjFuse(mo) LUAh_MobjHook(mo, hook_MobjFuse) // Hook for mobj->fuse == 0 by mobj type diff --git a/src/lua_hooklib.c b/src/lua_hooklib.c index d548f6a65..2d9a98c4b 100644 --- a/src/lua_hooklib.c +++ b/src/lua_hooklib.c @@ -36,6 +36,7 @@ const char *const hookNames[hook_MAX+1] = { "PostThinkFrame", "MobjSpawn", "MobjCollide", + "MobjLineCollide", "MobjMoveCollide", "TouchSpecial", "MobjFuse", @@ -125,6 +126,7 @@ static int lib_addHook(lua_State *L) // Take a mobjtype enum which this hook is specifically for. case hook_MobjSpawn: case hook_MobjCollide: + case hook_MobjLineCollide: case hook_MobjMoveCollide: case hook_TouchSpecial: case hook_MobjFuse: @@ -184,6 +186,7 @@ static int lib_addHook(lua_State *L) lastp = &mobjthinkerhooks[hook.s.mt]; break; case hook_MobjCollide: + case hook_MobjLineCollide: case hook_MobjMoveCollide: lastp = &mobjcollidehooks[hook.s.mt]; break; @@ -562,6 +565,84 @@ UINT8 LUAh_MobjCollideHook(mobj_t *thing1, mobj_t *thing2, enum hook which) return shouldCollide; } +UINT8 LUAh_MobjLineCollideHook(mobj_t *thing, line_t *line, enum hook which) +{ + hook_p hookp; + UINT8 shouldCollide = 0; // 0 = default, 1 = force yes, 2 = force no. + if (!gL || !(hooksAvailable[which/8] & (1<<(which%8)))) + return 0; + + I_Assert(thing->type < NUMMOBJTYPES); + + lua_settop(gL, 0); + + // Look for all generic mobj collision hooks + for (hookp = mobjcollidehooks[MT_NULL]; hookp; hookp = hookp->next) + { + if (hookp->type != which) + continue; + + if (lua_gettop(gL) == 0) + { + LUA_PushUserdata(gL, thing, META_MOBJ); + LUA_PushUserdata(gL, line, META_LINE); + } + 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)) + { // if nil, leave shouldCollide = 0. + if (lua_toboolean(gL, -1)) + shouldCollide = 1; // Force yes + else + shouldCollide = 2; // Force no + } + lua_pop(gL, 1); + } + + for (hookp = mobjcollidehooks[thing->type]; hookp; hookp = hookp->next) + { + if (hookp->type != which) + continue; + + if (lua_gettop(gL) == 0) + { + LUA_PushUserdata(gL, thing, META_MOBJ); + LUA_PushUserdata(gL, line, META_LINE); + } + 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)) + { // if nil, leave shouldCollide = 0. + if (lua_toboolean(gL, -1)) + shouldCollide = 1; // Force yes + else + shouldCollide = 2; // Force no + } + lua_pop(gL, 1); + } + + lua_settop(gL, 0); + return shouldCollide; +} + // Hook for mobj thinkers boolean LUAh_MobjThinker(mobj_t *mo) { diff --git a/src/p_map.c b/src/p_map.c index 1b6f23cde..628268bff 100644 --- a/src/p_map.c +++ b/src/p_map.c @@ -1988,6 +1988,17 @@ static boolean PIT_CheckLine(line_t *ld) if (lowfloor < tmdropoffz) tmdropoffz = lowfloor; +#ifdef HAVE_BLUA + { + UINT8 shouldCollide = LUAh_MobjLineCollide(tmthing, ld); // checks hook for thing's type + if (P_MobjWasRemoved(tmthing)) + return true; // one of them was removed??? + if (shouldCollide == 1) + return false; // force collide + else if (shouldCollide == 2) + return true; // force no collide + } +#endif return true; } From caf47019cee70fabab2530969fcabf5c41c05ee5 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 583/746] 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 b41cd59e5198415d71b03b794b73b1c9ea9ffcc7 Mon Sep 17 00:00:00 2001 From: Jaime Passos Date: Tue, 31 Dec 2019 23:40:17 +0000 Subject: [PATCH 584/746] Revert "Merge branch 'software-clownery' into 'master'" This reverts merge request !578 --- src/p_setup.c | 5 +- src/r_bsp.c | 2 +- src/r_defs.h | 3 +- src/r_main.c | 6 +- src/r_segs.c | 4765 +++++++++++++++++++++++-------------------------- src/r_state.h | 39 +- 6 files changed, 2261 insertions(+), 2559 deletions(-) diff --git a/src/p_setup.c b/src/p_setup.c index c29cc907e..42a6438a0 100644 --- a/src/p_setup.c +++ b/src/p_setup.c @@ -416,7 +416,9 @@ fixed_t P_SegLength(seg_t *seg) return FixedHypot(dx, dy)<<1; } +#ifdef HWRENDER /** Computes the length of a seg as a float. + * This is needed for OpenGL. * * \param seg Seg to compute length for. * \return Length as a float. @@ -431,6 +433,7 @@ static inline float P_SegLengthFloat(seg_t *seg) return (float)hypot(dx, dy); } +#endif /** Loads the SEGS resource from a level. * @@ -457,10 +460,10 @@ static void P_LoadRawSegs(UINT8 *data, size_t i) li->v2 = &vertexes[SHORT(ml->v2)]; li->length = P_SegLength(li); - li->flength = P_SegLengthFloat(li); #ifdef HWRENDER if (rendermode == render_opengl) { + li->flength = P_SegLengthFloat(li); //Hurdler: 04/12/2000: for now, only used in hardware mode li->lightmaps = NULL; // list of static lightmap for this seg } diff --git a/src/r_bsp.c b/src/r_bsp.c index b6dbfd76a..51d9bd3fd 100644 --- a/src/r_bsp.c +++ b/src/r_bsp.c @@ -410,7 +410,7 @@ static void R_AddLine(seg_t *line) return; // Global angle needed by segcalc. - rw.angle1 = angle1; + rw_angle1 = angle1; angle1 -= viewangle; angle2 -= viewangle; diff --git a/src/r_defs.h b/src/r_defs.h index cfc55ef18..2791ac8b0 100644 --- a/src/r_defs.h +++ b/src/r_defs.h @@ -582,12 +582,11 @@ typedef struct seg_s sector_t *backsector; fixed_t length; // precalculated seg length - float flength; // ditto but float - #ifdef HWRENDER // new pointers so that AdjustSegs doesn't mess with v1/v2 void *pv1; // polyvertex_t void *pv2; // polyvertex_t + float flength; // length of the seg, used by hardware renderer lightmap_t *lightmaps; // for static lightmap #endif diff --git a/src/r_main.c b/src/r_main.c index 8ef47d21d..a5f4bc118 100644 --- a/src/r_main.c +++ b/src/r_main.c @@ -366,7 +366,7 @@ angle_t R_PointToAngleEx(INT32 x2, INT32 y2, INT32 x1, INT32 y1) // R_ScaleFromGlobalAngle // Returns the texture mapping scale for the current line (horizontal span) // at the given angle. -// rw.distance must be calculated first. +// rw_distance must be calculated first. // // killough 5/2/98: reformatted, cleaned up // @@ -374,8 +374,8 @@ angle_t R_PointToAngleEx(INT32 x2, INT32 y2, INT32 x1, INT32 y1) fixed_t R_ScaleFromGlobalAngle(angle_t visangle) { angle_t anglea = ANGLE_90 + (visangle-viewangle); - angle_t angleb = ANGLE_90 + (visangle-rw.normalangle); - fixed_t den = FixedMul(rw.distance, FINESINE(anglea>>ANGLETOFINESHIFT)); + angle_t angleb = ANGLE_90 + (visangle-rw_normalangle); + fixed_t den = FixedMul(rw_distance, FINESINE(anglea>>ANGLETOFINESHIFT)); // proff 11/06/98: Changed for high-res fixed_t num = FixedMul(projectiony, FINESINE(angleb>>ANGLETOFINESHIFT)); diff --git a/src/r_segs.c b/src/r_segs.c index 750b32522..2c8aadec8 100644 --- a/src/r_segs.c +++ b/src/r_segs.c @@ -37,21 +37,25 @@ static boolean maskedtexture; static INT32 toptexture, bottomtexture, midtexture; static INT32 numthicksides, numbackffloors; -static boolean bothceilingssky; -static boolean bothfloorssky; - -#ifdef ESLOPE -static vertex_t segleft, segright; -static fixed_t ceilingfrontslide, floorfrontslide, ceilingbackslide, floorbackslide; -#endif +angle_t rw_normalangle; +// angle to line origin +angle_t rw_angle1; +fixed_t rw_distance; // // regular wall // -renderwall_t rw; +static INT32 rw_x, rw_stopx; +static angle_t rw_centerangle; +static fixed_t rw_offset; +static fixed_t rw_offset2; // for splats +static fixed_t rw_scale, rw_scalestep; +static fixed_t rw_midtexturemid, rw_toptexturemid, rw_bottomtexturemid; static INT32 worldtop, worldbottom, worldhigh, worldlow; #ifdef ESLOPE static INT32 worldtopslope, worldbottomslope, worldhighslope, worldlowslope; // worldtop/bottom at end of slope +static fixed_t rw_toptextureslide, rw_midtextureslide, rw_bottomtextureslide; // Defines how to adjust Y offsets along the wall for slopes +static fixed_t rw_midtextureback, rw_midtexturebackslide; // Values for masked midtexture height calculation #endif static fixed_t pixhigh, pixlow, pixhighstep, pixlowstep; static fixed_t topfrac, topstep; @@ -63,6 +67,1242 @@ static INT16 *maskedtexturecol; static fixed_t *maskedtextureheight = NULL; #endif +// ========================================================================== +// R_Splats Wall Splats Drawer +// ========================================================================== + +#ifdef WALLSPLATS +static INT16 last_ceilingclip[MAXVIDWIDTH]; +static INT16 last_floorclip[MAXVIDWIDTH]; + +static void R_DrawSplatColumn(column_t *column) +{ + INT32 topscreen, bottomscreen; + fixed_t basetexturemid; + INT32 topdelta, prevdelta = -1; + + basetexturemid = dc_texturemid; + + for (; column->topdelta != 0xff ;) + { + // calculate unclipped screen coordinates for post + topdelta = column->topdelta; + if (topdelta <= prevdelta) + topdelta += prevdelta; + prevdelta = topdelta; + topscreen = sprtopscreen + spryscale*topdelta; + bottomscreen = topscreen + spryscale*column->length; + + dc_yl = (topscreen+FRACUNIT-1)>>FRACBITS; + dc_yh = (bottomscreen-1)>>FRACBITS; + + if (dc_yh >= last_floorclip[dc_x]) + dc_yh = last_floorclip[dc_x] - 1; + if (dc_yl <= last_ceilingclip[dc_x]) + dc_yl = last_ceilingclip[dc_x] + 1; + if (dc_yl <= dc_yh && dl_yh < vid.height && yh > 0) + { + dc_source = (UINT8 *)column + 3; + dc_texturemid = basetexturemid - (topdelta<length + 4); + } + + dc_texturemid = basetexturemid; +} + +static void R_DrawWallSplats(void) +{ + wallsplat_t *splat; + seg_t *seg; + angle_t angle, angle1, angle2; + INT32 x1, x2; + size_t pindex; + column_t *col; + patch_t *patch; + fixed_t texturecolumn; + + splat = (wallsplat_t *)linedef->splats; + + I_Assert(splat != NULL); + + seg = ds_p->curline; + + // draw all splats from the line that touches the range of the seg + for (; splat; splat = splat->next) + { + angle1 = R_PointToAngle(splat->v1.x, splat->v1.y); + angle2 = R_PointToAngle(splat->v2.x, splat->v2.y); + angle1 = (angle1 - viewangle + ANGLE_90)>>ANGLETOFINESHIFT; + angle2 = (angle2 - viewangle + ANGLE_90)>>ANGLETOFINESHIFT; + // out of the viewangletox lut + /// \todo clip it to the screen + if (angle1 > FINEANGLES/2 || angle2 > FINEANGLES/2) + continue; + x1 = viewangletox[angle1]; + x2 = viewangletox[angle2]; + + if (x1 >= x2) + continue; // does not cross a pixel + + // splat is not in this seg range + if (x2 < ds_p->x1 || x1 > ds_p->x2) + continue; + + if (x1 < ds_p->x1) + x1 = ds_p->x1; + if (x2 > ds_p->x2) + x2 = ds_p->x2; + if (x2 <= x1) + continue; + + // calculate incremental stepping values for texture edges + rw_scalestep = ds_p->scalestep; + spryscale = ds_p->scale1 + (x1 - ds_p->x1)*rw_scalestep; + mfloorclip = floorclip; + mceilingclip = ceilingclip; + + patch = W_CachePatchNum(splat->patch, PU_PATCH); + + dc_texturemid = splat->top + (SHORT(patch->height)<<(FRACBITS-1)) - viewz; + if (splat->yoffset) + dc_texturemid += *splat->yoffset; + + sprtopscreen = centeryfrac - FixedMul(dc_texturemid, spryscale); + + // set drawing mode + switch (splat->flags & SPLATDRAWMODE_MASK) + { + case SPLATDRAWMODE_OPAQUE: + colfunc = colfuncs[BASEDRAWFUNC]; + break; + case SPLATDRAWMODE_TRANS: + if (!cv_translucency.value) + colfunc = colfuncs[BASEDRAWFUNC]; + else + { + dc_transmap = transtables + ((tr_trans50 - 1)<>LIGHTSCALESHIFT; + if (pindex >= MAXLIGHTSCALE) + pindex = MAXLIGHTSCALE - 1; + dc_colormap = walllights[pindex]; + + if (frontsector->extra_colormap) + dc_colormap = frontsector->extra_colormap->colormap + (dc_colormap - colormaps); + + sprtopscreen = centeryfrac - FixedMul(dc_texturemid, spryscale); + dc_iscale = 0xffffffffu / (unsigned)spryscale; + + // find column of patch, from perspective + angle = (rw_centerangle + xtoviewangle[dc_x])>>ANGLETOFINESHIFT; + texturecolumn = rw_offset2 - splat->offset + - FixedMul(FINETANGENT(angle), rw_distance); + + // FIXME! + texturecolumn >>= FRACBITS; + if (texturecolumn < 0 || texturecolumn >= SHORT(patch->width)) + continue; + + // draw the texture + col = (column_t *)((UINT8 *)patch + LONG(patch->columnofs[texturecolumn])); + R_DrawSplatColumn(col); + } + } // next splat + + colfunc = colfuncs[BASEDRAWFUNC]; +} + +#endif //WALLSPLATS + +// ========================================================================== +// R_RenderMaskedSegRange +// ========================================================================== + +// If we have a multi-patch texture on a 2sided wall (rare) then we draw +// it using R_DrawColumn, else we draw it using R_DrawMaskedColumn, this +// way we don't have to store extra post_t info with each column for +// multi-patch textures. They are not normally needed as multi-patch +// textures don't have holes in it. At least not for now. +static INT32 column2s_length; // column->length : for multi-patch on 2sided wall = texture->height + +static void R_Render2sidedMultiPatchColumn(column_t *column) +{ + INT32 topscreen, bottomscreen; + + topscreen = sprtopscreen; // + spryscale*column->topdelta; topdelta is 0 for the wall + bottomscreen = topscreen + spryscale * column2s_length; + + dc_yl = (sprtopscreen+FRACUNIT-1)>>FRACBITS; + dc_yh = (bottomscreen-1)>>FRACBITS; + + if (windowtop != INT32_MAX && windowbottom != INT32_MAX) + { + dc_yl = ((windowtop + FRACUNIT)>>FRACBITS); + dc_yh = (windowbottom - 1)>>FRACBITS; + } + + if (dc_yh >= mfloorclip[dc_x]) + dc_yh = mfloorclip[dc_x] - 1; + if (dc_yl <= mceilingclip[dc_x]) + dc_yl = mceilingclip[dc_x] + 1; + + if (dc_yl >= vid.height || dc_yh < 0) + return; + + if (dc_yl <= dc_yh && dc_yh < vid.height && dc_yh > 0) + { + dc_source = (UINT8 *)column + 3; + + if (colfunc == colfuncs[BASEDRAWFUNC]) + (colfuncs[COLDRAWFUNC_TWOSMULTIPATCH])(); + else if (colfunc == colfuncs[COLDRAWFUNC_FUZZY]) + (colfuncs[COLDRAWFUNC_TWOSMULTIPATCHTRANS])(); + else + colfunc(); + } +} + +// quick wrapper for R_DrawFlippedMaskedColumn so it can be set as a colfunc_2s value +// uses column2s_length for texture->height as above +static void R_DrawFlippedMaskedSegColumn(column_t *column) +{ + R_DrawFlippedMaskedColumn(column, column2s_length); +} + +void R_RenderMaskedSegRange(drawseg_t *ds, INT32 x1, INT32 x2) +{ + size_t pindex; + column_t *col; + INT32 lightnum, texnum, i; + fixed_t height, realbot; + lightlist_t *light; + r_lightlist_t *rlight; + void (*colfunc_2s)(column_t *); + line_t *ldef; + sector_t *front, *back; + INT32 times, repeats; + INT64 overflow_test; +#ifdef ESLOPE + INT32 range; +#endif + + // Calculate light table. + // Use different light tables + // for horizontal / vertical / diagonal. Diagonal? + // OPTIMIZE: get rid of LIGHTSEGSHIFT globally + curline = ds->curline; + frontsector = curline->frontsector; + backsector = curline->backsector; + texnum = R_GetTextureNum(curline->sidedef->midtexture); + windowbottom = windowtop = sprbotscreen = INT32_MAX; + + // hack translucent linedef types (900-909 for transtables 1-9) + ldef = curline->linedef; + switch (ldef->special) + { + case 900: + case 901: + case 902: + case 903: + case 904: + case 905: + case 906: + case 907: + case 908: + dc_transmap = transtables + ((ldef->special-900)<ceilingheight; + windowbottom = frontsector->floorheight; + break; + default: + colfunc = colfuncs[BASEDRAWFUNC]; + break; + } + + if (curline->polyseg && curline->polyseg->translucency > 0) + { + if (curline->polyseg->translucency >= NUMTRANSMAPS) + return; + + dc_transmap = transtables + ((curline->polyseg->translucency-1)<x2-ds->x1, 1); +#endif + rw_scalestep = ds->scalestep; + spryscale = ds->scale1 + (x1 - ds->x1)*rw_scalestep; + + // Texture must be cached before setting colfunc_2s, + // otherwise texture[texnum]->holes may be false when it shouldn't be + R_CheckTextureCache(texnum); + // handle case where multipatch texture is drawn on a 2sided wall, multi-patch textures + // are not stored per-column with post info in SRB2 + if (textures[texnum]->holes) + { + if (textures[texnum]->flip & 2) // vertically flipped? + { + colfunc_2s = R_DrawFlippedMaskedSegColumn; + column2s_length = textures[texnum]->height; + } + else + colfunc_2s = R_DrawMaskedColumn; // render the usual 2sided single-patch packed texture + } + else + { + colfunc_2s = R_Render2sidedMultiPatchColumn; // render multipatch with no holes (no post_t info) + column2s_length = textures[texnum]->height; + } + + // Setup lighting based on the presence/lack-of 3D floors. + dc_numlights = 0; + if (frontsector->numlights) + { + dc_numlights = frontsector->numlights; + if (dc_numlights >= dc_maxlights) + { + dc_maxlights = dc_numlights; + dc_lightlist = Z_Realloc(dc_lightlist, sizeof (*dc_lightlist) * dc_maxlights, PU_STATIC, NULL); + } + + for (i = 0; i < dc_numlights; i++) + { +#ifdef ESLOPE + fixed_t leftheight, rightheight; +#endif + light = &frontsector->lightlist[i]; + rlight = &dc_lightlist[i]; +#ifdef ESLOPE + if (light->slope) { + leftheight = P_GetZAt(light->slope, ds->leftpos.x, ds->leftpos.y); + rightheight = P_GetZAt(light->slope, ds->rightpos.x, ds->rightpos.y); + } else + leftheight = rightheight = light->height; + + leftheight -= viewz; + rightheight -= viewz; + + rlight->height = (centeryfrac) - FixedMul(leftheight, ds->scale1); + rlight->heightstep = (centeryfrac) - FixedMul(rightheight, ds->scale2); + rlight->heightstep = (rlight->heightstep-rlight->height)/(range); + //if (x1 > ds->x1) + //rlight->height -= (x1 - ds->x1)*rlight->heightstep; +#else + rlight->height = (centeryfrac) - FixedMul((light->height - viewz), spryscale); + rlight->heightstep = -FixedMul(rw_scalestep, (light->height - viewz)); +#endif + rlight->startheight = rlight->height; // keep starting value here to reset for each repeat + rlight->lightlevel = *light->lightlevel; + rlight->extra_colormap = *light->extra_colormap; + rlight->flags = light->flags; + + if (rlight->flags & FF_FOG || (rlight->extra_colormap && rlight->extra_colormap->fog)) + lightnum = (rlight->lightlevel >> LIGHTSEGSHIFT); + else if (colfunc == colfuncs[COLDRAWFUNC_FUZZY]) + lightnum = LIGHTLEVELS - 1; + else + lightnum = (rlight->lightlevel >> LIGHTSEGSHIFT); + + if (rlight->extra_colormap && rlight->extra_colormap->fog) + ; + else if (curline->v1->y == curline->v2->y) + lightnum--; + else if (curline->v1->x == curline->v2->x) + lightnum++; + + rlight->lightnum = lightnum; + } + } + else + { + if (colfunc == colfuncs[COLDRAWFUNC_FUZZY]) + { + if (frontsector->extra_colormap && frontsector->extra_colormap->fog) + lightnum = (frontsector->lightlevel >> LIGHTSEGSHIFT); + else + lightnum = LIGHTLEVELS - 1; + } + else + lightnum = (frontsector->lightlevel >> LIGHTSEGSHIFT); + + if (colfunc == colfuncs[COLDRAWFUNC_FOG] + || (frontsector->extra_colormap && frontsector->extra_colormap->fog)) + ; + else if (curline->v1->y == curline->v2->y) + lightnum--; + else if (curline->v1->x == curline->v2->x) + lightnum++; + + if (lightnum < 0) + walllights = scalelight[0]; + else if (lightnum >= LIGHTLEVELS) + walllights = scalelight[LIGHTLEVELS - 1]; + else + walllights = scalelight[lightnum]; + } + + maskedtexturecol = ds->maskedtexturecol; + + mfloorclip = ds->sprbottomclip; + mceilingclip = ds->sprtopclip; + + if (frontsector->heightsec != -1) + front = §ors[frontsector->heightsec]; + else + front = frontsector; + + if (backsector->heightsec != -1) + back = §ors[backsector->heightsec]; + else + back = backsector; + + if (ds->curline->sidedef->repeatcnt) + repeats = 1 + ds->curline->sidedef->repeatcnt; + else if (ldef->flags & ML_EFFECT5) + { + fixed_t high, low; + + if (front->ceilingheight > back->ceilingheight) + high = back->ceilingheight; + else + high = front->ceilingheight; + + if (front->floorheight > back->floorheight) + low = front->floorheight; + else + low = back->floorheight; + + repeats = (high - low)/textureheight[texnum]; + if ((high-low)%textureheight[texnum]) + repeats++; // tile an extra time to fill the gap -- Monster Iestyn + } + else + repeats = 1; + + for (times = 0; times < repeats; times++) + { + if (times > 0) + { + rw_scalestep = ds->scalestep; + spryscale = ds->scale1 + (x1 - ds->x1)*rw_scalestep; + if (dc_numlights) + { // reset all lights to their starting heights + for (i = 0; i < dc_numlights; i++) + { + rlight = &dc_lightlist[i]; + rlight->height = rlight->startheight; + } + } + } + +#ifndef ESLOPE + if (curline->linedef->flags & ML_DONTPEGBOTTOM) + { + dc_texturemid = front->floorheight > back->floorheight + ? front->floorheight : back->floorheight; + dc_texturemid = dc_texturemid + textureheight[texnum] - viewz; + } + else + { + dc_texturemid = front->ceilingheight < back->ceilingheight + ? front->ceilingheight : back->ceilingheight; + dc_texturemid = dc_texturemid - viewz; + } + dc_texturemid += curline->sidedef->rowoffset; + + if (curline->linedef->flags & ML_DONTPEGBOTTOM) + dc_texturemid += (textureheight[texnum])*times; + else + dc_texturemid -= (textureheight[texnum])*times; +#endif + + dc_texheight = textureheight[texnum]>>FRACBITS; + + // draw the columns + for (dc_x = x1; dc_x <= x2; dc_x++) + { +#ifdef ESLOPE + dc_texturemid = ds->maskedtextureheight[dc_x]; + + if (!!(curline->linedef->flags & ML_DONTPEGBOTTOM) ^ !!(curline->linedef->flags & ML_EFFECT3)) + dc_texturemid += (textureheight[texnum])*times + textureheight[texnum]; + else + dc_texturemid -= (textureheight[texnum])*times; +#endif + // calculate lighting + if (maskedtexturecol[dc_x] != INT16_MAX) + { + // Check for overflows first + overflow_test = (INT64)centeryfrac - (((INT64)dc_texturemid*spryscale)>>FRACBITS); + if (overflow_test < 0) overflow_test = -overflow_test; + if ((UINT64)overflow_test&0xFFFFFFFF80000000ULL) + { + // Eh, no, go away, don't waste our time + if (dc_numlights) + { + for (i = 0; i < dc_numlights; i++) + { + rlight = &dc_lightlist[i]; + rlight->height += rlight->heightstep; + } + } + spryscale += rw_scalestep; + continue; + } + + if (dc_numlights) + { + lighttable_t **xwalllights; + + sprbotscreen = INT32_MAX; + sprtopscreen = windowtop = (centeryfrac - FixedMul(dc_texturemid, spryscale)); + + realbot = windowbottom = FixedMul(textureheight[texnum], spryscale) + sprtopscreen; + dc_iscale = 0xffffffffu / (unsigned)spryscale; + + // draw the texture + col = (column_t *)((UINT8 *)R_GetColumn(texnum, maskedtexturecol[dc_x]) - 3); + + for (i = 0; i < dc_numlights; i++) + { + rlight = &dc_lightlist[i]; + + if ((rlight->flags & FF_NOSHADE)) + continue; + + if (rlight->lightnum < 0) + xwalllights = scalelight[0]; + else if (rlight->lightnum >= LIGHTLEVELS) + xwalllights = scalelight[LIGHTLEVELS-1]; + else + xwalllights = scalelight[rlight->lightnum]; + + pindex = FixedMul(spryscale, FixedDiv(640, vid.width))>>LIGHTSCALESHIFT; + + if (pindex >= MAXLIGHTSCALE) + pindex = MAXLIGHTSCALE - 1; + + if (rlight->extra_colormap) + rlight->rcolormap = rlight->extra_colormap->colormap + (xwalllights[pindex] - colormaps); + else + rlight->rcolormap = xwalllights[pindex]; + + height = rlight->height; + rlight->height += rlight->heightstep; + + if (height <= windowtop) + { + dc_colormap = rlight->rcolormap; + continue; + } + + windowbottom = height; + if (windowbottom >= realbot) + { + windowbottom = realbot; + colfunc_2s(col); + for (i++; i < dc_numlights; i++) + { + rlight = &dc_lightlist[i]; + rlight->height += rlight->heightstep; + } + + continue; + } + colfunc_2s(col); + windowtop = windowbottom + 1; + dc_colormap = rlight->rcolormap; + } + windowbottom = realbot; + if (windowtop < windowbottom) + colfunc_2s(col); + + spryscale += rw_scalestep; + continue; + } + + // calculate lighting + pindex = FixedMul(spryscale, FixedDiv(640, vid.width))>>LIGHTSCALESHIFT; + + if (pindex >= MAXLIGHTSCALE) + pindex = MAXLIGHTSCALE - 1; + + dc_colormap = walllights[pindex]; + + if (frontsector->extra_colormap) + dc_colormap = frontsector->extra_colormap->colormap + (dc_colormap - colormaps); + + sprtopscreen = centeryfrac - FixedMul(dc_texturemid, spryscale); + dc_iscale = 0xffffffffu / (unsigned)spryscale; + + // draw the texture + col = (column_t *)((UINT8 *)R_GetColumn(texnum, maskedtexturecol[dc_x]) - 3); + +//#ifdef POLYOBJECTS_PLANES +#if 0 // Disabling this allows inside edges to render below the planes, for until the clipping is fixed to work right when POs are near the camera. -Red + if (curline->dontrenderme && curline->polyseg && (curline->polyseg->flags & POF_RENDERPLANES)) + { + fixed_t my_topscreen; + fixed_t my_bottomscreen; + fixed_t my_yl, my_yh; + + my_topscreen = sprtopscreen + spryscale*col->topdelta; + my_bottomscreen = sprbotscreen == INT32_MAX ? my_topscreen + spryscale*col->length + : sprbotscreen + spryscale*col->length; + + my_yl = (my_topscreen+FRACUNIT-1)>>FRACBITS; + my_yh = (my_bottomscreen-1)>>FRACBITS; + // CONS_Debug(DBG_RENDER, "my_topscreen: %d\nmy_bottomscreen: %d\nmy_yl: %d\nmy_yh: %d\n", my_topscreen, my_bottomscreen, my_yl, my_yh); + + if (numffloors) + { + INT32 top = my_yl; + INT32 bottom = my_yh; + + for (i = 0; i < numffloors; i++) + { + if (!ffloor[i].polyobj || ffloor[i].polyobj != curline->polyseg) + continue; + + if (ffloor[i].height < viewz) + { + INT32 top_w = ffloor[i].plane->top[dc_x]; + + // CONS_Debug(DBG_RENDER, "Leveltime : %d\n", leveltime); + // CONS_Debug(DBG_RENDER, "Top is %d, top_w is %d\n", top, top_w); + if (top_w < top) + { + ffloor[i].plane->top[dc_x] = (INT16)top; + ffloor[i].plane->picnum = 0; + } + // CONS_Debug(DBG_RENDER, "top_w is now %d\n", ffloor[i].plane->top[dc_x]); + } + else if (ffloor[i].height > viewz) + { + INT32 bottom_w = ffloor[i].plane->bottom[dc_x]; + + if (bottom_w > bottom) + { + ffloor[i].plane->bottom[dc_x] = (INT16)bottom; + ffloor[i].plane->picnum = 0; + } + } + } + } + } + else +#endif + colfunc_2s(col); + } + spryscale += rw_scalestep; + } + } + colfunc = colfuncs[BASEDRAWFUNC]; +} + +// Loop through R_DrawMaskedColumn calls +static void R_DrawRepeatMaskedColumn(column_t *col) +{ + while (sprtopscreen < sprbotscreen) { + R_DrawMaskedColumn(col); + if ((INT64)sprtopscreen + dc_texheight*spryscale > (INT64)INT32_MAX) // prevent overflow + sprtopscreen = INT32_MAX; + else + sprtopscreen += dc_texheight*spryscale; + } +} + +static void R_DrawRepeatFlippedMaskedColumn(column_t *col) +{ + do { + R_DrawFlippedMaskedColumn(col, column2s_length); + sprtopscreen += dc_texheight*spryscale; + } while (sprtopscreen < sprbotscreen); +} + +// +// R_RenderThickSideRange +// Renders all the thick sides in the given range. +void R_RenderThickSideRange(drawseg_t *ds, INT32 x1, INT32 x2, ffloor_t *pfloor) +{ + size_t pindex; + column_t * col; + INT32 lightnum; + INT32 texnum; + sector_t tempsec; + INT32 templight; + INT32 i, p; + fixed_t bottombounds = viewheight << FRACBITS; + fixed_t topbounds = (con_clipviewtop - 1) << FRACBITS; + fixed_t offsetvalue = 0; + lightlist_t *light; + r_lightlist_t *rlight; +#ifdef ESLOPE + INT32 range; +#endif +#ifndef ESLOPE + fixed_t lheight; +#endif + line_t *newline = NULL; +#ifdef ESLOPE + // Render FOF sides kinda like normal sides, with the frac and step and everything + // NOTE: INT64 instead of fixed_t because overflow concerns + INT64 top_frac, top_step, bottom_frac, bottom_step; + // skew FOF walls with slopes? + boolean slopeskew = false; + fixed_t ffloortextureslide = 0; + INT32 oldx = -1; + fixed_t left_top, left_bottom; // needed here for slope skewing + pslope_t *skewslope = NULL; +#endif + + void (*colfunc_2s) (column_t *); + + // Calculate light table. + // Use different light tables + // for horizontal / vertical / diagonal. Diagonal? + // OPTIMIZE: get rid of LIGHTSEGSHIFT globally + + curline = ds->curline; + backsector = pfloor->target; + frontsector = curline->frontsector == pfloor->target ? curline->backsector : curline->frontsector; + texnum = R_GetTextureNum(sides[pfloor->master->sidenum[0]].midtexture); + + colfunc = colfuncs[BASEDRAWFUNC]; + + if (pfloor->master->flags & ML_TFERLINE) + { + size_t linenum = curline->linedef-backsector->lines[0]; + newline = pfloor->master->frontsector->lines[0] + linenum; + texnum = R_GetTextureNum(sides[newline->sidenum[0]].midtexture); + } + + if (pfloor->flags & FF_TRANSLUCENT) + { + boolean fuzzy = true; + + // Hacked up support for alpha value in software mode Tails 09-24-2002 + if (pfloor->alpha < 12) + return; // Don't even draw it + else if (pfloor->alpha < 38) + dc_transmap = transtables + ((tr_trans90-1)<alpha < 64) + dc_transmap = transtables + ((tr_trans80-1)<alpha < 89) + dc_transmap = transtables + ((tr_trans70-1)<alpha < 115) + dc_transmap = transtables + ((tr_trans60-1)<alpha < 140) + dc_transmap = transtables + ((tr_trans50-1)<alpha < 166) + dc_transmap = transtables + ((tr_trans40-1)<alpha < 192) + dc_transmap = transtables + ((tr_trans30-1)<alpha < 217) + dc_transmap = transtables + ((tr_trans20-1)<alpha < 243) + dc_transmap = transtables + ((tr_trans10-1)<flags & FF_FOG) + colfunc = colfuncs[COLDRAWFUNC_FOG]; + +#ifdef ESLOPE + range = max(ds->x2-ds->x1, 1); +#endif + //SoM: Moved these up here so they are available for my lightlist calculations + rw_scalestep = ds->scalestep; + spryscale = ds->scale1 + (x1 - ds->x1)*rw_scalestep; + + dc_numlights = 0; + if (frontsector->numlights) + { + dc_numlights = frontsector->numlights; + if (dc_numlights > dc_maxlights) + { + dc_maxlights = dc_numlights; + dc_lightlist = Z_Realloc(dc_lightlist, sizeof (*dc_lightlist) * dc_maxlights, PU_STATIC, NULL); + } + + for (i = p = 0; i < dc_numlights; i++) + { +#ifdef ESLOPE + fixed_t leftheight, rightheight; + fixed_t pfloorleft, pfloorright; + INT64 overflow_test; +#endif + light = &frontsector->lightlist[i]; + rlight = &dc_lightlist[p]; +#ifdef ESLOPE + +#define SLOPEPARAMS(slope, end1, end2, normalheight) \ + if (slope) { \ + end1 = P_GetZAt(slope, ds->leftpos.x, ds->leftpos.y); \ + end2 = P_GetZAt(slope, ds->rightpos.x, ds->rightpos.y); \ + } else \ + end1 = end2 = normalheight; + + SLOPEPARAMS(light->slope, leftheight, rightheight, light->height) + SLOPEPARAMS(*pfloor->b_slope, pfloorleft, pfloorright, *pfloor->bottomheight) + + if (leftheight < pfloorleft && rightheight < pfloorright) + continue; + + SLOPEPARAMS(*pfloor->t_slope, pfloorleft, pfloorright, *pfloor->topheight) + + if (leftheight > pfloorleft && rightheight > pfloorright && i+1 < dc_numlights) + { + lightlist_t *nextlight = &frontsector->lightlist[i+1]; + if ((nextlight->slope ? P_GetZAt(nextlight->slope, ds->leftpos.x, ds->leftpos.y) : nextlight->height) > pfloorleft + && (nextlight->slope ? P_GetZAt(nextlight->slope, ds->rightpos.x, ds->rightpos.y) : nextlight->height) > pfloorright) + continue; + } + + leftheight -= viewz; + rightheight -= viewz; + +#define CLAMPMAX INT32_MAX +#define CLAMPMIN (-INT32_MAX) // This is not INT32_MIN on purpose! INT32_MIN makes the drawers freak out. + // Monster Iestyn (25/03/18): do not skip these lights if they fail overflow test, just clamp them instead so they behave. + overflow_test = (INT64)centeryfrac - (((INT64)leftheight*ds->scale1)>>FRACBITS); + if (overflow_test > (INT64)CLAMPMAX) rlight->height = CLAMPMAX; + else if (overflow_test > (INT64)CLAMPMIN) rlight->height = (fixed_t)overflow_test; + else rlight->height = CLAMPMIN; + + overflow_test = (INT64)centeryfrac - (((INT64)rightheight*ds->scale2)>>FRACBITS); + if (overflow_test > (INT64)CLAMPMAX) rlight->heightstep = CLAMPMAX; + else if (overflow_test > (INT64)CLAMPMIN) rlight->heightstep = (fixed_t)overflow_test; + else rlight->heightstep = CLAMPMIN; + rlight->heightstep = (rlight->heightstep-rlight->height)/(range); +#else + if (light->height < *pfloor->bottomheight) + continue; + + if (light->height > *pfloor->topheight && i+1 < dc_numlights && frontsector->lightlist[i+1].height > *pfloor->topheight) + continue; + + lheight = light->height;// > *pfloor->topheight ? *pfloor->topheight + FRACUNIT : light->height; + rlight->heightstep = -FixedMul (rw_scalestep, (lheight - viewz)); + rlight->height = (centeryfrac) - FixedMul((lheight - viewz), spryscale); +#endif + rlight->flags = light->flags; + if (light->flags & FF_CUTLEVEL) + { +#ifdef ESLOPE + SLOPEPARAMS(*light->caster->b_slope, leftheight, rightheight, *light->caster->bottomheight) +#undef SLOPEPARAMS + leftheight -= viewz; + rightheight -= viewz; + + // Monster Iestyn (25/03/18): do not skip these lights if they fail overflow test, just clamp them instead so they behave. + overflow_test = (INT64)centeryfrac - (((INT64)leftheight*ds->scale1)>>FRACBITS); + if (overflow_test > (INT64)CLAMPMAX) rlight->botheight = CLAMPMAX; + else if (overflow_test > (INT64)CLAMPMIN) rlight->botheight = (fixed_t)overflow_test; + else rlight->botheight = CLAMPMIN; + + overflow_test = (INT64)centeryfrac - (((INT64)rightheight*ds->scale2)>>FRACBITS); + if (overflow_test > (INT64)CLAMPMAX) rlight->botheightstep = CLAMPMAX; + else if (overflow_test > (INT64)CLAMPMIN) rlight->botheightstep = (fixed_t)overflow_test; + else rlight->botheightstep = CLAMPMIN; + rlight->botheightstep = (rlight->botheightstep-rlight->botheight)/(range); +#else + lheight = *light->caster->bottomheight;// > *pfloor->topheight ? *pfloor->topheight + FRACUNIT : *light->caster->bottomheight; + rlight->botheightstep = -FixedMul (rw_scalestep, (lheight - viewz)); + rlight->botheight = (centeryfrac) - FixedMul((lheight - viewz), spryscale); +#endif + } + + rlight->lightlevel = *light->lightlevel; + rlight->extra_colormap = *light->extra_colormap; + + // Check if the current light effects the colormap/lightlevel + if (pfloor->flags & FF_FOG) + rlight->lightnum = (pfloor->master->frontsector->lightlevel >> LIGHTSEGSHIFT); + else + rlight->lightnum = (rlight->lightlevel >> LIGHTSEGSHIFT); + + if (pfloor->flags & FF_FOG || rlight->flags & FF_FOG || (rlight->extra_colormap && rlight->extra_colormap->fog)) + ; + else if (curline->v1->y == curline->v2->y) + rlight->lightnum--; + else if (curline->v1->x == curline->v2->x) + rlight->lightnum++; + + p++; + } + + dc_numlights = p; + } + else + { + // Get correct light level! + if ((frontsector->extra_colormap && frontsector->extra_colormap->fog)) + lightnum = (frontsector->lightlevel >> LIGHTSEGSHIFT); + else if (pfloor->flags & FF_FOG) + lightnum = (pfloor->master->frontsector->lightlevel >> LIGHTSEGSHIFT); + else if (colfunc == colfuncs[COLDRAWFUNC_FUZZY]) + lightnum = LIGHTLEVELS-1; + else + lightnum = R_FakeFlat(frontsector, &tempsec, &templight, &templight, false) + ->lightlevel >> LIGHTSEGSHIFT; + + if (pfloor->flags & FF_FOG || (frontsector->extra_colormap && frontsector->extra_colormap->fog)); + else if (curline->v1->y == curline->v2->y) + lightnum--; + else if (curline->v1->x == curline->v2->x) + lightnum++; + + if (lightnum < 0) + walllights = scalelight[0]; + else if (lightnum >= LIGHTLEVELS) + walllights = scalelight[LIGHTLEVELS-1]; + else + walllights = scalelight[lightnum]; + } + + maskedtexturecol = ds->thicksidecol; + + mfloorclip = ds->sprbottomclip; + mceilingclip = ds->sprtopclip; + dc_texheight = textureheight[texnum]>>FRACBITS; + +#ifdef ESLOPE + // calculate both left ends + if (*pfloor->t_slope) + left_top = P_GetZAt(*pfloor->t_slope, ds->leftpos.x, ds->leftpos.y) - viewz; + else + left_top = *pfloor->topheight - viewz; + + if (*pfloor->b_slope) + left_bottom = P_GetZAt(*pfloor->b_slope, ds->leftpos.x, ds->leftpos.y) - viewz; + else + left_bottom = *pfloor->bottomheight - viewz; + skewslope = *pfloor->t_slope; // skew using top slope by default + if (newline) + { + if (newline->flags & ML_DONTPEGTOP) + slopeskew = true; + } + else if (pfloor->master->flags & ML_DONTPEGTOP) + slopeskew = true; + + if (slopeskew) + dc_texturemid = left_top; + else +#endif + dc_texturemid = *pfloor->topheight - viewz; + + if (newline) + { + offsetvalue = sides[newline->sidenum[0]].rowoffset; + if (newline->flags & ML_DONTPEGBOTTOM) + { +#ifdef ESLOPE + skewslope = *pfloor->b_slope; // skew using bottom slope + if (slopeskew) + dc_texturemid = left_bottom; + else +#endif + offsetvalue -= *pfloor->topheight - *pfloor->bottomheight; + } + } + else + { + offsetvalue = sides[pfloor->master->sidenum[0]].rowoffset; + if (curline->linedef->flags & ML_DONTPEGBOTTOM) + { +#ifdef ESLOPE + skewslope = *pfloor->b_slope; // skew using bottom slope + if (slopeskew) + dc_texturemid = left_bottom; + else +#endif + offsetvalue -= *pfloor->topheight - *pfloor->bottomheight; + } + } + +#ifdef ESLOPE + if (slopeskew) + { + angle_t lineangle = R_PointToAngle2(curline->v1->x, curline->v1->y, curline->v2->x, curline->v2->y); + + if (skewslope) + ffloortextureslide = FixedMul(skewslope->zdelta, FINECOSINE((lineangle-skewslope->xydirection)>>ANGLETOFINESHIFT)); + } +#endif + + dc_texturemid += offsetvalue; + + // Texture must be cached before setting colfunc_2s, + // otherwise texture[texnum]->holes may be false when it shouldn't be + R_CheckTextureCache(texnum); + //faB: handle case where multipatch texture is drawn on a 2sided wall, multi-patch textures + // are not stored per-column with post info anymore in Doom Legacy + if (textures[texnum]->holes) + { + if (textures[texnum]->flip & 2) // vertically flipped? + { + colfunc_2s = R_DrawRepeatFlippedMaskedColumn; + column2s_length = textures[texnum]->height; + } + else + colfunc_2s = R_DrawRepeatMaskedColumn; // render the usual 2sided single-patch packed texture + } + else + { + colfunc_2s = R_Render2sidedMultiPatchColumn; //render multipatch with no holes (no post_t info) + column2s_length = textures[texnum]->height; + } + +#ifdef ESLOPE + // Set heights according to plane, or slope, whichever + { + fixed_t right_top, right_bottom; + + // calculate right ends now + if (*pfloor->t_slope) + right_top = P_GetZAt(*pfloor->t_slope, ds->rightpos.x, ds->rightpos.y) - viewz; + else + right_top = *pfloor->topheight - viewz; + + if (*pfloor->b_slope) + right_bottom = P_GetZAt(*pfloor->b_slope, ds->rightpos.x, ds->rightpos.y) - viewz; + else + right_bottom = *pfloor->bottomheight - viewz; + + // using INT64 to avoid 32bit overflow + top_frac = (INT64)centeryfrac - (((INT64)left_top * ds->scale1) >> FRACBITS); + bottom_frac = (INT64)centeryfrac - (((INT64)left_bottom * ds->scale1) >> FRACBITS); + top_step = (INT64)centeryfrac - (((INT64)right_top * ds->scale2) >> FRACBITS); + bottom_step = (INT64)centeryfrac - (((INT64)right_bottom * ds->scale2) >> FRACBITS); + + top_step = (top_step-top_frac)/(range); + bottom_step = (bottom_step-bottom_frac)/(range); + + top_frac += top_step * (x1 - ds->x1); + bottom_frac += bottom_step * (x1 - ds->x1); + } +#endif + + // draw the columns + for (dc_x = x1; dc_x <= x2; dc_x++) + { + if (maskedtexturecol[dc_x] != INT16_MAX) + { +#ifdef ESLOPE + if (ffloortextureslide) { // skew FOF walls + if (oldx != -1) + dc_texturemid += FixedMul(ffloortextureslide, (maskedtexturecol[oldx]-maskedtexturecol[dc_x])< (INT64)CLAMPMAX) sprtopscreen = windowtop = CLAMPMAX; + else if (top_frac > (INT64)CLAMPMIN) sprtopscreen = windowtop = (fixed_t)top_frac; + else sprtopscreen = windowtop = CLAMPMIN; + if (bottom_frac > (INT64)CLAMPMAX) sprbotscreen = windowbottom = CLAMPMAX; + else if (bottom_frac > (INT64)CLAMPMIN) sprbotscreen = windowbottom = (fixed_t)bottom_frac; + else sprbotscreen = windowbottom = CLAMPMIN; + + top_frac += top_step; + bottom_frac += bottom_step; +#else + sprtopscreen = windowtop = (centeryfrac - FixedMul((dc_texturemid - offsetvalue), spryscale)); + sprbotscreen = windowbottom = FixedMul(*pfloor->topheight - *pfloor->bottomheight, spryscale) + sprtopscreen; +#endif + + // SoM: If column is out of range, why bother with it?? + if (windowbottom < topbounds || windowtop > bottombounds) + { + if (dc_numlights) + { + for (i = 0; i < dc_numlights; i++) + { + rlight = &dc_lightlist[i]; + rlight->height += rlight->heightstep; + if (rlight->flags & FF_CUTLEVEL) + rlight->botheight += rlight->botheightstep; + } + } + spryscale += rw_scalestep; + continue; + } + + dc_iscale = 0xffffffffu / (unsigned)spryscale; + + // Get data for the column + col = (column_t *)((UINT8 *)R_GetColumn(texnum,maskedtexturecol[dc_x]) - 3); + + // SoM: New code does not rely on R_DrawColumnShadowed_8 which + // will (hopefully) put less strain on the stack. + if (dc_numlights) + { + lighttable_t **xwalllights; + fixed_t height; + fixed_t bheight = 0; + INT32 solid = 0; + INT32 lighteffect = 0; + + for (i = 0; i < dc_numlights; i++) + { + // Check if the current light effects the colormap/lightlevel + rlight = &dc_lightlist[i]; + lighteffect = !(dc_lightlist[i].flags & FF_NOSHADE); + if (lighteffect) + { + lightnum = rlight->lightnum; + + if (lightnum < 0) + xwalllights = scalelight[0]; + else if (lightnum >= LIGHTLEVELS) + xwalllights = scalelight[LIGHTLEVELS-1]; + else + xwalllights = scalelight[lightnum]; + + pindex = FixedMul(spryscale, FixedDiv(640, vid.width))>>LIGHTSCALESHIFT; + + if (pindex >= MAXLIGHTSCALE) + pindex = MAXLIGHTSCALE-1; + + if (pfloor->flags & FF_FOG) + { + if (pfloor->master->frontsector->extra_colormap) + rlight->rcolormap = pfloor->master->frontsector->extra_colormap->colormap + (xwalllights[pindex] - colormaps); + else + rlight->rcolormap = xwalllights[pindex]; + } + else + { + if (rlight->extra_colormap) + rlight->rcolormap = rlight->extra_colormap->colormap + (xwalllights[pindex] - colormaps); + else + rlight->rcolormap = xwalllights[pindex]; + } + } + + solid = 0; // don't carry over solid-cutting flag from the previous light + + // Check if the current light can cut the current 3D floor. + if (rlight->flags & FF_CUTSOLIDS && !(pfloor->flags & FF_EXTRA)) + solid = 1; + else if (rlight->flags & FF_CUTEXTRA && pfloor->flags & FF_EXTRA) + { + if (rlight->flags & FF_EXTRA) + { + // The light is from an extra 3D floor... Check the flags so + // there are no undesired cuts. + if ((rlight->flags & (FF_FOG|FF_SWIMMABLE)) == (pfloor->flags & (FF_FOG|FF_SWIMMABLE))) + solid = 1; + } + else + solid = 1; + } + else + solid = 0; + + height = rlight->height; + rlight->height += rlight->heightstep; + + if (solid) + { + bheight = rlight->botheight - (FRACUNIT >> 1); + rlight->botheight += rlight->botheightstep; + } + + if (height <= windowtop) + { + if (lighteffect) + dc_colormap = rlight->rcolormap; + if (solid && windowtop < bheight) + windowtop = bheight; + continue; + } + + windowbottom = height; + if (windowbottom >= sprbotscreen) + { + windowbottom = sprbotscreen; + // draw the texture + colfunc_2s (col); + for (i++; i < dc_numlights; i++) + { + rlight = &dc_lightlist[i]; + rlight->height += rlight->heightstep; + if (rlight->flags & FF_CUTLEVEL) + rlight->botheight += rlight->botheightstep; + } + continue; + } + // draw the texture + colfunc_2s (col); + if (solid) + windowtop = bheight; + else + windowtop = windowbottom + 1; + if (lighteffect) + dc_colormap = rlight->rcolormap; + } + windowbottom = sprbotscreen; + // draw the texture, if there is any space left + if (windowtop < windowbottom) + colfunc_2s (col); + + spryscale += rw_scalestep; + continue; + } + + // calculate lighting + pindex = FixedMul(spryscale, FixedDiv(640, vid.width))>>LIGHTSCALESHIFT; + + if (pindex >= MAXLIGHTSCALE) + pindex = MAXLIGHTSCALE - 1; + + dc_colormap = walllights[pindex]; + + if (pfloor->flags & FF_FOG && pfloor->master->frontsector->extra_colormap) + dc_colormap = pfloor->master->frontsector->extra_colormap->colormap + (dc_colormap - colormaps); + else if (frontsector->extra_colormap) + dc_colormap = frontsector->extra_colormap->colormap + (dc_colormap - colormaps); + + // draw the texture + colfunc_2s (col); + spryscale += rw_scalestep; + } + } + colfunc = colfuncs[BASEDRAWFUNC]; + +#undef CLAMPMAX +#undef CLAMPMIN +} + // R_ExpandPlaneY // // A simple function to modify a vsplane's top and bottom for a particular column @@ -101,7 +1341,7 @@ UINT32 nombre = 100000; static void R_RenderSegLoop (void) { angle_t angle; - size_t pindex = 0; + size_t pindex; INT32 yl; INT32 yh; @@ -114,16 +1354,12 @@ static void R_RenderSegLoop (void) INT32 bottom; INT32 i; - // Set the shadowed column drawer for light lists. - if (dc_numlights) - colfunc = colfuncs[COLDRAWFUNC_SHADOWED]; - - for (; rw.x < rw.stopx; rw.x++) + for (; rw_x < rw_stopx; rw_x++) { // mark floor / ceiling areas yl = (topfrac+HEIGHTUNIT-1)>>HEIGHTBITS; - top = ceilingclip[rw.x]+1; + top = ceilingclip[rw_x]+1; // no space above wall? if (yl < top) @@ -134,39 +1370,39 @@ static void R_RenderSegLoop (void) #if 0 bottom = yl-1; - if (bottom >= floorclip[rw.x]) - bottom = floorclip[rw.x]-1; + if (bottom >= floorclip[rw_x]) + bottom = floorclip[rw_x]-1; if (top <= bottom) #else - bottom = yl > floorclip[rw.x] ? floorclip[rw.x] : yl; + bottom = yl > floorclip[rw_x] ? floorclip[rw_x] : yl; if (top <= --bottom && ceilingplane) #endif - R_ExpandPlaneY(ceilingplane, rw.x, top, bottom); + R_ExpandPlaneY(ceilingplane, rw_x, top, bottom); } yh = bottomfrac>>HEIGHTBITS; - bottom = floorclip[rw.x]-1; + bottom = floorclip[rw_x]-1; if (yh > bottom) yh = bottom; if (markfloor) { - top = yh < ceilingclip[rw.x] ? ceilingclip[rw.x] : yh; + top = yh < ceilingclip[rw_x] ? ceilingclip[rw_x] : yh; if (++top <= bottom && floorplane) - R_ExpandPlaneY(floorplane, rw.x, top, bottom); + R_ExpandPlaneY(floorplane, rw_x, top, bottom); } if (numffloors) { - firstseg->frontscale[rw.x] = frontscale[rw.x]; - top = ceilingclip[rw.x]+1; // PRBoom - bottom = floorclip[rw.x]-1; // PRBoom + firstseg->frontscale[rw_x] = frontscale[rw_x]; + top = ceilingclip[rw_x]+1; // PRBoom + bottom = floorclip[rw_x]-1; // PRBoom for (i = 0; i < numffloors; i++) { @@ -178,7 +1414,7 @@ static void R_RenderSegLoop (void) if (ffloor[i].height < viewz) { INT32 top_w = (ffloor[i].f_frac >> HEIGHTBITS) + 1; - INT32 bottom_w = ffloor[i].f_clip[rw.x]; + INT32 bottom_w = ffloor[i].f_clip[rw_x]; if (top_w < top) top_w = top; @@ -189,20 +1425,20 @@ static void R_RenderSegLoop (void) #ifdef POLYOBJECTS_PLANES // Polyobject-specific hack to fix plane leaking -Red if (ffloor[i].polyobj && top_w >= bottom_w) { - ffloor[i].plane->top[rw.x] = 0xFFFF; - ffloor[i].plane->bottom[rw.x] = 0x0000; // fix for sky plane drawing crashes - Monster Iestyn 25/05/18 + ffloor[i].plane->top[rw_x] = 0xFFFF; + ffloor[i].plane->bottom[rw_x] = 0x0000; // fix for sky plane drawing crashes - Monster Iestyn 25/05/18 } else #endif if (top_w <= bottom_w) { - ffloor[i].plane->top[rw.x] = (INT16)top_w; - ffloor[i].plane->bottom[rw.x] = (INT16)bottom_w; + ffloor[i].plane->top[rw_x] = (INT16)top_w; + ffloor[i].plane->bottom[rw_x] = (INT16)bottom_w; } } else if (ffloor[i].height > viewz) { - INT32 top_w = ffloor[i].c_clip[rw.x] + 1; + INT32 top_w = ffloor[i].c_clip[rw_x] + 1; INT32 bottom_w = (ffloor[i].f_frac >> HEIGHTBITS); if (top_w < top) @@ -214,40 +1450,31 @@ static void R_RenderSegLoop (void) #ifdef POLYOBJECTS_PLANES // Polyobject-specific hack to fix plane leaking -Red if (ffloor[i].polyobj && top_w >= bottom_w) { - ffloor[i].plane->top[rw.x] = 0xFFFF; - ffloor[i].plane->bottom[rw.x] = 0x0000; // fix for sky plane drawing crashes - Monster Iestyn 25/05/18 + ffloor[i].plane->top[rw_x] = 0xFFFF; + ffloor[i].plane->bottom[rw_x] = 0x0000; // fix for sky plane drawing crashes - Monster Iestyn 25/05/18 } else #endif if (top_w <= bottom_w) { - ffloor[i].plane->top[rw.x] = (INT16)top_w; - ffloor[i].plane->bottom[rw.x] = (INT16)bottom_w; + ffloor[i].plane->top[rw_x] = (INT16)top_w; + ffloor[i].plane->bottom[rw_x] = (INT16)bottom_w; } } } } - // Calculate lighting. - // Done for light lists anyway to avoid doing it for every light. - if (segtextured || dc_numlights) - { - pindex = FixedMul(rw.scale, FixedDiv(640, vid.width))>>LIGHTSCALESHIFT; - if (pindex >= MAXLIGHTSCALE) - pindex = MAXLIGHTSCALE-1; - } - //SoM: Calculate offsets for Thick fake floors. // calculate texture offset - angle = (rw.centerangle + xtoviewangle[rw.x])>>ANGLETOFINESHIFT; - texturecolumn = rw.offset-FixedMul(FINETANGENT(angle),rw.distance); + angle = (rw_centerangle + xtoviewangle[rw_x])>>ANGLETOFINESHIFT; + texturecolumn = rw_offset-FixedMul(FINETANGENT(angle),rw_distance); #ifdef ESLOPE if (oldtexturecolumn != -1) { - rw.bottomtexturemid += FixedMul(rw.bottomtextureslide, oldtexturecolumn-texturecolumn); - rw.midtexturemid += FixedMul(rw.midtextureslide, oldtexturecolumn-texturecolumn); - rw.toptexturemid += FixedMul(rw.toptextureslide, oldtexturecolumn-texturecolumn); - rw.midtextureback += FixedMul(rw.midtexturebackslide, oldtexturecolumn-texturecolumn); + rw_bottomtexturemid += FixedMul(rw_bottomtextureslide, oldtexturecolumn-texturecolumn); + rw_midtexturemid += FixedMul(rw_midtextureslide, oldtexturecolumn-texturecolumn); + rw_toptexturemid += FixedMul(rw_toptextureslide, oldtexturecolumn-texturecolumn); + rw_midtextureback += FixedMul(rw_midtexturebackslide, oldtexturecolumn-texturecolumn); } oldtexturecolumn = texturecolumn; #endif @@ -257,9 +1484,15 @@ static void R_RenderSegLoop (void) // texturecolumn and lighting are independent of wall tiers if (segtextured) { + // calculate lighting + pindex = FixedMul(rw_scale, FixedDiv(640, vid.width))>>LIGHTSCALESHIFT; + + if (pindex >= MAXLIGHTSCALE) + pindex = MAXLIGHTSCALE-1; + dc_colormap = walllights[pindex]; - dc_x = rw.x; - dc_iscale = 0xffffffffu / (unsigned)rw.scale; + dc_x = rw_x; + dc_iscale = 0xffffffffu / (unsigned)rw_scale; if (frontsector->extra_colormap) dc_colormap = frontsector->extra_colormap->colormap + (dc_colormap - colormaps); @@ -287,14 +1520,21 @@ static void R_RenderSegLoop (void) else xwalllights = scalelight[lightnum]; + pindex = FixedMul(rw_scale, FixedDiv(640, vid.width))>>LIGHTSCALESHIFT; + + if (pindex >= MAXLIGHTSCALE) + pindex = MAXLIGHTSCALE-1; + if (dc_lightlist[i].extra_colormap) dc_lightlist[i].rcolormap = dc_lightlist[i].extra_colormap->colormap + (xwalllights[pindex] - colormaps); else dc_lightlist[i].rcolormap = xwalllights[pindex]; + + colfunc = colfuncs[COLDRAWFUNC_SHADOWED]; } } - frontscale[rw.x] = rw.scale; + frontscale[rw_x] = rw_scale; // draw the wall tiers if (midtexture) @@ -304,7 +1544,7 @@ static void R_RenderSegLoop (void) { dc_yl = yl; dc_yh = yh; - dc_texturemid = rw.midtexturemid; + dc_texturemid = rw_midtexturemid; dc_source = R_GetColumn(midtexture,texturecolumn); dc_texheight = textureheight[midtexture]>>FRACBITS; @@ -325,16 +1565,16 @@ static void R_RenderSegLoop (void) // dont draw anything more for this column, since // a midtexture blocks the view - ceilingclip[rw.x] = (INT16)viewheight; - floorclip[rw.x] = -1; + ceilingclip[rw_x] = (INT16)viewheight; + floorclip[rw_x] = -1; } else { // note: don't use min/max macros, since casting from INT32 to INT16 is involved here if (markceiling) - ceilingclip[rw.x] = (yl >= 0) ? ((yl > viewheight) ? (INT16)viewheight : (INT16)((INT16)yl - 1)) : -1; + ceilingclip[rw_x] = (yl >= 0) ? ((yl > viewheight) ? (INT16)viewheight : (INT16)((INT16)yl - 1)) : -1; if (markfloor) - floorclip[rw.x] = (yh < viewheight) ? ((yh < -1) ? -1 : (INT16)((INT16)yh + 1)) : (INT16)viewheight; + floorclip[rw_x] = (yh < viewheight) ? ((yh < -1) ? -1 : (INT16)((INT16)yh + 1)) : (INT16)viewheight; } } else @@ -346,31 +1586,31 @@ static void R_RenderSegLoop (void) mid = pixhigh>>HEIGHTBITS; pixhigh += pixhighstep; - if (mid >= floorclip[rw.x]) - mid = floorclip[rw.x]-1; + if (mid >= floorclip[rw_x]) + mid = floorclip[rw_x]-1; if (mid >= yl) // back ceiling lower than front ceiling ? { if (yl >= viewheight) // entirely off bottom of screen - ceilingclip[rw.x] = (INT16)viewheight; + ceilingclip[rw_x] = (INT16)viewheight; else if (mid >= 0) // safe to draw top texture { dc_yl = yl; dc_yh = mid; - dc_texturemid = rw.toptexturemid; + dc_texturemid = rw_toptexturemid; dc_source = R_GetColumn(toptexture,texturecolumn); dc_texheight = textureheight[toptexture]>>FRACBITS; colfunc(); - ceilingclip[rw.x] = (INT16)mid; + ceilingclip[rw_x] = (INT16)mid; } else // entirely off top of screen - ceilingclip[rw.x] = -1; + ceilingclip[rw_x] = -1; } else - ceilingclip[rw.x] = (yl >= 0) ? ((yl > viewheight) ? (INT16)viewheight : (INT16)((INT16)yl - 1)) : -1; + ceilingclip[rw_x] = (yl >= 0) ? ((yl > viewheight) ? (INT16)viewheight : (INT16)((INT16)yl - 1)) : -1; } else if (markceiling) // no top wall - ceilingclip[rw.x] = (yl >= 0) ? ((yl > viewheight) ? (INT16)viewheight : (INT16)((INT16)yl - 1)) : -1; + ceilingclip[rw_x] = (yl >= 0) ? ((yl > viewheight) ? (INT16)viewheight : (INT16)((INT16)yl - 1)) : -1; if (bottomtexture) { @@ -379,45 +1619,45 @@ static void R_RenderSegLoop (void) pixlow += pixlowstep; // no space above wall? - if (mid <= ceilingclip[rw.x]) - mid = ceilingclip[rw.x]+1; + if (mid <= ceilingclip[rw_x]) + mid = ceilingclip[rw_x]+1; if (mid <= yh) // back floor higher than front floor ? { if (yh < 0) // entirely off top of screen - floorclip[rw.x] = -1; + floorclip[rw_x] = -1; else if (mid < viewheight) // safe to draw bottom texture { dc_yl = mid; dc_yh = yh; - dc_texturemid = rw.bottomtexturemid; + dc_texturemid = rw_bottomtexturemid; dc_source = R_GetColumn(bottomtexture, texturecolumn); dc_texheight = textureheight[bottomtexture]>>FRACBITS; colfunc(); - floorclip[rw.x] = (INT16)mid; + floorclip[rw_x] = (INT16)mid; } else // entirely off bottom of screen - floorclip[rw.x] = (INT16)viewheight; + floorclip[rw_x] = (INT16)viewheight; } else - floorclip[rw.x] = (yh < viewheight) ? ((yh < -1) ? -1 : (INT16)((INT16)yh + 1)) : (INT16)viewheight; + floorclip[rw_x] = (yh < viewheight) ? ((yh < -1) ? -1 : (INT16)((INT16)yh + 1)) : (INT16)viewheight; } else if (markfloor) // no bottom wall - floorclip[rw.x] = (yh < viewheight) ? ((yh < -1) ? -1 : (INT16)((INT16)yh + 1)) : (INT16)viewheight; + floorclip[rw_x] = (yh < viewheight) ? ((yh < -1) ? -1 : (INT16)((INT16)yh + 1)) : (INT16)viewheight; } if (maskedtexture || numthicksides) { // save texturecol // for backdrawing of masked mid texture - maskedtexturecol[rw.x] = (INT16)texturecolumn; + maskedtexturecol[rw_x] = (INT16)texturecolumn; #ifdef ESLOPE if (maskedtextureheight != NULL) { - maskedtextureheight[rw.x] = (!!(curline->linedef->flags & ML_DONTPEGBOTTOM) ^ !!(curline->linedef->flags & ML_EFFECT3) ? - max(rw.midtexturemid, rw.midtextureback) : - min(rw.midtexturemid, rw.midtextureback)); + maskedtextureheight[rw_x] = (!!(curline->linedef->flags & ML_DONTPEGBOTTOM) ^ !!(curline->linedef->flags & ML_EFFECT3) ? + max(rw_midtexturemid, rw_midtextureback) : + min(rw_midtexturemid, rw_midtextureback)); } #endif } @@ -437,105 +1677,141 @@ static void R_RenderSegLoop (void) for (i = 0; i < numbackffloors; i++) { - ffloor[i].f_clip[rw.x] = ffloor[i].c_clip[rw.x] = (INT16)((ffloor[i].b_frac >> HEIGHTBITS) & 0xFFFF); + ffloor[i].f_clip[rw_x] = ffloor[i].c_clip[rw_x] = (INT16)((ffloor[i].b_frac >> HEIGHTBITS) & 0xFFFF); ffloor[i].b_frac += ffloor[i].b_step; } - rw.scale += rw.scalestep; + rw_scale += rw_scalestep; topfrac += topstep; bottomfrac += bottomstep; } } -// Macro for slope bullshit -#define SLOPEPARAMS(slope, end1, end2, normalheight) \ - if (slope) { \ - end1 = P_GetZAt(slope, segleft.x, segleft.y); \ - end2 = P_GetZAt(slope, segright.x, segright.y); \ - } else \ - end1 = end2 = normalheight; - -// -// R_CalculateSegDistance -// Calculate the distance from a seg. -// Uses precalculated seg length. -// -static void R_CalculateSegDistance(seg_t *seg, INT64 x2, INT64 y2, boolean longboi) +// Uses precalculated seg->length +static INT64 R_CalcSegDist(seg_t* seg, INT64 x2, INT64 y2) { -#ifdef SOFTWARE_USE_FLOATS - float v1x = FIXED_TO_FLOAT(seg->v1->x); - float v1y = FIXED_TO_FLOAT(seg->v1->y); - float v2x = FIXED_TO_FLOAT(seg->v2->x); - float v2y = FIXED_TO_FLOAT(seg->v2->y); - float dx, dy, vdx, vdy; - float distance = 0.0f; - - // The seg is vertical. if (!seg->linedef->dy) - distance = fabsf(y2 - v1y); - // The seg is horizontal. + return llabs(y2 - seg->v1->y); else if (!seg->linedef->dx) - distance = fabsf(x2 - v1x); - // Uses precalculated seg->flength - else if (longboi) - { - dx = v2x-v1x; - dy = v2y-v1y; - vdx = x2-v1x; - vdy = y2-v1y; - distance = ((dy*vdx)-(dx*vdy))/(seg->flength); - } - // Linguica's fix converted to floating-point math - else - { - fixed_t x, y; - float a, c, ac; - - v1x -= FIXED_TO_FLOAT(viewx); - v1y -= FIXED_TO_FLOAT(viewy); - v2x -= FIXED_TO_FLOAT(viewx); - v2y -= FIXED_TO_FLOAT(viewy); - dx = v2x - v1x; - dy = v2y - v1y; - - a = (v1x*v2y) - (v1y*v2x); - c = (dx*dx) + (dy*dy); - ac = (a/c); - - x = FLOAT_TO_FIXED(ac*(-dy)); - y = FLOAT_TO_FIXED(ac*dx); - - rw.distance = R_PointToDist(viewx + x, viewy + y); - return; - } - - rw.distance = FLOAT_TO_FIXED(distance); -#else - (void)longboi; - if (!seg->linedef->dy) - rw.distance = (fixed_t)(llabs(y2 - seg->v1->y)); - else if (!seg->linedef->dx) - rw.distance = (fixed_t)(llabs(x2 - seg->v1->x)); + return llabs(x2 - seg->v1->x); else { INT64 dx = (seg->v2->x)-(seg->v1->x); INT64 dy = (seg->v2->y)-(seg->v1->y); INT64 vdx = x2-(seg->v1->x); INT64 vdy = y2-(seg->v1->y); - rw.distance = (fixed_t)(((dy*vdx)-(dx*vdy))/(seg->length)); + return ((dy*vdx)-(dx*vdy))/(seg->length); } -#endif } // -// R_CalculateWallScale -// Calculate scale at both ends and step. +// R_StoreWallRange +// A wall segment will be drawn +// between start and stop pixels (inclusive). // -static INT32 R_CalculateWallScale(INT32 start, INT32 stop) +void R_StoreWallRange(INT32 start, INT32 stop) { - INT32 range = 1; + fixed_t hyp; + fixed_t sineval; + angle_t distangle, offsetangle; + boolean longboi; +#ifndef ESLOPE + fixed_t vtop; +#endif + INT32 lightnum; + INT32 i, p; + lightlist_t *light; + r_lightlist_t *rlight; + INT32 range; +#ifdef ESLOPE + vertex_t segleft, segright; + fixed_t ceilingfrontslide, floorfrontslide, ceilingbackslide, floorbackslide; +#endif + static size_t maxdrawsegs = 0; - ds_p->scale1 = rw.scale = R_ScaleFromGlobalAngle(viewangle + xtoviewangle[start]); +#ifdef ESLOPE + maskedtextureheight = NULL; + //initialize segleft and segright + memset(&segleft, 0x00, sizeof(segleft)); + memset(&segright, 0x00, sizeof(segright)); +#endif + + colfunc = colfuncs[BASEDRAWFUNC]; + + if (ds_p == drawsegs+maxdrawsegs) + { + size_t curpos = curdrawsegs - drawsegs; + size_t pos = ds_p - drawsegs; + size_t newmax = maxdrawsegs ? maxdrawsegs*2 : 128; + if (firstseg) + firstseg = (drawseg_t *)(firstseg - drawsegs); + drawsegs = Z_Realloc(drawsegs, newmax*sizeof (*drawsegs), PU_STATIC, NULL); + ds_p = drawsegs + pos; + maxdrawsegs = newmax; + curdrawsegs = drawsegs + curpos; + if (firstseg) + firstseg = drawsegs + (size_t)firstseg; + } + + sidedef = curline->sidedef; + linedef = curline->linedef; + + // calculate rw_distance for scale calculation + rw_normalangle = curline->angle + ANGLE_90; + offsetangle = abs((INT32)(rw_normalangle-rw_angle1)); + + if (offsetangle > ANGLE_90) + offsetangle = ANGLE_90; + + distangle = ANGLE_90 - offsetangle; + sineval = FINESINE(distangle>>ANGLETOFINESHIFT); + + hyp = R_PointToDist(curline->v1->x, curline->v1->y); + rw_distance = FixedMul(hyp, sineval); + longboi = (hyp >= INT32_MAX); + + // big room fix + if (longboi) + rw_distance = (fixed_t)R_CalcSegDist(curline,viewx,viewy); + + ds_p->x1 = rw_x = start; + ds_p->x2 = stop; + ds_p->curline = curline; + rw_stopx = stop+1; + + //SoM: Code to remove limits on openings. + { + size_t pos = lastopening - openings; + size_t need = (rw_stopx - start)*4 + pos; + if (need > maxopenings) + { + drawseg_t *ds; //needed for fix from *cough* zdoom *cough* + INT16 *oldopenings = openings; + INT16 *oldlast = lastopening; + + do + maxopenings = maxopenings ? maxopenings*2 : 16384; + while (need > maxopenings); + openings = Z_Realloc(openings, maxopenings * sizeof (*openings), PU_STATIC, NULL); + lastopening = openings + pos; + + // borrowed fix from *cough* zdoom *cough* + // [RH] We also need to adjust the openings pointers that + // were already stored in drawsegs. + for (ds = drawsegs; ds < ds_p; ds++) + { +#define ADJUST(p) if (ds->p + ds->x1 >= oldopenings && ds->p + ds->x1 <= oldlast) ds->p = ds->p - oldopenings + openings; + ADJUST(maskedtexturecol); + ADJUST(sprtopclip); + ADJUST(sprbottomclip); + ADJUST(thicksidecol); +#undef ADJUST + } + } + } // end of code to remove limits on openings + + // calculate scale at both ends and step + ds_p->scale1 = rw_scale = R_ScaleFromGlobalAngle(viewangle + xtoviewangle[start]); if (stop > start) { @@ -546,7 +1822,7 @@ static INT32 R_CalculateWallScale(INT32 start, INT32 stop) { // UNUSED: try to fix the stretched line bug #if 0 - if (rw.distance < FRACUNIT/2) + if (rw_distance < FRACUNIT/2) { fixed_t tr_x,tr_y; fixed_t gxt,gyt; @@ -561,20 +1837,13 @@ static INT32 R_CalculateWallScale(INT32 start, INT32 stop) } #endif ds_p->scale2 = ds_p->scale1; + range = 1; } - ds_p->scalestep = rw.scalestep = (ds_p->scale2 - rw.scale) / (range); + ds_p->scalestep = rw_scalestep = (ds_p->scale2 - rw_scale) / (range); - return range; -} - -// -// R_WorldTopAndBottom -// Calculate texture boundaries -// and decide if floor or ceiling marks are needed. -// -static void R_WorldTopAndBottom(INT32 start, INT32 stop) -{ + // calculate texture boundaries + // and decide if floor / ceiling marks are needed #ifdef ESLOPE // Figure out map coordinates of where start and end are mapping to on seg, so we can clip right for slope bullshit if (frontsector->hasslope || (backsector && backsector->hasslope)) // Commenting this out for FOFslop. -Red @@ -626,6 +1895,14 @@ static void R_WorldTopAndBottom(INT32 start, INT32 stop) } } + +#define SLOPEPARAMS(slope, end1, end2, normalheight) \ + if (slope) { \ + end1 = P_GetZAt(slope, segleft.x, segleft.y); \ + end2 = P_GetZAt(slope, segright.x, segright.y); \ + } else \ + end1 = end2 = normalheight; + SLOPEPARAMS(frontsector->c_slope, worldtop, worldtopslope, frontsector->ceilingheight) SLOPEPARAMS(frontsector->f_slope, worldbottom, worldbottomslope, frontsector->floorheight) // subtract viewz from these to turn them into @@ -638,350 +1915,60 @@ static void R_WorldTopAndBottom(INT32 start, INT32 stop) worldtop = frontsector->ceilingheight - viewz; worldbottom = frontsector->floorheight - viewz; #endif -} -// -// R_SegTextured -// Calculate rw.offset. -// Only needed for textured lines. -// -static void R_SegTextured(fixed_t hyp, boolean longboi) -{ - INT32 lightnum; - fixed_t sineval; - angle_t offsetangle = rw.normalangle-rw.angle1; + midtexture = toptexture = bottomtexture = maskedtexture = 0; + ds_p->maskedtexturecol = NULL; + ds_p->numthicksides = numthicksides = 0; + ds_p->thicksidecol = NULL; + ds_p->tsilheight = 0; - if (offsetangle > ANGLE_180) - offsetangle = -(signed)offsetangle; - if (offsetangle > ANGLE_90) - offsetangle = ANGLE_90; + numbackffloors = 0; - sineval = FINESINE(offsetangle>>ANGLETOFINESHIFT); - rw.offset = FixedMul(hyp, sineval); + for (i = 0; i < MAXFFLOORS; i++) + ds_p->thicksides[i] = NULL; - // big room fix - if (longboi) + if (numffloors) { - INT64 dx = (curline->v2->x)-(curline->v1->x); - INT64 dy = (curline->v2->y)-(curline->v1->y); - INT64 vdx = viewx-(curline->v1->x); - INT64 vdy = viewy-(curline->v1->y); - rw.offset = ((dx*vdx-dy*vdy))/(curline->length); + for (i = 0; i < numffloors; i++) + { +#ifdef POLYOBJECTS_PLANES + if (ffloor[i].polyobj && (!ds_p->curline->polyseg || ffloor[i].polyobj != ds_p->curline->polyseg)) + continue; +#endif + +#ifdef ESLOPE + if (ffloor[i].slope) { + ffloor[i].f_pos = P_GetZAt(ffloor[i].slope, segleft.x, segleft.y) - viewz; + ffloor[i].f_pos_slope = P_GetZAt(ffloor[i].slope, segright.x, segright.y) - viewz; + } else + ffloor[i].f_pos_slope = +#endif + ffloor[i].f_pos = ffloor[i].height - viewz; + } } - if (rw.normalangle-rw.angle1 < ANGLE_180) - rw.offset = -rw.offset; +#ifdef ESLOPE + // Set up texture Y offset slides for sloped walls + rw_toptextureslide = rw_midtextureslide = rw_bottomtextureslide = 0; + ceilingfrontslide = floorfrontslide = ceilingbackslide = floorbackslide = 0; - /// don't use texture offset for splats - rw.offset2 = rw.offset + curline->offset; - rw.offset += sidedef->textureoffset + curline->offset; - rw.centerangle = ANGLE_90 + viewangle - rw.normalangle; - - // calculate light table - // use different light tables - // for horizontal / vertical / diagonal - // OPTIMIZE: get rid of LIGHTSEGSHIFT globally - lightnum = (frontsector->lightlevel >> LIGHTSEGSHIFT); - - if (curline->v1->y == curline->v2->y) - lightnum--; - else if (curline->v1->x == curline->v2->x) - lightnum++; - - if (lightnum < 0) - walllights = scalelight[0]; - else if (lightnum >= LIGHTLEVELS) - walllights = scalelight[LIGHTLEVELS - 1]; - else - walllights = scalelight[lightnum]; -} - -// -// R_CheckMaskedTextures -// Midtexture stuff, presumably. -// -static void R_CheckMaskedTextures(void) -{ - INT32 i = 0; - // allocate space for masked texture tables - if (frontsector && backsector && frontsector->tag != backsector->tag && (backsector->ffloors || frontsector->ffloors)) { - ffloor_t *rover; - ffloor_t *r2; - fixed_t lowcut, highcut; -#ifdef ESLOPE - fixed_t lowcutslope, highcutslope; + angle_t lineangle = R_PointToAngle2(curline->v1->x, curline->v1->y, curline->v2->x, curline->v2->y); - // Used for height comparisons and etc across FOFs and slopes - fixed_t high1, highslope1, low1, lowslope1, high2, highslope2, low2, lowslope2; -#endif + if (frontsector->f_slope) + floorfrontslide = FixedMul(frontsector->f_slope->zdelta, FINECOSINE((lineangle-frontsector->f_slope->xydirection)>>ANGLETOFINESHIFT)); - //markceiling = markfloor = true; - maskedtexture = true; + if (frontsector->c_slope) + ceilingfrontslide = FixedMul(frontsector->c_slope->zdelta, FINECOSINE((lineangle-frontsector->c_slope->xydirection)>>ANGLETOFINESHIFT)); - ds_p->thicksidecol = maskedtexturecol = lastopening - rw.x; - lastopening += rw.stopx - rw.x; + if (backsector && backsector->f_slope) + floorbackslide = FixedMul(backsector->f_slope->zdelta, FINECOSINE((lineangle-backsector->f_slope->xydirection)>>ANGLETOFINESHIFT)); - lowcut = max(worldbottom, worldlow) + viewz; - highcut = min(worldtop, worldhigh) + viewz; -#ifdef ESLOPE - lowcutslope = max(worldbottomslope, worldlowslope) + viewz; - highcutslope = min(worldtopslope, worldhighslope) + viewz; -#endif - - if (frontsector->ffloors && backsector->ffloors) - { - i = 0; - for (rover = backsector->ffloors; rover && i < MAXFFLOORS; rover = rover->next) - { - if (!(rover->flags & FF_RENDERSIDES) || !(rover->flags & FF_EXISTS)) - continue; - if (rover->flags & FF_INVERTSIDES) - continue; - - if (rover->norender == leveltime) - continue; - -#ifdef ESLOPE - SLOPEPARAMS(*rover->t_slope, high1, highslope1, *rover->topheight) - SLOPEPARAMS(*rover->b_slope, low1, lowslope1, *rover->bottomheight) - - if ((high1 < lowcut && highslope1 < lowcutslope) || (low1 > highcut && lowslope1 > highcutslope)) - continue; -#else - if (*rover->topheight < lowcut || *rover->bottomheight > highcut) - continue; -#endif - - for (r2 = frontsector->ffloors; r2; r2 = r2->next) - { - if (!(r2->flags & FF_EXISTS) || !(r2->flags & FF_RENDERSIDES)) - continue; - - if (r2->norender == leveltime) - continue; - - if (rover->flags & FF_EXTRA) - { - if (!(r2->flags & FF_CUTEXTRA)) - continue; - - if (r2->flags & FF_EXTRA && (r2->flags & (FF_TRANSLUCENT|FF_FOG)) != (rover->flags & (FF_TRANSLUCENT|FF_FOG))) - continue; - } - else - { - if (!(r2->flags & FF_CUTSOLIDS)) - continue; - } - -#ifdef ESLOPE - SLOPEPARAMS(*r2->t_slope, high2, highslope2, *r2->topheight) - SLOPEPARAMS(*r2->b_slope, low2, lowslope2, *r2->bottomheight) - - if ((high2 < lowcut || highslope2 < lowcutslope) || (low2 > highcut || lowslope2 > highcutslope)) - continue; - if ((high1 > high2 || highslope1 > highslope2) || (low1 < low2 || lowslope1 < lowslope2)) - continue; -#else - if (*r2->topheight < lowcut || *r2->bottomheight > highcut) - continue; - if (*rover->topheight > *r2->topheight || *rover->bottomheight < *r2->bottomheight) - continue; -#endif - - break; - } - if (r2) - continue; - - ds_p->thicksides[i] = rover; - i++; - } - - for (rover = frontsector->ffloors; rover && i < MAXFFLOORS; rover = rover->next) - { - if (!(rover->flags & FF_RENDERSIDES) || !(rover->flags & FF_EXISTS)) - continue; - if (!(rover->flags & FF_ALLSIDES)) - continue; - - if (rover->norender == leveltime) - continue; - -#ifdef ESLOPE - SLOPEPARAMS(*rover->t_slope, high1, highslope1, *rover->topheight) - SLOPEPARAMS(*rover->b_slope, low1, lowslope1, *rover->bottomheight) - - if ((high1 < lowcut && highslope1 < lowcutslope) || (low1 > highcut && lowslope1 > highcutslope)) - continue; -#else - if (*rover->topheight < lowcut || *rover->bottomheight > highcut) - continue; -#endif - - for (r2 = backsector->ffloors; r2; r2 = r2->next) - { - if (!(r2->flags & FF_EXISTS) || !(r2->flags & FF_RENDERSIDES)) - continue; - - if (r2->norender == leveltime) - continue; - - if (rover->flags & FF_EXTRA) - { - if (!(r2->flags & FF_CUTEXTRA)) - continue; - - if (r2->flags & FF_EXTRA && (r2->flags & (FF_TRANSLUCENT|FF_FOG)) != (rover->flags & (FF_TRANSLUCENT|FF_FOG))) - continue; - } - else - { - if (!(r2->flags & FF_CUTSOLIDS)) - continue; - } - -#ifdef ESLOPE - SLOPEPARAMS(*r2->t_slope, high2, highslope2, *r2->topheight) - SLOPEPARAMS(*r2->b_slope, low2, lowslope2, *r2->bottomheight) - if ((high2 < lowcut || highslope2 < lowcutslope) || (low2 > highcut || lowslope2 > highcutslope)) - continue; - if ((high1 > high2 || highslope1 > highslope2) || (low1 < low2 || lowslope1 < lowslope2)) - continue; -#else - if (*r2->topheight < lowcut || *r2->bottomheight > highcut) - continue; - if (*rover->topheight > *r2->topheight || *rover->bottomheight < *r2->bottomheight) - continue; -#endif - - break; - } - if (r2) - continue; - - ds_p->thicksides[i] = rover; - i++; - } - } - else if (backsector->ffloors) - { - for (rover = backsector->ffloors, i = 0; rover && i < MAXFFLOORS; rover = rover->next) - { - if (!(rover->flags & FF_RENDERSIDES) || !(rover->flags & FF_EXISTS) || rover->flags & FF_INVERTSIDES) - continue; - if (rover->norender == leveltime) - continue; - -#ifdef ESLOPE - // Oy vey. - if (( (*rover->t_slope ? P_GetZAt(*rover->t_slope, segleft.x, segleft.y) : *rover->topheight) <= worldbottom+viewz - && (*rover->t_slope ? P_GetZAt(*rover->t_slope, segright.x, segright.y) : *rover->topheight) <= worldbottomslope+viewz) - ||((*rover->b_slope ? P_GetZAt(*rover->b_slope, segleft.x, segleft.y) : *rover->bottomheight) >= worldtop+viewz - && (*rover->b_slope ? P_GetZAt(*rover->b_slope, segright.x, segright.y) : *rover->bottomheight) >= worldtopslope+viewz)) - continue; -#else - if (*rover->topheight <= frontsector->floorheight || *rover->bottomheight >= frontsector->ceilingheight) - continue; -#endif - - ds_p->thicksides[i] = rover; - i++; - } - } - else if (frontsector->ffloors) - { - for (rover = frontsector->ffloors, i = 0; rover && i < MAXFFLOORS; rover = rover->next) - { - if (!(rover->flags & FF_RENDERSIDES) || !(rover->flags & FF_EXISTS) || !(rover->flags & FF_ALLSIDES)) - continue; - if (rover->norender == leveltime) - continue; -#ifdef ESLOPE - // Oy vey. - if (( (*rover->t_slope ? P_GetZAt(*rover->t_slope, segleft.x, segleft.y) : *rover->topheight) <= worldbottom+viewz - && (*rover->t_slope ? P_GetZAt(*rover->t_slope, segright.x, segright.y) : *rover->topheight) <= worldbottomslope+viewz) - ||((*rover->b_slope ? P_GetZAt(*rover->b_slope, segleft.x, segleft.y) : *rover->bottomheight) >= worldtop+viewz - && (*rover->b_slope ? P_GetZAt(*rover->b_slope, segright.x, segright.y) : *rover->bottomheight) >= worldtopslope+viewz)) - continue; - - if (( (*rover->t_slope ? P_GetZAt(*rover->t_slope, segleft.x, segleft.y) : *rover->topheight) <= worldlow+viewz - && (*rover->t_slope ? P_GetZAt(*rover->t_slope, segright.x, segright.y) : *rover->topheight) <= worldlowslope+viewz) - ||((*rover->b_slope ? P_GetZAt(*rover->b_slope, segleft.x, segleft.y) : *rover->bottomheight) >= worldhigh+viewz - && (*rover->b_slope ? P_GetZAt(*rover->b_slope, segright.x, segright.y) : *rover->bottomheight) >= worldhighslope+viewz)) - continue; -#else - if (*rover->topheight <= frontsector->floorheight || *rover->bottomheight >= frontsector->ceilingheight) - continue; - if (*rover->topheight <= backsector->floorheight || *rover->bottomheight >= backsector->ceilingheight) - continue; -#endif - - ds_p->thicksides[i] = rover; - i++; - } - } - - ds_p->numthicksides = numthicksides = i; + if (backsector && backsector->c_slope) + ceilingbackslide = FixedMul(backsector->c_slope->zdelta, FINECOSINE((lineangle-backsector->c_slope->xydirection)>>ANGLETOFINESHIFT)); } - - if (sidedef->midtexture > 0 && sidedef->midtexture < numtextures) - { - // masked midtexture - if (!ds_p->thicksidecol) - { - ds_p->maskedtexturecol = maskedtexturecol = lastopening - rw.x; - lastopening += rw.stopx - rw.x; - } - else - ds_p->maskedtexturecol = ds_p->thicksidecol; - -#ifdef ESLOPE - maskedtextureheight = ds_p->maskedtextureheight; // note to red, this == &(ds_p->maskedtextureheight[0]) - -#ifdef POLYOBJECTS - if (curline->polyseg) { // use REAL front and back floors please, so midtexture rendering isn't mucked up - rw.midtextureslide = rw.midtexturebackslide = 0; - if (!!(linedef->flags & ML_DONTPEGBOTTOM) ^ !!(linedef->flags & ML_EFFECT3)) - rw.midtexturemid = rw.midtextureback = max(curline->frontsector->floorheight, curline->backsector->floorheight) - viewz; - else - rw.midtexturemid = rw.midtextureback = min(curline->frontsector->ceilingheight, curline->backsector->ceilingheight) - viewz; - } else -#endif - // Set midtexture starting height - if (linedef->flags & ML_EFFECT2) { // Ignore slopes when texturing - rw.midtextureslide = rw.midtexturebackslide = 0; - if (!!(linedef->flags & ML_DONTPEGBOTTOM) ^ !!(linedef->flags & ML_EFFECT3)) - rw.midtexturemid = rw.midtextureback = max(frontsector->floorheight, backsector->floorheight) - viewz; - else - rw.midtexturemid = rw.midtextureback = min(frontsector->ceilingheight, backsector->ceilingheight) - viewz; - - } else if (!!(linedef->flags & ML_DONTPEGBOTTOM) ^ !!(linedef->flags & ML_EFFECT3)) { - rw.midtexturemid = worldbottom; - rw.midtextureslide = floorfrontslide; - rw.midtextureback = worldlow; - rw.midtexturebackslide = floorbackslide; - } else { - rw.midtexturemid = worldtop; - rw.midtextureslide = ceilingfrontslide; - rw.midtextureback = worldhigh; - rw.midtexturebackslide = ceilingbackslide; - } - rw.midtexturemid += sidedef->rowoffset; - rw.midtextureback += sidedef->rowoffset; #endif - maskedtexture = true; - } -} - -// -// R_CheckWallTextures -// Self-explanatory, I hope?! -// -static void R_CheckWallTextures(void) -{ if (!backsector) { fixed_t texheight; @@ -993,139 +1980,33 @@ static void R_CheckWallTextures(void) #ifdef ESLOPE if (linedef->flags & ML_EFFECT2) { if (linedef->flags & ML_DONTPEGBOTTOM) - rw.midtexturemid = frontsector->floorheight + texheight - viewz; + rw_midtexturemid = frontsector->floorheight + texheight - viewz; else - rw.midtexturemid = frontsector->ceilingheight - viewz; + rw_midtexturemid = frontsector->ceilingheight - viewz; } else #endif if (linedef->flags & ML_DONTPEGBOTTOM) { #ifdef ESLOPE - rw.midtexturemid = worldbottom + texheight; - rw.midtextureslide = floorfrontslide; + rw_midtexturemid = worldbottom + texheight; + rw_midtextureslide = floorfrontslide; #else vtop = frontsector->floorheight + texheight; // bottom of texture at bottom - rw.midtexturemid = vtop - viewz; + rw_midtexturemid = vtop - viewz; #endif } else { // top of texture at top - rw.midtexturemid = worldtop; + rw_midtexturemid = worldtop; #ifdef ESLOPE - rw.midtextureslide = ceilingfrontslide; + rw_midtextureslide = ceilingfrontslide; #endif } - rw.midtexturemid += sidedef->rowoffset; - } - else - { - // check TOP TEXTURE - if (!bothceilingssky // never draw the top texture if on - && (worldhigh < worldtop -#ifdef ESLOPE - || worldhighslope < worldtopslope -#endif - )) - { - fixed_t texheight; - // top texture - if ((linedef->flags & (ML_DONTPEGTOP) && (linedef->flags & ML_DONTPEGBOTTOM)) - && linedef->sidenum[1] != 0xffff) - { - // Special case... use offsets from 2nd side but only if it has a texture. - side_t *def = &sides[linedef->sidenum[1]]; - toptexture = R_GetTextureNum(def->toptexture); + rw_midtexturemid += sidedef->rowoffset; - if (!toptexture) //Second side has no texture, use the first side's instead. - toptexture = R_GetTextureNum(sidedef->toptexture); - texheight = textureheight[toptexture]; - } - else - { - toptexture = R_GetTextureNum(sidedef->toptexture); - texheight = textureheight[toptexture]; - } -#ifdef ESLOPE - if (!(linedef->flags & ML_EFFECT1)) { // Ignore slopes for lower/upper textures unless flag is checked - if (linedef->flags & ML_DONTPEGTOP) - rw.toptexturemid = frontsector->ceilingheight - viewz; - else - rw.toptexturemid = backsector->ceilingheight - viewz; - } else -#endif - if (linedef->flags & ML_DONTPEGTOP) - { - // top of texture at top - rw.toptexturemid = worldtop; -#ifdef ESLOPE - rw.toptextureslide = ceilingfrontslide; -#endif - } - else - { -#ifdef ESLOPE - rw.toptexturemid = worldhigh + texheight; - rw.toptextureslide = ceilingbackslide; -#else - vtop = backsector->ceilingheight + texheight; - // bottom of texture - rw.toptexturemid = vtop - viewz; -#endif - } - } - // check BOTTOM TEXTURE - if (!bothfloorssky // never draw the bottom texture if on - && (worldlow > worldbottom -#ifdef ESLOPE - || worldlowslope > worldbottomslope -#endif - )) //seulement si VISIBLE!!! - { - // bottom texture - bottomtexture = R_GetTextureNum(sidedef->bottomtexture); - -#ifdef ESLOPE - if (!(linedef->flags & ML_EFFECT1)) { // Ignore slopes for lower/upper textures unless flag is checked - if (linedef->flags & ML_DONTPEGBOTTOM) - rw.bottomtexturemid = frontsector->floorheight - viewz; - else - rw.bottomtexturemid = backsector->floorheight - viewz; - } else -#endif - if (linedef->flags & ML_DONTPEGBOTTOM) - { - // bottom of texture at bottom - // top of texture at top - rw.bottomtexturemid = worldbottom; -#ifdef ESLOPE - rw.bottomtextureslide = floorfrontslide; -#endif - } - else { // top of texture at top - rw.bottomtexturemid = worldlow; -#ifdef ESLOPE - rw.bottomtextureslide = floorbackslide; -#endif - } - } - - rw.toptexturemid += sidedef->rowoffset; - rw.bottomtexturemid += sidedef->rowoffset; - } -} - -// -// R_StoreWallSilhouette -// Sets the silhouette for the current seg. -// Also checks if any floors or ceilings have to be marked. -// -static void R_StoreWallSilhouette(void) -{ - if (!backsector) - { ds_p->silhouette = SIL_BOTH; ds_p->sprtopclip = screenheightarray; ds_p->sprbottomclip = negonearray; @@ -1135,8 +2016,8 @@ static void R_StoreWallSilhouette(void) else { // two sided line - bothceilingssky = false; // turned on if both back and front ceilings are sky - bothfloorssky = false; // likewise, but for floors + boolean bothceilingssky = false; // turned on if both back and front ceilings are sky + boolean bothfloorssky = false; // likewise, but for floors #ifdef ESLOPE SLOPEPARAMS(backsector->c_slope, worldhigh, worldhighslope, backsector->ceilingheight) @@ -1359,22 +2240,460 @@ static void R_StoreWallSilhouette(void) markceiling = markfloor = true; } } - } -} -// -// R_WorldStep -// Does... stepping... stuff? -// -static void R_WorldStep(INT32 range) -{ + // check TOP TEXTURE + if (!bothceilingssky // never draw the top texture if on + && (worldhigh < worldtop +#ifdef ESLOPE + || worldhighslope < worldtopslope +#endif + )) + { + fixed_t texheight; + // top texture + if ((linedef->flags & (ML_DONTPEGTOP) && (linedef->flags & ML_DONTPEGBOTTOM)) + && linedef->sidenum[1] != 0xffff) + { + // Special case... use offsets from 2nd side but only if it has a texture. + side_t *def = &sides[linedef->sidenum[1]]; + toptexture = R_GetTextureNum(def->toptexture); + + if (!toptexture) //Second side has no texture, use the first side's instead. + toptexture = R_GetTextureNum(sidedef->toptexture); + texheight = textureheight[toptexture]; + } + else + { + toptexture = R_GetTextureNum(sidedef->toptexture); + texheight = textureheight[toptexture]; + } +#ifdef ESLOPE + if (!(linedef->flags & ML_EFFECT1)) { // Ignore slopes for lower/upper textures unless flag is checked + if (linedef->flags & ML_DONTPEGTOP) + rw_toptexturemid = frontsector->ceilingheight - viewz; + else + rw_toptexturemid = backsector->ceilingheight - viewz; + } else +#endif + if (linedef->flags & ML_DONTPEGTOP) + { + // top of texture at top + rw_toptexturemid = worldtop; +#ifdef ESLOPE + rw_toptextureslide = ceilingfrontslide; +#endif + } + else + { +#ifdef ESLOPE + rw_toptexturemid = worldhigh + texheight; + rw_toptextureslide = ceilingbackslide; +#else + vtop = backsector->ceilingheight + texheight; + // bottom of texture + rw_toptexturemid = vtop - viewz; +#endif + } + } + // check BOTTOM TEXTURE + if (!bothfloorssky // never draw the bottom texture if on + && (worldlow > worldbottom +#ifdef ESLOPE + || worldlowslope > worldbottomslope +#endif + )) //seulement si VISIBLE!!! + { + // bottom texture + bottomtexture = R_GetTextureNum(sidedef->bottomtexture); + +#ifdef ESLOPE + if (!(linedef->flags & ML_EFFECT1)) { // Ignore slopes for lower/upper textures unless flag is checked + if (linedef->flags & ML_DONTPEGBOTTOM) + rw_bottomtexturemid = frontsector->floorheight - viewz; + else + rw_bottomtexturemid = backsector->floorheight - viewz; + } else +#endif + if (linedef->flags & ML_DONTPEGBOTTOM) + { + // bottom of texture at bottom + // top of texture at top + rw_bottomtexturemid = worldbottom; +#ifdef ESLOPE + rw_bottomtextureslide = floorfrontslide; +#endif + } + else { // top of texture at top + rw_bottomtexturemid = worldlow; +#ifdef ESLOPE + rw_bottomtextureslide = floorbackslide; +#endif + } + } + + rw_toptexturemid += sidedef->rowoffset; + rw_bottomtexturemid += sidedef->rowoffset; + + // allocate space for masked texture tables + if (frontsector && backsector && frontsector->tag != backsector->tag && (backsector->ffloors || frontsector->ffloors)) + { + ffloor_t *rover; + ffloor_t *r2; + fixed_t lowcut, highcut; +#ifdef ESLOPE + fixed_t lowcutslope, highcutslope; + + // Used for height comparisons and etc across FOFs and slopes + fixed_t high1, highslope1, low1, lowslope1, high2, highslope2, low2, lowslope2; +#endif + + //markceiling = markfloor = true; + maskedtexture = true; + + ds_p->thicksidecol = maskedtexturecol = lastopening - rw_x; + lastopening += rw_stopx - rw_x; + + lowcut = max(worldbottom, worldlow) + viewz; + highcut = min(worldtop, worldhigh) + viewz; +#ifdef ESLOPE + lowcutslope = max(worldbottomslope, worldlowslope) + viewz; + highcutslope = min(worldtopslope, worldhighslope) + viewz; +#endif + + if (frontsector->ffloors && backsector->ffloors) + { + i = 0; + for (rover = backsector->ffloors; rover && i < MAXFFLOORS; rover = rover->next) + { + if (!(rover->flags & FF_RENDERSIDES) || !(rover->flags & FF_EXISTS)) + continue; + if (rover->flags & FF_INVERTSIDES) + continue; + + if (rover->norender == leveltime) + continue; + +#ifdef ESLOPE + SLOPEPARAMS(*rover->t_slope, high1, highslope1, *rover->topheight) + SLOPEPARAMS(*rover->b_slope, low1, lowslope1, *rover->bottomheight) + + if ((high1 < lowcut && highslope1 < lowcutslope) || (low1 > highcut && lowslope1 > highcutslope)) + continue; +#else + if (*rover->topheight < lowcut || *rover->bottomheight > highcut) + continue; +#endif + + for (r2 = frontsector->ffloors; r2; r2 = r2->next) + { + if (!(r2->flags & FF_EXISTS) || !(r2->flags & FF_RENDERSIDES)) + continue; + + if (r2->norender == leveltime) + continue; + + if (rover->flags & FF_EXTRA) + { + if (!(r2->flags & FF_CUTEXTRA)) + continue; + + if (r2->flags & FF_EXTRA && (r2->flags & (FF_TRANSLUCENT|FF_FOG)) != (rover->flags & (FF_TRANSLUCENT|FF_FOG))) + continue; + } + else + { + if (!(r2->flags & FF_CUTSOLIDS)) + continue; + } + +#ifdef ESLOPE + SLOPEPARAMS(*r2->t_slope, high2, highslope2, *r2->topheight) + SLOPEPARAMS(*r2->b_slope, low2, lowslope2, *r2->bottomheight) + + if ((high2 < lowcut || highslope2 < lowcutslope) || (low2 > highcut || lowslope2 > highcutslope)) + continue; + if ((high1 > high2 || highslope1 > highslope2) || (low1 < low2 || lowslope1 < lowslope2)) + continue; +#else + if (*r2->topheight < lowcut || *r2->bottomheight > highcut) + continue; + if (*rover->topheight > *r2->topheight || *rover->bottomheight < *r2->bottomheight) + continue; +#endif + + break; + } + if (r2) + continue; + + ds_p->thicksides[i] = rover; + i++; + } + + for (rover = frontsector->ffloors; rover && i < MAXFFLOORS; rover = rover->next) + { + if (!(rover->flags & FF_RENDERSIDES) || !(rover->flags & FF_EXISTS)) + continue; + if (!(rover->flags & FF_ALLSIDES)) + continue; + + if (rover->norender == leveltime) + continue; + +#ifdef ESLOPE + SLOPEPARAMS(*rover->t_slope, high1, highslope1, *rover->topheight) + SLOPEPARAMS(*rover->b_slope, low1, lowslope1, *rover->bottomheight) + + if ((high1 < lowcut && highslope1 < lowcutslope) || (low1 > highcut && lowslope1 > highcutslope)) + continue; +#else + if (*rover->topheight < lowcut || *rover->bottomheight > highcut) + continue; +#endif + + for (r2 = backsector->ffloors; r2; r2 = r2->next) + { + if (!(r2->flags & FF_EXISTS) || !(r2->flags & FF_RENDERSIDES)) + continue; + + if (r2->norender == leveltime) + continue; + + if (rover->flags & FF_EXTRA) + { + if (!(r2->flags & FF_CUTEXTRA)) + continue; + + if (r2->flags & FF_EXTRA && (r2->flags & (FF_TRANSLUCENT|FF_FOG)) != (rover->flags & (FF_TRANSLUCENT|FF_FOG))) + continue; + } + else + { + if (!(r2->flags & FF_CUTSOLIDS)) + continue; + } + +#ifdef ESLOPE + SLOPEPARAMS(*r2->t_slope, high2, highslope2, *r2->topheight) + SLOPEPARAMS(*r2->b_slope, low2, lowslope2, *r2->bottomheight) +#undef SLOPEPARAMS + if ((high2 < lowcut || highslope2 < lowcutslope) || (low2 > highcut || lowslope2 > highcutslope)) + continue; + if ((high1 > high2 || highslope1 > highslope2) || (low1 < low2 || lowslope1 < lowslope2)) + continue; +#else + if (*r2->topheight < lowcut || *r2->bottomheight > highcut) + continue; + if (*rover->topheight > *r2->topheight || *rover->bottomheight < *r2->bottomheight) + continue; +#endif + + break; + } + if (r2) + continue; + + ds_p->thicksides[i] = rover; + i++; + } + } + else if (backsector->ffloors) + { + for (rover = backsector->ffloors, i = 0; rover && i < MAXFFLOORS; rover = rover->next) + { + if (!(rover->flags & FF_RENDERSIDES) || !(rover->flags & FF_EXISTS) || rover->flags & FF_INVERTSIDES) + continue; + if (rover->norender == leveltime) + continue; + +#ifdef ESLOPE + // Oy vey. + if (( (*rover->t_slope ? P_GetZAt(*rover->t_slope, segleft.x, segleft.y) : *rover->topheight) <= worldbottom+viewz + && (*rover->t_slope ? P_GetZAt(*rover->t_slope, segright.x, segright.y) : *rover->topheight) <= worldbottomslope+viewz) + ||((*rover->b_slope ? P_GetZAt(*rover->b_slope, segleft.x, segleft.y) : *rover->bottomheight) >= worldtop+viewz + && (*rover->b_slope ? P_GetZAt(*rover->b_slope, segright.x, segright.y) : *rover->bottomheight) >= worldtopslope+viewz)) + continue; +#else + if (*rover->topheight <= frontsector->floorheight || *rover->bottomheight >= frontsector->ceilingheight) + continue; +#endif + + ds_p->thicksides[i] = rover; + i++; + } + } + else if (frontsector->ffloors) + { + for (rover = frontsector->ffloors, i = 0; rover && i < MAXFFLOORS; rover = rover->next) + { + if (!(rover->flags & FF_RENDERSIDES) || !(rover->flags & FF_EXISTS) || !(rover->flags & FF_ALLSIDES)) + continue; + if (rover->norender == leveltime) + continue; +#ifdef ESLOPE + // Oy vey. + if (( (*rover->t_slope ? P_GetZAt(*rover->t_slope, segleft.x, segleft.y) : *rover->topheight) <= worldbottom+viewz + && (*rover->t_slope ? P_GetZAt(*rover->t_slope, segright.x, segright.y) : *rover->topheight) <= worldbottomslope+viewz) + ||((*rover->b_slope ? P_GetZAt(*rover->b_slope, segleft.x, segleft.y) : *rover->bottomheight) >= worldtop+viewz + && (*rover->b_slope ? P_GetZAt(*rover->b_slope, segright.x, segright.y) : *rover->bottomheight) >= worldtopslope+viewz)) + continue; + + if (( (*rover->t_slope ? P_GetZAt(*rover->t_slope, segleft.x, segleft.y) : *rover->topheight) <= worldlow+viewz + && (*rover->t_slope ? P_GetZAt(*rover->t_slope, segright.x, segright.y) : *rover->topheight) <= worldlowslope+viewz) + ||((*rover->b_slope ? P_GetZAt(*rover->b_slope, segleft.x, segleft.y) : *rover->bottomheight) >= worldhigh+viewz + && (*rover->b_slope ? P_GetZAt(*rover->b_slope, segright.x, segright.y) : *rover->bottomheight) >= worldhighslope+viewz)) + continue; +#else + if (*rover->topheight <= frontsector->floorheight || *rover->bottomheight >= frontsector->ceilingheight) + continue; + if (*rover->topheight <= backsector->floorheight || *rover->bottomheight >= backsector->ceilingheight) + continue; +#endif + + ds_p->thicksides[i] = rover; + i++; + } + } + + ds_p->numthicksides = numthicksides = i; + } + if (sidedef->midtexture > 0 && sidedef->midtexture < numtextures) + { + // masked midtexture + if (!ds_p->thicksidecol) + { + ds_p->maskedtexturecol = maskedtexturecol = lastopening - rw_x; + lastopening += rw_stopx - rw_x; + } + else + ds_p->maskedtexturecol = ds_p->thicksidecol; + +#ifdef ESLOPE + maskedtextureheight = ds_p->maskedtextureheight; // note to red, this == &(ds_p->maskedtextureheight[0]) + +#ifdef POLYOBJECTS + if (curline->polyseg) { // use REAL front and back floors please, so midtexture rendering isn't mucked up + rw_midtextureslide = rw_midtexturebackslide = 0; + if (!!(linedef->flags & ML_DONTPEGBOTTOM) ^ !!(linedef->flags & ML_EFFECT3)) + rw_midtexturemid = rw_midtextureback = max(curline->frontsector->floorheight, curline->backsector->floorheight) - viewz; + else + rw_midtexturemid = rw_midtextureback = min(curline->frontsector->ceilingheight, curline->backsector->ceilingheight) - viewz; + } else +#endif + // Set midtexture starting height + if (linedef->flags & ML_EFFECT2) { // Ignore slopes when texturing + rw_midtextureslide = rw_midtexturebackslide = 0; + if (!!(linedef->flags & ML_DONTPEGBOTTOM) ^ !!(linedef->flags & ML_EFFECT3)) + rw_midtexturemid = rw_midtextureback = max(frontsector->floorheight, backsector->floorheight) - viewz; + else + rw_midtexturemid = rw_midtextureback = min(frontsector->ceilingheight, backsector->ceilingheight) - viewz; + + } else if (!!(linedef->flags & ML_DONTPEGBOTTOM) ^ !!(linedef->flags & ML_EFFECT3)) { + rw_midtexturemid = worldbottom; + rw_midtextureslide = floorfrontslide; + rw_midtextureback = worldlow; + rw_midtexturebackslide = floorbackslide; + } else { + rw_midtexturemid = worldtop; + rw_midtextureslide = ceilingfrontslide; + rw_midtextureback = worldhigh; + rw_midtexturebackslide = ceilingbackslide; + } + rw_midtexturemid += sidedef->rowoffset; + rw_midtextureback += sidedef->rowoffset; +#endif + + maskedtexture = true; + } + } + + // calculate rw_offset (only needed for textured lines) + segtextured = midtexture || toptexture || bottomtexture || maskedtexture || (numthicksides > 0); + + if (segtextured) + { + offsetangle = rw_normalangle-rw_angle1; + + if (offsetangle > ANGLE_180) + offsetangle = -(signed)offsetangle; + + if (offsetangle > ANGLE_90) + offsetangle = ANGLE_90; + + sineval = FINESINE(offsetangle>>ANGLETOFINESHIFT); + rw_offset = FixedMul(hyp, sineval); + + // big room fix + if (longboi) + { + INT64 dx = (curline->v2->x)-(curline->v1->x); + INT64 dy = (curline->v2->y)-(curline->v1->y); + INT64 vdx = viewx-(curline->v1->x); + INT64 vdy = viewy-(curline->v1->y); + rw_offset = ((dx*vdx-dy*vdy))/(curline->length); + } + + if (rw_normalangle-rw_angle1 < ANGLE_180) + rw_offset = -rw_offset; + + /// don't use texture offset for splats + rw_offset2 = rw_offset + curline->offset; + rw_offset += sidedef->textureoffset + curline->offset; + rw_centerangle = ANGLE_90 + viewangle - rw_normalangle; + + // calculate light table + // use different light tables + // for horizontal / vertical / diagonal + // OPTIMIZE: get rid of LIGHTSEGSHIFT globally + lightnum = (frontsector->lightlevel >> LIGHTSEGSHIFT); + + if (curline->v1->y == curline->v2->y) + lightnum--; + else if (curline->v1->x == curline->v2->x) + lightnum++; + + if (lightnum < 0) + walllights = scalelight[0]; + else if (lightnum >= LIGHTLEVELS) + walllights = scalelight[LIGHTLEVELS - 1]; + else + walllights = scalelight[lightnum]; + } + + // if a floor / ceiling plane is on the wrong side + // of the view plane, it is definitely invisible + // and doesn't need to be marked. + if (frontsector->heightsec == -1) + { + if (frontsector->floorpic != skyflatnum + && ( +#ifdef ESLOPE + frontsector->f_slope ? P_GetZAt(frontsector->f_slope, viewx, viewy) : +#endif + frontsector->floorheight) >= viewz) + { + // above view plane + markfloor = false; + } + + if (frontsector->ceilingpic != skyflatnum + && ( +#ifdef ESLOPE + frontsector->c_slope ? P_GetZAt(frontsector->c_slope, viewx, viewy) : +#endif + frontsector->ceilingheight) <= viewz) + { + // below view plane + markceiling = false; + } + } + + // calculate incremental stepping values for texture edges worldtop >>= 4; worldbottom >>= 4; #ifdef ESLOPE worldtopslope >>= 4; worldbottomslope >>= 4; -#else - (void)range; #endif if (linedef->special == HORIZONSPECIAL) { // HORIZON LINES @@ -1382,11 +2701,11 @@ static void R_WorldStep(INT32 range) topfrac = bottomfrac = (centeryfrac>>4); topfrac++; // Prevent 1px HOM } else { - topstep = -FixedMul (rw.scalestep, worldtop); - topfrac = (centeryfrac>>4) - FixedMul (worldtop, rw.scale); + topstep = -FixedMul (rw_scalestep, worldtop); + topfrac = (centeryfrac>>4) - FixedMul (worldtop, rw_scale); - bottomstep = -FixedMul (rw.scalestep,worldbottom); - bottomfrac = (centeryfrac>>4) - FixedMul (worldbottom, rw.scale); + bottomstep = -FixedMul (rw_scalestep,worldbottom); + bottomfrac = (centeryfrac>>4) - FixedMul (worldbottom, rw_scale); #ifdef ESLOPE if (frontsector->c_slope) { @@ -1399,329 +2718,6 @@ static void R_WorldStep(INT32 range) } #endif } -} - -// -// R_WorldBackStep -// Does... stepping... stuff? For backsides?!?!?!?!?!?! -// -static void R_WorldBackStep(INT32 range) -{ - INT32 i; - - worldhigh >>= 4; - worldlow >>= 4; -#ifdef ESLOPE - worldhighslope >>= 4; - worldlowslope >>= 4; -#else - (void)range; -#endif - - if (toptexture) - { - pixhigh = (centeryfrac>>4) - FixedMul (worldhigh, rw.scale); - pixhighstep = -FixedMul (rw.scalestep,worldhigh); - -#ifdef ESLOPE - if (backsector->c_slope) { - fixed_t topfracend = (centeryfrac>>4) - FixedMul (worldhighslope, ds_p->scale2); - pixhighstep = (topfracend-pixhigh)/(range); - } -#endif - } - - if (bottomtexture) - { - pixlow = (centeryfrac>>4) - FixedMul (worldlow, rw.scale); - pixlowstep = -FixedMul (rw.scalestep,worldlow); -#ifdef ESLOPE - if (backsector->f_slope) { - fixed_t bottomfracend = (centeryfrac>>4) - FixedMul (worldlowslope, ds_p->scale2); - pixlowstep = (bottomfracend-pixlow)/(range); - } -#endif - } - - { - ffloor_t * rover; -#ifdef ESLOPE - fixed_t roverleft, roverright; - fixed_t planevistest; -#endif - i = 0; - - if (backsector->ffloors) - { - for (rover = backsector->ffloors; rover && i < MAXFFLOORS; rover = rover->next) - { - if (!(rover->flags & FF_EXISTS) || !(rover->flags & FF_RENDERPLANES)) - continue; - if (rover->norender == leveltime) - continue; - -#ifdef ESLOPE - // Let the renderer know this sector is sloped. - if (*rover->b_slope || *rover->t_slope) - backsector->hasslope = true; - - roverleft = (*rover->b_slope ? P_GetZAt(*rover->b_slope, segleft.x, segleft.y) : *rover->bottomheight) - viewz; - roverright = (*rover->b_slope ? P_GetZAt(*rover->b_slope, segright.x, segright.y) : *rover->bottomheight) - viewz; - planevistest = (*rover->b_slope ? P_GetZAt(*rover->b_slope, viewx, viewy) : *rover->bottomheight); - - if ((roverleft>>4 <= worldhigh || roverright>>4 <= worldhighslope) && - (roverleft>>4 >= worldlow || roverright>>4 >= worldlowslope) && - ((viewz < planevistest && !(rover->flags & FF_INVERTPLANES)) || - (viewz > planevistest && (rover->flags & FF_BOTHPLANES)))) - { - //ffloor[i].slope = *rover->b_slope; - ffloor[i].b_pos = roverleft; - ffloor[i].b_pos_slope = roverright; - ffloor[i].b_pos >>= 4; - ffloor[i].b_pos_slope >>= 4; - ffloor[i].b_frac = (centeryfrac >> 4) - FixedMul(ffloor[i].b_pos, rw.scale); - ffloor[i].b_step = (centeryfrac >> 4) - FixedMul(ffloor[i].b_pos_slope, ds_p->scale2); - ffloor[i].b_step = (ffloor[i].b_step-ffloor[i].b_frac)/(range); - i++; - } - - if (i >= MAXFFLOORS) - break; - - roverleft = (*rover->t_slope ? P_GetZAt(*rover->t_slope, segleft.x, segleft.y) : *rover->topheight) - viewz; - roverright = (*rover->t_slope ? P_GetZAt(*rover->t_slope, segright.x, segright.y) : *rover->topheight) - viewz; - planevistest = (*rover->t_slope ? P_GetZAt(*rover->t_slope, viewx, viewy) : *rover->topheight); - - if ((roverleft>>4 <= worldhigh || roverright>>4 <= worldhighslope) && - (roverleft>>4 >= worldlow || roverright>>4 >= worldlowslope) && - ((viewz > planevistest && !(rover->flags & FF_INVERTPLANES)) || - (viewz < planevistest && (rover->flags & FF_BOTHPLANES)))) - { - //ffloor[i].slope = *rover->t_slope; - ffloor[i].b_pos = roverleft; - ffloor[i].b_pos_slope = roverright; - ffloor[i].b_pos >>= 4; - ffloor[i].b_pos_slope >>= 4; - ffloor[i].b_frac = (centeryfrac >> 4) - FixedMul(ffloor[i].b_pos, rw.scale); - ffloor[i].b_step = (centeryfrac >> 4) - FixedMul(ffloor[i].b_pos_slope, ds_p->scale2); - ffloor[i].b_step = (ffloor[i].b_step-ffloor[i].b_frac)/(range); - i++; - } -#else - if (*rover->bottomheight <= backsector->ceilingheight && - *rover->bottomheight >= backsector->floorheight && - ((viewz < *rover->bottomheight && !(rover->flags & FF_INVERTPLANES)) || - (viewz > *rover->bottomheight && (rover->flags & FF_BOTHPLANES)))) - { - ffloor[i].b_pos = *rover->bottomheight; - ffloor[i].b_pos = (ffloor[i].b_pos - viewz) >> 4; - ffloor[i].b_step = FixedMul(-rw.scalestep, ffloor[i].b_pos); - ffloor[i].b_frac = (centeryfrac >> 4) - FixedMul(ffloor[i].b_pos, rw.scale); - i++; - } - - if (i >= MAXFFLOORS) - break; - - if (*rover->topheight >= backsector->floorheight && - *rover->topheight <= backsector->ceilingheight && - ((viewz > *rover->topheight && !(rover->flags & FF_INVERTPLANES)) || - (viewz < *rover->topheight && (rover->flags & FF_BOTHPLANES)))) - { - ffloor[i].b_pos = *rover->topheight; - ffloor[i].b_pos = (ffloor[i].b_pos - viewz) >> 4; - ffloor[i].b_step = FixedMul(-rw.scalestep, ffloor[i].b_pos); - ffloor[i].b_frac = (centeryfrac >> 4) - FixedMul(ffloor[i].b_pos, rw.scale); - i++; - } -#endif - } - } - else if (frontsector && frontsector->ffloors) - { - for (rover = frontsector->ffloors; rover && i < MAXFFLOORS; rover = rover->next) - { - if (!(rover->flags & FF_EXISTS) || !(rover->flags & FF_RENDERPLANES)) - continue; - if (rover->norender == leveltime) - continue; - - -#ifdef ESLOPE - // Let the renderer know this sector is sloped. - if (*rover->b_slope || *rover->t_slope) - frontsector->hasslope = true; - - roverleft = (*rover->b_slope ? P_GetZAt(*rover->b_slope, segleft.x, segleft.y) : *rover->bottomheight) - viewz; - roverright = (*rover->b_slope ? P_GetZAt(*rover->b_slope, segright.x, segright.y) : *rover->bottomheight) - viewz; - planevistest = (*rover->b_slope ? P_GetZAt(*rover->b_slope, viewx, viewy) : *rover->bottomheight); - - if ((roverleft>>4 <= worldhigh || roverright>>4 <= worldhighslope) && - (roverleft>>4 >= worldlow || roverright>>4 >= worldlowslope) && - ((viewz < planevistest && !(rover->flags & FF_INVERTPLANES)) || - (viewz > planevistest && (rover->flags & FF_BOTHPLANES)))) - { - //ffloor[i].slope = *rover->b_slope; - ffloor[i].b_pos = roverleft; - ffloor[i].b_pos_slope = roverright; - ffloor[i].b_pos >>= 4; - ffloor[i].b_pos_slope >>= 4; - ffloor[i].b_frac = (centeryfrac >> 4) - FixedMul(ffloor[i].b_pos, rw.scale); - ffloor[i].b_step = (centeryfrac >> 4) - FixedMul(ffloor[i].b_pos_slope, ds_p->scale2); - ffloor[i].b_step = (ffloor[i].b_step-ffloor[i].b_frac)/(range); - i++; - } - - if (i >= MAXFFLOORS) - break; - - roverleft = (*rover->t_slope ? P_GetZAt(*rover->t_slope, segleft.x, segleft.y) : *rover->topheight) - viewz; - roverright = (*rover->t_slope ? P_GetZAt(*rover->t_slope, segright.x, segright.y) : *rover->topheight) - viewz; - planevistest = (*rover->t_slope ? P_GetZAt(*rover->t_slope, viewx, viewy) : *rover->topheight); - - if ((roverleft>>4 <= worldhigh || roverright>>4 <= worldhighslope) && - (roverleft>>4 >= worldlow || roverright>>4 >= worldlowslope) && - ((viewz > planevistest && !(rover->flags & FF_INVERTPLANES)) || - (viewz < planevistest && (rover->flags & FF_BOTHPLANES)))) - { - //ffloor[i].slope = *rover->t_slope; - ffloor[i].b_pos = roverleft; - ffloor[i].b_pos_slope = roverright; - ffloor[i].b_pos >>= 4; - ffloor[i].b_pos_slope >>= 4; - ffloor[i].b_frac = (centeryfrac >> 4) - FixedMul(ffloor[i].b_pos, rw.scale); - ffloor[i].b_step = (centeryfrac >> 4) - FixedMul(ffloor[i].b_pos_slope, ds_p->scale2); - ffloor[i].b_step = (ffloor[i].b_step-ffloor[i].b_frac)/(range); - i++; - } -#else - if (*rover->bottomheight <= frontsector->ceilingheight && - *rover->bottomheight >= frontsector->floorheight && - ((viewz < *rover->bottomheight && !(rover->flags & FF_INVERTPLANES)) || - (viewz > *rover->bottomheight && (rover->flags & FF_BOTHPLANES)))) - { - ffloor[i].b_pos = *rover->bottomheight; - ffloor[i].b_pos = (ffloor[i].b_pos - viewz) >> 4; - ffloor[i].b_step = FixedMul(-rw.scalestep, ffloor[i].b_pos); - ffloor[i].b_frac = (centeryfrac >> 4) - FixedMul(ffloor[i].b_pos, rw.scale); - i++; - } - if (i >= MAXFFLOORS) - break; - if (*rover->topheight >= frontsector->floorheight && - *rover->topheight <= frontsector->ceilingheight && - ((viewz > *rover->topheight && !(rover->flags & FF_INVERTPLANES)) || - (viewz < *rover->topheight && (rover->flags & FF_BOTHPLANES)))) - { - ffloor[i].b_pos = *rover->topheight; - ffloor[i].b_pos = (ffloor[i].b_pos - viewz) >> 4; - ffloor[i].b_step = FixedMul(-rw.scalestep, ffloor[i].b_pos); - ffloor[i].b_frac = (centeryfrac >> 4) - FixedMul(ffloor[i].b_pos, rw.scale); - i++; - } -#endif - } - } - -#ifdef POLYOBJECTS_PLANES - if (curline->polyseg && frontsector && (curline->polyseg->flags & POF_RENDERPLANES)) - { - while (i < numffloors && ffloor[i].polyobj != curline->polyseg) i++; - if (i < numffloors && backsector->floorheight <= frontsector->ceilingheight && - backsector->floorheight >= frontsector->floorheight && - (viewz < backsector->floorheight)) - { - if (ffloor[i].plane->minx > ds_p->x1) - ffloor[i].plane->minx = ds_p->x1; - - if (ffloor[i].plane->maxx < ds_p->x2) - ffloor[i].plane->maxx = ds_p->x2; - -#ifdef ESLOPE - ffloor[i].slope = NULL; -#endif - ffloor[i].b_pos = backsector->floorheight; - ffloor[i].b_pos = (ffloor[i].b_pos - viewz) >> 4; - ffloor[i].b_step = FixedMul(-rw.scalestep, ffloor[i].b_pos); - ffloor[i].b_frac = (centeryfrac >> 4) - FixedMul(ffloor[i].b_pos, rw.scale); - i++; - } - if (i < numffloors && backsector->ceilingheight >= frontsector->floorheight && - backsector->ceilingheight <= frontsector->ceilingheight && - (viewz > backsector->ceilingheight)) - { - if (ffloor[i].plane->minx > ds_p->x1) - ffloor[i].plane->minx = ds_p->x1; - - if (ffloor[i].plane->maxx < ds_p->x2) - ffloor[i].plane->maxx = ds_p->x2; - -#ifdef ESLOPE - ffloor[i].slope = NULL; -#endif - ffloor[i].b_pos = backsector->ceilingheight; - ffloor[i].b_pos = (ffloor[i].b_pos - viewz) >> 4; - ffloor[i].b_step = FixedMul(-rw.scalestep, ffloor[i].b_pos); - ffloor[i].b_frac = (centeryfrac >> 4) - FixedMul(ffloor[i].b_pos, rw.scale); - i++; - } - } -#endif - - numbackffloors = i; - } -} - -// -// R_WorldFFloorStep -// Does... stepping... stuff? For FOFs?! -// -static void R_WorldFFloorStep(INT32 range) -{ - INT32 i; - -#ifndef ESLOPE - (void)range; // Not needed! -#endif - - for (i = 0; i < numffloors; i++) - { - ffloor[i].f_pos >>= 4; -#ifdef ESLOPE - ffloor[i].f_pos_slope >>= 4; -#endif - if (linedef->special == HORIZONSPECIAL) // Horizon lines extend FOFs in contact with them too. - { - ffloor[i].f_step = 0; - ffloor[i].f_frac = (centeryfrac>>4); - topfrac++; // Prevent 1px HOM - } - else - { -#ifdef ESLOPE - ffloor[i].f_frac = (centeryfrac>>4) - FixedMul(ffloor[i].f_pos, rw.scale); - ffloor[i].f_step = ((centeryfrac>>4) - FixedMul(ffloor[i].f_pos_slope, ds_p->scale2) - ffloor[i].f_frac)/(range); -#else - ffloor[i].f_step = FixedMul(-rw.scalestep, ffloor[i].f_pos); - ffloor[i].f_frac = (centeryfrac>>4) - FixedMul(ffloor[i].f_pos, rw.scale); -#endif - } - } -} - -// -// R_WorldLightLists -// Creates light lists. -// -static void R_WorldLightLists(INT32 range) -{ - INT32 i, p; - lightlist_t *light; - r_lightlist_t *rlight; - -#ifndef ESLOPE - (void)range; // Not needed! -#endif dc_numlights = 0; @@ -1778,12 +2774,12 @@ static void R_WorldLightLists(INT32 range) } #ifdef ESLOPE - rlight->height = (centeryfrac>>4) - FixedMul(leftheight, rw.scale); + rlight->height = (centeryfrac>>4) - FixedMul(leftheight, rw_scale); rlight->heightstep = (centeryfrac>>4) - FixedMul(rightheight, ds_p->scale2); rlight->heightstep = (rlight->heightstep-rlight->height)/(range); #else - rlight->height = (centeryfrac>>4) - FixedMul((light->height - viewz) >> 4, rw.scale); - rlight->heightstep = -FixedMul (rw.scalestep, (light->height - viewz) >> 4); + rlight->height = (centeryfrac>>4) - FixedMul((light->height - viewz) >> 4, rw_scale); + rlight->heightstep = -FixedMul (rw_scalestep, (light->height - viewz) >> 4); #endif rlight->flags = light->flags; @@ -1805,13 +2801,13 @@ static void R_WorldLightLists(INT32 range) leftheight >>= 4; rightheight >>= 4; - rlight->botheight = (centeryfrac>>4) - FixedMul(leftheight, rw.scale); + rlight->botheight = (centeryfrac>>4) - FixedMul(leftheight, rw_scale); rlight->botheightstep = (centeryfrac>>4) - FixedMul(rightheight, ds_p->scale2); rlight->botheightstep = (rlight->botheightstep-rlight->botheight)/(range); #else - rlight->botheight = (centeryfrac >> 4) - FixedMul((*light->caster->bottomheight - viewz) >> 4, rw.scale); - rlight->botheightstep = -FixedMul (rw.scalestep, (*light->caster->bottomheight - viewz) >> 4); + rlight->botheight = (centeryfrac >> 4) - FixedMul((*light->caster->bottomheight - viewz) >> 4, rw_scale); + rlight->botheightstep = -FixedMul (rw_scalestep, (*light->caster->bottomheight - viewz) >> 4); #endif } @@ -1822,21 +2818,301 @@ static void R_WorldLightLists(INT32 range) dc_numlights = p; } -} -// -// R_MarkPlanes -// Creates visplanes. -// -static void R_MarkPlanes(void) -{ - INT32 i; + if (numffloors) + { + for (i = 0; i < numffloors; i++) + { + ffloor[i].f_pos >>= 4; +#ifdef ESLOPE + ffloor[i].f_pos_slope >>= 4; +#endif + if (linedef->special == HORIZONSPECIAL) // Horizon lines extend FOFs in contact with them too. + { + ffloor[i].f_step = 0; + ffloor[i].f_frac = (centeryfrac>>4); + topfrac++; // Prevent 1px HOM + } + else + { +#ifdef ESLOPE + ffloor[i].f_frac = (centeryfrac>>4) - FixedMul(ffloor[i].f_pos, rw_scale); + ffloor[i].f_step = ((centeryfrac>>4) - FixedMul(ffloor[i].f_pos_slope, ds_p->scale2) - ffloor[i].f_frac)/(range); +#else + ffloor[i].f_step = FixedMul(-rw_scalestep, ffloor[i].f_pos); + ffloor[i].f_frac = (centeryfrac>>4) - FixedMul(ffloor[i].f_pos, rw_scale); +#endif + } + } + } + + if (backsector) + { + worldhigh >>= 4; + worldlow >>= 4; +#ifdef ESLOPE + worldhighslope >>= 4; + worldlowslope >>= 4; +#endif + + if (toptexture) + { + pixhigh = (centeryfrac>>4) - FixedMul (worldhigh, rw_scale); + pixhighstep = -FixedMul (rw_scalestep,worldhigh); + +#ifdef ESLOPE + if (backsector->c_slope) { + fixed_t topfracend = (centeryfrac>>4) - FixedMul (worldhighslope, ds_p->scale2); + pixhighstep = (topfracend-pixhigh)/(range); + } +#endif + } + + if (bottomtexture) + { + pixlow = (centeryfrac>>4) - FixedMul (worldlow, rw_scale); + pixlowstep = -FixedMul (rw_scalestep,worldlow); +#ifdef ESLOPE + if (backsector->f_slope) { + fixed_t bottomfracend = (centeryfrac>>4) - FixedMul (worldlowslope, ds_p->scale2); + pixlowstep = (bottomfracend-pixlow)/(range); + } +#endif + } + + { + ffloor_t * rover; +#ifdef ESLOPE + fixed_t roverleft, roverright; + fixed_t planevistest; +#endif + i = 0; + + if (backsector->ffloors) + { + for (rover = backsector->ffloors; rover && i < MAXFFLOORS; rover = rover->next) + { + if (!(rover->flags & FF_EXISTS) || !(rover->flags & FF_RENDERPLANES)) + continue; + if (rover->norender == leveltime) + continue; + +#ifdef ESLOPE + // Let the renderer know this sector is sloped. + if (*rover->b_slope || *rover->t_slope) + backsector->hasslope = true; + + roverleft = (*rover->b_slope ? P_GetZAt(*rover->b_slope, segleft.x, segleft.y) : *rover->bottomheight) - viewz; + roverright = (*rover->b_slope ? P_GetZAt(*rover->b_slope, segright.x, segright.y) : *rover->bottomheight) - viewz; + planevistest = (*rover->b_slope ? P_GetZAt(*rover->b_slope, viewx, viewy) : *rover->bottomheight); + + if ((roverleft>>4 <= worldhigh || roverright>>4 <= worldhighslope) && + (roverleft>>4 >= worldlow || roverright>>4 >= worldlowslope) && + ((viewz < planevistest && !(rover->flags & FF_INVERTPLANES)) || + (viewz > planevistest && (rover->flags & FF_BOTHPLANES)))) + { + //ffloor[i].slope = *rover->b_slope; + ffloor[i].b_pos = roverleft; + ffloor[i].b_pos_slope = roverright; + ffloor[i].b_pos >>= 4; + ffloor[i].b_pos_slope >>= 4; + ffloor[i].b_frac = (centeryfrac >> 4) - FixedMul(ffloor[i].b_pos, rw_scale); + ffloor[i].b_step = (centeryfrac >> 4) - FixedMul(ffloor[i].b_pos_slope, ds_p->scale2); + ffloor[i].b_step = (ffloor[i].b_step-ffloor[i].b_frac)/(range); + i++; + } + + if (i >= MAXFFLOORS) + break; + + roverleft = (*rover->t_slope ? P_GetZAt(*rover->t_slope, segleft.x, segleft.y) : *rover->topheight) - viewz; + roverright = (*rover->t_slope ? P_GetZAt(*rover->t_slope, segright.x, segright.y) : *rover->topheight) - viewz; + planevistest = (*rover->t_slope ? P_GetZAt(*rover->t_slope, viewx, viewy) : *rover->topheight); + + if ((roverleft>>4 <= worldhigh || roverright>>4 <= worldhighslope) && + (roverleft>>4 >= worldlow || roverright>>4 >= worldlowslope) && + ((viewz > planevistest && !(rover->flags & FF_INVERTPLANES)) || + (viewz < planevistest && (rover->flags & FF_BOTHPLANES)))) + { + //ffloor[i].slope = *rover->t_slope; + ffloor[i].b_pos = roverleft; + ffloor[i].b_pos_slope = roverright; + ffloor[i].b_pos >>= 4; + ffloor[i].b_pos_slope >>= 4; + ffloor[i].b_frac = (centeryfrac >> 4) - FixedMul(ffloor[i].b_pos, rw_scale); + ffloor[i].b_step = (centeryfrac >> 4) - FixedMul(ffloor[i].b_pos_slope, ds_p->scale2); + ffloor[i].b_step = (ffloor[i].b_step-ffloor[i].b_frac)/(range); + i++; + } +#else + if (*rover->bottomheight <= backsector->ceilingheight && + *rover->bottomheight >= backsector->floorheight && + ((viewz < *rover->bottomheight && !(rover->flags & FF_INVERTPLANES)) || + (viewz > *rover->bottomheight && (rover->flags & FF_BOTHPLANES)))) + { + ffloor[i].b_pos = *rover->bottomheight; + ffloor[i].b_pos = (ffloor[i].b_pos - viewz) >> 4; + ffloor[i].b_step = FixedMul(-rw_scalestep, ffloor[i].b_pos); + ffloor[i].b_frac = (centeryfrac >> 4) - FixedMul(ffloor[i].b_pos, rw_scale); + i++; + } + + if (i >= MAXFFLOORS) + break; + + if (*rover->topheight >= backsector->floorheight && + *rover->topheight <= backsector->ceilingheight && + ((viewz > *rover->topheight && !(rover->flags & FF_INVERTPLANES)) || + (viewz < *rover->topheight && (rover->flags & FF_BOTHPLANES)))) + { + ffloor[i].b_pos = *rover->topheight; + ffloor[i].b_pos = (ffloor[i].b_pos - viewz) >> 4; + ffloor[i].b_step = FixedMul(-rw_scalestep, ffloor[i].b_pos); + ffloor[i].b_frac = (centeryfrac >> 4) - FixedMul(ffloor[i].b_pos, rw_scale); + i++; + } +#endif + } + } + else if (frontsector && frontsector->ffloors) + { + for (rover = frontsector->ffloors; rover && i < MAXFFLOORS; rover = rover->next) + { + if (!(rover->flags & FF_EXISTS) || !(rover->flags & FF_RENDERPLANES)) + continue; + if (rover->norender == leveltime) + continue; + + +#ifdef ESLOPE + // Let the renderer know this sector is sloped. + if (*rover->b_slope || *rover->t_slope) + frontsector->hasslope = true; + + roverleft = (*rover->b_slope ? P_GetZAt(*rover->b_slope, segleft.x, segleft.y) : *rover->bottomheight) - viewz; + roverright = (*rover->b_slope ? P_GetZAt(*rover->b_slope, segright.x, segright.y) : *rover->bottomheight) - viewz; + planevistest = (*rover->b_slope ? P_GetZAt(*rover->b_slope, viewx, viewy) : *rover->bottomheight); + + if ((roverleft>>4 <= worldhigh || roverright>>4 <= worldhighslope) && + (roverleft>>4 >= worldlow || roverright>>4 >= worldlowslope) && + ((viewz < planevistest && !(rover->flags & FF_INVERTPLANES)) || + (viewz > planevistest && (rover->flags & FF_BOTHPLANES)))) + { + //ffloor[i].slope = *rover->b_slope; + ffloor[i].b_pos = roverleft; + ffloor[i].b_pos_slope = roverright; + ffloor[i].b_pos >>= 4; + ffloor[i].b_pos_slope >>= 4; + ffloor[i].b_frac = (centeryfrac >> 4) - FixedMul(ffloor[i].b_pos, rw_scale); + ffloor[i].b_step = (centeryfrac >> 4) - FixedMul(ffloor[i].b_pos_slope, ds_p->scale2); + ffloor[i].b_step = (ffloor[i].b_step-ffloor[i].b_frac)/(range); + i++; + } + + if (i >= MAXFFLOORS) + break; + + roverleft = (*rover->t_slope ? P_GetZAt(*rover->t_slope, segleft.x, segleft.y) : *rover->topheight) - viewz; + roverright = (*rover->t_slope ? P_GetZAt(*rover->t_slope, segright.x, segright.y) : *rover->topheight) - viewz; + planevistest = (*rover->t_slope ? P_GetZAt(*rover->t_slope, viewx, viewy) : *rover->topheight); + + if ((roverleft>>4 <= worldhigh || roverright>>4 <= worldhighslope) && + (roverleft>>4 >= worldlow || roverright>>4 >= worldlowslope) && + ((viewz > planevistest && !(rover->flags & FF_INVERTPLANES)) || + (viewz < planevistest && (rover->flags & FF_BOTHPLANES)))) + { + //ffloor[i].slope = *rover->t_slope; + ffloor[i].b_pos = roverleft; + ffloor[i].b_pos_slope = roverright; + ffloor[i].b_pos >>= 4; + ffloor[i].b_pos_slope >>= 4; + ffloor[i].b_frac = (centeryfrac >> 4) - FixedMul(ffloor[i].b_pos, rw_scale); + ffloor[i].b_step = (centeryfrac >> 4) - FixedMul(ffloor[i].b_pos_slope, ds_p->scale2); + ffloor[i].b_step = (ffloor[i].b_step-ffloor[i].b_frac)/(range); + i++; + } +#else + if (*rover->bottomheight <= frontsector->ceilingheight && + *rover->bottomheight >= frontsector->floorheight && + ((viewz < *rover->bottomheight && !(rover->flags & FF_INVERTPLANES)) || + (viewz > *rover->bottomheight && (rover->flags & FF_BOTHPLANES)))) + { + ffloor[i].b_pos = *rover->bottomheight; + ffloor[i].b_pos = (ffloor[i].b_pos - viewz) >> 4; + ffloor[i].b_step = FixedMul(-rw_scalestep, ffloor[i].b_pos); + ffloor[i].b_frac = (centeryfrac >> 4) - FixedMul(ffloor[i].b_pos, rw_scale); + i++; + } + if (i >= MAXFFLOORS) + break; + if (*rover->topheight >= frontsector->floorheight && + *rover->topheight <= frontsector->ceilingheight && + ((viewz > *rover->topheight && !(rover->flags & FF_INVERTPLANES)) || + (viewz < *rover->topheight && (rover->flags & FF_BOTHPLANES)))) + { + ffloor[i].b_pos = *rover->topheight; + ffloor[i].b_pos = (ffloor[i].b_pos - viewz) >> 4; + ffloor[i].b_step = FixedMul(-rw_scalestep, ffloor[i].b_pos); + ffloor[i].b_frac = (centeryfrac >> 4) - FixedMul(ffloor[i].b_pos, rw_scale); + i++; + } +#endif + } + } +#ifdef POLYOBJECTS_PLANES + if (curline->polyseg && frontsector && (curline->polyseg->flags & POF_RENDERPLANES)) + { + while (i < numffloors && ffloor[i].polyobj != curline->polyseg) i++; + if (i < numffloors && backsector->floorheight <= frontsector->ceilingheight && + backsector->floorheight >= frontsector->floorheight && + (viewz < backsector->floorheight)) + { + if (ffloor[i].plane->minx > ds_p->x1) + ffloor[i].plane->minx = ds_p->x1; + + if (ffloor[i].plane->maxx < ds_p->x2) + ffloor[i].plane->maxx = ds_p->x2; + +#ifdef ESLOPE + ffloor[i].slope = NULL; +#endif + ffloor[i].b_pos = backsector->floorheight; + ffloor[i].b_pos = (ffloor[i].b_pos - viewz) >> 4; + ffloor[i].b_step = FixedMul(-rw_scalestep, ffloor[i].b_pos); + ffloor[i].b_frac = (centeryfrac >> 4) - FixedMul(ffloor[i].b_pos, rw_scale); + i++; + } + if (i < numffloors && backsector->ceilingheight >= frontsector->floorheight && + backsector->ceilingheight <= frontsector->ceilingheight && + (viewz > backsector->ceilingheight)) + { + if (ffloor[i].plane->minx > ds_p->x1) + ffloor[i].plane->minx = ds_p->x1; + + if (ffloor[i].plane->maxx < ds_p->x2) + ffloor[i].plane->maxx = ds_p->x2; + +#ifdef ESLOPE + ffloor[i].slope = NULL; +#endif + ffloor[i].b_pos = backsector->ceilingheight; + ffloor[i].b_pos = (ffloor[i].b_pos - viewz) >> 4; + ffloor[i].b_step = FixedMul(-rw_scalestep, ffloor[i].b_pos); + ffloor[i].b_frac = (centeryfrac >> 4) - FixedMul(ffloor[i].b_pos, rw_scale); + i++; + } + } +#endif + + numbackffloors = i; + } + } // get a new or use the same visplane if (markceiling) { if (ceilingplane) //SoM: 3/29/2000: Check for null ceiling planes - ceilingplane = R_CheckPlane (ceilingplane, rw.x, rw.stopx-1); + ceilingplane = R_CheckPlane (ceilingplane, rw_x, rw_stopx-1); else markceiling = false; @@ -1850,7 +3126,7 @@ static void R_MarkPlanes(void) if (markfloor) { if (floorplane) //SoM: 3/29/2000: Check for null planes - floorplane = R_CheckPlane (floorplane, rw.x, rw.stopx-1); + floorplane = R_CheckPlane (floorplane, rw_x, rw_stopx-1); else markfloor = false; @@ -1870,7 +3146,7 @@ static void R_MarkPlanes(void) for (i = 0; i < numffloors; i++) { ds_p->ffloorplanes[i] = ffloor[i].plane = - R_CheckPlane(ffloor[i].plane, rw.x, rw.stopx - 1); + R_CheckPlane(ffloor[i].plane, rw_x, rw_stopx - 1); } firstseg = ds_p; @@ -1878,7 +3154,7 @@ static void R_MarkPlanes(void) else { for (i = 0; i < numffloors; i++) - R_ExpandPlane(ffloor[i].plane, rw.x, rw.stopx - 1); + R_ExpandPlane(ffloor[i].plane, rw_x, rw_stopx - 1); } #ifdef POLYOBJECTS_PLANES // FIXME hack to fix planes disappearing when a seg goes behind the camera. This NEEDS to be changed to be done properly. -Red @@ -1888,251 +3164,15 @@ static void R_MarkPlanes(void) { if (!ffloor[i].polyobj || ffloor[i].polyobj != curline->polyseg) continue; - if (ffloor[i].plane->minx > rw.x) - ffloor[i].plane->minx = rw.x; + if (ffloor[i].plane->minx > rw_x) + ffloor[i].plane->minx = rw_x; - if (ffloor[i].plane->maxx < rw.stopx - 1) - ffloor[i].plane->maxx = rw.stopx - 1; + if (ffloor[i].plane->maxx < rw_stopx - 1) + ffloor[i].plane->maxx = rw_stopx - 1; } } #endif } -} - -// -// R_RemoveOpeningLimits -// Code to remove limits on openings. -// -static void R_RemoveOpeningLimits(INT32 start) -{ - size_t pos = lastopening - openings; - size_t need = (rw.stopx - start)*4 + pos; - if (need > maxopenings) - { - drawseg_t *ds; //needed for fix from *cough* zdoom *cough* - INT16 *oldopenings = openings; - INT16 *oldlast = lastopening; - - do - maxopenings = maxopenings ? maxopenings*2 : 16384; - while (need > maxopenings); - openings = Z_Realloc(openings, maxopenings * sizeof (*openings), PU_STATIC, NULL); - lastopening = openings + pos; - - // borrowed fix from *cough* zdoom *cough* - // [RH] We also need to adjust the openings pointers that - // were already stored in drawsegs. - for (ds = drawsegs; ds < ds_p; ds++) - { -#define ADJUST(p) if (ds->p + ds->x1 >= oldopenings && ds->p + ds->x1 <= oldlast) ds->p = ds->p - oldopenings + openings; - ADJUST(maskedtexturecol); - ADJUST(sprtopclip); - ADJUST(sprbottomclip); - ADJUST(thicksidecol); -#undef ADJUST - } - } -} - -// -// R_StoreWallRange -// A wall segment will be drawn -// between start and stop pixels (inclusive). -// -void R_StoreWallRange(INT32 start, INT32 stop) -{ - fixed_t hyp; - fixed_t sineval; - angle_t distangle, offsetangle; - boolean longboi; -#ifndef ESLOPE - fixed_t vtop; -#endif - INT32 i; - INT32 range; - static size_t maxdrawsegs = 0; - -#ifdef ESLOPE - maskedtextureheight = NULL; - //initialize segleft and segright - memset(&segleft, 0x00, sizeof(segleft)); - memset(&segright, 0x00, sizeof(segright)); -#endif - - colfunc = colfuncs[BASEDRAWFUNC]; - - if (ds_p == drawsegs+maxdrawsegs) - { - size_t curpos = curdrawsegs - drawsegs; - size_t pos = ds_p - drawsegs; - size_t newmax = maxdrawsegs ? maxdrawsegs*2 : 128; - if (firstseg) - firstseg = (drawseg_t *)(firstseg - drawsegs); - drawsegs = Z_Realloc(drawsegs, newmax*sizeof (*drawsegs), PU_STATIC, NULL); - ds_p = drawsegs + pos; - maxdrawsegs = newmax; - curdrawsegs = drawsegs + curpos; - if (firstseg) - firstseg = drawsegs + (size_t)firstseg; - } - - sidedef = curline->sidedef; - linedef = curline->linedef; - - // calculate rw.distance for scale calculation - rw.normalangle = curline->angle + ANGLE_90; - offsetangle = abs((INT32)(rw.normalangle-rw.angle1)); - - if (offsetangle > ANGLE_90) - offsetangle = ANGLE_90; - - distangle = ANGLE_90 - offsetangle; - sineval = FINESINE(distangle>>ANGLETOFINESHIFT); - - hyp = R_PointToDist(curline->v1->x, curline->v1->y); - longboi = (hyp >= INT32_MAX); - - // The seg is vertical. - if (curline->v1->y == curline->v2->y) - rw.distance = (fixed_t)(llabs(viewy - curline->v1->y)); - // The seg is horizontal. - else if (curline->v1->x == curline->v2->x) - rw.distance = (fixed_t)(llabs(viewx - curline->v1->x)); - // big room fix -#ifdef SOFTWARE_USE_FLOATS - else if ((curline->length >= 1024<x1 = rw.x = start; - ds_p->x2 = stop; - ds_p->curline = curline; - rw.stopx = stop+1; - - //SoM: Code to remove limits on openings. - R_RemoveOpeningLimits(start); - - // calculate scale at both ends and step - range = R_CalculateWallScale(start, stop); - - // calculate texture boundaries - // and decide if floor / ceiling marks are needed - R_WorldTopAndBottom(start, stop); - - midtexture = toptexture = bottomtexture = maskedtexture = 0; - ds_p->maskedtexturecol = NULL; - ds_p->numthicksides = numthicksides = 0; - ds_p->thicksidecol = NULL; - ds_p->tsilheight = 0; - - numbackffloors = 0; - - for (i = 0; i < MAXFFLOORS; i++) - ds_p->thicksides[i] = NULL; - - if (numffloors) - { - for (i = 0; i < numffloors; i++) - { -#ifdef POLYOBJECTS_PLANES - if (ffloor[i].polyobj && (!ds_p->curline->polyseg || ffloor[i].polyobj != ds_p->curline->polyseg)) - continue; -#endif - -#ifdef ESLOPE - if (ffloor[i].slope) { - ffloor[i].f_pos = P_GetZAt(ffloor[i].slope, segleft.x, segleft.y) - viewz; - ffloor[i].f_pos_slope = P_GetZAt(ffloor[i].slope, segright.x, segright.y) - viewz; - } else - ffloor[i].f_pos_slope = -#endif - ffloor[i].f_pos = ffloor[i].height - viewz; - } - } - -#ifdef ESLOPE - // Set up texture Y offset slides for sloped walls - rw.toptextureslide = rw.midtextureslide = rw.bottomtextureslide = 0; - ceilingfrontslide = floorfrontslide = ceilingbackslide = floorbackslide = 0; - - { - angle_t lineangle = R_PointToAngle2(curline->v1->x, curline->v1->y, curline->v2->x, curline->v2->y); - - if (frontsector->f_slope) - floorfrontslide = FixedMul(frontsector->f_slope->zdelta, FINECOSINE((lineangle-frontsector->f_slope->xydirection)>>ANGLETOFINESHIFT)); - - if (frontsector->c_slope) - ceilingfrontslide = FixedMul(frontsector->c_slope->zdelta, FINECOSINE((lineangle-frontsector->c_slope->xydirection)>>ANGLETOFINESHIFT)); - - if (backsector && backsector->f_slope) - floorbackslide = FixedMul(backsector->f_slope->zdelta, FINECOSINE((lineangle-backsector->f_slope->xydirection)>>ANGLETOFINESHIFT)); - - if (backsector && backsector->c_slope) - ceilingbackslide = FixedMul(backsector->c_slope->zdelta, FINECOSINE((lineangle-backsector->c_slope->xydirection)>>ANGLETOFINESHIFT)); - } -#endif - - // Check for textures - R_StoreWallSilhouette(); - R_CheckWallTextures(); - if (backsector) - R_CheckMaskedTextures(); - -#undef SLOPEPARAMS - - // Calculate rw.offset (only needed for textured lines) - segtextured = midtexture || toptexture || bottomtexture || maskedtexture || (numthicksides > 0); - if (segtextured) - R_SegTextured(hyp, longboi); - - // if a floor / ceiling plane is on the wrong side - // of the view plane, it is definitely invisible - // and doesn't need to be marked. - if (frontsector->heightsec == -1) - { - if (frontsector->floorpic != skyflatnum - && ( -#ifdef ESLOPE - frontsector->f_slope ? P_GetZAt(frontsector->f_slope, viewx, viewy) : -#endif - frontsector->floorheight) >= viewz) - { - // above view plane - markfloor = false; - } - - if (frontsector->ceilingpic != skyflatnum - && ( -#ifdef ESLOPE - frontsector->c_slope ? P_GetZAt(frontsector->c_slope, viewx, viewy) : -#endif - frontsector->ceilingheight) <= viewz) - { - // below view plane - markceiling = false; - } - } - - // Calculate incremental stepping values for texture edges - R_WorldStep(range); - - // Create light lists - R_WorldLightLists(range); - - // Step FOFs - if (numffloors) - R_WorldFFloorStep(range); - - // Step world back - if (backsector) - R_WorldBackStep(range); - - // Mark floor and or ceiling visplanes - R_MarkPlanes(); #ifdef WALLSPLATS if (linedef->splats && cv_splats.value) @@ -2158,16 +3198,16 @@ void R_StoreWallRange(INT32 start, INT32 stop) // save sprite clipping info if (((ds_p->silhouette & SIL_TOP) || maskedtexture) && !ds_p->sprtopclip) { - M_Memcpy(lastopening, ceilingclip+start, 2*(rw.stopx - start)); + M_Memcpy(lastopening, ceilingclip+start, 2*(rw_stopx - start)); ds_p->sprtopclip = lastopening - start; - lastopening += rw.stopx - start; + lastopening += rw_stopx - start; } if (((ds_p->silhouette & SIL_BOTTOM) || maskedtexture) && !ds_p->sprbottomclip) { - M_Memcpy(lastopening, floorclip + start, 2*(rw.stopx-start)); + M_Memcpy(lastopening, floorclip + start, 2*(rw_stopx-start)); ds_p->sprbottomclip = lastopening - start; - lastopening += rw.stopx - start; + lastopening += rw_stopx - start; } if (maskedtexture && !(ds_p->silhouette & SIL_TOP)) @@ -2180,1314 +3220,5 @@ void R_StoreWallRange(INT32 start, INT32 stop) ds_p->silhouette |= SIL_BOTTOM; ds_p->bsilheight = (sidedef->midtexture > 0 && sidedef->midtexture < numtextures) ? INT32_MAX: INT32_MIN; } - ds_p++; } - -// ========================================================================== -// R_Splats Wall Splats Drawer -// ========================================================================== - -#ifdef WALLSPLATS -static INT16 last_ceilingclip[MAXVIDWIDTH]; -static INT16 last_floorclip[MAXVIDWIDTH]; - -static void R_DrawSplatColumn(column_t *column) -{ - INT32 topscreen, bottomscreen; - fixed_t basetexturemid; - INT32 topdelta, prevdelta = -1; - - basetexturemid = dc_texturemid; - - for (; column->topdelta != 0xff ;) - { - // calculate unclipped screen coordinates for post - topdelta = column->topdelta; - if (topdelta <= prevdelta) - topdelta += prevdelta; - prevdelta = topdelta; - topscreen = sprtopscreen + spryscale*topdelta; - bottomscreen = topscreen + spryscale*column->length; - - dc_yl = (topscreen+FRACUNIT-1)>>FRACBITS; - dc_yh = (bottomscreen-1)>>FRACBITS; - - if (dc_yh >= last_floorclip[dc_x]) - dc_yh = last_floorclip[dc_x] - 1; - if (dc_yl <= last_ceilingclip[dc_x]) - dc_yl = last_ceilingclip[dc_x] + 1; - if (dc_yl <= dc_yh && dl_yh < vid.height && yh > 0) - { - dc_source = (UINT8 *)column + 3; - dc_texturemid = basetexturemid - (topdelta<length + 4); - } - - dc_texturemid = basetexturemid; -} - -static void R_DrawWallSplats(void) -{ - wallsplat_t *splat; - seg_t *seg; - angle_t angle, angle1, angle2; - INT32 x1, x2; - size_t pindex; - column_t *col; - patch_t *patch; - fixed_t texturecolumn; - - splat = (wallsplat_t *)linedef->splats; - - I_Assert(splat != NULL); - - seg = ds_p->curline; - - // draw all splats from the line that touches the range of the seg - for (; splat; splat = splat->next) - { - angle1 = R_PointToAngle(splat->v1.x, splat->v1.y); - angle2 = R_PointToAngle(splat->v2.x, splat->v2.y); - angle1 = (angle1 - viewangle + ANGLE_90)>>ANGLETOFINESHIFT; - angle2 = (angle2 - viewangle + ANGLE_90)>>ANGLETOFINESHIFT; - // out of the viewangletox lut - /// \todo clip it to the screen - if (angle1 > FINEANGLES/2 || angle2 > FINEANGLES/2) - continue; - x1 = viewangletox[angle1]; - x2 = viewangletox[angle2]; - - if (x1 >= x2) - continue; // does not cross a pixel - - // splat is not in this seg range - if (x2 < ds_p->x1 || x1 > ds_p->x2) - continue; - - if (x1 < ds_p->x1) - x1 = ds_p->x1; - if (x2 > ds_p->x2) - x2 = ds_p->x2; - if (x2 <= x1) - continue; - - // calculate incremental stepping values for texture edges - rw.scalestep = ds_p->scalestep; - spryscale = ds_p->scale1 + (x1 - ds_p->x1)*rw.scalestep; - mfloorclip = floorclip; - mceilingclip = ceilingclip; - - patch = W_CachePatchNum(splat->patch, PU_PATCH); - - dc_texturemid = splat->top + (SHORT(patch->height)<<(FRACBITS-1)) - viewz; - if (splat->yoffset) - dc_texturemid += *splat->yoffset; - - sprtopscreen = centeryfrac - FixedMul(dc_texturemid, spryscale); - - // set drawing mode - switch (splat->flags & SPLATDRAWMODE_MASK) - { - case SPLATDRAWMODE_OPAQUE: - colfunc = colfuncs[BASEDRAWFUNC]; - break; - case SPLATDRAWMODE_TRANS: - if (!cv_translucency.value) - colfunc = colfuncs[BASEDRAWFUNC]; - else - { - dc_transmap = transtables + ((tr_trans50 - 1)<>LIGHTSCALESHIFT; - if (pindex >= MAXLIGHTSCALE) - pindex = MAXLIGHTSCALE - 1; - dc_colormap = walllights[pindex]; - - if (frontsector->extra_colormap) - dc_colormap = frontsector->extra_colormap->colormap + (dc_colormap - colormaps); - - sprtopscreen = centeryfrac - FixedMul(dc_texturemid, spryscale); - dc_iscale = 0xffffffffu / (unsigned)spryscale; - - // find column of patch, from perspective - angle = (rw.centerangle + xtoviewangle[dc_x])>>ANGLETOFINESHIFT; - texturecolumn = rw.offset2 - splat->offset - - FixedMul(FINETANGENT(angle), rw.distance); - - // FIXME! - texturecolumn >>= FRACBITS; - if (texturecolumn < 0 || texturecolumn >= SHORT(patch->width)) - continue; - - // draw the texture - col = (column_t *)((UINT8 *)patch + LONG(patch->columnofs[texturecolumn])); - R_DrawSplatColumn(col); - } - } // next splat - - colfunc = colfuncs[BASEDRAWFUNC]; -} - -#endif //WALLSPLATS - -// ========================================================================== -// R_RenderMaskedSegRange -// ========================================================================== - -// If we have a multi-patch texture on a 2sided wall (rare) then we draw -// it using R_DrawColumn, else we draw it using R_DrawMaskedColumn, this -// way we don't have to store extra post_t info with each column for -// multi-patch textures. They are not normally needed as multi-patch -// textures don't have holes in it. At least not for now. - -static void R_Render2sidedMultiPatchColumn(column_t *column) -{ - INT32 topscreen, bottomscreen; - - topscreen = sprtopscreen; // + spryscale*column->topdelta; topdelta is 0 for the wall - bottomscreen = topscreen + spryscale * rw.column2s_length; - - dc_yl = (sprtopscreen+FRACUNIT-1)>>FRACBITS; - dc_yh = (bottomscreen-1)>>FRACBITS; - - if (windowtop != INT32_MAX && windowbottom != INT32_MAX) - { - dc_yl = ((windowtop + FRACUNIT)>>FRACBITS); - dc_yh = (windowbottom - 1)>>FRACBITS; - } - - if (dc_yh >= mfloorclip[dc_x]) - dc_yh = mfloorclip[dc_x] - 1; - if (dc_yl <= mceilingclip[dc_x]) - dc_yl = mceilingclip[dc_x] + 1; - - if (dc_yl >= vid.height || dc_yh < 0) - return; - - if (dc_yl <= dc_yh && dc_yh < vid.height && dc_yh > 0) - { - dc_source = (UINT8 *)column + 3; - - if (colfunc == colfuncs[BASEDRAWFUNC]) - (colfuncs[COLDRAWFUNC_TWOSMULTIPATCH])(); - else if (colfunc == colfuncs[COLDRAWFUNC_FUZZY]) - (colfuncs[COLDRAWFUNC_TWOSMULTIPATCHTRANS])(); - else - colfunc(); - } -} - -// quick wrapper for R_DrawFlippedMaskedColumn so it can be set as a colfunc_2s value -// uses column2s_length for texture->height as above -static void R_DrawFlippedMaskedSegColumn(column_t *column) -{ - R_DrawFlippedMaskedColumn(column, rw.column2s_length); -} - -// -// R_RenderMaskedSegLoop -// Like R_RenderSegLoop, but for masked segs. -// -static void R_RenderMaskedSegLoop(drawseg_t *ds) -{ - size_t pindex; - column_t *col; - INT32 i; - fixed_t height, realbot; - r_lightlist_t *rlight; - INT64 overflow_test; - - for (dc_x = rw.x; dc_x <= rw.stopx; dc_x++) - { -#ifdef ESLOPE - dc_texturemid = ds->maskedtextureheight[dc_x]; - - if (!!(curline->linedef->flags & ML_DONTPEGBOTTOM) ^ !!(curline->linedef->flags & ML_EFFECT3)) - dc_texturemid += (textureheight[rw.texnum])*rw.maskedrepeat + textureheight[rw.texnum]; - else - dc_texturemid -= (textureheight[rw.texnum])*rw.maskedrepeat; -#endif - // calculate lighting - if (maskedtexturecol[dc_x] != INT16_MAX) - { - // Check for overflows first - overflow_test = (INT64)centeryfrac - (((INT64)dc_texturemid*spryscale)>>FRACBITS); - if (overflow_test < 0) overflow_test = -overflow_test; - if ((UINT64)overflow_test&0xFFFFFFFF80000000ULL) - { - // Eh, no, go away, don't waste our time - if (dc_numlights) - { - for (i = 0; i < dc_numlights; i++) - { - rlight = &dc_lightlist[i]; - rlight->height += rlight->heightstep; - } - } - spryscale += rw.scalestep; - continue; - } - - if (dc_numlights) - { - lighttable_t **xwalllights; - - sprbotscreen = INT32_MAX; - sprtopscreen = windowtop = (centeryfrac - FixedMul(dc_texturemid, spryscale)); - - realbot = windowbottom = FixedMul(textureheight[rw.texnum], spryscale) + sprtopscreen; - dc_iscale = 0xffffffffu / (unsigned)spryscale; - - // draw the texture - col = (column_t *)((UINT8 *)R_GetColumn(rw.texnum, maskedtexturecol[dc_x]) - 3); - - for (i = 0; i < dc_numlights; i++) - { - rlight = &dc_lightlist[i]; - - if ((rlight->flags & FF_NOSHADE)) - continue; - - if (rlight->lightnum < 0) - xwalllights = scalelight[0]; - else if (rlight->lightnum >= LIGHTLEVELS) - xwalllights = scalelight[LIGHTLEVELS-1]; - else - xwalllights = scalelight[rlight->lightnum]; - - pindex = FixedMul(spryscale, FixedDiv(640, vid.width))>>LIGHTSCALESHIFT; - - if (pindex >= MAXLIGHTSCALE) - pindex = MAXLIGHTSCALE - 1; - - if (rlight->extra_colormap) - rlight->rcolormap = rlight->extra_colormap->colormap + (xwalllights[pindex] - colormaps); - else - rlight->rcolormap = xwalllights[pindex]; - - height = rlight->height; - rlight->height += rlight->heightstep; - - if (height <= windowtop) - { - dc_colormap = rlight->rcolormap; - continue; - } - - windowbottom = height; - if (windowbottom >= realbot) - { - windowbottom = realbot; - rw.colfunc_2s(col); - for (i++; i < dc_numlights; i++) - { - rlight = &dc_lightlist[i]; - rlight->height += rlight->heightstep; - } - - continue; - } - rw.colfunc_2s(col); - windowtop = windowbottom + 1; - dc_colormap = rlight->rcolormap; - } - windowbottom = realbot; - if (windowtop < windowbottom) - rw.colfunc_2s(col); - - spryscale += rw.scalestep; - continue; - } - - // calculate lighting - pindex = FixedMul(spryscale, FixedDiv(640, vid.width))>>LIGHTSCALESHIFT; - - if (pindex >= MAXLIGHTSCALE) - pindex = MAXLIGHTSCALE - 1; - - dc_colormap = walllights[pindex]; - - if (frontsector->extra_colormap) - dc_colormap = frontsector->extra_colormap->colormap + (dc_colormap - colormaps); - - sprtopscreen = centeryfrac - FixedMul(dc_texturemid, spryscale); - dc_iscale = 0xffffffffu / (unsigned)spryscale; - - // draw the texture - col = (column_t *)((UINT8 *)R_GetColumn(rw.texnum, maskedtexturecol[dc_x]) - 3); - -//#ifdef POLYOBJECTS_PLANES -#if 0 // Disabling this allows inside edges to render below the planes, for until the clipping is fixed to work right when POs are near the camera. -Red - if (curline->dontrenderme && curline->polyseg && (curline->polyseg->flags & POF_RENDERPLANES)) - { - fixed_t my_topscreen; - fixed_t my_bottomscreen; - fixed_t my_yl, my_yh; - - my_topscreen = sprtopscreen + spryscale*col->topdelta; - my_bottomscreen = sprbotscreen == INT32_MAX ? my_topscreen + spryscale*col->length - : sprbotscreen + spryscale*col->length; - - my_yl = (my_topscreen+FRACUNIT-1)>>FRACBITS; - my_yh = (my_bottomscreen-1)>>FRACBITS; -// CONS_Debug(DBG_RENDER, "my_topscreen: %d\nmy_bottomscreen: %d\nmy_yl: %d\nmy_yh: %d\n", my_topscreen, my_bottomscreen, my_yl, my_yh); - - if (numffloors) - { - INT32 top = my_yl; - INT32 bottom = my_yh; - - for (i = 0; i < numffloors; i++) - { - if (!ffloor[i].polyobj || ffloor[i].polyobj != curline->polyseg) - continue; - - if (ffloor[i].height < viewz) - { - INT32 top_w = ffloor[i].plane->top[dc_x]; - -// CONS_Debug(DBG_RENDER, "Leveltime : %d\n", leveltime); -// CONS_Debug(DBG_RENDER, "Top is %d, top_w is %d\n", top, top_w); - if (top_w < top) - { - ffloor[i].plane->top[dc_x] = (INT16)top; - ffloor[i].plane->picnum = 0; - } -// CONS_Debug(DBG_RENDER, "top_w is now %d\n", ffloor[i].plane->top[dc_x]); - } - else if (ffloor[i].height > viewz) - { - INT32 bottom_w = ffloor[i].plane->bottom[dc_x]; - - if (bottom_w > bottom) - { - ffloor[i].plane->bottom[dc_x] = (INT16)bottom; - ffloor[i].plane->picnum = 0; - } - } - } - } - } - else -#endif - rw.colfunc_2s(col); - } - spryscale += rw.scalestep; - } -} - -// -// R_MaskedLightLists -// Creates light lists, but for masked segs. -// -static void R_MaskedLightLists(drawseg_t *ds, INT32 range) -{ - lightlist_t *light; - r_lightlist_t *rlight; - INT32 lightnum, i; - - dc_numlights = 0; - - if (frontsector->numlights) - { - dc_numlights = frontsector->numlights; - if (dc_numlights >= dc_maxlights) - { - dc_maxlights = dc_numlights; - dc_lightlist = Z_Realloc(dc_lightlist, sizeof (*dc_lightlist) * dc_maxlights, PU_STATIC, NULL); - } - - for (i = 0; i < dc_numlights; i++) - { -#ifdef ESLOPE - fixed_t leftheight, rightheight; -#else - (void)range; -#endif - light = &frontsector->lightlist[i]; - rlight = &dc_lightlist[i]; -#ifdef ESLOPE - if (light->slope) { - leftheight = P_GetZAt(light->slope, ds->leftpos.x, ds->leftpos.y); - rightheight = P_GetZAt(light->slope, ds->rightpos.x, ds->rightpos.y); - } else - leftheight = rightheight = light->height; - - leftheight -= viewz; - rightheight -= viewz; - - rlight->height = (centeryfrac) - FixedMul(leftheight, ds->scale1); - rlight->heightstep = (centeryfrac) - FixedMul(rightheight, ds->scale2); - rlight->heightstep = (rlight->heightstep-rlight->height)/(range); - //if (x1 > ds->x1) - //rlight->height -= (x1 - ds->x1)*rlight->heightstep; -#else - rlight->height = (centeryfrac) - FixedMul((light->height - viewz), spryscale); - rlight->heightstep = -FixedMul(rw.scalestep, (light->height - viewz)); -#endif - rlight->startheight = rlight->height; // keep starting value here to reset for each repeat - rlight->lightlevel = *light->lightlevel; - rlight->extra_colormap = *light->extra_colormap; - rlight->flags = light->flags; - - if (rlight->flags & FF_FOG || (rlight->extra_colormap && rlight->extra_colormap->fog)) - lightnum = (rlight->lightlevel >> LIGHTSEGSHIFT); - else if (colfunc == colfuncs[COLDRAWFUNC_FUZZY]) - lightnum = LIGHTLEVELS - 1; - else - lightnum = (rlight->lightlevel >> LIGHTSEGSHIFT); - - if (rlight->extra_colormap && rlight->extra_colormap->fog) - ; - else if (curline->v1->y == curline->v2->y) - lightnum--; - else if (curline->v1->x == curline->v2->x) - lightnum++; - - rlight->lightnum = lightnum; - } - } - else - { - if (colfunc == colfuncs[COLDRAWFUNC_FUZZY]) - { - if (frontsector->extra_colormap && frontsector->extra_colormap->fog) - lightnum = (frontsector->lightlevel >> LIGHTSEGSHIFT); - else - lightnum = LIGHTLEVELS - 1; - } - else - lightnum = (frontsector->lightlevel >> LIGHTSEGSHIFT); - - if (colfunc == colfuncs[COLDRAWFUNC_FOG] - || (frontsector->extra_colormap && frontsector->extra_colormap->fog)) - ; - else if (curline->v1->y == curline->v2->y) - lightnum--; - else if (curline->v1->x == curline->v2->x) - lightnum++; - - if (lightnum < 0) - walllights = scalelight[0]; - else if (lightnum >= LIGHTLEVELS) - walllights = scalelight[LIGHTLEVELS - 1]; - else - walllights = scalelight[lightnum]; - } -} - -// -// R_RenderMaskedSegRange -// Renders all the masked segs in the given range. -// -void R_RenderMaskedSegRange(drawseg_t *ds, INT32 x1, INT32 x2) -{ - INT32 texnum, i; - r_lightlist_t *rlight; - line_t *ldef; - sector_t *front, *back; - INT32 times, repeats; - INT32 range; - - // Calculate light table. - // Use different light tables - // for horizontal / vertical / diagonal. Diagonal? - // OPTIMIZE: get rid of LIGHTSEGSHIFT globally - curline = ds->curline; - frontsector = curline->frontsector; - backsector = curline->backsector; - texnum = R_GetTextureNum(curline->sidedef->midtexture); - windowbottom = windowtop = sprbotscreen = INT32_MAX; - - rw.x = x1; - rw.stopx = x2; - rw.texnum = texnum; - - // hack translucent linedef types (900-909 for transtables 1-9) - ldef = curline->linedef; - switch (ldef->special) - { - case 900: - case 901: - case 902: - case 903: - case 904: - case 905: - case 906: - case 907: - case 908: - dc_transmap = transtables + ((ldef->special-900)<ceilingheight; - windowbottom = frontsector->floorheight; - break; - default: - colfunc = colfuncs[BASEDRAWFUNC]; - break; - } - - if (curline->polyseg && curline->polyseg->translucency > 0) - { - if (curline->polyseg->translucency >= NUMTRANSMAPS) - return; - - dc_transmap = transtables + ((curline->polyseg->translucency-1)<x2-ds->x1, 1); -#endif - rw.scalestep = ds->scalestep; - spryscale = ds->scale1 + (x1 - ds->x1)*rw.scalestep; - - // Texture must be cached before setting colfunc_2s, - // otherwise texture[texnum]->holes may be false when it shouldn't be - R_CheckTextureCache(texnum); - // handle case where multipatch texture is drawn on a 2sided wall, multi-patch textures - // are not stored per-column with post info in SRB2 - if (textures[texnum]->holes) - { - if (textures[texnum]->flip & 2) // vertically flipped? - { - rw.colfunc_2s = R_DrawFlippedMaskedSegColumn; - rw.column2s_length = textures[texnum]->height; - } - else - rw.colfunc_2s = R_DrawMaskedColumn; // render the usual 2sided single-patch packed texture - } - else - { - rw.colfunc_2s = R_Render2sidedMultiPatchColumn; // render multipatch with no holes (no post_t info) - rw.column2s_length = textures[texnum]->height; - } - - // Setup lighting based on the presence/lack-of 3D floors. - R_MaskedLightLists(ds, range); - - maskedtexturecol = ds->maskedtexturecol; - - mfloorclip = ds->sprbottomclip; - mceilingclip = ds->sprtopclip; - - if (frontsector->heightsec != -1) - front = §ors[frontsector->heightsec]; - else - front = frontsector; - - if (backsector->heightsec != -1) - back = §ors[backsector->heightsec]; - else - back = backsector; - - if (ds->curline->sidedef->repeatcnt) - repeats = 1 + ds->curline->sidedef->repeatcnt; - else if (ldef->flags & ML_EFFECT5) - { - fixed_t high, low; - - if (front->ceilingheight > back->ceilingheight) - high = back->ceilingheight; - else - high = front->ceilingheight; - - if (front->floorheight > back->floorheight) - low = front->floorheight; - else - low = back->floorheight; - - repeats = (high - low)/textureheight[texnum]; - if ((high-low)%textureheight[texnum]) - repeats++; // tile an extra time to fill the gap -- Monster Iestyn - } - else - repeats = 1; - - for (times = 0; times < repeats; times++) - { - if (times > 0) - { - rw.scalestep = ds->scalestep; - spryscale = ds->scale1 + (x1 - ds->x1)*rw.scalestep; - if (dc_numlights) - { // reset all lights to their starting heights - for (i = 0; i < dc_numlights; i++) - { - rlight = &dc_lightlist[i]; - rlight->height = rlight->startheight; - } - } - } - -#ifndef ESLOPE - if (curline->linedef->flags & ML_DONTPEGBOTTOM) - { - dc_texturemid = front->floorheight > back->floorheight - ? front->floorheight : back->floorheight; - dc_texturemid = dc_texturemid + textureheight[texnum] - viewz; - } - else - { - dc_texturemid = front->ceilingheight < back->ceilingheight - ? front->ceilingheight : back->ceilingheight; - dc_texturemid = dc_texturemid - viewz; - } - dc_texturemid += curline->sidedef->rowoffset; - - if (curline->linedef->flags & ML_DONTPEGBOTTOM) - dc_texturemid += (textureheight[texnum])*times; - else - dc_texturemid -= (textureheight[texnum])*times; -#endif - - dc_texheight = textureheight[texnum]>>FRACBITS; - - // draw the columns - rw.maskedrepeat = times; - R_RenderMaskedSegLoop(ds); - } - colfunc = colfuncs[BASEDRAWFUNC]; -} - -// Loop through R_DrawMaskedColumn calls -static void R_DrawRepeatMaskedColumn(column_t *col) -{ - while (sprtopscreen < sprbotscreen) { - R_DrawMaskedColumn(col); - if ((INT64)sprtopscreen + dc_texheight*spryscale > (INT64)INT32_MAX) // prevent overflow - sprtopscreen = INT32_MAX; - else - sprtopscreen += dc_texheight*spryscale; - } -} - -static void R_DrawRepeatFlippedMaskedColumn(column_t *col) -{ - do { - R_DrawFlippedMaskedColumn(col, rw.column2s_length); - sprtopscreen += dc_texheight*spryscale; - } while (sprtopscreen < sprbotscreen); -} - -// -// R_RenderThickSegLoop -// Like R_RenderSegLoop, but for thick sides. -// -static void R_RenderThickSegLoop(void) -{ - column_t *col; - size_t pindex; - INT32 i; - INT32 lightnum; - r_lightlist_t *rlight; - - ffloor_t *pfloor = rw.pfloor; - fixed_t bottombounds = viewheight << FRACBITS; - fixed_t topbounds = (con_clipviewtop - 1) << FRACBITS; - -#ifdef ESLOPE - INT32 oldx = -1; -#endif - - for (dc_x = rw.x; dc_x <= rw.stopx; dc_x++) - { - if (maskedtexturecol[dc_x] != INT16_MAX) - { -#ifdef ESLOPE - if (rw.ffloortextureslide) { // skew FOF walls - if (oldx != -1) - dc_texturemid += FixedMul(rw.ffloortextureslide, (maskedtexturecol[oldx]-maskedtexturecol[dc_x])< (INT64)CLAMPMAX) sprtopscreen = windowtop = CLAMPMAX; - else if (rw.top_frac > (INT64)CLAMPMIN) sprtopscreen = windowtop = (fixed_t)rw.top_frac; - else sprtopscreen = windowtop = CLAMPMIN; - if (rw.bottom_frac > (INT64)CLAMPMAX) sprbotscreen = windowbottom = CLAMPMAX; - else if (rw.bottom_frac > (INT64)CLAMPMIN) sprbotscreen = windowbottom = (fixed_t)rw.bottom_frac; - else sprbotscreen = windowbottom = CLAMPMIN; - - rw.top_frac += rw.top_step; - rw.bottom_frac += rw.bottom_step; -#else - sprtopscreen = windowtop = (centeryfrac - FixedMul((dc_texturemid - offsetvalue), spryscale)); - sprbotscreen = windowbottom = FixedMul(*pfloor->topheight - *pfloor->bottomheight, spryscale) + sprtopscreen; -#endif - - // SoM: If column is out of range, why bother with it?? - if (windowbottom < topbounds || windowtop > bottombounds) - { - if (dc_numlights) - { - for (i = 0; i < dc_numlights; i++) - { - rlight = &dc_lightlist[i]; - rlight->height += rlight->heightstep; - if (rlight->flags & FF_CUTLEVEL) - rlight->botheight += rlight->botheightstep; - } - } - spryscale += rw.scalestep; - continue; - } - - dc_iscale = 0xffffffffu / (unsigned)spryscale; - - // Get data for the column - col = (column_t *)((UINT8 *)R_GetColumn(rw.texnum,maskedtexturecol[dc_x]) - 3); - - // SoM: New code does not rely on R_DrawColumnShadowed_8 which - // will (hopefully) put less strain on the stack. - if (dc_numlights) - { - lighttable_t **xwalllights; - fixed_t height; - fixed_t bheight = 0; - INT32 solid = 0; - INT32 lighteffect = 0; - - for (i = 0; i < dc_numlights; i++) - { - // Check if the current light effects the colormap/lightlevel - rlight = &dc_lightlist[i]; - lighteffect = !(dc_lightlist[i].flags & FF_NOSHADE); - if (lighteffect) - { - lightnum = rlight->lightnum; - - if (lightnum < 0) - xwalllights = scalelight[0]; - else if (lightnum >= LIGHTLEVELS) - xwalllights = scalelight[LIGHTLEVELS-1]; - else - xwalllights = scalelight[lightnum]; - - pindex = FixedMul(spryscale, FixedDiv(640, vid.width))>>LIGHTSCALESHIFT; - - if (pindex >= MAXLIGHTSCALE) - pindex = MAXLIGHTSCALE-1; - - if (pfloor->flags & FF_FOG) - { - if (pfloor->master->frontsector->extra_colormap) - rlight->rcolormap = pfloor->master->frontsector->extra_colormap->colormap + (xwalllights[pindex] - colormaps); - else - rlight->rcolormap = xwalllights[pindex]; - } - else - { - if (rlight->extra_colormap) - rlight->rcolormap = rlight->extra_colormap->colormap + (xwalllights[pindex] - colormaps); - else - rlight->rcolormap = xwalllights[pindex]; - } - } - - solid = 0; // don't carry over solid-cutting flag from the previous light - - // Check if the current light can cut the current 3D floor. - if (rlight->flags & FF_CUTSOLIDS && !(pfloor->flags & FF_EXTRA)) - solid = 1; - else if (rlight->flags & FF_CUTEXTRA && pfloor->flags & FF_EXTRA) - { - if (rlight->flags & FF_EXTRA) - { - // The light is from an extra 3D floor... Check the flags so - // there are no undesired cuts. - if ((rlight->flags & (FF_FOG|FF_SWIMMABLE)) == (pfloor->flags & (FF_FOG|FF_SWIMMABLE))) - solid = 1; - } - else - solid = 1; - } - else - solid = 0; - - height = rlight->height; - rlight->height += rlight->heightstep; - - if (solid) - { - bheight = rlight->botheight - (FRACUNIT >> 1); - rlight->botheight += rlight->botheightstep; - } - - if (height <= windowtop) - { - if (lighteffect) - dc_colormap = rlight->rcolormap; - if (solid && windowtop < bheight) - windowtop = bheight; - continue; - } - - windowbottom = height; - if (windowbottom >= sprbotscreen) - { - windowbottom = sprbotscreen; - // draw the texture - rw.colfunc_2s (col); - for (i++; i < dc_numlights; i++) - { - rlight = &dc_lightlist[i]; - rlight->height += rlight->heightstep; - if (rlight->flags & FF_CUTLEVEL) - rlight->botheight += rlight->botheightstep; - } - continue; - } - // draw the texture - rw.colfunc_2s (col); - if (solid) - windowtop = bheight; - else - windowtop = windowbottom + 1; - if (lighteffect) - dc_colormap = rlight->rcolormap; - } - windowbottom = sprbotscreen; - // draw the texture, if there is any space left - if (windowtop < windowbottom) - rw.colfunc_2s (col); - - spryscale += rw.scalestep; - continue; - } - - // calculate lighting - pindex = FixedMul(spryscale, FixedDiv(640, vid.width))>>LIGHTSCALESHIFT; - - if (pindex >= MAXLIGHTSCALE) - pindex = MAXLIGHTSCALE - 1; - - dc_colormap = walllights[pindex]; - - if (pfloor->flags & FF_FOG && pfloor->master->frontsector->extra_colormap) - dc_colormap = pfloor->master->frontsector->extra_colormap->colormap + (dc_colormap - colormaps); - else if (frontsector->extra_colormap) - dc_colormap = frontsector->extra_colormap->colormap + (dc_colormap - colormaps); - - // draw the texture - rw.colfunc_2s (col); - spryscale += rw.scalestep; - } - } -} - -// -// R_ThickLightLists -// Creates light lists, but for thick sides. -// -static void R_ThickLightLists(drawseg_t *ds, INT32 range) -{ - INT32 lightnum; - sector_t tempsec; - INT32 templight; - INT32 i, p; - - lightlist_t *light; - r_lightlist_t *rlight; - ffloor_t *pfloor = rw.pfloor; - - dc_numlights = 0; - - if (frontsector->numlights) - { - dc_numlights = frontsector->numlights; - if (dc_numlights > dc_maxlights) - { - dc_maxlights = dc_numlights; - dc_lightlist = Z_Realloc(dc_lightlist, sizeof (*dc_lightlist) * dc_maxlights, PU_STATIC, NULL); - } - - for (i = p = 0; i < dc_numlights; i++) - { -#ifdef ESLOPE - fixed_t leftheight, rightheight; - fixed_t pfloorleft, pfloorright; - INT64 overflow_test; -#else - (void)range; -#endif - light = &frontsector->lightlist[i]; - rlight = &dc_lightlist[p]; -#ifdef ESLOPE - -#define SLOPEPARAMS(slope, end1, end2, normalheight) \ - if (slope) { \ - end1 = P_GetZAt(slope, ds->leftpos.x, ds->leftpos.y); \ - end2 = P_GetZAt(slope, ds->rightpos.x, ds->rightpos.y); \ - } else \ - end1 = end2 = normalheight; - - SLOPEPARAMS(light->slope, leftheight, rightheight, light->height) - SLOPEPARAMS(*pfloor->b_slope, pfloorleft, pfloorright, *pfloor->bottomheight) - - if (leftheight < pfloorleft && rightheight < pfloorright) - continue; - - SLOPEPARAMS(*pfloor->t_slope, pfloorleft, pfloorright, *pfloor->topheight) - - if (leftheight > pfloorleft && rightheight > pfloorright && i+1 < dc_numlights) - { - lightlist_t *nextlight = &frontsector->lightlist[i+1]; - if ((nextlight->slope ? P_GetZAt(nextlight->slope, ds->leftpos.x, ds->leftpos.y) : nextlight->height) > pfloorleft - && (nextlight->slope ? P_GetZAt(nextlight->slope, ds->rightpos.x, ds->rightpos.y) : nextlight->height) > pfloorright) - continue; - } - - leftheight -= viewz; - rightheight -= viewz; - - // Monster Iestyn (25/03/18): do not skip these lights if they fail overflow test, just clamp them instead so they behave. - overflow_test = (INT64)centeryfrac - (((INT64)leftheight*ds->scale1)>>FRACBITS); - if (overflow_test > (INT64)CLAMPMAX) rlight->height = CLAMPMAX; - else if (overflow_test > (INT64)CLAMPMIN) rlight->height = (fixed_t)overflow_test; - else rlight->height = CLAMPMIN; - - overflow_test = (INT64)centeryfrac - (((INT64)rightheight*ds->scale2)>>FRACBITS); - if (overflow_test > (INT64)CLAMPMAX) rlight->heightstep = CLAMPMAX; - else if (overflow_test > (INT64)CLAMPMIN) rlight->heightstep = (fixed_t)overflow_test; - else rlight->heightstep = CLAMPMIN; - rlight->heightstep = (rlight->heightstep-rlight->height)/(range); -#else - if (light->height < *pfloor->bottomheight) - continue; - - if (light->height > *pfloor->topheight && i+1 < dc_numlights && frontsector->lightlist[i+1].height > *pfloor->topheight) - continue; - - lheight = light->height;// > *pfloor->topheight ? *pfloor->topheight + FRACUNIT : light->height; - rlight->heightstep = -FixedMul (rw.scalestep, (lheight - viewz)); - rlight->height = (centeryfrac) - FixedMul((lheight - viewz), spryscale); -#endif - rlight->flags = light->flags; - if (light->flags & FF_CUTLEVEL) - { -#ifdef ESLOPE - SLOPEPARAMS(*light->caster->b_slope, leftheight, rightheight, *light->caster->bottomheight) -#undef SLOPEPARAMS - leftheight -= viewz; - rightheight -= viewz; - - // Monster Iestyn (25/03/18): do not skip these lights if they fail overflow test, just clamp them instead so they behave. - overflow_test = (INT64)centeryfrac - (((INT64)leftheight*ds->scale1)>>FRACBITS); - if (overflow_test > (INT64)CLAMPMAX) rlight->botheight = CLAMPMAX; - else if (overflow_test > (INT64)CLAMPMIN) rlight->botheight = (fixed_t)overflow_test; - else rlight->botheight = CLAMPMIN; - - overflow_test = (INT64)centeryfrac - (((INT64)rightheight*ds->scale2)>>FRACBITS); - if (overflow_test > (INT64)CLAMPMAX) rlight->botheightstep = CLAMPMAX; - else if (overflow_test > (INT64)CLAMPMIN) rlight->botheightstep = (fixed_t)overflow_test; - else rlight->botheightstep = CLAMPMIN; - rlight->botheightstep = (rlight->botheightstep-rlight->botheight)/(range); -#else - lheight = *light->caster->bottomheight;// > *pfloor->topheight ? *pfloor->topheight + FRACUNIT : *light->caster->bottomheight; - rlight->botheightstep = -FixedMul (rw.scalestep, (lheight - viewz)); - rlight->botheight = (centeryfrac) - FixedMul((lheight - viewz), spryscale); -#endif - } - - rlight->lightlevel = *light->lightlevel; - rlight->extra_colormap = *light->extra_colormap; - - // Check if the current light effects the colormap/lightlevel - if (pfloor->flags & FF_FOG) - rlight->lightnum = (pfloor->master->frontsector->lightlevel >> LIGHTSEGSHIFT); - else - rlight->lightnum = (rlight->lightlevel >> LIGHTSEGSHIFT); - - if (pfloor->flags & FF_FOG || rlight->flags & FF_FOG || (rlight->extra_colormap && rlight->extra_colormap->fog)) - ; - else if (curline->v1->y == curline->v2->y) - rlight->lightnum--; - else if (curline->v1->x == curline->v2->x) - rlight->lightnum++; - - p++; - } - - dc_numlights = p; - } - else - { - // Get correct light level! - if ((frontsector->extra_colormap && frontsector->extra_colormap->fog)) - lightnum = (frontsector->lightlevel >> LIGHTSEGSHIFT); - else if (pfloor->flags & FF_FOG) - lightnum = (pfloor->master->frontsector->lightlevel >> LIGHTSEGSHIFT); - else if (colfunc == colfuncs[COLDRAWFUNC_FUZZY]) - lightnum = LIGHTLEVELS-1; - else - lightnum = R_FakeFlat(frontsector, &tempsec, &templight, &templight, false) - ->lightlevel >> LIGHTSEGSHIFT; - - if (pfloor->flags & FF_FOG || (frontsector->extra_colormap && frontsector->extra_colormap->fog)); - else if (curline->v1->y == curline->v2->y) - lightnum--; - else if (curline->v1->x == curline->v2->x) - lightnum++; - - if (lightnum < 0) - walllights = scalelight[0]; - else if (lightnum >= LIGHTLEVELS) - walllights = scalelight[LIGHTLEVELS-1]; - else - walllights = scalelight[lightnum]; - } -} - -// -// R_ThickStepping -// Set stepping values for thick sides. -// -#ifdef ESLOPE -static void R_ThickStepping(drawseg_t *ds, INT32 range) -{ - fixed_t right_top, right_bottom; - ffloor_t *pfloor = rw.pfloor; - - // calculate right ends now - if (*pfloor->t_slope) - right_top = P_GetZAt(*pfloor->t_slope, ds->rightpos.x, ds->rightpos.y) - viewz; - else - right_top = *pfloor->topheight - viewz; - - if (*pfloor->b_slope) - right_bottom = P_GetZAt(*pfloor->b_slope, ds->rightpos.x, ds->rightpos.y) - viewz; - else - right_bottom = *pfloor->bottomheight - viewz; - - // using INT64 to avoid 32bit overflow - rw.top_frac = (INT64)centeryfrac - (((INT64)rw.left_top * ds->scale1) >> FRACBITS); - rw.bottom_frac = (INT64)centeryfrac - (((INT64)rw.left_bottom * ds->scale1) >> FRACBITS); - rw.top_step = (INT64)centeryfrac - (((INT64)right_top * ds->scale2) >> FRACBITS); - rw.bottom_step = (INT64)centeryfrac - (((INT64)right_bottom * ds->scale2) >> FRACBITS); - - rw.top_step = (rw.top_step-rw.top_frac)/(range); - rw.bottom_step = (rw.bottom_step-rw.bottom_frac)/(range); - - rw.top_frac += rw.top_step * (rw.x - ds->x1); - rw.bottom_frac += rw.bottom_step * (rw.x - ds->x1); -} -#endif - -// -// R_RenderThickSideRange -// Renders all the thick sides in the given range. -// -void R_RenderThickSideRange(drawseg_t *ds, INT32 x1, INT32 x2, ffloor_t *pfloor) -{ - INT32 texnum; - - fixed_t offsetvalue = 0; - INT32 range; -#ifndef ESLOPE - fixed_t lheight; -#endif - line_t *newline = NULL; -#ifdef ESLOPE - // skew FOF walls with slopes? - boolean slopeskew = false; - pslope_t *skewslope = NULL; -#endif - - rw.x = x1; - rw.stopx = x2; - rw.pfloor = pfloor; - - // Calculate light table. - // Use different light tables - // for horizontal / vertical / diagonal. Diagonal? - // OPTIMIZE: get rid of LIGHTSEGSHIFT globally - - curline = ds->curline; - backsector = pfloor->target; - frontsector = curline->frontsector == pfloor->target ? curline->backsector : curline->frontsector; - texnum = R_GetTextureNum(sides[pfloor->master->sidenum[0]].midtexture); - - colfunc = colfuncs[BASEDRAWFUNC]; - - if (pfloor->master->flags & ML_TFERLINE) - { - size_t linenum = curline->linedef-backsector->lines[0]; - newline = pfloor->master->frontsector->lines[0] + linenum; - texnum = R_GetTextureNum(sides[newline->sidenum[0]].midtexture); - } - - if (pfloor->flags & FF_TRANSLUCENT) - { - boolean fuzzy = true; - - // Hacked up support for alpha value in software mode Tails 09-24-2002 - if (pfloor->alpha < 12) - return; // Don't even draw it - else if (pfloor->alpha < 38) - dc_transmap = transtables + ((tr_trans90-1)<alpha < 64) - dc_transmap = transtables + ((tr_trans80-1)<alpha < 89) - dc_transmap = transtables + ((tr_trans70-1)<alpha < 115) - dc_transmap = transtables + ((tr_trans60-1)<alpha < 140) - dc_transmap = transtables + ((tr_trans50-1)<alpha < 166) - dc_transmap = transtables + ((tr_trans40-1)<alpha < 192) - dc_transmap = transtables + ((tr_trans30-1)<alpha < 217) - dc_transmap = transtables + ((tr_trans20-1)<alpha < 243) - dc_transmap = transtables + ((tr_trans10-1)<flags & FF_FOG) - colfunc = colfuncs[COLDRAWFUNC_FOG]; - -#ifdef ESLOPE - range = max(ds->x2-ds->x1, 1); -#endif - //SoM: Moved these up here so they are available for my lightlist calculations - rw.scalestep = ds->scalestep; - spryscale = ds->scale1 + (x1 - ds->x1)*rw.scalestep; - - R_ThickLightLists(ds, range); - - maskedtexturecol = ds->thicksidecol; - - mfloorclip = ds->sprbottomclip; - mceilingclip = ds->sprtopclip; - dc_texheight = textureheight[texnum]>>FRACBITS; - -#ifdef ESLOPE - // calculate both left ends - if (*pfloor->t_slope) - rw.left_top = P_GetZAt(*pfloor->t_slope, ds->leftpos.x, ds->leftpos.y) - viewz; - else - rw.left_top = *pfloor->topheight - viewz; - - if (*pfloor->b_slope) - rw.left_bottom = P_GetZAt(*pfloor->b_slope, ds->leftpos.x, ds->leftpos.y) - viewz; - else - rw.left_bottom = *pfloor->bottomheight - viewz; - skewslope = *pfloor->t_slope; // skew using top slope by default - if (newline) - { - if (newline->flags & ML_DONTPEGTOP) - slopeskew = true; - } - else if (pfloor->master->flags & ML_DONTPEGTOP) - slopeskew = true; - - if (slopeskew) - dc_texturemid = rw.left_top; - else -#endif - dc_texturemid = *pfloor->topheight - viewz; - - if (newline) - { - offsetvalue = sides[newline->sidenum[0]].rowoffset; - if (newline->flags & ML_DONTPEGBOTTOM) - { -#ifdef ESLOPE - skewslope = *pfloor->b_slope; // skew using bottom slope - if (slopeskew) - dc_texturemid = rw.left_bottom; - else -#endif - offsetvalue -= *pfloor->topheight - *pfloor->bottomheight; - } - } - else - { - offsetvalue = sides[pfloor->master->sidenum[0]].rowoffset; - if (curline->linedef->flags & ML_DONTPEGBOTTOM) - { -#ifdef ESLOPE - skewslope = *pfloor->b_slope; // skew using bottom slope - if (slopeskew) - dc_texturemid = rw.left_bottom; - else -#endif - offsetvalue -= *pfloor->topheight - *pfloor->bottomheight; - } - } - -#ifdef ESLOPE - if (slopeskew) - { - angle_t lineangle = R_PointToAngle2(curline->v1->x, curline->v1->y, curline->v2->x, curline->v2->y); - - if (skewslope) - rw.ffloortextureslide = FixedMul(skewslope->zdelta, FINECOSINE((lineangle-skewslope->xydirection)>>ANGLETOFINESHIFT)); - } -#endif - - dc_texturemid += offsetvalue; - - // Texture must be cached before setting colfunc_2s, - // otherwise texture[texnum]->holes may be false when it shouldn't be - R_CheckTextureCache(texnum); - //faB: handle case where multipatch texture is drawn on a 2sided wall, multi-patch textures - // are not stored per-column with post info anymore in Doom Legacy - if (textures[texnum]->holes) - { - if (textures[texnum]->flip & 2) // vertically flipped? - { - rw.colfunc_2s = R_DrawRepeatFlippedMaskedColumn; - rw.column2s_length = textures[texnum]->height; - } - else - rw.colfunc_2s = R_DrawRepeatMaskedColumn; // render the usual 2sided single-patch packed texture - } - else - { - rw.colfunc_2s = R_Render2sidedMultiPatchColumn; //render multipatch with no holes (no post_t info) - rw.column2s_length = textures[texnum]->height; - } - -#ifdef ESLOPE - // Set heights according to plane, or slope, whichever - R_ThickStepping(ds, range); -#endif - - // draw the columns - rw.texnum = texnum; - R_RenderThickSegLoop(); - colfunc = colfuncs[BASEDRAWFUNC]; - -#undef CLAMPMAX -#undef CLAMPMIN -} diff --git a/src/r_state.h b/src/r_state.h index 2c5e5fcf7..75566923b 100644 --- a/src/r_state.h +++ b/src/r_state.h @@ -93,41 +93,10 @@ extern angle_t doubleclipangle; extern INT32 viewangletox[FINEANGLES/2]; extern angle_t xtoviewangle[MAXVIDWIDTH+1]; -// Wall rendering -typedef struct -{ - INT32 x, stopx; - angle_t centerangle; - fixed_t offset; - fixed_t offset2; // for splats - fixed_t scale, scalestep; - fixed_t midtexturemid, toptexturemid, bottomtexturemid; -#ifdef ESLOPE - fixed_t toptextureslide, midtextureslide, bottomtextureslide; // Defines how to adjust Y offsets along the wall for slopes - fixed_t midtextureback, midtexturebackslide; // Values for masked midtexture height calculation -#endif - fixed_t distance; - angle_t normalangle; - angle_t angle1; // angle to line origin +extern fixed_t rw_distance; +extern angle_t rw_normalangle; - // for masked segs and thick sides - INT32 texnum; - void (*colfunc_2s) (column_t *); - INT32 column2s_length; // column->length : for multi-patch on 2sided wall = texture->height - - // masked segs - INT32 maskedrepeat; - - // thick sides - ffloor_t *pfloor; -#ifdef ESLOPE - // Render FOF sides kinda like normal sides, with the frac and step and everything - // NOTE: INT64 instead of fixed_t because overflow concerns - INT64 top_frac, top_step, bottom_frac, bottom_step; - fixed_t ffloortextureslide; - fixed_t left_top, left_bottom; // needed here for slope skewing -#endif -} renderwall_t; -extern renderwall_t rw; +// angle to line origin +extern angle_t rw_angle1; #endif From caadf6aa6128c417496aefc358b973c2a49c1361 Mon Sep 17 00:00:00 2001 From: Louis-Antoine Date: Wed, 1 Jan 2020 13:29:07 +0100 Subject: [PATCH 585/746] 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 24d68ba07e862ce4b36633d416b00868c72b6607 Mon Sep 17 00:00:00 2001 From: MascaraSnake Date: Wed, 1 Jan 2020 13:40:17 +0100 Subject: [PATCH 586/746] P_LoadTextmap: Set defaults for all linedef and sidedef fields that UDMF is allowed to set --- src/p_setup.c | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/src/p_setup.c b/src/p_setup.c index a48cfe909..e71d6094f 100644 --- a/src/p_setup.c +++ b/src/p_setup.c @@ -1563,8 +1563,11 @@ static void P_LoadTextmap(void) for (i = 0, ld = lines; i < numlines; i++, ld++) { // Defaults. - ld->tag = 0; + ld->v1 = ld->v2 = NULL; + ld->flags = 0; ld->special = 0; + ld->tag = 0; + ld->sidenum[0] = 0xffff; ld->sidenum[1] = 0xffff; TextmapParse(linesPos[i], i, ParseTextmapLinedefParameter); @@ -1575,12 +1578,12 @@ static void P_LoadTextmap(void) for (i = 0, sd = sides; i < numsides; i++, sd++) { // Defaults. - sd->rowoffset = 0; sd->textureoffset = 0; - + sd->rowoffset = 0; sd->toptexture = R_TextureNumForName("-"); sd->midtexture = R_TextureNumForName("-"); sd->bottomtexture = R_TextureNumForName("-"); + sd->sector = NULL; sd->repeatcnt = 0; TextmapParse(sidesPos[i], i, ParseTextmapSidedefParameter); From b59532bccaa332182b56087d6a3ca1e2fe1455a2 Mon Sep 17 00:00:00 2001 From: MascaraSnake Date: Wed, 1 Jan 2020 14:13:24 +0100 Subject: [PATCH 587/746] Setup repeatcnt in P_LoadSidedefs instead of P_ProcessLinedefsWithSidedefs, since UDMF can set it directly --- src/p_setup.c | 36 ++++++++++++++++++++++-------------- 1 file changed, 22 insertions(+), 14 deletions(-) diff --git a/src/p_setup.c b/src/p_setup.c index e71d6094f..d00eebfc8 100644 --- a/src/p_setup.c +++ b/src/p_setup.c @@ -1014,13 +1014,11 @@ static void P_InitializeLinedef(line_t *ld) { sides[ld->sidenum[0]].special = ld->special; sides[ld->sidenum[0]].line = ld; - } if (ld->sidenum[1] != 0xffff) { sides[ld->sidenum[1]].special = ld->special; sides[ld->sidenum[1]].line = ld; - } } @@ -1053,10 +1051,30 @@ static void P_LoadSidedefs(UINT8 *data) for (i = 0; i < numsides; i++, sd++, msd++) { + INT16 textureoffset = SHORT(msd->textureoffset); UINT16 sector_num; - boolean isfrontside = !sd->line || sd->line->sidenum[0] == i; + boolean isfrontside; - sd->textureoffset = SHORT(msd->textureoffset)<line) + { + CONS_Debug(DBG_SETUP, "P_LoadSidedefs: Sidedef %s is not used by any linedef\n", sizeu1((size_t)(sd - sides))); + sd->line = &lines[0]; + } + + isfrontside = sd->line->sidenum[0] == i; + + // Repeat count for midtexture + if (((sd->line->flags & (ML_TWOSIDED|ML_EFFECT5)) == (ML_TWOSIDED|ML_EFFECT5)) + && !(sd->special >= 300 && sd->special < 500)) // exempt linedef exec specials + { + sd->repeatcnt = (INT16)(((unsigned)textureoffset) >> 12); + sd->textureoffset = (((unsigned)textureoffset) & 2047) << FRACBITS; + } + else + { + sd->repeatcnt = 0; + sd->textureoffset = textureoffset << FRACBITS; + } sd->rowoffset = SHORT(msd->rowoffset)<frontsector = sides[ld->sidenum[0]].sector; //e6y: Can't be -1 here ld->backsector = ld->sidenum[1] != 0xffff ? sides[ld->sidenum[1]].sector : 0; - // Repeat count for midtexture - if ((ld->flags & ML_EFFECT5) && (ld->sidenum[1] != 0xffff) - && !(ld->special >= 300 && ld->special < 500)) // exempt linedef exec specials - { - sides[ld->sidenum[0]].repeatcnt = (INT16)(((unsigned)sides[ld->sidenum[0]].textureoffset >> FRACBITS) >> 12); - sides[ld->sidenum[0]].textureoffset = (((unsigned)sides[ld->sidenum[0]].textureoffset >> FRACBITS) & 2047) << FRACBITS; - sides[ld->sidenum[1]].repeatcnt = (INT16)(((unsigned)sides[ld->sidenum[1]].textureoffset >> FRACBITS) >> 12); - sides[ld->sidenum[1]].textureoffset = (((unsigned)sides[ld->sidenum[1]].textureoffset >> FRACBITS) & 2047) << FRACBITS; - } - // Compile linedef 'text' from both sidedefs 'text' for appropriate specials. switch(ld->special) { From fe198b8a324e9cadee99ffcccf69b4102a4c3609 Mon Sep 17 00:00:00 2001 From: MascaraSnake Date: Wed, 1 Jan 2020 14:27:01 +0100 Subject: [PATCH 588/746] Check if certain mandatory linedef and sidedef fields are set, and use fallback values if not --- src/p_setup.c | 70 +++++++++++++++++++++++++++++++++++++++------------ 1 file changed, 54 insertions(+), 16 deletions(-) diff --git a/src/p_setup.c b/src/p_setup.c index d00eebfc8..c915000d9 100644 --- a/src/p_setup.c +++ b/src/p_setup.c @@ -1022,6 +1022,26 @@ static void P_InitializeLinedef(line_t *ld) } } +static void P_SetLinedefV1(size_t i, UINT16 vertex_num) +{ + if (vertex_num >= numvertexes) + { + CONS_Debug(DBG_SETUP, "P_SetLinedefV1: linedef %s has out-of-range v1 num %u\n", sizeu1(i), vertex_num); + vertex_num = 0; + } + lines[i].v1 = &vertexes[vertex_num]; +} + +static void P_SetLinedefV2(size_t i, UINT16 vertex_num) +{ + if (vertex_num >= numvertexes) + { + CONS_Debug(DBG_SETUP, "P_SetLinedefV2: linedef %s has out-of-range v2 num %u\n", sizeu1(i), vertex_num); + vertex_num = 0; + } + lines[i].v2 = &vertexes[vertex_num]; +} + static void P_LoadLinedefs(UINT8 *data) { maplinedef_t *mld = (maplinedef_t *)data; @@ -1033,8 +1053,8 @@ static void P_LoadLinedefs(UINT8 *data) ld->flags = SHORT(mld->flags); ld->special = SHORT(mld->special); ld->tag = SHORT(mld->tag); - ld->v1 = &vertexes[SHORT(mld->v1)]; - ld->v2 = &vertexes[SHORT(mld->v2)]; + P_SetLinedefV1(i, SHORT(mld->v1)); + P_SetLinedefV2(i, SHORT(mld->v2)); ld->sidenum[0] = SHORT(mld->sidenum[0]); ld->sidenum[1] = SHORT(mld->sidenum[1]); @@ -1043,6 +1063,17 @@ static void P_LoadLinedefs(UINT8 *data) } } +static void P_SetSidedefSector(size_t i, UINT16 sector_num) +{ + // cph 2006/09/30 - catch out-of-range sector numbers; use sector 0 instead + if (sector_num >= numsectors) + { + CONS_Debug(DBG_SETUP, "P_SetSidedefSector: sidedef %s has out-of-range sector num %u\n", sizeu1(i), sector_num); + sector_num = 0; + } + sides[i].sector = §ors[sector_num]; +} + static void P_LoadSidedefs(UINT8 *data) { mapsidedef_t *msd = (mapsidedef_t*)data; @@ -1052,12 +1083,11 @@ static void P_LoadSidedefs(UINT8 *data) for (i = 0; i < numsides; i++, sd++, msd++) { INT16 textureoffset = SHORT(msd->textureoffset); - UINT16 sector_num; boolean isfrontside; if (!sd->line) { - CONS_Debug(DBG_SETUP, "P_LoadSidedefs: Sidedef %s is not used by any linedef\n", sizeu1((size_t)(sd - sides))); + CONS_Debug(DBG_SETUP, "P_LoadSidedefs: Sidedef %s is not used by any linedef\n", sizeu1(i)); sd->line = &lines[0]; } @@ -1077,14 +1107,7 @@ static void P_LoadSidedefs(UINT8 *data) } sd->rowoffset = SHORT(msd->rowoffset)<sector); - if (sector_num >= numsectors) - { - CONS_Debug(DBG_SETUP, "P_LoadSidedefs: sidedef %s has out-of-range sector num %u\n", sizeu1(i), sector_num); - sector_num = 0; - } - sd->sector = §ors[sector_num]; + P_SetSidedefSector(i, SHORT(msd->sector)); sd->colormap_data = NULL; @@ -1385,7 +1408,7 @@ static void ParseTextmapSidedefParameter(UINT32 i, char *param) else if (fastcmp(param, "texturemiddle")) sides[i].midtexture = R_TextureNumForName(dat = M_GetToken(NULL)); else if (fastcmp(param, "sector")) - sides[i].sector = §ors[atol(dat = M_GetToken(NULL))]; + P_SetSidedefSector(i, atol(dat = M_GetToken(NULL))); else if (fastcmp(param, "repeatcnt")) sides[i].repeatcnt = atol(dat = M_GetToken(NULL)); } @@ -1397,9 +1420,9 @@ static void ParseTextmapLinedefParameter(UINT32 i, char *param) else if (fastcmp(param, "special")) lines[i].special = atol(dat = M_GetToken(NULL)); else if (fastcmp(param, "v1")) - lines[i].v1 = &vertexes[atol(dat = M_GetToken(NULL))]; + P_SetLinedefV1(i, atol(dat = M_GetToken(NULL))); else if (fastcmp(param, "v2")) - lines[i].v2 = &vertexes[atol(dat = M_GetToken(NULL))]; + P_SetLinedefV2(i, atol(dat = M_GetToken(NULL))); else if (fastcmp(param, "sidefront")) lines[i].sidenum[0] = atol(dat = M_GetToken(NULL)); else if (fastcmp(param, "sideback")) @@ -1589,7 +1612,16 @@ static void P_LoadTextmap(void) ld->sidenum[1] = 0xffff; TextmapParse(linesPos[i], i, ParseTextmapLinedefParameter); - + if (!ld->v1) + { + CONS_Debug(DBG_SETUP, "P_LoadTextmap: linedef %s has no v1 set; defaulting to 0\n", sizeu1(i)); + ld->v1 = &vertexes[0]; + } + if (!ld->v2) + { + CONS_Debug(DBG_SETUP, "P_LoadTextmap: linedef %s has no v2 set; defaulting to 0\n", sizeu1(i)); + ld->v2 = &vertexes[0]; + } P_InitializeLinedef(ld); } @@ -1605,6 +1637,12 @@ static void P_LoadTextmap(void) sd->repeatcnt = 0; TextmapParse(sidesPos[i], i, ParseTextmapSidedefParameter); + + if (!sd->sector) + { + CONS_Debug(DBG_SETUP, "P_LoadTextmap: sidedef %s has no sector set; defaulting to 0\n", sizeu1(i)); + sd->sector = §ors[0]; + } } for (i = 0, mt = mapthings; i < nummapthings; i++, mt++) From a41c6405591fd6ba8bd3f4081620be321f3dfc06 Mon Sep 17 00:00:00 2001 From: MascaraSnake Date: Wed, 1 Jan 2020 15:10:41 +0100 Subject: [PATCH 589/746] Move shared parts of sidedef initialization into P_InitializeSidedef --- src/p_setup.c | 22 +++++++++++++++------- 1 file changed, 15 insertions(+), 7 deletions(-) diff --git a/src/p_setup.c b/src/p_setup.c index c915000d9..e2ae29cf7 100644 --- a/src/p_setup.c +++ b/src/p_setup.c @@ -1074,6 +1074,19 @@ static void P_SetSidedefSector(size_t i, UINT16 sector_num) sides[i].sector = §ors[sector_num]; } +static void P_InitializeSidedef(side_t *sd) +{ + if (!sd->line) + { + CONS_Debug(DBG_SETUP, "P_LoadSidedefs: Sidedef %s is not used by any linedef\n", sizeu1(i)); + sd->line = &lines[0]; + sd->special = sd->line->special; + } + + sd->text = NULL; + sd->colormap_data = NULL; +} + static void P_LoadSidedefs(UINT8 *data) { mapsidedef_t *msd = (mapsidedef_t*)data; @@ -1085,11 +1098,7 @@ static void P_LoadSidedefs(UINT8 *data) INT16 textureoffset = SHORT(msd->textureoffset); boolean isfrontside; - if (!sd->line) - { - CONS_Debug(DBG_SETUP, "P_LoadSidedefs: Sidedef %s is not used by any linedef\n", sizeu1(i)); - sd->line = &lines[0]; - } + P_InitializeSidedef(sd); isfrontside = sd->line->sidenum[0] == i; @@ -1109,8 +1118,6 @@ static void P_LoadSidedefs(UINT8 *data) P_SetSidedefSector(i, SHORT(msd->sector)); - sd->colormap_data = NULL; - // Special info stored in texture fields! switch (sd->special) { @@ -1643,6 +1650,7 @@ static void P_LoadTextmap(void) CONS_Debug(DBG_SETUP, "P_LoadTextmap: sidedef %s has no sector set; defaulting to 0\n", sizeu1(i)); sd->sector = §ors[0]; } + P_InitializeSidedef(sd); } for (i = 0, mt = mapthings; i < nummapthings; i++, mt++) From 6724b11c368ced28b65315942de1bd5b6003df98 Mon Sep 17 00:00:00 2001 From: MascaraSnake Date: Wed, 1 Jan 2020 15:11:39 +0100 Subject: [PATCH 590/746] Whoops --- src/p_setup.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/p_setup.c b/src/p_setup.c index e2ae29cf7..f72e25da0 100644 --- a/src/p_setup.c +++ b/src/p_setup.c @@ -1078,7 +1078,7 @@ static void P_InitializeSidedef(side_t *sd) { if (!sd->line) { - CONS_Debug(DBG_SETUP, "P_LoadSidedefs: Sidedef %s is not used by any linedef\n", sizeu1(i)); + CONS_Debug(DBG_SETUP, "P_LoadSidedefs: Sidedef %s is not used by any linedef\n", sizeu1((size_t)(sd - sides))); sd->line = &lines[0]; sd->special = sd->line->special; } From 9cda82d896a47179f307c0177525e390494c9219 Mon Sep 17 00:00:00 2001 From: MascaraSnake Date: Wed, 1 Jan 2020 15:52:59 +0100 Subject: [PATCH 591/746] Rework textmap parser to always read a parameter's value, even if it doesn't recognize the parameter --- src/p_setup.c | 151 +++++++++++++++++++++++++------------------------- 1 file changed, 75 insertions(+), 76 deletions(-) diff --git a/src/p_setup.c b/src/p_setup.c index f72e25da0..dc115ed19 100644 --- a/src/p_setup.c +++ b/src/p_setup.c @@ -1362,135 +1362,133 @@ static boolean TextmapCount(UINT8 *data, size_t size) return true; } -static char* dat; - -static void ParseTextmapVertexParameter(UINT32 i, char *param) +static void ParseTextmapVertexParameter(UINT32 i, char *param, char *val) { if (fastcmp(param, "x")) - vertexes[i].x = FLOAT_TO_FIXED(atof(dat = M_GetToken(NULL))); + vertexes[i].x = FLOAT_TO_FIXED(atof(val)); else if (fastcmp(param, "y")) - vertexes[i].y = FLOAT_TO_FIXED(atof(dat = M_GetToken(NULL))); + vertexes[i].y = FLOAT_TO_FIXED(atof(val)); } -static void ParseTextmapSectorParameter(UINT32 i, char *param) +static void ParseTextmapSectorParameter(UINT32 i, char *param, char *val) { if (fastcmp(param, "heightfloor")) - sectors[i].floorheight = atol(dat = M_GetToken(NULL)) << FRACBITS; + sectors[i].floorheight = atol(val) << FRACBITS; else if (fastcmp(param, "heightceiling")) - sectors[i].ceilingheight = atol(dat = M_GetToken(NULL)) << FRACBITS; + sectors[i].ceilingheight = atol(val) << FRACBITS; if (fastcmp(param, "texturefloor")) - sectors[i].floorpic = P_AddLevelFlat(dat = M_GetToken(NULL), foundflats); + sectors[i].floorpic = P_AddLevelFlat(val, foundflats); else if (fastcmp(param, "textureceiling")) - sectors[i].ceilingpic = P_AddLevelFlat(dat = M_GetToken(NULL), foundflats); + sectors[i].ceilingpic = P_AddLevelFlat(val, foundflats); else if (fastcmp(param, "lightlevel")) - sectors[i].lightlevel = atol(dat = M_GetToken(NULL)); + sectors[i].lightlevel = atol(val); else if (fastcmp(param, "special")) - sectors[i].special = atol(dat = M_GetToken(NULL)); + sectors[i].special = atol(val); else if (fastcmp(param, "id")) - sectors[i].tag = atol(dat = M_GetToken(NULL)); + sectors[i].tag = atol(val); else if (fastcmp(param, "xpanningfloor")) - sectors[i].floor_xoffs = FLOAT_TO_FIXED(atof(dat = M_GetToken(NULL))); + sectors[i].floor_xoffs = FLOAT_TO_FIXED(atof(val)); else if (fastcmp(param, "ypanningfloor")) - sectors[i].floor_yoffs = FLOAT_TO_FIXED(atof(dat = M_GetToken(NULL))); + sectors[i].floor_yoffs = FLOAT_TO_FIXED(atof(val)); else if (fastcmp(param, "xpanningceiling")) - sectors[i].ceiling_xoffs = FLOAT_TO_FIXED(atof(dat = M_GetToken(NULL))); + sectors[i].ceiling_xoffs = FLOAT_TO_FIXED(atof(val)); else if (fastcmp(param, "ypanningceiling")) - sectors[i].ceiling_yoffs = FLOAT_TO_FIXED(atof(dat = M_GetToken(NULL))); + sectors[i].ceiling_yoffs = FLOAT_TO_FIXED(atof(val)); else if (fastcmp(param, "rotationfloor")) - sectors[i].floorpic_angle = FixedAngle(FLOAT_TO_FIXED(atof(dat = M_GetToken(NULL)))); + sectors[i].floorpic_angle = FixedAngle(FLOAT_TO_FIXED(atof(val))); else if (fastcmp(param, "rotationceiling")) - sectors[i].ceilingpic_angle = FixedAngle(FLOAT_TO_FIXED(atof(dat = M_GetToken(NULL)))); + sectors[i].ceilingpic_angle = FixedAngle(FLOAT_TO_FIXED(atof(val))); } -static void ParseTextmapSidedefParameter(UINT32 i, char *param) +static void ParseTextmapSidedefParameter(UINT32 i, char *param, char *val) { if (fastcmp(param, "offsetx")) - sides[i].textureoffset = atol(dat = M_GetToken(NULL))< Date: Wed, 1 Jan 2020 16:01:07 +0100 Subject: [PATCH 592/746] Move MAXFLATSIZE define to p_spec.h so p_spec.c doesn't have to redefine it --- src/p_setup.c | 4 ---- src/p_spec.c | 3 --- src/p_spec.h | 3 +++ 3 files changed, 3 insertions(+), 7 deletions(-) diff --git a/src/p_setup.c b/src/p_setup.c index dc115ed19..8b82e8c69 100644 --- a/src/p_setup.c +++ b/src/p_setup.c @@ -1527,8 +1527,6 @@ static void TextmapParse(UINT32 dataPos, size_t num, void (*parser)(UINT32, char } } -#define MAXFLATSIZE (2048<> ((j-1)*4))&15) +// This must be updated whenever we up the max flat size - quicker to assume rather than figuring out the sqrt of the specific flat's filesize. +#define MAXFLATSIZE (2048< Date: Wed, 1 Jan 2020 23:49:29 +0800 Subject: [PATCH 593/746] 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 35ff383a4a7ce23039422c356e7073204f3fc8f8 Mon Sep 17 00:00:00 2001 From: Jaime Passos Date: Wed, 1 Jan 2020 15:17:29 -0300 Subject: [PATCH 594/746] 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 98b7d8aaca1e9c667b4d8ee55d7015998588646f Mon Sep 17 00:00:00 2001 From: Jaime Passos Date: Wed, 1 Jan 2020 15:55:18 -0300 Subject: [PATCH 595/746] Fix broken model light lists in ACZ3 --- src/hardware/hw_md2.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/hardware/hw_md2.c b/src/hardware/hw_md2.c index 630c1e181..13a8cc44e 100644 --- a/src/hardware/hw_md2.c +++ b/src/hardware/hw_md2.c @@ -1108,7 +1108,7 @@ boolean HWR_DrawModel(gr_vissprite_t *spr) { sector_t *sector = spr->mobj->subsector->sector; UINT8 lightlevel = 255; - extracolormap_t *colormap = sector->extra_colormap; + extracolormap_t *colormap = NULL; if (sector->numlights) { From 401c35b4075d2345609b690420705c81d34b6423 Mon Sep 17 00:00:00 2001 From: Jaime Passos Date: Wed, 1 Jan 2020 17:28:22 -0300 Subject: [PATCH 596/746] Fix transparent PNG conversion --- src/r_patch.c | 61 ++++++++++++++++++++++++++++++++++++++++++--------- src/r_patch.h | 2 +- src/w_wad.c | 31 +++++++++++++------------- 3 files changed, 67 insertions(+), 27 deletions(-) diff --git a/src/r_patch.c b/src/r_patch.c index 18dfe523a..7508234a5 100644 --- a/src/r_patch.c +++ b/src/r_patch.c @@ -250,6 +250,9 @@ patch_t *R_FlatToPatch(UINT8 *raw, UINT16 width, UINT16 height, UINT16 leftoffse UINT8 *colpointers, *startofspan; size_t size = 0; + if (!raw) + return NULL; + // Write image size and offset WRITEINT16(imgptr, width); WRITEINT16(imgptr, height); @@ -353,12 +356,13 @@ patch_t *R_FlatToPatch(UINT8 *raw, UINT16 width, UINT16 height, UINT16 leftoffse // // Convert a 16-bit flat to a patch. // -patch_t *R_FlatToPatch_16bpp(UINT16 *raw, UINT16 width, UINT16 height, size_t *size) +patch_t *R_FlatToPatch_16bpp(UINT16 *raw, UINT16 width, UINT16 height, UINT16 leftoffset, UINT16 topoffset, size_t *destsize) { UINT32 x, y; UINT8 *img; UINT8 *imgptr = imgbuf; UINT8 *colpointers, *startofspan; + size_t size = 0; if (!raw) return NULL; @@ -366,9 +370,8 @@ patch_t *R_FlatToPatch_16bpp(UINT16 *raw, UINT16 width, UINT16 height, size_t *s // Write image size and offset WRITEINT16(imgptr, width); WRITEINT16(imgptr, height); - // no offsets - WRITEINT16(imgptr, 0); - WRITEINT16(imgptr, 0); + WRITEINT16(imgptr, leftoffset); + WRITEINT16(imgptr, topoffset); // Leave placeholder to column pointers colpointers = imgptr; @@ -452,9 +455,12 @@ patch_t *R_FlatToPatch_16bpp(UINT16 *raw, UINT16 width, UINT16 height, size_t *s WRITEUINT8(imgptr, 0xFF); } - *size = imgptr-imgbuf; - img = Z_Malloc(*size, PU_STATIC, NULL); - memcpy(img, imgbuf, *size); + size = imgptr-imgbuf; + img = Z_Malloc(size, PU_STATIC, NULL); + memcpy(img, imgbuf, size); + + if (destsize != NULL) + *destsize = size; return (patch_t *)img; } @@ -677,6 +683,41 @@ static UINT8 *PNG_RawConvert(const UINT8 *png, UINT16 *w, UINT16 *h, INT16 *topo return flat; } +// Convert a PNG with transparency to a raw image. +static UINT16 *PNG_RawConvert_16bpp(const UINT8 *png, UINT16 *w, UINT16 *h, INT16 *topoffset, INT16 *leftoffset, size_t size) +{ + UINT16 *flat; + png_uint_32 x, y; + png_bytep *row_pointers = PNG_Read(png, w, h, topoffset, leftoffset, size); + png_uint_32 width = *w, height = *h; + size_t flatsize, i; + + if (!row_pointers) + I_Error("PNG_RawConvert_16bpp: conversion failed"); + + // Convert the image to 16bpp + flatsize = (width * height); + flat = Z_Malloc(flatsize * sizeof(UINT16), PU_LEVEL, NULL); + + // can't memset here + for (i = 0; i < flatsize; i++) + flat[i] = 0xFF00; + + for (y = 0; y < height; y++) + { + png_bytep row = row_pointers[y]; + for (x = 0; x < width; x++) + { + png_bytep px = &(row[x * 4]); + if ((UINT8)px[3]) + flat[((y * width) + x)] = NearestColor((UINT8)px[0], (UINT8)px[1], (UINT8)px[2]); + } + } + free(row_pointers); + + return flat; +} + // // R_PNGToFlat // @@ -696,12 +737,12 @@ patch_t *R_PNGToPatch(const UINT8 *png, size_t size, size_t *destsize, boolean t { UINT16 width, height; INT16 topoffset = 0, leftoffset = 0; - UINT8 *raw = PNG_RawConvert(png, &width, &height, &topoffset, &leftoffset, size); + UINT16 *raw = PNG_RawConvert_16bpp(png, &width, &height, &topoffset, &leftoffset, size); if (!raw) I_Error("R_PNGToPatch: conversion failed"); - return R_FlatToPatch(raw, width, height, leftoffset, topoffset, destsize, transparency); + return R_FlatToPatch_16bpp(raw, width, height, leftoffset, topoffset, destsize); } // @@ -1264,7 +1305,7 @@ void R_CacheRotSprite(spritenum_t sprnum, UINT8 frame, spriteinfo_t *sprinfo, sp } // make patch - newpatch = R_FlatToPatch_16bpp(rawdst, newwidth, newheight, &size); + newpatch = R_FlatToPatch_16bpp(rawdst, newwidth, newheight, 0, 0, &size); { newpatch->leftoffset = (newpatch->width / 2) + (leftoffset - px); newpatch->topoffset = (newpatch->height / 2) + (patch->topoffset - py); diff --git a/src/r_patch.h b/src/r_patch.h index 53d306b88..71f715ccc 100644 --- a/src/r_patch.h +++ b/src/r_patch.h @@ -47,7 +47,7 @@ void R_TextureToFlat(size_t tex, UINT8 *flat); void R_PatchToFlat(patch_t *patch, UINT8 *flat); void R_PatchToFlat_16bpp(patch_t *patch, UINT16 *raw, boolean flip); patch_t *R_FlatToPatch(UINT8 *raw, UINT16 width, UINT16 height, UINT16 leftoffset, UINT16 topoffset, size_t *destsize, boolean transparency); -patch_t *R_FlatToPatch_16bpp(UINT16 *raw, UINT16 width, UINT16 height, size_t *size); +patch_t *R_FlatToPatch_16bpp(UINT16 *raw, UINT16 width, UINT16 height, UINT16 leftoffset, UINT16 topoffset, size_t *destsize); // Portable Network Graphics boolean R_IsLumpPNG(const UINT8 *d, size_t s); diff --git a/src/w_wad.c b/src/w_wad.c index d8b362d49..82f9526c6 100644 --- a/src/w_wad.c +++ b/src/w_wad.c @@ -1465,6 +1465,21 @@ boolean W_IsPatchCached(lumpnum_t lumpnum, void *ptr) return W_IsPatchCachedPWAD(WADFILENUM(lumpnum),LUMPNUM(lumpnum), ptr); } +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_HWRMODELTEXTURE); + Z_FreeTag(PU_HWRCACHE); + Z_FreeTags(PU_HWRCACHE_UNLOCKED, PU_HWRPATCHINFO_UNLOCKED); + } + needpatchflush = false; +} + // ========================================================================== // W_CacheLumpName // ========================================================================== @@ -1488,22 +1503,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_HWRMODELTEXTURE); - Z_FreeTag(PU_HWRCACHE); - Z_FreeTags(PU_HWRCACHE_UNLOCKED, PU_HWRPATCHINFO_UNLOCKED); - } - needpatchflush = false; -} - -// Software-only compile cache the data without conversion void *W_CachePatchNumPwad(UINT16 wad, UINT16 lump, INT32 tag) { #ifdef HWRENDER From 6d2f2e0865ffceb59e825897d5eda5b23facf541 Mon Sep 17 00:00:00 2001 From: Jaime Passos Date: Wed, 1 Jan 2020 17:30:07 -0300 Subject: [PATCH 597/746] Update copyrights --- src/r_patch.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/r_patch.c b/src/r_patch.c index 7508234a5..db5d874b4 100644 --- a/src/r_patch.c +++ b/src/r_patch.c @@ -2,8 +2,8 @@ //----------------------------------------------------------------------------- // Copyright (C) 1993-1996 by id Software, Inc. // Copyright (C) 2005-2009 by Andrey "entryway" Budko. -// Copyright (C) 2018-2019 by Jaime "Lactozilla" Passos. -// Copyright (C) 2019 by Sonic Team Junior. +// Copyright (C) 2018-2020 by Jaime "Lactozilla" Passos. +// Copyright (C) 2019-2020 by Sonic Team Junior. // // This program is free software distributed under the // terms of the GNU General Public License, version 2. From c7794d4ce03eff87afd40d59234de7129c319dc7 Mon Sep 17 00:00:00 2001 From: Jaime Passos Date: Wed, 1 Jan 2020 17:36:55 -0300 Subject: [PATCH 598/746] Remove unused parameter --- src/hardware/hw_cache.c | 4 ++-- src/r_data.c | 2 +- src/r_patch.c | 2 +- src/r_patch.h | 2 +- src/r_things.c | 2 +- src/w_wad.c | 2 +- 6 files changed, 7 insertions(+), 7 deletions(-) diff --git a/src/hardware/hw_cache.c b/src/hardware/hw_cache.c index c47833187..46f7b2bde 100644 --- a/src/hardware/hw_cache.c +++ b/src/hardware/hw_cache.c @@ -654,7 +654,7 @@ static void HWR_GenerateTexture(INT32 texnum, GLTexture_t *grtex) #ifndef NO_PNG_LUMPS if (R_IsLumpPNG((UINT8 *)realpatch, lumplength)) - realpatch = R_PNGToPatch((UINT8 *)realpatch, lumplength, NULL, false); + realpatch = R_PNGToPatch((UINT8 *)realpatch, lumplength, NULL); else #endif #ifdef WALLFLATS @@ -698,7 +698,7 @@ void HWR_MakePatch (const patch_t *patch, GLPatch_t *grPatch, GLMipmap_t *grMipm // lump is a png so convert it size_t len = W_LumpLengthPwad(grPatch->wadnum, grPatch->lumpnum); if ((patch != NULL) && R_IsLumpPNG((const UINT8 *)patch, len)) - patch = R_PNGToPatch((const UINT8 *)patch, len, NULL, true); + patch = R_PNGToPatch((const UINT8 *)patch, len, NULL); #endif // don't do it twice (like a cache) diff --git a/src/r_data.c b/src/r_data.c index bfd83a62d..5eac508d6 100644 --- a/src/r_data.c +++ b/src/r_data.c @@ -571,7 +571,7 @@ static UINT8 *R_GenerateTexture(size_t texnum) #ifndef NO_PNG_LUMPS if (R_IsLumpPNG((UINT8 *)realpatch, lumplength)) - realpatch = R_PNGToPatch((UINT8 *)realpatch, lumplength, NULL, false); + realpatch = R_PNGToPatch((UINT8 *)realpatch, lumplength, NULL); else #endif #ifdef WALLFLATS diff --git a/src/r_patch.c b/src/r_patch.c index db5d874b4..308385686 100644 --- a/src/r_patch.c +++ b/src/r_patch.c @@ -733,7 +733,7 @@ UINT8 *R_PNGToFlat(UINT16 *width, UINT16 *height, UINT8 *png, size_t size) // // Convert a PNG to a patch. // -patch_t *R_PNGToPatch(const UINT8 *png, size_t size, size_t *destsize, boolean transparency) +patch_t *R_PNGToPatch(const UINT8 *png, size_t size, size_t *destsize) { UINT16 width, height; INT16 topoffset = 0, leftoffset = 0; diff --git a/src/r_patch.h b/src/r_patch.h index 71f715ccc..2a216193f 100644 --- a/src/r_patch.h +++ b/src/r_patch.h @@ -55,7 +55,7 @@ boolean R_IsLumpPNG(const UINT8 *d, size_t s); #ifndef NO_PNG_LUMPS UINT8 *R_PNGToFlat(UINT16 *width, UINT16 *height, UINT8 *png, size_t size); -patch_t *R_PNGToPatch(const UINT8 *png, size_t size, size_t *destsize, boolean transparency); +patch_t *R_PNGToPatch(const UINT8 *png, size_t size, size_t *destsize); boolean R_PNGDimensions(UINT8 *png, INT16 *width, INT16 *height, size_t size); #endif diff --git a/src/r_things.c b/src/r_things.c index a328da03a..7ecb14e7e 100644 --- a/src/r_things.c +++ b/src/r_things.c @@ -284,7 +284,7 @@ static boolean R_AddSingleSpriteDef(const char *sprname, spritedef_t *spritedef, // lump is a png so convert it if (R_IsLumpPNG((UINT8 *)png, len)) { - png = R_PNGToPatch((UINT8 *)png, len, NULL, true); + png = R_PNGToPatch((UINT8 *)png, len, NULL); M_Memcpy(&patch, png, sizeof(INT16)*4); } Z_Free(png); diff --git a/src/w_wad.c b/src/w_wad.c index 82f9526c6..bbb30d3fa 100644 --- a/src/w_wad.c +++ b/src/w_wad.c @@ -1540,7 +1540,7 @@ void *W_CachePatchNumPwad(UINT16 wad, UINT16 lump, INT32 tag) if (R_IsLumpPNG((UINT8 *)lumpdata, len)) { size_t newlen; - srcdata = R_PNGToPatch((UINT8 *)lumpdata, len, &newlen, true); + srcdata = R_PNGToPatch((UINT8 *)lumpdata, len, &newlen); ptr = Z_Realloc(ptr, newlen, tag, &lumpcache[lump]); M_Memcpy(ptr, srcdata, newlen); Z_Free(srcdata); From 03d4082f218fa3cb8282357d70e2bcd838d0e69d Mon Sep 17 00:00:00 2001 From: Jaime Passos Date: Wed, 1 Jan 2020 17:46:26 -0300 Subject: [PATCH 599/746] Rename functions --- src/r_patch.c | 29 +++++++++++++++++------------ src/r_patch.h | 4 ++-- 2 files changed, 19 insertions(+), 14 deletions(-) diff --git a/src/r_patch.c b/src/r_patch.c index 308385686..31f4411b1 100644 --- a/src/r_patch.c +++ b/src/r_patch.c @@ -201,11 +201,15 @@ void R_PatchToFlat(patch_t *patch, UINT8 *flat) } // -// R_PatchToFlat_16bpp +// R_PatchToMaskedFlat // -// Convert a patch to a 16-bit flat. +// Convert a patch to a masked flat. +// Now, what is a "masked" flat anyway? +// It means the flat uses two bytes to store image data. +// The upper byte is used to store the transparent pixel, +// and the lower byte stores a palette index. // -void R_PatchToFlat_16bpp(patch_t *patch, UINT16 *raw, boolean flip) +void R_PatchToMaskedFlat(patch_t *patch, UINT16 *raw, boolean flip) { fixed_t col, ofs; column_t *column; @@ -352,11 +356,12 @@ patch_t *R_FlatToPatch(UINT8 *raw, UINT16 width, UINT16 height, UINT16 leftoffse } // -// R_FlatToPatch_16bpp +// R_MaskedFlatToPatch // -// Convert a 16-bit flat to a patch. +// Convert a masked flat to a patch. +// Explanation of "masked" flats in R_PatchToMaskedFlat. // -patch_t *R_FlatToPatch_16bpp(UINT16 *raw, UINT16 width, UINT16 height, UINT16 leftoffset, UINT16 topoffset, size_t *destsize) +patch_t *R_MaskedFlatToPatch(UINT16 *raw, UINT16 width, UINT16 height, UINT16 leftoffset, UINT16 topoffset, size_t *destsize) { UINT32 x, y; UINT8 *img; @@ -684,7 +689,7 @@ static UINT8 *PNG_RawConvert(const UINT8 *png, UINT16 *w, UINT16 *h, INT16 *topo } // Convert a PNG with transparency to a raw image. -static UINT16 *PNG_RawConvert_16bpp(const UINT8 *png, UINT16 *w, UINT16 *h, INT16 *topoffset, INT16 *leftoffset, size_t size) +static UINT16 *PNG_MaskedRawConvert(const UINT8 *png, UINT16 *w, UINT16 *h, INT16 *topoffset, INT16 *leftoffset, size_t size) { UINT16 *flat; png_uint_32 x, y; @@ -693,7 +698,7 @@ static UINT16 *PNG_RawConvert_16bpp(const UINT8 *png, UINT16 *w, UINT16 *h, INT1 size_t flatsize, i; if (!row_pointers) - I_Error("PNG_RawConvert_16bpp: conversion failed"); + I_Error("PNG_MaskedRawConvert: conversion failed"); // Convert the image to 16bpp flatsize = (width * height); @@ -737,12 +742,12 @@ patch_t *R_PNGToPatch(const UINT8 *png, size_t size, size_t *destsize) { UINT16 width, height; INT16 topoffset = 0, leftoffset = 0; - UINT16 *raw = PNG_RawConvert_16bpp(png, &width, &height, &topoffset, &leftoffset, size); + UINT16 *raw = PNG_MaskedRawConvert(png, &width, &height, &topoffset, &leftoffset, size); if (!raw) I_Error("R_PNGToPatch: conversion failed"); - return R_FlatToPatch_16bpp(raw, width, height, leftoffset, topoffset, destsize); + return R_MaskedFlatToPatch(raw, width, height, leftoffset, topoffset, destsize); } // @@ -1209,7 +1214,7 @@ void R_CacheRotSprite(spritenum_t sprnum, UINT8 frame, spriteinfo_t *sprinfo, sp for (i = 0; i < size; i++) rawsrc[i] = 0xFF00; - R_PatchToFlat_16bpp(patch, rawsrc, bflip); + R_PatchToMaskedFlat(patch, rawsrc, bflip); // Don't cache angle = 0 for (angle = 1; angle < ROTANGLES; angle++) @@ -1305,7 +1310,7 @@ void R_CacheRotSprite(spritenum_t sprnum, UINT8 frame, spriteinfo_t *sprinfo, sp } // make patch - newpatch = R_FlatToPatch_16bpp(rawdst, newwidth, newheight, 0, 0, &size); + newpatch = R_MaskedFlatToPatch(rawdst, newwidth, newheight, 0, 0, &size); { newpatch->leftoffset = (newpatch->width / 2) + (leftoffset - px); newpatch->topoffset = (newpatch->height / 2) + (patch->topoffset - py); diff --git a/src/r_patch.h b/src/r_patch.h index 2a216193f..f5c98ad76 100644 --- a/src/r_patch.h +++ b/src/r_patch.h @@ -45,9 +45,9 @@ typedef struct boolean R_CheckIfPatch(lumpnum_t lump); void R_TextureToFlat(size_t tex, UINT8 *flat); void R_PatchToFlat(patch_t *patch, UINT8 *flat); -void R_PatchToFlat_16bpp(patch_t *patch, UINT16 *raw, boolean flip); +void R_PatchToMaskedFlat(patch_t *patch, UINT16 *raw, boolean flip); patch_t *R_FlatToPatch(UINT8 *raw, UINT16 width, UINT16 height, UINT16 leftoffset, UINT16 topoffset, size_t *destsize, boolean transparency); -patch_t *R_FlatToPatch_16bpp(UINT16 *raw, UINT16 width, UINT16 height, UINT16 leftoffset, UINT16 topoffset, size_t *destsize); +patch_t *R_MaskedFlatToPatch(UINT16 *raw, UINT16 width, UINT16 height, UINT16 leftoffset, UINT16 topoffset, size_t *destsize); // Portable Network Graphics boolean R_IsLumpPNG(const UINT8 *d, size_t s); From 874d4d01ee3320aa1474c1ba83458095fa5bbf26 Mon Sep 17 00:00:00 2001 From: Jaime Passos Date: Wed, 1 Jan 2020 18:00:01 -0300 Subject: [PATCH 600/746] Don't Y-billboard papersprite models (?!?!??!??!?!?) --- src/hardware/hw_md2.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/src/hardware/hw_md2.c b/src/hardware/hw_md2.c index 13a8cc44e..d1d6e91a2 100644 --- a/src/hardware/hw_md2.c +++ b/src/hardware/hw_md2.c @@ -1145,6 +1145,7 @@ boolean HWR_DrawModel(gr_vissprite_t *spr) INT32 durs = spr->mobj->state->tics; INT32 tics = spr->mobj->tics; //mdlframe_t *next = NULL; + const boolean papersprite = (spr->mobj->frame & FF_PAPERSPRITE); const UINT8 flip = (UINT8)(!(spr->mobj->eflags & MFE_VERTICALFLIP) != !(spr->mobj->frame & FF_VERTICALFLIP)); spritedef_t *sprdef; spriteframe_t *sprframe; @@ -1367,14 +1368,12 @@ boolean HWR_DrawModel(gr_vissprite_t *spr) sprframe = &sprdef->spriteframes[spr->mobj->frame & FF_FRAMEMASK]; - if (sprframe->rotate) + if (sprframe->rotate || papersprite) { fixed_t anglef = AngleFixed(spr->mobj->angle); if (spr->mobj->player) anglef = AngleFixed(spr->mobj->player->drawangle); - else - anglef = AngleFixed(spr->mobj->angle); p.angley = FIXED_TO_FLOAT(anglef); } From 2da9c3cf8199ac0ef0206354bbcd84789cf9b00c Mon Sep 17 00:00:00 2001 From: MascaraSnake Date: Wed, 1 Jan 2020 23:52:30 +0100 Subject: [PATCH 601/746] P_LoadTextmap: Bail out if certain mandatory fields are not set --- src/p_setup.c | 28 +++++++++++++++------------- 1 file changed, 15 insertions(+), 13 deletions(-) diff --git a/src/p_setup.c b/src/p_setup.c index 8b82e8c69..de6503dca 100644 --- a/src/p_setup.c +++ b/src/p_setup.c @@ -1574,9 +1574,15 @@ static void P_LoadTextmap(void) for (i = 0, vt = vertexes; i < numvertexes; i++, vt++) { // Defaults. - vt->x = vt->y = vt->z = 0; + vt->x = vt->y = INT32_MAX; + vt->z = 0; TextmapParse(vertexesPos[i], i, ParseTextmapVertexParameter); + + if (vt->x == INT32_MAX) + I_Error("P_LoadTextmap: vertex %s has no x value set!\n", sizeu1(i)); + if (vt->y == INT32_MAX) + I_Error("P_LoadTextmap: vertex %s has no y value set!\n", sizeu1(i)); } for (i = 0, sc = sectors; i < numsectors; i++, sc++) @@ -1614,16 +1620,14 @@ static void P_LoadTextmap(void) ld->sidenum[1] = 0xffff; TextmapParse(linesPos[i], i, ParseTextmapLinedefParameter); + if (!ld->v1) - { - CONS_Debug(DBG_SETUP, "P_LoadTextmap: linedef %s has no v1 set; defaulting to 0\n", sizeu1(i)); - ld->v1 = &vertexes[0]; - } + I_Error("P_LoadTextmap: linedef %s has no v1 value set!\n", sizeu1(i)); if (!ld->v2) - { - CONS_Debug(DBG_SETUP, "P_LoadTextmap: linedef %s has no v2 set; defaulting to 0\n", sizeu1(i)); - ld->v2 = &vertexes[0]; - } + I_Error("P_LoadTextmap: linedef %s has no v2 value set!\n", sizeu1(i)); + if (ld->sidenum[0] == 0xffff) + I_Error("P_LoadTextmap: linedef %s has no sidefront value set!\n", sizeu1(i)); + P_InitializeLinedef(ld); } @@ -1641,10 +1645,8 @@ static void P_LoadTextmap(void) TextmapParse(sidesPos[i], i, ParseTextmapSidedefParameter); if (!sd->sector) - { - CONS_Debug(DBG_SETUP, "P_LoadTextmap: sidedef %s has no sector set; defaulting to 0\n", sizeu1(i)); - sd->sector = §ors[0]; - } + I_Error("P_LoadTextmap: sidedef %s has no sector value set!\n", sizeu1(i)); + P_InitializeSidedef(sd); } From 02acf6222be72d9c594f55792ad6324221e4bc52 Mon Sep 17 00:00:00 2001 From: MascaraSnake Date: Thu, 2 Jan 2020 00:32:29 +0100 Subject: [PATCH 602/746] P_LoadExtendedSubsectorsAndSegs: Slightly simplify the seg vertex reading code --- src/p_setup.c | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/src/p_setup.c b/src/p_setup.c index de6503dca..d83b7adaa 100644 --- a/src/p_setup.c +++ b/src/p_setup.c @@ -2027,13 +2027,8 @@ static boolean P_LoadExtendedSubsectorsAndSegs(UINT8 **data, nodetype_t nodetype for (m = 0; m < subsectors[i].numlines; m++, k++) { UINT16 linenum; - UINT32 vert = READUINT32((*data)); - segs[k].v1 = &vertexes[vert]; - if (m == 0) - segs[k + subsectors[i].numlines - 1].v2 = &vertexes[vert]; - else - segs[k - 1].v2 = segs[k].v1; + segs[k - 1 + ((m == 0) ? 0 : subsectors[i].numlines)].v2 = segs[k].v1 = &vertexes[READUINT32((*data))]; (*data) += 4; // partner, can be ignored by software renderer if (nodetype == NT_XGL3) From 62397a36ec7a618588a8e23dbb94c733ec7f77e4 Mon Sep 17 00:00:00 2001 From: Louis-Antoine Date: Thu, 2 Jan 2020 00:38:43 +0100 Subject: [PATCH 603/746] Grab mouse on game startup --- src/sdl/i_video.c | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/src/sdl/i_video.c b/src/sdl/i_video.c index d21edb1c6..645b65e84 100644 --- a/src/sdl/i_video.c +++ b/src/sdl/i_video.c @@ -639,11 +639,14 @@ static void Impl_HandleKeyboardEvent(SDL_KeyboardEvent evt, Uint32 type) static void Impl_HandleMouseMotionEvent(SDL_MouseMotionEvent evt) { + static boolean firstmove = true; + if (USE_MOUSEINPUT) { - if ((SDL_GetMouseFocus() != window && SDL_GetKeyboardFocus() != window) || IGNORE_MOUSE) + if ((SDL_GetMouseFocus() != window && SDL_GetKeyboardFocus() != window) || (IGNORE_MOUSE && !firstmove)) { SDLdoUngrabMouse(); + firstmove = false; return; } @@ -657,6 +660,7 @@ static void Impl_HandleMouseMotionEvent(SDL_MouseMotionEvent evt) mousemovey += -evt.yrel; SDL_SetWindowGrab(window, SDL_TRUE); } + firstmove = false; return; } @@ -664,6 +668,7 @@ static void Impl_HandleMouseMotionEvent(SDL_MouseMotionEvent evt) // of the screen then ignore it. if ((evt.x == realwidth/2) && (evt.y == realheight/2)) { + firstmove = false; return; } @@ -676,6 +681,8 @@ static void Impl_HandleMouseMotionEvent(SDL_MouseMotionEvent evt) SDLdoGrabMouse(); } } + + firstmove = false; } static void Impl_HandleMouseButtonEvent(SDL_MouseButtonEvent evt, Uint32 type) From 5bde4df4393cd586410ad8d08f405dc6459b2776 Mon Sep 17 00:00:00 2001 From: Louis-Antoine Date: Thu, 2 Jan 2020 00:45:28 +0100 Subject: [PATCH 604/746] Grab mouse again when closing menu, unpausing, etc --- src/android/i_system.c | 2 ++ src/console.c | 4 ++++ src/d_netcmd.c | 2 ++ src/dehacked.c | 2 ++ src/dummy/i_system.c | 2 ++ src/g_game.c | 1 + src/hu_stuff.c | 4 ++++ src/i_system.h | 4 ++++ src/m_menu.c | 3 +++ src/sdl/i_video.c | 8 ++++++++ src/win32/win_sys.c | 2 ++ 11 files changed, 34 insertions(+) diff --git a/src/android/i_system.c b/src/android/i_system.c index 58fca7c19..752e9f6c6 100644 --- a/src/android/i_system.c +++ b/src/android/i_system.c @@ -245,6 +245,8 @@ void I_GetJoystick2Events(void){} void I_GetMouseEvents(void){} +void I_UpdateMouseGrab(void){} + char *I_GetEnv(const char *name) { LOGW("I_GetEnv() called?!"); diff --git a/src/console.c b/src/console.c index 6549370ee..01d1ddaa2 100644 --- a/src/console.c +++ b/src/console.c @@ -592,6 +592,8 @@ void CON_ToggleOff(void) CON_ClearHUD(); con_forcepic = 0; con_clipviewtop = -1; // remove console clipping of view + + I_UpdateMouseGrab(); } boolean CON_Ready(void) @@ -616,6 +618,7 @@ void CON_Ticker(void) consoletoggle = false; con_destlines = 0; CON_ClearHUD(); + I_UpdateMouseGrab(); } // console key was pushed @@ -628,6 +631,7 @@ void CON_Ticker(void) { con_destlines = 0; CON_ClearHUD(); + I_UpdateMouseGrab(); } else CON_ChangeHeight(); diff --git a/src/d_netcmd.c b/src/d_netcmd.c index 28843c0d7..0cd0ae20a 100644 --- a/src/d_netcmd.c +++ b/src/d_netcmd.c @@ -2203,6 +2203,8 @@ static void Got_Pause(UINT8 **cp, INT32 playernum) else S_ResumeAudio(); } + + I_UpdateMouseGrab(); } // Command for stuck characters in netgames, griefing, etc. diff --git a/src/dehacked.c b/src/dehacked.c index c9e10c064..78be8b0b3 100644 --- a/src/dehacked.c +++ b/src/dehacked.c @@ -4539,11 +4539,13 @@ static void DEH_LoadDehackedFile(MYFILE *f, boolean mainfile) if (introchanged) { menuactive = false; + I_UpdateMouseGrab(); COM_BufAddText("playintro"); } else if (titlechanged) { menuactive = false; + I_UpdateMouseGrab(); COM_BufAddText("exitgame"); // Command_ExitGame_f() but delayed } } diff --git a/src/dummy/i_system.c b/src/dummy/i_system.c index a3fe3077c..5c0f7eb99 100644 --- a/src/dummy/i_system.c +++ b/src/dummy/i_system.c @@ -150,6 +150,8 @@ void I_GetJoystick2Events(void){} void I_GetMouseEvents(void){} +void I_UpdateMouseGrab(void){} + char *I_GetEnv(const char *name) { (void)name; diff --git a/src/g_game.c b/src/g_game.c index e4caa3a36..354d75e82 100644 --- a/src/g_game.c +++ b/src/g_game.c @@ -1832,6 +1832,7 @@ void G_DoLoadLevel(boolean resetplayer) titlemapinaction = TITLEMAP_OFF; G_SetGamestate(GS_LEVEL); + I_UpdateMouseGrab(); for (i = 0; i < MAXPLAYERS; i++) { diff --git a/src/hu_stuff.c b/src/hu_stuff.c index 07eb5d24e..772d1cd58 100644 --- a/src/hu_stuff.c +++ b/src/hu_stuff.c @@ -1173,6 +1173,8 @@ void HU_clearChatChars(void) w_chat[i] = 0; // reset this. chat_on = false; c_input = 0; + + I_UpdateMouseGrab(); } #ifndef NONET @@ -1323,6 +1325,7 @@ boolean HU_Responder(event_t *ev) chat_on = false; c_input = 0; // reset input cursor chat_scrollmedown = true; // you hit enter, so you might wanna autoscroll to see what you just sent. :) + I_UpdateMouseGrab(); } else if (c == KEY_ESCAPE || ((c == gamecontrol[gc_talkkey][0] || c == gamecontrol[gc_talkkey][1] @@ -1331,6 +1334,7 @@ boolean HU_Responder(event_t *ev) { chat_on = false; c_input = 0; // reset input cursor + I_UpdateMouseGrab(); } else if ((c == KEY_UPARROW || c == KEY_MOUSEWHEELUP) && chat_scroll > 0 && !OLDCHAT) // CHAT SCROLLING YAYS! { diff --git a/src/i_system.h b/src/i_system.h index 2532ba0ee..a60b56310 100644 --- a/src/i_system.h +++ b/src/i_system.h @@ -288,6 +288,10 @@ void I_GetJoystick2Events(void); */ void I_GetMouseEvents(void); +/** \brief Checks if the mouse needs to be grabbed +*/ +void I_UpdateMouseGrab(void); + char *I_GetEnv(const char *name); INT32 I_PutEnv(char *variable); diff --git a/src/m_menu.c b/src/m_menu.c index ae00c8062..1a3c43b75 100644 --- a/src/m_menu.c +++ b/src/m_menu.c @@ -2867,6 +2867,7 @@ static void M_GoBack(INT32 choice) menuactive = false; wipetypepre = menupres[M_GetYoungestChildMenu()].exitwipe; + I_UpdateMouseGrab(); D_StartTitle(); } else @@ -3592,6 +3593,8 @@ void M_ClearMenus(boolean callexitmenufunc) currentMenu = &MainDef; // Not like it matters menuactive = false; hidetitlemap = false; + + I_UpdateMouseGrab(); } // diff --git a/src/sdl/i_video.c b/src/sdl/i_video.c index 645b65e84..553ce3676 100644 --- a/src/sdl/i_video.c +++ b/src/sdl/i_video.c @@ -388,6 +388,14 @@ void SDLforceUngrabMouse(void) } } +void I_UpdateMouseGrab(void) +{ + if (SDL_WasInit(SDL_INIT_VIDEO) == SDL_INIT_VIDEO && window != NULL + && SDL_GetMouseFocus() == window && SDL_GetKeyboardFocus() == window + && !IGNORE_MOUSE) + SDLdoGrabMouse(); +} + static void VID_Command_NumModes_f (void) { CONS_Printf(M_GetText("%d video mode(s) available(s)\n"), VID_NumModes()); diff --git a/src/win32/win_sys.c b/src/win32/win_sys.c index c9fdb1c97..42733c309 100644 --- a/src/win32/win_sys.c +++ b/src/win32/win_sys.c @@ -1354,6 +1354,8 @@ getBufferedData: } } +void I_UpdateMouseGrab(void) {} + // =========================================================================================== // DIRECT INPUT JOYSTICK // =========================================================================================== From 17636ccc01b82cd4d85dee35a00a474c211b8bde Mon Sep 17 00:00:00 2001 From: Louis-Antoine Date: Thu, 2 Jan 2020 00:46:50 +0100 Subject: [PATCH 605/746] Ungrab mouse when watching a record --- src/sdl/i_video.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/sdl/i_video.c b/src/sdl/i_video.c index 553ce3676..d6b36d0ed 100644 --- a/src/sdl/i_video.c +++ b/src/sdl/i_video.c @@ -109,7 +109,7 @@ static SDL_bool disable_fullscreen = SDL_FALSE; #define USE_FULLSCREEN (disable_fullscreen||!allow_fullscreen)?0:cv_fullscreen.value static SDL_bool disable_mouse = SDL_FALSE; #define USE_MOUSEINPUT (!disable_mouse && cv_usemouse.value && havefocus) -#define IGNORE_MOUSE (menuactive || paused || con_destlines || chat_on || gamestate != GS_LEVEL) +#define IGNORE_MOUSE (menuactive || paused || con_destlines || chat_on || demoplayback || gamestate != GS_LEVEL) #define MOUSE_MENU false //(!disable_mouse && cv_usemouse.value && menuactive && !USE_FULLSCREEN) #define MOUSEBUTTONS_MAX MOUSEBUTTONS From 3af00ac93e215af45c4a67dbf29b8161f425261b Mon Sep 17 00:00:00 2001 From: Louis-Antoine Date: Thu, 2 Jan 2020 00:47:20 +0100 Subject: [PATCH 606/746] Minor code refactoring --- src/m_menu.c | 3 --- src/sdl/i_video.c | 7 +------ 2 files changed, 1 insertion(+), 9 deletions(-) diff --git a/src/m_menu.c b/src/m_menu.c index 1a3c43b75..5d1bbd07d 100644 --- a/src/m_menu.c +++ b/src/m_menu.c @@ -3212,10 +3212,7 @@ boolean M_Responder(event_t *ev) case KEY_ESCAPE: // Pop up menu if (chat_on) - { HU_clearChatChars(); - chat_on = false; - } else M_StartControlPanel(); return true; diff --git a/src/sdl/i_video.c b/src/sdl/i_video.c index d6b36d0ed..e1b3781d9 100644 --- a/src/sdl/i_video.c +++ b/src/sdl/i_video.c @@ -380,12 +380,7 @@ static void SDLdoUngrabMouse(void) void SDLforceUngrabMouse(void) { if (SDL_WasInit(SDL_INIT_VIDEO)==SDL_INIT_VIDEO && window != NULL) - { - SDL_ShowCursor(SDL_ENABLE); - SDL_SetWindowGrab(window, SDL_FALSE); - wrapmouseok = SDL_FALSE; - SDL_SetRelativeMouseMode(SDL_FALSE); - } + SDLdoUngrabMouse(); } void I_UpdateMouseGrab(void) From b9cecea25c2efd62dd241aa1fd3a92191dbe69b0 Mon Sep 17 00:00:00 2001 From: James R Date: Wed, 1 Jan 2020 15:52:23 -0800 Subject: [PATCH 607/746] 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 ad610ba4aa65ead17d1a9696bbc76077ea3dd830 Mon Sep 17 00:00:00 2001 From: Nami <50415197+namishere@users.noreply.github.com> Date: Wed, 1 Jan 2020 19:38:48 -0800 Subject: [PATCH 608/746] Move MobjLineCollide up a bit to where we first know for sure that we hit a line --- src/p_map.c | 26 ++++++++++++++------------ 1 file changed, 14 insertions(+), 12 deletions(-) diff --git a/src/p_map.c b/src/p_map.c index 628268bff..4cc591330 100644 --- a/src/p_map.c +++ b/src/p_map.c @@ -1943,6 +1943,19 @@ static boolean PIT_CheckLine(line_t *ld) // this line is out of the if so upper and lower textures can be hit by a splat blockingline = ld; + +#ifdef HAVE_BLUA + { + UINT8 shouldCollide = LUAh_MobjLineCollide(tmthing, blockingline); // checks hook for thing's type + if (P_MobjWasRemoved(tmthing)) + return true; // one of them was removed??? + if (shouldCollide == 1) + return false; // force collide + else if (shouldCollide == 2) + return true; // force no collide + } +#endif + if (!ld->backsector) // one sided line { if (P_PointOnLineSide(tmthing->x, tmthing->y, ld)) @@ -1987,18 +2000,7 @@ static boolean PIT_CheckLine(line_t *ld) if (lowfloor < tmdropoffz) tmdropoffz = lowfloor; - -#ifdef HAVE_BLUA - { - UINT8 shouldCollide = LUAh_MobjLineCollide(tmthing, ld); // checks hook for thing's type - if (P_MobjWasRemoved(tmthing)) - return true; // one of them was removed??? - if (shouldCollide == 1) - return false; // force collide - else if (shouldCollide == 2) - return true; // force no collide - } -#endif + return true; } From 5ba179ad7c53a82cdb5810c1f292d2a0e00ed2b1 Mon Sep 17 00:00:00 2001 From: MascaraSnake Date: Thu, 2 Jan 2020 09:51:07 +0100 Subject: [PATCH 609/746] Fix two bugs in extended segs loading, and add some error checking while I'm at it --- src/p_setup.c | 41 +++++++++++++++++++++++++++++++---------- 1 file changed, 31 insertions(+), 10 deletions(-) diff --git a/src/p_setup.c b/src/p_setup.c index d83b7adaa..4de5fedc8 100644 --- a/src/p_setup.c +++ b/src/p_setup.c @@ -1840,10 +1840,13 @@ static inline float P_SegLengthFloat(seg_t *seg) static void P_InitializeSeg(seg_t *seg) { - seg->sidedef = &sides[seg->linedef->sidenum[seg->side]]; + if (seg->linedef) + { + seg->sidedef = &sides[seg->linedef->sidenum[seg->side]]; - seg->frontsector = seg->sidedef->sector; - seg->backsector = (seg->linedef->flags & ML_TWOSIDED) ? sides[seg->linedef->sidenum[seg->side ^ 1]].sector : NULL; + seg->frontsector = seg->sidedef->sector; + seg->backsector = (seg->linedef->flags & ML_TWOSIDED) ? sides[seg->linedef->sidenum[seg->side ^ 1]].sector : NULL; + } #ifdef HWRENDER seg->pv1 = seg->pv2 = NULL; @@ -2026,15 +2029,21 @@ static boolean P_LoadExtendedSubsectorsAndSegs(UINT8 **data, nodetype_t nodetype case NT_XGL3: for (m = 0; m < subsectors[i].numlines; m++, k++) { + UINT32 vertexnum = READUINT32((*data)); UINT16 linenum; - segs[k - 1 + ((m == 0) ? 0 : subsectors[i].numlines)].v2 = segs[k].v1 = &vertexes[READUINT32((*data))]; + if (vertexnum >= numvertexes) + I_Error("P_LoadExtendedSubsectorsAndSegs: Seg %d in subsector %d has invalid vertex %d!\n", k, m, vertexnum); - (*data) += 4; // partner, can be ignored by software renderer + segs[k - 1 + ((m == 0) ? subsectors[i].numlines : 0)].v2 = segs[k].v1 = &vertexes[vertexnum]; + + READUINT32((*data)); // partner, can be ignored by software renderer if (nodetype == NT_XGL3) - (*data) += 2; // Line number is 32-bit in XGL3, but we're limited to 16 bits. + READUINT16((*data)); // Line number is 32-bit in XGL3, but we're limited to 16 bits. linenum = READUINT16((*data)); + if (linenum != 0xFFFF && linenum >= numlines) + I_Error("P_LoadExtendedSubsectorsAndSegs: Seg %d in subsector %d has invalid linedef %d!\n", k, m, linenum); segs[k].glseg = (linenum == 0xFFFF); segs[k].linedef = (linenum == 0xFFFF) ? NULL : &lines[linenum]; segs[k].side = READUINT8((*data)); @@ -2044,9 +2053,20 @@ static boolean P_LoadExtendedSubsectorsAndSegs(UINT8 **data, nodetype_t nodetype case NT_XNOD: for (m = 0; m < subsectors[i].numlines; m++, k++) { - segs[k].v1 = &vertexes[READUINT32((*data))]; - segs[k].v2 = &vertexes[READUINT32((*data))]; - segs[k].linedef = &lines[READUINT16((*data))]; + UINT32 v1num = READUINT32((*data)); + UINT32 v2num = READUINT32((*data)); + UINT16 linenum = READUINT16((*data)); + + if (v1num >= numvertexes) + I_Error("P_LoadExtendedSubsectorsAndSegs: Seg %d in subsector %d has invalid v1 %d!\n", k, m, v1num); + if (v2num >= numvertexes) + I_Error("P_LoadExtendedSubsectorsAndSegs: Seg %d in subsector %d has invalid v2 %d!\n", k, m, v2num); + if (linenum >= numlines) + I_Error("P_LoadExtendedSubsectorsAndSegs: Seg %d in subsector %d has invalid linedef %d!\n", k, m, linenum); + + segs[k].v1 = &vertexes[v1num]; + segs[k].v2 = &vertexes[v2num]; + segs[k].linedef = &lines[linenum]; segs[k].side = READUINT8((*data)); segs[k].glseg = false; } @@ -2063,7 +2083,8 @@ static boolean P_LoadExtendedSubsectorsAndSegs(UINT8 **data, nodetype_t nodetype vertex_t *v2 = seg->v2; P_InitializeSeg(seg); seg->angle = R_PointToAngle2(v1->x, v1->y, v2->x, v2->y); - seg->offset = FixedHypot(v1->x - seg->linedef->v1->x, v1->y - seg->linedef->v1->y); + if (seg->linedef) + segs[i].offset = FixedHypot(v1->x - seg->linedef->v1->x, v1->y - seg->linedef->v1->y); } return true; From e0e5e83869e22beeb1dc6abc373d166dc2c1af99 Mon Sep 17 00:00:00 2001 From: Louis-Antoine Date: Thu, 2 Jan 2020 20:29:51 +0100 Subject: [PATCH 610/746] Revert "Ungrab mouse when watching a record" This reverts commit 17636ccc01b82cd4d85dee35a00a474c211b8bde. --- src/sdl/i_video.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/sdl/i_video.c b/src/sdl/i_video.c index e1b3781d9..7123a2d20 100644 --- a/src/sdl/i_video.c +++ b/src/sdl/i_video.c @@ -109,7 +109,7 @@ static SDL_bool disable_fullscreen = SDL_FALSE; #define USE_FULLSCREEN (disable_fullscreen||!allow_fullscreen)?0:cv_fullscreen.value static SDL_bool disable_mouse = SDL_FALSE; #define USE_MOUSEINPUT (!disable_mouse && cv_usemouse.value && havefocus) -#define IGNORE_MOUSE (menuactive || paused || con_destlines || chat_on || demoplayback || gamestate != GS_LEVEL) +#define IGNORE_MOUSE (menuactive || paused || con_destlines || chat_on || gamestate != GS_LEVEL) #define MOUSE_MENU false //(!disable_mouse && cv_usemouse.value && menuactive && !USE_FULLSCREEN) #define MOUSEBUTTONS_MAX MOUSEBUTTONS From dc0c17dbb85ebd06cf0e659ac33cc7ff2add7cc7 Mon Sep 17 00:00:00 2001 From: MascaraSnake Date: Thu, 2 Jan 2020 22:28:32 +0100 Subject: [PATCH 611/746] P_LoadExtendedSubsectorsAndSegs: Print size_t with %s --- src/p_setup.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/p_setup.c b/src/p_setup.c index 4de5fedc8..e3a7e1e58 100644 --- a/src/p_setup.c +++ b/src/p_setup.c @@ -2033,7 +2033,7 @@ static boolean P_LoadExtendedSubsectorsAndSegs(UINT8 **data, nodetype_t nodetype UINT16 linenum; if (vertexnum >= numvertexes) - I_Error("P_LoadExtendedSubsectorsAndSegs: Seg %d in subsector %d has invalid vertex %d!\n", k, m, vertexnum); + I_Error("P_LoadExtendedSubsectorsAndSegs: Seg %s in subsector %d has invalid vertex %d!\n", sizeu1(k), m, vertexnum); segs[k - 1 + ((m == 0) ? subsectors[i].numlines : 0)].v2 = segs[k].v1 = &vertexes[vertexnum]; @@ -2043,7 +2043,7 @@ static boolean P_LoadExtendedSubsectorsAndSegs(UINT8 **data, nodetype_t nodetype linenum = READUINT16((*data)); if (linenum != 0xFFFF && linenum >= numlines) - I_Error("P_LoadExtendedSubsectorsAndSegs: Seg %d in subsector %d has invalid linedef %d!\n", k, m, linenum); + I_Error("P_LoadExtendedSubsectorsAndSegs: Seg %s in subsector %d has invalid linedef %d!\n", sizeu1(k), m, linenum); segs[k].glseg = (linenum == 0xFFFF); segs[k].linedef = (linenum == 0xFFFF) ? NULL : &lines[linenum]; segs[k].side = READUINT8((*data)); @@ -2058,11 +2058,11 @@ static boolean P_LoadExtendedSubsectorsAndSegs(UINT8 **data, nodetype_t nodetype UINT16 linenum = READUINT16((*data)); if (v1num >= numvertexes) - I_Error("P_LoadExtendedSubsectorsAndSegs: Seg %d in subsector %d has invalid v1 %d!\n", k, m, v1num); + I_Error("P_LoadExtendedSubsectorsAndSegs: Seg %s in subsector %d has invalid v1 %d!\n", sizeu1(k), m, v1num); if (v2num >= numvertexes) - I_Error("P_LoadExtendedSubsectorsAndSegs: Seg %d in subsector %d has invalid v2 %d!\n", k, m, v2num); + I_Error("P_LoadExtendedSubsectorsAndSegs: Seg %s in subsector %d has invalid v2 %d!\n", sizeu1(k), m, v2num); if (linenum >= numlines) - I_Error("P_LoadExtendedSubsectorsAndSegs: Seg %d in subsector %d has invalid linedef %d!\n", k, m, linenum); + I_Error("P_LoadExtendedSubsectorsAndSegs: Seg %s in subsector %d has invalid linedef %d!\n", sizeu1(k), m, linenum); segs[k].v1 = &vertexes[v1num]; segs[k].v2 = &vertexes[v2num]; From 945f50c2736ee64734dcc94f36ff7dff4085c8e2 Mon Sep 17 00:00:00 2001 From: James R Date: Thu, 2 Jan 2020 14:58:09 -0800 Subject: [PATCH 612/746] Remove Direct Draw from AppVeyor config --- appveyor.yml | 9 --------- 1 file changed, 9 deletions(-) diff --git a/appveyor.yml b/appveyor.yml index 0edc7ce28..c64e69665 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -55,8 +55,6 @@ cache: install: - if [%CONFIGURATION%] == [SDL64] ( set "X86_64=1" ) - if [%CONFIGURATION%] == [SDL64] ( set "CONFIGURATION=SDL" ) -- if [%CONFIGURATION%] == [DD64] ( set "X86_64=1" ) -- if [%CONFIGURATION%] == [DD64] ( set "CONFIGURATION=DD" ) - if [%X86_64%] == [1] ( set "MINGW_SDK=%MINGW_SDK_64%" ) - if [%X86_64%] == [1] ( set "CCACHE_CC=%CCACHE_CC_64%" ) @@ -75,13 +73,6 @@ install: configuration: - SDL - SDL64 -- DD -- DD64 - -matrix: - allow_failures: - - configuration: DD - - configuration: DD64 before_build: - set "Path=%MINGW_SDK%\bin;%Path%" From 49934007d7e904e78a2038d1dc0715f36fffa66b Mon Sep 17 00:00:00 2001 From: Louis-Antoine Date: Fri, 3 Jan 2020 00:25:58 +0100 Subject: [PATCH 613/746] Add a "alwaysgrabmouse" console variable --- src/sdl/i_video.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/sdl/i_video.c b/src/sdl/i_video.c index 7123a2d20..e6a40327b 100644 --- a/src/sdl/i_video.c +++ b/src/sdl/i_video.c @@ -100,6 +100,7 @@ boolean highcolor = false; // synchronize page flipping with screen refresh consvar_t cv_vidwait = {"vid_wait", "On", CV_SAVE, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL}; static consvar_t cv_stretch = {"stretch", "Off", CV_SAVE|CV_NOSHOWHELP, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL}; +static consvar_t cv_alwaysgrabmouse = {"alwaysgrabmouse", "Off", CV_SAVE, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL}; UINT8 graphics_started = 0; // Is used in console.c and screen.c @@ -109,7 +110,7 @@ static SDL_bool disable_fullscreen = SDL_FALSE; #define USE_FULLSCREEN (disable_fullscreen||!allow_fullscreen)?0:cv_fullscreen.value static SDL_bool disable_mouse = SDL_FALSE; #define USE_MOUSEINPUT (!disable_mouse && cv_usemouse.value && havefocus) -#define IGNORE_MOUSE (menuactive || paused || con_destlines || chat_on || gamestate != GS_LEVEL) +#define IGNORE_MOUSE (!cv_alwaysgrabmouse.value && (menuactive || paused || con_destlines || chat_on || gamestate != GS_LEVEL)) #define MOUSE_MENU false //(!disable_mouse && cv_usemouse.value && menuactive && !USE_FULLSCREEN) #define MOUSEBUTTONS_MAX MOUSEBUTTONS @@ -1626,6 +1627,7 @@ void I_StartupGraphics(void) COM_AddCommand ("vid_mode", VID_Command_Mode_f); CV_RegisterVar (&cv_vidwait); CV_RegisterVar (&cv_stretch); + CV_RegisterVar (&cv_alwaysgrabmouse); disable_mouse = M_CheckParm("-nomouse"); disable_fullscreen = M_CheckParm("-win") ? 1 : 0; From 1845266bc835f6d9b82f6ada75a50d4d1c1ad579 Mon Sep 17 00:00:00 2001 From: Louis-Antoine Date: Fri, 3 Jan 2020 00:40:49 +0100 Subject: [PATCH 614/746] 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 658b8dcfa95935bbaef92c15476ad57ecc96950f Mon Sep 17 00:00:00 2001 From: James R Date: Thu, 2 Jan 2020 15:45:13 -0800 Subject: [PATCH 615/746] Use GCC 8.1 for x86_64 --- appveyor.yml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/appveyor.yml b/appveyor.yml index 0edc7ce28..c8a5832c2 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -9,7 +9,7 @@ environment: # c:\mingw-w64 i686 has gcc 6.3.0, so use c:\msys64 7.3.0 instead MINGW_SDK: c:\msys64\mingw32 # c:\msys64 x86_64 has gcc 8.2.0, so use c:\mingw-w64 7.3.0 instead - MINGW_SDK_64: C:\mingw-w64\x86_64-7.3.0-posix-seh-rt_v5-rev0\mingw64 + MINGW_SDK_64: C:\mingw-w64\x86_64-8.1.0-posix-seh-rt_v6-rev0\mingw64 CFLAGS: -Wall -W -Werror -Wno-error=implicit-fallthrough -Wimplicit-fallthrough=3 -Wno-tautological-compare -Wno-error=suggest-attribute=noreturn NASM_ZIP: nasm-2.12.01 NASM_URL: http://www.nasm.us/pub/nasm/releasebuilds/2.12.01/win64/nasm-2.12.01-win64.zip @@ -92,8 +92,8 @@ before_build: - ccache -V - ccache -s - if [%NOUPX%] == [1] ( set "NOUPX=NOUPX=1" ) else ( set "NOUPX=" ) -- set "SRB2_MFLAGS=-C src WARNINGMODE=1 CCACHE=1 GCC73=1 NOOBJDUMP=1 %NOUPX%" -- if [%X86_64%] == [1] ( set "MINGW_FLAGS=MINGW64=1 X86_64=1" ) else ( set "MINGW_FLAGS=MINGW=1 GCC91=1" ) +- set "SRB2_MFLAGS=-C src WARNINGMODE=1 CCACHE=1 NOOBJDUMP=1 %NOUPX%" +- if [%X86_64%] == [1] ( set "MINGW_FLAGS=MINGW64=1 X86_64=1 GCC81=1" ) else ( set "MINGW_FLAGS=MINGW=1 GCC91=1" ) - set "SRB2_MFLAGS=%SRB2_MFLAGS% %MINGW_FLAGS% %CONFIGURATION%=1" build_script: From b45ee059e31f01ba20ea2cec89f4a6c41746fab5 Mon Sep 17 00:00:00 2001 From: Louis-Antoine Date: Fri, 3 Jan 2020 02:58:23 +0100 Subject: [PATCH 616/746] 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 da226139f11bfc1e588ccd379c87d01db301ad1c Mon Sep 17 00:00:00 2001 From: lachwright Date: Fri, 3 Jan 2020 13:12:18 +0800 Subject: [PATCH 617/746] Add generic signpost sprite for skins that don't have one --- src/dehacked.c | 1 + src/info.c | 27 ++++++++++++++------------- src/info.h | 1 + src/p_enemy.c | 22 ++++++++++++++++++---- 4 files changed, 34 insertions(+), 17 deletions(-) diff --git a/src/dehacked.c b/src/dehacked.c index 4b6d76a6a..b412fa0b2 100644 --- a/src/dehacked.c +++ b/src/dehacked.c @@ -6009,6 +6009,7 @@ static const char *const STATE_LIST[] = { // array length left dynamic for sanit "S_SIGNSTOP", "S_SIGNBOARD", "S_EGGMANSIGN", + "S_CLEARSIGN", // Spike Ball "S_SPIKEBALL1", diff --git a/src/info.c b/src/info.c index 30f3e96d0..4e9cbbb10 100644 --- a/src/info.c +++ b/src/info.c @@ -1849,18 +1849,19 @@ state_t states[NUMSTATES] = {SPR_BBLS, 3, 8, {A_BubbleCheck}, 0, 0, S_BUBBLES1}, // S_BUBBLES4 // Level End Sign - {SPR_SIGN, 0, -1, {A_SignPlayer}, -3, 0, S_NULL}, // S_SIGN - {SPR_SIGN, 0, 1, {A_SignSpin}, 30, 0, S_SIGNSPIN2}, // S_SIGNSPIN1 - {SPR_SIGN, 0, 0, {A_Repeat}, 4, S_SIGNSPIN1, S_SIGNSPIN3}, // S_SIGNSPIN2 - {SPR_SIGN, 0, 0, {A_SignPlayer}, -2, 0, S_SIGNSPIN4}, // S_SIGNSPIN3 - {SPR_SIGN, 0, 1, {A_SignSpin}, 30, 0, S_SIGNSPIN5}, // S_SIGNSPIN4 - {SPR_SIGN, 0, 0, {A_Repeat}, 4, S_SIGNSPIN4, S_SIGNSPIN6}, // S_SIGNSPIN5 - {SPR_SIGN, 0, 0, {A_SignPlayer}, -3, 0, S_SIGNSPIN1}, // S_SIGNSPIN6 - {SPR_SIGN, 0, 1, {A_SignPlayer}, -1, 0, S_SIGNSLOW}, // S_SIGNPLAYER - {SPR_SIGN, 0, 1, {A_SignSpin}, 30, 0, S_SIGNSLOW}, // S_SIGNSLOW - {SPR_SIGN, 0, -1, {NULL}, 0, 0, S_NULL}, // S_SIGNSTOP - {SPR_SIGN, FF_PAPERSPRITE|2, -1, {NULL}, 0, 0, S_NULL}, // S_SIGNBOARD - {SPR_SIGN, FF_PAPERSPRITE|1, -1, {NULL}, 0, 29, S_NULL}, // S_EGGMANSIGN + {SPR_SIGN, 0, -1, {A_SignPlayer}, -3, 0, S_NULL}, // S_SIGN + {SPR_SIGN, 0, 1, {A_SignSpin}, 30, 0, S_SIGNSPIN2}, // S_SIGNSPIN1 + {SPR_SIGN, 0, 0, {A_Repeat}, 4, S_SIGNSPIN1, S_SIGNSPIN3}, // S_SIGNSPIN2 + {SPR_SIGN, 0, 0, {A_SignPlayer}, -2, 0, S_SIGNSPIN4}, // S_SIGNSPIN3 + {SPR_SIGN, 0, 1, {A_SignSpin}, 30, 0, S_SIGNSPIN5}, // S_SIGNSPIN4 + {SPR_SIGN, 0, 0, {A_Repeat}, 4, S_SIGNSPIN4, S_SIGNSPIN6}, // S_SIGNSPIN5 + {SPR_SIGN, 0, 0, {A_SignPlayer}, -3, 0, S_SIGNSPIN1}, // S_SIGNSPIN6 + {SPR_SIGN, 0, 1, {A_SignPlayer}, -1, 0, S_SIGNSLOW}, // S_SIGNPLAYER + {SPR_SIGN, 0, 1, {A_SignSpin}, 30, 0, S_SIGNSLOW}, // S_SIGNSLOW + {SPR_SIGN, 0, -1, {NULL}, 0, 0, S_NULL}, // S_SIGNSTOP + {SPR_SIGN, FF_PAPERSPRITE| 2, -1, {NULL}, 0, 0, S_NULL}, // S_SIGNBOARD + {SPR_SIGN, FF_PAPERSPRITE| 1, -1, {NULL}, 0, 29, S_NULL}, // S_EGGMANSIGN + {SPR_SIGN, FF_PAPERSPRITE|18, -1, {NULL}, 0, 29, S_NULL}, // S_CLEARSIGN // Spike Ball {SPR_SPIK, 0, 1, {NULL}, 0, 0, S_SPIKEBALL2}, // S_SPIKEBALL1 @@ -7850,7 +7851,7 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] = MT_SPARK, // painchance sfx_s3kb8, // painsound S_EGGMANSIGN, // meleestate - S_NULL, // missilestate + S_CLEARSIGN, // missilestate S_SIGNSTOP, // deathstate S_NULL, // xdeathstate sfx_s3k64, // deathsound diff --git a/src/info.h b/src/info.h index 261abbac5..de766503a 100644 --- a/src/info.h +++ b/src/info.h @@ -2021,6 +2021,7 @@ typedef enum state S_SIGNSTOP, S_SIGNBOARD, S_EGGMANSIGN, + S_CLEARSIGN, // Spike Ball S_SPIKEBALL1, diff --git a/src/p_enemy.c b/src/p_enemy.c index ce201844f..c8edf293a 100644 --- a/src/p_enemy.c +++ b/src/p_enemy.c @@ -5177,6 +5177,8 @@ void A_SignPlayer(mobj_t *actor) if (signcolor) ; + else if (!skin->sprites[SPR2_SIGN].numframes) + signcolor = facecolor; else if ((actor->target->player->skincolor == skin->prefcolor) && (skin->prefoppositecolor)) // Set it as the skin's preferred oppositecolor? signcolor = skin->prefoppositecolor; else if (actor->target->player->skincolor) // Set the sign to be an appropriate background color for this player's skincolor. @@ -5221,21 +5223,33 @@ void A_SignPlayer(mobj_t *actor) facecolor = skin->prefcolor; if (signcolor) ; + else if (!skin->sprites[SPR2_SIGN].numframes) + signcolor = facecolor; else if (skin->prefoppositecolor) signcolor = skin->prefoppositecolor; else if (facecolor) signcolor = Color_Opposite[facecolor - 1][0]; } - if (skin && skin->sprites[SPR2_SIGN].numframes) // player face + if (skin) { - ov->color = facecolor; - ov->skin = skin; - P_SetMobjState(ov, actor->info->seestate); // S_PLAY_SIGN + if (skin->sprites[SPR2_SIGN].numframes) // player face + { + ov->color = facecolor; + ov->skin = skin; + P_SetMobjState(ov, actor->info->seestate); // S_PLAY_SIGN + } + else // CLEAR! sign + { + ov->color = SKINCOLOR_NONE; + ov->skin = NULL; // needs to be NULL in the case of SF_HIRES characters + P_SetMobjState(ov, actor->info->missilestate); // S_CLEARSIGN + } } else // Eggman face { ov->color = SKINCOLOR_NONE; + ov->skin = NULL; P_SetMobjState(ov, actor->info->meleestate); // S_EGGMANSIGN if (!signcolor) signcolor = SKINCOLOR_CARBON; From 26bb0b3c67d6e05d4b3ccc54891d10e348bdcc04 Mon Sep 17 00:00:00 2001 From: MascaraSnake Date: Fri, 3 Jan 2020 21:50:27 +0100 Subject: [PATCH 618/746] 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 eac8732bc85c50059f61b9908ee8a09ba1c32ef2 Mon Sep 17 00:00:00 2001 From: fickleheart Date: Fri, 3 Jan 2020 23:26:31 -0600 Subject: [PATCH 619/746] Make holding both turn keys freeze camera direction (broke in merge) --- 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 0a3753972..9bb1c241e 100644 --- a/src/g_game.c +++ b/src/g_game.c @@ -1291,7 +1291,8 @@ void G_BuildTiccmd(ticcmd_t *cmd, INT32 realtics, UINT8 ssplayer) } else { - if (turnright) + if (turnright && turnleft); + else if (turnright) cmd->angleturn = (INT16)(cmd->angleturn - ((angleturn[tspeed] * cv_cam_turnmultiplier.value)>>FRACBITS)); else if (turnleft) cmd->angleturn = (INT16)(cmd->angleturn + ((angleturn[tspeed] * cv_cam_turnmultiplier.value)>>FRACBITS)); From 6f5833f8b3c9324a64cb237135177c0581a0c2ee Mon Sep 17 00:00:00 2001 From: lachwright Date: Sat, 4 Jan 2020 14:49:44 +0800 Subject: [PATCH 620/746] Randomize skin during signpost roulette --- src/p_enemy.c | 34 +++++++++++++--------------------- 1 file changed, 13 insertions(+), 21 deletions(-) diff --git a/src/p_enemy.c b/src/p_enemy.c index c8edf293a..74faa76f4 100644 --- a/src/p_enemy.c +++ b/src/p_enemy.c @@ -5189,33 +5189,25 @@ void A_SignPlayer(mobj_t *actor) else if (locvar1 != -3) // set to a defined skin { // I turned this function into a fucking mess. I'm so sorry. -Lach - if (locvar1 == -2) // next skin + if (locvar1 == -2) // random skin { +#define skincheck(num) (player ? !R_SkinUsable(player-players, num) : skins[num].availability > 0) player_t *player = actor->target ? actor->target->player : NULL; UINT8 skinnum; -#define skincheck(num) (player ? !R_SkinUsable(player-players, num) : skins[num].availability > 0) - if (ov->skin == NULL) // pick a random skin to start with! + UINT8 skincount = 0; + for (skincount = 0; skincount < numskins; skincount++) + if (!skincheck(skincount)) + skincount++; + skinnum = P_RandomKey(skincount); + for (skincount = 0; skincount < numskins; skincount++) { - UINT8 skincount = 0; - for (skincount = 0; skincount < numskins; skincount++) - if (!skincheck(skincount)) - skincount++; - skinnum = P_RandomKey(skincount); - for (skincount = 0; skincount < numskins; skincount++) - { - if (skincount > skinnum) - break; - if (skincheck(skincount)) - skinnum++; - } + if (skincount > skinnum) + break; + if (skincheck(skincount)) + skinnum++; } - else // otherwise, advance 1 skin - { - skinnum = (skin_t*)ov->skin-skins; - while ((skinnum = (skinnum + 1) % numskins) && skincheck(skinnum)); - } -#undef skincheck skin = &skins[skinnum]; +#undef skincheck } else // specific skin skin = &skins[locvar1]; From 0b21a34ddd41d648eafd562b78d36dbdbf32fe6a Mon Sep 17 00:00:00 2001 From: Nev3r Date: Sat, 4 Jan 2020 10:24:42 +0100 Subject: [PATCH 621/746] Add vertex height vars into the vertex struct, and their textmap parsing. --- src/p_setup.c | 12 ++++++++++++ src/r_defs.h | 2 ++ 2 files changed, 14 insertions(+) diff --git a/src/p_setup.c b/src/p_setup.c index bd1c53104..0a802583a 100644 --- a/src/p_setup.c +++ b/src/p_setup.c @@ -1368,6 +1368,16 @@ static void ParseTextmapVertexParameter(UINT32 i, char *param, char *val) vertexes[i].x = FLOAT_TO_FIXED(atof(val)); else if (fastcmp(param, "y")) vertexes[i].y = FLOAT_TO_FIXED(atof(val)); + else if (fastcmp(param, "zfloor")) + { + vertexes[i].floorz = FLOAT_TO_FIXED(atof(val)); + vertexes[i].floorzset = true; + } + else if (fastcmp(param, "zceiling")) + { + vertexes[i].ceilingz = FLOAT_TO_FIXED(atof(val)); + vertexes[i].ceilingzset = true; + } } static void ParseTextmapSectorParameter(UINT32 i, char *param, char *val) @@ -1576,6 +1586,8 @@ static void P_LoadTextmap(void) // Defaults. vt->x = vt->y = INT32_MAX; vt->z = 0; + vt->floorzset = vt->ceilingzset = false; + vt->floorz = vt->ceilingz = 0; TextmapParse(vertexesPos[i], i, ParseTextmapVertexParameter); diff --git a/src/r_defs.h b/src/r_defs.h index 96ef953ce..5f96958c9 100644 --- a/src/r_defs.h +++ b/src/r_defs.h @@ -84,6 +84,8 @@ typedef struct extracolormap_s typedef struct { fixed_t x, y, z; + boolean floorzset, ceilingzset; + fixed_t floorz, ceilingz; } vertex_t; // Forward of linedefs, for sectors. From faf127ff8860e18c5cba47572ca629527b0e4779 Mon Sep 17 00:00:00 2001 From: Nev3r Date: Sat, 4 Jan 2020 10:39:45 +0100 Subject: [PATCH 622/746] Add vertex slope spawning function. Rename P_ResetDynamicSlopes() to P_SpawnSlopes(). --- src/p_setup.c | 2 +- src/p_slopes.c | 60 +++++++++++++++++++++++++++++++++++++++++++++++--- src/p_slopes.h | 2 +- 3 files changed, 59 insertions(+), 5 deletions(-) diff --git a/src/p_setup.c b/src/p_setup.c index 0a802583a..a1aaeb4ba 100644 --- a/src/p_setup.c +++ b/src/p_setup.c @@ -3582,7 +3582,7 @@ boolean P_LoadLevel(boolean fromnetsave) P_InitSpecials(); #ifdef ESLOPE - P_ResetDynamicSlopes(fromnetsave); + P_SpawnSlopes(fromnetsave); #endif P_SpawnMapThings(!fromnetsave); diff --git a/src/p_slopes.c b/src/p_slopes.c index e66d7ed21..5c47c7226 100644 --- a/src/p_slopes.c +++ b/src/p_slopes.c @@ -507,6 +507,56 @@ static void line_SpawnViaVertexes(const int linenum, const boolean spawnthinker) side->sector->hasslope = true; } +/// Spawn textmap vertex slopes. +void SpawnVertexSlopes (void) +{ + line_t *l1, *l2; + sector_t* sc; + vertex_t *v1, *v2, *v3; + size_t i; + for (i = 0, sc = sectors; i < numsectors; i++, sc++) + { + // The vertex slopes only work for 3-vertex sectors (and thus 3-sided sectors). + if (sc->linecount != 3) + continue; + + l1 = sc->lines[0]; + l2 = sc->lines[1]; + + // Determine the vertexes. + v1 = l1->v1; + v2 = l1->v2; + if ((l2->v1 != v1) && (l2->v1 != v2)) + v3 = l2->v1; + else + v3 = l2->v2; + + if (v1->floorzset || v2->floorzset || v3->floorzset) + { + vector3_t vtx[3] = { + {v1->x, v1->y, v1->floorzset == true ? v1->floorz : sc->floorheight}, + {v2->x, v2->y, v2->floorzset == true ? v2->floorz : sc->floorheight}, + {v3->x, v3->y, v3->floorzset == true ? v3->floorz : sc->floorheight}}; + pslope_t* slop = Slope_Add(0); + sc->f_slope = slop; + sc->hasslope = true; + ReconfigureViaVertexes(slop, vtx[0], vtx[1], vtx[2]); + } + + if (v1->ceilingzset || v2->ceilingzset || v3->ceilingzset) + { + vector3_t vtx[3] = { + {v1->x, v1->y, v1->ceilingzset == true ? v1->ceilingz : sc->ceilingheight}, + {v2->x, v2->y, v2->ceilingzset == true ? v2->ceilingz : sc->ceilingheight}, + {v3->x, v3->y, v3->ceilingzset == true ? v3->ceilingz : sc->ceilingheight}}; + pslope_t* slop = Slope_Add(0); + sc->c_slope = slop; + sc->hasslope = true; + ReconfigureViaVertexes(slop, vtx[0], vtx[1], vtx[2]); + } + + } +} // // P_CopySectorSlope @@ -551,12 +601,16 @@ pslope_t *P_SlopeById(UINT16 id) return ret; } -/// Reset slopes and read them from special lines. -void P_ResetDynamicSlopes(const boolean fromsave) { +/// Initializes and reads the slopes from the map data. +void P_SpawnSlopes(const boolean fromsave) { size_t i; + slopelist = NULL; slopecount = 0; + /// Generates vertex slopes. + SpawnVertexSlopes(); + /// Generates line special-defined slopes. for (i = 0; i < numlines; i++) { @@ -577,7 +631,7 @@ void P_ResetDynamicSlopes(const boolean fromsave) { case 705: case 714: case 715: - line_SpawnViaVertexes(i, !fromsave); + line_SpawnViaVertexes(i, !fromsave); // Mapthing-based vertex slopes. break; default: diff --git a/src/p_slopes.h b/src/p_slopes.h index 96764051b..0bf03f26d 100644 --- a/src/p_slopes.h +++ b/src/p_slopes.h @@ -23,7 +23,7 @@ extern UINT16 slopecount; void P_LinkSlopeThinkers (void); void P_CalculateSlopeNormal(pslope_t *slope); -void P_ResetDynamicSlopes(const boolean fromsave); +void P_SpawnSlopes(const boolean fromsave); // // P_CopySectorSlope From 1e42dc7ee519ba800354ff2d78d15bcaa8c23ec0 Mon Sep 17 00:00:00 2001 From: MascaraSnake Date: Sat, 4 Jan 2020 11:08:05 +0100 Subject: [PATCH 623/746] Move P_ProcessLinedefsAfterSidedefs into P_LoadMapData, but move map data copying after everything else --- src/p_setup.c | 83 ++++++++++++++++++++++++++------------------------- 1 file changed, 42 insertions(+), 41 deletions(-) diff --git a/src/p_setup.c b/src/p_setup.c index bd1c53104..a4e6707c0 100644 --- a/src/p_setup.c +++ b/src/p_setup.c @@ -1665,6 +1665,37 @@ static void P_LoadTextmap(void) } } +static void P_ProcessLinedefsAfterSidedefs(void) +{ + size_t i = numlines; + register line_t *ld = lines; + for (; i--; ld++) + { + ld->frontsector = sides[ld->sidenum[0]].sector; //e6y: Can't be -1 here + ld->backsector = ld->sidenum[1] != 0xffff ? sides[ld->sidenum[1]].sector : 0; + + // Compile linedef 'text' from both sidedefs 'text' for appropriate specials. + switch (ld->special) + { + case 331: // Trigger linedef executor: Skin - Continuous + case 332: // Trigger linedef executor: Skin - Each time + case 333: // Trigger linedef executor: Skin - Once + case 443: // Calls a named Lua function + if (sides[ld->sidenum[0]].text) + { + size_t len = strlen(sides[ld->sidenum[0]].text) + 1; + if (ld->sidenum[1] != 0xffff && sides[ld->sidenum[1]].text) + len += strlen(sides[ld->sidenum[1]].text); + ld->text = Z_Malloc(len, PU_LEVEL, NULL); + M_Memcpy(ld->text, sides[ld->sidenum[0]].text, strlen(sides[ld->sidenum[0]].text) + 1); + if (ld->sidenum[1] != 0xffff && sides[ld->sidenum[1]].text) + M_Memcpy(ld->text + strlen(ld->text) + 1, sides[ld->sidenum[1]].text, strlen(sides[ld->sidenum[1]].text) + 1); + } + break; + } + } +} + static boolean P_LoadMapData(const virtres_t *virt) { virtlump_t *virtvertexes = NULL, *virtsectors = NULL, *virtsidedefs = NULL, *virtlinedefs = NULL, *virtthings = NULL; @@ -1738,6 +1769,8 @@ static boolean P_LoadMapData(const virtres_t *virt) P_LoadThings(virtthings->data); } + P_ProcessLinedefsAfterSidedefs(); + R_ClearTextureNumCache(true); // set the sky flat num @@ -1750,15 +1783,6 @@ static boolean P_LoadMapData(const virtres_t *virt) // search for animated flats and set up P_SetupLevelFlatAnims(); - // Copy relevant map data for NetArchive purposes. - spawnsectors = Z_Calloc(numsectors * sizeof (*sectors), PU_LEVEL, NULL); - spawnlines = Z_Calloc(numlines * sizeof (*lines), PU_LEVEL, NULL); - spawnsides = Z_Calloc(numsides * sizeof (*sides), PU_LEVEL, NULL); - - memcpy(spawnsectors, sectors, numsectors * sizeof (*sectors)); - memcpy(spawnlines, lines, numlines * sizeof (*lines)); - memcpy(spawnsides, sides, numsides * sizeof (*sides)); - return true; } @@ -2517,37 +2541,6 @@ static void P_LoadMapLUT(const virtres_t *virt) P_CreateBlockMap(); } -static void P_ProcessLinedefsWithSidedefs(void) -{ - size_t i = numlines; - register line_t *ld = lines; - for (;i--;ld++) - { - ld->frontsector = sides[ld->sidenum[0]].sector; //e6y: Can't be -1 here - ld->backsector = ld->sidenum[1] != 0xffff ? sides[ld->sidenum[1]].sector : 0; - - // Compile linedef 'text' from both sidedefs 'text' for appropriate specials. - switch(ld->special) - { - case 331: // Trigger linedef executor: Skin - Continuous - case 332: // Trigger linedef executor: Skin - Each time - case 333: // Trigger linedef executor: Skin - Once - case 443: // Calls a named Lua function - if (sides[ld->sidenum[0]].text) - { - size_t len = strlen(sides[ld->sidenum[0]].text)+1; - if (ld->sidenum[1] != 0xffff && sides[ld->sidenum[1]].text) - len += strlen(sides[ld->sidenum[1]].text); - ld->text = Z_Malloc(len, PU_LEVEL, NULL); - M_Memcpy(ld->text, sides[ld->sidenum[0]].text, strlen(sides[ld->sidenum[0]].text)+1); - if (ld->sidenum[1] != 0xffff && sides[ld->sidenum[1]].text) - M_Memcpy(ld->text+strlen(ld->text)+1, sides[ld->sidenum[1]].text, strlen(sides[ld->sidenum[1]].text)+1); - } - break; - } - } -} - // // P_LinkMapData // Builds sector line lists and subsector sector numbers. @@ -2713,9 +2706,17 @@ static boolean P_LoadMapFromFile(void) P_LoadMapBSP(virt); P_LoadMapLUT(virt); - P_ProcessLinedefsWithSidedefs(); P_LinkMapData(); + // Copy relevant map data for NetArchive purposes. + spawnsectors = Z_Calloc(numsectors * sizeof(*sectors), PU_LEVEL, NULL); + spawnlines = Z_Calloc(numlines * sizeof(*lines), PU_LEVEL, NULL); + spawnsides = Z_Calloc(numsides * sizeof(*sides), PU_LEVEL, NULL); + + memcpy(spawnsectors, sectors, numsectors * sizeof(*sectors)); + memcpy(spawnlines, lines, numlines * sizeof(*lines)); + memcpy(spawnsides, sides, numsides * sizeof(*sides)); + P_MakeMapMD5(virt, &mapmd5); vres_Free(virt); From c9294d1e3283588b9f1b742e5e4dae5541141683 Mon Sep 17 00:00:00 2001 From: Nev3r Date: Sat, 4 Jan 2020 11:17:54 +0100 Subject: [PATCH 624/746] 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 5c47c7226..870cd621f 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 { @@ -707,7 +707,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 @@ -764,8 +766,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; From 60999c7b8483805c271bd89e485edb5fd8f76357 Mon Sep 17 00:00:00 2001 From: Nev3r Date: Sat, 4 Jan 2020 11:25:46 +0100 Subject: [PATCH 625/746] Revert "Provide a fix for "non-sloped" slopes launch/land behavior by checking the normal's components." This reverts commit c9294d1e3283588b9f1b742e5e4dae5541141683. --- src/p_slopes.c | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/src/p_slopes.c b/src/p_slopes.c index 870cd621f..5c47c7226 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 { @@ -707,9 +707,7 @@ 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. - && (mo->standingslope->normal.x != 0 - || mo->standingslope->normal.y != 0)) + if (!(mo->standingslope->flags & SL_NOPHYSICS)) // If there's physics, time for launching. { // Double the pre-rotation Z, then halve the post-rotation Z. This reduces the // vertical launch given from slopes while increasing the horizontal launch @@ -766,7 +764,8 @@ 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 || (slope->normal.x == 0 && slope->normal.y == 0)) { // No physics, no need to make anything complicated. + + if (slope->flags & SL_NOPHYSICS) { // No physics, no need to make anything complicated. if (P_MobjFlip(thing)*(thing->momz) < 0) // falling, land on slope { thing->standingslope = slope; From 49667689c1e43908c0f88bc120be13bd4f09539b Mon Sep 17 00:00:00 2001 From: Nev3r Date: Sat, 4 Jan 2020 11:17:54 +0100 Subject: [PATCH 626/746] 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; From f207048ab2f38133f18f5c162b2671e1f41bc8fa Mon Sep 17 00:00:00 2001 From: Nev3r Date: Sat, 4 Jan 2020 11:38:23 +0100 Subject: [PATCH 627/746] Add Lua support for vertex heights. --- src/lua_maplib.c | 22 +++++++++++++++++++++- 1 file changed, 21 insertions(+), 1 deletion(-) diff --git a/src/lua_maplib.c b/src/lua_maplib.c index 8ce6551f7..7e1097ced 100644 --- a/src/lua_maplib.c +++ b/src/lua_maplib.c @@ -158,7 +158,11 @@ enum vertex_e { vertex_valid = 0, vertex_x, vertex_y, - vertex_z + vertex_z, + vertex_floorz, + vertex_floorzset, + vertex_ceilingz, + vertex_ceilingzset }; static const char *const vertex_opt[] = { @@ -166,6 +170,10 @@ static const char *const vertex_opt[] = { "x", "y", "z", + "floorz", + "floorzset", + "ceilingz", + "ceilingzset", NULL}; enum ffloor_e { @@ -973,6 +981,18 @@ static int vertex_get(lua_State *L) case vertex_z: lua_pushfixed(L, vertex->z); return 1; + case vertex_floorzset: + lua_pushboolean(L, vertex->floorzset); + return 1; + case vertex_ceilingzset: + lua_pushboolean(L, vertex->ceilingzset); + return 1; + case vertex_floorz: + lua_pushfixed(L, vertex->floorz); + return 1; + case vertex_ceilingz: + lua_pushfixed(L, vertex->ceilingz); + return 1; } return 0; } From 34fe284416dd43beaa41f782c0c98ec7efbd4f1d Mon Sep 17 00:00:00 2001 From: fickleheart Date: Sat, 4 Jan 2020 09:54:56 -0600 Subject: [PATCH 628/746] Fix camera stuff in splitscreen --- src/g_game.c | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-) diff --git a/src/g_game.c b/src/g_game.c index 1abd904c2..0bb6e798f 100644 --- a/src/g_game.c +++ b/src/g_game.c @@ -1291,7 +1291,8 @@ void G_BuildTiccmd(ticcmd_t *cmd, INT32 realtics, UINT8 ssplayer) } else { - if (turnright) + if (turnright && turnleft); + else if (turnright) cmd->angleturn = (INT16)(cmd->angleturn - ((angleturn[tspeed] * cv_cam_turnmultiplier.value)>>FRACBITS)); else if (turnleft) cmd->angleturn = (INT16)(cmd->angleturn + ((angleturn[tspeed] * cv_cam_turnmultiplier.value)>>FRACBITS)); @@ -1489,8 +1490,8 @@ void G_BuildTiccmd(ticcmd_t *cmd, INT32 realtics, UINT8 ssplayer) if (PLAYERINPUTDOWN(ssplayer, gc_camreset)) { - if (camera.chase && !resetdown[forplayer]) - P_ResetCamera(&players[ssplayer == 1 ? displayplayer : secondarydisplayplayer], &camera); + if (thiscam->chase && !resetdown[forplayer]) + P_ResetCamera(&players[ssplayer == 1 ? displayplayer : secondarydisplayplayer], thiscam); resetdown[forplayer] = true; } @@ -1508,7 +1509,7 @@ void G_BuildTiccmd(ticcmd_t *cmd, INT32 realtics, UINT8 ssplayer) INT32 player_invert = invertmouse ? -1 : 1; INT32 screen_invert = (player->mo && (player->mo->eflags & MFE_VERTICALFLIP) - && (!camera.chase || player->pflags & PF_FLIPCAM)) //because chasecam's not inverted + && (!thiscam->chase || player->pflags & PF_FLIPCAM)) //because chasecam's not inverted ? -1 : 1; // set to -1 or 1 to multiply INT32 lookaxis = ssplayer == 1 ? cv_lookaxis.value : cv_lookaxis2.value; @@ -1592,7 +1593,7 @@ void G_BuildTiccmd(ticcmd_t *cmd, INT32 realtics, UINT8 ssplayer) } //Silly hack to make 2d mode *somewhat* playable with no chasecam. - if ((twodlevel || (player->mo && player->mo->flags2 & MF2_TWOD)) && !camera.chase) + if ((twodlevel || (player->mo && player->mo->flags2 & MF2_TWOD)) && !thiscam->chase) { INT32 temp = forward; forward = side; @@ -1628,7 +1629,7 @@ void G_BuildTiccmd(ticcmd_t *cmd, INT32 realtics, UINT8 ssplayer) cmd->angleturn = (INT16)(*myangle >> 16); // Adjust camera angle by player input - if (abilitydirection && !forcestrafe && camera.chase && !turnheld[forplayer] && !ticcmd_centerviewdown[forplayer] && !player->climbing && player->powers[pw_carry] != CR_MINECART) + if (abilitydirection && !forcestrafe && thiscam->chase && !turnheld[forplayer] && !ticcmd_centerviewdown[forplayer] && !player->climbing && player->powers[pw_carry] != CR_MINECART) { fixed_t camadjustfactor = cv_cam_turnfacinginput[forplayer].value; @@ -1648,7 +1649,7 @@ void G_BuildTiccmd(ticcmd_t *cmd, INT32 realtics, UINT8 ssplayer) cmd->sidemove = 0; } - if (abilitydirection && camera.chase && !ticcmd_centerviewdown[forplayer] && !player->climbing && !forcestrafe && (player->pflags & PF_DIRECTIONCHAR) && player->powers[pw_carry] != CR_MINECART) + if (abilitydirection && thiscam->chase && !ticcmd_centerviewdown[forplayer] && !player->climbing && !forcestrafe && (player->pflags & PF_DIRECTIONCHAR) && player->powers[pw_carry] != CR_MINECART) { ///@TODO This block of code is a hack to get the desired abilitydirection and player angle behaviors while remaining netplay-compatible with EXEs without those features. // This has side effects like making F12 spectate look kind of weird, and making the input viewer inaccurate. @@ -1671,7 +1672,7 @@ void G_BuildTiccmd(ticcmd_t *cmd, INT32 realtics, UINT8 ssplayer) // Adjust camera angle to face player direction, depending on circumstances // Nothing happens if cam left/right are held, so you can hold both to lock the camera in one direction - if (abilitydirection && !forcestrafe && camera.chase && !turnheld[forplayer] && !ticcmd_centerviewdown[forplayer] && player->powers[pw_carry] != CR_MINECART) + if (abilitydirection && !forcestrafe && thiscam->chase && !turnheld[forplayer] && !ticcmd_centerviewdown[forplayer] && player->powers[pw_carry] != CR_MINECART) { fixed_t camadjustfactor; boolean alt = false; // Reduce intensity on diagonals and prevent backwards movement from turning the camera From 91222f75271aa6bf92362ba01b6993880c325e70 Mon Sep 17 00:00:00 2001 From: Nev3r Date: Sat, 4 Jan 2020 18:05:03 +0100 Subject: [PATCH 629/746] Adapt P_ClosestPointOnLine3D() to be much like FV3_ClosestPointOnLine() and use vector3_t's as args, save for the hypotenuse calculation, which remains the same; the output should be the same as before. Adapt the rope hang snapping to the new function's form. --- src/p_maputl.c | 65 +++++++++++++------------------------------------- src/p_maputl.h | 2 +- src/p_spec.c | 43 +++++++++++++++------------------ 3 files changed, 37 insertions(+), 73 deletions(-) diff --git a/src/p_maputl.c b/src/p_maputl.c index f598595e2..afa020504 100644 --- a/src/p_maputl.c +++ b/src/p_maputl.c @@ -78,68 +78,37 @@ void P_ClosestPointOnLine(fixed_t x, fixed_t y, line_t *line, vertex_t *result) return; } -// -// P_ClosestPointOnLine3D -// Finds the closest point on a given line to the supplied point IN 3D!!! -// -void P_ClosestPointOnLine3D(fixed_t x, fixed_t y, fixed_t z, line_t *line, vertex_t *result) +/// Similar to FV3_ClosestPointOnLine() except it actually works. +void P_ClosestPointOnLine3D(const vector3_t *p, const vector3_t *Line, vector3_t *result) { - fixed_t startx = line->v1->x; - fixed_t starty = line->v1->y; - fixed_t startz = line->v1->z; - fixed_t dx = line->dx; - fixed_t dy = line->dy; - fixed_t dz = line->v2->z - line->v1->z; + const vector3_t* v1 = &Line[0]; + const vector3_t* v2 = &Line[1]; + vector3_t c, V, n; + fixed_t t, d; + FV3_SubEx(v2, v1, &V); + FV3_SubEx(p, v1, &c); - // Determine t (the length of the vector from �Line[0]� to �p�) - fixed_t cx, cy, cz; - fixed_t vx, vy, vz; - fixed_t magnitude; - fixed_t t; + d = R_PointToDist2(0, v2->z, R_PointToDist2(v2->x, v2->y, v1->x, v1->y), v1->z); + FV3_Copy(&n, &V); + FV3_Divide(&n, d); - //Sub (p, &Line[0], &c); - cx = x - startx; - cy = y - starty; - cz = z - startz; - - //Sub (&Line[1], &Line[0], &V); - vx = dx; - vy = dy; - vz = dz; - - //Normalize (&V, &V); - magnitude = R_PointToDist2(0, line->v2->z, R_PointToDist2(line->v2->x, line->v2->y, startx, starty), startz); - vx = FixedDiv(vx, magnitude); - vy = FixedDiv(vy, magnitude); - vz = FixedDiv(vz, magnitude); - - t = (FixedMul(vx, cx) + FixedMul(vy, cy) + FixedMul(vz, cz)); + t = FV3_Dot(&n, &c); // Set closest point to the end if it extends past -Red if (t <= 0) { - result->x = line->v1->x; - result->y = line->v1->y; - result->z = line->v1->z; + FV3_Copy(result, v1); return; } - else if (t >= magnitude) + else if (t >= d) { - result->x = line->v2->x; - result->y = line->v2->y; - result->z = line->v2->z; + FV3_Copy(result, v2); return; } - // Return the point between �Line[0]� and �Line[1]� - vx = FixedMul(vx, t); - vy = FixedMul(vy, t); - vz = FixedMul(vz, t); + FV3_Mul(&n, t); - //Add (&Line[0], &V, out); - result->x = startx + vx; - result->y = starty + vy; - result->z = startz + vz; + FV3_AddEx(v1, &n, result); return; } diff --git a/src/p_maputl.h b/src/p_maputl.h index 2ca718779..16cfc834e 100644 --- a/src/p_maputl.h +++ b/src/p_maputl.h @@ -43,7 +43,7 @@ boolean P_PathTraverse(fixed_t px1, fixed_t py1, fixed_t px2, fixed_t py2, FUNCMATH fixed_t P_AproxDistance(fixed_t dx, fixed_t dy); void P_ClosestPointOnLine(fixed_t x, fixed_t y, line_t *line, vertex_t *result); -void P_ClosestPointOnLine3D(fixed_t x, fixed_t y, fixed_t z, line_t *line, vertex_t *result); +void P_ClosestPointOnLine3D(const vector3_t *p, const vector3_t *line, vector3_t *result); INT32 P_PointOnLineSide(fixed_t x, fixed_t y, line_t *line); void P_MakeDivline(line_t *li, divline_t *dl); void P_CameraLineOpening(line_t *plinedef); diff --git a/src/p_spec.c b/src/p_spec.c index a97d1f92f..00a71602b 100644 --- a/src/p_spec.c +++ b/src/p_spec.c @@ -5038,8 +5038,7 @@ DoneSection2: mobj_t *waypointlow = NULL; mobj_t *mo2; mobj_t *closest = NULL; - line_t junk; - vertex_t v1, v2, resulthigh, resultlow; + vector3_t p, line[2], resulthigh, resultlow; mobj_t *highest = NULL; if (player->mo->tracer && player->mo->tracer->type == MT_TUBEWAYPOINT && player->powers[pw_carry] == CR_ROPEHANG) @@ -5186,38 +5185,34 @@ DoneSection2: // Next, we need to find the closest point on the line between each set, and determine which one we're // closest to. + p.x = player->mo->x; + p.y = player->mo->y; + p.z = player->mo->z; + // Waypointmid and Waypointlow: if (waypointlow) { - v1.x = waypointmid->x; - v1.y = waypointmid->y; - v1.z = waypointmid->z; - v2.x = waypointlow->x; - v2.y = waypointlow->y; - v2.z = waypointlow->z; - junk.v1 = &v1; - junk.v2 = &v2; - junk.dx = v2.x - v1.x; - junk.dy = v2.y - v1.y; + line[0].x = waypointmid->x; + line[0].y = waypointmid->y; + line[0].z = waypointmid->z; + line[1].x = waypointlow->x; + line[1].y = waypointlow->y; + line[1].z = waypointlow->z; - P_ClosestPointOnLine3D(player->mo->x, player->mo->y, player->mo->z, &junk, &resultlow); + P_ClosestPointOnLine3D(&p, line, &resultlow); } // Waypointmid and Waypointhigh: if (waypointhigh) { - v1.x = waypointmid->x; - v1.y = waypointmid->y; - v1.z = waypointmid->z; - v2.x = waypointhigh->x; - v2.y = waypointhigh->y; - v2.z = waypointhigh->z; - junk.v1 = &v1; - junk.v2 = &v2; - junk.dx = v2.x - v1.x; - junk.dy = v2.y - v1.y; + line[0].x = waypointmid->x; + line[0].y = waypointmid->y; + line[0].z = waypointmid->z; + line[1].x = waypointhigh->x; + line[1].y = waypointhigh->y; + line[1].z = waypointhigh->z; - P_ClosestPointOnLine3D(player->mo->x, player->mo->y, player->mo->z, &junk, &resulthigh); + P_ClosestPointOnLine3D(&p, line, &resulthigh); } // 3D support now available. Disregard the previous notice here. -Red From 9999be2d6e14fd605d55ac3fe4f28c088e497880 Mon Sep 17 00:00:00 2001 From: Nev3r Date: Sat, 4 Jan 2020 18:29:02 +0100 Subject: [PATCH 630/746] Remove vertex_t's z variable. --- src/lua_maplib.c | 7 +------ src/p_setup.c | 2 -- src/r_defs.h | 2 +- 3 files changed, 2 insertions(+), 9 deletions(-) diff --git a/src/lua_maplib.c b/src/lua_maplib.c index 8ce6551f7..309ba86a1 100644 --- a/src/lua_maplib.c +++ b/src/lua_maplib.c @@ -157,15 +157,13 @@ static const char *const side_opt[] = { enum vertex_e { vertex_valid = 0, vertex_x, - vertex_y, - vertex_z + vertex_y }; static const char *const vertex_opt[] = { "valid", "x", "y", - "z", NULL}; enum ffloor_e { @@ -970,9 +968,6 @@ static int vertex_get(lua_State *L) case vertex_y: lua_pushfixed(L, vertex->y); return 1; - case vertex_z: - lua_pushfixed(L, vertex->z); - return 1; } return 0; } diff --git a/src/p_setup.c b/src/p_setup.c index bd1c53104..fa60fcf6d 100644 --- a/src/p_setup.c +++ b/src/p_setup.c @@ -846,7 +846,6 @@ static void P_LoadVertices(UINT8 *data) { v->x = SHORT(mv->x)<y = SHORT(mv->y)<z = 0; } } @@ -1575,7 +1574,6 @@ static void P_LoadTextmap(void) { // Defaults. vt->x = vt->y = INT32_MAX; - vt->z = 0; TextmapParse(vertexesPos[i], i, ParseTextmapVertexParameter); diff --git a/src/r_defs.h b/src/r_defs.h index 96ef953ce..c7c198d66 100644 --- a/src/r_defs.h +++ b/src/r_defs.h @@ -83,7 +83,7 @@ typedef struct extracolormap_s */ typedef struct { - fixed_t x, y, z; + fixed_t x, y; } vertex_t; // Forward of linedefs, for sectors. From 72f23a1075eb0e6b8d745bd8f2c24cb511aa57bb Mon Sep 17 00:00:00 2001 From: Nev3r Date: Sat, 4 Jan 2020 23:01:01 +0100 Subject: [PATCH 631/746] Add missing initialization on vertex heights for binary maps. --- src/p_setup.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/p_setup.c b/src/p_setup.c index 2819cb570..0a1c675ef 100644 --- a/src/p_setup.c +++ b/src/p_setup.c @@ -846,6 +846,8 @@ static void P_LoadVertices(UINT8 *data) { v->x = SHORT(mv->x)<y = SHORT(mv->y)<floorzset = vt->ceilingzset = false; + vt->floorz = vt->ceilingz = 0; } } From 3bcf6b4b7ec71d4959a4ce8b52255929bc1d70fc Mon Sep 17 00:00:00 2001 From: Alam Ed Arias Date: Sat, 4 Jan 2020 18:33:58 -0500 Subject: [PATCH 632/746] SpawnVertexSlops() is only used in p_slopes.c --- src/p_slopes.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/p_slopes.c b/src/p_slopes.c index 5c47c7226..13b283af6 100644 --- a/src/p_slopes.c +++ b/src/p_slopes.c @@ -508,7 +508,7 @@ static void line_SpawnViaVertexes(const int linenum, const boolean spawnthinker) } /// Spawn textmap vertex slopes. -void SpawnVertexSlopes (void) +static void SpawnVertexSlopes (void) { line_t *l1, *l2; sector_t* sc; From 641ac72b3f7e1a435e9095a618623c6718bfefeb Mon Sep 17 00:00:00 2001 From: Alam Ed Arias Date: Sat, 4 Jan 2020 18:34:16 -0500 Subject: [PATCH 633/746] Copy and Paste error --- src/p_setup.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/p_setup.c b/src/p_setup.c index 0a1c675ef..a2872cf4b 100644 --- a/src/p_setup.c +++ b/src/p_setup.c @@ -846,8 +846,8 @@ static void P_LoadVertices(UINT8 *data) { v->x = SHORT(mv->x)<y = SHORT(mv->y)<floorzset = vt->ceilingzset = false; - vt->floorz = vt->ceilingz = 0; + v->floorzset = v->ceilingzset = false; + v->floorz = v->ceilingz = 0; } } From 6d754821fbe565ed6dd714c877caad7ed68015f9 Mon Sep 17 00:00:00 2001 From: Jaime Passos Date: Fri, 3 Jan 2020 23:25:26 -0300 Subject: [PATCH 634/746] AA trees are not needed at all for rotated patches --- src/hardware/hw_cache.c | 17 ----------------- src/hardware/hw_glob.h | 3 --- src/r_defs.h | 3 --- src/r_patch.c | 6 ++++-- src/r_things.c | 3 --- 5 files changed, 4 insertions(+), 28 deletions(-) diff --git a/src/hardware/hw_cache.c b/src/hardware/hw_cache.c index 46f7b2bde..3b69c3c40 100644 --- a/src/hardware/hw_cache.c +++ b/src/hardware/hw_cache.c @@ -1324,23 +1324,6 @@ GLPatch_t *HWR_GetCachedGLPatch(lumpnum_t lumpnum) return HWR_GetCachedGLPatchPwad(WADFILENUM(lumpnum),LUMPNUM(lumpnum)); } -#ifdef ROTSPRITE -GLPatch_t *HWR_GetCachedGLRotSprite(aatree_t *hwrcache, UINT16 rollangle, patch_t *rawpatch) -{ - GLPatch_t *grpatch; - - if (!(grpatch = M_AATreeGet(hwrcache, rollangle))) - { - grpatch = Z_Calloc(sizeof(GLPatch_t), PU_HWRPATCHINFO, NULL); - grpatch->rawpatch = rawpatch; - grpatch->mipmap = Z_Calloc(sizeof(GLMipmap_t), PU_HWRPATCHINFO, NULL); - M_AATreeSet(hwrcache, rollangle, grpatch); - } - - return grpatch; -} -#endif - // Need to do this because they aren't powers of 2 static void HWR_DrawFadeMaskInCache(GLMipmap_t *mipmap, INT32 pblockwidth, INT32 pblockheight, lumpnum_t fademasklumpnum, UINT16 fmwidth, UINT16 fmheight) diff --git a/src/hardware/hw_glob.h b/src/hardware/hw_glob.h index cf98e7317..a2bf79817 100644 --- a/src/hardware/hw_glob.h +++ b/src/hardware/hw_glob.h @@ -113,9 +113,6 @@ GLPatch_t *HWR_GetPic(lumpnum_t lumpnum); void HWR_SetPalette(RGBA_t *palette); GLPatch_t *HWR_GetCachedGLPatchPwad(UINT16 wad, UINT16 lump); GLPatch_t *HWR_GetCachedGLPatch(lumpnum_t lumpnum); -#ifdef ROTSPRITE -GLPatch_t *HWR_GetCachedGLRotSprite(aatree_t *hwrcache, UINT16 rollangle, patch_t *rawpatch); -#endif void HWR_GetFadeMask(lumpnum_t fademasklumpnum); // -------- diff --git a/src/r_defs.h b/src/r_defs.h index 2791ac8b0..f6ea36f9f 100644 --- a/src/r_defs.h +++ b/src/r_defs.h @@ -740,9 +740,6 @@ typedef struct { patch_t *patch[8][ROTANGLES]; boolean cached[8]; -#ifdef HWRENDER - aatree_t *hardware_patch[8]; -#endif/*HWRENDER*/ } rotsprite_t; #endif/*ROTSPRITE*/ diff --git a/src/r_patch.c b/src/r_patch.c index 31f4411b1..c1f251ae7 100644 --- a/src/r_patch.c +++ b/src/r_patch.c @@ -1326,9 +1326,11 @@ void R_CacheRotSprite(spritenum_t sprnum, UINT8 frame, spriteinfo_t *sprinfo, sp #ifdef HWRENDER if (rendermode == render_opengl) { - GLPatch_t *grPatch = HWR_GetCachedGLRotSprite(sprframe->rotsprite.hardware_patch[rot], angle, newpatch); - HWR_MakePatch(newpatch, grPatch, grPatch->mipmap, false); + GLPatch_t *grPatch = Z_Calloc(sizeof(GLPatch_t), PU_HWRPATCHINFO, NULL); + grPatch->mipmap = Z_Calloc(sizeof(GLMipmap_t), PU_HWRPATCHINFO, NULL); + grPatch->rawpatch = newpatch; sprframe->rotsprite.patch[rot][angle] = (patch_t *)grPatch; + HWR_MakePatch(newpatch, grPatch, grPatch->mipmap, false); } else #endif // HWRENDER diff --git a/src/r_things.c b/src/r_things.c index 7ecb14e7e..d22c8d2ca 100644 --- a/src/r_things.c +++ b/src/r_things.c @@ -125,9 +125,6 @@ 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/*ROTSPRITE*/ From deee2a0d6fae77ed8cd1a17669fb6384ecde2119 Mon Sep 17 00:00:00 2001 From: Jaime Passos Date: Sat, 4 Jan 2020 22:19:30 -0300 Subject: [PATCH 635/746] I was using V_GetColor in a lot of places I shouldn't have, making the game look wrong with a non-default colour profile. Though, I left R_RainbowColormap alone. --- src/r_data.c | 6 +++--- src/v_video.h | 1 + 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/src/r_data.c b/src/r_data.c index bfd83a62d..986b65dea 100644 --- a/src/r_data.c +++ b/src/r_data.c @@ -324,8 +324,8 @@ UINT8 ASTBlendPixel_8bpp(UINT8 background, UINT8 foreground, int style, UINT8 al else if (style != AST_TRANSLUCENT) { RGBA_t texel; - RGBA_t bg = V_GetColor(background); - RGBA_t fg = V_GetColor(foreground); + RGBA_t bg = V_GetMasterColor(background); + RGBA_t fg = V_GetMasterColor(foreground); texel.rgba = ASTBlendPixel(bg, fg, style, alpha); return NearestColor(texel.s.red, texel.s.green, texel.s.blue); } @@ -1664,7 +1664,7 @@ static void R_CreateFadeColormaps(void) #define GETCOLOR \ px = colormaps[i%256]; \ fade = (i/256) * (256 / FADECOLORMAPROWS); \ - rgba = V_GetColor(px); + rgba = V_GetMasterColor(px); // to black makeblack: diff --git a/src/v_video.h b/src/v_video.h index 36d1914af..eb75a414f 100644 --- a/src/v_video.h +++ b/src/v_video.h @@ -64,6 +64,7 @@ void V_CubeApply(UINT8 *red, UINT8 *green, UINT8 *blue); // Retrieve the ARGB value from a palette color index #define V_GetColor(color) (pLocalPalette[color&0xFF]) +#define V_GetMasterColor(color) (pMasterPalette[color&0xFF]) // Bottom 8 bits are used for parameter (screen or character) #define V_PARAMMASK 0x000000FF From 6c85c4e1d39f6d686d19595539f6b349d01df887 Mon Sep 17 00:00:00 2001 From: Louis-Antoine Date: Sun, 5 Jan 2020 18:39:16 +0100 Subject: [PATCH 636/746] Fix mouse being grabbed even when not used --- 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 e6a40327b..785d8c4dc 100644 --- a/src/sdl/i_video.c +++ b/src/sdl/i_video.c @@ -110,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 (!cv_alwaysgrabmouse.value && (menuactive || paused || con_destlines || chat_on || gamestate != GS_LEVEL)) +#define IGNORE_MOUSE (!USE_MOUSEINPUT || (!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 From d93adbacbb60b5f571991bcc7874059db38e7490 Mon Sep 17 00:00:00 2001 From: Jaime Passos Date: Fri, 3 Jan 2020 23:01:12 -0300 Subject: [PATCH 637/746] Fix GetTextureUsed --- src/hardware/r_opengl/r_opengl.c | 22 +++++++++++++++++++--- 1 file changed, 19 insertions(+), 3 deletions(-) diff --git a/src/hardware/r_opengl/r_opengl.c b/src/hardware/r_opengl/r_opengl.c index 129bf5678..9fa49cf76 100644 --- a/src/hardware/r_opengl/r_opengl.c +++ b/src/hardware/r_opengl/r_opengl.c @@ -2275,14 +2275,30 @@ EXPORT void HWRAPI(SetTransform) (FTransform *stransform) EXPORT INT32 HWRAPI(GetTextureUsed) (void) { - FTextureInfo* tmp = gr_cachehead; - INT32 res = 0; + FTextureInfo *tmp = gr_cachehead; + INT32 res = 0; while (tmp) { - res += tmp->height*tmp->width*(screen_depth/8); + // Figure out the correct bytes-per-pixel for this texture + // I don't know which one the game actually _uses_ but this + // follows format2bpp in hw_cache.c + int bpp = 1; + int format = tmp->grInfo.format; + if (format == GR_RGBA) + bpp = 4; + else if (format == GR_TEXFMT_RGB_565 + || format == GR_TEXFMT_ARGB_1555 + || format == GR_TEXFMT_ARGB_4444 + || format == GR_TEXFMT_ALPHA_INTENSITY_88 + || format == GR_TEXFMT_AP_88) + bpp = 2; + + // Add it up! + res += tmp->height*tmp->width*bpp; tmp = tmp->nextmipmap; } + return res; } From 88c8049c77f3c38768de19c02394f5b888028f96 Mon Sep 17 00:00:00 2001 From: Louis-Antoine Date: Sun, 5 Jan 2020 18:39:16 +0100 Subject: [PATCH 638/746] Revert "Fix mouse being grabbed even when not used" This reverts commit 6c85c4e1d39f6d686d19595539f6b349d01df887. --- 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 785d8c4dc..e6a40327b 100644 --- a/src/sdl/i_video.c +++ b/src/sdl/i_video.c @@ -110,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 (!USE_MOUSEINPUT || (!cv_alwaysgrabmouse.value && (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 From e847777a35eab5a5c3e05bd189b6f308457ca5db Mon Sep 17 00:00:00 2001 From: Louis-Antoine Date: Sun, 5 Jan 2020 18:39:16 +0100 Subject: [PATCH 639/746] Fix mouse being grabbed even when not used The other way around this time. --- 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 e6a40327b..2b8633e5b 100644 --- a/src/sdl/i_video.c +++ b/src/sdl/i_video.c @@ -388,7 +388,7 @@ void I_UpdateMouseGrab(void) { if (SDL_WasInit(SDL_INIT_VIDEO) == SDL_INIT_VIDEO && window != NULL && SDL_GetMouseFocus() == window && SDL_GetKeyboardFocus() == window - && !IGNORE_MOUSE) + && USE_MOUSEINPUT && !IGNORE_MOUSE) SDLdoGrabMouse(); } From 9086b1851d0c76a52a724e3c183cd1ada4c84f39 Mon Sep 17 00:00:00 2001 From: Jaime Passos Date: Sun, 5 Jan 2020 22:04:19 -0300 Subject: [PATCH 640/746] Fix chroma key --- src/hardware/hw_cache.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/hardware/hw_cache.c b/src/hardware/hw_cache.c index 3b69c3c40..ccffc8a49 100644 --- a/src/hardware/hw_cache.c +++ b/src/hardware/hw_cache.c @@ -122,11 +122,11 @@ static void HWR_DrawColumnInCache(const column_t *patchcol, UINT8 *block, GLMipm if (mipmap->colormap) texel = mipmap->colormap[texel]; - // transparent pixel - if (texel == HWR_PATCHES_CHROMAKEY_COLORINDEX) + // If the mipmap is chromakeyed, check if the texel's color + // is equivalent to the chroma key's color index. + alpha = 0xff; + if ((mipmap->flags & TF_CHROMAKEYED) && (texel == HWR_PATCHES_CHROMAKEY_COLORINDEX)) alpha = 0x00; - else - alpha = 0xff; // hope compiler will get this switch out of the loops (dreams...) // gcc do it ! but vcc not ! (why don't use cygwin gcc for win32 ?) From 664bce71deae6135cbb58c840ba2293a61ab7ea7 Mon Sep 17 00:00:00 2001 From: Tatsuru <44866610+Ikkarin@users.noreply.github.com> Date: Sun, 5 Jan 2020 23:18:38 -0300 Subject: [PATCH 641/746] :amybruh: --- src/p_mobj.c | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/src/p_mobj.c b/src/p_mobj.c index e8461957f..713a4d476 100644 --- a/src/p_mobj.c +++ b/src/p_mobj.c @@ -7977,15 +7977,18 @@ static void P_MobjSceneryThink(mobj_t *mobj) mobj->x = mobj->extravalue1 + P_ReturnThrustX(mobj, mobj->movedir, mobj->cvmem*mobj->scale); mobj->y = mobj->extravalue2 + P_ReturnThrustY(mobj, mobj->movedir, mobj->cvmem*mobj->scale); P_SetThingPosition(mobj); - if ((--mobj->fuse) < 6) - { - if (!mobj->fuse) + + // :amybruh: + if (!mobj->fuse) { - P_RemoveMobj(mobj); +#ifdef HAVE_BLUA + if (!LUAh_MobjFuse(mobj)) +#endif + P_RemoveMobj(mobj); return; } + if ((--mobj->fuse) < 6) mobj->frame = (mobj->frame & ~FF_TRANSMASK) | ((10 - (mobj->fuse*2)) << (FF_TRANSSHIFT)); - } } break; case MT_VWREF: From fce1313517658f86b7865d823a2e42af6dbba919 Mon Sep 17 00:00:00 2001 From: Tatsuru <44866610+Ikkarin@users.noreply.github.com> Date: Sun, 5 Jan 2020 23:19:52 -0300 Subject: [PATCH 642/746] No comments --- src/p_mobj.c | 1 - 1 file changed, 1 deletion(-) diff --git a/src/p_mobj.c b/src/p_mobj.c index 713a4d476..05a535175 100644 --- a/src/p_mobj.c +++ b/src/p_mobj.c @@ -7978,7 +7978,6 @@ static void P_MobjSceneryThink(mobj_t *mobj) mobj->y = mobj->extravalue2 + P_ReturnThrustY(mobj, mobj->movedir, mobj->cvmem*mobj->scale); P_SetThingPosition(mobj); - // :amybruh: if (!mobj->fuse) { #ifdef HAVE_BLUA From 07f9ddc45a169e3ab23aa528428482df58f142b6 Mon Sep 17 00:00:00 2001 From: Tatsuru <44866610+Ikkarin@users.noreply.github.com> Date: Sun, 5 Jan 2020 23:41:22 -0300 Subject: [PATCH 643/746] Don't fuck with the fuse if it's negative --- src/p_mobj.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/p_mobj.c b/src/p_mobj.c index 05a535175..fbfbaab00 100644 --- a/src/p_mobj.c +++ b/src/p_mobj.c @@ -7986,6 +7986,8 @@ static void P_MobjSceneryThink(mobj_t *mobj) P_RemoveMobj(mobj); return; } + if (mobj->fuse < 0) + return; if ((--mobj->fuse) < 6) mobj->frame = (mobj->frame & ~FF_TRANSMASK) | ((10 - (mobj->fuse*2)) << (FF_TRANSSHIFT)); } From 0fbc459243323a4de96faaffb1c9ff7e2e7a4ee9 Mon Sep 17 00:00:00 2001 From: Alam Ed Arias Date: Sun, 5 Jan 2020 21:49:07 -0500 Subject: [PATCH 644/746] cleanup whitespace --- src/m_menu.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/m_menu.c b/src/m_menu.c index e9d794bd1..ea2c5c6d8 100644 --- a/src/m_menu.c +++ b/src/m_menu.c @@ -10524,7 +10524,7 @@ static void M_HandleConnectIP(INT32 choice) case 'V': // ctrl+v, pasting { const char *paste = I_ClipboardPaste(); - + if (paste != NULL) { strncat(setupm_ip, paste, 28-1 - l); // Concat the ip field with clipboard if (strlen(paste) != 0) // Don't play sound if nothing was pasted @@ -10558,7 +10558,7 @@ static void M_HandleConnectIP(INT32 choice) case KEY_INS: // shift+insert, pasting { const char *paste = I_ClipboardPaste(); - + if (paste != NULL) { strncat(setupm_ip, paste, 28-1 - l); // Concat the ip field with clipboard if (strlen(paste) != 0) // Don't play sound if nothing was pasted From 759b1c82e28325530deec9c4720b31ca33965c96 Mon Sep 17 00:00:00 2001 From: MascaraSnake Date: Mon, 6 Jan 2020 14:40:59 +0100 Subject: [PATCH 645/746] Add missing glseg checks (and remove a superfluous one) --- src/hardware/hw_bsp.c | 6 +++++- src/hardware/hw_main.c | 7 ++++--- src/p_sight.c | 3 +++ src/r_main.c | 12 +++++++++--- src/r_segs.c | 3 --- 5 files changed, 21 insertions(+), 10 deletions(-) diff --git a/src/hardware/hw_bsp.c b/src/hardware/hw_bsp.c index f8d4f43d9..6f3dd9fbd 100644 --- a/src/hardware/hw_bsp.c +++ b/src/hardware/hw_bsp.c @@ -449,8 +449,12 @@ static poly_t *CutOutSubsecPoly(seg_t *lseg, INT32 count, poly_t *poly) // for each seg of the subsector for (; count--; lseg++) { - //x,y,dx,dy (like a divline) line_t *line = lseg->linedef; + + if (lseg->glseg) + continue; + + //x,y,dx,dy (like a divline) p1.x = FIXED_TO_FLOAT(lseg->side ? line->v2->x : line->v1->x); p1.y = FIXED_TO_FLOAT(lseg->side ? line->v2->y : line->v1->y); p2.x = FIXED_TO_FLOAT(lseg->side ? line->v1->x : line->v2->x); diff --git a/src/hardware/hw_main.c b/src/hardware/hw_main.c index 276a66670..8c36eeded 100644 --- a/src/hardware/hw_main.c +++ b/src/hardware/hw_main.c @@ -2714,8 +2714,6 @@ static void HWR_AddLine(seg_t * line) static sector_t tempsec; fixed_t v1x, v1y, v2x, v2y; // the seg's vertexes as fixed_t - if (line->glseg) - return; #ifdef POLYOBJECTS if (line->polyseg && !(line->polyseg->flags & POF_RENDERSIDES)) return; @@ -3773,9 +3771,12 @@ static void HWR_Subsector(size_t num) while (count--) { + + if (!line->glseg #ifdef POLYOBJECTS - if (!line->polyseg) // ignore segs that belong to polyobjects + && !line->polyseg // ignore segs that belong to polyobjects #endif + ) HWR_AddLine(line); line++; } diff --git a/src/p_sight.c b/src/p_sight.c index 499d4a095..07dfabbc1 100644 --- a/src/p_sight.c +++ b/src/p_sight.c @@ -222,6 +222,9 @@ static boolean P_CrossSubsector(size_t num, register los_t *los) fixed_t fracx, fracy; #endif + if (seg->glseg) + continue; + // already checked other side? if (line->validcount == validcount) continue; diff --git a/src/r_main.c b/src/r_main.c index a5f4bc118..22061b407 100644 --- a/src/r_main.c +++ b/src/r_main.c @@ -698,6 +698,7 @@ subsector_t *R_IsPointInSubsector(fixed_t x, fixed_t y) INT32 side, i; size_t nodenum; subsector_t *ret; + seg_t *seg; // single subsector is a special case if (numnodes == 0) @@ -713,10 +714,15 @@ subsector_t *R_IsPointInSubsector(fixed_t x, fixed_t y) } ret = &subsectors[nodenum & ~NF_SUBSECTOR]; - for (i = 0; i < ret->numlines; i++) - //if (R_PointOnSegSide(x, y, &segs[ret->firstline + i])) -- breaks in ogl because polyvertex_t cast over vertex pointers - if (P_PointOnLineSide(x, y, segs[ret->firstline + i].linedef) != segs[ret->firstline + i].side) + for (i = 0, seg = &segs[ret->firstline]; i < ret->numlines; i++, seg++) + { + if (seg->glseg) + continue; + + //if (R_PointOnSegSide(x, y, seg)) -- breaks in ogl because polyvertex_t cast over vertex pointers + if (P_PointOnLineSide(x, y, seg->linedef) != seg->side) return 0; + } return ret; } diff --git a/src/r_segs.c b/src/r_segs.c index 1af1cb2a2..dcb5fc160 100644 --- a/src/r_segs.c +++ b/src/r_segs.c @@ -309,9 +309,6 @@ void R_RenderMaskedSegRange(drawseg_t *ds, INT32 x1, INT32 x2) // OPTIMIZE: get rid of LIGHTSEGSHIFT globally curline = ds->curline; - if (curline->glseg) - return; - frontsector = curline->frontsector; backsector = curline->backsector; texnum = R_GetTextureNum(curline->sidedef->midtexture); From 21c224fce0a2a72f5a6be2477fe6a892120161fe Mon Sep 17 00:00:00 2001 From: Alam Ed Arias Date: Mon, 6 Jan 2020 09:58:05 -0500 Subject: [PATCH 646/746] idented hell --- src/hardware/hw_main.c | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/src/hardware/hw_main.c b/src/hardware/hw_main.c index 8c36eeded..2f986085a 100644 --- a/src/hardware/hw_main.c +++ b/src/hardware/hw_main.c @@ -3774,11 +3774,13 @@ static void HWR_Subsector(size_t num) if (!line->glseg #ifdef POLYOBJECTS - && !line->polyseg // ignore segs that belong to polyobjects + && !line->polyseg // ignore segs that belong to polyobjects #endif - ) + ) + { HWR_AddLine(line); - line++; + } + line++; } } From 808d7316527375c323eb1fbd9f492ad07ed253c3 Mon Sep 17 00:00:00 2001 From: Steel Titanium Date: Mon, 6 Jan 2020 17:16:27 -0500 Subject: [PATCH 647/746] Update copyright statements for changed names --- src/f_wipe.c | 2 +- src/m_anigif.c | 2 +- src/m_anigif.h | 2 +- src/m_cond.c | 2 +- src/m_cond.h | 2 +- src/m_menu.c | 2 +- src/m_menu.h | 2 +- src/m_random.c | 2 +- src/m_random.h | 2 +- 9 files changed, 9 insertions(+), 9 deletions(-) diff --git a/src/f_wipe.c b/src/f_wipe.c index a83d104f2..a350e0f36 100644 --- a/src/f_wipe.c +++ b/src/f_wipe.c @@ -2,7 +2,7 @@ //----------------------------------------------------------------------------- // Copyright (C) 1993-1996 by id Software, Inc. // Copyright (C) 1998-2000 by DooM Legacy Team. -// Copyright (C) 2013-2016 by Matthew "Inuyasha" Walsh. +// Copyright (C) 2013-2016 by Matthew "Kaito Sinclaire" Walsh. // Copyright (C) 1999-2019 by Sonic Team Junior. // // This program is free software distributed under the diff --git a/src/m_anigif.c b/src/m_anigif.c index f761db143..32fc2746d 100644 --- a/src/m_anigif.c +++ b/src/m_anigif.c @@ -1,6 +1,6 @@ // SONIC ROBO BLAST 2 //----------------------------------------------------------------------------- -// Copyright (C) 2013-2016 by Matthew "Inuyasha" Walsh. +// Copyright (C) 2013-2016 by Matthew "Kaito Sinclaire" Walsh. // Copyright (C) 2013 by "Ninji". // Copyright (C) 2013-2019 by Sonic Team Junior. // diff --git a/src/m_anigif.h b/src/m_anigif.h index 592d2cf19..9bdf2cc7f 100644 --- a/src/m_anigif.h +++ b/src/m_anigif.h @@ -1,6 +1,6 @@ // SONIC ROBO BLAST 2 //----------------------------------------------------------------------------- -// Copyright (C) 2013-2016 by Matthew "Inuyasha" Walsh. +// Copyright (C) 2013-2016 by Matthew "Kaito Sinclaire" Walsh. // Copyright (C) 2013-2019 by Sonic Team Junior. // // This program is free software distributed under the diff --git a/src/m_cond.c b/src/m_cond.c index 1e761fdb4..08f3fe038 100644 --- a/src/m_cond.c +++ b/src/m_cond.c @@ -1,6 +1,6 @@ // SONIC ROBO BLAST 2 //----------------------------------------------------------------------------- -// Copyright (C) 2012-2016 by Matthew "Inuyasha" Walsh. +// Copyright (C) 2012-2016 by Matthew "Kaito Sinclaire" Walsh. // Copyright (C) 2012-2019 by Sonic Team Junior. // // This program is free software distributed under the diff --git a/src/m_cond.h b/src/m_cond.h index 3ea77145d..f4f017787 100644 --- a/src/m_cond.h +++ b/src/m_cond.h @@ -1,6 +1,6 @@ // SONIC ROBO BLAST 2 //----------------------------------------------------------------------------- -// Copyright (C) 2012-2016 by Matthew "Inuyasha" Walsh. +// Copyright (C) 2012-2016 by Matthew "Kaito Sinclaire" Walsh. // Copyright (C) 2012-2019 by Sonic Team Junior. // // This program is free software distributed under the diff --git a/src/m_menu.c b/src/m_menu.c index ea2c5c6d8..fb89b7e7b 100644 --- a/src/m_menu.c +++ b/src/m_menu.c @@ -2,7 +2,7 @@ //----------------------------------------------------------------------------- // Copyright (C) 1993-1996 by id Software, Inc. // Copyright (C) 1998-2000 by DooM Legacy Team. -// Copyright (C) 2011-2016 by Matthew "Inuyasha" Walsh. +// Copyright (C) 2011-2016 by Matthew "Kaito Sinclaire" Walsh. // Copyright (C) 1999-2019 by Sonic Team Junior. // // This program is free software distributed under the diff --git a/src/m_menu.h b/src/m_menu.h index 00c258fe8..3504868c9 100644 --- a/src/m_menu.h +++ b/src/m_menu.h @@ -2,7 +2,7 @@ //----------------------------------------------------------------------------- // Copyright (C) 1993-1996 by id Software, Inc. // Copyright (C) 1998-2000 by DooM Legacy Team. -// Copyright (C) 2011-2016 by Matthew "Inuyasha" Walsh. +// Copyright (C) 2011-2016 by Matthew "Kaito Sinclaire" Walsh. // Copyright (C) 1999-2019 by Sonic Team Junior. // // This program is free software distributed under the diff --git a/src/m_random.c b/src/m_random.c index 8a7b62b19..8fd0e1e4e 100644 --- a/src/m_random.c +++ b/src/m_random.c @@ -2,7 +2,7 @@ //----------------------------------------------------------------------------- // Copyright (C) 1993-1996 by id Software, Inc. // Copyright (C) 1998-2000 by DooM Legacy Team. -// Copyright (C) 2012-2016 by Matthew "Inuyasha" Walsh. +// Copyright (C) 2012-2016 by Matthew "Kaito Sinclaire" Walsh. // Copyright (C) 1999-2019 by Sonic Team Junior. // // This program is free software distributed under the diff --git a/src/m_random.h b/src/m_random.h index fb14249bc..5efd3e02c 100644 --- a/src/m_random.h +++ b/src/m_random.h @@ -2,7 +2,7 @@ //----------------------------------------------------------------------------- // Copyright (C) 1993-1996 by id Software, Inc. // Copyright (C) 1998-2000 by DooM Legacy Team. -// Copyright (C) 2012-2016 by Matthew "Inuyasha" Walsh. +// Copyright (C) 2012-2016 by Matthew "Kaito Sinclaire" Walsh. // Copyright (C) 1999-2019 by Sonic Team Junior. // // This program is free software distributed under the From 360e8f28b4da34062eaf1845855070af8c3e4492 Mon Sep 17 00:00:00 2001 From: Tatsuru <44866610+Ikkarin@users.noreply.github.com> Date: Tue, 7 Jan 2020 01:24:04 -0300 Subject: [PATCH 648/746] ifdefs make indenting confusing --- src/p_mobj.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/p_mobj.c b/src/p_mobj.c index fbfbaab00..3d8d81d9b 100644 --- a/src/p_mobj.c +++ b/src/p_mobj.c @@ -7979,13 +7979,13 @@ static void P_MobjSceneryThink(mobj_t *mobj) P_SetThingPosition(mobj); if (!mobj->fuse) - { + { #ifdef HAVE_BLUA - if (!LUAh_MobjFuse(mobj)) + if (!LUAh_MobjFuse(mobj)) #endif - P_RemoveMobj(mobj); - return; - } + P_RemoveMobj(mobj); + return; + } if (mobj->fuse < 0) return; if ((--mobj->fuse) < 6) From e069e149d983a6795aecb362bd502efa46007dc3 Mon Sep 17 00:00:00 2001 From: lachwright Date: Tue, 7 Jan 2020 13:56:54 +0800 Subject: [PATCH 649/746] Apply skin's highresscale to continue screen --- src/f_finale.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/f_finale.c b/src/f_finale.c index bf5f2ba40..bc904d8f2 100644 --- a/src/f_finale.c +++ b/src/f_finale.c @@ -3790,7 +3790,7 @@ void F_ContinueDrawer(void) sprdef = &contskins[n]->sprites[cont_spr2[n][0]];\ sprframe = &sprdef->spriteframes[cont_spr2[n][1]];\ patch = W_CachePatchNum(sprframe->lumppat[cont_spr2[n][2]], PU_PATCH);\ - V_DrawFixedPatch((dx), (dy), FRACUNIT, (sprframe->flip & (1<highresscale, (sprframe->flip & (1< Date: Tue, 7 Jan 2020 15:38:48 +0800 Subject: [PATCH 650/746] Dashmode tweaks: - Remove the ability for non-SF_MACHINE players in dashmode to break spikes and monitors - Replace instances of dashmode magic numbers with dashmode constants - Add dashmode constants to dehacked.c --- src/dehacked.c | 4 ++++ src/p_map.c | 4 ++-- src/p_mobj.c | 2 +- 3 files changed, 7 insertions(+), 3 deletions(-) diff --git a/src/dehacked.c b/src/dehacked.c index 161a41c46..a4571eddb 100644 --- a/src/dehacked.c +++ b/src/dehacked.c @@ -9461,6 +9461,10 @@ struct { {"SF_MULTIABILITY",SF_MULTIABILITY}, {"SF_NONIGHTSROTATION",SF_NONIGHTSROTATION}, + // Dashmode constants + {"DASHMODE_THRESHOLD",DASHMODE_THRESHOLD}, + {"DASHMODE_MAX",DASHMODE_MAX}, + // Character abilities! // Primary {"CA_NONE",CA_NONE}, // now slot 0! diff --git a/src/p_map.c b/src/p_map.c index a522418f7..c468e5b3c 100644 --- a/src/p_map.c +++ b/src/p_map.c @@ -426,7 +426,7 @@ boolean P_DoSpring(mobj_t *spring, mobj_t *object) object->player->pflags |= pflags; object->player->secondjump = secondjump; } - else if (object->player->dashmode >= 3*TICRATE) + else if (object->player->dashmode >= DASHMODE_THRESHOLD) P_SetPlayerMobjState(object, S_PLAY_DASH); else if (P_IsObjectOnGround(object) && horizspeed >= FixedMul(object->player->runspeed, object->scale)) P_SetPlayerMobjState(object, S_PLAY_RUN); @@ -806,7 +806,7 @@ static boolean PIT_CheckThing(mobj_t *thing) // SF_DASHMODE users destroy spikes and monitors, CA_TWINSPIN users and CA2_MELEE users destroy spikes. if ((tmthing->player) - && (((tmthing->player->charflags & SF_DASHMODE) && (tmthing->player->dashmode >= 3*TICRATE) + && ((((tmthing->player->charflags & (SF_DASHMODE|SF_MACHINE)) == (SF_DASHMODE|SF_MACHINE)) && (tmthing->player->dashmode >= DASHMODE_THRESHOLD) && (thing->flags & (MF_MONITOR) || (thing->type == MT_SPIKE || thing->type == MT_WALLSPIKE))) diff --git a/src/p_mobj.c b/src/p_mobj.c index e8461957f..2f24bc6e0 100644 --- a/src/p_mobj.c +++ b/src/p_mobj.c @@ -3298,7 +3298,7 @@ boolean P_CanRunOnWater(player_t *player, ffloor_t *rover) *rover->topheight; if (!player->powers[pw_carry] && !player->homing - && ((player->powers[pw_super] || player->charflags & SF_RUNONWATER || player->dashmode >= 3*TICRATE) && player->mo->ceilingz-topheight >= player->mo->height) + && ((player->powers[pw_super] || player->charflags & SF_RUNONWATER || player->dashmode >= DASHMODE_THRESHOLD) && player->mo->ceilingz-topheight >= player->mo->height) && (rover->flags & FF_SWIMMABLE) && !(player->pflags & PF_SPINNING) && player->speed > FixedMul(player->runspeed, player->mo->scale) && !(player->pflags & PF_SLIDING) && abs(player->mo->z - topheight) < FixedMul(30*FRACUNIT, player->mo->scale)) From 5abf0c24f962a0034d875c207a8269a679582f07 Mon Sep 17 00:00:00 2001 From: fickleheart Date: Wed, 8 Jan 2020 00:21:03 -0600 Subject: [PATCH 651/746] oh god I forget why this is here but let's not remove it now --- src/g_game.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/g_game.c b/src/g_game.c index 08e6865e3..33f871a83 100644 --- a/src/g_game.c +++ b/src/g_game.c @@ -1514,7 +1514,7 @@ void G_BuildTiccmd(ticcmd_t *cmd, INT32 realtics, UINT8 ssplayer) (player->mo && (player->mo->eflags & MFE_VERTICALFLIP) && (!thiscam->chase || player->pflags & PF_FLIPCAM)) //because chasecam's not inverted ? -1 : 1; // set to -1 or 1 to multiply - INT32 lookaxis = ssplayer == 1 ? cv_lookaxis.value : cv_lookaxis2.value; + INT32 configlookaxis = ssplayer == 1 ? cv_lookaxis.value : cv_lookaxis2.value; // mouse look stuff (mouse look is not the same as mouse aim) if (mouseaiming) @@ -1525,11 +1525,11 @@ void G_BuildTiccmd(ticcmd_t *cmd, INT32 realtics, UINT8 ssplayer) *myaiming += (*mly<<19)*player_invert*screen_invert; } - if (analogjoystickmove && joyaiming[forplayer] && lookjoystickvector.yaxis != 0 && lookaxis != 0) + if (analogjoystickmove && joyaiming[forplayer] && lookjoystickvector.yaxis != 0 && configlookaxis != 0) *myaiming += (lookjoystickvector.yaxis<<16) * screen_invert; // spring back if not using keyboard neither mouselookin' - if (!keyboard_look[forplayer] && lookaxis == 0 && !joyaiming[forplayer] && !mouseaiming) + if (!keyboard_look[forplayer] && configlookaxis == 0 && !joyaiming[forplayer] && !mouseaiming) *myaiming = 0; if (!(player->powers[pw_carry] == CR_NIGHTSMODE)) From 6211c80a697f28f80477dc72d13a9c3f99f61fb9 Mon Sep 17 00:00:00 2001 From: fickleheart Date: Wed, 8 Jan 2020 00:22:17 -0600 Subject: [PATCH 652/746] Mixed code and declaration stuff --- 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 33f871a83..f7778df8f 100644 --- a/src/g_game.c +++ b/src/g_game.c @@ -1641,11 +1641,12 @@ void G_BuildTiccmd(ticcmd_t *cmd, INT32 realtics, UINT8 ssplayer) if (camadjustfactor) { fixed_t sine = FINESINE((R_PointToAngle2(0, 0, player->rmomx, player->rmomy) - localangle)>>ANGLETOFINESHIFT); + fixed_t factor; if ((sine > 0) == (cmd->sidemove > 0)) sine = 0; // Prevent jerking right when braking from going left, or vice versa - fixed_t factor = min(40, FixedMul(player->speed, abs(sine))*2 / FRACUNIT); + factor = min(40, FixedMul(player->speed, abs(sine))*2 / FRACUNIT); *myangle -= cmd->sidemove * factor * camadjustfactor; } From 031e7cfb824937fc0e1f9f41304824767c7c525b Mon Sep 17 00:00:00 2001 From: MascaraSnake Date: Wed, 8 Jan 2020 08:43:36 +0100 Subject: [PATCH 653/746] Fix a condition in the flame jet thinkers I accidentally messed up --- src/p_mobj.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/p_mobj.c b/src/p_mobj.c index e8461957f..a36189d6e 100644 --- a/src/p_mobj.c +++ b/src/p_mobj.c @@ -7286,7 +7286,7 @@ static void P_FlameJetSceneryThink(mobj_t *mobj) if (!(mobj->flags2 & MF2_FIRING)) return; - if ((leveltime & 3) == 0) + if ((leveltime & 3) != 0) return; // Wave the flames back and forth. Reactiontime determines which direction it's going. @@ -7325,7 +7325,7 @@ static void P_VerticalFlameJetSceneryThink(mobj_t *mobj) if (!(mobj->flags2 & MF2_FIRING)) return; - if ((leveltime & 3) == 0) + if ((leveltime & 3) != 0) return; // Wave the flames back and forth. Reactiontime determines which direction it's going. From faac4ea545fbceb413f8366525e26076b780b349 Mon Sep 17 00:00:00 2001 From: MascaraSnake Date: Wed, 8 Jan 2020 09:28:37 +0100 Subject: [PATCH 654/746] Don't create colormap data out of sidedef text for fake planes linedef (the colormap data isn't even used anymore) --- src/p_setup.c | 1 - 1 file changed, 1 deletion(-) diff --git a/src/p_setup.c b/src/p_setup.c index c61f97d92..df276d34b 100644 --- a/src/p_setup.c +++ b/src/p_setup.c @@ -1120,7 +1120,6 @@ static void P_LoadSidedefs(UINT8 *data) // Special info stored in texture fields! switch (sd->special) { - case 63: // Fake floor/ceiling planes case 606: //SoM: 4/4/2000: Just colormap transfer case 447: // Change colormap of tagged sectors! -- Monster Iestyn 14/06/18 case 455: // Fade colormaps! mazmazz 9/12/2018 (:flag_us:) From 9e703f935a605455920736141adc35f87b4f91e9 Mon Sep 17 00:00:00 2001 From: James R Date: Wed, 8 Jan 2020 01:03:44 -0800 Subject: [PATCH 655/746] Right word jump --- src/console.c | 60 ++++++++++++++++++++++++++++++++++++--------------- 1 file changed, 43 insertions(+), 17 deletions(-) diff --git a/src/console.c b/src/console.c index 01d1ddaa2..a726d8628 100644 --- a/src/console.c +++ b/src/console.c @@ -41,6 +41,8 @@ #include "hardware/hw_main.h" #endif +#define PUNCTUATION "!\"#$%&'()*+,-./:;<=>?@[\\]^_`{|}~" + #define MAXHUDLINES 20 static boolean con_started = false; // console has been initialised @@ -815,6 +817,47 @@ boolean CON_Responder(event_t *ev) || key == KEY_LALT || key == KEY_RALT) return true; + if (key == KEY_LEFTARROW) + { + if (input_cur != 0) + --input_cur; + if (!shiftdown) + input_sel = input_cur; + return true; + } + else if (key == KEY_RIGHTARROW) + { + if (ctrldown) + { + char *line; + int c; + + line = &inputlines[inputline][input_cur]; + c = line[0]; + + if (isspace(c)) + input_cur += strspn(line, " "); + else if (ispunct(c)) + input_cur += strspn(line, PUNCTUATION); + else + { + if (isspace(line[1])) + input_cur += 1 + strspn(&line[1], " "); + else + input_cur += strcspn(line, " "PUNCTUATION); + } + } + else + { + if (input_cur < input_len) + ++input_cur; + } + + if (!shiftdown) + input_sel = input_cur; + return true; + } + // ctrl modifier -- changes behavior, adds shortcuts if (ctrldown) { @@ -967,23 +1010,6 @@ boolean CON_Responder(event_t *ev) con_scrollup--; return true; } - - if (key == KEY_LEFTARROW) - { - if (input_cur != 0) - --input_cur; - if (!shiftdown) - input_sel = input_cur; - return true; - } - else if (key == KEY_RIGHTARROW) - { - if (input_cur < input_len) - ++input_cur; - if (!shiftdown) - input_sel = input_cur; - return true; - } else if (key == KEY_HOME) { input_cur = 0; From 0d3c03ccd658ee1f0d321a38bddf967d70b071bf Mon Sep 17 00:00:00 2001 From: James R Date: Wed, 8 Jan 2020 02:54:17 -0800 Subject: [PATCH 656/746] Left word jump (whoo that took long) --- src/console.c | 26 +++++++++++++++++++++++++- 1 file changed, 25 insertions(+), 1 deletion(-) diff --git a/src/console.c b/src/console.c index a726d8628..f77d9b085 100644 --- a/src/console.c +++ b/src/console.c @@ -820,7 +820,31 @@ boolean CON_Responder(event_t *ev) if (key == KEY_LEFTARROW) { if (input_cur != 0) - --input_cur; + { + if (ctrldown) + { + int (*is)(int); + char *line; + int c; + line = inputlines[inputline]; + c = line[--input_cur]; + if (isspace(c)) + is = isspace; + else if (ispunct(c)) + is = ispunct; + else + is = isalnum; + c = (*is)(line[input_cur]); + while (input_cur > 0 && + (*is)(line[input_cur - 1]) == c) + input_cur--; + } + else + { + --input_cur; + } + } + if (!shiftdown) input_sel = input_cur; return true; From 6476a92817fee8fcb3c3bf6f832a881393d5a989 Mon Sep 17 00:00:00 2001 From: Sally Cochenour Date: Wed, 25 Dec 2019 18:46:30 -0500 Subject: [PATCH 657/746] Update blend textures to smooth out colors that have duplicate indices --- src/hardware/hw_md2.c | 101 ++++++++++++++++++++++++++++++++---------- 1 file changed, 77 insertions(+), 24 deletions(-) diff --git a/src/hardware/hw_md2.c b/src/hardware/hw_md2.c index 3800b6ad9..23145b525 100644 --- a/src/hardware/hw_md2.c +++ b/src/hardware/hw_md2.c @@ -654,10 +654,14 @@ static void HWR_CreateBlendedTexture(GLPatch_t *gpatch, GLPatch_t *blendgpatch, UINT16 w = gpatch->width, h = gpatch->height; UINT32 size = w*h; RGBA_t *image, *blendimage, *cur, blendcolor; + UINT8 i; + + UINT8 translation[16]; // First the color index + UINT8 cutoff[16]; // Brightness cutoff before using the next color + UINT8 translen = 0; - // vanilla port - UINT8 translation[16]; memset(translation, 0, sizeof(translation)); + memset(cutoff, 0, sizeof(cutoff)); if (grmip->width == 0) { @@ -684,7 +688,33 @@ static void HWR_CreateBlendedTexture(GLPatch_t *gpatch, GLPatch_t *blendgpatch, blendcolor = V_GetColor(0); // initialize if (color != SKINCOLOR_NONE) - memcpy(&translation, &Color_Index[color - 1], 16); + { + UINT8 numdupes = 1; + + translation[translen] = Color_Index[color-1][0]; + cutoff[translen] = 255; + + for (i = 1; i < 16; i++) + { + if (translation[translen] == Color_Index[color-1][i]) + { + numdupes++; + continue; + } + + if (translen > 0) + { + cutoff[translen] = cutoff[translen-1] - (256 / (16 / numdupes)); + } + + numdupes = 1; + translen++; + + translation[translen] = (UINT8)Color_Index[color-1][i]; + } + + translen++; + } while (size--) { @@ -710,7 +740,7 @@ static void HWR_CreateBlendedTexture(GLPatch_t *gpatch, GLPatch_t *blendgpatch, // Turn everything below a certain blue threshold white if (image->s.red == 0 && image->s.green == 0 && image->s.blue <= 82) { - cur->s.red = cur->s.green = cur->s.blue = 255; + cur->s.red = cur->s.green = cur->s.blue = (255 - image->s.blue); } else { @@ -762,6 +792,8 @@ static void HWR_CreateBlendedTexture(GLPatch_t *gpatch, GLPatch_t *blendgpatch, { UINT16 brightness; + I_Assert(translen > 0); + // Don't bother with blending the pixel if the alpha of the blend pixel is 0 if (skinnum == TC_RAINBOW) { @@ -798,8 +830,8 @@ static void HWR_CreateBlendedTexture(GLPatch_t *gpatch, GLPatch_t *blendgpatch, // (Me splitting this into a function didn't work, so I had to ruin this entire function's groove...) { RGBA_t nextcolor; - UINT8 firsti, secondi, mul; - UINT32 r, g, b; + UINT8 firsti, secondi, mul, mulmax; + INT32 r, g, b; // Rainbow needs to find the closest match to the textures themselves, instead of matching brightnesses to other colors. // Ensue horrible mess. @@ -808,7 +840,6 @@ static void HWR_CreateBlendedTexture(GLPatch_t *gpatch, GLPatch_t *blendgpatch, UINT16 brightdif = 256; UINT8 colorbrightnesses[16]; INT32 compare, m, d; - UINT8 i; // Ignore pure white & pitch black if (brightness > 253 || brightness < 2) @@ -820,18 +851,21 @@ static void HWR_CreateBlendedTexture(GLPatch_t *gpatch, GLPatch_t *blendgpatch, firsti = 0; mul = 0; + mulmax = 1; - for (i = 0; i < 16; i++) + for (i = 0; i < translen; i++) { RGBA_t tempc = V_GetColor(translation[i]); SETBRIGHTNESS(colorbrightnesses[i], tempc.s.red, tempc.s.green, tempc.s.blue); // store brightnesses for comparison } - for (i = 0; i < 16; i++) + for (i = 0; i < translen; i++) { if (brightness > colorbrightnesses[i]) // don't allow greater matches (because calculating a makeshift gradient for this is already a huge mess as is) continue; + compare = abs((INT16)(colorbrightnesses[i]) - (INT16)(brightness)); + if (compare < brightdif) { brightdif = (UINT16)compare; @@ -840,7 +874,7 @@ static void HWR_CreateBlendedTexture(GLPatch_t *gpatch, GLPatch_t *blendgpatch, } secondi = firsti+1; // next color in line - if (secondi == 16) + if (secondi >= translen) { m = (INT16)brightness; // - 0; d = (INT16)colorbrightnesses[firsti]; // - 0; @@ -856,38 +890,57 @@ static void HWR_CreateBlendedTexture(GLPatch_t *gpatch, GLPatch_t *blendgpatch, // calculate the "gradient" multiplier based on how close this color is to the one next in line if (m <= 0 || d <= 0) + { mul = 0; + } else - mul = 15 - ((m * 16) / d); + { + mulmax = cutoff[firsti]; + if (secondi < translen) + mulmax -= cutoff[secondi]; + + mul = (mulmax-1) - ((m * mulmax) / d); + } } else { - // Thankfully, it's normally way more simple. - // Just convert brightness to a skincolor value, use remainder to find the gradient multipler - firsti = ((UINT8)(255-brightness) / 16); + // Just convert brightness to a skincolor value, use distance to next position to find the gradient multipler + firsti = 0; + + for (i = 1; i < translen; i++) + { + if (brightness >= cutoff[i]) + break; + firsti = i; + } + secondi = firsti+1; - mul = ((UINT8)(255-brightness) % 16); + + mulmax = cutoff[firsti]; + if (secondi < translen) + mulmax -= cutoff[secondi]; + + mul = cutoff[firsti] - brightness; } blendcolor = V_GetColor(translation[firsti]); - if (mul > 0 // If it's 0, then we only need the first color. - && translation[firsti] != translation[secondi]) // Some colors have duplicate colors in a row, so let's just save the process + if (mul > 0) // If it's 0, then we only need the first color. { - if (secondi == 16) // blend to black + if (secondi >= translen) // blend to black nextcolor = V_GetColor(31); else nextcolor = V_GetColor(translation[secondi]); // Find difference between points - r = (UINT32)(nextcolor.s.red - blendcolor.s.red); - g = (UINT32)(nextcolor.s.green - blendcolor.s.green); - b = (UINT32)(nextcolor.s.blue - blendcolor.s.blue); + r = (INT32)(nextcolor.s.red - blendcolor.s.red); + g = (INT32)(nextcolor.s.green - blendcolor.s.green); + b = (INT32)(nextcolor.s.blue - blendcolor.s.blue); // Find the gradient of the two points - r = ((mul * r) / 16); - g = ((mul * g) / 16); - b = ((mul * b) / 16); + r = ((mul * r) / mulmax); + g = ((mul * g) / mulmax); + b = ((mul * b) / mulmax); // Add gradient value to color blendcolor.s.red += r; From ac365a0c81204f756ad91a0b07e69748e8e70ac9 Mon Sep 17 00:00:00 2001 From: Sally Cochenour Date: Wed, 25 Dec 2019 20:09:31 -0500 Subject: [PATCH 658/746] Fake contrast --- src/hardware/hw_main.c | 66 +++++++++++++++++++++++++++++++++++------- src/hardware/hw_main.h | 1 + 2 files changed, 56 insertions(+), 11 deletions(-) diff --git a/src/hardware/hw_main.c b/src/hardware/hw_main.c index 2f986085a..9f6e497a6 100644 --- a/src/hardware/hw_main.c +++ b/src/hardware/hw_main.c @@ -1026,6 +1026,46 @@ static float HWR_ClipViewSegment(INT32 x, polyvertex_t *v1, polyvertex_t *v2) } #endif +static FUINT HWR_CalcWallLight(FUINT lightnum, fixed_t v1x, fixed_t v1y, fixed_t v2x, fixed_t v2y) +{ + INT16 finallight = lightnum; + + if (cv_grfakecontrast.value != 0) + { + const UINT8 contrast = 8; + fixed_t extralight = 0; + + if (cv_grfakecontrast.value == 2) // Smooth setting + { + extralight = -(contrast<>1)) >> FRACBITS; + } + else + { + if (v1y == v2y) + extralight = -contrast; + else if (v1x == v2x) + extralight = contrast; + } + + if (extralight != 0) + { + finallight += extralight; + + if (finallight < 0) + finallight = 0; + if (finallight > 255) + finallight = 255; + } + } + + return (FUINT)finallight; +} + // // HWR_SplitWall // @@ -1044,19 +1084,20 @@ static void HWR_SplitWall(sector_t *sector, wallVert3D *wallVerts, INT32 texnum, float endpegt, endpegb, endpegmul; float endheight = 0.0f, endbheight = 0.0f; - fixed_t v1x = FLOAT_TO_FIXED(wallVerts[0].x); - fixed_t v1y = FLOAT_TO_FIXED(wallVerts[0].z); // not a typo - fixed_t v2x = FLOAT_TO_FIXED(wallVerts[1].x); - fixed_t v2y = FLOAT_TO_FIXED(wallVerts[1].z); // not a typo // compiler complains when P_GetZAt is used in FLOAT_TO_FIXED directly // use this as a temp var to store P_GetZAt's return value each time fixed_t temp; #endif - INT32 solid, i; + fixed_t v1x = FLOAT_TO_FIXED(wallVerts[0].x); + fixed_t v1y = FLOAT_TO_FIXED(wallVerts[0].z); // not a typo + fixed_t v2x = FLOAT_TO_FIXED(wallVerts[1].x); + fixed_t v2y = FLOAT_TO_FIXED(wallVerts[1].z); // not a typo + + INT32 solid, i; lightlist_t * list = sector->lightlist; const UINT8 alpha = Surf->FlatColor.s.alpha; - FUINT lightnum = sector->lightlevel; + FUINT lightnum = HWR_CalcWallLight(sector->lightlevel, v1x, v1y, v2x, v2y); extracolormap_t *colormap = NULL; realtop = top = wallVerts[3].y; @@ -1086,12 +1127,12 @@ static void HWR_SplitWall(sector_t *sector, wallVert3D *wallVerts, INT32 texnum, { if (pfloor && (pfloor->flags & FF_FOG)) { - lightnum = pfloor->master->frontsector->lightlevel; + lightnum = HWR_CalcWallLight(pfloor->master->frontsector->lightlevel, v1x, v1y, v2x, v2y); colormap = pfloor->master->frontsector->extra_colormap; } else { - lightnum = *list[i].lightlevel; + lightnum = HWR_CalcWallLight(*list[i].lightlevel, v1x, v1y, v2x, v2y); colormap = *list[i].extra_colormap; } } @@ -1395,7 +1436,7 @@ static void HWR_StoreWallRange(double startfrac, double endfrac) cliphigh = (float)(texturehpeg + (gr_curline->flength*FRACUNIT)); } - lightnum = gr_frontsector->lightlevel; + lightnum = HWR_CalcWallLight(gr_frontsector->lightlevel, vs.x, vs.y, ve.x, ve.y); colormap = gr_frontsector->extra_colormap; if (gr_frontsector) @@ -2150,7 +2191,7 @@ static void HWR_StoreWallRange(double startfrac, double endfrac) blendmode = PF_Fog|PF_NoTexture; - lightnum = rover->master->frontsector->lightlevel; + lightnum = HWR_CalcWallLight(rover->master->frontsector->lightlevel, vs.x, vs.y, ve.x, ve.y); colormap = rover->master->frontsector->extra_colormap; if (rover->master->frontsector->extra_colormap) @@ -2270,7 +2311,7 @@ static void HWR_StoreWallRange(double startfrac, double endfrac) blendmode = PF_Fog|PF_NoTexture; - lightnum = rover->master->frontsector->lightlevel; + lightnum = HWR_CalcWallLight(rover->master->frontsector->lightlevel, vs.x, vs.y, ve.x, ve.y); colormap = rover->master->frontsector->extra_colormap; if (rover->master->frontsector->extra_colormap) @@ -6544,6 +6585,7 @@ static void HWR_FoggingOn(void) static CV_PossibleValue_t grsoftwarefog_cons_t[] = {{0, "Off"}, {1, "On"}, {2, "LightPlanes"}, {0, NULL}}; static CV_PossibleValue_t grmodelinterpolation_cons_t[] = {{0, "Off"}, {1, "Sometimes"}, {2, "Always"}, {0, NULL}}; +static CV_PossibleValue_t grfakecontrast_cons_t[] = {{0, "Off"}, {1, "On"}, {2, "Smooth"}, {0, NULL}}; static void CV_grmodellighting_OnChange(void); static void CV_grfiltermode_OnChange(void); @@ -6578,6 +6620,7 @@ consvar_t cv_grmodellighting = {"gr_modellighting", "Off", CV_SAVE|CV_CALL, CV_O consvar_t cv_grspritebillboarding = {"gr_spritebillboarding", "Off", CV_SAVE, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL}; consvar_t cv_grskydome = {"gr_skydome", "On", CV_SAVE, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL}; +consvar_t cv_grfakecontrast = {"gr_fakecontrast", "Smooth", CV_SAVE, grfakecontrast_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL}; consvar_t cv_grrounddown = {"gr_rounddown", "Off", 0, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL}; consvar_t cv_grfov = {"gr_fov", "90", CV_FLOAT|CV_CALL, grfov_cons_t, CV_grfov_OnChange, 0, NULL, NULL, 0, 0, NULL}; @@ -6646,6 +6689,7 @@ void HWR_AddCommands(void) CV_RegisterVar(&cv_grskydome); CV_RegisterVar(&cv_grspritebillboarding); + CV_RegisterVar(&cv_grfakecontrast); CV_RegisterVar(&cv_grfiltermode); CV_RegisterVar(&cv_grrounddown); diff --git a/src/hardware/hw_main.h b/src/hardware/hw_main.h index 573338226..20ff3ad9f 100644 --- a/src/hardware/hw_main.h +++ b/src/hardware/hw_main.h @@ -99,6 +99,7 @@ extern consvar_t cv_grfovchange; extern consvar_t cv_grsolvetjoin; extern consvar_t cv_grspritebillboarding; extern consvar_t cv_grskydome; +extern consvar_t cv_grfakecontrast; extern float gr_viewwidth, gr_viewheight, gr_baseviewwindowy; From 65a02b0f8f4179ab28ddfdcbc0361fd75830cde6 Mon Sep 17 00:00:00 2001 From: Sally Cochenour Date: Wed, 25 Dec 2019 22:50:41 -0500 Subject: [PATCH 659/746] Increase precision of smooth contrast (cherry picked from commit 4c6664292e1f9b0d5c2ff34e28f05a8b63a4dd45) --- src/hardware/hw_main.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/src/hardware/hw_main.c b/src/hardware/hw_main.c index 9f6e497a6..769aad5b7 100644 --- a/src/hardware/hw_main.c +++ b/src/hardware/hw_main.c @@ -1037,12 +1037,11 @@ static FUINT HWR_CalcWallLight(FUINT lightnum, fixed_t v1x, fixed_t v1y, fixed_t if (cv_grfakecontrast.value == 2) // Smooth setting { - extralight = -(contrast<>1)) >> FRACBITS; + * (contrast * 2)) >> FRACBITS; } else { From 15075d4e1be0ce830c7470bc8c0fd29df5d33753 Mon Sep 17 00:00:00 2001 From: Sally Cochenour Date: Sun, 29 Dec 2019 16:36:53 -0500 Subject: [PATCH 660/746] More blend image updates - Allow the translations that don't make use a blend image to work without requiring a blend image to be present - Fix TC_RAINBOW not working properly - TC_METALSONIC now remaps the _blend image to SKINCOLOR_COBALT, then inverts all of the blue, replicating how it works in Software (cherry picked from commit 74d7f256a7849d0c829177614b37089e2446f86b) --- src/hardware/hw_md2.c | 502 ++++++++++++++++++++++-------------------- 1 file changed, 260 insertions(+), 242 deletions(-) diff --git a/src/hardware/hw_md2.c b/src/hardware/hw_md2.c index 23145b525..099eaec4f 100644 --- a/src/hardware/hw_md2.c +++ b/src/hardware/hw_md2.c @@ -654,12 +654,12 @@ static void HWR_CreateBlendedTexture(GLPatch_t *gpatch, GLPatch_t *blendgpatch, UINT16 w = gpatch->width, h = gpatch->height; UINT32 size = w*h; RGBA_t *image, *blendimage, *cur, blendcolor; - UINT8 i; - UINT8 translation[16]; // First the color index UINT8 cutoff[16]; // Brightness cutoff before using the next color UINT8 translen = 0; + UINT8 i; + blendcolor = V_GetColor(0); // initialize memset(translation, 0, sizeof(translation)); memset(cutoff, 0, sizeof(cutoff)); @@ -685,7 +685,10 @@ static void HWR_CreateBlendedTexture(GLPatch_t *gpatch, GLPatch_t *blendgpatch, image = gpatch->mipmap->grInfo.data; blendimage = blendgpatch->mipmap->grInfo.data; - blendcolor = V_GetColor(0); // initialize + + // TC_METALSONIC includes an actual skincolor translation, on top of its flashing. + if (skinnum == TC_METALSONIC) + color = SKINCOLOR_COBALT; if (color != SKINCOLOR_NONE) { @@ -721,7 +724,7 @@ static void HWR_CreateBlendedTexture(GLPatch_t *gpatch, GLPatch_t *blendgpatch, if (skinnum == TC_BOSS) { // Turn everything below a certain threshold white - if ((image->s.red == image->s.green) && (image->s.green == image->s.blue) && image->s.blue <= 82) + if ((image->s.red == image->s.green) && (image->s.green == image->s.blue) && image->s.blue < 127) { // Lactozilla: Invert the colors cur->s.red = cur->s.green = cur->s.blue = (255 - image->s.blue); @@ -735,53 +738,6 @@ static void HWR_CreateBlendedTexture(GLPatch_t *gpatch, GLPatch_t *blendgpatch, cur->s.alpha = image->s.alpha; } - else if (skinnum == TC_METALSONIC) - { - // Turn everything below a certain blue threshold white - if (image->s.red == 0 && image->s.green == 0 && image->s.blue <= 82) - { - cur->s.red = cur->s.green = cur->s.blue = (255 - image->s.blue); - } - else - { - cur->s.red = image->s.red; - cur->s.green = image->s.green; - cur->s.blue = image->s.blue; - } - - cur->s.alpha = image->s.alpha; - } - else if (skinnum == TC_DASHMODE) - { - if (image->s.alpha == 0 && blendimage->s.alpha == 0) - { - // Don't bother with blending the pixel if the alpha of the blend pixel is 0 - cur->rgba = image->rgba; - } - else - { - UINT8 ialpha = 255 - blendimage->s.alpha, balpha = blendimage->s.alpha; - RGBA_t icolor = *image, bcolor; - - memset(&bcolor, 0x00, sizeof(RGBA_t)); - - if (blendimage->s.alpha) - { - bcolor.s.blue = 0; - bcolor.s.red = 255; - bcolor.s.green = (blendimage->s.red + blendimage->s.green + blendimage->s.blue) / 3; - } - if (image->s.alpha && image->s.red > image->s.green << 1) // this is pretty arbitrary, but it works well for Metal Sonic - { - icolor.s.red = image->s.blue; - icolor.s.blue = image->s.red; - } - cur->s.red = (ialpha * icolor.s.red + balpha * bcolor.s.red)/255; - cur->s.green = (ialpha * icolor.s.green + balpha * bcolor.s.green)/255; - cur->s.blue = (ialpha * icolor.s.blue + balpha * bcolor.s.blue)/255; - cur->s.alpha = image->s.alpha; - } - } else if (skinnum == TC_ALLWHITE) { // Turn everything white @@ -790,208 +746,268 @@ static void HWR_CreateBlendedTexture(GLPatch_t *gpatch, GLPatch_t *blendgpatch, } else { - UINT16 brightness; + // Everything below requires a blend image + if (blendimage == NULL) + { + cur->rgba = image->rgba; + goto skippixel; + } - I_Assert(translen > 0); - - // Don't bother with blending the pixel if the alpha of the blend pixel is 0 - if (skinnum == TC_RAINBOW) + // Metal Sonic dash mode + if (skinnum == TC_DASHMODE) { if (image->s.alpha == 0 && blendimage->s.alpha == 0) { + // Don't bother with blending the pixel if the alpha of the blend pixel is 0 cur->rgba = image->rgba; - cur++; image++; blendimage++; - continue; } else { - UINT16 imagebright, blendbright; - SETBRIGHTNESS(imagebright,image->s.red,image->s.green,image->s.blue); - SETBRIGHTNESS(blendbright,blendimage->s.red,blendimage->s.green,blendimage->s.blue); - // slightly dumb average between the blend image color and base image colour, usually one or the other will be fully opaque anyway - brightness = (imagebright*(255-blendimage->s.alpha))/255 + (blendbright*blendimage->s.alpha)/255; + UINT8 ialpha = 255 - blendimage->s.alpha, balpha = blendimage->s.alpha; + RGBA_t icolor = *image, bcolor; + + memset(&bcolor, 0x00, sizeof(RGBA_t)); + + if (blendimage->s.alpha) + { + bcolor.s.blue = 0; + bcolor.s.red = 255; + bcolor.s.green = (blendimage->s.red + blendimage->s.green + blendimage->s.blue) / 3; + } + + if (image->s.alpha && image->s.red > image->s.green << 1) // this is pretty arbitrary, but it works well for Metal Sonic + { + icolor.s.red = image->s.blue; + icolor.s.blue = image->s.red; + } + + cur->s.red = (ialpha * icolor.s.red + balpha * bcolor.s.red)/255; + cur->s.green = (ialpha * icolor.s.green + balpha * bcolor.s.green)/255; + cur->s.blue = (ialpha * icolor.s.blue + balpha * bcolor.s.blue)/255; + cur->s.alpha = image->s.alpha; } } else { - if (blendimage->s.alpha == 0) + // All settings that use skincolors! + UINT16 brightness; + + if (translen <= 0) { cur->rgba = image->rgba; - cur++; image++; blendimage++; - continue; + goto skippixel; + } + + // Don't bother with blending the pixel if the alpha of the blend pixel is 0 + if (skinnum == TC_RAINBOW) + { + if (image->s.alpha == 0 && blendimage->s.alpha == 0) + { + cur->rgba = image->rgba; + goto skippixel; + } + else + { + UINT16 imagebright, blendbright; + SETBRIGHTNESS(imagebright,image->s.red,image->s.green,image->s.blue); + SETBRIGHTNESS(blendbright,blendimage->s.red,blendimage->s.green,blendimage->s.blue); + // slightly dumb average between the blend image color and base image colour, usually one or the other will be fully opaque anyway + brightness = (imagebright*(255-blendimage->s.alpha))/255 + (blendbright*blendimage->s.alpha)/255; + } } else { - SETBRIGHTNESS(brightness,blendimage->s.red,blendimage->s.green,blendimage->s.blue); - } - } - - // Calculate a sort of "gradient" for the skincolor - // (Me splitting this into a function didn't work, so I had to ruin this entire function's groove...) - { - RGBA_t nextcolor; - UINT8 firsti, secondi, mul, mulmax; - INT32 r, g, b; - - // Rainbow needs to find the closest match to the textures themselves, instead of matching brightnesses to other colors. - // Ensue horrible mess. - if (skinnum == TC_RAINBOW) - { - UINT16 brightdif = 256; - UINT8 colorbrightnesses[16]; - INT32 compare, m, d; - - // Ignore pure white & pitch black - if (brightness > 253 || brightness < 2) + if (blendimage->s.alpha == 0) { cur->rgba = image->rgba; - cur++; image++; blendimage++; - continue; + goto skippixel; // for metal sonic blend } - - firsti = 0; - mul = 0; - mulmax = 1; - - for (i = 0; i < translen; i++) + else { - RGBA_t tempc = V_GetColor(translation[i]); - SETBRIGHTNESS(colorbrightnesses[i], tempc.s.red, tempc.s.green, tempc.s.blue); // store brightnesses for comparison + SETBRIGHTNESS(brightness,blendimage->s.red,blendimage->s.green,blendimage->s.blue); } + } - for (i = 0; i < translen; i++) + // Calculate a sort of "gradient" for the skincolor + // (Me splitting this into a function didn't work, so I had to ruin this entire function's groove...) + { + RGBA_t nextcolor; + UINT8 firsti, secondi, mul, mulmax; + INT32 r, g, b; + + // Rainbow needs to find the closest match to the textures themselves, instead of matching brightnesses to other colors. + // Ensue horrible mess. + if (skinnum == TC_RAINBOW) { - if (brightness > colorbrightnesses[i]) // don't allow greater matches (because calculating a makeshift gradient for this is already a huge mess as is) - continue; + UINT16 brightdif = 256; + UINT8 colorbrightnesses[16]; + INT32 compare, m, d; - compare = abs((INT16)(colorbrightnesses[i]) - (INT16)(brightness)); - - if (compare < brightdif) + // Ignore pure white & pitch black + if (brightness > 253 || brightness < 2) { - brightdif = (UINT16)compare; - firsti = i; // best matching color that's equal brightness or darker + cur->rgba = image->rgba; + cur++; image++; blendimage++; + continue; } - } - secondi = firsti+1; // next color in line - if (secondi >= translen) - { - m = (INT16)brightness; // - 0; - d = (INT16)colorbrightnesses[firsti]; // - 0; - } - else - { - m = (INT16)brightness - (INT16)colorbrightnesses[secondi]; - d = (INT16)colorbrightnesses[firsti] - (INT16)colorbrightnesses[secondi]; - } - - if (m >= d) - m = d-1; - - // calculate the "gradient" multiplier based on how close this color is to the one next in line - if (m <= 0 || d <= 0) - { + firsti = 0; mul = 0; + mulmax = 1; + + for (i = 0; i < translen; i++) + { + RGBA_t tempc = V_GetColor(translation[i]); + SETBRIGHTNESS(colorbrightnesses[i], tempc.s.red, tempc.s.green, tempc.s.blue); // store brightnesses for comparison + } + + for (i = 0; i < translen; i++) + { + if (brightness > colorbrightnesses[i]) // don't allow greater matches (because calculating a makeshift gradient for this is already a huge mess as is) + continue; + + compare = abs((INT16)(colorbrightnesses[i]) - (INT16)(brightness)); + + if (compare < brightdif) + { + brightdif = (UINT16)compare; + firsti = i; // best matching color that's equal brightness or darker + } + } + + secondi = firsti+1; // next color in line + if (secondi >= translen) + { + m = (INT16)brightness; // - 0; + d = (INT16)colorbrightnesses[firsti]; // - 0; + } + else + { + m = (INT16)brightness - (INT16)colorbrightnesses[secondi]; + d = (INT16)colorbrightnesses[firsti] - (INT16)colorbrightnesses[secondi]; + } + + if (m >= d) + m = d-1; + + mulmax = 16; + + // calculate the "gradient" multiplier based on how close this color is to the one next in line + if (m <= 0 || d <= 0) + mul = 0; + else + mul = (mulmax-1) - ((m * mulmax) / d); } else { + // Just convert brightness to a skincolor value, use distance to next position to find the gradient multipler + firsti = 0; + + for (i = 1; i < translen; i++) + { + if (brightness >= cutoff[i]) + break; + firsti = i; + } + + secondi = firsti+1; + mulmax = cutoff[firsti]; if (secondi < translen) mulmax -= cutoff[secondi]; - mul = (mulmax-1) - ((m * mulmax) / d); + mul = cutoff[firsti] - brightness; } + + blendcolor = V_GetColor(translation[firsti]); + + if (mul > 0) // If it's 0, then we only need the first color. + { + if (secondi >= translen) // blend to black + nextcolor = V_GetColor(31); + else + nextcolor = V_GetColor(translation[secondi]); + + // Find difference between points + r = (INT32)(nextcolor.s.red - blendcolor.s.red); + g = (INT32)(nextcolor.s.green - blendcolor.s.green); + b = (INT32)(nextcolor.s.blue - blendcolor.s.blue); + + // Find the gradient of the two points + r = ((mul * r) / mulmax); + g = ((mul * g) / mulmax); + b = ((mul * b) / mulmax); + + // Add gradient value to color + blendcolor.s.red += r; + blendcolor.s.green += g; + blendcolor.s.blue += b; + } + } + + if (skinnum == TC_RAINBOW) + { + UINT32 tempcolor; + UINT16 colorbright; + + SETBRIGHTNESS(colorbright,blendcolor.s.red,blendcolor.s.green,blendcolor.s.blue); + if (colorbright == 0) + colorbright = 1; // no dividing by 0 please + + tempcolor = (brightness * blendcolor.s.red) / colorbright; + tempcolor = min(255, tempcolor); + cur->s.red = (UINT8)tempcolor; + + tempcolor = (brightness * blendcolor.s.green) / colorbright; + tempcolor = min(255, tempcolor); + cur->s.green = (UINT8)tempcolor; + + tempcolor = (brightness * blendcolor.s.blue) / colorbright; + tempcolor = min(255, tempcolor); + cur->s.blue = (UINT8)tempcolor; + cur->s.alpha = image->s.alpha; } else { - // Just convert brightness to a skincolor value, use distance to next position to find the gradient multipler - firsti = 0; + // Color strength depends on image alpha + INT32 tempcolor; - for (i = 1; i < translen; i++) + tempcolor = ((image->s.red * (255-blendimage->s.alpha)) / 255) + ((blendcolor.s.red * blendimage->s.alpha) / 255); + tempcolor = min(255, tempcolor); + cur->s.red = (UINT8)tempcolor; + + tempcolor = ((image->s.green * (255-blendimage->s.alpha)) / 255) + ((blendcolor.s.green * blendimage->s.alpha) / 255); + tempcolor = min(255, tempcolor); + cur->s.green = (UINT8)tempcolor; + + tempcolor = ((image->s.blue * (255-blendimage->s.alpha)) / 255) + ((blendcolor.s.blue * blendimage->s.alpha) / 255); + tempcolor = min(255, tempcolor); + cur->s.blue = (UINT8)tempcolor; + cur->s.alpha = image->s.alpha; + } + +skippixel: + + // *Now* we can do Metal Sonic's flashing + if (skinnum == TC_METALSONIC) + { + // Blend dark blue into white + if (cur->s.alpha > 0 && cur->s.red == 0 && cur->s.green == 0 && cur->s.blue < 255 && cur->s.blue > 31) { - if (brightness >= cutoff[i]) - break; - firsti = i; + // Sal: Invert non-blue + cur->s.red = cur->s.green = (255 - cur->s.blue); + cur->s.blue = 255; } - secondi = firsti+1; - - mulmax = cutoff[firsti]; - if (secondi < translen) - mulmax -= cutoff[secondi]; - - mul = cutoff[firsti] - brightness; + cur->s.alpha = image->s.alpha; } - - blendcolor = V_GetColor(translation[firsti]); - - if (mul > 0) // If it's 0, then we only need the first color. - { - if (secondi >= translen) // blend to black - nextcolor = V_GetColor(31); - else - nextcolor = V_GetColor(translation[secondi]); - - // Find difference between points - r = (INT32)(nextcolor.s.red - blendcolor.s.red); - g = (INT32)(nextcolor.s.green - blendcolor.s.green); - b = (INT32)(nextcolor.s.blue - blendcolor.s.blue); - - // Find the gradient of the two points - r = ((mul * r) / mulmax); - g = ((mul * g) / mulmax); - b = ((mul * b) / mulmax); - - // Add gradient value to color - blendcolor.s.red += r; - blendcolor.s.green += g; - blendcolor.s.blue += b; - } - } - - if (skinnum == TC_RAINBOW) - { - UINT32 tempcolor; - UINT16 colorbright; - - SETBRIGHTNESS(colorbright,blendcolor.s.red,blendcolor.s.green,blendcolor.s.blue); - if (colorbright == 0) - colorbright = 1; // no dividing by 0 please - - tempcolor = (brightness * blendcolor.s.red) / colorbright; - tempcolor = min(255, tempcolor); - cur->s.red = (UINT8)tempcolor; - - tempcolor = (brightness * blendcolor.s.green) / colorbright; - tempcolor = min(255, tempcolor); - cur->s.green = (UINT8)tempcolor; - - tempcolor = (brightness * blendcolor.s.blue) / colorbright; - tempcolor = min(255, tempcolor); - cur->s.blue = (UINT8)tempcolor; - cur->s.alpha = image->s.alpha; - } - else - { - // Color strength depends on image alpha - INT32 tempcolor; - - tempcolor = ((image->s.red * (255-blendimage->s.alpha)) / 255) + ((blendcolor.s.red * blendimage->s.alpha) / 255); - tempcolor = min(255, tempcolor); - cur->s.red = (UINT8)tempcolor; - - tempcolor = ((image->s.green * (255-blendimage->s.alpha)) / 255) + ((blendcolor.s.green * blendimage->s.alpha) / 255); - tempcolor = min(255, tempcolor); - cur->s.green = (UINT8)tempcolor; - - tempcolor = ((image->s.blue * (255-blendimage->s.alpha)) / 255) + ((blendcolor.s.blue * blendimage->s.alpha) / 255); - tempcolor = min(255, tempcolor); - cur->s.blue = (UINT8)tempcolor; - cur->s.alpha = image->s.alpha; } } - cur++; image++; blendimage++; + cur++; image++; + + if (blendimage != NULL) + blendimage++; } return; @@ -1030,6 +1046,14 @@ static void HWR_GetBlendedTexture(GLPatch_t *gpatch, GLPatch_t *blendgpatch, INT // If here, the blended texture has not been created // So we create it + if ((blendgpatch && blendgpatch->mipmap->grInfo.format) + && (gpatch->width != blendgpatch->width || gpatch->height != blendgpatch->height)) + { + // Blend image exists, but it's bad. + HWD.pfnSetTexture(gpatch->mipmap); + return; + } + //BP: WARNING: don't free it manually without clearing the cache of harware renderer // (it have a liste of mipmap) // this malloc is cleared in HWR_FreeTextureCache @@ -1273,50 +1297,44 @@ boolean HWR_DrawModel(gr_vissprite_t *spr) if (gpatch && gpatch->mipmap->grInfo.format) // else if meant that if a texture couldn't be loaded, it would just end up using something else's texture { - if (md2->blendgrpatch && ((GLPatch_t *)md2->blendgrpatch)->mipmap->grInfo.format - && gpatch->width == ((GLPatch_t *)md2->blendgrpatch)->width && gpatch->height == ((GLPatch_t *)md2->blendgrpatch)->height) - { - INT32 skinnum = INT32_MAX; - if ((spr->mobj->flags & (MF_ENEMY|MF_BOSS)) && (spr->mobj->flags2 & MF2_FRET) && !(spr->mobj->flags & MF_GRENADEBOUNCE) && (leveltime & 1)) // Bosses "flash" - { - if (spr->mobj->type == MT_CYBRAKDEMON || spr->mobj->colorized) - skinnum = TC_ALLWHITE; - else if (spr->mobj->type == MT_METALSONIC_BATTLE) - skinnum = TC_METALSONIC; - else - skinnum = TC_BOSS; - } - else if ((skincolors_t)spr->mobj->color != SKINCOLOR_NONE) - { - if (spr->mobj->colorized) - skinnum = TC_RAINBOW; - else if (spr->mobj->player && spr->mobj->player->dashmode >= DASHMODE_THRESHOLD - && (spr->mobj->player->charflags & SF_DASHMODE) - && ((leveltime/2) & 1)) - { - if (spr->mobj->player->charflags & SF_MACHINE) - skinnum = TC_DASHMODE; - else - skinnum = TC_RAINBOW; - } - else if (spr->mobj->skin && spr->mobj->sprite == SPR_PLAY) - skinnum = (INT32)((skin_t*)spr->mobj->skin-skins); - else - skinnum = TC_DEFAULT; - } + INT32 skinnum = INT32_MAX; - // Translation or skin number found - if (skinnum != INT32_MAX) - HWR_GetBlendedTexture(gpatch, (GLPatch_t *)md2->blendgrpatch, skinnum, spr->colormap, (skincolors_t)spr->mobj->color); + if ((spr->mobj->flags & (MF_ENEMY|MF_BOSS)) && (spr->mobj->flags2 & MF2_FRET) && !(spr->mobj->flags & MF_GRENADEBOUNCE) && (leveltime & 1)) // Bosses "flash" + { + if (spr->mobj->type == MT_CYBRAKDEMON || spr->mobj->colorized) + skinnum = TC_ALLWHITE; + else if (spr->mobj->type == MT_METALSONIC_BATTLE) + skinnum = TC_METALSONIC; else + skinnum = TC_BOSS; + } + else if ((skincolors_t)spr->mobj->color != SKINCOLOR_NONE) + { + if (spr->mobj->colorized) + skinnum = TC_RAINBOW; + else if (spr->mobj->player && spr->mobj->player->dashmode >= DASHMODE_THRESHOLD + && (spr->mobj->player->charflags & SF_DASHMODE) + && ((leveltime/2) & 1)) { - // Sorry nothing - HWD.pfnSetTexture(gpatch->mipmap); + if (spr->mobj->player->charflags & SF_MACHINE) + skinnum = TC_DASHMODE; + else + skinnum = TC_RAINBOW; } + else if (spr->mobj->skin && spr->mobj->sprite == SPR_PLAY) + skinnum = (INT32)((skin_t*)spr->mobj->skin-skins); + else + skinnum = TC_DEFAULT; + } + + // Translation or skin number found + if (skinnum != INT32_MAX) + { + HWR_GetBlendedTexture(gpatch, (GLPatch_t *)md2->blendgrpatch, skinnum, spr->colormap, (skincolors_t)spr->mobj->color); } else { - // This is safe, since we know the texture has been downloaded + // Sorry nothing HWD.pfnSetTexture(gpatch->mipmap); } } From d49cd9755bdb11b7037a3fe906c322df22225180 Mon Sep 17 00:00:00 2001 From: Sally Cochenour Date: Wed, 8 Jan 2020 04:10:23 -0500 Subject: [PATCH 661/746] Fullbright transparent planes (I disagree with this feature so hard but w/e) (cherry picked from commit fe809b2734d430655966151e56f96963e2d7b2cf) --- src/hardware/hw_main.c | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/src/hardware/hw_main.c b/src/hardware/hw_main.c index 769aad5b7..50b6fcbf5 100644 --- a/src/hardware/hw_main.c +++ b/src/hardware/hw_main.c @@ -5158,7 +5158,12 @@ void HWR_AddTransparentFloor(levelflat_t *levelflat, extrasubsector_t *xsub, boo planeinfo[numplanes].isceiling = isceiling; planeinfo[numplanes].fixedheight = fixedheight; - planeinfo[numplanes].lightlevel = lightlevel; + + if (planecolormap && (planecolormap->fog & 1)) + planeinfo[numplanes].lightlevel = lightlevel; + else + planeinfo[numplanes].lightlevel = 255; + planeinfo[numplanes].levelflat = levelflat; planeinfo[numplanes].xsub = xsub; planeinfo[numplanes].alpha = alpha; @@ -5190,7 +5195,12 @@ void HWR_AddTransparentPolyobjectFloor(levelflat_t *levelflat, polyobj_t *polyse polyplaneinfo[numpolyplanes].isceiling = isceiling; polyplaneinfo[numpolyplanes].fixedheight = fixedheight; - polyplaneinfo[numpolyplanes].lightlevel = lightlevel; + + if (planecolormap && (planecolormap->fog & 1)) + polyplaneinfo[numpolyplanes].lightlevel = lightlevel; + else + polyplaneinfo[numpolyplanes].lightlevel = 255; + polyplaneinfo[numpolyplanes].levelflat = levelflat; polyplaneinfo[numpolyplanes].polysector = polysector; polyplaneinfo[numpolyplanes].alpha = alpha; From 0b1108425d4a95815eaf6bf0fdf2c9aaa10b8683 Mon Sep 17 00:00:00 2001 From: toaster Date: Wed, 8 Jan 2020 20:49:14 +0000 Subject: [PATCH 662/746] Hexafaceted sprite angle support (See merge request description coming soon). Also, some minor memory efficiency fixes to both rotsprite and ordinary sprite rotations. --- src/hardware/hw_main.c | 23 ++++----- src/lua_hudlib.c | 8 ++-- src/r_data.c | 27 ++++++++--- src/r_defs.h | 26 ++++++----- src/r_patch.c | 10 ++-- src/r_things.c | 104 +++++++++++++++++++++++++---------------- src/r_things.h | 27 ++++++++--- 7 files changed, 136 insertions(+), 89 deletions(-) diff --git a/src/hardware/hw_main.c b/src/hardware/hw_main.c index 2f986085a..80ca623ca 100644 --- a/src/hardware/hw_main.c +++ b/src/hardware/hw_main.c @@ -5493,7 +5493,7 @@ static void HWR_ProjectSprite(mobj_t *thing) spriteinfo_t *sprinfo; size_t lumpoff; unsigned rot; - UINT8 flip; + UINT16 flip; boolean vflip = (!(thing->eflags & MFE_VERTICALFLIP) != !(thing->frame & FF_VERTICALFLIP)); angle_t ang; @@ -5579,12 +5579,7 @@ static void HWR_ProjectSprite(mobj_t *thing) flip = sprframe->flip; // Will only be 0x00 or 0xFF if (papersprite && ang < ANGLE_180) - { - if (flip) - flip = 0; - else - flip = 255; - } + flip ^= 0xFFFF; } else { @@ -5593,6 +5588,11 @@ static void HWR_ProjectSprite(mobj_t *thing) rot = 6; // F7 slot else if ((sprframe->rotate & SRF_LEFT) && (ang >= ANGLE_180)) // See from left rot = 2; // F3 slot + else if (sprframe->rotate & SRF_3DGE) // 16-angle mode + { + rot = (ang+ANGLE_180+ANGLE_11hh)>>28; + rot = ((rot & 1)<<3)|(rot>>1); + } else // Normal behaviour rot = (ang+ANGLE_202h)>>29; @@ -5601,12 +5601,7 @@ static void HWR_ProjectSprite(mobj_t *thing) flip = sprframe->flip & (1<skin && ((skin_t *)thing->skin)->flags & SF_HIRES) @@ -5621,7 +5616,7 @@ static void HWR_ProjectSprite(mobj_t *thing) if (thing->rollangle) { rollangle = R_GetRollAngle(thing->rollangle); - if (!sprframe->rotsprite.cached[rot]) + if (!(sprframe->rotsprite.cached & (1<sprite, (thing->frame & FF_FRAMEMASK), sprinfo, sprframe, rot, flip); rotsprite = sprframe->rotsprite.patch[rot][rollangle]; if (rotsprite != NULL) diff --git a/src/lua_hudlib.c b/src/lua_hudlib.c index 58af64359..f451944e3 100644 --- a/src/lua_hudlib.c +++ b/src/lua_hudlib.c @@ -468,11 +468,11 @@ static int libd_getSpritePatch(lua_State *L) // convert WAD editor angle numbers (1-8) to internal angle numbers (0-7) // keep 0 the same since we'll make it default to angle 1 (which is internally 0) - // in case somebody didn't know that angle 0 really just maps all 8 angles to the same patch + // in case somebody didn't know that angle 0 really just maps all 8/16 angles to the same patch if (angle != 0) angle--; - if (angle >= 8) // out of range? + if (angle >= ((sprframe->rotate & SRF_3DGE) ? 16 : 8)) // out of range? return 0; // push both the patch and it's "flip" value @@ -563,11 +563,11 @@ static int libd_getSprite2Patch(lua_State *L) // convert WAD editor angle numbers (1-8) to internal angle numbers (0-7) // keep 0 the same since we'll make it default to angle 1 (which is internally 0) - // in case somebody didn't know that angle 0 really just maps all 8 angles to the same patch + // in case somebody didn't know that angle 0 really just maps all 8/16 angles to the same patch if (angle != 0) angle--; - if (angle >= 8) // out of range? + if (angle >= ((sprframe->rotate & SRF_3DGE) ? 16 : 8)) // out of range? return 0; // push both the patch and it's "flip" value diff --git a/src/r_data.c b/src/r_data.c index 986b65dea..26fc0043c 100644 --- a/src/r_data.c +++ b/src/r_data.c @@ -2710,14 +2710,29 @@ void R_PrecacheLevel(void) for (j = 0; j < sprites[i].numframes; j++) { sf = &sprites[i].spriteframes[j]; - for (k = 0; k < 8; k++) +#define cacheang(a) {\ + lump = sf->lumppat[a];\ + if (devparm)\ + spritememory += W_LumpLength(lump);\ + W_CachePatchNum(lump, PU_PATCH);\ + } + // see R_InitSprites for more about lumppat,lumpid + switch (sf->rotate) { - // see R_InitSprites for more about lumppat,lumpid - lump = sf->lumppat[k]; - if (devparm) - spritememory += W_LumpLength(lump); - W_CachePatchNum(lump, PU_PATCH); + case SRF_SINGLE: + cacheang(0); + break; + case SRF_2D: + cacheang(2); + cacheang(6); + break; + default: + k = (sf->rotate & SRF_3DGE ? 16 : 8); + while (k--) + cacheang(k); + break; } +#undef cacheang } } free(spritepresent); diff --git a/src/r_defs.h b/src/r_defs.h index c7c198d66..a841bca08 100644 --- a/src/r_defs.h +++ b/src/r_defs.h @@ -727,10 +727,10 @@ typedef struct #ifdef ROTSPRITE typedef struct { - patch_t *patch[8][ROTANGLES]; - boolean cached[8]; + patch_t *patch[16][ROTANGLES]; + UINT16 cached; #ifdef HWRENDER - aatree_t *hardware_patch[8]; + aatree_t *hardware_patch[16]; #endif/*HWRENDER*/ } rotsprite_t; #endif/*ROTSPRITE*/ @@ -739,9 +739,11 @@ typedef enum { SRF_SINGLE = 0, // 0-angle for all rotations SRF_3D = 1, // Angles 1-8 - SRF_LEFT = 2, // Left side uses single patch - SRF_RIGHT = 4, // Right side uses single patch - SRF_2D = SRF_LEFT|SRF_RIGHT, // 6 + SRF_3DGE = 2, // 3DGE, ZDoom and Doom Legacy all have 16-angle support. Why not us? + SRF_3DMASK = SRF_3D|SRF_3DGE, // 3 + SRF_LEFT = 4, // Left side uses single patch + SRF_RIGHT = 8, // Right side uses single patch + SRF_2D = SRF_LEFT|SRF_RIGHT, // 12 SRF_NONE = 0xff // Initial value } spriterotateflags_t; // SRF's up! @@ -767,7 +769,7 @@ typedef struct patchinfo_s patchinfo_t; // Sprites are patches with a special naming convention so they can be // recognized by R_InitSprites. // The base name is NNNNFx or NNNNFxFx, with x indicating the rotation, -// x = 0, 1-8, L/R +// x = 0, 1-8, 9+A-G, L/R // The sprite and frame specified by a thing_t is range checked at run time. // A sprite is a patch_t that is assumed to represent a three dimensional // object and may have multiple rotations predrawn. @@ -784,12 +786,12 @@ typedef struct // name eight times. UINT8 rotate; // see spriterotateflags_t above - // Lump to use for view angles 0-7. - lumpnum_t lumppat[8]; // lump number 16 : 16 wad : lump - size_t lumpid[8]; // id in the spriteoffset, spritewidth, etc. tables + // Lump to use for view angles 0-7/15. + lumpnum_t lumppat[16]; // lump number 16 : 16 wad : lump + size_t lumpid[16]; // id in the spriteoffset, spritewidth, etc. tables - // Flip bits (1 = flip) to use for view angles 0-7. - UINT8 flip; + // Flip bits (1 = flip) to use for view angles 0-7/15. + UINT16 flip; #ifdef ROTSPRITE rotsprite_t rotsprite; diff --git a/src/r_patch.c b/src/r_patch.c index fbb64e362..7fb764d22 100644 --- a/src/r_patch.c +++ b/src/r_patch.c @@ -1159,7 +1159,7 @@ void R_CacheRotSprite(spritenum_t sprnum, UINT8 frame, spriteinfo_t *sprinfo, sp #define ROTSPRITE_XCENTER (newwidth / 2) #define ROTSPRITE_YCENTER (newheight / 2) - if (!sprframe->rotsprite.cached[rot]) + if (!(sprframe->rotsprite.cached & (1<rotsprite.cached[rot] = true; + sprframe->rotsprite.cached |= (1<numframes; frame++) { spriteframe_t *sprframe = &spritedef->spriteframes[frame]; - for (rot = 0; rot < 8; rot++) + for (rot = 0; rot < 16; rot++) { - if (sprframe->rotsprite.cached[rot]) + if (sprframe->rotsprite.cached & (1<rotsprite.cached[rot] = false; + sprframe->rotsprite.cached &= ~(1<= 64 || !(R_ValidSpriteAngle(rotation))) - I_Error("R_InstallSpriteLump: Bad frame characters in lump %s", W_CheckNameForNum(lumppat)); - if (maxframe ==(size_t)-1 || frame > maxframe) maxframe = frame; // rotsprite #ifdef ROTSPRITE - for (r = 0; r < 8; r++) + sprtemp[frame].rotsprite.cached = 0; + for (r = 0; r < 16; r++) { - sprtemp[frame].rotsprite.cached[r] = false; for (ang = 0; ang < ROTANGLES; ang++) sprtemp[frame].rotsprite.patch[r][ang] = NULL; #ifdef HWRENDER @@ -136,16 +133,16 @@ static void R_InstallSpriteLump(UINT16 wad, // graphics patch // the lump should be used for all rotations if (sprtemp[frame].rotate == SRF_SINGLE) CONS_Debug(DBG_SETUP, "R_InitSprites: Sprite %s frame %c has multiple rot = 0 lump\n", spritename, cn); - else if (sprtemp[frame].rotate != SRF_NONE) // Let's bundle 1-8 and L/R rotations into one debug message. + else if (sprtemp[frame].rotate != SRF_NONE) // Let's bundle 1-8/16 and L/R rotations into one debug message. CONS_Debug(DBG_SETUP, "R_InitSprites: Sprite %s frame %c has rotations and a rot = 0 lump\n", spritename, cn); sprtemp[frame].rotate = SRF_SINGLE; - for (r = 0; r < 8; r++) + for (r = 0; r < 16; r++) { sprtemp[frame].lumppat[r] = lumppat; sprtemp[frame].lumpid[r] = lumpid; } - sprtemp[frame].flip = flipped ? 0xFF : 0; // 11111111 in binary + sprtemp[frame].flip = flipped ? 0xFFFF : 0; // 1111111111111111 in binary return; } @@ -154,54 +151,67 @@ static void R_InstallSpriteLump(UINT16 wad, // graphics patch UINT8 rightfactor = ((rotation == ROT_R) ? 4 : 0); // the lump should be used for half of all rotations - if (sprtemp[frame].rotate == SRF_SINGLE) + if (sprtemp[frame].rotate == SRF_NONE) + sprtemp[frame].rotate = SRF_SINGLE; + else if (sprtemp[frame].rotate == SRF_SINGLE) CONS_Debug(DBG_SETUP, "R_InitSprites: Sprite %s frame %c has L/R rotations and a rot = 0 lump\n", spritename, cn); else if (sprtemp[frame].rotate == SRF_3D) CONS_Debug(DBG_SETUP, "R_InitSprites: Sprite %s frame %c has both L/R and 1-8 rotations\n", spritename, cn); + else if (sprtemp[frame].rotate == SRF_3DGE) + CONS_Debug(DBG_SETUP, "R_InitSprites: Sprite %s frame %c has both L/R and 1-G rotations\n", spritename, cn); else if ((sprtemp[frame].rotate & SRF_LEFT) && (rotation == ROT_L)) CONS_Debug(DBG_SETUP, "R_InitSprites: Sprite %s frame %c has multiple L rotations\n", spritename, cn); else if ((sprtemp[frame].rotate & SRF_RIGHT) && (rotation == ROT_R)) CONS_Debug(DBG_SETUP, "R_InitSprites: Sprite %s frame %c has multiple R rotations\n", spritename, cn); - if (sprtemp[frame].rotate == SRF_NONE) - sprtemp[frame].rotate = SRF_SINGLE; - sprtemp[frame].rotate |= ((rotation == ROT_R) ? SRF_RIGHT : SRF_LEFT); - if (sprtemp[frame].rotate == (SRF_3D|SRF_2D)) - sprtemp[frame].rotate = SRF_2D; // SRF_3D|SRF_2D being enabled at the same time doesn't HURT in the current sprite angle implementation, but it DOES mean more to check in some of the helper functions. Let's not allow this scenario to happen. + if ((sprtemp[frame].rotate & SRF_2D) == SRF_2D) + sprtemp[frame].rotate &= ~SRF_3DMASK; // SRF_3D|SRF_2D being enabled at the same time doesn't HURT in the current sprite angle implementation, but it DOES mean more to check in some of the helper functions. Let's not allow this scenario to happen. - for (r = 0; r < 4; r++) // Thanks to R_PrecacheLevel, we can't leave sprtemp[*].lumppat[*] == LUMPERROR... so we load into the front/back angle too. + // load into every relevant angle, including the front one + for (r = 0; r < 4; r++) { sprtemp[frame].lumppat[r + rightfactor] = lumppat; sprtemp[frame].lumpid[r + rightfactor] = lumpid; + sprtemp[frame].lumppat[r + rightfactor + 8] = lumppat; + sprtemp[frame].lumpid[r + rightfactor + 8] = lumpid; + } if (flipped) - sprtemp[frame].flip |= (0x0F< 3) // Right side - sprtemp[frame].rotate = (SRF_3D | (sprtemp[frame].rotate & SRF_LEFT)); // Continue allowing L frame changeover - else // if (rotation <= 3) // Left side - sprtemp[frame].rotate = (SRF_3D | (sprtemp[frame].rotate & SRF_RIGHT)); // Continue allowing R frame changeover + { + // SRF_3D|SRF_3DGE being enabled at the same time doesn't HURT in the current sprite angle implementation, but it DOES mean more to check in some of the helper functions. Let's not allow this scenario to happen. + UINT8 threedrot = (rotation > 7) ? SRF_3DGE : (sprtemp[frame].rotate & SRF_3DMASK); + if (!threedrot) + threedrot = SRF_3D; + + if (rotation == 0 || rotation == 4) // Front or back... + sprtemp[frame].rotate = threedrot; // Prevent L and R changeover + else if ((rotation & 7) > 3) // Right side + sprtemp[frame].rotate = (threedrot | (sprtemp[frame].rotate & SRF_LEFT)); // Continue allowing L frame changeover + else // if ((rotation & 7) <= 3) // Left side + sprtemp[frame].rotate = (threedrot | (sprtemp[frame].rotate & SRF_RIGHT)); // Continue allowing R frame changeover + } if (sprtemp[frame].lumppat[rotation] != LUMPERROR) - CONS_Debug(DBG_SETUP, "R_InitSprites: Sprite %s: %c%c has two lumps mapped to it\n", spritename, cn, '1'+rotation); + CONS_Debug(DBG_SETUP, "R_InitSprites: Sprite %s: %c%c has two lumps mapped to it\n", spritename, cn, cr); // lumppat & lumpid are the same for original Doom, but different // when using sprites in pwad : the lumppat points the new graphics @@ -262,9 +272,9 @@ static boolean R_AddSingleSpriteDef(const char *sprname, spritedef_t *spritedef, if (memcmp(lumpinfo[l].name,sprname,4)==0) { frame = R_Char2Frame(lumpinfo[l].name[4]); - rotation = (UINT8)(lumpinfo[l].name[5] - '0'); + rotation = R_Char2Rotation(lumpinfo[l].name[5]); - if (frame >= 64 || !(R_ValidSpriteAngle(rotation))) // Give an actual NAME error -_-... + if (frame >= 64 || rotation == 255) // Give an actual NAME error -_-... { CONS_Alert(CONS_WARNING, M_GetText("Bad sprite name: %s\n"), W_CheckNameForNumPwad(wadnum,l)); continue; @@ -311,7 +321,13 @@ static boolean R_AddSingleSpriteDef(const char *sprname, spritedef_t *spritedef, if (lumpinfo[l].name[6]) { frame = R_Char2Frame(lumpinfo[l].name[6]); - rotation = (UINT8)(lumpinfo[l].name[7] - '0'); + rotation = R_Char2Rotation(lumpinfo[l].name[7]); + + if (frame >= 64 || rotation == 255) // Give an actual NAME error -_-... + { + CONS_Alert(CONS_WARNING, M_GetText("Bad sprite name: %s\n"), W_CheckNameForNumPwad(wadnum,l)); + continue; + } R_InstallSpriteLump(wadnum, l, numspritelumps, frame, rotation, 1); } @@ -372,18 +388,19 @@ static boolean R_AddSingleSpriteDef(const char *sprname, spritedef_t *spritedef, case SRF_2D: // both Left and Right rotations // we test to see whether the left and right slots are present if ((sprtemp[frame].lumppat[2] == LUMPERROR) || (sprtemp[frame].lumppat[6] == LUMPERROR)) - I_Error("R_AddSingleSpriteDef: Sprite %.4s frame %c is missing rotations", + I_Error("R_AddSingleSpriteDef: Sprite %.4s frame %c is missing rotations (L-R mode)", sprname, R_Frame2Char(frame)); break; default: - // must have all 8 frames - for (rotation = 0; rotation < 8; rotation++) + // must have all 8/16 frames + rotation = ((sprtemp[frame].rotate & SRF_3DGE) ? 16 : 8); + while (rotation--) // we test the patch lump, or the id lump whatever // if it was not loaded the two are LUMPERROR if (sprtemp[frame].lumppat[rotation] == LUMPERROR) - I_Error("R_AddSingleSpriteDef: Sprite %.4s frame %c is missing rotations", - sprname, R_Frame2Char(frame)); + I_Error("R_AddSingleSpriteDef: Sprite %.4s frame %c is missing rotations (1-%c mode)", + sprname, R_Frame2Char(frame), ((sprtemp[frame].rotate & SRF_3DGE) ? 'G' : '8')); break; } } @@ -1097,7 +1114,7 @@ static void R_ProjectSprite(mobj_t *thing) size_t lump; size_t rot; - UINT8 flip; + UINT16 flip; boolean vflip = (!(thing->eflags & MFE_VERTICALFLIP) != !(thing->frame & FF_VERTICALFLIP)); INT32 lindex; @@ -1227,7 +1244,7 @@ static void R_ProjectSprite(mobj_t *thing) // use single rotation for all views rot = 0; //Fab: for vis->patch below lump = sprframe->lumpid[0]; //Fab: see note above - flip = sprframe->flip; // Will only be 0x00 or 0xFF + flip = sprframe->flip; // Will only be 0 or 0xFFFF } else { @@ -1238,6 +1255,11 @@ static void R_ProjectSprite(mobj_t *thing) rot = 6; // F7 slot else if ((sprframe->rotate & SRF_LEFT) && (ang >= ANGLE_180)) // See from left rot = 2; // F3 slot + else if (sprframe->rotate & SRF_3DGE) // 16-angle mode + { + rot = (ang+ANGLE_180+ANGLE_11hh)>>28; + rot = ((rot & 1)<<3)|(rot>>1); + } else // Normal behaviour rot = (ang+ANGLE_202h)>>29; @@ -1260,7 +1282,7 @@ static void R_ProjectSprite(mobj_t *thing) if (thing->rollangle) { rollangle = R_GetRollAngle(thing->rollangle); - if (!sprframe->rotsprite.cached[rot]) + if (!(sprframe->rotsprite.cached & (1<sprite, (thing->frame & FF_FRAMEMASK), sprinfo, sprframe, rot, flip); rotsprite = sprframe->rotsprite.patch[rot][rollangle]; if (rotsprite != NULL) diff --git a/src/r_things.h b/src/r_things.h index 8e4a543c3..b4ef66a62 100644 --- a/src/r_things.h +++ b/src/r_things.h @@ -20,10 +20,6 @@ #include "r_portal.h" #include "r_defs.h" -// "Left" and "Right" character symbols for additional rotation functionality -#define ROT_L ('L' - '0') -#define ROT_R ('R' - '0') - // number of sprite lumps for spritewidth,offset,topoffset lookup tables // Fab: this is a hack : should allocate the lookup tables per sprite #define MAXVISSPRITES 2048 // added 2-2-98 was 128 @@ -270,7 +266,7 @@ FUNCMATH FUNCINLINE static ATTRINLINE UINT8 R_Char2Frame(char cn) if (cn == '+') return '\\' - 'A'; // PK3 can't use backslash, so use + instead return cn - 'A'; #else - if (cn >= 'A' && cn <= 'Z') return cn - 'A'; + if (cn >= 'A' && cn <= 'Z') return (cn - 'A'); if (cn >= '0' && cn <= '9') return (cn - '0') + 26; if (cn >= 'a' && cn <= 'z') return (cn - 'a') + 36; if (cn == '!') return 62; @@ -279,9 +275,26 @@ FUNCMATH FUNCINLINE static ATTRINLINE UINT8 R_Char2Frame(char cn) #endif } -FUNCMATH FUNCINLINE static ATTRINLINE boolean R_ValidSpriteAngle(UINT8 rotation) +// "Left" and "Right" character symbols for additional rotation functionality +#define ROT_L 17 +#define ROT_R 18 + +FUNCMATH FUNCINLINE static ATTRINLINE char R_Rotation2Char(UINT8 rot) { - return ((rotation <= 8) || (rotation == ROT_L) || (rotation == ROT_R)); + if (rot <= 9) return '0' + rot; + if (rot <= 16) return 'A' + (rot - 10); + if (rot == ROT_L) return 'L'; + if (rot == ROT_R) return 'R'; + return '\xFF'; +} + +FUNCMATH FUNCINLINE static ATTRINLINE UINT8 R_Char2Rotation(char cn) +{ + if (cn >= '0' && cn <= '9') return (cn - '0'); + if (cn >= 'A' && cn <= 'G') return (cn - 'A') + 10; + if (cn == 'L') return ROT_L; + if (cn == 'R') return ROT_R; + return 255; } #endif //__R_THINGS__ From 702b23ec3f7db75c94bcff065b45d0a367644b56 Mon Sep 17 00:00:00 2001 From: James R Date: Wed, 8 Jan 2020 12:58:19 -0800 Subject: [PATCH 663/746] Put the word jumping code in functions --- src/console.c | 49 +++++-------------------------------------------- src/doomdef.h | 2 ++ src/m_misc.c | 37 +++++++++++++++++++++++++++++++++++++ src/m_misc.h | 8 ++++++++ 4 files changed, 52 insertions(+), 44 deletions(-) diff --git a/src/console.c b/src/console.c index f77d9b085..786eb8c2b 100644 --- a/src/console.c +++ b/src/console.c @@ -32,6 +32,7 @@ #include "d_main.h" #include "m_menu.h" #include "filesrch.h" +#include "m_misc.h" #ifdef _WINDOWS #include "win32/win_main.h" @@ -41,8 +42,6 @@ #include "hardware/hw_main.h" #endif -#define PUNCTUATION "!\"#$%&'()*+,-./:;<=>?@[\\]^_`{|}~" - #define MAXHUDLINES 20 static boolean con_started = false; // console has been initialised @@ -822,61 +821,23 @@ boolean CON_Responder(event_t *ev) if (input_cur != 0) { if (ctrldown) - { - int (*is)(int); - char *line; - int c; - line = inputlines[inputline]; - c = line[--input_cur]; - if (isspace(c)) - is = isspace; - else if (ispunct(c)) - is = ispunct; - else - is = isalnum; - c = (*is)(line[input_cur]); - while (input_cur > 0 && - (*is)(line[input_cur - 1]) == c) - input_cur--; - } + input_cur = M_JumpWordReverse(inputlines[inputline], input_cur); else - { --input_cur; - } } - if (!shiftdown) input_sel = input_cur; return true; } else if (key == KEY_RIGHTARROW) { - if (ctrldown) + if (input_cur < input_len) { - char *line; - int c; - - line = &inputlines[inputline][input_cur]; - c = line[0]; - - if (isspace(c)) - input_cur += strspn(line, " "); - else if (ispunct(c)) - input_cur += strspn(line, PUNCTUATION); + if (ctrldown) + input_cur += M_JumpWord(&inputlines[inputline][input_cur]); else - { - if (isspace(line[1])) - input_cur += 1 + strspn(&line[1], " "); - else - input_cur += strcspn(line, " "PUNCTUATION); - } - } - else - { - if (input_cur < input_len) ++input_cur; } - if (!shiftdown) input_sel = input_cur; return true; diff --git a/src/doomdef.h b/src/doomdef.h index 55ad8abed..7b4f6343f 100644 --- a/src/doomdef.h +++ b/src/doomdef.h @@ -541,6 +541,8 @@ INT32 I_GetKey(void); #define PATHSEP "/" #endif +#define PUNCTUATION "!\"#$%&'()*+,-./:;<=>?@[\\]^_`{|}~" + // Compile date and time and revision. extern const char *compdate, *comptime, *comprevision, *compbranch; diff --git a/src/m_misc.c b/src/m_misc.c index 83c0c7bec..91447b415 100644 --- a/src/m_misc.c +++ b/src/m_misc.c @@ -2540,3 +2540,40 @@ void M_MkdirEach(const char *path, int start, int mode) { M_MkdirEachUntil(path, start, -1, mode); } + +int M_JumpWord(const char *line) +{ + int c; + + c = line[0]; + + if (isspace(c)) + return strspn(line, " "); + else if (ispunct(c)) + return strspn(line, PUNCTUATION); + else + { + if (isspace(line[1])) + return 1 + strspn(&line[1], " "); + else + return strcspn(line, " "PUNCTUATION); + } +} + +int M_JumpWordReverse(const char *line, int offset) +{ + int (*is)(int); + int c; + c = line[--offset]; + if (isspace(c)) + is = isspace; + else if (ispunct(c)) + is = ispunct; + else + is = isalnum; + c = (*is)(line[offset]); + while (offset > 0 && + (*is)(line[offset - 1]) == c) + offset--; + return offset; +} diff --git a/src/m_misc.h b/src/m_misc.h index e0a73e0b7..3fb9f031a 100644 --- a/src/m_misc.h +++ b/src/m_misc.h @@ -101,6 +101,14 @@ boolean M_IsPathAbsolute (const char *path); void M_MkdirEach (const char *path, int start, int mode); void M_MkdirEachUntil (const char *path, int start, int end, int mode); +/* Return offset to the first word in a string. */ +/* E.g. cursor += M_JumpWord(line + cursor); */ +int M_JumpWord (const char *s); + +/* Return index of the last word behind offset bytes in a string. */ +/* E.g. cursor = M_JumpWordReverse(line, cursor); */ +int M_JumpWordReverse (const char *line, int offset); + // counting bits, for weapon ammo code, usually FUNCMATH UINT8 M_CountBits(UINT32 num, UINT8 size); From 8bc7b4c72d3a0dd94e29d0cab806037836958a28 Mon Sep 17 00:00:00 2001 From: James R Date: Wed, 8 Jan 2020 12:58:34 -0800 Subject: [PATCH 664/746] Give chat word jumping --- src/hu_stuff.c | 15 +++++++++++++-- 1 file changed, 13 insertions(+), 2 deletions(-) diff --git a/src/hu_stuff.c b/src/hu_stuff.c index 772d1cd58..d75b478ab 100644 --- a/src/hu_stuff.c +++ b/src/hu_stuff.c @@ -17,6 +17,7 @@ #include "m_menu.h" // gametype_cons_t #include "m_cond.h" // emblems +#include "m_misc.h" // word jumping #include "d_clisrv.h" @@ -1349,9 +1350,19 @@ boolean HU_Responder(event_t *ev) chat_scrolltime = 4; } else if (c == KEY_LEFTARROW && c_input != 0 && !OLDCHAT) // i said go back - c_input--; + { + if (ctrldown) + c_input = M_JumpWordReverse(w_chat, c_input); + else + c_input--; + } else if (c == KEY_RIGHTARROW && c_input < strlen(w_chat) && !OLDCHAT) // don't need to check for admin or w/e here since the chat won't ever contain anything if it's muted. - c_input++; + { + if (ctrldown) + c_input += M_JumpWord(&w_chat[c_input]); + else + c_input++; + } return true; } #endif From 07dfc5cce79b5e02a0b353e38f85942d7e1ef2e7 Mon Sep 17 00:00:00 2001 From: Steel Titanium Date: Wed, 8 Jan 2020 16:00:02 -0500 Subject: [PATCH 665/746] Fix S_HAMMER being off by one --- src/info.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/info.c b/src/info.c index 30f3e96d0..5f1cb8fbe 100644 --- a/src/info.c +++ b/src/info.c @@ -3565,7 +3565,7 @@ state_t states[NUMSTATES] = {SPR_PUMA, FF_FULLBRIGHT|FF_TRANS60|8, 3, {NULL}, 0, 0, S_NULL}, // S_PUMATRAIL4 // Hammer - {SPR_HAMM, FF_ANIMATE, -1, {NULL}, 4, 3, S_NULL}, // S_HAMMER + {SPR_HAMM, FF_ANIMATE, -1, {NULL}, 3, 3, S_NULL}, // S_HAMMER // Koopa {SPR_KOOP, 0, -1, {NULL}, 0, 0, S_NULL}, // S_KOOPA1 From 74364b84f9d0563eae4fba2cd111ca52bed9e6b5 Mon Sep 17 00:00:00 2001 From: James R Date: Wed, 8 Jan 2020 14:26:47 -0800 Subject: [PATCH 666/746] Revert "Oh right, the keywords..." This reverts commit a00dfcf4205f88cd6149daf73fec4831a7d7c2e5. --- src/dehacked.c | 5 +++++ src/doomstat.h | 1 + src/g_game.c | 3 +++ src/lua_maplib.c | 2 ++ src/p_setup.c | 1 + 5 files changed, 12 insertions(+) diff --git a/src/dehacked.c b/src/dehacked.c index 8220f5aa3..8b4b92494 100644 --- a/src/dehacked.c +++ b/src/dehacked.c @@ -1629,6 +1629,11 @@ static void readlevelheader(MYFILE *f, INT32 num) mapheaderinfo[num-1]->typeoflevel = tol; } } + else if (fastcmp(word, "KEYWORD")) + { + deh_strlcpy(mapheaderinfo[num-1]->keyword, word2, + sizeof(mapheaderinfo[num-1]->keyword), va("Level header %d: keyword", num)); + } else if (fastcmp(word, "MUSIC")) { if (fastcmp(word2, "NONE")) diff --git a/src/doomstat.h b/src/doomstat.h index 7e961677f..0fad811d9 100644 --- a/src/doomstat.h +++ b/src/doomstat.h @@ -289,6 +289,7 @@ typedef struct UINT8 actnum; ///< Act number or 0 for none. UINT32 typeoflevel; ///< Combination of typeoflevel flags. INT16 nextlevel; ///< Map number of next level, or 1100-1102 to end. + char keyword[33]; ///< Keywords separated by space to search for. 32 characters. char musname[7]; ///< Music track to play. "" for no music. UINT16 mustrack; ///< Subsong to play. Only really relevant for music modules and specific formats supported by GME. 0 to ignore. UINT32 muspos; ///< Music position to jump to. diff --git a/src/g_game.c b/src/g_game.c index f7778df8f..45730adac 100644 --- a/src/g_game.c +++ b/src/g_game.c @@ -4761,6 +4761,9 @@ INT32 G_FindMap(const char *mapname, char **foundmapnamep, measurekeywords(&freq[freqc], &freq[freqc].matchd, &freq[freqc].matchc, realmapname, mapname, wanttable); + measurekeywords(&freq[freqc], + &freq[freqc].keywhd, &freq[freqc].keywhc, + mapheaderinfo[i]->keyword, mapname, wanttable); if (freq[freqc].total) freqc++; } diff --git a/src/lua_maplib.c b/src/lua_maplib.c index 309ba86a1..64e60c99a 100644 --- a/src/lua_maplib.c +++ b/src/lua_maplib.c @@ -2014,6 +2014,8 @@ static int mapheaderinfo_get(lua_State *L) lua_pushinteger(L, header->typeoflevel); else if (fastcmp(field,"nextlevel")) lua_pushinteger(L, header->nextlevel); + else if (fastcmp(field,"keyword")) + lua_pushstring(L, header->keyword); else if (fastcmp(field,"musname")) lua_pushstring(L, header->musname); else if (fastcmp(field,"mustrack")) diff --git a/src/p_setup.c b/src/p_setup.c index 104b4e5a0..a9585d0c2 100644 --- a/src/p_setup.c +++ b/src/p_setup.c @@ -222,6 +222,7 @@ static void P_ClearSingleMapHeaderInfo(INT16 i) mapheaderinfo[num]->typeoflevel = 0; mapheaderinfo[num]->nextlevel = (INT16)(i + 1); mapheaderinfo[num]->startrings = 0; + mapheaderinfo[num]->keyword[0] = '\0'; snprintf(mapheaderinfo[num]->musname, 7, "%sM", G_BuildMapName(i)); mapheaderinfo[num]->musname[6] = 0; mapheaderinfo[num]->mustrack = 0; From 004cfb45aa2edbc9a1b1a18a26372822896e4ef5 Mon Sep 17 00:00:00 2001 From: toaster Date: Wed, 8 Jan 2020 22:36:29 +0000 Subject: [PATCH 667/746] Allow Rollout Rocks that are being ridden to: * Break bustable FOFs like pushables. * Activate pushable-counting executor activators. * Get pushed by currents/wind. This takes advantage of the previously-existing hack relating to objects with MF_PUSHABLE infotable (but not active) flags and a nonzero fuse, which is used as the condition to group this under (rather than MT_ROLLOUTROCK specific fuckery). Thanks to the bug report submitted by our kirbs pal for getting me off my ass this evening. --- src/p_enemy.c | 7 ++----- src/p_mobj.c | 2 +- src/p_spec.c | 5 +++-- 3 files changed, 6 insertions(+), 8 deletions(-) diff --git a/src/p_enemy.c b/src/p_enemy.c index ce201844f..bd7b81d40 100644 --- a/src/p_enemy.c +++ b/src/p_enemy.c @@ -14603,12 +14603,9 @@ void A_RolloutRock(mobj_t *actor) if (!actor->tracer || P_MobjWasRemoved(actor->tracer) || !actor->tracer->health) actor->flags |= MF_PUSHABLE; - if (!(actor->flags & MF_PUSHABLE)) // if being ridden, don't disappear - actor->fuse = 0; - else if (!actor->fuse && actor->movecount == 1) // otherwise if rock has moved, set its fuse + if (!(actor->flags & MF_PUSHABLE) || (actor->movecount != 1)) // if being ridden or haven't moved, don't disappear actor->fuse = actor->info->painchance; - - if (actor->fuse && actor->fuse < 2*TICRATE) + else if (actor->fuse < 2*TICRATE) actor->flags2 ^= MF2_DONTDRAW; } diff --git a/src/p_mobj.c b/src/p_mobj.c index b771103a9..1b2fc7d6a 100644 --- a/src/p_mobj.c +++ b/src/p_mobj.c @@ -1892,7 +1892,7 @@ void P_XYMovement(mobj_t *mo) #endif // Pushables can break some blocks - if (CheckForBustableBlocks && mo->flags & MF_PUSHABLE) + if (CheckForBustableBlocks && ((mo->flags & MF_PUSHABLE) || ((mo->info->flags & MF_PUSHABLE) && mo->fuse))) P_PushableCheckBustables(mo); if (!P_TryMove(mo, mo->x + xmove, mo->y + ymove, true) diff --git a/src/p_spec.c b/src/p_spec.c index cc0b185ad..f2cb17e0e 100644 --- a/src/p_spec.c +++ b/src/p_spec.c @@ -1887,7 +1887,7 @@ boolean P_RunTriggerLinedef(line_t *triggerline, mobj_t *actor, sector_t *caller while (node) { mo = node->m_thing; - if (mo->flags & MF_PUSHABLE) + if ((mo->flags & MF_PUSHABLE) || ((mo->info->flags & MF_PUSHABLE) && mo->fuse)) numpush++; node = node->m_thinglist_next; } @@ -8974,7 +8974,8 @@ void T_Pusher(pusher_t *p) || thing->type == MT_EXTRALARGEBUBBLE)) continue; - if (!(thing->flags & MF_PUSHABLE) && !(thing->type == MT_PLAYER + if (!((thing->flags & MF_PUSHABLE) || ((thing->info->flags & MF_PUSHABLE) && thing->fuse)) + && !(thing->type == MT_PLAYER || thing->type == MT_SMALLBUBBLE || thing->type == MT_MEDIUMBUBBLE || thing->type == MT_EXTRALARGEBUBBLE From 735289502c0fb9e91615f06dec94bf7b799fd560 Mon Sep 17 00:00:00 2001 From: James R Date: Wed, 8 Jan 2020 14:41:38 -0800 Subject: [PATCH 668/746] Call it KEYWORDS --- src/dehacked.c | 6 +++--- src/doomstat.h | 2 +- src/g_game.c | 2 +- src/lua_maplib.c | 4 ++-- src/p_setup.c | 2 +- 5 files changed, 8 insertions(+), 8 deletions(-) diff --git a/src/dehacked.c b/src/dehacked.c index 8b4b92494..91d67c63f 100644 --- a/src/dehacked.c +++ b/src/dehacked.c @@ -1629,10 +1629,10 @@ static void readlevelheader(MYFILE *f, INT32 num) mapheaderinfo[num-1]->typeoflevel = tol; } } - else if (fastcmp(word, "KEYWORD")) + else if (fastcmp(word, "KEYWORDS")) { - deh_strlcpy(mapheaderinfo[num-1]->keyword, word2, - sizeof(mapheaderinfo[num-1]->keyword), va("Level header %d: keyword", num)); + deh_strlcpy(mapheaderinfo[num-1]->keywords, word2, + sizeof(mapheaderinfo[num-1]->keywords), va("Level header %d: keywords", num)); } else if (fastcmp(word, "MUSIC")) { diff --git a/src/doomstat.h b/src/doomstat.h index 0fad811d9..c7c12632a 100644 --- a/src/doomstat.h +++ b/src/doomstat.h @@ -289,7 +289,7 @@ typedef struct UINT8 actnum; ///< Act number or 0 for none. UINT32 typeoflevel; ///< Combination of typeoflevel flags. INT16 nextlevel; ///< Map number of next level, or 1100-1102 to end. - char keyword[33]; ///< Keywords separated by space to search for. 32 characters. + char keywords[33]; ///< Keywords separated by space to search for. 32 characters. char musname[7]; ///< Music track to play. "" for no music. UINT16 mustrack; ///< Subsong to play. Only really relevant for music modules and specific formats supported by GME. 0 to ignore. UINT32 muspos; ///< Music position to jump to. diff --git a/src/g_game.c b/src/g_game.c index 45730adac..dd7540ae8 100644 --- a/src/g_game.c +++ b/src/g_game.c @@ -4763,7 +4763,7 @@ INT32 G_FindMap(const char *mapname, char **foundmapnamep, realmapname, mapname, wanttable); measurekeywords(&freq[freqc], &freq[freqc].keywhd, &freq[freqc].keywhc, - mapheaderinfo[i]->keyword, mapname, wanttable); + mapheaderinfo[i]->keywords, mapname, wanttable); if (freq[freqc].total) freqc++; } diff --git a/src/lua_maplib.c b/src/lua_maplib.c index 64e60c99a..3d98bee33 100644 --- a/src/lua_maplib.c +++ b/src/lua_maplib.c @@ -2014,8 +2014,8 @@ static int mapheaderinfo_get(lua_State *L) lua_pushinteger(L, header->typeoflevel); else if (fastcmp(field,"nextlevel")) lua_pushinteger(L, header->nextlevel); - else if (fastcmp(field,"keyword")) - lua_pushstring(L, header->keyword); + else if (fastcmp(field,"keywords")) + lua_pushstring(L, header->keywords); else if (fastcmp(field,"musname")) lua_pushstring(L, header->musname); else if (fastcmp(field,"mustrack")) diff --git a/src/p_setup.c b/src/p_setup.c index a9585d0c2..14bdca2e3 100644 --- a/src/p_setup.c +++ b/src/p_setup.c @@ -222,7 +222,7 @@ static void P_ClearSingleMapHeaderInfo(INT16 i) mapheaderinfo[num]->typeoflevel = 0; mapheaderinfo[num]->nextlevel = (INT16)(i + 1); mapheaderinfo[num]->startrings = 0; - mapheaderinfo[num]->keyword[0] = '\0'; + mapheaderinfo[num]->keywords[0] = '\0'; snprintf(mapheaderinfo[num]->musname, 7, "%sM", G_BuildMapName(i)); mapheaderinfo[num]->musname[6] = 0; mapheaderinfo[num]->mustrack = 0; From c0380a30529cddce70e38fc19101e34aea24b208 Mon Sep 17 00:00:00 2001 From: fickleheart Date: Fri, 27 Dec 2019 04:57:16 -0600 Subject: [PATCH 669/746] Make papersprite projection completely correct in software I heard properpaper had some weird crashes? I couldn't reproduce them no matter how hard I tried, but I added some bounds checking to this version too just in case. Gotta get other people's help to try to reproduce those. --- src/r_things.c | 106 ++++++++++++++++++++----------------------------- src/r_things.h | 3 ++ 2 files changed, 47 insertions(+), 62 deletions(-) diff --git a/src/r_things.c b/src/r_things.c index 2f01ac7f6..50f799d2c 100644 --- a/src/r_things.c +++ b/src/r_things.c @@ -743,7 +743,8 @@ void R_DrawFlippedMaskedColumn(column_t *column, INT32 texheight) static void R_DrawVisSprite(vissprite_t *vis) { column_t *column; -#ifdef RANGECHECK +//#ifdef RANGECHECK +#if 1 INT32 texturecolumn; #endif fixed_t frac; @@ -895,21 +896,34 @@ static void R_DrawVisSprite(vissprite_t *vis) for (dc_x = vis->x1; dc_x <= vis->x2; dc_x++, frac += vis->xiscale) { -#ifdef RANGECHECK - - texturecolumn = frac>>FRACBITS; - - if (texturecolumn < 0 || texturecolumn >= SHORT(patch->width)) - I_Error("R_DrawSpriteRange: bad texturecolumn at %d from end", vis->x2 - dc_x); - column = (column_t *)((UINT8 *)patch + LONG(patch->columnofs[texturecolumn])); -#else - column = (column_t *)((UINT8 *)patch + LONG(patch->columnofs[frac>>FRACBITS])); -#endif if (vis->scalestep) { + angle_t angle = ((vis->centerangle + xtoviewangle[dc_x]) >> ANGLETOFINESHIFT) & 0xFFF; + texturecolumn = (vis->paperoffset - FixedMul(FINETANGENT(angle), vis->paperdistance)) >> FRACBITS; + + if (texturecolumn < 0 || texturecolumn >= SHORT(patch->width)) + { + spryscale += vis->scalestep; + continue; + } + + if (vis->xiscale < 0) + texturecolumn = SHORT(patch->width) - 1 - texturecolumn; + sprtopscreen = (centeryfrac - FixedMul(dc_texturemid, spryscale)); dc_iscale = (0xffffffffu / (unsigned)spryscale); } + else + { + texturecolumn = frac>>FRACBITS; +#ifdef RANGECHECK + if (texturecolumn < 0 || texturecolumn >= SHORT(patch->width)) + I_Error("R_DrawSpriteRange: bad texturecolumn at %d from end", vis->x2 - dc_x); +#endif + } + + column = (column_t *)((UINT8 *)patch + LONG(patch->columnofs[texturecolumn])); + if (vis->cut & SC_VFLIP) R_DrawFlippedMaskedColumn(column, patch->height); else @@ -1073,8 +1087,6 @@ static void R_SplitSprite(vissprite_t *sprite) } } -//#define PROPERPAPER // This was reverted less than 7 hours before 2.2's release because of very strange, frequent crashes. - // // R_ProjectSprite // Generates a vissprite for a thing @@ -1111,7 +1123,9 @@ static void R_ProjectSprite(mobj_t *thing) fixed_t iscale; fixed_t scalestep; fixed_t offset, offset2; + boolean papersprite = !!(thing->frame & FF_PAPERSPRITE); + fixed_t paperoffset = 0, paperdistance = 0; angle_t centerangle = 0; INT32 dispoffset = thing->info->dispoffset; @@ -1130,10 +1144,6 @@ static void R_ProjectSprite(mobj_t *thing) UINT32 rollangle = AngleFixed(arollangle)>>FRACBITS; #endif -#ifndef PROPERPAPER - fixed_t ang_scale = FRACUNIT; -#endif - // transform the origin point tr_x = thing->x - viewx; tr_y = thing->y - viewy; @@ -1216,13 +1226,7 @@ static void R_ProjectSprite(mobj_t *thing) #endif if (sprframe->rotate != SRF_SINGLE || papersprite) - { ang = R_PointToAngle (thing->x, thing->y) - (thing->player ? thing->player->drawangle : thing->angle); -#ifndef PROPERPAPER - if (papersprite) - ang_scale = abs(FINESINE(ang>>ANGLETOFINESHIFT)); -#endif - } if (sprframe->rotate == SRF_SINGLE) { @@ -1283,31 +1287,11 @@ static void R_ProjectSprite(mobj_t *thing) else offset = -spr_offset; offset = FixedMul(offset, this_scale); -#ifndef PROPERPAPER - tx += FixedMul(offset, ang_scale); - x1 = (centerxfrac + FixedMul (tx,xscale)) >>FRACBITS; - - // off the right side? - if (x1 > viewwidth) - return; -#endif offset2 = FixedMul(spr_width, this_scale); -#ifndef PROPERPAPER - tx += FixedMul(offset2, ang_scale); - x2 = ((centerxfrac + FixedMul (tx,xscale)) >> FRACBITS) - (papersprite ? 2 : 1); - - // off the left side - if (x2 < 0) - return; -#endif if (papersprite) { - fixed_t -#ifdef PROPERPAPER - xscale2, -#endif - yscale2, cosmul, sinmul, tz2; + fixed_t xscale2, yscale2, cosmul, sinmul, tz2; INT32 range; if (ang >= ANGLE_180) @@ -1327,7 +1311,6 @@ static void R_ProjectSprite(mobj_t *thing) yscale = FixedDiv(projectiony, tz); if (yscale < 64) return; // Fix some funky visuals -#ifdef PROPERPAPER gxt = -FixedMul(tr_x, viewsin); gyt = FixedMul(tr_y, viewcos); tx = -(gyt + gxt); @@ -1337,7 +1320,16 @@ static void R_ProjectSprite(mobj_t *thing) // off the right side? if (x1 > viewwidth) return; -#endif + + // Get paperoffset (offset) and paperoffset (distance) + paperoffset = -FixedMul(tr_x, cosmul) - FixedMul(tr_y, sinmul); + paperdistance = -FixedMul(tr_x, sinmul) + FixedMul(tr_y, cosmul); + if (paperdistance < 0) + { + paperoffset = -paperoffset; + paperdistance = -paperdistance; + } + centerangle = viewangle - thing->angle; tr_x += FixedMul(offset2, cosmul); tr_y += FixedMul(offset2, sinmul); @@ -1347,36 +1339,25 @@ static void R_ProjectSprite(mobj_t *thing) yscale2 = FixedDiv(projectiony, tz2); if (yscale2 < 64) return; // ditto -#ifdef PROPERPAPER gxt = -FixedMul(tr_x, viewsin); gyt = FixedMul(tr_y, viewcos); tx = -(gyt + gxt); xscale2 = FixedDiv(projection, tz2); - x2 = (centerxfrac + FixedMul(tx,xscale2))>>FRACBITS; x2--; + x2 = ((centerxfrac + FixedMul(tx,xscale2))>>FRACBITS); // off the left side if (x2 < 0) return; -#endif - if (max(tz, tz2) < FixedMul(MINZ, this_scale)) // non-papersprite clipping is handled earlier return; if ((range = x2 - x1) <= 0) return; -#ifdef PROPERPAPER range++; // fencepost problem -#endif - scalestep = (yscale2 - yscale)/range; - xscale = -#ifdef PROPERPAPER - FixedDiv(range<>FRACBITS; @@ -1400,7 +1380,6 @@ static void R_ProjectSprite(mobj_t *thing) // off the left side if (x2 < 0) return; -#endif } if ((thing->flags2 & MF2_LINKDRAW) && thing->tracer) // toast 16/09/16 (SYMMETRY) @@ -1521,6 +1500,9 @@ static void R_ProjectSprite(mobj_t *thing) vis->pzt = vis->pz + vis->thingheight; vis->texturemid = vis->gzt - viewz; vis->scalestep = scalestep; + vis->paperoffset = paperoffset; + vis->paperdistance = paperdistance; + vis->centerangle = centerangle; vis->mobj = thing; // Easy access! Tails 06-07-2002 diff --git a/src/r_things.h b/src/r_things.h index 8e4a543c3..1b74dd74e 100644 --- a/src/r_things.h +++ b/src/r_things.h @@ -181,8 +181,11 @@ typedef struct vissprite_s fixed_t startfrac; // horizontal position of x1 fixed_t scale, sortscale; // sortscale only differs from scale for paper sprites and MF2_LINKDRAW fixed_t scalestep; // only for paper sprites, 0 otherwise + fixed_t paperoffset, paperdistance; // for paper sprites, offset/dist relative to the angle fixed_t xiscale; // negative if flipped + angle_t centerangle; // for paper sprites + fixed_t texturemid; patch_t *patch; From 1790891fd8f85cf91b0e4badf52e0b907e85e6d1 Mon Sep 17 00:00:00 2001 From: fickleheart Date: Fri, 27 Dec 2019 11:42:02 -0600 Subject: [PATCH 670/746] Reduce disappearance of vissprites close to the camera --- src/r_things.c | 52 +++++++++++++++++++++++++++++++++----------------- 1 file changed, 35 insertions(+), 17 deletions(-) diff --git a/src/r_things.c b/src/r_things.c index 50f799d2c..7efa31a44 100644 --- a/src/r_things.c +++ b/src/r_things.c @@ -743,10 +743,7 @@ void R_DrawFlippedMaskedColumn(column_t *column, INT32 texheight) static void R_DrawVisSprite(vissprite_t *vis) { column_t *column; -//#ifdef RANGECHECK -#if 1 INT32 texturecolumn; -#endif fixed_t frac; patch_t *patch = vis->patch; fixed_t this_scale = vis->mobj->scale; @@ -899,7 +896,7 @@ static void R_DrawVisSprite(vissprite_t *vis) if (vis->scalestep) { angle_t angle = ((vis->centerangle + xtoviewangle[dc_x]) >> ANGLETOFINESHIFT) & 0xFFF; - texturecolumn = (vis->paperoffset - FixedMul(FINETANGENT(angle), vis->paperdistance)) >> FRACBITS; + texturecolumn = (vis->paperoffset - FixedMul(FINETANGENT(angle), vis->paperdistance)) / this_scale; if (texturecolumn < 0 || texturecolumn >= SHORT(patch->width)) { @@ -1154,7 +1151,7 @@ static void R_ProjectSprite(mobj_t *thing) tz = gxt-gyt; // thing is behind view plane? - if (!(papersprite) && (tz < FixedMul(MINZ, this_scale))) // papersprite clipping is handled later + if (!papersprite && (tz < FixedMul(MINZ, this_scale))) // papersprite clipping is handled later return; gxt = -FixedMul(tr_x, viewsin); @@ -1162,7 +1159,7 @@ static void R_ProjectSprite(mobj_t *thing) tx = -(gyt + gxt); // too far off the side? - if (abs(tx) > tz<<2) + if (!papersprite && abs(tx) > tz<<2) // papersprite clipping is handled later return; // aspect ratio stuff @@ -1291,7 +1288,7 @@ static void R_ProjectSprite(mobj_t *thing) if (papersprite) { - fixed_t xscale2, yscale2, cosmul, sinmul, tz2; + fixed_t xscale2, yscale2, cosmul, sinmul, tx2, tz2; INT32 range; if (ang >= ANGLE_180) @@ -1309,7 +1306,7 @@ static void R_ProjectSprite(mobj_t *thing) gyt = -FixedMul(tr_y, viewsin); tz = gxt-gyt; yscale = FixedDiv(projectiony, tz); - if (yscale < 64) return; // Fix some funky visuals + //if (yscale < 64) return; // Fix some funky visuals gxt = -FixedMul(tr_x, viewsin); gyt = FixedMul(tr_y, viewcos); @@ -1317,10 +1314,6 @@ static void R_ProjectSprite(mobj_t *thing) xscale = FixedDiv(projection, tz); x1 = (centerxfrac + FixedMul(tx,xscale))>>FRACBITS; - // off the right side? - if (x1 > viewwidth) - return; - // Get paperoffset (offset) and paperoffset (distance) paperoffset = -FixedMul(tr_x, cosmul) - FixedMul(tr_y, sinmul); paperdistance = -FixedMul(tr_x, sinmul) + FixedMul(tr_y, cosmul); @@ -1337,19 +1330,44 @@ static void R_ProjectSprite(mobj_t *thing) gyt = -FixedMul(tr_y, viewsin); tz2 = gxt-gyt; yscale2 = FixedDiv(projectiony, tz2); - if (yscale2 < 64) return; // ditto + //if (yscale2 < 64) return; // ditto gxt = -FixedMul(tr_x, viewsin); gyt = FixedMul(tr_y, viewcos); - tx = -(gyt + gxt); + tx2 = -(gyt + gxt); xscale2 = FixedDiv(projection, tz2); - x2 = ((centerxfrac + FixedMul(tx,xscale2))>>FRACBITS); + x2 = ((centerxfrac + FixedMul(tx2,xscale2))>>FRACBITS); + + if (max(tz, tz2) < FixedMul(MINZ, this_scale)) // non-papersprite clipping is handled earlier + return; + + // Needs partially clipped + if (tz < FixedMul(MINZ, this_scale)) + { + fixed_t div = FixedDiv(tz2-tz, FixedMul(MINZ, this_scale)-tz); + tx += FixedDiv(tx2-tx, div); + tz = FixedMul(MINZ, this_scale); + yscale = FixedDiv(projectiony, tz); + xscale = FixedDiv(projection, tz); + x1 = (centerxfrac + FixedMul(tx,xscale))>>FRACBITS; + } + else if (tz2 < FixedMul(MINZ, this_scale)) + { + fixed_t div = FixedDiv(tz-tz2, FixedMul(MINZ, this_scale)-tz2); + tx2 += FixedDiv(tx-tx2, div); + tz2 = FixedMul(MINZ, this_scale); + yscale2 = FixedDiv(projectiony, tz2); + xscale2 = FixedDiv(projection, tz2); + x2 = (centerxfrac + FixedMul(tx2,xscale2))>>FRACBITS; + } + + // off the right side? + if (x1 > viewwidth) + return; // off the left side if (x2 < 0) return; - if (max(tz, tz2) < FixedMul(MINZ, this_scale)) // non-papersprite clipping is handled earlier - return; if ((range = x2 - x1) <= 0) return; From ccc473917e5133c8d862011ce6383acc5529667d Mon Sep 17 00:00:00 2001 From: fickleheart Date: Fri, 27 Dec 2019 11:48:40 -0600 Subject: [PATCH 671/746] Check for papersprites per-sprite instead of per-row In theory, should be a performance improvement. In practice idk --- src/r_things.c | 42 ++++++++++++++++++++++++++---------------- 1 file changed, 26 insertions(+), 16 deletions(-) diff --git a/src/r_things.c b/src/r_things.c index 7efa31a44..c9fe795fb 100644 --- a/src/r_things.c +++ b/src/r_things.c @@ -891,41 +891,51 @@ static void R_DrawVisSprite(vissprite_t *vis) if (vis->x2 >= vid.width) vis->x2 = vid.width-1; - for (dc_x = vis->x1; dc_x <= vis->x2; dc_x++, frac += vis->xiscale) + // Split drawing loops for paper and non-paper to reduce conditional checks per sprite + if (vis->scalestep) { - if (vis->scalestep) + // Papersprite drawing loop + + for (dc_x = vis->x1; dc_x <= vis->x2; dc_x++, spryscale += vis->scalestep) { angle_t angle = ((vis->centerangle + xtoviewangle[dc_x]) >> ANGLETOFINESHIFT) & 0xFFF; texturecolumn = (vis->paperoffset - FixedMul(FINETANGENT(angle), vis->paperdistance)) / this_scale; if (texturecolumn < 0 || texturecolumn >= SHORT(patch->width)) - { - spryscale += vis->scalestep; continue; - } - if (vis->xiscale < 0) + if (vis->xiscale < 0) // Flipped sprite texturecolumn = SHORT(patch->width) - 1 - texturecolumn; sprtopscreen = (centeryfrac - FixedMul(dc_texturemid, spryscale)); dc_iscale = (0xffffffffu / (unsigned)spryscale); + + column = (column_t *)((UINT8 *)patch + LONG(patch->columnofs[texturecolumn])); + + if (vis->cut & SC_VFLIP) + R_DrawFlippedMaskedColumn(column, patch->height); + else + R_DrawMaskedColumn(column); } - else + } + else + { + // Non-paper drawing loop + for (dc_x = vis->x1; dc_x <= vis->x2; dc_x++, frac += vis->xiscale) { - texturecolumn = frac>>FRACBITS; #ifdef RANGECHECK + texturecolumn = frac>>FRACBITS; if (texturecolumn < 0 || texturecolumn >= SHORT(patch->width)) I_Error("R_DrawSpriteRange: bad texturecolumn at %d from end", vis->x2 - dc_x); + column = (column_t *)((UINT8 *)patch + LONG(patch->columnofs[texturecolumn])); +#else + column = (column_t *)((UINT8 *)patch + LONG(patch->columnofs[frac>>FRACBITS])); #endif + if (vis->cut & SC_VFLIP) + R_DrawFlippedMaskedColumn(column, patch->height); + else + R_DrawMaskedColumn(column); } - - column = (column_t *)((UINT8 *)patch + LONG(patch->columnofs[texturecolumn])); - - if (vis->cut & SC_VFLIP) - R_DrawFlippedMaskedColumn(column, patch->height); - else - R_DrawMaskedColumn(column); - spryscale += vis->scalestep; } colfunc = colfuncs[BASEDRAWFUNC]; From 48c1ce3ac3c0869a9272d3685da9ddaa3c1b014b Mon Sep 17 00:00:00 2001 From: fickleheart Date: Fri, 27 Dec 2019 15:31:20 -0600 Subject: [PATCH 672/746] Add render-based drop shadows to some objects Uses a hardcoded list for now. I was experiencing some crashes with this, but the shadowyscale check seems to have suppressed them. --- src/r_things.c | 133 ++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 132 insertions(+), 1 deletion(-) diff --git a/src/r_things.c b/src/r_things.c index c9fe795fb..558ea280e 100644 --- a/src/r_things.c +++ b/src/r_things.c @@ -1094,6 +1094,124 @@ static void R_SplitSprite(vissprite_t *sprite) } } +static void R_ProjectDropShadow(mobj_t *thing, vissprite_t *vis, fixed_t tx, fixed_t tz) +{ + vissprite_t *shadow; + patch_t *patch; + fixed_t xscale, yscale, shadowxscale, shadowyscale, x1, x2; + INT32 light = 0; + fixed_t scalemul; UINT8 trans; + fixed_t floordiff; + fixed_t floorz; + + // Get floorz as the first floor below the object that's visible + floorz = (vis->heightsec != -1) ? sectors[vis->heightsec].floorheight : thing->floorz; + if (vis->sector->ffloors) + { + ffloor_t *rover = vis->sector->ffloors; + fixed_t z; + + for (; rover; rover = rover->next) + { + if (!(rover->flags & FF_EXISTS) || !(rover->flags & FF_RENDERPLANES) || (rover->alpha < 90 && !(rover->flags & FF_SWIMMABLE))) + continue; + + z = *rover->t_slope ? P_GetZAt(*rover->t_slope, thing->x, thing->y) : *rover->topheight; + if (z < thing->z+thing->height/3 && z > floorz) + floorz = z; + } + } + + floordiff = abs(thing->z - floorz); + + trans = floordiff / (100*FRACUNIT) + 3; + if (trans >= 9) return; + + scalemul = FRACUNIT - floordiff/640; + + patch = W_CachePatchNum(sprites[SPR_THOK].spriteframes[0].lumppat[0], PU_CACHE); + xscale = FixedDiv(projection, tz); + yscale = FixedDiv(projectiony, tz); + shadowxscale = FixedMul(thing->radius*2, scalemul) / patch->width; + shadowyscale = FixedMul(FixedMul(thing->radius*2 / patch->height, scalemul), FixedDiv(abs(floorz - viewz), tz)); + + tx -= patch->width * shadowxscale/2; + x1 = (centerxfrac + FixedMul(tx,xscale))>>FRACBITS; + if (x1 >= viewwidth) return; + + tx += patch->width * shadowxscale; + x2 = ((centerxfrac + FixedMul(tx,xscale))>>FRACBITS); x2--; + if (x2 < 0 || x2 <= x1) return; + + if (shadowyscale < FRACUNIT/patch->height) return; // fix some crashes? + + shadow = R_NewVisSprite(); + shadow->patch = patch; + shadow->heightsec = vis->heightsec; + + shadow->thingheight = FRACUNIT; + shadow->pz = floorz; + shadow->pzt = shadow->pz + shadow->thingheight; + + shadow->mobjflags = 0; + shadow->sortscale = vis->sortscale; + shadow->dispoffset = vis->dispoffset - 5; + shadow->gx = thing->x; + shadow->gy = thing->y; + shadow->gzt = shadow->pz + shadow->patch->height * shadowyscale / 2; + shadow->gz = shadow->gzt - shadow->patch->height * shadowyscale; + shadow->texturemid = FixedDiv(shadow->gzt - viewz, shadowyscale); + shadow->scalestep = 0; + + shadow->mobj = thing; // Easy access! Tails 06-07-2002 + + shadow->x1 = x1 < 0 ? 0 : x1; + shadow->x2 = x2 >= viewwidth ? viewwidth-1 : x2; + + shadow->xscale = FixedMul(xscale, shadowxscale); //SoM: 4/17/2000 + shadow->scale = FixedMul(yscale, shadowyscale); + shadow->sector = vis->sector; + shadow->szt = (INT16)((centeryfrac - FixedMul(shadow->gzt - viewz, yscale))>>FRACBITS); + shadow->sz = (INT16)((centeryfrac - FixedMul(shadow->gz - viewz, yscale))>>FRACBITS); + shadow->cut = SC_ISSCALED; //check this + + + shadow->startfrac = 0; + shadow->xiscale = 0x7fffff00 / (shadow->xscale/2); + + if (shadow->x1 > x1) + shadow->startfrac += shadow->xiscale*(vis->x1-x1); + + if (thing->subsector->sector->numlights) + { + INT32 lightnum; +#ifdef ESLOPE // R_GetPlaneLight won't work on sloped lights! + light = thing->subsector->sector->numlights - 1; + + for (lightnum = 1; lightnum < thing->subsector->sector->numlights; lightnum++) { + fixed_t h = thing->subsector->sector->lightlist[lightnum].slope ? P_GetZAt(thing->subsector->sector->lightlist[lightnum].slope, thing->x, thing->y) + : thing->subsector->sector->lightlist[lightnum].height; + if (h <= shadow->gzt) { + light = lightnum - 1; + break; + } + } +#else + light = R_GetPlaneLight(thing->subsector->sector, shadow->gzt, false); +#endif + } + + if (thing->subsector->sector->numlights) + shadow->extra_colormap = *thing->subsector->sector->lightlist[light].extra_colormap; + else + shadow->extra_colormap = thing->subsector->sector->extra_colormap; + + shadow->transmap = transtables + (trans<colormap = scalelight[0][0]; // full dark! + + objectsdrawn++; +} + // // R_ProjectSprite // Generates a vissprite for a thing @@ -1131,6 +1249,8 @@ static void R_ProjectSprite(mobj_t *thing) fixed_t scalestep; fixed_t offset, offset2; + fixed_t basetx; // drop shadows + boolean papersprite = !!(thing->frame & FF_PAPERSPRITE); fixed_t paperoffset = 0, paperdistance = 0; angle_t centerangle = 0; @@ -1166,7 +1286,7 @@ static void R_ProjectSprite(mobj_t *thing) gxt = -FixedMul(tr_x, viewsin); gyt = FixedMul(tr_y, viewcos); - tx = -(gyt + gxt); + basetx = tx = -(gyt + gxt); // too far off the side? if (!papersprite && abs(tx) > tz<<2) // papersprite clipping is handled later @@ -1623,6 +1743,17 @@ static void R_ProjectSprite(mobj_t *thing) if (thing->subsector->sector->numlights) R_SplitSprite(vis); + // temporary: whitelist. eventually: MF/2/E flag? + if (( + oldthing->type == MT_PLAYER || + (oldthing->state - states) == S_RING || + oldthing->type == MT_ROLLOUTROCK || + oldthing->flags & MF_ENEMY || + oldthing->type == MT_EGGMOBILE4_MACE || + (oldthing->type >= MT_SMALLMACE && oldthing->type <= MT_REDSPRINGBALL) // .W. + ) && !papersprite) + R_ProjectDropShadow(oldthing, vis, basetx, tz); + // Debug ++objectsdrawn; } From c46c92d605efa401fbb24193eef170b64ecb99ca Mon Sep 17 00:00:00 2001 From: fickleheart Date: Sun, 29 Dec 2019 18:30:29 -0600 Subject: [PATCH 673/746] Prevent linkdraw sprites from connecting to shadows --- src/r_things.c | 11 ++++++++++- src/r_things.h | 3 ++- 2 files changed, 12 insertions(+), 2 deletions(-) diff --git a/src/r_things.c b/src/r_things.c index 558ea280e..953952c56 100644 --- a/src/r_things.c +++ b/src/r_things.c @@ -1122,6 +1122,8 @@ static void R_ProjectDropShadow(mobj_t *thing, vissprite_t *vis, fixed_t tx, fix } } + if (abs(floorz-viewz)/tz > 4) return; // Prevent stretchy shadows and possible crashes + floordiff = abs(thing->z - floorz); trans = floordiff / (100*FRACUNIT) + 3; @@ -1173,7 +1175,7 @@ static void R_ProjectDropShadow(mobj_t *thing, vissprite_t *vis, fixed_t tx, fix shadow->sector = vis->sector; shadow->szt = (INT16)((centeryfrac - FixedMul(shadow->gzt - viewz, yscale))>>FRACBITS); shadow->sz = (INT16)((centeryfrac - FixedMul(shadow->gz - viewz, yscale))>>FRACBITS); - shadow->cut = SC_ISSCALED; //check this + shadow->cut = SC_ISSCALED|SC_SHADOW; //check this shadow->startfrac = 0; @@ -2069,6 +2071,9 @@ static void R_SortVisSprites(vissprite_t* vsprsortedhead, UINT32 start, UINT32 e if (!(ds->cut & SC_LINKDRAW)) continue; + if (ds->cut & SC_SHADOW) + continue; + // reuse dsfirst... for (dsfirst = unsorted.prev; dsfirst != &unsorted; dsfirst = dsfirst->prev) { @@ -2076,6 +2081,10 @@ static void R_SortVisSprites(vissprite_t* vsprsortedhead, UINT32 start, UINT32 e if (dsfirst->cut & SC_LINKDRAW) continue; + // don't connect to your shadow! + if (dsfirst->cut & SC_SHADOW) + continue; + // don't connect if it's not the tracer if (dsfirst->mobj != ds->mobj) continue; diff --git a/src/r_things.h b/src/r_things.h index 1b74dd74e..a6ef92802 100644 --- a/src/r_things.h +++ b/src/r_things.h @@ -153,7 +153,8 @@ typedef enum SC_LINKDRAW = 1<<3, SC_FULLBRIGHT = 1<<4, SC_VFLIP = 1<<5, - SC_ISSCALED = 1>>6, + SC_ISSCALED = 1<<6, + SC_SHADOW = 1<<7, // masks SC_CUTMASK = SC_TOP|SC_BOTTOM, SC_FLAGMASK = ~SC_CUTMASK From 5929b4797e33f3869131be37b2ff52daf30d469e Mon Sep 17 00:00:00 2001 From: fickleheart Date: Sun, 29 Dec 2019 19:19:26 -0600 Subject: [PATCH 674/746] This acursed crash-inducing typo spat in my face and called me a bitch --- src/r_things.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/src/r_things.c b/src/r_things.c index 953952c56..174ada10a 100644 --- a/src/r_things.c +++ b/src/r_things.c @@ -1177,12 +1177,11 @@ static void R_ProjectDropShadow(mobj_t *thing, vissprite_t *vis, fixed_t tx, fix shadow->sz = (INT16)((centeryfrac - FixedMul(shadow->gz - viewz, yscale))>>FRACBITS); shadow->cut = SC_ISSCALED|SC_SHADOW; //check this - shadow->startfrac = 0; - shadow->xiscale = 0x7fffff00 / (shadow->xscale/2); + shadow->xiscale = 0x7ffffff0 / (shadow->xscale/2); if (shadow->x1 > x1) - shadow->startfrac += shadow->xiscale*(vis->x1-x1); + shadow->startfrac += shadow->xiscale*(shadow->x1-x1); if (thing->subsector->sector->numlights) { From 9c49e020c3abd7d748ea93e37c1b2eb67a4f90ea Mon Sep 17 00:00:00 2001 From: fickleheart Date: Sun, 29 Dec 2019 20:19:27 -0600 Subject: [PATCH 675/746] FUCK IT, SLOPED SHADOWS NOW --- src/r_things.c | 76 ++++++++++++++++++++++++++++++++++++++++++++------ 1 file changed, 67 insertions(+), 9 deletions(-) diff --git a/src/r_things.c b/src/r_things.c index 174ada10a..628239957 100644 --- a/src/r_things.c +++ b/src/r_things.c @@ -876,6 +876,7 @@ static void R_DrawVisSprite(vissprite_t *vis) if (!(vis->scalestep)) { sprtopscreen = centeryfrac - FixedMul(dc_texturemid, spryscale); + sprtopscreen += vis->paperdistance * vis->paperoffset; dc_iscale = FixedDiv(FRACUNIT, vis->scale); } @@ -921,7 +922,7 @@ static void R_DrawVisSprite(vissprite_t *vis) else { // Non-paper drawing loop - for (dc_x = vis->x1; dc_x <= vis->x2; dc_x++, frac += vis->xiscale) + for (dc_x = vis->x1; dc_x <= vis->x2; dc_x++, frac += vis->xiscale, sprtopscreen += vis->paperdistance) { #ifdef RANGECHECK texturecolumn = frac>>FRACBITS; @@ -1098,30 +1099,59 @@ static void R_ProjectDropShadow(mobj_t *thing, vissprite_t *vis, fixed_t tx, fix { vissprite_t *shadow; patch_t *patch; - fixed_t xscale, yscale, shadowxscale, shadowyscale, x1, x2; + fixed_t xscale, yscale, shadowxscale, shadowyscale, shadowskew, x1, x2; INT32 light = 0; fixed_t scalemul; UINT8 trans; fixed_t floordiff; fixed_t floorz; + pslope_t *floorslope; // Get floorz as the first floor below the object that's visible floorz = (vis->heightsec != -1) ? sectors[vis->heightsec].floorheight : thing->floorz; - if (vis->sector->ffloors) + floorslope = (vis->heightsec != -1) ? NULL : thing->standingslope; + { - ffloor_t *rover = vis->sector->ffloors; + boolean original = true; fixed_t z; - for (; rover; rover = rover->next) + if (vis->sector->ffloors) { - if (!(rover->flags & FF_EXISTS) || !(rover->flags & FF_RENDERPLANES) || (rover->alpha < 90 && !(rover->flags & FF_SWIMMABLE))) - continue; + ffloor_t *rover = vis->sector->ffloors; - z = *rover->t_slope ? P_GetZAt(*rover->t_slope, thing->x, thing->y) : *rover->topheight; - if (z < thing->z+thing->height/3 && z > floorz) + for (; rover; rover = rover->next) + { + if (!(rover->flags & FF_EXISTS) || !(rover->flags & FF_RENDERPLANES) || (rover->alpha < 90 && !(rover->flags & FF_SWIMMABLE))) + continue; + + z = *rover->t_slope ? P_GetZAt(*rover->t_slope, thing->x, thing->y) : *rover->topheight; + if (z < thing->z+thing->height/3 && z > floorz) + { + floorz = z; + floorslope = *rover->t_slope; + original = false; + } + else if (original && (*rover->t_slope) && z < thing->z+thing->height/3 && z > floorz - FixedMul(abs((*rover->t_slope)->zdelta), thing->radius*2)) + { + // Guesstimated to be a usable floor. This is here to handle floorslope of non-grounded things, I guess. + floorz = z; + floorslope = *rover->t_slope; + original = false; + } + } + } + + if (original && vis->sector->f_slope) + { + z = P_GetZAt(vis->sector->f_slope, thing->x, thing->y); + if (z < thing->z+thing->height/3 && z > floorz - FixedMul(abs(vis->sector->f_slope->zdelta), thing->radius*2)) + { floorz = z; + floorslope = vis->sector->f_slope; + } } } + if (abs(floorz-viewz)/tz > 4) return; // Prevent stretchy shadows and possible crashes floordiff = abs(thing->z - floorz); @@ -1136,6 +1166,28 @@ static void R_ProjectDropShadow(mobj_t *thing, vissprite_t *vis, fixed_t tx, fix yscale = FixedDiv(projectiony, tz); shadowxscale = FixedMul(thing->radius*2, scalemul) / patch->width; shadowyscale = FixedMul(FixedMul(thing->radius*2 / patch->height, scalemul), FixedDiv(abs(floorz - viewz), tz)); + shadowskew = 0; + + if (floorslope) + { + // haha let's try some dumb stuff + fixed_t xslope, zslope; + angle_t sloperelang = (R_PointToAngle(thing->x, thing->y) - floorslope->xydirection) >> ANGLETOFINESHIFT; + + xslope = FixedMul(FINESINE(sloperelang), floorslope->zdelta); + zslope = FixedMul(FINECOSINE(sloperelang), floorslope->zdelta); + + //CONS_Printf("Shadow is sloped by %d %d\n", xslope, zslope); + + if (viewz < floorz) + shadowyscale += FixedMul(FixedMul(thing->radius*2 / patch->height, scalemul), zslope); + else + shadowyscale -= FixedMul(FixedMul(thing->radius*2 / patch->height, scalemul), zslope); + + shadowyscale = abs(shadowyscale); + + shadowskew = xslope; + } tx -= patch->width * shadowxscale/2; x1 = (centerxfrac + FixedMul(tx,xscale))>>FRACBITS; @@ -1164,6 +1216,7 @@ static void R_ProjectDropShadow(mobj_t *thing, vissprite_t *vis, fixed_t tx, fix shadow->gz = shadow->gzt - shadow->patch->height * shadowyscale; shadow->texturemid = FixedDiv(shadow->gzt - viewz, shadowyscale); shadow->scalestep = 0; + shadow->paperdistance = shadowskew; // repurposed variable shadow->mobj = thing; // Easy access! Tails 06-07-2002 @@ -1183,6 +1236,10 @@ static void R_ProjectDropShadow(mobj_t *thing, vissprite_t *vis, fixed_t tx, fix if (shadow->x1 > x1) shadow->startfrac += shadow->xiscale*(shadow->x1-x1); + // reusing x1 variable + x1 += (x2-x1)/2; + shadow->paperoffset = (vis->x1-x1)/2; + if (thing->subsector->sector->numlights) { INT32 lightnum; @@ -1878,6 +1935,7 @@ static void R_ProjectPrecipitationSprite(precipmobj_t *thing) vis->pzt = vis->pz + vis->thingheight; vis->texturemid = vis->gzt - viewz; vis->scalestep = 0; + vis->paperdistance = 0; vis->x1 = x1 < 0 ? 0 : x1; vis->x2 = x2 >= viewwidth ? viewwidth-1 : x2; From c078ab630d83b5bc18d4e0ba4c5db3571be8706a Mon Sep 17 00:00:00 2001 From: fickleheart Date: Sun, 29 Dec 2019 20:45:07 -0600 Subject: [PATCH 676/746] Fix more shadow crashes and save my sanity --- src/r_things.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/r_things.c b/src/r_things.c index 628239957..4db6cae58 100644 --- a/src/r_things.c +++ b/src/r_things.c @@ -1231,7 +1231,8 @@ static void R_ProjectDropShadow(mobj_t *thing, vissprite_t *vis, fixed_t tx, fix shadow->cut = SC_ISSCALED|SC_SHADOW; //check this shadow->startfrac = 0; - shadow->xiscale = 0x7ffffff0 / (shadow->xscale/2); + //shadow->xiscale = 0x7ffffff0 / (shadow->xscale/2); + shadow->xiscale = (patch->width<x1 > x1) shadow->startfrac += shadow->xiscale*(shadow->x1-x1); From 8757194d7347ba15fa7b25a7c66a509e123e19d0 Mon Sep 17 00:00:00 2001 From: fickleheart Date: Sun, 29 Dec 2019 20:53:28 -0600 Subject: [PATCH 677/746] Make ring shadows smaller and fix scale bug --- src/r_things.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/r_things.c b/src/r_things.c index 4db6cae58..e6d0d53e6 100644 --- a/src/r_things.c +++ b/src/r_things.c @@ -1161,6 +1161,10 @@ static void R_ProjectDropShadow(mobj_t *thing, vissprite_t *vis, fixed_t tx, fix scalemul = FRACUNIT - floordiff/640; + //@TODO make this configurable instead of hardcoding to the ring + if (thing->type == MT_RING) + scalemul = scalemul*2/3; + patch = W_CachePatchNum(sprites[SPR_THOK].spriteframes[0].lumppat[0], PU_CACHE); xscale = FixedDiv(projection, tz); yscale = FixedDiv(projectiony, tz); @@ -1214,7 +1218,7 @@ static void R_ProjectDropShadow(mobj_t *thing, vissprite_t *vis, fixed_t tx, fix shadow->gy = thing->y; shadow->gzt = shadow->pz + shadow->patch->height * shadowyscale / 2; shadow->gz = shadow->gzt - shadow->patch->height * shadowyscale; - shadow->texturemid = FixedDiv(shadow->gzt - viewz, shadowyscale); + shadow->texturemid = FixedMul(thing->scale, FixedDiv(shadow->gzt - viewz, shadowyscale)); shadow->scalestep = 0; shadow->paperdistance = shadowskew; // repurposed variable From ef4974ab4dfd1d6551079cb6d157cbe4fdfd301f Mon Sep 17 00:00:00 2001 From: fickleheart Date: Sun, 29 Dec 2019 22:15:01 -0600 Subject: [PATCH 678/746] Apply portal clipping to drop shadows too --- src/r_things.c | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/src/r_things.c b/src/r_things.c index e6d0d53e6..1f48bcb52 100644 --- a/src/r_things.c +++ b/src/r_things.c @@ -1227,6 +1227,15 @@ static void R_ProjectDropShadow(mobj_t *thing, vissprite_t *vis, fixed_t tx, fix shadow->x1 = x1 < 0 ? 0 : x1; shadow->x2 = x2 >= viewwidth ? viewwidth-1 : x2; + // PORTAL SEMI-CLIPPING + if (portalrender) + { + if (shadow->x1 < portalclipstart) + shadow->x1 = portalclipstart; + if (shadow->x2 >= portalclipend) + shadow->x2 = portalclipend-1; + } + shadow->xscale = FixedMul(xscale, shadowxscale); //SoM: 4/17/2000 shadow->scale = FixedMul(yscale, shadowyscale); shadow->sector = vis->sector; From a7edf51cb9fbfaa36bd6208dfbc2b5783a5c120b Mon Sep 17 00:00:00 2001 From: fickleheart Date: Wed, 8 Jan 2020 21:52:10 -0600 Subject: [PATCH 679/746] Stop misusing papersprite vars for sprite skew --- src/r_things.c | 12 ++++++++---- src/r_things.h | 5 +++++ 2 files changed, 13 insertions(+), 4 deletions(-) diff --git a/src/r_things.c b/src/r_things.c index 1f48bcb52..ca3993322 100644 --- a/src/r_things.c +++ b/src/r_things.c @@ -876,7 +876,7 @@ static void R_DrawVisSprite(vissprite_t *vis) if (!(vis->scalestep)) { sprtopscreen = centeryfrac - FixedMul(dc_texturemid, spryscale); - sprtopscreen += vis->paperdistance * vis->paperoffset; + sprtopscreen += vis->shear.tan * vis->shear.offset; dc_iscale = FixedDiv(FRACUNIT, vis->scale); } @@ -922,7 +922,7 @@ static void R_DrawVisSprite(vissprite_t *vis) else { // Non-paper drawing loop - for (dc_x = vis->x1; dc_x <= vis->x2; dc_x++, frac += vis->xiscale, sprtopscreen += vis->paperdistance) + for (dc_x = vis->x1; dc_x <= vis->x2; dc_x++, frac += vis->xiscale, sprtopscreen += vis->shear.tan) { #ifdef RANGECHECK texturecolumn = frac>>FRACBITS; @@ -1220,7 +1220,7 @@ static void R_ProjectDropShadow(mobj_t *thing, vissprite_t *vis, fixed_t tx, fix shadow->gz = shadow->gzt - shadow->patch->height * shadowyscale; shadow->texturemid = FixedMul(thing->scale, FixedDiv(shadow->gzt - viewz, shadowyscale)); shadow->scalestep = 0; - shadow->paperdistance = shadowskew; // repurposed variable + shadow->shear.tan = shadowskew; // repurposed variable shadow->mobj = thing; // Easy access! Tails 06-07-2002 @@ -1252,7 +1252,7 @@ static void R_ProjectDropShadow(mobj_t *thing, vissprite_t *vis, fixed_t tx, fix // reusing x1 variable x1 += (x2-x1)/2; - shadow->paperoffset = (vis->x1-x1)/2; + shadow->shear.offset = (vis->x1-x1)/2; if (thing->subsector->sector->numlights) { @@ -1723,6 +1723,8 @@ static void R_ProjectSprite(mobj_t *thing) vis->paperoffset = paperoffset; vis->paperdistance = paperdistance; vis->centerangle = centerangle; + vis->shear.tan = 0; + vis->shear.offset = 0; vis->mobj = thing; // Easy access! Tails 06-07-2002 @@ -1950,6 +1952,8 @@ static void R_ProjectPrecipitationSprite(precipmobj_t *thing) vis->texturemid = vis->gzt - viewz; vis->scalestep = 0; vis->paperdistance = 0; + vis->shear.tan = 0; + vis->shear.offset = 0; vis->x1 = x1 < 0 ? 0 : x1; vis->x2 = x2 >= viewwidth ? viewwidth-1 : x2; diff --git a/src/r_things.h b/src/r_things.h index a6ef92802..12f0008eb 100644 --- a/src/r_things.h +++ b/src/r_things.h @@ -187,6 +187,11 @@ typedef struct vissprite_s angle_t centerangle; // for paper sprites + struct { + fixed_t tan; // The amount to shear the sprite vertically per row + INT32 offset; // The center of the shearing location offset from x1 + } shear; + fixed_t texturemid; patch_t *patch; From 0f8c7361880c6147c4b46f7724da9d229793380f Mon Sep 17 00:00:00 2001 From: James R Date: Wed, 8 Jan 2020 20:49:38 -0800 Subject: [PATCH 680/746] Don't make player transparent if the orbital camera is looking straight down --- src/p_user.c | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/src/p_user.c b/src/p_user.c index 20fbc99f4..5bce0535d 100644 --- a/src/p_user.c +++ b/src/p_user.c @@ -10293,7 +10293,13 @@ boolean P_MoveChaseCamera(player_t *player, camera_t *thiscam, boolean resetcall vy = player->awayviewmobj->y; } - if (P_AproxDistance(vx - mo->x, vy - mo->y) < FixedMul(48*FRACUNIT, mo->scale)) + /* + When the orbital camera looks straight down, its distance + will be very close to the player. So give it a threshold... + */ + if (( !( camorbit && rendermode == render_opengl ) || + focusaiming < ANGLE_90 || focusaiming > ANGLE_292h ) && + P_AproxDistance(vx - mo->x, vy - mo->y) < FixedMul(48*FRACUNIT, mo->scale)) mo->flags2 |= MF2_SHADOW; else mo->flags2 &= ~MF2_SHADOW; From 66cf1be0d85a879c844f89299ed9afb884217cf3 Mon Sep 17 00:00:00 2001 From: James R Date: Wed, 8 Jan 2020 20:52:34 -0800 Subject: [PATCH 681/746] Don't clip player MD2 either! --- src/hardware/hw_main.c | 18 ++++++++++++++++-- 1 file changed, 16 insertions(+), 2 deletions(-) diff --git a/src/hardware/hw_main.c b/src/hardware/hw_main.c index e8d16c092..78cdc70cc 100644 --- a/src/hardware/hw_main.c +++ b/src/hardware/hw_main.c @@ -5486,6 +5486,7 @@ static void HWR_ProjectSprite(mobj_t *thing) spritedef_t *sprdef; spriteframe_t *sprframe; spriteinfo_t *sprinfo; + md2_t *md2; size_t lumpoff; unsigned rot; UINT8 flip; @@ -5522,8 +5523,21 @@ static void HWR_ProjectSprite(mobj_t *thing) tz = (tr_x * gr_viewcos) + (tr_y * gr_viewsin); // thing is behind view plane? - if (tz < ZCLIP_PLANE && !papersprite && (!cv_grmodels.value || md2_models[thing->sprite].notfound == true)) //Yellow: Only MD2's dont disappear - return; + if (tz < ZCLIP_PLANE && !papersprite) + { + if (cv_grmodels.value) //Yellow: Only MD2's dont disappear + { + if (thing->skin && thing->sprite == SPR_PLAY) + md2 = &md2_playermodels[( (skin_t *)thing->skin - skins )]; + else + md2 = &md2_models[thing->sprite]; + + if (md2->notfound || md2->scale < 0.0f) + return; + } + else + return; + } // The above can stay as it works for cutting sprites that are too close tr_x = FIXED_TO_FLOAT(thing->x); From fa4b49d52cb75abd06cee204a1ac0678c919afc8 Mon Sep 17 00:00:00 2001 From: fickleheart Date: Wed, 8 Jan 2020 23:19:52 -0600 Subject: [PATCH 682/746] Refactor shadow floor finding code a bit I tried to fix ring shadows on polyobjects and got this in return: https://media.discordapp.net/attachments/629477786943356938/664695818913185822/srb20156.png --- src/r_things.c | 160 +++++++++++++++++++++++++++++++++++-------------- src/r_things.h | 2 + 2 files changed, 117 insertions(+), 45 deletions(-) diff --git a/src/r_things.c b/src/r_things.c index ca3993322..018f5d37f 100644 --- a/src/r_things.c +++ b/src/r_things.c @@ -1095,6 +1095,120 @@ static void R_SplitSprite(vissprite_t *sprite) } } +// +// R_GetShadowZ(thing, shadowslope) +// Get the first visible floor below the object for shadows +// shadowslope is filled with the floor's slope, if provided +// +fixed_t R_GetShadowZ(mobj_t *thing, pslope_t **shadowslope) +{ + fixed_t z, floorz = INT32_MIN; + pslope_t *slope, *floorslope = NULL; + msecnode_t *node; + sector_t *sector; + ffloor_t *rover; + + for (node = thing->touching_sectorlist; node; node = node->m_sectorlist_next) + { + sector = node->m_sector; + + slope = (sector->heightsec != -1) ? NULL : sector->f_slope; + z = slope ? P_GetZAt(slope, thing->x, thing->y) : ( + (sector->heightsec != -1) ? sectors[sector->heightsec].floorheight : sector->floorheight + ); + + if (z < thing->z+thing->height/2 && z > floorz) + { + floorz = z; + floorslope = slope; + } + + if (sector->ffloors) + for (rover = sector->ffloors; rover; rover = rover->next) + { + if (!(rover->flags & FF_EXISTS) || !(rover->flags & FF_RENDERPLANES) || (rover->alpha < 90 && !(rover->flags & FF_SWIMMABLE))) + continue; + + z = *rover->t_slope ? P_GetZAt(*rover->t_slope, thing->x, thing->y) : *rover->topheight; + if (z < thing->z+thing->height/2 && z > floorz) + { + floorz = z; + floorslope = *rover->t_slope; + } + } + } + + if (thing->floorz > floorz + (!floorslope ? 0 : FixedMul(abs(floorslope->zdelta), thing->radius*3/2))) + { + floorz = thing->floorz; + floorslope = NULL; + } + +#if 0 // Unfortunately, this drops CEZ2 down to sub-17 FPS on my i7. +//#ifdef POLYOBJECTS + // Check polyobjects and see if floorz needs to be altered, for rings only because they don't update floorz + if (thing->type == MT_RING) + { + INT32 xl, xh, yl, yh, bx, by; + + xl = (unsigned)(thing->x - thing->radius - bmaporgx)>>MAPBLOCKSHIFT; + xh = (unsigned)(thing->x + thing->radius - bmaporgx)>>MAPBLOCKSHIFT; + yl = (unsigned)(thing->y - thing->radius - bmaporgy)>>MAPBLOCKSHIFT; + yh = (unsigned)(thing->y + thing->radius - bmaporgy)>>MAPBLOCKSHIFT; + + BMBOUNDFIX(xl, xh, yl, yh); + + validcount++; + + for (by = yl; by <= yh; by++) + for (bx = xl; bx <= xh; bx++) + { + INT32 offset; + polymaplink_t *plink; // haleyjd 02/22/06 + + if (bx < 0 || by < 0 || bx >= bmapwidth || by >= bmapheight) + continue; + + offset = by*bmapwidth + bx; + + // haleyjd 02/22/06: consider polyobject lines + plink = polyblocklinks[offset]; + + while (plink) + { + polyobj_t *po = plink->po; + + if (po->validcount != validcount) // if polyobj hasn't been checked + { + po->validcount = validcount; + + if (!P_MobjInsidePolyobj(po, thing) || !(po->flags & POF_RENDERPLANES)) + { + plink = (polymaplink_t *)(plink->link.next); + continue; + } + + // We're inside it! Yess... + z = po->lines[0]->backsector->ceilingheight; + + if (z < thing->z+thing->height/2 && z > floorz) + { + floorz = z; + floorslope = NULL; + } + } + plink = (polymaplink_t *)(plink->link.next); + } + } + } +#endif + + if (shadowslope != NULL) + *shadowslope = floorslope; + + return floorz; +} + static void R_ProjectDropShadow(mobj_t *thing, vissprite_t *vis, fixed_t tx, fixed_t tz) { vissprite_t *shadow; @@ -1106,51 +1220,7 @@ static void R_ProjectDropShadow(mobj_t *thing, vissprite_t *vis, fixed_t tx, fix fixed_t floorz; pslope_t *floorslope; - // Get floorz as the first floor below the object that's visible - floorz = (vis->heightsec != -1) ? sectors[vis->heightsec].floorheight : thing->floorz; - floorslope = (vis->heightsec != -1) ? NULL : thing->standingslope; - - { - boolean original = true; - fixed_t z; - - if (vis->sector->ffloors) - { - ffloor_t *rover = vis->sector->ffloors; - - for (; rover; rover = rover->next) - { - if (!(rover->flags & FF_EXISTS) || !(rover->flags & FF_RENDERPLANES) || (rover->alpha < 90 && !(rover->flags & FF_SWIMMABLE))) - continue; - - z = *rover->t_slope ? P_GetZAt(*rover->t_slope, thing->x, thing->y) : *rover->topheight; - if (z < thing->z+thing->height/3 && z > floorz) - { - floorz = z; - floorslope = *rover->t_slope; - original = false; - } - else if (original && (*rover->t_slope) && z < thing->z+thing->height/3 && z > floorz - FixedMul(abs((*rover->t_slope)->zdelta), thing->radius*2)) - { - // Guesstimated to be a usable floor. This is here to handle floorslope of non-grounded things, I guess. - floorz = z; - floorslope = *rover->t_slope; - original = false; - } - } - } - - if (original && vis->sector->f_slope) - { - z = P_GetZAt(vis->sector->f_slope, thing->x, thing->y); - if (z < thing->z+thing->height/3 && z > floorz - FixedMul(abs(vis->sector->f_slope->zdelta), thing->radius*2)) - { - floorz = z; - floorslope = vis->sector->f_slope; - } - } - } - + floorz = R_GetShadowZ(thing, &floorslope); if (abs(floorz-viewz)/tz > 4) return; // Prevent stretchy shadows and possible crashes diff --git a/src/r_things.h b/src/r_things.h index 12f0008eb..5649b226b 100644 --- a/src/r_things.h +++ b/src/r_things.h @@ -55,6 +55,8 @@ void R_DrawFlippedMaskedColumn(column_t *column, INT32 texheight); // (only sprites from namelist are added or replaced) void R_AddSpriteDefs(UINT16 wadnum); +fixed_t R_GetShadowZ(mobj_t *thing, pslope_t **shadowslope); + //SoM: 6/5/2000: Light sprites correctly! void R_AddSprites(sector_t *sec, INT32 lightlevel); void R_InitSprites(void); From 9e8d20504e6f25b5d10b1c44731a2ef696dc4554 Mon Sep 17 00:00:00 2001 From: fickleheart Date: Wed, 8 Jan 2020 23:24:31 -0600 Subject: [PATCH 683/746] Refactor shadow scale into an argument --- src/r_things.c | 15 +++++++-------- 1 file changed, 7 insertions(+), 8 deletions(-) diff --git a/src/r_things.c b/src/r_things.c index 018f5d37f..f2b205429 100644 --- a/src/r_things.c +++ b/src/r_things.c @@ -1209,7 +1209,7 @@ fixed_t R_GetShadowZ(mobj_t *thing, pslope_t **shadowslope) return floorz; } -static void R_ProjectDropShadow(mobj_t *thing, vissprite_t *vis, fixed_t tx, fixed_t tz) +static void R_ProjectDropShadow(mobj_t *thing, vissprite_t *vis, fixed_t scale, fixed_t tx, fixed_t tz) { vissprite_t *shadow; patch_t *patch; @@ -1229,11 +1229,7 @@ static void R_ProjectDropShadow(mobj_t *thing, vissprite_t *vis, fixed_t tx, fix trans = floordiff / (100*FRACUNIT) + 3; if (trans >= 9) return; - scalemul = FRACUNIT - floordiff/640; - - //@TODO make this configurable instead of hardcoding to the ring - if (thing->type == MT_RING) - scalemul = scalemul*2/3; + scalemul = FixedMul(FRACUNIT - floordiff/640, scale); patch = W_CachePatchNum(sprites[SPR_THOK].spriteframes[0].lumppat[0], PU_CACHE); xscale = FixedDiv(projection, tz); @@ -1887,7 +1883,7 @@ static void R_ProjectSprite(mobj_t *thing) if (thing->subsector->sector->numlights) R_SplitSprite(vis); - // temporary: whitelist. eventually: MF/2/E flag? + ///@TODO temporary: whitelist. eventually: MF/2/E flag? if (( oldthing->type == MT_PLAYER || (oldthing->state - states) == S_RING || @@ -1896,7 +1892,10 @@ static void R_ProjectSprite(mobj_t *thing) oldthing->type == MT_EGGMOBILE4_MACE || (oldthing->type >= MT_SMALLMACE && oldthing->type <= MT_REDSPRINGBALL) // .W. ) && !papersprite) - R_ProjectDropShadow(oldthing, vis, basetx, tz); + R_ProjectDropShadow(oldthing, vis, + ///@TODO make this scale configurable! + ((oldthing->state - states) == S_RING) ? 2*FRACUNIT/3 : FRACUNIT, + basetx, tz); // Debug ++objectsdrawn; From 7d2402ac62d5c4a8871aa2f89af5b60f8d5c8d45 Mon Sep 17 00:00:00 2001 From: fickleheart Date: Wed, 8 Jan 2020 23:33:43 -0600 Subject: [PATCH 684/746] Fix shadows under hiresscale characters --- src/r_things.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/r_things.c b/src/r_things.c index f2b205429..73c598549 100644 --- a/src/r_things.c +++ b/src/r_things.c @@ -1285,6 +1285,8 @@ static void R_ProjectDropShadow(mobj_t *thing, vissprite_t *vis, fixed_t scale, shadow->gzt = shadow->pz + shadow->patch->height * shadowyscale / 2; shadow->gz = shadow->gzt - shadow->patch->height * shadowyscale; shadow->texturemid = FixedMul(thing->scale, FixedDiv(shadow->gzt - viewz, shadowyscale)); + if (thing->skin && ((skin_t *)thing->skin)->flags & SF_HIRES) + shadow->texturemid = FixedMul(shadow->texturemid, ((skin_t *)thing->skin)->highresscale); shadow->scalestep = 0; shadow->shear.tan = shadowskew; // repurposed variable From 487e1b02f1fb3b3b018390c5505775c10d371e1f Mon Sep 17 00:00:00 2001 From: Sally Cochenour Date: Thu, 9 Jan 2020 01:28:14 -0500 Subject: [PATCH 685/746] Remove smooth setting It got denied before for Software so I won't include it in the merge request :( --- src/hardware/hw_main.c | 22 +++++----------------- 1 file changed, 5 insertions(+), 17 deletions(-) diff --git a/src/hardware/hw_main.c b/src/hardware/hw_main.c index 50b6fcbf5..9bfd75edc 100644 --- a/src/hardware/hw_main.c +++ b/src/hardware/hw_main.c @@ -1035,21 +1035,10 @@ static FUINT HWR_CalcWallLight(FUINT lightnum, fixed_t v1x, fixed_t v1y, fixed_t const UINT8 contrast = 8; fixed_t extralight = 0; - if (cv_grfakecontrast.value == 2) // Smooth setting - { - extralight = (-(contrast<> FRACBITS; - } - else - { - if (v1y == v2y) - extralight = -contrast; - else if (v1x == v2x) - extralight = contrast; - } + if (v1y == v2y) + extralight = -contrast; + else if (v1x == v2x) + extralight = contrast; if (extralight != 0) { @@ -6594,7 +6583,6 @@ static void HWR_FoggingOn(void) static CV_PossibleValue_t grsoftwarefog_cons_t[] = {{0, "Off"}, {1, "On"}, {2, "LightPlanes"}, {0, NULL}}; static CV_PossibleValue_t grmodelinterpolation_cons_t[] = {{0, "Off"}, {1, "Sometimes"}, {2, "Always"}, {0, NULL}}; -static CV_PossibleValue_t grfakecontrast_cons_t[] = {{0, "Off"}, {1, "On"}, {2, "Smooth"}, {0, NULL}}; static void CV_grmodellighting_OnChange(void); static void CV_grfiltermode_OnChange(void); @@ -6629,7 +6617,7 @@ consvar_t cv_grmodellighting = {"gr_modellighting", "Off", CV_SAVE|CV_CALL, CV_O consvar_t cv_grspritebillboarding = {"gr_spritebillboarding", "Off", CV_SAVE, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL}; consvar_t cv_grskydome = {"gr_skydome", "On", CV_SAVE, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL}; -consvar_t cv_grfakecontrast = {"gr_fakecontrast", "Smooth", CV_SAVE, grfakecontrast_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL}; +consvar_t cv_grfakecontrast = {"gr_fakecontrast", "On", CV_SAVE, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL}; consvar_t cv_grrounddown = {"gr_rounddown", "Off", 0, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL}; consvar_t cv_grfov = {"gr_fov", "90", CV_FLOAT|CV_CALL, grfov_cons_t, CV_grfov_OnChange, 0, NULL, NULL, 0, 0, NULL}; From 3e3cb48feba3bd7f777cd14acb1622771ca62cd4 Mon Sep 17 00:00:00 2001 From: Tatsuru <44866610+Ikkarin@users.noreply.github.com> Date: Thu, 9 Jan 2020 12:15:26 -0300 Subject: [PATCH 686/746] This is stupid --- src/dehacked.c | 1 + src/info.c | 29 ++++++++++++++++++++++++++++- src/info.h | 1 + 3 files changed, 30 insertions(+), 1 deletion(-) diff --git a/src/dehacked.c b/src/dehacked.c index 8220f5aa3..50b5c81da 100644 --- a/src/dehacked.c +++ b/src/dehacked.c @@ -8669,6 +8669,7 @@ static const char *const MOBJTYPE_LIST[] = { // array length left dynamic for s "MT_NIGHTSCHIP", // NiGHTS Chip "MT_FLINGNIGHTSCHIP", // Lost NiGHTS Chip "MT_NIGHTSSTAR", // NiGHTS Star + "MT_FLINGNIGHTSSTAR", // Lost NiGHTS Star "MT_NIGHTSSUPERLOOP", "MT_NIGHTSDRILLREFILL", "MT_NIGHTSHELPER", diff --git a/src/info.c b/src/info.c index 5f1cb8fbe..a5483d961 100644 --- a/src/info.c +++ b/src/info.c @@ -19791,7 +19791,7 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] = 1000, // spawnhealth S_NIGHTSSTARXMAS, // seestate sfx_None, // seesound - 8, // reactiontime + MT_FLINGNIGHTSSTAR, // reactiontime sfx_None, // attacksound S_NULL, // painstate 0, // painchance @@ -19811,6 +19811,33 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] = MF_SLIDEME|MF_SPECIAL|MF_NOGRAVITY|MF_NOCLIPHEIGHT, // flags S_NULL // raisestate }, + + { // MT_FLINGNIGHTSSTAR + -1, // doomednum + S_NIGHTSSTAR, // spawnstate + 1000, // spawnhealth + S_NIGHTSSTARXMAS, // seestate + sfx_None, // seesound + MT_FLINGNIGHTSSTAR, // reactiontime + sfx_None, // attacksound + S_NULL, // painstate + MT_NIGHTSSTAR, // painchance + sfx_s3k33, // painsound + S_RING, // meleestate + S_NULL, // missilestate + S_SPRK1, // deathstate + S_NULL, // xdeathstate + sfx_ncitem, // deathsound + 38*FRACUNIT, // speed + 16*FRACUNIT, // radius + 24*FRACUNIT, // height + 0, // display offset + 100, // mass + 0, // damage + sfx_None, // activesound + MF_SLIDEME|MF_SPECIAL, // flags + S_NULL // raisestate + }, { // MT_NIGHTSSUPERLOOP 1707, // doomednum diff --git a/src/info.h b/src/info.h index 261abbac5..324795d45 100644 --- a/src/info.h +++ b/src/info.h @@ -4702,6 +4702,7 @@ typedef enum mobj_type MT_NIGHTSCHIP, // NiGHTS Chip MT_FLINGNIGHTSCHIP, // Lost NiGHTS Chip MT_NIGHTSSTAR, // NiGHTS Star + MT_FLINGNIGHTSSTAR, // Lost NiGHTS Star MT_NIGHTSSUPERLOOP, MT_NIGHTSDRILLREFILL, MT_NIGHTSHELPER, From 10e9dd2c23929132b4175c9bebd2fec8dcd444da Mon Sep 17 00:00:00 2001 From: Tatsuru <44866610+Ikkarin@users.noreply.github.com> Date: Thu, 9 Jan 2020 16:16:24 -0300 Subject: [PATCH 687/746] *bends over seductively to pick up whitespace* --- src/info.c | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/src/info.c b/src/info.c index a5483d961..60913b519 100644 --- a/src/info.c +++ b/src/info.c @@ -19760,14 +19760,14 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] = { // MT_FLINGNIGHTSCHIP -1, // doomednum - S_NIGHTSCHIP, // spawnstate + S_NIGHTSCHIP, // spawnstate 1000, // spawnhealth S_NULL, // seestate sfx_None, // seesound - MT_FLINGNIGHTSCHIP, // reactiontime + MT_FLINGNIGHTSCHIP, // reactiontime sfx_None, // attacksound S_NULL, // painstate - MT_NIGHTSCHIP, // painchance + MT_NIGHTSCHIP, // painchance sfx_None, // painsound S_NULL, // meleestate S_NULL, // missilestate @@ -19791,7 +19791,7 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] = 1000, // spawnhealth S_NIGHTSSTARXMAS, // seestate sfx_None, // seesound - MT_FLINGNIGHTSSTAR, // reactiontime + MT_FLINGNIGHTSSTAR, // reactiontime sfx_None, // attacksound S_NULL, // painstate 0, // painchance @@ -19818,21 +19818,21 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] = 1000, // spawnhealth S_NIGHTSSTARXMAS, // seestate sfx_None, // seesound - MT_FLINGNIGHTSSTAR, // reactiontime + MT_FLINGNIGHTSSTAR, // reactiontime sfx_None, // attacksound S_NULL, // painstate - MT_NIGHTSSTAR, // painchance + MT_NIGHTSSTAR, // painchance sfx_s3k33, // painsound S_RING, // meleestate S_NULL, // missilestate S_SPRK1, // deathstate S_NULL, // xdeathstate sfx_ncitem, // deathsound - 38*FRACUNIT, // speed + 38*FRACUNIT, // speed 16*FRACUNIT, // radius 24*FRACUNIT, // height 0, // display offset - 100, // mass + 100, // mass 0, // damage sfx_None, // activesound MF_SLIDEME|MF_SPECIAL, // flags From 71c2ee38501df6773e085d7a9de6f74a94647465 Mon Sep 17 00:00:00 2001 From: Alam Ed Arias Date: Thu, 9 Jan 2020 16:19:12 -0500 Subject: [PATCH 688/746] whitespace cleanup --- src/p_map.c | 2 +- src/p_mobj.c | 2 +- src/p_user.c | 4 ++-- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/p_map.c b/src/p_map.c index b6f532124..40fee7b46 100644 --- a/src/p_map.c +++ b/src/p_map.c @@ -2005,7 +2005,7 @@ static boolean PIT_CheckLine(line_t *ld) if (lowfloor < tmdropoffz) tmdropoffz = lowfloor; - + return true; } diff --git a/src/p_mobj.c b/src/p_mobj.c index b771103a9..f281db50d 100644 --- a/src/p_mobj.c +++ b/src/p_mobj.c @@ -7977,7 +7977,7 @@ static void P_MobjSceneryThink(mobj_t *mobj) mobj->x = mobj->extravalue1 + P_ReturnThrustX(mobj, mobj->movedir, mobj->cvmem*mobj->scale); mobj->y = mobj->extravalue2 + P_ReturnThrustY(mobj, mobj->movedir, mobj->cvmem*mobj->scale); P_SetThingPosition(mobj); - + if (!mobj->fuse) { #ifdef HAVE_BLUA diff --git a/src/p_user.c b/src/p_user.c index c5024d7ec..b40e647b6 100644 --- a/src/p_user.c +++ b/src/p_user.c @@ -349,11 +349,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_NIGHTSMODE) players[i].powers[pw_carry] = CR_NONE; - + P_SetTarget(&players[i].mo->tracer, emmo); if (pnum == 255) From 3179797331b37870a3f500ac016a68551d4d9c20 Mon Sep 17 00:00:00 2001 From: James R Date: Thu, 9 Jan 2020 22:16:46 -0800 Subject: [PATCH 689/746] Let Escape close the console --- src/console.c | 2 +- src/d_main.c | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/src/console.c b/src/console.c index 01d1ddaa2..5a74c85b6 100644 --- a/src/console.c +++ b/src/console.c @@ -777,7 +777,7 @@ boolean CON_Responder(event_t *ev) // check for console toggle key if (ev->type != ev_console) { - if (modeattacking || metalrecording) + if (modeattacking || metalrecording || menuactive) return false; if (key == gamecontrol[gc_console][0] || key == gamecontrol[gc_console][1]) diff --git a/src/d_main.c b/src/d_main.c index e55c65bbb..62ec9e449 100644 --- a/src/d_main.c +++ b/src/d_main.c @@ -188,14 +188,14 @@ void D_ProcessEvents(void) continue; } - // Menu input - if (M_Responder(ev)) - continue; // menu ate the event - // console input if (CON_Responder(ev)) continue; // ate the event + // Menu input + if (M_Responder(ev)) + continue; // menu ate the event + G_Responder(ev); } } From 48dd6b0580333dcb1348c829e0d6e44d9718674e Mon Sep 17 00:00:00 2001 From: James R Date: Thu, 9 Jan 2020 22:39:01 -0800 Subject: [PATCH 690/746] Show Sonic's ass if con_backpic. No wait, I mean crop the backpic... --- src/console.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/src/console.c b/src/console.c index 01d1ddaa2..fa91828ce 100644 --- a/src/console.c +++ b/src/console.c @@ -1551,9 +1551,14 @@ static void CON_DrawConsole(void) if (cons_backpic.value || con_forcepic) { patch_t *con_backpic = W_CachePatchName("CONSBACK", PU_PATCH); + int h; + + h = con_curlines/vid.dupy; // Jimita: CON_DrawBackpic just called V_DrawScaledPatch - V_DrawScaledPatch(0, 0, 0, con_backpic); + //V_DrawScaledPatch(0, 0, 0, con_backpic); + V_DrawCroppedPatch(0, 0, FRACUNIT, 0, con_backpic, + 0, ( BASEVIDHEIGHT - h ), BASEVIDWIDTH, h); W_UnlockCachedPatch(con_backpic); } From ef3d462eb7d6de12fb950894e3fa6aaece75ef1c Mon Sep 17 00:00:00 2001 From: James R Date: Thu, 9 Jan 2020 22:42:00 -0800 Subject: [PATCH 691/746] Let the console open in menus --- src/console.c | 11 +---------- src/d_main.c | 15 +++++++-------- 2 files changed, 8 insertions(+), 18 deletions(-) diff --git a/src/console.c b/src/console.c index fa91828ce..2488ac80a 100644 --- a/src/console.c +++ b/src/console.c @@ -612,15 +612,6 @@ void CON_Ticker(void) con_tick++; con_tick &= 7; - // if the menu is open then close the console. - if (menuactive && con_destlines) - { - consoletoggle = false; - con_destlines = 0; - CON_ClearHUD(); - I_UpdateMouseGrab(); - } - // console key was pushed if (consoletoggle) { @@ -792,7 +783,7 @@ boolean CON_Responder(event_t *ev) // check other keys only if console prompt is active if (!consoleready && key < NUMINPUTS) // metzgermeister: boundary check!! { - if (bindtable[key]) + if (! menuactive && bindtable[key]) { COM_BufAddText(bindtable[key]); COM_BufAddText("\n"); diff --git a/src/d_main.c b/src/d_main.c index e55c65bbb..f5390e2df 100644 --- a/src/d_main.c +++ b/src/d_main.c @@ -188,14 +188,14 @@ void D_ProcessEvents(void) continue; } - // Menu input - if (M_Responder(ev)) - continue; // menu ate the event - // console input if (CON_Responder(ev)) continue; // ate the event + // Menu input + if (M_Responder(ev)) + continue; // menu ate the event + G_Responder(ev); } } @@ -502,13 +502,12 @@ static void D_Display(void) // vid size change is now finished if it was on... vid.recalc = 0; - // FIXME: draw either console or menu, not the two - if (gamestate != GS_TIMEATTACK) - CON_Drawer(); - M_Drawer(); // menu is drawn even on top of everything // focus lost moved to M_Drawer + if (gamestate != GS_TIMEATTACK) + CON_Drawer(); + // // wipe update // From 2459ca255f6df5b5e5767aa3813fceed07ab1cd7 Mon Sep 17 00:00:00 2001 From: James R Date: Fri, 10 Jan 2020 00:04:17 -0800 Subject: [PATCH 692/746] Factor z distance into camera translucency --- src/p_user.c | 12 +++++------- 1 file changed, 5 insertions(+), 7 deletions(-) diff --git a/src/p_user.c b/src/p_user.c index 5bce0535d..5b7e50995 100644 --- a/src/p_user.c +++ b/src/p_user.c @@ -10287,19 +10287,17 @@ boolean P_MoveChaseCamera(player_t *player, camera_t *thiscam, boolean resetcall if (!(multiplayer || netgame) && !splitscreen) { fixed_t vx = thiscam->x, vy = thiscam->y; + fixed_t vz = thiscam->z + thiscam->height / 2; if (player->awayviewtics && player->awayviewmobj != NULL && !P_MobjWasRemoved(player->awayviewmobj)) // Camera must obviously exist { vx = player->awayviewmobj->x; vy = player->awayviewmobj->y; + vz = player->awayviewmobj->z + player->awayviewmobj->height / 2; } - /* - When the orbital camera looks straight down, its distance - will be very close to the player. So give it a threshold... - */ - if (( !( camorbit && rendermode == render_opengl ) || - focusaiming < ANGLE_90 || focusaiming > ANGLE_292h ) && - P_AproxDistance(vx - mo->x, vy - mo->y) < FixedMul(48*FRACUNIT, mo->scale)) + /* check z distance too for orbital camera */ + if (P_AproxDistance(P_AproxDistance(vx - mo->x, vy - mo->y), + vz - ( mo->z + mo->height / 2 )) < FixedMul(48*FRACUNIT, mo->scale)) mo->flags2 |= MF2_SHADOW; else mo->flags2 &= ~MF2_SHADOW; From 80b801e91e540dfb88a5cff25cb99f85b975e501 Mon Sep 17 00:00:00 2001 From: toaster Date: Fri, 10 Jan 2020 11:43:41 +0000 Subject: [PATCH 693/746] Mario brick blocks are likely to always have square sectors dividing seperate bricks, so allow them to be busted individually. --- src/p_mobj.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/p_mobj.c b/src/p_mobj.c index 7d83fffb0..a4231fa74 100644 --- a/src/p_mobj.c +++ b/src/p_mobj.c @@ -3127,7 +3127,7 @@ nightsdone: { // DO THE MARIO! if (rover->flags & FF_SHATTERBOTTOM) // Brick block! - EV_CrumbleChain(NULL, rover); // node->m_sector + EV_CrumbleChain(node->m_sector, rover); else // Question block! EV_MarioBlock(rover, node->m_sector, mo); } From cbbc76b673e9d4f87459881cffcb39a87d9de4ef Mon Sep 17 00:00:00 2001 From: toaster Date: Fri, 10 Jan 2020 12:50:58 +0000 Subject: [PATCH 694/746] Fix snapping of extra multiplayer text. (Resolves #101) --- 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 68803b665..4676506fc 100644 --- a/src/st_stuff.c +++ b/src/st_stuff.c @@ -2208,7 +2208,7 @@ static void ST_drawTextHUD(void) #define textHUDdraw(str) \ {\ - V_DrawThinString(16, y, V_PERPLAYER|V_HUDTRANS|V_SNAPTOLEFT|V_SNAPTOBOTTOM, str);\ + V_DrawThinString(16, y, V_PERPLAYER|V_HUDTRANS|V_SNAPTOLEFT|V_SNAPTOTOP, str);\ y += 8;\ } From ba7a1c0375b37f34b627bcb9027e990881284c0c Mon Sep 17 00:00:00 2001 From: MascaraSnake Date: Fri, 10 Jan 2020 19:56:29 +0100 Subject: [PATCH 695/746] Some minor cleanup --- src/p_setup.c | 2 +- src/p_slopes.c | 19 +++++++++---------- src/p_spec.c | 2 +- 3 files changed, 11 insertions(+), 12 deletions(-) diff --git a/src/p_setup.c b/src/p_setup.c index a2872cf4b..f1b12b2f9 100644 --- a/src/p_setup.c +++ b/src/p_setup.c @@ -3578,7 +3578,7 @@ boolean P_LoadLevel(boolean fromnetsave) return false; // init gravity, tag lists, - // anything that P_ResetDynamicSlopes/P_LoadThings needs to know + // anything that P_SpawnSlopes/P_LoadThings needs to know P_InitSpecials(); #ifdef ESLOPE diff --git a/src/p_slopes.c b/src/p_slopes.c index 13b283af6..18489c65e 100644 --- a/src/p_slopes.c +++ b/src/p_slopes.c @@ -508,7 +508,7 @@ static void line_SpawnViaVertexes(const int linenum, const boolean spawnthinker) } /// Spawn textmap vertex slopes. -static void SpawnVertexSlopes (void) +static void SpawnVertexSlopes(void) { line_t *l1, *l2; sector_t* sc; @@ -534,10 +534,10 @@ static void SpawnVertexSlopes (void) if (v1->floorzset || v2->floorzset || v3->floorzset) { vector3_t vtx[3] = { - {v1->x, v1->y, v1->floorzset == true ? v1->floorz : sc->floorheight}, - {v2->x, v2->y, v2->floorzset == true ? v2->floorz : sc->floorheight}, - {v3->x, v3->y, v3->floorzset == true ? v3->floorz : sc->floorheight}}; - pslope_t* slop = Slope_Add(0); + {v1->x, v1->y, v1->floorzset ? v1->floorz : sc->floorheight}, + {v2->x, v2->y, v2->floorzset ? v2->floorz : sc->floorheight}, + {v3->x, v3->y, v3->floorzset ? v3->floorz : sc->floorheight}}; + pslope_t *slop = Slope_Add(0); sc->f_slope = slop; sc->hasslope = true; ReconfigureViaVertexes(slop, vtx[0], vtx[1], vtx[2]); @@ -546,15 +546,14 @@ static void SpawnVertexSlopes (void) if (v1->ceilingzset || v2->ceilingzset || v3->ceilingzset) { vector3_t vtx[3] = { - {v1->x, v1->y, v1->ceilingzset == true ? v1->ceilingz : sc->ceilingheight}, - {v2->x, v2->y, v2->ceilingzset == true ? v2->ceilingz : sc->ceilingheight}, - {v3->x, v3->y, v3->ceilingzset == true ? v3->ceilingz : sc->ceilingheight}}; - pslope_t* slop = Slope_Add(0); + {v1->x, v1->y, v1->ceilingzset ? v1->ceilingz : sc->ceilingheight}, + {v2->x, v2->y, v2->ceilingzset ? v2->ceilingz : sc->ceilingheight}, + {v3->x, v3->y, v3->ceilingzset ? v3->ceilingz : sc->ceilingheight}}; + pslope_t *slop = Slope_Add(0); sc->c_slope = slop; sc->hasslope = true; ReconfigureViaVertexes(slop, vtx[0], vtx[1], vtx[2]); } - } } diff --git a/src/p_spec.c b/src/p_spec.c index 00a71602b..75cdb0cf1 100644 --- a/src/p_spec.c +++ b/src/p_spec.c @@ -6353,7 +6353,7 @@ static void P_RunLevelLoadExecutors(void) } /** Before things are loaded, initialises certain stuff in case they're needed - * by P_ResetDynamicSlopes or P_LoadThings. This was split off from + * by P_SpawnSlopes or P_LoadThings. This was split off from * P_SpawnSpecials, in case you couldn't tell. * * \sa P_SpawnSpecials, P_InitTagLists From 1113a13621a549fa180910f0767592e51a5f43a8 Mon Sep 17 00:00:00 2001 From: James R Date: Fri, 10 Jan 2020 12:55:03 -0800 Subject: [PATCH 696/746] 1upsound always plays a sound instead of jingle --- src/p_user.c | 7 +++++++ src/s_sound.c | 9 +++++++++ src/s_sound.h | 2 ++ 3 files changed, 18 insertions(+) diff --git a/src/p_user.c b/src/p_user.c index a97e62052..f56b321e1 100644 --- a/src/p_user.c +++ b/src/p_user.c @@ -1463,6 +1463,13 @@ void P_PlayLivesJingle(player_t *player) S_StartSound(NULL, sfx_oneup); else if (mariomode) S_StartSound(NULL, sfx_marioa); + else if (cv_1upsound.value) + { + if (S_sfx[sfx_oneup].lumpnum != LUMPERROR) + S_StartSound(NULL, sfx_oneup); + else + S_StartSound(NULL, sfx_chchng);/* at least play something! */ + } else { P_PlayJingle(player, JT_1UP); diff --git a/src/s_sound.c b/src/s_sound.c index 0235d8376..019f5c765 100644 --- a/src/s_sound.c +++ b/src/s_sound.c @@ -117,6 +117,14 @@ static consvar_t surround = {"surround", "Off", CV_SAVE, CV_OnOff, NULL, 0, NULL consvar_t cv_resetmusic = {"resetmusic", "Off", CV_SAVE, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL}; consvar_t cv_resetmusicbyheader = {"resetmusicbyheader", "Yes", CV_SAVE, CV_YesNo, NULL, 0, NULL, NULL, 0, 0, NULL}; +static CV_PossibleValue_t cons_1upsound_t[] = { + {0, "Jingle"}, + {1, "Sound"}, + + {0} +}; +consvar_t cv_1upsound = {"1upsound", "Jingle", CV_SAVE, cons_1upsound_t, NULL, 0, NULL, NULL, 0, 0, NULL}; + // Sound system toggles, saved into the config consvar_t cv_gamedigimusic = {"digimusic", "On", CV_SAVE|CV_CALL|CV_NOINIT, CV_OnOff, GameDigiMusic_OnChange, 0, NULL, NULL, 0, 0, NULL}; consvar_t cv_gamemidimusic = {"midimusic", "On", CV_SAVE|CV_CALL|CV_NOINIT, CV_OnOff, GameMIDIMusic_OnChange, 0, NULL, NULL, 0, 0, NULL}; @@ -287,6 +295,7 @@ void S_RegisterSoundStuff(void) CV_RegisterVar(&cv_samplerate); CV_RegisterVar(&cv_resetmusic); CV_RegisterVar(&cv_resetmusicbyheader); + CV_RegisterVar(&cv_1upsound); CV_RegisterVar(&cv_playsoundsifunfocused); CV_RegisterVar(&cv_playmusicifunfocused); CV_RegisterVar(&cv_gamesounds); diff --git a/src/s_sound.h b/src/s_sound.h index 18f2d3743..9a4cbe48b 100644 --- a/src/s_sound.h +++ b/src/s_sound.h @@ -35,6 +35,8 @@ extern consvar_t cv_numChannels; extern consvar_t cv_resetmusic; extern consvar_t cv_resetmusicbyheader; +extern consvar_t cv_1upsound; + #define RESETMUSIC (!modeattacking && \ (cv_resetmusicbyheader.value ? \ (mapheaderinfo[gamemap-1]->musforcereset != -1 ? mapheaderinfo[gamemap-1]->musforcereset : cv_resetmusic.value) \ From 134d1831e3d7d4abfce8a562c11f7a202bd2bd1f Mon Sep 17 00:00:00 2001 From: James R Date: Fri, 10 Jan 2020 12:55:22 -0800 Subject: [PATCH 697/746] Menu option for 1upsound --- src/m_menu.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/m_menu.c b/src/m_menu.c index 5e6b6f8ba..0d19a6a43 100644 --- a/src/m_menu.c +++ b/src/m_menu.c @@ -1375,8 +1375,9 @@ static menuitem_t OP_SoundOptionsMenu[] = {IT_HEADER, NULL, "Miscellaneous", NULL, 102}, {IT_STRING | IT_CVAR, NULL, "Closed Captioning", &cv_closedcaptioning, 114}, {IT_STRING | IT_CVAR, NULL, "Reset Music Upon Dying", &cv_resetmusic, 124}, + {IT_STRING | IT_CVAR, NULL, "Default 1-Up sound", &cv_1upsound, 134}, - {IT_STRING | IT_SUBMENU, NULL, "Advanced Settings...", &OP_SoundAdvancedDef, 144}, + {IT_STRING | IT_SUBMENU, NULL, "Advanced Settings...", &OP_SoundAdvancedDef, 154}, }; #ifdef HAVE_OPENMPT From 2046f524c776b4f3d1fdd467499d5c07eea63050 Mon Sep 17 00:00:00 2001 From: MascaraSnake Date: Fri, 10 Jan 2020 23:32:31 +0100 Subject: [PATCH 698/746] Fix incorrect cast --- src/p_setup.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/p_setup.c b/src/p_setup.c index 9a924e67d..cfe141381 100644 --- a/src/p_setup.c +++ b/src/p_setup.c @@ -1105,8 +1105,8 @@ static void P_LoadSidedefs(UINT8 *data) if (((sd->line->flags & (ML_TWOSIDED|ML_EFFECT5)) == (ML_TWOSIDED|ML_EFFECT5)) && !(sd->special >= 300 && sd->special < 500)) // exempt linedef exec specials { - sd->repeatcnt = (INT16)(((unsigned)textureoffset) >> 12); - sd->textureoffset = (((unsigned)textureoffset) & 2047) << FRACBITS; + sd->repeatcnt = (INT16)(((UINT16)textureoffset) >> 12); + sd->textureoffset = (((UINT16)textureoffset) & 2047) << FRACBITS; } else { From afcaa94cd01ced5802c534b954131dca2e3f1727 Mon Sep 17 00:00:00 2001 From: Nev3r Date: Sat, 11 Jan 2020 08:52:30 +0100 Subject: [PATCH 699/746] Clarify ambiguity regarding mapthing-based vertex slopes. --- src/p_slopes.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/p_slopes.c b/src/p_slopes.c index 18489c65e..dffc96e55 100644 --- a/src/p_slopes.c +++ b/src/p_slopes.c @@ -458,8 +458,8 @@ static pslope_t *MakeViaMapthings(INT16 tag1, INT16 tag2, INT16 tag3, UINT8 flag return ret; } -/// Create vertex based slopes. -static void line_SpawnViaVertexes(const int linenum, const boolean spawnthinker) +/// Create vertex based slopes using tagged mapthings. +static void line_SpawnViaMapthingVertexes(const int linenum, const boolean spawnthinker) { line_t *line = lines + linenum; side_t *side; @@ -630,7 +630,7 @@ void P_SpawnSlopes(const boolean fromsave) { case 705: case 714: case 715: - line_SpawnViaVertexes(i, !fromsave); // Mapthing-based vertex slopes. + line_SpawnViaMapthingVertexes(i, !fromsave); break; default: From e6ddfc7cdf0a94a8f161e0de7062bcd45d3a87bd Mon Sep 17 00:00:00 2001 From: Zwip-Zwap Zapony Date: Sat, 11 Jan 2020 14:59:10 +0100 Subject: [PATCH 700/746] Make >5 <10 emblem hints appear "symmetrical"-ish With more than 5 but less than 10 emblem hints, only put half of the hints on each side of the hint menu, instead of putting e.g. 5 on the left and 1 on the right. --- src/m_menu.c | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/src/m_menu.c b/src/m_menu.c index f2287177f..27514df5e 100644 --- a/src/m_menu.c +++ b/src/m_menu.c @@ -7234,7 +7234,7 @@ static void M_EmblemHints(INT32 choice) static void M_DrawEmblemHints(void) { INT32 i, j = 0, x, y; - UINT32 collected = 0, local = 0; + UINT32 collected = 0, local = 0, left_hints = NUMHINTS; emblem_t *emblem; const char *hint; @@ -7250,6 +7250,11 @@ static void M_DrawEmblemHints(void) x = (local > NUMHINTS ? 4 : 12); y = 8; + // If there are more than 1 page's but less than 2 pages' worth of emblems, + // put half (rounded up) of the hints on the left, and half (rounded down) on the right + if (local > NUMHINTS && local < (NUMHINTS*2)-1) + left_hints = (local + 1) / 2; + if (!local) V_DrawCenteredString(160, 48, V_YELLOWMAP, "No hidden emblems on this map."); else for (i = 0; i < numemblems; i++) @@ -7282,7 +7287,7 @@ static void M_DrawEmblemHints(void) y += 28; - if (++j == NUMHINTS) + if (++j == left_hints) { x = 4+(BASEVIDWIDTH/2); y = 8; From 926cbc414103e98905ed02e52f2538c0ad17cbad Mon Sep 17 00:00:00 2001 From: toaster Date: Sat, 11 Jan 2020 14:41:37 +0000 Subject: [PATCH 701/746] Make P_HomingAttack and P_LookForEnemies consistent, preventing targeting TNT barrels just launching you in place. --- src/p_user.c | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/src/p_user.c b/src/p_user.c index b40e647b6..953641471 100644 --- a/src/p_user.c +++ b/src/p_user.c @@ -9279,6 +9279,7 @@ mobj_t *P_LookForFocusTarget(player_t *player, mobj_t *exclude, SINT8 direction, // If nonenemies is true, includes monitors and springs! // If bullet is true, you can look up and the distance is further, // but your total angle span you can look is limited to compensate. (Also, allows monitors.) +// If you modify this, please also modify P_HomingAttack. // mobj_t *P_LookForEnemies(player_t *player, boolean nonenemies, boolean bullet) { @@ -9374,15 +9375,18 @@ boolean P_HomingAttack(mobj_t *source, mobj_t *enemy) // Home in on your target if (!enemy) return false; - if (!enemy->health) + if (enemy->flags & MF_NOCLIPTHING) + return false; + + if (enemy->health <= 0) // dead + return false; + + if (!((enemy->flags & (MF_ENEMY|MF_BOSS|MF_MONITOR) && (enemy->flags & MF_SHOOTABLE)) || (enemy->flags & MF_SPRING)) == !(enemy->flags2 & MF2_INVERTAIMABLE)) // allows if it has the flags desired XOR it has the invert aimable flag return false; if (enemy->flags2 & MF2_FRET) return false; - if (!(enemy->flags & (MF_SHOOTABLE|MF_SPRING)) == !(enemy->flags2 & MF2_INVERTAIMABLE)) // allows if it has the flags desired XOR it has the invert aimable flag - return false; - // change angle source->angle = R_PointToAngle2(source->x, source->y, enemy->x, enemy->y); if (source->player) From e938f16fefcd1fe801a89fd4185da07600eff1ad Mon Sep 17 00:00:00 2001 From: toaster Date: Sat, 11 Jan 2020 16:40:42 +0000 Subject: [PATCH 702/746] Fix Egg Slimer pogo hitbox being intangible. (WHY does it have MF_NOCLIPTHING????) --- src/info.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/info.c b/src/info.c index 60913b519..bd672af12 100644 --- a/src/info.c +++ b/src/info.c @@ -5734,7 +5734,7 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] = 0, // mass 0, // damage sfx_spring, // activesound - MF_SPECIAL|MF_NOGRAVITY|MF_NOCLIP|MF_NOCLIPHEIGHT|MF_NOCLIPTHING, // flags + MF_SPECIAL|MF_NOGRAVITY|MF_NOCLIP|MF_NOCLIPHEIGHT, // flags S_EGGMOBILE2_POGO5 // raisestate }, From a5ad02eab9573032154a1a7c099ddc6259e52ce9 Mon Sep 17 00:00:00 2001 From: toaster Date: Sat, 11 Jan 2020 17:08:08 +0000 Subject: [PATCH 703/746] Make Fangboss' player pogo a little less bullshit by having an actually sensible calculation instead of trying to be smart. The old behaviour was trying way too hard to be smart and as a consequence made the hitbox way too huge. --- 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 71740822e..8334a2a4e 100644 --- a/src/p_inter.c +++ b/src/p_inter.c @@ -433,7 +433,7 @@ void P_TouchSpecialThing(mobj_t *special, mobj_t *toucher, boolean heightcheck) || special->state == &states[S_FANG_BOUNCE4] || special->state == &states[S_FANG_PINCHBOUNCE3] || special->state == &states[S_FANG_PINCHBOUNCE4]) - && P_MobjFlip(special)*((special->z + special->height/2) - (toucher->z - toucher->height/2)) > (special->height/4)) + && P_MobjFlip(special)*((special->z + special->height/2) - (toucher->z + toucher->height/2)) > (toucher->height/2)) { P_DamageMobj(toucher, special, special, 1, 0); P_SetTarget(&special->tracer, toucher); From 9c8988ab57c872193a84a3505bb48de6b4654913 Mon Sep 17 00:00:00 2001 From: Monster Iestyn Date: Sat, 11 Jan 2020 18:48:47 +0000 Subject: [PATCH 704/746] Don't make locale code dependent on GETTEXT, save that for the actual gettext related stuff! --- src/d_main.c | 2 -- src/doomdef.h | 2 +- src/m_misc.c | 18 +++++++++++------- 3 files changed, 12 insertions(+), 10 deletions(-) diff --git a/src/d_main.c b/src/d_main.c index e55c65bbb..1001e99a9 100644 --- a/src/d_main.c +++ b/src/d_main.c @@ -1046,10 +1046,8 @@ void D_SRB2Main(void) I_OutputMsg("setvbuf didnt work\n"); #endif -#ifdef GETTEXT // initialise locale code M_StartupLocale(); -#endif // get parameters from a response file (eg: srb2 @parms.txt) M_FindResponseFile(); diff --git a/src/doomdef.h b/src/doomdef.h index 55ad8abed..1c4e9dc89 100644 --- a/src/doomdef.h +++ b/src/doomdef.h @@ -98,8 +98,8 @@ #ifdef GETTEXT #include -#include #endif +#include // locale should not be dependent on GETTEXT -- 11/01/20 Monster Iestyn #include #include diff --git a/src/m_misc.c b/src/m_misc.c index 83c0c7bec..5ee7b0ac9 100644 --- a/src/m_misc.c +++ b/src/m_misc.c @@ -1594,16 +1594,19 @@ boolean M_ScreenshotResponder(event_t *ev) // M_StartupLocale. // Sets up gettext to translate SRB2's strings. #ifdef GETTEXT -#if defined (__unix__) || defined(__APPLE__) || defined (UNIXCOMMON) -#define GETTEXTDOMAIN1 "/usr/share/locale" -#define GETTEXTDOMAIN2 "/usr/local/share/locale" -#elif defined (_WIN32) -#define GETTEXTDOMAIN1 "." -#endif + #if defined (__unix__) || defined(__APPLE__) || defined (UNIXCOMMON) + #define GETTEXTDOMAIN1 "/usr/share/locale" + #define GETTEXTDOMAIN2 "/usr/local/share/locale" + #elif defined (_WIN32) + #define GETTEXTDOMAIN1 "." + #endif +#endif // GETTEXT void M_StartupLocale(void) { +#ifdef GETTEXT char *textdomhandle = NULL; +#endif //GETTEXT CONS_Printf("M_StartupLocale...\n"); @@ -1612,6 +1615,7 @@ void M_StartupLocale(void) // Do not set numeric locale as that affects atof setlocale(LC_NUMERIC, "C"); +#ifdef GETTEXT // FIXME: global name define anywhere? #ifdef GETTEXTDOMAIN1 textdomhandle = bindtextdomain("srb2", GETTEXTDOMAIN1); @@ -1632,8 +1636,8 @@ void M_StartupLocale(void) textdomain("srb2"); else CONS_Printf("Could not find locale text domain!\n"); +#endif //GETTEXT } -#endif // ========================================================================== // MISC STRING FUNCTIONS From 1643e6623df1eeed9d02e399bfc9444f3bfa1a95 Mon Sep 17 00:00:00 2001 From: Monster Iestyn Date: Sat, 11 Jan 2020 20:24:43 +0000 Subject: [PATCH 705/746] whoops, forgot to do this --- src/doomdef.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/doomdef.h b/src/doomdef.h index 1c4e9dc89..696071597 100644 --- a/src/doomdef.h +++ b/src/doomdef.h @@ -451,12 +451,12 @@ char savegamename[256]; // m_misc.h #ifdef GETTEXT #define M_GetText(String) gettext(String) -void M_StartupLocale(void); #else // If no translations are to be used, make a stub // M_GetText function that just returns the string. #define M_GetText(x) (x) #endif +void M_StartupLocale(void); extern void *(*M_Memcpy)(void* dest, const void* src, size_t n) FUNCNONNULL; char *va(const char *format, ...) FUNCPRINTF; char *M_GetToken(const char *inputString); From 4e5f49c60d11382bd054f2bb84b80da7e692d0ee Mon Sep 17 00:00:00 2001 From: fickleheart Date: Sat, 11 Jan 2020 17:39:53 -0600 Subject: [PATCH 706/746] Fix player shadows while on rope hangs etc --- src/p_mobj.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/p_mobj.c b/src/p_mobj.c index a4231fa74..50f6106d1 100644 --- a/src/p_mobj.c +++ b/src/p_mobj.c @@ -3902,11 +3902,15 @@ static void P_PlayerMobjThinker(mobj_t *mobj) mobj->z += mobj->momz; P_SetThingPosition(mobj); P_CheckPosition(mobj, mobj->x, mobj->y); + mobj->floorz = tmfloorz; + mobj->ceilingz = tmceilingz; goto animonly; } else if (mobj->player->powers[pw_carry] == CR_MACESPIN) { P_CheckPosition(mobj, mobj->x, mobj->y); + mobj->floorz = tmfloorz; + mobj->ceilingz = tmceilingz; goto animonly; } } From 1b0a3d0fe3bb6f5af5cb7177b2e6d3ade4e137c0 Mon Sep 17 00:00:00 2001 From: fickleheart Date: Sat, 11 Jan 2020 17:56:49 -0600 Subject: [PATCH 707/746] Use dedicated shadow graphic --- 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 6cedced1c..ff9993525 100644 --- a/src/r_things.c +++ b/src/r_things.c @@ -1244,7 +1244,7 @@ static void R_ProjectDropShadow(mobj_t *thing, vissprite_t *vis, fixed_t scale, scalemul = FixedMul(FRACUNIT - floordiff/640, scale); - patch = W_CachePatchNum(sprites[SPR_THOK].spriteframes[0].lumppat[0], PU_CACHE); + patch = W_CachePatchName("DSHADOW", PU_CACHE); xscale = FixedDiv(projection, tz); yscale = FixedDiv(projectiony, tz); shadowxscale = FixedMul(thing->radius*2, scalemul) / patch->width; From ba8ff3d502b2d8e06d1159f5f27062ae8f3cc49e Mon Sep 17 00:00:00 2001 From: fickleheart Date: Sat, 11 Jan 2020 18:24:08 -0600 Subject: [PATCH 708/746] Add mobj shadowscale property --- src/p_inter.c | 1 + src/p_mobj.c | 16 ++++++++++++++++ src/p_mobj.h | 1 + src/r_things.c | 15 ++------------- 4 files changed, 20 insertions(+), 13 deletions(-) diff --git a/src/p_inter.c b/src/p_inter.c index 71740822e..b2d158062 100644 --- a/src/p_inter.c +++ b/src/p_inter.c @@ -1869,6 +1869,7 @@ void P_TouchSpecialThing(mobj_t *special, mobj_t *toucher, boolean heightcheck) S_StartSound(toucher, special->info->deathsound); // was NULL, but changed to player so you could hear others pick up rings P_KillMobj(special, NULL, toucher, 0); + special->shadowscale = 0; } /** Prints death messages relating to a dying or hit player. diff --git a/src/p_mobj.c b/src/p_mobj.c index 50f6106d1..e4de59031 100644 --- a/src/p_mobj.c +++ b/src/p_mobj.c @@ -10557,6 +10557,22 @@ mobj_t *P_SpawnMobj(fixed_t x, fixed_t y, fixed_t z, mobjtype_t type) else mobj->z = z; + // Set shadowscale here, before spawn hook so that Lua can change it + if ( + type == MT_PLAYER || + type == MT_ROLLOUTROCK || + type == MT_EGGMOBILE4_MACE || + (type >= MT_SMALLMACE && type <= MT_REDSPRINGBALL) || + (mobj->flags & MF_ENEMY) + ) + mobj->shadowscale = FRACUNIT; + else if ( + type >= MT_RING && type <= MT_FLINGEMERALD && type != MT_EMERALDSPAWN + ) + mobj->shadowscale = 2*FRACUNIT/3; + else + mobj->shadowscale = 0; + #ifdef HAVE_BLUA // DANGER! This can cause P_SpawnMobj to return NULL! // Avoid using P_RemoveMobj on the newly created mobj in "MobjSpawn" Lua hooks! diff --git a/src/p_mobj.h b/src/p_mobj.h index 92160d9e2..fd0c95a56 100644 --- a/src/p_mobj.h +++ b/src/p_mobj.h @@ -375,6 +375,7 @@ typedef struct mobj_s #endif boolean colorized; // Whether the mobj uses the rainbow colormap + fixed_t shadowscale; // If this object casts a shadow, and the size relative to radius // WARNING: New fields must be added separately to savegame and Lua. } mobj_t; diff --git a/src/r_things.c b/src/r_things.c index ff9993525..0fc806071 100644 --- a/src/r_things.c +++ b/src/r_things.c @@ -1902,19 +1902,8 @@ static void R_ProjectSprite(mobj_t *thing) if (thing->subsector->sector->numlights) R_SplitSprite(vis); - ///@TODO temporary: whitelist. eventually: MF/2/E flag? - if (( - oldthing->type == MT_PLAYER || - (oldthing->state - states) == S_RING || - oldthing->type == MT_ROLLOUTROCK || - oldthing->flags & MF_ENEMY || - oldthing->type == MT_EGGMOBILE4_MACE || - (oldthing->type >= MT_SMALLMACE && oldthing->type <= MT_REDSPRINGBALL) // .W. - ) && !papersprite) - R_ProjectDropShadow(oldthing, vis, - ///@TODO make this scale configurable! - ((oldthing->state - states) == S_RING) ? 2*FRACUNIT/3 : FRACUNIT, - basetx, tz); + if (oldthing->shadowscale && !papersprite) + R_ProjectDropShadow(oldthing, vis, oldthing->shadowscale, basetx, tz); // Debug ++objectsdrawn; From cfb9b3c234ef55dd719174aa50176c41eb45a206 Mon Sep 17 00:00:00 2001 From: fickleheart Date: Sat, 11 Jan 2020 18:28:15 -0600 Subject: [PATCH 709/746] Expose mobj->shadowscale to Lua --- src/lua_mobjlib.c | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/src/lua_mobjlib.c b/src/lua_mobjlib.c index 222487751..fd32b2134 100644 --- a/src/lua_mobjlib.c +++ b/src/lua_mobjlib.c @@ -88,7 +88,8 @@ enum mobj_e { #ifdef ESLOPE mobj_standingslope, #endif - mobj_colorized + mobj_colorized, + mobj_shadowscale }; static const char *const mobj_opt[] = { @@ -156,6 +157,7 @@ static const char *const mobj_opt[] = { "standingslope", #endif "colorized", + "shadowscale", NULL}; #define UNIMPLEMENTED luaL_error(L, LUA_QL("mobj_t") " field " LUA_QS " is not implemented for Lua and cannot be accessed.", mobj_opt[field]) @@ -390,6 +392,9 @@ static int mobj_get(lua_State *L) case mobj_colorized: lua_pushboolean(L, mo->colorized); break; + case mobj_shadowscale: + lua_pushfixed(L, mo->shadowscale); + break; default: // extra custom variables in Lua memory lua_getfield(L, LUA_REGISTRYINDEX, LREG_EXTVARS); I_Assert(lua_istable(L, -1)); @@ -719,6 +724,8 @@ static int mobj_set(lua_State *L) case mobj_colorized: mo->colorized = luaL_checkboolean(L, 3); break; + case mobj_shadowscale: + mo->shadowscale = luaL_checkfixed(L, 3); default: lua_getfield(L, LUA_REGISTRYINDEX, LREG_EXTVARS); I_Assert(lua_istable(L, -1)); From 9e101fc2bb8d86cbc0e8317368f1e21fd9fed42b Mon Sep 17 00:00:00 2001 From: fickleheart Date: Sun, 12 Jan 2020 09:10:09 -0600 Subject: [PATCH 710/746] Limit shadow Y scale to prevent graphical bugs --- src/r_things.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/r_things.c b/src/r_things.c index 0fc806071..41fb103e3 100644 --- a/src/r_things.c +++ b/src/r_things.c @@ -1247,8 +1247,10 @@ static void R_ProjectDropShadow(mobj_t *thing, vissprite_t *vis, fixed_t scale, patch = W_CachePatchName("DSHADOW", PU_CACHE); xscale = FixedDiv(projection, tz); yscale = FixedDiv(projectiony, tz); - shadowxscale = FixedMul(thing->radius*2, scalemul) / patch->width; - shadowyscale = FixedMul(FixedMul(thing->radius*2 / patch->height, scalemul), FixedDiv(abs(floorz - viewz), tz)); + shadowxscale = FixedMul(thing->radius*2, scalemul); + shadowyscale = FixedMul(FixedMul(thing->radius*2, scalemul), FixedDiv(abs(floorz - viewz), tz)); + shadowyscale = min(shadowyscale, shadowxscale) / patch->height; + shadowxscale /= patch->width; shadowskew = 0; if (floorslope) From f6244ec9a443cab3c86e95b65c592c28c1b47254 Mon Sep 17 00:00:00 2001 From: Louis-Antoine Date: Sun, 12 Jan 2020 20:08:41 +0100 Subject: [PATCH 711/746] Disable title map when entering a netgame --- src/d_clisrv.c | 1 + 1 file changed, 1 insertion(+) diff --git a/src/d_clisrv.c b/src/d_clisrv.c index 586e3077c..2c7493cbe 100644 --- a/src/d_clisrv.c +++ b/src/d_clisrv.c @@ -1622,6 +1622,7 @@ static void CL_LoadReceivedSavegame(void) paused = false; demoplayback = false; + titlemapinaction = TITLEMAP_OFF; titledemo = false; automapactive = false; From 66c9e8e3aaad93c8d147d11aa6c8de1f21dc9017 Mon Sep 17 00:00:00 2001 From: Zwip-Zwap Zapony Date: Sun, 12 Jan 2020 23:09:27 +0100 Subject: [PATCH 712/746] Fix "symmetrical"-ish emblem hints for ERRORMODE "left_hints" is always 3, 4, or 5, so the signedness is irrelevant. But with ERRORMODE set to 1 when compiling, the compile would previously stop due to comparing INT32 to UINT32. --- src/m_menu.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/m_menu.c b/src/m_menu.c index 27514df5e..142361bf2 100644 --- a/src/m_menu.c +++ b/src/m_menu.c @@ -7233,8 +7233,8 @@ static void M_EmblemHints(INT32 choice) static void M_DrawEmblemHints(void) { - INT32 i, j = 0, x, y; - UINT32 collected = 0, local = 0, left_hints = NUMHINTS; + INT32 i, j = 0, x, y, left_hints = NUMHINTS; + UINT32 collected = 0, local = 0; emblem_t *emblem; const char *hint; From 84ac743d734152d06b105543cbc963d973420e71 Mon Sep 17 00:00:00 2001 From: James R Date: Sun, 12 Jan 2020 20:04:05 -0800 Subject: [PATCH 713/746] Kill Lua adminplayer --- src/lua_script.c | 6 ------ 1 file changed, 6 deletions(-) diff --git a/src/lua_script.c b/src/lua_script.c index eb1afaf09..2538fb711 100644 --- a/src/lua_script.c +++ b/src/lua_script.c @@ -274,12 +274,6 @@ int LUA_PushGlobals(lua_State *L, const char *word) return 0; LUA_PushUserdata(L, &players[serverplayer], META_PLAYER); return 1; - } else if (fastcmp(word,"admin")) { // BACKWARDS COMPATIBILITY HACK: This was replaced with IsPlayerAdmin(), but some 2.1 Lua scripts still use the admin variable. It now points to the first admin player in the array. - LUA_Deprecated(L, "admin", "IsPlayerAdmin(player)"); - if (!playeringame[adminplayers[0]] || IsPlayerAdmin(serverplayer)) - return 0; - LUA_PushUserdata(L, &players[adminplayers[0]], META_PLAYER); - return 1; } else if (fastcmp(word,"emeralds")) { lua_pushinteger(L, emeralds); return 1; From 339ceafdf03a54cb562d70079f15587acd639619 Mon Sep 17 00:00:00 2001 From: James R Date: Sun, 12 Jan 2020 20:21:35 -0800 Subject: [PATCH 714/746] Remove adminplayer from SERVERINFO (PACKETVERSION 2) --- src/d_clisrv.h | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/d_clisrv.h b/src/d_clisrv.h index 5bd5e5d98..408d0f8dd 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 1 +#define PACKETVERSION 2 // Network play related stuff. // There is a data struct that stores network @@ -366,7 +366,6 @@ typedef struct UINT8 cheatsenabled; UINT8 isdedicated; UINT8 fileneedednum; - SINT8 adminplayer; tic_t time; tic_t leveltime; char servername[MAXSERVERNAME]; From 0d6b6efe0ffd458d24d9f0218c244d306524f88e Mon Sep 17 00:00:00 2001 From: James R Date: Mon, 13 Jan 2020 15:20:50 -0800 Subject: [PATCH 715/746] Refactor R_LoadTextures into something manageable (no goto!!) --- src/r_data.c | 496 ++++++++++++++++++++++++++------------------------- 1 file changed, 256 insertions(+), 240 deletions(-) diff --git a/src/r_data.c b/src/r_data.c index d35777664..ebb73cd42 100644 --- a/src/r_data.c +++ b/src/r_data.c @@ -699,254 +699,29 @@ void R_FlushTextureCache(void) int R_CountTexturesInTEXTURESLump(UINT16 wadNum, UINT16 lumpNum); void R_ParseTEXTURESLump(UINT16 wadNum, UINT16 lumpNum, INT32 *index); -// -// R_LoadTextures -// Initializes the texture list with the textures from the world map. -// -#define TX_START "TX_START" -#define TX_END "TX_END" -void R_LoadTextures(void) +#ifdef WALLFLATS +static INT32 +Rloadflats (INT32 i, INT32 w) { - INT32 i, w; UINT16 j; - UINT16 texstart, texend, texturesLumpPos; - patch_t *patchlump; - texpatch_t *patch; + UINT16 texstart, texend; texture_t *texture; + texpatch_t *patch; - // Free previous memory before numtextures change. - if (numtextures) + // Yes + if (wadfiles[w]->type == RET_PK3) { - for (i = 0; i < numtextures; i++) - { - Z_Free(textures[i]); - Z_Free(texturecache[i]); - } - Z_Free(texturetranslation); - Z_Free(textures); - Z_Free(texflats); + texstart = W_CheckNumForFolderStartPK3("flats/", (UINT16)w, 0); + texend = W_CheckNumForFolderEndPK3("flats/", (UINT16)w, texstart); + } + else + { + texstart = W_CheckNumForNamePwad("F_START", (UINT16)w, 0); + texend = W_CheckNumForNamePwad("F_END", (UINT16)w, texstart); } - // Load patches and textures. - - // Get the number of textures to check. - // NOTE: Make SURE the system does not process - // the markers. - // This system will allocate memory for all duplicate/patched textures even if it never uses them, - // but the alternative is to spend a ton of time checking and re-checking all previous entries just to skip any potentially patched textures. - for (w = 0, numtextures = 0; w < numwadfiles; w++) + if (!( texstart == INT16_MAX || texend == INT16_MAX )) { - // Count the textures from TEXTURES lumps - texturesLumpPos = W_CheckNumForNamePwad("TEXTURES", (UINT16)w, 0); - while (texturesLumpPos != INT16_MAX) - { - numtextures += R_CountTexturesInTEXTURESLump((UINT16)w, (UINT16)texturesLumpPos); - texturesLumpPos = W_CheckNumForNamePwad("TEXTURES", (UINT16)w, texturesLumpPos + 1); - } - - // Count single-patch textures - if (wadfiles[w]->type == RET_PK3) - { - texstart = W_CheckNumForFolderStartPK3("textures/", (UINT16)w, 0); - texend = W_CheckNumForFolderEndPK3("textures/", (UINT16)w, texstart); - } - else - { - texstart = W_CheckNumForNamePwad(TX_START, (UINT16)w, 0); - texend = W_CheckNumForNamePwad(TX_END, (UINT16)w, 0); - } - - if (texstart == INT16_MAX || texend == INT16_MAX) -#ifdef WALLFLATS - goto countflats; -#else - continue; -#endif - - texstart++; // Do not count the first marker - - // PK3s have subfolders, so we can't just make a simple sum - if (wadfiles[w]->type == RET_PK3) - { - for (j = texstart; j < texend; j++) - { - if (!W_IsLumpFolder((UINT16)w, j)) // Check if lump is a folder; if not, then count it - numtextures++; - } - } - else // Add all the textures between TX_START and TX_END - { - numtextures += (UINT32)(texend - texstart); - } - -#ifdef WALLFLATS -countflats: - // Count flats - if (wadfiles[w]->type == RET_PK3) - { - texstart = W_CheckNumForFolderStartPK3("flats/", (UINT16)w, 0); - texend = W_CheckNumForFolderEndPK3("flats/", (UINT16)w, texstart); - } - else - { - texstart = W_CheckNumForNamePwad("F_START", (UINT16)w, 0); - texend = W_CheckNumForNamePwad("F_END", (UINT16)w, texstart); - } - - if (texstart == INT16_MAX || texend == INT16_MAX) - continue; - - texstart++; // Do not count the first marker - - // PK3s have subfolders, so we can't just make a simple sum - if (wadfiles[w]->type == RET_PK3) - { - for (j = texstart; j < texend; j++) - { - if (!W_IsLumpFolder((UINT16)w, j)) // Check if lump is a folder; if not, then count it - numtextures++; - } - } - else // Add all the textures between F_START and F_END - { - numtextures += (UINT32)(texend - texstart); - } -#endif - } - - // If no textures found by this point, bomb out - if (!numtextures) - I_Error("No textures detected in any WADs!\n"); - - // Allocate memory and initialize to 0 for all the textures we are initialising. - // There are actually 5 buffers allocated in one for convenience. - textures = Z_Calloc((numtextures * sizeof(void *)) * 5, PU_STATIC, NULL); - texflats = Z_Calloc((numtextures * sizeof(*texflats)), PU_STATIC, NULL); - - // Allocate texture column offset table. - texturecolumnofs = (void *)((UINT8 *)textures + (numtextures * sizeof(void *))); - // Allocate texture referencing cache. - texturecache = (void *)((UINT8 *)textures + ((numtextures * sizeof(void *)) * 2)); - // Allocate texture width table. - texturewidth = (void *)((UINT8 *)textures + ((numtextures * sizeof(void *)) * 3)); - // Allocate texture height table. - textureheight = (void *)((UINT8 *)textures + ((numtextures * sizeof(void *)) * 4)); - // Create translation table for global animation. - texturetranslation = Z_Malloc((numtextures + 1) * sizeof(*texturetranslation), PU_STATIC, NULL); - - for (i = 0; i < numtextures; i++) - texturetranslation[i] = i; - - for (i = 0, w = 0; w < numwadfiles; w++) - { - // Get the lump numbers for the markers in the WAD, if they exist. - if (wadfiles[w]->type == RET_PK3) - { - texstart = W_CheckNumForFolderStartPK3("textures/", (UINT16)w, 0); - texend = W_CheckNumForFolderEndPK3("textures/", (UINT16)w, texstart); - texturesLumpPos = W_CheckNumForNamePwad("TEXTURES", (UINT16)w, 0); - while (texturesLumpPos != INT16_MAX) - { - R_ParseTEXTURESLump(w, texturesLumpPos, &i); - texturesLumpPos = W_CheckNumForNamePwad("TEXTURES", (UINT16)w, texturesLumpPos + 1); - } - } - else - { - texstart = W_CheckNumForNamePwad(TX_START, (UINT16)w, 0); - texend = W_CheckNumForNamePwad(TX_END, (UINT16)w, 0); - texturesLumpPos = W_CheckNumForNamePwad("TEXTURES", (UINT16)w, 0); - if (texturesLumpPos != INT16_MAX) - R_ParseTEXTURESLump(w, texturesLumpPos, &i); - } - - if (texstart == INT16_MAX || texend == INT16_MAX) -#ifdef WALLFLATS - goto checkflats; -#else - continue; -#endif - - texstart++; // Do not count the first marker - - // Work through each lump between the markers in the WAD. - for (j = 0; j < (texend - texstart); j++) - { - UINT16 wadnum = (UINT16)w; - lumpnum_t lumpnum = texstart + j; -#ifndef NO_PNG_LUMPS - size_t lumplength; -#endif - - if (wadfiles[w]->type == RET_PK3) - { - if (W_IsLumpFolder(wadnum, lumpnum)) // Check if lump is a folder - continue; // If it is then SKIP IT - } - - patchlump = W_CacheLumpNumPwad(wadnum, lumpnum, PU_CACHE); -#ifndef NO_PNG_LUMPS - lumplength = W_LumpLengthPwad(wadnum, lumpnum); -#endif - - //CONS_Printf("\n\"%s\" is a single patch, dimensions %d x %d",W_CheckNameForNumPwad((UINT16)w,texstart+j),patchlump->width, patchlump->height); - texture = textures[i] = Z_Calloc(sizeof(texture_t) + sizeof(texpatch_t), PU_STATIC, NULL); - - // Set texture properties. - M_Memcpy(texture->name, W_CheckNameForNumPwad(wadnum, lumpnum), sizeof(texture->name)); - -#ifndef NO_PNG_LUMPS - if (R_IsLumpPNG((UINT8 *)patchlump, lumplength)) - { - INT16 width, height; - R_PNGDimensions((UINT8 *)patchlump, &width, &height, lumplength); - texture->width = width; - texture->height = height; - } - else -#endif - { - texture->width = SHORT(patchlump->width); - texture->height = SHORT(patchlump->height); - } - - texture->type = TEXTURETYPE_SINGLEPATCH; - texture->patchcount = 1; - texture->holes = false; - texture->flip = 0; - - // Allocate information for the texture's patches. - patch = &texture->patches[0]; - - patch->originx = patch->originy = 0; - patch->wad = (UINT16)w; - patch->lump = texstart + j; - patch->flip = 0; - - Z_Unlock(patchlump); - - texturewidth[i] = texture->width; - textureheight[i] = texture->height << FRACBITS; - i++; - } - -#ifdef WALLFLATS -checkflats: - // Yes - if (wadfiles[w]->type == RET_PK3) - { - texstart = W_CheckNumForFolderStartPK3("flats/", (UINT16)w, 0); - texend = W_CheckNumForFolderEndPK3("flats/", (UINT16)w, texstart); - } - else - { - texstart = W_CheckNumForNamePwad("F_START", (UINT16)w, 0); - texend = W_CheckNumForNamePwad("F_END", (UINT16)w, texstart); - } - - if (texstart == INT16_MAX || texend == INT16_MAX) - continue; - texstart++; // Do not count the first marker // Work through each lump between the markers in the WAD. @@ -1029,6 +804,247 @@ checkflats: textureheight[i] = texture->height << FRACBITS; i++; } + } + + return i; +} +#endif/*WALLFLATS*/ + +#define TX_START "TX_START" +#define TX_END "TX_END" + +static INT32 +Rloadtextures (INT32 i, INT32 w) +{ + UINT16 j; + UINT16 texstart, texend, texturesLumpPos; + texture_t *texture; + patch_t *patchlump; + texpatch_t *patch; + + // Get the lump numbers for the markers in the WAD, if they exist. + if (wadfiles[w]->type == RET_PK3) + { + texstart = W_CheckNumForFolderStartPK3("textures/", (UINT16)w, 0); + texend = W_CheckNumForFolderEndPK3("textures/", (UINT16)w, texstart); + texturesLumpPos = W_CheckNumForNamePwad("TEXTURES", (UINT16)w, 0); + while (texturesLumpPos != INT16_MAX) + { + R_ParseTEXTURESLump(w, texturesLumpPos, &i); + texturesLumpPos = W_CheckNumForNamePwad("TEXTURES", (UINT16)w, texturesLumpPos + 1); + } + } + else + { + texstart = W_CheckNumForNamePwad(TX_START, (UINT16)w, 0); + texend = W_CheckNumForNamePwad(TX_END, (UINT16)w, 0); + texturesLumpPos = W_CheckNumForNamePwad("TEXTURES", (UINT16)w, 0); + if (texturesLumpPos != INT16_MAX) + R_ParseTEXTURESLump(w, texturesLumpPos, &i); + } + + if (!( texstart == INT16_MAX || texend == INT16_MAX )) + { + texstart++; // Do not count the first marker + + // Work through each lump between the markers in the WAD. + for (j = 0; j < (texend - texstart); j++) + { + UINT16 wadnum = (UINT16)w; + lumpnum_t lumpnum = texstart + j; +#ifndef NO_PNG_LUMPS + size_t lumplength; +#endif + + if (wadfiles[w]->type == RET_PK3) + { + if (W_IsLumpFolder(wadnum, lumpnum)) // Check if lump is a folder + continue; // If it is then SKIP IT + } + + patchlump = W_CacheLumpNumPwad(wadnum, lumpnum, PU_CACHE); +#ifndef NO_PNG_LUMPS + lumplength = W_LumpLengthPwad(wadnum, lumpnum); +#endif + + //CONS_Printf("\n\"%s\" is a single patch, dimensions %d x %d",W_CheckNameForNumPwad((UINT16)w,texstart+j),patchlump->width, patchlump->height); + texture = textures[i] = Z_Calloc(sizeof(texture_t) + sizeof(texpatch_t), PU_STATIC, NULL); + + // Set texture properties. + M_Memcpy(texture->name, W_CheckNameForNumPwad(wadnum, lumpnum), sizeof(texture->name)); + +#ifndef NO_PNG_LUMPS + if (R_IsLumpPNG((UINT8 *)patchlump, lumplength)) + { + INT16 width, height; + R_PNGDimensions((UINT8 *)patchlump, &width, &height, lumplength); + texture->width = width; + texture->height = height; + } + else +#endif + { + texture->width = SHORT(patchlump->width); + texture->height = SHORT(patchlump->height); + } + + texture->type = TEXTURETYPE_SINGLEPATCH; + texture->patchcount = 1; + texture->holes = false; + texture->flip = 0; + + // Allocate information for the texture's patches. + patch = &texture->patches[0]; + + patch->originx = patch->originy = 0; + patch->wad = (UINT16)w; + patch->lump = texstart + j; + patch->flip = 0; + + Z_Unlock(patchlump); + + texturewidth[i] = texture->width; + textureheight[i] = texture->height << FRACBITS; + i++; + } + } + + return i; +} + +// +// R_LoadTextures +// Initializes the texture list with the textures from the world map. +// +void R_LoadTextures(void) +{ + INT32 i, w; + UINT16 j; + UINT16 texstart, texend, texturesLumpPos; + + // Free previous memory before numtextures change. + if (numtextures) + { + for (i = 0; i < numtextures; i++) + { + Z_Free(textures[i]); + Z_Free(texturecache[i]); + } + Z_Free(texturetranslation); + Z_Free(textures); + Z_Free(texflats); + } + + // Load patches and textures. + + // Get the number of textures to check. + // NOTE: Make SURE the system does not process + // the markers. + // This system will allocate memory for all duplicate/patched textures even if it never uses them, + // but the alternative is to spend a ton of time checking and re-checking all previous entries just to skip any potentially patched textures. + for (w = 0, numtextures = 0; w < numwadfiles; w++) + { +#ifdef WALLFLATS + // Count flats + if (wadfiles[w]->type == RET_PK3) + { + texstart = W_CheckNumForFolderStartPK3("flats/", (UINT16)w, 0); + texend = W_CheckNumForFolderEndPK3("flats/", (UINT16)w, texstart); + } + else + { + texstart = W_CheckNumForNamePwad("F_START", (UINT16)w, 0); + texend = W_CheckNumForNamePwad("F_END", (UINT16)w, texstart); + } + + if (!( texstart == INT16_MAX || texend == INT16_MAX )) + { + texstart++; // Do not count the first marker + + // PK3s have subfolders, so we can't just make a simple sum + if (wadfiles[w]->type == RET_PK3) + { + for (j = texstart; j < texend; j++) + { + if (!W_IsLumpFolder((UINT16)w, j)) // Check if lump is a folder; if not, then count it + numtextures++; + } + } + else // Add all the textures between F_START and F_END + { + numtextures += (UINT32)(texend - texstart); + } + } +#endif/*WALLFLATS*/ + + // Count the textures from TEXTURES lumps + texturesLumpPos = W_CheckNumForNamePwad("TEXTURES", (UINT16)w, 0); + while (texturesLumpPos != INT16_MAX) + { + numtextures += R_CountTexturesInTEXTURESLump((UINT16)w, (UINT16)texturesLumpPos); + texturesLumpPos = W_CheckNumForNamePwad("TEXTURES", (UINT16)w, texturesLumpPos + 1); + } + + // Count single-patch textures + if (wadfiles[w]->type == RET_PK3) + { + texstart = W_CheckNumForFolderStartPK3("textures/", (UINT16)w, 0); + texend = W_CheckNumForFolderEndPK3("textures/", (UINT16)w, texstart); + } + else + { + texstart = W_CheckNumForNamePwad(TX_START, (UINT16)w, 0); + texend = W_CheckNumForNamePwad(TX_END, (UINT16)w, 0); + } + + if (texstart == INT16_MAX || texend == INT16_MAX) + continue; + + texstart++; // Do not count the first marker + + // PK3s have subfolders, so we can't just make a simple sum + if (wadfiles[w]->type == RET_PK3) + { + for (j = texstart; j < texend; j++) + { + if (!W_IsLumpFolder((UINT16)w, j)) // Check if lump is a folder; if not, then count it + numtextures++; + } + } + else // Add all the textures between TX_START and TX_END + { + numtextures += (UINT32)(texend - texstart); + } + } + + // If no textures found by this point, bomb out + if (!numtextures) + I_Error("No textures detected in any WADs!\n"); + + // Allocate memory and initialize to 0 for all the textures we are initialising. + // There are actually 5 buffers allocated in one for convenience. + textures = Z_Calloc((numtextures * sizeof(void *)) * 5, PU_STATIC, NULL); + texflats = Z_Calloc((numtextures * sizeof(*texflats)), PU_STATIC, NULL); + + // Allocate texture column offset table. + texturecolumnofs = (void *)((UINT8 *)textures + (numtextures * sizeof(void *))); + // Allocate texture referencing cache. + texturecache = (void *)((UINT8 *)textures + ((numtextures * sizeof(void *)) * 2)); + // Allocate texture width table. + texturewidth = (void *)((UINT8 *)textures + ((numtextures * sizeof(void *)) * 3)); + // Allocate texture height table. + textureheight = (void *)((UINT8 *)textures + ((numtextures * sizeof(void *)) * 4)); + // Create translation table for global animation. + texturetranslation = Z_Malloc((numtextures + 1) * sizeof(*texturetranslation), PU_STATIC, NULL); + + for (i = 0; i < numtextures; i++) + texturetranslation[i] = i; + + for (i = 0, w = 0; w < numwadfiles; w++) + { + i = Rloadtextures(i, w); +#ifdef WALLFLATS + i = Rloadflats(i, w); #endif } From 68b78f44d8e72664fbac0a8676e2ad656b137edd Mon Sep 17 00:00:00 2001 From: James R Date: Mon, 13 Jan 2020 15:21:35 -0800 Subject: [PATCH 716/746] Load flats first so textures with the same name are prefered on walls --- src/r_data.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/r_data.c b/src/r_data.c index ebb73cd42..9f80e257b 100644 --- a/src/r_data.c +++ b/src/r_data.c @@ -1042,10 +1042,10 @@ void R_LoadTextures(void) for (i = 0, w = 0; w < numwadfiles; w++) { - i = Rloadtextures(i, w); #ifdef WALLFLATS i = Rloadflats(i, w); #endif + i = Rloadtextures(i, w); } #ifdef HWRENDER From af2d3cfd16a59c385f25cb06f6717502ccbc9b2e Mon Sep 17 00:00:00 2001 From: James R Date: Sat, 3 Aug 2019 13:27:57 -0700 Subject: [PATCH 717/746] Let MS_Connect use -bindaddr And so now you really can host from multiple IP addresses. (cherry picked from commit e56bf12537700af7b7fcd0d3b0e8586e41edddd1) --- src/mserv.c | 94 ++++++++++++++++++++++++++++++++++++++--------------- 1 file changed, 67 insertions(+), 27 deletions(-) diff --git a/src/mserv.c b/src/mserv.c index ddabdb6c0..1052de80c 100644 --- a/src/mserv.c +++ b/src/mserv.c @@ -323,7 +323,7 @@ static INT32 GetServersList(void) // // MS_Connect() // -static INT32 MS_Connect(const char *ip_addr, const char *str_port, INT32 async) +static INT32 MS_SubConnect(const char *ip_addr, const char *str_port, INT32 async, struct sockaddr *bindaddr, socklen_t bindaddrlen) { #ifdef NONET (void)ip_addr; @@ -356,44 +356,48 @@ static INT32 MS_Connect(const char *ip_addr, const char *str_port, INT32 async) socket_fd = socket(runp->ai_family, runp->ai_socktype, runp->ai_protocol); if (socket_fd != (SOCKET_TYPE)ERRSOCKET) { - if (async) // do asynchronous connection + if (!bindaddr || bind(socket_fd, bindaddr, bindaddrlen) == 0) { + if (async) // do asynchronous connection + { #ifdef FIONBIO #ifdef WATTCP - char res = 1; + char res = 1; #else - unsigned long res = 1; + unsigned long res = 1; #endif - ioctl(socket_fd, FIONBIO, &res); + ioctl(socket_fd, FIONBIO, &res); #endif - if (connect(socket_fd, runp->ai_addr, (socklen_t)runp->ai_addrlen) == ERRSOCKET) - { -#ifdef _WIN32 // humm, on win32/win64 it doesn't work with EINPROGRESS (stupid windows) - if (WSAGetLastError() != WSAEWOULDBLOCK) -#else - if (errno != EINPROGRESS) -#endif + if (connect(socket_fd, runp->ai_addr, (socklen_t)runp->ai_addrlen) == ERRSOCKET) { - con_state = MSCS_FAILED; - CloseConnection(); - I_freeaddrinfo(ai); - return MS_CONNECT_ERROR; +#ifdef _WIN32 // humm, on win32/win64 it doesn't work with EINPROGRESS (stupid windows) + if (WSAGetLastError() != WSAEWOULDBLOCK) +#else + if (errno != EINPROGRESS) +#endif + { + con_state = MSCS_FAILED; + CloseConnection(); + I_freeaddrinfo(ai); + return MS_CONNECT_ERROR; + } } + con_state = MSCS_WAITING; + FD_ZERO(&wset); + FD_SET(socket_fd, &wset); + select_timeout.tv_sec = 0, select_timeout.tv_usec = 0; + I_freeaddrinfo(ai); + return 0; + } + else if (connect(socket_fd, runp->ai_addr, (socklen_t)runp->ai_addrlen) != ERRSOCKET) + { + I_freeaddrinfo(ai); + return 0; } - con_state = MSCS_WAITING; - FD_ZERO(&wset); - FD_SET(socket_fd, &wset); - select_timeout.tv_sec = 0, select_timeout.tv_usec = 0; - I_freeaddrinfo(ai); - return 0; - } - else if (connect(socket_fd, runp->ai_addr, (socklen_t)runp->ai_addrlen) != ERRSOCKET) - { - I_freeaddrinfo(ai); - return 0; } + close(socket_fd); } runp = runp->ai_next; } @@ -402,6 +406,42 @@ static INT32 MS_Connect(const char *ip_addr, const char *str_port, INT32 async) return MS_CONNECT_ERROR; } +static INT32 MS_Connect(const char *ip_addr, const char *str_port, INT32 async) +{ + const char *lhost; + struct my_addrinfo hints; + struct my_addrinfo *ai, *aip; + int c; + if (M_CheckParm("-bindaddr") && ( lhost = M_GetNextParm() )) + { + memset (&hints, 0x00, sizeof(hints)); +#ifdef AI_ADDRCONFIG + hints.ai_flags = AI_ADDRCONFIG; +#endif + hints.ai_family = AF_INET; + hints.ai_socktype = SOCK_STREAM; + hints.ai_protocol = IPPROTO_TCP; + if (( c = I_getaddrinfo(lhost, 0, &hints, &ai) ) != 0) + { + CONS_Printf( + "mserv.c: bind to %s: %s\n", + lhost, + gai_strerror(c)); + return MS_GETHOSTBYNAME_ERROR; + } + for (aip = ai; aip; aip = aip->ai_next) + { + c = MS_SubConnect(ip_addr, str_port, async, aip->ai_addr, aip->ai_addrlen); + if (c == 0) + return 0; + } + I_freeaddrinfo(ai); + return c; + } + else + return MS_SubConnect(ip_addr, str_port, async, 0, 0); +} + #define NUM_LIST_SERVER MAXSERVERLIST const msg_server_t *GetShortServersList(INT32 room) { From 619efb3d4ecf89b242784d17bbec70a8f7ef6ed6 Mon Sep 17 00:00:00 2001 From: James R Date: Sat, 3 Aug 2019 13:30:22 -0700 Subject: [PATCH 718/746] And free addrinfo (cherry picked from commit 986c80fb13e7ae6900792de5b4b43327af7ca76c) --- src/mserv.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/mserv.c b/src/mserv.c index 1052de80c..a842e92e9 100644 --- a/src/mserv.c +++ b/src/mserv.c @@ -433,7 +433,10 @@ static INT32 MS_Connect(const char *ip_addr, const char *str_port, INT32 async) { c = MS_SubConnect(ip_addr, str_port, async, aip->ai_addr, aip->ai_addrlen); if (c == 0) + { + I_freeaddrinfo(ai); return 0; + } } I_freeaddrinfo(ai); return c; From 708ab6ff907cb77bdd05813eefde1f6d81d41a5e Mon Sep 17 00:00:00 2001 From: James R Date: Tue, 14 Jan 2020 21:40:58 -0800 Subject: [PATCH 719/746] Update buffer for SendNameAndColor --- 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 723748448..23ec00b2e 100644 --- a/src/d_netcmd.c +++ b/src/d_netcmd.c @@ -1174,7 +1174,7 @@ static INT32 snacpending = 0, snac2pending = 0, chmappending = 0; // static void SendNameAndColor(void) { - char buf[MAXPLAYERNAME+2]; + char buf[MAXPLAYERNAME+6]; char *p; p = buf; From 1489b4bcdd1cbd6346db24ab3f14785ca6297d90 Mon Sep 17 00:00:00 2001 From: James R Date: Wed, 15 Jan 2020 02:14:20 -0800 Subject: [PATCH 720/746] It's FALLTHRU not fallthru It took a week and me staying up until 2AM to look at the damn manpage and figure out THIS is why I was getting an error about 'if (tutorialmode)' falling through. But I still don't know why it didn't trigger on the MT_TNTBARREL case. Oh well. --- 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 0c4d25554..cd308d932 100644 --- a/src/p_user.c +++ b/src/p_user.c @@ -9185,7 +9185,7 @@ mobj_t *P_LookForFocusTarget(player_t *player, mobj_t *exclude, SINT8 direction, case MT_TNTBARREL: if (lockonflags & LOCK_INTERESTS) break; - /*fallthru*/ + /*FALLTHRU*/ case MT_PLAYER: // Don't chase other players! case MT_DETON: continue; // Don't be STUPID, Sonic! @@ -9203,7 +9203,7 @@ mobj_t *P_LookForFocusTarget(player_t *player, mobj_t *exclude, SINT8 direction, case MT_EGGSTATUE: if (tutorialmode) break; // Always focus egg statue in the tutorial - /*fallthru*/ + /*FALLTHRU*/ default: if ((lockonflags & LOCK_BOSS) && ((mo->flags & (MF_BOSS|MF_SHOOTABLE)) == (MF_BOSS|MF_SHOOTABLE))) // allows if it has the flags desired XOR it has the invert aimable flag From 9504ba96da07ec9ec6f4eb4d41bde87024130fd0 Mon Sep 17 00:00:00 2001 From: Louis-Antoine Date: Wed, 15 Jan 2020 15:36:11 +0100 Subject: [PATCH 721/746] Increase maximum and default chat width --- src/g_game.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/g_game.c b/src/g_game.c index eba53627d..a80d0f40a 100644 --- a/src/g_game.c +++ b/src/g_game.c @@ -352,8 +352,8 @@ static CV_PossibleValue_t chattime_cons_t[] = {{5, "MIN"}, {999, "MAX"}, {0, NUL consvar_t cv_chattime = {"chattime", "8", CV_SAVE, chattime_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL}; // chatwidth -static CV_PossibleValue_t chatwidth_cons_t[] = {{64, "MIN"}, {150, "MAX"}, {0, NULL}}; -consvar_t cv_chatwidth = {"chatwidth", "128", CV_SAVE, chatwidth_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL}; +static CV_PossibleValue_t chatwidth_cons_t[] = {{64, "MIN"}, {300, "MAX"}, {0, NULL}}; +consvar_t cv_chatwidth = {"chatwidth", "150", CV_SAVE, chatwidth_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL}; // chatheight static CV_PossibleValue_t chatheight_cons_t[] = {{6, "MIN"}, {22, "MAX"}, {0, NULL}}; From ec5db89e550e842ab7a0ebb24415f39c4e31ab15 Mon Sep 17 00:00:00 2001 From: Louis-Antoine Date: Wed, 15 Jan 2020 15:48:03 +0100 Subject: [PATCH 722/746] Cleanup chat code a little --- src/hu_stuff.c | 54 ++++++++++++++++---------------------------------- 1 file changed, 17 insertions(+), 37 deletions(-) diff --git a/src/hu_stuff.c b/src/hu_stuff.c index 14cb481b0..9e708e1cf 100644 --- a/src/hu_stuff.c +++ b/src/hu_stuff.c @@ -501,37 +501,31 @@ static void DoSayCommand(SINT8 target, size_t usedargs, UINT8 flags) // what we're gonna do now is check if the player exists // with that logic, characters 4 and 5 are our numbers: const char *newmsg; - char *playernum = (char*) malloc(3); + char playernum[3]; INT32 spc = 1; // used if playernum[1] is a space. strncpy(playernum, msg+3, 3); // check for undesirable characters in our "number" - if (((playernum[0] < '0') || (playernum[0] > '9')) || ((playernum[1] < '0') || (playernum[1] > '9'))) + if (((playernum[0] < '0') || (playernum[0] > '9')) || ((playernum[1] < '0') || (playernum[1] > '9'))) { // check if playernum[1] is a space if (playernum[1] == ' ') spc = 0; - // let it slide + // let it slide else { HU_AddChatText("\x82NOTICE: \x80Invalid command format. Correct format is \'/pm \'.", false); - free(playernum); return; } } // I'm very bad at C, I swear I am, additional checks eww! - if (spc != 0) - { - if (msg[5] != ' ') - { - HU_AddChatText("\x82NOTICE: \x80Invalid command format. Correct format is \'/pm \'.", false); - free(playernum); - return; - } - } + if (spc != 0 && msg[5] != ' ') + { + HU_AddChatText("\x82NOTICE: \x80Invalid command format. Correct format is \'/pm \'.", false); + return; + } - target = atoi((const char*) playernum); // turn that into a number - free(playernum); + target = atoi(playernum); // turn that into a number //CONS_Printf("%d\n", target); // check for target player, if it doesn't exist then we can't send the message! @@ -1021,9 +1015,6 @@ void HU_Ticker(void) #ifndef NONET static boolean teamtalk = false; -/*static char chatchars[QUEUESIZE]; -static INT32 head = 0, tail = 0;*/ -// WHY DO YOU OVERCOMPLICATE EVERYTHING????????? // Clear spaces so we don't end up with messages only made out of emptiness static boolean HU_clearChatSpaces(void) @@ -1083,7 +1074,7 @@ static void HU_queueChatChar(char c) if (strlen(msg) > 4 && strnicmp(msg, "/pm", 3) == 0) // used /pm { INT32 spc = 1; // used if nodenum[1] is a space. - char *nodenum = (char*) malloc(3); + char nodenum[3]; const char *newmsg; // what we're gonna do now is check if the node exists @@ -1098,7 +1089,7 @@ static void HU_queueChatChar(char c) strncpy(nodenum, msg+3, 3); // check for undesirable characters in our "number" - if (((nodenum[0] < '0') || (nodenum[0] > '9')) || ((nodenum[1] < '0') || (nodenum[1] > '9'))) + if (((nodenum[0] < '0') || (nodenum[0] > '9')) || ((nodenum[1] < '0') || (nodenum[1] > '9'))) { // check if nodenum[1] is a space if (nodenum[1] == ' ') @@ -1107,7 +1098,6 @@ static void HU_queueChatChar(char c) else { HU_AddChatText("\x82NOTICE: \x80Invalid command format. Correct format is \'/pm \'.", false); - free(nodenum); return; } } @@ -1117,13 +1107,11 @@ static void HU_queueChatChar(char c) if (msg[5] != ' ') { HU_AddChatText("\x82NOTICE: \x80Invalid command format. Correct format is \'/pm \'.", false); - free(nodenum); return; } } - target = atoi((const char*) nodenum); // turn that into a number - free(nodenum); + target = atoi(nodenum); // turn that into a number //CONS_Printf("%d\n", target); // check for target player, if it doesn't exist then we can't send the message! @@ -1648,12 +1636,9 @@ static void HU_drawChatLog(INT32 offset) } chat_scrollmedown = false; - // getmaxscroll through a lazy hack. We do all these loops, so let's not do more loops that are gonna lag the game more. :P - chat_maxscroll = (dy/charheight); // welcome to C, we don't know what min() and max() are. - if (chat_maxscroll <= (UINT32)cv_chatheight.value) - chat_maxscroll = 0; - else - chat_maxscroll -= cv_chatheight.value; + // getmaxscroll through a lazy hack. We do all these loops, + // so let's not do more loops that are gonna lag the game more. :P + chat_maxscroll = max(dy / charheight - cv_chatheight.value, 0); // if we're not bound by the time, autoscroll for next frame: if (atbottom) @@ -1794,21 +1779,17 @@ static void HU_DrawChat(void) i = 0; for(i=0; (i '9'))) || ((w_chat[4] != 0) && (((w_chat[4] < '0') || (w_chat[4] > '9'))))) && (w_chat[4] != ' ')) break; - - nodenum = (char*) malloc(3); strncpy(nodenum, w_chat+3, 3); - n = atoi((const char*) nodenum); // turn that into a number - free(nodenum); + n = atoi(nodenum); // turn that into a number // special cases: if ((n == 0) && !(w_chat[4] == '0')) @@ -1855,7 +1836,6 @@ static void HU_DrawChat(void) } HU_drawChatLog(typelines-1); // typelines is the # of lines we're typing. If there's more than 1 then the log should scroll up to give us more space. - } From 0197a83db7f80dc8a412ee41200989322fca1c5b Mon Sep 17 00:00:00 2001 From: Louis-Antoine Date: Wed, 15 Jan 2020 15:57:38 +0100 Subject: [PATCH 723/746] bruh --- src/hu_stuff.c | 28 ++++++++++++++-------------- 1 file changed, 14 insertions(+), 14 deletions(-) diff --git a/src/hu_stuff.c b/src/hu_stuff.c index 9e708e1cf..87e888eeb 100644 --- a/src/hu_stuff.c +++ b/src/hu_stuff.c @@ -1073,11 +1073,11 @@ static void HU_queueChatChar(char c) if (strlen(msg) > 4 && strnicmp(msg, "/pm", 3) == 0) // used /pm { - INT32 spc = 1; // used if nodenum[1] is a space. - char nodenum[3]; + INT32 spc = 1; // used if playernum[1] is a space. + char playernum[3]; const char *newmsg; - // what we're gonna do now is check if the node exists + // what we're gonna do now is check if the player exists // with that logic, characters 4 and 5 are our numbers: // teamtalk can't send PMs, just don't send it, else everyone would be able to see it, and no one wants to see your sex RP sicko. @@ -1087,17 +1087,17 @@ static void HU_queueChatChar(char c) return; } - strncpy(nodenum, msg+3, 3); + strncpy(playernum, msg+3, 3); // check for undesirable characters in our "number" - if (((nodenum[0] < '0') || (nodenum[0] > '9')) || ((nodenum[1] < '0') || (nodenum[1] > '9'))) + if (((playernum[0] < '0') || (playernum[0] > '9')) || ((playernum[1] < '0') || (playernum[1] > '9'))) { - // check if nodenum[1] is a space - if (nodenum[1] == ' ') + // check if playernum[1] is a space + if (playernum[1] == ' ') spc = 0; // let it slide else { - HU_AddChatText("\x82NOTICE: \x80Invalid command format. Correct format is \'/pm \'.", false); + HU_AddChatText("\x82NOTICE: \x80Invalid command format. Correct format is \'/pm \'.", false); return; } } @@ -1106,12 +1106,12 @@ static void HU_queueChatChar(char c) { if (msg[5] != ' ') { - HU_AddChatText("\x82NOTICE: \x80Invalid command format. Correct format is \'/pm \'.", false); + HU_AddChatText("\x82NOTICE: \x80Invalid command format. Correct format is \'/pm \'.", false); return; } } - target = atoi(nodenum); // turn that into a number + target = atoi(playernum); // turn that into a number //CONS_Printf("%d\n", target); // check for target player, if it doesn't exist then we can't send the message! @@ -1123,7 +1123,7 @@ static void HU_queueChatChar(char c) return; } - // we need to get rid of the /pm + // we need to get rid of the /pm newmsg = msg+5+spc; strlcpy(msg, newmsg, 255); } @@ -1782,14 +1782,14 @@ static void HU_DrawChat(void) // filter: (code needs optimization pls help I'm bad with C) if (w_chat[3]) { - char nodenum[3]; + char playernum[3]; UINT32 n; // right, that's half important: (w_chat[4] may be a space since /pm0 msg is perfectly acceptable!) if ( ( ((w_chat[3] != 0) && ((w_chat[3] < '0') || (w_chat[3] > '9'))) || ((w_chat[4] != 0) && (((w_chat[4] < '0') || (w_chat[4] > '9'))))) && (w_chat[4] != ' ')) break; - strncpy(nodenum, w_chat+3, 3); - n = atoi(nodenum); // turn that into a number + strncpy(playernum, w_chat+3, 3); + n = atoi(playernum); // turn that into a number // special cases: if ((n == 0) && !(w_chat[4] == '0')) From 0134be8b78ecc04b92d5f4e3fd781f937cc46285 Mon Sep 17 00:00:00 2001 From: Alam Ed Arias Date: Thu, 16 Jan 2020 12:05:21 -0500 Subject: [PATCH 724/746] please stop breaking clang --- src/s_sound.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/s_sound.c b/src/s_sound.c index 019f5c765..606cde597 100644 --- a/src/s_sound.c +++ b/src/s_sound.c @@ -120,8 +120,7 @@ consvar_t cv_resetmusicbyheader = {"resetmusicbyheader", "Yes", CV_SAVE, CV_YesN static CV_PossibleValue_t cons_1upsound_t[] = { {0, "Jingle"}, {1, "Sound"}, - - {0} + {0, NULL} }; consvar_t cv_1upsound = {"1upsound", "Jingle", CV_SAVE, cons_1upsound_t, NULL, 0, NULL, NULL, 0, 0, NULL}; From 4e481340ce70c82c1c66400e3e85d47b2071190c Mon Sep 17 00:00:00 2001 From: Sally Cochenour Date: Thu, 16 Jan 2020 12:37:32 -0500 Subject: [PATCH 725/746] OpenGL shadows --- src/hardware/hw_main.c | 280 ++++++++++++----------------------------- src/r_main.c | 12 -- src/r_main.h | 6 - 3 files changed, 81 insertions(+), 217 deletions(-) diff --git a/src/hardware/hw_main.c b/src/hardware/hw_main.c index 74be53db5..14121518b 100644 --- a/src/hardware/hw_main.c +++ b/src/hardware/hw_main.c @@ -41,6 +41,7 @@ #include "../i_system.h" #include "../m_cheat.h" #include "../f_finale.h" +#include "../r_things.h" // R_GetShadowZ #ifdef ESLOPE #include "../p_slopes.h" #endif @@ -4050,39 +4051,6 @@ static gr_vissprite_t *HWR_NewVisSprite(void) return HWR_GetVisSprite(gr_visspritecount++); } -#ifdef GLBADSHADOWS -// Finds a floor through which light does not pass. -static fixed_t HWR_OpaqueFloorAtPos(fixed_t x, fixed_t y, fixed_t z, fixed_t height) -{ - const sector_t *sec = R_PointInSubsector(x, y)->sector; - fixed_t floorz = sec->floorheight; - - if (sec->ffloors) - { - ffloor_t *rover; - fixed_t delta1, delta2; - const fixed_t thingtop = z + height; - - for (rover = sec->ffloors; rover; rover = rover->next) - { - if (!(rover->flags & FF_EXISTS) - || !(rover->flags & FF_RENDERPLANES) - || rover->flags & FF_TRANSLUCENT - || rover->flags & FF_FOG - || rover->flags & FF_INVERTPLANES) - continue; - - delta1 = z - (*rover->bottomheight + ((*rover->topheight - *rover->bottomheight)/2)); - delta2 = thingtop - (*rover->bottomheight + ((*rover->topheight - *rover->bottomheight)/2)); - if (*rover->topheight > floorz && abs(delta1) < abs(delta2)) - floorz = *rover->topheight; - } - } - - return floorz; -} -#endif //#ifdef GLBADSHADOWS - // // HWR_DoCulling // Hardware version of R_DoCulling @@ -4123,180 +4091,123 @@ static boolean HWR_DoCulling(line_t *cullheight, line_t *viewcullheight, float v return false; } -#ifdef GLBADSHADOWS -static void HWR_DrawSpriteShadow(gr_vissprite_t *spr, GLPatch_t *gpatch, float this_scale) +static void HWR_DrawDropShadow(mobj_t *thing, gr_vissprite_t *spr, fixed_t scale) { - FOutVector swallVerts[4]; + GLPatch_t *gpatch; + FOutVector shadowVerts[4]; FSurfaceInfo sSurf; - fixed_t floorheight, mobjfloor; - float offset = 0; + float fscale; float fx; float fy; float offset; + UINT8 lightlevel = 255; + extracolormap_t *colormap = NULL; + UINT8 i; - mobjfloor = HWR_OpaqueFloorAtPos( - spr->mobj->x, spr->mobj->y, - spr->mobj->z, spr->mobj->height); - if (cv_shadowoffs.value) - { - angle_t shadowdir; + INT32 light; + fixed_t scalemul; + UINT16 alpha; + fixed_t floordiff; + fixed_t floorz; + fixed_t slopez; + pslope_t *floorslope; - // Set direction - if (splitscreen && stplyr == &players[secondarydisplayplayer]) - shadowdir = localangle2 + FixedAngle(cv_cam2_rotate.value); - else - shadowdir = localangle + FixedAngle(cv_cam_rotate.value); + floorz = R_GetShadowZ(thing, &floorslope); - // Find floorheight - floorheight = HWR_OpaqueFloorAtPos( - spr->mobj->x + P_ReturnThrustX(spr->mobj, shadowdir, spr->mobj->z - mobjfloor), - spr->mobj->y + P_ReturnThrustY(spr->mobj, shadowdir, spr->mobj->z - mobjfloor), - spr->mobj->z, spr->mobj->height); + //if (abs(floorz - gr_viewz) / tz > 4) return; // Prevent stretchy shadows and possible crashes - // The shadow is falling ABOVE it's mobj? - // Don't draw it, then! - if (spr->mobj->z < floorheight) - return; - else - { - fixed_t floorz; - floorz = HWR_OpaqueFloorAtPos( - spr->mobj->x + P_ReturnThrustX(spr->mobj, shadowdir, spr->mobj->z - floorheight), - spr->mobj->y + P_ReturnThrustY(spr->mobj, shadowdir, spr->mobj->z - floorheight), - spr->mobj->z, spr->mobj->height); - // The shadow would be falling on a wall? Don't draw it, then. - // Would draw midair otherwise. - if (floorz < floorheight) - return; - } + floordiff = abs(thing->z - floorz); - floorheight = FixedInt(spr->mobj->z - floorheight); + alpha = floordiff / (4*FRACUNIT) + 75; + if (alpha >= 255) return; + alpha = 255 - alpha; - offset = floorheight; - } - else - floorheight = FixedInt(spr->mobj->z - mobjfloor); + gpatch = (GLPatch_t *)W_CachePatchName("DSHADOW", PU_CACHE); + if (!(gpatch && gpatch->mipmap->grInfo.format)) return; + HWR_GetPatch(gpatch); + + scalemul = FixedMul(FRACUNIT - floordiff/640, scale); + scalemul = FixedMul(scalemul, (thing->radius*2) / gpatch->height); + + fscale = FIXED_TO_FLOAT(scalemul); + fx = FIXED_TO_FLOAT(thing->x); + fy = FIXED_TO_FLOAT(thing->y); - // create the sprite billboard - // // 3--2 // | /| // |/ | // 0--1 - // x1/x2 were already scaled in HWR_ProjectSprite - // First match the normal sprite - swallVerts[0].x = swallVerts[3].x = spr->x1; - swallVerts[2].x = swallVerts[1].x = spr->x2; - swallVerts[0].z = swallVerts[3].z = spr->z1; - swallVerts[2].z = swallVerts[1].z = spr->z2; + if (thing && fabsf(fscale - 1.0f) > 1.0E-36f) + offset = (gpatch->height/2) * fscale; + else + offset = (float)(gpatch->height/2); - if (spr->mobj && fabsf(this_scale - 1.0f) > 1.0E-36f) + shadowVerts[0].x = shadowVerts[3].x = fx - offset; + shadowVerts[2].x = shadowVerts[1].x = fx + offset; + shadowVerts[0].z = shadowVerts[1].z = fy - offset; + shadowVerts[3].z = shadowVerts[2].z = fy + offset; + + if (floorslope) { - // Always a pixel above the floor, perfectly flat. - swallVerts[0].y = swallVerts[1].y = swallVerts[2].y = swallVerts[3].y = spr->ty - gpatch->topoffset * this_scale - (floorheight+3); - - // Now transform the TOP vertices along the floor in the direction of the camera - swallVerts[3].x = spr->x1 + ((gpatch->height * this_scale) + offset) * gr_viewcos; - swallVerts[2].x = spr->x2 + ((gpatch->height * this_scale) + offset) * gr_viewcos; - swallVerts[3].z = spr->z1 + ((gpatch->height * this_scale) + offset) * gr_viewsin; - swallVerts[2].z = spr->z2 + ((gpatch->height * this_scale) + offset) * gr_viewsin; + for (i = 0; i < 4; i++) + { + slopez = P_GetZAt(floorslope, FLOAT_TO_FIXED(shadowVerts[i].x), FLOAT_TO_FIXED(shadowVerts[i].z)); + shadowVerts[i].y = FIXED_TO_FLOAT(slopez) + 0.05f; + } } else { - // Always a pixel above the floor, perfectly flat. - swallVerts[0].y = swallVerts[1].y = swallVerts[2].y = swallVerts[3].y = spr->ty - gpatch->topoffset - (floorheight+3); - - // Now transform the TOP vertices along the floor in the direction of the camera - swallVerts[3].x = spr->x1 + (gpatch->height + offset) * gr_viewcos; - swallVerts[2].x = spr->x2 + (gpatch->height + offset) * gr_viewcos; - swallVerts[3].z = spr->z1 + (gpatch->height + offset) * gr_viewsin; - swallVerts[2].z = spr->z2 + (gpatch->height + offset) * gr_viewsin; - } - - // We also need to move the bottom ones away when shadowoffs is on - if (cv_shadowoffs.value) - { - swallVerts[0].x = spr->x1 + offset * gr_viewcos; - swallVerts[1].x = spr->x2 + offset * gr_viewcos; - swallVerts[0].z = spr->z1 + offset * gr_viewsin; - swallVerts[1].z = spr->z2 + offset * gr_viewsin; + for (i = 0; i < 4; i++) + shadowVerts[i].y = FIXED_TO_FLOAT(floorz) + 0.05f; } if (spr->flip) { - swallVerts[0].sow = swallVerts[3].sow = gpatch->max_s; - swallVerts[2].sow = swallVerts[1].sow = 0; + shadowVerts[0].sow = shadowVerts[3].sow = gpatch->max_s; + shadowVerts[2].sow = shadowVerts[1].sow = 0; } else { - swallVerts[0].sow = swallVerts[3].sow = 0; - swallVerts[2].sow = swallVerts[1].sow = gpatch->max_s; + shadowVerts[0].sow = shadowVerts[3].sow = 0; + shadowVerts[2].sow = shadowVerts[1].sow = gpatch->max_s; } // flip the texture coords (look familiar?) if (spr->vflip) { - swallVerts[3].tow = swallVerts[2].tow = gpatch->max_t; - swallVerts[0].tow = swallVerts[1].tow = 0; + shadowVerts[3].tow = shadowVerts[2].tow = gpatch->max_t; + shadowVerts[0].tow = shadowVerts[1].tow = 0; } else { - swallVerts[3].tow = swallVerts[2].tow = 0; - swallVerts[0].tow = swallVerts[1].tow = gpatch->max_t; + shadowVerts[3].tow = shadowVerts[2].tow = 0; + shadowVerts[0].tow = shadowVerts[1].tow = gpatch->max_t; } - sSurf.FlatColor.s.red = 0x00; - sSurf.FlatColor.s.blue = 0x00; - sSurf.FlatColor.s.green = 0x00; - - /*if (spr->mobj->frame & FF_TRANSMASK || spr->mobj->flags2 & MF2_SHADOW) + if (thing->subsector->sector->numlights) { - sector_t *sector = spr->mobj->subsector->sector; - UINT8 lightlevel = 255; - extracolormap_t *colormap = sector->extra_colormap; + light = R_GetPlaneLight(thing->subsector->sector, floorz, false); // Always use the light at the top instead of whatever I was doing before - if (sector->numlights) - { - INT32 light = R_GetPlaneLight(sector, spr->mobj->floorz, false); + lightlevel = *thing->subsector->sector->lightlist[light].lightlevel; - if (!(spr->mobj->frame & FF_FULLBRIGHT)) - lightlevel = *sector->lightlist[light].lightlevel; - - if (*sector->lightlist[light].extra_colormap) - colormap = *sector->lightlist[light].extra_colormap; - } - else - { - lightlevel = sector->lightlevel; - - if (sector->extra_colormap) - colormap = sector->extra_colormap; - } - - if (colormap) - sSurf.FlatColor.rgba = HWR_Lighting(lightlevel/2, colormap->rgba, colormap->fadergba, false, true); - else - sSurf.FlatColor.rgba = HWR_Lighting(lightlevel/2, NORMALFOG, FADEFOG, false, true); - }*/ - - // shadow is always half as translucent as the sprite itself - if (!cv_translucency.value) // use default translucency (main sprite won't have any translucency) - sSurf.FlatColor.s.alpha = 0x80; // default - else if (spr->mobj->flags2 & MF2_SHADOW) - sSurf.FlatColor.s.alpha = 0x20; - else if (spr->mobj->frame & FF_TRANSMASK) - { - HWR_TranstableToAlpha((spr->mobj->frame & FF_TRANSMASK)>>FF_TRANSSHIFT, &sSurf); - sSurf.FlatColor.s.alpha /= 2; //cut alpha in half! + if (*thing->subsector->sector->lightlist[light].extra_colormap) + colormap = *thing->subsector->sector->lightlist[light].extra_colormap; } else - sSurf.FlatColor.s.alpha = 0x80; // default - - if (sSurf.FlatColor.s.alpha > floorheight/4) { - sSurf.FlatColor.s.alpha = (UINT8)(sSurf.FlatColor.s.alpha - floorheight/4); - HWD.pfnDrawPolygon(&sSurf, swallVerts, 4, PF_Translucent|PF_Modulated|PF_Clip); + lightlevel = thing->subsector->sector->lightlevel; + + if (thing->subsector->sector->extra_colormap) + colormap = thing->subsector->sector->extra_colormap; } + + if (colormap) + sSurf.FlatColor.rgba = HWR_Lighting(lightlevel, colormap->rgba, colormap->fadergba, false, false); + else + sSurf.FlatColor.rgba = HWR_Lighting(lightlevel, NORMALFOG, FADEFOG, false, false); + + sSurf.FlatColor.s.alpha = alpha; + + HWD.pfnDrawPolygon(&sSurf, shadowVerts, 4, PF_Translucent|PF_Modulated|PF_Clip); } -#endif //#ifdef GLBADSHADOWS // This is expecting a pointer to an array containing 4 wallVerts for a sprite static void HWR_RotateSpritePolyToAim(gr_vissprite_t *spr, FOutVector *wallVerts) @@ -4372,24 +4283,6 @@ static void HWR_SplitSprite(gr_vissprite_t *spr) //Hurdler: 25/04/2000: now support colormap in hardware mode HWR_GetMappedPatch(gpatch, spr->colormap); -#ifdef GLBADSHADOWS - // Draw shadow BEFORE sprite - if (cv_shadow.value // Shadows enabled - && (spr->mobj->flags & (MF_SCENERY|MF_SPAWNCEILING|MF_NOGRAVITY)) != (MF_SCENERY|MF_SPAWNCEILING|MF_NOGRAVITY) // Ceiling scenery have no shadow. - && !(spr->mobj->flags2 & MF2_DEBRIS) // Debris have no corona or shadow. -#ifdef ALAM_LIGHTING - && !(t_lspr[spr->mobj->sprite]->type // Things with dynamic lights have no shadow. - && (!spr->mobj->player || spr->mobj->player->powers[pw_super])) // Except for non-super players. -#endif - && (spr->mobj->z >= spr->mobj->floorz)) // Without this, your shadow shows on the floor, even after you die and fall through the ground. - { - //////////////////// - // SHADOW SPRITE! // - //////////////////// - HWR_DrawSpriteShadow(spr, gpatch, this_scale); - } -#endif //#ifdef GLBADSHADOWS - baseWallVerts[0].x = baseWallVerts[3].x = spr->x1; baseWallVerts[2].x = baseWallVerts[1].x = spr->x2; baseWallVerts[0].z = baseWallVerts[3].z = spr->z1; @@ -4776,24 +4669,6 @@ static void HWR_DrawSprite(gr_vissprite_t *spr) //Hurdler: 25/04/2000: now support colormap in hardware mode HWR_GetMappedPatch(gpatch, spr->colormap); -#ifdef GLBADSHADOWS - // Draw shadow BEFORE sprite - if (cv_shadow.value // Shadows enabled - && (spr->mobj->flags & (MF_SCENERY|MF_SPAWNCEILING|MF_NOGRAVITY)) != (MF_SCENERY|MF_SPAWNCEILING|MF_NOGRAVITY) // Ceiling scenery have no shadow. - && !(spr->mobj->flags2 & MF2_DEBRIS) // Debris have no corona or shadow. -#ifdef ALAM_LIGHTING - && !(t_lspr[spr->mobj->sprite]->type // Things with dynamic lights have no shadow. - && (!spr->mobj->player || spr->mobj->player->powers[pw_super])) // Except for non-super players. -#endif - && (spr->mobj->z >= spr->mobj->floorz)) // Without this, your shadow shows on the floor, even after you die and fall through the ground. - { - //////////////////// - // SHADOW SPRITE! // - //////////////////// - HWR_DrawSpriteShadow(spr, gpatch, this_scale); - } -#endif //#ifdef GLBADSHADOWS - // if it has a dispoffset, push it a little towards the camera if (spr->dispoffset) { float co = -gr_viewcos*(0.05f*spr->dispoffset); @@ -5407,6 +5282,12 @@ static void HWR_DrawSprites(void) HWR_DrawPrecipitationSprite(spr); else #endif + { + if (spr->mobj && spr->mobj->shadowscale && !(spr->mobj->frame & FF_PAPERSPRITE)) + { + HWR_DrawDropShadow(spr->mobj, spr, spr->mobj->shadowscale); + } + if (spr->mobj && spr->mobj->skin && spr->mobj->sprite == SPR_PLAY) { if (!cv_grmodels.value || md2_playermodels[(skin_t*)spr->mobj->skin-skins].notfound || md2_playermodels[(skin_t*)spr->mobj->skin-skins].scale < 0.0f) @@ -5427,6 +5308,7 @@ static void HWR_DrawSprites(void) HWR_DrawSprite(spr); } } + } } } } diff --git a/src/r_main.c b/src/r_main.c index 3c6aaf6a6..49d7594e9 100644 --- a/src/r_main.c +++ b/src/r_main.c @@ -128,12 +128,6 @@ consvar_t cv_chasecam2 = {"chasecam2", "On", CV_CALL, CV_OnOff, ChaseCam2_OnChan consvar_t cv_flipcam = {"flipcam", "No", CV_SAVE|CV_CALL|CV_NOINIT, CV_YesNo, FlipCam_OnChange, 0, NULL, NULL, 0, 0, NULL}; consvar_t cv_flipcam2 = {"flipcam2", "No", CV_SAVE|CV_CALL|CV_NOINIT, CV_YesNo, FlipCam2_OnChange, 0, NULL, NULL, 0, 0, NULL}; -#if defined(FLOORSPLATS) || defined(GLBADSHADOWS) -consvar_t cv_shadow = {"shadow", "Off", CV_SAVE, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL}; -#endif //#if defined(FLOORSPLATS) || defined(GLBADSHADOWS) -#ifdef GLBADSHADOWS -consvar_t cv_shadowoffs = {"offsetshadows", "Off", CV_SAVE, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL}; -#endif //#ifdef GLBADSHADOWS consvar_t cv_skybox = {"skybox", "On", CV_SAVE, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL}; consvar_t cv_allowmlook = {"allowmlook", "Yes", CV_NETVAR, CV_YesNo, NULL, 0, NULL, NULL, 0, 0, NULL}; consvar_t cv_showhud = {"showhud", "Yes", CV_CALL, CV_YesNo, R_SetViewSize, 0, NULL, NULL, 0, 0, NULL}; @@ -1223,12 +1217,6 @@ void R_RegisterEngineStuff(void) CV_RegisterVar(&cv_chasecam); CV_RegisterVar(&cv_chasecam2); -#if defined(FLOORSPLATS) || defined(GLBADSHADOWS) - CV_RegisterVar(&cv_shadow); -#endif //#if defined(FLOORSPLATS) || defined(GLBADSHADOWS) -#ifdef GLBADSHADOWS - CV_RegisterVar(&cv_shadowoffs); -#endif //#ifdef GLBADSHADOWS CV_RegisterVar(&cv_skybox); CV_RegisterVar(&cv_cam_dist); diff --git a/src/r_main.h b/src/r_main.h index 998bb50ef..4654f4d72 100644 --- a/src/r_main.h +++ b/src/r_main.h @@ -76,12 +76,6 @@ extern consvar_t cv_showhud, cv_translucenthud; extern consvar_t cv_homremoval; extern consvar_t cv_chasecam, cv_chasecam2; extern consvar_t cv_flipcam, cv_flipcam2; -#if defined(FLOORSPLATS) || defined(GLBADSHADOWS) -extern consvar_t cv_shadow; -#endif -#ifdef GLBADSHADOWS -extern conscar_t cv_shadowoffs; -#endif //#ifdef GLBADSHADOWS extern consvar_t cv_translucency; extern consvar_t cv_drawdist, cv_drawdist_nights, cv_drawdist_precip; extern consvar_t cv_fov; From 36511afda9a9e6485cfe752cba3455753bb6c637 Mon Sep 17 00:00:00 2001 From: Steel Titanium Date: Thu, 16 Jan 2020 14:28:03 -0500 Subject: [PATCH 726/746] Add missing name to the credits --- src/f_finale.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/f_finale.c b/src/f_finale.c index bbee48bdc..8f6eb51fc 100644 --- a/src/f_finale.c +++ b/src/f_finale.c @@ -1233,6 +1233,7 @@ static const char *credits[] = { "Thomas \"Shadow Hog\" Igoe", "Alexander \"DrTapeworm\" Moench-Ford", "\"Kaito Sinclaire\"", + "\"QueenDelta\"", "Wessel \"sphere\" Smit", "\"Spazzo\"", "\"SSNTails\"", @@ -1240,7 +1241,7 @@ static const char *credits[] = { "\"Torgo\"", "Jarrett \"JEV3\" Voight", "Johnny \"Sonikku\" Wallbank", - "Marco \"mazmazz\" Zafra", + "Marco \"mazmazz\" Zafra" "", "\1Boss Design", "Ben \"Mystic\" Geyer", From 4c6edd87dfb195a0f141bc101888b354677c3374 Mon Sep 17 00:00:00 2001 From: Steel Titanium Date: Thu, 16 Jan 2020 14:31:36 -0500 Subject: [PATCH 727/746] Restore this that got removed shomehow --- src/f_finale.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/f_finale.c b/src/f_finale.c index 8f6eb51fc..87e41df78 100644 --- a/src/f_finale.c +++ b/src/f_finale.c @@ -1241,7 +1241,7 @@ static const char *credits[] = { "\"Torgo\"", "Jarrett \"JEV3\" Voight", "Johnny \"Sonikku\" Wallbank", - "Marco \"mazmazz\" Zafra" + "Marco \"mazmazz\" Zafra", "", "\1Boss Design", "Ben \"Mystic\" Geyer", From 32c65ae8444a30fa846daba2f7de6e0a608565b6 Mon Sep 17 00:00:00 2001 From: Steel Titanium Date: Thu, 16 Jan 2020 18:59:39 -0500 Subject: [PATCH 728/746] Move to the end of the list --- src/f_finale.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/f_finale.c b/src/f_finale.c index 87e41df78..1d97038b8 100644 --- a/src/f_finale.c +++ b/src/f_finale.c @@ -1233,7 +1233,6 @@ static const char *credits[] = { "Thomas \"Shadow Hog\" Igoe", "Alexander \"DrTapeworm\" Moench-Ford", "\"Kaito Sinclaire\"", - "\"QueenDelta\"", "Wessel \"sphere\" Smit", "\"Spazzo\"", "\"SSNTails\"", @@ -1242,6 +1241,7 @@ static const char *credits[] = { "Jarrett \"JEV3\" Voight", "Johnny \"Sonikku\" Wallbank", "Marco \"mazmazz\" Zafra", + "\"QueenDelta\"", "", "\1Boss Design", "Ben \"Mystic\" Geyer", From 54ec64062c4f8d84c9b8569bfef3edf5ac0c9948 Mon Sep 17 00:00:00 2001 From: Steel Titanium Date: Thu, 16 Jan 2020 19:20:05 -0500 Subject: [PATCH 729/746] Revert "Move to the end of the list" This reverts commit 32c65ae8444a30fa846daba2f7de6e0a608565b6. --- src/f_finale.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/f_finale.c b/src/f_finale.c index 1d97038b8..87e41df78 100644 --- a/src/f_finale.c +++ b/src/f_finale.c @@ -1233,6 +1233,7 @@ static const char *credits[] = { "Thomas \"Shadow Hog\" Igoe", "Alexander \"DrTapeworm\" Moench-Ford", "\"Kaito Sinclaire\"", + "\"QueenDelta\"", "Wessel \"sphere\" Smit", "\"Spazzo\"", "\"SSNTails\"", @@ -1241,7 +1242,6 @@ static const char *credits[] = { "Jarrett \"JEV3\" Voight", "Johnny \"Sonikku\" Wallbank", "Marco \"mazmazz\" Zafra", - "\"QueenDelta\"", "", "\1Boss Design", "Ben \"Mystic\" Geyer", From f9dd5056c6283344a5e2bac724e4a6ab5cba7676 Mon Sep 17 00:00:00 2001 From: James R Date: Thu, 16 Jan 2020 16:36:10 -0800 Subject: [PATCH 730/746] musicdef-2.2.1 for converting 2.2.0 MUSICDEF to new format --- tools/musicdef-2.2.1/Makefile | 1 + tools/musicdef-2.2.1/musicdef-2.2.1.c | 76 +++++++++++++++++++++++++++ 2 files changed, 77 insertions(+) create mode 100644 tools/musicdef-2.2.1/Makefile create mode 100644 tools/musicdef-2.2.1/musicdef-2.2.1.c diff --git a/tools/musicdef-2.2.1/Makefile b/tools/musicdef-2.2.1/Makefile new file mode 100644 index 000000000..403d27b04 --- /dev/null +++ b/tools/musicdef-2.2.1/Makefile @@ -0,0 +1 @@ +musicdef-2.2.1: diff --git a/tools/musicdef-2.2.1/musicdef-2.2.1.c b/tools/musicdef-2.2.1/musicdef-2.2.1.c new file mode 100644 index 000000000..d73f16efc --- /dev/null +++ b/tools/musicdef-2.2.1/musicdef-2.2.1.c @@ -0,0 +1,76 @@ +/* +Copyright 2019 James R. +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + +1. Redistributions of source code must retain the above copyright notice, this + list of conditions and the following disclaimer. +2. Redistributions in binary form must reproduce the above copyright notice. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +*/ + +#include +#include + +#ifdef _WIN32 +#define strcasecmp _stricmp +#else +#include +#endif + +int +main (int ac, char **av) +{ + char line[256]; + char buf[256]; + char *var; + char *val; + char *p; + int n; + (void)ac; + (void)av; + fputs( + "Copyright 2019 James R.\n" + "All rights reserved.\n" + "\n" + "Usage: musicdef-2.2.1 < old-MUSICDEF > new-MUSICDEF\n" + "\n" + ,stderr); + while (fgets(line, sizeof line, stdin)) + { + memcpy(buf, line, sizeof buf); + if (( var = strtok(buf, " =") )) + { + if (!( + strcasecmp(var, "TITLE") && + strcasecmp(var, "AUTHORS") + )){ + if (( val = strtok(0, "") )) + { + for (p = val; ( p = strchr(p, '_') ); ) + { + n = strspn(p, "_"); + memset(p, ' ', n); + p += n; + } + printf("%s %s", var, val); + continue; + } + } + } + fputs(line, stdout); + } + return 0; +} From 90c9a467f31215946f55fcffdd855a04e88a9139 Mon Sep 17 00:00:00 2001 From: James R Date: Thu, 16 Jan 2020 16:45:52 -0800 Subject: [PATCH 731/746] Bah it's a new year! --- tools/musicdef-2.2.1/musicdef-2.2.1.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tools/musicdef-2.2.1/musicdef-2.2.1.c b/tools/musicdef-2.2.1/musicdef-2.2.1.c index d73f16efc..585bc6bb0 100644 --- a/tools/musicdef-2.2.1/musicdef-2.2.1.c +++ b/tools/musicdef-2.2.1/musicdef-2.2.1.c @@ -1,5 +1,5 @@ /* -Copyright 2019 James R. +Copyright 2020 James R. All rights reserved. Redistribution and use in source and binary forms, with or without @@ -42,7 +42,7 @@ main (int ac, char **av) (void)ac; (void)av; fputs( - "Copyright 2019 James R.\n" + "Copyright 2020 James R.\n" "All rights reserved.\n" "\n" "Usage: musicdef-2.2.1 < old-MUSICDEF > new-MUSICDEF\n" From 51f1f4f2b155999f696be93fc8422360ad7aa8c4 Mon Sep 17 00:00:00 2001 From: James R Date: Thu, 16 Jan 2020 16:46:31 -0800 Subject: [PATCH 732/746] Also check ALTTITLE --- tools/musicdef-2.2.1/musicdef-2.2.1.c | 1 + 1 file changed, 1 insertion(+) diff --git a/tools/musicdef-2.2.1/musicdef-2.2.1.c b/tools/musicdef-2.2.1/musicdef-2.2.1.c index 585bc6bb0..65d434c8a 100644 --- a/tools/musicdef-2.2.1/musicdef-2.2.1.c +++ b/tools/musicdef-2.2.1/musicdef-2.2.1.c @@ -55,6 +55,7 @@ main (int ac, char **av) { if (!( strcasecmp(var, "TITLE") && + strcasecmp(var, "ALTTITLE") && strcasecmp(var, "AUTHORS") )){ if (( val = strtok(0, "") )) From e4f0fa46f58c4a2236d48f9774ba5eeb65d021e4 Mon Sep 17 00:00:00 2001 From: James R Date: Thu, 16 Jan 2020 18:07:28 -0800 Subject: [PATCH 733/746] Dumbass NONET stuff... --- src/mserv.c | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) diff --git a/src/mserv.c b/src/mserv.c index a842e92e9..4ddab05b9 100644 --- a/src/mserv.c +++ b/src/mserv.c @@ -323,13 +323,9 @@ static INT32 GetServersList(void) // // MS_Connect() // +#ifndef NONET static INT32 MS_SubConnect(const char *ip_addr, const char *str_port, INT32 async, struct sockaddr *bindaddr, socklen_t bindaddrlen) { -#ifdef NONET - (void)ip_addr; - (void)str_port; - (void)async; -#else struct my_addrinfo *ai, *runp, hints; int gaie; @@ -402,12 +398,18 @@ static INT32 MS_SubConnect(const char *ip_addr, const char *str_port, INT32 asyn runp = runp->ai_next; } I_freeaddrinfo(ai); -#endif return MS_CONNECT_ERROR; } +#endif/*NONET xd*/ static INT32 MS_Connect(const char *ip_addr, const char *str_port, INT32 async) { +#ifdef NONET + (void)ip_addr; + (void)str_port; + (void)async; + return MS_CONNECT_ERROR; +#else const char *lhost; struct my_addrinfo hints; struct my_addrinfo *ai, *aip; @@ -443,6 +445,7 @@ static INT32 MS_Connect(const char *ip_addr, const char *str_port, INT32 async) } else return MS_SubConnect(ip_addr, str_port, async, 0, 0); +#endif/*NONET xd*/ } #define NUM_LIST_SERVER MAXSERVERLIST From 7adc108a2af8bbd621d3293ba38161b8b5a96f19 Mon Sep 17 00:00:00 2001 From: Jaime Passos Date: Fri, 17 Jan 2020 00:34:31 -0300 Subject: [PATCH 734/746] typoe --- src/dehacked.c | 2 +- src/p_maputl.c | 8 ++++---- src/p_spec.c | 2 +- src/r_defs.h | 2 +- 4 files changed, 7 insertions(+), 7 deletions(-) diff --git a/src/dehacked.c b/src/dehacked.c index e6e2a29b2..082adda24 100644 --- a/src/dehacked.c +++ b/src/dehacked.c @@ -9670,7 +9670,7 @@ struct { {"FF_QUICKSAND",FF_QUICKSAND}, ///< Quicksand! {"FF_PLATFORM",FF_PLATFORM}, ///< You can jump up through this to the top. {"FF_REVERSEPLATFORM",FF_REVERSEPLATFORM}, ///< A fall-through floor in normal gravity, a platform in reverse gravity. - {"FF_INTANGABLEFLATS",FF_INTANGABLEFLATS}, ///< Both flats are intangable, but the sides are still solid. + {"FF_INTANGIBLEFLATS",FF_INTANGIBLEFLATS}, ///< Both flats are intangible, but the sides are still solid. {"FF_SHATTER",FF_SHATTER}, ///< Used with ::FF_BUSTUP. Bustable on mere touch. {"FF_SPINBUST",FF_SPINBUST}, ///< Used with ::FF_BUSTUP. Also bustable if you're in your spinning frames. {"FF_STRONGBUST",FF_STRONGBUST }, ///< Used with ::FF_BUSTUP. Only bustable by "strong" characters (Knuckles) and abilities (bouncing, twinspin, melee). diff --git a/src/p_maputl.c b/src/p_maputl.c index afa020504..b4043d643 100644 --- a/src/p_maputl.c +++ b/src/p_maputl.c @@ -643,7 +643,7 @@ void P_LineOpening(line_t *linedef, mobj_t *mobj) delta1 = abs(mobj->z - (bottomheight + ((topheight - bottomheight)/2))); delta2 = abs(thingtop - (bottomheight + ((topheight - bottomheight)/2))); - if (delta1 >= delta2 && (rover->flags & FF_INTANGABLEFLATS) != FF_PLATFORM) // thing is below FOF + if (delta1 >= delta2 && (rover->flags & FF_INTANGIBLEFLATS) != FF_PLATFORM) // thing is below FOF { if (bottomheight < opentop) { opentop = bottomheight; @@ -656,7 +656,7 @@ void P_LineOpening(line_t *linedef, mobj_t *mobj) highceiling = bottomheight; } - if (delta1 < delta2 && (rover->flags & FF_INTANGABLEFLATS) != FF_REVERSEPLATFORM) // thing is above FOF + if (delta1 < delta2 && (rover->flags & FF_INTANGIBLEFLATS) != FF_REVERSEPLATFORM) // thing is above FOF { if (topheight > openbottom) { openbottom = topheight; @@ -689,7 +689,7 @@ void P_LineOpening(line_t *linedef, mobj_t *mobj) delta1 = abs(mobj->z - (bottomheight + ((topheight - bottomheight)/2))); delta2 = abs(thingtop - (bottomheight + ((topheight - bottomheight)/2))); - if (delta1 >= delta2 && (rover->flags & FF_INTANGABLEFLATS) != FF_PLATFORM) // thing is below FOF + if (delta1 >= delta2 && (rover->flags & FF_INTANGIBLEFLATS) != FF_PLATFORM) // thing is below FOF { if (bottomheight < opentop) { opentop = bottomheight; @@ -702,7 +702,7 @@ void P_LineOpening(line_t *linedef, mobj_t *mobj) highceiling = bottomheight; } - if (delta1 < delta2 && (rover->flags & FF_INTANGABLEFLATS) != FF_REVERSEPLATFORM) // thing is above FOF + if (delta1 < delta2 && (rover->flags & FF_INTANGIBLEFLATS) != FF_REVERSEPLATFORM) // thing is above FOF { if (topheight > openbottom) { openbottom = topheight; diff --git a/src/p_spec.c b/src/p_spec.c index 9defc33a0..e5b026a3d 100644 --- a/src/p_spec.c +++ b/src/p_spec.c @@ -6931,7 +6931,7 @@ void P_SpawnSpecials(boolean fromnetsave) break; case 146: // Intangible floor/ceiling with solid sides (fences/hoops maybe?) - P_AddFakeFloorsByLine(i, FF_EXISTS|FF_SOLID|FF_RENDERSIDES|FF_ALLSIDES|FF_INTANGABLEFLATS, secthinkers); + P_AddFakeFloorsByLine(i, FF_EXISTS|FF_SOLID|FF_RENDERSIDES|FF_ALLSIDES|FF_INTANGIBLEFLATS, secthinkers); break; case 150: // Air bobbing platform diff --git a/src/r_defs.h b/src/r_defs.h index eade61db5..88d418fc9 100644 --- a/src/r_defs.h +++ b/src/r_defs.h @@ -144,7 +144,7 @@ typedef enum FF_QUICKSAND = 0x1000000, ///< Quicksand! FF_PLATFORM = 0x2000000, ///< You can jump up through this to the top. FF_REVERSEPLATFORM = 0x4000000, ///< A fall-through floor in normal gravity, a platform in reverse gravity. - FF_INTANGABLEFLATS = 0x6000000, ///< Both flats are intangable, but the sides are still solid. + FF_INTANGIBLEFLATS = 0x6000000, ///< Both flats are intangible, but the sides are still solid. FF_SHATTER = 0x8000000, ///< Used with ::FF_BUSTUP. Bustable on mere touch. FF_SPINBUST = 0x10000000, ///< Used with ::FF_BUSTUP. Also bustable if you're in your spinning frames. FF_STRONGBUST = 0x20000000, ///< Used with ::FF_BUSTUP. Only bustable by "strong" characters (Knuckles) and abilities (bouncing, twinspin, melee). From 8bfdb52231b0cdff953410c0c150c8a28ea9b465 Mon Sep 17 00:00:00 2001 From: Jaime Passos Date: Fri, 17 Jan 2020 00:49:43 -0300 Subject: [PATCH 735/746] add R_IsPointInSubsector to lua baselib --- src/lua_baselib.c | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/src/lua_baselib.c b/src/lua_baselib.c index 2a82ec512..7a16f3c69 100644 --- a/src/lua_baselib.c +++ b/src/lua_baselib.c @@ -2193,6 +2193,20 @@ static int lib_rPointInSubsector(lua_State *L) return 1; } +static int lib_rIsPointInSubsector(lua_State *L) +{ + fixed_t x = luaL_checkfixed(L, 1); + fixed_t y = luaL_checkfixed(L, 2); + subsector_t *sub = R_IsPointInSubsector(x, y); + //HUDSAFE + INLEVEL + if (sub) + LUA_PushUserdata(L, sub, META_SUBSECTOR); + else + lua_pushnil(L); + return 1; +} + // R_THINGS //////////// @@ -3127,6 +3141,7 @@ static luaL_Reg lib[] = { {"R_PointToDist",lib_rPointToDist}, {"R_PointToDist2",lib_rPointToDist2}, {"R_PointInSubsector",lib_rPointInSubsector}, + {"R_IsPointInSubsector",lib_rIsPointInSubsector}, // r_things (sprite) {"R_Char2Frame",lib_rChar2Frame}, From f0843cba132c8da35e76d23f59d8ce6ffa542232 Mon Sep 17 00:00:00 2001 From: fickleheart Date: Fri, 17 Jan 2020 00:13:05 -0600 Subject: [PATCH 736/746] Let vissprites have shadows too fuck it, hopefully it works --- 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 41fb103e3..85452b745 100644 --- a/src/r_things.c +++ b/src/r_things.c @@ -1904,7 +1904,7 @@ static void R_ProjectSprite(mobj_t *thing) if (thing->subsector->sector->numlights) R_SplitSprite(vis); - if (oldthing->shadowscale && !papersprite) + if (oldthing->shadowscale) R_ProjectDropShadow(oldthing, vis, oldthing->shadowscale, basetx, tz); // Debug From 9a4ad2094743a520c9a09222465abed02f1d0197 Mon Sep 17 00:00:00 2001 From: fickleheart Date: Fri, 17 Jan 2020 00:13:13 -0600 Subject: [PATCH 737/746] DAMNIT --- 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 85452b745..430542a20 100644 --- a/src/r_things.c +++ b/src/r_things.c @@ -1335,7 +1335,7 @@ static void R_ProjectDropShadow(mobj_t *thing, vissprite_t *vis, fixed_t scale, // reusing x1 variable x1 += (x2-x1)/2; - shadow->shear.offset = (vis->x1-x1)/2; + shadow->shear.offset = (shadow->x1-x1)/2; if (thing->subsector->sector->numlights) { From 4ca44f2d578bf7d708196388b3883fdb6d0a4808 Mon Sep 17 00:00:00 2001 From: fickleheart Date: Fri, 17 Jan 2020 00:16:15 -0600 Subject: [PATCH 738/746] Bosses need dropshadows too --- src/p_mobj.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/p_mobj.c b/src/p_mobj.c index e4de59031..a8599ceb5 100644 --- a/src/p_mobj.c +++ b/src/p_mobj.c @@ -10563,7 +10563,7 @@ mobj_t *P_SpawnMobj(fixed_t x, fixed_t y, fixed_t z, mobjtype_t type) type == MT_ROLLOUTROCK || type == MT_EGGMOBILE4_MACE || (type >= MT_SMALLMACE && type <= MT_REDSPRINGBALL) || - (mobj->flags & MF_ENEMY) + (mobj->flags & (MF_ENEMY|MF_BOSS)) ) mobj->shadowscale = FRACUNIT; else if ( From 919661ff8f149878c18c8628484d626b2ffb77ec Mon Sep 17 00:00:00 2001 From: fickleheart Date: Fri, 17 Jan 2020 00:18:00 -0600 Subject: [PATCH 739/746] Give me a break --- src/lua_mobjlib.c | 1 + 1 file changed, 1 insertion(+) diff --git a/src/lua_mobjlib.c b/src/lua_mobjlib.c index fd32b2134..90733b2c6 100644 --- a/src/lua_mobjlib.c +++ b/src/lua_mobjlib.c @@ -726,6 +726,7 @@ static int mobj_set(lua_State *L) break; case mobj_shadowscale: mo->shadowscale = luaL_checkfixed(L, 3); + break; default: lua_getfield(L, LUA_REGISTRYINDEX, LREG_EXTVARS); I_Assert(lua_istable(L, -1)); From d39d8506caeeb2530d9b02ac94ac48e8f5eff63a Mon Sep 17 00:00:00 2001 From: fickleheart Date: Fri, 17 Jan 2020 00:20:10 -0600 Subject: [PATCH 740/746] Let nerds turn off shadows --- src/r_main.c | 6 +----- src/r_main.h | 2 -- src/r_things.c | 2 +- 3 files changed, 2 insertions(+), 8 deletions(-) diff --git a/src/r_main.c b/src/r_main.c index 3c6aaf6a6..4b044c6cc 100644 --- a/src/r_main.c +++ b/src/r_main.c @@ -128,9 +128,7 @@ consvar_t cv_chasecam2 = {"chasecam2", "On", CV_CALL, CV_OnOff, ChaseCam2_OnChan consvar_t cv_flipcam = {"flipcam", "No", CV_SAVE|CV_CALL|CV_NOINIT, CV_YesNo, FlipCam_OnChange, 0, NULL, NULL, 0, 0, NULL}; consvar_t cv_flipcam2 = {"flipcam2", "No", CV_SAVE|CV_CALL|CV_NOINIT, CV_YesNo, FlipCam2_OnChange, 0, NULL, NULL, 0, 0, NULL}; -#if defined(FLOORSPLATS) || defined(GLBADSHADOWS) -consvar_t cv_shadow = {"shadow", "Off", CV_SAVE, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL}; -#endif //#if defined(FLOORSPLATS) || defined(GLBADSHADOWS) +consvar_t cv_shadow = {"shadow", "On", CV_SAVE, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL}; #ifdef GLBADSHADOWS consvar_t cv_shadowoffs = {"offsetshadows", "Off", CV_SAVE, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL}; #endif //#ifdef GLBADSHADOWS @@ -1223,9 +1221,7 @@ void R_RegisterEngineStuff(void) CV_RegisterVar(&cv_chasecam); CV_RegisterVar(&cv_chasecam2); -#if defined(FLOORSPLATS) || defined(GLBADSHADOWS) CV_RegisterVar(&cv_shadow); -#endif //#if defined(FLOORSPLATS) || defined(GLBADSHADOWS) #ifdef GLBADSHADOWS CV_RegisterVar(&cv_shadowoffs); #endif //#ifdef GLBADSHADOWS diff --git a/src/r_main.h b/src/r_main.h index 998bb50ef..0764c40d2 100644 --- a/src/r_main.h +++ b/src/r_main.h @@ -76,9 +76,7 @@ extern consvar_t cv_showhud, cv_translucenthud; extern consvar_t cv_homremoval; extern consvar_t cv_chasecam, cv_chasecam2; extern consvar_t cv_flipcam, cv_flipcam2; -#if defined(FLOORSPLATS) || defined(GLBADSHADOWS) extern consvar_t cv_shadow; -#endif #ifdef GLBADSHADOWS extern conscar_t cv_shadowoffs; #endif //#ifdef GLBADSHADOWS diff --git a/src/r_things.c b/src/r_things.c index 430542a20..680ae4d4f 100644 --- a/src/r_things.c +++ b/src/r_things.c @@ -1904,7 +1904,7 @@ static void R_ProjectSprite(mobj_t *thing) if (thing->subsector->sector->numlights) R_SplitSprite(vis); - if (oldthing->shadowscale) + if (oldthing->shadowscale && cv_shadow.value) R_ProjectDropShadow(oldthing, vis, oldthing->shadowscale, basetx, tz); // Debug From f59ed6b2f48fab3350f6bebe9373128042c49b1d Mon Sep 17 00:00:00 2001 From: fickleheart Date: Fri, 17 Jan 2020 00:34:57 -0600 Subject: [PATCH 741/746] DOUBLE DAMNIT --- 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 680ae4d4f..8fa0f2d0e 100644 --- a/src/r_things.c +++ b/src/r_things.c @@ -1335,7 +1335,7 @@ static void R_ProjectDropShadow(mobj_t *thing, vissprite_t *vis, fixed_t scale, // reusing x1 variable x1 += (x2-x1)/2; - shadow->shear.offset = (shadow->x1-x1)/2; + shadow->shear.offset = shadow->x1-x1; if (thing->subsector->sector->numlights) { From 999094f2f6f395c2a63db0789c8e1545e47e13df Mon Sep 17 00:00:00 2001 From: Jaime Passos Date: Fri, 17 Jan 2020 16:11:17 -0300 Subject: [PATCH 742/746] backwards compat --- src/dehacked.c | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/src/dehacked.c b/src/dehacked.c index 082adda24..0dbfe3318 100644 --- a/src/dehacked.c +++ b/src/dehacked.c @@ -9427,7 +9427,7 @@ struct { {"SH_FORCE",SH_FORCE}, {"SH_FORCEHP",SH_FORCEHP}, // to be used as a bitmask only // Mostly for use with Mario mode. - {"SH_FIREFLOWER", SH_FIREFLOWER}, + {"SH_FIREFLOWER",SH_FIREFLOWER}, {"SH_STACK",SH_STACK}, {"SH_NOSTACK",SH_NOSTACK}, @@ -9442,7 +9442,7 @@ struct { {"CR_ROPEHANG",CR_ROPEHANG}, {"CR_MACESPIN",CR_MACESPIN}, {"CR_MINECART",CR_MINECART}, - {"CR_ROLLOUT", CR_ROLLOUT}, + {"CR_ROLLOUT",CR_ROLLOUT}, {"CR_PTERABYTE",CR_PTERABYTE}, // Ring weapons (ringweapons_t) @@ -9609,7 +9609,7 @@ struct { {"NUM_WEAPONS",NUM_WEAPONS}, // Value for infinite lives - {"INFLIVES", INFLIVES}, + {"INFLIVES",INFLIVES}, // Got Flags, for player->gotflag! // Used to be MF_ for some stupid reason, now they're GF_ to stop them looking like mobjflags @@ -9671,9 +9671,10 @@ struct { {"FF_PLATFORM",FF_PLATFORM}, ///< You can jump up through this to the top. {"FF_REVERSEPLATFORM",FF_REVERSEPLATFORM}, ///< A fall-through floor in normal gravity, a platform in reverse gravity. {"FF_INTANGIBLEFLATS",FF_INTANGIBLEFLATS}, ///< Both flats are intangible, but the sides are still solid. + {"FF_INTANGABLEFLATS",FF_INTANGIBLEFLATS}, ///< Both flats are intangable, but the sides are still solid. {"FF_SHATTER",FF_SHATTER}, ///< Used with ::FF_BUSTUP. Bustable on mere touch. {"FF_SPINBUST",FF_SPINBUST}, ///< Used with ::FF_BUSTUP. Also bustable if you're in your spinning frames. - {"FF_STRONGBUST",FF_STRONGBUST }, ///< Used with ::FF_BUSTUP. Only bustable by "strong" characters (Knuckles) and abilities (bouncing, twinspin, melee). + {"FF_STRONGBUST",FF_STRONGBUST}, ///< Used with ::FF_BUSTUP. Only bustable by "strong" characters (Knuckles) and abilities (bouncing, twinspin, melee). {"FF_RIPPLE",FF_RIPPLE}, ///< Ripple the flats {"FF_COLORMAPONLY",FF_COLORMAPONLY}, ///< Only copy the colormap, not the lightlevel {"FF_GOOWATER",FF_GOOWATER}, ///< Used with ::FF_SWIMMABLE. Makes thick bouncey goop. From 43828f265c58afab1b9e3ec0193e33d13f9ac0b4 Mon Sep 17 00:00:00 2001 From: Sally Cochenour Date: Fri, 17 Jan 2020 22:20:04 -0500 Subject: [PATCH 743/746] Use shadow cvar --- src/hardware/hw_main.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/hardware/hw_main.c b/src/hardware/hw_main.c index 14121518b..2a5eae9f1 100644 --- a/src/hardware/hw_main.c +++ b/src/hardware/hw_main.c @@ -5283,7 +5283,7 @@ static void HWR_DrawSprites(void) else #endif { - if (spr->mobj && spr->mobj->shadowscale && !(spr->mobj->frame & FF_PAPERSPRITE)) + if (spr->mobj && spr->mobj->shadowscale && cv_shadow.value) { HWR_DrawDropShadow(spr->mobj, spr, spr->mobj->shadowscale); } From 0c7c5742a80b1fd849cf4aaa4f8f12045d4ba44b Mon Sep 17 00:00:00 2001 From: Tatsuru <44866610+Ikkarin@users.noreply.github.com> Date: Sat, 18 Jan 2020 12:06:04 -0300 Subject: [PATCH 744/746] Put cv_exitmove in the menus --- src/m_menu.c | 47 ++++++++++++++++++++++++----------------------- 1 file changed, 24 insertions(+), 23 deletions(-) diff --git a/src/m_menu.c b/src/m_menu.c index ec4e51c9c..8d62028e4 100644 --- a/src/m_menu.c +++ b/src/m_menu.c @@ -1584,32 +1584,33 @@ static menuitem_t OP_ServerOptionsMenu[] = {IT_STRING | IT_CVAR, NULL, "Players required for exit", &cv_playersforexit, 96}, {IT_STRING | IT_CVAR, NULL, "Starposts", &cv_coopstarposts, 101}, {IT_STRING | IT_CVAR, NULL, "Life sharing", &cv_cooplives, 106}, + {IT_STRING | IT_CVAR, NULL, "Post goal free roaming", &cv_exitmove, 111}, - {IT_HEADER, NULL, "Race, Competition", NULL, 115}, - {IT_STRING | IT_CVAR, NULL, "Level completion countdown", &cv_countdowntime, 121}, - {IT_STRING | IT_CVAR, NULL, "Item Monitors", &cv_competitionboxes, 126}, + {IT_HEADER, NULL, "Race, Competition", NULL, 120}, + {IT_STRING | IT_CVAR, NULL, "Level completion countdown", &cv_countdowntime, 126}, + {IT_STRING | IT_CVAR, NULL, "Item Monitors", &cv_competitionboxes, 131}, - {IT_HEADER, NULL, "Ringslinger (Match, CTF, Tag, H&S)", NULL, 135}, - {IT_STRING | IT_CVAR, NULL, "Time Limit", &cv_timelimit, 141}, - {IT_STRING | IT_CVAR, NULL, "Score Limit", &cv_pointlimit, 146}, - {IT_STRING | IT_CVAR, NULL, "Overtime on Tie", &cv_overtime, 151}, - {IT_STRING | IT_CVAR, NULL, "Player respawn delay", &cv_respawntime, 156}, + {IT_HEADER, NULL, "Ringslinger (Match, CTF, Tag, H&S)", NULL, 140}, + {IT_STRING | IT_CVAR, NULL, "Time Limit", &cv_timelimit, 146}, + {IT_STRING | IT_CVAR, NULL, "Score Limit", &cv_pointlimit, 151}, + {IT_STRING | IT_CVAR, NULL, "Overtime on Tie", &cv_overtime, 156}, + {IT_STRING | IT_CVAR, NULL, "Player respawn delay", &cv_respawntime, 161}, - {IT_STRING | IT_CVAR, NULL, "Item Monitors", &cv_matchboxes, 166}, - {IT_STRING | IT_CVAR, NULL, "Weapon Rings", &cv_specialrings, 171}, - {IT_STRING | IT_CVAR, NULL, "Power Stones", &cv_powerstones, 176}, + {IT_STRING | IT_CVAR, NULL, "Item Monitors", &cv_matchboxes, 171}, + {IT_STRING | IT_CVAR, NULL, "Weapon Rings", &cv_specialrings, 176}, + {IT_STRING | IT_CVAR, NULL, "Power Stones", &cv_powerstones, 181}, - {IT_STRING | IT_CVAR, NULL, "Flag respawn delay", &cv_flagtime, 186}, - {IT_STRING | IT_CVAR, NULL, "Hiding time", &cv_hidetime, 191}, + {IT_STRING | IT_CVAR, NULL, "Flag respawn delay", &cv_flagtime, 191}, + {IT_STRING | IT_CVAR, NULL, "Hiding time", &cv_hidetime, 196}, - {IT_HEADER, NULL, "Teams", NULL, 200}, - {IT_STRING | IT_CVAR, NULL, "Autobalance sizes", &cv_autobalance, 206}, - {IT_STRING | IT_CVAR, NULL, "Scramble on Map Change", &cv_scrambleonchange, 211}, + {IT_HEADER, NULL, "Teams", NULL, 205}, + {IT_STRING | IT_CVAR, NULL, "Autobalance sizes", &cv_autobalance, 211}, + {IT_STRING | IT_CVAR, NULL, "Scramble on Map Change", &cv_scrambleonchange, 216}, #ifndef NONET - {IT_HEADER, NULL, "Advanced", NULL, 220}, - {IT_STRING | IT_CVAR | IT_CV_STRING, NULL, "Master server", &cv_masterserver, 226}, - {IT_STRING | IT_CVAR, NULL, "Attempts to resynchronise", &cv_resynchattempts, 240}, + {IT_HEADER, NULL, "Advanced", NULL, 225}, + {IT_STRING | IT_CVAR | IT_CV_STRING, NULL, "Master server", &cv_masterserver, 231}, + {IT_STRING | IT_CVAR, NULL, "Attempts to resynchronise", &cv_resynchattempts, 245}, #endif }; @@ -10632,8 +10633,8 @@ static void M_ServerOptions(INT32 choice) OP_ServerOptionsMenu[ 2].status = IT_GRAYEDOUT; // Max players OP_ServerOptionsMenu[ 3].status = IT_GRAYEDOUT; // Allow add-on downloading OP_ServerOptionsMenu[ 4].status = IT_GRAYEDOUT; // Allow players to join - OP_ServerOptionsMenu[34].status = IT_GRAYEDOUT; // Master server - OP_ServerOptionsMenu[35].status = IT_GRAYEDOUT; // Attempts to resynchronise + OP_ServerOptionsMenu[35].status = IT_GRAYEDOUT; // Master server + OP_ServerOptionsMenu[36].status = IT_GRAYEDOUT; // Attempts to resynchronise } else { @@ -10641,10 +10642,10 @@ static void M_ServerOptions(INT32 choice) OP_ServerOptionsMenu[ 2].status = IT_STRING | IT_CVAR; OP_ServerOptionsMenu[ 3].status = IT_STRING | IT_CVAR; OP_ServerOptionsMenu[ 4].status = IT_STRING | IT_CVAR; - OP_ServerOptionsMenu[34].status = (netgame + OP_ServerOptionsMenu[35].status = (netgame ? IT_GRAYEDOUT : (IT_STRING | IT_CVAR | IT_CV_STRING)); - OP_ServerOptionsMenu[35].status = IT_STRING | IT_CVAR; + OP_ServerOptionsMenu[36].status = IT_STRING | IT_CVAR; } #endif From cdc3386d48a5571205dacdf981a95494c3499b36 Mon Sep 17 00:00:00 2001 From: Jaime Passos Date: Sat, 18 Jan 2020 12:10:48 -0300 Subject: [PATCH 745/746] Fix missing constant --- src/dehacked.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/dehacked.c b/src/dehacked.c index 0dbfe3318..4c36639a2 100644 --- a/src/dehacked.c +++ b/src/dehacked.c @@ -8847,7 +8847,7 @@ static const char *const MOBJEFLAG_LIST[] = { #ifdef HAVE_BLUA static const char *const MAPTHINGFLAG_LIST[4] = { - NULL, + "EXTRA", // Extra flag for objects. "OBJECTFLIP", // Reverse gravity flag for objects. "OBJECTSPECIAL", // Special flag used with certain objects. "AMBUSH" // Deaf monsters/do not react to sound. From 8348123a70474869d3dc9bae127e421f76fa2080 Mon Sep 17 00:00:00 2001 From: Tatsuru <44866610+Ikkarin@users.noreply.github.com> Date: Sat, 18 Jan 2020 13:15:24 -0300 Subject: [PATCH 746/746] Goal posts --- 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 8d62028e4..62bea7ae0 100644 --- a/src/m_menu.c +++ b/src/m_menu.c @@ -1584,7 +1584,7 @@ static menuitem_t OP_ServerOptionsMenu[] = {IT_STRING | IT_CVAR, NULL, "Players required for exit", &cv_playersforexit, 96}, {IT_STRING | IT_CVAR, NULL, "Starposts", &cv_coopstarposts, 101}, {IT_STRING | IT_CVAR, NULL, "Life sharing", &cv_cooplives, 106}, - {IT_STRING | IT_CVAR, NULL, "Post goal free roaming", &cv_exitmove, 111}, + {IT_STRING | IT_CVAR, NULL, "Post-goal free roaming", &cv_exitmove, 111}, {IT_HEADER, NULL, "Race, Competition", NULL, 120}, {IT_STRING | IT_CVAR, NULL, "Level completion countdown", &cv_countdowntime, 126},