/** * 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(retro_input_t input, retro_input_t old_input, retro_input_t trigger_input) { int32_t ret = 0; unsigned action = 0; runloop_t *runloop = rarch_main_get_ptr(); menu_display_t *disp = menu_display_get_ptr(); menu_input_t *menu_input = menu_input_get_ptr(); menu_animation_update_time(disp->animation); menu_input->joypad.state = menu_input_frame(input, trigger_input); action = menu_input->joypad.state; ret = menu_entry_iterate(action); if (menu_driver_alive() && !runloop->is_idle) menu_display_fb(); menu_driver_set_texture(); if (ret) return -1; 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 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; }