mirror of
https://git.do.srb2.org/KartKrew/Kart-Public.git
synced 2024-12-27 04:41:23 +00:00
Merge branch 'fickle-replay-v1' into replay-freecam-rewind
This commit is contained in:
commit
bb1c320236
4 changed files with 129 additions and 16 deletions
|
@ -5567,3 +5567,61 @@ tic_t GetLag(INT32 node)
|
||||||
{
|
{
|
||||||
return gametic - nettics[node];
|
return gametic - nettics[node];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#define REWIND_POINT_INTERVAL 4*TICRATE + 16
|
||||||
|
rewind_t *rewindhead;
|
||||||
|
|
||||||
|
void CL_ClearRewinds(void)
|
||||||
|
{
|
||||||
|
rewind_t *head;
|
||||||
|
while ((head = rewindhead))
|
||||||
|
{
|
||||||
|
rewindhead = rewindhead->next;
|
||||||
|
free(head);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
rewind_t *CL_SaveRewindPoint(size_t demopos)
|
||||||
|
{
|
||||||
|
rewind_t *rewind;
|
||||||
|
|
||||||
|
if (rewindhead && rewindhead->leveltime + REWIND_POINT_INTERVAL > leveltime)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
rewind = (rewind_t *)malloc(sizeof (rewind_t));
|
||||||
|
if (!rewind)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
CONS_Printf("Saving rewind point for time %d\n", leveltime);
|
||||||
|
save_p = rewind->savebuffer;
|
||||||
|
P_SaveNetGame();
|
||||||
|
rewind->leveltime = leveltime;
|
||||||
|
rewind->next = rewindhead;
|
||||||
|
rewind->demopos = demopos;
|
||||||
|
rewindhead = rewind;
|
||||||
|
|
||||||
|
return rewind;
|
||||||
|
}
|
||||||
|
|
||||||
|
rewind_t *CL_RewindToTime(tic_t time)
|
||||||
|
{
|
||||||
|
rewind_t *rewind;
|
||||||
|
|
||||||
|
while (rewindhead && rewindhead->leveltime > time)
|
||||||
|
{
|
||||||
|
rewind = rewindhead->next;
|
||||||
|
free(rewindhead);
|
||||||
|
rewindhead = rewind;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!rewindhead)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
CONS_Printf("Restoring rewind to time %d for goal time %d\n", rewindhead->leveltime, time);
|
||||||
|
save_p = rewindhead->savebuffer;
|
||||||
|
P_LoadNetGame();
|
||||||
|
wipegamestate = gamestate; // No fading back in!
|
||||||
|
timeinmap = leveltime;
|
||||||
|
|
||||||
|
return rewindhead;
|
||||||
|
}
|
||||||
|
|
|
@ -604,4 +604,19 @@ UINT8 GetFreeXCmdSize(void);
|
||||||
|
|
||||||
extern UINT8 hu_resynching;
|
extern UINT8 hu_resynching;
|
||||||
extern UINT8 hu_stopped; // kart, true when the game is stopped for players due to a disconnecting or connecting player
|
extern UINT8 hu_stopped; // kart, true when the game is stopped for players due to a disconnecting or connecting player
|
||||||
|
|
||||||
|
typedef struct rewind_s {
|
||||||
|
UINT8 savebuffer[(768*1024)];
|
||||||
|
tic_t leveltime;
|
||||||
|
size_t demopos;
|
||||||
|
|
||||||
|
ticcmd_t oldcmd[MAXPLAYERS];
|
||||||
|
mobj_t oldghost[MAXPLAYERS];
|
||||||
|
|
||||||
|
struct rewind_s *next;
|
||||||
|
} rewind_t;
|
||||||
|
|
||||||
|
void CL_ClearRewinds(void);
|
||||||
|
rewind_t *CL_SaveRewindPoint(size_t demopos);
|
||||||
|
rewind_t *CL_RewindToTime(tic_t time);
|
||||||
#endif
|
#endif
|
||||||
|
|
39
src/g_game.c
39
src/g_game.c
|
@ -4867,6 +4867,16 @@ void G_ReadDemoExtraData(void)
|
||||||
INT32 p, extradata, i;
|
INT32 p, extradata, i;
|
||||||
char name[17];
|
char name[17];
|
||||||
|
|
||||||
|
if (leveltime > starttime)
|
||||||
|
{
|
||||||
|
rewind_t *rewind = CL_SaveRewindPoint(demo_p - demobuffer);
|
||||||
|
if (rewind)
|
||||||
|
{
|
||||||
|
memcpy(rewind->oldcmd, oldcmd, sizeof (oldcmd));
|
||||||
|
memcpy(rewind->oldghost, oldghost, sizeof (oldghost));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
memset(name, '\0', 17);
|
memset(name, '\0', 17);
|
||||||
|
|
||||||
p = READUINT8(demo_p);
|
p = READUINT8(demo_p);
|
||||||
|
@ -5905,6 +5915,8 @@ static rewindinfo_t *rewindhead = NULL; // Reverse chronological order
|
||||||
|
|
||||||
void G_InitDemoRewind(void)
|
void G_InitDemoRewind(void)
|
||||||
{
|
{
|
||||||
|
CL_ClearRewinds();
|
||||||
|
|
||||||
while (rewindhead)
|
while (rewindhead)
|
||||||
{
|
{
|
||||||
rewindinfo_t *p = rewindhead->prev;
|
rewindinfo_t *p = rewindhead->prev;
|
||||||
|
@ -6026,19 +6038,35 @@ void G_ConfirmRewind(tic_t rewindtime)
|
||||||
|
|
||||||
CV_StealthSetValue(&cv_renderview, 0);
|
CV_StealthSetValue(&cv_renderview, 0);
|
||||||
|
|
||||||
if (rewindtime > starttime)
|
if (rewindtime <= starttime)
|
||||||
{
|
{
|
||||||
sound_disabled = true; // Prevent sound spam
|
demo.rewinding = false;
|
||||||
demo.rewinding = true;
|
G_DoPlayDemo(NULL); // Restart the current demo
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
demo.rewinding = false;
|
{
|
||||||
|
rewind_t *rewind;
|
||||||
|
sound_disabled = true; // Prevent sound spam
|
||||||
|
demo.rewinding = true;
|
||||||
|
|
||||||
|
rewind = CL_RewindToTime(rewindtime);
|
||||||
|
|
||||||
|
if (rewind)
|
||||||
|
{
|
||||||
|
demo_p = demobuffer + rewind->demopos;
|
||||||
|
memcpy(oldcmd, rewind->oldcmd, sizeof (oldcmd));
|
||||||
|
memcpy(oldghost, rewind->oldghost, sizeof (oldghost));
|
||||||
|
paused = false;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
demo.rewinding = true;
|
||||||
G_DoPlayDemo(NULL); // Restart the current demo
|
G_DoPlayDemo(NULL); // Restart the current demo
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
for (j = 0; j < rewindtime && leveltime < rewindtime; j++)
|
for (j = 0; j < rewindtime && leveltime < rewindtime; j++)
|
||||||
{
|
{
|
||||||
//TryRunTics(1);
|
|
||||||
G_Ticker((j % NEWTICRATERATIO) == 0);
|
G_Ticker((j % NEWTICRATERATIO) == 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -8126,6 +8154,7 @@ void G_StopDemo(void)
|
||||||
|
|
||||||
CV_SetValue(&cv_playbackspeed, 1);
|
CV_SetValue(&cv_playbackspeed, 1);
|
||||||
demo.rewinding = false;
|
demo.rewinding = false;
|
||||||
|
CL_ClearRewinds();
|
||||||
|
|
||||||
if (gamestate == GS_LEVEL && rendermode != render_none)
|
if (gamestate == GS_LEVEL && rendermode != render_none)
|
||||||
{
|
{
|
||||||
|
|
31
src/m_menu.c
31
src/m_menu.c
|
@ -517,6 +517,7 @@ static menuitem_t MISC_ReplayOptionsMenu[] =
|
||||||
{IT_CVAR|IT_STRING, NULL, "Sync Check Interval", &cv_netdemosyncquality, 10},
|
{IT_CVAR|IT_STRING, NULL, "Sync Check Interval", &cv_netdemosyncquality, 10},
|
||||||
};
|
};
|
||||||
|
|
||||||
|
static tic_t playback_last_menu_interaction_leveltime = 0;
|
||||||
static menuitem_t PlaybackMenu[] =
|
static menuitem_t PlaybackMenu[] =
|
||||||
{
|
{
|
||||||
{IT_CALL | IT_STRING, "M_PHIDE", "Hide Menu (Esc)", M_SelectableClearMenus, 0},
|
{IT_CALL | IT_STRING, "M_PHIDE", "Hide Menu (Esc)", M_SelectableClearMenus, 0},
|
||||||
|
@ -2786,6 +2787,7 @@ boolean M_Responder(event_t *ev)
|
||||||
|
|
||||||
if (currentMenu == &PlaybackMenuDef)
|
if (currentMenu == &PlaybackMenuDef)
|
||||||
{
|
{
|
||||||
|
playback_last_menu_interaction_leveltime = leveltime;
|
||||||
// Flip left/right with up/down for the playback menu, since it's a horizontal icon row.
|
// Flip left/right with up/down for the playback menu, since it's a horizontal icon row.
|
||||||
switch (ch)
|
switch (ch)
|
||||||
{
|
{
|
||||||
|
@ -2897,9 +2899,9 @@ boolean M_Responder(event_t *ev)
|
||||||
if (currentMenu == &PlaybackMenuDef)
|
if (currentMenu == &PlaybackMenuDef)
|
||||||
{
|
{
|
||||||
boolean held = (boolean)playback_enterheld;
|
boolean held = (boolean)playback_enterheld;
|
||||||
playback_enterheld = TICRATE/7;
|
|
||||||
if (held)
|
if (held)
|
||||||
return true;
|
return true;
|
||||||
|
playback_enterheld = 3;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (routine)
|
if (routine)
|
||||||
|
@ -3159,6 +3161,7 @@ void M_StartControlPanel(void)
|
||||||
if (demo.playback)
|
if (demo.playback)
|
||||||
{
|
{
|
||||||
currentMenu = &PlaybackMenuDef;
|
currentMenu = &PlaybackMenuDef;
|
||||||
|
playback_last_menu_interaction_leveltime = leveltime;
|
||||||
}
|
}
|
||||||
else if (!Playing())
|
else if (!Playing())
|
||||||
{
|
{
|
||||||
|
@ -5331,6 +5334,7 @@ void M_ReplayHut(INT32 choice)
|
||||||
G_SetGamestate(GS_TIMEATTACK);
|
G_SetGamestate(GS_TIMEATTACK);
|
||||||
|
|
||||||
demo.rewinding = false;
|
demo.rewinding = false;
|
||||||
|
CL_ClearRewinds();
|
||||||
|
|
||||||
S_ChangeMusicInternal("replst", true);
|
S_ChangeMusicInternal("replst", true);
|
||||||
}
|
}
|
||||||
|
@ -5343,7 +5347,8 @@ static void M_HandleReplayHutList(INT32 choice)
|
||||||
if (dir_on[menudepthleft])
|
if (dir_on[menudepthleft])
|
||||||
dir_on[menudepthleft]--;
|
dir_on[menudepthleft]--;
|
||||||
else
|
else
|
||||||
M_PrevOpt();
|
return;
|
||||||
|
//M_PrevOpt();
|
||||||
|
|
||||||
S_StartSound(NULL, sfx_menu1);
|
S_StartSound(NULL, sfx_menu1);
|
||||||
replayScrollTitle = 0; replayScrollDelay = TICRATE; replayScrollDir = 1;
|
replayScrollTitle = 0; replayScrollDelay = TICRATE; replayScrollDir = 1;
|
||||||
|
@ -5353,7 +5358,8 @@ static void M_HandleReplayHutList(INT32 choice)
|
||||||
if (dir_on[menudepthleft] < sizedirmenu-1)
|
if (dir_on[menudepthleft] < sizedirmenu-1)
|
||||||
dir_on[menudepthleft]++;
|
dir_on[menudepthleft]++;
|
||||||
else
|
else
|
||||||
itemOn = 0; // Not M_NextOpt because that would take us to the extra dummy item
|
return;
|
||||||
|
//itemOn = 0; // Not M_NextOpt because that would take us to the extra dummy item
|
||||||
|
|
||||||
S_StartSound(NULL, sfx_menu1);
|
S_StartSound(NULL, sfx_menu1);
|
||||||
replayScrollTitle = 0; replayScrollDelay = TICRATE; replayScrollDir = 1;
|
replayScrollTitle = 0; replayScrollDelay = TICRATE; replayScrollDir = 1;
|
||||||
|
@ -5860,6 +5866,11 @@ static void M_DrawPlaybackMenu(void)
|
||||||
INT16 i;
|
INT16 i;
|
||||||
patch_t *icon;
|
patch_t *icon;
|
||||||
UINT8 *activemap = R_GetTranslationColormap(TC_RAINBOW, SKINCOLOR_GOLD, GTC_MENUCACHE);
|
UINT8 *activemap = R_GetTranslationColormap(TC_RAINBOW, SKINCOLOR_GOLD, GTC_MENUCACHE);
|
||||||
|
UINT32 transmap = max(0, (INT32)(leveltime - playback_last_menu_interaction_leveltime - 4*TICRATE)) / 5;
|
||||||
|
transmap = min(8, transmap) << V_ALPHASHIFT;
|
||||||
|
|
||||||
|
if (leveltime - playback_last_menu_interaction_leveltime >= 6*TICRATE)
|
||||||
|
playback_last_menu_interaction_leveltime = leveltime - 6*TICRATE;
|
||||||
|
|
||||||
// Toggle items
|
// Toggle items
|
||||||
if (paused && !demo.rewinding)
|
if (paused && !demo.rewinding)
|
||||||
|
@ -5935,16 +5946,16 @@ static void M_DrawPlaybackMenu(void)
|
||||||
icon = W_CachePatchName("PLAYRANK", PU_CACHE); // temp
|
icon = W_CachePatchName("PLAYRANK", PU_CACHE); // temp
|
||||||
|
|
||||||
if ((i == playback_fastforward && cv_playbackspeed.value > 1) || (i == playback_rewind && demo.rewinding))
|
if ((i == playback_fastforward && cv_playbackspeed.value > 1) || (i == playback_rewind && demo.rewinding))
|
||||||
V_DrawMappedPatch(currentMenu->x + currentMenu->menuitems[i].alphaKey, currentMenu->y, V_SNAPTOTOP, icon, R_GetTranslationColormap(TC_RAINBOW, SKINCOLOR_JAWZ, GTC_MENUCACHE));
|
V_DrawMappedPatch(currentMenu->x + currentMenu->menuitems[i].alphaKey, currentMenu->y, transmap|V_SNAPTOTOP, icon, R_GetTranslationColormap(TC_RAINBOW, SKINCOLOR_JAWZ, GTC_MENUCACHE));
|
||||||
else
|
else
|
||||||
V_DrawMappedPatch(currentMenu->x + currentMenu->menuitems[i].alphaKey, currentMenu->y, V_SNAPTOTOP, icon, (i == itemOn) ? activemap : inactivemap);
|
V_DrawMappedPatch(currentMenu->x + currentMenu->menuitems[i].alphaKey, currentMenu->y, transmap|V_SNAPTOTOP, icon, (i == itemOn) ? activemap : inactivemap);
|
||||||
|
|
||||||
if (i == itemOn)
|
if (i == itemOn)
|
||||||
{
|
{
|
||||||
V_DrawCharacter(currentMenu->x + currentMenu->menuitems[i].alphaKey + 4, currentMenu->y + 14,
|
V_DrawCharacter(currentMenu->x + currentMenu->menuitems[i].alphaKey + 4, currentMenu->y + 14,
|
||||||
'\x1A' | V_SNAPTOTOP|highlightflags, false);
|
'\x1A' | transmap|V_SNAPTOTOP|highlightflags, false);
|
||||||
|
|
||||||
V_DrawCenteredString(BASEVIDWIDTH/2, currentMenu->y + 18, V_SNAPTOTOP|V_ALLOWLOWERCASE, currentMenu->menuitems[i].text);
|
V_DrawCenteredString(BASEVIDWIDTH/2, currentMenu->y + 18, transmap|V_SNAPTOTOP|V_ALLOWLOWERCASE, currentMenu->menuitems[i].text);
|
||||||
|
|
||||||
if ((currentMenu->menuitems[i].status & IT_TYPE) == IT_ARROWS)
|
if ((currentMenu->menuitems[i].status & IT_TYPE) == IT_ARROWS)
|
||||||
{
|
{
|
||||||
|
@ -5952,11 +5963,11 @@ static void M_DrawPlaybackMenu(void)
|
||||||
|
|
||||||
if (!(i == playback_viewcount && splitscreen == 3))
|
if (!(i == playback_viewcount && splitscreen == 3))
|
||||||
V_DrawCharacter(BASEVIDWIDTH/2 - 4, currentMenu->y + 28 - (skullAnimCounter/5),
|
V_DrawCharacter(BASEVIDWIDTH/2 - 4, currentMenu->y + 28 - (skullAnimCounter/5),
|
||||||
'\x1A' | V_SNAPTOTOP|highlightflags, false); // up arrow
|
'\x1A' | transmap|V_SNAPTOTOP|highlightflags, false); // up arrow
|
||||||
|
|
||||||
if (!(i == playback_viewcount && splitscreen == 0))
|
if (!(i == playback_viewcount && splitscreen == 0))
|
||||||
V_DrawCharacter(BASEVIDWIDTH/2 - 4, currentMenu->y + 48 + (skullAnimCounter/5),
|
V_DrawCharacter(BASEVIDWIDTH/2 - 4, currentMenu->y + 48 + (skullAnimCounter/5),
|
||||||
'\x1B' | V_SNAPTOTOP|highlightflags, false); // down arrow
|
'\x1B' | transmap|V_SNAPTOTOP|highlightflags, false); // down arrow
|
||||||
|
|
||||||
switch (i)
|
switch (i)
|
||||||
{
|
{
|
||||||
|
@ -5975,7 +5986,7 @@ static void M_DrawPlaybackMenu(void)
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
V_DrawCenteredString(BASEVIDWIDTH/2, currentMenu->y + 38, V_SNAPTOTOP|V_ALLOWLOWERCASE|highlightflags, str);
|
V_DrawCenteredString(BASEVIDWIDTH/2, currentMenu->y + 38, transmap|V_SNAPTOTOP|V_ALLOWLOWERCASE|highlightflags, str);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue