RetroArch/menu/drivers/glui.c

816 lines
22 KiB
C
Raw Normal View History

/* RetroArch - A frontend for libretro.
2015-01-07 16:46:50 +00:00
* Copyright (C) 2011-2015 - Daniel De Matteis
* Copyright (C) 2014-2015 - Jean-André Santoni
*
* RetroArch is free software: you can redistribute it and/or modify it under the terms
* of the GNU General Public License as published by the Free Software Found-
* ation, either version 3 of the License, or (at your option) any later version.
*
* RetroArch is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
* PURPOSE. See the GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along with RetroArch.
* If not, see <http://www.gnu.org/licenses/>.
*/
2015-01-26 09:54:13 +00:00
#include <stdint.h>
#include <stdlib.h>
#include <stddef.h>
#include <stdio.h>
#include <string.h>
#include <limits.h>
#include <retro_log.h>
2015-06-05 16:22:15 +00:00
#include <compat/posix_string.h>
#include <file/file_path.h>
2015-01-10 03:53:37 +00:00
#include "../menu.h"
#include "../menu_driver.h"
2015-07-09 16:39:40 +00:00
#include "../menu_hash.h"
#include "../menu_entry.h"
#include "../menu_display.h"
2015-07-09 16:39:40 +00:00
#include "../menu_video.h"
#include "../../gfx/video_thread_wrapper.h"
#include "../../gfx/font_driver.h"
#include "../../gfx/video_texture.h"
2015-07-09 16:39:40 +00:00
#include "../../runloop_data.h"
typedef struct glui_handle
{
unsigned line_height;
unsigned margin;
2015-04-04 19:26:11 +00:00
unsigned ticker_limit;
char box_message[PATH_MAX_LENGTH];
struct
{
struct
{
GLuint id;
char path[PATH_MAX_LENGTH];
} bg;
GLuint white;
} textures;
gl_font_raster_block_t list_block;
} glui_handle_t;
2015-04-26 04:18:58 +00:00
static void glui_blit_line(float x, float y,
2015-04-21 14:59:02 +00:00
const char *message, uint32_t color, enum text_alignment text_align)
{
unsigned width, height;
2015-06-12 14:20:45 +00:00
glui_handle_t *glui = NULL;
2015-06-05 16:12:57 +00:00
struct font_params params = {0};
2015-06-12 14:20:45 +00:00
menu_handle_t *menu = menu_driver_get_ptr();
2015-06-14 13:34:05 +00:00
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;
2015-06-14 13:34:05 +00:00
params.y = 1.0f - (y + glui->line_height/2 + disp->font.size/3)
2015-07-08 15:26:51 +00:00
/ height;
2015-01-19 05:44:46 +00:00
params.scale = 1.0;
2015-03-14 22:44:27 +00:00
params.color = color;
params.full_screen = true;
2015-04-04 19:26:11 +00:00
params.text_align = text_align;
2015-01-19 05:44:46 +00:00
2015-06-14 13:34:05 +00:00
video_driver_set_osd_msg(message, &params, disp->font.buf);
}
2015-04-04 19:26:11 +00:00
static void glui_render_quad(gl_t *gl, int x, int y, int w, int h,
float r, float g, float b, float a)
2014-10-26 23:55:14 +00:00
{
unsigned width, height;
struct gl_coords coords;
2015-06-30 16:53:57 +00:00
GLfloat color[16], tex_coord[8], vertex[8];
menu_handle_t *menu = menu_driver_get_ptr();
glui_handle_t *glui = (glui_handle_t*)menu->userdata;
2015-06-30 16:53:57 +00:00
vertex[0] = 0;
vertex[1] = 0;
vertex[2] = 1;
vertex[3] = 0;
vertex[4] = 0;
vertex[5] = 1;
vertex[6] = 1;
vertex[7] = 1;
tex_coord[0] = 0;
tex_coord[1] = 1;
tex_coord[2] = 1;
tex_coord[3] = 1;
tex_coord[4] = 0;
tex_coord[5] = 0;
tex_coord[6] = 1;
tex_coord[7] = 0;
color[ 0] = r;
color[ 1] = g;
color[ 2] = b;
color[ 3] = a;
color[ 4] = r;
color[ 5] = g;
color[ 6] = b;
color[ 7] = a;
color[ 8] = r;
color[ 9] = g;
color[10] = b;
color[11] = a;
color[12] = r;
color[13] = g;
color[14] = b;
color[15] = a;
2014-10-26 23:55:14 +00:00
video_driver_get_size(&width, &height);
glViewport(x, height - y - h, w, h);
2014-10-26 23:55:14 +00:00
coords.vertices = 4;
coords.vertex = vertex;
coords.tex_coord = tex_coord;
2014-10-26 23:55:14 +00:00
coords.lut_tex_coord = tex_coord;
coords.color = color;
2015-07-09 16:39:40 +00:00
menu_video_draw_frame(gl->shader, &coords,
2015-06-25 06:26:59 +00:00
&gl->mvp_no_rot, true, glui->textures.white);
2014-10-26 23:55:14 +00:00
gl->coords.color = gl->white_color_ptr;
}
2015-04-04 19:26:11 +00:00
static void glui_draw_cursor(gl_t *gl, float x, float y)
{
glui_render_quad(gl, x-5, y-5, 10, 10, 1, 1, 1, 1);
}
2015-04-21 02:47:02 +00:00
static void glui_draw_scrollbar(gl_t *gl)
{
unsigned width, height;
float content_height, total_height, scrollbar_height, y;
2015-06-14 13:34:05 +00:00
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();
2015-04-21 02:47:02 +00:00
if (!menu)
return;
video_driver_get_size(&width, &height);
2015-04-21 14:59:02 +00:00
glui = (glui_handle_t*)menu->userdata;
2015-05-14 22:03:06 +00:00
content_height = menu_entries_get_end() * glui->line_height;
2015-06-14 13:34:05 +00:00
total_height = height - disp->header_height * 2;
scrollbar_height = total_height / (content_height / total_height);
2015-04-21 14:59:02 +00:00
y = total_height * menu->scroll_y / content_height;
2015-04-21 02:47:02 +00:00
if (content_height < total_height)
return;
glui_render_quad(gl,
width - scrollbar_width,
2015-06-14 13:34:05 +00:00
disp->header_height + y,
scrollbar_width,
scrollbar_height,
2015-04-21 02:47:02 +00:00
1, 1, 1, 1);
}
static void glui_get_message(const char *message)
2014-09-15 10:36:52 +00:00
{
glui_handle_t *glui = NULL;
menu_handle_t *menu = menu_driver_get_ptr();
2014-09-15 10:36:52 +00:00
if (!menu)
return;
if (!message || !*message)
2014-09-15 10:36:52 +00:00
return;
glui = (glui_handle_t*)menu->userdata;
2015-02-02 17:51:48 +00:00
if (glui)
strlcpy(glui->box_message, message, sizeof(glui->box_message));
2014-09-15 10:36:52 +00:00
}
static void glui_render_messagebox(const char *message)
{
unsigned i;
unsigned width, height;
2015-03-16 15:57:27 +00:00
uint32_t normal_color;
int x, y;
struct string_list *list = NULL;
2015-06-05 16:12:57 +00:00
menu_handle_t *menu = menu_driver_get_ptr();
2015-06-14 13:34:05 +00:00
menu_display_t *disp = menu_display_get_ptr();
2015-06-05 16:12:57 +00:00
settings_t *settings = config_get_ptr();
2014-09-15 10:36:52 +00:00
2015-06-14 13:34:05 +00:00
if (!menu || !disp || !menu->userdata)
return;
list = (struct string_list*)string_split(message, "\n");
2014-09-15 10:36:52 +00:00
if (!list)
return;
2014-09-15 10:36:52 +00:00
if (list->elems == 0)
2015-02-02 17:51:48 +00:00
goto end;
2014-09-15 10:36:52 +00:00
video_driver_get_size(&width, &height);
x = width / 2;
2015-06-14 13:34:05 +00:00
y = height / 2 - list->size * disp->font.size / 2;
2015-03-20 21:22:06 +00:00
normal_color = FONT_COLOR_ARGB_TO_RGBA(settings->menu.entry_normal_color);
2014-09-15 10:36:52 +00:00
for (i = 0; i < list->size; i++)
{
const char *msg = list->elems[i].data;
2015-02-02 17:51:48 +00:00
if (msg)
2015-06-25 06:26:59 +00:00
glui_blit_line(x, y + i * disp->font.size,
msg, normal_color, TEXT_ALIGN_CENTER);
2014-09-15 10:36:52 +00:00
}
2015-02-02 17:51:48 +00:00
end:
2014-09-15 10:36:52 +00:00
string_list_free(list);
}
static void glui_render(void)
{
2015-04-04 19:26:11 +00:00
int bottom;
unsigned width, height;
glui_handle_t *glui = NULL;
2015-06-14 13:34:05 +00:00
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();
2015-06-13 20:57:55 +00:00
menu_input_t *menu_input = menu_input_get_ptr();
settings_t *settings = config_get_ptr();
2015-05-01 12:35:27 +00:00
if (!menu || !menu->userdata)
return;
video_driver_get_size(&width, &height);
glui = (glui_handle_t*)menu->userdata;
2015-06-15 15:34:12 +00:00
menu_animation_update(disp->animation,
disp->animation->delta_time / IDEAL_DT);
2015-04-20 14:22:55 +00:00
/* 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;
2015-04-04 19:26:11 +00:00
if (settings->menu.pointer.enable)
{
2015-06-13 20:57:55 +00:00
menu_input->pointer.ptr =
2015-07-08 15:26:51 +00:00
(menu_input->pointer.y - glui->line_height + menu->scroll_y - 16)
/ glui->line_height;
2015-04-04 19:26:11 +00:00
2015-06-13 20:57:55 +00:00
if (menu_input->pointer.dragging)
menu->scroll_y -= menu_input->pointer.dy;
2015-04-04 19:26:11 +00:00
}
if (settings->menu.mouse.enable)
{
2015-06-13 20:57:55 +00:00
if (menu_input->mouse.scrolldown)
2015-04-04 19:26:11 +00:00
menu->scroll_y += 10;
2014-10-26 23:55:14 +00:00
2015-06-13 20:57:55 +00:00
if (menu_input->mouse.scrollup)
2015-04-04 19:26:11 +00:00
menu->scroll_y -= 10;
2015-06-13 20:57:55 +00:00
menu_input->mouse.ptr =
2015-07-08 15:26:51 +00:00
(menu_input->mouse.y - glui->line_height + menu->scroll_y - 16)
/ glui->line_height;
2015-04-04 19:26:11 +00:00
}
2015-06-22 21:00:05 +00:00
if (menu_entries_get_end() < height / glui->line_height)
menu_entries_set_start(0);
2015-04-04 19:26:11 +00:00
if (menu->scroll_y < 0)
menu->scroll_y = 0;
2015-05-14 22:03:06 +00:00
bottom = menu_entries_get_end() * glui->line_height
2015-07-08 15:26:51 +00:00
- height + disp->header_height * 2;
2015-04-04 19:26:11 +00:00
if (menu->scroll_y > bottom)
menu->scroll_y = bottom;
2015-05-14 22:03:06 +00:00
if (menu_entries_get_end() * glui->line_height
2015-07-08 15:26:51 +00:00
< height - disp->header_height*2)
2015-04-04 19:26:11 +00:00
menu->scroll_y = 0;
}
2015-05-20 01:09:28 +00:00
static void glui_render_menu_list(glui_handle_t *glui,
menu_handle_t *menu,
2015-05-07 08:15:33 +00:00
uint32_t normal_color,
2015-04-21 14:59:02 +00:00
uint32_t hover_color)
{
unsigned width, height;
2015-06-12 14:20:45 +00:00
size_t i = 0;
uint64_t frame_count = video_driver_get_frame_count();
size_t end = menu_entries_get_end();
2015-06-14 13:34:05 +00:00
menu_display_t *disp = menu_display_get_ptr();
if (!menu_display_update_pending())
2015-04-24 20:46:19 +00:00
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];
2015-06-14 13:34:05 +00:00
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);
2015-06-01 12:59:15 +00:00
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,
2015-06-01 13:31:08 +00:00
frame_count / 100, entry_path, entry_selected);
menu_animation_ticker_line(type_str_buf, glui->ticker_limit,
2015-06-01 13:31:08 +00:00
frame_count / 100, entry_value, entry_selected);
strlcpy(message, entry_title_buf, sizeof(message));
2015-04-26 04:18:58 +00:00
glui_blit_line(glui->margin, y, message,
2015-06-01 13:31:08 +00:00
entry_selected ? hover_color : normal_color, TEXT_ALIGN_LEFT);
glui_blit_line(width - glui->margin, y, type_str_buf,
2015-06-01 13:31:08 +00:00
entry_selected ? hover_color : normal_color, TEXT_ALIGN_RIGHT);
}
}
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];
2015-06-12 14:20:45 +00:00
gl_t *gl = NULL;
glui_handle_t *glui = NULL;
const struct font_renderer *font_driver = NULL;
2015-06-12 14:20:45 +00:00
driver_t *driver = driver_get_ptr();
menu_handle_t *menu = menu_driver_get_ptr();
2015-06-13 21:23:29 +00:00
menu_animation_t *anim = menu_animation_get_ptr();
2015-06-13 14:22:05 +00:00
menu_navigation_t *nav = menu_navigation_get_ptr();
2015-06-14 13:34:05 +00:00
menu_display_t *disp = menu_display_get_ptr();
2015-06-12 14:20:45 +00:00
settings_t *settings = config_get_ptr();
2015-06-13 20:57:55 +00:00
menu_input_t *menu_input = menu_input_get_ptr();
2015-06-12 14:20:45 +00:00
uint64_t frame_count = video_driver_get_frame_count();
2015-06-12 17:28:12 +00:00
const uint32_t normal_color = FONT_COLOR_ARGB_TO_RGBA(
2015-04-21 14:59:02 +00:00
settings->menu.entry_normal_color);
2015-06-12 17:28:12 +00:00
const uint32_t hover_color = FONT_COLOR_ARGB_TO_RGBA(
2015-04-21 14:59:02 +00:00
settings->menu.entry_hover_color);
2015-06-12 17:28:12 +00:00
const uint32_t title_color = FONT_COLOR_ARGB_TO_RGBA(
2015-04-21 14:59:02 +00:00
settings->menu.title_color);
2015-05-01 12:35:27 +00:00
if (!menu || !menu->userdata)
return;
gl = (gl_t*)video_driver_get_ptr(NULL);
if (!gl)
return;
glui = (glui_handle_t*)menu->userdata;
title[0] = '\0';
title_buf[0] = '\0';
title_msg[0] = '\0';
timedate[0] = '\0';
video_driver_get_size(&width, &height);
menu_display_set_viewport();
2015-07-09 16:39:40 +00:00
menu_video_frame_background(menu, settings,
2015-06-12 14:20:45 +00:00
gl, glui->textures.bg.id, 0.75f, 0.75f, false);
2015-05-14 22:07:07 +00:00
menu_entries_get_title(title, sizeof(title));
font_driver = driver->font_osd_driver;
2015-04-24 20:46:19 +00:00
menu_display_font_bind_block(menu, font_driver, &glui->list_block);
2015-04-24 20:46:19 +00:00
2015-05-20 01:09:28 +00:00
glui_render_menu_list(glui, menu, normal_color, hover_color);
2015-04-24 22:45:25 +00:00
menu_display_font_flush_block(menu, font_driver);
glui_render_quad(gl, 0,
2015-06-14 13:34:05 +00:00
disp->header_height - menu->scroll_y + glui->line_height *
2015-06-15 00:37:32 +00:00
nav->selection_ptr, width, glui->line_height, 1, 1, 1, 0.1);
2015-06-15 00:37:32 +00:00
anim->is_active = true;
anim->label.is_updated = false;
2015-04-04 19:26:11 +00:00
glui_render_quad(gl, 0, 0, width,
2015-06-14 13:34:05 +00:00
disp->header_height, 0.2, 0.2, 0.2, 1);
2015-04-04 19:26:11 +00:00
menu_animation_ticker_line(title_buf, glui->ticker_limit,
frame_count / 100, title, true);
glui_blit_line(width / 2, 0, title_buf,
2015-04-21 14:59:02 +00:00
title_color, TEXT_ALIGN_CENTER);
2015-04-04 19:26:11 +00:00
2015-05-14 22:16:39 +00:00
if (menu_entries_show_back())
2015-06-25 05:15:19 +00:00
glui_blit_line(glui->margin, 0, menu_hash_to_str(MENU_VALUE_BACK),
2015-04-21 14:59:02 +00:00
title_color, TEXT_ALIGN_LEFT);
2015-04-04 19:26:11 +00:00
2015-06-14 13:34:05 +00:00
glui_render_quad(gl,
0,
height - disp->header_height,
width,
disp->header_height,
2015-04-04 19:26:11 +00:00
0.2, 0.2, 0.2, 1);
2015-04-21 02:47:02 +00:00
glui_draw_scrollbar(gl);
2015-04-04 19:26:11 +00:00
if (settings->menu.core_enable)
{
menu_entries_get_core_title(title_msg, sizeof(title_msg));
2015-04-04 19:26:11 +00:00
2015-04-26 04:18:58 +00:00
glui_blit_line(glui->margin,
height - glui->line_height, title_msg,
2015-04-04 19:26:11 +00:00
title_color, TEXT_ALIGN_LEFT);
}
if (settings->menu.timedate_enable)
{
2015-06-08 12:57:46 +00:00
menu_display_timedate(timedate, sizeof(timedate), 0);
glui_blit_line(width - glui->margin,
height - glui->line_height, timedate, hover_color,
2015-04-04 19:26:11 +00:00
TEXT_ALIGN_RIGHT);
}
2015-06-13 20:57:55 +00:00
if (menu_input->keyboard.display)
{
char msg[PATH_MAX_LENGTH];
2015-06-13 20:57:55 +00:00
const char *str = *menu_input->keyboard.buffer;
msg[0] = '\0';
2015-06-12 22:09:09 +00:00
if (!str)
str = "";
glui_render_quad(gl, 0, 0, width, height, 0, 0, 0, 0.75);
2015-06-13 20:57:55 +00:00
snprintf(msg, sizeof(msg), "%s\n%s", menu_input->keyboard.label, str);
glui_render_messagebox(msg);
}
if (glui->box_message[0] != '\0')
2014-09-15 10:36:52 +00:00
{
glui_render_quad(gl, 0, 0, width, height, 0, 0, 0, 0.75);
glui_render_messagebox(glui->box_message);
glui->box_message[0] = '\0';
2014-09-15 10:36:52 +00:00
}
2015-03-27 19:17:11 +00:00
if (settings->menu.mouse.enable)
2015-06-13 20:57:55 +00:00
glui_draw_cursor(gl, menu_input->mouse.x, menu_input->mouse.y);
2015-03-27 19:17:11 +00:00
gl->shader->use(gl, GL_SHADER_STOCK_BLEND);
menu_display_unset_viewport();
}
static void glui_allocate_white_texture(glui_handle_t *glui)
{
struct texture_image ti;
2015-06-12 14:20:45 +00:00
static const uint8_t white_data[] = { 0xff, 0xff, 0xff, 0xff };
ti.width = 1;
ti.height = 1;
ti.pixels = (uint32_t*)&white_data;
glui->textures.white = video_texture_load(&ti,
TEXTURE_BACKEND_OPENGL, TEXTURE_FILTER_NEAREST);
}
static void glui_layout(menu_handle_t *menu, glui_handle_t *glui)
{
float scale_factor, glyph_width;
unsigned width, height;
video_driver_get_size(&width, &height);
2015-07-08 15:26:51 +00:00
/* 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. */
#ifdef RARCH_MOBILE
scale_factor = menu_display_get_dpi();
#else
scale_factor = width / 7.5;
#endif
glui->line_height = scale_factor / 3;
glui->margin = scale_factor / 6;
menu->display.header_height = scale_factor / 3;
menu->display.font.size = scale_factor / 8;
/* we assume the average glyph aspect ratio is close to 3:4 */
glyph_width = menu->display.font.size * 3/4;
glui->ticker_limit = (width/2) / glyph_width;
}
static void *glui_init(void)
{
2015-04-21 14:59:02 +00:00
glui_handle_t *glui = NULL;
const video_driver_t *video_driver = NULL;
menu_handle_t *menu = NULL;
gl_t *gl = (gl_t*)
video_driver_get_ptr(&video_driver);
if (video_driver != &video_gl || !gl)
{
RARCH_ERR("Cannot initialize GLUI menu driver: gl video driver is not active.\n");
return NULL;
}
2015-04-21 14:59:02 +00:00
menu = (menu_handle_t*)calloc(1, sizeof(*menu));
if (!menu)
2015-02-02 17:51:48 +00:00
goto error;
2015-04-21 14:59:02 +00:00
menu->userdata = (glui_handle_t*)calloc(1, sizeof(glui_handle_t));
if (!menu->userdata)
2015-02-02 17:51:48 +00:00
goto error;
2015-06-14 13:34:05 +00:00
glui = (glui_handle_t*)menu->userdata;
glui_layout(menu, glui);
glui_allocate_white_texture(glui);
return menu;
2015-02-02 17:51:48 +00:00
error:
if (menu)
free(menu);
return NULL;
}
static void glui_free(void *data)
{
2015-04-21 14:59:02 +00:00
gl_t *gl = NULL;
const struct font_renderer *font_driver = NULL;
2015-04-21 14:59:02 +00:00
menu_handle_t *menu = (menu_handle_t*)data;
driver_t *driver = driver_get_ptr();
2015-04-21 14:59:02 +00:00
glui_handle_t *glui = (glui_handle_t*)menu->userdata;
2015-04-21 14:59:02 +00:00
if (!glui || !menu)
return;
gl_coord_array_free(&glui->list_block.carr);
2015-04-21 14:59:02 +00:00
gl = (gl_t*)video_driver_get_ptr(NULL);
2015-03-28 19:50:51 +00:00
font_driver = gl ? (const struct font_renderer*)driver->font_osd_driver : NULL;
2015-04-21 14:59:02 +00:00
2015-04-24 20:17:08 +00:00
if (font_driver && font_driver->bind_block)
font_driver->bind_block(driver->font_osd_data, NULL);
if (menu->userdata)
free(menu->userdata);
2015-06-11 19:12:08 +00:00
menu->userdata = NULL;
}
static void glui_context_bg_destroy(glui_handle_t *glui)
{
if (glui)
{
if (glui->textures.bg.id)
glDeleteTextures(1, &glui->textures.bg.id);
if (glui->textures.white)
glDeleteTextures(1, &glui->textures.white);
2015-05-11 16:49:46 +00:00
glui->textures.bg.id = 0;
glui->textures.white = 0;
}
}
static void glui_context_destroy(void)
{
2015-05-01 12:02:03 +00:00
gl_t *gl = (gl_t*)video_driver_get_ptr(NULL);
glui_handle_t *glui = NULL;
menu_handle_t *menu = menu_driver_get_ptr();
driver_t *driver = driver_get_ptr();
2015-07-08 15:26:51 +00:00
2015-05-01 12:02:03 +00:00
if (!menu || !menu->userdata || !gl || !driver)
return;
glui = (glui_handle_t*)menu->userdata;
2015-05-01 12:02:03 +00:00
menu_display_free_main_font(menu);
glui_context_bg_destroy(glui);
}
static bool glui_load_image(void *data, menu_image_type_t type)
{
glui_handle_t *glui = NULL;
menu_handle_t *menu = menu_driver_get_ptr();
2015-05-01 12:35:27 +00:00
if (!menu || !menu->userdata)
return false;
2015-07-08 15:26:51 +00:00
glui = (glui_handle_t*)menu->userdata;
switch (type)
{
case MENU_IMAGE_NONE:
break;
case MENU_IMAGE_WALLPAPER:
glui_context_bg_destroy(glui);
glui->textures.bg.id = video_texture_load(data,
TEXTURE_BACKEND_OPENGL, TEXTURE_FILTER_MIPMAP_LINEAR);
glui_allocate_white_texture(glui);
break;
case MENU_IMAGE_BOXART:
break;
}
return true;
}
2015-04-24 22:54:17 +00:00
static float glui_get_scroll(void)
2014-10-26 23:55:14 +00:00
{
int half = 0;
unsigned width, height;
glui_handle_t *glui = NULL;
menu_handle_t *menu = menu_driver_get_ptr();
menu_navigation_t *nav = menu_navigation_get_ptr();
2014-10-26 23:55:14 +00:00
2015-05-01 12:35:27 +00:00
if (!menu || !menu->userdata)
return 0;
2015-04-21 14:59:02 +00:00
video_driver_get_size(&width, &height);
2014-10-26 23:55:14 +00:00
glui = (glui_handle_t*)menu->userdata;
if (glui->line_height)
2015-07-08 15:26:51 +00:00
half = (height / glui->line_height) / 2;
2015-04-04 19:26:11 +00:00
if (nav->selection_ptr < (unsigned)half)
return 0;
return ((nav->selection_ptr + 2 - half) * glui->line_height);
}
static void glui_navigation_set(bool scroll)
{
2015-06-15 15:34:12 +00:00
menu_display_t *disp = menu_display_get_ptr();
menu_handle_t *menu = menu_driver_get_ptr();
float scroll_pos = 0;
2015-04-20 14:22:55 +00:00
2015-06-15 15:34:12 +00:00
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);
2014-10-26 23:55:14 +00:00
}
static void glui_navigation_clear(bool pending_push)
{
menu_handle_t *menu = menu_driver_get_ptr();
if (!menu)
return;
menu_entries_set_start(0);
2015-04-21 14:59:02 +00:00
menu->scroll_y = 0;
}
static void glui_navigation_set_last(void)
{
glui_navigation_set(true);
}
2015-06-06 22:48:50 +00:00
static void glui_navigation_alphabet(size_t *unused)
{
glui_navigation_set(true);
}
static void glui_populate_entries(const char *path,
const char *label, unsigned i)
{
menu_handle_t *menu = menu_driver_get_ptr();
if (!menu)
return;
2015-04-21 14:59:02 +00:00
menu->scroll_y = glui_get_scroll();
}
static void glui_font(menu_handle_t *menu)
{
settings_t *settings = config_get_ptr();
const char *font_path = NULL;
font_path = settings->video.font_enable ? settings->video.font_path : NULL;
if (!menu_display_init_main_font(menu, font_path, menu->display.font.size))
RARCH_WARN("Failed to load font.");
}
static void glui_context_reset(void)
{
2015-05-01 12:02:03 +00:00
glui_handle_t *glui = NULL;
menu_handle_t *menu = menu_driver_get_ptr();
settings_t *settings = config_get_ptr();
2015-05-01 12:35:27 +00:00
if (!menu || !menu->userdata || !settings)
return;
2015-04-21 14:59:02 +00:00
2015-05-01 12:35:27 +00:00
glui = (glui_handle_t*)menu->userdata;
glui_layout(menu, glui);
glui_font(menu);
glui_context_bg_destroy(glui);
glui_allocate_white_texture(glui);
rarch_main_data_msg_queue_push(DATA_TYPE_IMAGE,
settings->menu.wallpaper, "cb_menu_wallpaper", 0, 1, true);
}
static int glui_environ(menu_environ_cb_t type, void *data)
2015-07-07 22:37:44 +00:00
{
switch (type)
{
2015-07-08 22:24:10 +00:00
case 0:
2015-07-07 22:37:44 +00:00
default:
return -1;
}
return 0;
}
2014-09-11 05:06:20 +00:00
menu_ctx_driver_t menu_ctx_glui = {
NULL,
2014-09-15 10:36:52 +00:00
glui_get_message,
glui_render,
glui_frame,
glui_init,
glui_free,
glui_context_reset,
glui_context_destroy,
glui_populate_entries,
NULL,
2014-10-26 23:55:14 +00:00
glui_navigation_clear,
NULL,
NULL,
2014-10-26 23:55:14 +00:00
glui_navigation_set,
glui_navigation_set_last,
2015-06-06 22:48:50 +00:00
glui_navigation_alphabet,
glui_navigation_alphabet,
NULL,
NULL,
NULL,
NULL,
NULL,
2015-06-07 13:43:03 +00:00
NULL,
2015-06-08 14:01:57 +00:00
NULL,
NULL,
2015-06-15 17:00:52 +00:00
NULL,
glui_load_image,
"glui",
2015-07-07 22:37:44 +00:00
glui_environ,
NULL,
};