static void glui_render_menu_list(glui_handle_t *glui, menu_handle_t *menu, uint32_t normal_color, uint32_t hover_color) { unsigned width, height; size_t i = 0; uint64_t frame_count = video_driver_get_frame_count(); size_t end = menu_entries_get_end(); menu_display_t *disp = menu_display_get_ptr(); if (!menu_display_update_pending()) return; video_driver_get_size(&width, &height); glui->list_block.carr.coords.vertices = 0; for (i = menu_entries_get_start(); i < end; i++) { bool entry_selected; char entry_path[PATH_MAX_LENGTH]; char entry_value[PATH_MAX_LENGTH]; char message[PATH_MAX_LENGTH]; char entry_title_buf[PATH_MAX_LENGTH]; char type_str_buf[PATH_MAX_LENGTH]; int y = disp->header_height - menu->scroll_y + (glui->line_height * i); if (y > (int)height || ((y + (int)glui->line_height) < 0)) continue; entry_path[0] = '\0'; entry_value[0] = '\0'; message[0] = '\0'; entry_title_buf[0] = '\0'; type_str_buf[0] = '\0'; entry_selected = menu_entry_is_currently_selected(i); menu_entry_get_value(i, entry_value, sizeof(entry_value)); menu_entry_get_path(i, entry_path, sizeof(entry_path)); menu_animation_ticker_line(entry_title_buf, glui->ticker_limit, frame_count / 100, entry_path, entry_selected); menu_animation_ticker_line(type_str_buf, glui->ticker_limit, frame_count / 100, entry_value, entry_selected); strlcpy(message, entry_title_buf, sizeof(message)); glui_blit_line(glui->margin, y, message, entry_selected ? hover_color : normal_color, TEXT_ALIGN_LEFT); glui_blit_line(width - glui->margin, y, type_str_buf, entry_selected ? hover_color : normal_color, TEXT_ALIGN_RIGHT); } }
int menu_entry_iterate(unsigned action) { const char *label = NULL; menu_file_list_cbs_t *cbs = NULL; menu_list_t *menu_list = menu_list_get_ptr(); if (!menu_list) return -1; if (action != MENU_ACTION_NOOP || menu_entries_needs_refresh() || menu_display_update_pending()) menu_display_fb_set_dirty(); cbs = (menu_file_list_cbs_t*)menu_list_get_last_stack_actiondata(menu_list); menu_list_get_last_stack(menu_list, NULL, &label, NULL, NULL); if (cbs && cbs->action_iterate) return cbs->action_iterate(label, action); return -1; }
static void glui_render_menu_list(glui_handle_t *glui, menu_handle_t *menu, uint32_t normal_color, uint32_t hover_color) { unsigned width, height; size_t i = 0; uint64_t *frame_count = video_driver_get_frame_count(); size_t end = menu_entries_get_end(); menu_display_t *disp = menu_display_get_ptr(); menu_entries_t *entries = menu_entries_get_ptr(); if (!menu_display_update_pending()) return; video_driver_get_size(&width, &height); glui->list_block.carr.coords.vertices = 0; for (i = menu_entries_get_start(); i < end; i++) { bool entry_selected; menu_entry_t entry; int y = disp->header_height - menu->scroll_y + (glui->line_height * i); if (y > (int)height || ((y + (int)glui->line_height) < 0)) continue; menu_entries_get(i, &entry); entry_selected = entries->navigation.selection_ptr == i; glui_render_label_value(glui, y, width, *frame_count / 40, entry_selected ? hover_color : normal_color, entry_selected, entry.path, entry.value); } }
/** * 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; }