mirror of
https://github.com/libretro/RetroArch
synced 2025-03-01 16:13:40 +00:00
Cleaning up netplay headers.
This commit is contained in:
parent
9c6ac2b934
commit
da7efcb939
@ -13,6 +13,8 @@
|
||||
* If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include <stdlib.h>
|
||||
|
||||
#include <net/net_compat.h>
|
||||
#include <net/net_socket.h>
|
||||
|
||||
@ -47,6 +49,11 @@ static size_t buf_remaining(struct socket_buffer *sbuf)
|
||||
return sbuf->bufsz - buf_used(sbuf) - 1;
|
||||
}
|
||||
|
||||
/**
|
||||
* netplay_init_socket_buffer
|
||||
*
|
||||
* Initialize a new socket buffer.
|
||||
*/
|
||||
bool netplay_init_socket_buffer(struct socket_buffer *sbuf, size_t size)
|
||||
{
|
||||
sbuf->data = malloc(size);
|
||||
@ -57,6 +64,11 @@ bool netplay_init_socket_buffer(struct socket_buffer *sbuf, size_t size)
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* netplay_resize_socket_buffer
|
||||
*
|
||||
* Resize the given socket_buffer's buffer to the requested size.
|
||||
*/
|
||||
bool netplay_resize_socket_buffer(struct socket_buffer *sbuf, size_t newsize)
|
||||
{
|
||||
unsigned char *newdata = malloc(newsize);
|
||||
@ -91,6 +103,11 @@ bool netplay_resize_socket_buffer(struct socket_buffer *sbuf, size_t newsize)
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* netplay_deinit_socket_buffer
|
||||
*
|
||||
* Free a socket buffer.
|
||||
*/
|
||||
void netplay_deinit_socket_buffer(struct socket_buffer *sbuf)
|
||||
{
|
||||
if (sbuf->data)
|
||||
@ -102,7 +119,13 @@ void netplay_clear_socket_buffer(struct socket_buffer *sbuf)
|
||||
sbuf->start = sbuf->read = sbuf->end = 0;
|
||||
}
|
||||
|
||||
bool netplay_send(struct socket_buffer *sbuf, int sockfd, const void *buf, size_t len)
|
||||
/**
|
||||
* netplay_send
|
||||
*
|
||||
* Queue the given data for sending.
|
||||
*/
|
||||
bool netplay_send(struct socket_buffer *sbuf, int sockfd, const void *buf,
|
||||
size_t len)
|
||||
{
|
||||
if (buf_remaining(sbuf) < len)
|
||||
{
|
||||
@ -143,6 +166,14 @@ bool netplay_send(struct socket_buffer *sbuf, int sockfd, const void *buf, size_
|
||||
return netplay_send_flush(sbuf, sockfd, false);
|
||||
}
|
||||
|
||||
/**
|
||||
* netplay_send_flush
|
||||
*
|
||||
* Flush unsent data in the given socket buffer, blocking to do so if
|
||||
* requested.
|
||||
*
|
||||
* Returns false only on socket failures, true otherwise.
|
||||
*/
|
||||
bool netplay_send_flush(struct socket_buffer *sbuf, int sockfd, bool block)
|
||||
{
|
||||
ssize_t sent;
|
||||
@ -205,7 +236,15 @@ bool netplay_send_flush(struct socket_buffer *sbuf, int sockfd, bool block)
|
||||
return true;
|
||||
}
|
||||
|
||||
ssize_t netplay_recv(struct socket_buffer *sbuf, int sockfd, void *buf, size_t len, bool block)
|
||||
/**
|
||||
* netplay_recv
|
||||
*
|
||||
* Receive buffered or fresh data.
|
||||
*
|
||||
* Returns number of bytes returned, which may be short or 0, or -1 on error.
|
||||
*/
|
||||
ssize_t netplay_recv(struct socket_buffer *sbuf, int sockfd, void *buf,
|
||||
size_t len, bool block)
|
||||
{
|
||||
bool error;
|
||||
ssize_t recvd;
|
||||
@ -295,11 +334,23 @@ ssize_t netplay_recv(struct socket_buffer *sbuf, int sockfd, void *buf, size_t l
|
||||
return recvd;
|
||||
}
|
||||
|
||||
/**
|
||||
* netplay_recv_reset
|
||||
*
|
||||
* Reset our recv buffer so that future netplay_recvs will read the same data
|
||||
* again.
|
||||
*/
|
||||
void netplay_recv_reset(struct socket_buffer *sbuf)
|
||||
{
|
||||
sbuf->read = sbuf->start;
|
||||
}
|
||||
|
||||
/**
|
||||
* netplay_recv_flush
|
||||
*
|
||||
* Flush our recv buffer, so a future netplay_recv_reset will reset to this
|
||||
* point.
|
||||
*/
|
||||
void netplay_recv_flush(struct socket_buffer *sbuf)
|
||||
{
|
||||
sbuf->start = sbuf->read;
|
||||
|
@ -23,7 +23,17 @@
|
||||
|
||||
#include "netplay_private.h"
|
||||
|
||||
bool netplay_delta_frame_ready(netplay_t *netplay, struct delta_frame *delta, uint32_t frame)
|
||||
/**
|
||||
* netplay_delta_frame_ready
|
||||
*
|
||||
* Prepares, if possible, a delta frame for input, and reports whether it is
|
||||
* ready.
|
||||
*
|
||||
* Returns: True if the delta frame is ready for input at the given frame,
|
||||
* false otherwise.
|
||||
*/
|
||||
bool netplay_delta_frame_ready(netplay_t *netplay, struct delta_frame *delta,
|
||||
uint32_t frame)
|
||||
{
|
||||
void *remember_state;
|
||||
if (delta->used)
|
||||
@ -43,6 +53,11 @@ bool netplay_delta_frame_ready(netplay_t *netplay, struct delta_frame *delta, ui
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* netplay_delta_frame_crc
|
||||
*
|
||||
* Get the CRC for the serialization of this frame.
|
||||
*/
|
||||
uint32_t netplay_delta_frame_crc(netplay_t *netplay, struct delta_frame *delta)
|
||||
{
|
||||
if (!netplay->state_size)
|
||||
|
@ -32,6 +32,7 @@
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include <compat/strl.h>
|
||||
@ -191,6 +192,11 @@ error:
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* netplay_lan_ad_server
|
||||
*
|
||||
* Respond to any LAN ad queries that the netplay server has received.
|
||||
*/
|
||||
bool netplay_lan_ad_server(netplay_t *netplay)
|
||||
{
|
||||
fd_set fds;
|
||||
|
@ -28,10 +28,6 @@
|
||||
#include "../../input/input_driver.h"
|
||||
#include "../../runloop.h"
|
||||
|
||||
#ifndef HAVE_SOCKET_LEGACY
|
||||
static void announce_nat_traversal(netplay_t *netplay);
|
||||
#endif
|
||||
|
||||
/* Only used before init_netplay */
|
||||
static bool netplay_enabled = false;
|
||||
static bool netplay_is_client = false;
|
||||
@ -286,13 +282,18 @@ static bool netplay_poll(void)
|
||||
return true;
|
||||
}
|
||||
|
||||
/* Netplay polling callbacks */
|
||||
/**
|
||||
* input_poll_net
|
||||
*
|
||||
* Poll the network if necessary.
|
||||
*/
|
||||
void input_poll_net(void)
|
||||
{
|
||||
if (!netplay_should_skip(netplay_data) && netplay_can_poll(netplay_data))
|
||||
netplay_poll();
|
||||
}
|
||||
|
||||
/* Netplay polling callbacks */
|
||||
void video_frame_net(const void *data, unsigned width,
|
||||
unsigned height, size_t pitch)
|
||||
{
|
||||
@ -436,6 +437,42 @@ static void netplay_flip_users(netplay_t *netplay)
|
||||
netplay->flip_frame = flip_frame;
|
||||
}
|
||||
|
||||
/**
|
||||
* netplay_frontend_paused
|
||||
* @netplay : pointer to netplay object
|
||||
* @paused : true if frontend is paused
|
||||
*
|
||||
* Inform Netplay of the frontend's pause state (paused or otherwise)
|
||||
*/
|
||||
static void netplay_frontend_paused(netplay_t *netplay, bool paused)
|
||||
{
|
||||
size_t i;
|
||||
|
||||
/* Nothing to do if we already knew this */
|
||||
if (netplay->local_paused == paused)
|
||||
return;
|
||||
|
||||
netplay->local_paused = paused;
|
||||
|
||||
/* If other connections are paused, nothing to say */
|
||||
if (netplay->remote_paused)
|
||||
return;
|
||||
|
||||
/* Have to send manually because every buffer must be flushed immediately */
|
||||
for (i = 0; i < netplay->connections_size; i++)
|
||||
{
|
||||
struct netplay_connection *connection = &netplay->connections[i];
|
||||
if (connection->active && connection->mode >= NETPLAY_CONNECTION_CONNECTED)
|
||||
{
|
||||
netplay_send_raw_cmd(netplay, connection,
|
||||
paused ? NETPLAY_CMD_PAUSE : NETPLAY_CMD_RESUME, NULL, 0);
|
||||
|
||||
/* 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_pre_frame:
|
||||
* @netplay : pointer to netplay object
|
||||
@ -478,7 +515,7 @@ bool netplay_pre_frame(netplay_t *netplay)
|
||||
#ifndef HAVE_SOCKET_LEGACY
|
||||
if (!netplay->nat_traversal_state.request_outstanding ||
|
||||
netplay->nat_traversal_state.have_inet4)
|
||||
announce_nat_traversal(netplay);
|
||||
netplay_announce_nat_traversal(netplay);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
@ -515,42 +552,6 @@ void netplay_post_frame(netplay_t *netplay)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* netplay_frontend_paused
|
||||
* @netplay : pointer to netplay object
|
||||
* @paused : true if frontend is paused
|
||||
*
|
||||
* Inform Netplay of the frontend's pause state (paused or otherwise)
|
||||
**/
|
||||
void netplay_frontend_paused(netplay_t *netplay, bool paused)
|
||||
{
|
||||
size_t i;
|
||||
|
||||
/* Nothing to do if we already knew this */
|
||||
if (netplay->local_paused == paused)
|
||||
return;
|
||||
|
||||
netplay->local_paused = paused;
|
||||
|
||||
/* If other connections are paused, nothing to say */
|
||||
if (netplay->remote_paused)
|
||||
return;
|
||||
|
||||
/* Have to send manually because every buffer must be flushed immediately */
|
||||
for (i = 0; i < netplay->connections_size; i++)
|
||||
{
|
||||
struct netplay_connection *connection = &netplay->connections[i];
|
||||
if (connection->active && connection->mode >= NETPLAY_CONNECTION_CONNECTED)
|
||||
{
|
||||
netplay_send_raw_cmd(netplay, connection,
|
||||
paused ? NETPLAY_CMD_PAUSE : NETPLAY_CMD_RESUME, NULL, 0);
|
||||
|
||||
/* 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_load_savestate
|
||||
* @netplay : pointer to netplay object
|
||||
@ -669,63 +670,6 @@ void netplay_load_savestate(netplay_t *netplay,
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* netplay_init_nat_traversal
|
||||
*
|
||||
* Initialize the NAT traversal library and try to open a port
|
||||
*/
|
||||
void netplay_init_nat_traversal(netplay_t *netplay)
|
||||
{
|
||||
natt_init();
|
||||
|
||||
if (!natt_new(&netplay->nat_traversal_state))
|
||||
{
|
||||
netplay->nat_traversal = false;
|
||||
return;
|
||||
}
|
||||
|
||||
natt_open_port_any(&netplay->nat_traversal_state, netplay->tcp_port, SOCKET_PROTOCOL_TCP);
|
||||
|
||||
#ifndef HAVE_SOCKET_LEGACY
|
||||
if (!netplay->nat_traversal_state.request_outstanding)
|
||||
announce_nat_traversal(netplay);
|
||||
#endif
|
||||
}
|
||||
|
||||
#ifndef HAVE_SOCKET_LEGACY
|
||||
static void announce_nat_traversal(netplay_t *netplay)
|
||||
{
|
||||
char msg[512], host[PATH_MAX_LENGTH], port[6];
|
||||
|
||||
if (netplay->nat_traversal_state.have_inet4)
|
||||
{
|
||||
if (getnameinfo((const struct sockaddr *) &netplay->nat_traversal_state.ext_inet4_addr,
|
||||
sizeof(struct sockaddr_in),
|
||||
host, PATH_MAX_LENGTH, port, 6, NI_NUMERICHOST|NI_NUMERICSERV) != 0)
|
||||
return;
|
||||
|
||||
}
|
||||
#ifdef HAVE_INET6
|
||||
else if (netplay->nat_traversal_state.have_inet6)
|
||||
{
|
||||
if (getnameinfo((const struct sockaddr *) &netplay->nat_traversal_state.ext_inet6_addr,
|
||||
sizeof(struct sockaddr_in6),
|
||||
host, PATH_MAX_LENGTH, port, 6, NI_NUMERICHOST|NI_NUMERICSERV) != 0)
|
||||
return;
|
||||
|
||||
}
|
||||
#endif
|
||||
else
|
||||
return;
|
||||
|
||||
snprintf(msg, sizeof(msg), "%s: %s:%s\n",
|
||||
msg_hash_to_str(MSG_PUBLIC_ADDRESS),
|
||||
host, port);
|
||||
runloop_msg_queue_push(msg, 1, 180, false);
|
||||
RARCH_LOG("%s\n", msg);
|
||||
}
|
||||
#endif
|
||||
|
||||
/**
|
||||
* netplay_toggle_play_spectate
|
||||
*
|
||||
|
@ -229,7 +229,13 @@ static uint32_t simple_rand_uint32()
|
||||
parts[2]);
|
||||
}
|
||||
|
||||
bool netplay_handshake_init_send(netplay_t *netplay, struct netplay_connection *connection)
|
||||
/**
|
||||
* netplay_handshake_init_send
|
||||
*
|
||||
* Initialize our handshake and send the first part of the handshake protocol.
|
||||
*/
|
||||
bool netplay_handshake_init_send(netplay_t *netplay,
|
||||
struct netplay_connection *connection)
|
||||
{
|
||||
uint32_t *content_crc_ptr = NULL;
|
||||
uint32_t header[5] = {0};
|
||||
@ -307,7 +313,14 @@ static void handshake_password(void *ignore, const char *line)
|
||||
rarch_ctl(RARCH_CTL_MENU_RUNNING_FINISHED, NULL);
|
||||
}
|
||||
|
||||
bool netplay_handshake_init(netplay_t *netplay, struct netplay_connection *connection, bool *had_input)
|
||||
/**
|
||||
* netplay_handshake_init
|
||||
*
|
||||
* Data receiver for the initial part of the handshake, i.e., waiting for the
|
||||
* netplay header.
|
||||
*/
|
||||
bool netplay_handshake_init(netplay_t *netplay,
|
||||
struct netplay_connection *connection, bool *had_input)
|
||||
{
|
||||
uint32_t header[5] = {0};
|
||||
ssize_t recvd;
|
||||
@ -509,7 +522,14 @@ bool netplay_handshake_sync(netplay_t *netplay, struct netplay_connection *conne
|
||||
return true;
|
||||
}
|
||||
|
||||
bool netplay_handshake_pre_nick(netplay_t *netplay, struct netplay_connection *connection, bool *had_input)
|
||||
/**
|
||||
* netplay_handshake_pre_nick
|
||||
*
|
||||
* Data receiver for the second stage of handshake, receiving the other side's
|
||||
* nickname.
|
||||
*/
|
||||
bool netplay_handshake_pre_nick(netplay_t *netplay,
|
||||
struct netplay_connection *connection, bool *had_input)
|
||||
{
|
||||
struct nick_buf_s nick_buf;
|
||||
ssize_t recvd;
|
||||
@ -567,7 +587,14 @@ bool netplay_handshake_pre_nick(netplay_t *netplay, struct netplay_connection *c
|
||||
return true;
|
||||
}
|
||||
|
||||
bool netplay_handshake_pre_password(netplay_t *netplay, struct netplay_connection *connection, bool *had_input)
|
||||
/**
|
||||
* netplay_handshake_pre_password
|
||||
*
|
||||
* Data receiver for the third, optional stage of server handshake, receiving
|
||||
* the password.
|
||||
*/
|
||||
bool netplay_handshake_pre_password(netplay_t *netplay,
|
||||
struct netplay_connection *connection, bool *had_input)
|
||||
{
|
||||
struct password_buf_s password_buf, corr_password_buf;
|
||||
char password[8+NETPLAY_PASS_LEN]; /* 8 for salt */
|
||||
@ -630,7 +657,14 @@ bool netplay_handshake_pre_password(netplay_t *netplay, struct netplay_connectio
|
||||
return true;
|
||||
}
|
||||
|
||||
bool netplay_handshake_pre_sync(netplay_t *netplay, struct netplay_connection *connection, bool *had_input)
|
||||
/**
|
||||
* netplay_handshake_pre_sync
|
||||
*
|
||||
* Data receiver for the client's third handshake stage, receiving the
|
||||
* synchronization information.
|
||||
*/
|
||||
bool netplay_handshake_pre_sync(netplay_t *netplay,
|
||||
struct netplay_connection *connection, bool *had_input)
|
||||
{
|
||||
uint32_t cmd[2];
|
||||
uint32_t new_frame_count, connected_players, flip_frame;
|
||||
|
@ -264,62 +264,6 @@ static bool netplay_init_socket_buffers(netplay_t *netplay)
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* netplay_try_init_serialization
|
||||
*
|
||||
* Try to initialize serialization. For quirky cores.
|
||||
*
|
||||
* Returns true if serialization is now ready, false otherwise.
|
||||
*/
|
||||
bool netplay_try_init_serialization(netplay_t *netplay)
|
||||
{
|
||||
retro_ctx_serialize_info_t serial_info;
|
||||
size_t packet_buffer_size;
|
||||
|
||||
if (netplay->state_size)
|
||||
return true;
|
||||
|
||||
if (!netplay_init_serialization(netplay))
|
||||
return false;
|
||||
|
||||
/* Check if we can actually save */
|
||||
serial_info.data_const = NULL;
|
||||
serial_info.data = netplay->buffer[netplay->self_ptr].state;
|
||||
serial_info.size = netplay->state_size;
|
||||
|
||||
if (!core_serialize(&serial_info))
|
||||
return false;
|
||||
|
||||
/* Once initialized, we no longer exhibit this quirk */
|
||||
netplay->quirks &= ~((uint64_t) NETPLAY_QUIRK_INITIALIZATION);
|
||||
|
||||
return netplay_init_socket_buffers(netplay);
|
||||
}
|
||||
|
||||
bool netplay_wait_and_init_serialization(netplay_t *netplay)
|
||||
{
|
||||
int frame;
|
||||
|
||||
if (netplay->state_size)
|
||||
return true;
|
||||
|
||||
/* Wait a maximum of 60 frames */
|
||||
for (frame = 0; frame < 60; frame++) {
|
||||
if (netplay_try_init_serialization(netplay))
|
||||
return true;
|
||||
|
||||
#if defined(HAVE_THREADS)
|
||||
autosave_lock();
|
||||
#endif
|
||||
core_run();
|
||||
#if defined(HAVE_THREADS)
|
||||
autosave_unlock();
|
||||
#endif
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool netplay_init_serialization(netplay_t *netplay)
|
||||
{
|
||||
unsigned i;
|
||||
@ -358,6 +302,70 @@ bool netplay_init_serialization(netplay_t *netplay)
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* netplay_try_init_serialization
|
||||
*
|
||||
* Try to initialize serialization. For quirky cores.
|
||||
*
|
||||
* Returns true if serialization is now ready, false otherwise.
|
||||
*/
|
||||
bool netplay_try_init_serialization(netplay_t *netplay)
|
||||
{
|
||||
retro_ctx_serialize_info_t serial_info;
|
||||
size_t packet_buffer_size;
|
||||
|
||||
if (netplay->state_size)
|
||||
return true;
|
||||
|
||||
if (!netplay_init_serialization(netplay))
|
||||
return false;
|
||||
|
||||
/* Check if we can actually save */
|
||||
serial_info.data_const = NULL;
|
||||
serial_info.data = netplay->buffer[netplay->self_ptr].state;
|
||||
serial_info.size = netplay->state_size;
|
||||
|
||||
if (!core_serialize(&serial_info))
|
||||
return false;
|
||||
|
||||
/* Once initialized, we no longer exhibit this quirk */
|
||||
netplay->quirks &= ~((uint64_t) NETPLAY_QUIRK_INITIALIZATION);
|
||||
|
||||
return netplay_init_socket_buffers(netplay);
|
||||
}
|
||||
|
||||
/**
|
||||
* netplay_wait_and_init_serialization
|
||||
*
|
||||
* Try very hard to initialize serialization, simulating multiple frames if
|
||||
* necessary. For quirky cores.
|
||||
*
|
||||
* Returns true if serialization is now ready, false otherwise.
|
||||
*/
|
||||
bool netplay_wait_and_init_serialization(netplay_t *netplay)
|
||||
{
|
||||
int frame;
|
||||
|
||||
if (netplay->state_size)
|
||||
return true;
|
||||
|
||||
/* Wait a maximum of 60 frames */
|
||||
for (frame = 0; frame < 60; frame++) {
|
||||
if (netplay_try_init_serialization(netplay))
|
||||
return true;
|
||||
|
||||
#if defined(HAVE_THREADS)
|
||||
autosave_lock();
|
||||
#endif
|
||||
core_run();
|
||||
#if defined(HAVE_THREADS)
|
||||
autosave_unlock();
|
||||
#endif
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
static bool netplay_init_buffers(netplay_t *netplay, unsigned frames)
|
||||
{
|
||||
size_t packet_buffer_size;
|
||||
@ -397,15 +405,16 @@ static bool netplay_init_buffers(netplay_t *netplay, unsigned frames)
|
||||
* @nick : Nickname of user.
|
||||
* @quirks : Netplay quirks required for this session.
|
||||
*
|
||||
* Creates a new netplay handle. A NULL host means we're
|
||||
* hosting (user 1).
|
||||
* Creates a new netplay handle. A NULL server means we're
|
||||
* hosting.
|
||||
*
|
||||
* Returns: new netplay handle.
|
||||
**/
|
||||
* Returns: new netplay data.
|
||||
*/
|
||||
netplay_t *netplay_new(void *direct_host, const char *server, uint16_t port,
|
||||
const char *play_password, const char *spectate_password,
|
||||
unsigned delay_frames, unsigned check_frames, const struct retro_callbacks
|
||||
*cb, bool nat_traversal, const char *nick, uint64_t quirks)
|
||||
unsigned delay_frames, unsigned check_frames,
|
||||
const struct retro_callbacks *cb, bool nat_traversal, const char *nick,
|
||||
uint64_t quirks)
|
||||
{
|
||||
netplay_t *netplay = (netplay_t*)calloc(1, sizeof(*netplay));
|
||||
if (!netplay)
|
||||
@ -486,11 +495,11 @@ error:
|
||||
}
|
||||
|
||||
/**
|
||||
* netplay_free:
|
||||
* netplay_free
|
||||
* @netplay : pointer to netplay object
|
||||
*
|
||||
* Frees netplay handle.
|
||||
**/
|
||||
* Frees netplay data/
|
||||
*/
|
||||
void netplay_free(netplay_t *netplay)
|
||||
{
|
||||
size_t i;
|
||||
|
@ -54,7 +54,7 @@ static void remote_unpaused(netplay_t *netplay, struct netplay_connection *conne
|
||||
* netplay_hangup:
|
||||
*
|
||||
* Disconnects an active Netplay connection due to an error
|
||||
**/
|
||||
*/
|
||||
void netplay_hangup(netplay_t *netplay, struct netplay_connection *connection)
|
||||
{
|
||||
if (!netplay)
|
||||
@ -145,7 +145,13 @@ static bool send_input_frame(netplay_t *netplay,
|
||||
return true;
|
||||
}
|
||||
|
||||
/* Send the current input frame */
|
||||
/**
|
||||
* netplay_send_cur_input
|
||||
*
|
||||
* Send the current input frame to a given connection.
|
||||
*
|
||||
* Returns true if successful, false otherwise.
|
||||
*/
|
||||
bool netplay_send_cur_input(netplay_t *netplay,
|
||||
struct netplay_connection *connection)
|
||||
{
|
||||
@ -203,9 +209,9 @@ bool netplay_send_cur_input(netplay_t *netplay,
|
||||
/**
|
||||
* netplay_send_raw_cmd
|
||||
*
|
||||
* Send a raw Netplay command to the given connection
|
||||
* Send a raw Netplay command to the given connection.
|
||||
*
|
||||
* Returns true on success, false on failure
|
||||
* Returns true on success, false on failure.
|
||||
*/
|
||||
bool netplay_send_raw_cmd(netplay_t *netplay,
|
||||
struct netplay_connection *connection, uint32_t cmd, const void *data,
|
||||
@ -258,6 +264,11 @@ static bool netplay_cmd_nak(netplay_t *netplay,
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* netplay_cmd_crc
|
||||
*
|
||||
* Send a CRC command to all active clients.
|
||||
*/
|
||||
bool netplay_cmd_crc(netplay_t *netplay, struct delta_frame *delta)
|
||||
{
|
||||
uint32_t payload[2];
|
||||
@ -275,6 +286,11 @@ bool netplay_cmd_crc(netplay_t *netplay, struct delta_frame *delta)
|
||||
return success;
|
||||
}
|
||||
|
||||
/**
|
||||
* netplay_cmd_request_savestate
|
||||
*
|
||||
* Send a savestate request command.
|
||||
*/
|
||||
bool netplay_cmd_request_savestate(netplay_t *netplay)
|
||||
{
|
||||
if (netplay->connections_size == 0 ||
|
||||
@ -288,6 +304,11 @@ bool netplay_cmd_request_savestate(netplay_t *netplay)
|
||||
NETPLAY_CMD_REQUEST_SAVESTATE, NULL, 0);
|
||||
}
|
||||
|
||||
/**
|
||||
* netplay_cmd_mode
|
||||
*
|
||||
* Send a mode request command to either play or spectate.
|
||||
*/
|
||||
bool netplay_cmd_mode(netplay_t *netplay,
|
||||
struct netplay_connection *connection,
|
||||
enum rarch_netplay_connection_mode mode)
|
||||
@ -1079,3 +1100,65 @@ bool netplay_flip_port(netplay_t *netplay)
|
||||
|
||||
return netplay->flip ^ (frame < netplay->flip_frame);
|
||||
}
|
||||
|
||||
/**
|
||||
* netplay_announce_nat_traversal
|
||||
*
|
||||
* Announce successful NAT traversal.
|
||||
*/
|
||||
void netplay_announce_nat_traversal(netplay_t *netplay)
|
||||
{
|
||||
#ifndef HAVE_SOCKET_LEGACY
|
||||
char msg[512], host[PATH_MAX_LENGTH], port[6];
|
||||
|
||||
if (netplay->nat_traversal_state.have_inet4)
|
||||
{
|
||||
if (getnameinfo((const struct sockaddr *) &netplay->nat_traversal_state.ext_inet4_addr,
|
||||
sizeof(struct sockaddr_in),
|
||||
host, PATH_MAX_LENGTH, port, 6, NI_NUMERICHOST|NI_NUMERICSERV) != 0)
|
||||
return;
|
||||
|
||||
}
|
||||
#ifdef HAVE_INET6
|
||||
else if (netplay->nat_traversal_state.have_inet6)
|
||||
{
|
||||
if (getnameinfo((const struct sockaddr *) &netplay->nat_traversal_state.ext_inet6_addr,
|
||||
sizeof(struct sockaddr_in6),
|
||||
host, PATH_MAX_LENGTH, port, 6, NI_NUMERICHOST|NI_NUMERICSERV) != 0)
|
||||
return;
|
||||
|
||||
}
|
||||
#endif
|
||||
else
|
||||
return;
|
||||
|
||||
snprintf(msg, sizeof(msg), "%s: %s:%s\n",
|
||||
msg_hash_to_str(MSG_PUBLIC_ADDRESS),
|
||||
host, port);
|
||||
runloop_msg_queue_push(msg, 1, 180, false);
|
||||
RARCH_LOG("%s\n", msg);
|
||||
#endif
|
||||
}
|
||||
|
||||
/**
|
||||
* netplay_init_nat_traversal
|
||||
*
|
||||
* Initialize the NAT traversal library and try to open a port
|
||||
*/
|
||||
void netplay_init_nat_traversal(netplay_t *netplay)
|
||||
{
|
||||
natt_init();
|
||||
|
||||
if (!natt_new(&netplay->nat_traversal_state))
|
||||
{
|
||||
netplay->nat_traversal = false;
|
||||
return;
|
||||
}
|
||||
|
||||
natt_open_port_any(&netplay->nat_traversal_state, netplay->tcp_port, SOCKET_PROTOCOL_TCP);
|
||||
|
||||
#ifndef HAVE_SOCKET_LEGACY
|
||||
if (!netplay->nat_traversal_state.request_outstanding)
|
||||
netplay_announce_nat_traversal(netplay);
|
||||
#endif
|
||||
}
|
||||
|
@ -24,16 +24,10 @@
|
||||
#include <net/net_natt.h>
|
||||
#include <features/features_cpu.h>
|
||||
#include <streams/trans_stream.h>
|
||||
#include <retro_endianness.h>
|
||||
|
||||
#include "../../core.h"
|
||||
#include "../../msg_hash.h"
|
||||
#include "../../verbosity.h"
|
||||
|
||||
#ifdef ANDROID
|
||||
#define HAVE_IPV6
|
||||
#endif
|
||||
|
||||
#define WORDS_PER_INPUT 3 /* Buttons, left stick, right stick */
|
||||
#define WORDS_PER_FRAME (WORDS_PER_INPUT+2) /* + frameno, playerno */
|
||||
|
||||
@ -419,8 +413,209 @@ struct netplay
|
||||
uint32_t check_frames;
|
||||
};
|
||||
|
||||
|
||||
/***************************************************************
|
||||
* NETPLAY-BUF.C
|
||||
**************************************************************/
|
||||
|
||||
/**
|
||||
* netplay_init_socket_buffer
|
||||
*
|
||||
* Initialize a new socket buffer.
|
||||
*/
|
||||
bool netplay_init_socket_buffer(struct socket_buffer *sbuf, size_t size);
|
||||
|
||||
/**
|
||||
* netplay_resize_socket_buffer
|
||||
*
|
||||
* Resize the given socket_buffer's buffer to the requested size.
|
||||
*/
|
||||
bool netplay_resize_socket_buffer(struct socket_buffer *sbuf, size_t newsize);
|
||||
|
||||
/**
|
||||
* netplay_deinit_socket_buffer
|
||||
*
|
||||
* Free a socket buffer.
|
||||
*/
|
||||
void netplay_deinit_socket_buffer(struct socket_buffer *sbuf);
|
||||
|
||||
/**
|
||||
* netplay_send
|
||||
*
|
||||
* Queue the given data for sending.
|
||||
*/
|
||||
bool netplay_send(struct socket_buffer *sbuf, int sockfd, const void *buf,
|
||||
size_t len);
|
||||
|
||||
/**
|
||||
* netplay_send_flush
|
||||
*
|
||||
* Flush unsent data in the given socket buffer, blocking to do so if
|
||||
* requested.
|
||||
*
|
||||
* Returns false only on socket failures, true otherwise.
|
||||
*/
|
||||
bool netplay_send_flush(struct socket_buffer *sbuf, int sockfd, bool block);
|
||||
|
||||
/**
|
||||
* netplay_recv
|
||||
*
|
||||
* Receive buffered or fresh data.
|
||||
*
|
||||
* Returns number of bytes returned, which may be short or 0, or -1 on error.
|
||||
*/
|
||||
ssize_t netplay_recv(struct socket_buffer *sbuf, int sockfd, void *buf,
|
||||
size_t len, bool block);
|
||||
|
||||
/**
|
||||
* netplay_recv_reset
|
||||
*
|
||||
* Reset our recv buffer so that future netplay_recvs will read the same data
|
||||
* again.
|
||||
*/
|
||||
void netplay_recv_reset(struct socket_buffer *sbuf);
|
||||
|
||||
/**
|
||||
* netplay_recv_flush
|
||||
*
|
||||
* Flush our recv buffer, so a future netplay_recv_reset will reset to this
|
||||
* point.
|
||||
*/
|
||||
void netplay_recv_flush(struct socket_buffer *sbuf);
|
||||
|
||||
|
||||
/***************************************************************
|
||||
* NETPLAY-DELTA.C
|
||||
**************************************************************/
|
||||
|
||||
/**
|
||||
* netplay_delta_frame_ready
|
||||
*
|
||||
* Prepares, if possible, a delta frame for input, and reports whether it is
|
||||
* ready.
|
||||
*
|
||||
* Returns: True if the delta frame is ready for input at the given frame,
|
||||
* false otherwise.
|
||||
*/
|
||||
bool netplay_delta_frame_ready(netplay_t *netplay, struct delta_frame *delta,
|
||||
uint32_t frame);
|
||||
|
||||
/**
|
||||
* netplay_delta_frame_crc
|
||||
*
|
||||
* Get the CRC for the serialization of this frame.
|
||||
*/
|
||||
uint32_t netplay_delta_frame_crc(netplay_t *netplay, struct delta_frame *delta);
|
||||
|
||||
|
||||
/***************************************************************
|
||||
* NETPLAY-DISCOVERY.C
|
||||
**************************************************************/
|
||||
|
||||
/**
|
||||
* netplay_lan_ad_server
|
||||
*
|
||||
* Respond to any LAN ad queries that the netplay server has received.
|
||||
*/
|
||||
bool netplay_lan_ad_server(netplay_t *netplay);
|
||||
|
||||
|
||||
/***************************************************************
|
||||
* NETPLAY-FRONTEND.C
|
||||
**************************************************************/
|
||||
|
||||
/**
|
||||
* netplay_load_savestate
|
||||
* @netplay : pointer to netplay object
|
||||
* @serial_info : the savestate being loaded, NULL means
|
||||
* "load it yourself"
|
||||
* @save : Whether to save the provided serial_info
|
||||
* into the frame buffer
|
||||
*
|
||||
* Inform Netplay of a savestate load and send it to the other side
|
||||
**/
|
||||
void netplay_load_savestate(netplay_t *netplay,
|
||||
retro_ctx_serialize_info_t *serial_info, bool save);
|
||||
|
||||
/**
|
||||
* input_poll_net
|
||||
*
|
||||
* Poll the network if necessary.
|
||||
*/
|
||||
void input_poll_net(void);
|
||||
|
||||
/***************************************************************
|
||||
* NETPLAY-HANDSHAKE.C
|
||||
**************************************************************/
|
||||
|
||||
/**
|
||||
* netplay_handshake_init_send
|
||||
*
|
||||
* Initialize our handshake and send the first part of the handshake protocol.
|
||||
*/
|
||||
bool netplay_handshake_init_send(netplay_t *netplay,
|
||||
struct netplay_connection *connection);
|
||||
|
||||
/**
|
||||
* netplay_handshake_init
|
||||
*
|
||||
* Data receiver for the initial part of the handshake, i.e., waiting for the
|
||||
* netplay header.
|
||||
*/
|
||||
bool netplay_handshake_init(netplay_t *netplay,
|
||||
struct netplay_connection *connection, bool *had_input);
|
||||
|
||||
/**
|
||||
* netplay_handshake_pre_nick
|
||||
*
|
||||
* Data receiver for the second stage of handshake, receiving the other side's
|
||||
* nickname.
|
||||
*/
|
||||
bool netplay_handshake_pre_nick(netplay_t *netplay,
|
||||
struct netplay_connection *connection, bool *had_input);
|
||||
|
||||
/**
|
||||
* netplay_handshake_pre_password
|
||||
*
|
||||
* Data receiver for the third, optional stage of server handshake, receiving
|
||||
* the password.
|
||||
*/
|
||||
bool netplay_handshake_pre_password(netplay_t *netplay,
|
||||
struct netplay_connection *connection, bool *had_input);
|
||||
|
||||
/**
|
||||
* netplay_handshake_pre_sync
|
||||
*
|
||||
* Data receiver for the client's third handshake stage, receiving the
|
||||
* synchronization information.
|
||||
*/
|
||||
bool netplay_handshake_pre_sync(netplay_t *netplay,
|
||||
struct netplay_connection *connection, bool *had_input);
|
||||
|
||||
|
||||
/***************************************************************
|
||||
* NETPLAY-INIT.C
|
||||
**************************************************************/
|
||||
|
||||
/**
|
||||
* netplay_try_init_serialization
|
||||
*
|
||||
* Try to initialize serialization. For quirky cores.
|
||||
*
|
||||
* Returns true if serialization is now ready, false otherwise.
|
||||
*/
|
||||
bool netplay_try_init_serialization(netplay_t *netplay);
|
||||
|
||||
/**
|
||||
* netplay_wait_and_init_serialization
|
||||
*
|
||||
* Try very hard to initialize serialization, simulating multiple frames if
|
||||
* necessary. For quirky cores.
|
||||
*
|
||||
* Returns true if serialization is now ready, false otherwise.
|
||||
*/
|
||||
bool netplay_wait_and_init_serialization(netplay_t *netplay);
|
||||
|
||||
/**
|
||||
* netplay_new:
|
||||
* @direct_host : Netplay host discovered from scanning.
|
||||
@ -435,160 +630,158 @@ void input_poll_net(void);
|
||||
* @nick : Nickname of user.
|
||||
* @quirks : Netplay quirks required for this session.
|
||||
*
|
||||
* Creates a new netplay handle. A NULL host means we're
|
||||
* hosting (user 1).
|
||||
* Creates a new netplay handle. A NULL server means we're
|
||||
* hosting.
|
||||
*
|
||||
* Returns: new netplay handle.
|
||||
**/
|
||||
* Returns: new netplay data.
|
||||
*/
|
||||
netplay_t *netplay_new(void *direct_host, const char *server, uint16_t port,
|
||||
const char *play_password, const char *spectate_password,
|
||||
unsigned delay_frames, unsigned check_frames, const struct retro_callbacks
|
||||
*cb, bool nat_traversal, const char *nick, uint64_t quirks);
|
||||
unsigned delay_frames, unsigned check_frames,
|
||||
const struct retro_callbacks *cb, bool nat_traversal, const char *nick,
|
||||
uint64_t quirks);
|
||||
|
||||
/**
|
||||
* netplay_free:
|
||||
* netplay_free
|
||||
* @netplay : pointer to netplay object
|
||||
*
|
||||
* Frees netplay handle.
|
||||
**/
|
||||
void netplay_free(netplay_t *handle);
|
||||
* Frees netplay data/
|
||||
*/
|
||||
void netplay_free(netplay_t *netplay);
|
||||
|
||||
|
||||
/***************************************************************
|
||||
* NETPLAY-IO.C
|
||||
**************************************************************/
|
||||
|
||||
/**
|
||||
* netplay_pre_frame:
|
||||
* @netplay : pointer to netplay object
|
||||
* netplay_hangup:
|
||||
*
|
||||
* Pre-frame for Netplay.
|
||||
* Call this before running retro_run().
|
||||
*
|
||||
* Returns: true (1) if the frontend is clear to emulate the frame, false (0)
|
||||
* if we're stalled or paused
|
||||
**/
|
||||
bool netplay_pre_frame(netplay_t *handle);
|
||||
* Disconnects an active Netplay connection due to an error
|
||||
*/
|
||||
void netplay_hangup(netplay_t *netplay, struct netplay_connection *connection);
|
||||
|
||||
/**
|
||||
* netplay_post_frame:
|
||||
* @netplay : pointer to netplay object
|
||||
* netplay_send_cur_input
|
||||
*
|
||||
* Post-frame for Netplay.
|
||||
* We check if we have new input and replay from recorded input.
|
||||
* Call this after running retro_run().
|
||||
**/
|
||||
void netplay_post_frame(netplay_t *handle);
|
||||
|
||||
/**
|
||||
* netplay_frontend_paused
|
||||
* @netplay : pointer to netplay object
|
||||
* @paused : true if frontend is paused
|
||||
* Send the current input frame to a given connection.
|
||||
*
|
||||
* Inform Netplay of the frontend's pause state (paused or otherwise)
|
||||
**/
|
||||
void netplay_frontend_paused(netplay_t *netplay, bool paused);
|
||||
|
||||
/**
|
||||
* netplay_load_savestate
|
||||
* @netplay : pointer to netplay object
|
||||
* @serial_info : the savestate being loaded, NULL means "load it yourself"
|
||||
* @save : whether to save the provided serial_info into the frame buffer
|
||||
*
|
||||
* Inform Netplay of a savestate load and send it to the other side
|
||||
**/
|
||||
void netplay_load_savestate(netplay_t *netplay, retro_ctx_serialize_info_t *serial_info, bool save);
|
||||
|
||||
/**
|
||||
* netplay_disconnect
|
||||
* @netplay : pointer to netplay object
|
||||
*
|
||||
* Disconnect netplay.
|
||||
*
|
||||
* Returns: true (1) if successful. At present, cannot fail.
|
||||
**/
|
||||
bool netplay_disconnect(netplay_t *netplay);
|
||||
|
||||
bool netplay_sync_pre_frame(netplay_t *netplay);
|
||||
|
||||
void netplay_sync_post_frame(netplay_t *netplay);
|
||||
|
||||
/* 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, size_t sim_ptr, bool resim);
|
||||
|
||||
void netplay_log_connection(const struct sockaddr_storage *their_addr,
|
||||
unsigned slot, const char *nick);
|
||||
|
||||
bool netplay_get_nickname(netplay_t *netplay, int fd);
|
||||
|
||||
bool netplay_send_nickname(netplay_t *netplay, int fd);
|
||||
|
||||
/* Various netplay initialization modes: */
|
||||
bool netplay_handshake_init_send(netplay_t *netplay, struct netplay_connection *connection);
|
||||
bool netplay_handshake_init(netplay_t *netplay, struct netplay_connection *connection, bool *had_input);
|
||||
bool netplay_handshake_pre_nick(netplay_t *netplay, struct netplay_connection *connection, bool *had_input);
|
||||
bool netplay_handshake_pre_password(netplay_t *netplay, struct netplay_connection *connection, bool *had_input);
|
||||
bool netplay_handshake_pre_sync(netplay_t *netplay, struct netplay_connection *connection, bool *had_input);
|
||||
|
||||
uint32_t netplay_impl_magic(void);
|
||||
|
||||
bool netplay_is_server(netplay_t* netplay);
|
||||
|
||||
bool netplay_delta_frame_ready(netplay_t *netplay, struct delta_frame *delta, uint32_t frame);
|
||||
|
||||
uint32_t netplay_delta_frame_crc(netplay_t *netplay, struct delta_frame *delta);
|
||||
|
||||
bool netplay_cmd_crc(netplay_t *netplay, struct delta_frame *delta);
|
||||
|
||||
bool netplay_cmd_request_savestate(netplay_t *netplay);
|
||||
|
||||
bool netplay_cmd_mode(netplay_t *netplay,
|
||||
struct netplay_connection *connection,
|
||||
enum rarch_netplay_connection_mode mode);
|
||||
|
||||
* Returns true if successful, false otherwise.
|
||||
*/
|
||||
bool netplay_send_cur_input(netplay_t *netplay,
|
||||
struct netplay_connection *connection);
|
||||
|
||||
int netplay_poll_net_input(netplay_t *netplay, bool block);
|
||||
|
||||
void netplay_hangup(netplay_t *netplay, struct netplay_connection *connection);
|
||||
|
||||
void netplay_update_unread_ptr(netplay_t *netplay);
|
||||
|
||||
bool netplay_flip_port(netplay_t *netplay);
|
||||
|
||||
/**
|
||||
* netplay_send_raw_cmd
|
||||
*
|
||||
* Send a raw Netplay command to the given connection.
|
||||
*
|
||||
* Returns true on success, false on failure.
|
||||
*/
|
||||
bool netplay_send_raw_cmd(netplay_t *netplay,
|
||||
struct netplay_connection *connection, uint32_t cmd, const void *data,
|
||||
size_t size);
|
||||
|
||||
/**
|
||||
* netplay_send_raw_cmd_all
|
||||
*
|
||||
* Send a raw Netplay command to all connections, optionally excluding one
|
||||
* (typically the client that the relevant command came from)
|
||||
*/
|
||||
void netplay_send_raw_cmd_all(netplay_t *netplay,
|
||||
struct netplay_connection *except, uint32_t cmd, const void *data,
|
||||
size_t size);
|
||||
|
||||
bool netplay_try_init_serialization(netplay_t *netplay);
|
||||
/**
|
||||
* netplay_cmd_crc
|
||||
*
|
||||
* Send a CRC command to all active clients.
|
||||
*/
|
||||
bool netplay_cmd_crc(netplay_t *netplay, struct delta_frame *delta);
|
||||
|
||||
/**
|
||||
* netplay_cmd_request_savestate
|
||||
*
|
||||
* Send a savestate request command.
|
||||
*/
|
||||
bool netplay_cmd_request_savestate(netplay_t *netplay);
|
||||
|
||||
/**
|
||||
* netplay_cmd_mode
|
||||
*
|
||||
* Send a mode request command to either play or spectate.
|
||||
*/
|
||||
bool netplay_cmd_mode(netplay_t *netplay,
|
||||
struct netplay_connection *connection,
|
||||
enum rarch_netplay_connection_mode mode);
|
||||
|
||||
/**
|
||||
* netplay_poll_net_input
|
||||
*
|
||||
* Poll input from the network
|
||||
*/
|
||||
int netplay_poll_net_input(netplay_t *netplay, bool block);
|
||||
|
||||
/**
|
||||
* netplay_flip_port
|
||||
*
|
||||
* Should we flip ports 0 and 1?
|
||||
*/
|
||||
bool netplay_flip_port(netplay_t *netplay);
|
||||
|
||||
/**
|
||||
* netplay_announce_nat_traversal
|
||||
*
|
||||
* Announce successful NAT traversal.
|
||||
*/
|
||||
void netplay_announce_nat_traversal(netplay_t *netplay);
|
||||
|
||||
/**
|
||||
* netplay_init_nat_traversal
|
||||
*
|
||||
* Initialize the NAT traversal library and try to open a port
|
||||
*/
|
||||
void netplay_init_nat_traversal(netplay_t *netplay);
|
||||
|
||||
/* DISCOVERY: */
|
||||
|
||||
bool netplay_lan_ad_server(netplay_t *netplay);
|
||||
/***************************************************************
|
||||
* NETPLAY-SYNC.C
|
||||
**************************************************************/
|
||||
|
||||
bool netplay_init_socket_buffer(struct socket_buffer *sbuf, size_t size);
|
||||
/**
|
||||
* netplay_update_unread_ptr
|
||||
*
|
||||
* Update the global unread_ptr and unread_frame_count to correspond to the
|
||||
* earliest unread frame count of any connected player
|
||||
*/
|
||||
void netplay_update_unread_ptr(netplay_t *netplay);
|
||||
|
||||
bool netplay_resize_socket_buffer(struct socket_buffer *sbuf, size_t newsize);
|
||||
/**
|
||||
* netplay_simulate_input
|
||||
* @netplay : pointer to netplay object
|
||||
* @sim_ptr : frame index for which to simulate input
|
||||
* @resim : are we resimulating, or simulating this frame for the
|
||||
* first time?
|
||||
*
|
||||
* "Simulate" input by assuming it hasn't changed since the last read input.
|
||||
*/
|
||||
void netplay_simulate_input(netplay_t *netplay, size_t sim_ptr, bool resim);
|
||||
|
||||
void netplay_deinit_socket_buffer(struct socket_buffer *sbuf);
|
||||
/**
|
||||
* netplay_sync_pre_frame
|
||||
* @netplay : pointer to netplay object
|
||||
*
|
||||
* Pre-frame for Netplay synchronization.
|
||||
*/
|
||||
bool netplay_sync_pre_frame(netplay_t *netplay);
|
||||
|
||||
void netplay_clear_socket_buffer(struct socket_buffer *sbuf);
|
||||
|
||||
bool netplay_send(struct socket_buffer *sbuf, int sockfd, const void *buf, size_t len);
|
||||
|
||||
bool netplay_send_flush(struct socket_buffer *sbuf, int sockfd, bool block);
|
||||
|
||||
ssize_t netplay_recv(struct socket_buffer *sbuf, int sockfd, void *buf, size_t len, bool block);
|
||||
|
||||
void netplay_recv_reset(struct socket_buffer *sbuf);
|
||||
|
||||
void netplay_recv_flush(struct socket_buffer *sbuf);
|
||||
/**
|
||||
* netplay_sync_post_frame
|
||||
* @netplay : pointer to netplay object
|
||||
*
|
||||
* Post-frame for Netplay synchronization.
|
||||
* We check if we have new input and replay from recorded input.
|
||||
*/
|
||||
void netplay_sync_post_frame(netplay_t *netplay);
|
||||
|
||||
#endif
|
||||
|
@ -32,7 +32,8 @@
|
||||
* netplay_update_unread_ptr
|
||||
*
|
||||
* Update the global unread_ptr and unread_frame_count to correspond to the
|
||||
* earliest unread frame count of any connected player */
|
||||
* earliest unread frame count of any connected player
|
||||
*/
|
||||
void netplay_update_unread_ptr(netplay_t *netplay)
|
||||
{
|
||||
if (netplay->is_server && !netplay->connected_players)
|
||||
@ -70,7 +71,7 @@ void netplay_update_unread_ptr(netplay_t *netplay)
|
||||
}
|
||||
|
||||
/**
|
||||
* netplay_simulate_input:
|
||||
* netplay_simulate_input
|
||||
* @netplay : pointer to netplay object
|
||||
* @sim_ptr : frame index for which to simulate input
|
||||
* @resim : are we resimulating, or simulating this frame for the
|
||||
@ -162,11 +163,11 @@ static void netplay_handle_frame_hash(netplay_t *netplay, struct delta_frame *de
|
||||
}
|
||||
|
||||
/**
|
||||
* netplay_sync_pre_frame:
|
||||
* netplay_sync_pre_frame
|
||||
* @netplay : pointer to netplay object
|
||||
*
|
||||
* Pre-frame for Netplay synchronization.
|
||||
**/
|
||||
*/
|
||||
bool netplay_sync_pre_frame(netplay_t *netplay)
|
||||
{
|
||||
retro_ctx_serialize_info_t serial_info;
|
||||
@ -329,12 +330,12 @@ process:
|
||||
}
|
||||
|
||||
/**
|
||||
* netplay_sync_post_frame:
|
||||
* netplay_sync_post_frame
|
||||
* @netplay : pointer to netplay object
|
||||
*
|
||||
* Post-frame for Netplay synchronization.
|
||||
* We check if we have new input and replay from recorded input.
|
||||
**/
|
||||
*/
|
||||
void netplay_sync_post_frame(netplay_t *netplay)
|
||||
{
|
||||
netplay->self_ptr = NEXT_PTR(netplay->self_ptr);
|
||||
|
Loading…
x
Reference in New Issue
Block a user