Skip to content

Commit 097de30

Browse files
committed
changelog; add cfg to control deserializing replay checkpoints
1 parent 32dd839 commit 097de30

12 files changed

Lines changed: 60 additions & 2 deletions

CHANGES.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,11 @@
3131
- INPUT: Reset and close content hotkeys now require confirmation, similar to quit
3232
- INPUT/ANDROID: Favor mouse coordinates for lightgun
3333
- INPUT/UDEV: Fix lost terminal settings after restart from menu
34+
- INPUT/BSV/REPLAY: Bumped replay format version to 2. Old replays will still play back fine.
35+
- INPUT/BSV/REPLAY: Add option to skip deserializing checkpoints from replay files (it introduces jank in some emulators).
36+
- INPUT/BSV/REPLAY: Add checkpoint and initial savestate compression, following the `savestate_file_compression` config boolean. Use zstd if available, or fall back to zlib.
37+
- INPUT/BSV/REPLAY: Add incremental checkpoints based on statestreams (depending on `HAVE_STATESTREAM` compile time flag). As an example, 60 `pcsx_rearmed` savestates would take 267MB uncompressed; with incremental encoding this is reduced to 77MB. Compressing the result can reduce the size to just 4MB.
38+
- INPUT/BSV/REPLAY: Checkpoint compression and encoding can be combined. For example, 60 `pcsx_rearmed` checkpoints can take up just 15MB if each state is incremental and compressed. This is not as optimal as using incremental states without save state compression followed by offline compression, but is a good compromise in many use cases.
3439
- INTL: Add Irish Gaelic to selectable languages
3540
- IOS: Fix crash on iOS9 when fetching refresh rate
3641
- LINUX: Add full complement of key/value pairs to desktop entry

config.def.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1407,6 +1407,11 @@
14071407
/* Specifies how often checkpoints will be saved to replay files during recording.
14081408
* > Setting value to zero disables recording checkpoints. */
14091409
#define DEFAULT_REPLAY_CHECKPOINT_INTERVAL 0
1410+
/* Specifies whether checkpoints in replay files should be loaded
1411+
* during playback. This can be helpful for cores that are not
1412+
* deterministic but in some cores produces janky results depending on
1413+
* when inputs are processed. */
1414+
#define DEFAULT_REPLAY_CHECKPOINT_DESERIALIZE true
14101415

14111416
/* Automatically saves a savestate at the end of RetroArch's lifetime.
14121417
* The path is $SRAM_PATH.auto.

configuration.c

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2247,6 +2247,9 @@ static struct config_bool_setting *populate_settings_bool(
22472247
SETTING_BOOL("network_remote_enable", &settings->bools.network_remote_enable, false, false /* TODO */, false);
22482248
#endif
22492249
#endif
2250+
#ifdef HAVE_BSV_MOVIE
2251+
SETTING_BOOL("replay_checkpoint_deserialize", &settings->bools.replay_checkpoint_deserialize, true, DEFAULT_REPLAY_CHECKPOINT_DESERIALIZE, false);
2252+
#endif
22502253

22512254
#ifdef ANDROID
22522255
SETTING_BOOL("android_input_disconnect_workaround", &settings->bools.android_input_disconnect_workaround, true, false, false);

configuration.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1108,6 +1108,10 @@ typedef struct settings
11081108
bool ai_service_pause;
11091109

11101110
bool gamemode_enable;
1111+
#ifdef HAVE_BSV_MOVIE
1112+
bool replay_checkpoint_deserialize;
1113+
#endif
1114+
11111115
#ifdef _3DS
11121116
bool new3ds_speedup_enable;
11131117
bool bottom_font_enable;

