/** * core_unset_netplay_callbacks * * Unset the I/O callbacks from having used netplay's interceding callback * system. Should only be called while uninitializing netplay. */ bool core_unset_netplay_callbacks(void) { struct retro_callbacks cbs; if (!core_set_default_callbacks(&cbs)) return false; current_core.retro_set_video_refresh(cbs.frame_cb); current_core.retro_set_audio_sample(cbs.sample_cb); current_core.retro_set_audio_sample_batch(cbs.sample_batch_cb); current_core.retro_set_input_state(cbs.state_cb); return true; }
/** * core_init_libretro_cbs: * @data : pointer to retro_callbacks object * * Initializes libretro callbacks, and binds the libretro callbacks * to default callback functions. **/ static bool core_init_libretro_cbs(struct retro_callbacks *cbs) { current_core.retro_set_video_refresh(video_driver_frame); current_core.retro_set_audio_sample(audio_driver_sample); current_core.retro_set_audio_sample_batch(audio_driver_sample_batch); current_core.retro_set_input_state(core_input_state_poll); current_core.retro_set_input_poll(core_input_state_poll_maybe); core_set_default_callbacks(cbs); #ifdef HAVE_NETWORKING if (!netplay_driver_ctl(RARCH_NETPLAY_CTL_IS_DATA_INITED, NULL)) return true; core_set_netplay_callbacks(); #endif return true; }
/** * core_init_libretro_cbs: * @data : pointer to retro_callbacks object * * Initializes libretro callbacks, and binds the libretro callbacks * to default callback functions. **/ static bool core_init_libretro_cbs(void *data) { struct retro_callbacks *cbs = (struct retro_callbacks*)data; #ifdef HAVE_NETPLAY global_t *global = global_get_ptr(); #endif if (!cbs) return false; core.retro_set_video_refresh(video_driver_frame); core.retro_set_audio_sample(audio_driver_sample); core.retro_set_audio_sample_batch(audio_driver_sample_batch); core.retro_set_input_state(core_input_state_poll); core.retro_set_input_poll(core_input_state_poll_maybe); core_set_default_callbacks(cbs); #ifdef HAVE_NETPLAY if (!netplay_driver_ctl(RARCH_NETPLAY_CTL_IS_DATA_INITED, NULL)) return true; /* Force normal poll type for netplay. */ core_poll_type = POLL_TYPE_NORMAL; if (global->netplay.is_spectate) { core.retro_set_input_state( (global->netplay.is_client ? input_state_spectate_client : input_state_spectate) ); } else { core.retro_set_video_refresh(video_frame_net); core.retro_set_audio_sample(audio_sample_net); core.retro_set_audio_sample_batch(audio_sample_batch_net); core.retro_set_input_state(input_state_net); } #endif return true; }
bool init_netplay(bool is_spectate, const char *server, unsigned port) { struct retro_callbacks cbs = {0}; settings_t *settings = config_get_ptr(); uint64_t serialization_quirks = 0; uint64_t quirks = 0; if (!netplay_enabled) return false; if (bsv_movie_ctl(BSV_MOVIE_CTL_START_PLAYBACK, NULL)) { RARCH_WARN("%s\n", msg_hash_to_str(MSG_NETPLAY_FAILED_MOVIE_PLAYBACK_HAS_STARTED)); return false; } core_set_default_callbacks(&cbs); /* Map the core's quirks to our quirks */ serialization_quirks = core_serialization_quirks(); if (serialization_quirks & ~((uint64_t) NETPLAY_QUIRK_MAP_UNDERSTOOD)) { /* Quirks we don't support! Just disable everything. */ quirks |= NETPLAY_QUIRK_NO_SAVESTATES; } if (serialization_quirks & NETPLAY_QUIRK_MAP_NO_SAVESTATES) quirks |= NETPLAY_QUIRK_NO_SAVESTATES; if (serialization_quirks & NETPLAY_QUIRK_MAP_NO_TRANSMISSION) quirks |= NETPLAY_QUIRK_NO_TRANSMISSION; if (serialization_quirks & NETPLAY_QUIRK_MAP_INITIALIZATION) quirks |= NETPLAY_QUIRK_INITIALIZATION; if (serialization_quirks & NETPLAY_QUIRK_MAP_ENDIAN_DEPENDENT) quirks |= NETPLAY_QUIRK_ENDIAN_DEPENDENT; if (serialization_quirks & NETPLAY_QUIRK_MAP_PLATFORM_DEPENDENT) quirks |= NETPLAY_QUIRK_PLATFORM_DEPENDENT; if (netplay_is_client) { RARCH_LOG("Connecting to netplay host...\n"); } else { RARCH_LOG("Waiting for client...\n"); runloop_msg_queue_push( "Waiting for client...", 0, 180, false); } netplay_data = (netplay_t*)netplay_new( netplay_is_client ? server : NULL, port ? port : RARCH_DEFAULT_PORT, settings->netplay.sync_frames, settings->netplay.check_frames, &cbs, is_spectate, settings->username, quirks); if (netplay_data) return true; RARCH_WARN("%s\n", msg_hash_to_str(MSG_NETPLAY_FAILED)); runloop_msg_queue_push( msg_hash_to_str(MSG_NETPLAY_FAILED), 0, 180, false); return false; }
/** * init_netplay * @direct_host : Host to connect to directly, if applicable (client only) * @server : server address to connect to (client only) * @port : TCP port to host on/connect to * * Initializes netplay. * * If netplay is already initialized, will return false (0). * * Returns: true (1) if successful, otherwise false (0). **/ bool init_netplay(void *direct_host, const char *server, unsigned port) { struct retro_callbacks cbs = {0}; settings_t *settings = config_get_ptr(); uint64_t serialization_quirks = 0; uint64_t quirks = 0; if (!netplay_enabled) return false; core_set_default_callbacks(&cbs); if (!core_set_netplay_callbacks()) return false; /* Map the core's quirks to our quirks */ serialization_quirks = core_serialization_quirks(); if (serialization_quirks & ~((uint64_t) NETPLAY_QUIRK_MAP_UNDERSTOOD)) { /* Quirks we don't support! Just disable everything. */ quirks |= NETPLAY_QUIRK_NO_SAVESTATES; } if (serialization_quirks & NETPLAY_QUIRK_MAP_NO_SAVESTATES) quirks |= NETPLAY_QUIRK_NO_SAVESTATES; if (serialization_quirks & NETPLAY_QUIRK_MAP_NO_TRANSMISSION) quirks |= NETPLAY_QUIRK_NO_TRANSMISSION; if (serialization_quirks & NETPLAY_QUIRK_MAP_INITIALIZATION) quirks |= NETPLAY_QUIRK_INITIALIZATION; if (serialization_quirks & NETPLAY_QUIRK_MAP_ENDIAN_DEPENDENT) quirks |= NETPLAY_QUIRK_ENDIAN_DEPENDENT; if (serialization_quirks & NETPLAY_QUIRK_MAP_PLATFORM_DEPENDENT) quirks |= NETPLAY_QUIRK_PLATFORM_DEPENDENT; if (netplay_is_client) { RARCH_LOG("[netplay] %s\n", msg_hash_to_str(MSG_CONNECTING_TO_NETPLAY_HOST)); } else { RARCH_LOG("[netplay] %s\n", msg_hash_to_str(MSG_WAITING_FOR_CLIENT)); runloop_msg_queue_push( msg_hash_to_str(MSG_WAITING_FOR_CLIENT), 0, 180, false); if (settings->bools.netplay_public_announce) netplay_announce(); } netplay_data = (netplay_t*)netplay_new( netplay_is_client ? direct_host : NULL, netplay_is_client ? (!netplay_client_deferred ? server : server_address_deferred) : NULL, netplay_is_client ? (!netplay_client_deferred ? port : server_port_deferred ) : (port != 0 ? port : RARCH_DEFAULT_PORT), settings->bools.netplay_stateless_mode, settings->ints.netplay_check_frames, &cbs, settings->bools.netplay_nat_traversal, settings->paths.username, quirks); if (netplay_data) { if (netplay_data->is_server && !settings->bools.netplay_start_as_spectator) netplay_toggle_play_spectate(netplay_data); return true; } RARCH_WARN("%s\n", msg_hash_to_str(MSG_NETPLAY_FAILED)); runloop_msg_queue_push( msg_hash_to_str(MSG_NETPLAY_FAILED), 0, 180, false); return false; }