From 6f6e87f9df7d74ef7c0abc26576ae7e52f51fd42 Mon Sep 17 00:00:00 2001 From: toaster Date: Fri, 27 Nov 2020 17:32:04 +0000 Subject: [PATCH 1/7] Fix replays not being accessible via menus. --- src/m_menu.c | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/src/m_menu.c b/src/m_menu.c index 7f6f542c6..56c5585b4 100644 --- a/src/m_menu.c +++ b/src/m_menu.c @@ -8139,11 +8139,11 @@ static void M_ReplayTimeAttack(INT32 choice) break; case 3: // guest // srb2/replay/main/map01-guest.lmp - G_DoPlayDemo(va("%s"PATHSEP"replay"PATHSEP"%s"PATHSEP"%s-guest.lmp", srb2home, timeattackfolder, G_BuildMapName(cv_nextmap.value))); + G_DoPlayDemo(va("%s"PATHSEP"media"PATHSEP"replay"PATHSEP"%s"PATHSEP"%s-guest.lmp", srb2home, timeattackfolder, G_BuildMapName(cv_nextmap.value))); return; } // srb2/replay/main/map01-sonic-time-best.lmp - G_DoPlayDemo(va("%s"PATHSEP"replay"PATHSEP"%s"PATHSEP"%s-%s-%s.lmp", srb2home, timeattackfolder, G_BuildMapName(cv_nextmap.value), cv_chooseskin.string, which)); + G_DoPlayDemo(va("%s"PATHSEP"media"PATHSEP"replay"PATHSEP"%s"PATHSEP"%s-%s-%s.lmp", srb2home, timeattackfolder, G_BuildMapName(cv_nextmap.value), cv_chooseskin.string, which)); } /*else if (currentMenu == &SP_NightsReplayDef) { @@ -8165,13 +8165,13 @@ static void M_ReplayTimeAttack(INT32 choice) break; } // srb2/replay/main/map01-score-best.lmp - G_DoPlayDemo(va("%s"PATHSEP"replay"PATHSEP"%s"PATHSEP"%s-%s.lmp", srb2home, timeattackfolder, G_BuildMapName(cv_nextmap.value), which)); + G_DoPlayDemo(va("%s"PATHSEP"media"PATHSEP"replay"PATHSEP"%s"PATHSEP"%s-%s.lmp", srb2home, timeattackfolder, G_BuildMapName(cv_nextmap.value), which)); }*/ } static void M_EraseGuest(INT32 choice) { - const char *rguest = va("%s"PATHSEP"replay"PATHSEP"%s"PATHSEP"%s-guest.lmp", srb2home, timeattackfolder, G_BuildMapName(cv_nextmap.value)); + const char *rguest = va("%s"PATHSEP"media"PATHSEP"replay"PATHSEP"%s"PATHSEP"%s-guest.lmp", srb2home, timeattackfolder, G_BuildMapName(cv_nextmap.value)); (void)choice; if (FIL_FileExists(rguest)) remove(rguest); @@ -8186,10 +8186,10 @@ static void M_EraseGuest(INT32 choice) static void M_OverwriteGuest(const char *which) { - char *rguest = Z_StrDup(va("%s"PATHSEP"replay"PATHSEP"%s"PATHSEP"%s-guest.lmp", srb2home, timeattackfolder, G_BuildMapName(cv_nextmap.value))); + char *rguest = Z_StrDup(va("%s"PATHSEP"media"PATHSEP"replay"PATHSEP"%s"PATHSEP"%s-guest.lmp", srb2home, timeattackfolder, G_BuildMapName(cv_nextmap.value))); UINT8 *buf; size_t len; - len = FIL_ReadFile(va("%s"PATHSEP"replay"PATHSEP"%s"PATHSEP"%s-%s-%s.lmp", srb2home, timeattackfolder, G_BuildMapName(cv_nextmap.value), cv_chooseskin.string, which), &buf); + len = FIL_ReadFile(va("%s"PATHSEP"media"PATHSEP"replay"PATHSEP"%s"PATHSEP"%s-%s-%s.lmp", srb2home, timeattackfolder, G_BuildMapName(cv_nextmap.value), cv_chooseskin.string, which), &buf); if (!len) { return; } @@ -8258,7 +8258,7 @@ static void M_SetGuestReplay(INT32 choice) M_StartMessage(M_GetText("Are you sure you want to\ndelete the guest replay data?\n\n(Press 'Y' to confirm)\n"),M_EraseGuest,MM_YESNO); return; } - if (FIL_FileExists(va("%s"PATHSEP"replay"PATHSEP"%s"PATHSEP"%s-guest.lmp", srb2home, timeattackfolder, G_BuildMapName(cv_nextmap.value)))) + if (FIL_FileExists(va("%s"PATHSEP"media"PATHSEP"replay"PATHSEP"%s"PATHSEP"%s-guest.lmp", srb2home, timeattackfolder, G_BuildMapName(cv_nextmap.value)))) M_StartMessage(M_GetText("Are you sure you want to\noverwrite the guest replay data?\n\n(Press 'Y' to confirm)\n"),which,MM_YESNO); else which(0); From 9c0edb097f728c87ed214bebbd32671e753ea6dc Mon Sep 17 00:00:00 2001 From: toaster Date: Fri, 27 Nov 2020 17:59:57 +0000 Subject: [PATCH 2/7] Fix demos doing incomprehensibly nasty bullshit; now they only desync for a handful of easier-to-hammer-down cases. --- src/g_demo.c | 24 +++++++++++++++++------- 1 file changed, 17 insertions(+), 7 deletions(-) diff --git a/src/g_demo.c b/src/g_demo.c index 7c2f9f25c..9b5687750 100644 --- a/src/g_demo.c +++ b/src/g_demo.c @@ -1205,9 +1205,6 @@ void G_GhostTicker(void) g->p += 12; // kartitem, kartamount, kartbumpers } - if (READUINT8(g->p) != 0xFF) // Make sure there isn't other ghost data here. - I_Error("Ghost is not a record attack ghost"); //@TODO lmao don't blow up like this - skippedghosttic: // Tick ghost colors (Super and Mario Invincibility flashing) switch(g->color) @@ -1294,6 +1291,7 @@ skippedghosttic: P_RemoveMobj(follow); P_SetTarget(&follow, NULL); } + // Demo ends after ghost data. if (*g->p == DEMOMARKER) { @@ -1314,6 +1312,10 @@ skippedghosttic: Z_Free(g); continue; } + + if (READUINT8(g->p) != 0xFF) // Make sure there isn't other ghost data here. + I_Error("Ghost is not a record attack ghost"); //@TODO lmao don't blow up like this + p = g; #undef follow } @@ -1899,7 +1901,8 @@ void G_BeginRecording(void) if (encoremode) demoflags |= DF_ENCORE; - demoflags |= DF_LUAVARS; + if (multiplayer) + demoflags |= DF_LUAVARS; // Setup header. M_Memcpy(demo_p, DEMOHEADER, 12); demo_p += 12; @@ -2033,9 +2036,8 @@ void G_BeginRecording(void) WRITEUINT8(demo_p, 0xFF); // Denote the end of the player listing // player lua vars, always saved even if empty - LUA_Archive(&demo_p); - - WRITEUINT32(demo_p,P_GetInitSeed()); + if (demoflags & DF_LUAVARS) + LUA_Archive(&demo_p); memset(&oldcmd,0,sizeof(oldcmd)); memset(&oldghost,0,sizeof(oldghost)); @@ -3145,6 +3147,14 @@ void G_AddGhost(char *defdemoname) return; } + if (flags & DF_LUAVARS) // can't be arsed to add support for grinding away ported lua material + { + CONS_Alert(CONS_NOTICE, M_GetText("Ghost %s: Replay data contains luavars, cannot continue.\n"), pdemoname); + Z_Free(pdemoname); + Z_Free(buffer); + return; + } + p++; // gametype G_SkipDemoExtraFiles(&p); // Don't wanna modify the file list for ghosts. From f72108c4faa6ec5abb06b1f788f78d646202b764 Mon Sep 17 00:00:00 2001 From: toaster Date: Fri, 27 Nov 2020 20:30:28 +0000 Subject: [PATCH 3/7] A whole bunch of cleanup to get most record attack/replay stuff reasonably functional. * Fix the screen being stuck black at the very start of start record attack. * Bump up the demoversion to 7, because I want all previous v2 demos to be guaranteed kaput (it was previously 4, but 7 is a nice number). * Fix a ton MORE shitcausing misalignments in the replay system, this time specifically focused on getting ghosts functional. * Plug a few holes in the "best lap" record implementation that allowed for stupidly easy records due to the way v2's finish lines work. * Make a few follower-related things sane, to prevent spurious console prints that were getting in the way of my test prints. --- src/d_netcmd.c | 15 ++---- src/g_demo.c | 127 +++++++++++++++++++++++++------------------------ src/p_spec.c | 17 +++---- src/p_tick.c | 4 +- src/p_user.c | 4 +- src/r_skins.c | 5 ++ 6 files changed, 85 insertions(+), 87 deletions(-) diff --git a/src/d_netcmd.c b/src/d_netcmd.c index a87d04cb5..46ecc1b97 100644 --- a/src/d_netcmd.c +++ b/src/d_netcmd.c @@ -289,10 +289,10 @@ consvar_t cv_skin[MAXSPLITSCREENPLAYERS] = { // player's followers. Also saved. consvar_t cv_follower[MAXSPLITSCREENPLAYERS] = { - CVAR_INIT ("follower", "-1", CV_SAVE|CV_CALL|CV_NOINIT, NULL, Follower_OnChange), - CVAR_INIT ("follower2", "-1", CV_SAVE|CV_CALL|CV_NOINIT, NULL, Follower2_OnChange), - CVAR_INIT ("follower3", "-1", CV_SAVE|CV_CALL|CV_NOINIT, NULL, Follower3_OnChange), - CVAR_INIT ("follower4", "-1", CV_SAVE|CV_CALL|CV_NOINIT, NULL, Follower4_OnChange) + CVAR_INIT ("follower", "None", CV_SAVE|CV_CALL|CV_NOINIT, NULL, Follower_OnChange), + CVAR_INIT ("follower2", "None", CV_SAVE|CV_CALL|CV_NOINIT, NULL, Follower2_OnChange), + CVAR_INIT ("follower3", "None", CV_SAVE|CV_CALL|CV_NOINIT, NULL, Follower3_OnChange), + CVAR_INIT ("follower4", "None", CV_SAVE|CV_CALL|CV_NOINIT, NULL, Follower4_OnChange) }; // player's follower colors... Also saved... @@ -2858,13 +2858,6 @@ static void Got_Mapcmd(UINT8 **cp, INT32 playernum) memset(&luabanks, 0, sizeof(luabanks)); } - if (modeattacking) - { - SetPlayerSkinByNum(0, cv_chooseskin.value-1); - players[0].skincolor = skins[players[0].skin].prefcolor; - CV_StealthSetValue(&cv_playercolor[0], players[0].skincolor); - } - mapnumber = M_MapNumber(mapname[3], mapname[4]); LUAh_MapChange(mapnumber); diff --git a/src/g_demo.c b/src/g_demo.c index 9b5687750..69c8fb760 100644 --- a/src/g_demo.c +++ b/src/g_demo.c @@ -104,7 +104,7 @@ demoghost *ghosts = NULL; // DEMO RECORDING // -#define DEMOVERSION 0x0004 +#define DEMOVERSION 0x0007 #define DEMOHEADER "\xF0" "KartReplay" "\x0F" #define DF_GHOST 0x01 // This demo contains ghost data too! @@ -112,7 +112,7 @@ demoghost *ghosts = NULL; #define DF_BREAKTHECAPSULES 0x04 // This demo is from Break the Capsules and contains its final completion time! #define DF_ATTACKMASK 0x06 // This demo is from ??? attack and contains ??? -#define DF_LUAVARS 0x20 // this demo contains extra lua vars; this is mostly used for backwards compability +#define DF_LUAVARS 0x20 // this demo contains extra lua vars #define DF_ATTACKSHIFT 1 #define DF_ENCORE 0x40 @@ -419,7 +419,10 @@ void G_WriteDemoExtraData(void) { // write follower memset(name, 0, 16); - strncpy(name, followers[players[i].followerskin].skinname, 16); + if (players[i].followerskin == -1) + strncpy(name, "None", 16); + else + strncpy(name, followers[players[i].followerskin].skinname, 16); M_Memcpy(demo_p, name, 16); demo_p += 16; @@ -619,13 +622,21 @@ void G_WriteAllGhostTics(void) counter++; - if (counter % cv_netdemosyncquality.value != 0) // Only write 1 in this many ghost datas per tic to cut down on multiplayer replay size. + if (multiplayer && (counter % cv_netdemosyncquality.value != 0)) // Only write 1 in this many ghost datas per tic to cut down on multiplayer replay size. continue; WRITEUINT8(demo_p, i); G_WriteGhostTic(players[i].mo, i); } WRITEUINT8(demo_p, 0xFF); + + // attention here for the ticcmd size! + // latest demos with mouse aiming byte in ticcmd + if (demo_p >= demoend - (13 + 9 + 9)) + { + G_CheckDemoStatus(); // no more space + return; + } } void G_WriteGhostTic(mobj_t *ghost, INT32 playernum) @@ -722,26 +733,22 @@ void G_WriteGhostTic(mobj_t *ghost, INT32 playernum) ghostext[playernum].flags |= EZT_SPRITE; } + if (ghost->player && ( + ghostext[playernum].kartitem != ghost->player->kartstuff[k_itemtype] || + ghostext[playernum].kartamount != ghost->player->kartstuff[k_itemamount] || + ghostext[playernum].kartbumpers != ghost->player->kartstuff[k_bumper] + )) + { + ghostext[playernum].flags |= EZT_KART; + ghostext[playernum].kartitem = ghost->player->kartstuff[k_itemtype]; + ghostext[playernum].kartamount = ghost->player->kartstuff[k_itemamount]; + ghostext[playernum].kartbumpers = ghost->player->kartstuff[k_bumper]; + } + if (ghostext[playernum].flags) { ziptic |= GZT_EXTRA; - if (ghost->player) - { - if ( - ghostext[playernum].kartitem != ghost->player->kartstuff[k_itemtype] || - ghostext[playernum].kartamount != ghost->player->kartstuff[k_itemamount] || - ghostext[playernum].kartbumpers != ghost->player->kartstuff[k_bumper] - ) - { - ghostext[playernum].flags |= EZT_KART; - ghostext[playernum].kartitem = ghost->player->kartstuff[k_itemtype]; - ghostext[playernum].kartamount = ghost->player->kartstuff[k_itemamount]; - ghostext[playernum].kartbumpers = ghost->player->kartstuff[k_bumper]; - - } - } - if (ghostext[playernum].color == ghostext[playernum].lastcolor) ghostext[playernum].flags &= ~EZT_COLOR; if (ghostext[playernum].scale == ghostext[playernum].lastscale) @@ -836,14 +843,6 @@ void G_WriteGhostTic(mobj_t *ghost, INT32 playernum) oldghost[playernum].flags2 &= ~MF2_AMBUSH; *ziptic_p = ziptic; - - // attention here for the ticcmd size! - // latest demos with mouse aiming byte in ticcmd - if (demo_p >= demoend - (13 + 9 + 9)) - { - G_CheckDemoStatus(); // no more space - return; - } } void G_ConsAllGhostTics(void) @@ -1067,16 +1066,18 @@ void G_GhostTicker(void) if (ziptic & DXD_FOLLOWER) g->p += 32; // ok (32 because there's both the skin and the colour) if (ziptic & DXD_PLAYSTATE && READUINT8(g->p) != DXD_PST_PLAYING) - I_Error("Ghost is not a record attack ghost"); //@TODO lmao don't blow up like this + I_Error("Ghost is not a record attack ghost PLAYSTATE"); //@TODO lmao don't blow up like this } else if (ziptic == DW_RNG) g->p += 4; // RNG seed else - I_Error("Ghost is not a record attack ghost"); //@TODO lmao don't blow up like this + I_Error("Ghost is not a record attack ghost DXD"); //@TODO lmao don't blow up like this ziptic = READUINT8(g->p); } + ziptic = READUINT8(g->p); + if (ziptic & ZT_FWD) g->p++; if (ziptic & ZT_TURNING) @@ -1086,9 +1087,9 @@ void G_GhostTicker(void) if (ziptic & ZT_AIMING) g->p += 2; if (ziptic & ZT_LATENCY) - g->p += 1; + g->p++; if (ziptic & ZT_FLAGS) - g->p += 1; + g->p++; // Grab ghost data. ziptic = READUINT8(g->p); @@ -1096,7 +1097,7 @@ void G_GhostTicker(void) if (ziptic == 0xFF) goto skippedghosttic; // Didn't write ghost info this frame else if (ziptic != 0) - I_Error("Ghost is not a record attack ghost"); //@TODO lmao don't blow up like this + I_Error("Ghost is not a record attack ghost ZIPTIC"); //@TODO lmao don't blow up like this ziptic = READUINT8(g->p); if (ziptic & GZT_XYZ) @@ -1109,17 +1110,17 @@ void G_GhostTicker(void) { if (ziptic & GZT_MOMXY) { - g->oldmo.momx = (g->version < 0x000e) ? READINT16(g->p)<<8 : READFIXED(g->p); - g->oldmo.momy = (g->version < 0x000e) ? READINT16(g->p)<<8 : READFIXED(g->p); + g->oldmo.momx = READFIXED(g->p); + g->oldmo.momy = READFIXED(g->p); } if (ziptic & GZT_MOMZ) - g->oldmo.momz = (g->version < 0x000e) ? READINT16(g->p)<<8 : READFIXED(g->p); + g->oldmo.momz = READFIXED(g->p); g->oldmo.x += g->oldmo.momx; g->oldmo.y += g->oldmo.momy; g->oldmo.z += g->oldmo.momz; } if (ziptic & GZT_ANGLE) - g->mo->angle = READUINT8(g->p)<<24; + g->oldmo.angle = READUINT8(g->p)<<24; if (ziptic & GZT_FRAME) g->oldmo.frame = READUINT8(g->p); if (ziptic & GZT_SPR2) @@ -1205,27 +1206,6 @@ void G_GhostTicker(void) g->p += 12; // kartitem, kartamount, kartbumpers } -skippedghosttic: - // Tick ghost colors (Super and Mario Invincibility flashing) - switch(g->color) - { - case GHC_SUPER: // Super (P_DoSuperStuff) - if (g->mo->skin) - { - skin_t *skin = (skin_t *)g->mo->skin; - g->mo->color = skin->supercolor; - } - else - g->mo->color = SKINCOLOR_SUPERGOLD1; - g->mo->color += abs( ( (signed)( (unsigned)leveltime >> 1 ) % 9) - 4); - break; - case GHC_INVINCIBLE: // Mario invincibility (P_CheckInvincibilityTimer) - g->mo->color = (UINT16)(SKINCOLOR_RUBY + (leveltime % (FIRSTSUPERCOLOR - SKINCOLOR_RUBY))); // Passes through all saturated colours - break; - default: - break; - } - #define follow g->mo->tracer if (ziptic & GZT_FOLLOW) { // Even more... @@ -1292,6 +1272,30 @@ skippedghosttic: P_SetTarget(&follow, NULL); } +skippedghosttic: + // Tick ghost colors (Super and Mario Invincibility flashing) + switch(g->color) + { + case GHC_SUPER: // Super (P_DoSuperStuff) + if (g->mo->skin) + { + skin_t *skin = (skin_t *)g->mo->skin; + g->mo->color = skin->supercolor; + } + else + g->mo->color = SKINCOLOR_SUPERGOLD1; + g->mo->color += abs( ( (signed)( (unsigned)leveltime >> 1 ) % 9) - 4); + break; + case GHC_INVINCIBLE: // Mario invincibility (P_CheckInvincibilityTimer) + g->mo->color = (UINT16)(SKINCOLOR_RUBY + (leveltime % (FIRSTSUPERCOLOR - SKINCOLOR_RUBY))); // Passes through all saturated colours + break; + default: + break; + } + + if (READUINT8(g->p) != 0xFF) // Make sure there isn't other ghost data here. + I_Error("Ghost is not a record attack ghost GHOSTEND"); //@TODO lmao don't blow up like this + // Demo ends after ghost data. if (*g->p == DEMOMARKER) { @@ -1313,9 +1317,6 @@ skippedghosttic: continue; } - if (READUINT8(g->p) != 0xFF) // Make sure there isn't other ghost data here. - I_Error("Ghost is not a record attack ghost"); //@TODO lmao don't blow up like this - p = g; #undef follow } @@ -2714,7 +2715,6 @@ void G_DoPlayDemo(char *defdemoname) demo.version = READUINT16(demo_p); switch(demo.version) { - case 0x000d: case DEMOVERSION: // latest always supported break; // too old, cannot support. @@ -3103,7 +3103,6 @@ void G_AddGhost(char *defdemoname) ghostversion = READUINT16(p); switch(ghostversion) { - case 0x000d: case DEMOVERSION: // latest always supported break; // too old, cannot support. @@ -3221,6 +3220,8 @@ void G_AddGhost(char *defdemoname) kartspeed = READUINT8(p); kartweight = READUINT8(p); + p += 4; // followitem (maybe change later) + if (READUINT8(p) != 0xFF) { CONS_Alert(CONS_NOTICE, M_GetText("Failed to add ghost %s: Invalid player slot.\n"), pdemoname); diff --git a/src/p_spec.c b/src/p_spec.c index 3d0eddd2e..519f21cd4 100644 --- a/src/p_spec.c +++ b/src/p_spec.c @@ -2028,6 +2028,14 @@ static void K_HandleLapIncrement(player_t *player) player->karthud[khud_laphand] = 0; // No hands in FREE PLAY player->karthud[khud_lapanimation] = 80; + + // save best lap for record attack + if (player == &players[consoleplayer]) + { + if (curlap < bestlap || bestlap == 0) + bestlap = curlap; + curlap = 0; + } } if (rainbowstartavailable == true) @@ -2041,14 +2049,6 @@ static void K_HandleLapIncrement(player_t *player) if (netgame && player->laps >= (UINT8)cv_numlaps.value) CON_LogMessage(va(M_GetText("%s has finished the race.\n"), player_names[player-players])); - // SRB2Kart: save best lap for record attack - if (player == &players[consoleplayer]) - { - if (curlap < bestlap || bestlap == 0) - bestlap = curlap; - curlap = 0; - } - player->starpostnum = 0; if (P_IsDisplayPlayer(player)) @@ -2133,6 +2133,7 @@ static void K_HandleLapDecrement(player_t *player) { player->starpostnum = numstarposts; player->laps--; + curlap = UINT32_MAX; } } } diff --git a/src/p_tick.c b/src/p_tick.c index 79e71c655..9d7a6ac5c 100644 --- a/src/p_tick.c +++ b/src/p_tick.c @@ -613,9 +613,7 @@ void P_Ticker(boolean run) if (run) leveltime++; - // as this is mostly used for HUD stuff, add the record attack specific hack to it as well! - if (!(modeattacking && !demo.playback) || leveltime >= starttime - TICRATE*4) - timeinmap++; + timeinmap++; if (G_GametypeHasTeams()) P_DoTeamStuff(); diff --git a/src/p_user.c b/src/p_user.c index f03c63464..10b2c9a97 100644 --- a/src/p_user.c +++ b/src/p_user.c @@ -2644,7 +2644,7 @@ static void P_DeathThink(player_t *player) { if (player->spectator || !circuitmap) curlap = 0; - else + else if (curlap != UINT32_MAX) curlap++; // This is too complicated to sync to realtime, just sorta hope for the best :V } } @@ -4385,7 +4385,7 @@ void P_PlayerThink(player_t *player) { if (player->spectator || !circuitmap) curlap = 0; - else + else if (curlap != UINT32_MAX) curlap++; // This is too complicated to sync to realtime, just sorta hope for the best :V } } diff --git a/src/r_skins.c b/src/r_skins.c index 951eeaad6..135221ea6 100644 --- a/src/r_skins.c +++ b/src/r_skins.c @@ -876,6 +876,11 @@ boolean SetPlayerFollower(INT32 playernum, const char *skinname) INT32 i; player_t *player = &players[playernum]; + if (stricmp("None", skinname) == 0) + { + SetFollower(playernum, -1); // reminder that -1 is nothing + return true; + } for (i = 0; i < numfollowers; i++) { // search in the skin list From c2447154ecec27e0a6e9e1ab7acf5ee077f99004 Mon Sep 17 00:00:00 2001 From: toaster Date: Sat, 28 Nov 2020 11:32:29 +0000 Subject: [PATCH 4/7] Bracketing fix for Sryder. --- src/g_demo.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/g_demo.c b/src/g_demo.c index 69c8fb760..773c0119e 100644 --- a/src/g_demo.c +++ b/src/g_demo.c @@ -622,7 +622,7 @@ void G_WriteAllGhostTics(void) counter++; - if (multiplayer && (counter % cv_netdemosyncquality.value != 0)) // Only write 1 in this many ghost datas per tic to cut down on multiplayer replay size. + if (multiplayer && ((counter % cv_netdemosyncquality.value) != 0)) // Only write 1 in this many ghost datas per tic to cut down on multiplayer replay size. continue; WRITEUINT8(demo_p, i); From 495e4896dcef5a4e9f0d911cdac5cfcc751e575e Mon Sep 17 00:00:00 2001 From: toaster Date: Sat, 28 Nov 2020 11:45:25 +0000 Subject: [PATCH 5/7] Fixed Chengi's sprite2 bug, and started on (but haven't nailed down) the rewind crash. --- src/g_demo.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/g_demo.c b/src/g_demo.c index 773c0119e..aebc447f2 100644 --- a/src/g_demo.c +++ b/src/g_demo.c @@ -1439,8 +1439,11 @@ void G_PreviewRewind(tic_t previewtime) players[i].drawangle = info->playerinfo[i].player.drawangle + FixedMul((INT32) (next_info->playerinfo[i].player.drawangle - info->playerinfo[i].player.drawangle), tweenvalue); players[i].mo->sprite = info->playerinfo[i].mobj.sprite; + players[i].mo->sprite2 = info->playerinfo[i].mobj.sprite2; players[i].mo->frame = info->playerinfo[i].mobj.frame; + players[i].mo->hitlag = info->playerinfo[i].mobj.hitlag; + players[i].realtime = info->playerinfo[i].player.realtime; for (j = 0; j < NUMKARTSTUFF; j++) players[i].kartstuff[j] = info->playerinfo[i].player.kartstuff[j]; From 762dfd3063f50854399a46865fe9b34379f18b08 Mon Sep 17 00:00:00 2001 From: toaster Date: Sat, 28 Nov 2020 12:31:16 +0000 Subject: [PATCH 6/7] When resuming from a rewind, don't: * run wipes again * run titlecards again * stop the music --- src/g_demo.c | 2 +- src/g_game.c | 2 +- src/p_setup.c | 60 +++++++++++++++++++++++++-------------------------- src/p_tick.c | 2 ++ 4 files changed, 34 insertions(+), 32 deletions(-) diff --git a/src/g_demo.c b/src/g_demo.c index aebc447f2..693a4f095 100644 --- a/src/g_demo.c +++ b/src/g_demo.c @@ -1468,7 +1468,7 @@ void G_ConfirmRewind(tic_t rewindtime) if (rewindtime <= starttime) { - demo.rewinding = false; + demo.rewinding = true; // this doesn't APPEAR to cause any misery, and it allows us to prevent running all the wipes again G_DoPlayDemo(NULL); // Restart the current demo } else diff --git a/src/g_game.c b/src/g_game.c index 0151783e9..1f17fc181 100644 --- a/src/g_game.c +++ b/src/g_game.c @@ -1252,7 +1252,7 @@ void G_StartTitleCard(void) { // The title card has been disabled for this map. // Oh well. - if (!G_IsTitleCardAvailable()) + if (!G_IsTitleCardAvailable() || demo.rewinding) { WipeStageTitle = false; return; diff --git a/src/p_setup.c b/src/p_setup.c index 50f39c5fa..15e6767a5 100644 --- a/src/p_setup.c +++ b/src/p_setup.c @@ -3924,40 +3924,40 @@ boolean P_LoadLevel(boolean fromnetsave) } */ - // Make sure all sounds are stopped before Z_FreeTags. - S_StopSounds(); - S_ClearSfx(); - - // Fade out music here. Deduct 2 tics so the fade volume actually reaches 0. - // But don't halt the music! S_Start will take care of that. This dodges a MIDI crash bug. - if (!titlemapinaction) - S_FadeMusic(0, FixedMul( - FixedDiv((F_GetWipeLength(wipedefs[wipe_level_toblack])-2)*NEWTICRATERATIO, NEWTICRATE), MUSICRATE)); - - // Reset the palette now all fades have been done - if (rendermode != render_none) - V_SetPaletteLump(GetPalette()); // Set the level palette - - if (!titlemapinaction) - { - if (ranspecialwipe == 2) - { - pausedelay = -3; // preticker plus one - S_StartSound(NULL, sfx_s3k73); - } - - // As oddly named as this is, this handles music only. - // We should be fine starting it here. - // Don't do this during titlemap, because the menu code handles music by itself. - S_Start(); - } - - levelfadecol = (encoremode ? 0 : 31); - // Let's fade to white here // But only if we didn't do the encore startup wipe if (!demo.rewinding) { + // Make sure all sounds are stopped before Z_FreeTags. + S_StopSounds(); + S_ClearSfx(); + + // Fade out music here. Deduct 2 tics so the fade volume actually reaches 0. + // But don't halt the music! S_Start will take care of that. This dodges a MIDI crash bug. + if (!titlemapinaction) + S_FadeMusic(0, FixedMul( + FixedDiv((F_GetWipeLength(wipedefs[wipe_level_toblack])-2)*NEWTICRATERATIO, NEWTICRATE), MUSICRATE)); + + // Reset the palette now all fades have been done + if (rendermode != render_none) + V_SetPaletteLump(GetPalette()); // Set the level palette + + if (!titlemapinaction) + { + if (ranspecialwipe == 2) + { + pausedelay = -3; // preticker plus one + S_StartSound(NULL, sfx_s3k73); + } + + // As oddly named as this is, this handles music only. + // We should be fine starting it here. + // Don't do this during titlemap, because the menu code handles music by itself. + S_Start(); + } + + levelfadecol = (encoremode ? 0 : 31); + if (rendermode != render_none) { F_WipeStartScreen(); diff --git a/src/p_tick.c b/src/p_tick.c index 9d7a6ac5c..cef59ea8d 100644 --- a/src/p_tick.c +++ b/src/p_tick.c @@ -516,6 +516,8 @@ void P_Ticker(boolean run) if (demo.rewinding && leveltime > 0) { leveltime = (leveltime-1) & ~3; + if (timeinmap > 0) + timeinmap = (timeinmap-1) & ~3; G_PreviewRewind(leveltime); } else if (demo.freecam && democam.cam) // special case: allow freecam to MOVE during pause! From 891f14dd26848fa4b4abbbdf3a395f18d7e20974 Mon Sep 17 00:00:00 2001 From: toaster Date: Sat, 28 Nov 2020 17:29:28 +0000 Subject: [PATCH 7/7] Don't show post-race bot inputs on input display UI. --- 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 42c7fd7c2..056beb408 100644 --- a/src/k_hud.c +++ b/src/k_hud.c @@ -3523,7 +3523,7 @@ static void K_drawInput(void) #define BUTTH 11 #define drawbutt(xoffs, butt, symb)\ - if (stplyr->cmd.buttons & butt)\ + if (!stplyr->exiting && (cmd->buttons & butt))\ {\ offs = 2;\ col = accent1;\ @@ -3549,7 +3549,7 @@ static void K_drawInput(void) y -= 1; - if (!cmd->turning) // no turn + if (stplyr->exiting || !cmd->turning) // no turn target = 0; else // turning of multiple strengths! {