static int action_iterate_main(const char *label, unsigned action)
{
   int ret                   = 0;
   unsigned type_offset      = 0;
   const char *label_offset  = NULL;
   const char *path_offset   = NULL;
   menu_file_list_cbs_t *cbs = NULL;
   menu_handle_t *menu       = menu_driver_get_ptr();
   global_t *global          = global_get_ptr();
   if (!menu)
      return 0;

   cbs = (menu_file_list_cbs_t*)
      menu_list_get_actiondata_at_offset(menu->menu_list->selection_buf,
            menu->navigation.selection_ptr);

   menu_list_get_at_offset(menu->menu_list->selection_buf,
         menu->navigation.selection_ptr, &path_offset, &label_offset, &type_offset);

   if (!strcmp(label, "help"))
      return action_iterate_help(label, action);
   else if (!strcmp(label, "info_screen"))
      return action_iterate_info(label, action);
   else if (!strcmp(label, "load_open_zip"))
      return action_iterate_load_open_zip(label, action);
   else if (!strcmp(label, "message"))
      return action_iterate_message(label, action);
   else if (
         !strcmp(label, "custom_viewport_1") ||
         !strcmp(label, "custom_viewport_2")
         )
      return action_iterate_menu_viewport(label, action);
   else if (
         !strcmp(label, "custom_bind") ||
         !strcmp(label, "custom_bind_all") ||
         !strcmp(label, "custom_bind_defaults")
         )
   {
      if (global->menu.bind_mode_keyboard)
         return action_iterate_custom_bind_keyboard(label, action);
      else
         return action_iterate_custom_bind(label, action);
   }

   if (menu->need_refresh && !menu->nonblocking_refresh && action != MENU_ACTION_MESSAGE)
      action = MENU_ACTION_REFRESH;

   switch (action)
   {
      case MENU_ACTION_UP:
      case MENU_ACTION_DOWN:
         if (cbs && cbs->action_up_or_down)
            ret = cbs->action_up_or_down(type_offset, label_offset, action);
         break;
      case MENU_ACTION_SCROLL_UP:
         menu_navigation_descend_alphabet(&menu->navigation, &menu->navigation.selection_ptr);
         break;
      case MENU_ACTION_SCROLL_DOWN:
         menu_navigation_ascend_alphabet(&menu->navigation, &menu->navigation.selection_ptr);
         break;

      case MENU_ACTION_CANCEL:
         if (cbs && cbs->action_cancel)
            return cbs->action_cancel(path_offset, label_offset, type_offset, menu->navigation.selection_ptr);
         break;

      case MENU_ACTION_OK:
         if (cbs && cbs->action_ok)
            return cbs->action_ok(path_offset, label_offset, type_offset, menu->navigation.selection_ptr);
         break;
      case MENU_ACTION_START:
         if (cbs && cbs->action_start)
            return cbs->action_start(type_offset, label_offset, action);
         break;
      case MENU_ACTION_LEFT:
      case MENU_ACTION_RIGHT:
         if (cbs && cbs->action_toggle)
            ret = cbs->action_toggle(type_offset, label_offset, action, false);
         break;
      case MENU_ACTION_SELECT:
         if (cbs && cbs->action_select)
            ret = cbs->action_select(type_offset, label_offset, action);
         break;

      case MENU_ACTION_REFRESH:
         if (cbs && cbs->action_refresh)
            ret = cbs->action_refresh(menu->menu_list->selection_buf,
                  menu->menu_list->menu_stack);
         break;

      case MENU_ACTION_MESSAGE:
         menu->msg_force = true;
         break;

      case MENU_ACTION_SEARCH:
         menu_input_search_start();
         break;

      case MENU_ACTION_TEST:
#if 0
         menu->rdl = database_info_write_rdl_init("/home/twinaphex/roms");

         if (!menu->rdl)
            return -1;
#endif
         break;

      default:
         break;
   }

   if (ret)
      return ret;

   ret  = mouse_post_iterate(cbs, path_offset, label_offset, type_offset, action);
   ret |= pointer_post_iterate(cbs, path_offset, label_offset, type_offset, action);

   menu_driver_render();

   /* Have to defer it so we let settings refresh. */
   if (menu->push_start_screen)
   {
      menu_list_push_stack(menu->menu_list, "", "help", 0, 0);
      menu->push_start_screen = false;
   }

   return ret;
}
示例#2
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;
}
示例#3
0
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;
}