From a6d1043d1736b09dfd40ac4cd1a628c71fc04d98 Mon Sep 17 00:00:00 2001 From: Sally Coolatta Date: Fri, 17 Dec 2021 18:29:35 -0500 Subject: [PATCH 01/20] Reduce turning for bots when they stair jank --- src/k_bot.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/k_bot.c b/src/k_bot.c index 24f3517a2..44f9c27c2 100644 --- a/src/k_bot.c +++ b/src/k_bot.c @@ -662,7 +662,10 @@ fixed_t K_DistanceOfLineFromPoint(fixed_t v1x, fixed_t v1y, fixed_t v2x, fixed_t --------------------------------------------------*/ static botprediction_t *K_CreateBotPrediction(player_t *player) { - const INT16 handling = K_GetKartTurnValue(player, KART_FULLTURN); // Reduce prediction based on how fast you can turn + // Stair janking makes it harder to steer, so attempt to steer harder. + const UINT8 jankDiv = (player->stairjank > 0 ? 2 : 1); + + const INT16 handling = K_GetKartTurnValue(player, KART_FULLTURN) / jankDiv; // Reduce prediction based on how fast you can turn const INT16 normal = KART_FULLTURN; // "Standard" handling to compare to const tic_t futuresight = (TICRATE * normal) / max(1, handling); // How far ahead into the future to try and predict From 436b6d50ea03300719d4d8b28d65aa55c9a6cbbc Mon Sep 17 00:00:00 2001 From: Sally Coolatta Date: Sat, 18 Dec 2021 16:31:08 -0500 Subject: [PATCH 02/20] Bot predict nudging scale is based on the prediction's radius --- src/k_botsearch.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/k_botsearch.c b/src/k_botsearch.c index 846521e6f..a06eb55f1 100644 --- a/src/k_botsearch.c +++ b/src/k_botsearch.c @@ -619,7 +619,7 @@ void K_NudgePredictionTowardsObjects(botprediction_t *predict, player_t *player) fixed_t avgX = 0, avgY = 0; fixed_t avgDist = 0; - const fixed_t baseNudge = 128 * mapobjectscale; + const fixed_t baseNudge = predict->radius; fixed_t maxNudge = distToPredict; fixed_t nudgeDist = 0; angle_t nudgeDir = 0; From 9e3e06547911d11ea9dfde39d684065a89ecbf2c Mon Sep 17 00:00:00 2001 From: Sally Coolatta Date: Wed, 5 Jan 2022 02:09:31 -0500 Subject: [PATCH 03/20] Bot lookback - Bots use lookback when they have a attack item that hits back & they see you. - Bot item throwing was made slower for easier difficulties. (Lv. 9 should still be pretty fast.) - Bot cone detection was made much much farther & wider Lookback sparkle is a signal for "they are contemplating throwing backwards" --- src/k_botitem.c | 81 +++++++++++++++++++++++++++++++++++++------------ src/k_kart.c | 20 ++++++------ 2 files changed, 72 insertions(+), 29 deletions(-) diff --git a/src/k_botitem.c b/src/k_botitem.c index 4bb83931c..90e3d8172 100644 --- a/src/k_botitem.c +++ b/src/k_botitem.c @@ -382,6 +382,8 @@ static void K_BotItemGenericTap(player_t *player, ticcmd_t *cmd) --------------------------------------------------*/ static boolean K_BotRevealsGenericTrap(player_t *player, INT16 turnamt, boolean mine) { + const fixed_t coneDist = FixedMul(1280 * mapobjectscale, K_GetKartGameSpeedScalar(gamespeed)); + if (abs(turnamt) >= KART_FULLTURN/2) { // DON'T reveal on turns, we can place bananas on turns whenever we have multiple to spare, @@ -404,7 +406,7 @@ static boolean K_BotRevealsGenericTrap(player_t *player, INT16 turnamt, boolean } // Check your behind. - if (K_PlayerInCone(player, player->mo->radius * 16, 10, true) != NULL) + if (K_PlayerInCone(player, coneDist, 15, true) != NULL) { return true; } @@ -536,16 +538,19 @@ static void K_BotItemRocketSneaker(player_t *player, ticcmd_t *cmd) --------------------------------------------------*/ static void K_BotItemBanana(player_t *player, ticcmd_t *cmd, INT16 turnamt) { + const fixed_t coneDist = FixedMul(1280 * mapobjectscale, K_GetKartGameSpeedScalar(gamespeed)); SINT8 throwdir = -1; + boolean tryLookback = false; player_t *target = NULL; player->botvars.itemconfirm++; - target = K_PlayerInCone(player, player->mo->radius * 16, 10, true); + target = K_PlayerInCone(player, coneDist, 15, true); if (target != NULL) { K_ItemConfirmForTarget(player, target, player->botvars.difficulty); throwdir = -1; + tryLookback = true; } if (abs(turnamt) >= KART_FULLTURN/2) @@ -564,7 +569,12 @@ static void K_BotItemBanana(player_t *player, ticcmd_t *cmd, INT16 turnamt) } } - if (player->botvars.itemconfirm > 2*TICRATE || player->bananadrag >= TICRATE) + if (tryLookback == true && throwdir == -1) + { + cmd->buttons |= BT_LOOKBACK; + } + + if (player->botvars.itemconfirm > 10*TICRATE || player->bananadrag >= TICRATE) { K_BotGenericPressItem(player, cmd, throwdir); } @@ -585,12 +595,14 @@ static void K_BotItemBanana(player_t *player, ticcmd_t *cmd, INT16 turnamt) --------------------------------------------------*/ static void K_BotItemMine(player_t *player, ticcmd_t *cmd, INT16 turnamt) { + const fixed_t coneDist = FixedMul(1280 * mapobjectscale, K_GetKartGameSpeedScalar(gamespeed)); SINT8 throwdir = 0; + boolean tryLookback = false; player_t *target = NULL; player->botvars.itemconfirm++; - target = K_PlayerInCone(player, player->mo->radius * 16, 10, true); + target = K_PlayerInCone(player, coneDist, 15, true); if (target != NULL) { K_ItemConfirmForTarget(player, target, player->botvars.difficulty); @@ -601,6 +613,7 @@ static void K_BotItemMine(player_t *player, ticcmd_t *cmd, INT16 turnamt) { player->botvars.itemconfirm += player->botvars.difficulty / 2; throwdir = -1; + tryLookback = true; } else { @@ -619,7 +632,12 @@ static void K_BotItemMine(player_t *player, ticcmd_t *cmd, INT16 turnamt) } } - if (player->botvars.itemconfirm > 2*TICRATE || player->bananadrag >= TICRATE) + if (tryLookback == true && throwdir == -1) + { + cmd->buttons |= BT_LOOKBACK; + } + + if (player->botvars.itemconfirm > 10*TICRATE || player->bananadrag >= TICRATE) { K_BotGenericPressItem(player, cmd, throwdir); } @@ -640,6 +658,7 @@ static void K_BotItemMine(player_t *player, ticcmd_t *cmd, INT16 turnamt) --------------------------------------------------*/ static void K_BotItemLandmine(player_t *player, ticcmd_t *cmd, INT16 turnamt) { + const fixed_t coneDist = FixedMul(1280 * mapobjectscale, K_GetKartGameSpeedScalar(gamespeed)); player_t *target = NULL; player->botvars.itemconfirm++; @@ -649,13 +668,14 @@ static void K_BotItemLandmine(player_t *player, ticcmd_t *cmd, INT16 turnamt) player->botvars.itemconfirm += player->botvars.difficulty / 2; } - target = K_PlayerInCone(player, player->mo->radius * 16, 10, true); + target = K_PlayerInCone(player, coneDist, 15, true); if (target != NULL) { K_ItemConfirmForTarget(player, target, player->botvars.difficulty); + cmd->buttons |= BT_LOOKBACK; } - if (player->botvars.itemconfirm > 2*TICRATE) + if (player->botvars.itemconfirm > 10*TICRATE) { K_BotGenericPressItem(player, cmd, -1); } @@ -675,8 +695,10 @@ static void K_BotItemLandmine(player_t *player, ticcmd_t *cmd, INT16 turnamt) --------------------------------------------------*/ static void K_BotItemEggman(player_t *player, ticcmd_t *cmd) { + const fixed_t coneDist = FixedMul(1280 * mapobjectscale, K_GetKartGameSpeedScalar(gamespeed)); const UINT8 stealth = K_EggboxStealth(player->mo->x, player->mo->y); SINT8 throwdir = -1; + boolean tryLookback = false; player_t *target = NULL; player->botvars.itemconfirm++; @@ -688,11 +710,12 @@ static void K_BotItemEggman(player_t *player, ticcmd_t *cmd) throwdir = 1; } - target = K_PlayerInCone(player, player->mo->radius * 16, 10, true); + target = K_PlayerInCone(player, coneDist, 15, true); if (target != NULL) { K_ItemConfirmForTarget(player, target, player->botvars.difficulty); throwdir = -1; + tryLookback = true; } if (stealth > 1 || player->itemroulette > 0) @@ -701,7 +724,12 @@ static void K_BotItemEggman(player_t *player, ticcmd_t *cmd) throwdir = -1; } - if (player->botvars.itemconfirm > 2*TICRATE || player->bananadrag >= TICRATE) + if (tryLookback == true && throwdir == -1) + { + cmd->buttons |= BT_LOOKBACK; + } + + if (player->botvars.itemconfirm > 10*TICRATE || player->bananadrag >= TICRATE) { K_BotGenericPressItem(player, cmd, throwdir); } @@ -720,6 +748,7 @@ static void K_BotItemEggman(player_t *player, ticcmd_t *cmd) --------------------------------------------------*/ static boolean K_BotRevealsEggbox(player_t *player) { + const fixed_t coneDist = FixedMul(1280 * mapobjectscale, K_GetKartGameSpeedScalar(gamespeed)); const UINT8 stealth = K_EggboxStealth(player->mo->x, player->mo->y); player_t *target = NULL; @@ -737,7 +766,7 @@ static boolean K_BotRevealsEggbox(player_t *player) } // Check your behind. - target = K_PlayerInCone(player, player->mo->radius * 16, 10, true); + target = K_PlayerInCone(player, coneDist, 15, true); if (target != NULL) { return true; @@ -810,8 +839,9 @@ static void K_BotItemEggmanExplosion(player_t *player, ticcmd_t *cmd) static void K_BotItemOrbinaut(player_t *player, ticcmd_t *cmd) { const fixed_t topspeed = K_GetKartSpeed(player, false); - fixed_t radius = (player->mo->radius * 32); + fixed_t radius = FixedMul(2560 * mapobjectscale, K_GetKartGameSpeedScalar(gamespeed)); SINT8 throwdir = -1; + boolean tryLookback = false; UINT8 snipeMul = 2; player_t *target = NULL; @@ -823,24 +853,30 @@ static void K_BotItemOrbinaut(player_t *player, ticcmd_t *cmd) player->botvars.itemconfirm++; - target = K_PlayerInCone(player, radius, 10, false); + target = K_PlayerInCone(player, radius, 15, false); if (target != NULL) { K_ItemConfirmForTarget(player, target, player->botvars.difficulty * snipeMul); throwdir = 1; } - else if (K_PlayerInCone(player, radius, 10, true)) + else { - target = K_PlayerInCone(player, radius, 10, true); + target = K_PlayerInCone(player, radius, 15, true); if (target != NULL) { K_ItemConfirmForTarget(player, target, player->botvars.difficulty); throwdir = -1; + tryLookback = true; } } - if (player->botvars.itemconfirm > 5*TICRATE) + if (tryLookback == true && throwdir == -1) + { + cmd->buttons |= BT_LOOKBACK; + } + + if (player->botvars.itemconfirm > 25*TICRATE) { K_BotGenericPressItem(player, cmd, throwdir); } @@ -861,8 +897,9 @@ static void K_BotItemOrbinaut(player_t *player, ticcmd_t *cmd) static void K_BotItemJawz(player_t *player, ticcmd_t *cmd) { const fixed_t topspeed = K_GetKartSpeed(player, false); - fixed_t radius = (player->mo->radius * 32); + fixed_t radius = FixedMul(2560 * mapobjectscale, K_GetKartGameSpeedScalar(gamespeed)); SINT8 throwdir = 1; + boolean tryLookback = false; UINT8 snipeMul = 2; INT32 lastTarg = player->lastjawztarget; player_t *target = NULL; @@ -875,11 +912,12 @@ static void K_BotItemJawz(player_t *player, ticcmd_t *cmd) player->botvars.itemconfirm++; - target = K_PlayerInCone(player, radius, 10, true); + target = K_PlayerInCone(player, radius, 15, true); if (target != NULL) { K_ItemConfirmForTarget(player, target, player->botvars.difficulty); throwdir = -1; + tryLookback = true; } if (lastTarg != -1 @@ -913,7 +951,12 @@ static void K_BotItemJawz(player_t *player, ticcmd_t *cmd) } } - if (player->botvars.itemconfirm > 5*TICRATE) + if (tryLookback == true && throwdir == -1) + { + cmd->buttons |= BT_LOOKBACK; + } + + if (player->botvars.itemconfirm > 25*TICRATE) { K_BotGenericPressItem(player, cmd, throwdir); } @@ -1007,7 +1050,7 @@ static void K_BotItemBubble(player_t *player, ticcmd_t *cmd) } else if (player->bubbleblowup >= bubbletime) { - if (player->botvars.itemconfirm >= 10*TICRATE) + if (player->botvars.itemconfirm > 10*TICRATE) { hold = true; } diff --git a/src/k_kart.c b/src/k_kart.c index ca32c6f6d..baf93a01e 100644 --- a/src/k_kart.c +++ b/src/k_kart.c @@ -2211,19 +2211,19 @@ void K_KartMoveAnimation(player_t *player) SINT8 destGlanceDir = 0; SINT8 drift = player->drift; - // Uses turning over steering -- it's important to show player feedback immediately. - if (player->cmd.turning < -minturn) - { - turndir = -1; - } - else if (player->cmd.turning > minturn) - { - turndir = 1; - } - if (!lookback) { player->pflags &= ~PF_LOOKDOWN; + + // Uses turning over steering -- it's important to show player feedback immediately. + if (player->cmd.turning < -minturn) + { + turndir = -1; + } + else if (player->cmd.turning > minturn) + { + turndir = 1; + } } else if (drift == 0) { From 11ced1c3d61c944eaf462b2c32a4092cd9d0dc9f Mon Sep 17 00:00:00 2001 From: James R Date: Wed, 5 Jan 2022 22:32:07 -0800 Subject: [PATCH 04/20] Fix nametag distance check --- src/k_hud.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/k_hud.c b/src/k_hud.c index ae6124a75..0404046be 100644 --- a/src/k_hud.c +++ b/src/k_hud.c @@ -2850,8 +2850,8 @@ static void K_drawKartNameTags(void) } v.x = R_InterpolateFixed(ntplayer->mo->old_x, ntplayer->mo->x); - v.y = R_InterpolateFixed(ntplayer->mo->old_x, ntplayer->mo->x); - v.z = R_InterpolateFixed(ntplayer->mo->old_x, ntplayer->mo->x); + v.y = R_InterpolateFixed(ntplayer->mo->old_x, ntplayer->mo->y); + v.z = R_InterpolateFixed(ntplayer->mo->old_x, ntplayer->mo->z); if (!(ntplayer->mo->eflags & MFE_VERTICALFLIP)) { From 93c36af2c083d71bfd89a528b3fc99fba26289d2 Mon Sep 17 00:00:00 2001 From: James R Date: Thu, 6 Jan 2022 00:46:14 -0800 Subject: [PATCH 05/20] Oops almost fucked it again 11ced1c3d --- src/k_hud.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/k_hud.c b/src/k_hud.c index 0404046be..fd83afd56 100644 --- a/src/k_hud.c +++ b/src/k_hud.c @@ -2850,8 +2850,8 @@ static void K_drawKartNameTags(void) } v.x = R_InterpolateFixed(ntplayer->mo->old_x, ntplayer->mo->x); - v.y = R_InterpolateFixed(ntplayer->mo->old_x, ntplayer->mo->y); - v.z = R_InterpolateFixed(ntplayer->mo->old_x, ntplayer->mo->z); + v.y = R_InterpolateFixed(ntplayer->mo->old_y, ntplayer->mo->y); + v.z = R_InterpolateFixed(ntplayer->mo->old_z, ntplayer->mo->z); if (!(ntplayer->mo->eflags & MFE_VERTICALFLIP)) { From fc103834afe1141365243c71c926150c67dff637 Mon Sep 17 00:00:00 2001 From: James R Date: Tue, 11 Jan 2022 22:49:01 -0800 Subject: [PATCH 06/20] Cache terrain on levelflats --- src/k_terrain.c | 5 +---- src/p_setup.c | 3 +++ src/p_setup.h | 3 +++ 3 files changed, 7 insertions(+), 4 deletions(-) diff --git a/src/k_terrain.c b/src/k_terrain.c index f0a5347ea..44b8b3163 100644 --- a/src/k_terrain.c +++ b/src/k_terrain.c @@ -312,16 +312,13 @@ terrain_t *K_GetTerrainForTextureNum(INT32 textureNum) --------------------------------------------------*/ terrain_t *K_GetTerrainForFlatNum(INT32 flatID) { - levelflat_t *levelFlat = NULL; - if (flatID < 0 || flatID >= (signed)numlevelflats) { // Clearly invalid floor... return NULL; } - levelFlat = &levelflats[flatID]; - return K_GetTerrainForTextureName(levelFlat->name); + return levelflats[flatID].terrain; } /*-------------------------------------------------- diff --git a/src/p_setup.c b/src/p_setup.c index 6c5903483..853fdd30c 100644 --- a/src/p_setup.c +++ b/src/p_setup.c @@ -661,6 +661,9 @@ flatfound: levelflat->u.flat.baselumpnum = LUMPERROR; } + levelflat->terrain = + K_GetTerrainForTextureName(levelflat->name); + CONS_Debug(DBG_SETUP, "flat #%03d: %s\n", atoi(sizeu1(numlevelflats)), levelflat->name); return ( numlevelflats++ ); diff --git a/src/p_setup.h b/src/p_setup.h index 0a7587ec0..dfa79da14 100644 --- a/src/p_setup.h +++ b/src/p_setup.h @@ -17,6 +17,7 @@ #include "doomdata.h" #include "doomstat.h" #include "r_defs.h" +#include "k_terrain.h" // map md5, sent to players via PT_SERVERINFO extern unsigned char mapmd5[16]; @@ -71,6 +72,8 @@ typedef struct UINT16 width, height; + terrain_t *terrain; + // for flat animation INT32 animseq; // start pos. in the anim sequence INT32 numpics; From 8a7a20e6f2652c598b6dbdb0d9d6acf973ace6e7 Mon Sep 17 00:00:00 2001 From: James R Date: Wed, 12 Jan 2022 00:33:35 -0800 Subject: [PATCH 07/20] Fix NOMIXER --- src/sdl/sdl_sound.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/src/sdl/sdl_sound.c b/src/sdl/sdl_sound.c index d7a5cb384..ac7a35167 100644 --- a/src/sdl/sdl_sound.c +++ b/src/sdl/sdl_sound.c @@ -517,7 +517,7 @@ static inline void I_SetChannels(void) } } -void I_SetSfxVolume(UINT8 volume) +void I_SetSfxVolume(int volume) { INT32 i; @@ -1466,7 +1466,7 @@ void I_ResumeSong(void) #endif } -void I_SetMusicVolume(UINT8 volume) +void I_SetMusicVolume(int volume) { (void)volume; } @@ -1477,6 +1477,9 @@ boolean I_SetSongTrack(int track) return false; } +void I_UpdateSongLagThreshold(void){} +void I_UpdateSongLagConditions(void){} + /// ------------------------ /// MUSIC FADING /// ------------------------ From 969d449973cc5b8cfef6bd736a7f8db160ff3085 Mon Sep 17 00:00:00 2001 From: James R Date: Wed, 12 Jan 2022 03:36:02 -0800 Subject: [PATCH 08/20] 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 2c6dfd5498d2a23b2d0254c64af80741c6345374 Mon Sep 17 00:00:00 2001 From: James R Date: Wed, 12 Jan 2022 04:30:03 -0800 Subject: [PATCH 09/20] Do not speed up underwater/heatwave effect in OpenGL --- src/hardware/hw_main.c | 12 +----------- 1 file changed, 1 insertion(+), 11 deletions(-) diff --git a/src/hardware/hw_main.c b/src/hardware/hw_main.c index 13d31dc14..962c8f986 100644 --- a/src/hardware/hw_main.c +++ b/src/hardware/hw_main.c @@ -6751,7 +6751,6 @@ void HWR_DoPostProcessor(player_t *player) // 10 by 10 grid. 2 coordinates (xy) float v[SCREENVERTS][SCREENVERTS][2]; static double disStart = 0; - static fixed_t last_fractime = 0; UINT8 x, y; INT32 WAVELENGTH; @@ -6783,16 +6782,7 @@ void HWR_DoPostProcessor(player_t *player) } HWD.pfnPostImgRedraw(v); if (!(paused || P_AutoPause())) - disStart += 1; - if (renderdeltatics > FRACUNIT) - { - disStart = disStart - FIXED_TO_FLOAT(last_fractime) + 1 + FIXED_TO_FLOAT(rendertimefrac); - } - else - { - disStart = disStart - FIXED_TO_FLOAT(last_fractime) + FIXED_TO_FLOAT(rendertimefrac); - } - last_fractime = rendertimefrac; + disStart += FIXED_TO_FLOAT(renderdeltatics); // Capture the screen again for screen waving on the intermission if(gamestate != GS_INTERMISSION) From 0d41c36f0979652fa3c38d46ea8c46a730607585 Mon Sep 17 00:00:00 2001 From: James R Date: Wed, 12 Jan 2022 04:30:43 -0800 Subject: [PATCH 10/20] Closer OpenGL underwater/heatwave effect to Software --- src/hardware/hw_main.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/src/hardware/hw_main.c b/src/hardware/hw_main.c index 962c8f986..74f13ff0e 100644 --- a/src/hardware/hw_main.c +++ b/src/hardware/hw_main.c @@ -6760,15 +6760,15 @@ void HWR_DoPostProcessor(player_t *player) // Modifies the wave. if (*type == postimg_water) { - WAVELENGTH = 20; // Lower is longer - AMPLITUDE = 20; // Lower is bigger - FREQUENCY = 16; // Lower is faster + WAVELENGTH = 5; + AMPLITUDE = 20; + FREQUENCY = 8; } else { - WAVELENGTH = 10; // Lower is longer - AMPLITUDE = 30; // Lower is bigger - FREQUENCY = 4; // Lower is faster + WAVELENGTH = 10; + AMPLITUDE = 60; + FREQUENCY = 4; } for (x = 0; x < SCREENVERTS; x++) From 85ce207e9ca323d8979cca7a603a922e07476b82 Mon Sep 17 00:00:00 2001 From: James R Date: Wed, 12 Jan 2022 04:36:37 -0800 Subject: [PATCH 11/20] 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 12/20] 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 2af1c6fc3011d09e6d37e71a09d882793b835720 Mon Sep 17 00:00:00 2001 From: SteelT Date: Wed, 12 Jan 2022 20:57:25 -0500 Subject: [PATCH 13/20] Fix sounds playing multiple times during intro if interpolation is on --- src/f_finale.c | 24 ++++++++++++++---------- 1 file changed, 14 insertions(+), 10 deletions(-) diff --git a/src/f_finale.c b/src/f_finale.c index eff9ed3f7..0fc575e8e 100644 --- a/src/f_finale.c +++ b/src/f_finale.c @@ -345,16 +345,6 @@ static void F_IntroDrawScene(void) // DRAW A FULL PIC INSTEAD OF FLAT! if (intro_scenenum == 0) { - if (finalecount == 8) - S_StartSound(NULL, sfx_vroom); - else if (finalecount == 47) - { - // Need to use M_Random otherwise it always uses the same sound - INT32 rskin = M_RandomKey(numskins); - UINT8 rtaunt = M_RandomKey(2); - sfxenum_t rsound = skins[rskin].soundsid[SKSKBST1+rtaunt]; - S_StartSound(NULL, rsound); - } background = W_CachePatchName("KARTKREW", PU_CACHE); highres = true; } @@ -453,6 +443,20 @@ void F_IntroTicker(void) timetonext--; + if (intro_scenenum == 0) + { + if (finalecount == 8) + S_StartSound(NULL, sfx_vroom); + else if (finalecount == 47) + { + // Need to use M_Random otherwise it always uses the same sound + INT32 rskin = M_RandomKey(numskins); + UINT8 rtaunt = M_RandomKey(2); + sfxenum_t rsound = skins[rskin].soundsid[SKSKBST1+rtaunt]; + S_StartSound(NULL, rsound); + } + } + F_WriteText(); // check for skipping From 521f8eac3e687349cbd3a9b95a62fbdbcc32b0d5 Mon Sep 17 00:00:00 2001 From: James R Date: Fri, 14 Jan 2022 22:36:49 -0800 Subject: [PATCH 14/20] Fix overflow in precipitation sector search --- src/p_mobj.c | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/src/p_mobj.c b/src/p_mobj.c index f3d326862..fcf0a8e9e 100644 --- a/src/p_mobj.c +++ b/src/p_mobj.c @@ -10536,7 +10536,8 @@ void P_PrecipitationEffects(void) volume = 255; // Sky above? We get it full blast. else { - fixed_t x, y, yl, yh, xl, xh; + /* GCC is optimizing away y >= yl, FUCK YOU */ + volatile fixed_t x, y, yl, yh, xl, xh; fixed_t closedist, newdist; // Essentially check in a 1024 unit radius of the player for an outdoor area. @@ -10545,8 +10546,8 @@ void P_PrecipitationEffects(void) xl = players[g_localplayers[0]].mo->x - 1024*FRACUNIT; xh = players[g_localplayers[0]].mo->x + 1024*FRACUNIT; closedist = 2048*FRACUNIT; - for (y = yl; y <= yh; y += FRACUNIT*64) - for (x = xl; x <= xh; x += FRACUNIT*64) + for (y = yl; y >= yl && y <= yh; y += FRACUNIT*64) + for (x = xl; x >= xl && x <= xh; x += FRACUNIT*64) { if (R_PointInSubsector(x, y)->sector->ceilingpic == skyflatnum) // Found the outdoors! { @@ -13316,4 +13317,4 @@ fixed_t P_GetMobjZMovement(mobj_t *mo) speed = FixedHypot(mo->momx, mo->momy); return P_ReturnThrustY(mo, slope->zangle, P_ReturnThrustX(mo, angDiff, speed)); -} \ No newline at end of file +} From 3eac1fed0f44a8285a9f6b82a12e86997bbb0d34 Mon Sep 17 00:00:00 2001 From: toaster Date: Sun, 16 Jan 2022 20:57:56 +0000 Subject: [PATCH 15/20] Rewrote the fix to: - be comprehensive (still allow rain to be heard against the topleft corner, not just the bottomright corner) - not use volatile (now uses INT64) - not perform this pointinsubsector search if the map has no rain/thunder (yes I tested EHZ with this check dummied out so this bug won't crop up again later) --- src/p_mobj.c | 44 ++++++++++++++++++++++++++++++++------------ 1 file changed, 32 insertions(+), 12 deletions(-) diff --git a/src/p_mobj.c b/src/p_mobj.c index fcf0a8e9e..1d8b2f3ee 100644 --- a/src/p_mobj.c +++ b/src/p_mobj.c @@ -10488,6 +10488,8 @@ void P_PrecipitationEffects(void) boolean effects_lightning = (precipprops[curWeather].effects & PRECIPFX_LIGHTNING); boolean lightningStrike = false; + boolean sounds_rain = (rainsfx != sfx_None && (!leveltime || leveltime % rainfreq == 1)); + // No thunder except every other tic. if (!(leveltime & 1)) { @@ -10532,30 +10534,48 @@ void P_PrecipitationEffects(void) if (sound_disabled) return; // Sound off? D'aw, no fun. + if (!sounds_rain && !sounds_thunder) + return; // no need to calculate volume at ALL + if (players[g_localplayers[0]].mo->subsector->sector->ceilingpic == skyflatnum) volume = 255; // Sky above? We get it full blast. else { - /* GCC is optimizing away y >= yl, FUCK YOU */ - volatile fixed_t x, y, yl, yh, xl, xh; + INT64 x, y, yl, yh, xl, xh; fixed_t closedist, newdist; // Essentially check in a 1024 unit radius of the player for an outdoor area. - yl = players[g_localplayers[0]].mo->y - 1024*FRACUNIT; - yh = players[g_localplayers[0]].mo->y + 1024*FRACUNIT; - xl = players[g_localplayers[0]].mo->x - 1024*FRACUNIT; - xh = players[g_localplayers[0]].mo->x + 1024*FRACUNIT; - closedist = 2048*FRACUNIT; - for (y = yl; y >= yl && y <= yh; y += FRACUNIT*64) - for (x = xl; x >= xl && x <= xh; x += FRACUNIT*64) +#define RADIUSSTEP (64*FRACUNIT) +#define SEARCHRADIUS (16*RADIUSSTEP) + yl = yh = players[g_localplayers[0]].mo->y; + yl -= SEARCHRADIUS; + while (yl < INT32_MIN) + yl += RADIUSSTEP; + yh += SEARCHRADIUS; + while (yh > INT32_MAX) + yh -= RADIUSSTEP; + + xl = xh = players[g_localplayers[0]].mo->x; + xl -= SEARCHRADIUS; + while (xl < INT32_MIN) + xl += RADIUSSTEP; + xh += SEARCHRADIUS; + while (xh > INT32_MAX) + xh -= RADIUSSTEP; + + closedist = SEARCHRADIUS*2; +#undef SEARCHRADIUS + for (y = yl; y <= yh; y += RADIUSSTEP) + for (x = xl; x <= xh; x += RADIUSSTEP) { - if (R_PointInSubsector(x, y)->sector->ceilingpic == skyflatnum) // Found the outdoors! + if (R_PointInSubsector((fixed_t)x, (fixed_t)y)->sector->ceilingpic == skyflatnum) // Found the outdoors! { - newdist = S_CalculateSoundDistance(players[g_localplayers[0]].mo->x, players[g_localplayers[0]].mo->y, 0, x, y, 0); + newdist = S_CalculateSoundDistance(players[g_localplayers[0]].mo->x, players[g_localplayers[0]].mo->y, 0, (fixed_t)x, (fixed_t)y, 0); if (newdist < closedist) closedist = newdist; } } +#undef RADIUSSTEP volume = 255 - (closedist>>(FRACBITS+2)); } @@ -10565,7 +10585,7 @@ void P_PrecipitationEffects(void) else if (volume > 255) volume = 255; - if (rainsfx != sfx_None && (!leveltime || leveltime % rainfreq == 1)) + if (sounds_rain) S_StartSoundAtVolume(players[g_localplayers[0]].mo, rainsfx, volume); if (!sounds_thunder) From ef6ee928acbc762b8dbf863c0cf377e8952c7d8e Mon Sep 17 00:00:00 2001 From: toaster Date: Sun, 16 Jan 2022 22:02:11 +0000 Subject: [PATCH 16/20] After I experienced a few consistent crashes for invalid subsector references in P_BounceMove/P_SlideMove, add a few extra checks for whether the mobj is removed. --- src/p_map.c | 9 ++++++++- src/p_mobj.c | 5 +++++ 2 files changed, 13 insertions(+), 1 deletion(-) diff --git a/src/p_map.c b/src/p_map.c index 8fb58cd0a..fb79b6677 100644 --- a/src/p_map.c +++ b/src/p_map.c @@ -3732,7 +3732,7 @@ stairstep: tmymove = 0; } if (!P_TryMove(mo, newx, newy, true)) { - if (success) + if (success || P_MobjWasRemoved(mo)) return; // Good enough!! else goto retry; @@ -3856,6 +3856,9 @@ void P_BounceMove(mobj_t *mo) INT32 hitcount; fixed_t mmomx = 0, mmomy = 0; + if (P_MobjWasRemoved(mo)) + return; + if (mo->player) { P_BouncePlayerMove(mo); @@ -3979,7 +3982,11 @@ bounceback: mo->momy = tmymove; if (!P_TryMove(mo, mo->x + tmxmove, mo->y + tmymove, true)) + { + if (P_MobjWasRemoved(mo)) + return; goto retry; + } } // diff --git a/src/p_mobj.c b/src/p_mobj.c index f3d326862..b93c8d8d3 100644 --- a/src/p_mobj.c +++ b/src/p_mobj.c @@ -1694,6 +1694,8 @@ void P_XYMovement(mobj_t *mo) else { P_BounceMove(mo); + if (P_MobjWasRemoved(mo)) + return; xmove = ymove = 0; S_StartSound(mo, mo->info->activesound); @@ -1843,6 +1845,9 @@ void P_SceneryXYMovement(mobj_t *mo) if (!P_SceneryTryMove(mo, mo->x + mo->momx, mo->y + mo->momy)) P_BounceMove(mo); + if (P_MobjWasRemoved(mo)) + return; + if ((!(mo->eflags & MFE_VERTICALFLIP) && mo->z > mo->floorz) || (mo->eflags & MFE_VERTICALFLIP && mo->z+mo->height < mo->ceilingz)) return; // no friction when airborne From 14e5ee638e16848cb45555c3fbfcf2ade8819627 Mon Sep 17 00:00:00 2001 From: toaster Date: Sun, 16 Jan 2022 23:21:38 +0000 Subject: [PATCH 17/20] blessings be to hannu Hannu's dropshadow hack, copied across and edited for Kart's column drawer setting functions. --- src/r_draw.h | 1 + src/r_draw8.c | 33 +++++++++++++++++++++++++++++++++ src/r_things.c | 10 +++++++++- src/screen.c | 1 + src/screen.h | 1 + 5 files changed, 45 insertions(+), 1 deletion(-) diff --git a/src/r_draw.h b/src/r_draw.h index 7b44d6185..741ddcc2a 100644 --- a/src/r_draw.h +++ b/src/r_draw.h @@ -180,6 +180,7 @@ void R_DrawViewBorder(void); void R_DrawColumn_8(void); void R_DrawShadeColumn_8(void); void R_DrawTranslucentColumn_8(void); +void R_DrawDropShadowColumn_8(void); void R_DrawTranslatedColumn_8(void); void R_DrawTranslatedTranslucentColumn_8(void); void R_Draw2sMultiPatchColumn_8(void); diff --git a/src/r_draw8.c b/src/r_draw8.c index 0dd8463f6..61b22bc66 100644 --- a/src/r_draw8.c +++ b/src/r_draw8.c @@ -566,6 +566,39 @@ void R_DrawTranslucentColumn_8(void) } } +// Hack: A cut-down copy of R_DrawTranslucentColumn_8 that does not read texture +// data since something about calculating the texture reading address for drop shadows is broken. +// dc_texturemid and dc_iscale get wrong values for drop shadows, however those are not strictly +// needed for the current design of the shadows, so this function bypasses the issue +// by not using those variables at all. +void R_DrawDropShadowColumn_8(void) +{ + register INT32 count; + register UINT8 *dest; + + count = dc_yh - dc_yl + 1; + + if (count <= 0) // Zero length, column does not exceed a pixel. + return; + + dest = &topleft[dc_yl*vid.width + dc_x]; + + { +#define DSCOLOR 15 // palette index for the color of the shadow + register const UINT8 *transmap_offset = dc_transmap + (dc_colormap[DSCOLOR] << 8); +#undef DSCOLOR + while ((count -= 2) >= 0) + { + *dest = *(transmap_offset + (*dest)); + dest += vid.width; + *dest = *(transmap_offset + (*dest)); + dest += vid.width; + } + if (count & 1) + *dest = *(transmap_offset + (*dest)); + } +} + /** \brief The R_DrawTranslatedTranslucentColumn_8 function Spiffy function. Not only does it colormap a sprite, but does translucency as well. Uber-kudos to Cyan Helkaraxe diff --git a/src/r_things.c b/src/r_things.c index 97d45d62d..4779e4df8 100644 --- a/src/r_things.c +++ b/src/r_things.c @@ -836,7 +836,15 @@ static void R_DrawVisSprite(vissprite_t *vis) dc_fullbright = colormaps; dc_translation = R_GetSpriteTranslation(vis); - if (R_SpriteIsFlashing(vis)) // Bosses "flash" + // Hack: Use a special column function for drop shadows that bypasses + // invalid memory access crashes caused by R_ProjectDropShadow putting wrong values + // in dc_texturemid and dc_iscale when the shadow is sloped. + if (vis->cut & SC_SHADOW) + { + R_SetColumnFunc(COLDRAWFUNC_DROPSHADOW, false); + dc_transmap = vis->transmap; + } + else if (R_SpriteIsFlashing(vis)) // Bosses "flash" R_SetColumnFunc(COLDRAWFUNC_TRANS, false); // translate certain pixels to white else if (vis->mobj->color && vis->transmap) // Color mapping { diff --git a/src/screen.c b/src/screen.c index 25dcbb1f7..5ca870cfe 100644 --- a/src/screen.c +++ b/src/screen.c @@ -133,6 +133,7 @@ void SCR_SetDrawFuncs(void) colfuncs[COLDRAWFUNC_TWOSMULTIPATCH] = R_Draw2sMultiPatchColumn_8; colfuncs[COLDRAWFUNC_TWOSMULTIPATCHTRANS] = R_Draw2sMultiPatchTranslucentColumn_8; colfuncs[COLDRAWFUNC_FOG] = R_DrawFogColumn_8; + colfuncs[COLDRAWFUNC_DROPSHADOW] = R_DrawDropShadowColumn_8; spanfuncs[SPANDRAWFUNC_TRANS] = R_DrawTranslucentSpan_8; spanfuncs[SPANDRAWFUNC_TILTED] = R_DrawTiltedSpan_8; diff --git a/src/screen.h b/src/screen.h index 66c52dd67..f279e8444 100644 --- a/src/screen.h +++ b/src/screen.h @@ -131,6 +131,7 @@ enum COLDRAWFUNC_TWOSMULTIPATCH, COLDRAWFUNC_TWOSMULTIPATCHTRANS, COLDRAWFUNC_FOG, + COLDRAWFUNC_DROPSHADOW, COLDRAWFUNC_MAX }; From 867b0516e6ddc48d71f760d29d95cb1dc0d14a94 Mon Sep 17 00:00:00 2001 From: toaster Date: Sun, 16 Jan 2022 23:53:14 +0000 Subject: [PATCH 18/20] Terrain pointers were not getting properly relinked on netsave load, now they are. Thanks Sal for taking a moment out of your day to rubber duck with me --- src/p_saveg.c | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/src/p_saveg.c b/src/p_saveg.c index 7710ee0de..6aff9a33f 100644 --- a/src/p_saveg.c +++ b/src/p_saveg.c @@ -4119,6 +4119,15 @@ static void P_RelinkPointers(void) if (!(mobj->itnext = P_FindNewPosition(temp))) CONS_Debug(DBG_GAMELOGIC, "itnext not found on %d\n", mobj->type); } + if (mobj->terrain) + { + temp = (UINT32)(size_t)mobj->terrain; + mobj->terrain = K_GetTerrainByIndex(temp); + if (mobj->terrain == NULL) + { + CONS_Debug(DBG_GAMELOGIC, "terrain not found on %d\n", mobj->type); + } + } if (mobj->player) { if ( mobj->player->awayviewmobj) From 159994c2f04e0193a8d00dad2209c09439614608 Mon Sep 17 00:00:00 2001 From: SteelT Date: Mon, 17 Jan 2022 15:46:44 -0500 Subject: [PATCH 19/20] 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 7fc72d03ffdf4e7b7ff42f4379e2a56011d22f4f Mon Sep 17 00:00:00 2001 From: James R Date: Mon, 17 Jan 2022 23:07:04 -0800 Subject: [PATCH 20/20] 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);