input/bsv/bsvmovie.c

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -537,7 +537,7 @@ int64_t bsv_movie_write_checkpoint(bsv_movie_t *handle, uint8_t compression, uin
537537

538538
bool bsv_movie_read_next_events(bsv_movie_t *handle, bool skip_checkpoints)
539539
{
540-
input_driver_state_t *input_st = input_state_get_ptr();
540+
input_driver_state_t *input_st = input_state_get_ptr();
541541
/* Skip over backref */
542542
intfstream_seek(handle->file, sizeof(uint32_t), SEEK_CUR);
543543
/* Start by reading key event */
@@ -671,6 +671,7 @@ void bsv_movie_scan_from_start(input_driver_state_t *input_st, int32_t len)
671671
void bsv_movie_next_frame(input_driver_state_t *input_st)
672672
{
673673
unsigned checkpoint_interval = config_get_ptr()->uints.replay_checkpoint_interval;
674+
unsigned checkpoint_deserialize= config_get_ptr()->bools.replay_checkpoint_deserialize;
674675
/* if bsv_movie_state_next_handle is not null, deinit and set
675676
bsv_movie_state_handle to bsv_movie_state_next_handle and clear
676677
next_handle */
@@ -747,7 +748,7 @@ void bsv_movie_next_frame(input_driver_state_t *input_st)
747748
}
748749

749750
if (input_st->bsv_movie_state.flags & BSV_FLAG_MOVIE_PLAYBACK)
750-
bsv_movie_read_next_events(handle, false);
751+
bsv_movie_read_next_events(handle, !checkpoint_deserialize);
751752
handle->frame_pos[handle->frame_counter & handle->frame_mask] = intfstream_tell(handle->file);
752753
}
753754

intl/msg_hash_lbl.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -402,6 +402,10 @@ MSG_HASH(
402402
MENU_ENUM_LABEL_REPLAY_CHECKPOINT_INTERVAL,
403403
"replay_checkpoint_interval"
404404
)
405+
MSG_HASH(
406+
MENU_ENUM_LABEL_REPLAY_CHECKPOINT_DESERIALIZE,
407+
"replay_checkpoint_deserialize"
408+
)
405409
MSG_HASH(
406410
MENU_ENUM_LABEL_AUTO_OVERRIDES_ENABLE,
407411
"auto_overrides_enable"

intl/msg_hash_us.c

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -310,6 +310,9 @@ int msg_hash_get_help_us_enum(enum msg_hash_enums msg, char *s, size_t len)
310310
case MENU_ENUM_LABEL_REPLAY_CHECKPOINT_INTERVAL:
311311
strlcpy(s, msg_hash_to_str(MENU_ENUM_LABEL_HELP_REPLAY_CHECKPOINT_INTERVAL), len);
312312
break;
313+
case MENU_ENUM_LABEL_REPLAY_CHECKPOINT_DESERIALIZE:
314+
strlcpy(s, msg_hash_to_str(MENU_ENUM_LABEL_HELP_REPLAY_CHECKPOINT_DESERIALIZE), len);
315+
break;
313316
case MENU_ENUM_LABEL_VALUE_INPUT_ADC_TYPE:
314317
strlcpy(s, msg_hash_to_str(MENU_ENUM_LABEL_HELP_INPUT_ADC_TYPE), len);
315318
break;

intl/msg_hash_us.h

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4819,6 +4819,18 @@ MSG_HASH(
48194819
MENU_ENUM_LABEL_HELP_REPLAY_CHECKPOINT_INTERVAL,
48204820
"Autosaves the game state during replay recording at a regular interval. This is disabled by default unless set otherwise. The interval is measured in seconds. A value of 0 disables checkpoint recording."
48214821
)
4822+
MSG_HASH(
4823+
MENU_ENUM_SUBLABEL_REPLAY_CHECKPOINT_DESERIALIZE,
4824+
"Whether to deserialize checkpoints stored in replays during regular playback."
4825+
)
4826+
MSG_HASH(
4827+
MENU_ENUM_LABEL_VALUE_REPLAY_CHECKPOINT_DESERIALIZE,
4828+
"Replay Checkpoint Deserialize"
4829+
)
4830+
MSG_HASH(
4831+
MENU_ENUM_LABEL_HELP_REPLAY_CHECKPOINT_DESERIALIZE,
4832+
"Whether to deserialize checkpoints stored in replays during regular playback. Should be set to true for most cores, but some may exhibit janky behavior when deserializing content."
4833+
)
48224834
MSG_HASH(
48234835
MENU_ENUM_LABEL_VALUE_SAVESTATE_AUTO_INDEX,
48244836
"Increment Save State Index Automatically"

menu/cbs/menu_cbs_sublabel.c

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -814,6 +814,7 @@ DEFAULT_SUBLABEL_MACRO(action_bind_sublabel_savestate_max_keep, MENU_
814814
DEFAULT_SUBLABEL_MACRO(action_bind_sublabel_autosave_interval, MENU_ENUM_SUBLABEL_AUTOSAVE_INTERVAL)
815815
DEFAULT_SUBLABEL_MACRO(action_bind_sublabel_replay_max_keep, MENU_ENUM_SUBLABEL_REPLAY_MAX_KEEP)
816816
DEFAULT_SUBLABEL_MACRO(action_bind_sublabel_replay_checkpoint_interval, MENU_ENUM_SUBLABEL_REPLAY_CHECKPOINT_INTERVAL)
817+
DEFAULT_SUBLABEL_MACRO(action_bind_sublabel_replay_checkpoint_deserialize, MENU_ENUM_SUBLABEL_REPLAY_CHECKPOINT_DESERIALIZE)
817818
DEFAULT_SUBLABEL_MACRO(action_bind_sublabel_input_remap_binds_enable, MENU_ENUM_SUBLABEL_INPUT_REMAP_BINDS_ENABLE)
818819
DEFAULT_SUBLABEL_MACRO(action_bind_sublabel_input_remap_sort_by_controller_enable, MENU_ENUM_SUBLABEL_INPUT_REMAP_SORT_BY_CONTROLLER_ENABLE)
819820
DEFAULT_SUBLABEL_MACRO(action_bind_sublabel_input_autodetect_enable, MENU_ENUM_SUBLABEL_INPUT_AUTODETECT_ENABLE)
@@ -4125,6 +4126,9 @@ int menu_cbs_init_bind_sublabel(menu_file_list_cbs_t *cbs,
41254126
case MENU_ENUM_LABEL_REPLAY_CHECKPOINT_INTERVAL:
41264127
BIND_ACTION_SUBLABEL(cbs, action_bind_sublabel_replay_checkpoint_interval);
41274128
break;
4129+
case MENU_ENUM_LABEL_REPLAY_CHECKPOINT_DESERIALIZE:
4130+
BIND_ACTION_SUBLABEL(cbs, action_bind_sublabel_replay_checkpoint_deserialize);
4131+
break;
41284132
case MENU_ENUM_LABEL_SAVESTATE_MAX_KEEP:
41294133
BIND_ACTION_SUBLABEL(cbs, action_bind_sublabel_savestate_max_keep);
41304134
break;

menu/menu_displaylist.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10995,6 +10995,7 @@ unsigned menu_displaylist_build_list(
1099510995
{MENU_ENUM_LABEL_REPLAY_AUTO_INDEX, PARSE_ONLY_BOOL, true},
1099610996
{MENU_ENUM_LABEL_REPLAY_MAX_KEEP, PARSE_ONLY_UINT, false},
1099710997
{MENU_ENUM_LABEL_REPLAY_CHECKPOINT_INTERVAL, PARSE_ONLY_UINT, true},
10998+
{MENU_ENUM_LABEL_REPLAY_CHECKPOINT_DESERIALIZE, PARSE_ONLY_BOOL, true},
1099810999
{MENU_ENUM_LABEL_CONTENT_RUNTIME_LOG, PARSE_ONLY_BOOL, true},
1099911000
{MENU_ENUM_LABEL_CONTENT_RUNTIME_LOG_AGGREGATE, PARSE_ONLY_BOOL, true},
1100011001
#if HAVE_CLOUDSYNC

0 commit comments

Comments
 (0)