/** * hangup: * * Disconnects an active Netplay connection due to an error **/ static void hangup(netplay_t *netplay) { if (!netplay) return; if (!netplay->has_connection) return; RARCH_WARN("Netplay has disconnected. Will continue without connection ...\n"); runloop_msg_queue_push("Netplay has disconnected. Will continue without connection.", 0, 480, false); socket_close(netplay->fd); netplay->fd = -1; if (netplay->is_server && !netplay->spectate.enabled) { /* In server mode, make the socket listen for a new connection */ if (!init_socket(netplay, NULL, netplay->tcp_port)) { RARCH_WARN("Failed to reinitialize Netplay.\n"); runloop_msg_queue_push("Failed to reinitialize Netplay.", 0, 480, false); } } netplay->has_connection = false; /* Reset things that will behave oddly if we get a new connection */ netplay->remote_paused = false; netplay->flip = false; netplay->flip_frame = 0; netplay->stall = 0; }
static void input_autoconfigure_joypad_add(config_file_t *conf, autoconfig_params_t *params) { bool block_osd_spam; static bool remote_is_bound = false; char msg[PATH_MAX_LENGTH] = {0}; char display_name[PATH_MAX_LENGTH] = {0}; char device_type[PATH_MAX_LENGTH] = {0}; settings_t *settings = config_get_ptr(); config_get_array(conf, "input_device_display_name", display_name, sizeof(display_name)); config_get_array(conf, "input_device_type", device_type, sizeof(device_type)); if (!settings) return; /* This will be the case if input driver is reinitialized. * No reason to spam autoconfigure messages every time. */ block_osd_spam = settings->input.autoconfigured[params->idx] && *params->name; settings->input.autoconfigured[params->idx] = true; input_autoconfigure_joypad_conf(conf, settings->input.autoconf_binds[params->idx]); if (!strcmp(device_type,"remote")) { if (!string_is_empty(display_name) || strcmp(display_name, "")) snprintf(msg, sizeof(msg), "%s configured", display_name); else snprintf(msg, sizeof(msg), "%s configured", params->name); if(!remote_is_bound) runloop_msg_queue_push(msg, 0, 60, false); remote_is_bound = true; } else { if (!string_is_empty(display_name) || strcmp(display_name, "")) snprintf(msg, sizeof(msg), "%s configured in port #%u.", display_name, params->idx); else snprintf(msg, sizeof(msg), "%s configured in port #%u.", params->name, params->idx); if (!block_osd_spam) runloop_msg_queue_push(msg, 0, 60, false); } input_reindex_devices(); #if 0 RARCH_LOG("Autodetect: %s\n", msg); #endif }
/** * netplay_command: * @netplay : pointer to netplay object * @cmd : command to send * @data : data to send as argument * @sz : size of data * @flags : flags of CMD_OPT_* * @command_str : name of action * @success_msg : message to display upon success * * Sends a single netplay command and waits for response. */ bool netplay_command(netplay_t* netplay, enum netplay_cmd cmd, void* data, size_t sz, uint32_t flags, const char* command_str, const char* success_msg) { char m[256]; const char* msg = NULL; bool allowed_spectate = !!(flags & CMD_OPT_ALLOWED_IN_SPECTATE_MODE); bool host_only = !!(flags & CMD_OPT_HOST_ONLY); bool require_sync = !!(flags & CMD_OPT_REQUIRE_SYNC); assert(netplay); if (netplay->spectate.enabled && !allowed_spectate) { msg = "Cannot %s in spectate mode."; goto error; } if (host_only && netplay->port == 0) { msg = "Cannot %s as a client."; goto error; } if(require_sync && check_netplay_synched(netplay)) { msg = "Cannot %s while host and client are not in sync."; goto error; } if(netplay_send_raw_cmd(netplay, cmd, data, sz)) { if(netplay_get_response(netplay)) runloop_msg_queue_push(success_msg, 1, 180, false); else { msg = "Failed to send command \"%s\""; goto error; } } return true; error: snprintf(m, sizeof(m), msg, command_str); RARCH_WARN("%s\n", m); runloop_msg_queue_push(m, 1, 180, false); return false; }
static bool runloop_check_movie_init(void) { char msg[128] = {0}; char path[PATH_MAX_LENGTH] = {0}; settings_t *settings = config_get_ptr(); if (bsv_movie_ctl(BSV_MOVIE_CTL_IS_INITED, NULL)) return false; settings->rewind_granularity = 1; if (settings->state_slot > 0) snprintf(path, sizeof(path), "%s%d", bsv_movie_get_path(), settings->state_slot); else strlcpy(path, bsv_movie_get_path(), sizeof(path)); strlcat(path, file_path_str(FILE_PATH_BSV_EXTENSION), sizeof(path)); snprintf(msg, sizeof(msg), "%s \"%s\".", msg_hash_to_str(MSG_STARTING_MOVIE_RECORD_TO), path); bsv_movie_init_handle(path, RARCH_MOVIE_RECORD); if (!bsv_movie_ctl(BSV_MOVIE_CTL_IS_INITED, NULL)) return false; if (bsv_movie_ctl(BSV_MOVIE_CTL_IS_INITED, NULL)) { runloop_msg_queue_push(msg, 2, 180, true); RARCH_LOG("%s \"%s\".\n", msg_hash_to_str(MSG_STARTING_MOVIE_RECORD_TO), path); } else { runloop_msg_queue_push( msg_hash_to_str(MSG_FAILED_TO_START_MOVIE_RECORD), 2, 180, true); RARCH_ERR("%s\n", msg_hash_to_str(MSG_FAILED_TO_START_MOVIE_RECORD)); } return true; }
/** * netplay_post_frame_spectate: * @netplay : pointer to netplay object * * Post-frame for Netplay (spectate mode version). * We check if we have new input and replay from recorded input. **/ static void netplay_spectate_post_frame(netplay_t *netplay) { unsigned i; if (!np_is_server(netplay)) return; for (i = 0; i < MAX_SPECTATORS; i++) { char msg[128]; if (netplay->spectate.fds[i] == -1) continue; if (socket_send_all_blocking(netplay->spectate.fds[i], netplay->spectate.input, netplay->spectate.input_ptr * sizeof(int16_t))) continue; RARCH_LOG("Client (#%u) disconnected ...\n", i); snprintf(msg, sizeof(msg), "Client (#%u) disconnected.", i); runloop_msg_queue_push(msg, 1, 180, false); socket_close(netplay->spectate.fds[i]); netplay->spectate.fds[i] = -1; break; } netplay->spectate.input_ptr = 0; }
static void gfx_ctx_d3d_update_title(void *data) { char buf[128] = {0}; char buffer_fps[128] = {0}; settings_t *settings = config_get_ptr(); HWND window = win32_get_window(); if (video_monitor_get_fps(buf, sizeof(buf), buffer_fps, sizeof(buffer_fps))) { #ifndef _XBOX SetWindowText(window, buf); #endif } if (settings->fps_show) { #ifdef _XBOX MEMORYSTATUS stat; char mem[128] = {0}; GlobalMemoryStatus(&stat); snprintf(mem, sizeof(mem), "|| MEM: %.2f/%.2fMB", stat.dwAvailPhys/(1024.0f*1024.0f), stat.dwTotalPhys/(1024.0f*1024.0f)); strlcat(buffer_fps, mem, sizeof(buffer_fps)); #endif runloop_msg_queue_push(buffer_fps, 1, 1, false); } }
static int task_database_iterate_start(database_info_handle_t *db, const char *name) { char msg[511]; msg[0] = msg[510] = '\0'; snprintf(msg, sizeof(msg), STRING_REP_USIZE "/" STRING_REP_USIZE ": %s %s...\n", (size_t)db->list_ptr, (size_t)db->list->size, msg_hash_to_str(MSG_SCANNING), name); if (!string_is_empty(msg)) { #ifdef RARCH_INTERNAL runloop_msg_queue_push(msg, 1, 180, true); #else fprintf(stderr, "msg: %s\n", msg); #endif } db->status = DATABASE_STATUS_ITERATE; return 0; }
static int task_database_iterate_start(database_info_handle_t *db, const char *name) { char msg[128] = {0}; snprintf(msg, sizeof(msg), STRING_REP_ULONG "/" STRING_REP_ULONG ": %s %s...\n", #if defined(_WIN32) || defined(__STDC_VERSION__) && __STDC_VERSION__>=199901L db->list_ptr, db->list->size, #else (unsigned long)db->list_ptr, (unsigned long)db->list->size, #endif msg_hash_to_str(MSG_SCANNING), name); if (!string_is_empty(msg)) runloop_msg_queue_push(msg, 1, 180, true); #if 0 RARCH_LOG("msg: %s\n", msg); #endif db->status = DATABASE_STATUS_ITERATE; return 0; }
static void event_load_auto_state(void) { bool ret; char msg[128] = {0}; char savestate_name_auto[PATH_MAX_LENGTH] = {0}; settings_t *settings = config_get_ptr(); global_t *global = global_get_ptr(); #ifdef HAVE_NETPLAY if (global->netplay.enable && !global->netplay.is_spectate) return; #endif if (!settings->savestate_auto_load) return; fill_pathname_noext(savestate_name_auto, global->name.savestate, ".auto", sizeof(savestate_name_auto)); if (!path_file_exists(savestate_name_auto)) return; ret = load_state(savestate_name_auto); RARCH_LOG("Found auto savestate in: %s\n", savestate_name_auto); snprintf(msg, sizeof(msg), "Auto-loading savestate from \"%s\" %s.", savestate_name_auto, ret ? "succeeded" : "failed"); runloop_msg_queue_push(msg, 1, 180, false); RARCH_LOG("%s\n", msg); }
bool input_config_autoconfigure_joypad(autoconfig_params_t *params) { char msg[PATH_MAX_LENGTH]; if (!input_config_autoconfigure_joypad_init(params)) goto error; if (!*params->name) goto error; if (input_autoconfigure_joypad_from_conf_dir(params)) return true; #if defined(HAVE_BUILTIN_AUTOCONFIG) if (input_autoconfigure_joypad_from_conf_internal(params)) return true; #endif RARCH_LOG("Autodetect: no profiles found for %s (%d/%d)\n", params->name, params->vid, params->pid); snprintf(msg, sizeof(msg), "%s (%ld/%ld) not configured", params->name, (long)params->vid, (long)params->pid); runloop_msg_queue_push(msg, 0, 60, false); error: return false; }
static void connmanctl_scan(void) { char line[512]; union string_list_elem_attr attr; FILE *serv_file = NULL; attr.i = RARCH_FILETYPE_UNSET; if (lines) free(lines); lines = string_list_new(); pclose(popen("connmanctl enable wifi", "r")); pclose(popen("connmanctl scan wifi", "r")); runloop_msg_queue_push("Wi-Fi scan complete.", 1, 180, true); serv_file = popen("connmanctl services", "r"); while (fgets (line, 512, serv_file) != NULL) { size_t len = strlen(line); if (len > 0 && line[len-1] == '\n') line[--len] = '\0'; string_list_append(lines, line, attr); } pclose(serv_file); }
static void event_main_state(unsigned cmd) { char path[PATH_MAX_LENGTH] = {0}; char msg[128] = {0}; global_t *global = global_get_ptr(); settings_t *settings = config_get_ptr(); if (settings->state_slot > 0) snprintf(path, sizeof(path), "%s%d", global->name.savestate, settings->state_slot); else if (settings->state_slot < 0) fill_pathname_join_delim(path, global->name.savestate, "auto", '.', sizeof(path)); else strlcpy(path, global->name.savestate, sizeof(path)); if (core.retro_serialize_size()) { switch (cmd) { case EVENT_CMD_SAVE_STATE: event_save_state(path, msg, sizeof(msg)); break; case EVENT_CMD_LOAD_STATE: event_load_state(path, msg, sizeof(msg)); break; } } else strlcpy(msg, msg_hash_to_str(MSG_CORE_DOES_NOT_SUPPORT_SAVESTATES), sizeof(msg)); runloop_msg_queue_push(msg, 2, 180, true); RARCH_LOG("%s\n", msg); }
/** * driver_update_system_av_info: * @data : pointer to new A/V info * * Update the system Audio/Video information. * Will reinitialize audio/video drivers. * Used by RETRO_ENVIRONMENT_SET_SYSTEM_AV_INFO. * * Returns: true (1) if successful, otherwise false (0). **/ static bool driver_update_system_av_info(const struct retro_system_av_info *info) { struct retro_system_av_info *av_info = video_viewport_get_system_av_info(); settings_t *settings = config_get_ptr(); memcpy(av_info, info, sizeof(*av_info)); command_event(CMD_EVENT_REINIT, NULL); /* Cannot continue recording with different parameters. * Take the easiest route out and just restart the recording. */ if (recording_driver_get_data_ptr()) { runloop_msg_queue_push( msg_hash_to_str(MSG_RESTARTING_RECORDING_DUE_TO_DRIVER_REINIT), 2, 180, false); command_event(CMD_EVENT_RECORD_DEINIT, NULL); command_event(CMD_EVENT_RECORD_INIT, NULL); } /* Hide mouse cursor in fullscreen after * a RETRO_ENVIRONMENT_SET_SYSTEM_AV_INFO call. */ if (settings->bools.video_fullscreen) video_driver_hide_mouse(); return true; }
static bool menu_content_load(void) { content_ctx_info_t content_info; char name[PATH_MAX_LENGTH]; char msg[PATH_MAX_LENGTH]; bool msg_force = true; char *fullpath = NULL; runloop_ctl(RUNLOOP_CTL_GET_CONTENT_PATH, &fullpath); /* redraw menu frame */ menu_display_ctl(MENU_DISPLAY_CTL_SET_MSG_FORCE, &msg_force); menu_driver_ctl(RARCH_MENU_CTL_RENDER, NULL); if (*fullpath) fill_pathname_base(name, fullpath, sizeof(name)); content_info.argc = 0; content_info.argv = NULL; content_info.args = NULL; content_info.environ_get = menu_content_environment_get; if (!content_ctl(CONTENT_CTL_LOAD, &content_info)) goto error; if (*fullpath) { snprintf(msg, sizeof(msg), "INFO - Loading %s ...", name); runloop_msg_queue_push(msg, 1, 1, false); } if (*fullpath || menu_driver_ctl(RARCH_MENU_CTL_HAS_LOAD_NO_CONTENT, NULL)) { struct retro_system_info *info = NULL; menu_driver_ctl(RARCH_MENU_CTL_SYSTEM_INFO_GET, &info); content_push_to_history_playlist(true, fullpath, info); content_playlist_write_file(g_defaults.history); } return true; error: snprintf(msg, sizeof(msg), "Failed to load %s.\n", name); runloop_msg_queue_push(msg, 1, 90, false); return false; }
void input_config_autoconfigure_disconnect(unsigned i, const char *ident) { char msg[PATH_MAX_LENGTH]; snprintf(msg, sizeof(msg), "Device #%u (%s) disconnected.", i, ident); runloop_msg_queue_push(msg, 0, 60, false); RARCH_LOG("Autodetect: %s\n", msg); }
static void bsv_movie_init_state(void) { settings_t *settings = config_get_ptr(); if (bsv_movie_ctl(BSV_MOVIE_CTL_START_PLAYBACK, NULL)) { if (!(bsv_movie_init_handle(bsv_movie_state.movie_start_path, RARCH_MOVIE_PLAYBACK))) { RARCH_ERR("%s: \"%s\".\n", msg_hash_to_str(MSG_FAILED_TO_LOAD_MOVIE_FILE), bsv_movie_state.movie_start_path); retro_fail(1, "event_init_movie()"); } bsv_movie_state.movie_playback = true; runloop_msg_queue_push(msg_hash_to_str(MSG_STARTING_MOVIE_PLAYBACK), 2, 180, false); RARCH_LOG("%s.\n", msg_hash_to_str(MSG_STARTING_MOVIE_PLAYBACK)); settings->rewind_granularity = 1; } else if (bsv_movie_ctl(BSV_MOVIE_CTL_START_RECORDING, NULL)) { char msg[256]; snprintf(msg, sizeof(msg), "%s \"%s\".", msg_hash_to_str(MSG_STARTING_MOVIE_RECORD_TO), bsv_movie_state.movie_start_path); if (!(bsv_movie_init_handle(bsv_movie_state.movie_start_path, RARCH_MOVIE_RECORD))) { runloop_msg_queue_push( msg_hash_to_str(MSG_FAILED_TO_START_MOVIE_RECORD), 1, 180, true); RARCH_ERR("%s.\n", msg_hash_to_str(MSG_FAILED_TO_START_MOVIE_RECORD)); return; } runloop_msg_queue_push(msg, 1, 180, true); RARCH_LOG("%s \"%s\".\n", msg_hash_to_str(MSG_STARTING_MOVIE_RECORD_TO), bsv_movie_state.movie_start_path); settings->rewind_granularity = 1; } }
static bool connmanctl_connect_ssid(unsigned i, const char* passphrase) { char ln[512] = {0}; char name[20] = {0}; char service[128] = {0}; char command[256] = {0}; char settings_dir[PATH_MAX_LENGTH] = {0}; char settings_path[PATH_MAX_LENGTH] = {0}; FILE *command_file = NULL; FILE *settings_file = NULL; FILE *serv_file = NULL; union string_list_elem_attr attr; const char *line = lines->elems[i].data; strlcpy(name, line+4, sizeof(name)); strlcpy(name, string_trim_whitespace(name), sizeof(name)); strlcpy(service, line+25, sizeof(service)); strlcat(settings_dir, LAKKA_CONNMAN_DIR, sizeof(settings_dir)); strlcat(settings_dir, service, sizeof(settings_dir)); path_mkdir(settings_dir); strlcat(settings_path, settings_dir, sizeof(settings_path)); strlcat(settings_path, "/settings", sizeof(settings_path)); settings_file = fopen(settings_path, "w"); fprintf(settings_file, "[%s]\n", service); fprintf(settings_file, "Name=%s\n", name); fprintf(settings_file, "SSID="); for (int i=0; i < strlen(name); i++) fprintf(settings_file, "%02x", (unsigned int) name[i]); fprintf(settings_file, "\n"); fprintf(settings_file, "Favorite=%s\n", "true"); fprintf(settings_file, "AutoConnect=%s\n", "true"); fprintf(settings_file, "Passphrase=%s\n", passphrase); fprintf(settings_file, "IPv4.method=%s\n", "dhcp"); fclose(settings_file); pclose(popen("systemctl restart connman", "r")); strlcat(command, "connmanctl connect ", sizeof(command)); strlcat(command, service, sizeof(command)); strlcat(command, " 2>&1", sizeof(command)); command_file = popen(command, "r"); while (fgets (ln, 512, command_file) != NULL) { runloop_msg_queue_push(ln, 1, 180, true); } pclose(command_file); return true; }
/** * check_shader_dir: * @pressed_next : was next shader key pressed? * @pressed_previous : was previous shader key pressed? * * Checks if any one of the shader keys has been pressed for this frame: * a) Next shader index. * b) Previous shader index. * * Will also immediately apply the shader. **/ static void check_shader_dir(rarch_dir_list_t *dir_list, bool pressed_next, bool pressed_prev) { uint32_t ext_hash; char msg[128]; const char *shader = NULL; const char *ext = NULL; enum rarch_shader_type type = RARCH_SHADER_NONE; if (!dir_list || !dir_list->list) return; if (pressed_next) { dir_list->ptr = (dir_list->ptr + 1) % dir_list->list->size; } else if (pressed_prev) { if (dir_list->ptr == 0) dir_list->ptr = dir_list->list->size - 1; else dir_list->ptr--; } else return; shader = dir_list->list->elems[dir_list->ptr].data; ext = path_get_extension(shader); ext_hash = msg_hash_calculate(ext); switch (ext_hash) { case SHADER_EXT_GLSL: case SHADER_EXT_GLSLP: type = RARCH_SHADER_GLSL; break; case SHADER_EXT_CG: case SHADER_EXT_CGP: type = RARCH_SHADER_CG; break; default: return; } snprintf(msg, sizeof(msg), "%s #%u: \"%s\".", msg_hash_to_str(MSG_SHADER), (unsigned)dir_list->ptr, shader); runloop_msg_queue_push(msg, 1, 120, true); RARCH_LOG("%s \"%s\".\n", msg_hash_to_str(MSG_APPLYING_SHADER), shader); if (!video_driver_set_shader(type, shader)) RARCH_WARN("%s\n", msg_hash_to_str(MSG_FAILED_TO_APPLY_SHADER)); }
void runloop_msg_queue_push_new(uint32_t hash, unsigned prio, unsigned duration, bool flush) { const char *msg = msg_hash_to_str(hash); if (!msg) return; runloop_msg_queue_push(msg, prio, duration, flush); }
void task_msg_queue_pushf(unsigned prio, unsigned duration, bool flush, const char *fmt, ...) { char buf[1024]; va_list ap; va_start(ap, fmt); vsnprintf(buf, sizeof(buf), fmt, ap); va_end(ap); runloop_msg_queue_push(buf, prio, duration, flush); }
/** * menu_content_playlist_load: * @playlist : Playlist handle. * @idx : Index in playlist. * * Initializes core and loads content based on playlist entry. **/ void menu_content_playlist_load(void *data, unsigned idx) { const char *core_path = NULL; const char *path = NULL; content_playlist_t *playlist = (content_playlist_t*)data; if (!playlist) return; content_playlist_get_index(playlist, idx, &path, NULL, &core_path, NULL, NULL, NULL); if (path && !string_is_empty(path)) { unsigned i; RFILE *fp = NULL; char *path_check = NULL; char *path_tolower = strdup(path); for (i = 0; i < strlen(path_tolower); ++i) path_tolower[i] = tolower(path_tolower[i]); if (strstr(path_tolower, ".zip")) strstr(path_tolower, ".zip")[4] = '\0'; else if (strstr(path_tolower, ".7z")) strstr(path_tolower, ".7z")[3] = '\0'; path_check = (char *)calloc(strlen(path_tolower) + 1, sizeof(char)); strncpy(path_check, path, strlen(path_tolower)); fp = retro_fopen(path_check, RFILE_MODE_READ, -1); if (!fp) { runloop_msg_queue_push("File could not be loaded.\n", 1, 100, true); RARCH_LOG("File at %s failed to load.\n", path_check); free(path_tolower); free(path_check); return; } retro_fclose(fp); free(path_tolower); free(path_check); } runloop_ctl(RUNLOOP_CTL_SET_LIBRETRO_PATH, (void*)core_path); if (path) menu_driver_ctl(RARCH_MENU_CTL_UNSET_LOAD_NO_CONTENT, NULL); else menu_driver_ctl(RARCH_MENU_CTL_SET_LOAD_NO_CONTENT, NULL); rarch_environment_cb(RETRO_ENVIRONMENT_EXEC, (void*)path); event_cmd_ctl(EVENT_CMD_LOAD_CORE, NULL); }
void netplay_log_connection(const struct sockaddr_storage *their_addr, unsigned slot, const char *nick) { char msg[512] = {0}; snprintf(msg, sizeof(msg), "Got connection from: \"%s\"", nick); runloop_msg_queue_push(msg, 1, 180, false); RARCH_LOG("%s\n", msg); RARCH_LOG("Connection slot %u\n", slot); }
/* Checks if slowmotion toggle/hold was being pressed and/or held. */ static bool runloop_check_slowmotion(bool *ptr) { settings_t *settings = config_get_ptr(); if (!ptr) return false; runloop_slowmotion = *ptr; if (!runloop_slowmotion) return false; if (settings->video.black_frame_insertion) video_driver_cached_frame_render(); if (state_manager_frame_is_reversed()) runloop_msg_queue_push(msg_hash_to_str(MSG_SLOW_MOTION_REWIND), 2, 30, true); else runloop_msg_queue_push(msg_hash_to_str(MSG_SLOW_MOTION), 2, 30, true); return true; }
static void gfx_ctx_drm_update_window_title(void *data) { char buf[128]; char buf_fps[128]; settings_t *settings = config_get_ptr(); video_monitor_get_fps(buf, sizeof(buf), buf_fps, sizeof(buf_fps)); if (settings->fps_show) runloop_msg_queue_push( buf_fps, 1, 1, false); }
bool netplay_send_info(netplay_t *netplay) { unsigned sram_size; retro_ctx_memory_info_t mem_info; char msg[512] = {0}; uint32_t *content_crc_ptr = NULL; void *sram = NULL; uint32_t header[3] = {0}; mem_info.id = RETRO_MEMORY_SAVE_RAM; core_get_memory(&mem_info); content_get_crc(&content_crc_ptr); header[0] = htonl(*content_crc_ptr); header[1] = htonl(netplay_impl_magic()); header[2] = htonl(mem_info.size); if (!socket_send_all_blocking(netplay->fd, header, sizeof(header), false)) return false; if (!netplay_send_nickname(netplay, netplay->fd)) { RARCH_ERR("%s\n", msg_hash_to_str(MSG_FAILED_TO_SEND_NICKNAME_TO_HOST)); return false; } /* Get SRAM data from User 1. */ sram = mem_info.data; sram_size = mem_info.size; if (!socket_receive_all_blocking(netplay->fd, sram, sram_size)) { RARCH_ERR("%s\n", msg_hash_to_str(MSG_FAILED_TO_RECEIVE_SRAM_DATA_FROM_HOST)); return false; } if (!netplay_get_nickname(netplay, netplay->fd)) { RARCH_ERR("%s\n", msg_hash_to_str(MSG_FAILED_TO_RECEIVE_NICKNAME_FROM_HOST)); return false; } snprintf(msg, sizeof(msg), "%s: \"%s\"", msg_hash_to_str(MSG_CONNECTED_TO), netplay->other_nick); RARCH_LOG("%s\n", msg); runloop_msg_queue_push(msg, 1, 180, false); return true; }
/** * event_disk_control_append_image: * @path : Path to disk image. * * Appends disk image to disk image list. **/ static bool event_disk_control_append_image(const char *path) { unsigned new_idx; char msg[128] = {0}; struct retro_game_info info = {0}; global_t *global = global_get_ptr(); const struct retro_disk_control_callback *control = NULL; rarch_system_info_t *sysinfo = NULL; runloop_ctl(RUNLOOP_CTL_SYSTEM_INFO_GET, &sysinfo); if (sysinfo) control = (const struct retro_disk_control_callback*) &sysinfo->disk_control_cb; if (!control) return false; event_disk_control_set_eject(true, false); control->add_image_index(); new_idx = control->get_num_images(); if (!new_idx) return false; new_idx--; info.path = path; control->replace_image_index(new_idx, &info); snprintf(msg, sizeof(msg), "%s: ", msg_hash_to_str(MSG_APPENDED_DISK)); strlcat(msg, path, sizeof(msg)); RARCH_LOG("%s\n", msg); runloop_msg_queue_push(msg, 0, 180, true); event_cmd_ctl(EVENT_CMD_AUTOSAVE_DEINIT, NULL); /* TODO: Need to figure out what to do with subsystems case. */ if (!*global->subsystem) { /* Update paths for our new image. * If we actually use append_image, we assume that we * started out in a single disk case, and that this way * of doing it makes the most sense. */ rarch_ctl(RARCH_CTL_SET_PATHS, (void*)path); rarch_ctl(RARCH_CTL_FILL_PATHNAMES, NULL); } event_cmd_ctl(EVENT_CMD_AUTOSAVE_INIT, NULL); event_disk_control_set_index(new_idx); event_disk_control_set_eject(false, false); return true; }
/* Custom inet_ntop. Win32 doesn't seem to support this ... */ void np_log_connection(const struct sockaddr_storage *their_addr, unsigned slot, const char *nick) { union { const struct sockaddr_storage *storage; const struct sockaddr_in *v4; const struct sockaddr_in6 *v6; } u; const char *str = NULL; char buf_v4[INET_ADDRSTRLEN] = {0}; char buf_v6[INET6_ADDRSTRLEN] = {0}; u.storage = their_addr; if (their_addr->ss_family == AF_INET) { struct sockaddr_in in; str = buf_v4; memset(&in, 0, sizeof(in)); in.sin_family = AF_INET; memcpy(&in.sin_addr, &u.v4->sin_addr, sizeof(struct in_addr)); getnameinfo((struct sockaddr*)&in, sizeof(struct sockaddr_in), buf_v4, sizeof(buf_v4), NULL, 0, NI_NUMERICHOST); } else if (their_addr->ss_family == AF_INET6) { struct sockaddr_in6 in; str = buf_v6; memset(&in, 0, sizeof(in)); in.sin6_family = AF_INET6; memcpy(&in.sin6_addr, &u.v6->sin6_addr, sizeof(struct in6_addr)); getnameinfo((struct sockaddr*)&in, sizeof(struct sockaddr_in6), buf_v6, sizeof(buf_v6), NULL, 0, NI_NUMERICHOST); } if (str) { char msg[512] = {0}; snprintf(msg, sizeof(msg), "Got connection from: \"%s (%s)\" (#%u)", nick, str, slot); runloop_msg_queue_push(msg, 1, 180, false); RARCH_LOG("%s\n", msg); } }
/** * driver_location_start: * * Starts location driver interface.. * Used by RETRO_ENVIRONMENT_GET_LOCATION_INTERFACE. * * Returns: true (1) if successful, otherwise false (0). **/ bool driver_location_start(void) { settings_t *settings = config_get_ptr(); if (location_driver && location_data && location_driver->start) { if (settings->location.allow) return location_driver->start(location_data); runloop_msg_queue_push("Location is explicitly disabled.\n", 1, 180, true); } return false; }
/** * netplay_command: * @netplay : pointer to netplay object * @cmd : command to send * @data : data to send as argument * @sz : size of data * @flags : flags of CMD_OPT_* * @command_str : name of action * @success_msg : message to display upon success * * Sends a single netplay command and waits for response. */ bool netplay_command(netplay_t* netplay, enum netplay_cmd cmd, void* data, size_t sz, uint32_t flags, const char* command_str, const char* success_msg) { char m[256]; const char* msg = NULL; bool allowed_spectate = !!(flags & CMD_OPT_ALLOWED_IN_SPECTATE_MODE); bool host_only = !!(flags & CMD_OPT_HOST_ONLY); retro_assert(netplay); if (netplay->spectate.enabled && !allowed_spectate) { msg = "Cannot %s in spectate mode."; goto error; } if (host_only && netplay->port == 0) { msg = "Cannot %s as a client."; goto error; } if (!netplay_send_raw_cmd(netplay, cmd, data, sz)) goto error; runloop_msg_queue_push(success_msg, 1, 180, false); return true; error: if (msg) snprintf(m, sizeof(m), msg, command_str); RARCH_WARN("%s\n", m); runloop_msg_queue_push(m, 1, 180, false); return false; }
/* Checks if movie is being recorded. */ static bool runloop_check_movie_record(void) { if (!bsv_movie_ctl(BSV_MOVIE_CTL_IS_INITED, NULL)) return false; runloop_msg_queue_push( msg_hash_to_str(MSG_MOVIE_RECORD_STOPPED), 2, 180, true); RARCH_LOG("%s\n", msg_hash_to_str(MSG_MOVIE_RECORD_STOPPED)); command_event(CMD_EVENT_BSV_MOVIE_DEINIT, NULL); return true; }