mirror of
https://git.do.srb2.org/KartKrew/Kart-Public.git
synced 2024-12-26 12:21:19 +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];
|
||||
}
|
||||
|
||||
#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_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
|
||||
|
|
39
src/g_game.c
39
src/g_game.c
|
@ -4867,6 +4867,16 @@ void G_ReadDemoExtraData(void)
|
|||
INT32 p, extradata, i;
|
||||
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);
|
||||
|
||||
p = READUINT8(demo_p);
|
||||
|
@ -5905,6 +5915,8 @@ static rewindinfo_t *rewindhead = NULL; // Reverse chronological order
|
|||
|
||||
void G_InitDemoRewind(void)
|
||||
{
|
||||
CL_ClearRewinds();
|
||||
|
||||
while (rewindhead)
|
||||
{
|
||||
rewindinfo_t *p = rewindhead->prev;
|
||||
|
@ -6026,19 +6038,35 @@ void G_ConfirmRewind(tic_t rewindtime)
|
|||
|
||||
CV_StealthSetValue(&cv_renderview, 0);
|
||||
|
||||
if (rewindtime > starttime)
|
||||
if (rewindtime <= starttime)
|
||||
{
|
||||
sound_disabled = true; // Prevent sound spam
|
||||
demo.rewinding = true;
|
||||
demo.rewinding = false;
|
||||
G_DoPlayDemo(NULL); // Restart the current demo
|
||||
}
|
||||
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
|
||||
}
|
||||
}
|
||||
|
||||
for (j = 0; j < rewindtime && leveltime < rewindtime; j++)
|
||||
{
|
||||
//TryRunTics(1);
|
||||
G_Ticker((j % NEWTICRATERATIO) == 0);
|
||||
}
|
||||
|
||||
|
@ -8126,6 +8154,7 @@ void G_StopDemo(void)
|
|||
|
||||
CV_SetValue(&cv_playbackspeed, 1);
|
||||
demo.rewinding = false;
|
||||
CL_ClearRewinds();
|
||||
|
||||
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},
|
||||
};
|
||||
|
||||
static tic_t playback_last_menu_interaction_leveltime = 0;
|
||||
static menuitem_t PlaybackMenu[] =
|
||||
{
|
||||
{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)
|
||||
{
|
||||
playback_last_menu_interaction_leveltime = leveltime;
|
||||
// Flip left/right with up/down for the playback menu, since it's a horizontal icon row.
|
||||
switch (ch)
|
||||
{
|
||||
|
@ -2897,9 +2899,9 @@ boolean M_Responder(event_t *ev)
|
|||
if (currentMenu == &PlaybackMenuDef)
|
||||
{
|
||||
boolean held = (boolean)playback_enterheld;
|
||||
playback_enterheld = TICRATE/7;
|
||||
if (held)
|
||||
return true;
|
||||
playback_enterheld = 3;
|
||||
}
|
||||
|
||||
if (routine)
|
||||
|
@ -3159,6 +3161,7 @@ void M_StartControlPanel(void)
|
|||
if (demo.playback)
|
||||
{
|
||||
currentMenu = &PlaybackMenuDef;
|
||||
playback_last_menu_interaction_leveltime = leveltime;
|
||||
}
|
||||
else if (!Playing())
|
||||
{
|
||||
|
@ -5331,6 +5334,7 @@ void M_ReplayHut(INT32 choice)
|
|||
G_SetGamestate(GS_TIMEATTACK);
|
||||
|
||||
demo.rewinding = false;
|
||||
CL_ClearRewinds();
|
||||
|
||||
S_ChangeMusicInternal("replst", true);
|
||||
}
|
||||
|
@ -5343,7 +5347,8 @@ static void M_HandleReplayHutList(INT32 choice)
|
|||
if (dir_on[menudepthleft])
|
||||
dir_on[menudepthleft]--;
|
||||
else
|
||||
M_PrevOpt();
|
||||
return;
|
||||
//M_PrevOpt();
|
||||
|
||||
S_StartSound(NULL, sfx_menu1);
|
||||
replayScrollTitle = 0; replayScrollDelay = TICRATE; replayScrollDir = 1;
|
||||
|
@ -5353,7 +5358,8 @@ static void M_HandleReplayHutList(INT32 choice)
|
|||
if (dir_on[menudepthleft] < sizedirmenu-1)
|
||||
dir_on[menudepthleft]++;
|
||||
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);
|
||||
replayScrollTitle = 0; replayScrollDelay = TICRATE; replayScrollDir = 1;
|
||||
|
@ -5860,6 +5866,11 @@ static void M_DrawPlaybackMenu(void)
|
|||
INT16 i;
|
||||
patch_t *icon;
|
||||
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
|
||||
if (paused && !demo.rewinding)
|
||||
|
@ -5935,16 +5946,16 @@ static void M_DrawPlaybackMenu(void)
|
|||
icon = W_CachePatchName("PLAYRANK", PU_CACHE); // temp
|
||||
|
||||
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
|
||||
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)
|
||||
{
|
||||
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)
|
||||
{
|
||||
|
@ -5952,11 +5963,11 @@ static void M_DrawPlaybackMenu(void)
|
|||
|
||||
if (!(i == playback_viewcount && splitscreen == 3))
|
||||
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))
|
||||
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)
|
||||
{
|
||||
|
@ -5975,7 +5986,7 @@ static void M_DrawPlaybackMenu(void)
|
|||
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