예제 #1
0
파일: glui.c 프로젝트: jwdehart/RetroArch
static void glui_draw_scrollbar(gl_t *gl, unsigned width, unsigned height, GRfloat *coord_color)
{
   float content_height, total_height, scrollbar_height, y;
   int scrollbar_width  = 4;
   glui_handle_t *glui  = NULL;
   menu_handle_t *menu  = menu_driver_get_ptr();
   menu_display_t *disp = menu_display_get_ptr();

   if (!menu)
      return;

   glui                 = (glui_handle_t*)menu->userdata;
   content_height       = menu_entries_get_end() * glui->line_height;
   total_height         = height - disp->header_height * 2;
   scrollbar_height     = total_height / (content_height / total_height);
   y                    = total_height * menu->scroll_y / content_height;

   if (content_height >= total_height)
      glui_render_quad(gl,
            width - scrollbar_width,
            disp->header_height + y,
            scrollbar_width,
            scrollbar_height,
            width, height,
            coord_color);
}
예제 #2
0
static void glui_navigation_set(bool scroll)
{
   menu_display_t *disp = menu_display_get_ptr();
   menu_handle_t *menu  = menu_driver_get_ptr();
   float scroll_pos = 0;

   if (!menu || !disp || !scroll)
      return;

   scroll_pos = glui_get_scroll();

   if (menu->userdata)
   {
      unsigned height = 0, num_lines = 0, end = 0;
      glui_handle_t *glui    = (glui_handle_t*)menu->userdata;
      menu_navigation_t *nav = menu_navigation_get_ptr();

      video_driver_get_size(NULL, &height);
      num_lines = height / glui->line_height;
      end       = menu_entries_get_end();

      if (nav->selection_ptr < num_lines / 2 || end <= num_lines)
         menu_entries_set_start(0);
      else if (nav->selection_ptr < (end - num_lines / 2))
         menu_entries_set_start(nav->selection_ptr - num_lines / 2);
      else
         menu_entries_set_start(end - num_lines);

      if (menu_entries_get_start() >= 5)
         menu_entries_set_start(menu_entries_get_start() - 5);
   }

   menu_animation_push(disp->animation, 10, scroll_pos,
         &menu->scroll_y, EASING_IN_OUT_QUAD, -1, NULL);
}
예제 #3
0
파일: menu.c 프로젝트: 6lackmag3/RetroArch
/**
 * menu_free:
 * @menu                     : Menu handle.
 *
 * Frees a menu handle
 **/
