static int zarch_iterate(enum menu_action action) { int ret = 0; int action_id; menu_entry_t entry; zui_t *zui = NULL; menu_handle_t *menu = menu_driver_get_ptr(); enum menu_action act = (enum menu_action)action; bool perform_action = true; if (!menu) return 0; zui = (zui_t*)menu->userdata; if (!zui) return -1; if (!menu_navigation_ctl(MENU_NAVIGATION_CTL_GET_SELECTION, &action_id)) return 0; BIT64_SET(menu->state, MENU_STATE_RENDER_FRAMEBUFFER); BIT64_SET(menu->state, MENU_STATE_BLIT); menu_entry_get(&entry, 0, action_id, NULL, false); if (action_id >= 0) zui->pending_selection = action_id; if (zui->pending_action_ok.enable) { menu_entry_get(&entry, 0, zui->pending_action_ok.idx, NULL, false); zui->pending_action_ok.enable = false; act = MENU_ACTION_OK; action_id = zui->pending_action_ok.idx; zui->pending_action_ok.idx = 0; } else { zui->action = act; } if (perform_action) ret = menu_entry_action(&entry, action_id, act); if (zui->time_to_exit) { zui->time_to_exit = false; return -1; } if (zui->time_to_quit) { zui->time_to_quit = false; if (!event_command(EVENT_CMD_QUIT)) return -1; return 0; } return ret; }
void menu_entry_get_label(uint32_t i, char *s, size_t len) { menu_entry_t entry = {{0}}; menu_entry_get(&entry, i, NULL, true); strlcpy(s, entry.label, len); }
void menu_input_post_iterate(int *ret, unsigned action) { size_t selection; menu_entry_t entry; menu_file_list_cbs_t *cbs = NULL; settings_t *settings = config_get_ptr(); file_list_t *selection_buf = menu_entries_get_selection_buf_ptr(0); if (!menu_navigation_ctl(MENU_NAVIGATION_CTL_GET_SELECTION, &selection)) return; if (selection_buf) cbs = menu_entries_get_actiondata_at_offset(selection_buf, selection); entry.path[0] = '\0'; entry.label[0] = '\0'; entry.sublabel[0] = '\0'; entry.value[0] = '\0'; entry.rich_label[0] = '\0'; entry.enum_idx = MSG_UNKNOWN; entry.entry_idx = 0; entry.idx = 0; entry.type = 0; entry.spacing = 0; menu_entry_get(&entry, 0, selection, NULL, false); *ret = menu_input_mouse_frame(cbs, &entry, action); if (settings->menu.pointer.enable) *ret |= menu_input_pointer_post_iterate(cbs, &entry, action); }
unsigned menu_entry_get_spacing(uint32_t i) { menu_entry_t entry = {{0}}; menu_entry_get(&entry, i, NULL, true); return entry.spacing; }
void menu_entry_reset(uint32_t i) { menu_entry_t entry = {{0}}; menu_entry_get(&entry, i, NULL, true); menu_entry_action(&entry, i, MENU_ACTION_START); }
unsigned menu_entry_get_type_new(uint32_t i) { menu_entry_t entry = {{0}}; menu_entry_get(&entry, i, NULL, true); return entry.type; }
void menu_input_post_iterate(int *ret, unsigned action) { size_t selection; menu_file_list_cbs_t *cbs = NULL; menu_entry_t entry = {{0}}; menu_input_t *menu_input = menu_input_get_ptr(); settings_t *settings = config_get_ptr(); file_list_t *selection_buf = menu_entries_get_selection_buf_ptr(0); if (!menu_navigation_ctl(MENU_NAVIGATION_CTL_GET_SELECTION, &selection)) return; if (selection_buf) cbs = menu_entries_get_actiondata_at_offset(selection_buf, selection); menu_entry_get(&entry, 0, selection, NULL, false); if (settings->menu.mouse.enable) *ret = menu_input_mouse_post_iterate (&menu_input->mouse.state, cbs, action); *ret = menu_input_mouse_frame(cbs, &entry, menu_input->mouse.state, action); if (settings->menu.pointer.enable) *ret |= menu_input_pointer_post_iterate(cbs, &entry, action); }
void menu_entry_get_label(uint32_t i, char *label, size_t sizeof_label) { menu_entry_t entry; menu_entry_get(&entry, i, NULL, true); strlcpy(label, entry.path, sizeof_label); }
void menu_entry_get_path(uint32_t i, char *s, size_t len) { menu_entry_t entry = {{0}}; menu_entry_get(&entry, 0, i, NULL, true); strlcpy(s, entry.path, len); }
static int zarch_zui_render_lay_root_recent(zui_t *zui, struct zui_tabbed *tabbed) { if (zarch_zui_tab(zui, tabbed, "Recent", 0)) { static int gamepad_index = 0; unsigned size = menu_entries_get_size(); unsigned i, j = 0; if (zarch_zui_gamepad_input(zui, &gamepad_index, &zui->recent_dlist_first, 0)) zui->recent_dlist_first = gamepad_index; for (i = zui->recent_dlist_first; i < size; ++i) { menu_entry_t entry; menu_entry_get(&entry, 0, i, NULL, true); if (zarch_zui_list_item(zui, tabbed, 0, tabbed->tabline_size + j * ZUI_ITEM_SIZE_PX, entry.path, i, entry.value, gamepad_index == (signed)i)) { if (menu_entry_action(&entry, i, MENU_ACTION_OK)) return 1; } j++; } } return 0; }
static int action_select_default(const char *path, const char *label, unsigned type, size_t idx) { menu_entry_t entry; int ret = 0; enum menu_action action = MENU_ACTION_NOOP; menu_file_list_cbs_t *cbs = NULL; menu_list_t *menu_list = menu_list_get_ptr(); menu_entry_get(&entry, idx, NULL, false); cbs = menu_list_get_actiondata_at_offset(menu_list->selection_buf, idx); if (cbs->setting) { switch (cbs->setting->type) { case ST_BOOL: case ST_INT: case ST_UINT: case ST_FLOAT: action = MENU_ACTION_RIGHT; break; case ST_PATH: case ST_DIR: case ST_ACTION: case ST_STRING: case ST_HEX: case ST_BIND: action = MENU_ACTION_OK; break; default: break; } } if (action == MENU_ACTION_NOOP) { if (cbs && cbs->action_ok) action = MENU_ACTION_OK; else { if (cbs && cbs->action_start) action = MENU_ACTION_START; if (cbs && cbs->action_right) action = MENU_ACTION_RIGHT; } } if (action != MENU_ACTION_NOOP) ret = menu_entry_action(&entry, idx, action); rarch_main_data_iterate(); return ret; }
static int action_select_default(const char *path, const char *label, unsigned type, size_t idx) { menu_entry_t entry; int ret = 0; enum menu_action action = MENU_ACTION_NOOP; menu_file_list_cbs_t *cbs = NULL; file_list_t *selection_buf = menu_entries_get_selection_buf_ptr(0); menu_entry_get(&entry, 0, idx, NULL, false); cbs = menu_entries_get_actiondata_at_offset(selection_buf, idx); if (!cbs) return -1; switch (menu_setting_get_type(cbs->setting)) { case ST_BOOL: case ST_INT: case ST_UINT: case ST_FLOAT: action = MENU_ACTION_RIGHT; break; case ST_PATH: case ST_DIR: case ST_ACTION: case ST_STRING: case ST_HEX: case ST_BIND: action = MENU_ACTION_OK; break; default: break; } if (action == MENU_ACTION_NOOP) { if (cbs->action_ok) action = MENU_ACTION_OK; else { if (cbs->action_start) action = MENU_ACTION_START; if (cbs->action_right) action = MENU_ACTION_RIGHT; } } if (action != MENU_ACTION_NOOP) ret = menu_entry_action(&entry, idx, action); task_queue_ctl(TASK_QUEUE_CTL_CHECK, NULL); return ret; }
/* Performs whatever actions are associated with menu entry 'i'. * * This is the most important function because it does all the work * associated with clicking on things in the UI. * * This includes loading cores and updating the * currently displayed menu. */ int menu_entry_select(uint32_t i) { menu_entry_t entry = {{0}}; menu_navigation_ctl(MENU_NAVIGATION_CTL_SET_SELECTION, &i); menu_entry_get(&entry, 0, i, NULL, false); return menu_entry_action(&entry, i, MENU_ACTION_SELECT); }
/* Performs whatever actions are associated with menu entry 'i'. * * This is the most important function because it does all the work * associated with clicking on things in the UI. * * This includes loading cores and updating the * currently displayed menu. */ int menu_entry_select(uint32_t i) { menu_entry_t entry = {{0}}; menu_navigation_t *nav = menu_navigation_get_ptr(); nav->selection_ptr = i; menu_entry_get(&entry, i, NULL, false); return menu_entry_action(&entry, i, MENU_ACTION_SELECT); }
/* Performs whatever actions are associated with menu entry 'i'. * * This is the most important function because it does all the work * associated with clicking on things in the UI. * * This includes loading cores and updating the * currently displayed menu. */ int menu_entry_select(uint32_t i) { menu_entry_t entry; menu_navigation_set_selection(i); menu_entry_init(&entry); menu_entry_get(&entry, 0, i, NULL, false); return menu_entry_action(&entry, i, MENU_ACTION_SELECT); }
int menu_entry_get_current_id(bool use_representation) { size_t i; menu_list_t *menu_list = menu_list_get_ptr(); size_t end = menu_list_get_size(menu_list); for (i = 0; i < end; i++) { menu_entry_t entry = {{0}}; menu_entry_get(&entry, i, NULL, use_representation); if (menu_entry_is_currently_selected(entry.idx)) return i; } return -1; }
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); } }
void menu_input_post_iterate(int *ret, unsigned action) { menu_entry_t entry; settings_t *settings = config_get_ptr(); file_list_t *selection_buf = menu_entries_get_selection_buf_ptr(0); size_t selection = menu_navigation_get_selection(); menu_file_list_cbs_t *cbs = selection_buf ? (menu_file_list_cbs_t*)file_list_get_actiondata_at_offset(selection_buf, selection) : NULL; menu_entry_init(&entry); menu_entry_get(&entry, 0, selection, NULL, false); *ret = menu_input_mouse_frame(cbs, &entry, action); if (settings->bools.menu_pointer_enable) *ret |= menu_input_pointer_post_iterate(cbs, &entry, action); menu_entry_free(&entry); }
void menu_input_post_iterate(int *ret, unsigned action) { menu_entry_t entry; menu_handle_t *menu = menu_driver_get_ptr(); menu_list_t *menu_list = menu_list_get_ptr(); settings_t *settings = config_get_ptr(); size_t selected = menu_navigation_get_current_selection(); menu_file_list_cbs_t *cbs = menu_list_get_actiondata_at_offset (menu_list->selection_buf, selected); menu_entry_get(&entry, selected, NULL, false); if (settings->menu.mouse.enable) *ret = menu_input_mouse_post_iterate (&menu->input.mouse, cbs, &entry, action); *ret = menu_input_mouse_frame(cbs, &entry, menu->input.mouse); if (settings->menu.pointer.enable) *ret |= menu_input_pointer_post_iterate(cbs, &entry, action); }
static int zarch_iterate(void *data, void *userdata, enum menu_action action) { int ret; size_t selection; menu_entry_t entry; zui_t *zui = (zui_t*)userdata; if (!zui) return -1; if (!menu_navigation_ctl(MENU_NAVIGATION_CTL_GET_SELECTION, &selection)) return 0; menu_entry_get(&entry, 0, selection, NULL, false); zui->action = action; ret = menu_entry_action(&entry, selection, action); if (ret) return -1; return 0; }
static int nk_menu_iterate(void *data, void *userdata, enum menu_action action) { int ret; size_t selection; menu_entry_t entry; nk_menu_handle_t *nk = (nk_menu_handle_t*)userdata; if (!nk) return -1; if (!menu_navigation_ctl(MENU_NAVIGATION_CTL_GET_SELECTION, &selection)) return 0; menu_entry_get(&entry, 0, selection, NULL, false); nk->action = action; ret = menu_entry_action(&entry, selection, action); if (ret) return -1; return 0; }
static int zarch_zui_render_lay_root_recent(zui_t *zui, struct zui_tabbed *tabbed) { if (zarch_zui_tab(zui, tabbed, "Recent", 0)) { static int gamepad_index = 0; unsigned size = menu_entries_get_size(); unsigned i, j = 0; if (zarch_zui_gamepad_input(zui, &gamepad_index, &zui->recent_dlist_first, 0)) zui->recent_dlist_first = gamepad_index; for (i = zui->recent_dlist_first; i < size; ++i) { char rich_label[PATH_MAX_LENGTH]; char entry_value[PATH_MAX_LENGTH]; menu_entry_t entry = {{0}}; rich_label[0] = entry_value[0] = '\0'; menu_entry_get(&entry, 0, i, NULL, true); menu_entry_get_rich_label(i, rich_label, sizeof(rich_label)); menu_entry_get_value(i, NULL, entry_value,sizeof(entry_value)); if (zarch_zui_list_item(zui, tabbed, 0, tabbed->tabline_size + j * ZUI_ITEM_SIZE_PX, rich_label, i, entry_value, gamepad_index == (signed)i)) { if (menu_entry_action(&entry, i, MENU_ACTION_OK)) return 1; } j++; } } return 0; }
// Performs whatever actions are associated with menu entry 'i'. This // is the most important function because it does all the work // associated with clicking on things in the UI. This includes loading // cores and updating the currently displayed menu int menu_entry_select(uint32_t i) { int ret = 0; menu_entry_t entry; enum menu_action action = MENU_ACTION_NOOP; menu_file_list_cbs_t *cbs = NULL; menu_navigation_t *nav = menu_navigation_get_ptr(); menu_list_t *menu_list = menu_list_get_ptr(); rarch_setting_t *setting = menu_setting_find( menu_list->selection_buf->list[i].label); menu_entry_get(&entry, i, NULL, false); cbs = menu_list_get_actiondata_at_offset(menu_list->selection_buf, i); if (setting_is_of_path_type(setting)) return 0; nav->selection_ptr = i; if ((cbs && cbs->action_ok) || setting_is_of_general_type(setting)) action = MENU_ACTION_OK; else { if (cbs && cbs->action_start) action = MENU_ACTION_START; if (cbs && cbs->action_right) action = MENU_ACTION_RIGHT; } if (action != MENU_ACTION_NOOP) ret = menu_entry_action(&entry, i, action); rarch_main_data_iterate(); return ret; }
static int zarch_zui_render_lay_root_recent(zui_t *zui, zui_tabbed_t *tabbed) { if (zarch_zui_tab(zui, tabbed, "Recent", 0)) { unsigned size = menu_entries_get_size(); unsigned i, j = 0; zui->recent_dlist_first += zui->mouse.wheel; if (zui->recent_dlist_first < 0) zui->recent_dlist_first = 0; else if (zui->recent_dlist_first > size - 5) zui->recent_dlist_first = size - 5; zui->recent_dlist_first = min(max(zui->recent_dlist_first, 0), size - 5); for (i = zui->recent_dlist_first; i < size; ++i) { menu_entry_t entry; menu_entry_get(&entry, 0, i, NULL, true); if (zarch_zui_list_item(zui, tabbed, 0, tabbed->tabline_size + j * 54, entry.path, i, entry.value)) { zui->pending_action_ok.enable = true; zui->pending_action_ok.idx = i; return 1; } j++; } } return 0; }
/** * menu_iterate: * @input : input sample for this frame * @old_input : input sample of the previous frame * @trigger_input : difference' input sample - difference * between 'input' and 'old_input' * * Runs RetroArch menu for one frame. * * Returns: 0 on success, -1 if we need to quit out of the loop. **/ int generic_menu_iterate(void *data, void *userdata, enum menu_action action) { menu_entry_t entry; enum action_iterate_type iterate_type; size_t selection = 0; unsigned file_type = 0; int ret = 0; uint32_t hash = 0; enum msg_hash_enums enum_idx = MSG_UNKNOWN; const char *label = NULL; menu_handle_t *menu = (menu_handle_t*)data; menu_entries_get_last_stack(NULL, &label, &file_type, &enum_idx, NULL); if (!menu) return 0; if (!menu_navigation_ctl(MENU_NAVIGATION_CTL_GET_SELECTION, &selection)) return 0; menu->menu_state.msg[0] = '\0'; hash = msg_hash_calculate(label); iterate_type = action_iterate_type(hash); menu_driver_set_binding_state(iterate_type == ITERATE_TYPE_BIND); if ( action != MENU_ACTION_NOOP || menu_entries_ctl(MENU_ENTRIES_CTL_NEEDS_REFRESH, NULL) || menu_display_get_update_pending()) { BIT64_SET(menu->state, MENU_STATE_RENDER_FRAMEBUFFER); } switch (iterate_type) { case ITERATE_TYPE_HELP: ret = menu_dialog_iterate( menu->menu_state.msg, sizeof(menu->menu_state.msg), label); BIT64_SET(menu->state, MENU_STATE_RENDER_MESSAGEBOX); BIT64_SET(menu->state, MENU_STATE_POST_ITERATE); if (ret == 1 || action == MENU_ACTION_OK) { BIT64_SET(menu->state, MENU_STATE_POP_STACK); menu_dialog_set_active(false); } if (action == MENU_ACTION_CANCEL) { BIT64_SET(menu->state, MENU_STATE_POP_STACK); menu_dialog_set_active(false); } break; case ITERATE_TYPE_BIND: { menu_input_ctx_bind_t bind; bind.s = menu->menu_state.msg; bind.len = sizeof(menu->menu_state.msg); if (menu_input_key_bind_iterate(&bind)) { menu_entries_pop_stack(&selection, 0, 0); menu_navigation_ctl( MENU_NAVIGATION_CTL_SET_SELECTION, &selection); } else BIT64_SET(menu->state, MENU_STATE_RENDER_MESSAGEBOX); } break; case ITERATE_TYPE_INFO: { file_list_t *selection_buf = menu_entries_get_selection_buf_ptr(0); menu_file_list_cbs_t *cbs = menu_entries_get_actiondata_at_offset(selection_buf, selection); if (cbs->enum_idx != MSG_UNKNOWN) { ret = menu_hash_get_help_enum(cbs->enum_idx, menu->menu_state.msg, sizeof(menu->menu_state.msg)); } else { unsigned type = 0; enum msg_hash_enums enum_idx = MSG_UNKNOWN; menu_entries_get_at_offset(selection_buf, selection, NULL, NULL, &type, NULL, NULL); switch (type) { case FILE_TYPE_FONT: enum_idx = MENU_ENUM_LABEL_FILE_BROWSER_FONT; break; case FILE_TYPE_RDB: enum_idx = MENU_ENUM_LABEL_FILE_BROWSER_RDB; break; case FILE_TYPE_OVERLAY: enum_idx = MENU_ENUM_LABEL_FILE_BROWSER_OVERLAY; break; case FILE_TYPE_CHEAT: enum_idx = MENU_ENUM_LABEL_FILE_BROWSER_CHEAT; break; case FILE_TYPE_SHADER_PRESET: enum_idx = MENU_ENUM_LABEL_FILE_BROWSER_SHADER_PRESET; break; case FILE_TYPE_SHADER: enum_idx = MENU_ENUM_LABEL_FILE_BROWSER_SHADER; break; case FILE_TYPE_REMAP: enum_idx = MENU_ENUM_LABEL_FILE_BROWSER_REMAP; break; case FILE_TYPE_RECORD_CONFIG: enum_idx = MENU_ENUM_LABEL_FILE_BROWSER_RECORD_CONFIG; break; case FILE_TYPE_CURSOR: enum_idx = MENU_ENUM_LABEL_FILE_BROWSER_CURSOR; break; case FILE_TYPE_CONFIG: enum_idx = MENU_ENUM_LABEL_FILE_BROWSER_CONFIG; break; case FILE_TYPE_CARCHIVE: enum_idx = MENU_ENUM_LABEL_FILE_BROWSER_COMPRESSED_ARCHIVE; break; case FILE_TYPE_DIRECTORY: enum_idx = MENU_ENUM_LABEL_FILE_BROWSER_DIRECTORY; break; case FILE_TYPE_VIDEOFILTER: /* TODO/FIXME */ case FILE_TYPE_AUDIOFILTER: /* TODO/FIXME */ case FILE_TYPE_SHADER_SLANG: /* TODO/FIXME */ case FILE_TYPE_SHADER_GLSL: /* TODO/FIXME */ case FILE_TYPE_SHADER_HLSL: /* TODO/FIXME */ case FILE_TYPE_SHADER_CG: /* TODO/FIXME */ case FILE_TYPE_SHADER_PRESET_GLSLP: /* TODO/FIXME */ case FILE_TYPE_SHADER_PRESET_HLSLP: /* TODO/FIXME */ case FILE_TYPE_SHADER_PRESET_CGP: /* TODO/FIXME */ case FILE_TYPE_SHADER_PRESET_SLANGP: /* TODO/FIXME */ case FILE_TYPE_PLAIN: enum_idx = MENU_ENUM_LABEL_FILE_BROWSER_PLAIN_FILE; break; default: break; } if (enum_idx != MSG_UNKNOWN) ret = menu_hash_get_help_enum(enum_idx, menu->menu_state.msg, sizeof(menu->menu_state.msg)); } } BIT64_SET(menu->state, MENU_STATE_RENDER_MESSAGEBOX); BIT64_SET(menu->state, MENU_STATE_POST_ITERATE); if (action == MENU_ACTION_OK || action == MENU_ACTION_CANCEL) { BIT64_SET(menu->state, MENU_STATE_POP_STACK); } menu_dialog_set_active(false); break; case ITERATE_TYPE_DEFAULT: /* FIXME: Crappy hack, needed for mouse controls * to not be completely broken in case we press back. * * We need to fix this entire mess, mouse controls * should not rely on a hack like this in order to work. */ selection = MAX(MIN(selection, (menu_entries_get_size() - 1)), 0); menu_entry_get(&entry, 0, selection, NULL, false); ret = menu_entry_action(&entry, selection, (enum menu_action)action); if (ret) goto end; BIT64_SET(menu->state, MENU_STATE_POST_ITERATE); /* Have to defer it so we let settings refresh. */ menu_dialog_push(); break; } BIT64_SET(menu->state, MENU_STATE_BLIT); if (BIT64_GET(menu->state, MENU_STATE_POP_STACK)) { size_t new_selection_ptr = selection; menu_entries_pop_stack(&new_selection_ptr, 0, 0); menu_navigation_ctl(MENU_NAVIGATION_CTL_SET_SELECTION, &selection); } if (BIT64_GET(menu->state, MENU_STATE_POST_ITERATE)) menu_input_post_iterate(&ret, action); end: if (ret) return -1; return 0; }
void menu_entry_pathdir_get_value(uint32_t i, char *s, size_t len) { menu_entry_t entry = {{0}}; menu_entry_get(&entry, i, NULL, true); strlcpy(s, entry.value, len); }
static int action_iterate_main(const char *label, unsigned action) { menu_entry_t entry; static bool did_messagebox = false; char msg[PATH_MAX_LENGTH] = {0}; enum action_iterate_type iterate_type; size_t selected; size_t *pop_selected = NULL; bool do_messagebox = false; bool do_pop_stack = false; bool do_post_iterate = false; bool do_render = false; int ret = 0; menu_handle_t *menu = menu_driver_get_ptr(); menu_navigation_t *nav = menu_navigation_get_ptr(); menu_display_t *disp = menu_display_get_ptr(); menu_list_t *menu_list = menu_list_get_ptr(); uint32_t hash = menu_hash_calculate(label); if (!menu || !menu_list) return 0; iterate_type = action_iterate_type(hash); switch (iterate_type) { case ITERATE_TYPE_HELP: ret = action_iterate_help(msg, sizeof(msg), label); pop_selected = NULL; do_messagebox = true; do_pop_stack = true; do_post_iterate = true; if (ret == 1) action = MENU_ACTION_OK; break; case ITERATE_TYPE_BIND: if (menu_input_bind_iterate()) menu_list_pop_stack(menu_list); break; case ITERATE_TYPE_VIEWPORT: ret = action_iterate_menu_viewport(msg, sizeof(msg), label, action, hash); break; case ITERATE_TYPE_INFO: ret = action_iterate_info(msg, sizeof(msg), label); pop_selected = &nav->selection_ptr; do_messagebox = true; do_pop_stack = true; do_post_iterate = true; break; case ITERATE_TYPE_MESSAGE: strlcpy(msg, disp->message_contents, sizeof(msg)); pop_selected = &nav->selection_ptr; do_messagebox = true; do_pop_stack = true; break; case ITERATE_TYPE_DEFAULT: selected = menu_navigation_get_current_selection(); /* FIXME: selected > selection_buf->list->size, i don't know why. */ selected = max(min(selected, menu_list_get_size(menu_list)-1), 0); menu_entry_get(&entry, selected, NULL, false); ret = menu_entry_action(&entry, selected, (enum menu_action)action); if (ret) return ret; do_post_iterate = true; do_render = true; /* Have to defer it so we let settings refresh. */ if (menu->push_help_screen) { menu_displaylist_info_t info = {0}; info.list = menu_list->menu_stack; strlcpy(info.label, menu_hash_to_str(MENU_LABEL_HELP), sizeof(info.label)); menu_displaylist_push_list(&info, DISPLAYLIST_HELP); } break; } did_messagebox = did_messagebox != do_messagebox; if (did_messagebox) menu_display_fb_set_dirty(); if (do_messagebox) menu_driver_render_messagebox(msg); if (do_pop_stack && action == MENU_ACTION_OK) menu_list_pop(menu_list->menu_stack, pop_selected); if (do_post_iterate) menu_input_post_iterate(&ret, action); if (do_render) menu_driver_render(); return ret; }
/** * menu_iterate: * @input : input sample for this frame * @old_input : input sample of the previous frame * @trigger_input : difference' input sample - difference * between 'input' and 'old_input' * * Runs RetroArch menu for one frame. * * Returns: 0 on success, -1 if we need to quit out of the loop. **/ int generic_menu_iterate(enum menu_action action) { size_t selection; menu_entry_t entry; enum action_iterate_type iterate_type; const char *label = NULL; int ret = 0; uint32_t label_hash = 0; uint32_t hash = 0; menu_handle_t *menu = menu_driver_get_ptr(); file_list_t *menu_stack = menu_entries_get_menu_stack_ptr(); file_list_t *selection_buf = menu_entries_get_selection_buf_ptr(); menu_entries_get_last_stack(NULL, &label, NULL, NULL); if (!menu) return 0; if (!menu_navigation_ctl(MENU_NAVIGATION_CTL_GET_SELECTION, &selection)) return 0; menu->menu_state.msg[0] = '\0'; hash = menu_hash_calculate(label); iterate_type = action_iterate_type(hash); if (action != MENU_ACTION_NOOP || menu_entries_needs_refresh() || menu_display_ctl(MENU_DISPLAY_CTL_UPDATE_PENDING, NULL)) { BIT64_SET(menu->state, MENU_STATE_RENDER_FRAMEBUFFER); } switch (iterate_type) { case ITERATE_TYPE_HELP: ret = action_iterate_help(menu->menu_state.msg, sizeof(menu->menu_state.msg), label); BIT64_SET(menu->state, MENU_STATE_RENDER_MESSAGEBOX); BIT64_SET(menu->state, MENU_STATE_POST_ITERATE); if (ret == 1 || action == MENU_ACTION_OK) BIT64_SET(menu->state, MENU_STATE_POP_STACK); break; case ITERATE_TYPE_BIND: if (menu_input_key_bind_iterate(menu->menu_state.msg, sizeof(menu->menu_state.msg))) { menu_entries_pop_stack(&selection); menu_navigation_ctl(MENU_NAVIGATION_CTL_SET_SELECTION, &selection); } else BIT64_SET(menu->state, MENU_STATE_RENDER_MESSAGEBOX); break; case ITERATE_TYPE_INFO: { menu_file_list_cbs_t *cbs = menu_entries_get_actiondata_at_offset(selection_buf, selection); rarch_setting_t *setting = cbs->setting; if (setting) { char needle[PATH_MAX_LENGTH]; strlcpy(needle, menu_setting_get_name(setting), sizeof(needle)); label_hash = menu_hash_calculate(needle); } ret = menu_hash_get_help(label_hash, menu->menu_state.msg, sizeof(menu->menu_state.msg)); } BIT64_SET(menu->state, MENU_STATE_RENDER_MESSAGEBOX); BIT64_SET(menu->state, MENU_STATE_POST_ITERATE); if (action == MENU_ACTION_OK) BIT64_SET(menu->state, MENU_STATE_POP_STACK); break; case ITERATE_TYPE_DEFAULT: /* FIXME: Crappy hack, needed for mouse controls to not be completely broken * in case we press back. * * We need to fix this entire mess, mouse controls should not rely on a * hack like this in order to work. */ selection = max(min(selection, (menu_entries_get_size() - 1)), 0); menu_entry_get(&entry, selection, NULL, false); ret = menu_entry_action(&entry, selection, (enum menu_action)action); if (ret) goto end; BIT64_SET(menu->state, MENU_STATE_POST_ITERATE); /* Have to defer it so we let settings refresh. */ if (menu->push_help_screen) { menu_displaylist_info_t info = {0}; info.list = menu_stack; strlcpy(info.label, menu_hash_to_str(MENU_LABEL_HELP), sizeof(info.label)); menu_displaylist_push_list(&info, DISPLAYLIST_HELP); } break; } BIT64_SET(menu->state, MENU_STATE_BLIT); if (BIT64_GET(menu->state, MENU_STATE_POP_STACK)) { size_t new_selection_ptr = selection; menu_entries_pop_stack(&new_selection_ptr); menu_navigation_ctl(MENU_NAVIGATION_CTL_SET_SELECTION, &selection); } if (BIT64_GET(menu->state, MENU_STATE_POST_ITERATE)) menu_input_post_iterate(&ret, action); end: if (ret) return -1; return 0; }
static void xui_render(void *data, bool is_idle) { size_t end, i, selection, fb_pitch; unsigned fb_width, fb_height; char title[PATH_MAX_LENGTH] = {0}; const char *dir = NULL; const char *label = NULL; unsigned menu_type = 0; uint64_t frame_count = xui_frame_count; bool msg_force = menu_display_get_msg_force(); menu_display_get_fb_size(&fb_width, &fb_height, &fb_pitch); if ( menu_entries_ctl(MENU_ENTRIES_CTL_NEEDS_REFRESH, NULL) && menu_driver_is_alive() && !msg_force ) return; menu_display_unset_framebuffer_dirty_flag(); menu_animation_ctl(MENU_ANIMATION_CTL_CLEAR_ACTIVE, NULL); xui_render_background(); if (XuiHandleIsValid(m_menutitle)) { menu_animation_ctx_ticker_t ticker; menu_entries_get_title(title, sizeof(title)); mbstowcs(strw_buffer, title, sizeof(strw_buffer) / sizeof(wchar_t)); XuiTextElementSetText(m_menutitle, strw_buffer); ticker.s = title; ticker.len = RXUI_TERM_WIDTH(fb_width) - 3; ticker.idx = (unsigned int)frame_count / 15; ticker.str = title; ticker.selected = true; menu_animation_ticker(&ticker); } if (XuiHandleIsValid(m_menutitle)) { if ( menu_entries_get_core_title(title, sizeof(title)) == 0) { mbstowcs(strw_buffer, title, sizeof(strw_buffer) / sizeof(wchar_t)); XuiTextElementSetText(m_menutitlebottom, strw_buffer); } } end = menu_entries_get_size(); for (i = 0; i < end; i++) { menu_entry_t entry; char *entry_path = NULL; char entry_value[PATH_MAX_LENGTH] = {0}; wchar_t msg_right[PATH_MAX_LENGTH] = {0}; wchar_t msg_left[PATH_MAX_LENGTH] = {0}; menu_entry_init(&entry); menu_entry_get(&entry, 0, i, NULL, true); menu_entry_get_value(&entry, entry_value, sizeof(entry_value)); entry_path = menu_entry_get_path(&entry); mbstowcs(msg_left, entry_path, sizeof(msg_left) / sizeof(wchar_t)); mbstowcs(msg_right, entry_value, sizeof(msg_right) / sizeof(wchar_t)); xui_set_list_text(i, msg_left, msg_right); menu_entry_free(&entry); if (!string_is_empty(entry_path)) free(entry_path); } selection = menu_navigation_get_selection(); XuiListSetCurSelVisible(m_menulist, selection); if (menu_input_dialog_get_display_kb()) { char msg[1024] = {0}; const char *str = menu_input_dialog_get_buffer(); const char *label = menu_input_dialog_get_label_buffer(); snprintf(msg, sizeof(msg), "%s\n%s", label, str); xui_render_messagebox(NULL, msg); } }
/** * menu_iterate: * @input : input sample for this frame * @old_input : input sample of the previous frame * @trigger_input : difference' input sample - difference * between 'input' and 'old_input' * * Runs RetroArch menu for one frame. * * Returns: 0 on success, -1 if we need to quit out of the loop. **/ int menu_iterate(bool render_this_frame, unsigned action) { menu_entry_t entry; enum action_iterate_type iterate_type; size_t selected; const char *label = NULL; int ret = 0; uint32_t hash = 0; menu_handle_t *menu = menu_driver_get_ptr(); menu_navigation_t *nav = menu_navigation_get_ptr(); menu_display_t *disp = menu_display_get_ptr(); menu_list_t *menu_list = menu_list_get_ptr(); if (render_this_frame) menu_animation_update_time(); menu_list_get_last_stack(menu_list, NULL, &label, NULL, NULL); if (!menu || !menu_list) return 0; menu->state.fb_is_dirty = false; menu->state.do_messagebox = false; menu->state.do_render = false; menu->state.do_pop_stack = false; menu->state.do_post_iterate = false; menu->state.pop_selected = NULL; menu->state.msg[0] = '\0'; hash = menu_hash_calculate(label); iterate_type = action_iterate_type(hash); if (action != MENU_ACTION_NOOP || menu_entries_needs_refresh() || menu_display_update_pending()) { if (render_this_frame) menu->state.fb_is_dirty = true; } switch (iterate_type) { case ITERATE_TYPE_HELP: ret = action_iterate_help(menu->state.msg, sizeof(menu->state.msg), label); if (render_this_frame) menu->state.do_render = true; menu->state.pop_selected = NULL; menu->state.do_messagebox = true; menu->state.do_pop_stack = true; menu->state.do_post_iterate = true; if (ret == 1) action = MENU_ACTION_OK; break; case ITERATE_TYPE_BIND: if (menu_input_bind_iterate(menu->state.msg, sizeof(menu->state.msg))) menu_list_pop_stack(menu_list, &nav->selection_ptr); else menu->state.do_messagebox = true; if (render_this_frame) menu->state.do_render = true; break; case ITERATE_TYPE_VIEWPORT: ret = action_iterate_menu_viewport(menu->state.msg, sizeof(menu->state.msg), label, action, hash); if (render_this_frame) menu->state.do_render = true; menu->state.do_messagebox = true; break; case ITERATE_TYPE_INFO: ret = action_iterate_info(menu->state.msg, sizeof(menu->state.msg), label); menu->state.pop_selected = &nav->selection_ptr; if (render_this_frame) menu->state.do_render = true; menu->state.do_messagebox = true; menu->state.do_pop_stack = true; menu->state.do_post_iterate = true; break; case ITERATE_TYPE_MESSAGE: strlcpy(menu->state.msg, disp->message_contents, sizeof(menu->state.msg)); menu->state.pop_selected = &nav->selection_ptr; menu->state.do_messagebox = true; menu->state.do_pop_stack = true; break; case ITERATE_TYPE_DEFAULT: selected = menu_navigation_get_selection(nav); /* FIXME: selected > selection_buf->list->size, i don't know why. */ selected = max(min(selected, menu_list_get_size(menu_list)-1), 0); menu_entry_get(&entry, selected, NULL, false); ret = menu_entry_action(&entry, selected, (enum menu_action)action); if (ret) goto end; menu->state.do_post_iterate = true; if (render_this_frame) menu->state.do_render = true; /* Have to defer it so we let settings refresh. */ if (menu->push_help_screen) { menu_displaylist_info_t info = {0}; info.list = menu_list->menu_stack; strlcpy(info.label, menu_hash_to_str(MENU_LABEL_HELP), sizeof(info.label)); menu_displaylist_push_list(&info, DISPLAYLIST_HELP); } break; } if (menu->state.do_pop_stack && action == MENU_ACTION_OK) menu_list_pop_stack(menu_list, menu->state.pop_selected); if (menu->state.do_post_iterate) menu_input_post_iterate(&ret, action); end: if (ret) return -1; return 0; }