static void menu_list_flush_stack(menu_list_t *list, size_t idx, const char *needle, unsigned final_type) { bool refresh = false; const char *path = NULL; const char *label = NULL; unsigned type = 0; size_t entry_idx = 0; file_list_t *menu_list = menu_list_get(list, (unsigned)idx); if (!list) return; menu_entries_ctl(MENU_ENTRIES_CTL_SET_REFRESH, &refresh); file_list_get_last(menu_list, &path, &label, &type, &entry_idx); while (menu_list_flush_stack_type( needle, label, type, final_type) != 0) { size_t new_selection_ptr = menu_navigation_get_selection(); if (!menu_list_pop_stack(list, idx, &new_selection_ptr, 1)) break; menu_navigation_set_selection(new_selection_ptr); menu_list = menu_list_get(list, (unsigned)idx); file_list_get_last(menu_list, &path, &label, &type, &entry_idx); } }
static bool menu_list_pop_stack(menu_list_t *list, size_t idx, size_t *directory_ptr, bool animate) { menu_ctx_list_t list_info; bool refresh = false; file_list_t *menu_list = menu_list_get(list, (unsigned)idx); if (menu_list_get_stack_size(list, idx) <= 1) return false; list_info.type = MENU_LIST_PLAIN; list_info.action = 0; if (animate) menu_driver_list_cache(&list_info); if (menu_list->size != 0) { menu_ctx_list_t list_info; list_info.list = menu_list; list_info.idx = menu_list->size - 1; list_info.list_size = menu_list->size - 1; menu_driver_ctl(RARCH_MENU_CTL_LIST_FREE, &list_info); } file_list_pop(menu_list, directory_ptr); menu_driver_list_set_selection(menu_list); if (animate) menu_entries_ctl(MENU_ENTRIES_CTL_SET_REFRESH, &refresh); return true; }
bool menu_entries_increment_selection_buf(void) { file_list_t **selection_buf = NULL; menu_list_t *menu_list = NULL; menu_entries_ctl(MENU_ENTRIES_CTL_LIST_GET, &menu_list); if (!menu_list) return false; selection_buf = (file_list_t**) realloc(selection_buf, (menu_list->selection_buf_size + 1) * sizeof(*menu_list->selection_buf)); if (!selection_buf) goto error; menu_list->selection_buf = selection_buf; menu_list->selection_buf[menu_list->selection_buf_size] = (file_list_t*) calloc(1, sizeof(*menu_list->selection_buf[menu_list->selection_buf_size])); menu_list->selection_buf_size = menu_list->selection_buf_size + 1; return true; error: if (selection_buf) free(selection_buf); return false; }
bool menu_entries_increment_menu_stack(void) { file_list_t **menu_stack = NULL; menu_list_t *menu_list = NULL; menu_entries_ctl(MENU_ENTRIES_CTL_LIST_GET, &menu_list); if (!menu_list) return false; menu_stack = (file_list_t**)realloc(menu_stack, (menu_list->menu_stack_size + 1) * sizeof(*menu_list->menu_stack)); if (!menu_stack) goto error; menu_list->menu_stack = menu_stack; menu_list->menu_stack[menu_list->menu_stack_size] = (file_list_t*) calloc(1, sizeof(*menu_list->menu_stack[menu_list->menu_stack_size])); menu_list->menu_stack_size = menu_list->menu_stack_size + 1; return true; error: if (menu_stack) free(menu_stack); return false; }
static bool menu_list_pop_stack(menu_list_t *list, size_t idx, size_t *directory_ptr) { menu_ctx_list_t list_info; bool refresh = false; file_list_t *menu_list = NULL; if (!list) return false; menu_list = list->menu_stack[idx]; if (menu_list_get_stack_size(list, idx) <= 1) return false; list_info.type = MENU_LIST_PLAIN; list_info.action = 0; menu_driver_ctl(RARCH_MENU_CTL_LIST_CACHE, &list_info); if (menu_list->size != 0) { menu_ctx_list_t list_info; list_info.list = menu_list; list_info.idx = menu_list->size - 1; list_info.list_size = menu_list->size - 1; menu_driver_ctl(RARCH_MENU_CTL_LIST_FREE, &list_info); } file_list_pop(menu_list, directory_ptr); menu_driver_ctl(RARCH_MENU_CTL_LIST_SET_SELECTION, menu_list); menu_entries_ctl(MENU_ENTRIES_CTL_SET_REFRESH, &refresh); return true; }
static void menu_list_flush_stack(menu_list_t *list, size_t idx, const char *needle, unsigned final_type) { bool refresh = false; const char *path = NULL; const char *label = NULL; unsigned type = 0; size_t entry_idx = 0; if (!list) return; menu_entries_ctl(MENU_ENTRIES_CTL_SET_REFRESH, &refresh); menu_entries_get_last(list->menu_stack[idx], &path, &label, &type, &entry_idx); while (menu_entries_flush_stack_type( needle, label, type, final_type) != 0) { size_t new_selection_ptr; menu_navigation_ctl(MENU_NAVIGATION_CTL_GET_SELECTION, &new_selection_ptr); if (!menu_list_pop_stack(list, idx, &new_selection_ptr)) break; menu_navigation_ctl(MENU_NAVIGATION_CTL_SET_SELECTION, &new_selection_ptr); menu_entries_get_last(list->menu_stack[idx], &path, &label, &type, &entry_idx); } }
static bool menu_entries_init(void) { if (!menu_entries_ctl(MENU_ENTRIES_CTL_LIST_INIT, NULL)) goto error; if (!menu_entries_ctl(MENU_ENTRIES_CTL_SETTINGS_INIT, NULL)) goto error; return true; error: menu_entries_ctl(MENU_ENTRIES_CTL_LIST_DEINIT, NULL); menu_entries_ctl(MENU_ENTRIES_CTL_SETTINGS_DEINIT, NULL); return false; }
void menu_entries_pop_stack(size_t *ptr, size_t idx) { menu_list_t *menu_list = NULL; menu_entries_ctl(MENU_ENTRIES_CTL_LIST_GET, &menu_list); if (menu_list) menu_list_pop_stack(menu_list, idx, ptr); }
void menu_entries_flush_stack(const char *needle, unsigned final_type) { menu_list_t *menu_list = NULL; menu_entries_ctl(MENU_ENTRIES_CTL_LIST_GET, &menu_list); if (menu_list) menu_list_flush_stack(menu_list, 0, needle, final_type); }
void menu_entries_get_last_stack(const char **path, const char **label, unsigned *file_type, size_t *entry_idx) { menu_list_t *menu_list = NULL; menu_entries_ctl(MENU_ENTRIES_CTL_LIST_GET, &menu_list); if (menu_list) menu_entries_get_last(menu_list->menu_stack[0], path, label, file_type, entry_idx); }
menu_file_list_cbs_t *menu_entries_get_last_stack_actiondata(void) { menu_list_t *menu_list = NULL; menu_entries_ctl(MENU_ENTRIES_CTL_LIST_GET, &menu_list); if (!menu_list) return NULL; return (menu_file_list_cbs_t*)file_list_get_last_actiondata(menu_list->menu_stack[0]); }
size_t menu_entries_get_size(void) { menu_list_t *menu_list = NULL; menu_entries_ctl(MENU_ENTRIES_CTL_LIST_GET, &menu_list); if (!menu_list) return 0; return file_list_get_size(menu_list->selection_buf[0]); }
file_list_t *menu_entries_get_menu_stack_ptr(size_t idx) { menu_list_t *menu_list = NULL; menu_entries_ctl(MENU_ENTRIES_CTL_LIST_GET, &menu_list); if (!menu_list) return NULL; return menu_list->menu_stack[idx]; }
file_list_t *menu_entries_get_selection_buf_ptr(size_t idx) { menu_list_t *menu_list = NULL; menu_entries_ctl(MENU_ENTRIES_CTL_LIST_GET, &menu_list); if (!menu_list) return NULL; return menu_list->selection_buf[idx]; }
size_t menu_entries_get_stack_size(size_t idx) { menu_list_t *menu_list = NULL; menu_entries_ctl(MENU_ENTRIES_CTL_LIST_GET, &menu_list); if (!menu_list) return 0; return menu_list_get_stack_size(menu_list, idx); }
static void menu_driver_toggle(bool latch) { retro_keyboard_event_t *key_event = NULL; retro_keyboard_event_t *frontend_key_event = NULL; settings_t *settings = config_get_ptr(); menu_driver_ctl(RARCH_MENU_CTL_TOGGLE, &latch); if (latch) menu_driver_ctl(RARCH_MENU_CTL_SET_ALIVE, NULL); else menu_driver_ctl(RARCH_MENU_CTL_UNSET_ALIVE, NULL); runloop_ctl(RUNLOOP_CTL_FRONTEND_KEY_EVENT_GET, &frontend_key_event); runloop_ctl(RUNLOOP_CTL_KEY_EVENT_GET, &key_event); if (menu_driver_ctl(RARCH_MENU_CTL_IS_ALIVE, NULL)) { bool refresh = false; menu_entries_ctl(MENU_ENTRIES_CTL_SET_REFRESH, &refresh); /* Menu should always run with vsync on. */ command_event(CMD_EVENT_VIDEO_SET_BLOCKING_STATE, NULL); /* Stop all rumbling before entering the menu. */ command_event(CMD_EVENT_RUMBLE_STOP, NULL); if (settings->menu.pause_libretro) command_event(CMD_EVENT_AUDIO_STOP, NULL); /* Override keyboard callback to redirect to menu instead. * We'll use this later for something ... */ if (key_event && frontend_key_event) { *frontend_key_event = *key_event; *key_event = menu_input_key_event; runloop_ctl(RUNLOOP_CTL_SET_FRAME_TIME_LAST, NULL); } } else { if (!runloop_ctl(RUNLOOP_CTL_IS_SHUTDOWN, NULL)) driver_ctl(RARCH_DRIVER_CTL_SET_NONBLOCK_STATE, NULL); if (settings && settings->menu.pause_libretro) command_event(CMD_EVENT_AUDIO_START, NULL); /* Prevent stray input from going to libretro core */ input_driver_set_flushing_input(); /* Restore libretro keyboard callback. */ if (key_event && frontend_key_event) *key_event = *frontend_key_event; } }
static void mui_navigation_clear(void *data, bool pending_push) { size_t i = 0; mui_handle_t *mui = (mui_handle_t*)data; if (!mui) return; menu_entries_ctl(MENU_ENTRIES_CTL_SET_START, &i); mui->scroll_y = 0; }
static int action_start_cheat_num_passes(unsigned type, const char *label) { if (cheat_manager_get_size()) { bool refresh = false; menu_entries_ctl(MENU_ENTRIES_CTL_SET_REFRESH, &refresh); cheat_manager_realloc(0); } return 0; }
static int action_right_cheat_num_passes(unsigned type, const char *label, bool wraparound) { bool refresh = false; unsigned new_size = 0; new_size = cheat_manager_get_size() + 1; menu_entries_ctl(MENU_ENTRIES_CTL_SET_REFRESH, &refresh); menu_driver_ctl(RARCH_MENU_CTL_SET_PREVENT_POPULATE, NULL); cheat_manager_realloc(new_size); return 0; }
/** * menu_init: * @data : Menu context handle. * * Create and initialize menu handle. * * Returns: menu handle on success, otherwise NULL. **/ static bool menu_init(menu_handle_t *menu_data) { settings_t *settings = config_get_ptr(); if (!menu_entries_ctl(MENU_ENTRIES_CTL_INIT, NULL)) return false; if (!core_info_init_current_core()) return false; if (!menu_driver_ctl(RARCH_MENU_CTL_SHADER_INIT, NULL)) return false; if (settings->menu_show_start_screen) { menu_data->push_help_screen = true; menu_data->help_screen_type = MENU_HELP_WELCOME; settings->menu_show_start_screen = false; command_event(CMD_EVENT_MENU_SAVE_CURRENT_CONFIG, NULL); } if ( settings->bundle_assets_extract_enable && !string_is_empty(settings->path.bundle_assets_src) && !string_is_empty(settings->path.bundle_assets_dst) #ifdef IOS && menu_data->push_help_screen #else && (settings->bundle_assets_extract_version_current != settings->bundle_assets_extract_last_version) #endif ) { menu_data->help_screen_type = MENU_HELP_EXTRACT; menu_data->push_help_screen = true; #ifdef HAVE_ZLIB rarch_task_push_decompress(settings->path.bundle_assets_src, settings->path.bundle_assets_dst, NULL, settings->path.bundle_assets_dst_subdir, NULL, bundle_decompressed, NULL); #endif } menu_driver_ctl(RARCH_MENU_CTL_SHADER_MANAGER_INIT, NULL); if (!menu_display_init()) return false; return true; }
int menu_shader_manager_clear_num_passes(void) { #ifdef HAVE_SHADER_MANAGER bool refresh = false; struct video_shader *shader = menu_shader_get(); if (shader->passes) shader->passes = 0; menu_entries_ctl(MENU_ENTRIES_CTL_SET_REFRESH, &refresh); video_shader_resolve_parameters(NULL, shader); #endif return 0; }
void menu_entries_get_last_stack(const char **path, const char **label, unsigned *file_type, enum msg_hash_enums *enum_idx, size_t *entry_idx) { menu_file_list_cbs_t *cbs = NULL; menu_list_t *menu_list = NULL; menu_entries_ctl(MENU_ENTRIES_CTL_LIST_GET, &menu_list); if (!menu_list) return; menu_entries_get_last(menu_list_get(menu_list, 0), path, label, file_type, entry_idx); cbs = menu_entries_get_last_stack_actiondata(); if (cbs) *enum_idx = cbs->enum_idx; }
/** * menu_shader_manager_set_preset: * @shader : Shader handle. * @type : Type of shader. * @preset_path : Preset path to load from. * * Sets shader preset. **/ void menu_shader_manager_set_preset(void *data, unsigned type, const char *preset_path) { #ifdef HAVE_SHADER_MANAGER struct video_shader *shader = (struct video_shader*)data; config_file_t *conf = NULL; bool refresh = false; settings_t *settings = config_get_ptr(); if (!video_driver_set_shader((enum rarch_shader_type)type, preset_path)) { configuration_set_bool(settings, settings->bools.video_shader_enable, false); return; } /* Makes sure that we use Menu Preset shader on driver reinit. * Only do this when the cgp actually works to avoid potential errors. */ strlcpy(settings->paths.path_shader, preset_path ? preset_path : "", sizeof(settings->paths.path_shader)); configuration_set_bool(settings, settings->bools.video_shader_enable, true); if (!preset_path || !shader) return; /* Load stored Preset into menu on success. * Used when a preset is directly loaded. * No point in updating when the Preset was * created from the menu itself. */ conf = config_file_new(preset_path); if (!conf) return; RARCH_LOG("Setting Menu shader: %s.\n", preset_path); if (video_shader_read_conf_cgp(conf, shader)) { video_shader_resolve_relative(shader, preset_path); video_shader_resolve_parameters(conf, shader); } config_file_free(conf); menu_entries_ctl(MENU_ENTRIES_CTL_SET_REFRESH, &refresh); #endif }
static void mui_render_menu_list(mui_handle_t *mui, unsigned width, unsigned height, uint32_t normal_color, uint32_t hover_color, float *pure_white) { unsigned header_height; uint64_t *frame_count; size_t i = 0; size_t end = menu_entries_get_end(); video_driver_ctl(RARCH_DISPLAY_CTL_GET_FRAME_COUNT, &frame_count); if (!menu_display_ctl(MENU_DISPLAY_CTL_UPDATE_PENDING, NULL)) return; menu_display_ctl(MENU_DISPLAY_CTL_HEADER_HEIGHT, &header_height); mui->list_block.carr.coords.vertices = 0; menu_entries_ctl(MENU_ENTRIES_CTL_START_GET, &i); for (; i < end; i++) { int y; size_t selection; bool entry_selected; menu_entry_t entry; if (!menu_navigation_ctl(MENU_NAVIGATION_CTL_GET_SELECTION, &selection)) continue; y = header_height - mui->scroll_y + (mui->line_height * i); if ((y - (int)mui->line_height) > (int)height || ((y + (int)mui->line_height) < 0)) continue; menu_entry_get(&entry, 0, i, NULL, true); entry_selected = selection == i; mui_render_label_value(mui, y, width, height, *frame_count / 20, entry_selected ? hover_color : normal_color, entry_selected, entry.path, entry.value, pure_white); } }
static int action_right_shader_num_passes(unsigned type, const char *label, bool wraparound) { bool refresh = false; struct video_shader *shader = menu_shader_get(); unsigned pass_count = shader ? shader->passes : 0; if (!shader) return menu_cbs_exit(); if (pass_count < GFX_MAX_SHADERS) menu_shader_manager_increment_amount_passes(); menu_entries_ctl(MENU_ENTRIES_CTL_SET_REFRESH, &refresh); menu_driver_ctl(RARCH_MENU_CTL_SET_PREVENT_POPULATE, NULL); video_shader_resolve_parameters(NULL, shader); return 0; }
static int action_start_shader_num_passes(unsigned type, const char *label) { #ifdef HAVE_SHADER_MANAGER bool refresh = false; struct video_shader *shader = NULL; menu_driver_ctl(RARCH_MENU_CTL_SHADER_GET, &shader); if (!shader) return -1; if (shader->passes) shader->passes = 0; menu_entries_ctl(MENU_ENTRIES_CTL_SET_REFRESH, &refresh); video_shader_resolve_parameters(NULL, shader); #endif return 0; }
static int action_left_shader_num_passes(unsigned type, const char *label, bool wraparound) { #ifdef HAVE_SHADER_MANAGER bool refresh = false; struct video_shader *shader = menu_shader_get(); if (!shader) return menu_cbs_exit(); if (menu_shader_manager_get_amount_passes()) menu_shader_manager_decrement_amount_passes(); menu_entries_ctl(MENU_ENTRIES_CTL_SET_REFRESH, &refresh); menu_driver_ctl(RARCH_MENU_CTL_SET_PREVENT_POPULATE, NULL); video_shader_resolve_parameters(NULL, shader); #endif return 0; }
static int action_right_shader_num_passes(unsigned type, const char *label, bool wraparound) { #ifdef HAVE_SHADER_MANAGER bool refresh = false; struct video_shader *shader = NULL; menu_driver_ctl(RARCH_MENU_CTL_SHADER_GET, &shader); if (!shader) return menu_cbs_exit(); if ((shader->passes < GFX_MAX_SHADERS)) shader->passes++; menu_entries_ctl(MENU_ENTRIES_CTL_SET_REFRESH, &refresh); menu_driver_ctl(RARCH_MENU_CTL_SET_PREVENT_POPULATE, NULL); video_shader_resolve_parameters(NULL, shader); #endif return 0; }
static void netplay_lan_scan_callback(void *task_data, void *user_data, const char *error) { unsigned i; unsigned menu_type = 0; const char *path = NULL; const char *label = NULL; enum msg_hash_enums enum_idx = MSG_UNKNOWN; file_list_t *file_list = NULL; struct netplay_host_list *netplay_hosts = NULL; menu_entries_get_last_stack(&path, &label, &menu_type, &enum_idx, NULL); /* Don't push the results if we left the LAN scan menu */ if (!string_is_equal(label, msg_hash_to_str( MENU_ENUM_LABEL_DEFERRED_NETPLAY_LAN_SCAN_SETTINGS_LIST))) return; if (netplay_discovery_driver_ctl( RARCH_NETPLAY_DISCOVERY_CTL_LAN_GET_RESPONSES, (void *) &netplay_hosts)) { if (netplay_hosts->size > 0) { file_list = menu_entries_get_selection_buf_ptr(0); menu_entries_ctl(MENU_ENTRIES_CTL_CLEAR, file_list); } for (i = 0; i < netplay_hosts->size; i++) { struct netplay_host *host = &netplay_hosts->hosts[i]; menu_entries_append_enum(file_list, host->nick, msg_hash_to_str(MENU_ENUM_LABEL_NETPLAY_CONNECT_TO), MENU_ENUM_LABEL_NETPLAY_CONNECT_TO, MENU_NETPLAY_LAN_SCAN, 0, 0); } } }
static int action_right_cheat_delete_all(unsigned type, const char *label, bool wraparound) { bool refresh = false ; char msg[256]; if ( ++cheat_manager_state.delete_state >= 5 ) { msg[0] = '\0'; cheat_manager_state.delete_state = 0 ; cheat_manager_realloc(0, CHEAT_HANDLER_TYPE_EMU) ; menu_entries_ctl(MENU_ENTRIES_CTL_SET_REFRESH, &refresh); menu_driver_ctl(RARCH_MENU_CTL_SET_PREVENT_POPULATE, NULL); strlcpy(msg, msg_hash_to_str(MSG_CHEAT_DELETE_ALL_SUCCESS), sizeof(msg)); msg[sizeof(msg) - 1] = 0; runloop_msg_queue_push(msg, 1, 180, true); } return 0; }