void menu_free(menu_handle_t *menu)
{
   global_t        *global    = global_get_ptr();
   menu_display_t    *disp    = menu_display_get_ptr();
   if (!menu || !disp)
      return;

   if (menu->playlist)
      content_playlist_free(menu->playlist);
   menu->playlist = NULL;
  
   menu_shader_free(menu);

   menu_driver_free(menu);

#ifdef HAVE_DYNAMIC
   libretro_free_system_info(&global->menu.info);
#endif

   menu_display_free(menu);

   menu_entries_free();

   event_command(EVENT_CMD_HISTORY_DEINIT);

   if (global->core_info.list)
      core_info_list_free(global->core_info.list);

   if (global->core_info.current)
      free(global->core_info.current);
   global->core_info.current = NULL;

   free(menu);
}
예제 #4
0
static void glui_draw_scrollbar(gl_t *gl)
{
   unsigned width, height;
   float content_height, total_height, scrollbar_height, y;
   int scrollbar_width  = 4;
   glui_handle_t *glui  = NULL;
   menu_handle_t *menu  = menu_driver_get_ptr();
   menu_display_t *disp = menu_display_get_ptr();

   if (!menu)
      return;

   video_driver_get_size(&width, &height);

   glui                 = (glui_handle_t*)menu->userdata;
   content_height       = menu_entries_get_end() * glui->line_height;
   total_height         = height - disp->header_height * 2;
   scrollbar_height     = total_height / (content_height / total_height);
   y                    = total_height * menu->scroll_y / content_height;

   if (content_height < total_height)
      return;

   glui_render_quad(gl,
         width - scrollbar_width,
         disp->header_height + y,
         scrollbar_width,
         scrollbar_height,
         1, 1, 1, 1);
}
예제 #5
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(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;
}
예제 #6
0
menu_animation_t *menu_animation_get_ptr(void)
{
   menu_display_t *disp = menu_display_get_ptr();
   if (!disp)
      return NULL;
   return disp->animation;
}
예제 #7
0
파일: glui.c 프로젝트: bentley/RetroArch
static void glui_layout(menu_handle_t *menu, glui_handle_t *glui)
{
   menu_display_t *disp = menu_display_get_ptr();
   float scale_factor;
   unsigned width, height;
   video_driver_get_size(&width, &height);

   /* Mobiles platforms may have very small display metrics coupled to a high
      resolution, so we should be dpi aware to ensure the entries hitboxes are big
      enough. On desktops, we just care about readability, with every widget size
      proportional to the display width. */
   scale_factor = menu_display_get_dpi();

   glui->line_height            = scale_factor / 3;
   glui->margin                 = scale_factor / 6;
   menu->display.header_height  = scale_factor / 3;
   menu->display.font.size      = scale_factor / 10;
   /* we assume the average glyph aspect ratio is close to 3:4 */
   glui->glyph_width            = menu->display.font.size * 3/4;

   glui_font(menu);

   if (disp && disp->font.buf) /* calculate a more realistic ticker_limit */
   {
      driver_t *driver   = driver_get_ptr();
      int m_width = driver->font_osd_driver->get_message_width(disp->font.buf, "a", 1, 1);

      if (m_width)
         glui->glyph_width = m_width;
   }
}
예제 #8
0
static menu_display_ctx_driver_t *menu_display_context_get_ptr(void)
{
   menu_display_t *disp = menu_display_get_ptr();
   if (!disp)
      return NULL;
   return disp->display_ctx;
}
예제 #9
0
파일: menu.c 프로젝트: 6lackmag3/RetroArch
void menu_common_load_content(bool persist, enum rarch_core_type type)
{
   menu_display_t *disp         = menu_display_get_ptr();
   menu_list_t *menu_list       = menu_list_get_ptr();
   if (!menu_list)
      return;

   switch (type)
   {
      case CORE_TYPE_PLAIN:
      case CORE_TYPE_DUMMY:
         event_command(persist ? EVENT_CMD_LOAD_CONTENT_PERSIST : EVENT_CMD_LOAD_CONTENT);
         break;
#ifdef HAVE_FFMPEG
      case CORE_TYPE_FFMPEG:
         event_command(EVENT_CMD_LOAD_CONTENT_FFMPEG);
         break;
#endif
      case CORE_TYPE_IMAGEVIEWER:
#ifdef HAVE_IMAGEVIEWER
         event_command(EVENT_CMD_LOAD_CONTENT_IMAGEVIEWER);
#endif
         break;
   }

   menu_list_flush_stack(menu_list, NULL, MENU_SETTINGS);
   disp->msg_force = true;

   menu_common_push_content_settings();
}
예제 #10
0
bool menu_display_init_main_font(void *data,
      const char *font_path, float font_size)
{
   bool      ret;
   driver_t    *driver  = driver_get_ptr();
   void        *video   = video_driver_get_ptr(NULL);
   menu_display_t *disp = menu_display_get_ptr();

   if (!disp)
      return false;

   if (disp->font.buf)
      menu_display_free_main_font();

   ret = menu_display_font_init_first(
         (const void**)&driver->font_osd_driver,
         &disp->font.buf, video,
         font_path, font_size);

   if (ret)
      disp->font.size = font_size;
   else
      disp->font.buf = NULL;

   return ret;
}
예제 #11
0
static void glui_blit_line(float x, float y,
      const char *message, uint32_t color, enum text_alignment text_align)
{
   unsigned width, height;
   glui_handle_t *glui       = NULL;
   struct font_params params = {0};
   menu_handle_t *menu       = menu_driver_get_ptr();
   menu_display_t *disp      = menu_display_get_ptr();

   if (!menu)
      return;

   video_driver_get_size(&width, &height);

   glui = (glui_handle_t*)menu->userdata;

   params.x           = x / width;
   params.y           = 1.0f - (y + glui->line_height/2 + disp->font.size/3) 
                        / height;
   params.scale       = 1.0;
   params.color       = color;
   params.full_screen = true;
   params.text_align  = text_align;

   video_driver_set_osd_msg(message, &params, disp->font.buf);
}
예제 #12
0
bool menu_display_init(void)
{
   menu_display_t *disp = menu_display_get_ptr();
   if (!disp)
      return false;

   retro_assert(disp->msg_queue = msg_queue_new(8));

   return true;
}
예제 #13
0
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);
   }
}
예제 #14
0
파일: glui.c 프로젝트: dalter/RetroArch
static void glui_font(menu_handle_t *menu)
{
   const char *font_path = NULL;
   settings_t *settings  = config_get_ptr();
   menu_display_t *disp  = menu_display_get_ptr();

   font_path = settings->video.font_enable ? settings->video.font_path : NULL;

   if (!menu_display_init_main_font(menu, font_path, disp->font.size))
      RARCH_ERR("Failed to load font.");
}
예제 #15
0
void menu_display_free_main_font(void)
{
   driver_t     *driver = driver_get_ptr();
   menu_display_t *disp = menu_display_get_ptr();
    
   if (disp && disp->font.buf)
   {
      driver->font_osd_driver->free(disp->font.buf);
      disp->font.buf = NULL;
   }
}
예제 #16
0
파일: glui.c 프로젝트: jwdehart/RetroArch
static void glui_navigation_set(bool scroll)
{
   menu_display_t *disp = menu_display_get_ptr();
   menu_handle_t *menu  = menu_driver_get_ptr();
   float     scroll_pos = glui_get_scroll();

   if (!menu || !disp || !scroll)
      return;

   menu_animation_push(disp->animation, 10, scroll_pos,
         &menu->scroll_y, EASING_IN_OUT_QUAD, -1, NULL);
}
예제 #17
0
void menu_common_load_content(bool persist)
{
   menu_display_t *disp   = menu_display_get_ptr();
   menu_list_t *menu_list = menu_list_get_ptr();
   if (!menu_list)
      return;

   event_command(persist ? EVENT_CMD_LOAD_CONTENT_PERSIST : EVENT_CMD_LOAD_CONTENT);

   menu_list_flush_stack(menu_list, NULL, MENU_SETTINGS);
   disp->msg_force = true;
}
예제 #18
0
bool menu_display_font_bind_block(void *data, const void *font_data, void *userdata)
{
   const struct font_renderer *font_driver = 
      (const struct font_renderer*)font_data;
   menu_display_t *disp = menu_display_get_ptr();
   if (!disp || !font_driver || !font_driver->bind_block)
      return false;

   font_driver->bind_block(disp->font.buf, userdata);

   return true;
}
예제 #19
0
파일: menu.c 프로젝트: Hobbes43/RetroArch
int menu_common_load_content(
      const char *core_path, const char *fullpath,
      bool persist, enum rarch_core_type type)
{
   settings_t *settings         = config_get_ptr();
   global_t *global             = global_get_ptr();
   menu_display_t *disp         = menu_display_get_ptr();
   menu_list_t *menu_list       = menu_list_get_ptr();
   enum event_command cmd       = EVENT_CMD_NONE;

   if (core_path)
   {
      strlcpy(settings->libretro, core_path, sizeof(settings->libretro));
      event_command(EVENT_CMD_LOAD_CORE);
   }

   if (fullpath)
   {
      strlcpy(global->path.fullpath, fullpath, sizeof(global->path.fullpath));
   }

   switch (type)
   {
      case CORE_TYPE_PLAIN:
      case CORE_TYPE_DUMMY:
         cmd = persist ? EVENT_CMD_LOAD_CONTENT_PERSIST : EVENT_CMD_LOAD_CONTENT;
         break;
#ifdef HAVE_FFMPEG
      case CORE_TYPE_FFMPEG:
         cmd = EVENT_CMD_LOAD_CONTENT_FFMPEG;
         break;
#endif
      case CORE_TYPE_IMAGEVIEWER:
#ifdef HAVE_IMAGEVIEWER
         cmd = EVENT_CMD_LOAD_CONTENT_IMAGEVIEWER;
#endif
         break;
   }

   if (cmd != EVENT_CMD_NONE)
      event_command(cmd);

   menu_list_flush_stack(menu_list, NULL, MENU_SETTINGS);
   disp->msg_force = true;

   generic_action_ok_displaylist_push("",
         "", 0, 0, 0, ACTION_OK_DL_CONTENT_SETTINGS);

   return -1;
}
예제 #20
0
bool menu_display_font_flush_block(void *data, const void *font_data)
{
   const struct font_renderer *font_driver = 
      (const struct font_renderer*)font_data;
   menu_handle_t *menu = (menu_handle_t*)data;
   menu_display_t *disp = menu_display_get_ptr();
   if (!font_driver || !font_driver->flush)
      return false;

   font_driver->flush(disp->font.buf);

   return menu_display_font_bind_block(menu,
         font_driver, NULL);
}
예제 #21
0
void menu_display_free(void)
{
   menu_display_t *disp = menu_display_get_ptr();
   if (!disp)
      return;

   if (disp->msg_queue)
      msg_queue_free(disp->msg_queue);
   disp->msg_queue = NULL;

   menu_animation_free();

   menu_display_fb_free(&frame_buf_state);
   memset(&frame_buf_state,    0, sizeof(menu_framebuf_t));
   memset(&menu_display_state, 0, sizeof(menu_display_t));
}
예제 #22
0
const bool menu_display_driver_init_first(void)
{
   unsigned i;
   menu_display_t *disp = menu_display_get_ptr();

   for (i = 0; menu_display_ctx_drivers[i]; i++)
   {
      if (!menu_display_check_compatibility(menu_display_ctx_drivers[i]->type))
         continue;

      RARCH_LOG("Found menu display driver: \"%s\".\n",
            menu_display_ctx_drivers[i]->ident);
      disp->display_ctx = menu_display_ctx_drivers[i];
      return true;
   }

   return false;
}
예제 #23
0
/**
 * menu_load_content:
 *
 * Loads content into currently selected core.
 * Will also optionally push the content entry to the history playlist.
 *
 * Returns: true (1) if successful, otherwise false (0).
 **/
