Improvements to the communication of netplay pausing.

This commit is contained in:
Gregor Richards 2016-12-16 19:54:50 -05:00
parent db2c8de44c
commit 1fa60b396f
5 changed files with 71 additions and 10 deletions

View File

@ -98,6 +98,10 @@ MSG_HASH(
MSG_NETPLAY_CANNOT_PLAY, MSG_NETPLAY_CANNOT_PLAY,
"Cannot switch to play mode." "Cannot switch to play mode."
) )
MSG_HASH(
MSG_NETPLAY_PEER_PAUSED,
"Netplay peer \"%s\" paused."
)
MSG_HASH( MSG_HASH(
MENU_ENUM_SUBLABEL_VIDEO_SHARED_CONTEXT, MENU_ENUM_SUBLABEL_VIDEO_SHARED_CONTEXT,
"Give hardware-rendered cores their own private context. Avoids having to assume hardware state changes inbetween frames." "Give hardware-rendered cores their own private context. Avoids having to assume hardware state changes inbetween frames."

View File

@ -160,6 +160,7 @@ enum msg_hash_enums
MSG_NETPLAY_CANNOT_PLAY_UNPRIVILEGED, MSG_NETPLAY_CANNOT_PLAY_UNPRIVILEGED,
MSG_NETPLAY_CANNOT_PLAY_NO_SLOTS, MSG_NETPLAY_CANNOT_PLAY_NO_SLOTS,
MSG_NETPLAY_CANNOT_PLAY, MSG_NETPLAY_CANNOT_PLAY,
MSG_NETPLAY_PEER_PAUSED,
MSG_AUTODETECT, MSG_AUTODETECT,
MSG_AUDIO_VOLUME, MSG_AUDIO_VOLUME,
MSG_LIBRETRO_FRONTEND, MSG_LIBRETRO_FRONTEND,

View File

@ -255,11 +255,18 @@ Description:
serialized state is zlib compressed. Otherwise it is uncompressed. serialized state is zlib compressed. Otherwise it is uncompressed.
Command: PAUSE Command: PAUSE
Payload: None Payload:
{
nickname: char[32]
}
Description:
Indicates that the core is paused. The receiving peer should also pause. Indicates that the core is paused. The receiving peer should also pause.
The server should pass it on, using the known correct name rather than the
provided name.
Command: RESUME Command: RESUME
Payload: None Payload: None
Description:
Indicates that the core is no longer paused. Indicates that the core is no longer paused.
Command: CHEATS Command: CHEATS

View File

@ -467,6 +467,7 @@ static void netplay_flip_users(netplay_t *netplay)
static void netplay_frontend_paused(netplay_t *netplay, bool paused) static void netplay_frontend_paused(netplay_t *netplay, bool paused)
{ {
size_t i; size_t i;
uint32_t paused_ct;
/* Nothing to do if we already knew this */ /* Nothing to do if we already knew this */
if (netplay->local_paused == paused) if (netplay->local_paused == paused)
@ -474,18 +475,33 @@ static void netplay_frontend_paused(netplay_t *netplay, bool paused)
netplay->local_paused = paused; netplay->local_paused = paused;
/* If other connections are paused, nothing to say */ /* Communicating this is a bit odd: If exactly one other connection is
if (netplay->remote_paused) * paused, then we must tell them that we're unpaused, as from their
* perspective we are. If more than one other connection is paused, then our
* status as proxy means we are NOT unpaused to either of them. */
paused_ct = 0;
for (i = 0; i < netplay->connections_size; i++)
{
struct netplay_connection *connection = &netplay->connections[i];
if (connection->active && connection->paused)
paused_ct++;
}
if (paused_ct > 1)
return; return;
/* Have to send manually because every buffer must be flushed immediately */ /* Send our unpaused status. Must send manually because we must immediately
* flush the buffer: If we're paused, we won't be polled. */
for (i = 0; i < netplay->connections_size; i++) for (i = 0; i < netplay->connections_size; i++)
{ {
struct netplay_connection *connection = &netplay->connections[i]; struct netplay_connection *connection = &netplay->connections[i];
if (connection->active && connection->mode >= NETPLAY_CONNECTION_CONNECTED) if (connection->active && connection->mode >= NETPLAY_CONNECTION_CONNECTED)
{ {
netplay_send_raw_cmd(netplay, connection, if (paused)
paused ? NETPLAY_CMD_PAUSE : NETPLAY_CMD_RESUME, NULL, 0); netplay_send_raw_cmd(netplay, connection, NETPLAY_CMD_PAUSE,
netplay->nick, NETPLAY_NICK_LEN);
else
netplay_send_raw_cmd(netplay, connection, NETPLAY_CMD_RESUME,
NULL, 0);
/* We're not going to be polled, so we need to flush this command now */ /* We're not going to be polled, so we need to flush this command now */
netplay_send_flush(&connection->send_packet_buffer, connection->fd, true); netplay_send_flush(&connection->send_packet_buffer, connection->fd, true);

View File

@ -1095,10 +1095,43 @@ static bool netplay_get_cmd(netplay_t *netplay,
} }
case NETPLAY_CMD_PAUSE: case NETPLAY_CMD_PAUSE:
connection->paused = true; {
netplay->remote_paused = true; char msg[512], nick[NETPLAY_NICK_LEN];
netplay_send_raw_cmd_all(netplay, connection, NETPLAY_CMD_PAUSE, NULL, 0); msg[sizeof(msg)-1] = '\0';
break;
/* Read in the paused nick */
if (cmd_size != sizeof(nick))
{
RARCH_ERR("NETPLAY_CMD_PAUSE received invalid payload size.\n");
return netplay_cmd_nak(netplay, connection);
}
RECV(nick, sizeof(nick))
{
RARCH_ERR("Failed to receive paused nickname.\n");
return netplay_cmd_nak(netplay, connection);
}
nick[sizeof(nick)-1] = '\0';
/* We outright ignore pausing from spectators */
if (connection->mode != NETPLAY_CONNECTION_PLAYING)
break;
connection->paused = true;
netplay->remote_paused = true;
if (netplay->is_server)
{
snprintf(msg, sizeof(msg)-1, msg_hash_to_str(MSG_NETPLAY_PEER_PAUSED), connection->nick);
netplay_send_raw_cmd_all(netplay, connection, NETPLAY_CMD_PAUSE,
connection->nick, NETPLAY_NICK_LEN);
}
else
{
snprintf(msg, sizeof(msg)-1, msg_hash_to_str(MSG_NETPLAY_PEER_PAUSED), nick);
}
RARCH_LOG("%s\n", msg);
runloop_msg_queue_push(msg, 1, 180, false);
break;
}
case NETPLAY_CMD_RESUME: case NETPLAY_CMD_RESUME:
remote_unpaused(netplay, connection); remote_unpaused(netplay, connection);