Merge pull request #5429 from GregorR/netplay-input-upgrades-1

Netplay input upgrades 1
This commit is contained in:
Twinaphex 2018-01-23 05:01:45 +01:00 committed by GitHub
commit 4a6a97be60
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
56 changed files with 2407 additions and 1101 deletions

View File

@ -1549,6 +1549,7 @@ ifeq ($(HAVE_NETWORKING), 1)
network/netplay/netplay_handshake.o \
network/netplay/netplay_init.o \
network/netplay/netplay_io.o \
network/netplay/netplay_keyboard.o \
network/netplay/netplay_sync.o \
network/netplay/netplay_discovery.o \
network/netplay/netplay_buf.o \

View File

@ -159,7 +159,6 @@ static const struct cmd_map map[] = {
{ "SCREENSHOT", RARCH_SCREENSHOT },
{ "MUTE", RARCH_MUTE },
{ "OSK", RARCH_OSK },
{ "NETPLAY_FLIP", RARCH_NETPLAY_FLIP },
{ "NETPLAY_GAME_WATCH", RARCH_NETPLAY_GAME_WATCH },
{ "SLOWMOTION", RARCH_SLOWMOTION },
{ "VOLUME_UP", RARCH_VOLUME_UP },
@ -2559,9 +2558,6 @@ TODO: Add a setting for these tweaks */
#endif
}
break;
case CMD_EVENT_NETPLAY_FLIP_PLAYERS:
netplay_driver_ctl(RARCH_NETPLAY_CTL_FLIP_PLAYERS, NULL);
break;
case CMD_EVENT_NETPLAY_GAME_WATCH:
netplay_driver_ctl(RARCH_NETPLAY_CTL_GAME_WATCH, NULL);
break;
@ -2572,7 +2568,6 @@ TODO: Add a setting for these tweaks */
case CMD_EVENT_NETPLAY_INIT:
case CMD_EVENT_NETPLAY_INIT_DIRECT:
case CMD_EVENT_NETPLAY_INIT_DIRECT_DEFERRED:
case CMD_EVENT_NETPLAY_FLIP_PLAYERS:
case CMD_EVENT_NETPLAY_GAME_WATCH:
return false;
#endif

View File

@ -179,8 +179,6 @@ enum event_command
CMD_EVENT_NETPLAY_INIT_DIRECT_DEFERRED,
/* Deinitializes netplay system. */
CMD_EVENT_NETPLAY_DEINIT,
/* Flip netplay players. */
CMD_EVENT_NETPLAY_FLIP_PLAYERS,
/* Switch between netplay gaming and watching. */
CMD_EVENT_NETPLAY_GAME_WATCH,
/* Initializes BSV movie. */

View File

@ -27,6 +27,10 @@
#include "config.h"
#endif
#ifdef HAVE_NETWORKING
#include "network/netplay/netplay.h"
#endif
#if defined(HW_RVL)
#define MAX_GAMMA_SETTING 30
#elif defined(GEKKO)
@ -544,6 +548,10 @@ static const int netplay_check_frames = 600;
static const bool netplay_use_mitm_server = false;
static const unsigned netplay_share_digital = RARCH_NETPLAY_SHARE_DIGITAL_NO_PREFERENCE;
static const unsigned netplay_share_analog = RARCH_NETPLAY_SHARE_ANALOG_NO_PREFERENCE;
/* On save state load, block SRAM from being overwritten.
* This could potentially lead to buggy games. */
static const bool block_sram_overwrite = false;

View File