bool menu_load_content(void)
{
   menu_handle_t *menu  = menu_driver_get_ptr();
   menu_display_t *disp = menu_display_get_ptr();
   driver_t *driver     = driver_get_ptr();
   global_t *global     = global_get_ptr();

   /* redraw menu frame */
   if (disp)
      disp->msg_force = true;

   menu_entry_iterate(MENU_ACTION_NOOP);

   menu_display_fb();

   if (!(main_load_content(0, NULL, NULL, menu_environment_get,
         driver->frontend_ctx->process_args)))
   {
      char name[PATH_MAX_LENGTH] = {0};
      char msg[PATH_MAX_LENGTH]  = {0};

      fill_pathname_base(name, global->fullpath, sizeof(name));
      snprintf(msg, sizeof(msg), "Failed to load %s.\n", name);
      rarch_main_msg_queue_push(msg, 1, 90, false);

      if (disp)
         disp->msg_force = true;

      return false;
   }

   menu_shader_manager_init(menu);

   event_command(EVENT_CMD_HISTORY_INIT);

   if (*global->fullpath || (menu && menu->load_no_content))
      menu_push_to_history_playlist();

   event_command(EVENT_CMD_VIDEO_SET_ASPECT_RATIO);
   event_command(EVENT_CMD_RESUME);

   return true;
}
예제 #24
0
파일: glui.c 프로젝트: jwdehart/RetroArch
static void glui_render_messagebox(const char *message)
{
   unsigned i;
   unsigned width, height;
   uint32_t normal_color;
   int x, y;
   struct string_list *list = NULL;
   menu_handle_t *menu      = menu_driver_get_ptr();
   menu_display_t *disp     = menu_display_get_ptr();
   settings_t *settings     = config_get_ptr();

   if (!menu || !disp || !menu->userdata)
      return;

   list = (struct string_list*)string_split(message, "\n");

   if (!list)
      return;

   if (list->elems == 0)
      goto end;

   video_driver_get_size(&width, &height);

   x = width  / 2;
   y = height / 2 - list->size * disp->font.size / 2;

   normal_color = FONT_COLOR_ARGB_TO_RGBA(settings->menu.entry_normal_color);

   for (i = 0; i < list->size; i++)
   {
      const char *msg = list->elems[i].data;
      if (msg)
         glui_blit_line(x, y + i * disp->font.size,
               width, height,
               msg, normal_color, TEXT_ALIGN_CENTER);
   }

end:
   string_list_free(list);
}
예제 #25
0
파일: glui.c 프로젝트: bentley/RetroArch
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);
   }
}
예제 #26
0
void menu_animation_update_time(void)
{
   static retro_time_t last_clock_update = 0;
   menu_display_t *disp     = menu_display_get_ptr();
   menu_animation_t *anim   = disp->animation;
   settings_t *settings     = config_get_ptr();

   anim->cur_time           = retro_get_time_usec();
   anim->delta_time         = anim->cur_time - anim->old_time;

   if (anim->delta_time >= IDEAL_DT * 4)
      anim->delta_time = IDEAL_DT * 4;
   if (anim->delta_time <= IDEAL_DT / 4)
      anim->delta_time = IDEAL_DT / 4;
   anim->old_time      = anim->cur_time;

   if (((anim->cur_time - last_clock_update) > 1000000) 
         && settings->menu.timedate_enable)
   {
      anim->is_active           = true;
      last_clock_update = anim->cur_time;
   }
}
예제 #27
0
static void glui_frame(void)
{
   unsigned width, height;
   char title[PATH_MAX_LENGTH];
   char title_buf[PATH_MAX_LENGTH];
   char title_msg[PATH_MAX_LENGTH];
   char timedate[PATH_MAX_LENGTH];
   gl_t *gl                                = NULL;
   glui_handle_t *glui                     = NULL;
   const struct font_renderer *font_driver = NULL;
   driver_t *driver                        = driver_get_ptr();
   menu_handle_t *menu                     = menu_driver_get_ptr();
   menu_animation_t *anim                  = menu_animation_get_ptr();
   menu_navigation_t *nav                  = menu_navigation_get_ptr();
   menu_display_t *disp                    = menu_display_get_ptr();
   settings_t *settings                    = config_get_ptr();
   menu_input_t *menu_input                = menu_input_get_ptr();
   uint64_t frame_count                    = video_driver_get_frame_count();
   const uint32_t normal_color             = FONT_COLOR_ARGB_TO_RGBA(
         settings->menu.entry_normal_color);
   const uint32_t hover_color              = FONT_COLOR_ARGB_TO_RGBA(
         settings->menu.entry_hover_color);
   const uint32_t title_color              = FONT_COLOR_ARGB_TO_RGBA(
         settings->menu.title_color);

   if (!menu || !menu->userdata)
      return;

   gl = (gl_t*)video_driver_get_ptr(NULL);

   if (!gl)
      return;

   glui = (glui_handle_t*)menu->userdata;

   if (
         menu_entries_needs_refresh()
         && menu_driver_alive() 
         && !disp->msg_force
         && !glui->box_message[0]
      )
      return;

   title[0]     = '\0';
   title_buf[0] = '\0';
   title_msg[0] = '\0';
   timedate[0]  = '\0';

   video_driver_get_size(&width, &height);

   menu_display_set_viewport();

   gl_menu_frame_background(menu, settings,
         gl, glui->textures.bg.id, 0.75f, 0.75f, false);

   menu_entries_get_title(title, sizeof(title));

   font_driver = driver->font_osd_driver;

   menu_display_font_bind_block(menu, font_driver, &glui->list_block);

   glui_render_menu_list(glui, menu, normal_color, hover_color);

   menu_display_font_flush_block(menu, font_driver);

   glui_render_quad(gl, 0,
         disp->header_height - menu->scroll_y + glui->line_height *
         nav->selection_ptr, width, glui->line_height, 1, 1, 1, 0.1);

   anim->is_active           = true;
   anim->label.is_updated    = false;

   glui_render_quad(gl, 0, 0, width,
         disp->header_height, 0.2, 0.2, 0.2, 1);

   menu_animation_ticker_line(title_buf, glui->ticker_limit,
         frame_count / 100, title, true);
   glui_blit_line(width / 2, 0, title_buf,
         title_color, TEXT_ALIGN_CENTER);

   if (menu_entries_show_back())
      glui_blit_line(glui->margin, 0, menu_hash_to_str(MENU_VALUE_BACK),
            title_color, TEXT_ALIGN_LEFT);

   glui_render_quad(gl,
         0,
         height - disp->header_height,
         width,
         disp->header_height,
         0.2, 0.2, 0.2, 1);

   glui_draw_scrollbar(gl);

   if (settings->menu.core_enable)
   {
      menu_entries_get_core_title(title_msg, sizeof(title_msg));

      glui_blit_line(glui->margin,
            height - glui->line_height, title_msg,
            title_color, TEXT_ALIGN_LEFT);
   }

   if (settings->menu.timedate_enable)
   {
      menu_display_timedate(timedate, sizeof(timedate), 0);
      glui_blit_line(width - glui->margin,
            height - glui->line_height, timedate, hover_color,
            TEXT_ALIGN_RIGHT);
   }

   if (menu_input->keyboard.display)
   {
      char msg[PATH_MAX_LENGTH];
      const char           *str = *menu_input->keyboard.buffer;
      msg[0] = '\0';

      if (!str)
         str = "";
      glui_render_quad(gl, 0, 0, width, height, 0, 0, 0, 0.75);
      snprintf(msg, sizeof(msg), "%s\n%s", menu_input->keyboard.label, str);
      glui_render_messagebox(msg);
   }

   if (glui->box_message[0] != '\0')
   {
      glui_render_quad(gl, 0, 0, width, height, 0, 0, 0, 0.75);
      glui_render_messagebox(glui->box_message);
      glui->box_message[0] = '\0';
   }

   if (settings->menu.mouse.enable)
      glui_draw_cursor(gl, menu_input->mouse.x, menu_input->mouse.y);

   gl->shader->use(gl, GL_SHADER_STOCK_BLEND);

   menu_display_unset_viewport();
}
예제 #28
0
static void glui_render(void)
{
   int bottom;
   unsigned width, height;
   glui_handle_t *glui                = NULL;
   menu_display_t *disp               = menu_display_get_ptr();
   menu_framebuf_t *frame_buf         = menu_display_fb_get_ptr();
   menu_handle_t *menu                = menu_driver_get_ptr();
   menu_input_t *menu_input           = menu_input_get_ptr();
   settings_t *settings               = config_get_ptr();

   if (!menu || !menu->userdata)
      return;

   video_driver_get_size(&width, &height);

   glui = (glui_handle_t*)menu->userdata;

   menu_animation_update(disp->animation,
         disp->animation->delta_time / IDEAL_DT);

   /* TODO/FIXME - we don't use framebuffer at all
    * for GLUI, we should refactor this dependency
    * away. */
   frame_buf->width  = width;
   frame_buf->height = height;

   if (settings->menu.pointer.enable)
   {
      menu_input->pointer.ptr =
            (menu_input->pointer.y - glui->line_height + menu->scroll_y - 16)
            / glui->line_height;

      if (menu_input->pointer.dragging)
         menu->scroll_y -= menu_input->pointer.dy;
   }

   if (settings->menu.mouse.enable)
   {
      if (menu_input->mouse.scrolldown)
         menu->scroll_y += 10;

      if (menu_input->mouse.scrollup)
         menu->scroll_y -= 10;

      menu_input->mouse.ptr =
            (menu_input->mouse.y - glui->line_height + menu->scroll_y - 16)
            / glui->line_height;
   }

   if (menu_entries_get_end() < height / glui->line_height)
      menu_entries_set_start(0);

   if (menu->scroll_y < 0)
      menu->scroll_y = 0;

   bottom = menu_entries_get_end() * glui->line_height
         - height + disp->header_height * 2;
   if (menu->scroll_y > bottom)
      menu->scroll_y = bottom;

   if (menu_entries_get_end() * glui->line_height
      < height - disp->header_height*2)
      menu->scroll_y = 0;
}
예제 #29
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;
}
예제 #30
0
int menu_entry_action(menu_entry_t *entry, unsigned i, enum menu_action action)
{
   int ret                   = 0;
   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();
   menu_file_list_cbs_t *cbs = menu_list_get_actiondata_at_offset(menu_list->selection_buf, i);

   switch (action)
   {
      case MENU_ACTION_UP:
         if (cbs && cbs->action_up)
            ret = cbs->action_up(entry->type, entry->label);
         break;
      case MENU_ACTION_DOWN:
         if (cbs && cbs->action_down)
            ret = cbs->action_down(entry->type, entry->label);
         break;
      case MENU_ACTION_SCROLL_UP:
         menu_navigation_descend_alphabet(nav, &nav->selection_ptr);
         break;
      case MENU_ACTION_SCROLL_DOWN:
         menu_navigation_ascend_alphabet(nav, &nav->selection_ptr);
         break;

      case MENU_ACTION_CANCEL:
         if (cbs && cbs->action_cancel)
            ret = cbs->action_cancel(entry->path, entry->label, entry->type, i);
         break;

      case MENU_ACTION_OK:
         if (cbs && cbs->action_ok)
            ret = cbs->action_ok(entry->path, entry->label, entry->type, i, entry->entry_idx);
         break;
      case MENU_ACTION_START:
         if (cbs && cbs->action_start)
            ret = cbs->action_start(entry->type, entry->label);
         break;
      case MENU_ACTION_LEFT:
         if (cbs && cbs->action_left)
            ret = cbs->action_left(entry->type, entry->label, false);
         break;
      case MENU_ACTION_RIGHT:
         if (cbs && cbs->action_right)
            ret = cbs->action_right(entry->type, entry->label, false);
         break;
      case MENU_ACTION_INFO:
         if (cbs && cbs->action_info)
            ret = cbs->action_info(entry->type, entry->label);
         break;
      case MENU_ACTION_SELECT:
         if (cbs && cbs->action_select)
            ret = cbs->action_select(entry->path, entry->label, entry->type, i);
         break;

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

      case MENU_ACTION_MESSAGE:
         if (disp)
            disp->msg_force = true;
         break;

      case MENU_ACTION_SEARCH:
         menu_input_search_start();
         break;

      case MENU_ACTION_SCAN:
         if (cbs && cbs->action_scan)
            ret = cbs->action_scan(entry->path, entry->label, entry->type, i);
         break;

      default:
         break;
   }

   return ret;
}