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. */
|
/* Gets the number of bytes required to serialize the state. */
|
||||||
size_t content_get_serialized_size(void);
|
size_t content_get_serialized_size(void);
|
||||||
|
|
||||||
/* Serializes the current state. buffer must be at least content_get_serialized_size bytes */
|
/* Gets the number of bytes required to serialize the state for rewind. */
|
||||||
bool content_serialize_state(void* buffer, size_t buffer_size);
|
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. */
|
/* Deserializes the current state. */
|
||||||
bool content_deserialize_state(const void* serialized_data, size_t serialized_size);
|
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;
|
bsv_movie_t *handle = input_st->bsv_movie_state_handle;
|
||||||
if (!handle)
|
if (!handle)
|
||||||
return;
|
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)
|
if (input_st->bsv_movie_state.flags & BSV_FLAG_MOVIE_RECORDING)
|
||||||
{
|
{
|
||||||
int i;
|
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)
|
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;
|
const uint8_t *oldb, *newb;
|
||||||
uint8_t *compressed;
|
uint8_t *compressed;
|
||||||
size_t headpos, tailpos, remaining;
|
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;
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
recheckcapacity:;
|
recheckcapacity:;
|
||||||
headpos = state->head - state->data;
|
headpos = state->head - state->data;
|
||||||
|
@ -617,7 +619,7 @@ void state_manager_event_init(
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
rewind_st->size = content_get_serialized_size();
|
rewind_st->size = content_get_serialized_size_rewind();
|
||||||
|
|
||||||
if (!rewind_st->size)
|
if (!rewind_st->size)
|
||||||
{
|
{
|
||||||
|
@ -638,7 +640,7 @@ void state_manager_event_init(
|
||||||
|
|
||||||
state_manager_push_where(rewind_st->state, &state);
|
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);
|
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)))
|
&& ((cnt == 0) || retroarch_ctl(RARCH_CTL_BSV_MOVIE_IS_INITED, NULL)))
|
||||||
{
|
{
|
||||||
void *state = NULL;
|
void *state = NULL;
|
||||||
|
|
||||||
state_manager_push_where(rewind_st->state, &state);
|
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);
|
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 */
|
/* Align to 8-byte boundary */
|
||||||
#define CONTENT_ALIGN_SIZE(size) ((((size) + 7) & ~7))
|
#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;
|
retro_ctx_size_info_t info;
|
||||||
core_serialize_size(&info);
|
core_serialize_size(&info);
|
||||||
|
@ -632,12 +632,18 @@ static size_t content_get_rastate_size(rastate_size_info_t* size)
|
||||||
#ifdef HAVE_CHEEVOS
|
#ifdef HAVE_CHEEVOS
|
||||||
/* 8-byte block header + content */
|
/* 8-byte block header + content */
|
||||||
if ((size->cheevos_size = rcheevos_get_serialize_size()) > 0)
|
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
|
#endif
|
||||||
#ifdef HAVE_BSV_MOVIE
|
#ifdef HAVE_BSV_MOVIE
|
||||||
/* 8-byte block header + content */
|
/* 8-byte block header + content */
|
||||||
if ((size->replay_size = replay_get_serialize_size()) > 0)
|
if(!rewind)
|
||||||
size->total_size += 8 + CONTENT_ALIGN_SIZE(size->replay_size);
|
{
|
||||||
|
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
|
#endif
|
||||||
return size->total_size;
|
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)
|
size_t content_get_serialized_size(void)
|
||||||
{
|
{
|
||||||
rastate_size_info_t size;
|
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)
|
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,
|
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;
|
retro_ctx_serialize_info_t serial_info;
|
||||||
unsigned char* output = (unsigned char*)buffer;
|
unsigned char* output = (unsigned char*)buffer;
|
||||||
|
@ -673,7 +685,7 @@ static bool content_write_serialized_state(void* buffer,
|
||||||
#ifdef HAVE_BSV_MOVIE
|
#ifdef HAVE_BSV_MOVIE
|
||||||
{
|
{
|
||||||
input_driver_state_t *input_st = input_state_get_ptr();
|
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,
|
content_write_block_header(output,
|
||||||
RASTATE_REPLAY_BLOCK, size->replay_size);
|
RASTATE_REPLAY_BLOCK, size->replay_size);
|
||||||
|
@ -710,13 +722,13 @@ static bool content_write_serialized_state(void* buffer,
|
||||||
return true;
|
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;
|
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)
|
if (len == 0 || len > buffer_size)
|
||||||
return false;
|
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)
|
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;
|
size_t len;
|
||||||
void* data;
|
void* data;
|
||||||
rastate_size_info_t size;
|
rastate_size_info_t size;
|
||||||
if ((len = content_get_rastate_size(&size)) == 0)
|
if ((len = content_get_rastate_size(&size, false)) == 0)
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
/* Ensure buffer is initialised to zero
|
/* 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)))
|
if (!(data = calloc(len, 1)))
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
if (!content_write_serialized_state(data, &size))
|
if (!content_write_serialized_state(data, &size, false))
|
||||||
{
|
{
|
||||||
free(data);
|
free(data);
|
||||||
return NULL;
|
return NULL;
|
||||||
|
@ -1116,13 +1128,13 @@ static bool content_load_rastate1(unsigned char* input, size_t size)
|
||||||
#ifdef HAVE_BSV_MOVIE
|
#ifdef HAVE_BSV_MOVIE
|
||||||
{
|
{
|
||||||
input_driver_state_t *input_st = input_state_get_ptr();
|
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 */
|
/* TODO OSD message */
|
||||||
RARCH_ERR("[Replay] Can't load state without replay data during recording.\n");
|
RARCH_ERR("[Replay] Can't load state without replay data during recording.\n");
|
||||||
return false;
|
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 */
|
/* TODO OSD message */
|
||||||
RARCH_WARN("[Replay] Loading state without replay data during replay will cancel replay.\n");
|
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
|
#ifdef HAVE_BSV_MOVIE
|
||||||
else if (memcmp(marker, RASTATE_REPLAY_BLOCK, 4) == 0)
|
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;
|
seen_replay = true;
|
||||||
else
|
else
|
||||||
return false;
|
return false;
|
||||||
|
@ -1167,7 +1180,7 @@ static bool content_load_rastate1(unsigned char* input, size_t size)
|
||||||
rcheevos_set_serialized_data(NULL);
|
rcheevos_set_serialized_data(NULL);
|
||||||
#endif
|
#endif
|
||||||
#ifdef HAVE_BSV_MOVIE
|
#ifdef HAVE_BSV_MOVIE
|
||||||
if (!seen_replay)
|
if (!seen_replay && !state_manager_frame_is_reversed())
|
||||||
replay_set_serialized_data(NULL);
|
replay_set_serialized_data(NULL);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
@ -1190,7 +1203,8 @@ bool content_deserialize_state(
|
||||||
rcheevos_set_serialized_data(NULL);
|
rcheevos_set_serialized_data(NULL);
|
||||||
#endif
|
#endif
|
||||||
#ifdef HAVE_BSV_MOVIE
|
#ifdef HAVE_BSV_MOVIE
|
||||||
replay_set_serialized_data(NULL);
|
if(!state_manager_frame_is_reversed())
|
||||||
|
replay_set_serialized_data(NULL);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
|
Loading…
Reference in New Issue