struct string_list *dir_list_new_special(const char *input_dir, enum dir_list_type type, const char *filter) { char ext_shaders[PATH_MAX_LENGTH] = {0}; char ext_name[PATH_MAX_LENGTH] = {0}; const char *dir = NULL; const char *exts = NULL; bool include_dirs = false; (void)input_dir; switch (type) { case DIR_LIST_AUTOCONFIG: dir = input_dir; exts = filter; break; case DIR_LIST_CORES: dir = input_dir; if (!frontend_driver_get_core_extension(ext_name, sizeof(ext_name))) return NULL; exts = ext_name; break; case DIR_LIST_CORE_INFO: { core_info_list_t *list = NULL; core_info_get_list(&list); dir = input_dir; exts = list->all_ext; } break; case DIR_LIST_SHADERS: { union string_list_elem_attr attr = {0}; struct string_list *str_list = string_list_new(); if (!str_list) return NULL; dir = input_dir; #ifdef HAVE_CG string_list_append(str_list, "cg", attr); string_list_append(str_list, "cgp", attr); #endif #ifdef HAVE_GLSL string_list_append(str_list, "glsl", attr); string_list_append(str_list, "glslp", attr); #endif #ifdef HAVE_VULKAN string_list_append(str_list, "slang", attr); string_list_append(str_list, "slangp", attr); #endif string_list_join_concat(ext_shaders, sizeof(ext_shaders), str_list, "|"); string_list_free(str_list); exts = ext_shaders; } break; case DIR_LIST_COLLECTIONS: dir = input_dir; exts = "lpl"; break; case DIR_LIST_DATABASES: dir = input_dir; exts = "rdb"; break; case DIR_LIST_PLAIN: dir = input_dir; exts = filter; break; case DIR_LIST_NONE: default: return NULL; } return dir_list_new(dir, exts, include_dirs, type == DIR_LIST_CORE_INFO); }
int init_xkb(void) { settings_t *settings = config_get_ptr(); mod_map_idx = (xkb_mod_index_t *)calloc(MOD_MAP_SIZE, sizeof(xkb_mod_index_t)); if (!mod_map_idx) goto error; mod_map_bit = (uint16_t*)calloc(MOD_MAP_SIZE, sizeof(uint16_t)); if (!mod_map_bit) goto error; xkb_ctx = xkb_context_new(XKB_CONTEXT_NO_FLAGS); if (xkb_ctx) { struct string_list *list = NULL; struct xkb_rule_names rule = {0}; rule.rules = "evdev"; if (*settings->input.keyboard_layout) { list = string_split(settings->input.keyboard_layout, ":"); if (list && list->size >= 2) rule.variant = list->elems[1].data; if (list && list->size >= 1) rule.layout = list->elems[0].data; } xkb_map = xkb_keymap_new_from_names(xkb_ctx, &rule, XKB_MAP_COMPILE_NO_FLAGS); if (list) string_list_free(list); } if (xkb_map) { xkb_mod_index_t *map_idx = (xkb_mod_index_t*)&mod_map_idx[0]; uint16_t *map_bit = (uint16_t*)&mod_map_bit[0]; xkb_state = xkb_state_new(xkb_map); *map_idx = xkb_keymap_mod_get_index(xkb_map, XKB_MOD_NAME_CAPS); map_idx++; *map_bit = RETROKMOD_CAPSLOCK; map_bit++; *map_idx = xkb_keymap_mod_get_index(xkb_map, XKB_MOD_NAME_SHIFT); map_idx++; *map_bit = RETROKMOD_SHIFT; map_bit++; *map_idx = xkb_keymap_mod_get_index(xkb_map, XKB_MOD_NAME_CTRL); map_idx++; *map_bit = RETROKMOD_CTRL; map_bit++; *map_idx = xkb_keymap_mod_get_index(xkb_map, XKB_MOD_NAME_ALT); map_idx++; *map_bit = RETROKMOD_ALT; map_bit++; *map_idx = xkb_keymap_mod_get_index(xkb_map, XKB_MOD_NAME_LOGO); *map_bit = RETROKMOD_META; } return 0; error: free_xkb(); return -1; }
unsigned print_buf_lines(file_list_t *list, char *buf, const char *label, int buf_size, enum msg_file_type type, bool append, bool extended) { char c; unsigned count = 0; int i, j = 0; char *line_start = buf; if (!buf || !buf_size) return 0; for (i = 0; i < buf_size; i++) { size_t ln; const char *core_date = NULL; const char *core_crc = NULL; const char *core_pathname = NULL; struct string_list *str_list = NULL; /* The end of the buffer, print the last bit */ if (*(buf + i) == '\0') break; if (*(buf + i) != '\n') continue; /* Found a line ending, print the line and compute new line_start */ /* Save the next char */ c = *(buf + i + 1); /* replace with \0 */ *(buf + i + 1) = '\0'; /* We need to strip the newline. */ ln = strlen(line_start) - 1; if (line_start[ln] == '\n') line_start[ln] = '\0'; str_list = string_split(line_start, " "); if (str_list->elems[0].data) core_date = str_list->elems[0].data; if (str_list->elems[1].data) core_crc = str_list->elems[1].data; if (str_list->elems[2].data) core_pathname = str_list->elems[2].data; (void)core_date; (void)core_crc; if (extended) { if (append) { if (menu_entries_append_enum(list, core_pathname, "", MENU_ENUM_LABEL_URL_ENTRY, type, 0, 0)) count++; } else { menu_entries_prepend(list, core_pathname, "", MENU_ENUM_LABEL_URL_ENTRY, type, 0, 0); count++; } } else { if (append) { if (menu_entries_append_enum(list, line_start, label, MENU_ENUM_LABEL_URL_ENTRY, type, 0, 0)) count++; } else { menu_entries_prepend(list, line_start, label, MENU_ENUM_LABEL_URL_ENTRY, type, 0, 0); count++; } } switch (type) { case FILE_TYPE_DOWNLOAD_CORE: { settings_t *settings = config_get_ptr(); if (settings) { char display_name[255]; char core_path[PATH_MAX_LENGTH]; char *last = NULL; display_name[0] = core_path[0] = '\0'; fill_pathname_join_noext( core_path, settings->paths.path_libretro_info, (extended && !string_is_empty(core_pathname)) ? core_pathname : line_start, sizeof(core_path)); path_remove_extension(core_path); last = (char*)strrchr(core_path, '_'); if (!string_is_empty(last)) { if (string_is_not_equal_fast(last, "_libretro", 9)) *last = '\0'; } strlcat(core_path, file_path_str(FILE_PATH_CORE_INFO_EXTENSION), sizeof(core_path)); if ( filestream_exists(core_path) && core_info_get_display_name( core_path, display_name, sizeof(display_name))) file_list_set_alt_at_offset(list, j, display_name); } } break; default: case FILE_TYPE_NONE: break; } j++; string_list_free(str_list); /* Restore the saved char */ *(buf + i + 1) = c; line_start = buf + i + 1; } if (append) file_list_sort_on_alt(list); /* If the buffer was completely full, and didn't end * with a newline, just ignore the partial last line. */ return count; }
static bool input_overlay_load_overlay(config_file_t *conf, const char *config_path, struct overlay *overlay, unsigned index) { char overlay_path_key[64]; char overlay_path[PATH_MAX]; char overlay_resolved_path[PATH_MAX]; snprintf(overlay_path_key, sizeof(overlay_path_key), "overlay%u_overlay", index); if (!config_get_path(conf, overlay_path_key, overlay_path, sizeof(overlay_path))) { RARCH_ERR("[Overlay]: Config key: %s is not set.\n", overlay_path_key); return false; } fill_pathname_resolve_relative(overlay_resolved_path, config_path, overlay_path, sizeof(overlay_resolved_path)); struct texture_image img = {0}; if (!texture_image_load(overlay_resolved_path, &img)) { RARCH_ERR("Failed to load image: %s.\n", overlay_path); return false; } overlay->image = img.pixels; overlay->width = img.width; overlay->height = img.height; // By default, we stretch the overlay out in full. overlay->x = overlay->y = 0.0f; overlay->w = overlay->h = 1.0f; char overlay_rect_key[64]; snprintf(overlay_rect_key, sizeof(overlay_rect_key), "overlay%u_rect", index); char overlay_rect[256]; if (config_get_array(conf, overlay_rect_key, overlay_rect, sizeof(overlay_rect))) { struct string_list *list = string_split(overlay_rect, ", "); if (list->size < 4) { RARCH_ERR("[Overlay]: Failed to split rect \"%s\" into at least four tokens.\n", overlay_rect); return false; } overlay->x = strtod(list->elems[0].data, NULL); overlay->y = strtod(list->elems[1].data, NULL); overlay->w = strtod(list->elems[2].data, NULL); overlay->h = strtod(list->elems[3].data, NULL); string_list_free(list); } char overlay_full_screen_key[64]; snprintf(overlay_full_screen_key, sizeof(overlay_full_screen_key), "overlay%u_full_screen", index); overlay->full_screen = false; config_get_bool(conf, overlay_full_screen_key, &overlay->full_screen); char overlay_descs_key[64]; snprintf(overlay_descs_key, sizeof(overlay_descs_key), "overlay%u_descs", index); unsigned descs = 0; if (!config_get_uint(conf, overlay_descs_key, &descs)) { RARCH_ERR("[Overlay]: Failed to read number of descs from config key: %s.\n", overlay_descs_key); return false; } overlay->descs = (struct overlay_desc*)calloc(descs, sizeof(*overlay->descs)); if (!overlay->descs) { RARCH_ERR("[Overlay]: Failed to allocate descs.\n"); return false; } overlay->size = descs; for (size_t i = 0; i < overlay->size; i++) { if (!input_overlay_load_desc(conf, &overlay->descs[i], index, i, img.width, img.height)) { RARCH_ERR("[Overlay]: Failed to load overlay descs for overlay #%u.\n", (unsigned)i); return false; } } // Assume for now that scaling center is in the middle. // TODO: Make this configurable. overlay->block_scale = false; overlay->center_x = overlay->x + 0.5f * overlay->w; overlay->center_y = overlay->y + 0.5f * overlay->h; return true; }
static struct string_list *compressed_7zip_file_list_new( const char *path, const char* ext) { CFileInStream archiveStream; CLookToRead lookStream; CSzArEx db; ISzAlloc allocImp; ISzAlloc allocTempImp; size_t temp_size = 0; struct string_list *list = NULL; /* These are the allocation routines - currently using * the non-standard 7zip choices. */ allocImp.Alloc = SzAlloc; allocImp.Free = SzFree; allocTempImp.Alloc = SzAllocTemp; allocTempImp.Free = SzFreeTemp; if (InFile_Open(&archiveStream.file, path)) { RARCH_ERR("Could not open %s as 7z archive.\n",path); return NULL; } list = string_list_new(); if (!list) { File_Close(&archiveStream.file); return NULL; } FileInStream_CreateVTable(&archiveStream); LookToRead_CreateVTable(&lookStream, False); lookStream.realStream = &archiveStream.s; LookToRead_Init(&lookStream); CrcGenerateTable(); SzArEx_Init(&db); if (SzArEx_Open(&db, &lookStream.s, &allocImp, &allocTempImp) == SZ_OK) { uint32_t i; struct string_list *ext_list = ext ? string_split(ext, "|"): NULL; SRes res = SZ_OK; uint16_t *temp = NULL; for (i = 0; i < db.db.NumFiles; i++) { union string_list_elem_attr attr; char infile[PATH_MAX_LENGTH]; const char *file_ext = NULL; size_t len = 0; bool supported_by_core = false; const CSzFileItem *f = db.db.Files + i; /* we skip over everything, which is a directory. */ if (f->IsDir) continue; len = SzArEx_GetFileNameUtf16(&db, i, NULL); if (len > temp_size) { free(temp); temp_size = len; temp = (uint16_t *)malloc(temp_size * sizeof(temp[0])); if (temp == 0) { res = SZ_ERROR_MEM; break; } } SzArEx_GetFileNameUtf16(&db, i, temp); res = utf16_to_char_string(temp, infile, sizeof(infile)) ? SZ_OK : SZ_ERROR_FAIL; file_ext = path_get_extension(infile); if (string_list_find_elem_prefix(ext_list, ".", file_ext)) supported_by_core = true; /* * Currently we only support files without subdirs in the archives. * Folders are not supported (differences between win and lin. * Archives within archives should imho never be supported. */ if (!supported_by_core) continue; attr.i = RARCH_COMPRESSED_FILE_IN_ARCHIVE; if (!string_list_append(list, infile, attr)) { res = SZ_ERROR_MEM; break; } } string_list_free(ext_list); free(temp); if (res != SZ_OK) { /* Error handling */ RARCH_ERR("Failed to open compressed_file: \"%s\"\n", path); string_list_free(list); list = NULL; } } SzArEx_Free(&db, &allocImp); File_Close(&archiveStream.file); return list; }
int init_xkb(int fd, size_t size) { char *map_str = NULL; mod_map_idx = (xkb_mod_index_t *)calloc( MOD_MAP_SIZE, sizeof(xkb_mod_index_t)); if (!mod_map_idx) goto error; mod_map_bit = (uint16_t*) calloc(MOD_MAP_SIZE, sizeof(uint16_t)); if (!mod_map_bit) goto error; xkb_ctx = xkb_context_new(XKB_CONTEXT_NO_FLAGS); if (xkb_ctx) { if (fd >= 0) { map_str = (char*)mmap(NULL, size, PROT_READ, MAP_SHARED, fd, 0); if (map_str == MAP_FAILED) goto error; xkb_map = xkb_keymap_new_from_string(xkb_ctx, map_str, XKB_KEYMAP_FORMAT_TEXT_V1, XKB_KEYMAP_COMPILE_NO_FLAGS); munmap(map_str, size); } else { struct string_list *list = NULL; struct xkb_rule_names rule = {0}; settings_t *settings = config_get_ptr(); rule.rules = "evdev"; if (*settings->arrays.input_keyboard_layout) { list = string_split(settings->arrays.input_keyboard_layout, ":"); if (list && list->size >= 2) rule.variant = list->elems[1].data; if (list && list->size >= 1) rule.layout = list->elems[0].data; } xkb_map = xkb_keymap_new_from_names(xkb_ctx, &rule, XKB_MAP_COMPILE_NO_FLAGS); if (list) string_list_free(list); } } if (xkb_map) { xkb_mod_index_t *map_idx = (xkb_mod_index_t*)&mod_map_idx[0]; uint16_t *map_bit = (uint16_t*)&mod_map_bit[0]; xkb_state = xkb_state_new(xkb_map); *map_idx = xkb_keymap_mod_get_index(xkb_map, XKB_MOD_NAME_CAPS); map_idx++; *map_bit = RETROKMOD_CAPSLOCK; map_bit++; *map_idx = xkb_keymap_mod_get_index(xkb_map, XKB_MOD_NAME_SHIFT); map_idx++; *map_bit = RETROKMOD_SHIFT; map_bit++; *map_idx = xkb_keymap_mod_get_index(xkb_map, XKB_MOD_NAME_CTRL); map_idx++; *map_bit = RETROKMOD_CTRL; map_bit++; *map_idx = xkb_keymap_mod_get_index(xkb_map, XKB_MOD_NAME_ALT); map_idx++; *map_bit = RETROKMOD_ALT; map_bit++; *map_idx = xkb_keymap_mod_get_index(xkb_map, XKB_MOD_NAME_LOGO); *map_bit = RETROKMOD_META; } return 0; error: free_xkb(); return -1; }
/** * event_command: * @cmd : Event command index. * * Performs program event command with index @cmd. * * Returns: true (1) on success, otherwise false (0). **/ bool event_command(enum event_command cmd) { unsigned i = 0; bool boolean = false; runloop_t *runloop = rarch_main_get_ptr(); driver_t *driver = driver_get_ptr(); global_t *global = global_get_ptr(); settings_t *settings = config_get_ptr(); rarch_system_info_t *system = rarch_system_info_get_ptr(); (void)i; switch (cmd) { case EVENT_CMD_LOAD_CONTENT_PERSIST: #ifdef HAVE_DYNAMIC event_command(EVENT_CMD_LOAD_CORE); #endif rarch_main_set_state(RARCH_ACTION_STATE_LOAD_CONTENT); break; #ifdef HAVE_FFMPEG case EVENT_CMD_LOAD_CONTENT_FFMPEG: rarch_main_set_state(RARCH_ACTION_STATE_LOAD_CONTENT_FFMPEG); break; #endif case EVENT_CMD_LOAD_CONTENT_IMAGEVIEWER: rarch_main_set_state(RARCH_ACTION_STATE_LOAD_CONTENT_IMAGEVIEWER); break; case EVENT_CMD_LOAD_CONTENT: #ifdef HAVE_DYNAMIC event_command(EVENT_CMD_LOAD_CONTENT_PERSIST); #else rarch_environment_cb(RETRO_ENVIRONMENT_SET_LIBRETRO_PATH, (void*)settings->libretro); rarch_environment_cb(RETRO_ENVIRONMENT_EXEC, (void*)global->fullpath); event_command(EVENT_CMD_QUIT); #endif break; case EVENT_CMD_LOAD_CORE_DEINIT: #ifdef HAVE_DYNAMIC libretro_free_system_info(&global->menu.info); #endif break; case EVENT_CMD_LOAD_CORE_PERSIST: event_command(EVENT_CMD_LOAD_CORE_DEINIT); { #ifdef HAVE_MENU menu_handle_t *menu = menu_driver_get_ptr(); if (menu) event_update_system_info(&global->menu.info, &menu->load_no_content); #endif } break; case EVENT_CMD_LOAD_CORE: event_command(EVENT_CMD_LOAD_CORE_PERSIST); #ifndef HAVE_DYNAMIC event_command(EVENT_CMD_QUIT); #endif break; case EVENT_CMD_LOAD_STATE: /* Immutable - disallow savestate load when * we absolutely cannot change game state. */ if (global->bsv.movie) return false; #ifdef HAVE_NETPLAY if (driver->netplay_data) return false; #endif event_main_state(cmd); break; case EVENT_CMD_RESIZE_WINDOWED_SCALE: if (global->pending.windowed_scale == 0) return false; settings->video.scale = global->pending.windowed_scale; if (!settings->video.fullscreen) event_command(EVENT_CMD_REINIT); global->pending.windowed_scale = 0; break; case EVENT_CMD_MENU_TOGGLE: if (menu_driver_alive()) rarch_main_set_state(RARCH_ACTION_STATE_MENU_RUNNING_FINISHED); else rarch_main_set_state(RARCH_ACTION_STATE_MENU_RUNNING); break; case EVENT_CMD_CONTROLLERS_INIT: event_init_controllers(); break; case EVENT_CMD_RESET: RARCH_LOG("%s.\n", msg_hash_to_str(MSG_RESET)); rarch_main_msg_queue_push_new(MSG_RESET, 1, 120, true); pretro_reset(); /* bSNES since v073r01 resets controllers to JOYPAD * after a reset, so just enforce it here. */ event_command(EVENT_CMD_CONTROLLERS_INIT); break; case EVENT_CMD_SAVE_STATE: if (settings->savestate_auto_index) settings->state_slot++; event_main_state(cmd); break; case EVENT_CMD_TAKE_SCREENSHOT: if (!take_screenshot()) return false; break; case EVENT_CMD_PREPARE_DUMMY: { #ifdef HAVE_MENU menu_handle_t *menu = menu_driver_get_ptr(); if (menu) menu->load_no_content = false; #endif rarch_main_data_deinit(); *global->fullpath = '\0'; rarch_main_set_state(RARCH_ACTION_STATE_LOAD_CONTENT); } break; case EVENT_CMD_UNLOAD_CORE: event_command(EVENT_CMD_PREPARE_DUMMY); event_command(EVENT_CMD_LOAD_CORE_DEINIT); break; case EVENT_CMD_QUIT: rarch_main_set_state(RARCH_ACTION_STATE_QUIT); break; case EVENT_CMD_REINIT: { const struct retro_hw_render_callback *hw_render = (const struct retro_hw_render_callback*)video_driver_callback(); driver->video_cache_context = hw_render->cache_context; driver->video_cache_context_ack = false; event_command(EVENT_CMD_RESET_CONTEXT); driver->video_cache_context = false; /* Poll input to avoid possibly stale data to corrupt things. */ input_driver_poll(); #ifdef HAVE_MENU menu_display_fb_set_dirty(); if (menu_driver_alive()) event_command(EVENT_CMD_VIDEO_SET_BLOCKING_STATE); #endif } break; case EVENT_CMD_CHEATS_DEINIT: if (!global) break; if (global->cheat) cheat_manager_free(global->cheat); global->cheat = NULL; break; case EVENT_CMD_CHEATS_INIT: event_command(EVENT_CMD_CHEATS_DEINIT); event_init_cheats(); break; case EVENT_CMD_REMAPPING_DEINIT: break; case EVENT_CMD_REMAPPING_INIT: event_command(EVENT_CMD_REMAPPING_DEINIT); event_init_remapping(); break; case EVENT_CMD_REWIND_DEINIT: if (!global) break; #ifdef HAVE_NETPLAY if (driver->netplay_data) return false; #endif if (global->rewind.state) state_manager_free(global->rewind.state); global->rewind.state = NULL; break; case EVENT_CMD_REWIND_INIT: init_rewind(); break; case EVENT_CMD_REWIND_TOGGLE: if (settings->rewind_enable) event_command(EVENT_CMD_REWIND_INIT); else event_command(EVENT_CMD_REWIND_DEINIT); break; case EVENT_CMD_AUTOSAVE_DEINIT: #ifdef HAVE_THREADS event_deinit_autosave(); #endif break; case EVENT_CMD_AUTOSAVE_INIT: event_command(EVENT_CMD_AUTOSAVE_DEINIT); #ifdef HAVE_THREADS event_init_autosave(); #endif break; case EVENT_CMD_AUTOSAVE_STATE: event_save_auto_state(); break; case EVENT_CMD_AUDIO_STOP: if (!driver->audio_data) return false; if (!audio_driver_alive()) return false; if (!audio_driver_stop()) return false; break; case EVENT_CMD_AUDIO_START: if (!driver->audio_data || audio_driver_alive()) return false; if (!settings->audio.mute_enable && !audio_driver_start()) { RARCH_ERR("Failed to start audio driver. Will continue without audio.\n"); driver->audio_active = false; } break; case EVENT_CMD_AUDIO_MUTE_TOGGLE: { const char *msg = !settings->audio.mute_enable ? msg_hash_to_str(MSG_AUDIO_MUTED): msg_hash_to_str(MSG_AUDIO_UNMUTED); if (!audio_driver_mute_toggle()) { RARCH_ERR("%s.\n", msg_hash_to_str(MSG_FAILED_TO_UNMUTE_AUDIO)); return false; } rarch_main_msg_queue_push(msg, 1, 180, true); RARCH_LOG("%s\n", msg); } break; case EVENT_CMD_OVERLAY_DEINIT: #ifdef HAVE_OVERLAY if (driver->overlay) input_overlay_free(driver->overlay); driver->overlay = NULL; memset(&driver->overlay_state, 0, sizeof(driver->overlay_state)); #endif break; case EVENT_CMD_OVERLAY_INIT: event_command(EVENT_CMD_OVERLAY_DEINIT); #ifdef HAVE_OVERLAY if (driver->osk_enable) { if (!*settings->osk.overlay) break; } else { if (!*settings->input.overlay) break; } driver->overlay = input_overlay_new( driver->osk_enable ? settings->osk.overlay : settings->input.overlay, driver->osk_enable ? settings->osk.enable : settings->input.overlay_enable, settings->input.overlay_opacity, settings->input.overlay_scale); if (!driver->overlay) RARCH_ERR("%s.\n", msg_hash_to_str(MSG_FAILED_TO_LOAD_OVERLAY)); #endif break; case EVENT_CMD_OVERLAY_NEXT: #ifdef HAVE_OVERLAY input_overlay_next(driver->overlay, settings->input.overlay_opacity); #endif break; case EVENT_CMD_DSP_FILTER_DEINIT: if (!global) break; audio_driver_dsp_filter_free(); break; case EVENT_CMD_DSP_FILTER_INIT: event_command(EVENT_CMD_DSP_FILTER_DEINIT); if (!*settings->audio.dsp_plugin) break; audio_driver_dsp_filter_init(settings->audio.dsp_plugin); break; case EVENT_CMD_GPU_RECORD_DEINIT: if (!global) break; if (global->record.gpu_buffer) free(global->record.gpu_buffer); global->record.gpu_buffer = NULL; break; case EVENT_CMD_RECORD_DEINIT: if (!recording_deinit()) return false; break; case EVENT_CMD_RECORD_INIT: event_command(EVENT_CMD_HISTORY_DEINIT); if (!recording_init()) return false; break; case EVENT_CMD_HISTORY_DEINIT: if (g_defaults.history) { content_playlist_write_file(g_defaults.history); content_playlist_free(g_defaults.history); } g_defaults.history = NULL; break; case EVENT_CMD_HISTORY_INIT: event_command(EVENT_CMD_HISTORY_DEINIT); if (!settings->history_list_enable) return false; RARCH_LOG("%s: [%s].\n", msg_hash_to_str(MSG_LOADING_HISTORY_FILE), settings->content_history_path); g_defaults.history = content_playlist_init( settings->content_history_path, settings->content_history_size); break; case EVENT_CMD_CORE_INFO_DEINIT: if (!global) break; if (global->core_info) core_info_list_free(global->core_info); global->core_info = NULL; break; case EVENT_CMD_DATA_RUNLOOP_FREE: rarch_main_data_free(); break; case EVENT_CMD_CORE_INFO_INIT: event_command(EVENT_CMD_CORE_INFO_DEINIT); if (*settings->libretro_directory) global->core_info = core_info_list_new(); break; case EVENT_CMD_CORE_DEINIT: { struct retro_hw_render_callback *cb = video_driver_callback(); event_deinit_core(true); if (cb) memset(cb, 0, sizeof(*cb)); break; } case EVENT_CMD_CORE_INIT: if (!event_init_core()) return false; break; case EVENT_CMD_VIDEO_APPLY_STATE_CHANGES: video_driver_apply_state_changes(); break; case EVENT_CMD_VIDEO_SET_NONBLOCKING_STATE: boolean = true; /* fall-through */ case EVENT_CMD_VIDEO_SET_BLOCKING_STATE: video_driver_set_nonblock_state(boolean); break; case EVENT_CMD_VIDEO_SET_ASPECT_RATIO: video_driver_set_aspect_ratio(settings->video.aspect_ratio_idx); break; case EVENT_CMD_AUDIO_SET_NONBLOCKING_STATE: boolean = true; /* fall-through */ case EVENT_CMD_AUDIO_SET_BLOCKING_STATE: audio_driver_set_nonblock_state(boolean); break; case EVENT_CMD_OVERLAY_SET_SCALE_FACTOR: #ifdef HAVE_OVERLAY input_overlay_set_scale_factor(driver->overlay, settings->input.overlay_scale); #endif break; case EVENT_CMD_OVERLAY_SET_ALPHA_MOD: #ifdef HAVE_OVERLAY input_overlay_set_alpha_mod(driver->overlay, settings->input.overlay_opacity); #endif break; case EVENT_CMD_DRIVERS_DEINIT: uninit_drivers(DRIVERS_CMD_ALL); break; case EVENT_CMD_DRIVERS_INIT: init_drivers(DRIVERS_CMD_ALL); break; case EVENT_CMD_AUDIO_REINIT: uninit_drivers(DRIVER_AUDIO); init_drivers(DRIVER_AUDIO); break; case EVENT_CMD_RESET_CONTEXT: event_command(EVENT_CMD_DRIVERS_DEINIT); event_command(EVENT_CMD_DRIVERS_INIT); break; case EVENT_CMD_QUIT_RETROARCH: rarch_main_set_state(RARCH_ACTION_STATE_FORCE_QUIT); break; case EVENT_CMD_RESUME: rarch_main_set_state(RARCH_ACTION_STATE_MENU_RUNNING_FINISHED); break; case EVENT_CMD_RESTART_RETROARCH: #if defined(GEKKO) && defined(HW_RVL) fill_pathname_join(global->fullpath, g_defaults.core_dir, SALAMANDER_FILE, sizeof(global->fullpath)); #endif if (driver->frontend_ctx && driver->frontend_ctx->set_fork) driver->frontend_ctx->set_fork(true, false); break; case EVENT_CMD_MENU_SAVE_CONFIG: if (!event_save_core_config()) return false; break; case EVENT_CMD_SHADERS_APPLY_CHANGES: #ifdef HAVE_MENU menu_shader_manager_apply_changes(); #endif break; case EVENT_CMD_PAUSE_CHECKS: if (runloop->is_paused) { RARCH_LOG("%s\n", msg_hash_to_str(MSG_PAUSED)); event_command(EVENT_CMD_AUDIO_STOP); if (settings->video.black_frame_insertion) video_driver_cached_frame(); } else { RARCH_LOG("%s\n", msg_hash_to_str(MSG_UNPAUSED)); event_command(EVENT_CMD_AUDIO_START); } break; case EVENT_CMD_PAUSE_TOGGLE: runloop->is_paused = !runloop->is_paused; event_command(EVENT_CMD_PAUSE_CHECKS); break; case EVENT_CMD_UNPAUSE: runloop->is_paused = false; event_command(EVENT_CMD_PAUSE_CHECKS); break; case EVENT_CMD_PAUSE: runloop->is_paused = true; event_command(EVENT_CMD_PAUSE_CHECKS); break; case EVENT_CMD_MENU_PAUSE_LIBRETRO: if (menu_driver_alive()) { if (settings->menu.pause_libretro) event_command(EVENT_CMD_AUDIO_STOP); else event_command(EVENT_CMD_AUDIO_START); } else { if (settings->menu.pause_libretro) event_command(EVENT_CMD_AUDIO_START); } break; case EVENT_CMD_SHADER_DIR_DEINIT: if (!global) break; dir_list_free(global->shader_dir.list); global->shader_dir.list = NULL; global->shader_dir.ptr = 0; break; case EVENT_CMD_SHADER_DIR_INIT: event_command(EVENT_CMD_SHADER_DIR_DEINIT); if (!*settings->video.shader_dir) return false; global->shader_dir.list = dir_list_new_special(NULL, DIR_LIST_SHADERS); if (!global->shader_dir.list || global->shader_dir.list->size == 0) { event_command(EVENT_CMD_SHADER_DIR_DEINIT); return false; } global->shader_dir.ptr = 0; dir_list_sort(global->shader_dir.list, false); for (i = 0; i < global->shader_dir.list->size; i++) RARCH_LOG("%s \"%s\"\n", msg_hash_to_str(MSG_FOUND_SHADER), global->shader_dir.list->elems[i].data); break; case EVENT_CMD_SAVEFILES: event_save_files(); break; case EVENT_CMD_SAVEFILES_DEINIT: if (!global) break; if (global->savefiles) string_list_free(global->savefiles); global->savefiles = NULL; break; case EVENT_CMD_SAVEFILES_INIT: global->use_sram = global->use_sram && !global->sram_save_disable #ifdef HAVE_NETPLAY && (!driver->netplay_data || !global->netplay_is_client) #endif ; if (!global->use_sram) RARCH_LOG("%s\n", msg_hash_to_str(MSG_SRAM_WILL_NOT_BE_SAVED)); if (global->use_sram) event_command(EVENT_CMD_AUTOSAVE_INIT); break; case EVENT_CMD_MSG_QUEUE_DEINIT: rarch_main_msg_queue_free(); break; case EVENT_CMD_MSG_QUEUE_INIT: event_command(EVENT_CMD_MSG_QUEUE_DEINIT); rarch_main_msg_queue_init(); rarch_main_data_init_queues(); break; case EVENT_CMD_BSV_MOVIE_DEINIT: if (!global) break; if (global->bsv.movie) bsv_movie_free(global->bsv.movie); global->bsv.movie = NULL; break; case EVENT_CMD_BSV_MOVIE_INIT: event_command(EVENT_CMD_BSV_MOVIE_DEINIT); event_init_movie(); break; case EVENT_CMD_NETPLAY_DEINIT: #ifdef HAVE_NETPLAY deinit_netplay(); #endif break; case EVENT_CMD_NETWORK_DEINIT: #ifdef HAVE_NETWORKING network_deinit(); #endif break; case EVENT_CMD_NETWORK_INIT: #ifdef HAVE_NETWORKING network_init(); #endif break; case EVENT_CMD_NETPLAY_INIT: event_command(EVENT_CMD_NETPLAY_DEINIT); #ifdef HAVE_NETPLAY if (!init_netplay()) return false; #endif break; case EVENT_CMD_NETPLAY_FLIP_PLAYERS: #ifdef HAVE_NETPLAY { netplay_t *netplay = (netplay_t*)driver->netplay_data; if (!netplay) return false; netplay_flip_users(netplay); } #endif break; case EVENT_CMD_FULLSCREEN_TOGGLE: if (!video_driver_has_windowed()) return false; /* If we go fullscreen we drop all drivers and * reinitialize to be safe. */ settings->video.fullscreen = !settings->video.fullscreen; event_command(EVENT_CMD_REINIT); break; case EVENT_CMD_COMMAND_DEINIT: #ifdef HAVE_COMMAND if (driver->command) rarch_cmd_free(driver->command); driver->command = NULL; #endif break; case EVENT_CMD_COMMAND_INIT: event_command(EVENT_CMD_COMMAND_DEINIT); #ifdef HAVE_COMMAND event_init_command(); #endif break; case EVENT_CMD_TEMPORARY_CONTENT_DEINIT: if (!global) break; if (global->temporary_content) event_free_temporary_content(); global->temporary_content = NULL; break; case EVENT_CMD_SUBSYSTEM_FULLPATHS_DEINIT: if (!global) break; if (global->subsystem_fullpaths) string_list_free(global->subsystem_fullpaths); global->subsystem_fullpaths = NULL; break; case EVENT_CMD_LOG_FILE_DEINIT: if (!global) break; if (global->log_file && global->log_file != stderr) fclose(global->log_file); global->log_file = NULL; break; case EVENT_CMD_DISK_EJECT_TOGGLE: if (system && system->disk_control.get_num_images) { const struct retro_disk_control_callback *control = (const struct retro_disk_control_callback*) &system->disk_control; if (control) event_check_disk_eject(control); } else rarch_main_msg_queue_push_new( MSG_CORE_DOES_NOT_SUPPORT_DISK_OPTIONS, 1, 120, true); break; case EVENT_CMD_DISK_NEXT: if (system && system->disk_control.get_num_images) { const struct retro_disk_control_callback *control = (const struct retro_disk_control_callback*) &system->disk_control; if (!control) return false; if (!control->get_eject_state()) return false; event_check_disk_next(control); } else rarch_main_msg_queue_push_new( MSG_CORE_DOES_NOT_SUPPORT_DISK_OPTIONS, 1, 120, true); break; case EVENT_CMD_DISK_PREV: if (system && system->disk_control.get_num_images) { const struct retro_disk_control_callback *control = (const struct retro_disk_control_callback*) &system->disk_control; if (!control) return false; if (!control->get_eject_state()) return false; event_check_disk_prev(control); } else rarch_main_msg_queue_push_new( MSG_CORE_DOES_NOT_SUPPORT_DISK_OPTIONS, 1, 120, true); break; case EVENT_CMD_RUMBLE_STOP: for (i = 0; i < MAX_USERS; i++) { input_driver_set_rumble_state(i, RETRO_RUMBLE_STRONG, 0); input_driver_set_rumble_state(i, RETRO_RUMBLE_WEAK, 0); } break; case EVENT_CMD_GRAB_MOUSE_TOGGLE: { static bool grab_mouse_state = false; grab_mouse_state = !grab_mouse_state; if (!driver->input || !input_driver_grab_mouse(grab_mouse_state)) return false; RARCH_LOG("%s: %s.\n", msg_hash_to_str(MSG_GRAB_MOUSE_STATE), grab_mouse_state ? "yes" : "no"); video_driver_show_mouse(!grab_mouse_state); } break; case EVENT_CMD_PERFCNT_REPORT_FRONTEND_LOG: rarch_perf_log(); break; case EVENT_CMD_VOLUME_UP: event_set_volume(0.5f); break; case EVENT_CMD_VOLUME_DOWN: event_set_volume(-0.5f); break; case EVENT_CMD_NONE: default: return false; } return true; }
static gint64 repo_share_usage (const char *user, const char *repo_id) { GHashTable *user_hash; int dummy; GList *personal = NULL, *groups = NULL, *members = NULL, *p; SearpcClient *client = NULL; gint64 usage = -1; /* seaf_debug ("Computing share usage for repo %s.\n", repo_id); */ /* If a repo is shared to both a user and a group, and that user is also * a member of the group, we don't want to count that user twice. * This also applies to two groups with overlapped members. * So we have to use a hash table to filter out duplicated users. */ user_hash = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, NULL); /* First count personal share */ personal = seaf_share_manager_list_shared_to (seaf->share_mgr, user, repo_id); for (p = personal; p; p = p->next) { char *email = p->data; g_hash_table_insert (user_hash, g_strdup(email), &dummy); /* seaf_debug ("Shared to %s.\n", email); */ } /* Then groups... */ client = ccnet_create_pooled_rpc_client (seaf->client_pool, NULL, "ccnet-threaded-rpcserver"); if (!client) { seaf_warning ("Failed to alloc rpc client.\n"); goto out; } groups = seaf_repo_manager_get_groups_by_repo (seaf->repo_mgr, repo_id, NULL); for (p = groups; p; p = p->next) { members = ccnet_get_group_members (client, (int)p->data); if (!members) { seaf_warning ("Cannot get member list for groupd %d.\n", (int)p->data); goto out; } count_group_members (user_hash, members); } /* Remove myself if i'm in a group. */ g_hash_table_remove (user_hash, user); guint n_shared_to = g_hash_table_size(user_hash); /* seaf_debug ("n_shared_to = %u.\n", n_shared_to); */ if (n_shared_to == 0) { usage = 0; goto out; } gint64 size = seaf_repo_manager_get_repo_size (seaf->repo_mgr, repo_id); if (size < 0) { seaf_warning ("Cannot get size of repo %s.\n", repo_id); goto out; } /* share_usage = repo_size * n_shared_to */ usage = size * n_shared_to; out: g_hash_table_destroy (user_hash); string_list_free (personal); g_list_free (groups); ccnet_rpc_client_free (client); return usage; }
/** * Execute the command READCSS to read a CSS file * * @param nerr * Error Return Flag * - 0 on Success * * @date 970403: New option to conveniently select the channel. * @date 970206: New option to specify which magnitude to read. maf * @date 961216: Now filtering on station rather than gain. maf * @date 920420: Changed null string, "", to ' ' - porting to IBM. * @date 910703: add # to parameter keyword GAIN; * add * as a legal value for params GAIN, BAND, ORIENT * @date 910402: New code. * */ void xrcss(int *nerr) { char _c0[2]; char file[MCMSG+1]; int len; int lmore, lshift, lscale, larray ; int nchar; static int Verbose = 0; static int ibinORasc; static string_list *last_list = NULL; double memory_max; memory_max = 0.30; char kmag[4] ; /* magnitude type: mb, ms, or ml. maf 970206 */ string_list *list; if(!last_list) { last_list = string_list_init(); } *nerr = 0; list = string_list_init(); /* PARSING PHASE: */ /* - Parse position-dependent tokens: */ lmore = FALSE; while ( lcmore( nerr ) ){ /* -- "MORE": signifies addition of more files to current read * filelist rather than replacement of current list with new one */ if( lckey( "MORE#$",7 ) && cmdfm.ndfl > 0 ){ lmore = TRUE; continue ; } /* -- "VERBOSE ON|OFF": turn Verbose mode on or off. */ else if( lklog( "VER$BOSE",9, &Verbose ) ){ continue ; } /* -- "SHIFT ON|OFF": turn calibration on or off. */ else if( lklog( "SHIFT$",7, &lshift ) ){ cmdfm.lshift = lshift ; continue ; } /* -- "SCALE ON|OFF": turn scaling on or off. */ else if( lklog( "SCALE$",7, &lscale ) ){ cmdfm.lscale = lscale ; continue ; } /* -- "ARRAY ON|OFF": turn lienient array behavior on or off. */ else if ( lklog ( "ARRAY$" , 7 , &larray ) ) { cmdfm.larray = larray ; continue ; } /* -- "MAXMEM v": change maximum fractional memory used by SeisMgr*/ else if( lkreal( "MAX#MEM$",9, &memory_max ) ) { MaxMem = memory_max; } /* -- "DIR CURRENT|name": set the name of the default subdirectory*/ else if(lkchar("DIR#$",6,MCPFN,kmdfm.krdcssdir,MCPFN+1,&nchar)){ if( memcmp(kmdfm.krdcssdir,"CURRENT",7) == 0 || memcmp(kmdfm.krdcssdir ,"current",7) == 0 ){ cfmt( "ILLEGAL PARAM VALUE: current",30 ); cresp(); return ; } else if( kmdfm.krdcssdir[nchar - 1] != KDIRDL ){ _c0[0] = KDIRDL; _c0[1] = '\0'; subscpy( kmdfm.krdcssdir, nchar, -1, MCPFN, _c0 ); } continue; } /* -- "MAGNITUDE|mb|ms|ml|def": specify a field for magnitude, or if def is found, use the algorithm to determine which magnitude to read. maf 970206. */ else if ( lkchar ( "MAG#NITUDE$", 12 , 4 , kmag , 4 , &nchar ) ) { if ( kmag [ 0 ] == 'm' || kmag[ 0 ] == 'M' ) { if ( kmag [ 1 ] == 'b' || kmag [ 1 ] == 'B' ) cmdfm.nMagSpec = MbMag ; else if ( kmag [ 1 ] == 's' || kmag [ 1 ] == 'S' ) cmdfm.nMagSpec = MsMag ; else if ( kmag [ 1 ] == 'l' || kmag [ 1 ] == 'L' ) cmdfm.nMagSpec = MlMag ; else { cfmt( "ILLEGAL PARAM VALUE:",22 ); cresp(); return ; } } /* end if ( kmag [ 0 ] == 'm' ... ) */ else if ( strncmp ( kmag , "def" , 3 ) == 0 || strncmp ( kmag , "DEF" , 3 ) == 0 ) cmdfm.nMagSpec = Any ; else { cfmt( "ILLEGAL PARAM VALUE:",22 ); cresp(); return ; } } /* end if ( lkchar ( "MAG#NITUDE$", ... ) */ /* -- "STATION": whether wfdisc record fld 'sta' matches given */ /* string. maf 961216 */ else if( lklogc("STA#TION$",10,&kmdfm.lstation,kmdfm.kstation,7 ) ){ char *ptr ; ptr = strchr ( kmdfm.kstation , ' ' ) ; if ( ptr != NULL ) *ptr = '\0' ; continue; } /* -- "CHANNEL": whether wfdisc record fld 'chan' matches the * given string. maf 970403 */ else if( lklogc("CHAN#NEL$",10,&kmdfm.lchannel,kmdfm.kchannel,9 ) ){ char *ptr ; ptr = strchr ( kmdfm.kchannel , ' ' ) ; if ( ptr != NULL ) *ptr = '\0' ; //if( jcdflbeg > 0 && jcdflend == 0 ) // jcdflend = jcparmbeg - 1; continue; } /* -- "BANDWIDTH": whether wfdisc record fld 'chan' has a leading * letter which is S(short), M(medium), or L(long) */ else if( lklogc( "BAND#WIDTH$",12, &kmdfm.lbandw,kmdfm.kbandw,9 ) ){ //if( jcdflbeg > 0 && jcdflend == 0 ) //jcdflend = jcparmbeg - 1; continue; } /* end else if( lklogc( "BAND#WIDTH$" ... */ /* -- "ORIENTATION: whether wfdisc record fld 'chan' has a second * letter which is N(north), E(east), or Z(vertical) */ else if(lklogc("ORIENT#ATION$",14,&kmdfm.lorient,kmdfm.korient,9)){ //if( jcdflbeg > 0 && jcdflend == 0 ) //jcdflend = jcparmbeg - 1; continue; } /* end else if( lklogc( "ORIENT#ATION$" ... */ /* -- TRUST: whether or not to trust matching evids while moving data from SAC buffers to CSS buffers. */ else if( lklog( "TRUST#$",8, &cmdfm.ltrust ) ) { /* do nothing */ } /* -- "COMMIT|RECALLTRACE|ROLLBACK": how to treat existing data */ else if ( lckeyExact ( "COMMIT" , 7 ) ) cmdfm.icomORroll = COMMIT ; else if (lckeyExact ( "RECALLTRACE" , 12 ) ) cmdfm.icomORroll = RECALL ; else if ( lckeyExact ( "RECALL" , 7 ) ) cmdfm.icomORroll = RECALL ; else if ( lckeyExact ( "ROLLBACK" , 9 ) ) cmdfm.icomORroll = ROLLBACK ; /* -- "BINARY|ASCII": CSSB versus flat files */ else if( lclist( (char*)kmdfm.kbinORasc,9, 2, &ibinORasc ) ) { cmdfm.lrascii = ibinORasc - 1 ; } /* -- Else assume it to be beginning/continuing dfl, if not * recognized as above * Use kdflin as dummy buffer to skip a string */ else if(lcchar(MCMSG, file, MCMSG+1, &len)) { string_list_put(list, file, len); } } /* - The above loop is over when one of two conditions has been met: * (1) An error in parsing has occurred. In this case NERR is > 0 . * (2) All the tokens in the command have been successfully parsed. */ if( *nerr != 0 ) return ; if(string_list_length(list) <= 0) { string_list_extend(list, last_list); } /* EXECUTION PHASE: */ /* - Commit or rollback data according to lmore and cmdfm.icomORroll */ if ( lmore ) { alignFiles ( nerr ) ; if ( *nerr ) return ; cmdfm.nfilesFirst = cmdfm.ndfl ; } /* end if */ else { cmdfm.nreadflag = HIGH ; cmdfm.nfilesFirst = 0 ; } /* Copy Current List to Last_List */ string_list_clear(last_list); string_list_extend(last_list, list); /* - Expand the filelist and read the files into memory. * -- Parameter kstation, kband, korient are picked up in readcfl from * ../../inc/dfm */ readcfl( lmore, kmdfm.krdcssdir,MCPFN+1, list, Verbose, cmdfm.lrascii, MaxMem, nerr ); string_list_free(list); list = NULL; return; }
static bool input_autoconfigure_joypad_from_conf_dir( autoconfig_params_t *params) { size_t i; char path[PATH_MAX_LENGTH]; int ret = 0; int index = -1; int current_best = 0; config_file_t *conf = NULL; struct string_list *list = NULL; settings_t *settings = config_get_ptr(); if (!settings) return false; fill_pathname_join(path, settings->directory.autoconfig, settings->input.joypad_driver, sizeof(path)); list = dir_list_new_special(path, DIR_LIST_AUTOCONFIG, "cfg"); if (!list || !list->size) list = dir_list_new_special(settings->directory.autoconfig, DIR_LIST_AUTOCONFIG, "cfg"); if(!list) return false; RARCH_LOG("Autodetect: %d profiles found\n", list->size); for (i = 0; i < list->size; i++) { conf = config_file_new(list->elems[i].data); ret = input_try_autoconfigure_joypad_from_conf(conf, params); if(ret >= current_best) { index = i; current_best = ret; } config_file_free(conf); } if(index >= 0 && current_best > 0) { conf = config_file_new(list->elems[index].data); if (conf) { char conf_path[PATH_MAX_LENGTH]; config_get_config_path(conf, conf_path, sizeof(conf_path)); RARCH_LOG("Autodetect: selected configuration: %s\n", conf_path); input_autoconfigure_joypad_add(conf, params); config_file_free(conf); ret = 1; } } else ret = 0; string_list_free(list); if (ret == 0) return false; return true; }
void menu_cbs_init(void *data, menu_file_list_cbs_t *cbs, const char *path, const char *label, unsigned type, size_t idx) { char elem0[PATH_MAX_LENGTH]; char elem1[PATH_MAX_LENGTH]; const char *repr_label = NULL; struct string_list *str_list = NULL; const char *menu_label = NULL; int ret = 0; uint32_t label_hash = 0; uint32_t menu_label_hash = 0; file_list_t *list = (file_list_t*)data; if (!list) return; elem0[0] = '\0'; elem1[0] = '\0'; menu_entries_get_last_stack(NULL, &menu_label, NULL, NULL); if (label) str_list = string_split(label, "|"); if (str_list && str_list->size > 0) strlcpy(elem0, str_list->elems[0].data, sizeof(elem0)); if (str_list && str_list->size > 1) strlcpy(elem1, str_list->elems[1].data, sizeof(elem1)); if (!label || !menu_label) goto error; label_hash = menu_hash_calculate(label); menu_label_hash = menu_hash_calculate(menu_label); #ifdef DEBUG_LOG RARCH_LOG("\n"); #endif repr_label = (!string_is_empty(label)) ? label : path; ret = menu_cbs_init_bind_ok(cbs, path, label, type, idx, elem0, elem1, menu_label, label_hash, menu_label_hash); menu_cbs_init_log(repr_label, "OK", cbs->action_ok_ident); ret = menu_cbs_init_bind_cancel(cbs, path, label, type, idx, elem0, elem1, label_hash, menu_label_hash); menu_cbs_init_log(repr_label, "CANCEL", cbs->action_cancel_ident); ret = menu_cbs_init_bind_scan(cbs, path, label, type, idx, elem0, elem1, label_hash, menu_label_hash); menu_cbs_init_log(repr_label, "SCAN", cbs->action_scan_ident); ret = menu_cbs_init_bind_start(cbs, path, label, type, idx, elem0, elem1, label_hash, menu_label_hash); menu_cbs_init_log(repr_label, "START", cbs->action_start_ident); ret = menu_cbs_init_bind_select(cbs, path, label, type, idx, elem0, elem1, label_hash, menu_label_hash); menu_cbs_init_log(repr_label, "SELECT", cbs->action_select_ident); ret = menu_cbs_init_bind_info(cbs, path, label, type, idx, elem0, elem1, label_hash, menu_label_hash); menu_cbs_init_log(repr_label, "INFO", cbs->action_info_ident); ret = menu_cbs_init_bind_content_list_switch(cbs, path, label, type, idx, elem0, elem1, label_hash, menu_label_hash); menu_cbs_init_log(repr_label, "CONTENT SWITCH", cbs->action_content_list_switch_ident); ret = menu_cbs_init_bind_up(cbs, path, label, type, idx, elem0, elem1, label_hash, menu_label_hash); menu_cbs_init_log(repr_label, "UP", cbs->action_up_ident); ret = menu_cbs_init_bind_down(cbs, path, label, type, idx, elem0, elem1, label_hash, menu_label_hash); menu_cbs_init_log(repr_label, "DOWN", cbs->action_down_ident); ret = menu_cbs_init_bind_left(cbs, path, label, type, idx, elem0, elem1, menu_label, label_hash, menu_label_hash); menu_cbs_init_log(repr_label, "LEFT", cbs->action_left_ident); ret = menu_cbs_init_bind_right(cbs, path, label, type, idx, elem0, elem1, menu_label, label_hash, menu_label_hash); menu_cbs_init_log(repr_label, "RIGHT", cbs->action_right_ident); ret = menu_cbs_init_bind_deferred_push(cbs, path, label, type, idx, elem0, elem1, label_hash, menu_label_hash); menu_cbs_init_log(repr_label, "DEFERRED PUSH", cbs->action_deferred_push_ident); ret = menu_cbs_init_bind_refresh(cbs, path, label, type, idx, elem0, elem1, label_hash, menu_label_hash); menu_cbs_init_log(repr_label, "REFRESH", cbs->action_refresh_ident); ret = menu_cbs_init_bind_get_string_representation(cbs, path, label, type, idx, elem0, elem1, label_hash, menu_label_hash); menu_cbs_init_log(repr_label, "GET VALUE", cbs->action_get_value_ident); ret = menu_cbs_init_bind_title(cbs, path, label, type, idx, elem0, elem1, label_hash, menu_label_hash); menu_cbs_init_log(repr_label, "GET TITLE", cbs->action_get_title_ident); ret = menu_driver_bind_init(cbs, path, label, type, idx, elem0, elem1, label_hash, menu_label_hash); (void)ret; error: string_list_free(str_list); str_list = NULL; }
/* Takes a list of files and folders and adds them to the currently selected playlist. Folders will have their contents added recursively. */ void MainWindow::addFilesToPlaylist(QStringList files) { QStringList list; QString currentPlaylistPath; QListWidgetItem *currentItem = m_listWidget->currentItem(); QByteArray currentPlaylistArray; QScopedPointer<QProgressDialog> dialog(NULL); PlaylistEntryDialog *playlistDialog = playlistEntryDialog(); QHash<QString, QString> selectedCore; QHash<QString, QString> itemToAdd; QString selectedDatabase; QString selectedName; QString selectedPath; const char *currentPlaylistData = NULL; playlist_t *playlist = NULL; int i; /* Assume a blank list means we will manually enter in all fields. */ if (files.isEmpty()) { /* Make sure hash isn't blank, that would mean there's multiple entries to add at once. */ itemToAdd["label"] = ""; itemToAdd["path"] = ""; } else if (files.count() == 1) { QString path = files.at(0); QFileInfo info(path); if (info.isFile()) { itemToAdd["label"] = info.completeBaseName(); itemToAdd["path"] = path; } } if (currentItem) { currentPlaylistPath = currentItem->data(Qt::UserRole).toString(); if (!currentPlaylistPath.isEmpty()) { currentPlaylistArray = currentPlaylistPath.toUtf8(); currentPlaylistData = currentPlaylistArray.constData(); } } if (currentPlaylistPath == ALL_PLAYLISTS_TOKEN) { showMessageBox(msg_hash_to_str(MENU_ENUM_LABEL_VALUE_QT_CANNOT_ADD_TO_ALL_PLAYLISTS), MainWindow::MSGBOX_TYPE_ERROR, Qt::ApplicationModal, false); return; } /* a blank itemToAdd means there will be multiple */ if (!playlistDialog->showDialog(itemToAdd)) return; selectedName = m_playlistEntryDialog->getSelectedName(); selectedPath = m_playlistEntryDialog->getSelectedPath(); selectedCore = m_playlistEntryDialog->getSelectedCore(); selectedDatabase = m_playlistEntryDialog->getSelectedDatabase(); if (selectedDatabase.isEmpty()) selectedDatabase = QFileInfo(currentPlaylistPath).fileName(); else selectedDatabase += file_path_str(FILE_PATH_LPL_EXTENSION); dialog.reset(new QProgressDialog(msg_hash_to_str(MENU_ENUM_LABEL_VALUE_QT_GATHERING_LIST_OF_FILES), "Cancel", 0, 0, this)); dialog->setWindowModality(Qt::ApplicationModal); if (selectedName.isEmpty() || selectedPath.isEmpty() || selectedDatabase.isEmpty()) { showMessageBox(msg_hash_to_str(MENU_ENUM_LABEL_VALUE_QT_PLEASE_FILL_OUT_REQUIRED_FIELDS), MainWindow::MSGBOX_TYPE_ERROR, Qt::ApplicationModal, false); return; } if (files.isEmpty()) files.append(selectedPath); for (i = 0; i < files.count(); i++) { QString path(files.at(i)); QFileInfo fileInfo(path); if (dialog->wasCanceled()) return; if (i % 25 == 0) { /* Needed to update progress dialog while doing a lot of stuff on the main thread. */ qApp->processEvents(); } if (fileInfo.isDir()) { QDir dir(path); addDirectoryFilesToList(list, dir); continue; } if (fileInfo.isFile()) list.append(fileInfo.absoluteFilePath()); else if (files.count() == 1) { /* If adding a single file, tell user that it doesn't exist. */ showMessageBox(msg_hash_to_str(MENU_ENUM_LABEL_VALUE_QT_FILE_DOES_NOT_EXIST), MainWindow::MSGBOX_TYPE_ERROR, Qt::ApplicationModal, false); return; } } dialog->setLabelText(msg_hash_to_str(MENU_ENUM_LABEL_VALUE_QT_ADDING_FILES_TO_PLAYLIST)); dialog->setMaximum(list.count()); playlist = playlist_init(currentPlaylistData, COLLECTION_SIZE); for (i = 0; i < list.count(); i++) { QString fileName = list.at(i); QFileInfo fileInfo; QByteArray fileBaseNameArray; QByteArray pathArray; QByteArray corePathArray; QByteArray coreNameArray; QByteArray databaseArray; const char *pathData = NULL; const char *fileNameNoExten = NULL; const char *corePathData = NULL; const char *coreNameData = NULL; const char *databaseData = NULL; if (dialog->wasCanceled()) { playlist_free(playlist); return; } if (fileName.isEmpty()) continue; fileInfo = fileName; if (files.count() == 1 && list.count() == 1 && i == 0) { fileBaseNameArray = selectedName.toUtf8(); pathArray = QDir::toNativeSeparators(selectedPath).toUtf8(); } else { fileBaseNameArray = fileInfo.completeBaseName().toUtf8(); pathArray = QDir::toNativeSeparators(fileName).toUtf8(); } fileNameNoExten = fileBaseNameArray.constData(); /* a modal QProgressDialog calls processEvents() automatically in setValue() */ dialog->setValue(i + 1); pathData = pathArray.constData(); if (selectedCore.isEmpty()) { corePathData = "DETECT"; coreNameData = "DETECT"; } else { corePathArray = QDir::toNativeSeparators(selectedCore.value("core_path")).toUtf8(); coreNameArray = selectedCore.value("core_name").toUtf8(); corePathData = corePathArray.constData(); coreNameData = coreNameArray.constData(); } databaseArray = selectedDatabase.toUtf8(); databaseData = databaseArray.constData(); if (path_is_compressed_file(pathData)) { struct string_list *list = file_archive_get_file_list(pathData, NULL); if (list) { if (list->size == 1) { /* assume archives with one file should have that file loaded directly */ pathArray = QDir::toNativeSeparators(QString(pathData) + "#" + list->elems[0].data).toUtf8(); pathData = pathArray.constData(); } string_list_free(list); } } playlist_push(playlist, pathData, fileNameNoExten, corePathData, coreNameData, "00000000|crc", databaseData); } playlist_write_file(playlist); playlist_free(playlist); reloadPlaylists(); }
void MainWindow::onPlaylistWidgetContextMenuRequested(const QPoint&) { settings_t *settings = config_get_ptr(); QScopedPointer<QMenu> menu; QScopedPointer<QMenu> associateMenu; QScopedPointer<QMenu> hiddenPlaylistsMenu; QScopedPointer<QAction> hideAction; QScopedPointer<QAction> newPlaylistAction; QScopedPointer<QAction> deletePlaylistAction; QPointer<QAction> selectedAction; QPoint cursorPos = QCursor::pos(); QListWidgetItem *selectedItem = m_listWidget->itemAt(m_listWidget->viewport()->mapFromGlobal(cursorPos)); QDir playlistDir(settings->paths.directory_playlist); QString playlistDirAbsPath = playlistDir.absolutePath(); QString currentPlaylistDirPath; QString currentPlaylistPath; QString currentPlaylistFileName; QFile currentPlaylistFile; QByteArray currentPlaylistFileNameArray; QFileInfo currentPlaylistFileInfo; QMap<QString, const core_info_t*> coreList; core_info_list_t *core_info_list = NULL; union string_list_elem_attr attr = {0}; struct string_list *stnames = NULL; struct string_list *stcores = NULL; unsigned i = 0; int j = 0; size_t found = 0; const char *currentPlaylistFileNameData = NULL; char new_playlist_names[PATH_MAX_LENGTH]; char new_playlist_cores[PATH_MAX_LENGTH]; bool specialPlaylist = false; bool foundHiddenPlaylist = false; new_playlist_names[0] = new_playlist_cores[0] = '\0'; stnames = string_split(settings->arrays.playlist_names, ";"); stcores = string_split(settings->arrays.playlist_cores, ";"); if (selectedItem) { currentPlaylistPath = selectedItem->data(Qt::UserRole).toString(); currentPlaylistFile.setFileName(currentPlaylistPath); currentPlaylistFileInfo = QFileInfo(currentPlaylistPath); currentPlaylistFileName = currentPlaylistFileInfo.fileName(); currentPlaylistDirPath = currentPlaylistFileInfo.absoluteDir().absolutePath(); currentPlaylistFileNameArray.append(currentPlaylistFileName); currentPlaylistFileNameData = currentPlaylistFileNameArray.constData(); } menu.reset(new QMenu(this)); menu->setObjectName("menu"); hiddenPlaylistsMenu.reset(new QMenu(msg_hash_to_str(MENU_ENUM_LABEL_VALUE_QT_HIDDEN_PLAYLISTS), this)); newPlaylistAction.reset(new QAction(QString(msg_hash_to_str(MENU_ENUM_LABEL_VALUE_QT_NEW_PLAYLIST)) + "...", this)); hiddenPlaylistsMenu->setObjectName("hiddenPlaylistsMenu"); menu->addAction(newPlaylistAction.data()); if (currentPlaylistFile.exists()) { deletePlaylistAction.reset(new QAction(QString(msg_hash_to_str(MENU_ENUM_LABEL_VALUE_QT_DELETE_PLAYLIST)) + "...", this)); menu->addAction(deletePlaylistAction.data()); } if (selectedItem) { hideAction.reset(new QAction(msg_hash_to_str(MENU_ENUM_LABEL_VALUE_QT_HIDE), this)); menu->addAction(hideAction.data()); } for (j = 0; j < m_listWidget->count(); j++) { QListWidgetItem *item = m_listWidget->item(j); bool hidden = m_listWidget->isItemHidden(item); if (hidden) { QAction *action = hiddenPlaylistsMenu->addAction(item->text()); action->setProperty("row", j); action->setProperty("core_path", item->data(Qt::UserRole).toString()); foundHiddenPlaylist = true; } } if (!foundHiddenPlaylist) { QAction *action = hiddenPlaylistsMenu->addAction(msg_hash_to_str(MENU_ENUM_LABEL_VALUE_NONE)); action->setProperty("row", -1); } menu->addMenu(hiddenPlaylistsMenu.data()); if (currentPlaylistDirPath != playlistDirAbsPath) { /* special playlists like history etc. can't have an association */ specialPlaylist = true; } if (!specialPlaylist) { associateMenu.reset(new QMenu(msg_hash_to_str(MENU_ENUM_LABEL_VALUE_QT_ASSOCIATE_CORE), this)); associateMenu->setObjectName("associateMenu"); core_info_get_list(&core_info_list); for (i = 0; i < core_info_list->count && core_info_list->count > 0; i++) { const core_info_t *core = &core_info_list->list[i]; coreList[core->core_name] = core; } { QMapIterator<QString, const core_info_t*> coreListIterator(coreList); QVector<QHash<QString, QString> > cores; while (coreListIterator.hasNext()) { QString key; const core_info_t *core = NULL; QString name; QHash<QString, QString> hash; coreListIterator.next(); key = coreListIterator.key(); core = coreList.value(key); if (string_is_empty(core->core_name)) name = core->display_name; else name = core->core_name; if (name.isEmpty()) continue; hash["name"] = name; hash["core_path"] = core->path; cores.append(hash); } std::sort(cores.begin(), cores.end(), comp_hash_name_key_lower); for (j = 0; j < cores.count(); j++) { const QHash<QString, QString> &hash = cores.at(j); QAction *action = associateMenu->addAction(hash.value("name")); action->setProperty("core_path", hash.value("core_path")); } } menu->addMenu(associateMenu.data()); } selectedAction = menu->exec(cursorPos); if (!selectedAction) goto end; if (!specialPlaylist && selectedAction->parent() == associateMenu.data()) { found = string_list_find_elem(stnames, currentPlaylistFileNameData); if (found) string_list_set(stcores, static_cast<unsigned>(found - 1), selectedAction->property("core_path").toString().toUtf8().constData()); else { string_list_append(stnames, currentPlaylistFileNameData, attr); string_list_append(stcores, "DETECT", attr); found = string_list_find_elem(stnames, currentPlaylistFileNameData); if (found) string_list_set(stcores, static_cast<unsigned>(found - 1), selectedAction->property("core_path").toString().toUtf8().constData()); } string_list_join_concat(new_playlist_names, sizeof(new_playlist_names), stnames, ";"); string_list_join_concat(new_playlist_cores, sizeof(new_playlist_cores), stcores, ";"); strlcpy(settings->arrays.playlist_names, new_playlist_names, sizeof(settings->arrays.playlist_names)); strlcpy(settings->arrays.playlist_cores, new_playlist_cores, sizeof(settings->arrays.playlist_cores)); } else if (selectedItem && selectedAction == deletePlaylistAction.data()) { if (currentPlaylistFile.exists()) { if (showMessageBox(QString(msg_hash_to_str(MENU_ENUM_LABEL_VALUE_QT_CONFIRM_DELETE_PLAYLIST)).arg(selectedItem->text()), MainWindow::MSGBOX_TYPE_QUESTION_YESNO, Qt::ApplicationModal, false)) { if (currentPlaylistFile.remove()) reloadPlaylists(); else showMessageBox(msg_hash_to_str(MENU_ENUM_LABEL_VALUE_QT_COULD_NOT_DELETE_FILE), MainWindow::MSGBOX_TYPE_ERROR, Qt::ApplicationModal, false); } } } else if (selectedAction == newPlaylistAction.data()) { QString name = QInputDialog::getText(this, msg_hash_to_str(MENU_ENUM_LABEL_VALUE_QT_NEW_PLAYLIST), msg_hash_to_str(MENU_ENUM_LABEL_VALUE_QT_ENTER_NEW_PLAYLIST_NAME)); QString newPlaylistPath = playlistDirAbsPath + "/" + name + file_path_str(FILE_PATH_LPL_EXTENSION); QFile file(newPlaylistPath); if (file.open(QIODevice::WriteOnly)) file.close(); reloadPlaylists(); } else if (selectedItem && selectedAction == hideAction.data()) { int row = m_listWidget->row(selectedItem); if (row >= 0) { QStringList hiddenPlaylists = m_settings->value("hidden_playlists").toStringList(); if (!hiddenPlaylists.contains(currentPlaylistFileName)) { hiddenPlaylists.append(currentPlaylistFileName); m_settings->setValue("hidden_playlists", hiddenPlaylists); } m_listWidget->setRowHidden(row, true); } } else if (selectedAction->parent() == hiddenPlaylistsMenu.data()) { QVariant rowVariant = selectedAction->property("row"); if (rowVariant.isValid()) { QStringList hiddenPlaylists = m_settings->value("hidden_playlists").toStringList(); int row = rowVariant.toInt(); if (row >= 0) { QString playlistPath = selectedAction->property("core_path").toString(); QFileInfo playlistFileInfo(playlistPath); QString playlistFileName = playlistFileInfo.fileName(); if (hiddenPlaylists.contains(playlistFileName)) { hiddenPlaylists.removeOne(playlistFileName); m_settings->setValue("hidden_playlists", hiddenPlaylists); } m_listWidget->setRowHidden(row, false); } } } setCoreActions(); end: if (stnames) string_list_free(stnames); if (stcores) string_list_free(stcores); }
bool MainWindow::updateCurrentPlaylistEntry(const QHash<QString, QString> &contentHash) { QString playlistPath = getCurrentPlaylistPath(); QString path; QString label; QString corePath; QString coreName; QString dbName; QString crc32; QByteArray playlistPathArray; QByteArray pathArray; QByteArray labelArray; QByteArray corePathArray; QByteArray coreNameArray; QByteArray dbNameArray; QByteArray crc32Array; const char *playlistPathData = NULL; const char *pathData = NULL; const char *labelData = NULL; const char *corePathData = NULL; const char *coreNameData = NULL; const char *dbNameData = NULL; const char *crc32Data = NULL; playlist_t *playlist = NULL; unsigned index = 0; bool ok = false; if (playlistPath.isEmpty() || contentHash.isEmpty() || !contentHash.contains("index")) return false; index = contentHash.value("index").toUInt(&ok); if (!ok) return false; path = contentHash.value("path"); label = contentHash.value("label"); coreName = contentHash.value("core_name"); corePath = contentHash.value("core_path"); dbName = contentHash.value("db_name"); crc32 = contentHash.value("crc32"); if (path.isEmpty() || label.isEmpty() || coreName.isEmpty() || corePath.isEmpty() || dbName.isEmpty() || crc32.isEmpty() ) return false; playlistPathArray = playlistPath.toUtf8(); pathArray = QDir::toNativeSeparators(path).toUtf8(); labelArray = label.toUtf8(); coreNameArray = coreName.toUtf8(); corePathArray = QDir::toNativeSeparators(corePath).toUtf8(); dbNameArray = (dbName + file_path_str(FILE_PATH_LPL_EXTENSION)).toUtf8(); crc32Array = crc32.toUtf8(); playlistPathData = playlistPathArray.constData(); pathData = pathArray.constData(); labelData = labelArray.constData(); coreNameData = coreNameArray.constData(); corePathData = corePathArray.constData(); dbNameData = dbNameArray.constData(); crc32Data = crc32Array.constData(); if (path_is_compressed_file(pathData)) { struct string_list *list = file_archive_get_file_list(pathData, NULL); if (list) { if (list->size == 1) { /* assume archives with one file should have that file loaded directly */ pathArray = QDir::toNativeSeparators(QString(pathData) + "#" + list->elems[0].data).toUtf8(); pathData = pathArray.constData(); } string_list_free(list); } } playlist = playlist_init(playlistPathData, COLLECTION_SIZE); playlist_update(playlist, index, pathData, labelData, corePathData, coreNameData, crc32Data, dbNameData); playlist_write_file(playlist); playlist_free(playlist); reloadPlaylists(); return true; }
/** * content_file_load: * @special : subsystem of content to be loaded. Can be NULL. * content : * * Load content file (for libretro core). * * Returns : true if successful, otherwise false. **/ static bool content_file_load( struct retro_game_info *info, const struct string_list *content, content_information_ctx_t *content_ctx, char *error_string, const struct retro_subsystem_info *special ) { unsigned i; retro_ctx_load_content_info_t load_info; char msg[1024]; struct string_list *additional_path_allocs = string_list_new(); msg[0] = '\0'; if (!additional_path_allocs) return false; for (i = 0; i < content->size; i++) { int attr = content->elems[i].attr.i; const char *path = content->elems[i].data; bool need_fullpath = attr & 2; bool require_content = attr & 4; if (require_content && string_is_empty(path)) { snprintf(msg, sizeof(msg), "%s\n", msg_hash_to_str(MSG_ERROR_LIBRETRO_CORE_REQUIRES_CONTENT)); error_string = strdup(msg); goto error; } info[i].path = NULL; if (!string_is_empty(path)) info[i].path = path; if (!need_fullpath && !string_is_empty(path)) { /* Load the content into memory. */ ssize_t len = 0; if (!load_content_into_memory(i, path, (void**)&info[i].data, &len)) { snprintf(msg, sizeof(msg), "%s \"%s\".\n", msg_hash_to_str(MSG_COULD_NOT_READ_CONTENT_FILE), path); error_string = strdup(msg); goto error; } info[i].size = len; } else { RARCH_LOG("%s\n", msg_hash_to_str( MSG_CONTENT_LOADING_SKIPPED_IMPLEMENTATION_WILL_DO_IT)); #ifdef HAVE_COMPRESSION if ( !content_ctx->block_extract && need_fullpath && path_contains_compressed_file(path) && !load_content_from_compressed_archive( content_ctx, &info[i], i, additional_path_allocs, need_fullpath, path, error_string)) goto error; #endif } } load_info.content = content; load_info.special = special; load_info.info = info; if (!core_load_game(&load_info)) { snprintf(msg, sizeof(msg), "%s.\n", msg_hash_to_str(MSG_FAILED_TO_LOAD_CONTENT)); error_string = strdup(msg); goto error; } #ifdef HAVE_CHEEVOS if (!special) { const void *load_data = NULL; const char *path = content->elems[0].data; cheevos_set_cheats(); if (!string_is_empty(path)) load_data = info; cheevos_load(load_data); } #endif string_list_free(additional_path_allocs); return true; error: if (additional_path_allocs) string_list_free(additional_path_allocs); return false; }
struct string_list *string_list_new_special(enum string_list_type type, void *data, unsigned *len, size_t *list_size) { union string_list_elem_attr attr; unsigned i; core_info_list_t *core_info_list = NULL; const core_info_t *core_info = NULL; struct string_list *s = string_list_new(); if (!s || !len) goto error; attr.i = 0; *len = 0; switch (type) { case STRING_LIST_MENU_DRIVERS: #ifdef HAVE_MENU for (i = 0; menu_driver_find_handle(i); i++) { const char *opt = menu_driver_find_ident(i); *len += strlen(opt) + 1; string_list_append(s, opt, attr); } break; #endif case STRING_LIST_CAMERA_DRIVERS: #ifdef HAVE_CAMERA for (i = 0; camera_driver_find_handle(i); i++) { const char *opt = camera_driver_find_ident(i); *len += strlen(opt) + 1; string_list_append(s, opt, attr); } break; #endif case STRING_LIST_LOCATION_DRIVERS: #ifdef HAVE_LOCATION for (i = 0; location_driver_find_handle(i); i++) { const char *opt = location_driver_find_ident(i); *len += strlen(opt) + 1; string_list_append(options_l, opt, attr); } break; #endif case STRING_LIST_AUDIO_DRIVERS: for (i = 0; audio_driver_find_handle(i); i++) { const char *opt = audio_driver_find_ident(i); *len += strlen(opt) + 1; string_list_append(s, opt, attr); } break; case STRING_LIST_AUDIO_RESAMPLER_DRIVERS: for (i = 0; audio_resampler_driver_find_handle(i); i++) { const char *opt = audio_resampler_driver_find_ident(i); *len += strlen(opt) + 1; string_list_append(s, opt, attr); } break; case STRING_LIST_VIDEO_DRIVERS: for (i = 0; video_driver_find_handle(i); i++) { const char *opt = video_driver_find_ident(i); *len += strlen(opt) + 1; string_list_append(s, opt, attr); } break; case STRING_LIST_INPUT_DRIVERS: for (i = 0; input_driver_find_handle(i); i++) { const char *opt = input_driver_find_ident(i); *len += strlen(opt) + 1; string_list_append(s, opt, attr); } break; case STRING_LIST_INPUT_HID_DRIVERS: for (i = 0; hid_driver_find_handle(i); i++) { const char *opt = hid_driver_find_ident(i); *len += strlen(opt) + 1; string_list_append(s, opt, attr); } break; case STRING_LIST_INPUT_JOYPAD_DRIVERS: for (i = 0; joypad_driver_find_handle(i); i++) { const char *opt = joypad_driver_find_ident(i); *len += strlen(opt) + 1; string_list_append(s, opt, attr); } break; case STRING_LIST_RECORD_DRIVERS: for (i = 0; record_driver_find_handle(i); i++) { const char *opt = record_driver_find_ident(i); *len += strlen(opt) + 1; string_list_append(s, opt, attr); } break; case STRING_LIST_SUPPORTED_CORES_PATHS: core_info_get_list(&core_info_list); core_info_list_get_supported_cores(core_info_list, (const char*)data, &core_info, list_size); if (*list_size == 0) goto error; for (i = 0; i < *list_size; i++) { const char *opt = NULL; const core_info_t *info = (const core_info_t*)&core_info[i]; opt = info ? info->path : NULL; if (!opt) goto error; *len += strlen(opt) + 1; string_list_append(s, opt, attr); } break; case STRING_LIST_SUPPORTED_CORES_NAMES: core_info_get_list(&core_info_list); core_info_list_get_supported_cores(core_info_list, (const char*)data, &core_info, list_size); if (*list_size == 0) goto error; for (i = 0; i < *list_size; i++) { const core_info_t *info = (const core_info_t*)&core_info[i]; const char *opt = info->display_name; if (!opt) goto error; *len += strlen(opt) + 1; string_list_append(s, opt, attr); } break; case STRING_LIST_NONE: default: goto error; } return s; error: string_list_free(s); s = NULL; return NULL; }
static void menu_action_setting_disp_set_label(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) { uint32_t hash_label = menu_hash_calculate(label); *s = '\0'; *w = 19; switch (hash_label) { case MENU_LABEL_LOAD_CONTENT_HISTORY: *w = strlen(label); break; case MENU_LABEL_SYSTEM_INFORMATION: *w = 2; break; case MENU_LABEL_DEBUG_INFORMATION: *w = 2; break; case MENU_LABEL_ACHIEVEMENT_LIST: *w = 2; break; } if (type >= MENU_SETTINGS_PLAYLIST_ASSOCIATION_START) { char playlist_name_with_ext[PATH_MAX_LENGTH]; unsigned i; bool found_matching_core_association = false; settings_t *settings = config_get_ptr(); struct string_list *str_list = string_split(settings->playlist_names, ";"); struct string_list *str_list2 = string_split(settings->playlist_cores, ";"); strlcpy(playlist_name_with_ext, path, sizeof(playlist_name_with_ext)); strlcat(playlist_name_with_ext, ".lpl", sizeof(playlist_name_with_ext)); for (i = 0; i < str_list->size; i++) { if (string_is_equal(str_list->elems[i].data, playlist_name_with_ext)) { if (str_list->size != str_list2->size) break; if (str_list2->elems[i].data == NULL) break; found_matching_core_association = true; strlcpy(s, str_list2->elems[i].data, len); } } string_list_free(str_list); string_list_free(str_list2); if (string_is_equal(s, "DETECT") || !found_matching_core_association) strlcpy(s, "N/A", len); else { char buf[PATH_MAX_LENGTH]; core_info_list_t *list = NULL; core_info_ctl(CORE_INFO_CTL_LIST_GET, &list); if (core_info_list_get_display_name(list, s, buf, sizeof(buf))) strlcpy(s, buf, len); } } else if (type >= MENU_SETTINGS_CORE_OPTION_START) { core_option_manager_t *coreopts = NULL; const char *core_opt = NULL; if (runloop_ctl(RUNLOOP_CTL_COREOPTS_GET, &coreopts)) { core_opt = core_option_get_val(coreopts, type - MENU_SETTINGS_CORE_OPTION_START); strlcpy(s, "", len); if (core_opt) strlcpy(s, core_opt, len); } } else menu_setting_get_label(list, s, len, w, type, label, entry_label, i); strlcpy(s2, path, len2); }
static bool load_content(const struct retro_subsystem_info *special, const struct string_list *content) { unsigned i; bool ret = true; struct string_list* additional_path_allocs = string_list_new(); struct retro_game_info *info = (struct retro_game_info*) calloc(content->size, sizeof(*info)); if (!info) return false; for (i = 0; i < content->size; i++) { const char *path = content->elems[i].data; int attr = content->elems[i].attr.i; bool need_fullpath = attr & 2; bool require_content = attr & 4; if (require_content && !*path) { RARCH_LOG("libretro core requires content, but nothing was provided.\n"); ret = false; goto end; } info[i].path = *path ? path : NULL; if (!need_fullpath && *path) { /* Load the content into memory. */ RARCH_LOG("Loading content file: %s.\n", path); /* First content file is significant, attempt to do patching, * CRC checking, etc. */ long size = i == 0 ? read_content_file(path, (void**)&info[i].data) : read_file(path, (void**)&info[i].data); if (size < 0) { RARCH_ERR("Could not read content file \"%s\".\n", path); ret = false; goto end; } info[i].size = size; } else { RARCH_LOG("Content loading skipped. Implementation will" " load it on its own.\n"); if (need_fullpath && path_contains_compressed_file(path)) { RARCH_LOG("Compressed file in case of need_fullpath." "Now extracting to temporary directory.\n"); if ((!strcmp(g_settings.extraction_directory,"")) || !path_is_directory(g_settings.extraction_directory)) { RARCH_ERR("Tried extracting to extraction directory, but " "extraction directory was not set or found. Exiting.\n"); rarch_assert(false); } char new_path[PATH_MAX]; union string_list_elem_attr attr; attr.i = 0; fill_pathname_join(new_path,g_settings.extraction_directory, path_basename(path),sizeof(new_path)); read_compressed_file(path,NULL,new_path); string_list_append(additional_path_allocs,new_path,attr); info[i].path = additional_path_allocs->elems [additional_path_allocs->size -1 ].data; /* g_extern.temporary_content is initialized in init_content_file * The following part takes care of cleanup of the unzipped files * after exit. */ rarch_assert(g_extern.temporary_content != NULL); string_list_append(g_extern.temporary_content, new_path, attr); } } } if (special) ret = pretro_load_game_special(special->id, info, content->size); else ret = pretro_load_game(*content->elems[0].data ? info : NULL); if (!ret) RARCH_ERR("Failed to load game.\n"); end: for (i = 0; i < content->size; i++) free((void*)info[i].data); string_list_free(additional_path_allocs); free(info); return ret; }
/** * event_cmd_ctl: * @cmd : Event command index. * * Performs program event command with index @cmd. * * Returns: true (1) on success, otherwise false (0). **/ bool event_cmd_ctl(enum event_command cmd, void *data) { unsigned i = 0; bool boolean = false; settings_t *settings = config_get_ptr(); rarch_system_info_t *info = NULL; runloop_ctl(RUNLOOP_CTL_SYSTEM_INFO_GET, &info); (void)i; switch (cmd) { case EVENT_CMD_MENU_REFRESH: #ifdef HAVE_MENU menu_driver_ctl(RARCH_MENU_CTL_REFRESH, NULL); #endif break; case EVENT_CMD_SET_PER_GAME_RESOLUTION: #if defined(GEKKO) { unsigned width = 0, height = 0; event_cmd_ctl(EVENT_CMD_VIDEO_SET_ASPECT_RATIO, NULL); if (video_driver_get_video_output_size(&width, &height)) { char msg[128] = {0}; video_driver_set_video_mode(width, height, true); if (width == 0 || height == 0) strlcpy(msg, "Resolution: DEFAULT", sizeof(msg)); else snprintf(msg, sizeof(msg),"Resolution: %dx%d",width, height); runloop_msg_queue_push(msg, 1, 100, true); } } #endif break; case EVENT_CMD_LOAD_CONTENT_PERSIST: #ifdef HAVE_DYNAMIC event_cmd_ctl(EVENT_CMD_LOAD_CORE, NULL); #endif rarch_ctl(RARCH_CTL_LOAD_CONTENT, NULL); break; #ifdef HAVE_FFMPEG case EVENT_CMD_LOAD_CONTENT_FFMPEG: rarch_ctl(RARCH_CTL_LOAD_CONTENT_FFMPEG, NULL); break; #endif case EVENT_CMD_LOAD_CONTENT_IMAGEVIEWER: rarch_ctl(RARCH_CTL_LOAD_CONTENT_IMAGEVIEWER, NULL); break; case EVENT_CMD_LOAD_CONTENT: { #ifdef HAVE_DYNAMIC event_cmd_ctl(EVENT_CMD_LOAD_CONTENT_PERSIST, NULL); #else char *fullpath = NULL; runloop_ctl(RUNLOOP_CTL_GET_CONTENT_PATH, &fullpath); runloop_ctl(RUNLOOP_CTL_SET_LIBRETRO_PATH, settings->path.libretro); event_cmd_ctl(EVENT_CMD_EXEC, (void*)fullpath); event_cmd_ctl(EVENT_CMD_QUIT, NULL); #endif } break; case EVENT_CMD_LOAD_CORE_DEINIT: #ifdef HAVE_MENU menu_driver_ctl(RARCH_MENU_CTL_SYSTEM_INFO_DEINIT, NULL); #endif break; case EVENT_CMD_LOAD_CORE_PERSIST: event_cmd_ctl(EVENT_CMD_LOAD_CORE_DEINIT, NULL); { #ifdef HAVE_MENU bool *ptr = NULL; struct retro_system_info *system = NULL; menu_driver_ctl(RARCH_MENU_CTL_SYSTEM_INFO_GET, &system); if (menu_driver_ctl(RARCH_MENU_CTL_LOAD_NO_CONTENT_GET, &ptr)) { core_info_ctx_find_t info_find; #if defined(HAVE_DYNAMIC) if (!(*settings->path.libretro)) return false; libretro_get_system_info( settings->path.libretro, system, ptr); #else libretro_get_system_info_static(system, ptr); #endif info_find.path = settings->path.libretro; if (!core_info_ctl(CORE_INFO_CTL_LOAD, &info_find)) return false; } #endif } break; case EVENT_CMD_LOAD_CORE: event_cmd_ctl(EVENT_CMD_LOAD_CORE_PERSIST, NULL); #ifndef HAVE_DYNAMIC event_cmd_ctl(EVENT_CMD_QUIT, NULL); #endif break; case EVENT_CMD_LOAD_STATE: /* Immutable - disallow savestate load when * we absolutely cannot change game state. */ if (bsv_movie_ctl(BSV_MOVIE_CTL_IS_INITED, NULL)) return false; #ifdef HAVE_NETPLAY if (netplay_driver_ctl(RARCH_NETPLAY_CTL_IS_DATA_INITED, NULL)) return false; #endif #ifdef HAVE_CHEEVOS if (settings->cheevos.hardcore_mode_enable) return false; #endif event_main_state(cmd); break; case EVENT_CMD_RESIZE_WINDOWED_SCALE: { unsigned idx = 0; unsigned *window_scale = NULL; runloop_ctl(RUNLOOP_CTL_GET_WINDOWED_SCALE, &window_scale); if (*window_scale == 0) return false; settings->video.scale = *window_scale; if (!settings->video.fullscreen) event_cmd_ctl(EVENT_CMD_REINIT, NULL); runloop_ctl(RUNLOOP_CTL_SET_WINDOWED_SCALE, &idx); } break; case EVENT_CMD_MENU_TOGGLE: #ifdef HAVE_MENU if (menu_driver_ctl(RARCH_MENU_CTL_IS_ALIVE, NULL)) rarch_ctl(RARCH_CTL_MENU_RUNNING_FINISHED, NULL); else rarch_ctl(RARCH_CTL_MENU_RUNNING, NULL); #endif break; case EVENT_CMD_CONTROLLERS_INIT: event_init_controllers(); break; case EVENT_CMD_RESET: RARCH_LOG("%s.\n", msg_hash_to_str(MSG_RESET)); runloop_msg_queue_push(msg_hash_to_str(MSG_RESET), 1, 120, true); #ifdef HAVE_CHEEVOS cheevos_ctl(CHEEVOS_CTL_SET_CHEATS, NULL); #endif core_ctl(CORE_CTL_RETRO_RESET, NULL); break; case EVENT_CMD_SAVE_STATE: #ifdef HAVE_CHEEVOS if (settings->cheevos.hardcore_mode_enable) return false; #endif if (settings->savestate_auto_index) settings->state_slot++; event_main_state(cmd); break; case EVENT_CMD_SAVE_STATE_DECREMENT: /* Slot -1 is (auto) slot. */ if (settings->state_slot >= 0) settings->state_slot--; break; case EVENT_CMD_SAVE_STATE_INCREMENT: settings->state_slot++; break; case EVENT_CMD_TAKE_SCREENSHOT: if (!take_screenshot()) return false; break; case EVENT_CMD_UNLOAD_CORE: runloop_ctl(RUNLOOP_CTL_PREPARE_DUMMY, NULL); event_cmd_ctl(EVENT_CMD_LOAD_CORE_DEINIT, NULL); break; case EVENT_CMD_QUIT: rarch_ctl(RARCH_CTL_QUIT, NULL); break; case EVENT_CMD_CHEEVOS_HARDCORE_MODE_TOGGLE: #ifdef HAVE_CHEEVOS cheevos_ctl(CHEEVOS_CTL_TOGGLE_HARDCORE_MODE, NULL); #endif break; case EVENT_CMD_REINIT: { struct retro_hw_render_callback *hwr = NULL; video_driver_ctl(RARCH_DISPLAY_CTL_HW_CONTEXT_GET, &hwr); if (hwr->cache_context) video_driver_ctl( RARCH_DISPLAY_CTL_SET_VIDEO_CACHE_CONTEXT, NULL); else video_driver_ctl( RARCH_DISPLAY_CTL_UNSET_VIDEO_CACHE_CONTEXT, NULL); video_driver_ctl( RARCH_DISPLAY_CTL_UNSET_VIDEO_CACHE_CONTEXT_ACK, NULL); event_cmd_ctl(EVENT_CMD_RESET_CONTEXT, NULL); video_driver_ctl( RARCH_DISPLAY_CTL_UNSET_VIDEO_CACHE_CONTEXT, NULL); /* Poll input to avoid possibly stale data to corrupt things. */ input_driver_ctl(RARCH_INPUT_CTL_POLL, NULL); #ifdef HAVE_MENU menu_display_ctl( MENU_DISPLAY_CTL_SET_FRAMEBUFFER_DIRTY_FLAG, NULL); if (menu_driver_ctl(RARCH_MENU_CTL_IS_ALIVE, NULL)) event_cmd_ctl(EVENT_CMD_VIDEO_SET_BLOCKING_STATE, NULL); #endif } break; case EVENT_CMD_CHEATS_DEINIT: cheat_manager_state_free(); break; case EVENT_CMD_CHEATS_INIT: event_cmd_ctl(EVENT_CMD_CHEATS_DEINIT, NULL); event_init_cheats(); break; case EVENT_CMD_CHEATS_APPLY: cheat_manager_apply_cheats(); break; case EVENT_CMD_REWIND_DEINIT: #ifdef HAVE_NETPLAY if (netplay_driver_ctl(RARCH_NETPLAY_CTL_IS_DATA_INITED, NULL)) return false; #endif #ifdef HAVE_CHEEVOS if (settings->cheevos.hardcore_mode_enable) return false; #endif state_manager_event_deinit(); break; case EVENT_CMD_REWIND_INIT: #ifdef HAVE_CHEEVOS if (settings->cheevos.hardcore_mode_enable) return false; #endif #ifdef HAVE_NETPLAY if (!netplay_driver_ctl(RARCH_NETPLAY_CTL_IS_DATA_INITED, NULL)) #endif init_rewind(); break; case EVENT_CMD_REWIND_TOGGLE: if (settings->rewind_enable) event_cmd_ctl(EVENT_CMD_REWIND_INIT, NULL); else event_cmd_ctl(EVENT_CMD_REWIND_DEINIT, NULL); break; case EVENT_CMD_AUTOSAVE_DEINIT: #ifdef HAVE_THREADS { global_t *global = global_get_ptr(); if (!global->sram.use) return false; autosave_event_deinit(); } #endif break; case EVENT_CMD_AUTOSAVE_INIT: event_cmd_ctl(EVENT_CMD_AUTOSAVE_DEINIT, NULL); #ifdef HAVE_THREADS autosave_event_init(); #endif break; case EVENT_CMD_AUTOSAVE_STATE: event_save_auto_state(); break; case EVENT_CMD_AUDIO_STOP: if (!audio_driver_ctl(RARCH_AUDIO_CTL_ALIVE, NULL)) return false; if (!audio_driver_ctl(RARCH_AUDIO_CTL_STOP, NULL)) return false; break; case EVENT_CMD_AUDIO_START: if (audio_driver_ctl(RARCH_AUDIO_CTL_ALIVE, NULL)) return false; if (!settings->audio.mute_enable && !audio_driver_ctl(RARCH_AUDIO_CTL_START, NULL)) { RARCH_ERR("Failed to start audio driver. " "Will continue without audio.\n"); audio_driver_ctl(RARCH_AUDIO_CTL_UNSET_ACTIVE, NULL); } break; case EVENT_CMD_AUDIO_MUTE_TOGGLE: { const char *msg = !settings->audio.mute_enable ? msg_hash_to_str(MSG_AUDIO_MUTED): msg_hash_to_str(MSG_AUDIO_UNMUTED); if (!audio_driver_ctl(RARCH_AUDIO_CTL_MUTE_TOGGLE, NULL)) { RARCH_ERR("%s.\n", msg_hash_to_str(MSG_FAILED_TO_UNMUTE_AUDIO)); return false; } runloop_msg_queue_push(msg, 1, 180, true); RARCH_LOG("%s\n", msg); } break; case EVENT_CMD_OVERLAY_DEINIT: #ifdef HAVE_OVERLAY input_overlay_free(); #endif break; case EVENT_CMD_OVERLAY_INIT: event_cmd_ctl(EVENT_CMD_OVERLAY_DEINIT, NULL); #ifdef HAVE_OVERLAY input_overlay_init(); #endif break; case EVENT_CMD_OVERLAY_NEXT: #ifdef HAVE_OVERLAY input_overlay_next(settings->input.overlay_opacity); #endif break; case EVENT_CMD_DSP_FILTER_DEINIT: audio_driver_dsp_filter_free(); break; case EVENT_CMD_DSP_FILTER_INIT: event_cmd_ctl(EVENT_CMD_DSP_FILTER_DEINIT, NULL); if (!*settings->path.audio_dsp_plugin) break; audio_driver_dsp_filter_init(settings->path.audio_dsp_plugin); break; case EVENT_CMD_GPU_RECORD_DEINIT: video_driver_ctl(RARCH_DISPLAY_CTL_GPU_RECORD_DEINIT, NULL); break; case EVENT_CMD_RECORD_DEINIT: if (!recording_deinit()) return false; break; case EVENT_CMD_RECORD_INIT: event_cmd_ctl(EVENT_CMD_HISTORY_DEINIT, NULL); if (!recording_init()) return false; break; case EVENT_CMD_HISTORY_DEINIT: if (g_defaults.history) { content_playlist_write_file(g_defaults.history); content_playlist_free(g_defaults.history); } g_defaults.history = NULL; break; case EVENT_CMD_HISTORY_INIT: event_cmd_ctl(EVENT_CMD_HISTORY_DEINIT, NULL); if (!settings->history_list_enable) return false; RARCH_LOG("%s: [%s].\n", msg_hash_to_str(MSG_LOADING_HISTORY_FILE), settings->path.content_history); g_defaults.history = content_playlist_init( settings->path.content_history, settings->content_history_size); break; case EVENT_CMD_CORE_INFO_DEINIT: core_info_ctl(CORE_INFO_CTL_LIST_DEINIT, NULL); break; case EVENT_CMD_CORE_INFO_INIT: event_cmd_ctl(EVENT_CMD_CORE_INFO_DEINIT, NULL); if (*settings->directory.libretro) core_info_ctl(CORE_INFO_CTL_LIST_INIT, NULL); break; case EVENT_CMD_CORE_DEINIT: { struct retro_hw_render_callback *hwr = NULL; video_driver_ctl(RARCH_DISPLAY_CTL_HW_CONTEXT_GET, &hwr); event_deinit_core(true); if (hwr) memset(hwr, 0, sizeof(*hwr)); break; } case EVENT_CMD_CORE_INIT: if (!event_init_core(data)) return false; break; case EVENT_CMD_VIDEO_APPLY_STATE_CHANGES: video_driver_ctl(RARCH_DISPLAY_CTL_APPLY_STATE_CHANGES, NULL); break; case EVENT_CMD_VIDEO_SET_NONBLOCKING_STATE: boolean = true; /* fall-through */ case EVENT_CMD_VIDEO_SET_BLOCKING_STATE: video_driver_ctl(RARCH_DISPLAY_CTL_SET_NONBLOCK_STATE, &boolean); break; case EVENT_CMD_VIDEO_SET_ASPECT_RATIO: video_driver_ctl(RARCH_DISPLAY_CTL_SET_ASPECT_RATIO, NULL); break; case EVENT_CMD_AUDIO_SET_NONBLOCKING_STATE: boolean = true; /* fall-through */ case EVENT_CMD_AUDIO_SET_BLOCKING_STATE: audio_driver_set_nonblocking_state(boolean); break; case EVENT_CMD_OVERLAY_SET_SCALE_FACTOR: #ifdef HAVE_OVERLAY input_overlay_set_scale_factor(settings->input.overlay_scale); #endif break; case EVENT_CMD_OVERLAY_SET_ALPHA_MOD: #ifdef HAVE_OVERLAY input_overlay_set_alpha_mod(settings->input.overlay_opacity); #endif break; case EVENT_CMD_AUDIO_REINIT: { int flags = DRIVER_AUDIO; driver_ctl(RARCH_DRIVER_CTL_UNINIT, &flags); driver_ctl(RARCH_DRIVER_CTL_INIT, &flags); } break; case EVENT_CMD_RESET_CONTEXT: { /* RARCH_DRIVER_CTL_UNINIT clears the callback struct so we * need to make sure to keep a copy */ struct retro_hw_render_callback *hwr = NULL; struct retro_hw_render_callback hwr_copy; int flags = DRIVERS_CMD_ALL; video_driver_ctl(RARCH_DISPLAY_CTL_HW_CONTEXT_GET, &hwr); memcpy(&hwr_copy, hwr, sizeof(hwr_copy)); driver_ctl(RARCH_DRIVER_CTL_UNINIT, &flags); memcpy(hwr, &hwr_copy, sizeof(*hwr)); driver_ctl(RARCH_DRIVER_CTL_INIT, &flags); } break; case EVENT_CMD_QUIT_RETROARCH: rarch_ctl(RARCH_CTL_FORCE_QUIT, NULL); break; case EVENT_CMD_SHUTDOWN: #if defined(__linux__) && !defined(ANDROID) runloop_msg_queue_push("Shutting down...", 1, 180, true); rarch_ctl(RARCH_CTL_FORCE_QUIT, NULL); system("shutdown -P now"); #endif break; case EVENT_CMD_REBOOT: #if defined(__linux__) && !defined(ANDROID) runloop_msg_queue_push("Rebooting...", 1, 180, true); rarch_ctl(RARCH_CTL_FORCE_QUIT, NULL); system("shutdown -r now"); #endif break; case EVENT_CMD_RESUME: rarch_ctl(RARCH_CTL_MENU_RUNNING_FINISHED, NULL); if (ui_companion_is_on_foreground()) ui_companion_driver_toggle(); break; case EVENT_CMD_RESTART_RETROARCH: if (!frontend_driver_set_fork(FRONTEND_FORK_RESTART)) return false; break; case EVENT_CMD_MENU_SAVE_CURRENT_CONFIG: event_save_current_config(); break; case EVENT_CMD_MENU_SAVE_CONFIG: if (!event_save_core_config()) return false; break; case EVENT_CMD_SHADERS_APPLY_CHANGES: #ifdef HAVE_MENU menu_shader_manager_apply_changes(); #endif break; case EVENT_CMD_PAUSE_CHECKS: if (runloop_ctl(RUNLOOP_CTL_IS_PAUSED, NULL)) { RARCH_LOG("%s\n", msg_hash_to_str(MSG_PAUSED)); event_cmd_ctl(EVENT_CMD_AUDIO_STOP, NULL); if (settings->video.black_frame_insertion) video_driver_ctl(RARCH_DISPLAY_CTL_CACHED_FRAME_RENDER, NULL); } else { RARCH_LOG("%s\n", msg_hash_to_str(MSG_UNPAUSED)); event_cmd_ctl(EVENT_CMD_AUDIO_START, NULL); } break; case EVENT_CMD_PAUSE_TOGGLE: boolean = runloop_ctl(RUNLOOP_CTL_IS_PAUSED, NULL); boolean = !boolean; runloop_ctl(RUNLOOP_CTL_SET_PAUSED, &boolean); event_cmd_ctl(EVENT_CMD_PAUSE_CHECKS, NULL); break; case EVENT_CMD_UNPAUSE: boolean = false; runloop_ctl(RUNLOOP_CTL_SET_PAUSED, &boolean); event_cmd_ctl(EVENT_CMD_PAUSE_CHECKS, NULL); break; case EVENT_CMD_PAUSE: boolean = true; runloop_ctl(RUNLOOP_CTL_SET_PAUSED, &boolean); event_cmd_ctl(EVENT_CMD_PAUSE_CHECKS, NULL); break; case EVENT_CMD_MENU_PAUSE_LIBRETRO: #ifdef HAVE_MENU if (menu_driver_ctl(RARCH_MENU_CTL_IS_ALIVE, NULL)) { if (settings->menu.pause_libretro) event_cmd_ctl(EVENT_CMD_AUDIO_STOP, NULL); else event_cmd_ctl(EVENT_CMD_AUDIO_START, NULL); } else { if (settings->menu.pause_libretro) event_cmd_ctl(EVENT_CMD_AUDIO_START, NULL); } #endif break; case EVENT_CMD_SHADER_DIR_DEINIT: runloop_ctl(RUNLOOP_CTL_SHADER_DIR_DEINIT, NULL); break; case EVENT_CMD_SHADER_DIR_INIT: event_cmd_ctl(EVENT_CMD_SHADER_DIR_DEINIT, NULL); if (!runloop_ctl(RUNLOOP_CTL_SHADER_DIR_INIT, NULL)) return false; break; case EVENT_CMD_SAVEFILES: { global_t *global = global_get_ptr(); if (!global->savefiles || !global->sram.use) return false; for (i = 0; i < global->savefiles->size; i++) { ram_type_t ram; ram.type = global->savefiles->elems[i].attr.i; ram.path = global->savefiles->elems[i].data; RARCH_LOG("%s #%u %s \"%s\".\n", msg_hash_to_str(MSG_SAVING_RAM_TYPE), ram.type, msg_hash_to_str(MSG_TO), ram.path); content_ctl(CONTENT_CTL_SAVE_RAM_FILE, &ram); } } return true; case EVENT_CMD_SAVEFILES_DEINIT: { global_t *global = global_get_ptr(); if (!global) break; if (global->savefiles) string_list_free(global->savefiles); global->savefiles = NULL; } break; case EVENT_CMD_SAVEFILES_INIT: { global_t *global = global_get_ptr(); global->sram.use = global->sram.use && !global->sram.save_disable; #ifdef HAVE_NETPLAY global->sram.use = global->sram.use && (!netplay_driver_ctl(RARCH_NETPLAY_CTL_IS_DATA_INITED, NULL) || !global->netplay.is_client); #endif if (!global->sram.use) RARCH_LOG("%s\n", msg_hash_to_str(MSG_SRAM_WILL_NOT_BE_SAVED)); if (global->sram.use) event_cmd_ctl(EVENT_CMD_AUTOSAVE_INIT, NULL); } break; case EVENT_CMD_BSV_MOVIE_DEINIT: bsv_movie_ctl(BSV_MOVIE_CTL_DEINIT, NULL); break; case EVENT_CMD_BSV_MOVIE_INIT: event_cmd_ctl(EVENT_CMD_BSV_MOVIE_DEINIT, NULL); bsv_movie_ctl(BSV_MOVIE_CTL_INIT, NULL); break; case EVENT_CMD_NETPLAY_DEINIT: #ifdef HAVE_NETPLAY deinit_netplay(); #endif break; case EVENT_CMD_NETWORK_DEINIT: #ifdef HAVE_NETWORKING network_deinit(); #endif break; case EVENT_CMD_NETWORK_INIT: #ifdef HAVE_NETWORKING network_init(); #endif break; case EVENT_CMD_NETPLAY_INIT: event_cmd_ctl(EVENT_CMD_NETPLAY_DEINIT, NULL); #ifdef HAVE_NETPLAY if (!init_netplay()) return false; #endif break; case EVENT_CMD_NETPLAY_FLIP_PLAYERS: #ifdef HAVE_NETPLAY netplay_driver_ctl(RARCH_NETPLAY_CTL_FLIP_PLAYERS, NULL); #endif break; case EVENT_CMD_FULLSCREEN_TOGGLE: if (!video_driver_ctl(RARCH_DISPLAY_CTL_HAS_WINDOWED, NULL)) return false; /* If we go fullscreen we drop all drivers and * reinitialize to be safe. */ settings->video.fullscreen = !settings->video.fullscreen; event_cmd_ctl(EVENT_CMD_REINIT, NULL); break; case EVENT_CMD_COMMAND_DEINIT: input_driver_ctl(RARCH_INPUT_CTL_COMMAND_DEINIT, NULL); break; case EVENT_CMD_COMMAND_INIT: event_cmd_ctl(EVENT_CMD_COMMAND_DEINIT, NULL); input_driver_ctl(RARCH_INPUT_CTL_COMMAND_INIT, NULL); break; case EVENT_CMD_REMOTE_DEINIT: input_driver_ctl(RARCH_INPUT_CTL_REMOTE_DEINIT, NULL); break; case EVENT_CMD_REMOTE_INIT: event_cmd_ctl(EVENT_CMD_REMOTE_DEINIT, NULL); input_driver_ctl(RARCH_INPUT_CTL_REMOTE_INIT, NULL); break; case EVENT_CMD_TEMPORARY_CONTENT_DEINIT: content_ctl(CONTENT_CTL_DEINIT, NULL); break; case EVENT_CMD_SUBSYSTEM_FULLPATHS_DEINIT: { global_t *global = global_get_ptr(); if (!global) break; if (global->subsystem_fullpaths) string_list_free(global->subsystem_fullpaths); global->subsystem_fullpaths = NULL; } break; case EVENT_CMD_LOG_FILE_DEINIT: retro_main_log_file_deinit(); break; case EVENT_CMD_DISK_APPEND_IMAGE: { const char *path = (const char*)data; if (string_is_empty(path)) return false; return event_disk_control_append_image(path); } case EVENT_CMD_DISK_EJECT_TOGGLE: if (info && info->disk_control_cb.get_num_images) { const struct retro_disk_control_callback *control = (const struct retro_disk_control_callback*) &info->disk_control_cb; if (control) { bool new_state = !control->get_eject_state(); event_disk_control_set_eject(new_state, true); } } else runloop_msg_queue_push( msg_hash_to_str(MSG_CORE_DOES_NOT_SUPPORT_DISK_OPTIONS), 1, 120, true); break; case EVENT_CMD_DISK_NEXT: if (info && info->disk_control_cb.get_num_images) { const struct retro_disk_control_callback *control = (const struct retro_disk_control_callback*) &info->disk_control_cb; if (!control) return false; if (!control->get_eject_state()) return false; event_check_disk_next(control); } else runloop_msg_queue_push( msg_hash_to_str(MSG_CORE_DOES_NOT_SUPPORT_DISK_OPTIONS), 1, 120, true); break; case EVENT_CMD_DISK_PREV: if (info && info->disk_control_cb.get_num_images) { const struct retro_disk_control_callback *control = (const struct retro_disk_control_callback*) &info->disk_control_cb; if (!control) return false; if (!control->get_eject_state()) return false; event_check_disk_prev(control); } else runloop_msg_queue_push( msg_hash_to_str(MSG_CORE_DOES_NOT_SUPPORT_DISK_OPTIONS), 1, 120, true); break; case EVENT_CMD_RUMBLE_STOP: for (i = 0; i < MAX_USERS; i++) { input_driver_set_rumble_state(i, RETRO_RUMBLE_STRONG, 0); input_driver_set_rumble_state(i, RETRO_RUMBLE_WEAK, 0); } break; case EVENT_CMD_GRAB_MOUSE_TOGGLE: { bool ret = false; static bool grab_mouse_state = false; grab_mouse_state = !grab_mouse_state; if (grab_mouse_state) ret = input_driver_ctl(RARCH_INPUT_CTL_GRAB_MOUSE, NULL); else ret = input_driver_ctl(RARCH_INPUT_CTL_UNGRAB_MOUSE, NULL); if (!ret) return false; RARCH_LOG("%s: %s.\n", msg_hash_to_str(MSG_GRAB_MOUSE_STATE), grab_mouse_state ? "yes" : "no"); if (grab_mouse_state) video_driver_ctl(RARCH_DISPLAY_CTL_HIDE_MOUSE, NULL); else video_driver_ctl(RARCH_DISPLAY_CTL_SHOW_MOUSE, NULL); } break; case EVENT_CMD_PERFCNT_REPORT_FRONTEND_LOG: rarch_perf_log(); break; case EVENT_CMD_VOLUME_UP: event_set_volume(0.5f); break; case EVENT_CMD_VOLUME_DOWN: event_set_volume(-0.5f); break; case EVENT_CMD_SET_FRAME_LIMIT: runloop_ctl(RUNLOOP_CTL_SET_FRAME_LIMIT, NULL); break; case EVENT_CMD_EXEC: return event_cmd_exec(data); case EVENT_CMD_NONE: default: return false; } return true; }
bool init_content_file(void) { unsigned i; g_extern.temporary_content = string_list_new(); if (!g_extern.temporary_content) return false; const struct retro_subsystem_info *special = NULL; if (*g_extern.subsystem) { special = libretro_find_subsystem_info(g_extern.system.special, g_extern.system.num_special, g_extern.subsystem); if (!special) { RARCH_ERR( "Failed to find subsystem \"%s\" in libretro implementation.\n", g_extern.subsystem); return false; } if (special->num_roms && !g_extern.subsystem_fullpaths) { RARCH_ERR("libretro core requires special content, but none were provided.\n"); return false; } else if (special->num_roms && special->num_roms != g_extern.subsystem_fullpaths->size) { RARCH_ERR("libretro core requires %u content files for subsystem \"%s\", but %u content files were provided.\n", special->num_roms, special->desc, (unsigned)g_extern.subsystem_fullpaths->size); return false; } else if (!special->num_roms && g_extern.subsystem_fullpaths && g_extern.subsystem_fullpaths->size) { RARCH_ERR("libretro core takes no content for subsystem \"%s\", but %u content files were provided.\n", special->desc, (unsigned)g_extern.subsystem_fullpaths->size); return false; } } union string_list_elem_attr attr; attr.i = 0; struct string_list *content = (struct string_list*)string_list_new(); if (!content) return false; if (*g_extern.subsystem) { for (i = 0; i < g_extern.subsystem_fullpaths->size; i++) { attr.i = special->roms[i].block_extract; attr.i |= special->roms[i].need_fullpath << 1; attr.i |= special->roms[i].required << 2; string_list_append(content, g_extern.subsystem_fullpaths->elems[i].data, attr); } } else { attr.i = g_extern.system.info.block_extract; attr.i |= g_extern.system.info.need_fullpath << 1; attr.i |= (!g_extern.system.no_content) << 2; string_list_append(content, g_extern.libretro_no_content ? "" : g_extern.fullpath, attr); } #ifdef HAVE_ZLIB /* Try to extract all content we're going to load if appropriate. */ for (i = 0; i < content->size; i++) { /* Block extract check. */ if (content->elems[i].attr.i & 1) continue; const char *ext = path_get_extension(content->elems[i].data); const char *valid_ext = special ? special->roms[i].valid_extensions : g_extern.system.info.valid_extensions; if (ext && !strcasecmp(ext, "zip")) { char temporary_content[PATH_MAX]; strlcpy(temporary_content, content->elems[i].data, sizeof(temporary_content)); if (!zlib_extract_first_content_file(temporary_content, sizeof(temporary_content), valid_ext, *g_settings.extraction_directory ? g_settings.extraction_directory : NULL)) { RARCH_ERR("Failed to extract content from zipped file: %s.\n", temporary_content); string_list_free(content); return false; } string_list_set(content, i, temporary_content); string_list_append(g_extern.temporary_content, temporary_content, attr); } } #endif /* Set attr to need_fullpath as appropriate. */ bool ret = load_content(special, content); string_list_free(content); return ret; }
static bool input_overlay_load_desc(config_file_t *conf, struct overlay_desc *desc, unsigned ol_index, unsigned desc_index, unsigned width, unsigned height) { bool ret = true; char overlay_desc_key[64]; snprintf(overlay_desc_key, sizeof(overlay_desc_key), "overlay%u_desc%u", ol_index, desc_index); char overlay[256]; if (!config_get_array(conf, overlay_desc_key, overlay, sizeof(overlay))) { RARCH_ERR("[Overlay]: Didn't find key: %s.\n", overlay_desc_key); return false; } struct string_list *list = string_split(overlay, ", "); if (!list) { RARCH_ERR("[Overlay]: Failed to split overlay desc.\n"); return false; } if (list->size < 6) { string_list_free(list); RARCH_ERR("[Overlay]: Overlay desc is invalid. Requires at least 6 tokens.\n"); return false; } const char *x = list->elems[1].data; const char *y = list->elems[2].data; const char *box = list->elems[3].data; char *key = list->elems[0].data; char *save; desc->key_mask = 0; for (const char *tmp = strtok_r(key, "|", &save); tmp; tmp = strtok_r(NULL, "|", &save)) desc->key_mask |= UINT64_C(1) << input_str_to_bind(tmp); desc->x = strtod(x, NULL) / width; desc->y = strtod(y, NULL) / height; if (!strcmp(box, "radial")) desc->hitbox = OVERLAY_HITBOX_RADIAL; else if (!strcmp(box, "rect")) desc->hitbox = OVERLAY_HITBOX_RECT; else { RARCH_ERR("[Overlay]: Hitbox type (%s) is invalid. Use \"radial\" or \"rect\".\n", box); ret = false; goto end; } desc->range_x = strtod(list->elems[4].data, NULL) / width; desc->range_y = strtod(list->elems[5].data, NULL) / height; end: if (list) string_list_free(list); return ret; }
rarch_softfilter_t *rarch_softfilter_new(const char *filter_config, unsigned threads, enum retro_pixel_format in_pixel_format, unsigned max_width, unsigned max_height) { softfilter_simd_mask_t cpu_features = (softfilter_simd_mask_t)cpu_features_get(); char basedir[PATH_MAX_LENGTH]; #ifdef HAVE_DYLIB char ext_name[PATH_MAX_LENGTH]; #endif struct string_list *plugs = NULL; rarch_softfilter_t *filt = NULL; (void)basedir; filt = (rarch_softfilter_t*)calloc(1, sizeof(*filt)); if (!filt) return NULL; filt->conf = config_file_new(filter_config); if (!filt->conf) { RARCH_ERR("[SoftFilter]: Did not find config: %s\n", filter_config); goto error; } #if defined(HAVE_DYLIB) fill_pathname_basedir(basedir, filter_config, sizeof(basedir)); if (!frontend_driver_get_core_extension(ext_name, sizeof(ext_name))) goto error; plugs = dir_list_new(basedir, ext_name, false, false, false, false); if (!plugs) { RARCH_ERR("[SoftFilter]: Could not build up string list...\n"); goto error; } #endif if (!append_softfilter_plugs(filt, plugs)) { RARCH_ERR("[SoftFitler]: Failed to append softfilter plugins...\n"); goto error; } if (plugs) string_list_free(plugs); plugs = NULL; if (!create_softfilter_graph(filt, in_pixel_format, max_width, max_height, cpu_features, threads)) { RARCH_ERR("[SoftFitler]: Failed to create softfilter graph...\n"); goto error; } return filt; error: if (plugs) string_list_free(plugs); plugs = NULL; rarch_softfilter_free(filt); return NULL; }
static void menu_action_setting_disp_set_label(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) { rarch_system_info_t *system = rarch_system_info_get_ptr(); uint32_t hash_label = menu_hash_calculate(label); *s = '\0'; *w = 19; switch (hash_label) { case MENU_LABEL_LOAD_CONTENT_HISTORY: *w = strlen(label); break; case MENU_LABEL_SYSTEM_INFORMATION: *w = 2; break; case MENU_LABEL_DEBUG_INFORMATION: *w = 2; break; } if (type >= MENU_SETTINGS_PLAYLIST_ASSOCIATION_START) { char playlist_name_with_ext[PATH_MAX_LENGTH]; unsigned i; bool found_matching_core_association = false; settings_t *settings = config_get_ptr(); struct string_list *str_list = string_split(settings->playlist_names, ";"); struct string_list *str_list2 = string_split(settings->playlist_cores, ";"); strlcpy(playlist_name_with_ext, path, sizeof(playlist_name_with_ext)); strlcat(playlist_name_with_ext, ".lpl", sizeof(playlist_name_with_ext)); for (i = 0; i < str_list->size; i++) { if (!strcmp(str_list->elems[i].data, playlist_name_with_ext)) { if (str_list->size != str_list2->size) break; if (str_list2->elems[i].data == NULL) break; found_matching_core_association = true; strlcpy(s, str_list2->elems[i].data, len); } } string_list_free(str_list); string_list_free(str_list2); if (!strcmp(s, "DETECT") || !found_matching_core_association) strlcpy(s, "N/A", len); else { global_t *global = global_get_ptr(); char buf[PATH_MAX_LENGTH]; if (core_info_list_get_display_name(global->core_info.list, s, buf, sizeof(buf))) strlcpy(s, buf, len); } } else if (type >= MENU_SETTINGS_CORE_OPTION_START) { const char *core_opt = NULL; if (!system) return; core_opt = core_option_get_val(system->core_options, type - MENU_SETTINGS_CORE_OPTION_START); strlcpy(s, core_opt ? core_opt : "", len); } else menu_setting_get_label(list, s, len, w, type, label, entry_label, i); strlcpy(s2, path, len2); }
static bool input_overlay_load_desc(input_overlay_t *ol, config_file_t *conf, struct overlay_desc *desc, unsigned ol_index, unsigned desc_index, unsigned width, unsigned height, bool normalized, float alpha_mod, float range_mod) { bool ret = true; char overlay_desc_key[64]; snprintf(overlay_desc_key, sizeof(overlay_desc_key), "overlay%u_desc%u", ol_index, desc_index); char overlay_desc_image_key[64]; snprintf(overlay_desc_image_key, sizeof(overlay_desc_image_key), "overlay%u_desc%u_overlay", ol_index, desc_index); char image_path[PATH_MAX]; if (config_get_path(conf, overlay_desc_image_key, image_path, sizeof(image_path))) { char path[PATH_MAX]; fill_pathname_resolve_relative(path, ol->overlay_path, image_path, sizeof(path)); struct texture_image img = {0}; if (texture_image_load(driver.video_data, path, &img)) desc->image = img; } char overlay_desc_normalized_key[64]; snprintf(overlay_desc_normalized_key, sizeof(overlay_desc_normalized_key), "overlay%u_desc%u_normalized", ol_index, desc_index); config_get_bool(conf, overlay_desc_normalized_key, &normalized); bool by_pixel = !normalized; if (by_pixel && (width == 0 || height == 0)) { RARCH_ERR("[Overlay]: Base overlay is not set and not using normalized coordinates.\n"); return false; } char overlay[256]; if (!config_get_array(conf, overlay_desc_key, overlay, sizeof(overlay))) { RARCH_ERR("[Overlay]: Didn't find key: %s.\n", overlay_desc_key); return false; } struct string_list *list = string_split(overlay, ", "); if (!list) { RARCH_ERR("[Overlay]: Failed to split overlay desc.\n"); return false; } if (list->size < 6) { string_list_free(list); RARCH_ERR("[Overlay]: Overlay desc is invalid. Requires at least 6 tokens.\n"); return false; } const char *x = list->elems[1].data; const char *y = list->elems[2].data; const char *box = list->elems[3].data; char *key = list->elems[0].data; char *save; desc->key_mask = 0; if (strcmp(key, "analog_left") == 0) desc->type = OVERLAY_TYPE_ANALOG_LEFT; else if (strcmp(key, "analog_right") == 0) desc->type = OVERLAY_TYPE_ANALOG_RIGHT; else if (strstr(key, "retrok_") == key) { desc->type = OVERLAY_TYPE_KEYBOARD; desc->key_mask = input_translate_str_to_rk(key + 7); } else { const char *tmp; desc->type = OVERLAY_TYPE_BUTTONS; for (tmp = strtok_r(key, "|", &save); tmp; tmp = strtok_r(NULL, "|", &save)) { if (strcmp(tmp, "nul") != 0) desc->key_mask |= UINT64_C(1) << input_translate_str_to_bind_id(tmp); } if (desc->key_mask & (UINT64_C(1) << RARCH_OVERLAY_NEXT)) { char overlay_target_key[64]; snprintf(overlay_target_key, sizeof(overlay_target_key), "overlay%u_desc%u_next_target", ol_index, desc_index); config_get_array(conf, overlay_target_key, desc->next_index_name, sizeof(desc->next_index_name)); } } float width_mod = by_pixel ? (1.0f / width) : 1.0f; float height_mod = by_pixel ? (1.0f / height) : 1.0f; desc->x = (float)strtod(x, NULL) * width_mod; desc->y = (float)strtod(y, NULL) * height_mod; if (!strcmp(box, "radial")) desc->hitbox = OVERLAY_HITBOX_RADIAL; else if (!strcmp(box, "rect")) desc->hitbox = OVERLAY_HITBOX_RECT; else { RARCH_ERR("[Overlay]: Hitbox type (%s) is invalid. Use \"radial\" or \"rect\".\n", box); ret = false; goto end; } if (desc->type == OVERLAY_TYPE_ANALOG_LEFT || desc->type == OVERLAY_TYPE_ANALOG_RIGHT) { if (desc->hitbox != OVERLAY_HITBOX_RADIAL) { RARCH_ERR("[Overlay]: Analog hitbox type must be \"radial\".\n"); ret = false; goto end; } char overlay_analog_saturate_key[64]; snprintf(overlay_analog_saturate_key, sizeof(overlay_analog_saturate_key), "overlay%u_desc%u_saturate_pct", ol_index, desc_index); if (!config_get_float(conf, overlay_analog_saturate_key, &desc->analog_saturate_pct)) desc->analog_saturate_pct = 1.0f; } desc->range_x = (float)strtod(list->elems[4].data, NULL) * width_mod; desc->range_y = (float)strtod(list->elems[5].data, NULL) * height_mod; desc->mod_x = desc->x - desc->range_x; desc->mod_w = 2.0f * desc->range_x; desc->mod_y = desc->y - desc->range_y; desc->mod_h = 2.0f * desc->range_y; char conf_key[64]; snprintf(conf_key, sizeof(conf_key), "overlay%u_desc%u_alpha_mod", ol_index, desc_index); desc->alpha_mod = alpha_mod; config_get_float(conf, conf_key, &desc->alpha_mod); snprintf(conf_key, sizeof(conf_key), "overlay%u_desc%u_range_mod", ol_index, desc_index); desc->range_mod = range_mod; config_get_float(conf, conf_key, &desc->range_mod); snprintf(conf_key, sizeof(conf_key), "overlay%u_desc%u_movable", ol_index, desc_index); desc->movable = false; desc->delta_x = 0.0f; desc->delta_y = 0.0f; config_get_bool(conf, conf_key, &desc->movable); desc->range_x_mod = desc->range_x; desc->range_y_mod = desc->range_y; end: if (list) string_list_free(list); return ret; }
/* Generic compressed file loader. * Extracts to buf, unless optional_filename != 0 * Then extracts to optional_filename and leaves buf alone. */ static int content_file_compressed_read( const char * path, void **buf, const char* optional_filename, ssize_t *length) { int ret = 0; const char* file_ext = NULL; struct string_list *str_list = string_split(path, "#"); /* Safety check. * If optional_filename and optional_filename * exists, we simply return 0, * hoping that optional_filename is the * same as requested. */ if (optional_filename && path_file_exists(optional_filename)) { *length = 0; return 1; } /* We assure that there is something after the '#' symbol. * * This error condition happens for example, when * path = /path/to/file.7z, or * path = /path/to/file.7z# */ if (str_list->size <= 1) goto error; #if defined(HAVE_7ZIP) || defined(HAVE_ZLIB) file_ext = path_get_extension(str_list->elems[0].data); #endif #ifdef HAVE_7ZIP if (string_is_equal_noncase(file_ext, "7z")) { *length = content_7zip_file_read(str_list->elems[0].data, str_list->elems[1].data, buf, optional_filename); if (*length != -1) ret = 1; } #endif #ifdef HAVE_ZLIB if (string_is_equal_noncase(file_ext, "zip")) { *length = content_zip_file_read(str_list->elems[0].data, str_list->elems[1].data, buf, optional_filename); if (*length != -1) ret = 1; } string_list_free(str_list); #endif return ret; error: RARCH_ERR("Could not extract string and substring from " ": %s.\n", path); string_list_free(str_list); *length = 0; return 0; }
static bool input_overlay_load_overlay(input_overlay_t *ol, config_file_t *conf, const char *config_path, struct overlay *overlay, unsigned index) { size_t i; char overlay_path_key[64]; char overlay_name_key[64]; char overlay_path[PATH_MAX]; char overlay_resolved_path[PATH_MAX]; snprintf(overlay_path_key, sizeof(overlay_path_key), "overlay%u_overlay", index); if (config_get_path(conf, overlay_path_key, overlay_path, sizeof(overlay_path))) { struct texture_image img = {0}; fill_pathname_resolve_relative(overlay_resolved_path, config_path, overlay_path, sizeof(overlay_resolved_path)); if (texture_image_load(driver.video_data, overlay_resolved_path, &img)) overlay->image = img; else { RARCH_ERR("[Overlay]: Failed to load image: %s.\n", overlay_resolved_path); return false; } } snprintf(overlay_name_key, sizeof(overlay_name_key), "overlay%u_name", index); config_get_array(conf, overlay_name_key, overlay->name, sizeof(overlay->name)); // By default, we stretch the overlay out in full. overlay->x = overlay->y = 0.0f; overlay->w = overlay->h = 1.0f; char overlay_rect_key[64]; snprintf(overlay_rect_key, sizeof(overlay_rect_key), "overlay%u_rect", index); char overlay_rect[256]; if (config_get_array(conf, overlay_rect_key, overlay_rect, sizeof(overlay_rect))) { struct string_list *list = string_split(overlay_rect, ", "); if (list->size < 4) { RARCH_ERR("[Overlay]: Failed to split rect \"%s\" into at least four tokens.\n", overlay_rect); return false; } overlay->x = (float)strtod(list->elems[0].data, NULL); overlay->y = (float)strtod(list->elems[1].data, NULL); overlay->w = (float)strtod(list->elems[2].data, NULL); overlay->h = (float)strtod(list->elems[3].data, NULL); string_list_free(list); } char overlay_full_screen_key[64]; snprintf(overlay_full_screen_key, sizeof(overlay_full_screen_key), "overlay%u_full_screen", index); overlay->full_screen = false; config_get_bool(conf, overlay_full_screen_key, &overlay->full_screen); char overlay_descs_key[64]; snprintf(overlay_descs_key, sizeof(overlay_descs_key), "overlay%u_descs", index); unsigned descs = 0; if (!config_get_uint(conf, overlay_descs_key, &descs)) { RARCH_ERR("[Overlay]: Failed to read number of descs from config key: %s.\n", overlay_descs_key); return false; } overlay->descs = (struct overlay_desc*)calloc(descs, sizeof(*overlay->descs)); if (!overlay->descs) { RARCH_ERR("[Overlay]: Failed to allocate descs.\n"); return false; } overlay->size = descs; char conf_key[64]; bool normalized = false; snprintf(conf_key, sizeof(conf_key), "overlay%u_normalized", index); config_get_bool(conf, conf_key, &normalized); float alpha_mod = 1.0f; snprintf(conf_key, sizeof(conf_key), "overlay%u_alpha_mod", index); config_get_float(conf, conf_key, &alpha_mod); float range_mod = 1.0f; snprintf(conf_key, sizeof(conf_key), "overlay%u_range_mod", index); config_get_float(conf, conf_key, &range_mod); for (i = 0; i < overlay->size; i++) { if (!input_overlay_load_desc(ol, conf, &overlay->descs[i], index, i, overlay->image.width, overlay->image.height, normalized, alpha_mod, range_mod)) { RARCH_ERR("[Overlay]: Failed to load overlay descs for overlay #%u.\n", (unsigned)i); return false; } } // Precache load image array for simplicity. overlay->load_images = (struct texture_image*)calloc(1 + overlay->size, sizeof(struct texture_image)); if (!overlay->load_images) { RARCH_ERR("[Overlay]: Failed to allocate load_images.\n"); return false; } if (overlay->image.pixels) overlay->load_images[overlay->load_images_size++] = overlay->image; for (i = 0; i < overlay->size; i++) { if (overlay->descs[i].image.pixels) { overlay->descs[i].image_index = overlay->load_images_size; overlay->load_images[overlay->load_images_size++] = overlay->descs[i].image; } } // Assume for now that scaling center is in the middle. // TODO: Make this configurable. overlay->block_scale = false; overlay->center_x = overlay->x + 0.5f * overlay->w; overlay->center_y = overlay->y + 0.5f * overlay->h; return true; }
/** * dir_list_free: * @list : pointer to the directory listing * * Frees a directory listing. * **/ void dir_list_free(struct string_list *list) { string_list_free(list); }
config_file_t *config_file_new_from_string(const char *from_string) { size_t i; struct string_list *lines = NULL; struct config_file *conf = (struct config_file*)malloc(sizeof(*conf)); if (!conf) return NULL; if (!from_string) return conf; conf->path = NULL; conf->entries = NULL; conf->tail = NULL; conf->last = NULL; conf->includes = NULL; conf->include_depth = 0; conf->guaranteed_no_duplicates = false ; lines = string_split(from_string, "\n"); if (!lines) return conf; for (i = 0; i < lines->size; i++) { struct config_entry_list *list = (struct config_entry_list*) malloc(sizeof(*list)); char *line = lines->elems[i].data; if (!list) { string_list_free(lines); config_file_free(conf); return NULL; } list->readonly = false; list->key = NULL; list->value = NULL; list->next = NULL; if (line && conf) { if (*line && parse_line(conf, list, line, NULL)) { if (conf->entries) conf->tail->next = list; else conf->entries = list; conf->tail = list; } } if (list != conf->tail) free(list); } string_list_free(lines); return conf; }
static int rarch_main_data_nbio_iterate_poll(nbio_handle_t *nbio) { char elem0[PATH_MAX_LENGTH]; unsigned elem0_hash = 0; uint32_t cb_type_hash = 0; struct nbio_t* handle = NULL; struct string_list *str_list = NULL; const char *path = NULL; if (!nbio) return -1; path = msg_queue_pull(nbio->msg_queue); if (!path) return -1; /* Can only deal with one NBIO transfer at a time for now */ if (nbio->handle) return -1; str_list = string_split(path, "|"); if (!str_list || (str_list->size < 1)) goto error; strlcpy(elem0, str_list->elems[0].data, sizeof(elem0)); elem0_hash = djb2_calculate(elem0); /* TODO/FIXME - should be able to deal with this * in a better way. */ switch(elem0_hash) { case CB_MENU_WALLPAPER: case CB_MENU_BOXART: goto error; default: break; } if (str_list->size > 1) cb_type_hash = djb2_calculate(str_list->elems[1].data); handle = nbio_open(elem0, NBIO_READ); if (!handle) { RARCH_ERR("Could not create new file loading handle.\n"); goto error; } nbio->handle = handle; nbio->is_finished = false; nbio->cb = &cb_nbio_default; switch (cb_type_hash) { #if defined(HAVE_MENU) && defined(HAVE_RPNG) case CB_MENU_WALLPAPER: nbio->cb = &cb_nbio_image_menu_wallpaper; break; case CB_MENU_BOXART: nbio->cb = &cb_nbio_image_menu_boxart; break; #endif } nbio_begin_read(handle); string_list_free(str_list); return 0; error: if (str_list) string_list_free(str_list); return -1; }
/** * dir_list_new: * @dir : directory path. * @ext : allowed extensions of file directory entries to include. * @include_dirs : include directories as part of the finished directory listing? * * Create a directory listing. * * Returns: pointer to a directory listing of type 'struct string_list *' on success, * NULL in case of error. Has to be freed manually. **/ struct string_list *dir_list_new(const char *dir, const char *ext, bool include_dirs) { #ifdef _WIN32 WIN32_FIND_DATA ffd; HANDLE hFind = INVALID_HANDLE_VALUE; #else DIR *directory = NULL; const struct dirent *entry = NULL; #endif char path_buf[PATH_MAX_LENGTH] = {0}; struct string_list *ext_list = NULL; struct string_list *list = NULL; (void)path_buf; if (!(list = string_list_new())) return NULL; if (ext) ext_list = string_split(ext, "|"); #ifdef _WIN32 snprintf(path_buf, sizeof(path_buf), "%s\\*", dir); hFind = FindFirstFile(path_buf, &ffd); if (hFind == INVALID_HANDLE_VALUE) goto error; do { int ret = 0; char file_path[PATH_MAX_LENGTH] = {0}; const char *name = ffd.cFileName; const char *file_ext = path_get_extension(name); bool is_dir = ffd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY; fill_pathname_join(file_path, dir, name, sizeof(file_path)); ret = parse_dir_entry(name, file_path, is_dir, include_dirs, list, ext_list, file_ext); if (ret == -1) goto error; if (ret == 1) continue; }while (FindNextFile(hFind, &ffd) != 0); FindClose(hFind); string_list_free(ext_list); return list; error: if (hFind != INVALID_HANDLE_VALUE) FindClose(hFind); #else directory = opendir(dir); if (!directory) goto error; while ((entry = readdir(directory))) { int ret = 0; char file_path[PATH_MAX_LENGTH] = {0}; const char *name = entry->d_name; const char *file_ext = path_get_extension(name); bool is_dir = false; fill_pathname_join(file_path, dir, name, sizeof(file_path)); is_dir = dirent_is_directory(file_path, entry); ret = parse_dir_entry(name, file_path, is_dir, include_dirs, list, ext_list, file_ext); if (ret == -1) goto error; if (ret == 1) continue; } closedir(directory); string_list_free(ext_list); return list; error: if (directory) closedir(directory); #endif string_list_free(list); string_list_free(ext_list); return NULL; }