@ -85,7 +85,6 @@ static const struct retro_keybind retro_keybinds_1[] = {
{ true, RARCH_SCREENSHOT, MENU_ENUM_LABEL_VALUE_INPUT_META_SCREENSHOT, RETROK_UNKNOWN, NO_BTN, NO_BTN, 0, AXIS_NONE },
{ true, RARCH_MUTE, MENU_ENUM_LABEL_VALUE_INPUT_META_MUTE, RETROK_UNKNOWN, NO_BTN, NO_BTN, 0, AXIS_NONE },
{ true, RARCH_OSK, MENU_ENUM_LABEL_VALUE_INPUT_META_OSK, RETROK_UNKNOWN, NO_BTN, NO_BTN, 0, AXIS_NONE },
{ true, RARCH_NETPLAY_FLIP, MENU_ENUM_LABEL_VALUE_INPUT_META_NETPLAY_FLIP, RETROK_UNKNOWN, NO_BTN, NO_BTN, 0, AXIS_NONE },
{ true, RARCH_NETPLAY_GAME_WATCH, MENU_ENUM_LABEL_VALUE_INPUT_META_NETPLAY_GAME_WATCH, RETROK_UNKNOWN, NO_BTN, NO_BTN, 0, AXIS_NONE },
{ true, RARCH_SLOWMOTION, MENU_ENUM_LABEL_VALUE_INPUT_META_SLOWMOTION, RETROK_UNKNOWN, NO_BTN, NO_BTN, 0, AXIS_NONE },
{ true, RARCH_ENABLE_HOTKEY, MENU_ENUM_LABEL_VALUE_INPUT_META_ENABLE_HOTKEY, RETROK_UNKNOWN, NO_BTN, NO_BTN, 0, AXIS_NONE },
@ -160,7 +159,6 @@ static const struct retro_keybind retro_keybinds_1[] = {
{ true, RARCH_SCREENSHOT, MENU_ENUM_LABEL_VALUE_INPUT_META_SCREENSHOT, RETROK_F8, NO_BTN, NO_BTN, 0, AXIS_NONE },
{ true, RARCH_MUTE, MENU_ENUM_LABEL_VALUE_INPUT_META_MUTE, RETROK_F9, NO_BTN, NO_BTN, 0, AXIS_NONE },
{ true, RARCH_OSK, MENU_ENUM_LABEL_VALUE_INPUT_META_OSK, RETROK_F12, NO_BTN, NO_BTN, 0, AXIS_NONE },
{ true, RARCH_NETPLAY_FLIP, MENU_ENUM_LABEL_VALUE_INPUT_META_NETPLAY_FLIP, RETROK_UNKNOWN, NO_BTN, NO_BTN, 0, AXIS_NONE },
{ true, RARCH_NETPLAY_GAME_WATCH, MENU_ENUM_LABEL_VALUE_INPUT_META_NETPLAY_GAME_WATCH, RETROK_i, NO_BTN, NO_BTN, 0, AXIS_NONE },
{ true, RARCH_SLOWMOTION, MENU_ENUM_LABEL_VALUE_INPUT_META_SLOWMOTION, RETROK_e, NO_BTN, NO_BTN, 0, AXIS_NONE },
{ true, RARCH_ENABLE_HOTKEY, MENU_ENUM_LABEL_VALUE_INPUT_META_ENABLE_HOTKEY, RETROK_UNKNOWN, NO_BTN, NO_BTN, 0, AXIS_NONE },

View File

@ -1158,7 +1158,9 @@ static struct config_bool_setting *populate_settings_bool(settings_t *settings,
{
struct config_bool_setting *tmp = (struct config_bool_setting*)malloc((*size + 1) * sizeof(struct config_bool_setting));
unsigned count = 0;
unsigned user;
global_t *global = global_get_ptr();
char cfg[64] = {0};
SETTING_BOOL("automatically_add_content_to_playlist", &settings->bools.automatically_add_content_to_playlist, true, automatically_add_content_to_playlist, false);
SETTING_BOOL("ui_companion_start_on_boot", &settings->bools.ui_companion_start_on_boot, true, ui_companion_start_on_boot, false);
@ -1173,8 +1175,12 @@ static struct config_bool_setting *populate_settings_bool(settings_t *settings,
SETTING_BOOL("netplay_allow_slaves", &settings->bools.netplay_allow_slaves, true, netplay_allow_slaves, false);
SETTING_BOOL("netplay_require_slaves", &settings->bools.netplay_require_slaves, true, netplay_require_slaves, false);
SETTING_BOOL("netplay_stateless_mode", &settings->bools.netplay_stateless_mode, true, netplay_stateless_mode, false);
SETTING_BOOL("netplay_client_swap_input", &settings->bools.netplay_swap_input, true, netplay_client_swap_input, false);
SETTING_BOOL("netplay_use_mitm_server", &settings->bools.netplay_use_mitm_server, true, netplay_use_mitm_server, false);
for (user = 0; user < MAX_USERS; user++)
{
snprintf(cfg, sizeof(cfg)-1, "netplay_request_device_p%u", user + 1);
SETTING_BOOL(strdup(cfg), &settings->bools.netplay_request_devices[user], true, false, false);
}
#endif
SETTING_BOOL("input_descriptor_label_show", &settings->bools.input_descriptor_label_show, true, input_descriptor_label_show, false);
SETTING_BOOL("input_descriptor_hide_unbound", &settings->bools.input_descriptor_hide_unbound, true, input_descriptor_hide_unbound, false);
@ -1468,6 +1474,8 @@ static struct config_uint_setting *populate_settings_uint(settings_t *settings,
SETTING_UINT("netplay_ip_port", &settings->uints.netplay_port, true, RARCH_DEFAULT_PORT, false);
SETTING_UINT("netplay_input_latency_frames_min",&settings->uints.netplay_input_latency_frames_min, true, 0, false);
SETTING_UINT("netplay_input_latency_frames_range",&settings->uints.netplay_input_latency_frames_range, true, 0, false);
SETTING_UINT("netplay_share_digital", &settings->uints.netplay_share_digital, true, netplay_share_digital, false);
SETTING_UINT("netplay_share_analog", &settings->uints.netplay_share_analog, true, netplay_share_analog, false);
#endif
#ifdef HAVE_LANGEXTRA
SETTING_UINT("user_language", msg_hash_get_uint(MSG_HASH_USER_LANGUAGE), true, RETRO_LANGUAGE_ENGLISH, false);

View File

@ -174,9 +174,9 @@ typedef struct settings
bool netplay_allow_slaves;
bool netplay_require_slaves;
bool netplay_stateless_mode;
bool netplay_swap_input;
bool netplay_nat_traversal;
bool netplay_use_mitm_server;
bool netplay_request_devices[MAX_USERS];
/* Network */
bool network_buildbot_auto_extract_archive;
@ -315,6 +315,8 @@ typedef struct settings
unsigned netplay_port;
unsigned netplay_input_latency_frames_min;
unsigned netplay_input_latency_frames_range;
unsigned netplay_share_digital;
unsigned netplay_share_analog;
unsigned bundle_assets_extract_version_current;
unsigned bundle_assets_extract_last_version;
unsigned content_history_size;

View File

@ -1057,6 +1057,7 @@ NETPLAY
#include "../network/netplay/netplay_handshake.c"
#include "../network/netplay/netplay_init.c"
#include "../network/netplay/netplay_io.c"
#include "../network/netplay/netplay_keyboard.c"
#include "../network/netplay/netplay_sync.c"
#include "../network/netplay/netplay_discovery.c"
#include "../network/netplay/netplay_buf.c"

View File

@ -91,7 +91,6 @@ enum
RARCH_SCREENSHOT,
RARCH_MUTE,
RARCH_OSK,
RARCH_NETPLAY_FLIP,
RARCH_NETPLAY_GAME_WATCH,
RARCH_SLOWMOTION,
RARCH_ENABLE_HOTKEY,

View File

@ -317,7 +317,6 @@ const struct input_bind_map input_config_bind_map[RARCH_BIND_LIST_END_NULL] = {
DECLARE_META_BIND(2, screenshot, RARCH_SCREENSHOT, MENU_ENUM_LABEL_VALUE_INPUT_META_SCREENSHOT),
DECLARE_META_BIND(2, audio_mute, RARCH_MUTE, MENU_ENUM_LABEL_VALUE_INPUT_META_MUTE),
DECLARE_META_BIND(2, osk_toggle, RARCH_OSK, MENU_ENUM_LABEL_VALUE_INPUT_META_OSK),
DECLARE_META_BIND(2, netplay_flip_players_1_2, RARCH_NETPLAY_FLIP, MENU_ENUM_LABEL_VALUE_INPUT_META_NETPLAY_FLIP),
DECLARE_META_BIND(2, netplay_game_watch, RARCH_NETPLAY_GAME_WATCH, MENU_ENUM_LABEL_VALUE_INPUT_META_NETPLAY_GAME_WATCH),
DECLARE_META_BIND(2, slowmotion, RARCH_SLOWMOTION, MENU_ENUM_LABEL_VALUE_INPUT_META_SLOWMOTION),
DECLARE_META_BIND(2, enable_hotkey, RARCH_ENABLE_HOTKEY, MENU_ENUM_LABEL_VALUE_INPUT_META_ENABLE_HOTKEY),

View File

@ -92,10 +92,6 @@ int menu_hash_get_help_chs_enum(enum msg_hash_enums msg, char *s, size_t len)
snprintf(s, len,
"显示/隐藏屏显键盘。");
break;
case RARCH_NETPLAY_FLIP:
snprintf(s, len,
"Netplay flip users.");
break;
case RARCH_SLOWMOTION:
snprintf(s, len,
"按住并以慢动作运行。");
@ -1641,11 +1637,6 @@ int menu_hash_get_help_chs_enum(enum msg_hash_enums msg, char *s, size_t len)
"The username of the person running RetroArch. \n"
"This will be used for playing online games.");
break;
case MENU_ENUM_LABEL_NETPLAY_CLIENT_SWAP_INPUT:
snprintf(s, len,
"When being client over netplay, use \n"
"keybinds for player 1.");
break;
case MENU_ENUM_LABEL_NETPLAY_TCP_UDP_PORT:
snprintf(s, len,
"The port of the host IP address. \n"
@ -1748,10 +1739,6 @@ int menu_hash_get_help_chs_enum(enum msg_hash_enums msg, char *s, size_t len)
snprintf(s, len,
"Saves state.");
break;
case MENU_ENUM_LABEL_NETPLAY_FLIP_PLAYERS:
snprintf(s, len,
"Netplay flip users.");
break;
case MENU_ENUM_LABEL_CHEAT_INDEX_PLUS:
snprintf(s, len,
"Increment cheat index.\n");

View File

@ -34,10 +34,6 @@ MSG_HASH(
MSG_NO_ARGUMENTS_SUPPLIED_AND_NO_MENU_BUILTIN,
"未提供参数也没有内建菜单,显示帮助..."
)
MSG_HASH(
MSG_NETPLAY_USERS_HAS_FLIPPED,
"联机游戏用户已被踢出"
)
MSG_HASH(
MSG_SETTING_DISK_IN_TRAY,
"Setting disk in tray"
@ -54,10 +50,6 @@ MSG_HASH(
MSG_NETPLAY_YOU_HAVE_JOINED_AS_PLAYER_N,
"你已作为玩家 %d 加入"
)
MSG_HASH(
MSG_NETPLAY_IMPLEMENTATIONS_DIFFER,
"实现有差异。确保正在使用的RetroArch和核心是同版本的。"
)
MSG_HASH(
MSG_NETPLAY_ENDIAN_DEPENDENT,
"This core does not support inter-architecture netplay between these systems"
@ -824,8 +816,6 @@ MSG_HASH(MENU_ENUM_LABEL_VALUE_INPUT_META_MOVIE_RECORD_TOGGLE,
"视频录制开关")
MSG_HASH(MENU_ENUM_LABEL_VALUE_INPUT_META_MUTE,
"静音开关")
MSG_HASH(MENU_ENUM_LABEL_VALUE_INPUT_META_NETPLAY_FLIP,
"联机游戏踢出用户")
MSG_HASH(MENU_ENUM_LABEL_VALUE_INPUT_META_NETPLAY_GAME_WATCH,
"联机游戏切换 游戏/围观 模式")
MSG_HASH(MENU_ENUM_LABEL_VALUE_INPUT_META_OSK,
@ -1016,8 +1006,6 @@ MSG_HASH(MENU_ENUM_LABEL_VALUE_NETPLAY,
"在线游戏")
MSG_HASH(MENU_ENUM_LABEL_VALUE_NETPLAY_CHECK_FRAMES,
"在线游戏检查帧数")
MSG_HASH(MENU_ENUM_LABEL_VALUE_NETPLAY_CLIENT_SWAP_INPUT,
"在线玩家P2使用C1")
MSG_HASH(MENU_ENUM_LABEL_VALUE_NETPLAY_DELAY_FRAMES,
"在线游戏延迟帧数")
MSG_HASH(MENU_ENUM_LABEL_VALUE_NETPLAY_DISCONNECT,
@ -2775,8 +2763,6 @@ MSG_HASH(MENU_ENUM_SUBLABEL_SORT_SAVEFILES_ENABLE,
MSG_HASH(MENU_ENUM_SUBLABEL_SORT_SAVESTATES_ENABLE,
"Sort save states in folders named after the core used."
)
MSG_HASH(MENU_ENUM_SUBLABEL_NETPLAY_CLIENT_SWAP_INPUT,
"When being client over netplay, use keybinds for Player 1.")
MSG_HASH(MENU_ENUM_SUBLABEL_CORE_UPDATER_BUILDBOT_URL,
"URL to core updater directory on the Libretro buildbot.")
MSG_HASH(MENU_ENUM_SUBLABEL_BUILDBOT_ASSETS_URL,

View File

@ -92,10 +92,6 @@ int menu_hash_get_help_cht_enum(enum msg_hash_enums msg, char *s, size_t len)
snprintf(s, len,
"顯示/隱藏營幕鍵盤。");
break;
case RARCH_NETPLAY_FLIP:
snprintf(s, len,
"Netplay flip users.");
break;
case RARCH_SLOWMOTION:
snprintf(s, len,
"按住並以慢動作運行。");
@ -1638,11 +1634,6 @@ int menu_hash_get_help_cht_enum(enum msg_hash_enums msg, char *s, size_t len)
"The username of the person running RetroArch. \n"
"This will be used for playing online games.");
break;
case MENU_ENUM_LABEL_NETPLAY_CLIENT_SWAP_INPUT:
snprintf(s, len,
"When being client over netplay, use \n"
"keybinds for player 1.");
break;
case MENU_ENUM_LABEL_NETPLAY_TCP_UDP_PORT:
snprintf(s, len,
"The port of the host IP address. \n"
@ -1745,10 +1736,6 @@ int menu_hash_get_help_cht_enum(enum msg_hash_enums msg, char *s, size_t len)
snprintf(s, len,
"儲存即時存檔.");
break;
case MENU_ENUM_LABEL_NETPLAY_FLIP_PLAYERS:
snprintf(s, len,
"踢掉連線遊戲的使用者.");
break;
case MENU_ENUM_LABEL_CHEAT_INDEX_PLUS:
snprintf(s, len,
"Increment cheat index.\n");

View File

@ -34,10 +34,6 @@ MSG_HASH(
MSG_NO_ARGUMENTS_SUPPLIED_AND_NO_MENU_BUILTIN,
"未提供參數也沒有內建選單,顯示幫助..."
)
MSG_HASH(
MSG_NETPLAY_USERS_HAS_FLIPPED,
"連線遊戲用戶已被踢出"
)
MSG_HASH(
MSG_SETTING_DISK_IN_TRAY,
"設定光碟機裡光碟"
@ -54,10 +50,6 @@ MSG_HASH(
MSG_NETPLAY_YOU_HAVE_JOINED_AS_PLAYER_N,
"你已作為玩家 %d 加入"
)
MSG_HASH(
MSG_NETPLAY_IMPLEMENTATIONS_DIFFER,
"執行時錯誤發生。請確保雙方的所使用的RetroArch跟核心是同版本的。"
)
MSG_HASH(
MSG_NETPLAY_ENDIAN_DEPENDENT,
"This core does not support inter-architecture netplay between these systems"
@ -824,8 +816,6 @@ MSG_HASH(MENU_ENUM_LABEL_VALUE_INPUT_META_MOVIE_RECORD_TOGGLE,
"視訊錄製開關")
MSG_HASH(MENU_ENUM_LABEL_VALUE_INPUT_META_MUTE,
"靜音開關")
MSG_HASH(MENU_ENUM_LABEL_VALUE_INPUT_META_NETPLAY_FLIP,
"連線遊戲踢出用戶")
MSG_HASH(MENU_ENUM_LABEL_VALUE_INPUT_META_NETPLAY_GAME_WATCH,
"連線遊戲切換 遊戲/圍觀 模式")
MSG_HASH(MENU_ENUM_LABEL_VALUE_INPUT_META_OSK,
@ -1016,8 +1006,6 @@ MSG_HASH(MENU_ENUM_LABEL_VALUE_NETPLAY,
"連線遊戲")
MSG_HASH(MENU_ENUM_LABEL_VALUE_NETPLAY_CHECK_FRAMES,
"連線遊戲檢查幀數")
MSG_HASH(MENU_ENUM_LABEL_VALUE_NETPLAY_CLIENT_SWAP_INPUT,
"連線玩家P2使用C1")
MSG_HASH(MENU_ENUM_LABEL_VALUE_NETPLAY_DELAY_FRAMES,
"連線遊戲延遲幀數")
MSG_HASH(MENU_ENUM_LABEL_VALUE_NETPLAY_DISCONNECT,
@ -2769,8 +2757,6 @@ MSG_HASH(MENU_ENUM_SUBLABEL_SORT_SAVEFILES_ENABLE,
MSG_HASH(MENU_ENUM_SUBLABEL_SORT_SAVESTATES_ENABLE,
"Sort save states in folders named after the core used."
)
MSG_HASH(MENU_ENUM_SUBLABEL_NETPLAY_CLIENT_SWAP_INPUT,
"When being client over netplay, use keybinds for Player 1.")
MSG_HASH(MENU_ENUM_SUBLABEL_CORE_UPDATER_BUILDBOT_URL,
"URL to core updater directory on the Libretro buildbot.")
MSG_HASH(MENU_ENUM_SUBLABEL_BUILDBOT_ASSETS_URL,

View File

@ -87,10 +87,6 @@ int menu_hash_get_help_de_enum(enum msg_hash_enums msg, char *s, size_t len)
snprintf(s, len,
"Bildschirmtastatur ein-/ausschalten.");
break;
case RARCH_NETPLAY_FLIP:
snprintf(s, len,
"Netplay-Spieler tauschen.");
break;
case RARCH_NETPLAY_GAME_WATCH:
snprintf(s, len,
"Im Netplay zwischen Spiel- und Beobachter-Modus wechseln.");
@ -1772,11 +1768,6 @@ int menu_hash_get_help_de_enum(enum msg_hash_enums msg, char *s, size_t len)
"Der Benutzername der Person, die RetroArch verwendet. \n"
"Wird in Online-Spielen verwendet.");
break;
case MENU_ENUM_LABEL_NETPLAY_CLIENT_SWAP_INPUT:
snprintf(s, len,
"Verwendet Tastenbelegung für Spieler 1, \n"
"wenn du Teilnehmer an einem Netplay-Spiel bist.");
break;
case MENU_ENUM_LABEL_NETPLAY_TCP_UDP_PORT:
snprintf(s, len,
"Der Port der Host-IP-Adresse. \n"
@ -1892,10 +1883,6 @@ int menu_hash_get_help_de_enum(enum msg_hash_enums msg, char *s, size_t len)
snprintf(s, len,
"Speichert Save-State.");
break;
case MENU_ENUM_LABEL_NETPLAY_FLIP_PLAYERS:
snprintf(s, len,
"Netplay-Benutzer vertauschen.");
break;
case MENU_ENUM_LABEL_CHEAT_INDEX_PLUS:
snprintf(s, len,
"Cheat-Index erhöhen.\n");

View File

@ -34,10 +34,6 @@ MSG_HASH(
MSG_NO_ARGUMENTS_SUPPLIED_AND_NO_MENU_BUILTIN,
"Es wurden keine Argumente übergeben, außerdem ist kein Menü vorhanden - zeige Hilfe an..."
)
MSG_HASH(
MSG_NETPLAY_USERS_HAS_FLIPPED,
"Netplay-Benutzer wurden vertauscht"
)
MSG_HASH(
MSG_SETTING_DISK_IN_TRAY,
"Lege Datenträger in Laufwerksschublade ein"
@ -54,10 +50,6 @@ MSG_HASH(
MSG_NETPLAY_YOU_HAVE_JOINED_AS_PLAYER_N,
"Du bist als Spieler %d beigetreten"
)
MSG_HASH(
MSG_NETPLAY_IMPLEMENTATIONS_DIFFER,
"Unterschiedliche Implementierungen. Stelle sicher, dass Du die gleiche Version von RetroArch und dem Core verwendest."
)
MSG_HASH(
MSG_NETPLAY_ENDIAN_DEPENDENT,
"Dieser Core unterstützt kein Netplay zwischen diesen Systemen"
@ -831,8 +823,6 @@ MSG_HASH(MENU_ENUM_LABEL_VALUE_INPUT_META_MOVIE_RECORD_TOGGLE,
"Videoaufzeichnung starten/beenden")
MSG_HASH(MENU_ENUM_LABEL_VALUE_INPUT_META_MUTE,
"Audio stumm-/lautschalten")
MSG_HASH(MENU_ENUM_LABEL_VALUE_INPUT_META_NETPLAY_FLIP,
"Netplay-Benutzer vertauschen")
MSG_HASH(MENU_ENUM_LABEL_VALUE_INPUT_META_NETPLAY_GAME_WATCH,
"Zwischen Spieler- und Beobachter-Modus wechseln")
MSG_HASH(MENU_ENUM_LABEL_VALUE_INPUT_META_OSK,
@ -1033,8 +1023,6 @@ MSG_HASH(MENU_ENUM_LABEL_VALUE_NETPLAY_INPUT_LATENCY_FRAMES_MIN,
"Eingabeverzögerung")
MSG_HASH(MENU_ENUM_LABEL_VALUE_NETPLAY_INPUT_LATENCY_FRAMES_RANGE,
"Erlaubte Eingabeverzögerung")
MSG_HASH(MENU_ENUM_LABEL_VALUE_NETPLAY_CLIENT_SWAP_INPUT,
"Netplay-Spieler 2 verwendet Client 1")
MSG_HASH(MENU_ENUM_LABEL_VALUE_NETPLAY_DELAY_FRAMES,
"Netplay-Verzögerung")
MSG_HASH(MENU_ENUM_LABEL_VALUE_NETPLAY_DISCONNECT,
@ -2855,8 +2843,6 @@ MSG_HASH(MENU_ENUM_SUBLABEL_SORT_SAVEFILES_ENABLE,
MSG_HASH(MENU_ENUM_SUBLABEL_SORT_SAVESTATES_ENABLE,
"Speichere Spielstände in Ordnern ab, die nach dem verwendeten Core benannt sind."
)
MSG_HASH(MENU_ENUM_SUBLABEL_NETPLAY_CLIENT_SWAP_INPUT,
"Verwende die Tastenbelegung für Spieler 1, wenn Du ein Client im Netplay bist.")
MSG_HASH(MENU_ENUM_SUBLABEL_CORE_UPDATER_BUILDBOT_URL,
"URL zum Core-Verzeichnis auf dem libretro-Buildbot.")
MSG_HASH(MENU_ENUM_SUBLABEL_BUILDBOT_ASSETS_URL,

View File

@ -30,10 +30,6 @@ MSG_HASH(
MSG_NO_ARGUMENTS_SUPPLIED_AND_NO_MENU_BUILTIN,
"No arguments supplied and no menu builtin, displaying help..."
)
MSG_HASH(
MSG_NETPLAY_USERS_HAS_FLIPPED,
"Netplay users has flipped"
)
MSG_HASH(
MSG_SETTING_DISK_IN_TRAY,
"Setting disk in tray"
@ -738,8 +734,6 @@ MSG_HASH(MENU_ENUM_LABEL_VALUE_INPUT_META_MOVIE_RECORD_TOGGLE,
"Movie record toggle")
MSG_HASH(MENU_ENUM_LABEL_VALUE_INPUT_META_MUTE,
"Audio mute toggle")
MSG_HASH(MENU_ENUM_LABEL_VALUE_INPUT_META_NETPLAY_FLIP,
"Netplay flip users")
MSG_HASH(MENU_ENUM_LABEL_VALUE_INPUT_META_OSK,
"On-screen keyboard toggle")
MSG_HASH(MENU_ENUM_LABEL_VALUE_INPUT_META_OVERLAY_NEXT,
@ -928,8 +922,6 @@ MSG_HASH(MENU_ENUM_LABEL_VALUE_NETPLAY,
"Netplay")
MSG_HASH(MENU_ENUM_LABEL_VALUE_NETPLAY_CHECK_FRAMES,
"Netplay Check Frames")
MSG_HASH(MENU_ENUM_LABEL_VALUE_NETPLAY_CLIENT_SWAP_INPUT,
"Netplay P2 Uses C1")
MSG_HASH(MENU_ENUM_LABEL_VALUE_NETPLAY_DELAY_FRAMES,
"Netplay Delay Frames")
MSG_HASH(MENU_ENUM_LABEL_VALUE_NETPLAY_DISCONNECT,
@ -2636,8 +2628,6 @@ MSG_HASH(MENU_ENUM_SUBLABEL_SORT_SAVEFILES_ENABLE,
MSG_HASH(MENU_ENUM_SUBLABEL_SORT_SAVESTATES_ENABLE,
"Sort save states in folders named after the core used."
)
MSG_HASH(MENU_ENUM_SUBLABEL_NETPLAY_CLIENT_SWAP_INPUT,
"When being client over netplay, use keybinds for Player 1.")
MSG_HASH(MENU_ENUM_SUBLABEL_CORE_UPDATER_BUILDBOT_URL,
"URL to core updater directory on the Libretro buildbot.")
MSG_HASH(MENU_ENUM_SUBLABEL_BUILDBOT_ASSETS_URL,

View File

@ -1084,10 +1084,6 @@ int menu_hash_get_help_es_enum(enum msg_hash_enums msg, char *s, size_t len)
snprintf(s, len,
"Guarda rápidamente la partida.");
break;
case MENU_ENUM_LABEL_NETPLAY_FLIP_PLAYERS:
snprintf(s, len,
"Cambia los usuarios en red.");
break;
case MENU_ENUM_LABEL_CHEAT_INDEX_PLUS:
snprintf(s, len,
"Aumenta el índice de trucos.\n");

View File

@ -34,10 +34,6 @@ MSG_HASH(
MSG_NO_ARGUMENTS_SUPPLIED_AND_NO_MENU_BUILTIN,
"No se pasaron argumentos y no hay menú integrado, Mostrando ayuda.."
)
MSG_HASH(
MSG_NETPLAY_USERS_HAS_FLIPPED,
"Usuarios de juego en red se fueron"
)
MSG_HASH(
MSG_SETTING_DISK_IN_TRAY,
"Poniendo disco en bandeja"
@ -54,10 +50,6 @@ MSG_HASH(
MSG_NETPLAY_YOU_HAVE_JOINED_AS_PLAYER_N,
"Unido como jugador %d"
)
MSG_HASH(
MSG_NETPLAY_IMPLEMENTATIONS_DIFFER,
"Las implementaciones difieren. Asegurate de usar la misma versión de Retroarch y del núcleo"
)
MSG_HASH(
MSG_NETPLAY_ENDIAN_DEPENDENT,
"Este núcleo no soporta juego en red entre diferentes arquitecturas de sistemas"
@ -1182,10 +1174,6 @@ MSG_HASH(
MENU_ENUM_LABEL_VALUE_INPUT_META_MUTE,
"Silenciar audio"
)
MSG_HASH(
MENU_ENUM_LABEL_VALUE_INPUT_META_NETPLAY_FLIP,
"Juego en red: intercambiar usuarios"
)
MSG_HASH(
MENU_ENUM_LABEL_VALUE_INPUT_META_NETPLAY_GAME_WATCH,
"Juego en red: cambiar modo juego/espectador"
@ -1586,10 +1574,6 @@ MSG_HASH(
MENU_ENUM_LABEL_VALUE_NETPLAY_INPUT_LATENCY_FRAMES_RANGE,
"Rango de latencia en frames"
)
MSG_HASH(
MENU_ENUM_LABEL_VALUE_NETPLAY_CLIENT_SWAP_INPUT,
"Juego en red: P2 Usa Control 1"
)
MSG_HASH(
MENU_ENUM_LABEL_VALUE_NETPLAY_DELAY_FRAMES,
"Juego en red: retrasar frames"
@ -4846,10 +4830,6 @@ MSG_HASH(
MENU_ENUM_SUBLABEL_SORT_SAVESTATES_ENABLE,
"Ordenar guardados rápidos en carpetas nombradas por núcleo"
)
MSG_HASH(
MENU_ENUM_SUBLABEL_NETPLAY_CLIENT_SWAP_INPUT,
"Al ser cliente de juego en red, usar controles de jugador 1"
)
MSG_HASH(
MENU_ENUM_SUBLABEL_CORE_UPDATER_BUILDBOT_URL,
"URL de la carpeta del actualizador de núcleos en el buildbot Libretro"

View File

@ -34,10 +34,6 @@ MSG_HASH(
MSG_NO_ARGUMENTS_SUPPLIED_AND_NO_MENU_BUILTIN,
"Aucun paramètre fourni et pas de menu intégré, affichage de l'aide..."
)
MSG_HASH(
MSG_NETPLAY_USERS_HAS_FLIPPED,
"Utilisateurs réseau intervertis"
)
MSG_HASH(
MSG_SETTING_DISK_IN_TRAY,
"Disque inséré dans le lecteur"
@ -54,10 +50,6 @@ MSG_HASH(
MSG_NETPLAY_YOU_HAVE_JOINED_AS_PLAYER_N,
"Vous avez rejoint le jeu en tant que joueur %d"
)
MSG_HASH(
MSG_NETPLAY_IMPLEMENTATIONS_DIFFER,
"Les implémentations diffèrent. Assurez vous d'utiliser les mêmes versions de RetroArch et du cœur."
)
MSG_HASH(
MSG_NETPLAY_ENDIAN_DEPENDENT,
"Ce cœur ne supporte pas le netplay inter-architectures entre ces systèmes"
@ -825,8 +817,6 @@ MSG_HASH(MENU_ENUM_LABEL_VALUE_INPUT_META_MOVIE_RECORD_TOGGLE,
"Activer l'enregistrement")
MSG_HASH(MENU_ENUM_LABEL_VALUE_INPUT_META_MUTE,
"Sourdine")
MSG_HASH(MENU_ENUM_LABEL_VALUE_INPUT_META_NETPLAY_FLIP,
"Intervertir les joueurs en réseau")
MSG_HASH(MENU_ENUM_LABEL_VALUE_INPUT_META_NETPLAY_GAME_WATCH,
"Changer de mode joueur/spectateur")
MSG_HASH(MENU_ENUM_LABEL_VALUE_INPUT_META_OSK,
@ -1021,8 +1011,6 @@ MSG_HASH(MENU_ENUM_LABEL_VALUE_NETPLAY_INPUT_LATENCY_FRAMES_MIN,
"Latence d'entrées minimale")
MSG_HASH(MENU_ENUM_LABEL_VALUE_NETPLAY_INPUT_LATENCY_FRAMES_RANGE,
"Intervalle de latence d'entées")
MSG_HASH(MENU_ENUM_LABEL_VALUE_NETPLAY_CLIENT_SWAP_INPUT,
"Joueur #2 contrôle manette #1")
MSG_HASH(MENU_ENUM_LABEL_VALUE_NETPLAY_DELAY_FRAMES,
"Netplay Delay Frames")
MSG_HASH(MENU_ENUM_LABEL_VALUE_NETPLAY_DISCONNECT,
@ -2807,8 +2795,6 @@ MSG_HASH(MENU_ENUM_SUBLABEL_SORT_SAVEFILES_ENABLE,
MSG_HASH(MENU_ENUM_SUBLABEL_SORT_SAVESTATES_ENABLE,
"Sort save states in folders named after the core used."
)
MSG_HASH(MENU_ENUM_SUBLABEL_NETPLAY_CLIENT_SWAP_INPUT,
"When being client over netplay, use keybinds for Player 1.")
MSG_HASH(MENU_ENUM_SUBLABEL_CORE_UPDATER_BUILDBOT_URL,
"URL to core updater directory on the Libretro buildbot.")
MSG_HASH(MENU_ENUM_SUBLABEL_BUILDBOT_ASSETS_URL,

View File

@ -968,14 +968,6 @@ int menu_hash_get_help_it_enum(enum msg_hash_enums msg, char *s, size_t len)
snprintf(s, len,
"Saves state.");
break;
case MENU_ENUM_LABEL_NETPLAY_FLIP_PLAYERS:
snprintf(s, len,
"Netplay flip users.");
break;
case MENU_ENUM_LABEL_CHEAT_INDEX_PLUS:
snprintf(s, len,
"Increment cheat index.\n");
break;
case MENU_ENUM_LABEL_CHEAT_INDEX_MINUS:
snprintf(s, len,
"Decrement cheat index.\n");

View File

@ -34,10 +34,6 @@ MSG_HASH(
MSG_NO_ARGUMENTS_SUPPLIED_AND_NO_MENU_BUILTIN,
"Nessun argomento fornito e nessun menu incorporato, visualizzazione della guida..."
)
MSG_HASH(
MSG_NETPLAY_USERS_HAS_FLIPPED,
"Gli utenti del Netplay hanno flippato"
)
MSG_HASH(
MSG_SETTING_DISK_IN_TRAY,
"impostazioni del disco nel cassetto"
@ -54,10 +50,6 @@ MSG_HASH(
MSG_NETPLAY_YOU_HAVE_JOINED_AS_PLAYER_N,
"Sei entrato come giocatore %d"
)
MSG_HASH(
MSG_NETPLAY_IMPLEMENTATIONS_DIFFER,
"Le implementazioni differiscono. Assicurati di utilizzare le stesse versioni di RetroArch e del core."
)
MSG_HASH(
MSG_NETPLAY_ENDIAN_DEPENDENT,
"Questo core non supporta la rete di inter-architettura tra questi sistemi"
@ -831,8 +823,6 @@ MSG_HASH(MENU_ENUM_LABEL_VALUE_INPUT_META_MOVIE_RECORD_TOGGLE,
"Pulsante registratore Film")
MSG_HASH(MENU_ENUM_LABEL_VALUE_INPUT_META_MUTE,
"Pulsante per disattivare l'audio ")
MSG_HASH(MENU_ENUM_LABEL_VALUE_INPUT_META_NETPLAY_FLIP,
"Netplay flip users")
MSG_HASH(MENU_ENUM_LABEL_VALUE_INPUT_META_NETPLAY_GAME_WATCH,
"Pulsante Netplay per la modalità giocatore/spettatore")
MSG_HASH(MENU_ENUM_LABEL_VALUE_INPUT_META_OSK,
@ -1033,8 +1023,6 @@ MSG_HASH(MENU_ENUM_LABEL_VALUE_NETPLAY_INPUT_LATENCY_FRAMES_MIN,
"Input della latenza del Frames")
MSG_HASH(MENU_ENUM_LABEL_VALUE_NETPLAY_INPUT_LATENCY_FRAMES_RANGE,
"Input Latency Frames Range")
MSG_HASH(MENU_ENUM_LABEL_VALUE_NETPLAY_CLIENT_SWAP_INPUT,
"Netplay P2 Utilizza C1")
MSG_HASH(MENU_ENUM_LABEL_VALUE_NETPLAY_DELAY_FRAMES,
"Netplay Delay Frames")
MSG_HASH(MENU_ENUM_LABEL_VALUE_NETPLAY_DISCONNECT,
@ -2853,8 +2841,6 @@ MSG_HASH(MENU_ENUM_SUBLABEL_SORT_SAVEFILES_ENABLE,
MSG_HASH(MENU_ENUM_SUBLABEL_SORT_SAVESTATES_ENABLE,
"Ordina i salva stati in cartelle dopo che un core viene utilizzato."
)
MSG_HASH(MENU_ENUM_SUBLABEL_NETPLAY_CLIENT_SWAP_INPUT,
"Quando sei un client su netplay, utilizza i tasti di comando per il giocatore 1.")
MSG_HASH(MENU_ENUM_SUBLABEL_CORE_UPDATER_BUILDBOT_URL,
"URL alla directory di aggiornamento del core nel buildbot di Libretro.")
MSG_HASH(MENU_ENUM_SUBLABEL_BUILDBOT_ASSETS_URL,

View File

@ -93,10 +93,6 @@ int menu_hash_get_help_jp_enum(enum msg_hash_enums msg, char *s, size_t len)
snprintf(s, len,
"Toggles onscreen keyboard.");
break;
case RARCH_NETPLAY_FLIP:
snprintf(s, len,
"Netplay flip users.");
break;
case RARCH_SLOWMOTION:
snprintf(s, len,
"Hold for slowmotion.");
@ -1670,11 +1666,6 @@ int menu_hash_get_help_jp_enum(enum msg_hash_enums msg, char *s, size_t len)
"The username of the person running RetroArch. \n"
"This will be used for playing online games.");
break;
case MENU_ENUM_LABEL_NETPLAY_CLIENT_SWAP_INPUT:
snprintf(s, len,
"When being client over netplay, use \n"
"keybinds for player 1.");
break;
case MENU_ENUM_LABEL_NETPLAY_TCP_UDP_PORT:
snprintf(s, len,
"The port of the host IP address. \n"
@ -1777,10 +1768,6 @@ int menu_hash_get_help_jp_enum(enum msg_hash_enums msg, char *s, size_t len)
snprintf(s, len,
"Saves state.");
break;
case MENU_ENUM_LABEL_NETPLAY_FLIP_PLAYERS:
snprintf(s, len,
"Netplay flip users.");
break;
case MENU_ENUM_LABEL_CHEAT_INDEX_PLUS:
snprintf(s, len,
"Increment cheat index.\n");

View File

@ -39,10 +39,6 @@ MSG_HASH(
MSG_NO_ARGUMENTS_SUPPLIED_AND_NO_MENU_BUILTIN,
"No arguments supplied and no menu builtin, displaying help..."
)
MSG_HASH(
MSG_NETPLAY_USERS_HAS_FLIPPED,
"Netplay users has flipped"
)
MSG_HASH(
MSG_SETTING_DISK_IN_TRAY,
"ディスクがトレイに入りました。"
@ -59,10 +55,6 @@ MSG_HASH(
MSG_NETPLAY_YOU_HAVE_JOINED_AS_PLAYER_N,
"「プレイヤー%d」で接続しました"
)
MSG_HASH(
MSG_NETPLAY_IMPLEMENTATIONS_DIFFER,
"実装が異なります。相手のRetroArchとコアのバージョンが同じに確認してください。"
)
MSG_HASH(
MSG_NETPLAY_ENDIAN_DEPENDENT,
"This core does not support inter-architecture netplay between these systems"
@ -861,8 +853,6 @@ MSG_HASH(MENU_ENUM_LABEL_VALUE_INPUT_META_MOVIE_RECORD_TOGGLE,
"録画")
MSG_HASH(MENU_ENUM_LABEL_VALUE_INPUT_META_MUTE,
"消音")
MSG_HASH(MENU_ENUM_LABEL_VALUE_INPUT_META_NETPLAY_FLIP,
"ネットプレイのユーザ交換")
MSG_HASH(MENU_ENUM_LABEL_VALUE_INPUT_META_NETPLAY_GAME_WATCH,
"ネットプレイの観覧を切り替え")
MSG_HASH(MENU_ENUM_LABEL_VALUE_INPUT_META_OSK,
@ -1063,8 +1053,6 @@ MSG_HASH(MENU_ENUM_LABEL_VALUE_NETPLAY_INPUT_LATENCY_FRAMES_MIN,
"入力遅延フレーム数")
MSG_HASH(MENU_ENUM_LABEL_VALUE_NETPLAY_INPUT_LATENCY_FRAMES_RANGE,
"入力遅延フレーム範囲")
MSG_HASH(MENU_ENUM_LABEL_VALUE_NETPLAY_CLIENT_SWAP_INPUT,
"ネットプレイのP2がC1を使用")
MSG_HASH(MENU_ENUM_LABEL_VALUE_NETPLAY_DELAY_FRAMES,
"ネットプレイの延期フレーム")
MSG_HASH(MENU_ENUM_LABEL_VALUE_NETPLAY_DISCONNECT,
@ -2841,8 +2829,6 @@ MSG_HASH(MENU_ENUM_SUBLABEL_SORT_SAVEFILES_ENABLE,
MSG_HASH(MENU_ENUM_SUBLABEL_SORT_SAVESTATES_ENABLE,
"Sort save states in folders named after the core used."
)
MSG_HASH(MENU_ENUM_SUBLABEL_NETPLAY_CLIENT_SWAP_INPUT,
"When being client over netplay, use keybinds for Player 1.")
MSG_HASH(MENU_ENUM_SUBLABEL_CORE_UPDATER_BUILDBOT_URL,
"URL to core updater directory on the Libretro buildbot.")
MSG_HASH(MENU_ENUM_SUBLABEL_BUILDBOT_ASSETS_URL,

View File

@ -91,10 +91,6 @@ int menu_hash_get_help_ko_enum(enum msg_hash_enums msg, char *s, size_t len) {
snprintf(s, len,
"온스크린 키보드 전환.");
break;
case RARCH_NETPLAY_FLIP:
snprintf(s, len,
"넷플레이 사용자 넘김.");
break;
case RARCH_NETPLAY_GAME_WATCH:
snprintf(s, len,
"넷플레이 플레이/관전 모드 전환.");
@ -1729,11 +1725,6 @@ int menu_hash_get_help_ko_enum(enum msg_hash_enums msg, char *s, size_t len) {
"The username of the person running RetroArch. \n"
"This will be used for playing online games.");
break;
case MENU_ENUM_LABEL_NETPLAY_CLIENT_SWAP_INPUT:
snprintf(s, len,
"When being client over netplay, use \n"
"keybinds for player 1.");
break;
case MENU_ENUM_LABEL_NETPLAY_TCP_UDP_PORT:
snprintf(s, len,
"The port of the host IP address. \n"
@ -1849,10 +1840,6 @@ int menu_hash_get_help_ko_enum(enum msg_hash_enums msg, char *s, size_t len) {
snprintf(s, len,
"Saves state.");
break;
case MENU_ENUM_LABEL_NETPLAY_FLIP_PLAYERS:
snprintf(s, len,
"Netplay flip users.");
break;
case MENU_ENUM_LABEL_NETPLAY_GAME_WATCH:
snprintf(s, len,
"Netplay toggle play/spectate mode.");

View File

@ -34,10 +34,6 @@ MSG_HASH(
MSG_NO_ARGUMENTS_SUPPLIED_AND_NO_MENU_BUILTIN,
"제공되는 인수 및 메뉴, 도움말이 없습니다..."
)
MSG_HASH(
MSG_NETPLAY_USERS_HAS_FLIPPED,
"넷플레이 사용자가 변경되었습니다"
)
MSG_HASH(
MSG_SETTING_DISK_IN_TRAY,
"디스크 트레이 설정"
@ -54,10 +50,6 @@ MSG_HASH(
MSG_NETPLAY_YOU_HAVE_JOINED_AS_PLAYER_N,
"Y%d 플레이어로 입장했습니다"
)
MSG_HASH(
MSG_NETPLAY_IMPLEMENTATIONS_DIFFER,
"구현 방법에 차이가 있습니다. 동일한 버전의 RetroArch와 코어인지 확인하십시오."
)
MSG_HASH(
MSG_NETPLAY_ENDIAN_DEPENDENT,
"현재 코어는 해당 시스템 사이에서 구조 간 넷플레이를 지원하지 않습니다"
@ -811,8 +803,6 @@ MSG_HASH(MENU_ENUM_LABEL_VALUE_INPUT_META_MOVIE_RECORD_TOGGLE,
"동영상 기록 시작/중지")
MSG_HASH(MENU_ENUM_LABEL_VALUE_INPUT_META_MUTE,
"음소거 켜기/끄기")
MSG_HASH(MENU_ENUM_LABEL_VALUE_INPUT_META_NETPLAY_FLIP,
"넷플레이 사용자 전환")
MSG_HASH(MENU_ENUM_LABEL_VALUE_INPUT_META_NETPLAY_GAME_WATCH,
"넷플레이 플레이/관전 전환")
MSG_HASH(MENU_ENUM_LABEL_VALUE_INPUT_META_OSK,
@ -1007,8 +997,6 @@ MSG_HASH(MENU_ENUM_LABEL_VALUE_NETPLAY_INPUT_LATENCY_FRAMES_MIN,
"입력 대기 프레임")
MSG_HASH(MENU_ENUM_LABEL_VALUE_NETPLAY_INPUT_LATENCY_FRAMES_RANGE,
"입력 대기 프레임 범위")
MSG_HASH(MENU_ENUM_LABEL_VALUE_NETPLAY_CLIENT_SWAP_INPUT,
"넷플레이 P2 사용 C1")
MSG_HASH(MENU_ENUM_LABEL_VALUE_NETPLAY_DELAY_FRAMES,
"넷플레이 지연 프레임")
MSG_HASH(MENU_ENUM_LABEL_VALUE_NETPLAY_DISCONNECT,
@ -2771,8 +2759,6 @@ MSG_HASH(MENU_ENUM_SUBLABEL_SORT_SAVEFILES_ENABLE,
MSG_HASH(MENU_ENUM_SUBLABEL_SORT_SAVESTATES_ENABLE,
"코어 이름 폴더별로 저장된 상태저장파일 정렬."
)
MSG_HASH(MENU_ENUM_SUBLABEL_NETPLAY_CLIENT_SWAP_INPUT,
"클라이어트로 넷플레이 접속시 사용자 1 키설정 사용.")
MSG_HASH(MENU_ENUM_SUBLABEL_CORE_UPDATER_BUILDBOT_URL,
"Libretro 빌드봇 상의 코어 업데이터 디렉토리 URL.")
MSG_HASH(MENU_ENUM_SUBLABEL_BUILDBOT_ASSETS_URL,

View File

@ -625,8 +625,12 @@ MSG_HASH(MENU_ENUM_LABEL_NETPLAY,
"netplay")
MSG_HASH(MENU_ENUM_LABEL_NETPLAY_CHECK_FRAMES,
"netplay_check_frames")
MSG_HASH(MENU_ENUM_LABEL_NETPLAY_CLIENT_SWAP_INPUT,
"netplay_client_swap_input")
MSG_HASH(MENU_ENUM_LABEL_NETPLAY_REQUEST_DEVICE_I,
"netplay_request_device_%u")
MSG_HASH(MENU_ENUM_LABEL_NETPLAY_SHARE_ANALOG,
"netplay_share_analog")
MSG_HASH(MENU_ENUM_LABEL_NETPLAY_SHARE_DIGITAL,
"netplay_share_digital")
MSG_HASH(MENU_ENUM_LABEL_NETPLAY_INPUT_LATENCY_FRAMES_MIN,
"netplay_input_latency_frames_min")
MSG_HASH(MENU_ENUM_LABEL_NETPLAY_INPUT_LATENCY_FRAMES_RANGE,

View File

@ -30,10 +30,6 @@ MSG_HASH(
MSG_NO_ARGUMENTS_SUPPLIED_AND_NO_MENU_BUILTIN,
"No arguments supplied and no menu builtin, displaying help..."
)
MSG_HASH(
MSG_NETPLAY_USERS_HAS_FLIPPED,
"Netplay users has flipped"
)
MSG_HASH(
MSG_SETTING_DISK_IN_TRAY,
"Setting disk in tray"
@ -738,8 +734,6 @@ MSG_HASH(MENU_ENUM_LABEL_VALUE_INPUT_META_MOVIE_RECORD_TOGGLE,
"Movie record toggle")
MSG_HASH(MENU_ENUM_LABEL_VALUE_INPUT_META_MUTE,
"Audio mute toggle")
MSG_HASH(MENU_ENUM_LABEL_VALUE_INPUT_META_NETPLAY_FLIP,
"Netplay flip users")
MSG_HASH(MENU_ENUM_LABEL_VALUE_INPUT_META_OSK,
"On-screen keyboard toggle")
MSG_HASH(MENU_ENUM_LABEL_VALUE_INPUT_META_OVERLAY_NEXT,
@ -926,8 +920,6 @@ MSG_HASH(MENU_ENUM_LABEL_VALUE_NETPLAY,
"Netplay")
MSG_HASH(MENU_ENUM_LABEL_VALUE_NETPLAY_CHECK_FRAMES,
"Netplay Check Frames")
MSG_HASH(MENU_ENUM_LABEL_VALUE_NETPLAY_CLIENT_SWAP_INPUT,
"Netplay P2 Uses C1")
MSG_HASH(MENU_ENUM_LABEL_VALUE_NETPLAY_DELAY_FRAMES,
"Netplay Vertraging Frames")
MSG_HASH(MENU_ENUM_LABEL_VALUE_NETPLAY_DISCONNECT,
@ -2640,8 +2632,6 @@ MSG_HASH(MENU_ENUM_SUBLABEL_SORT_SAVEFILES_ENABLE,
MSG_HASH(MENU_ENUM_SUBLABEL_SORT_SAVESTATES_ENABLE,
"Sort save states in folders named after the core used."
)
MSG_HASH(MENU_ENUM_SUBLABEL_NETPLAY_CLIENT_SWAP_INPUT,
"When being client over netplay, use keybinds for Player 1.")
MSG_HASH(MENU_ENUM_SUBLABEL_CORE_UPDATER_BUILDBOT_URL,
"URL to core updater directory on the Libretro buildbot.")
MSG_HASH(MENU_ENUM_SUBLABEL_BUILDBOT_ASSETS_URL,

View File

@ -34,10 +34,6 @@ MSG_HASH(
MSG_NO_ARGUMENTS_SUPPLIED_AND_NO_MENU_BUILTIN,
"Brak argumentów i brak wbudowanego menu, wyświetlanie pomocy..."
)
MSG_HASH(
MSG_NETPLAY_USERS_HAS_FLIPPED,
"Użytkownicy Netplay odwrócili się"
)
MSG_HASH(
MSG_SETTING_DISK_IN_TRAY,
"Ustawianie dysku w zasobniku"
@ -54,10 +50,6 @@ MSG_HASH(
MSG_NETPLAY_YOU_HAVE_JOINED_AS_PLAYER_N,
"Dołączyłeś jako gracz %d"
)
MSG_HASH(
MSG_NETPLAY_IMPLEMENTATIONS_DIFFER,
"Implementacja różni się. Upewnij się, że używasz dokładnie tych samych wersji RetroArch i rdzenia."
)
MSG_HASH(
MSG_NETPLAY_ENDIAN_DEPENDENT,
"Ten rdzeń nie obsługuje net-play między architekturami w tych systemach"
@ -843,8 +835,6 @@ MSG_HASH(MENU_ENUM_LABEL_VALUE_INPUT_META_MOVIE_RECORD_TOGGLE,
"Przełącznik nagrywania filmu")
MSG_HASH(MENU_ENUM_LABEL_VALUE_INPUT_META_MUTE,
"Przełącznik wyciszania dźwięku")
MSG_HASH(MENU_ENUM_LABEL_VALUE_INPUT_META_NETPLAY_FLIP,
"Netplay przerzuca użytkowników")
MSG_HASH(MENU_ENUM_LABEL_VALUE_INPUT_META_NETPLAY_GAME_WATCH,
"Netplay przełącza tryb play / spectate")
MSG_HASH(MENU_ENUM_LABEL_VALUE_INPUT_META_OSK,
@ -1045,8 +1035,6 @@ MSG_HASH(MENU_ENUM_LABEL_VALUE_NETPLAY_INPUT_LATENCY_FRAMES_MIN,
"Wejściowe klatki opóźnień")
MSG_HASH(MENU_ENUM_LABEL_VALUE_NETPLAY_INPUT_LATENCY_FRAMES_RANGE,
"Zakres latencji wejściowych klatek")
MSG_HASH(MENU_ENUM_LABEL_VALUE_NETPLAY_CLIENT_SWAP_INPUT,
"Netplay P2 Używa C1")
MSG_HASH(MENU_ENUM_LABEL_VALUE_NETPLAY_DELAY_FRAMES,
"Netplay opóźnij klatki")
MSG_HASH(MENU_ENUM_LABEL_VALUE_NETPLAY_DISCONNECT,
@ -2867,8 +2855,6 @@ MSG_HASH(MENU_ENUM_SUBLABEL_SORT_SAVEFILES_ENABLE,
MSG_HASH(MENU_ENUM_SUBLABEL_SORT_SAVESTATES_ENABLE,
"Sortuj stany zachowywania w folderach nazwanych po używanym rdzeniu."
)
MSG_HASH(MENU_ENUM_SUBLABEL_NETPLAY_CLIENT_SWAP_INPUT,
"When being client over netplay, use keybinds for Player 1.")
MSG_HASH(MENU_ENUM_SUBLABEL_CORE_UPDATER_BUILDBOT_URL,
"Adres URL do głównego katalogu Updater na kompilatorze Libretro.")
MSG_HASH(MENU_ENUM_SUBLABEL_BUILDBOT_ASSETS_URL,

View File

@ -93,10 +93,6 @@ int menu_hash_get_help_pt_br_enum(enum msg_hash_enums msg, char *s, size_t len)
snprintf(s, len,
"Alternar o teclado virtual.");
break;
case RARCH_NETPLAY_FLIP:
snprintf(s, len,
"Inverter usuários do Netplay.");
break;
case RARCH_NETPLAY_GAME_WATCH:
snprintf(s, len,
"Alternar modo jogador/espectador do Netplay.");
@ -1828,11 +1824,6 @@ int menu_hash_get_help_pt_br_enum(enum msg_hash_enums msg, char *s, size_t len)
"o RetroArch. \n"
"Será utilizado para jogos online.");
break;
case MENU_ENUM_LABEL_NETPLAY_CLIENT_SWAP_INPUT:
snprintf(s, len,
"Ao ser o cliente de Netplay, use os \n"
"vínculos de teclas do jogador 1.");
break;
case MENU_ENUM_LABEL_NETPLAY_TCP_UDP_PORT:
snprintf(s, len,
"A porta do endereço de IP do hospedeiro. \n"
@ -1952,10 +1943,6 @@ int menu_hash_get_help_pt_br_enum(enum msg_hash_enums msg, char *s, size_t len)
snprintf(s, len,
"Salvar Estado de Jogo.");
break;
case MENU_ENUM_LABEL_NETPLAY_FLIP_PLAYERS:
snprintf(s, len,
"Inverter usuários do Netplay.");
break;
case MENU_ENUM_LABEL_NETPLAY_GAME_WATCH:
snprintf(s, len,
"Alternar modo jogador/espectador do Netplay.");

View File

@ -25,9 +25,6 @@ MSG_HASH(MSG_PUBLIC_ADDRESS,
MSG_HASH(MSG_NO_ARGUMENTS_SUPPLIED_AND_NO_MENU_BUILTIN,
"Nenhum argumento fornecido e nenhum menu interno, exibindo ajuda..."
)
MSG_HASH(MSG_NETPLAY_USERS_HAS_FLIPPED,
"Usuários do Netplay foram invertidos"
)
MSG_HASH(MSG_SETTING_DISK_IN_TRAY,
"Definindo disco na bandeja"
)
@ -40,9 +37,6 @@ MSG_HASH(MSG_NETPLAY_YOU_HAVE_LEFT_THE_GAME,
MSG_HASH(MSG_NETPLAY_YOU_HAVE_JOINED_AS_PLAYER_N,
"Você se juntou como jogador %d"
)
MSG_HASH(MSG_NETPLAY_IMPLEMENTATIONS_DIFFER,
"As implementações são diferentes. Certifique-se de que está usando exatamente as mesmas versões do RetroArch e do núcleo."
)
MSG_HASH(MSG_NETPLAY_ENDIAN_DEPENDENT,
"Este núcleo não suporta Netplay inter-arquitetura entre estes sistemas"
)
@ -857,9 +851,6 @@ MSG_HASH(MENU_ENUM_LABEL_VALUE_INPUT_META_MOVIE_RECORD_TOGGLE,
MSG_HASH(MENU_ENUM_LABEL_VALUE_INPUT_META_MUTE,
"Alternar áudio mudo"
)
MSG_HASH(MENU_ENUM_LABEL_VALUE_INPUT_META_NETPLAY_FLIP,
"Inverter usuários do Netplay"
)
MSG_HASH(MENU_ENUM_LABEL_VALUE_INPUT_META_NETPLAY_GAME_WATCH,
"Alternar modo jogador/espectador do Netplay"
)
@ -1160,9 +1151,6 @@ MSG_HASH(MENU_ENUM_LABEL_VALUE_NETPLAY_INPUT_LATENCY_FRAMES_MIN,
MSG_HASH(MENU_ENUM_LABEL_VALUE_NETPLAY_INPUT_LATENCY_FRAMES_RANGE,
"Faixa de Quadros de Latência de Entrada"
)
MSG_HASH(MENU_ENUM_LABEL_VALUE_NETPLAY_CLIENT_SWAP_INPUT,
"J2 do Netplay Usa C1"
)
MSG_HASH(MENU_ENUM_LABEL_VALUE_NETPLAY_DELAY_FRAMES,
"Atraso de Quadros do Netplay"
)
@ -3581,9 +3569,6 @@ MSG_HASH(MENU_ENUM_SUBLABEL_SORT_SAVEFILES_ENABLE,
MSG_HASH(MENU_ENUM_SUBLABEL_SORT_SAVESTATES_ENABLE,
"Ordenar os Estados de Jogo em pastas com o nome do núcleo utilizado."
)
MSG_HASH(MENU_ENUM_SUBLABEL_NETPLAY_CLIENT_SWAP_INPUT,
"Ao se tornar cliente do Netplay, use os vínculos de teclas para o Jogador 1."
)
MSG_HASH(MENU_ENUM_SUBLABEL_CORE_UPDATER_BUILDBOT_URL,
"URL para o diretório de atualização de núcleos no buildbot do Libreto."
)

View File

@ -870,10 +870,6 @@ int menu_hash_get_help_pt_pt_enum(enum msg_hash_enums msg, char *s, size_t len)
snprintf(s, len,
"Salva Savestates.");
break;
case MENU_ENUM_LABEL_NETPLAY_FLIP_PLAYERS:
snprintf(s, len,
"Netplay inverte usuários.");
break;
case MENU_ENUM_LABEL_CHEAT_INDEX_PLUS:
snprintf(s, len,
"Incrementa o índice de cheats.\n");

View File

@ -34,10 +34,6 @@ MSG_HASH(
MSG_NO_ARGUMENTS_SUPPLIED_AND_NO_MENU_BUILTIN,
"Não foi fornecido qualquer argumento e nenhum menu está contido, mostrando ajuda..."
)
MSG_HASH(
MSG_NETPLAY_USERS_HAS_FLIPPED,
"Utilizadores do Netplay devolveram"
)
MSG_HASH(
MSG_SETTING_DISK_IN_TRAY,
"Definindo disco na bandeja"
@ -54,10 +50,6 @@ MSG_HASH(
MSG_NETPLAY_YOU_HAVE_JOINED_AS_PLAYER_N,
"Você juntou-se como jogador %d"
)
MSG_HASH(
MSG_NETPLAY_IMPLEMENTATIONS_DIFFER,
"As implementações são diferentes. Certifique-se de que está a versão do RetroArch e do núcleo são as mesmas."
)
MSG_HASH(
MSG_NETPLAY_ENDIAN_DEPENDENT,
"Este núcleo não suporta inter-arquitetura de Netplay entre estes sistemas"
@ -811,8 +803,6 @@ MSG_HASH(MENU_ENUM_LABEL_VALUE_INPUT_META_MOVIE_RECORD_TOGGLE,
"Alternar gravação de filme")
MSG_HASH(MENU_ENUM_LABEL_VALUE_INPUT_META_MUTE,
"Alternar áudio mudo")
MSG_HASH(MENU_ENUM_LABEL_VALUE_INPUT_META_NETPLAY_FLIP,
"Giro de usuários do Netplay")
MSG_HASH(MENU_ENUM_LABEL_VALUE_INPUT_META_NETPLAY_GAME_WATCH,
"Alternar modo jogar/olhar no Netplay")
MSG_HASH(MENU_ENUM_LABEL_VALUE_INPUT_META_OSK,
@ -1005,8 +995,6 @@ MSG_HASH(MENU_ENUM_LABEL_VALUE_NETPLAY_INPUT_LATENCY_FRAMES_MIN,
"Entrada de Latência de Quadros")
MSG_HASH(MENU_ENUM_LABEL_VALUE_NETPLAY_INPUT_LATENCY_FRAMES_RANGE,
"Alcance da Entrada de latência de Quadros")
MSG_HASH(MENU_ENUM_LABEL_VALUE_NETPLAY_CLIENT_SWAP_INPUT,
"J2 do Netplay Usa C1")
MSG_HASH(MENU_ENUM_LABEL_VALUE_NETPLAY_DELAY_FRAMES,
"Atraso de Quadros do Netplay")
MSG_HASH(MENU_ENUM_LABEL_VALUE_NETPLAY_DISCONNECT,
@ -2749,8 +2737,6 @@ MSG_HASH(MENU_ENUM_SUBLABEL_SORT_SAVEFILES_ENABLE,
MSG_HASH(MENU_ENUM_SUBLABEL_SORT_SAVESTATES_ENABLE,
"Ordenar salvamento de estados em pastas com o nome do Core usado."
)
MSG_HASH(MENU_ENUM_SUBLABEL_NETPLAY_CLIENT_SWAP_INPUT,
"Ao se tornar cliente do netplay, use uma lista de teclas para o Jogador 1.")
MSG_HASH(MENU_ENUM_SUBLABEL_CORE_UPDATER_BUILDBOT_URL,
"URL para o diretório de atualização do Core no buildbot do Libreto.")
MSG_HASH(MENU_ENUM_SUBLABEL_BUILDBOT_ASSETS_URL,

View File

@ -39,10 +39,6 @@ MSG_HASH(
MSG_NO_ARGUMENTS_SUPPLIED_AND_NO_MENU_BUILTIN,
"Нет аргументов и встроенного меню, отображается справка..."
)
MSG_HASH(
MSG_NETPLAY_USERS_HAS_FLIPPED,
"Пользователи Netplay отключились"
)
MSG_HASH(
MSG_SETTING_DISK_IN_TRAY,
"Установка диска в привод"
@ -59,10 +55,6 @@ MSG_HASH(
MSG_NETPLAY_YOU_HAVE_JOINED_AS_PLAYER_N,
"Вы присоединились под именем %d"
)
MSG_HASH(
MSG_NETPLAY_IMPLEMENTATIONS_DIFFER,
"Реализации различаются. Убедитесь, что вы используете одинаковые версии RetroArch и выбранного ядра."
)
MSG_HASH(
MSG_NETPLAY_ENDIAN_DEPENDENT,
"Выбранное ядро не поддерживает архитектуру netplay между этими системами"
@ -834,8 +826,6 @@ MSG_HASH(MENU_ENUM_LABEL_VALUE_INPUT_META_MOVIE_RECORD_TOGGLE,
"Переключатель записи видео")
MSG_HASH(MENU_ENUM_LABEL_VALUE_INPUT_META_MUTE,
"Отключения звука")
MSG_HASH(MENU_ENUM_LABEL_VALUE_INPUT_META_NETPLAY_FLIP,
"Отключить пользователей Netplay")
MSG_HASH(MENU_ENUM_LABEL_VALUE_INPUT_META_NETPLAY_GAME_WATCH,
"Переключить режим игры/наблюдателя Netplay")
MSG_HASH(MENU_ENUM_LABEL_VALUE_INPUT_META_OSK,
@ -1030,8 +1020,6 @@ MSG_HASH(MENU_ENUM_LABEL_VALUE_NETPLAY_INPUT_LATENCY_FRAMES_MIN,
"Кадры задержки ввода")
MSG_HASH(MENU_ENUM_LABEL_VALUE_NETPLAY_INPUT_LATENCY_FRAMES_RANGE,
"Диапазон кадров задержки ввода")
MSG_HASH(MENU_ENUM_LABEL_VALUE_NETPLAY_CLIENT_SWAP_INPUT,
"Netplay P2 использует C1")
MSG_HASH(MENU_ENUM_LABEL_VALUE_NETPLAY_DELAY_FRAMES,
"Задержка кадров Netplay")
MSG_HASH(MENU_ENUM_LABEL_VALUE_NETPLAY_DISCONNECT,
@ -2822,8 +2810,6 @@ MSG_HASH(MENU_ENUM_SUBLABEL_SORT_SAVEFILES_ENABLE,
MSG_HASH(MENU_ENUM_SUBLABEL_SORT_SAVESTATES_ENABLE,
"Сортировать файлы сохранений в каталогах, названные после использования ядра."
)
MSG_HASH(MENU_ENUM_SUBLABEL_NETPLAY_CLIENT_SWAP_INPUT,
"Будучи клиентом netplay, использовать привязки клавиш для Игрока 1.")
MSG_HASH(MENU_ENUM_SUBLABEL_CORE_UPDATER_BUILDBOT_URL,
"URL каталога обновлений ядра на билдботе Libretro.")
MSG_HASH(MENU_ENUM_SUBLABEL_BUILDBOT_ASSETS_URL,

View File

@ -95,10 +95,6 @@ int menu_hash_get_help_us_enum(enum msg_hash_enums msg, char *s, size_t len)
snprintf(s, len,
"Toggles onscreen keyboard.");
break;
case RARCH_NETPLAY_FLIP:
snprintf(s, len,
"Netplay flip users.");
break;
case RARCH_NETPLAY_GAME_WATCH:
snprintf(s, len,
"Netplay toggle play/spectate mode.");
@ -1753,11 +1749,6 @@ int menu_hash_get_help_us_enum(enum msg_hash_enums msg, char *s, size_t len)
"The username of the person running RetroArch. \n"
"This will be used for playing online games.");
break;
case MENU_ENUM_LABEL_NETPLAY_CLIENT_SWAP_INPUT:
snprintf(s, len,
"When being client over netplay, use \n"
"keybinds for player 1.");
break;
case MENU_ENUM_LABEL_NETPLAY_TCP_UDP_PORT:
snprintf(s, len,
"The port of the host IP address. \n"
@ -1873,10 +1864,6 @@ int menu_hash_get_help_us_enum(enum msg_hash_enums msg, char *s, size_t len)
snprintf(s, len,
"Saves state.");
break;
case MENU_ENUM_LABEL_NETPLAY_FLIP_PLAYERS:
snprintf(s, len,
"Netplay flip users.");
break;
case MENU_ENUM_LABEL_NETPLAY_GAME_WATCH:
snprintf(s, len,
"Netplay toggle play/spectate mode.");

View File

@ -34,10 +34,6 @@ MSG_HASH(
MSG_NO_ARGUMENTS_SUPPLIED_AND_NO_MENU_BUILTIN,
"No arguments supplied and no menu builtin, displaying help..."
)
MSG_HASH(
MSG_NETPLAY_USERS_HAS_FLIPPED,
"Netplay users have flipped"
)
MSG_HASH(
MSG_SETTING_DISK_IN_TRAY,
"Setting disk in tray"
@ -52,11 +48,43 @@ MSG_HASH(
)
MSG_HASH(
MSG_NETPLAY_YOU_HAVE_JOINED_AS_PLAYER_N,
"You have joined as player %d"
"You have joined as player %u"
)
MSG_HASH(
MSG_NETPLAY_IMPLEMENTATIONS_DIFFER,
"Implementations differ. Make sure you're using the exact same versions of RetroArch and the core."
MSG_NETPLAY_YOU_HAVE_JOINED_WITH_INPUT_DEVICES_S,
"You have joined with input devices %.*s"
)
MSG_HASH(
MSG_NETPLAY_PLAYER_S_LEFT,
"Player %.*s has left the game"
)
MSG_HASH(
MSG_NETPLAY_S_HAS_JOINED_AS_PLAYER_N,
"%2$.*1$s has joined as player %3$u"
)
MSG_HASH(
MSG_NETPLAY_S_HAS_JOINED_WITH_INPUT_DEVICES_S,
"%2$.*1$s has joined with input devices %4$.*3$s"
)
MSG_HASH(
MSG_NETPLAY_NOT_RETROARCH,
"A netplay connection attempt failed because the peer is not running RetroArch, or is running an old version of RetroArch."
)
MSG_HASH(
MSG_NETPLAY_OUT_OF_DATE,
"The netplay peer is running an old version of RetroArch. Cannot connect."
)
MSG_HASH(
MSG_NETPLAY_DIFFERENT_VERSIONS,
"WARNING: A netplay peer is running a different version of RetroArch. If problems occur, use the same version."
)
MSG_HASH(
MSG_NETPLAY_DIFFERENT_CORES,
"A netplay peer is running a different core. Cannot connect."
)
MSG_HASH(
MSG_NETPLAY_DIFFERENT_CORE_VERSIONS,
"WARNING: A netlpay peer is running a different version of the core. If problems occur, use the same version."
)
MSG_HASH(
MSG_NETPLAY_ENDIAN_DEPENDENT,
@ -94,6 +122,10 @@ MSG_HASH(
MSG_NETPLAY_CANNOT_PLAY_NO_SLOTS,
"There are no free player slots"
)
MSG_HASH(
MSG_NETPLAY_CANNOT_PLAY_NOT_AVAILABLE,
"The input devices requested are not available"
)
MSG_HASH(
MSG_NETPLAY_CANNOT_PLAY,
"Cannot switch to play mode"
@ -843,8 +875,6 @@ MSG_HASH(MENU_ENUM_LABEL_VALUE_INPUT_META_MOVIE_RECORD_TOGGLE,
"Movie record toggle")
MSG_HASH(MENU_ENUM_LABEL_VALUE_INPUT_META_MUTE,
"Audio mute toggle")
MSG_HASH(MENU_ENUM_LABEL_VALUE_INPUT_META_NETPLAY_FLIP,
"Netplay flip users")
MSG_HASH(MENU_ENUM_LABEL_VALUE_INPUT_META_NETPLAY_GAME_WATCH,
"Netplay toggle play/spectate mode")
MSG_HASH(MENU_ENUM_LABEL_VALUE_INPUT_META_OSK,
@ -1045,8 +1075,6 @@ MSG_HASH(MENU_ENUM_LABEL_VALUE_NETPLAY_INPUT_LATENCY_FRAMES_MIN,
"Input Latency Frames")
MSG_HASH(MENU_ENUM_LABEL_VALUE_NETPLAY_INPUT_LATENCY_FRAMES_RANGE,
"Input Latency Frames Range")
MSG_HASH(MENU_ENUM_LABEL_VALUE_NETPLAY_CLIENT_SWAP_INPUT,
"Netplay P2 Uses C1")
MSG_HASH(MENU_ENUM_LABEL_VALUE_NETPLAY_DELAY_FRAMES,
"Netplay Delay Frames")
MSG_HASH(MENU_ENUM_LABEL_VALUE_NETPLAY_DISCONNECT,
@ -1071,10 +1099,30 @@ MSG_HASH(MENU_ENUM_LABEL_VALUE_NETPLAY_PASSWORD,
"Server Password")
MSG_HASH(MENU_ENUM_LABEL_VALUE_NETPLAY_PUBLIC_ANNOUNCE,
"Publicly Announce Netplay")
MSG_HASH(MENU_ENUM_LABEL_VALUE_NETPLAY_REQUEST_DEVICE_I,
"Request Device %u")
MSG_HASH(MENU_ENUM_LABEL_VALUE_NETPLAY_REQUIRE_SLAVES,
"Disallow Non-Slave-Mode Clients")
MSG_HASH(MENU_ENUM_LABEL_VALUE_NETPLAY_SETTINGS,
"Netplay settings")
MSG_HASH(MENU_ENUM_LABEL_VALUE_NETPLAY_SHARE_ANALOG,
"Analog Input Sharing")
MSG_HASH(MENU_ENUM_LABEL_VALUE_NETPLAY_SHARE_ANALOG_MAX,
"Max")
MSG_HASH(MENU_ENUM_LABEL_VALUE_NETPLAY_SHARE_ANALOG_AVERAGE,
"Average")
MSG_HASH(MENU_ENUM_LABEL_VALUE_NETPLAY_SHARE_DIGITAL,
"Digital Input Sharing")
MSG_HASH(MENU_ENUM_LABEL_VALUE_NETPLAY_SHARE_DIGITAL_OR,
"Share")
MSG_HASH(MENU_ENUM_LABEL_VALUE_NETPLAY_SHARE_DIGITAL_XOR,
"Grapple")
MSG_HASH(MENU_ENUM_LABEL_VALUE_NETPLAY_SHARE_DIGITAL_VOTE,
"Vote")
MSG_HASH(MENU_ENUM_LABEL_VALUE_NETPLAY_SHARE_NONE,
"None")
MSG_HASH(MENU_ENUM_LABEL_VALUE_NETPLAY_SHARE_NO_PREFERENCE,
"No preference")
MSG_HASH(MENU_ENUM_LABEL_VALUE_NETPLAY_START_AS_SPECTATOR,
"Netplay Spectator Mode")
MSG_HASH(MENU_ENUM_LABEL_VALUE_NETPLAY_STATELESS_MODE,
@ -2875,8 +2923,8 @@ MSG_HASH(MENU_ENUM_SUBLABEL_SORT_SAVEFILES_ENABLE,
MSG_HASH(MENU_ENUM_SUBLABEL_SORT_SAVESTATES_ENABLE,
"Sort save states in folders named after the core used."
)
MSG_HASH(MENU_ENUM_SUBLABEL_NETPLAY_CLIENT_SWAP_INPUT,
"When being client over netplay, use keybinds for Player 1.")
MSG_HASH(MENU_ENUM_SUBLABEL_NETPLAY_REQUEST_DEVICE_I,
"Request to play with the given input device.")
MSG_HASH(MENU_ENUM_SUBLABEL_CORE_UPDATER_BUILDBOT_URL,
"URL to core updater directory on the Libretro buildbot.")
MSG_HASH(MENU_ENUM_SUBLABEL_BUILDBOT_ASSETS_URL,

View File

@ -93,10 +93,6 @@ int menu_hash_get_help_vn_enum(enum msg_hash_enums msg, char *s, size_t len)
snprintf(s, len,
"Bật/tắt bàn phím trên màn hình.");
break;
case RARCH_NETPLAY_FLIP:
snprintf(s, len,
"Netplay flip users.");
break;
case RARCH_SLOWMOTION:
snprintf(s, len,
"Nhấn để xem chậm.");
@ -1671,11 +1667,6 @@ int menu_hash_get_help_vn_enum(enum msg_hash_enums msg, char *s, size_t len)
"The username of the person running RetroArch. \n"
"This will be used for playing online games.");
break;
case MENU_ENUM_LABEL_NETPLAY_CLIENT_SWAP_INPUT:
snprintf(s, len,
"When being client over netplay, use \n"
"keybinds for player 1.");
break;
case MENU_ENUM_LABEL_NETPLAY_TCP_UDP_PORT:
snprintf(s, len,
"The port of the host IP address. \n"
@ -1778,10 +1769,6 @@ int menu_hash_get_help_vn_enum(enum msg_hash_enums msg, char *s, size_t len)
snprintf(s, len,
"Saves state.");
break;
case MENU_ENUM_LABEL_NETPLAY_FLIP_PLAYERS:
snprintf(s, len,
"Netplay flip users.");
break;
case MENU_ENUM_LABEL_CHEAT_INDEX_PLUS:
snprintf(s, len,
"Increment cheat index.\n");

View File

@ -34,10 +34,6 @@ MSG_HASH(
MSG_NO_ARGUMENTS_SUPPLIED_AND_NO_MENU_BUILTIN,
"No arguments supplied and no menu builtin, displaying help..."
)
MSG_HASH(
MSG_NETPLAY_USERS_HAS_FLIPPED,
"Người dùng Netplay đã flipped"
)
MSG_HASH(
MSG_SETTING_DISK_IN_TRAY,
"Setting disk in tray"
@ -54,10 +50,6 @@ MSG_HASH(
MSG_NETPLAY_YOU_HAVE_JOINED_AS_PLAYER_N,
"You have joined as player %d"
)
MSG_HASH(
MSG_NETPLAY_IMPLEMENTATIONS_DIFFER,
"Implementations differ. Make sure you're using the exact same versions of RetroArch and the core."
)
MSG_HASH(
MSG_NETPLAY_ENDIAN_DEPENDENT,
"This core does not support inter-architecture netplay between these systems"
@ -823,8 +815,6 @@ MSG_HASH(MENU_ENUM_LABEL_VALUE_INPUT_META_MOVIE_RECORD_TOGGLE,
"Movie record toggle")
MSG_HASH(MENU_ENUM_LABEL_VALUE_INPUT_META_MUTE,
"Âm thanh mute toggle")
MSG_HASH(MENU_ENUM_LABEL_VALUE_INPUT_META_NETPLAY_FLIP,
"Netplay flip users")
MSG_HASH(MENU_ENUM_LABEL_VALUE_INPUT_META_NETPLAY_GAME_WATCH,
"Netplay toggle play/spectate mode")
MSG_HASH(MENU_ENUM_LABEL_VALUE_INPUT_META_OSK,
@ -1019,8 +1009,6 @@ MSG_HASH(MENU_ENUM_LABEL_VALUE_NETPLAY_INPUT_LATENCY_FRAMES_MIN,
"Input Latency Frames")
MSG_HASH(MENU_ENUM_LABEL_VALUE_NETPLAY_INPUT_LATENCY_FRAMES_RANGE,
"Input Latency Frames Range")
MSG_HASH(MENU_ENUM_LABEL_VALUE_NETPLAY_CLIENT_SWAP_INPUT,
"Netplay P2 Uses C1")
MSG_HASH(MENU_ENUM_LABEL_VALUE_NETPLAY_DELAY_FRAMES,
"Netplay Delay Frames")
MSG_HASH(MENU_ENUM_LABEL_VALUE_NETPLAY_DISCONNECT,
@ -2799,8 +2787,6 @@ MSG_HASH(MENU_ENUM_SUBLABEL_SORT_SAVEFILES_ENABLE,
MSG_HASH(MENU_ENUM_SUBLABEL_SORT_SAVESTATES_ENABLE,
"Sort save states in folders named after the core used."
)
MSG_HASH(MENU_ENUM_SUBLABEL_NETPLAY_CLIENT_SWAP_INPUT,
"When being client over netplay, use keybinds for Player 1.")
MSG_HASH(MENU_ENUM_SUBLABEL_CORE_UPDATER_BUILDBOT_URL,
"URL to core updater directory on the Libretro buildbot.")
MSG_HASH(MENU_ENUM_SUBLABEL_BUILDBOT_ASSETS_URL,

View File

@ -43,6 +43,10 @@
#include "../../verbosity.h"
#include "../../wifi/wifi_driver.h"
#ifdef HAVE_NETWORKING
#include "../network/netplay/netplay.h"
#endif
#ifndef BIND_ACTION_GET_VALUE
#define BIND_ACTION_GET_VALUE(cbs, name) \
cbs->action_get_value = name; \
@ -1714,6 +1718,84 @@ static void menu_action_setting_disp_set_label_setting_path(file_list_t* list,
strlcpy(s2, path, len2);
}
static void menu_action_setting_disp_set_label_netplay_share_digital(file_list_t* list,
unsigned *w, unsigned type, unsigned i,
const char *label,
char *s, size_t len,
const char *entry_label,
const char *path,
char *s2, size_t len2)
{
settings_t *settings = config_get_ptr();
const char *src;
if (!settings)
return;
strlcpy(s2, path, len2);
*w = 19;
switch (settings->uints.netplay_share_digital)
{
case RARCH_NETPLAY_SHARE_DIGITAL_NO_PREFERENCE:
src = msg_hash_to_str(MENU_ENUM_LABEL_VALUE_NETPLAY_SHARE_NO_PREFERENCE);
break;
case RARCH_NETPLAY_SHARE_DIGITAL_OR:
src = msg_hash_to_str(MENU_ENUM_LABEL_VALUE_NETPLAY_SHARE_DIGITAL_OR);
break;
case RARCH_NETPLAY_SHARE_DIGITAL_XOR:
src = msg_hash_to_str(MENU_ENUM_LABEL_VALUE_NETPLAY_SHARE_DIGITAL_XOR);
break;
case RARCH_NETPLAY_SHARE_DIGITAL_VOTE:
src = msg_hash_to_str(MENU_ENUM_LABEL_VALUE_NETPLAY_SHARE_DIGITAL_VOTE);
break;
default:
src = msg_hash_to_str(MENU_ENUM_LABEL_VALUE_NETPLAY_SHARE_NONE);
break;
}
strlcpy(s, src, len);
}
static void menu_action_setting_disp_set_label_netplay_share_analog(file_list_t* list,
unsigned *w, unsigned type, unsigned i,
const char *label,
char *s, size_t len,
const char *entry_label,
const char *path,
char *s2, size_t len2)
{
settings_t *settings = config_get_ptr();
const char *src;
if (!settings)
return;
strlcpy(s2, path, len2);
*w = 19;
switch (settings->uints.netplay_share_analog)
{
case RARCH_NETPLAY_SHARE_ANALOG_NO_PREFERENCE:
src = msg_hash_to_str(MENU_ENUM_LABEL_VALUE_NETPLAY_SHARE_NO_PREFERENCE);
break;
case RARCH_NETPLAY_SHARE_ANALOG_MAX:
src = msg_hash_to_str(MENU_ENUM_LABEL_VALUE_NETPLAY_SHARE_ANALOG_MAX);
break;
case RARCH_NETPLAY_SHARE_ANALOG_AVERAGE:
src = msg_hash_to_str(MENU_ENUM_LABEL_VALUE_NETPLAY_SHARE_ANALOG_AVERAGE);
break;
default:
src = msg_hash_to_str(MENU_ENUM_LABEL_VALUE_NETPLAY_SHARE_NONE);
break;
}
strlcpy(s, src, len);
}
static int menu_cbs_init_bind_get_string_representation_compare_label(
menu_file_list_cbs_t *cbs)
{
@ -1817,6 +1899,14 @@ static int menu_cbs_init_bind_get_string_representation_compare_label(
BIND_ACTION_GET_VALUE(cbs,
menu_action_setting_disp_set_label_menu_input_keyboard_gamepad_mapping_type);
break;
case MENU_ENUM_LABEL_NETPLAY_SHARE_DIGITAL:
BIND_ACTION_GET_VALUE(cbs,
menu_action_setting_disp_set_label_netplay_share_digital);
break;
case MENU_ENUM_LABEL_NETPLAY_SHARE_ANALOG:
BIND_ACTION_GET_VALUE(cbs,
menu_action_setting_disp_set_label_netplay_share_analog);
break;
case MENU_ENUM_LABEL_CONTENT_COLLECTION_LIST:
case MENU_ENUM_LABEL_LOAD_CONTENT_HISTORY:
case MENU_ENUM_LABEL_DOWNLOADED_FILE_DETECT_CORE_LIST:

View File

@ -229,7 +229,6 @@ default_sublabel_macro(action_bind_sublabel_scan_directory, MENU_
default_sublabel_macro(action_bind_sublabel_video_swap_interval, MENU_ENUM_SUBLABEL_VIDEO_SWAP_INTERVAL)
default_sublabel_macro(action_bind_sublabel_sort_savefiles_enable, MENU_ENUM_SUBLABEL_SORT_SAVEFILES_ENABLE)
default_sublabel_macro(action_bind_sublabel_sort_savestates_enable, MENU_ENUM_SUBLABEL_SORT_SAVESTATES_ENABLE)
default_sublabel_macro(action_bind_sublabel_netplay_client_swap_input, MENU_ENUM_SUBLABEL_NETPLAY_CLIENT_SWAP_INPUT)
default_sublabel_macro(action_bind_sublabel_core_updater_buildbot_url, MENU_ENUM_SUBLABEL_CORE_UPDATER_BUILDBOT_URL)
default_sublabel_macro(action_bind_sublabel_input_overlay_show_physical_inputs, MENU_ENUM_SUBLABEL_INPUT_OVERLAY_SHOW_PHYSICAL_INPUTS)
default_sublabel_macro(action_bind_sublabel_input_overlay_show_physical_inputs_port, MENU_ENUM_SUBLABEL_INPUT_OVERLAY_SHOW_PHYSICAL_INPUTS_PORT)
@ -886,9 +885,6 @@ int menu_cbs_init_bind_sublabel(menu_file_list_cbs_t *cbs,
case MENU_ENUM_LABEL_BUILDBOT_ASSETS_URL:
BIND_ACTION_SUBLABEL(cbs, action_bind_sublabel_core_updater_buildbot_assets_url);
break;
case MENU_ENUM_LABEL_NETPLAY_CLIENT_SWAP_INPUT:
BIND_ACTION_SUBLABEL(cbs, action_bind_sublabel_netplay_client_swap_input);
break;
case MENU_ENUM_LABEL_SORT_SAVEFILES_ENABLE:
BIND_ACTION_SUBLABEL(cbs, action_bind_sublabel_sort_savefiles_enable);
break;

View File

@ -5544,9 +5544,20 @@ bool menu_displaylist_ctl(enum menu_displaylist_ctl_state type, void *data)
PARSE_ONLY_BOOL, false) != -1)
count++;
if (menu_displaylist_parse_settings_enum(menu, info,
MENU_ENUM_LABEL_NETPLAY_CLIENT_SWAP_INPUT,
PARSE_ONLY_BOOL, false) != -1)
MENU_ENUM_LABEL_NETPLAY_SHARE_DIGITAL,
PARSE_ONLY_UINT, false) != -1)
count++;
if (menu_displaylist_parse_settings_enum(menu, info,
MENU_ENUM_LABEL_NETPLAY_SHARE_ANALOG,
PARSE_ONLY_UINT, false) != -1)
count++;
for (user = 0; user < MAX_USERS; user++)
{
if (menu_displaylist_parse_settings_enum(menu, info,
MENU_ENUM_LABEL_NETPLAY_REQUEST_DEVICE_1 + user,
PARSE_ONLY_BOOL, false) != -1)
count++;
}
if (menu_displaylist_parse_settings_enum(menu, info,
MENU_ENUM_LABEL_NETWORK_CMD_ENABLE,
PARSE_ONLY_BOOL, false) != -1)

View File

@ -86,6 +86,10 @@
#include "../tasks/tasks_internal.h"
#ifdef HAVE_NETWORKING
#include "../network/netplay/netplay.h"
#endif
enum settings_list_type
{
SETTINGS_LIST_NONE = 0,
@ -6698,9 +6702,10 @@ static bool setting_append_list(
{
#if defined(HAVE_NETWORKING)
#if defined(HAVE_NETWORK_CMD)
unsigned user;
#endif
char dev_req_label[64];
char dev_req_value[64];
CONFIG_BOOL(
list, list_info,
&settings->bools.netplay_public_announce,
@ -6908,21 +6913,55 @@ static bool setting_append_list(
SD_FLAG_NONE);
settings_data_list_current_add_flags(list, list_info, SD_FLAG_ADVANCED);
CONFIG_BOOL(
CONFIG_UINT(
list, list_info,
&settings->bools.netplay_swap_input,
MENU_ENUM_LABEL_NETPLAY_CLIENT_SWAP_INPUT,
MENU_ENUM_LABEL_VALUE_NETPLAY_CLIENT_SWAP_INPUT,
netplay_client_swap_input,
MENU_ENUM_LABEL_VALUE_OFF,
MENU_ENUM_LABEL_VALUE_ON,
&settings->uints.netplay_share_digital,
MENU_ENUM_LABEL_NETPLAY_SHARE_DIGITAL,
MENU_ENUM_LABEL_VALUE_NETPLAY_SHARE_DIGITAL,
0,
&group_info,
&subgroup_info,
parent_group,
general_write_handler,
general_read_handler,
SD_FLAG_NONE);
settings_data_list_current_add_flags(list, list_info, SD_FLAG_ADVANCED);
general_read_handler);
menu_settings_list_current_add_range(list, list_info, 0, RARCH_NETPLAY_SHARE_DIGITAL_LAST-1, 1, true, true);
CONFIG_UINT(
list, list_info,
&settings->uints.netplay_share_analog,
MENU_ENUM_LABEL_NETPLAY_SHARE_ANALOG,
MENU_ENUM_LABEL_VALUE_NETPLAY_SHARE_ANALOG,
0,
&group_info,
&subgroup_info,
parent_group,
general_write_handler,
general_read_handler);
menu_settings_list_current_add_range(list, list_info, 0, RARCH_NETPLAY_SHARE_ANALOG_LAST-1, 1, true, true);
for (user = 0; user < MAX_USERS; user++)
{
snprintf(dev_req_label, sizeof(dev_req_label),
msg_hash_to_str(MENU_ENUM_LABEL_NETPLAY_REQUEST_DEVICE_I), user + 1);
snprintf(dev_req_value, sizeof(dev_req_value),
msg_hash_to_str(MENU_ENUM_LABEL_VALUE_NETPLAY_REQUEST_DEVICE_I), user + 1);
CONFIG_BOOL_ALT(
list, list_info,
&settings->bools.netplay_request_devices[user],
strdup(dev_req_label),
strdup(dev_req_value),
false,
MENU_ENUM_LABEL_VALUE_NO,
MENU_ENUM_LABEL_VALUE_YES,
&group_info,
&subgroup_info,
parent_group,
general_write_handler,
general_read_handler,
SD_FLAG_ADVANCED);
settings_data_list_current_add_free_flags(list, list_info, SD_FREE_FLAG_NAME | SD_FREE_FLAG_SHORT);
menu_settings_list_current_add_enum_idx(list, list_info, (enum msg_hash_enums)(MENU_ENUM_LABEL_NETPLAY_REQUEST_DEVICE_1 + user));
}
END_SUB_GROUP(list, list_info, parent_group);

View File

@ -153,7 +153,6 @@ enum msg_hash_enums
MSG_SETTING_DISK_IN_TRAY,
MSG_FAILED_TO_SET_DISK,
MSG_NETPLAY_FAILED,
MSG_NETPLAY_USERS_HAS_FLIPPED,
MSG_UNKNOWN_NETPLAY_COMMAND_RECEIVED,
MSG_CONNECTING_TO_NETPLAY_HOST,
MSG_NETPLAY_LAN_SCAN_COMPLETE,
@ -161,7 +160,15 @@ enum msg_hash_enums
MSG_WAITING_FOR_CLIENT,
MSG_NETPLAY_YOU_HAVE_LEFT_THE_GAME,
MSG_NETPLAY_YOU_HAVE_JOINED_AS_PLAYER_N,
MSG_NETPLAY_IMPLEMENTATIONS_DIFFER,
MSG_NETPLAY_YOU_HAVE_JOINED_WITH_INPUT_DEVICES_S,
MSG_NETPLAY_PLAYER_S_LEFT,
MSG_NETPLAY_S_HAS_JOINED_AS_PLAYER_N,
MSG_NETPLAY_S_HAS_JOINED_WITH_INPUT_DEVICES_S,
MSG_NETPLAY_NOT_RETROARCH,
MSG_NETPLAY_OUT_OF_DATE,
MSG_NETPLAY_DIFFERENT_VERSIONS,
MSG_NETPLAY_DIFFERENT_CORES,
MSG_NETPLAY_DIFFERENT_CORE_VERSIONS,
MSG_NETPLAY_ENDIAN_DEPENDENT,
MSG_NETPLAY_PLATFORM_DEPENDENT,
MSG_NETPLAY_ENTER_PASSWORD,
@ -171,6 +178,7 @@ enum msg_hash_enums
MSG_NETPLAY_CLIENT_HANGUP,
MSG_NETPLAY_CANNOT_PLAY_UNPRIVILEGED,
MSG_NETPLAY_CANNOT_PLAY_NO_SLOTS,
MSG_NETPLAY_CANNOT_PLAY_NOT_AVAILABLE,
MSG_NETPLAY_CANNOT_PLAY,
MSG_NETPLAY_PEER_PAUSED,
MSG_NETPLAY_CHANGED_NICK,
@ -605,7 +613,6 @@ enum msg_hash_enums
MENU_ENUM_LABEL_VALUE_INPUT_META_SCREENSHOT,
MENU_ENUM_LABEL_VALUE_INPUT_META_MUTE,
MENU_ENUM_LABEL_VALUE_INPUT_META_OSK,
MENU_ENUM_LABEL_VALUE_INPUT_META_NETPLAY_FLIP,
MENU_ENUM_LABEL_VALUE_INPUT_META_NETPLAY_GAME_WATCH,
MENU_ENUM_LABEL_VALUE_INPUT_META_SLOWMOTION,
MENU_ENUM_LABEL_VALUE_INPUT_META_ENABLE_HOTKEY,
@ -1103,7 +1110,6 @@ enum msg_hash_enums
MENU_LABEL(UNDO_LOAD_STATE),
MENU_LABEL(UNDO_SAVE_STATE),
MENU_LABEL(NETPLAY_FLIP_PLAYERS),
MENU_LABEL(NETPLAY_GAME_WATCH),
MENU_LABEL(CHEAT_INDEX_MINUS),
MENU_LABEL(CHEAT_INDEX_PLUS),
@ -1156,7 +1162,6 @@ enum msg_hash_enums
MENU_LABEL(SSH_ENABLE),
MENU_LABEL(SAMBA_ENABLE),
MENU_LABEL(BLUETOOTH_ENABLE),
MENU_LABEL(NETPLAY_CLIENT_SWAP_INPUT),
MENU_LABEL(NETPLAY_DELAY_FRAMES),
MENU_LABEL(NETPLAY_PUBLIC_ANNOUNCE),
MENU_LABEL(NETPLAY_START_AS_SPECTATOR),
@ -1169,6 +1174,19 @@ enum msg_hash_enums
MENU_LABEL(NETPLAY_SPECTATOR_MODE_ENABLE),
MENU_LABEL(NETPLAY_TCP_UDP_PORT),
MENU_LABEL(NETPLAY_NAT_TRAVERSAL),
MENU_LABEL(NETPLAY_REQUEST_DEVICE_I),
MENU_ENUM_LABEL_NETPLAY_REQUEST_DEVICE_1,
MENU_ENUM_LABEL_NETPLAY_REQUEST_DEVICE_LAST = MENU_ENUM_LABEL_NETPLAY_REQUEST_DEVICE_1 + MAX_USERS,
MENU_ENUM_LABEL_VALUE_NETPLAY_SHARE_NONE,
MENU_ENUM_LABEL_VALUE_NETPLAY_SHARE_NO_PREFERENCE,
MENU_LABEL(NETPLAY_SHARE_DIGITAL),
MENU_ENUM_LABEL_VALUE_NETPLAY_SHARE_DIGITAL_OR,
MENU_ENUM_LABEL_VALUE_NETPLAY_SHARE_DIGITAL_XOR,
MENU_ENUM_LABEL_VALUE_NETPLAY_SHARE_DIGITAL_VOTE,
MENU_LABEL(NETPLAY_SHARE_ANALOG),
MENU_ENUM_LABEL_VALUE_NETPLAY_SHARE_ANALOG_MAX,
MENU_ENUM_LABEL_VALUE_NETPLAY_SHARE_ANALOG_AVERAGE,
MENU_LABEL(SORT_SAVEFILES_ENABLE),
MENU_LABEL(SORT_SAVESTATES_ENABLE),
MENU_LABEL(SAVEFILES_IN_CONTENT_DIR_ENABLE),

View File

@ -106,6 +106,10 @@ early (i.e., it only forwards data on the frame it's reached), it must also
inform all clients of its own current frame even if it has no input. The
NOINPUT command is provided for that purpose.
Each client has a client number, and the server is always client number 0.
Client numbers are currently limited to 0-31, as they're used in 32-bit
bitmaps.
The handshake procedure (this part is done by both server and client):
1) Send connection header
2) Receive and verify connection header
@ -155,18 +159,16 @@ Command: INPUT
Payload:
{
frame number: uint32
is server data: 1 bit
player: 31 bits
joypad input: uint32
analog 1 input: uint32
analog 2 input: uint32
client number: uint32
input data: variable
}
Description:
Input state for each frame. Netplay must send an INPUT command for every
frame in order to function at all. Client's player value is ignored. Server
indicates which frames are its own input data because INPUT is a
synchronization point: No synchronization events from the given frame may
arrive after the server's input for the frame.
frame in order to function at all. When sent from the server (client 0),
INPUT is a synchronization point: No synchronization events from the given
frame may arrive after the server's input for the frame. The actual size of
the input data is variable, but must match the expected size for each of
the devices the given client controls.
Command: NOINPUT
Payload:
@ -213,9 +215,10 @@ Payload:
{
frame number: uint32
paused?: 1 bit
connected players: 31 bits
flip frame: uint32
client number: 31 bits
controller devices: uint32[16]
share modes: uint8[16]
controller-client mapping: uint32[16]
client nick: char[32]
sram: variable
}
@ -236,23 +239,31 @@ Description:
Command: PLAY
Payload:
{
reserved: 31 bits
as slave?: 1 bit
reserved: 7 bits
preferred share mode: 8 bits
requested device(s): 16 bits
}
Description:
Request to enter player mode. The client must wait for a MODE command
before sending input. Server may refuse or force slave connections, so the
request is not necessarily honored. Payload may be elided if zero.
request is not necessarily honored. If no devices are explicitly requested,
the server may choose how to assign; the default is to assign the first
unassigned device, and share the first device if all devices are assigned
and the first device is shareable.
Command: MODE
Payload:
{
frame number: uint32
reserved: 13 bits
slave: 1 bit
playing: 1 bit
you: 1 bit
player number: uint16
playing: 1 bit
slave: 1 bit
reserved: 13 bits
client number: uint16
device bitmap: uint32
share modes: uint8[16]
nick: char[32]
}
Description:
Inform of a connection mode change (possibly of the receiving client). Only
@ -346,3 +357,43 @@ Unused
Command: CFG_ACK
Unused
Input types
Each input device uses a number of words fixed by the type of device. When
buttons are listed, they are listed from lowest bit to highest bit, i.e.,
reverse order. When insufficient buttons are present to represent to represent
a full 32-bit word, the remainder are reserved and unused.
JOYPAD
{
B, Y, Select, Start, Up, Down, Left, Right, A, X, L, R, L2, R2, L3, R3
}
MOUSE
{
unused, unused, Left, Right, Wheel up, Wheel down, Middle, Horizontal
wheel up, Horizontal wheel down
Y: int16
X: int16
}
KEYBOARD
(5 words, see netplay_keys.h)
LIGHTGUN
{
unused, unused, Trigger, Cursor, Turbo, Pause, Start
Y: int16
X: int16
}
ANALOG
{
buttons: uint32, as JOYPAD
Left analog Y: int16
Left analog X: int16
Right analog Y: int16
Right analog X: int16
}

View File

@ -32,7 +32,6 @@ typedef struct netplay netplay_t;
enum rarch_netplay_ctl_state
{
RARCH_NETPLAY_CTL_NONE = 0,
RARCH_NETPLAY_CTL_FLIP_PLAYERS,
RARCH_NETPLAY_CTL_GAME_WATCH,
RARCH_NETPLAY_CTL_POST_FRAME,
RARCH_NETPLAY_CTL_PRE_FRAME,
@ -53,6 +52,27 @@ enum rarch_netplay_ctl_state
RARCH_NETPLAY_CTL_DESYNC_POP
};
/* Preferences for sharing digital devices */
enum rarch_netplay_share_digital_preference
{
RARCH_NETPLAY_SHARE_DIGITAL_NO_SHARING,
RARCH_NETPLAY_SHARE_DIGITAL_NO_PREFERENCE,
RARCH_NETPLAY_SHARE_DIGITAL_OR,
RARCH_NETPLAY_SHARE_DIGITAL_XOR,
RARCH_NETPLAY_SHARE_DIGITAL_VOTE,
RARCH_NETPLAY_SHARE_DIGITAL_LAST
};
/* Preferences for sharing analog devices */
enum rarch_netplay_share_analog_preference
{
RARCH_NETPLAY_SHARE_ANALOG_NO_SHARING,
RARCH_NETPLAY_SHARE_ANALOG_NO_PREFERENCE,
RARCH_NETPLAY_SHARE_ANALOG_MAX,
RARCH_NETPLAY_SHARE_ANALOG_AVERAGE,
RARCH_NETPLAY_SHARE_ANALOG_LAST
};
int16_t input_state_net(unsigned port, unsigned device,
unsigned idx, unsigned id);

View File

@ -23,6 +23,15 @@
#include "netplay_private.h"
static void clear_input(netplay_input_state_t istate)
{
while (istate)
{
istate->used = false;
istate = istate->next;
}
}
/**
* netplay_delta_frame_ready
*
@ -35,7 +44,7 @@
bool netplay_delta_frame_ready(netplay_t *netplay, struct delta_frame *delta,
uint32_t frame)
{
void *remember_state;
size_t i;
if (delta->used)
{
if (delta->frame == frame) return true;
@ -45,11 +54,18 @@ bool netplay_delta_frame_ready(netplay_t *netplay, struct delta_frame *delta,
return false;
}
}
remember_state = delta->state;
memset(delta, 0, sizeof(struct delta_frame));
delta->used = true;
delta->frame = frame;
delta->state = remember_state;
delta->crc = 0;
for (i = 0; i < MAX_INPUT_DEVICES; i++)
{
clear_input(delta->resolved_input[i]);
clear_input(delta->real_input[i]);
clear_input(delta->simlated_input[i]);
}
delta->have_local = false;
for (i = 0; i < MAX_CLIENTS; i++)
delta->have_real[i] = false;
return true;
}
@ -64,3 +80,110 @@ uint32_t netplay_delta_frame_crc(netplay_t *netplay, struct delta_frame *delta)
return 0;
return encoding_crc32(0L, (const unsigned char*)delta->state, netplay->state_size);
}
/*
* Free an input state list
*/
static void free_input_state(netplay_input_state_t *list)
{
netplay_input_state_t cur, next;
cur = *list;
while (cur)
{
next = cur->next;
free(cur);
cur = next;
}
*list = NULL;
}
/**
* netplay_delta_frame_free
*
* Free a delta frame's dependencies
*/
void netplay_delta_frame_free(struct delta_frame *delta)
{
uint32_t i;
if (delta->state)
{
free(delta->state);
delta->state = NULL;
}
for (i = 0; i < MAX_INPUT_DEVICES; i++)
{
free_input_state(&delta->resolved_input[i]);
free_input_state(&delta->real_input[i]);
free_input_state(&delta->simlated_input[i]);
}
}
/**
* 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_input_state_t ret;
while (*list)
{
ret = *list;
if (!ret->used && !must_not_create && ret->size == size)
{
ret->client_num = client_num;
ret->used = true;
memset(ret->data, 0, size*sizeof(uint32_t));
return ret;
}
else if (ret->used && ret->client_num == client_num)
{
if (!must_create && ret->size == size)
return ret;
return NULL;
}
list = &(ret->next);
}
if (must_not_create)
return NULL;
/* Couldn't find a slot, allocate a fresh one */
ret = calloc(1, sizeof(struct netplay_input_state) + (size-1) * sizeof(uint32_t));
if (!ret)
return NULL;
*list = ret;
ret->client_num = client_num;
ret->used = true;
ret->size = size;
return ret;
}
/**
* 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)
{
uint32_t ret = 0, device;
for (device = 0; device < MAX_INPUT_DEVICES; device++)
{
if (!(devices & (1<<device))) continue;
switch (netplay->config_devices[device]&RETRO_DEVICE_MASK)
{
/* These are all essentially magic numbers, but each device has a
* fixed size, documented in network/netplay/README */
case RETRO_DEVICE_JOYPAD: ret += 1; break;
case RETRO_DEVICE_MOUSE: ret += 2; break;
case RETRO_DEVICE_KEYBOARD: ret += 5; break;
case RETRO_DEVICE_LIGHTGUN: ret += 2; break;
case RETRO_DEVICE_ANALOG: ret += 3; break;
default: break; /* Unsupported */
}
}
return ret;
}

View File

@ -71,7 +71,7 @@ static bool netplay_is_alive(void)
{
if (!netplay_data)
return false;
return (netplay_data->is_server && !!netplay_data->connected_players) ||
return (netplay_data->is_server) ||
(!netplay_data->is_server && netplay_data->self_mode >= NETPLAY_CONNECTION_CONNECTED);
}
@ -115,8 +115,9 @@ static bool netplay_can_poll(netplay_t *netplay)
*/
static bool get_self_input_state(netplay_t *netplay)
{
uint32_t state[WORDS_PER_INPUT] = {0, 0, 0};
struct delta_frame *ptr = &netplay->buffer[netplay->self_ptr];
netplay_input_state_t istate = NULL;
uint32_t devices, used_devices = 0, devi, dev_type, local_device;
size_t i;
if (!netplay_delta_frame_ready(netplay, ptr, netplay->self_frame_count))
@ -128,37 +129,110 @@ static bool get_self_input_state(netplay_t *netplay)
return true;
}
if (!input_driver_is_libretro_input_blocked() && netplay->self_frame_count > 0)
devices = netplay->self_devices;
used_devices = 0;
for (devi = 0; devi < MAX_INPUT_DEVICES; devi++)
{
if (!(devices & (1<<devi)))
continue;
/* Find an appropriate local device */
dev_type = netplay->config_devices[devi]&RETRO_DEVICE_MASK;
for (local_device = 0; local_device < MAX_INPUT_DEVICES; local_device++)
{
if (used_devices & (1<<local_device)) continue;
if ((netplay->config_devices[local_device]&RETRO_DEVICE_MASK) == dev_type) break;
}
if (local_device == MAX_INPUT_DEVICES)
local_device = 0;
used_devices |= (1<<local_device);
istate = netplay_input_state_for(&ptr->real_input[devi],
/* If we're a slave, we write our own input to MAX_CLIENTS to keep it separate */
(netplay->self_mode==NETPLAY_CONNECTION_SLAVE)?MAX_CLIENTS:netplay->self_client_num,
netplay_expected_input_size(netplay, 1 << devi),
true, false);
if (!istate)
continue; /* FIXME: More severe? */
/* First frame we always give zero input since relying on
* input from first frame screws up when we use -F 0. */
retro_input_state_t cb = netplay->cbs.state_cb;
for (i = 0; i < RARCH_FIRST_CUSTOM_BIND; i++)
if (!input_driver_is_libretro_input_blocked() && netplay->self_frame_count > 0)
{
int16_t tmp = cb(0,
RETRO_DEVICE_JOYPAD, 0, (unsigned)i);
state[0] |= tmp ? 1 << i : 0;
}
uint32_t *state = istate->data;
retro_input_state_t cb = netplay->cbs.state_cb;
unsigned dtype = netplay->config_devices[devi]&RETRO_DEVICE_MASK;
for (i = 0; i < 2; i++)
{
int16_t tmp_x = cb(0,
RETRO_DEVICE_ANALOG, (unsigned)i, 0);
int16_t tmp_y = cb(0,
RETRO_DEVICE_ANALOG, (unsigned)i, 1);
state[1 + i] = (uint16_t)tmp_x | (((uint16_t)tmp_y) << 16);
switch (dtype)
{
case RETRO_DEVICE_ANALOG:
for (i = 0; i < 2; i++)
{
int16_t tmp_x = cb(local_device,
RETRO_DEVICE_ANALOG, (unsigned)i, 0);
int16_t tmp_y = cb(local_device,
RETRO_DEVICE_ANALOG, (unsigned)i, 1);
state[1 + i] = (uint16_t)tmp_x | (((uint16_t)tmp_y) << 16);
}
/* no break */
case RETRO_DEVICE_JOYPAD:
for (i = 0; i <= RETRO_DEVICE_ID_JOYPAD_R3; i++)
{
int16_t tmp = cb(local_device,
RETRO_DEVICE_JOYPAD, 0, (unsigned)i);
state[0] |= tmp ? 1 << i : 0;
}
break;
case RETRO_DEVICE_MOUSE:
case RETRO_DEVICE_LIGHTGUN:
{
int16_t tmp_x = cb(local_device, dtype, 0, 0);
int16_t tmp_y = cb(local_device, dtype, 0, 1);
state[1] = (uint16_t)tmp_x | (((uint16_t)tmp_y) << 16);
for (i = 2;
i <= ((dtype == RETRO_DEVICE_MOUSE) ?
RETRO_DEVICE_ID_MOUSE_HORIZ_WHEELDOWN :
RETRO_DEVICE_ID_LIGHTGUN_START);
i++)
{
int16_t tmp = cb(local_device, dtype, 0,
(unsigned) i);
state[0] |= tmp ? 1 << i : 0;
}
break;
}
case RETRO_DEVICE_KEYBOARD:
{
unsigned key, word = 0, bit = 1;
for (key = 1; key < NETPLAY_KEY_LAST; key++)
{
state[word] |=
cb(local_device, RETRO_DEVICE_KEYBOARD, 0, netplay_key_ntoh(key)) ?
(1U << bit) : 0;
bit++;
if (bit >= 32)
{
bit = 0;
word++;
if (word >= istate->size)
break;
}
}
break;
}
}
}
}
memcpy(ptr->self_state, state, sizeof(state));
ptr->have_local = true;
/* If we're playing, copy it in as real input */
if (netplay->self_mode == NETPLAY_CONNECTION_PLAYING)
{
memcpy(ptr->real_input_state[netplay->self_player], state,
sizeof(state));
ptr->have_real[netplay->self_player] = true;
ptr->have_real[netplay->self_client_num] = true;
netplay->read_ptr[netplay->self_client_num] = NEXT_PTR(netplay->self_ptr);
netplay->read_frame_count[netplay->self_client_num] = netplay->self_frame_count + 1;
}
/* And send this input to our peers */
@ -203,7 +277,7 @@ bool init_netplay_deferred(const char* server, unsigned port)
static bool netplay_poll(void)
{
int res;
uint32_t player;
uint32_t client;
size_t i;
netplay_data->can_poll = false;
@ -219,7 +293,7 @@ static bool netplay_poll(void)
* frame */
netplay_update_unread_ptr(netplay_data);
if (netplay_data->stateless_mode &&
netplay_data->connected_players &&
(netplay_data->connected_players>1) &&
netplay_data->unread_frame_count <= netplay_data->run_frame_count)
res = netplay_poll_net_input(netplay_data, true);
else
@ -227,8 +301,8 @@ static bool netplay_poll(void)
if (res == -1)
goto catastrophe;
/* Simulate the input if we don't have real input */
netplay_simulate_input(netplay_data, netplay_data->run_ptr, false);
/* Resolve and/or simulate the input if we don't have real input */
netplay_resolve_input(netplay_data, netplay_data->run_ptr, false);
/* Handle any slaves */
if (netplay_data->is_server && netplay_data->connected_slaves)
@ -369,21 +443,19 @@ static bool netplay_poll(void)
/* Figure out who to blame */
if (netplay_data->is_server)
{
for (player = 0; player < MAX_USERS; player++)
for (client = 1; client < MAX_CLIENTS; client++)
{
if (!(netplay_data->connected_players & (1<<player))) continue;
if (netplay_data->read_frame_count[player] > netplay_data->unread_frame_count) continue;
for (i = 0; i < netplay_data->connections_size; i++)
struct netplay_connection *connection;
if (!(netplay_data->connected_players & (1<<client)))
continue;
if (netplay_data->read_frame_count[client] > netplay_data->unread_frame_count)
continue;
connection = &netplay_data->connections[client-1];
if (connection->active &&
connection->mode == NETPLAY_CONNECTION_PLAYING)
{
struct netplay_connection *connection = &netplay_data->connections[i];
if (connection->active &&
connection->mode == NETPLAY_CONNECTION_PLAYING &&
connection->player == player)
{
connection->stall = NETPLAY_STALL_RUNNING_FAST;
connection->stall_time = netplay_data->stall_time;
break;
}
connection->stall = NETPLAY_STALL_RUNNING_FAST;
connection->stall_time = netplay_data->stall_time;
}
}
}
@ -480,32 +552,37 @@ static int16_t netplay_input_state(netplay_t *netplay,
{
size_t ptr = netplay->is_replay ?
netplay->replay_ptr : netplay->run_ptr;
struct delta_frame *delta;
netplay_input_state_t istate;
const uint32_t *curr_input_state = NULL;
if (port <= 1)
{
/* Possibly flip the port */
if (netplay_flip_port(netplay))
port ^= 1;
}
else if (port >= MAX_USERS)
{
if (port >= MAX_INPUT_DEVICES)
return 0;
/* If the port doesn't seem to correspond to the device, "correct" it. This
* is common with devices that typically only have one instance, such as
* keyboards, mice and lightguns. */
if (device != RETRO_DEVICE_JOYPAD &&
(netplay->config_devices[port]&RETRO_DEVICE_MASK) != device)
{
for (port = 0; port < MAX_INPUT_DEVICES; port++)
{
if ((netplay->config_devices[port]&RETRO_DEVICE_MASK) == device)
break;
}
if (port == MAX_INPUT_DEVICES)
return 0;
}
if (port > netplay->player_max)
netplay->player_max = port;
delta = &netplay->buffer[ptr];
istate = delta->resolved_input[port];
if (!istate || !istate->used)
return 0;
if (netplay->buffer[ptr].have_real[port])
{
netplay->buffer[ptr].used_real[port] = true;
curr_input_state = netplay->buffer[ptr].real_input_state[port];
}
else
{
curr_input_state = netplay->buffer[ptr].simulated_input_state[port];
}
if (istate->size == 0)
return 0;
curr_input_state = istate->data;
switch (device)
{
@ -514,10 +591,36 @@ static int16_t netplay_input_state(netplay_t *netplay,
case RETRO_DEVICE_ANALOG:
{
uint32_t state = curr_input_state[1 + idx];
uint32_t state;
if (istate->size != 3)
return 0;
state = curr_input_state[1 + idx];
return (int16_t)(uint16_t)(state >> (id * 16));
}
case RETRO_DEVICE_MOUSE:
case RETRO_DEVICE_LIGHTGUN:
{
if (istate->size != 2)
return 0;
if (id <= RETRO_DEVICE_ID_MOUSE_Y)
return (int16_t)(uint16_t)(curr_input_state[1] >> (id * 16));
return ((1 << id) & curr_input_state[0]) ? 1 : 0;
}
case RETRO_DEVICE_KEYBOARD:
{
unsigned key, word, bit;
key = netplay_key_hton(id);
if (key == NETPLAY_KEY_UNKNOWN)
return 0;
word = key/32;
bit = key%32;
if (word <= istate->size)
return ((1U<<bit) & curr_input_state[word]) ? 1 : 0;
return 0;
}
default:
return 0;
}
@ -736,36 +839,7 @@ bool netplay_command(netplay_t* netplay, struct netplay_connection *connection,
}
/**
* netplay_flip_users:
* @netplay : pointer to netplay object
*
* Flip who controls user 1 and 2.
*/
static void netplay_flip_users(netplay_t *netplay)
{
/* Must be in the future because we may have
* already sent this frame's data */
uint32_t flip_frame = netplay->self_frame_count + 1;
uint32_t flip_frame_net = htonl(flip_frame);
size_t i;
for (i = 0; i < netplay->connections_size; i++)
{
struct netplay_connection *connection = &netplay->connections[i];
if (connection->active && connection->mode >= NETPLAY_CONNECTION_CONNECTED)
{
netplay_command(netplay, connection, NETPLAY_CMD_FLIP_PLAYERS,
&flip_frame_net, sizeof flip_frame_net, "flip users",
"Successfully flipped users.\n");
}
}
netplay->flip ^= true;
netplay->flip_frame = flip_frame;
}
/**
* netplay_frontend_paused
* netplay_frontend_paused
* @netplay : pointer to netplay object
* @paused : true if frontend is paused
*
@ -889,7 +963,7 @@ bool netplay_pre_frame(netplay_t *netplay)
}
if (sync_stalled ||
((!netplay->is_server || netplay->connected_players) &&
((!netplay->is_server || (netplay->connected_players>1)) &&
(netplay->stall || netplay->remote_paused)))
{
/* We may have received data even if we're stalled, so run post-frame
@ -942,19 +1016,20 @@ static void netplay_force_future(netplay_t *netplay)
netplay->run_ptr = netplay->self_ptr;
netplay->run_frame_count = netplay->self_frame_count;
/* We need to ignore any intervening data from the other side,
* and never rewind past this */
netplay_update_unread_ptr(netplay);
if (netplay->unread_frame_count < netplay->run_frame_count)
{
uint32_t player;
for (player = 0; player < MAX_USERS; player++)
uint32_t client;
for (client = 0; client < MAX_CLIENTS; client++)
{
if (!(netplay->connected_players & (1<<player))) continue;
if (netplay->read_frame_count[player] < netplay->run_frame_count)
if (!(netplay->connected_players & (1<<client))) continue;
if (netplay->read_frame_count[client] < netplay->run_frame_count)
{
netplay->read_ptr[player] = netplay->run_ptr;
netplay->read_frame_count[player] = netplay->run_frame_count;
netplay->read_ptr[client] = netplay->run_ptr;
netplay->read_frame_count[client] = netplay->run_frame_count;
}
}
if (netplay->server_frame_count < netplay->run_frame_count)
@ -1121,6 +1196,49 @@ static void netplay_core_reset(netplay_t *netplay)
}
}
/**
* netplay_settings_share_mode
*
* Get the preferred share mode
*/
uint8_t netplay_settings_share_mode(void)
{
settings_t *settings = config_get_ptr();
uint8_t share_mode = 0;
if (settings->uints.netplay_share_digital
|| settings->uints.netplay_share_analog)
{
switch (settings->uints.netplay_share_digital)
{
case RARCH_NETPLAY_SHARE_DIGITAL_OR:
share_mode |= NETPLAY_SHARE_DIGITAL_OR;
break;
case RARCH_NETPLAY_SHARE_DIGITAL_XOR:
share_mode |= NETPLAY_SHARE_DIGITAL_XOR;
break;
case RARCH_NETPLAY_SHARE_DIGITAL_VOTE:
share_mode |= NETPLAY_SHARE_DIGITAL_VOTE;
break;
default:
share_mode |= NETPLAY_SHARE_NO_PREFERENCE;
}
switch (settings->uints.netplay_share_analog)
{
case RARCH_NETPLAY_SHARE_ANALOG_MAX:
share_mode |= NETPLAY_SHARE_ANALOG_MAX;
break;
case RARCH_NETPLAY_SHARE_ANALOG_AVERAGE:
share_mode |= NETPLAY_SHARE_ANALOG_AVERAGE;
break;
default:
share_mode |= NETPLAY_SHARE_NO_PREFERENCE;
}
}
return share_mode;
}
/**
* netplay_toggle_play_spectate
*
@ -1128,67 +1246,24 @@ static void netplay_core_reset(netplay_t *netplay)
*/
static void netplay_toggle_play_spectate(netplay_t *netplay)
{
if (netplay->is_server)
size_t i;
enum rarch_netplay_connection_mode mode;
if (netplay->self_mode == NETPLAY_CONNECTION_PLAYING ||
netplay->self_mode == NETPLAY_CONNECTION_SLAVE)
{
/* FIXME: Duplication */
uint32_t payload[2];
char msg[512];
const char *dmsg = NULL;
payload[0] = htonl(netplay->self_frame_count);
if (netplay->self_mode == NETPLAY_CONNECTION_PLAYING ||
netplay->self_mode == NETPLAY_CONNECTION_SLAVE)
{
/* Mark us as no longer playing */
payload[1] = htonl(netplay->self_player);
netplay->self_mode = NETPLAY_CONNECTION_SPECTATING;
dmsg = msg_hash_to_str(MSG_NETPLAY_YOU_HAVE_LEFT_THE_GAME);
}
else if (netplay->self_mode == NETPLAY_CONNECTION_SPECTATING)
{
uint32_t player;
/* Take a player number */
for (player = 0; player < MAX_USERS; player++)
if (!(netplay->connected_players & (1<<player))) break;
if (player == MAX_USERS) return; /* Failure! */
payload[1] = htonl(NETPLAY_CMD_MODE_BIT_PLAYING | player);
netplay->self_mode = NETPLAY_CONNECTION_PLAYING;
netplay->self_player = player;
dmsg = msg;
msg[sizeof(msg)-1] = '\0';
snprintf(msg, sizeof(msg)-1, msg_hash_to_str(MSG_NETPLAY_YOU_HAVE_JOINED_AS_PLAYER_N), player+1);
}
RARCH_LOG("[netplay] %s\n", dmsg);
runloop_msg_queue_push(dmsg, 1, 180, false);
netplay_send_raw_cmd_all(netplay, NULL, NETPLAY_CMD_MODE, payload, sizeof(payload));
/* Switch to spectator mode immediately */
netplay->self_mode = NETPLAY_CONNECTION_SPECTATING;
mode = NETPLAY_CONNECTION_SPECTATING;
}
else
else if (netplay->self_mode == NETPLAY_CONNECTION_SPECTATING)
{
uint32_t cmd;
if (netplay->self_mode == NETPLAY_CONNECTION_PLAYING ||
netplay->self_mode == NETPLAY_CONNECTION_SLAVE)
{
/* Switch to spectator mode immediately */
netplay->self_mode = NETPLAY_CONNECTION_SPECTATING;
cmd = NETPLAY_CMD_SPECTATE;
}
else if (netplay->self_mode == NETPLAY_CONNECTION_SPECTATING)
{
/* Switch only after getting permission */
cmd = NETPLAY_CMD_PLAY;
}
else return;
netplay_send_raw_cmd_all(netplay, NULL, cmd, NULL, 0);
/* Switch only after getting permission */
mode = NETPLAY_CONNECTION_PLAYING;
}
else return;
netplay_cmd_mode(netplay, mode);
}
/**
@ -1300,7 +1375,7 @@ bool init_netplay(void *direct_host, const char *server, unsigned port)
if (netplay_data)
{
if (netplay_data->is_server && !settings->bools.netplay_start_as_spectator)
netplay_data->self_mode = NETPLAY_CONNECTION_PLAYING;
netplay_toggle_play_spectate(netplay_data);
return true;
}
@ -1388,10 +1463,6 @@ bool netplay_driver_ctl(enum rarch_netplay_ctl_state state, void *data)
case RARCH_NETPLAY_CTL_PRE_FRAME:
ret = netplay_pre_frame(netplay_data);
goto done;
case RARCH_NETPLAY_CTL_FLIP_PLAYERS:
if (netplay_data->is_server)
netplay_flip_users(netplay_data);
break;
case RARCH_NETPLAY_CTL_GAME_WATCH:
netplay_toggle_play_spectate(netplay_data);
break;

View File

@ -35,12 +35,13 @@
#include "../../content.h"
#include "../../retroarch.h"
#include "../../version.h"
#include "../../input/input_driver.h"
#ifdef HAVE_MENU
#include "../../menu/widgets/menu_input_dialog.h"
#endif
const uint32_t netplay_magic = 0x52414E50; /* RANP */
/* TODO/FIXME - replace netplay_log_connection with calls
* to inet_ntop_compat and move runloop message queue pushing
* outside */
@ -203,13 +204,15 @@ static uint32_t simple_rand_uint32(void)
bool netplay_handshake_init_send(netplay_t *netplay,
struct netplay_connection *connection)
{
uint32_t header[4];
uint32_t header[6];
settings_t *settings = config_get_ptr();
header[0] = htonl(netplay_impl_magic());
header[0] = htonl(netplay_magic);
header[1] = htonl(netplay_platform_magic());
header[2] = htonl(NETPLAY_COMPRESSION_SUPPORTED);
header[3] = 0;
header[4] = htonl(NETPLAY_PROTOCOL_VERSION);
header[5] = htonl(netplay_impl_magic());
if (netplay->is_server &&
(settings->paths.netplay_password[0] ||
@ -303,30 +306,49 @@ bool netplay_handshake_init(netplay_t *netplay,
{
ssize_t recvd;
struct nick_buf_s nick_buf;
uint32_t header[4];
uint32_t header[6];
uint32_t local_pmagic = 0;
uint32_t remote_pmagic = 0;
uint32_t remote_version = 0;
uint32_t compression = 0;
struct compression_transcoder *ctrans = NULL;
const char *dmsg = NULL;
header[0] = 0;
header[1] = 0;
header[2] = 0;
header[3] = 0;
memset(header, 0, sizeof(header));
RECV(header, sizeof(header))
RECV(header, sizeof(uint32_t))
{
dmsg = msg_hash_to_str(MSG_FAILED_TO_RECEIVE_HEADER_FROM_CLIENT);
goto error;
}
if (netplay_impl_magic() != ntohl(header[0]))
if (ntohl(header[0]) != netplay_magic)
{
dmsg = msg_hash_to_str(MSG_NETPLAY_IMPLEMENTATIONS_DIFFER);
dmsg = msg_hash_to_str(MSG_NETPLAY_NOT_RETROARCH);
goto error;
}
RECV(header + 1, sizeof(header) - sizeof(uint32_t))
{
dmsg = msg_hash_to_str(MSG_FAILED_TO_RECEIVE_HEADER_FROM_CLIENT);
goto error;
}
remote_version = ntohl(header[4]);
if (remote_version < NETPLAY_PROTOCOL_VERSION)
{
dmsg = msg_hash_to_str(MSG_NETPLAY_OUT_OF_DATE);
goto error;
}
if (ntohl(header[5]) != netplay_impl_magic())
{
/* We allow the connection but warn that this could cause issues. */
dmsg = msg_hash_to_str(MSG_NETPLAY_DIFFERENT_VERSIONS);
RARCH_WARN("%s\n", dmsg);
runloop_msg_queue_push(dmsg, 1, 180, false);
}
/* We only care about platform magic if our core is quirky */
local_pmagic = netplay_platform_magic();
remote_pmagic = ntohl(header[1]);
@ -529,10 +551,10 @@ bool netplay_handshake_sync(netplay_t *netplay,
/* If we're the server, now we send sync info */
size_t i;
int matchct;
uint32_t cmd[5];
uint32_t cmd[4];
retro_ctx_memory_info_t mem_info;
uint32_t client_num = 0;
uint32_t device = 0;
uint32_t connected_players = 0;
size_t nicklen, nickmangle = 0;
bool nick_matched = false;
@ -543,30 +565,51 @@ bool netplay_handshake_sync(netplay_t *netplay,
/* Send basic sync info */
cmd[0] = htonl(NETPLAY_CMD_SYNC);
cmd[1] = htonl(3*sizeof(uint32_t) + MAX_USERS*sizeof(uint32_t) +
NETPLAY_NICK_LEN + mem_info.size);
cmd[1] = htonl(2*sizeof(uint32_t)
/* Controller devices */
+ MAX_INPUT_DEVICES*sizeof(uint32_t)
/* Share modes */
+ MAX_INPUT_DEVICES*sizeof(uint8_t)
/* Device-client mapping */
+ MAX_INPUT_DEVICES*sizeof(uint32_t)
/* Client nick */
+ NETPLAY_NICK_LEN
/* And finally, sram */
+ mem_info.size);
cmd[2] = htonl(netplay->self_frame_count);
connected_players = netplay->connected_players;
if (netplay->self_mode == NETPLAY_CONNECTION_PLAYING)
connected_players |= 1<<netplay->self_player;
client_num = connection - netplay->connections + 1;
if (netplay->local_paused || netplay->remote_paused)
connected_players |= NETPLAY_CMD_SYNC_BIT_PAUSED;
cmd[3] = htonl(connected_players);
if (netplay->flip)
cmd[4] = htonl(netplay->flip_frame);
else
cmd[4] = htonl(0);
client_num |= NETPLAY_CMD_SYNC_BIT_PAUSED;
cmd[3] = htonl(client_num);
if (!netplay_send(&connection->send_packet_buffer, connection->fd, cmd,
sizeof(cmd)))
return false;
/* Now send the device info */
for (i = 0; i < MAX_USERS; i++)
for (i = 0; i < MAX_INPUT_DEVICES; i++)
{
device = htonl(input_config_get_device((unsigned)i));
device = htonl(netplay->config_devices[i]);
if (!netplay_send(&connection->send_packet_buffer, connection->fd,
&device, sizeof(device)))
&device, sizeof(device)))
return false;
}
/* Then the share mode */
if (!netplay_send(&connection->send_packet_buffer, connection->fd,
netplay->device_share_modes, sizeof(netplay->device_share_modes)))
return false;
/* Then the device-client mapping */
for (i = 0; i < MAX_INPUT_DEVICES; i++)
{
device = htonl(netplay->device_clients[i]);
if (!netplay_send(&connection->send_packet_buffer, connection->fd,
&device, sizeof(device)))
return false;
}
@ -835,12 +878,21 @@ bool netplay_handshake_pre_info(netplay_t *netplay,
if (core_info)
{
if (strncmp(info_buf.core_name,
core_info->info.library_name, sizeof(info_buf.core_name)) ||
strncmp(info_buf.core_version,
core_info->info.library_name, sizeof(info_buf.core_name)))
{
/* Wrong core! */
dmsg = msg_hash_to_str(MSG_NETPLAY_DIFFERENT_CORES);
RARCH_ERR("%s\n", dmsg);
runloop_msg_queue_push(dmsg, 1, 180, false);
/* FIXME: Should still send INFO, so the other side knows what's what */
return false;
}
if (strncmp(info_buf.core_version,
core_info->info.library_version, sizeof(info_buf.core_version)))
{
dmsg = msg_hash_to_str(MSG_NETPLAY_IMPLEMENTATIONS_DIFFER);
goto error;
dmsg = msg_hash_to_str(MSG_NETPLAY_DIFFERENT_CORE_VERSIONS);
RARCH_WARN("%s\n", dmsg);
runloop_msg_queue_push(dmsg, 1, 180, false);
}
}
@ -852,7 +904,8 @@ bool netplay_handshake_pre_info(netplay_t *netplay,
if (ntohl(info_buf.content_crc) != content_crc)
{
dmsg = msg_hash_to_str(MSG_CONTENT_CRC32S_DIFFER);
goto error;
RARCH_WARN("%s\n", dmsg);
runloop_msg_queue_push(dmsg, 1, 180, false);
}
}
@ -873,24 +926,8 @@ bool netplay_handshake_pre_info(netplay_t *netplay,
*had_input = true;
netplay_recv_flush(&connection->recv_packet_buffer);
return true;
error:
if (dmsg)
{
RARCH_ERR("%s\n", dmsg);
runloop_msg_queue_push(dmsg, 1, 180, false);
}
if (!netplay->is_server)
{
/* Counter-intuitively, we still want to send our info. This is simply so
* that the server knows why we disconnected. */
if (!netplay_handshake_info(netplay, connection))
return false;
}
return false;
}
/**
* netplay_handshake_pre_sync
*
@ -901,10 +938,10 @@ bool netplay_handshake_pre_sync(netplay_t *netplay,
struct netplay_connection *connection, bool *had_input)
{
uint32_t cmd[2];
uint32_t new_frame_count, connected_players, flip_frame;
uint32_t new_frame_count, client_num, flip_frame;
uint32_t device;
uint32_t local_sram_size, remote_sram_size;
size_t i;
size_t i, j;
ssize_t recvd;
retro_ctx_controller_info_t pad;
char new_nick[NETPLAY_NICK_LEN];
@ -921,7 +958,7 @@ bool netplay_handshake_pre_sync(netplay_t *netplay,
/* Only expecting a sync command */
if (ntohl(cmd[0]) != NETPLAY_CMD_SYNC ||
ntohl(cmd[1]) < 3*sizeof(uint32_t) + MAX_USERS*sizeof(uint32_t) +
ntohl(cmd[1]) < (2+2*MAX_INPUT_DEVICES)*sizeof(uint32_t) + (MAX_INPUT_DEVICES)*sizeof(uint8_t) +
NETPLAY_NICK_LEN)
{
RARCH_ERR("%s\n",
@ -934,30 +971,23 @@ bool netplay_handshake_pre_sync(netplay_t *netplay,
return false;
new_frame_count = ntohl(new_frame_count);
/* Get the connected players and pause mode */
RECV(&connected_players, sizeof(connected_players))
/* Get our client number and pause mode */
RECV(&client_num, sizeof(client_num))
return false;
connected_players = ntohl(connected_players);
if (connected_players & NETPLAY_CMD_SYNC_BIT_PAUSED)
client_num = ntohl(client_num);
if (client_num & NETPLAY_CMD_SYNC_BIT_PAUSED)
{
netplay->remote_paused = true;
connected_players ^= NETPLAY_CMD_SYNC_BIT_PAUSED;
client_num ^= NETPLAY_CMD_SYNC_BIT_PAUSED;
}
netplay->connected_players = connected_players;
/* And the flip state */
RECV(&flip_frame, sizeof(flip_frame))
return false;
flip_frame = ntohl(flip_frame);
netplay->flip = !!flip_frame;
netplay->flip_frame = flip_frame;
netplay->self_client_num = client_num;
/* Set our frame counters as requested */
netplay->self_frame_count = netplay->run_frame_count =
netplay->other_frame_count = netplay->unread_frame_count =
netplay->server_frame_count = new_frame_count;
/* And clear out the framebuffer */
for (i = 0; i < netplay->buffer_size; i++)
{
struct delta_frame *ptr = &netplay->buffer[i];
@ -977,27 +1007,55 @@ bool netplay_handshake_pre_sync(netplay_t *netplay,
}
}
for (i = 0; i < MAX_USERS; i++)
for (i = 0; i < MAX_CLIENTS; i++)
{
if (connected_players & (1<<i))
{
netplay->read_ptr[i] = netplay->self_ptr;
netplay->read_frame_count[i] = netplay->self_frame_count;
}
netplay->read_ptr[i] = netplay->self_ptr;
netplay->read_frame_count[i] = netplay->self_frame_count;
}
/* Get and set each pad */
for (i = 0; i < MAX_USERS; i++)
/* Get and set each input device */
for (i = 0; i < MAX_INPUT_DEVICES; i++)
{
RECV(&device, sizeof(device))
return false;
pad.port = (unsigned)i;
pad.device = ntohl(device);
netplay->config_devices[i] = pad.device;
if ((pad.device&RETRO_DEVICE_MASK) == RETRO_DEVICE_KEYBOARD)
{
netplay->have_updown_device = true;
netplay_key_hton_init();
}
core_set_controller_port_device(&pad);
}
/* Get the share modes */
RECV(netplay->device_share_modes, sizeof(netplay->device_share_modes))
return false;
/* Get the client-controller mapping */
netplay->connected_players =
netplay->connected_slaves =
netplay->self_devices = 0;
for (i = 0; i < MAX_CLIENTS; i++)
netplay->client_devices[i] = 0;
for (i = 0; i < MAX_INPUT_DEVICES; i++)
{
RECV(&device, sizeof(device))
return false;
device = ntohl(device);
netplay->device_clients[i] = device;
netplay->connected_players |= device;
for (j = 0; j < MAX_CLIENTS; j++)
{
if (device & (1<<j))
netplay->client_devices[j] |= 1<<i;
}
}
/* Get our nick */
RECV(new_nick, NETPLAY_NICK_LEN)
return false;
@ -1018,8 +1076,8 @@ bool netplay_handshake_pre_sync(netplay_t *netplay,
core_get_memory(&mem_info);
local_sram_size = (unsigned)mem_info.size;
remote_sram_size = ntohl(cmd[1]) - 3*sizeof(uint32_t) -
MAX_USERS*sizeof(uint32_t) - NETPLAY_NICK_LEN;
remote_sram_size = ntohl(cmd[1]) -
(2+2*MAX_INPUT_DEVICES)*sizeof(uint32_t) - (MAX_INPUT_DEVICES)*sizeof(uint8_t) - NETPLAY_NICK_LEN;
if (local_sram_size != 0 && local_sram_size == remote_sram_size)
{
@ -1063,7 +1121,7 @@ bool netplay_handshake_pre_sync(netplay_t *netplay,
/* Ask to switch to playing mode if we should */
if (!settings->bools.netplay_start_as_spectator)
return netplay_cmd_mode(netplay, connection, NETPLAY_CONNECTION_PLAYING);
return netplay_cmd_mode(netplay, NETPLAY_CONNECTION_PLAYING);
return true;
}

View File

@ -32,6 +32,7 @@
#include "../../autosave.h"
#include "../../retroarch.h"
#include "../../input/input_driver.h"
#if defined(AF_INET6) && !defined(HAVE_SOCKET_LEGACY)
#define HAVE_INET6 1
@ -183,12 +184,8 @@ static bool init_tcp_socket(netplay_t *netplay, void *direct_host,
while (tmp_info)
{
struct sockaddr_storage sad;
int fd;
memset(&sad, 0, sizeof(sad));
fd = init_tcp_connection(
struct sockaddr_storage sad = {0};
int fd = init_tcp_connection(
tmp_info,
direct_host || server,
(struct sockaddr*)&sad,
@ -243,7 +240,7 @@ static bool netplay_init_socket_buffers(netplay_t *netplay)
* frames of input data, plus the headers for each of them */
size_t i;
size_t packet_buffer_size = netplay->zbuffer_size +
NETPLAY_MAX_STALL_FRAMES * WORDS_PER_FRAME + (NETPLAY_MAX_STALL_FRAMES+1)*3;
NETPLAY_MAX_STALL_FRAMES * 16;
netplay->packet_buffer_size = packet_buffer_size;
for (i = 0; i < netplay->connections_size; i++)
@ -430,8 +427,6 @@ netplay_t *netplay_new(void *direct_host, const char *server, uint16_t port,
netplay->listen_fd = -1;
netplay->tcp_port = port;
netplay->cbs = *cb;
netplay->connected_players = 0;
netplay->player_max = 1;
netplay->is_server = (direct_host == NULL && server == NULL);
netplay->is_connected = false;;
netplay->nat_traversal = netplay->is_server ? nat_traversal : false;
@ -472,8 +467,26 @@ netplay_t *netplay_new(void *direct_host, const char *server, uint16_t port,
return NULL;
}
if (!netplay->is_server)
if (netplay->is_server)
{
/* Clients get device info from the server */
unsigned i;
for (i = 0; i < MAX_INPUT_DEVICES; i++)
{
uint32_t dtype = input_config_get_device(i);
netplay->config_devices[i] = dtype;
if ((dtype&RETRO_DEVICE_MASK) == RETRO_DEVICE_KEYBOARD)
{
netplay->have_updown_device = true;
netplay_key_hton_init();
}
if (dtype != RETRO_DEVICE_NONE && !netplay_expected_input_size(netplay, 1<<i))
RARCH_WARN("Netplay does not support input device %u\n", i+1);
}
}
else
{
/* Start our handshake */
netplay_handshake_init_send(netplay, &netplay->connections[0]);
netplay->connections[0].mode = NETPLAY_CONNECTION_INIT;
@ -539,8 +552,7 @@ void netplay_free(netplay_t *netplay)
if (netplay->buffer)
{
for (i = 0; i < netplay->buffer_size; i++)
if (netplay->buffer[i].state)
free(netplay->buffer[i].state);
netplay_delta_frame_free(&netplay->buffer[i]);
free(netplay->buffer);
}

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,53 @@
/* RetroArch - A frontend for libretro.
* Copyright (C) 2017 - Gregor Richards
*
* RetroArch is free software: you can redistribute it and/or modify it under the terms
* of the GNU General Public License as published by the Free Software Found-
* ation, either version 3 of the License, or (at your option) any later version.
*
* RetroArch is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
* PURPOSE. See the GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along with RetroArch.
* If not, see <http://www.gnu.org/licenses/>.
*/
#include <stdio.h>
#include "netplay_private.h"
/* The mapping of keys from netplay (network) to libretro (host) */
const uint16_t netplay_key_ntoh_mapping[] = {
(uint16_t) RETROK_UNKNOWN,
#define K(k) (uint16_t) RETROK_ ## k,
#define KL(k,l) (uint16_t) l,
#include "netplay_keys.h"
#undef KL
#undef K
0
};
static bool mapping_defined = false;
static uint16_t mapping[RETROK_LAST];
/* The mapping of keys from libretro (host) to netplay (network) */
uint32_t netplay_key_hton(unsigned key)
{
if (key >= RETROK_LAST)
return NETPLAY_KEY_UNKNOWN;
return mapping[key];
}
/* Because the hton keymapping has to be generated, call this before using
* netplay_key_hton */
void netplay_key_hton_init(void)
{
if (!mapping_defined)
{
uint16_t i;
for (i = 0; i < NETPLAY_KEY_LAST; i++)
mapping[netplay_key_ntoh(i)] = i;
mapping_defined = true;
}
}

View File

@ -0,0 +1,169 @@
/* RetroArch - A frontend for libretro.
* Copyright (C) 2016-2017 - Gregor Richards
*
* RetroArch is free software: you can redistribute it and/or modify it under the terms
* of the GNU General Public License as published by the Free Software Found-
* ation, either version 3 of the License, or (at your option) any later version.
*
* RetroArch is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
* PURPOSE. See the GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along with RetroArch.
* If not, see <http://www.gnu.org/licenses/>.
*/
/* This is an X-include file which defines the mapping of keycodes used by
* libretro to keycodes used by RetroArch Netplay. The keycodes are different
* because the keycodes supported by libretro are in discontiguous blocks,
* which would create gaps in the input data, requiring more space and more
* network bandwidth to represent them.
*
* If you want to add a new keycode, make sure you add it to the END. The order
* that the keys appear in this file defines their indices in the netplay
* protocol, so adding a key in the middle will break backwards compatibility.
* If you want to clean up the order and thereby break backwards compatibility,
* make sure you bump the protocol version in netplay_private.h.
*/
K(BACKSPACE)
K(TAB)
KL(LINEFEED, 10)
K(CLEAR)
K(RETURN)
K(PAUSE)
K(ESCAPE)
K(SPACE)
K(EXCLAIM)
K(QUOTEDBL)
K(HASH)
K(DOLLAR)
K(AMPERSAND)
K(QUOTE)
K(LEFTPAREN)
K(RIGHTPAREN)
K(ASTERISK)
K(PLUS)
K(COMMA)
K(MINUS)
K(PERIOD)
K(SLASH)
K(0)
K(1)
K(2)
K(3)
K(4)
K(5)
K(6)
K(7)
K(8)
K(9)
K(COLON)
K(SEMICOLON)
K(LESS)
K(EQUALS)
K(GREATER)
K(QUESTION)
K(AT)
K(LEFTBRACKET)
K(BACKSLASH)
K(RIGHTBRACKET)
K(CARET)
K(UNDERSCORE)
K(BACKQUOTE)
K(a)
K(b)
K(c)
K(d)
K(e)
K(f)
K(g)
K(h)
K(i)
K(j)
K(k)
K(l)
K(m)
K(n)
K(o)
K(p)
K(q)
K(r)
K(s)
K(t)
K(u)
K(v)
K(w)
K(x)
K(y)
K(z)
K(DELETE)
K(KP0)
K(KP1)
K(KP2)
K(KP3)
K(KP4)
K(KP5)
K(KP6)
K(KP7)
K(KP8)
K(KP9)
K(KP_PERIOD)
K(KP_DIVIDE)
K(KP_MULTIPLY)
K(KP_MINUS)
K(KP_PLUS)
K(KP_ENTER)
K(KP_EQUALS)
K(UP)
K(DOWN)
K(RIGHT)
K(LEFT)
K(INSERT)
K(HOME)
K(END)
K(PAGEUP)
K(PAGEDOWN)
K(F1)
K(F2)
K(F3)
K(F4)
K(F5)
K(F6)
K(F7)
K(F8)
K(F9)
K(F10)
K(F11)
K(F12)
K(F13)
K(F14)
K(F15)
K(NUMLOCK)
K(CAPSLOCK)
K(SCROLLOCK)
K(RSHIFT)
K(LSHIFT)
K(RCTRL)
K(LCTRL)
K(RALT)
K(LALT)
K(RMETA)
K(LMETA)
K(LSUPER)
K(RSUPER)
K(MODE)
K(COMPOSE)
K(HELP)
K(PRINT)
K(SYSREQ)
K(BREAK)
K(MENU)
K(POWER)
K(EURO)
K(UNDO)

View File

@ -28,10 +28,7 @@
#include "../../msg_hash.h"
#include "../../verbosity.h"
#define WORDS_PER_INPUT 3 /* Buttons, left stick, right stick */
#define WORDS_PER_FRAME (WORDS_PER_INPUT+2) /* + frameno, playerno */
#define NETPLAY_PROTOCOL_VERSION 4
#define NETPLAY_PROTOCOL_VERSION 5
#define RARCH_DEFAULT_PORT 55435
#define RARCH_DEFAULT_NICK "Anonymous"
@ -45,6 +42,15 @@
#define CATCH_UP_CHECK_TIME_USEC (500*1000)
#define MAX_RETRIES 16
#define RETRY_MS 500
#define MAX_INPUT_DEVICES 16
/* We allow only 32 clients to fit into a 32-bit bitmap */
#define MAX_CLIENTS 32
typedef uint32_t client_bitmap_t;
/* Because the callback keyboard reverses some assumptions, when the keyboard
* callbacks are in use, we assign a pseudodevice for it */
#define RETRO_DEVICE_NETPLAY_KEYBOARD RETRO_DEVICE_SUBCLASS(RETRO_DEVICE_KEYBOARD, 65535)
#define NETPLAY_MAX_STALL_FRAMES 60
#define NETPLAY_FRAME_RUN_TIME_WINDOW 120
@ -89,6 +95,13 @@
#define NETPLAY_COMPRESSION_SUPPORTED 0
#endif
/* Positional snprintf */
#ifdef _MSC_VER
#define snprintf_p _snprintf_p
#else /* sensible systems */
#define snprintf_p snprintf
#endif
enum netplay_cmd
{
/* Basic commands */
@ -162,9 +175,6 @@ enum netplay_cmd
/* Misc. commands */
/* Swap inputs between player 1 and player 2 */
NETPLAY_CMD_FLIP_PLAYERS = 0x0060,
/* Sends multiple config requests over,
* See enum netplay_cmd_cfg */
NETPLAY_CMD_CFG = 0x0061,
@ -175,12 +185,11 @@ enum netplay_cmd
NETPLAY_CMD_CFG_ACK = 0x0062
};
#define NETPLAY_CMD_INPUT_BIT_SERVER (1U<<31)
#define NETPLAY_CMD_SYNC_BIT_PAUSED (1U<<31)
#define NETPLAY_CMD_PLAY_BIT_SLAVE (1U)
#define NETPLAY_CMD_MODE_BIT_SLAVE (1U<<18)
#define NETPLAY_CMD_MODE_BIT_PLAYING (1U<<17)
#define NETPLAY_CMD_MODE_BIT_YOU (1U<<16)
#define NETPLAY_CMD_PLAY_BIT_SLAVE (1U<<31)
#define NETPLAY_CMD_MODE_BIT_YOU (1U<<31)
#define NETPLAY_CMD_MODE_BIT_PLAYING (1U<<30)
#define NETPLAY_CMD_MODE_BIT_SLAVE (1U<<29)
/* These are the reasons given for mode changes to be rejected */
enum netplay_cmd_mode_reasons
@ -195,9 +204,35 @@ enum netplay_cmd_mode_reasons
NETPLAY_CMD_MODE_REFUSED_REASON_NO_SLOTS,
/* You're changing modes too fast */
NETPLAY_CMD_MODE_REFUSED_REASON_TOO_FAST
NETPLAY_CMD_MODE_REFUSED_REASON_TOO_FAST,
/* You requested a particular port but it's not available */
NETPLAY_CMD_MODE_REFUSED_REASON_NOT_AVAILABLE
};
/* Real preferences for sharing devices */
enum rarch_netplay_share_preference
{
/* Prefer not to share, shouldn't be set as a sharing mode for an shared device */
NETPLAY_SHARE_NO_SHARING = 0x0,
/* No preference. Only for requests. Set if sharing is requested but either
* digital or analog doesn't have a preference. */
NETPLAY_SHARE_NO_PREFERENCE = 0x1,
/* For digital devices */
NETPLAY_SHARE_DIGITAL_BITS = 0x1C,
NETPLAY_SHARE_DIGITAL_OR = 0x4,
NETPLAY_SHARE_DIGITAL_XOR = 0x8,
NETPLAY_SHARE_DIGITAL_VOTE = 0xC,
/* For analog devices */
NETPLAY_SHARE_ANALOG_BITS = 0xE0,
NETPLAY_SHARE_ANALOG_MAX = 0x20,
NETPLAY_SHARE_ANALOG_AVERAGE = 0x40
};
/* The current status of a connection */
enum rarch_netplay_connection_mode
{
NETPLAY_CONNECTION_NONE = 0,
@ -240,7 +275,24 @@ enum rarch_netplay_stall_reason
NETPLAY_STALL_NO_CONNECTION
};
typedef uint32_t netplay_input_state_t[WORDS_PER_INPUT];
/* Input state for a particular client-device pair */
typedef struct netplay_input_state
{
/* The next input state (forming a list) */
struct netplay_input_state *next;
/* Is this a buffer with real data? */
bool used;
/* Whose data is this? */
uint32_t client_num;
/* How many words of input data do we have? */
uint32_t size;
/* The input data itself (note: should expand beyond 1 by overallocating). */
uint32_t data[1];
} *netplay_input_state_t;
struct delta_frame
{
@ -253,20 +305,22 @@ struct delta_frame
/* The CRC-32 of the serialized state if we've calculated it, else 0 */
uint32_t crc;
/* The real, simulated and local input. If we're playing, self_state is
* mirrored to the appropriate real_input_state player. */
netplay_input_state_t real_input_state[MAX_USERS];
netplay_input_state_t simulated_input_state[MAX_USERS];
netplay_input_state_t self_state;
/* The resolved input, i.e., what's actually going to the core. One input
* per device. */
netplay_input_state_t resolved_input[MAX_INPUT_DEVICES];
/* The real input */
netplay_input_state_t real_input[MAX_INPUT_DEVICES];
/* The simulated input. is_real here means the simulation is done, i.e.,
* it's a real simulation, not real input. */
netplay_input_state_t simlated_input[MAX_INPUT_DEVICES];
/* Have we read local input? */
bool have_local;
/* Have we read the real (remote) input? */
bool have_real[MAX_USERS];
/* Is the current state as of self_frame_count using the real (remote) data? */
bool used_real[MAX_USERS];
bool have_real[MAX_CLIENTS];
};
struct socket_buffer
@ -309,9 +363,6 @@ struct netplay_connection
* to wait for, or 0 if no delay is active. */
uint32_t delay_frame;
/* Player # of connected player */
uint32_t player;
/* What compression does this peer support? */
uint32_t compression_supported;
@ -350,8 +401,8 @@ struct netplay
/* TCP connection for listening (server only) */
int listen_fd;
/* Our player number */
uint32_t self_player;
/* Our client number */
uint32_t self_client_num;
/* Our mode and status */
enum rarch_netplay_connection_mode self_mode;
@ -361,19 +412,39 @@ struct netplay
size_t connections_size;
struct netplay_connection one_connection; /* Client only */
/* Bitmap of players with controllers (low bit is player 1) */
/* Bitmap of clients with input devices */
uint32_t connected_players;
/* Bitmap of players playing in slave mode (should be a subset of
/* Bitmap of clients playing in slave mode (should be a subset of
* connected_players) */
uint32_t connected_slaves;
/* For each client, the bitmap of devices they're connected to */
uint32_t client_devices[MAX_CLIENTS];
/* For each device, the bitmap of clients connected */
client_bitmap_t device_clients[MAX_INPUT_DEVICES];
/* The sharing mode for each device */
uint8_t device_share_modes[MAX_INPUT_DEVICES];
/* Our own device bitmap */
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;
/* Maximum player number */
uint32_t player_max;
/* The device types for every connected device. We store them and ignore any
* menu changes, as netplay needs fixed devices. */
uint32_t config_devices[MAX_INPUT_DEVICES];
/* Set to true if we have a device that most cores translate to "up/down"
* actions, typically a keyboard. We need to keep track of this because with
* such a device, we need to "fix" the input state to the frame BEFORE a
* state load, then perform the state load, and the up/down states will
* proceed as expected */
bool have_updown_device;
struct retro_callbacks cbs;
@ -418,9 +489,9 @@ struct netplay
size_t unread_ptr;
uint32_t unread_frame_count;
/* Pointer to the next frame to read from each player */
size_t read_ptr[MAX_USERS];
uint32_t read_frame_count[MAX_USERS];
/* Pointer to the next frame to read from each client */
size_t read_ptr[MAX_CLIENTS];
uint32_t read_frame_count[MAX_CLIENTS];
/* Pointer to the next frame to read from the server (as it might not be a
* player but still synchronizes) */
@ -441,7 +512,7 @@ struct netplay
bool can_poll;
/* Force a rewind to other_frame_count/other_ptr. This is for synchronized
* events, such as player flipping or savestate loading. */
* events, such as restarting or savestate loading. */
bool force_rewind;
/* Force a reset */
@ -456,21 +527,12 @@ struct netplay
/* Have we requested a savestate as a sync point? */
bool savestate_request_outstanding;
/* A buffer for outgoing input packets. */
uint32_t input_packet_buffer[2 + WORDS_PER_FRAME];
/* Our local socket info */
struct addrinfo *addr;
/* Counter for timeouts */
unsigned timeout_cnt;
/* User flipping
* Flipping state. If frame >= flip_frame, we apply the flip.
* If not, we apply the opposite, effectively creating a trigger point. */
bool flip;
uint32_t flip_frame;
/* Netplay pausing */
bool local_paused;
bool remote_paused;
@ -608,6 +670,28 @@ bool netplay_delta_frame_ready(netplay_t *netplay, struct delta_frame *delta,
*/
uint32_t netplay_delta_frame_crc(netplay_t *netplay, struct delta_frame *delta);
/**
* netplay_delta_frame_free
*
* Free a delta frame's dependencies
*/
void netplay_delta_frame_free(struct delta_frame *delta);
/**
* 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-DISCOVERY.C
@ -638,6 +722,13 @@ bool netplay_lan_ad_server(netplay_t *netplay);
void netplay_load_savestate(netplay_t *netplay,
retro_ctx_serialize_info_t *serial_info, bool save);
/**
* netplay_settings_share_mode
*
* Get the preferred share mode
*/
uint8_t netplay_settings_share_mode(void);
/**
* input_poll_net
*
@ -787,10 +878,10 @@ bool netplay_cmd_request_savestate(netplay_t *netplay);
/**
* netplay_cmd_mode
*
* Send a mode request command to either play or spectate.
* Send a mode change request. As a server, the request is to ourself, and so
* honored instantly.
*/
bool netplay_cmd_mode(netplay_t *netplay,
struct netplay_connection *connection,
enum rarch_netplay_connection_mode mode);
/**
@ -816,13 +907,6 @@ int netplay_poll_net_input(netplay_t *netplay, bool block);
*/
void netplay_handle_slaves(netplay_t *netplay);
/**
* netplay_flip_port
*
* Should we flip ports 0 and 1?
*/
bool netplay_flip_port(netplay_t *netplay);
/**
* netplay_announce_nat_traversal
*
@ -838,6 +922,33 @@ void netplay_announce_nat_traversal(netplay_t *netplay);
void netplay_init_nat_traversal(netplay_t *netplay);
/***************************************************************
* NETPLAY-KEYBOARD.C
**************************************************************/
/* 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
};
/* The mapping of keys from netplay (network) to libretro (host) */
extern const uint16_t netplay_key_ntoh_mapping[];
#define netplay_key_ntoh(k) (netplay_key_ntoh_mapping[k])
/* 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
**************************************************************/
@ -851,15 +962,17 @@ void netplay_init_nat_traversal(netplay_t *netplay);
void netplay_update_unread_ptr(netplay_t *netplay);
/**
* netplay_simulate_input
* netplay_resolve_input
* @netplay : pointer to netplay object
* @sim_ptr : frame index for which to simulate input
* @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.
*/
void netplay_simulate_input(netplay_t *netplay, size_t sim_ptr, bool resim);
bool netplay_resolve_input(netplay_t *netplay, size_t sim_ptr, bool resim);
/**
* netplay_sync_pre_frame

View File

@ -39,7 +39,7 @@
*/
void netplay_update_unread_ptr(netplay_t *netplay)
{
if (netplay->is_server && !netplay->connected_players)
if (netplay->is_server && netplay->connected_players<=1)
{
/* Nothing at all to read! */
netplay->unread_ptr = netplay->self_ptr;
@ -50,16 +50,16 @@ void netplay_update_unread_ptr(netplay_t *netplay)
{
size_t new_unread_ptr = 0;
uint32_t new_unread_frame_count = (uint32_t) -1;
uint32_t player;
uint32_t client;
for (player = 0; player < MAX_USERS; player++)
for (client = 0; client < MAX_CLIENTS; client++)
{
if (!(netplay->connected_players & (1<<player))) continue;
if ((netplay->connected_slaves & (1<<player))) continue;
if (netplay->read_frame_count[player] < new_unread_frame_count)
if (!(netplay->connected_players & (1<<client))) continue;
if ((netplay->connected_slaves & (1<<client))) continue;
if (netplay->read_frame_count[client] < new_unread_frame_count)
{
new_unread_ptr = netplay->read_ptr[player];
new_unread_frame_count = netplay->read_frame_count[player];
new_unread_ptr = netplay->read_ptr[client];
new_unread_frame_count = netplay->read_frame_count[client];
}
}
@ -82,63 +82,373 @@ void netplay_update_unread_ptr(netplay_t *netplay)
}
}
struct vote_count {
uint16_t votes[32];
};
/**
* netplay_simulate_input
* netplay_device_client_state
* @netplay : pointer to netplay object
* @sim_ptr : frame index for which to simulate input
* @simframe : frame in which merging is being performed
* @device : device being merged
* @client : client to find state for
*/
netplay_input_state_t netplay_device_client_state(netplay_t *netplay,
struct delta_frame *simframe, uint32_t device, uint32_t client)
{
uint32_t dsize = netplay_expected_input_size(netplay, 1 << device);
netplay_input_state_t simstate =
netplay_input_state_for(
&simframe->real_input[device], client,
dsize, false, true);
if (!simstate)
{
if (netplay->read_frame_count[client] > simframe->frame)
return NULL;
simstate = netplay_input_state_for(&simframe->simlated_input[device],
client, dsize, false, true);
}
return simstate;
}
/**
* netplay_merge_digital
* @netplay : pointer to netplay object
* @resstate : state being resolved
* @simframe : frame in which merging is being performed
* @device : device being merged
* @clients : bitmap of clients being merged
* @digital : bitmap of digital bits
*/
static void netplay_merge_digital(netplay_t *netplay,
netplay_input_state_t resstate, struct delta_frame *simframe,
uint32_t device, uint32_t clients, const uint32_t *digital)
{
netplay_input_state_t simstate;
uint32_t word, bit, client;
uint8_t share_mode = netplay->device_share_modes[device] & NETPLAY_SHARE_DIGITAL_BITS;
/* Make sure all real clients are accounted for */
for (simstate = simframe->real_input[device]; simstate; simstate = simstate->next)
{
if (!simstate->used || simstate->size != resstate->size) continue;
clients |= 1<<simstate->client_num;
}
if (share_mode == NETPLAY_SHARE_DIGITAL_VOTE)
{
/* Vote mode requires counting all the bits */
uint32_t client_count = 0;
/* This just assumes we have no more than three words, will need to be adjusted for new devices */
struct vote_count votes[3] = {0};
for (client = 0; client < MAX_CLIENTS; client++)
{
if (!(clients & (1<<client))) continue;
simstate = netplay_device_client_state(netplay, simframe, device, client);
if (!simstate) continue;
client_count++;
for (word = 0; word < resstate->size; word++)
{
if (!digital[word]) continue;
for (bit = 0; bit < 32; bit++)
{
if (!(digital[word] & (1<<bit))) continue;
if (simstate->data[word] & (1<<bit))
votes[word].votes[bit]++;
}
}
}
/* Now count all the bits */
client_count /= 2;
for (word = 0; word < resstate->size; word++)
{
for (bit = 0; bit < 32; bit++)
{
if (votes[word].votes[bit] > client_count)
resstate->data[word] |= (1<<bit);
}
}
}
else /* !VOTE */
{
for (client = 0; client < MAX_CLIENTS; client++)
{
if (!(clients & (1<<client))) continue;
simstate = netplay_device_client_state(netplay, simframe, device, client);
if (!simstate) continue;
for (word = 0; word < resstate->size; word++)
{
uint32_t part;
if (!digital[word]) continue;
part = simstate->data[word];
if (digital[word] == (uint32_t) -1)
{
/* Combine the whole word */
switch (share_mode)
{
case NETPLAY_SHARE_DIGITAL_XOR: resstate->data[word] ^= part; break;
default: resstate->data[word] |= part;
}
}
else /* !whole word */
{
for (bit = 0; bit < 32; bit++)
{
if (!(digital[word] & (1<<bit))) continue;
switch (share_mode)
{
case NETPLAY_SHARE_DIGITAL_XOR: resstate->data[word] ^= part & (1<<bit); break;
default: resstate->data[word] |= part & (1<<bit);
}
}
}
}
}
}
}
/**
* merge_analog_part
* @netplay : pointer to netplay object
* @resstate : state being resolved
* @simframe : frame in which merging is being performed
* @device : device being merged
* @clients : bitmap of clients being merged
* @word : word to merge
* @bit : first bit to merge
*/
static void merge_analog_part(netplay_t *netplay,
netplay_input_state_t resstate, struct delta_frame *simframe,
uint32_t device, uint32_t clients, uint32_t word, uint8_t bit)
{
netplay_input_state_t simstate;
uint32_t client, client_count = 0;;
uint8_t share_mode = netplay->device_share_modes[device] & NETPLAY_SHARE_ANALOG_BITS;
int32_t value = 0, new_value;
/* Make sure all real clients are accounted for */
for (simstate = simframe->real_input[device]; simstate; simstate = simstate->next)
{
if (!simstate->used || simstate->size != resstate->size) continue;
clients |= 1<<simstate->client_num;
}
for (client = 0; client < MAX_CLIENTS; client++)
{
if (!(clients & (1<<client))) continue;
simstate = netplay_device_client_state(netplay, simframe, device, client);
if (!simstate) continue;
client_count++;
new_value = (int16_t) ((simstate->data[word]>>bit) & 0xFFFF);
switch (share_mode)
{
case NETPLAY_SHARE_ANALOG_AVERAGE:
value += (int32_t) new_value;
break;
default:
if (abs(new_value) > abs(value) ||
(abs(new_value) == abs(value) && new_value > value))
value = new_value;
}
}
if (share_mode == NETPLAY_SHARE_ANALOG_AVERAGE)
value /= client_count;
resstate->data[word] |= ((uint32_t) (uint16_t) value) << bit;
}
/**
* netplay_merge_analog
* @netplay : pointer to netplay object
* @resstate : state being resolved
* @simframe : frame in which merging is being performed
* @device : device being merged
* @clients : bitmap of clients being merged
* @dtype : device type
*/
static void netplay_merge_analog(netplay_t *netplay,
netplay_input_state_t resstate, struct delta_frame *simframe,
uint32_t device, uint32_t clients, unsigned dtype)
{
/* Devices with no analog parts */
if (dtype == RETRO_DEVICE_JOYPAD || dtype == RETRO_DEVICE_KEYBOARD)
return;
/* All other devices have at least one analog word */
merge_analog_part(netplay, resstate, simframe, device, clients, 1, 0);
merge_analog_part(netplay, resstate, simframe, device, clients, 1, 16);
/* And the ANALOG device has two (two sticks) */
if (dtype == RETRO_DEVICE_ANALOG)
{
merge_analog_part(netplay, resstate, simframe, device, clients, 2, 0);
merge_analog_part(netplay, resstate, simframe, device, clients, 2, 16);
}
}
/**
* 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.
*/
void netplay_simulate_input(netplay_t *netplay, size_t sim_ptr, bool resim)
bool netplay_resolve_input(netplay_t *netplay, size_t sim_ptr, bool resim)
{
uint32_t player;
size_t prev;
struct delta_frame *simframe, *pframe;
netplay_input_state_t simstate, client_state = NULL, resstate, oldresstate, pstate;
uint32_t clients, client, client_count;
uint32_t device;
bool ret = false;
simframe = &netplay->buffer[sim_ptr];
for (player = 0; player < MAX_USERS; player++)
for (device = 0; device < MAX_INPUT_DEVICES; device++)
{
if (!(netplay->connected_players & (1<<player))) continue;
if (simframe->have_real[player]) continue;
unsigned dtype = netplay->config_devices[device]&RETRO_DEVICE_MASK;
uint32_t dsize = netplay_expected_input_size(netplay, 1 << device);
clients = netplay->device_clients[device];
client_count = 0;
prev = PREV_PTR(netplay->read_ptr[player]);
pframe = &netplay->buffer[prev];
if (resim)
/* Make sure all real clients are accounted for */
for (simstate = simframe->real_input[device]; simstate; simstate = simstate->next)
{
/* In resimulation mode, we only copy the buttons. The reason for this
* is nonobvious:
*
* If we resimulated nothing, then the /duration/ with which any input
* was pressed would be approximately correct, since the original
* simulation came in as the input came in, but the /number of times/
* the input was pressed would be wrong, as there would be an
* advancing wavefront of real data overtaking the simulated data
* (which is really just real data offset by some frames).
*
* That's acceptable for arrows in most situations, since the amount
* you move is tied to the duration, but unacceptable for buttons,
* which will seem to jerkily be pressed numerous times with those
* wavefronts.
*/
const uint32_t keep = (1U<<RETRO_DEVICE_ID_JOYPAD_UP) |
(1U<<RETRO_DEVICE_ID_JOYPAD_DOWN) |
(1U<<RETRO_DEVICE_ID_JOYPAD_LEFT) |
(1U<<RETRO_DEVICE_ID_JOYPAD_RIGHT);
uint32_t sim_state = simframe->simulated_input_state[player][0] & keep;
sim_state |= pframe->real_input_state[player][0] & ~keep;
simframe->simulated_input_state[player][0] = sim_state;
if (!simstate->used || simstate->size != dsize) continue;
clients |= 1<<simstate->client_num;
}
for (client = 0; client < MAX_CLIENTS; client++)
{
if (!(clients & (1<<client))) continue;
/* Resolve this client-device */
simstate = netplay_input_state_for(&simframe->real_input[device], client, dsize, false, true);
if (!simstate)
{
/* Don't already have this input, so must simulate if we're supposed to have it at all */
if (netplay->read_frame_count[client] > simframe->frame)
continue;
simstate = netplay_input_state_for(&simframe->simlated_input[device], client, dsize, false, false);
if (!simstate)
continue;
prev = PREV_PTR(netplay->read_ptr[client]);
pframe = &netplay->buffer[prev];
pstate = netplay_input_state_for(&pframe->real_input[device], client, dsize, false, true);
if (!pstate)
continue;
if (resim && (dtype == RETRO_DEVICE_JOYPAD || dtype == RETRO_DEVICE_ANALOG))
{
/* In resimulation mode, we only copy the buttons. The reason for this
* is nonobvious:
*
* If we resimulated nothing, then the /duration/ with which any input
* was pressed would be approximately correct, since the original
* simulation came in as the input came in, but the /number of times/
* the input was pressed would be wrong, as there would be an
* advancing wavefront of real data overtaking the simulated data
* (which is really just real data offset by some frames).
*
* That's acceptable for arrows in most situations, since the amount
* you move is tied to the duration, but unacceptable for buttons,
* which will seem to jerkily be pressed numerous times with those
* wavefronts.
*/
const uint32_t keep =
(1U<<RETRO_DEVICE_ID_JOYPAD_UP) |
(1U<<RETRO_DEVICE_ID_JOYPAD_DOWN) |
(1U<<RETRO_DEVICE_ID_JOYPAD_LEFT) |
(1U<<RETRO_DEVICE_ID_JOYPAD_RIGHT);
simstate->data[0] &= keep;
simstate->data[0] |= pstate->data[0] & ~keep;
}
else
{
memcpy(simstate->data, pstate->data,
dsize * sizeof(uint32_t));
}
}
client_state = simstate;
client_count++;
}
/* The frontend always uses the first resolved input, so make sure it's right */
while (simframe->resolved_input[device]
&& (simframe->resolved_input[device]->size != dsize
|| simframe->resolved_input[device]->client_num != 0))
{
/* The default resolved input is of the wrong size! */
netplay_input_state_t nextistate = simframe->resolved_input[device]->next;
free(simframe->resolved_input[device]);
simframe->resolved_input[device] = nextistate;
}
/* Now we copy the state, whether real or simulated, out into the resolved state */
resstate = netplay_input_state_for(&simframe->resolved_input[device], 0,
dsize, false, false);
if (!resstate)
continue;
if (client_count == 1)
{
/* Trivial in the common 1-client case */
if (memcmp(resstate->data, client_state->data, dsize * sizeof(uint32_t)))
ret = true;
memcpy(resstate->data, client_state->data, dsize * sizeof(uint32_t));
}
else if (client_count == 0)
{
uint32_t word;
for (word = 0; word < dsize; word++)
{
if (resstate->data[word])
ret = true;
resstate->data[word] = 0;
}
}
else
{
memcpy(simframe->simulated_input_state[player],
pframe->real_input_state[player],
WORDS_PER_INPUT * sizeof(uint32_t));
/* Merge them */
/* Most devices have all the digital parts in the first word. */
static const uint32_t digital_common[3] = {-1, 0, 0};
static const uint32_t digital_keyboard[5] = {-1, -1, -1, -1, -1};
const uint32_t *digital;
if (dtype == RETRO_DEVICE_KEYBOARD)
digital = digital_keyboard;
else
digital = digital_common;
oldresstate = netplay_input_state_for(&simframe->resolved_input[device], 1, dsize, false, false);
if (!oldresstate)
continue;
memcpy(oldresstate->data, resstate->data, dsize * sizeof(uint32_t));
memset(resstate->data, 0, dsize * sizeof(uint32_t));
netplay_merge_digital(netplay, resstate, simframe, device, clients, digital);
netplay_merge_analog(netplay, resstate, simframe, device, clients, dtype);
if (memcmp(resstate->data, oldresstate->data, dsize * sizeof(uint32_t)))
ret = true;
}
}
return ret;
}
static void netplay_handle_frame_hash(netplay_t *netplay, struct delta_frame *delta)
@ -391,7 +701,7 @@ void netplay_sync_post_frame(netplay_t *netplay, bool stalled)
}
/* Only relevant if we're connected and not in a desynching operation */
if ((netplay->is_server && !netplay->connected_players) ||
if ((netplay->is_server && (netplay->connected_players<=1)) ||
(netplay->self_mode < NETPLAY_CONNECTION_CONNECTED) ||
(netplay->desync))
{
@ -414,43 +724,72 @@ void netplay_sync_post_frame(netplay_t *netplay, bool stalled)
netplay->force_reset = false;
}
netplay->replay_ptr = netplay->other_ptr;
netplay->replay_frame_count = netplay->other_frame_count;
#ifndef DEBUG_NONDETERMINISTIC_CORES
if (!netplay->force_rewind)
{
bool cont = true;
/* Skip ahead if we predicted correctly.
* Skip until our simulation failed. */
while (netplay->other_frame_count < netplay->unread_frame_count &&
netplay->other_frame_count < netplay->run_frame_count)
{
struct delta_frame *ptr = &netplay->buffer[netplay->other_ptr];
size_t i;
for (i = 0; i < MAX_USERS; i++)
/* If resolving the input changes it, we used bad input */
if (netplay_resolve_input(netplay, netplay->other_ptr, true))
{
if (memcmp(ptr->simulated_input_state[i], ptr->real_input_state[i],
sizeof(ptr->real_input_state[i])) != 0
&& !ptr->used_real[i])
break;
cont = false;
break;
}
if (i != MAX_USERS) break;
netplay_handle_frame_hash(netplay, ptr);
netplay->other_ptr = NEXT_PTR(netplay->other_ptr);
netplay->other_frame_count++;
}
netplay->replay_ptr = netplay->other_ptr;
netplay->replay_frame_count = netplay->other_frame_count;
if (cont)
{
while (netplay->replay_frame_count < netplay->run_frame_count)
{
struct delta_frame *ptr = &netplay->buffer[netplay->replay_ptr];
if (netplay_resolve_input(netplay, netplay->replay_ptr, true))
break;
netplay->replay_ptr = NEXT_PTR(netplay->replay_ptr);
netplay->replay_frame_count++;
}
}
}
#endif
/* Now replay the real input if we've gotten ahead of it */
if (netplay->force_rewind ||
(netplay->other_frame_count < netplay->unread_frame_count &&
netplay->other_frame_count < netplay->run_frame_count))
(netplay->replay_frame_count < netplay->unread_frame_count &&
netplay->replay_frame_count < netplay->run_frame_count))
{
retro_ctx_serialize_info_t serial_info;
/* Replay frames. */
netplay->is_replay = true;
netplay->replay_ptr = netplay->other_ptr;
netplay->replay_frame_count = netplay->other_frame_count;
/* If we have a keyboard device, we replay the previous frame's input
* just to assert that the keydown/keyup events work if the core
* translates them in that way */
if (netplay->have_updown_device)
{
netplay->replay_ptr = PREV_PTR(netplay->replay_ptr);
netplay->replay_frame_count--;
autosave_lock();
core_run();
autosave_unlock();
netplay->replay_ptr = NEXT_PTR(netplay->replay_ptr);
netplay->replay_frame_count++;
}
if (netplay->quirks & NETPLAY_QUIRK_INITIALIZATION)
/* Make sure we're initialized before we start loading things */
@ -483,7 +822,7 @@ void netplay_sync_post_frame(netplay_t *netplay, bool stalled)
netplay_handle_frame_hash(netplay, ptr);
/* Re-simulate this frame's input */
netplay_simulate_input(netplay, netplay->replay_ptr, true);
netplay_resolve_input(netplay, netplay->replay_ptr, true);
autosave_lock();
core_run();
@ -536,16 +875,16 @@ void netplay_sync_post_frame(netplay_t *netplay, bool stalled)
if (netplay->is_server)
{
uint32_t player;
uint32_t client;
lo_frame_count = hi_frame_count = netplay->unread_frame_count;
/* Look for players that are ahead of us */
for (player = 0; player < MAX_USERS; player++)
for (client = 0; client < MAX_CLIENTS; client++)
{
if (!(netplay->connected_players & (1<<player))) continue;
if (netplay->read_frame_count[player] > hi_frame_count)
hi_frame_count = netplay->read_frame_count[player];
if (!(netplay->connected_players & (1<<client))) continue;
if (netplay->read_frame_count[client] > hi_frame_count)
hi_frame_count = netplay->read_frame_count[client];
}
}
else
@ -611,14 +950,14 @@ void netplay_sync_post_frame(netplay_t *netplay, bool stalled)
for (i = 0; i < netplay->connections_size; i++)
{
struct netplay_connection *connection = &netplay->connections[i];
int player;
uint32_t client_num;
if (!connection->active ||
connection->mode != NETPLAY_CONNECTION_PLAYING)
continue;
player = connection->player;
client_num = i + 1;
/* Are they ahead? */
if (netplay->self_frame_count + 3 < netplay->read_frame_count[player])
if (netplay->self_frame_count + 3 < netplay->read_frame_count[client_num])
{
/* Tell them to stall */
if (connection->stall_frame + NETPLAY_MAX_REQ_STALL_FREQUENCY <
@ -626,7 +965,7 @@ void netplay_sync_post_frame(netplay_t *netplay, bool stalled)
{
connection->stall_frame = netplay->self_frame_count;
netplay_cmd_stall(netplay, connection,
netplay->read_frame_count[player] -
netplay->read_frame_count[client_num] -
netplay->self_frame_count + 1);
}
}

View File

@ -2692,20 +2692,13 @@ static enum runloop_state runloop_check_state(
#ifdef HAVE_NETWORKING
/* Check Netplay */
{
static bool old_netplay_flip = false;
static bool old_netplay_watch = false;
bool netplay_flip = BIT256_GET(
current_input, RARCH_NETPLAY_FLIP);
bool netplay_watch = BIT256_GET(
current_input, RARCH_NETPLAY_GAME_WATCH);
if (netplay_flip && !old_netplay_flip)
netplay_driver_ctl(RARCH_NETPLAY_CTL_FLIP_PLAYERS, NULL);
if (netplay_watch && !old_netplay_watch)
netplay_driver_ctl(RARCH_NETPLAY_CTL_GAME_WATCH, NULL);
old_netplay_flip = netplay_flip;
old_netplay_watch = netplay_watch;
}
#endif

View File

@ -120,7 +120,6 @@ uint32_t frame_offset_cmd(bool ntoh)
case NETPLAY_CMD_CRC:
case NETPLAY_CMD_LOAD_SAVESTATE:
case NETPLAY_CMD_RESET:
case NETPLAY_CMD_FLIP_PLAYERS:
frame = ntohl(payload[0]);
if (ntoh)
frame -= frame_offset;
@ -285,7 +284,7 @@ int main(int argc, char **argv)
}
/* Expect the header */
if (!socket_receive_all_blocking(sock, payload, 4*sizeof(uint32_t)))
if (!socket_receive_all_blocking(sock, payload, 6*sizeof(uint32_t)))
{
fprintf(stderr, "Failed to receive connection header.\n");
return 1;
@ -299,7 +298,7 @@ int main(int argc, char **argv)
}
/* Echo the connection header back */
socket_send_all_blocking(sock, payload, 4*sizeof(uint32_t), true);
socket_send_all_blocking(sock, payload, 6*sizeof(uint32_t), true);
/* Send a nickname */
cmd = NETPLAY_CMD_NICK;
@ -340,7 +339,8 @@ int main(int argc, char **argv)
if (playing)
{
cmd = NETPLAY_CMD_PLAY;
cmd_size = 0;
cmd_size = sizeof(uint32_t);
payload[0] = htonl(1);
SEND();
}
@ -397,7 +397,7 @@ int main(int argc, char **argv)
/* Only sync based on server time */
if (cmd == NETPLAY_CMD_INPUT &&
(cmd_size < 2*sizeof(uint32_t) ||
!(ntohl(payload[1]) & NETPLAY_CMD_INPUT_BIT_SERVER)))
(ntohl(payload[1]) != 0)))
{
break;
}