mirror of
https://github.com/libretro/RetroArch.git
synced 2024-06-02 19:57:24 -04:00
Replay rewind fix (#15079)
* Rewind during recording isn't visibly busted anymore but it doesn't rewind the replay properly during playback or record, inputs get clobbered; check frame pos/ptr stuff. * Fix rewinding during movie recording and playback?
This commit is contained in:
parent
666fbdcb38
commit
be5b198692
|
@ -66,8 +66,11 @@ bool content_ram_state_pending(void);
|
|||
/* Gets the number of bytes required to serialize the state. */
|
||||
size_t content_get_serialized_size(void);
|
||||
|
||||
/* Serializes the current state. buffer must be at least content_get_serialized_size bytes */
|
||||
bool content_serialize_state(void* buffer, size_t buffer_size);
|
||||
/* Gets the number of bytes required to serialize the state for rewind. */
|
||||
size_t content_get_serialized_size_rewind(void);
|
||||
|
||||
/* Serializes the current state for rewinding. buffer must be at least content_get_serialized_size bytes */
|
||||
bool content_serialize_state_rewind(void* buffer, size_t buffer_size);
|
||||
|
||||
/* Deserializes the current state. */
|
||||
bool content_deserialize_state(const void* serialized_data, size_t serialized_size);
|
||||
|
|
|
@ -4789,7 +4789,8 @@ void bsv_movie_next_frame(input_driver_state_t *input_st)
|
|||
bsv_movie_t *handle = input_st->bsv_movie_state_handle;
|
||||
if (!handle)
|
||||
return;
|
||||
handle->frame_pos[handle->frame_ptr] = intfstream_tell(handle->file);
|
||||
if (state_manager_frame_is_reversed())
|
||||
return;
|
||||
if (input_st->bsv_movie_state.flags & BSV_FLAG_MOVIE_RECORDING)
|
||||
{
|
||||
int i;
|
||||
|
@ -4901,6 +4902,7 @@ void bsv_movie_next_frame(input_driver_state_t *input_st)
|
|||
}
|
||||
}
|
||||
}
|
||||
handle->frame_pos[handle->frame_ptr] = intfstream_tell(handle->file);
|
||||
}
|
||||
size_t replay_get_serialize_size(void)
|
||||
{
|
||||
|
|
|
@ -515,8 +515,10 @@ static void state_manager_push_do(state_manager_t *state)
|
|||
const uint8_t *oldb, *newb;
|
||||
uint8_t *compressed;
|
||||
size_t headpos, tailpos, remaining;
|
||||
if (state->capacity < sizeof(size_t) + state->maxcompsize)
|
||||
if (state->capacity < sizeof(size_t) + state->maxcompsize) {
|
||||
RARCH_ERR("State capacity insufficient\n");
|
||||
return;
|
||||
}
|
||||
|
||||
recheckcapacity:;
|
||||
headpos = state->head - state->data;
|
||||
|
@ -617,7 +619,7 @@ void state_manager_event_init(
|
|||
return;
|
||||
}
|
||||
|
||||
rewind_st->size = content_get_serialized_size();
|
||||
rewind_st->size = content_get_serialized_size_rewind();
|
||||
|
||||
if (!rewind_st->size)
|
||||
{
|
||||
|
@ -638,7 +640,7 @@ void state_manager_event_init(
|
|||
|
||||
state_manager_push_where(rewind_st->state, &state);
|
||||
|
||||
content_serialize_state(state, rewind_st->size);
|
||||
content_serialize_state_rewind(state, rewind_st->size);
|
||||
|
||||
state_manager_push_do(rewind_st->state);
|
||||
}
|
||||
|
@ -800,10 +802,9 @@ bool state_manager_check_rewind(
|
|||
&& ((cnt == 0) || retroarch_ctl(RARCH_CTL_BSV_MOVIE_IS_INITED, NULL)))
|
||||
{
|
||||
void *state = NULL;
|
||||
|
||||
state_manager_push_where(rewind_st->state, &state);
|
||||
|
||||
content_serialize_state(state, rewind_st->size);
|
||||
content_serialize_state_rewind(state, rewind_st->size);
|
||||
|
||||
state_manager_push_do(rewind_st->state);
|
||||
}
|
||||
|
|
|
@ -620,7 +620,7 @@ static void task_save_handler_finished(retro_task_t *task,
|
|||
/* Align to 8-byte boundary */
|
||||
#define CONTENT_ALIGN_SIZE(size) ((((size) + 7) & ~7))
|
||||
|
||||
static size_t content_get_rastate_size(rastate_size_info_t* size)
|
||||
static size_t content_get_rastate_size(rastate_size_info_t* size, bool rewind)
|
||||
{
|
||||
retro_ctx_size_info_t info;
|
||||
core_serialize_size(&info);
|
||||
|
@ -632,12 +632,18 @@ static size_t content_get_rastate_size(rastate_size_info_t* size)
|
|||
#ifdef HAVE_CHEEVOS
|
||||
/* 8-byte block header + content */
|
||||
if ((size->cheevos_size = rcheevos_get_serialize_size()) > 0)
|
||||
size->total_size += 8 + CONTENT_ALIGN_SIZE(size->cheevos_size);
|
||||
size->total_size += 8 + CONTENT_ALIGN_SIZE(size->cheevos_size);
|
||||
#endif
|
||||
#ifdef HAVE_BSV_MOVIE
|
||||
/* 8-byte block header + content */
|
||||
if ((size->replay_size = replay_get_serialize_size()) > 0)
|
||||
size->total_size += 8 + CONTENT_ALIGN_SIZE(size->replay_size);
|
||||
if(!rewind)
|
||||
{
|
||||
size->replay_size = replay_get_serialize_size();
|
||||
if(size->replay_size > 0)
|
||||
size->total_size += 8 + CONTENT_ALIGN_SIZE(size->replay_size);
|
||||
}
|
||||
else
|
||||
size->replay_size = 0;
|
||||
#endif
|
||||
return size->total_size;
|
||||
}
|
||||
|
@ -645,7 +651,12 @@ static size_t content_get_rastate_size(rastate_size_info_t* size)
|
|||
size_t content_get_serialized_size(void)
|
||||
{
|
||||
rastate_size_info_t size;
|
||||
return content_get_rastate_size(&size);
|
||||
return content_get_rastate_size(&size, false);
|
||||
}
|
||||
size_t content_get_serialized_size_rewind(void)
|
||||
{
|
||||
rastate_size_info_t size;
|
||||
return content_get_rastate_size(&size, true);
|
||||
}
|
||||
|
||||
static void content_write_block_header(unsigned char* output, const char* header, size_t size)
|
||||
|
@ -658,7 +669,8 @@ static void content_write_block_header(unsigned char* output, const char* header
|
|||
}
|
||||
|
||||
static bool content_write_serialized_state(void* buffer,
|
||||
rastate_size_info_t* size)
|
||||
rastate_size_info_t* size,
|
||||
bool rewind)
|
||||
{
|
||||
retro_ctx_serialize_info_t serial_info;
|
||||
unsigned char* output = (unsigned char*)buffer;
|
||||
|
@ -673,7 +685,7 @@ static bool content_write_serialized_state(void* buffer,
|
|||
#ifdef HAVE_BSV_MOVIE
|
||||
{
|
||||
input_driver_state_t *input_st = input_state_get_ptr();
|
||||
if (input_st->bsv_movie_state.flags & (BSV_FLAG_MOVIE_RECORDING | BSV_FLAG_MOVIE_PLAYBACK))
|
||||
if (!rewind && input_st->bsv_movie_state.flags & (BSV_FLAG_MOVIE_RECORDING | BSV_FLAG_MOVIE_PLAYBACK) && !state_manager_frame_is_reversed())
|
||||
{
|
||||
content_write_block_header(output,
|
||||
RASTATE_REPLAY_BLOCK, size->replay_size);
|
||||
|
@ -710,13 +722,13 @@ static bool content_write_serialized_state(void* buffer,
|
|||
return true;
|
||||
}
|
||||
|
||||
bool content_serialize_state(void* buffer, size_t buffer_size)
|
||||
bool content_serialize_state_rewind(void* buffer, size_t buffer_size)
|
||||
{
|
||||
rastate_size_info_t size;
|
||||
size_t len = content_get_rastate_size(&size);
|
||||
size_t len = content_get_rastate_size(&size, true);
|
||||
if (len == 0 || len > buffer_size)
|
||||
return false;
|
||||
return content_write_serialized_state(buffer, &size);
|
||||
return content_write_serialized_state(buffer, &size, true);
|
||||
}
|
||||
|
||||
static void *content_get_serialized_data(size_t* serial_size)
|
||||
|
@ -724,7 +736,7 @@ static void *content_get_serialized_data(size_t* serial_size)
|
|||
size_t len;
|
||||
void* data;
|
||||
rastate_size_info_t size;
|
||||
if ((len = content_get_rastate_size(&size)) == 0)
|
||||
if ((len = content_get_rastate_size(&size, false)) == 0)
|
||||
return NULL;
|
||||
|
||||
/* Ensure buffer is initialised to zero
|
||||
|
@ -735,7 +747,7 @@ static void *content_get_serialized_data(size_t* serial_size)
|
|||
if (!(data = calloc(len, 1)))
|
||||
return NULL;
|
||||
|
||||
if (!content_write_serialized_state(data, &size))
|
||||
if (!content_write_serialized_state(data, &size, false))
|
||||
{
|
||||
free(data);
|
||||
return NULL;
|
||||
|
@ -1116,13 +1128,13 @@ static bool content_load_rastate1(unsigned char* input, size_t size)
|
|||
#ifdef HAVE_BSV_MOVIE
|
||||
{
|
||||
input_driver_state_t *input_st = input_state_get_ptr();
|
||||
if (BSV_MOVIE_IS_RECORDING() && !seen_replay)
|
||||
if (BSV_MOVIE_IS_RECORDING() && !seen_replay && !state_manager_frame_is_reversed())
|
||||
{
|
||||
/* TODO OSD message */
|
||||
RARCH_ERR("[Replay] Can't load state without replay data during recording.\n");
|
||||
return false;
|
||||
}
|
||||
if (BSV_MOVIE_IS_PLAYBACK_ON() && !seen_replay)
|
||||
if (BSV_MOVIE_IS_PLAYBACK_ON() && !seen_replay && !state_manager_frame_is_reversed())
|
||||
{
|
||||
/* TODO OSD message */
|
||||
RARCH_WARN("[Replay] Loading state without replay data during replay will cancel replay.\n");
|
||||
|
@ -1145,7 +1157,8 @@ static bool content_load_rastate1(unsigned char* input, size_t size)
|
|||
#ifdef HAVE_BSV_MOVIE
|
||||
else if (memcmp(marker, RASTATE_REPLAY_BLOCK, 4) == 0)
|
||||
{
|
||||
if (replay_set_serialized_data((void*)input))
|
||||
input_driver_state_t *input_st = input_state_get_ptr();
|
||||
if (state_manager_frame_is_reversed() || replay_set_serialized_data((void*)input))
|
||||
seen_replay = true;
|
||||
else
|
||||
return false;
|
||||
|
@ -1167,7 +1180,7 @@ static bool content_load_rastate1(unsigned char* input, size_t size)
|
|||
rcheevos_set_serialized_data(NULL);
|
||||
#endif
|
||||
#ifdef HAVE_BSV_MOVIE
|
||||
if (!seen_replay)
|
||||
if (!seen_replay && !state_manager_frame_is_reversed())
|
||||
replay_set_serialized_data(NULL);
|
||||
#endif
|
||||
|
||||
|
@ -1190,7 +1203,8 @@ bool content_deserialize_state(
|
|||
rcheevos_set_serialized_data(NULL);
|
||||
#endif
|
||||
#ifdef HAVE_BSV_MOVIE
|
||||
replay_set_serialized_data(NULL);
|
||||
if(!state_manager_frame_is_reversed())
|
||||
replay_set_serialized_data(NULL);
|
||||
#endif
|
||||
}
|
||||
else
|
||||
|
|
Loading…
Reference in a new issue