mirror of
https://github.com/CTCaer/RetroArch.git
synced 2024-12-30 06:43:53 +00:00
Merge pull request #3747 from GregorR/netplay-platform-quirks
Netplay platform quirks
This commit is contained in:
commit
151046db5a
@ -1471,6 +1471,10 @@ bool init_netplay(bool is_spectate, const char *server, unsigned port)
|
|||||||
quirks |= NETPLAY_QUIRK_NO_TRANSMISSION;
|
quirks |= NETPLAY_QUIRK_NO_TRANSMISSION;
|
||||||
if (serialization_quirks & NETPLAY_QUIRK_MAP_INITIALIZATION)
|
if (serialization_quirks & NETPLAY_QUIRK_MAP_INITIALIZATION)
|
||||||
quirks |= NETPLAY_QUIRK_INITIALIZATION;
|
quirks |= NETPLAY_QUIRK_INITIALIZATION;
|
||||||
|
if (serialization_quirks & NETPLAY_QUIRK_MAP_ENDIAN_DEPENDENT)
|
||||||
|
quirks |= NETPLAY_QUIRK_ENDIAN_DEPENDENT;
|
||||||
|
if (serialization_quirks & NETPLAY_QUIRK_MAP_PLATFORM_DEPENDENT)
|
||||||
|
quirks |= NETPLAY_QUIRK_PLATFORM_DEPENDENT;
|
||||||
|
|
||||||
if (netplay_is_client)
|
if (netplay_is_client)
|
||||||
{
|
{
|
||||||
|
@ -125,24 +125,61 @@ uint32_t netplay_impl_magic(void)
|
|||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool netplay_send_info(netplay_t *netplay)
|
/**
|
||||||
|
* netplay_platform_magic
|
||||||
|
*
|
||||||
|
* Just enough info to tell us if our platforms mismatch: Endianness and a
|
||||||
|
* couple of type sizes.
|
||||||
|
*
|
||||||
|
* Format:
|
||||||
|
* bit 31: Reserved
|
||||||
|
* bit 30: 1 for big endian
|
||||||
|
* bits 29-15: sizeof(size_t)
|
||||||
|
* bits 14-0: sizeof(long)
|
||||||
|
*/
|
||||||
|
static uint32_t netplay_platform_magic(void)
|
||||||
|
{
|
||||||
|
uint32_t ret =
|
||||||
|
((1 == htonl(1)) << 30)
|
||||||
|
|(sizeof(size_t) << 15)
|
||||||
|
|(sizeof(long));
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* netplay_endian_mismatch
|
||||||
|
*
|
||||||
|
* Do the platform magics mismatch on endianness?
|
||||||
|
*/
|
||||||
|
static bool netplay_endian_mismatch(uint32_t pma, uint32_t pmb)
|
||||||
|
{
|
||||||
|
uint32_t ebit = (1<<30);
|
||||||
|
return (pma & ebit) != (pmb & ebit);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool netplay_handshake(netplay_t *netplay)
|
||||||
{
|
{
|
||||||
unsigned sram_size, remote_sram_size;
|
unsigned sram_size, remote_sram_size;
|
||||||
retro_ctx_memory_info_t mem_info;
|
retro_ctx_memory_info_t mem_info;
|
||||||
char msg[512] = {0};
|
char msg[512] = {0};
|
||||||
uint32_t *content_crc_ptr = NULL;
|
uint32_t *content_crc_ptr = NULL;
|
||||||
void *sram = NULL;
|
void *sram = NULL;
|
||||||
uint32_t header[3] = {0};
|
uint32_t header[4] = {0};
|
||||||
size_t i;
|
size_t i;
|
||||||
|
uint32_t local_pmagic, remote_pmagic;
|
||||||
|
bool is_server = netplay->is_server;
|
||||||
|
|
||||||
mem_info.id = RETRO_MEMORY_SAVE_RAM;
|
mem_info.id = RETRO_MEMORY_SAVE_RAM;
|
||||||
|
|
||||||
core_get_memory(&mem_info);
|
core_get_memory(&mem_info);
|
||||||
content_get_crc(&content_crc_ptr);
|
content_get_crc(&content_crc_ptr);
|
||||||
|
|
||||||
|
local_pmagic = netplay_platform_magic();
|
||||||
|
|
||||||
header[0] = htonl(*content_crc_ptr);
|
header[0] = htonl(*content_crc_ptr);
|
||||||
header[1] = htonl(netplay_impl_magic());
|
header[1] = htonl(netplay_impl_magic());
|
||||||
header[2] = htonl(mem_info.size);
|
header[2] = htonl(mem_info.size);
|
||||||
|
header[3] = htonl(local_pmagic);
|
||||||
|
|
||||||
if (!socket_send_all_blocking(netplay->fd, header, sizeof(header), false))
|
if (!socket_send_all_blocking(netplay->fd, header, sizeof(header), false))
|
||||||
return false;
|
return false;
|
||||||
@ -176,62 +213,116 @@ bool netplay_send_info(netplay_t *netplay)
|
|||||||
RARCH_WARN("Content SRAM sizes do not correspond.\n");
|
RARCH_WARN("Content SRAM sizes do not correspond.\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!netplay_send_nickname(netplay, netplay->fd))
|
/* We only care about platform magic if our core is quirky */
|
||||||
|
remote_pmagic = ntohl(header[3]);
|
||||||
|
if ((netplay->quirks & NETPLAY_QUIRK_ENDIAN_DEPENDENT) &&
|
||||||
|
netplay_endian_mismatch(local_pmagic, remote_pmagic))
|
||||||
{
|
{
|
||||||
RARCH_ERR("%s\n",
|
RARCH_ERR("Endianness mismatch with an endian-sensitive core.\n");
|
||||||
msg_hash_to_str(MSG_FAILED_TO_SEND_NICKNAME_TO_HOST));
|
return false;
|
||||||
|
}
|
||||||
|
if ((netplay->quirks & NETPLAY_QUIRK_PLATFORM_DEPENDENT) &&
|
||||||
|
(local_pmagic != remote_pmagic))
|
||||||
|
{
|
||||||
|
RARCH_ERR("Platform mismatch with a platform-sensitive core.\n");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Get SRAM data from User 1. */
|
/* Client sends nickname first, server replies with nickname */
|
||||||
if (sram_size != 0 && sram_size == remote_sram_size)
|
if (!is_server)
|
||||||
{
|
{
|
||||||
sram = mem_info.data;
|
if (!netplay_send_nickname(netplay, netplay->fd))
|
||||||
|
|
||||||
if (!socket_receive_all_blocking(netplay->fd, sram, sram_size))
|
|
||||||
{
|
{
|
||||||
RARCH_ERR("%s\n",
|
RARCH_ERR("%s\n",
|
||||||
msg_hash_to_str(MSG_FAILED_TO_RECEIVE_SRAM_DATA_FROM_HOST));
|
msg_hash_to_str(MSG_FAILED_TO_SEND_NICKNAME_TO_HOST));
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!netplay_get_nickname(netplay, netplay->fd))
|
||||||
|
{
|
||||||
|
if (is_server)
|
||||||
|
RARCH_ERR("%s\n",
|
||||||
|
msg_hash_to_str(MSG_FAILED_TO_GET_NICKNAME_FROM_CLIENT));
|
||||||
|
else
|
||||||
|
RARCH_ERR("%s\n",
|
||||||
|
msg_hash_to_str(MSG_FAILED_TO_RECEIVE_NICKNAME_FROM_HOST));
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (is_server)
|
||||||
|
{
|
||||||
|
if (!netplay_send_nickname(netplay, netplay->fd))
|
||||||
|
{
|
||||||
|
RARCH_ERR("%s\n",
|
||||||
|
msg_hash_to_str(MSG_FAILED_TO_SEND_NICKNAME_TO_CLIENT));
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Server sends SRAM, client receives */
|
||||||
|
if (is_server)
|
||||||
|
{
|
||||||
|
/* Send SRAM data to the client */
|
||||||
|
sram = mem_info.data;
|
||||||
|
|
||||||
|
if (!socket_send_all_blocking(netplay->fd, sram, sram_size, false))
|
||||||
|
{
|
||||||
|
RARCH_ERR("%s\n",
|
||||||
|
msg_hash_to_str(MSG_FAILED_TO_SEND_SRAM_DATA_TO_CLIENT));
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
else if (remote_sram_size != 0)
|
else
|
||||||
{
|
{
|
||||||
/* We can't load this, but we still need to get rid of the data */
|
/* Get SRAM data from User 1. */
|
||||||
uint32_t quickbuf;
|
if (sram_size != 0 && sram_size == remote_sram_size)
|
||||||
while (remote_sram_size > 0)
|
|
||||||
{
|
{
|
||||||
if (!socket_receive_all_blocking(netplay->fd, &quickbuf, (remote_sram_size > sizeof(uint32_t)) ? sizeof(uint32_t) : remote_sram_size))
|
sram = mem_info.data;
|
||||||
|
|
||||||
|
if (!socket_receive_all_blocking(netplay->fd, sram, sram_size))
|
||||||
{
|
{
|
||||||
RARCH_ERR("%s\n",
|
RARCH_ERR("%s\n",
|
||||||
msg_hash_to_str(MSG_FAILED_TO_RECEIVE_SRAM_DATA_FROM_HOST));
|
msg_hash_to_str(MSG_FAILED_TO_RECEIVE_SRAM_DATA_FROM_HOST));
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
if (remote_sram_size > sizeof(uint32_t))
|
|
||||||
remote_sram_size -= sizeof(uint32_t);
|
}
|
||||||
else
|
else if (remote_sram_size != 0)
|
||||||
remote_sram_size = 0;
|
{
|
||||||
|
/* We can't load this, but we still need to get rid of the data */
|
||||||
|
uint32_t quickbuf;
|
||||||
|
while (remote_sram_size > 0)
|
||||||
|
{
|
||||||
|
if (!socket_receive_all_blocking(netplay->fd, &quickbuf, (remote_sram_size > sizeof(uint32_t)) ? sizeof(uint32_t) : remote_sram_size))
|
||||||
|
{
|
||||||
|
RARCH_ERR("%s\n",
|
||||||
|
msg_hash_to_str(MSG_FAILED_TO_RECEIVE_SRAM_DATA_FROM_HOST));
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (remote_sram_size > sizeof(uint32_t))
|
||||||
|
remote_sram_size -= sizeof(uint32_t);
|
||||||
|
else
|
||||||
|
remote_sram_size = 0;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!netplay_get_nickname(netplay, netplay->fd))
|
|
||||||
{
|
|
||||||
RARCH_ERR("%s\n",
|
|
||||||
msg_hash_to_str(MSG_FAILED_TO_RECEIVE_NICKNAME_FROM_HOST));
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Reset our frame count so it's consistent with the server */
|
/* Reset our frame count so it's consistent with the server */
|
||||||
netplay->self_frame_count = netplay->read_frame_count = netplay->other_frame_count = 0;
|
netplay->self_frame_count = netplay->other_frame_count = 0;
|
||||||
|
netplay->read_frame_count = 1;
|
||||||
for (i = 0; i < netplay->buffer_size; i++)
|
for (i = 0; i < netplay->buffer_size; i++)
|
||||||
{
|
{
|
||||||
netplay->buffer[i].used = false;
|
netplay->buffer[i].used = false;
|
||||||
if (i == netplay->self_ptr)
|
if (i == netplay->self_ptr)
|
||||||
{
|
{
|
||||||
netplay_delta_frame_ready(netplay, &netplay->buffer[i], 0);
|
netplay_delta_frame_ready(netplay, &netplay->buffer[i], 0);
|
||||||
netplay->read_ptr = netplay->other_ptr = i;
|
netplay->buffer[i].have_remote = true;
|
||||||
|
netplay->other_ptr = i;
|
||||||
|
netplay->read_ptr = NEXT_PTR(i);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@ -239,108 +330,19 @@ bool netplay_send_info(netplay_t *netplay)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
snprintf(msg, sizeof(msg), "%s: \"%s\"",
|
if (is_server)
|
||||||
msg_hash_to_str(MSG_CONNECTED_TO),
|
|
||||||
netplay->other_nick);
|
|
||||||
RARCH_LOG("%s\n", msg);
|
|
||||||
runloop_msg_queue_push(msg, 1, 180, false);
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool netplay_get_info(netplay_t *netplay)
|
|
||||||
{
|
|
||||||
unsigned sram_size, remote_sram_size;
|
|
||||||
uint32_t header[3];
|
|
||||||
retro_ctx_memory_info_t mem_info;
|
|
||||||
uint32_t *content_crc_ptr = NULL;
|
|
||||||
const void *sram = NULL;
|
|
||||||
size_t i;
|
|
||||||
|
|
||||||
/* FIXME: There's a huge amount of duplication between send_info and
|
|
||||||
* get_info */
|
|
||||||
|
|
||||||
mem_info.id = RETRO_MEMORY_SAVE_RAM;
|
|
||||||
|
|
||||||
core_get_memory(&mem_info);
|
|
||||||
content_get_crc(&content_crc_ptr);
|
|
||||||
|
|
||||||
header[0] = htonl(*content_crc_ptr);
|
|
||||||
header[1] = htonl(netplay_impl_magic());
|
|
||||||
header[2] = htonl(mem_info.size);
|
|
||||||
|
|
||||||
if (!socket_send_all_blocking(netplay->fd, header, sizeof(header), false))
|
|
||||||
return false;
|
|
||||||
|
|
||||||
if (!socket_receive_all_blocking(netplay->fd, header, sizeof(header)))
|
|
||||||
{
|
{
|
||||||
RARCH_ERR("%s\n",
|
netplay_log_connection(&netplay->other_addr, 0, netplay->other_nick);
|
||||||
msg_hash_to_str(MSG_FAILED_TO_RECEIVE_HEADER_FROM_CLIENT));
|
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
|
else
|
||||||
if (*content_crc_ptr != ntohl(header[0]))
|
|
||||||
{
|
{
|
||||||
RARCH_ERR("%s\n", msg_hash_to_str(MSG_CONTENT_CRC32S_DIFFER));
|
snprintf(msg, sizeof(msg), "%s: \"%s\"",
|
||||||
return false;
|
msg_hash_to_str(MSG_CONNECTED_TO),
|
||||||
|
netplay->other_nick);
|
||||||
|
RARCH_LOG("%s\n", msg);
|
||||||
|
runloop_msg_queue_push(msg, 1, 180, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (netplay_impl_magic() != ntohl(header[1]))
|
|
||||||
{
|
|
||||||
RARCH_ERR("Implementations differ, make sure you're using exact same "
|
|
||||||
"libretro implementations and RetroArch version.\n");
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
sram_size = mem_info.size;
|
|
||||||
remote_sram_size = ntohl(header[2]);
|
|
||||||
if (sram_size != 0 && remote_sram_size != 0 && sram_size != remote_sram_size)
|
|
||||||
{
|
|
||||||
RARCH_WARN("Content SRAM sizes do not correspond.\n");
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!netplay_get_nickname(netplay, netplay->fd))
|
|
||||||
{
|
|
||||||
RARCH_ERR("%s\n",
|
|
||||||
msg_hash_to_str(MSG_FAILED_TO_GET_NICKNAME_FROM_CLIENT));
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Send SRAM data to our User 2. */
|
|
||||||
sram = mem_info.data;
|
|
||||||
|
|
||||||
if (!socket_send_all_blocking(netplay->fd, sram, sram_size, false))
|
|
||||||
{
|
|
||||||
RARCH_ERR("%s\n",
|
|
||||||
msg_hash_to_str(MSG_FAILED_TO_SEND_SRAM_DATA_TO_CLIENT));
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!netplay_send_nickname(netplay, netplay->fd))
|
|
||||||
{
|
|
||||||
RARCH_ERR("%s\n",
|
|
||||||
msg_hash_to_str(MSG_FAILED_TO_SEND_NICKNAME_TO_CLIENT));
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Reset our frame count so it's consistent with the client */
|
|
||||||
netplay->self_frame_count = netplay->read_frame_count = netplay->other_frame_count = 0;
|
|
||||||
for (i = 0; i < netplay->buffer_size; i++)
|
|
||||||
{
|
|
||||||
netplay->buffer[i].used = false;
|
|
||||||
if (i == netplay->self_ptr)
|
|
||||||
{
|
|
||||||
netplay_delta_frame_ready(netplay, &netplay->buffer[i], 0);
|
|
||||||
netplay->read_ptr = netplay->other_ptr = i;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
netplay->buffer[i].used = false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
netplay_log_connection(&netplay->other_addr, 0, netplay->other_nick);
|
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -81,7 +81,7 @@ static bool netplay_net_pre_frame(netplay_t *netplay)
|
|||||||
serial_info.size = netplay->state_size;
|
serial_info.size = netplay->state_size;
|
||||||
|
|
||||||
memset(serial_info.data, 0, serial_info.size);
|
memset(serial_info.data, 0, serial_info.size);
|
||||||
if (netplay->quirks & NETPLAY_QUIRK_INITIALIZATION)
|
if ((netplay->quirks & NETPLAY_QUIRK_INITIALIZATION) || netplay->self_frame_count == 0)
|
||||||
{
|
{
|
||||||
/* Don't serialize until it's safe */
|
/* Don't serialize until it's safe */
|
||||||
}
|
}
|
||||||
@ -105,6 +105,7 @@ static bool netplay_net_pre_frame(netplay_t *netplay)
|
|||||||
|
|
||||||
/* If we can't transmit savestates, we must stall until the client is ready */
|
/* If we can't transmit savestates, we must stall until the client is ready */
|
||||||
if (!netplay->has_connection &&
|
if (!netplay->has_connection &&
|
||||||
|
netplay->self_frame_count > 0 &&
|
||||||
(netplay->quirks & (NETPLAY_QUIRK_NO_SAVESTATES|NETPLAY_QUIRK_NO_TRANSMISSION)))
|
(netplay->quirks & (NETPLAY_QUIRK_NO_SAVESTATES|NETPLAY_QUIRK_NO_TRANSMISSION)))
|
||||||
netplay->stall = RARCH_NETPLAY_STALL_NO_CONNECTION;
|
netplay->stall = RARCH_NETPLAY_STALL_NO_CONNECTION;
|
||||||
}
|
}
|
||||||
@ -148,14 +149,23 @@ static bool netplay_net_pre_frame(netplay_t *netplay)
|
|||||||
RARCH_WARN("Cannot set Netplay port to close-on-exec. It may fail to reopen if the client disconnects.\n");
|
RARCH_WARN("Cannot set Netplay port to close-on-exec. It may fail to reopen if the client disconnects.\n");
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* Connection header */
|
/* Establish the connection */
|
||||||
if (netplay_get_info(netplay))
|
if (netplay_handshake(netplay))
|
||||||
{
|
{
|
||||||
netplay->has_connection = true;
|
netplay->has_connection = true;
|
||||||
|
|
||||||
/* Send them the savestate */
|
/* Send them the savestate */
|
||||||
if (!(netplay->quirks & (NETPLAY_QUIRK_NO_SAVESTATES|NETPLAY_QUIRK_NO_TRANSMISSION)))
|
if (!(netplay->quirks & (NETPLAY_QUIRK_NO_SAVESTATES|NETPLAY_QUIRK_NO_TRANSMISSION)))
|
||||||
netplay_load_savestate(netplay, NULL, true);
|
{
|
||||||
|
netplay->force_send_savestate = true;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
/* Because the first frame isn't serialized, we're actually at
|
||||||
|
* frame 1 */
|
||||||
|
netplay->self_ptr = NEXT_PTR(netplay->self_ptr);
|
||||||
|
netplay->self_frame_count = 1;
|
||||||
|
}
|
||||||
|
|
||||||
/* And expect the current frame from the other side */
|
/* And expect the current frame from the other side */
|
||||||
netplay->read_frame_count = netplay->other_frame_count = netplay->self_frame_count;
|
netplay->read_frame_count = netplay->other_frame_count = netplay->self_frame_count;
|
||||||
@ -322,7 +332,7 @@ static bool netplay_net_info_cb(netplay_t* netplay, unsigned frames)
|
|||||||
{
|
{
|
||||||
if (!netplay_is_server(netplay))
|
if (!netplay_is_server(netplay))
|
||||||
{
|
{
|
||||||
if (!netplay_send_info(netplay))
|
if (!netplay_handshake(netplay))
|
||||||
return false;
|
return false;
|
||||||
netplay->has_connection = true;
|
netplay->has_connection = true;
|
||||||
}
|
}
|
||||||
|
@ -35,7 +35,7 @@
|
|||||||
#define MAX_SPECTATORS 16
|
#define MAX_SPECTATORS 16
|
||||||
#define RARCH_DEFAULT_PORT 55435
|
#define RARCH_DEFAULT_PORT 55435
|
||||||
|
|
||||||
#define NETPLAY_PROTOCOL_VERSION 1
|
#define NETPLAY_PROTOCOL_VERSION 2
|
||||||
|
|
||||||
#define PREV_PTR(x) ((x) == 0 ? netplay->buffer_size - 1 : (x) - 1)
|
#define PREV_PTR(x) ((x) == 0 ? netplay->buffer_size - 1 : (x) - 1)
|
||||||
#define NEXT_PTR(x) ((x + 1) % netplay->buffer_size)
|
#define NEXT_PTR(x) ((x + 1) % netplay->buffer_size)
|
||||||
@ -45,6 +45,8 @@
|
|||||||
#define NETPLAY_QUIRK_NO_SAVESTATES (1<<0)
|
#define NETPLAY_QUIRK_NO_SAVESTATES (1<<0)
|
||||||
#define NETPLAY_QUIRK_NO_TRANSMISSION (1<<1)
|
#define NETPLAY_QUIRK_NO_TRANSMISSION (1<<1)
|
||||||
#define NETPLAY_QUIRK_INITIALIZATION (1<<2)
|
#define NETPLAY_QUIRK_INITIALIZATION (1<<2)
|
||||||
|
#define NETPLAY_QUIRK_ENDIAN_DEPENDENT (1<<3)
|
||||||
|
#define NETPLAY_QUIRK_PLATFORM_DEPENDENT (1<<4)
|
||||||
|
|
||||||
/* Mapping of serialization quirks to netplay quirks. */
|
/* Mapping of serialization quirks to netplay quirks. */
|
||||||
#define NETPLAY_QUIRK_MAP_UNDERSTOOD \
|
#define NETPLAY_QUIRK_MAP_UNDERSTOOD \
|
||||||
@ -56,11 +58,13 @@
|
|||||||
#define NETPLAY_QUIRK_MAP_NO_SAVESTATES \
|
#define NETPLAY_QUIRK_MAP_NO_SAVESTATES \
|
||||||
(RETRO_SERIALIZATION_QUIRK_INCOMPLETE)
|
(RETRO_SERIALIZATION_QUIRK_INCOMPLETE)
|
||||||
#define NETPLAY_QUIRK_MAP_NO_TRANSMISSION \
|
#define NETPLAY_QUIRK_MAP_NO_TRANSMISSION \
|
||||||
(RETRO_SERIALIZATION_QUIRK_SINGLE_SESSION \
|
(RETRO_SERIALIZATION_QUIRK_SINGLE_SESSION)
|
||||||
|RETRO_SERIALIZATION_QUIRK_ENDIAN_DEPENDENT \
|
|
||||||
|RETRO_SERIALIZATION_QUIRK_PLATFORM_DEPENDENT)
|
|
||||||
#define NETPLAY_QUIRK_MAP_INITIALIZATION \
|
#define NETPLAY_QUIRK_MAP_INITIALIZATION \
|
||||||
(RETRO_SERIALIZATION_QUIRK_MUST_INITIALIZE)
|
(RETRO_SERIALIZATION_QUIRK_MUST_INITIALIZE)
|
||||||
|
#define NETPLAY_QUIRK_MAP_ENDIAN_DEPENDENT \
|
||||||
|
(RETRO_SERIALIZATION_QUIRK_ENDIAN_DEPENDENT)
|
||||||
|
#define NETPLAY_QUIRK_MAP_PLATFORM_DEPENDENT \
|
||||||
|
(RETRO_SERIALIZATION_QUIRK_PLATFORM_DEPENDENT)
|
||||||
|
|
||||||
struct delta_frame
|
struct delta_frame
|
||||||
{
|
{
|
||||||
@ -214,14 +218,10 @@ bool netplay_get_nickname(netplay_t *netplay, int fd);
|
|||||||
|
|
||||||
bool netplay_send_nickname(netplay_t *netplay, int fd);
|
bool netplay_send_nickname(netplay_t *netplay, int fd);
|
||||||
|
|
||||||
bool netplay_send_info(netplay_t *netplay);
|
bool netplay_handshake(netplay_t *netplay);
|
||||||
|
|
||||||
uint32_t netplay_impl_magic(void);
|
uint32_t netplay_impl_magic(void);
|
||||||
|
|
||||||
bool netplay_send_info(netplay_t *netplay);
|
|
||||||
|
|
||||||
bool netplay_get_info(netplay_t *netplay);
|
|
||||||
|
|
||||||
bool netplay_is_server(netplay_t* netplay);
|
bool netplay_is_server(netplay_t* netplay);
|
||||||
|
|
||||||
bool netplay_is_spectate(netplay_t* netplay);
|
bool netplay_is_spectate(netplay_t* netplay);
|
||||||
|
Loading…
Reference in New Issue
Block a user