Implemented Netplay initialization quirk

This commit is contained in:
Gregor Richards 2016-09-30 14:03:18 -04:00
parent 5676d0b848
commit 07a4ad791d
4 changed files with 83 additions and 20 deletions

View File

@ -31,6 +31,7 @@
#include "netplay_private.h"
#include "../../autosave.h"
#include "../../configuration.h"
#include "../../command.h"
#include "../../movie.h"
@ -951,6 +952,57 @@ void netplay_log_connection(const struct sockaddr_storage *their_addr,
bool netplay_wait_and_init_serialization(netplay_t *netplay)
{
int frames;
if (netplay->state_size)
return true;
/* Wait maximally 60 frames, or until the core reports it's initialized */
for (frames = 0; (core_serialize_quirks() & RETRO_SERIALIZATION_QUIRK_INITIALIZING) && frames < 60; frames++)
{
#if defined(HAVE_THREADS)
autosave_lock();
#endif
core_run();
#if defined(HAVE_THREADS)
autosave_unlock();
#endif
}
return netplay_init_serialization(netplay);
}
bool netplay_init_serialization(netplay_t *netplay)
{
unsigned i;
retro_ctx_size_info_t info;
if (netplay->state_size)
return true;
core_serialize_size(&info);
netplay->state_size = info.size;
for (i = 0; i < netplay->buffer_size; i++)
{
netplay->buffer[i].state = calloc(netplay->state_size, 1);
if (!netplay->buffer[i].state)
{
netplay->quirks |= NETPLAY_QUIRK_NO_SAVESTATES;
return false;
}
}
/* Once initialized, we no longer exhibit this quirk */
netplay->quirks &= ~((uint32_t) NETPLAY_QUIRK_INITIALIZATION);
return true;
}
static bool netplay_init_buffers(netplay_t *netplay, unsigned frames)
{
@ -969,25 +1021,8 @@ static bool netplay_init_buffers(netplay_t *netplay, unsigned frames)
if (!netplay->buffer)
return false;
{
unsigned i;
retro_ctx_size_info_t info;
core_serialize_size(&info);
netplay->state_size = info.size;
for (i = 0; i < netplay->buffer_size; i++)
{
netplay->buffer[i].state = calloc(netplay->state_size, 1);
if (!netplay->buffer[i].state)
{
netplay->quirks |= NETPLAY_QUIRK_NO_SAVESTATES;
netplay->stall_frames = 0;
}
}
}
if (!(netplay->quirks & NETPLAY_QUIRK_INITIALIZATION))
return netplay_init_serialization(netplay);
return true;
}

View File

@ -69,7 +69,11 @@ static bool netplay_net_pre_frame(netplay_t *netplay)
serial_info.size = netplay->state_size;
memset(serial_info.data, 0, serial_info.size);
if (!(netplay->quirks & NETPLAY_QUIRK_NO_SAVESTATES) && core_serialize(&serial_info))
if (netplay->quirks & NETPLAY_QUIRK_INITIALIZATION)
{
/* Don't serialize until it's safe */
}
else if (!(netplay->quirks & NETPLAY_QUIRK_NO_SAVESTATES) && core_serialize(&serial_info))
{
if (netplay->force_send_savestate && !netplay->stall)
{
@ -216,6 +220,10 @@ static void netplay_net_post_frame(netplay_t *netplay)
netplay->replay_ptr = netplay->other_ptr;
netplay->replay_frame_count = netplay->other_frame_count;
if (netplay->quirks & NETPLAY_QUIRK_INITIALIZATION)
/* Make sure we're initialized before we start loading things */
netplay_wait_and_init_serialization(netplay);
serial_info.data = NULL;
serial_info.data_const = netplay->buffer[netplay->replay_ptr].state;
serial_info.size = netplay->state_size;

View File

@ -198,6 +198,12 @@ struct netplay_callbacks* netplay_get_cbs_net(void);
struct netplay_callbacks* netplay_get_cbs_spectate(void);
/* Normally called at init time, unless the INITIALIZATION quirk is set */
bool netplay_init_serialization(netplay_t *netplay);
/* Force serialization to be ready by fast-forwarding the core */
bool netplay_wait_and_init_serialization(netplay_t *netplay);
void netplay_simulate_input(netplay_t *netplay, uint32_t sim_ptr);
void netplay_log_connection(const struct sockaddr_storage *their_addr,

View File

@ -111,6 +111,16 @@ static bool netplay_spectate_pre_frame(netplay_t *netplay)
return true;
}
/* Wait until it's safe to serialize */
if (netplay->quirks & NETPLAY_QUIRK_INITIALIZATION)
{
netplay->is_replay = true;
netplay->replay_ptr = netplay->self_ptr;
netplay->replay_frame_count = netplay->self_frame_count;
netplay_wait_and_init_serialization(netplay);
netplay->is_replay = false;
}
/* Start them at the current frame */
netplay->spectate.frames[idx] = netplay->self_frame_count;
serial_info.data_const = NULL;
@ -197,6 +207,10 @@ static void netplay_spectate_post_frame(netplay_t *netplay)
netplay->replay_ptr = netplay->other_ptr;
netplay->replay_frame_count = netplay->other_frame_count;
/* Wait until it's safe to serialize */
if (netplay->quirks & NETPLAY_QUIRK_INITIALIZATION)
netplay_wait_and_init_serialization(netplay);
serial_info.data = NULL;
serial_info.data_const = netplay->buffer[netplay->replay_ptr].state;
serial_info.size = netplay->state_size;