Skip to content

Commit

Permalink
Rewind improvements (#91)
Browse files Browse the repository at this point in the history
* Prevent immediate deletion of restored key frames

Now, key frames will only be deleted if the user rewinds within less than 0.6 seconds (21 tics, give or take one tic) since the last rewind.

* Fix off-by-one error in countdown

There was one extra tic between key-frame saves, so they would be saved at e.g. 0:00.06, 0:01.09, 0:02.11 and so on.

* Keep key-framing time aligned

Now, key frames should always be saved at .06 seconds, regardless of level changes, save loads, and interval changes.

* Update documentation
  • Loading branch information
MrAlaux committed Apr 20, 2024
1 parent 5a23a99 commit a378582
Show file tree
Hide file tree
Showing 4 changed files with 37 additions and 20 deletions.
3 changes: 3 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,9 @@

## Changes

- **Rewind improvements:**
- Only delete key frames when rewinding within less than 0.6 seconds since the last rewind
- "Aligned" key-framing time
- **Support for _Milestone Completion Announcements_ in multiplayer**

## Bug Fixes
Expand Down
50 changes: 32 additions & 18 deletions src/g_game.c
Original file line number Diff line number Diff line change
Expand Up @@ -1058,6 +1058,9 @@ static void G_DoLoadLevel(void)

// [Nugget] ----------------------------------------------------------------

// Rewind
G_SetRewindCountdown(0);

// Minimap
if (minimap_was_on) {
AM_ChangeMode(AM_MINI);
Expand Down Expand Up @@ -2665,6 +2668,12 @@ static void G_DoLoadGame(void)
st_health = players[displayplayer].health;
st_armor = players[displayplayer].armorpoints;

// [Nugget] Rewind:
// Just like with `G_DoRewind`,
// this is called before the countdown decrement in `G_Ticker()`,
// so add 1 to keep it aligned
G_SetRewindCountdown(((rewind_interval * TICRATE) + 1) - ((leveltime - 1) % (rewind_interval * TICRATE)));

if (setsizeneeded)
R_ExecuteSetViewSize();

Expand Down Expand Up @@ -2697,9 +2706,9 @@ static void G_DoLoadGame(void)

// [Nugget] Rewind /----------------------------------------------------------

void G_ResetRewindCountdown(void)
void G_SetRewindCountdown(int value)
{
rewind_countdown = rewind_interval * TICRATE;
rewind_countdown = value;
}

static void G_SaveKeyFrame(void)
Expand Down Expand Up @@ -2814,14 +2823,30 @@ static void G_SaveKeyFrame(void)
rewind_on = false;
}

G_ResetRewindCountdown();
G_SetRewindCountdown(rewind_interval * TICRATE);

Z_Free(savebuffer);
savebuffer = save_p = NULL;
}

static void G_DoRewind(void)
{
static int last_rewind_time = 0;

if ((0 <= keyframe_index - 1)
&& (gametic - last_rewind_time <= 21)) // 0.6 seconds
{
keyframe_index--;

Z_Free(keyframe_list_tail->frame);

keyframe_list_tail = keyframe_list_tail->prev;
Z_Free(keyframe_list_tail->next);
keyframe_list_tail->next = NULL;
}

last_rewind_time = gametic;

int length, i;

I_SetFastdemoTimer(false);
Expand Down Expand Up @@ -2944,18 +2969,9 @@ static void G_DoRewind(void)

displaymsg("Restored key frame %i", keyframe_index);

if (0 <= keyframe_index - 1)
{
keyframe_index--;

Z_Free(savebuffer);

keyframe_list_tail = keyframe_list_tail->prev;
Z_Free(keyframe_list_tail->next);
keyframe_list_tail->next = NULL;
}

G_ResetRewindCountdown();
// This is called before the countdown decrement in `G_Ticker()`,
// so add 1 to keep it aligned
G_SetRewindCountdown((rewind_interval * TICRATE) + 1);
}

void G_EnableRewind(void)
Expand Down Expand Up @@ -3102,10 +3118,8 @@ void G_Ticker(void)
&& gamestate == GS_LEVEL && oldleveltime < leveltime
&& players[consoleplayer].playerstate != PST_DEAD)
{
if (!rewind_countdown)
if (--rewind_countdown <= 0)
{ G_SaveKeyFrame(); }
else
{ rewind_countdown--; }
}
else if (!CASUALPLAY(rewind_depth) || gamestate != GS_LEVEL)
{
Expand Down
2 changes: 1 addition & 1 deletion src/g_game.h
Original file line number Diff line number Diff line change
Expand Up @@ -114,7 +114,7 @@ extern int cpars[]; // hardcoded array size

// [Nugget] Rewind -----------------------------------------------------------

extern void G_ResetRewindCountdown(void);
extern void G_SetRewindCountdown(int value);
extern void G_EnableRewind(void);
extern void G_Rewind(void);
extern void G_ClearExcessKeyFrames(void);
Expand Down
2 changes: 1 addition & 1 deletion src/mn_setup.c
Original file line number Diff line number Diff line change
Expand Up @@ -2733,7 +2733,7 @@ setup_menu_t gen_settings8[] = {
static void UpdateRewindInterval(void)
{
G_EnableRewind();
G_ResetRewindCountdown();
G_SetRewindCountdown((rewind_interval * TICRATE) - ((leveltime - 1) % (rewind_interval * TICRATE)));
}

static void UpdateRewindDepth(void)
Expand Down

0 comments on commit a378582

Please sign in to comment.