Merge pull request #14054 from Cthulhu-throwaway/netplay-refactor
(Netplay) Some refactoring and fixes
This commit is contained in:
commit
838e5117d0
|
@ -5959,113 +5959,109 @@ static int action_ok_wifi_disconnect(const char *path,
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
static int action_ok_netplay_connect_room(const char *path,
|
static int action_ok_netplay_connect_room(const char *path, const char *label,
|
||||||
const char *label, unsigned type, size_t idx, size_t entry_idx)
|
unsigned type, size_t idx, size_t entry_idx)
|
||||||
{
|
{
|
||||||
char tmp_hostname[4115];
|
char hostname[512];
|
||||||
|
struct netplay_room *room;
|
||||||
net_driver_state_t *net_st = networking_state_get_ptr();
|
net_driver_state_t *net_st = networking_state_get_ptr();
|
||||||
unsigned room_index = type - MENU_SETTINGS_NETPLAY_ROOMS_START;
|
unsigned room_index = type - MENU_SETTINGS_NETPLAY_ROOMS_START;
|
||||||
|
|
||||||
if (room_index >= (unsigned)net_st->room_count)
|
if (room_index >= (unsigned)net_st->room_count)
|
||||||
return menu_cbs_exit();
|
return menu_cbs_exit();
|
||||||
|
|
||||||
tmp_hostname[0] = '\0';
|
room = &net_st->room_list[room_index];
|
||||||
|
|
||||||
if (netplay_driver_ctl(RARCH_NETPLAY_CTL_IS_DATA_INITED, NULL))
|
if (netplay_driver_ctl(RARCH_NETPLAY_CTL_IS_DATA_INITED, NULL))
|
||||||
generic_action_ok_command(CMD_EVENT_NETPLAY_DEINIT);
|
generic_action_ok_command(CMD_EVENT_NETPLAY_DEINIT);
|
||||||
|
|
||||||
netplay_driver_ctl(RARCH_NETPLAY_CTL_ENABLE_CLIENT, NULL);
|
netplay_driver_ctl(RARCH_NETPLAY_CTL_ENABLE_CLIENT, NULL);
|
||||||
|
|
||||||
if (net_st->room_list[room_index].host_method == NETPLAY_HOST_METHOD_MITM)
|
if (room->host_method == NETPLAY_HOST_METHOD_MITM)
|
||||||
snprintf(tmp_hostname,
|
snprintf(hostname, sizeof(hostname), "%s|%d|%s",
|
||||||
sizeof(tmp_hostname),
|
room->mitm_address, room->mitm_port, room->mitm_session);
|
||||||
"%s|%d|%s",
|
|
||||||
net_st->room_list[room_index].mitm_address,
|
|
||||||
net_st->room_list[room_index].mitm_port,
|
|
||||||
net_st->room_list[room_index].mitm_session);
|
|
||||||
else
|
else
|
||||||
snprintf(tmp_hostname,
|
snprintf(hostname, sizeof(hostname), "%s|%d", room->address, room->port);
|
||||||
sizeof(tmp_hostname),
|
|
||||||
"%s|%d",
|
|
||||||
net_st->room_list[room_index].address,
|
|
||||||
net_st->room_list[room_index].port);
|
|
||||||
|
|
||||||
#if 0
|
#if 0
|
||||||
RARCH_LOG("[lobby] connecting to: %s with game: %s/%08x\n",
|
RARCH_LOG("[Lobby] Connecting to: %s with game: %s/%08x\n",
|
||||||
tmp_hostname,
|
hostname, room->gamename, room->gamecrc);
|
||||||
net_st->room_list[room_index].gamename,
|
|
||||||
net_st->room_list[room_index].gamecrc);
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
task_push_netplay_crc_scan(
|
task_push_netplay_crc_scan(room->gamecrc, room->gamename, hostname,
|
||||||
net_st->room_list[room_index].gamecrc,
|
room->corename, room->subsystem_name);
|
||||||
net_st->room_list[room_index].gamename,
|
|
||||||
tmp_hostname,
|
|
||||||
net_st->room_list[room_index].corename,
|
|
||||||
net_st->room_list[room_index].subsystem_name);
|
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void netplay_refresh_rooms_cb(retro_task_t *task,
|
static void netplay_refresh_rooms_cb(retro_task_t *task, void *task_data,
|
||||||
void *task_data, void *user_data, const char *error)
|
void *user_data, const char *error)
|
||||||
{
|
{
|
||||||
char *new_data = NULL;
|
char *room_data = NULL;
|
||||||
const char *path = NULL;
|
const char *path = NULL;
|
||||||
const char *label = NULL;
|
const char *label = NULL;
|
||||||
unsigned menu_type = 0;
|
unsigned menu_type = 0;
|
||||||
enum msg_hash_enums enum_idx = MSG_UNKNOWN;
|
enum msg_hash_enums enum_idx = MSG_UNKNOWN;
|
||||||
net_driver_state_t *net_st = networking_state_get_ptr();
|
|
||||||
http_transfer_data_t *data = (http_transfer_data_t*)task_data;
|
|
||||||
bool refresh = false;
|
bool refresh = false;
|
||||||
|
http_transfer_data_t *data = (http_transfer_data_t*)task_data;
|
||||||
|
net_driver_state_t *net_st = networking_state_get_ptr();
|
||||||
|
|
||||||
|
free(net_st->room_list);
|
||||||
|
net_st->room_list = NULL;
|
||||||
|
net_st->room_count = 0;
|
||||||
|
|
||||||
menu_entries_get_last_stack(&path, &label, &menu_type, &enum_idx, NULL);
|
menu_entries_get_last_stack(&path, &label, &menu_type, &enum_idx, NULL);
|
||||||
|
|
||||||
/* Don't push the results if we left the netplay menu */
|
/* Don't push the results if we left the netplay menu */
|
||||||
if (!string_is_equal(label,
|
if (!string_is_equal(label, msg_hash_to_str(MENU_ENUM_LABEL_NETPLAY_TAB)) &&
|
||||||
msg_hash_to_str(MENU_ENUM_LABEL_NETPLAY_TAB)) &&
|
!string_is_equal(label, msg_hash_to_str(MENU_ENUM_LABEL_NETPLAY)))
|
||||||
!string_is_equal(label,
|
|
||||||
msg_hash_to_str(MENU_ENUM_LABEL_NETPLAY)))
|
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (error)
|
if (error)
|
||||||
{
|
{
|
||||||
RARCH_ERR("%s: %s\n", msg_hash_to_str(MSG_DOWNLOAD_FAILED),
|
RARCH_ERR("%s: %s\n", msg_hash_to_str(MSG_DOWNLOAD_FAILED), error);
|
||||||
error);
|
goto done;
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
if (!data || !data->data || !data->len || data->status != 200)
|
if (!data || !data->data || !data->len || data->status != 200)
|
||||||
{
|
{
|
||||||
RARCH_ERR("%s\n", msg_hash_to_str(MSG_DOWNLOAD_FAILED));
|
RARCH_ERR("%s\n", msg_hash_to_str(MSG_DOWNLOAD_FAILED));
|
||||||
return;
|
goto done;
|
||||||
}
|
}
|
||||||
|
|
||||||
new_data = (char*)realloc(data->data, data->len + 1);
|
room_data = (char*)malloc(data->len + 1);
|
||||||
if (!new_data)
|
if (!room_data)
|
||||||
return;
|
goto done;
|
||||||
data->data = new_data;
|
memcpy(room_data, data->data, data->len);
|
||||||
data->data[data->len] = '\0';
|
room_data[data->len] = '\0';
|
||||||
|
|
||||||
if (net_st->room_list)
|
if (!string_is_empty(room_data))
|
||||||
free(net_st->room_list);
|
|
||||||
|
|
||||||
net_st->room_list = NULL;
|
|
||||||
net_st->room_count = 0;
|
|
||||||
|
|
||||||
if (!string_is_empty(data->data))
|
|
||||||
{
|
{
|
||||||
int i;
|
int room_count;
|
||||||
|
|
||||||
netplay_rooms_parse(data->data);
|
netplay_rooms_parse(room_data);
|
||||||
|
|
||||||
net_st->room_count = netplay_rooms_get_count();
|
room_count = netplay_rooms_get_count();
|
||||||
net_st->room_list = (struct netplay_room*)calloc(net_st->room_count,
|
if (room_count > 0)
|
||||||
sizeof(*net_st->room_list));
|
{
|
||||||
|
net_st->room_list = (struct netplay_room*)calloc(room_count,
|
||||||
for (i = 0; i < net_st->room_count; i++)
|
|
||||||
memcpy(&net_st->room_list[i], netplay_room_get(i),
|
|
||||||
sizeof(*net_st->room_list));
|
sizeof(*net_st->room_list));
|
||||||
|
if (net_st->room_list)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
|
||||||
|
net_st->room_count = room_count;
|
||||||
|
for (i = 0; i < room_count; i++)
|
||||||
|
memcpy(&net_st->room_list[i], netplay_room_get(i),
|
||||||
|
sizeof(*net_st->room_list));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
netplay_rooms_free();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
free(room_data);
|
||||||
|
|
||||||
|
done:
|
||||||
menu_entries_ctl(MENU_ENTRIES_CTL_SET_REFRESH, &refresh);
|
menu_entries_ctl(MENU_ENTRIES_CTL_SET_REFRESH, &refresh);
|
||||||
menu_driver_ctl(RARCH_MENU_CTL_SET_PREVENT_POPULATE, NULL);
|
menu_driver_ctl(RARCH_MENU_CTL_SET_PREVENT_POPULATE, NULL);
|
||||||
}
|
}
|
||||||
|
@ -6073,92 +6069,81 @@ static void netplay_refresh_rooms_cb(retro_task_t *task,
|
||||||
static int action_ok_push_netplay_refresh_rooms(const char *path,
|
static int action_ok_push_netplay_refresh_rooms(const char *path,
|
||||||
const char *label, unsigned type, size_t idx, size_t entry_idx)
|
const char *label, unsigned type, size_t idx, size_t entry_idx)
|
||||||
{
|
{
|
||||||
#ifndef NETPLAY_TEST_BUILD
|
task_push_http_transfer(FILE_PATH_LOBBY_LIBRETRO_URL "list", true, NULL,
|
||||||
const char *url = "http://lobby.libretro.com/list";
|
netplay_refresh_rooms_cb, NULL);
|
||||||
#else
|
|
||||||
const char *url = "http://lobbytest.libretro.com/list";
|
|
||||||
#endif
|
|
||||||
|
|
||||||
task_push_http_transfer(url, true, NULL, netplay_refresh_rooms_cb, NULL);
|
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef HAVE_NETPLAYDISCOVERY
|
#ifdef HAVE_NETPLAYDISCOVERY
|
||||||
static void netplay_refresh_lan_cb(retro_task_t *task,
|
static void netplay_refresh_lan_cb(retro_task_t *task, void *task_data,
|
||||||
void *task_data, void *user_data, const char *error)
|
void *user_data, const char *error)
|
||||||
{
|
{
|
||||||
|
int i;
|
||||||
const char *path = NULL;
|
const char *path = NULL;
|
||||||
const char *label = NULL;
|
const char *label = NULL;
|
||||||
unsigned menu_type = 0;
|
unsigned menu_type = 0;
|
||||||
enum msg_hash_enums enum_idx = MSG_UNKNOWN;
|
enum msg_hash_enums enum_idx = MSG_UNKNOWN;
|
||||||
net_driver_state_t *net_st = networking_state_get_ptr();
|
|
||||||
struct netplay_host_list *hosts = NULL;
|
struct netplay_host_list *hosts = NULL;
|
||||||
bool refresh = false;
|
bool refresh = false;
|
||||||
|
net_driver_state_t *net_st = networking_state_get_ptr();
|
||||||
|
|
||||||
|
free(net_st->room_list);
|
||||||
|
net_st->room_list = NULL;
|
||||||
|
net_st->room_count = 0;
|
||||||
|
|
||||||
menu_entries_get_last_stack(&path, &label, &menu_type, &enum_idx, NULL);
|
menu_entries_get_last_stack(&path, &label, &menu_type, &enum_idx, NULL);
|
||||||
|
|
||||||
/* Don't push the results if we left the netplay menu */
|
/* Don't push the results if we left the netplay menu */
|
||||||
if (!string_is_equal(label,
|
if (!string_is_equal(label, msg_hash_to_str(MENU_ENUM_LABEL_NETPLAY_TAB)) &&
|
||||||
msg_hash_to_str(MENU_ENUM_LABEL_NETPLAY_TAB)) &&
|
!string_is_equal(label, msg_hash_to_str(MENU_ENUM_LABEL_NETPLAY)))
|
||||||
!string_is_equal(label,
|
goto deinit;
|
||||||
msg_hash_to_str(MENU_ENUM_LABEL_NETPLAY)))
|
|
||||||
goto finished;
|
|
||||||
|
|
||||||
if (!netplay_discovery_driver_ctl(
|
if (!netplay_discovery_driver_ctl(
|
||||||
RARCH_NETPLAY_DISCOVERY_CTL_LAN_GET_RESPONSES, &hosts) ||
|
RARCH_NETPLAY_DISCOVERY_CTL_LAN_GET_RESPONSES, &hosts))
|
||||||
!hosts)
|
goto done;
|
||||||
goto finished;
|
if (!hosts || !hosts->size)
|
||||||
|
goto done;
|
||||||
|
|
||||||
if (net_st->room_list)
|
net_st->room_list =
|
||||||
free(net_st->room_list);
|
(struct netplay_room*)calloc(hosts->size, sizeof(*net_st->room_list));
|
||||||
|
if (!net_st->room_list)
|
||||||
|
goto done;
|
||||||
|
net_st->room_count = hosts->size;
|
||||||
|
|
||||||
net_st->room_list = NULL;
|
for (i = 0; i < net_st->room_count; i++)
|
||||||
net_st->room_count = 0;
|
|
||||||
|
|
||||||
if (hosts->size)
|
|
||||||
{
|
{
|
||||||
int i;
|
struct netplay_host *host = &hosts->hosts[i];
|
||||||
|
struct netplay_room *room = &net_st->room_list[i];
|
||||||
|
|
||||||
net_st->room_count = hosts->size;
|
room->gamecrc = host->content_crc;
|
||||||
net_st->room_list = (struct netplay_room*)calloc(net_st->room_count,
|
room->port = host->port;
|
||||||
sizeof(*net_st->room_list));
|
|
||||||
|
|
||||||
for (i = 0; i < net_st->room_count; i++)
|
strlcpy(room->nickname, host->nick, sizeof(room->nickname));
|
||||||
{
|
strlcpy(room->frontend, host->frontend, sizeof(room->frontend));
|
||||||
struct netplay_host *host = &hosts->hosts[i];
|
strlcpy(room->corename, host->core, sizeof(room->corename));
|
||||||
struct netplay_room *room = &net_st->room_list[i];
|
strlcpy(room->coreversion, host->core_version,
|
||||||
|
sizeof(room->coreversion));
|
||||||
|
strlcpy(room->retroarch_version, host->retroarch_version,
|
||||||
|
sizeof(room->retroarch_version));
|
||||||
|
strlcpy(room->gamename, host->content, sizeof(room->gamename));
|
||||||
|
strlcpy(room->subsystem_name, host->subsystem_name,
|
||||||
|
sizeof(room->subsystem_name));
|
||||||
|
strlcpy(room->address, host->address, sizeof(room->address));
|
||||||
|
|
||||||
room->port = host->port;
|
room->has_password = host->has_password;
|
||||||
room->gamecrc = host->content_crc;
|
room->has_spectate_password = host->has_spectate_password;
|
||||||
strlcpy(room->retroarch_version, host->retroarch_version,
|
|
||||||
sizeof(room->retroarch_version));
|
room->connectable = true;
|
||||||
strlcpy(room->nickname, host->nick,
|
room->is_retroarch = true;
|
||||||
sizeof(room->nickname));
|
room->lan = true;
|
||||||
strlcpy(room->subsystem_name, host->subsystem_name,
|
|
||||||
sizeof(room->subsystem_name));
|
|
||||||
strlcpy(room->corename, host->core,
|
|
||||||
sizeof(room->corename));
|
|
||||||
strlcpy(room->frontend, host->frontend,
|
|
||||||
sizeof(room->frontend));
|
|
||||||
strlcpy(room->coreversion, host->core_version,
|
|
||||||
sizeof(room->coreversion));
|
|
||||||
strlcpy(room->gamename, host->content,
|
|
||||||
sizeof(room->gamename));
|
|
||||||
strlcpy(room->address, host->address,
|
|
||||||
sizeof(room->address));
|
|
||||||
room->has_password = host->has_password;
|
|
||||||
room->has_spectate_password = host->has_spectate_password;
|
|
||||||
room->connectable = true;
|
|
||||||
room->is_retroarch = true;
|
|
||||||
room->lan = true;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
done:
|
||||||
menu_entries_ctl(MENU_ENTRIES_CTL_SET_REFRESH, &refresh);
|
menu_entries_ctl(MENU_ENTRIES_CTL_SET_REFRESH, &refresh);
|
||||||
menu_driver_ctl(RARCH_MENU_CTL_SET_PREVENT_POPULATE, NULL);
|
menu_driver_ctl(RARCH_MENU_CTL_SET_PREVENT_POPULATE, NULL);
|
||||||
|
|
||||||
finished:
|
deinit:
|
||||||
deinit_netplay_discovery();
|
deinit_netplay_discovery();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1494,93 +1494,48 @@ static int action_bind_sublabel_cheat_desc(
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef HAVE_NETWORKING
|
#ifdef HAVE_NETWORKING
|
||||||
static int action_bind_sublabel_netplay_room(
|
static int action_bind_sublabel_netplay_room(file_list_t *list,
|
||||||
file_list_t *list,
|
|
||||||
unsigned type, unsigned i,
|
unsigned type, unsigned i,
|
||||||
const char *label, const char *path,
|
const char *label, const char *path,
|
||||||
char *s, size_t len)
|
char *s, size_t len)
|
||||||
{
|
{
|
||||||
uint32_t gamecrc = 0;
|
char buf[512];
|
||||||
const char *ra_version = NULL;
|
struct netplay_room *room;
|
||||||
const char *corename = NULL;
|
|
||||||
const char *gamename = NULL;
|
|
||||||
const char *core_ver = NULL;
|
|
||||||
const char *frontend = NULL;
|
|
||||||
const char *na = NULL;
|
|
||||||
const char *subsystem = NULL;
|
|
||||||
net_driver_state_t *net_st = networking_state_get_ptr();
|
net_driver_state_t *net_st = networking_state_get_ptr();
|
||||||
unsigned room_index = type - MENU_SETTINGS_NETPLAY_ROOMS_START;
|
unsigned room_index = type - MENU_SETTINGS_NETPLAY_ROOMS_START;
|
||||||
|
|
||||||
if (room_index >= (unsigned)net_st->room_count)
|
if (room_index >= (unsigned)net_st->room_count)
|
||||||
return menu_cbs_exit();
|
return menu_cbs_exit();
|
||||||
|
|
||||||
ra_version = net_st->room_list[room_index].retroarch_version;
|
room = &net_st->room_list[room_index];
|
||||||
corename = net_st->room_list[room_index].corename;
|
|
||||||
gamename = net_st->room_list[room_index].gamename;
|
|
||||||
core_ver = net_st->room_list[room_index].coreversion;
|
|
||||||
gamecrc = net_st->room_list[room_index].gamecrc;
|
|
||||||
frontend = net_st->room_list[room_index].frontend;
|
|
||||||
subsystem = net_st->room_list[room_index].subsystem_name;
|
|
||||||
na = msg_hash_to_str(MENU_ENUM_LABEL_VALUE_NOT_AVAILABLE);
|
|
||||||
|
|
||||||
if (string_is_empty(subsystem) || string_is_equal(subsystem,
|
snprintf(s, len,
|
||||||
msg_hash_to_str(MENU_ENUM_LABEL_VALUE_NOT_AVAILABLE)))
|
"%s: %s (%s)\n"
|
||||||
{
|
"%s: %s (%s)\n"
|
||||||
snprintf(s, len,
|
"%s: %s ",
|
||||||
"%s: %s (%s)\n%s: %s (%s)\nGame: %s (%08lx)",
|
msg_hash_to_str(MSG_PROGRAM),
|
||||||
msg_hash_to_str(MSG_PROGRAM),
|
!string_is_empty(room->retroarch_version) ? room->retroarch_version :
|
||||||
string_is_empty(ra_version) ? na : ra_version,
|
msg_hash_to_str(MENU_ENUM_LABEL_VALUE_NOT_AVAILABLE),
|
||||||
string_is_empty(frontend) ? na : frontend,
|
(!string_is_empty(room->frontend) &&
|
||||||
msg_hash_to_str(MENU_ENUM_LABEL_VALUE_CONTENT_INFO_CORE_NAME),
|
!string_is_equal_case_insensitive(room->frontend, "N/A")) ?
|
||||||
corename, core_ver,
|
room->frontend :
|
||||||
!string_is_equal(gamename, na) ? gamename : na,
|
msg_hash_to_str(MENU_ENUM_LABEL_VALUE_NOT_AVAILABLE),
|
||||||
(unsigned long)gamecrc);
|
msg_hash_to_str(MENU_ENUM_LABEL_VALUE_CONTENT_INFO_CORE_NAME),
|
||||||
}
|
room->corename, room->coreversion,
|
||||||
|
msg_hash_to_str(MENU_ENUM_LABEL_VALUE_CONTENT),
|
||||||
|
(!string_is_empty(room->gamename) &&
|
||||||
|
!string_is_equal_case_insensitive(room->gamename, "N/A")) ?
|
||||||
|
room->gamename :
|
||||||
|
msg_hash_to_str(MENU_ENUM_LABEL_VALUE_NOT_AVAILABLE));
|
||||||
|
|
||||||
|
if (string_is_empty(room->subsystem_name) ||
|
||||||
|
string_is_equal_case_insensitive(room->subsystem_name, "N/A"))
|
||||||
|
snprintf(buf, sizeof(buf), "(%08lX)", (unsigned long)room->gamecrc);
|
||||||
else
|
else
|
||||||
{
|
snprintf(buf, sizeof(buf), "(%s)", room->subsystem_name);
|
||||||
if (strstr(gamename, "|"))
|
|
||||||
{
|
|
||||||
char buf[4096];
|
|
||||||
unsigned i = 0;
|
|
||||||
struct string_list list = {0};
|
|
||||||
|
|
||||||
string_list_initialize(&list);
|
strlcat(s, buf, len);
|
||||||
string_split_noalloc(&list, gamename, "|");
|
|
||||||
|
|
||||||
buf[0] = '\0';
|
|
||||||
|
|
||||||
for (i = 0; i < list.size; i++)
|
|
||||||
{
|
|
||||||
strlcat(buf, " ", sizeof(buf));
|
|
||||||
strlcat(buf, list.elems[i].data, sizeof(buf));
|
|
||||||
/* Never terminate a UI string with a newline */
|
|
||||||
if (i != list.size - 1)
|
|
||||||
strlcat(buf, "\n", sizeof(buf));
|
|
||||||
}
|
|
||||||
snprintf(s, len,
|
|
||||||
"%s: %s (%s)\n%s: %s (%s)\nSubsystem: %s\nGames:\n%s",
|
|
||||||
msg_hash_to_str(MSG_PROGRAM),
|
|
||||||
string_is_empty(ra_version) ? na : ra_version,
|
|
||||||
string_is_empty(frontend) ? na : frontend,
|
|
||||||
msg_hash_to_str(MENU_ENUM_LABEL_VALUE_CONTENT_INFO_CORE_NAME),
|
|
||||||
corename, core_ver, subsystem,
|
|
||||||
!string_is_equal(gamename, na) ? buf : na
|
|
||||||
);
|
|
||||||
string_list_deinitialize(&list);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
snprintf(s, len,
|
|
||||||
"%s: %s (%s)\n%s: %s (%s)\nSubsystem: %s\nGame: %s (%08lx)",
|
|
||||||
msg_hash_to_str(MSG_PROGRAM),
|
|
||||||
string_is_empty(ra_version) ? na : ra_version,
|
|
||||||
string_is_empty(frontend) ? na : frontend,
|
|
||||||
msg_hash_to_str(MENU_ENUM_LABEL_VALUE_CONTENT_INFO_CORE_NAME),
|
|
||||||
corename, core_ver, subsystem,
|
|
||||||
!string_is_equal(gamename, na) ? gamename : na,
|
|
||||||
(unsigned long)gamecrc);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1590,10 +1545,10 @@ static int action_bind_sublabel_netplay_kick_client(file_list_t *list,
|
||||||
char *s, size_t len)
|
char *s, size_t len)
|
||||||
{
|
{
|
||||||
char buf[256];
|
char buf[256];
|
||||||
netplay_client_info_t *client = NULL;
|
netplay_client_info_t *client;
|
||||||
const char *status = NULL;
|
const char *status = NULL;
|
||||||
size_t idx = list->list[i].entry_idx;
|
size_t idx = list->list[i].entry_idx;
|
||||||
net_driver_state_t *net_st = networking_state_get_ptr();
|
net_driver_state_t *net_st = networking_state_get_ptr();
|
||||||
|
|
||||||
if (idx >= net_st->client_info_count)
|
if (idx >= net_st->client_info_count)
|
||||||
return menu_cbs_exit();
|
return menu_cbs_exit();
|
||||||
|
@ -1625,20 +1580,17 @@ static int action_bind_sublabel_netplay_kick_client(file_list_t *list,
|
||||||
snprintf(buf, sizeof(buf), "%s: %s",
|
snprintf(buf, sizeof(buf), "%s: %s",
|
||||||
msg_hash_to_str(MSG_NETPLAY_CHAT_SUPPORTED),
|
msg_hash_to_str(MSG_NETPLAY_CHAT_SUPPORTED),
|
||||||
msg_hash_to_str((client->protocol >= 6) ?
|
msg_hash_to_str((client->protocol >= 6) ?
|
||||||
MENU_ENUM_LABEL_VALUE_YES :
|
MENU_ENUM_LABEL_VALUE_YES : MENU_ENUM_LABEL_VALUE_NO));
|
||||||
MENU_ENUM_LABEL_VALUE_NO));
|
|
||||||
strlcat(s, buf, len);
|
strlcat(s, buf, len);
|
||||||
|
|
||||||
if (client->ping >= 0)
|
if (client->ping >= 0)
|
||||||
{
|
{
|
||||||
snprintf(buf, sizeof(buf), "\nPing: %u",
|
snprintf(buf, sizeof(buf), "\nPing: %u", (unsigned)client->ping);
|
||||||
(unsigned)client->ping);
|
|
||||||
strlcat(s, buf, len);
|
strlcat(s, buf, len);
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
static int action_bind_sublabel_playlist_entry(
|
static int action_bind_sublabel_playlist_entry(
|
||||||
|
|
|
@ -10386,9 +10386,16 @@ static unsigned menu_displaylist_build_shader_parameter(
|
||||||
unsigned menu_displaylist_netplay_refresh_rooms(file_list_t *list)
|
unsigned menu_displaylist_netplay_refresh_rooms(file_list_t *list)
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
|
char buf[256];
|
||||||
|
char passworded[64];
|
||||||
|
char country[8];
|
||||||
|
const char *room_type;
|
||||||
|
struct netplay_room *room;
|
||||||
unsigned count = 0;
|
unsigned count = 0;
|
||||||
settings_t *settings = config_get_ptr();
|
settings_t *settings = config_get_ptr();
|
||||||
net_driver_state_t *net_st = networking_state_get_ptr();
|
net_driver_state_t *net_st = networking_state_get_ptr();
|
||||||
|
bool show_only_connectable = settings->bools.netplay_show_only_connectable;
|
||||||
|
bool show_passworded = settings->bools.netplay_show_passworded;
|
||||||
|
|
||||||
menu_entries_ctl(MENU_ENTRIES_CTL_CLEAR, list);
|
menu_entries_ctl(MENU_ENTRIES_CTL_CLEAR, list);
|
||||||
|
|
||||||
|
@ -10400,8 +10407,8 @@ unsigned menu_displaylist_netplay_refresh_rooms(file_list_t *list)
|
||||||
count++;
|
count++;
|
||||||
|
|
||||||
if (netplay_driver_ctl(RARCH_NETPLAY_CTL_IS_ENABLED, NULL) &&
|
if (netplay_driver_ctl(RARCH_NETPLAY_CTL_IS_ENABLED, NULL) &&
|
||||||
!netplay_driver_ctl(RARCH_NETPLAY_CTL_IS_SERVER, NULL) &&
|
!netplay_driver_ctl(RARCH_NETPLAY_CTL_IS_SERVER, NULL) &&
|
||||||
netplay_driver_ctl(RARCH_NETPLAY_CTL_IS_CONNECTED, NULL))
|
netplay_driver_ctl(RARCH_NETPLAY_CTL_IS_CONNECTED, NULL))
|
||||||
{
|
{
|
||||||
if (menu_entries_append_enum(list,
|
if (menu_entries_append_enum(list,
|
||||||
msg_hash_to_str(MENU_ENUM_LABEL_VALUE_NETPLAY_DISCONNECT),
|
msg_hash_to_str(MENU_ENUM_LABEL_VALUE_NETPLAY_DISCONNECT),
|
||||||
|
@ -10412,10 +10419,10 @@ unsigned menu_displaylist_netplay_refresh_rooms(file_list_t *list)
|
||||||
}
|
}
|
||||||
|
|
||||||
if (menu_entries_append_enum(list,
|
if (menu_entries_append_enum(list,
|
||||||
msg_hash_to_str(MENU_ENUM_LABEL_VALUE_NETPLAY_ENABLE_CLIENT),
|
msg_hash_to_str(MENU_ENUM_LABEL_VALUE_NETPLAY_ENABLE_CLIENT),
|
||||||
msg_hash_to_str(MENU_ENUM_LABEL_NETPLAY_ENABLE_CLIENT),
|
msg_hash_to_str(MENU_ENUM_LABEL_NETPLAY_ENABLE_CLIENT),
|
||||||
MENU_ENUM_LABEL_NETPLAY_ENABLE_CLIENT,
|
MENU_ENUM_LABEL_NETPLAY_ENABLE_CLIENT,
|
||||||
MENU_SETTING_ACTION, 0, 0))
|
MENU_SETTING_ACTION, 0, 0))
|
||||||
count++;
|
count++;
|
||||||
|
|
||||||
if (menu_entries_append_enum(list,
|
if (menu_entries_append_enum(list,
|
||||||
|
@ -10450,11 +10457,7 @@ unsigned menu_displaylist_netplay_refresh_rooms(file_list_t *list)
|
||||||
|
|
||||||
for (i = 0; i < net_st->room_count; i++)
|
for (i = 0; i < net_st->room_count; i++)
|
||||||
{
|
{
|
||||||
char buf[8192];
|
room = &net_st->room_list[i];
|
||||||
char passworded[64];
|
|
||||||
char country[8];
|
|
||||||
const char *room_type;
|
|
||||||
struct netplay_room *room = &net_st->room_list[i];
|
|
||||||
|
|
||||||
/* Get rid of any room that is not running RetroArch. */
|
/* Get rid of any room that is not running RetroArch. */
|
||||||
if (!room->is_retroarch)
|
if (!room->is_retroarch)
|
||||||
|
@ -10464,7 +10467,7 @@ unsigned menu_displaylist_netplay_refresh_rooms(file_list_t *list)
|
||||||
if the user opt-in. */
|
if the user opt-in. */
|
||||||
if (!room->connectable)
|
if (!room->connectable)
|
||||||
{
|
{
|
||||||
if (settings->bools.netplay_show_only_connectable)
|
if (show_only_connectable)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
room_type = msg_hash_to_str(MSG_INTERNET_NOT_CONNECTABLE);
|
room_type = msg_hash_to_str(MSG_INTERNET_NOT_CONNECTABLE);
|
||||||
|
@ -10480,7 +10483,7 @@ unsigned menu_displaylist_netplay_refresh_rooms(file_list_t *list)
|
||||||
if the user opt-in. */
|
if the user opt-in. */
|
||||||
if (room->has_password || room->has_spectate_password)
|
if (room->has_password || room->has_spectate_password)
|
||||||
{
|
{
|
||||||
if (!settings->bools.netplay_show_passworded)
|
if (!show_passworded)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
snprintf(passworded, sizeof(passworded), "[%s] ",
|
snprintf(passworded, sizeof(passworded), "[%s] ",
|
||||||
|
@ -10490,46 +10493,20 @@ unsigned menu_displaylist_netplay_refresh_rooms(file_list_t *list)
|
||||||
*passworded = '\0';
|
*passworded = '\0';
|
||||||
|
|
||||||
if (!room->lan && !string_is_empty(room->country))
|
if (!room->lan && !string_is_empty(room->country))
|
||||||
snprintf(country, sizeof(country), " (%s)",
|
snprintf(country, sizeof(country), " (%s)", room->country);
|
||||||
room->country);
|
|
||||||
else
|
else
|
||||||
*country = '\0';
|
*country = '\0';
|
||||||
|
|
||||||
snprintf(buf, sizeof(buf), "%s%s: %s%s",
|
snprintf(buf, sizeof(buf), "%s%s: %s%s",
|
||||||
passworded, room_type,
|
passworded, room_type, room->nickname, country);
|
||||||
room->nickname, country);
|
|
||||||
|
|
||||||
if (menu_entries_append_enum(list,
|
if (menu_entries_append_enum(list, buf,
|
||||||
buf,
|
|
||||||
msg_hash_to_str(MENU_ENUM_LABEL_CONNECT_NETPLAY_ROOM),
|
msg_hash_to_str(MENU_ENUM_LABEL_CONNECT_NETPLAY_ROOM),
|
||||||
MENU_ENUM_LABEL_CONNECT_NETPLAY_ROOM,
|
MENU_ENUM_LABEL_CONNECT_NETPLAY_ROOM,
|
||||||
(unsigned)(MENU_SETTINGS_NETPLAY_ROOMS_START + i), 0, 0))
|
(unsigned)MENU_SETTINGS_NETPLAY_ROOMS_START + i, 0, 0))
|
||||||
count++;
|
count++;
|
||||||
|
|
||||||
/* Uncomment this to debug mismatched room parameters*/
|
|
||||||
#if 0
|
|
||||||
RARCH_LOG("[Lobby]: Room Data: %d\n"
|
|
||||||
"Nickname: %s\n"
|
|
||||||
"Address: %s\n"
|
|
||||||
"Port: %d\n"
|
|
||||||
"Core: %s\n"
|
|
||||||
"Core Version: %s\n"
|
|
||||||
"Game: %s\n"
|
|
||||||
"Game CRC: %08x\n"
|
|
||||||
"Timestamp: %d\n", room_data->elems[j + 6].data,
|
|
||||||
room->nickname,
|
|
||||||
room->address,
|
|
||||||
room->port,
|
|
||||||
room->corename,
|
|
||||||
room->coreversion,
|
|
||||||
room->gamename,
|
|
||||||
room->gamecrc,
|
|
||||||
room->timestamp);
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
netplay_rooms_free();
|
|
||||||
|
|
||||||
return count;
|
return count;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -10637,13 +10614,14 @@ static unsigned menu_displaylist_netplay_kick(file_list_t *list)
|
||||||
|
|
||||||
if (netplay_driver_ctl(RARCH_NETPLAY_CTL_REFRESH_CLIENT_INFO, NULL))
|
if (netplay_driver_ctl(RARCH_NETPLAY_CTL_REFRESH_CLIENT_INFO, NULL))
|
||||||
{
|
{
|
||||||
char client_id[4];
|
|
||||||
size_t i;
|
size_t i;
|
||||||
|
char client_id[4];
|
||||||
|
netplay_client_info_t *client;
|
||||||
net_driver_state_t *net_st = networking_state_get_ptr();
|
net_driver_state_t *net_st = networking_state_get_ptr();
|
||||||
|
|
||||||
for (i = 0; i < net_st->client_info_count; i++)
|
for (i = 0; i < net_st->client_info_count; i++)
|
||||||
{
|
{
|
||||||
netplay_client_info_t *client = &net_st->client_info[i];
|
client = &net_st->client_info[i];
|
||||||
|
|
||||||
snprintf(client_id, sizeof(client_id), "%d", client->id);
|
snprintf(client_id, sizeof(client_id), "%d", client->id);
|
||||||
if (menu_entries_append_enum(list, client->name, client_id,
|
if (menu_entries_append_enum(list, client->name, client_id,
|
||||||
|
@ -10664,7 +10642,6 @@ static unsigned menu_displaylist_netplay_kick(file_list_t *list)
|
||||||
|
|
||||||
return count;
|
return count;
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
bool menu_displaylist_has_subsystems(void)
|
bool menu_displaylist_has_subsystems(void)
|
||||||
|
|
|
@ -53,7 +53,7 @@ extern "C"
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
static discord_state_t discord_state_st; /* int64_t alignment */
|
static discord_state_t discord_state_st = {0}; /* int64_t alignment */
|
||||||
|
|
||||||
discord_state_t *discord_state_get_ptr(void)
|
discord_state_t *discord_state_get_ptr(void)
|
||||||
{
|
{
|
||||||
|
@ -153,99 +153,113 @@ static void handle_discord_error(int errcode, const char* message)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
static void handle_discord_join_cb(retro_task_t *task,
|
static void handle_discord_join_cb(retro_task_t *task, void *task_data,
|
||||||
void *task_data, void *user_data, const char *err)
|
void *user_data, const char *error)
|
||||||
{
|
{
|
||||||
char join_hostname[PATH_MAX_LENGTH];
|
char hostname[512];
|
||||||
struct netplay_room *room = NULL;
|
struct netplay_room *room;
|
||||||
http_transfer_data_t *data = (http_transfer_data_t*)task_data;
|
char *room_data = NULL;
|
||||||
discord_state_t *discord_st = &discord_state_st;
|
http_transfer_data_t *data = (http_transfer_data_t*)task_data;
|
||||||
|
discord_state_t *discord_st = &discord_state_st;
|
||||||
|
|
||||||
if (!data || err || !data->data || !data->len)
|
if (error)
|
||||||
goto finish;
|
goto done;
|
||||||
|
if (!data || !data->data || !data->len)
|
||||||
|
goto done;
|
||||||
|
if (data->status != 200)
|
||||||
|
goto done;
|
||||||
|
|
||||||
data->data = (char*)realloc(data->data, data->len + 1);
|
room_data = (char*)malloc(data->len + 1);
|
||||||
data->data[data->len] = '\0';
|
if (!room_data)
|
||||||
|
goto done;
|
||||||
|
memcpy(room_data, data->data, data->len);
|
||||||
|
room_data[data->len] = '\0';
|
||||||
|
|
||||||
netplay_rooms_parse(data->data);
|
netplay_rooms_parse(room_data);
|
||||||
room = netplay_room_get(0);
|
free(room_data);
|
||||||
|
|
||||||
|
room = netplay_room_get(0);
|
||||||
if (room)
|
if (room)
|
||||||
{
|
{
|
||||||
if (room->host_method == NETPLAY_HOST_METHOD_MITM)
|
|
||||||
snprintf(join_hostname, sizeof(join_hostname), "%s|%d|%s",
|
|
||||||
room->mitm_address, room->mitm_port, room->mitm_session);
|
|
||||||
else
|
|
||||||
snprintf(join_hostname, sizeof(join_hostname), "%s|%d",
|
|
||||||
room->address, room->port);
|
|
||||||
|
|
||||||
if (netplay_driver_ctl(RARCH_NETPLAY_CTL_IS_DATA_INITED, NULL))
|
if (netplay_driver_ctl(RARCH_NETPLAY_CTL_IS_DATA_INITED, NULL))
|
||||||
deinit_netplay();
|
deinit_netplay();
|
||||||
|
|
||||||
netplay_driver_ctl(RARCH_NETPLAY_CTL_ENABLE_CLIENT, NULL);
|
netplay_driver_ctl(RARCH_NETPLAY_CTL_ENABLE_CLIENT, NULL);
|
||||||
|
|
||||||
task_push_netplay_crc_scan(room->gamecrc,
|
if (room->host_method == NETPLAY_HOST_METHOD_MITM)
|
||||||
room->gamename, join_hostname, room->corename, room->subsystem_name);
|
snprintf(hostname, sizeof(hostname), "%s|%d|%s",
|
||||||
|
room->mitm_address, room->mitm_port, room->mitm_session);
|
||||||
|
else
|
||||||
|
snprintf(hostname, sizeof(hostname), "%s|%d",
|
||||||
|
room->address, room->port);
|
||||||
|
|
||||||
|
task_push_netplay_crc_scan(room->gamecrc, room->gamename, hostname,
|
||||||
|
room->corename, room->subsystem_name);
|
||||||
|
|
||||||
discord_st->connecting = true;
|
discord_st->connecting = true;
|
||||||
if (discord_st->ready)
|
if (discord_st->ready)
|
||||||
discord_update(PRESENCE_NETPLAY_CLIENT);
|
discord_update(PRESENCE_NETPLAY_CLIENT);
|
||||||
}
|
}
|
||||||
|
|
||||||
finish:
|
netplay_rooms_free();
|
||||||
if (user_data)
|
|
||||||
free(user_data);
|
done:
|
||||||
|
free(user_data);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void handle_discord_join(const char* secret)
|
static void handle_discord_join(const char *secret)
|
||||||
{
|
{
|
||||||
char url[2048];
|
char url[512];
|
||||||
struct string_list *list = string_split(secret, "|");
|
|
||||||
discord_state_t *discord_st = &discord_state_st;
|
discord_state_t *discord_st = &discord_state_st;
|
||||||
|
int room_id = (int)strtol(secret, NULL, 10);
|
||||||
|
|
||||||
strlcpy(discord_st->peer_party_id,
|
if (room_id)
|
||||||
list->elems[0].data, sizeof(discord_st->peer_party_id));
|
{
|
||||||
snprintf(url, sizeof(url), FILE_PATH_LOBBY_LIBRETRO_URL "%s/",
|
snprintf(discord_st->peer_party_id, sizeof(discord_st->peer_party_id),
|
||||||
discord_st->peer_party_id);
|
"%d", room_id);
|
||||||
|
|
||||||
task_push_http_transfer(url, true, NULL, handle_discord_join_cb, NULL);
|
strlcpy(url, FILE_PATH_LOBBY_LIBRETRO_URL, sizeof(url));
|
||||||
|
strlcat(url, discord_st->peer_party_id, sizeof(url));
|
||||||
|
|
||||||
|
task_push_http_transfer(url, true, NULL, handle_discord_join_cb, NULL);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void handle_discord_spectate(const char* secret)
|
static void handle_discord_spectate(const char *secret)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef HAVE_MENU
|
|
||||||
#if 0
|
#if 0
|
||||||
|
#ifdef HAVE_MENU
|
||||||
static void handle_discord_join_response(void *ignore, const char *line)
|
static void handle_discord_join_response(void *ignore, const char *line)
|
||||||
{
|
{
|
||||||
/* TODO/FIXME: needs in-game widgets */
|
/* TODO/FIXME: needs in-game widgets */
|
||||||
if (strstr(line, "yes"))
|
if (strstr(line, "yes"))
|
||||||
Discord_Respond(user_id, DISCORD_REPLY_YES);
|
Discord_Respond(user_id, DISCORD_REPLY_YES);
|
||||||
|
|
||||||
#ifdef HAVE_MENU
|
|
||||||
menu_input_dialog_end();
|
menu_input_dialog_end();
|
||||||
retroarch_menu_running_finished(false);
|
retroarch_menu_running_finished(false);
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
static void handle_discord_join_request(const DiscordUser* request)
|
static void handle_discord_join_request(const DiscordUser *request)
|
||||||
{
|
{
|
||||||
#ifdef HAVE_MENU
|
#ifdef HAVE_MENU
|
||||||
#if 0
|
#if 0
|
||||||
char buf[PATH_MAX_LENGTH];
|
char buf[PATH_MAX_LENGTH];
|
||||||
menu_input_ctx_line_t line;
|
menu_input_ctx_line_t line = {0};
|
||||||
#endif
|
#endif
|
||||||
discord_state_t *discord_st = &discord_state_st;
|
discord_state_t *discord_st = &discord_state_st;
|
||||||
|
|
||||||
discord_download_avatar(discord_st, request->userId, request->avatar);
|
discord_download_avatar(discord_st, request->userId, request->avatar);
|
||||||
|
|
||||||
#if 0
|
#if 0
|
||||||
/* TODO/FIXME: Needs in-game widgets */
|
/* TODO/FIXME: Needs in-game widgets */
|
||||||
retroarch_menu_running();
|
retroarch_menu_running();
|
||||||
|
|
||||||
memset(&line, 0, sizeof(line));
|
|
||||||
snprintf(buf, sizeof(buf), "%s %s?",
|
snprintf(buf, sizeof(buf), "%s %s?",
|
||||||
msg_hash_to_str(MSG_DISCORD_CONNECTION_REQUEST), request->username);
|
msg_hash_to_str(MSG_DISCORD_CONNECTION_REQUEST), request->username);
|
||||||
line.label = buf;
|
line.label = buf;
|
||||||
line.label_setting = "no_setting";
|
line.label_setting = "no_setting";
|
||||||
line.cb = handle_discord_join_response;
|
line.cb = handle_discord_join_response;
|
||||||
|
|
|
@ -23,8 +23,6 @@
|
||||||
#include <stddef.h>
|
#include <stddef.h>
|
||||||
|
|
||||||
#include <boolean.h>
|
#include <boolean.h>
|
||||||
#include <libretro.h>
|
|
||||||
#include <retro_miscellaneous.h>
|
|
||||||
|
|
||||||
#ifdef HAVE_CONFIG_H
|
#ifdef HAVE_CONFIG_H
|
||||||
#include "../../config.h"
|
#include "../../config.h"
|
||||||
|
@ -32,16 +30,14 @@
|
||||||
|
|
||||||
#include <net/net_compat.h>
|
#include <net/net_compat.h>
|
||||||
|
|
||||||
#include "../../retroarch_types.h"
|
|
||||||
|
|
||||||
#include "../natt.h"
|
#include "../natt.h"
|
||||||
|
|
||||||
#include "netplay_protocol.h"
|
|
||||||
|
|
||||||
#define NETPLAY_NICK_LEN 32
|
#define NETPLAY_NICK_LEN 32
|
||||||
#define NETPLAY_HOST_STR_LEN 32
|
#define NETPLAY_HOST_STR_LEN 32
|
||||||
#define NETPLAY_HOST_LONGSTR_LEN 256
|
#define NETPLAY_HOST_LONGSTR_LEN 256
|
||||||
|
|
||||||
|
#define NETPLAY_MITM_SERVERS 5
|
||||||
|
|
||||||
#define NETPLAY_CHAT_MAX_MESSAGES 5
|
#define NETPLAY_CHAT_MAX_MESSAGES 5
|
||||||
#define NETPLAY_CHAT_MAX_SIZE 96
|
#define NETPLAY_CHAT_MAX_SIZE 96
|
||||||
#define NETPLAY_CHAT_FRAME_TIME 900
|
#define NETPLAY_CHAT_FRAME_TIME 900
|
||||||
|
@ -132,10 +128,10 @@ enum netplay_host_method
|
||||||
|
|
||||||
enum rarch_netplay_discovery_ctl_state
|
enum rarch_netplay_discovery_ctl_state
|
||||||
{
|
{
|
||||||
RARCH_NETPLAY_DISCOVERY_CTL_NONE = 0,
|
RARCH_NETPLAY_DISCOVERY_CTL_NONE = 0,
|
||||||
RARCH_NETPLAY_DISCOVERY_CTL_LAN_SEND_QUERY,
|
RARCH_NETPLAY_DISCOVERY_CTL_LAN_SEND_QUERY,
|
||||||
RARCH_NETPLAY_DISCOVERY_CTL_LAN_GET_RESPONSES,
|
RARCH_NETPLAY_DISCOVERY_CTL_LAN_GET_RESPONSES,
|
||||||
RARCH_NETPLAY_DISCOVERY_CTL_LAN_CLEAR_RESPONSES
|
RARCH_NETPLAY_DISCOVERY_CTL_LAN_CLEAR_RESPONSES
|
||||||
};
|
};
|
||||||
|
|
||||||
typedef struct netplay netplay_t;
|
typedef struct netplay netplay_t;
|
||||||
|
@ -143,62 +139,38 @@ typedef struct netplay netplay_t;
|
||||||
typedef struct netplay_client_info
|
typedef struct netplay_client_info
|
||||||
{
|
{
|
||||||
uint32_t protocol;
|
uint32_t protocol;
|
||||||
int32_t ping;
|
int32_t ping;
|
||||||
int id;
|
int id;
|
||||||
enum rarch_netplay_connection_mode mode;
|
enum rarch_netplay_connection_mode mode;
|
||||||
char name[NETPLAY_NICK_LEN];
|
char name[NETPLAY_NICK_LEN];
|
||||||
} netplay_client_info_t;
|
} netplay_client_info_t;
|
||||||
|
|
||||||
struct ad_packet
|
|
||||||
{
|
|
||||||
uint32_t header;
|
|
||||||
int32_t content_crc;
|
|
||||||
int32_t port;
|
|
||||||
uint32_t has_password;
|
|
||||||
char nick[NETPLAY_NICK_LEN];
|
|
||||||
char frontend[NETPLAY_HOST_STR_LEN];
|
|
||||||
char core[NETPLAY_HOST_STR_LEN];
|
|
||||||
char core_version[NETPLAY_HOST_STR_LEN];
|
|
||||||
char retroarch_version[NETPLAY_HOST_STR_LEN];
|
|
||||||
char content[NETPLAY_HOST_LONGSTR_LEN];
|
|
||||||
char subsystem_name[NETPLAY_HOST_LONGSTR_LEN];
|
|
||||||
};
|
|
||||||
|
|
||||||
typedef struct mitm_server
|
typedef struct mitm_server
|
||||||
{
|
{
|
||||||
const char *name;
|
const char *name;
|
||||||
const char *description;
|
const char *description;
|
||||||
} mitm_server_t;
|
} mitm_server_t;
|
||||||
|
|
||||||
static const mitm_server_t netplay_mitm_server_list[] = {
|
|
||||||
{ "nyc", "New York City, USA" },
|
|
||||||
{ "madrid", "Madrid, Spain" },
|
|
||||||
{ "saopaulo", "Sao Paulo, Brazil" },
|
|
||||||
{ "singapore", "Singapore" },
|
|
||||||
{ "custom", "Custom" },
|
|
||||||
};
|
|
||||||
|
|
||||||
struct netplay_room
|
struct netplay_room
|
||||||
{
|
{
|
||||||
struct netplay_room *next;
|
struct netplay_room *next;
|
||||||
int id;
|
int id;
|
||||||
|
int gamecrc;
|
||||||
int port;
|
int port;
|
||||||
int mitm_port;
|
int mitm_port;
|
||||||
int gamecrc;
|
|
||||||
int timestamp;
|
|
||||||
int host_method;
|
int host_method;
|
||||||
char country [3];
|
char nickname[NETPLAY_NICK_LEN];
|
||||||
char retroarch_version [33];
|
char frontend[NETPLAY_HOST_STR_LEN];
|
||||||
char nickname [33];
|
char corename[NETPLAY_HOST_STR_LEN];
|
||||||
char subsystem_name [256];
|
char coreversion[NETPLAY_HOST_STR_LEN];
|
||||||
char corename [256];
|
char retroarch_version[NETPLAY_HOST_STR_LEN];
|
||||||
char frontend [256];
|
char gamename[NETPLAY_HOST_LONGSTR_LEN];
|
||||||
char coreversion [256];
|
char subsystem_name[NETPLAY_HOST_LONGSTR_LEN];
|
||||||
char gamename [256];
|
char country[3];
|
||||||
char address [256];
|
char address[NETPLAY_HOST_LONGSTR_LEN];
|
||||||
char mitm_handle [33];
|
char mitm_handle[NETPLAY_HOST_STR_LEN];
|
||||||
char mitm_address [256];
|
char mitm_address[NETPLAY_HOST_LONGSTR_LEN];
|
||||||
char mitm_session [33];
|
char mitm_session[NETPLAY_HOST_STR_LEN];
|
||||||
bool has_password;
|
bool has_password;
|
||||||
bool has_spectate_password;
|
bool has_spectate_password;
|
||||||
bool connectable;
|
bool connectable;
|
||||||
|
@ -216,7 +188,7 @@ struct netplay_host
|
||||||
{
|
{
|
||||||
int content_crc;
|
int content_crc;
|
||||||
int port;
|
int port;
|
||||||
char address[NETPLAY_HOST_STR_LEN];
|
char address[16];
|
||||||
char nick[NETPLAY_NICK_LEN];
|
char nick[NETPLAY_NICK_LEN];
|
||||||
char frontend[NETPLAY_HOST_STR_LEN];
|
char frontend[NETPLAY_HOST_STR_LEN];
|
||||||
char core[NETPLAY_HOST_STR_LEN];
|
char core[NETPLAY_HOST_STR_LEN];
|
||||||
|
@ -231,27 +203,17 @@ struct netplay_host
|
||||||
struct netplay_host_list
|
struct netplay_host_list
|
||||||
{
|
{
|
||||||
struct netplay_host *hosts;
|
struct netplay_host *hosts;
|
||||||
|
size_t allocated;
|
||||||
size_t size;
|
size_t size;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct netplay_chat
|
|
||||||
{
|
|
||||||
struct
|
|
||||||
{
|
|
||||||
uint32_t frames;
|
|
||||||
char nick[NETPLAY_NICK_LEN];
|
|
||||||
char msg[NETPLAY_CHAT_MAX_SIZE];
|
|
||||||
} messages[NETPLAY_CHAT_MAX_MESSAGES];
|
|
||||||
uint32_t message_slots;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct netplay_chat_buffer
|
struct netplay_chat_buffer
|
||||||
{
|
{
|
||||||
struct
|
struct
|
||||||
{
|
{
|
||||||
uint8_t alpha;
|
uint8_t alpha;
|
||||||
char nick[NETPLAY_NICK_LEN];
|
char nick[NETPLAY_NICK_LEN];
|
||||||
char msg[NETPLAY_CHAT_MAX_SIZE];
|
char msg[NETPLAY_CHAT_MAX_SIZE];
|
||||||
} messages[NETPLAY_CHAT_MAX_MESSAGES];
|
} messages[NETPLAY_CHAT_MAX_MESSAGES];
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -260,8 +222,6 @@ typedef struct
|
||||||
/* NAT traversal info (if NAT traversal is used and serving) */
|
/* NAT traversal info (if NAT traversal is used and serving) */
|
||||||
struct nat_traversal_data nat_traversal_request;
|
struct nat_traversal_data nat_traversal_request;
|
||||||
#ifdef HAVE_NETPLAYDISCOVERY
|
#ifdef HAVE_NETPLAYDISCOVERY
|
||||||
/* Packet buffer for advertisement and responses */
|
|
||||||
struct ad_packet ad_packet_buffer;
|
|
||||||
/* List of discovered hosts */
|
/* List of discovered hosts */
|
||||||
struct netplay_host_list discovered_hosts;
|
struct netplay_host_list discovered_hosts;
|
||||||
#endif
|
#endif
|
||||||
|
@ -272,21 +232,15 @@ typedef struct
|
||||||
/* Used while Netplay is running */
|
/* Used while Netplay is running */
|
||||||
netplay_t *data;
|
netplay_t *data;
|
||||||
netplay_client_info_t *client_info;
|
netplay_client_info_t *client_info;
|
||||||
/* Chat messages */
|
|
||||||
struct netplay_chat *chat;
|
|
||||||
size_t client_info_count;
|
size_t client_info_count;
|
||||||
#ifdef HAVE_NETPLAYDISCOVERY
|
#ifdef HAVE_NETPLAYDISCOVERY
|
||||||
size_t discovered_hosts_allocated;
|
|
||||||
/* LAN discovery sockets */
|
/* LAN discovery sockets */
|
||||||
int lan_ad_server_fd;
|
int lan_ad_server_fd;
|
||||||
int lan_ad_client_fd;
|
int lan_ad_client_fd;
|
||||||
#endif
|
#endif
|
||||||
int room_count;
|
int room_count;
|
||||||
int reannounce;
|
|
||||||
int reping;
|
|
||||||
int latest_ping;
|
int latest_ping;
|
||||||
unsigned server_port_deferred;
|
unsigned server_port_deferred;
|
||||||
uint16_t mapping[RETROK_LAST];
|
|
||||||
char server_address_deferred[256];
|
char server_address_deferred[256];
|
||||||
char server_session_deferred[32];
|
char server_session_deferred[32];
|
||||||
bool netplay_client_deferred;
|
bool netplay_client_deferred;
|
||||||
|
@ -302,101 +256,16 @@ typedef struct
|
||||||
|
|
||||||
net_driver_state_t *networking_state_get_ptr(void);
|
net_driver_state_t *networking_state_get_ptr(void);
|
||||||
|
|
||||||
bool netplay_driver_ctl(enum rarch_netplay_ctl_state state, void *data);
|
bool netplay_decode_hostname(const char *hostname,
|
||||||
|
char *address, unsigned *port, char *session, size_t len);
|
||||||
|
bool netplay_is_lan_address(struct sockaddr_in *addr);
|
||||||
|
bool netplay_6to4(struct sockaddr_storage *addr);
|
||||||
|
|
||||||
int netplay_rooms_parse(const char *buf);
|
int netplay_rooms_parse(const char *buf);
|
||||||
|
|
||||||
struct netplay_room* netplay_room_get(int index);
|
|
||||||
|
|
||||||
int netplay_rooms_get_count(void);
|
int netplay_rooms_get_count(void);
|
||||||
|
struct netplay_room *netplay_room_get(int index);
|
||||||
void netplay_rooms_free(void);
|
void netplay_rooms_free(void);
|
||||||
|
|
||||||
/**
|
|
||||||
* 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);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* netplay_toggle_play_spectate
|
|
||||||
*
|
|
||||||
* Toggle between play mode and spectate mode
|
|
||||||
*/
|
|
||||||
void netplay_toggle_play_spectate(netplay_t *netplay);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* netplay_input_chat
|
|
||||||
*
|
|
||||||
* Opens an input menu for sending netplay chat
|
|
||||||
*/
|
|
||||||
void netplay_input_chat(netplay_t *netplay);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 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_core_reset
|
|
||||||
* @netplay : pointer to netplay object
|
|
||||||
*
|
|
||||||
* Indicate that the core has been reset to netplay peers
|
|
||||||
**/
|
|
||||||
void netplay_core_reset(netplay_t *netplay);
|
|
||||||
|
|
||||||
int16_t netplay_input_state(netplay_t *netplay,
|
|
||||||
unsigned port, unsigned device,
|
|
||||||
unsigned idx, unsigned id);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* netplay_poll:
|
|
||||||
* @netplay : pointer to netplay object
|
|
||||||
*
|
|
||||||
* Polls network to see if we have anything new. If our
|
|
||||||
* network buffer is full, we simply have to block
|
|
||||||
* for new input data.
|
|
||||||
*
|
|
||||||
* Returns: true (1) if successful, otherwise false (0).
|
|
||||||
**/
|
|
||||||
bool netplay_poll(
|
|
||||||
bool block_libretro_input,
|
|
||||||
void *settings_data,
|
|
||||||
netplay_t *netplay);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* netplay_is_alive:
|
|
||||||
* @netplay : pointer to netplay object
|
|
||||||
*
|
|
||||||
* Checks if input port/index is controlled by netplay or not.
|
|
||||||
*
|
|
||||||
* Returns: true (1) if alive, otherwise false (0).
|
|
||||||
**/
|
|
||||||
bool netplay_is_alive(netplay_t *netplay);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* netplay_should_skip:
|
|
||||||
* @netplay : pointer to netplay object
|
|
||||||
*
|
|
||||||
* If we're fast-forward replaying to resync, check if we
|
|
||||||
* should actually show frame.
|
|
||||||
*
|
|
||||||
* Returns: bool (1) if we should skip this frame, otherwise
|
|
||||||
* false (0).
|
|
||||||
**/
|
|
||||||
bool netplay_should_skip(netplay_t *netplay);
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* init_netplay
|
* init_netplay
|
||||||
* @server : server address to connect to (client only)
|
* @server : server address to connect to (client only)
|
||||||
|
@ -410,33 +279,22 @@ bool netplay_should_skip(netplay_t *netplay);
|
||||||
* Returns: true (1) if successful, otherwise false (0).
|
* Returns: true (1) if successful, otherwise false (0).
|
||||||
**/
|
**/
|
||||||
bool init_netplay(const char *server, unsigned port, const char *mitm_session);
|
bool init_netplay(const char *server, unsigned port, const char *mitm_session);
|
||||||
|
bool init_netplay_deferred(const char *server, unsigned port,
|
||||||
bool init_netplay_deferred(const char *server, unsigned port, const char *mitm_session);
|
const char *mitm_session);
|
||||||
|
|
||||||
void deinit_netplay(void);
|
void deinit_netplay(void);
|
||||||
|
|
||||||
void video_frame_net(const void *data, unsigned width,
|
bool netplay_driver_ctl(enum rarch_netplay_ctl_state state, void *data);
|
||||||
unsigned height, size_t pitch);
|
|
||||||
void audio_sample_net(int16_t left, int16_t right);
|
|
||||||
size_t audio_sample_batch_net(const int16_t *data, size_t frames);
|
|
||||||
int16_t input_state_net(unsigned port, unsigned device,
|
|
||||||
unsigned idx, unsigned id);
|
|
||||||
|
|
||||||
#ifdef HAVE_NETPLAYDISCOVERY
|
#ifdef HAVE_NETPLAYDISCOVERY
|
||||||
/** Initialize Netplay discovery */
|
/** Initialize Netplay discovery */
|
||||||
bool init_netplay_discovery(void);
|
bool init_netplay_discovery(void);
|
||||||
|
|
||||||
/** Deinitialize and free Netplay discovery */
|
/** Deinitialize and free Netplay discovery */
|
||||||
void deinit_netplay_discovery(void);
|
void deinit_netplay_discovery(void);
|
||||||
|
|
||||||
/** Discovery control */
|
/** Discovery control */
|
||||||
bool netplay_discovery_driver_ctl(
|
bool netplay_discovery_driver_ctl(enum rarch_netplay_discovery_ctl_state state,
|
||||||
enum rarch_netplay_discovery_ctl_state state, void *data);
|
void *data);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
bool netplay_decode_hostname(const char *hostname,
|
extern const mitm_server_t netplay_mitm_server_list[NETPLAY_MITM_SERVERS];
|
||||||
char *address, unsigned *port, char *session, size_t len);
|
|
||||||
bool netplay_is_lan_address(struct sockaddr_in *addr);
|
|
||||||
bool netplay_6to4(struct sockaddr_storage *addr);
|
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -20,25 +20,30 @@
|
||||||
#define __RARCH_NETPLAY_PRIVATE_H
|
#define __RARCH_NETPLAY_PRIVATE_H
|
||||||
|
|
||||||
#include "netplay.h"
|
#include "netplay.h"
|
||||||
|
#include "netplay_protocol.h"
|
||||||
|
|
||||||
|
#include <libretro.h>
|
||||||
|
#include <retro_miscellaneous.h>
|
||||||
|
|
||||||
#include <streams/trans_stream.h>
|
#include <streams/trans_stream.h>
|
||||||
|
|
||||||
|
#include "../../retroarch_types.h"
|
||||||
|
|
||||||
#define RARCH_DEFAULT_PORT 55435
|
#define RARCH_DEFAULT_PORT 55435
|
||||||
#define RARCH_DEFAULT_NICK "Anonymous"
|
#define RARCH_DEFAULT_NICK "Anonymous"
|
||||||
|
|
||||||
#define NETPLAY_PASS_LEN 128
|
#define NETPLAY_PASS_LEN 128
|
||||||
#define NETPLAY_PASS_HASH_LEN 64 /* length of a SHA-256 hash */
|
#define NETPLAY_PASS_HASH_LEN 64 /* length of a SHA-256 hash */
|
||||||
|
|
||||||
#define MAX_SERVER_STALL_TIME_USEC (5*1000*1000)
|
#define MAX_SERVER_STALL_TIME_USEC (5*1000*1000)
|
||||||
#define MAX_CLIENT_STALL_TIME_USEC (10*1000*1000)
|
#define MAX_CLIENT_STALL_TIME_USEC (10*1000*1000)
|
||||||
#define CATCH_UP_CHECK_TIME_USEC (500*1000)
|
#define CATCH_UP_CHECK_TIME_USEC (500*1000)
|
||||||
#define MAX_RETRIES 16
|
#define MAX_RETRIES 16
|
||||||
#define RETRY_MS 500
|
#define RETRY_MS 500
|
||||||
#define MAX_INPUT_DEVICES 16
|
#define MAX_INPUT_DEVICES 16
|
||||||
|
|
||||||
/* We allow only 32 clients to fit into a 32-bit bitmap */
|
/* We allow only 32 clients to fit into a 32-bit bitmap */
|
||||||
#define MAX_CLIENTS 32
|
#define MAX_CLIENTS 32
|
||||||
typedef uint32_t client_bitmap_t;
|
|
||||||
|
|
||||||
/* Because the callback keyboard reverses some assumptions, when the keyboard
|
/* Because the callback keyboard reverses some assumptions, when the keyboard
|
||||||
* callbacks are in use, we assign a pseudodevice for it */
|
* callbacks are in use, we assign a pseudodevice for it */
|
||||||
|
@ -63,8 +68,9 @@ typedef uint32_t client_bitmap_t;
|
||||||
/* Mapping of serialization quirks to netplay quirks. */
|
/* Mapping of serialization quirks to netplay quirks. */
|
||||||
#define NETPLAY_QUIRK_MAP_UNDERSTOOD (\
|
#define NETPLAY_QUIRK_MAP_UNDERSTOOD (\
|
||||||
RETRO_SERIALIZATION_QUIRK_INCOMPLETE |\
|
RETRO_SERIALIZATION_QUIRK_INCOMPLETE |\
|
||||||
RETRO_SERIALIZATION_QUIRK_CORE_VARIABLE_SIZE |\
|
|
||||||
RETRO_SERIALIZATION_QUIRK_MUST_INITIALIZE |\
|
RETRO_SERIALIZATION_QUIRK_MUST_INITIALIZE |\
|
||||||
|
RETRO_SERIALIZATION_QUIRK_CORE_VARIABLE_SIZE |\
|
||||||
|
RETRO_SERIALIZATION_QUIRK_FRONT_VARIABLE_SIZE |\
|
||||||
RETRO_SERIALIZATION_QUIRK_SINGLE_SESSION |\
|
RETRO_SERIALIZATION_QUIRK_SINGLE_SESSION |\
|
||||||
RETRO_SERIALIZATION_QUIRK_ENDIAN_DEPENDENT |\
|
RETRO_SERIALIZATION_QUIRK_ENDIAN_DEPENDENT |\
|
||||||
RETRO_SERIALIZATION_QUIRK_PLATFORM_DEPENDENT \
|
RETRO_SERIALIZATION_QUIRK_PLATFORM_DEPENDENT \
|
||||||
|
@ -89,6 +95,18 @@ typedef uint32_t client_bitmap_t;
|
||||||
#define NETPLAY_COMPRESSION_SUPPORTED 0
|
#define NETPLAY_COMPRESSION_SUPPORTED 0
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
/* The keys supported by netplay */
|
||||||
|
enum netplay_keys
|
||||||
|
{
|
||||||
|
NETPLAY_KEY_UNKNOWN = 0,
|
||||||
|
#define K(k) NETPLAY_KEY_ ## k,
|
||||||
|
#define KL(k,l) K(k)
|
||||||
|
#include "netplay_keys.h"
|
||||||
|
#undef KL
|
||||||
|
#undef K
|
||||||
|
NETPLAY_KEY_LAST
|
||||||
|
};
|
||||||
|
|
||||||
enum netplay_cmd
|
enum netplay_cmd
|
||||||
{
|
{
|
||||||
/* Basic commands */
|
/* Basic commands */
|
||||||
|
@ -194,11 +212,11 @@ enum netplay_cmd
|
||||||
NETPLAY_CMD_SETTING_INPUT_LATENCY_FRAMES = 0x2001
|
NETPLAY_CMD_SETTING_INPUT_LATENCY_FRAMES = 0x2001
|
||||||
};
|
};
|
||||||
|
|
||||||
#define NETPLAY_CMD_SYNC_BIT_PAUSED (1U<<31)
|
#define NETPLAY_CMD_SYNC_BIT_PAUSED (1U<<31)
|
||||||
#define NETPLAY_CMD_PLAY_BIT_SLAVE (1U<<31)
|
#define NETPLAY_CMD_PLAY_BIT_SLAVE (1U<<31)
|
||||||
#define NETPLAY_CMD_MODE_BIT_YOU (1U<<31)
|
#define NETPLAY_CMD_MODE_BIT_YOU (1U<<31)
|
||||||
#define NETPLAY_CMD_MODE_BIT_PLAYING (1U<<30)
|
#define NETPLAY_CMD_MODE_BIT_PLAYING (1U<<30)
|
||||||
#define NETPLAY_CMD_MODE_BIT_SLAVE (1U<<29)
|
#define NETPLAY_CMD_MODE_BIT_SLAVE (1U<<29)
|
||||||
|
|
||||||
/* These are the reasons given for mode changes to be rejected */
|
/* These are the reasons given for mode changes to be rejected */
|
||||||
enum netplay_cmd_mode_reasons
|
enum netplay_cmd_mode_reasons
|
||||||
|
@ -224,22 +242,22 @@ enum rarch_netplay_share_preference
|
||||||
{
|
{
|
||||||
/* Prefer not to share, shouldn't be set
|
/* Prefer not to share, shouldn't be set
|
||||||
as a sharing mode for an shared device */
|
as a sharing mode for an shared device */
|
||||||
NETPLAY_SHARE_NO_SHARING = 0x0,
|
NETPLAY_SHARE_NO_SHARING = 0x00,
|
||||||
|
|
||||||
/* No preference. Only for requests.
|
/* No preference. Only for requests.
|
||||||
Set if sharing is requested but either
|
Set if sharing is requested but either
|
||||||
* digital or analog doesn't have a preference. */
|
* digital or analog doesn't have a preference. */
|
||||||
NETPLAY_SHARE_NO_PREFERENCE = 0x1,
|
NETPLAY_SHARE_NO_PREFERENCE = 0x01,
|
||||||
|
|
||||||
/* For digital devices */
|
/* For digital devices */
|
||||||
NETPLAY_SHARE_DIGITAL_BITS = 0x1C,
|
NETPLAY_SHARE_DIGITAL_BITS = 0x1C,
|
||||||
NETPLAY_SHARE_DIGITAL_OR = 0x4,
|
NETPLAY_SHARE_DIGITAL_OR = 0x04,
|
||||||
NETPLAY_SHARE_DIGITAL_XOR = 0x8,
|
NETPLAY_SHARE_DIGITAL_XOR = 0x08,
|
||||||
NETPLAY_SHARE_DIGITAL_VOTE = 0xC,
|
NETPLAY_SHARE_DIGITAL_VOTE = 0x0C,
|
||||||
|
|
||||||
/* For analog devices */
|
/* For analog devices */
|
||||||
NETPLAY_SHARE_ANALOG_BITS = 0xE0,
|
NETPLAY_SHARE_ANALOG_BITS = 0xE0,
|
||||||
NETPLAY_SHARE_ANALOG_MAX = 0x20,
|
NETPLAY_SHARE_ANALOG_MAX = 0x20,
|
||||||
NETPLAY_SHARE_ANALOG_AVERAGE = 0x40
|
NETPLAY_SHARE_ANALOG_AVERAGE = 0x40
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -300,7 +318,7 @@ struct delta_frame
|
||||||
|
|
||||||
/* The simulated input. is_real here means the simulation is done, i.e.,
|
/* The simulated input. is_real here means the simulation is done, i.e.,
|
||||||
* it's a real simulation, not real input. */
|
* it's a real simulation, not real input. */
|
||||||
netplay_input_state_t simlated_input[MAX_INPUT_DEVICES];
|
netplay_input_state_t simulated_input[MAX_INPUT_DEVICES];
|
||||||
|
|
||||||
/* The serialized state of the core at this frame, before input */
|
/* The serialized state of the core at this frame, before input */
|
||||||
void *state;
|
void *state;
|
||||||
|
@ -339,14 +357,18 @@ struct netplay_connection
|
||||||
/* Timer used to estimate a connection's latency */
|
/* Timer used to estimate a connection's latency */
|
||||||
retro_time_t ping_timer;
|
retro_time_t ping_timer;
|
||||||
|
|
||||||
/* Address of peer */
|
|
||||||
struct sockaddr_storage addr;
|
|
||||||
|
|
||||||
/* Buffers for sending and receiving data */
|
/* Buffers for sending and receiving data */
|
||||||
struct socket_buffer send_packet_buffer, recv_packet_buffer;
|
struct socket_buffer send_packet_buffer;
|
||||||
|
struct socket_buffer recv_packet_buffer;
|
||||||
|
|
||||||
/* fd associated with this connection */
|
/* What compression does this peer support? */
|
||||||
int fd;
|
uint32_t compression_supported;
|
||||||
|
|
||||||
|
/* Salt associated with password transaction */
|
||||||
|
uint32_t salt;
|
||||||
|
|
||||||
|
/* Which netplay protocol is this connection running? */
|
||||||
|
uint32_t netplay_protocol;
|
||||||
|
|
||||||
/* If the mode is a DELAYED_DISCONNECT or SPECTATOR,
|
/* If the mode is a DELAYED_DISCONNECT or SPECTATOR,
|
||||||
* the transmission of the mode change may have to
|
* the transmission of the mode change may have to
|
||||||
|
@ -355,43 +377,37 @@ struct netplay_connection
|
||||||
* is active. */
|
* is active. */
|
||||||
uint32_t delay_frame;
|
uint32_t delay_frame;
|
||||||
|
|
||||||
/* What compression does this peer support? */
|
|
||||||
uint32_t compression_supported;
|
|
||||||
|
|
||||||
/* For the server: When was the last time we requested
|
/* For the server: When was the last time we requested
|
||||||
* this client to stall?
|
* this client to stall?
|
||||||
* For the client: How many frames of stall do we have left? */
|
* For the client: How many frames of stall do we have left? */
|
||||||
uint32_t stall_frame;
|
uint32_t stall_frame;
|
||||||
|
|
||||||
/* Salt associated with password transaction */
|
|
||||||
uint32_t salt;
|
|
||||||
|
|
||||||
/* Which netplay protocol is this connection running? */
|
|
||||||
uint32_t netplay_protocol;
|
|
||||||
|
|
||||||
/* What latency is this connection running on?
|
/* What latency is this connection running on?
|
||||||
* Network latency has limited precision as we estimate it
|
* Network latency has limited precision as we estimate it
|
||||||
* once every pre-frame. */
|
* once every pre-frame. */
|
||||||
int32_t ping;
|
int32_t ping;
|
||||||
|
|
||||||
/* Is this connection stalling? */
|
/* fd associated with this connection */
|
||||||
enum rarch_netplay_stall_reason stall;
|
int fd;
|
||||||
|
|
||||||
/* Mode of the connection */
|
/* Mode of the connection */
|
||||||
enum rarch_netplay_connection_mode mode;
|
enum rarch_netplay_connection_mode mode;
|
||||||
|
|
||||||
|
/* Is this connection stalling? */
|
||||||
|
enum rarch_netplay_stall_reason stall;
|
||||||
|
|
||||||
/* Nickname of peer */
|
/* Nickname of peer */
|
||||||
char nick[NETPLAY_NICK_LEN];
|
char nick[NETPLAY_NICK_LEN];
|
||||||
|
|
||||||
|
/* Is this connection buffer in use? */
|
||||||
|
bool active;
|
||||||
|
|
||||||
/* Is this player paused? */
|
/* Is this player paused? */
|
||||||
bool paused;
|
bool paused;
|
||||||
|
|
||||||
/* Is this connection allowed to play (server only)? */
|
/* Is this connection allowed to play (server only)? */
|
||||||
bool can_play;
|
bool can_play;
|
||||||
|
|
||||||
/* Is this connection buffer in use? */
|
|
||||||
bool active;
|
|
||||||
|
|
||||||
/* Did we request a ping response? */
|
/* Did we request a ping response? */
|
||||||
bool ping_requested;
|
bool ping_requested;
|
||||||
};
|
};
|
||||||
|
@ -400,8 +416,8 @@ struct netplay_connection
|
||||||
struct compression_transcoder
|
struct compression_transcoder
|
||||||
{
|
{
|
||||||
const struct trans_stream_backend *compression_backend;
|
const struct trans_stream_backend *compression_backend;
|
||||||
void *compression_stream;
|
|
||||||
const struct trans_stream_backend *decompression_backend;
|
const struct trans_stream_backend *decompression_backend;
|
||||||
|
void *compression_stream;
|
||||||
void *decompression_stream;
|
void *decompression_stream;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -423,42 +439,52 @@ struct netplay_mitm_pending
|
||||||
int fds[NETPLAY_MITM_MAX_PENDING];
|
int fds[NETPLAY_MITM_MAX_PENDING];
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct netplay_chat
|
||||||
|
{
|
||||||
|
struct
|
||||||
|
{
|
||||||
|
uint32_t frames;
|
||||||
|
char nick[NETPLAY_NICK_LEN];
|
||||||
|
char msg[NETPLAY_CHAT_MAX_SIZE];
|
||||||
|
} messages[NETPLAY_CHAT_MAX_MESSAGES];
|
||||||
|
};
|
||||||
|
|
||||||
struct netplay
|
struct netplay
|
||||||
{
|
{
|
||||||
/* Quirks in the savestate implementation */
|
/* Quirks in the savestate implementation */
|
||||||
uint64_t quirks;
|
uint64_t quirks;
|
||||||
|
|
||||||
|
/* We stall if we're far enough ahead that we
|
||||||
|
* couldn't transparently rewind.
|
||||||
|
* To know if we could transparently rewind,
|
||||||
|
* we need to know how long running a frame takes.
|
||||||
|
* We record that every frame and get a running (window) average. */
|
||||||
|
retro_time_t frame_run_time[NETPLAY_FRAME_RUN_TIME_WINDOW];
|
||||||
|
retro_time_t frame_run_time_sum;
|
||||||
|
retro_time_t frame_run_time_avg;
|
||||||
|
|
||||||
/* When did we start falling behind? */
|
/* When did we start falling behind? */
|
||||||
retro_time_t catch_up_time;
|
retro_time_t catch_up_time;
|
||||||
/* How long have we been stalled? */
|
/* How long have we been stalled? */
|
||||||
retro_time_t stall_time;
|
retro_time_t stall_time;
|
||||||
|
|
||||||
/* We stall if we're far enough ahead that we
|
|
||||||
* couldn't transparently rewind.
|
|
||||||
* To know if we could transparently rewind,
|
|
||||||
* we need to know how long running a frame takes.
|
|
||||||
* We record that every frame and get a running (window) average. */
|
|
||||||
retro_time_t frame_run_time[NETPLAY_FRAME_RUN_TIME_WINDOW];
|
|
||||||
retro_time_t frame_run_time_sum, frame_run_time_avg;
|
|
||||||
|
|
||||||
struct retro_callbacks cbs;
|
struct retro_callbacks cbs;
|
||||||
|
|
||||||
/* Compression transcoder */
|
/* Compression transcoder */
|
||||||
struct compression_transcoder compress_nil,
|
struct compression_transcoder compress_nil;
|
||||||
compress_zlib;
|
struct compression_transcoder compress_zlib;
|
||||||
|
|
||||||
/* MITM session id */
|
/* MITM session id */
|
||||||
mitm_id_t mitm_session_id;
|
mitm_id_t mitm_session_id;
|
||||||
|
|
||||||
struct netplay_connection one_connection; /* Client only */
|
/* Chat messages */
|
||||||
/* All of our connections */
|
struct netplay_chat chat;
|
||||||
struct netplay_connection *connections;
|
|
||||||
|
|
||||||
/* MITM connection handler */
|
/* MITM connection handler */
|
||||||
struct netplay_mitm_pending *mitm_pending;
|
struct netplay_mitm_pending *mitm_pending;
|
||||||
|
|
||||||
/* Our local socket info */
|
/* All of our connections */
|
||||||
struct addrinfo *addr;
|
struct netplay_connection *connections;
|
||||||
|
|
||||||
struct delta_frame *buffer;
|
struct delta_frame *buffer;
|
||||||
|
|
||||||
|
@ -475,21 +501,21 @@ struct netplay
|
||||||
|
|
||||||
/* The frame we're currently inputting */
|
/* The frame we're currently inputting */
|
||||||
size_t self_ptr;
|
size_t self_ptr;
|
||||||
/* The frame we're currently running, which may be
|
/* The frame we're currently running, which may be
|
||||||
* behind the frame we're currently inputting if
|
* behind the frame we're currently inputting if
|
||||||
* we're using input latency */
|
* we're using input latency */
|
||||||
size_t run_ptr;
|
size_t run_ptr;
|
||||||
/* The first frame at which some data might be unreliable */
|
/* The first frame at which some data might be unreliable */
|
||||||
size_t other_ptr;
|
size_t other_ptr;
|
||||||
/* Pointer to the first frame for which we're missing
|
/* Pointer to the first frame for which we're missing
|
||||||
* the data of at least one connected player excluding ourself.
|
* the data of at least one connected player excluding ourself.
|
||||||
* Generally, other_ptr <= unread_ptr <= self_ptr,
|
* Generally, other_ptr <= unread_ptr <= self_ptr,
|
||||||
* but unread_ptr can get ahead of self_ptr if the peer
|
* but unread_ptr can get ahead of self_ptr if the peer
|
||||||
* is running fast. */
|
* is running fast. */
|
||||||
size_t unread_ptr;
|
size_t unread_ptr;
|
||||||
/* Pointer to the next frame to read from each client */
|
/* Pointer to the next frame to read from each client */
|
||||||
size_t read_ptr[MAX_CLIENTS];
|
size_t read_ptr[MAX_CLIENTS];
|
||||||
/* Pointer to the next frame to read from the server
|
/* Pointer to the next frame to read from the server
|
||||||
* (as it might not be a player but still synchronizes)
|
* (as it might not be a player but still synchronizes)
|
||||||
*/
|
*/
|
||||||
size_t server_ptr;
|
size_t server_ptr;
|
||||||
|
@ -499,9 +525,6 @@ struct netplay
|
||||||
/* Pseudo random seed */
|
/* Pseudo random seed */
|
||||||
unsigned long simple_rand_next;
|
unsigned long simple_rand_next;
|
||||||
|
|
||||||
/* TCP connection for listening (server only) */
|
|
||||||
int listen_fd;
|
|
||||||
|
|
||||||
/* Our client number */
|
/* Our client number */
|
||||||
uint32_t self_client_num;
|
uint32_t self_client_num;
|
||||||
|
|
||||||
|
@ -516,15 +539,11 @@ struct netplay
|
||||||
uint32_t client_devices[MAX_CLIENTS];
|
uint32_t client_devices[MAX_CLIENTS];
|
||||||
|
|
||||||
/* For each device, the bitmap of clients connected */
|
/* For each device, the bitmap of clients connected */
|
||||||
client_bitmap_t device_clients[MAX_INPUT_DEVICES];
|
uint32_t device_clients[MAX_INPUT_DEVICES];
|
||||||
|
|
||||||
/* Our own device bitmap */
|
/* Our own device bitmap */
|
||||||
uint32_t self_devices;
|
uint32_t self_devices;
|
||||||
|
|
||||||
/* Number of desync operations we're currently performing.
|
|
||||||
* If set, we don't attempt to stay in sync. */
|
|
||||||
uint32_t desync;
|
|
||||||
|
|
||||||
/* The device types for every connected device.
|
/* The device types for every connected device.
|
||||||
* We store them and ignore any menu changes,
|
* We store them and ignore any menu changes,
|
||||||
* as netplay needs fixed devices. */
|
* as netplay needs fixed devices. */
|
||||||
|
@ -538,31 +557,46 @@ struct netplay
|
||||||
uint32_t server_frame_count;
|
uint32_t server_frame_count;
|
||||||
uint32_t replay_frame_count;
|
uint32_t replay_frame_count;
|
||||||
|
|
||||||
int frame_run_time_ptr;
|
|
||||||
|
|
||||||
/* Counter for timeouts */
|
|
||||||
unsigned timeout_cnt;
|
|
||||||
|
|
||||||
/* Latency frames; positive to hide network latency,
|
|
||||||
* negative to hide input latency */
|
|
||||||
int input_latency_frames;
|
|
||||||
|
|
||||||
/* Frequency with which to check CRCs */
|
|
||||||
int check_frames;
|
|
||||||
|
|
||||||
/* How far behind did we fall? */
|
/* How far behind did we fall? */
|
||||||
uint32_t catch_up_behind;
|
uint32_t catch_up_behind;
|
||||||
|
|
||||||
|
/* Number of desync operations we're currently performing.
|
||||||
|
* If set, we don't attempt to stay in sync. */
|
||||||
|
uint32_t desync;
|
||||||
|
|
||||||
/* Host settings */
|
/* Host settings */
|
||||||
int32_t input_latency_frames_min;
|
int32_t input_latency_frames_min;
|
||||||
int32_t input_latency_frames_max;
|
int32_t input_latency_frames_max;
|
||||||
|
|
||||||
/* Are we stalled? */
|
/* Counter for timeouts */
|
||||||
enum rarch_netplay_stall_reason stall;
|
unsigned timeout_cnt;
|
||||||
|
|
||||||
|
/* TCP connection for listening (server only) */
|
||||||
|
int listen_fd;
|
||||||
|
|
||||||
|
int frame_run_time_ptr;
|
||||||
|
|
||||||
|
/* Frequency with which to check CRCs */
|
||||||
|
int check_frames;
|
||||||
|
|
||||||
|
/* Latency frames; positive to hide network latency,
|
||||||
|
* negative to hide input latency */
|
||||||
|
int input_latency_frames;
|
||||||
|
|
||||||
|
int reannounce;
|
||||||
|
|
||||||
|
int reping;
|
||||||
|
|
||||||
/* Our mode and status */
|
/* Our mode and status */
|
||||||
enum rarch_netplay_connection_mode self_mode;
|
enum rarch_netplay_connection_mode self_mode;
|
||||||
|
|
||||||
|
/* Are we stalled? */
|
||||||
|
enum rarch_netplay_stall_reason stall;
|
||||||
|
|
||||||
|
/* Keyboard mapping (network and host) */
|
||||||
|
uint16_t mapping_hton[RETROK_LAST];
|
||||||
|
uint16_t mapping_ntoh[NETPLAY_KEY_LAST];
|
||||||
|
|
||||||
/* TCP port (only set if serving) */
|
/* TCP port (only set if serving) */
|
||||||
uint16_t tcp_port;
|
uint16_t tcp_port;
|
||||||
uint16_t ext_tcp_port;
|
uint16_t ext_tcp_port;
|
||||||
|
@ -573,8 +607,6 @@ struct netplay
|
||||||
/* Our nickname */
|
/* Our nickname */
|
||||||
char nick[NETPLAY_NICK_LEN];
|
char nick[NETPLAY_NICK_LEN];
|
||||||
|
|
||||||
bool nat_traversal;
|
|
||||||
|
|
||||||
/* Set to true if we have a device that most cores
|
/* Set to true if we have a device that most cores
|
||||||
* translate to "up/down" actions, typically a keyboard.
|
* translate to "up/down" actions, typically a keyboard.
|
||||||
* We need to keep track of this because with such a device,
|
* We need to keep track of this because with such a device,
|
||||||
|
@ -583,11 +615,30 @@ struct netplay
|
||||||
* up/down states will proceed as expected. */
|
* up/down states will proceed as expected. */
|
||||||
bool have_updown_device;
|
bool have_updown_device;
|
||||||
|
|
||||||
|
/* If true, never progress without peer input
|
||||||
|
* (stateless/rewindless mode) */
|
||||||
|
bool stateless_mode;
|
||||||
|
|
||||||
|
/* Are we the server? */
|
||||||
|
bool is_server;
|
||||||
|
|
||||||
|
bool nat_traversal;
|
||||||
|
|
||||||
|
/* Have we checked whether CRCs are valid at all? */
|
||||||
|
bool crc_validity_checked;
|
||||||
|
|
||||||
|
/* Are they valid? */
|
||||||
|
bool crcs_valid;
|
||||||
|
|
||||||
|
/* Netplay pausing */
|
||||||
|
bool local_paused;
|
||||||
|
bool remote_paused;
|
||||||
|
|
||||||
/* Are we replaying old frames? */
|
/* Are we replaying old frames? */
|
||||||
bool is_replay;
|
bool is_replay;
|
||||||
|
|
||||||
/* We don't want to poll several times on a frame. */
|
/* Opposite of stalling, should we be catching up? */
|
||||||
bool can_poll;
|
bool catch_up;
|
||||||
|
|
||||||
/* Force a rewind to other_frame_count/other_ptr.
|
/* Force a rewind to other_frame_count/other_ptr.
|
||||||
* This is for synchronized events, such as restarting
|
* This is for synchronized events, such as restarting
|
||||||
|
@ -603,33 +654,17 @@ struct netplay
|
||||||
/* Have we requested a savestate as a sync point? */
|
/* Have we requested a savestate as a sync point? */
|
||||||
bool savestate_request_outstanding;
|
bool savestate_request_outstanding;
|
||||||
|
|
||||||
/* Netplay pausing */
|
|
||||||
bool local_paused;
|
|
||||||
bool remote_paused;
|
|
||||||
|
|
||||||
/* If true, never progress without peer input
|
|
||||||
* (stateless/rewindless mode) */
|
|
||||||
bool stateless_mode;
|
|
||||||
|
|
||||||
/* Opposite of stalling, should we be catching up? */
|
|
||||||
bool catch_up;
|
|
||||||
|
|
||||||
/* Have we checked whether CRCs are valid at all? */
|
|
||||||
bool crc_validity_checked;
|
|
||||||
|
|
||||||
/* Are they valid? */
|
|
||||||
bool crcs_valid;
|
|
||||||
|
|
||||||
/* Are we the server? */
|
|
||||||
bool is_server;
|
|
||||||
|
|
||||||
/* Are we the connected? */
|
|
||||||
bool is_connected;
|
|
||||||
|
|
||||||
/* Host settings */
|
/* Host settings */
|
||||||
bool allow_pausing;
|
bool allow_pausing;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
void video_frame_net(const void *data,
|
||||||
|
unsigned width, unsigned height, size_t pitch);
|
||||||
|
void audio_sample_net(int16_t left, int16_t right);
|
||||||
|
size_t audio_sample_batch_net(const int16_t *data, size_t frames);
|
||||||
|
int16_t input_state_net(unsigned port, unsigned device,
|
||||||
|
unsigned idx, unsigned id);
|
||||||
|
|
||||||
/***************************************************************
|
/***************************************************************
|
||||||
* NETPLAY-BUF.C
|
* NETPLAY-BUF.C
|
||||||
**************************************************************/
|
**************************************************************/
|
||||||
|
@ -699,69 +734,22 @@ bool netplay_delta_frame_ready(netplay_t *netplay,
|
||||||
struct delta_frame *delta,
|
struct delta_frame *delta,
|
||||||
uint32_t frame);
|
uint32_t frame);
|
||||||
|
|
||||||
/**
|
|
||||||
* netplay_input_state_for
|
|
||||||
*
|
|
||||||
* Get an input state for a particular client
|
|
||||||
*/
|
|
||||||
netplay_input_state_t netplay_input_state_for(
|
|
||||||
netplay_input_state_t *list,
|
|
||||||
uint32_t client_num, size_t size,
|
|
||||||
bool must_create, bool must_not_create);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* netplay_expected_input_size
|
|
||||||
*
|
|
||||||
* Size in words for a given set of devices.
|
|
||||||
*/
|
|
||||||
uint32_t netplay_expected_input_size(netplay_t *netplay,
|
|
||||||
uint32_t devices);
|
|
||||||
|
|
||||||
/***************************************************************
|
/***************************************************************
|
||||||
* NETPLAY-FRONTEND.C
|
* NETPLAY-FRONTEND.C
|
||||||
**************************************************************/
|
**************************************************************/
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* input_poll_net
|
* input_poll_net
|
||||||
|
* @netplay : pointer to netplay object
|
||||||
*
|
*
|
||||||
* Poll the network if necessary.
|
* Poll the network if necessary.
|
||||||
*/
|
*/
|
||||||
void input_poll_net(void);
|
void input_poll_net(netplay_t *netplay);
|
||||||
|
|
||||||
/***************************************************************
|
|
||||||
* 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, uint32_t protocol);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* netplay_handshake
|
|
||||||
*
|
|
||||||
* Data receiver for all handshake states.
|
|
||||||
*/
|
|
||||||
bool netplay_handshake(netplay_t *netplay,
|
|
||||||
struct netplay_connection *connection, bool *had_input);
|
|
||||||
|
|
||||||
/***************************************************************
|
/***************************************************************
|
||||||
* NETPLAY-INIT.C
|
* 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
|
* netplay_wait_and_init_serialization
|
||||||
*
|
*
|
||||||
|
@ -772,59 +760,10 @@ bool netplay_try_init_serialization(netplay_t *netplay);
|
||||||
*/
|
*/
|
||||||
bool netplay_wait_and_init_serialization(netplay_t *netplay);
|
bool netplay_wait_and_init_serialization(netplay_t *netplay);
|
||||||
|
|
||||||
/**
|
|
||||||
* netplay_new:
|
|
||||||
* @server : IP address of server.
|
|
||||||
* @mitm : IP address of the MITM/tunnel server.
|
|
||||||
* @port : Port of server.
|
|
||||||
* @mitm_session : Session id for MITM/tunnel.
|
|
||||||
* @stateless_mode : Shall we run in stateless mode?
|
|
||||||
* @check_frames : Frequency with which to check CRCs.
|
|
||||||
* @cb : Libretro callbacks.
|
|
||||||
* @nat_traversal : If true, attempt NAT traversal.
|
|
||||||
* @nick : Nickname of user.
|
|
||||||
* @quirks : Netplay quirks required for this session.
|
|
||||||
*
|
|
||||||
* Creates a new netplay handle. A NULL server means we're
|
|
||||||
* hosting.
|
|
||||||
*
|
|
||||||
* Returns: new netplay data.
|
|
||||||
*/
|
|
||||||
netplay_t *netplay_new(const char *server, const char *mitm, uint16_t port,
|
|
||||||
const char *mitm_session,
|
|
||||||
bool stateless_mode, int check_frames,
|
|
||||||
const struct retro_callbacks *cb,
|
|
||||||
bool nat_traversal, const char *nick,
|
|
||||||
uint64_t quirks);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* netplay_free
|
|
||||||
* @netplay : pointer to netplay object
|
|
||||||
*
|
|
||||||
* Frees netplay data/
|
|
||||||
*/
|
|
||||||
void netplay_free(netplay_t *netplay);
|
|
||||||
|
|
||||||
/***************************************************************
|
/***************************************************************
|
||||||
* NETPLAY-IO.C
|
* NETPLAY-IO.C
|
||||||
**************************************************************/
|
**************************************************************/
|
||||||
|
|
||||||
/**
|
|
||||||
* netplay_hangup:
|
|
||||||
*
|
|
||||||
* Disconnects an active Netplay connection due to an error
|
|
||||||
*/
|
|
||||||
void netplay_hangup(netplay_t *netplay,
|
|
||||||
struct netplay_connection *connection);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* netplay_delayed_state_change:
|
|
||||||
*
|
|
||||||
* Handle any pending state changes which are ready as
|
|
||||||
* of the beginning of the current frame.
|
|
||||||
*/
|
|
||||||
void netplay_delayed_state_change(netplay_t *netplay);
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* netplay_send_cur_input
|
* netplay_send_cur_input
|
||||||
*
|
*
|
||||||
|
@ -866,85 +805,20 @@ void netplay_send_raw_cmd_all(netplay_t *netplay,
|
||||||
bool netplay_cmd_mode(netplay_t *netplay,
|
bool netplay_cmd_mode(netplay_t *netplay,
|
||||||
enum rarch_netplay_connection_mode mode);
|
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_handle_slaves
|
|
||||||
*
|
|
||||||
* Handle any slave connections
|
|
||||||
*/
|
|
||||||
void netplay_handle_slaves(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);
|
|
||||||
|
|
||||||
void netplay_deinit_nat_traversal(void);
|
|
||||||
|
|
||||||
/***************************************************************
|
|
||||||
* NETPLAY-KEYBOARD.C
|
|
||||||
**************************************************************/
|
|
||||||
|
|
||||||
/* The mapping of keys from libretro (host) to netplay (network) */
|
|
||||||
uint32_t netplay_key_hton(unsigned key);
|
|
||||||
|
|
||||||
/* Because the hton keymapping has to be generated,
|
|
||||||
* call this before using netplay_key_hton */
|
|
||||||
void netplay_key_hton_init(void);
|
|
||||||
|
|
||||||
/***************************************************************
|
/***************************************************************
|
||||||
* NETPLAY-SYNC.C
|
* NETPLAY-SYNC.C
|
||||||
**************************************************************/
|
**************************************************************/
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* netplay_update_unread_ptr
|
* netplay_load_savestate
|
||||||
*
|
|
||||||
* 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);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* netplay_resolve_input
|
|
||||||
* @netplay : pointer to netplay object
|
|
||||||
* @sim_ptr : frame pointer for which to resolve 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.
|
|
||||||
* Returns true if the resolved input changed from the
|
|
||||||
* last time it was resolved.
|
|
||||||
*/
|
|
||||||
bool netplay_resolve_input(netplay_t *netplay,
|
|
||||||
size_t sim_ptr, bool resim);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* netplay_sync_pre_frame
|
|
||||||
* @netplay : pointer to netplay object
|
* @netplay : pointer to netplay object
|
||||||
* @disconnect : disconnect netplay
|
* @serial_info : the savestate being loaded, NULL means
|
||||||
|
* "load it yourself"
|
||||||
|
* @save : Whether to save the provided serial_info
|
||||||
|
* into the frame buffer
|
||||||
*
|
*
|
||||||
* Pre-frame for Netplay synchronization.
|
* Inform Netplay of a savestate load and send it to the other side
|
||||||
*/
|
**/
|
||||||
bool netplay_sync_pre_frame(netplay_t *netplay, bool *disconnect);
|
void netplay_load_savestate(netplay_t *netplay,
|
||||||
|
retro_ctx_serialize_info_t *serial_info, bool save);
|
||||||
/**
|
|
||||||
* netplay_sync_post_frame
|
|
||||||
* @netplay : pointer to netplay object
|
|
||||||
* @stalled : true if we're currently stalled
|
|
||||||
*
|
|
||||||
* 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, bool stalled);
|
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
Loading…
Reference in New Issue