From fa691c0ee4309fd63063b14d047e437954e10c3c Mon Sep 17 00:00:00 2001 From: James R Date: Sat, 18 Dec 2021 22:31:33 -0800 Subject: [PATCH 01/12] Create folder with branch name when saving replays --- src/g_demo.c | 6 +++--- src/p_setup.c | 12 +++++++----- 2 files changed, 10 insertions(+), 8 deletions(-) diff --git a/src/g_demo.c b/src/g_demo.c index 2dd3cd277..b8dda4299 100644 --- a/src/g_demo.c +++ b/src/g_demo.c @@ -60,7 +60,7 @@ boolean nodrawers; // for comparative timing purposes boolean noblit; // for comparative timing purposes tic_t demostarttime; // for comparative timing purposes -static char demoname[128]; +static char demoname[MAX_WADPATH]; static UINT8 *demobuffer = NULL; static UINT8 *demotime_p, *demoinfo_p; UINT8 *demo_p; @@ -3791,7 +3791,7 @@ void G_SaveDemo(void) demo_slug[strindex] = 0; if (dash) demo_slug[strindex-1] = 0; - writepoint = strstr(demoname, "-") + 1; + writepoint = strstr(strrchr(demoname, *PATHSEP), "-") + 1; demo_slug[128 - (writepoint - demoname) - 4] = 0; sprintf(writepoint, "%s.lmp", demo_slug); } @@ -3808,7 +3808,7 @@ void G_SaveDemo(void) md5_buffer((char *)p+16, (demobuffer + length) - (p+16), p); #endif - if (FIL_WriteFile(va(pandf, srb2home, demoname), demobuffer, demo_p - demobuffer)) // finally output the file. + if (FIL_WriteFile(demoname, demobuffer, demo_p - demobuffer)) // finally output the file. demo.savemode = DSM_SAVED; free(demobuffer); demo.recording = false; diff --git a/src/p_setup.c b/src/p_setup.c index db9a35a11..44717910b 100644 --- a/src/p_setup.c +++ b/src/p_setup.c @@ -3797,12 +3797,14 @@ static void P_InitGametype(void) //@TODO I'd like to fix dedis crashing when recording replays for the future too... if (!demo.playback && multiplayer && !dedicated) { - static char buf[256]; - char *path; - sprintf(buf, "media"PATHSEP"replay"PATHSEP"online"PATHSEP"%d-%s", (int) (time(NULL)), G_BuildMapName(gamemap)); + char buf[MAX_WADPATH]; + int parts; - path = va("%s"PATHSEP"media"PATHSEP"replay"PATHSEP"online", srb2home); - M_MkdirEach(path, M_PathParts(path) - 4, 0755); + sprintf(buf, "%s"PATHSEP"media"PATHSEP"replay"PATHSEP"online"PATHSEP"%s-%s"PATHSEP"%d-%s", + srb2home, compbranch, comprevision, (int) (time(NULL)), G_BuildMapName(gamemap)); + + parts = M_PathParts(buf); + M_MkdirEachUntil(buf, parts - 5, parts - 1, 0755); G_RecordDemo(buf); } From 66094ec72d97940ba78089307a7d5a0be6eeb52a Mon Sep 17 00:00:00 2001 From: James R Date: Mon, 20 Dec 2021 01:20:17 -0800 Subject: [PATCH 02/12] Replays: use git commit in DEVELOP, version string in release --- src/p_setup.c | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/src/p_setup.c b/src/p_setup.c index 44717910b..79d333f66 100644 --- a/src/p_setup.c +++ b/src/p_setup.c @@ -3798,10 +3798,16 @@ static void P_InitGametype(void) if (!demo.playback && multiplayer && !dedicated) { char buf[MAX_WADPATH]; + char ver[128]; int parts; - sprintf(buf, "%s"PATHSEP"media"PATHSEP"replay"PATHSEP"online"PATHSEP"%s-%s"PATHSEP"%d-%s", - srb2home, compbranch, comprevision, (int) (time(NULL)), G_BuildMapName(gamemap)); +#ifdef DEVELOP + sprintf(ver, "%s-%s", compbranch, comprevision); +#else + strcpy(ver, VERSIONSTRING); +#endif + sprintf(buf, "%s"PATHSEP"media"PATHSEP"replay"PATHSEP"online"PATHSEP"%s"PATHSEP"%d-%s", + srb2home, ver, (int) (time(NULL)), G_BuildMapName(gamemap)); parts = M_PathParts(buf); M_MkdirEachUntil(buf, parts - 5, parts - 1, 0755); From cdce6824f26eb257d12a16e1fa79bf4acf1ea213 Mon Sep 17 00:00:00 2001 From: James R Date: Wed, 29 Dec 2021 22:13:06 -0800 Subject: [PATCH 03/12] Fix M_MkdirEach and M_PathParts OKAY I didn't test this on Windows before, it was BROKEN AND SHITTY CODE. --- src/m_misc.c | 80 +++++++++++++++++++++++----------------------------- 1 file changed, 36 insertions(+), 44 deletions(-) diff --git a/src/m_misc.c b/src/m_misc.c index da0092845..f4649a3ad 100644 --- a/src/m_misc.c +++ b/src/m_misc.c @@ -2555,26 +2555,25 @@ const char *M_FileError(FILE *fp) /** Return the number of parts of this path. */ -int M_PathParts(const char *path) +int M_PathParts(const char *p) { - int n; - const char *p; - const char *t; - if (path == NULL) + int parts = 0; + + if (p == NULL) return 0; - for (n = 0, p = path ;; ++n) + +#ifdef _WIN32 + if (!strncmp(&p[1], ":\\", 2)) + p += 3; +#endif + + while (*(p += strspn(p, PATHSEP))) { - t = p; - if (( p = strchr(p, PATHSEP[0]) )) - p += strspn(p, PATHSEP); - else - { - if (*t)/* there is something after the final delimiter */ - n++; - break; - } + parts++; + p += strcspn(p, PATHSEP); } - return n; + + return parts; } /** Check whether a path is an absolute path. @@ -2592,50 +2591,43 @@ boolean M_IsPathAbsolute(const char *path) */ void M_MkdirEachUntil(const char *cpath, int start, int end, int mode) { - char path[MAX_WADPATH]; + char path[256]; char *p; - char *t; + int n; + int c; if (end > 0 && end <= start) return; strlcpy(path, cpath, sizeof path); + #ifdef _WIN32 - if (strncmp(&path[1], ":\\", 2) == 0) + if (!strncmp(&path[1], ":\\", 2)) p = &path[3]; else #endif p = path; - if (end > 0) - end -= start; - - for (; start > 0; --start) + while (end != 0 && *(p += strspn(p, PATHSEP))) { - p += strspn(p, PATHSEP); - if (!( p = strchr(p, PATHSEP[0]) )) - return; - } - p += strspn(p, PATHSEP); - for (;;) - { - if (end > 0 && !--end) - break; + n = strcspn(p, PATHSEP); - t = p; - if (( p = strchr(p, PATHSEP[0]) )) - { - *p = '\0'; - I_mkdir(path, mode); - *p = PATHSEP[0]; - p += strspn(p, PATHSEP); - } + if (start > 0) + start--; else { - if (*t) - I_mkdir(path, mode); - break; + c = p[n]; + p[n] = '\0'; + + I_mkdir(path, mode); + + p[n] = c; } + + p += n; + + if (end > 0) + end--; } } @@ -2697,4 +2689,4 @@ const char * M_Ftrim (double f) dig[i + 1] = '\0'; return &dig[1];/* skip the 0 */ } -} \ No newline at end of file +} From 969d449973cc5b8cfef6bd736a7f8db160ff3085 Mon Sep 17 00:00:00 2001 From: James R Date: Wed, 12 Jan 2022 03:36:02 -0800 Subject: [PATCH 04/12] Interpolate from time of previous tic Previously interpolated from last 35th of a second, which may be offset from game time due to connection lag. Consider this the proper fix to 6ecac4159a too. --- src/d_clisrv.c | 14 ++++++++++---- src/d_clisrv.h | 2 +- src/d_main.c | 16 +++++++++++++--- src/i_system.h | 4 ++-- src/sdl/i_system.c | 5 ++--- 5 files changed, 28 insertions(+), 13 deletions(-) diff --git a/src/d_clisrv.c b/src/d_clisrv.c index e6fcb6643..855056cf1 100644 --- a/src/d_clisrv.c +++ b/src/d_clisrv.c @@ -5235,8 +5235,10 @@ static void SV_Maketic(void) maketic++; } -void TryRunTics(tic_t realtics) +boolean TryRunTics(tic_t realtics) { + boolean ticking; + // the machine has lagged but it is not so bad if (realtics > TICRATE/7) // FIXME: consistency failure!! { @@ -5280,7 +5282,9 @@ void TryRunTics(tic_t realtics) } #endif - if (neededtic > gametic) + ticking = neededtic > gametic; + + if (ticking) { if (realtics) hu_stopped = false; @@ -5290,10 +5294,10 @@ void TryRunTics(tic_t realtics) { if (realtics) hu_stopped = true; - return; + return false; } - if (neededtic > gametic) + if (ticking) { if (advancedemo) { @@ -5330,6 +5334,8 @@ void TryRunTics(tic_t realtics) if (realtics) hu_stopped = true; } + + return ticking; } diff --git a/src/d_clisrv.h b/src/d_clisrv.h index 88712f01c..7cd8acce5 100644 --- a/src/d_clisrv.h +++ b/src/d_clisrv.h @@ -488,7 +488,7 @@ boolean Playing(void); void D_QuitNetGame(void); //? How many ticks to run? -void TryRunTics(tic_t realtic); +boolean TryRunTics(tic_t realtic); // extra data for lmps // these functions scare me. they contain magic. diff --git a/src/d_main.c b/src/d_main.c index 20f73ea69..4a824c8e6 100644 --- a/src/d_main.c +++ b/src/d_main.c @@ -685,6 +685,7 @@ tic_t rendergametic; void D_SRB2Loop(void) { tic_t oldentertics = 0, entertic = 0, realtics = 0, rendertimeout = INFTICS; + boolean ticked; if (dedicated) server = true; @@ -772,11 +773,20 @@ void D_SRB2Loop(void) realtics = 1; // process tics (but maybe not if realtic == 0) - TryRunTics(realtics); + ticked = TryRunTics(realtics); - if (cv_frameinterpolation.value == 1 && !(paused || P_AutoPause() || hu_stopped)) + if (cv_frameinterpolation.value == 1 && !(paused || P_AutoPause())) { - fixed_t entertimefrac = I_GetTimeFrac(); + static float tictime; + float entertime = I_GetTimeFrac(); + + fixed_t entertimefrac; + + if (ticked) + tictime = entertime; + + entertimefrac = FLOAT_TO_FIXED(entertime - tictime); + // renderdeltatics is a bit awkard to evaluate, since the system time interface is whole tic-based renderdeltatics = realtics * FRACUNIT; if (entertimefrac > rendertimefrac) diff --git a/src/i_system.h b/src/i_system.h index 789117eaa..4a8bf0c27 100644 --- a/src/i_system.h +++ b/src/i_system.h @@ -46,9 +46,9 @@ UINT32 I_GetFreeMem(UINT32 *total); */ tic_t I_GetTime(void); -/** \brief Get the current time as a fraction of a tic since the last tic. +/** \brief Get the current time in tics including fractions. */ -fixed_t I_GetTimeFrac(void); +float I_GetTimeFrac(void); /** \brief Returns precise time value for performance measurement. */ diff --git a/src/sdl/i_system.c b/src/sdl/i_system.c index 71b5af958..004a6ff33 100644 --- a/src/sdl/i_system.c +++ b/src/sdl/i_system.c @@ -1658,11 +1658,10 @@ tic_t I_GetTime(void) return (tic_t)f; } -fixed_t I_GetTimeFrac(void) +float I_GetTimeFrac(void) { UpdateElapsedTics(); - - return FLOAT_TO_FIXED((float) (elapsed_tics - floor(elapsed_tics))); + return elapsed_tics; } precise_t I_GetPreciseTime(void) From 85ce207e9ca323d8979cca7a603a922e07476b82 Mon Sep 17 00:00:00 2001 From: James R Date: Wed, 12 Jan 2022 04:36:37 -0800 Subject: [PATCH 05/12] Do not interpolate if time between game tics <1/35 --- src/d_main.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/d_main.c b/src/d_main.c index 4a824c8e6..f90ba411e 100644 --- a/src/d_main.c +++ b/src/d_main.c @@ -787,6 +787,9 @@ void D_SRB2Loop(void) entertimefrac = FLOAT_TO_FIXED(entertime - tictime); + if (entertimefrac < FRACUNIT) + entertimefrac = FRACUNIT; + // renderdeltatics is a bit awkard to evaluate, since the system time interface is whole tic-based renderdeltatics = realtics * FRACUNIT; if (entertimefrac > rendertimefrac) From 6a7ca44302996e5fcf9bb8b4ad54618de878352b Mon Sep 17 00:00:00 2001 From: James R Date: Wed, 12 Jan 2022 12:57:52 -0800 Subject: [PATCH 06/12] Don't interpolate frames if avg <35 Proper solution for 85ce207e9 --- src/d_main.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/d_main.c b/src/d_main.c index f90ba411e..ae4f23cc2 100644 --- a/src/d_main.c +++ b/src/d_main.c @@ -785,10 +785,10 @@ void D_SRB2Loop(void) if (ticked) tictime = entertime; - entertimefrac = FLOAT_TO_FIXED(entertime - tictime); - - if (entertimefrac < FRACUNIT) + if (aproxfps < 35.0) entertimefrac = FRACUNIT; + else + entertimefrac = FLOAT_TO_FIXED(entertime - tictime); // renderdeltatics is a bit awkard to evaluate, since the system time interface is whole tic-based renderdeltatics = realtics * FRACUNIT; From 159994c2f04e0193a8d00dad2209c09439614608 Mon Sep 17 00:00:00 2001 From: SteelT Date: Mon, 17 Jan 2022 15:46:44 -0500 Subject: [PATCH 07/12] Don't compile with dynamic base --- src/Makefile.d/win32.mk | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/Makefile.d/win32.mk b/src/Makefile.d/win32.mk index ec66107d4..83edc3c45 100644 --- a/src/Makefile.d/win32.mk +++ b/src/Makefile.d/win32.mk @@ -8,6 +8,11 @@ else EXENAME?=srb2kart64.exe endif +# disable dynamicbase if under msys2 +ifdef MSYSTEM +libs+=-Wl,--disable-dynamicbase +endif + sources+=win32/Srb2win.rc opts+=-DSTDC_HEADERS libs+=-ladvapi32 -lkernel32 -lmsvcrt -luser32 From 5e37a847f0208cad8bd90bbe891a351d6be688de Mon Sep 17 00:00:00 2001 From: James R Date: Mon, 17 Jan 2022 21:18:38 -0800 Subject: [PATCH 08/12] Interpolate viewrollangle before R_CheckViewMorph --- src/d_main.c | 2 ++ src/r_fps.c | 7 ++++++- src/r_fps.h | 2 ++ 3 files changed, 10 insertions(+), 1 deletion(-) diff --git a/src/d_main.c b/src/d_main.c index 20f73ea69..477f96436 100644 --- a/src/d_main.c +++ b/src/d_main.c @@ -293,6 +293,8 @@ static void D_Display(void) { for (i = 0; i <= r_splitscreen; ++i) { + R_SetViewContext(VIEWCONTEXT_PLAYER1 + i); + R_InterpolateViewRollAngle(rendertimefrac); R_CheckViewMorph(i); } } diff --git a/src/r_fps.c b/src/r_fps.c index 59f10bae8..9d3bf12ee 100644 --- a/src/r_fps.c +++ b/src/r_fps.c @@ -80,6 +80,11 @@ static void R_SetupFreelook(player_t *player, boolean skybox) #undef AIMINGTODY +void R_InterpolateViewRollAngle(fixed_t frac) +{ + viewroll = oldview->roll + R_LerpAngle(oldview->roll, newview->roll, frac); +} + void R_InterpolateView(fixed_t frac) { if (frac < 0) @@ -93,7 +98,7 @@ void R_InterpolateView(fixed_t frac) viewangle = oldview->angle + R_LerpAngle(oldview->angle, newview->angle, frac); aimingangle = oldview->aim + R_LerpAngle(oldview->aim, newview->aim, frac); - viewroll = oldview->roll + R_LerpAngle(oldview->roll, newview->roll, frac); + R_InterpolateViewRollAngle(frac); viewsin = FINESINE(viewangle>>ANGLETOFINESHIFT); viewcos = FINECOSINE(viewangle>>ANGLETOFINESHIFT); diff --git a/src/r_fps.h b/src/r_fps.h index 246c16e64..c93c4701e 100644 --- a/src/r_fps.h +++ b/src/r_fps.h @@ -51,6 +51,8 @@ extern viewvars_t *newview; // Interpolates the current view variables (r_state.h) against the selected view context in R_SetViewContext void R_InterpolateView(fixed_t frac); +// Special function just for software +void R_InterpolateViewRollAngle(fixed_t frac); // Buffer the current new views into the old views. Call once after each real tic. void R_UpdateViewInterpolation(void); // Set the current view context (the viewvars pointed to by newview) From d06355018df1834f9aee39b9bd75cc6223b81275 Mon Sep 17 00:00:00 2001 From: James R Date: Mon, 17 Jan 2022 22:46:01 -0800 Subject: [PATCH 09/12] Track skybox within player struct TODO: Lua Splitscreen and change viewpoint uses the proper skyboxes! --- src/d_player.h | 8 +++++++ src/hardware/hw_main.c | 2 +- src/lua_baselib.c | 4 ++++ src/p_mobj.c | 3 +++ src/p_saveg.c | 34 +++++++++++++++++++++++++++++ src/p_setup.c | 15 ++++++++----- src/p_spec.c | 49 ++++++++++++++++++++++++++++++------------ src/p_spec.h | 1 - src/r_main.c | 19 ++++++++-------- src/r_plane.h | 2 -- src/r_portal.c | 31 +++++++++++++++----------- src/r_portal.h | 4 ++-- 12 files changed, 125 insertions(+), 47 deletions(-) diff --git a/src/d_player.h b/src/d_player.h index 738f8240b..4a4b85981 100644 --- a/src/d_player.h +++ b/src/d_player.h @@ -290,6 +290,12 @@ typedef struct botvars_s tic_t spindashconfirm; // When high enough, they will try spindashing } botvars_t; +// player_t struct for all skybox variables +typedef struct { + mobj_t * viewpoint; + mobj_t * centerpoint; +} skybox_t; + // ======================================================================== // PLAYER STRUCTURE // ======================================================================== @@ -311,6 +317,8 @@ typedef struct player_s // bounded/scaled total momentum. fixed_t bob; + skybox_t skybox; + angle_t viewrollangle; angle_t old_viewrollangle; // camera tilt diff --git a/src/hardware/hw_main.c b/src/hardware/hw_main.c index 74f13ff0e..47ad59cb6 100644 --- a/src/hardware/hw_main.c +++ b/src/hardware/hw_main.c @@ -6221,7 +6221,7 @@ void HWR_RenderPlayerView(void) const float fpov = FIXED_TO_FLOAT(cv_fov[viewssnum].value+player->fovadd); postimg_t *type = &postimgtype[viewssnum]; - const boolean skybox = (skyboxmo[0] && cv_skybox.value); // True if there's a skybox object and skyboxes are on + const boolean skybox = (player->skybox.viewpoint && cv_skybox.value); // True if there's a skybox object and skyboxes are on FRGBAFloat ClearColor; diff --git a/src/lua_baselib.c b/src/lua_baselib.c index 534325283..596f8b158 100644 --- a/src/lua_baselib.c +++ b/src/lua_baselib.c @@ -2015,8 +2015,12 @@ static int lib_pSetSkyboxMobj(lua_State *L) if (w > 1 || w < 0) return luaL_error(L, "skybox mobj index %d is out of range for P_SetSkyboxMobj argument #2 (expected 0 or 1)", w); +#if 0 if (!user || P_IsLocalPlayer(user)) skyboxmo[w] = mo; +#else + CONS_Alert(CONS_WARNING, "TODO: P_SetSkyboxMobj is unimplemented\n"); +#endif return 0; } diff --git a/src/p_mobj.c b/src/p_mobj.c index 25f4f0fe6..33de100be 100644 --- a/src/p_mobj.c +++ b/src/p_mobj.c @@ -10867,6 +10867,9 @@ void P_SpawnPlayer(INT32 playernum) p->awayviewmobj = NULL; p->awayviewtics = 0; + p->skybox.viewpoint = skyboxviewpnts[0]; + p->skybox.centerpoint = skyboxcenterpnts[0]; + P_SetTarget(&p->follower, NULL); // cleanse follower from existence // set the scale to the mobj's destscale so settings get correctly set. if we don't, they sometimes don't. diff --git a/src/p_saveg.c b/src/p_saveg.c index 6aff9a33f..0561d365a 100644 --- a/src/p_saveg.c +++ b/src/p_saveg.c @@ -60,6 +60,8 @@ typedef enum AWAYVIEW = 0x01, FOLLOWITEM = 0x02, FOLLOWER = 0x04, + SKYBOXVIEW = 0x08, + SKYBOXCENTER = 0x10, } player_saveflags; static inline void P_ArchivePlayer(void) @@ -178,6 +180,12 @@ static void P_NetArchivePlayers(void) if (players[i].follower) flags |= FOLLOWER; + if (players[i].skybox.viewpoint) + flags |= SKYBOXVIEW; + + if (players[i].skybox.centerpoint) + flags |= SKYBOXCENTER; + WRITEINT16(save_p, players[i].lastsidehit); WRITEINT16(save_p, players[i].lastlinehit); @@ -190,6 +198,12 @@ static void P_NetArchivePlayers(void) WRITEUINT16(save_p, flags); + if (flags & SKYBOXVIEW) + WRITEUINT32(save_p, players[i].skybox.viewpoint->mobjnum); + + if (flags & SKYBOXCENTER) + WRITEUINT32(save_p, players[i].skybox.centerpoint->mobjnum); + if (flags & AWAYVIEW) WRITEUINT32(save_p, players[i].awayviewmobj->mobjnum); @@ -447,6 +461,12 @@ static void P_NetUnArchivePlayers(void) flags = READUINT16(save_p); + if (flags & SKYBOXVIEW) + players[i].skybox.viewpoint = (mobj_t *)(size_t)READUINT32(save_p); + + if (flags & SKYBOXCENTER) + players[i].skybox.centerpoint = (mobj_t *)(size_t)READUINT32(save_p); + if (flags & AWAYVIEW) players[i].awayviewmobj = (mobj_t *)(size_t)READUINT32(save_p); @@ -4130,6 +4150,20 @@ static void P_RelinkPointers(void) } if (mobj->player) { + if ( mobj->player->skybox.viewpoint) + { + temp = (UINT32)(size_t)mobj->player->skybox.viewpoint; + mobj->player->skybox.viewpoint = NULL; + if (!P_SetTarget(&mobj->player->skybox.viewpoint, P_FindNewPosition(temp))) + CONS_Debug(DBG_GAMELOGIC, "skybox.viewpoint not found on %d\n", mobj->type); + } + if ( mobj->player->skybox.centerpoint) + { + temp = (UINT32)(size_t)mobj->player->skybox.centerpoint; + mobj->player->skybox.centerpoint = NULL; + if (!P_SetTarget(&mobj->player->skybox.centerpoint, P_FindNewPosition(temp))) + CONS_Debug(DBG_GAMELOGIC, "skybox.centerpoint not found on %d\n", mobj->type); + } if ( mobj->player->awayviewmobj) { temp = (UINT32)(size_t)mobj->player->awayviewmobj; diff --git a/src/p_setup.c b/src/p_setup.c index 853fdd30c..85cfa6180 100644 --- a/src/p_setup.c +++ b/src/p_setup.c @@ -3514,6 +3514,7 @@ static void P_InitLevelSettings(void) speedscramble = encorescramble = -1; } +#if 0 // Respawns all the mapthings and mobjs in the map from the already loaded map data. void P_RespawnThings(void) { @@ -3548,6 +3549,7 @@ void P_RespawnThings(void) skyboxmo[0] = skyboxviewpnts[(viewid >= 0) ? viewid : 0]; skyboxmo[1] = skyboxcenterpnts[(centerid >= 0) ? centerid : 0]; } +#endif static void P_RunLevelScript(const char *scriptname) { @@ -3622,14 +3624,19 @@ static void P_ResetSpawnpoints(void) // reset the player starts for (i = 0; i < MAXPLAYERS; i++) + { playerstarts[i] = bluectfstarts[i] = redctfstarts[i] = NULL; + if (playeringame[i]) + { + players[i].skybox.viewpoint = NULL; + players[i].skybox.centerpoint = 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; } @@ -4068,8 +4075,6 @@ boolean P_LoadLevel(boolean fromnetsave, boolean reloadinggamestate) P_SpawnSpecialsAfterSlopes(); P_SpawnMapThings(!fromnetsave); - skyboxmo[0] = skyboxviewpnts[0]; - skyboxmo[1] = skyboxcenterpnts[0]; for (numcoopstarts = 0; numcoopstarts < MAXPLAYERS; numcoopstarts++) if (!playerstarts[numcoopstarts]) diff --git a/src/p_spec.c b/src/p_spec.c index fca9e9035..61862df96 100644 --- a/src/p_spec.c +++ b/src/p_spec.c @@ -52,7 +52,6 @@ // Not sure if this is necessary, but it was in w_wad.c, so I'm putting it here too -Shadow Hog #include -mobj_t *skyboxmo[2]; // current skybox mobjs: 0 = viewpoint, 1 = centerpoint mobj_t *skyboxviewpnts[16]; // array of MT_SKYBOX viewpoint mobjs mobj_t *skyboxcenterpnts[16]; // array of MT_SKYBOX centerpoint mobjs @@ -2090,6 +2089,19 @@ static mobj_t *P_GetObjectTypeInSectorNum(mobjtype_t type, size_t s) return NULL; } +static void P_SwitchSkybox(INT32 ldflags, player_t *player, skybox_t *skybox) +{ + if (!(ldflags & ML_EFFECT4)) // Solid Midtexture turns off viewpoint setting + { + player->skybox.viewpoint = skybox->viewpoint; + } + + if (ldflags & ML_BLOCKPLAYERS) // Block Enemies turns ON centerpoint setting + { + player->skybox.centerpoint = skybox->centerpoint; + } +} + /** Processes the line special triggered by an object. * * \param line Line with the special command on it. @@ -3155,7 +3167,7 @@ static void P_ProcessLineSpecial(line_t *line, mobj_t *mo, sector_t *callsec) break; } case 448: // Change skybox viewpoint/centerpoint - if ((mo && mo->player && P_IsLocalPlayer(mo->player)) || (line->flags & ML_NOCLIMB)) + if ((mo && mo->player) || (line->flags & ML_NOCLIMB)) { INT32 viewid = sides[line->sidenum[0]].textureoffset>>FRACBITS; INT32 centerid = sides[line->sidenum[0]].rowoffset>>FRACBITS; @@ -3168,23 +3180,32 @@ static void P_ProcessLineSpecial(line_t *line, mobj_t *mo, sector_t *callsec) } else { + skybox_t skybox; + // set viewpoint mobj - if (!(line->flags & ML_EFFECT4)) // Solid Midtexture turns off viewpoint setting - { - if (viewid >= 0 && viewid < 16) - skyboxmo[0] = skyboxviewpnts[viewid]; - else - skyboxmo[0] = NULL; - } + if (viewid >= 0 && viewid < 16) + skybox.viewpoint = skyboxviewpnts[viewid]; + else + skybox.viewpoint = NULL; // set centerpoint mobj - if (line->flags & ML_BLOCKPLAYERS) // Block Enemies turns ON centerpoint setting + if (centerid >= 0 && centerid < 16) + skybox.centerpoint = skyboxcenterpnts[centerid]; + else + skybox.centerpoint = NULL; + + if (line->flags & ML_NOCLIMB) // Applies to all players { - if (centerid >= 0 && centerid < 16) - skyboxmo[1] = skyboxcenterpnts[centerid]; - else - skyboxmo[1] = NULL; + INT32 i; + + for (i = 0; i < MAXPLAYERS; ++i) + { + if (playeringame[i]) + P_SwitchSkybox(line->flags, &players[i], &skybox); + } } + else + P_SwitchSkybox(line->flags, mo->player, &skybox); } CONS_Debug(DBG_GAMELOGIC, "Line type 448 Executor: viewid = %d, centerid = %d, viewpoint? = %s, centerpoint? = %s\n", diff --git a/src/p_spec.h b/src/p_spec.h index 9181dee7a..03f4c32fe 100644 --- a/src/p_spec.h +++ b/src/p_spec.h @@ -17,7 +17,6 @@ #ifndef __P_SPEC__ #define __P_SPEC__ -extern mobj_t *skyboxmo[2]; // current skybox mobjs: 0 = viewpoint, 1 = centerpoint extern mobj_t *skyboxviewpnts[16]; // array of MT_SKYBOX viewpoint mobjs extern mobj_t *skyboxcenterpnts[16]; // array of MT_SKYBOX centerpoint mobjs diff --git a/src/r_main.c b/src/r_main.c index c3e044ef2..144768606 100644 --- a/src/r_main.c +++ b/src/r_main.c @@ -28,7 +28,7 @@ #include "am_map.h" #include "d_main.h" #include "v_video.h" -#include "p_spec.h" // skyboxmo +//#include "p_spec.h" #include "p_setup.h" #include "z_zone.h" #include "m_random.h" // quake camera shake @@ -1331,7 +1331,7 @@ void R_SkyboxFrame(player_t *player) // cut-away view stuff newview->sky = true; - r_viewmobj = skyboxmo[0]; + r_viewmobj = player->skybox.viewpoint; #ifdef PARANOIA if (!r_viewmobj) { @@ -1372,6 +1372,7 @@ void R_SkyboxFrame(player_t *player) { mapheader_t *mh = mapheaderinfo[gamemap-1]; vector3_t campos = {0,0,0}; // Position of player's actual view point + mobj_t *center = player->skybox.centerpoint; if (player->awayviewtics) { campos.x = player->awayviewmobj->x; @@ -1393,18 +1394,18 @@ void R_SkyboxFrame(player_t *player) campos.y += quake.y; campos.z += quake.z; - if (skyboxmo[1]) // Is there a viewpoint? + if (center) // Is there a viewpoint? { fixed_t x = 0, y = 0; if (mh->skybox_scalex > 0) - x = (campos.x - skyboxmo[1]->x) / mh->skybox_scalex; + x = (campos.x - center->x) / mh->skybox_scalex; else if (mh->skybox_scalex < 0) - x = (campos.x - skyboxmo[1]->x) * -mh->skybox_scalex; + x = (campos.x - center->x) * -mh->skybox_scalex; if (mh->skybox_scaley > 0) - y = (campos.y - skyboxmo[1]->y) / mh->skybox_scaley; + y = (campos.y - center->y) / mh->skybox_scaley; else if (mh->skybox_scaley < 0) - y = (campos.y - skyboxmo[1]->y) * -mh->skybox_scaley; + y = (campos.y - center->y) * -mh->skybox_scaley; if (r_viewmobj->angle == 0) { @@ -1617,8 +1618,8 @@ void R_RenderPlayerView(void) // Add skybox portals caused by sky visplanes. - if (cv_skybox.value && skyboxmo[0]) - Portal_AddSkyboxPortals(); + if (cv_skybox.value && player->skybox.viewpoint) + Portal_AddSkyboxPortals(player); // Portal rendering. Hijacks the BSP traversal. ps_sw_portaltime = I_GetPreciseTime(); diff --git a/src/r_plane.h b/src/r_plane.h index 41305fb3c..fb489f704 100644 --- a/src/r_plane.h +++ b/src/r_plane.h @@ -127,6 +127,4 @@ typedef struct planemgr_s extern visffloor_t ffloor[MAXFFLOORS]; extern INT32 numffloors; - -void Portal_AddSkyboxPortals (void); #endif diff --git a/src/r_portal.c b/src/r_portal.c index 1aca145ec..66763dff3 100644 --- a/src/r_portal.c +++ b/src/r_portal.c @@ -256,12 +256,17 @@ static boolean TrimVisplaneBounds (const visplane_t* plane, INT16* start, INT16* * Applies the necessary offsets and rotation to give * a depth illusion to the skybox. */ -void Portal_AddSkybox (const visplane_t* plane) +void Portal_AddSkybox +( const player_t * player, + const visplane_t * plane) { INT16 start, end; mapheader_t *mh; portal_t* portal; + mobj_t *viewpoint = player->skybox.viewpoint; + mobj_t *center = player->skybox.centerpoint; + if (TrimVisplaneBounds(plane, &start, &end)) return; @@ -269,28 +274,28 @@ void Portal_AddSkybox (const visplane_t* plane) Portal_ClipVisplane(plane, portal); - portal->viewx = skyboxmo[0]->x; - portal->viewy = skyboxmo[0]->y; - portal->viewz = skyboxmo[0]->z; - portal->viewangle = viewangle + skyboxmo[0]->angle; + portal->viewx = viewpoint->x; + portal->viewy = viewpoint->y; + portal->viewz = viewpoint->z; + portal->viewangle = viewangle + viewpoint->angle; mh = mapheaderinfo[gamemap-1]; // If a relative viewpoint exists, offset the viewpoint. - if (skyboxmo[1]) + if (center) { fixed_t x = 0, y = 0; - angle_t ang = skyboxmo[0]->angle>>ANGLETOFINESHIFT; + angle_t ang = viewpoint->angle>>ANGLETOFINESHIFT; if (mh->skybox_scalex > 0) - x = (viewx - skyboxmo[1]->x) / mh->skybox_scalex; + x = (viewx - center->x) / mh->skybox_scalex; else if (mh->skybox_scalex < 0) - x = (viewx - skyboxmo[1]->x) * -mh->skybox_scalex; + x = (viewx - center->x) * -mh->skybox_scalex; if (mh->skybox_scaley > 0) - y = (viewy - skyboxmo[1]->y) / mh->skybox_scaley; + y = (viewy - center->y) / mh->skybox_scaley; else if (mh->skybox_scaley < 0) - y = (viewy - skyboxmo[1]->y) * -mh->skybox_scaley; + y = (viewy - center->y) * -mh->skybox_scaley; // Apply transform to account for the skybox viewport angle. portal->viewx += FixedMul(x,FINECOSINE(ang)) - FixedMul(y, FINESINE(ang)); @@ -308,7 +313,7 @@ void Portal_AddSkybox (const visplane_t* plane) /** Creates portals for the currently existing sky visplanes. * The visplanes are also removed and cleared from the list. */ -void Portal_AddSkyboxPortals (void) +void Portal_AddSkyboxPortals (const player_t *player) { visplane_t *pl; INT32 i; @@ -320,7 +325,7 @@ void Portal_AddSkyboxPortals (void) { if (pl->picnum == skyflatnum) { - Portal_AddSkybox(pl); + Portal_AddSkybox(player, pl); pl->minx = 0; pl->maxx = -1; diff --git a/src/r_portal.h b/src/r_portal.h index e665a26e6..3e77b2ef7 100644 --- a/src/r_portal.h +++ b/src/r_portal.h @@ -52,10 +52,10 @@ extern INT32 portalclipstart, portalclipend; void Portal_InitList (void); void Portal_Remove (portal_t* portal); void Portal_Add2Lines (const INT32 line1, const INT32 line2, const INT32 x1, const INT32 x2); -void Portal_AddSkybox (const visplane_t* plane); +void Portal_AddSkybox (const player_t* player, const visplane_t* plane); void Portal_ClipRange (portal_t* portal); void Portal_ClipApply (const portal_t* portal); -void Portal_AddSkyboxPortals (void); +void Portal_AddSkyboxPortals (const player_t* player); #endif From 7fc72d03ffdf4e7b7ff42f4379e2a56011d22f4f Mon Sep 17 00:00:00 2001 From: James R Date: Mon, 17 Jan 2022 23:07:04 -0800 Subject: [PATCH 10/12] Uncap frame interpolation on the viewpoint --- src/r_fps.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/r_fps.c b/src/r_fps.c index 59f10bae8..67f96498d 100644 --- a/src/r_fps.c +++ b/src/r_fps.c @@ -84,8 +84,10 @@ void R_InterpolateView(fixed_t frac) { if (frac < 0) frac = 0; +#if 0 if (frac > FRACUNIT) frac = FRACUNIT; +#endif viewx = oldview->x + R_LerpFixed(oldview->x, newview->x, frac); viewy = oldview->y + R_LerpFixed(oldview->y, newview->y, frac); From 606eb2831488c797dfdc7a5da5d4951da43905e8 Mon Sep 17 00:00:00 2001 From: SteelT Date: Thu, 20 Jan 2022 03:20:53 -0500 Subject: [PATCH 11/12] Linedef type 460: Don't award rings while SPB-locked --- src/p_spec.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/p_spec.c b/src/p_spec.c index 61862df96..9f75cf135 100644 --- a/src/p_spec.c +++ b/src/p_spec.c @@ -3620,6 +3620,10 @@ static void P_ProcessLineSpecial(line_t *line, mobj_t *mo, sector_t *callsec) INT32 delay = (sides[line->sidenum[0]].rowoffset>>FRACBITS); if (mo && mo->player) { + // Don't award rings while SPB is targetting you + if (mo->player->pflags & PF_RINGLOCK) + return; + if (delay <= 0 || !(leveltime % delay)) P_GivePlayerRings(mo->player, rings); } From 93dfbf382c756ef3e61cd8ca42b1dcddd70f8be7 Mon Sep 17 00:00:00 2001 From: toaster Date: Thu, 20 Jan 2022 19:27:02 +0000 Subject: [PATCH 12/12] The "free" changes from framezero - the crash fixes that have no complexity and therefore no negative consequence to introduce --- src/k_kart.c | 17 ++++++++++++----- src/p_map.c | 3 +++ src/p_mobj.c | 2 ++ 3 files changed, 17 insertions(+), 5 deletions(-) diff --git a/src/k_kart.c b/src/k_kart.c index b9fff95ba..9b7fde1fe 100644 --- a/src/k_kart.c +++ b/src/k_kart.c @@ -3811,7 +3811,7 @@ static mobj_t *K_SpawnKartMissile(mobj_t *source, mobjtype_t type, angle_t an, I y = source->y + source->momy + FixedMul(finalspeed, FINESINE(an>>ANGLETOFINESHIFT)); z = source->z; // spawn on the ground please - th = P_SpawnMobj(x, y, z, type); + th = P_SpawnMobj(x, y, z, type); // this will never return null because collision isn't processed here K_FlipFromObject(th, source); @@ -3830,7 +3830,10 @@ static mobj_t *K_SpawnKartMissile(mobj_t *source, mobjtype_t type, angle_t an, I { // floorz and ceilingz aren't properly set to account for FOFs and Polyobjects on spawn // This should set it for FOFs - P_SetOrigin(th, th->x, th->y, th->z); + P_SetOrigin(th, th->x, th->y, th->z); // however, THIS can fuck up your day. just absolutely ruin you. + if (P_MobjWasRemoved(th)) + return NULL; + // spawn on the ground if the player is on the ground if (P_MobjFlip(source) < 0) { @@ -3898,7 +3901,7 @@ static mobj_t *K_SpawnKartMissile(mobj_t *source, mobjtype_t type, angle_t an, I P_SetTarget(&throwmo->target, source); } - return NULL; + return th; } UINT16 K_DriftSparkColor(player_t *player, INT32 charge) @@ -4705,10 +4708,11 @@ mobj_t *K_ThrowKartItem(player_t *player, boolean missile, mobjtype_t mapthing, { if (mapthing == MT_BALLHOG) // Messy { + mo = NULL; // can't return multiple projectiles if (dir == -1) { // Shoot backward - mo = K_SpawnKartMissile(player->mo, mapthing, (player->mo->angle + ANGLE_180) - 0x06000000, 0, PROJSPEED/8); + K_SpawnKartMissile(player->mo, mapthing, (player->mo->angle + ANGLE_180) - 0x06000000, 0, PROJSPEED/8); K_SpawnKartMissile(player->mo, mapthing, (player->mo->angle + ANGLE_180) - 0x03000000, 0, PROJSPEED/8); K_SpawnKartMissile(player->mo, mapthing, player->mo->angle + ANGLE_180, 0, PROJSPEED/8); K_SpawnKartMissile(player->mo, mapthing, (player->mo->angle + ANGLE_180) + 0x03000000, 0, PROJSPEED/8); @@ -4717,7 +4721,7 @@ mobj_t *K_ThrowKartItem(player_t *player, boolean missile, mobjtype_t mapthing, else { // Shoot forward - mo = K_SpawnKartMissile(player->mo, mapthing, player->mo->angle - 0x06000000, 0, PROJSPEED); + K_SpawnKartMissile(player->mo, mapthing, player->mo->angle - 0x06000000, 0, PROJSPEED); K_SpawnKartMissile(player->mo, mapthing, player->mo->angle - 0x03000000, 0, PROJSPEED); K_SpawnKartMissile(player->mo, mapthing, player->mo->angle, 0, PROJSPEED); K_SpawnKartMissile(player->mo, mapthing, player->mo->angle + 0x03000000, 0, PROJSPEED); @@ -5329,6 +5333,9 @@ void K_KillBananaChain(mobj_t *banana, mobj_t *inflictor, mobj_t *source) mobj_t *cachenext; killnext: + if (P_MobjWasRemoved(banana)) + return; + cachenext = banana->hnext; if (banana->health) diff --git a/src/p_map.c b/src/p_map.c index fb79b6677..a0f4e3cfe 100644 --- a/src/p_map.c +++ b/src/p_map.c @@ -3496,6 +3496,9 @@ void P_SlideMove(mobj_t *mo) vertex_t v1, v2; // fake vertexes line_t junk; // fake linedef + if (P_MobjWasRemoved(mo)) + return; + if (tmhitthing && mo->z + mo->height > tmhitthing->z && mo->z < tmhitthing->z + tmhitthing->height) { // Don't mess with your momentum if it's a pushable object. Pushables do their own crazy things already. diff --git a/src/p_mobj.c b/src/p_mobj.c index 33de100be..ab6b30655 100644 --- a/src/p_mobj.c +++ b/src/p_mobj.c @@ -1689,6 +1689,8 @@ void P_XYMovement(mobj_t *mo) if (mo->flags & MF_SLIDEME) { P_SlideMove(mo); + if (P_MobjWasRemoved(mo)) + return; xmove = ymove = 0; } else