2015-10-02 00:15:23 +00:00
|
|
|
/* RetroArch - A frontend for libretro.
|
|
|
|
* 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/>.
|
|
|
|
*/
|
|
|
|
|
|
|
|
#include <stdint.h>
|
|
|
|
#include <stdlib.h>
|
|
|
|
#include <stddef.h>
|
|
|
|
#include <stdio.h>
|
|
|
|
#include <string.h>
|
|
|
|
#include <limits.h>
|
|
|
|
|
|
|
|
#include <file/file_path.h>
|
|
|
|
#include <file/dir_list.h>
|
|
|
|
#include <compat/posix_string.h>
|
|
|
|
#include <retro_log.h>
|
|
|
|
#include <retro_stat.h>
|
|
|
|
|
2015-10-03 01:15:47 +00:00
|
|
|
#include "menu_generic.h"
|
|
|
|
|
2015-10-06 11:38:44 +00:00
|
|
|
#include "../../config.def.h"
|
|
|
|
|
2015-10-02 00:15:23 +00:00
|
|
|
#include "../menu.h"
|
2015-10-06 10:30:10 +00:00
|
|
|
#include "../menu_animation.h"
|
2015-10-02 00:15:23 +00:00
|
|
|
#include "../menu_entry.h"
|
|
|
|
#include "../menu_display.h"
|
2015-10-24 04:36:13 +00:00
|
|
|
#include "../menu_hash.h"
|
2015-10-02 00:15:23 +00:00
|
|
|
#include "../../runloop_data.h"
|
|
|
|
|
|
|
|
#include "../../gfx/video_thread_wrapper.h"
|
|
|
|
#include "../../gfx/font_driver.h"
|
|
|
|
#include "../../gfx/video_texture.h"
|
|
|
|
|
2015-10-04 04:36:36 +00:00
|
|
|
const GLfloat ZUI_NORMAL[] = {
|
|
|
|
1, 1, 1, 1,
|
|
|
|
1, 1, 1, 1,
|
|
|
|
1, 1, 1, 1,
|
|
|
|
1, 1, 1, 1,
|
|
|
|
};
|
|
|
|
const GLfloat ZUI_HILITE[] = {
|
|
|
|
1, 0, 0, 1,
|
|
|
|
1, 0, 0, 1,
|
|
|
|
1, 0, 0, 1,
|
|
|
|
1, 0, 0, 1,
|
|
|
|
};
|
|
|
|
const GLfloat ZUI_PRESS[] = {
|
|
|
|
0, 1, 0, 1,
|
|
|
|
0, 1, 0, 1,
|
|
|
|
0, 1, 0, 1,
|
|
|
|
0, 1, 0, 1,
|
|
|
|
};
|
|
|
|
const GLfloat ZUI_BARBG[] = {
|
|
|
|
0, 0, 1, 1,
|
|
|
|
0, 0, 1, 1,
|
|
|
|
0, 0, 1, 1,
|
|
|
|
0, 0, 1, 1,
|
|
|
|
};
|
2015-10-02 00:15:23 +00:00
|
|
|
|
|
|
|
const uint32_t ZUI_FG_NORMAL = ~0;
|
2015-10-04 04:36:36 +00:00
|
|
|
const GLfloat ZUI_BG_PANEL[] = {
|
|
|
|
0, 0, 0, 0.25,
|
|
|
|
0, 0, 0, 0.25,
|
|
|
|
0, 0, 0, 0.25,
|
|
|
|
0, 0, 0, 0.25,
|
|
|
|
};
|
|
|
|
const GLfloat ZUI_BG_SCREEN[] = {
|
|
|
|
0.07, 0.19, 0.26, 1,
|
|
|
|
0.07, 0.19, 0.26, 1,
|
|
|
|
0.15, 0.31, 0.47, 1,
|
|
|
|
0.15, 0.31, 0.47, 1,
|
|
|
|
};
|
|
|
|
const GLfloat ZUI_BG_HILITE[] = {
|
|
|
|
0.22, 0.60, 0.74, 1,
|
|
|
|
0.22, 0.60, 0.74, 1,
|
|
|
|
0.22, 0.60, 0.74, 1,
|
|
|
|
0.22, 0.60, 0.74, 1,
|
|
|
|
};
|
|
|
|
|
2015-10-02 00:15:23 +00:00
|
|
|
|
|
|
|
typedef struct zarch_handle
|
|
|
|
{
|
|
|
|
bool rendering;
|
|
|
|
settings_t *set;
|
|
|
|
menu_handle_t *menu;
|
|
|
|
math_matrix_4x4 mvp;
|
|
|
|
unsigned width;
|
|
|
|
unsigned height;
|
|
|
|
gfx_font_raster_block_t tmp_block;
|
|
|
|
unsigned hash;
|
2015-10-06 11:38:44 +00:00
|
|
|
bool time_to_exit;
|
2015-10-02 00:15:23 +00:00
|
|
|
|
|
|
|
struct {
|
|
|
|
unsigned active;
|
|
|
|
unsigned hot;
|
|
|
|
} item;
|
|
|
|
|
|
|
|
gfx_coord_array_t ca;
|
|
|
|
|
|
|
|
struct
|
|
|
|
{
|
|
|
|
int wheel;
|
|
|
|
} mouse;
|
|
|
|
|
|
|
|
/* LAY_ROOT's "Load" file browser */
|
|
|
|
struct string_list *load_dlist;
|
|
|
|
char *load_cwd;
|
|
|
|
int load_dlist_first;
|
|
|
|
|
2015-10-02 03:34:12 +00:00
|
|
|
struct
|
|
|
|
{
|
|
|
|
struct
|
|
|
|
{
|
|
|
|
GRuint id;
|
|
|
|
char path[PATH_MAX_LENGTH];
|
|
|
|
} bg;
|
|
|
|
GRuint white;
|
|
|
|
} textures;
|
2015-10-02 00:15:23 +00:00
|
|
|
|
|
|
|
/* LAY_PICK_CORE */
|
|
|
|
int pick_first;
|
|
|
|
char pick_content[PATH_MAX_LENGTH];
|
|
|
|
const core_info_t *pick_cores;
|
|
|
|
size_t pick_supported;
|
|
|
|
|
|
|
|
void *fb_buf;
|
2015-10-04 05:46:37 +00:00
|
|
|
int font_size;
|
2015-10-02 00:15:23 +00:00
|
|
|
int header_height;
|
|
|
|
} zui_t;
|
|
|
|
|
2015-10-02 02:03:34 +00:00
|
|
|
typedef struct
|
|
|
|
{
|
|
|
|
unsigned active;
|
|
|
|
int x, y;
|
|
|
|
int width;
|
|
|
|
int height; /* unused */
|
|
|
|
int tabline_size;
|
|
|
|
bool update_width;
|
|
|
|
bool vertical;
|
|
|
|
int tab_width;
|
|
|
|
} zui_tabbed_t;
|
|
|
|
|
|
|
|
typedef struct
|
|
|
|
{
|
|
|
|
float x, y;
|
|
|
|
float xspeed, yspeed;
|
2015-10-04 04:36:36 +00:00
|
|
|
float alpha;
|
2015-10-02 02:03:34 +00:00
|
|
|
bool alive;
|
|
|
|
} part_t;
|
|
|
|
|
|
|
|
static enum
|
|
|
|
{
|
|
|
|
LAY_HOME,
|
|
|
|
LAY_PICK_CORE,
|
|
|
|
LAY_SETTINGS
|
|
|
|
} layout = LAY_HOME;
|
|
|
|
|
2015-10-02 03:34:12 +00:00
|
|
|
static const GRfloat zarch_vertexes[] = {
|
|
|
|
0, 0,
|
|
|
|
1, 0,
|
|
|
|
0, 1,
|
|
|
|
1, 1
|
|
|
|
};
|
|
|
|
|
|
|
|
static const GRfloat zarch_tex_coords[] = {
|
|
|
|
0, 1,
|
|
|
|
1, 1,
|
|
|
|
0, 0,
|
|
|
|
1, 0
|
|
|
|
};
|
|
|
|
|
2015-10-04 05:46:37 +00:00
|
|
|
static void zui_font(menu_handle_t *menu)
|
|
|
|
{
|
|
|
|
int font_size;
|
|
|
|
char mediapath[PATH_MAX_LENGTH], fontpath[PATH_MAX_LENGTH];
|
|
|
|
settings_t *settings = config_get_ptr();
|
|
|
|
|
|
|
|
menu_display_ctl(MENU_DISPLAY_CTL_FONT_SIZE, &font_size);
|
|
|
|
|
|
|
|
fill_pathname_join(mediapath, settings->assets_directory, "zarch", sizeof(mediapath));
|
|
|
|
fill_pathname_join(fontpath, mediapath, "Roboto-Condensed.ttf", sizeof(fontpath));
|
|
|
|
|
|
|
|
if (!menu_display_init_main_font(menu, fontpath, font_size))
|
|
|
|
RARCH_WARN("Failed to load font.");
|
|
|
|
}
|
|
|
|
|
2015-10-04 01:19:53 +00:00
|
|
|
static float zui_strwidth(void *fb_buf, const char *text, float scale)
|
2015-10-02 00:15:23 +00:00
|
|
|
{
|
|
|
|
driver_t *driver = (driver_t*)driver_get_ptr();
|
2015-10-04 01:19:53 +00:00
|
|
|
return driver->font_osd_driver->get_message_width(fb_buf, text, strlen(text), scale);
|
2015-10-02 00:15:23 +00:00
|
|
|
}
|
|
|
|
|
2015-10-04 01:19:53 +00:00
|
|
|
static void zui_begin(void)
|
2015-10-02 00:15:23 +00:00
|
|
|
{
|
2015-10-04 01:19:53 +00:00
|
|
|
zui_t *zui = NULL;
|
2015-10-10 09:38:22 +00:00
|
|
|
driver_t *driver = (driver_t*)driver_get_ptr();
|
|
|
|
menu_handle_t *menu = menu_driver_get_ptr();
|
2015-10-24 02:15:58 +00:00
|
|
|
gl_t *gl = (gl_t*)video_driver_get_ptr(NULL);
|
2015-10-04 01:19:53 +00:00
|
|
|
|
2015-10-24 02:15:58 +00:00
|
|
|
if (!gl || !menu)
|
2015-10-04 01:19:53 +00:00
|
|
|
return;
|
2015-10-04 00:26:06 +00:00
|
|
|
|
2015-10-04 01:19:53 +00:00
|
|
|
zui = (zui_t*)menu->userdata;
|
|
|
|
|
2015-10-10 09:38:22 +00:00
|
|
|
if (!zui || !driver)
|
2015-10-04 00:26:06 +00:00
|
|
|
return;
|
|
|
|
|
2015-10-02 00:15:23 +00:00
|
|
|
zui->rendering = true;
|
2015-10-24 02:15:58 +00:00
|
|
|
zui->hash = 0;
|
|
|
|
zui->item.hot = 0;
|
2015-10-02 00:15:23 +00:00
|
|
|
|
|
|
|
glViewport(0, 0, zui->width, zui->height);
|
2015-10-04 00:26:06 +00:00
|
|
|
|
|
|
|
if (gl && gl->shader && gl->shader->set_mvp)
|
|
|
|
gl->shader->set_mvp(gl, &zui->mvp);
|
2015-10-02 00:15:23 +00:00
|
|
|
|
|
|
|
/* why do i need this? */
|
2015-10-24 01:13:40 +00:00
|
|
|
zui->mouse.wheel = menu_input_mouse_state(MENU_MOUSE_WHEEL_DOWN) -
|
|
|
|
menu_input_mouse_state(MENU_MOUSE_WHEEL_UP);
|
2015-10-02 00:15:23 +00:00
|
|
|
|
|
|
|
zui->ca.coords.vertices = 0;
|
|
|
|
|
|
|
|
zui->tmp_block.carr.coords.vertices = 0;
|
|
|
|
menu_display_font_bind_block(zui->menu, driver->font_osd_driver, &zui->tmp_block);
|
|
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
2015-10-09 16:29:24 +00:00
|
|
|
static void zui_finish(zui_t *zui,
|
|
|
|
unsigned x, unsigned y,
|
|
|
|
unsigned width, unsigned height,
|
|
|
|
bool blend,
|
|
|
|
GLuint texture)
|
2015-10-02 00:15:23 +00:00
|
|
|
{
|
|
|
|
driver_t *driver = (driver_t*)driver_get_ptr();
|
2015-10-04 01:19:53 +00:00
|
|
|
gl_t *gl = (gl_t*)video_driver_get_ptr(NULL);
|
|
|
|
|
|
|
|
if (!gl)
|
|
|
|
return;
|
2015-10-02 00:15:23 +00:00
|
|
|
|
2015-10-23 07:30:46 +00:00
|
|
|
if (!menu_input_mouse_state(MENU_MOUSE_LEFT_BUTTON))
|
2015-10-02 00:15:23 +00:00
|
|
|
zui->item.active = 0;
|
|
|
|
else if (zui->item.active == 0)
|
|
|
|
zui->item.active = -1;
|
|
|
|
|
2015-10-09 16:29:24 +00:00
|
|
|
glViewport(x, y, width, height);
|
|
|
|
glBindTexture(GL_TEXTURE_2D, 0);
|
2015-10-02 00:15:23 +00:00
|
|
|
|
2015-10-09 16:29:24 +00:00
|
|
|
gl->shader->set_coords(&zui->ca);
|
2015-10-02 00:15:23 +00:00
|
|
|
|
2015-10-09 16:29:24 +00:00
|
|
|
glEnable(GL_BLEND);
|
|
|
|
glDrawArrays(GL_TRIANGLES, 0, zui->ca.coords.vertices);
|
2015-10-02 00:15:23 +00:00
|
|
|
|
2015-10-09 16:29:24 +00:00
|
|
|
menu_display_font_flush_block(zui->menu, driver->font_osd_driver);
|
2015-10-02 00:15:23 +00:00
|
|
|
|
2015-10-09 16:29:24 +00:00
|
|
|
glDisable(GL_BLEND);
|
2015-10-02 00:15:23 +00:00
|
|
|
|
2015-10-09 16:29:24 +00:00
|
|
|
gl->shader->set_mvp(gl, &gl->mvp_no_rot);
|
2015-10-02 00:15:23 +00:00
|
|
|
|
|
|
|
zui->rendering = false;
|
|
|
|
}
|
|
|
|
|
|
|
|
static bool check_button_down(zui_t *zui, unsigned id, int x1, int y1, int x2, int y2)
|
|
|
|
{
|
|
|
|
bool result = false;
|
2015-10-24 01:19:06 +00:00
|
|
|
bool inside = menu_input_mouse_check_hitbox(x1, y1, x2, y2);
|
2015-10-02 00:15:23 +00:00
|
|
|
|
|
|
|
if (inside)
|
|
|
|
zui->item.hot = id;
|
|
|
|
|
2015-10-23 07:30:46 +00:00
|
|
|
if (zui->item.hot == id && menu_input_mouse_state(MENU_MOUSE_LEFT_BUTTON))
|
2015-10-02 00:15:23 +00:00
|
|
|
{
|
|
|
|
result = true;
|
|
|
|
zui->item.active = id;
|
|
|
|
}
|
|
|
|
|
|
|
|
return result;
|
|
|
|
}
|
|
|
|
|
|
|
|
static bool check_button_up(zui_t *zui, unsigned id, int x1, int y1, int x2, int y2)
|
|
|
|
{
|
|
|
|
bool result = false;
|
2015-10-24 01:19:06 +00:00
|
|
|
bool inside = menu_input_mouse_check_hitbox(x1, y1, x2, y2);
|
2015-10-02 00:15:23 +00:00
|
|
|
|
|
|
|
if (inside)
|
|
|
|
zui->item.hot = id;
|
|
|
|
|
2015-10-23 07:30:46 +00:00
|
|
|
if (zui->item.active == id && !menu_input_mouse_state(MENU_MOUSE_LEFT_BUTTON))
|
2015-10-02 00:15:23 +00:00
|
|
|
{
|
|
|
|
if (zui->item.hot == id)
|
|
|
|
result = true;
|
|
|
|
|
|
|
|
zui->item.active = 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
check_button_down(zui, id, x1, y1, x2, y2);
|
|
|
|
|
|
|
|
return result;
|
|
|
|
}
|
|
|
|
|
|
|
|
static unsigned zui_hash(zui_t *zui, const char *s)
|
|
|
|
{
|
|
|
|
unsigned hval = zui->hash;
|
2015-10-02 02:03:34 +00:00
|
|
|
|
2015-10-02 00:15:23 +00:00
|
|
|
while(*s!=0)
|
|
|
|
{
|
|
|
|
hval+=*s++;
|
|
|
|
hval+=(hval<<10);
|
|
|
|
hval^=(hval>>6);
|
|
|
|
hval+=(hval<<3);
|
|
|
|
hval^=(hval>>11);
|
|
|
|
hval+=(hval<<15);
|
|
|
|
}
|
|
|
|
return zui->hash = hval;
|
|
|
|
}
|
|
|
|
|
2015-10-02 01:55:23 +00:00
|
|
|
#if 0
|
2015-10-02 00:15:23 +00:00
|
|
|
static uint32_t zui_rgba(uint8_t r, uint8_t g, uint8_t b, uint8_t a)
|
|
|
|
{
|
|
|
|
return FONT_COLOR_RGBA(r, g, b, a);
|
|
|
|
}
|
2015-10-02 01:55:23 +00:00
|
|
|
#endif
|
2015-10-02 00:15:23 +00:00
|
|
|
|
|
|
|
static void zui_draw_text(zui_t *zui, uint32_t color, int x, int y, const char *text)
|
|
|
|
{
|
|
|
|
struct font_params params = {0};
|
|
|
|
|
|
|
|
/* need to use height-y because the gl font renderer uses a different mvp */
|
|
|
|
params.x = x / (float)zui->width;
|
|
|
|
params.y = (zui->height - y) / (float)zui->height;
|
|
|
|
params.scale = 1.0;
|
|
|
|
params.color = color;
|
|
|
|
params.full_screen = true;
|
|
|
|
params.text_align = TEXT_ALIGN_LEFT;
|
|
|
|
|
|
|
|
video_driver_set_osd_msg(text, ¶ms, zui->fb_buf);
|
|
|
|
}
|
|
|
|
|
2015-10-04 04:36:36 +00:00
|
|
|
static void zui_push_quad(zui_t *zui, const GLfloat *colors, int x1, int y1,
|
|
|
|
int x2, int y2)
|
2015-10-02 00:15:23 +00:00
|
|
|
{
|
2015-10-04 00:34:18 +00:00
|
|
|
gfx_coords_t coords;
|
|
|
|
GLfloat vertex[8];
|
|
|
|
GLfloat tex_coord[8];
|
|
|
|
|
|
|
|
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;
|
|
|
|
|
|
|
|
vertex[0] = x1 / (float)zui->width;
|
|
|
|
vertex[1] = y1 / (float)zui->height;
|
|
|
|
vertex[2] = x2 / (float)zui->width;
|
|
|
|
vertex[3] = y1 / (float)zui->height;
|
|
|
|
vertex[4] = x1 / (float)zui->width;
|
|
|
|
vertex[5] = y2 / (float)zui->height;
|
|
|
|
vertex[6] = x2 / (float)zui->width;
|
|
|
|
vertex[7] = y2 / (float)zui->height;
|
|
|
|
|
2015-10-02 00:15:23 +00:00
|
|
|
coords.color = colors;
|
|
|
|
coords.vertex = vertex;
|
|
|
|
coords.tex_coord = tex_coord;
|
|
|
|
coords.lut_tex_coord = tex_coord;
|
|
|
|
coords.vertices = 3;
|
|
|
|
|
|
|
|
gfx_coord_array_add(&zui->ca, &coords, 3);
|
|
|
|
|
|
|
|
coords.color += 4;
|
|
|
|
coords.vertex += 2;
|
|
|
|
coords.tex_coord += 2;
|
|
|
|
coords.lut_tex_coord += 2;
|
|
|
|
|
|
|
|
gfx_coord_array_add(&zui->ca, &coords, 3);
|
|
|
|
}
|
|
|
|
|
|
|
|
static float randf(float min, float max)
|
|
|
|
{
|
|
|
|
return (rand() * ((max - min) / RAND_MAX)) + min;
|
|
|
|
}
|
|
|
|
|
|
|
|
static float scalef(float val, float oldmin, float oldmax, float newmin, float newmax)
|
|
|
|
{
|
|
|
|
return (((val - oldmin) * (newmax - newmin)) / (oldmax - oldmin)) + newmin;
|
|
|
|
}
|
|
|
|
|
2015-10-02 02:03:34 +00:00
|
|
|
#define NPARTICLES 100
|
|
|
|
|
2015-10-02 00:15:23 +00:00
|
|
|
static void zui_snow(zui_t *zui)
|
|
|
|
{
|
|
|
|
static part_t particles[NPARTICLES];
|
|
|
|
static bool initialized = false;
|
2015-10-02 02:03:34 +00:00
|
|
|
static int timeout = 0;
|
2015-10-10 09:10:59 +00:00
|
|
|
unsigned i, max_gen = 2;
|
2015-10-02 00:15:23 +00:00
|
|
|
|
|
|
|
if (!initialized)
|
|
|
|
{
|
|
|
|
memset(particles, 0, sizeof(particles));
|
|
|
|
initialized = true;
|
|
|
|
}
|
|
|
|
|
|
|
|
for (i = 0; i < NPARTICLES; ++i)
|
|
|
|
{
|
|
|
|
part_t *p = &particles[i];
|
2015-10-02 02:03:34 +00:00
|
|
|
|
2015-10-02 00:15:23 +00:00
|
|
|
if (p->alive)
|
|
|
|
{
|
2015-10-23 07:22:59 +00:00
|
|
|
int16_t mouse_x = menu_input_mouse_state(MENU_MOUSE_X_AXIS);
|
|
|
|
|
2015-10-02 00:15:23 +00:00
|
|
|
p->y += p->yspeed;
|
2015-10-23 07:22:59 +00:00
|
|
|
p->x += scalef(mouse_x, 0, zui->width, -0.3, 0.3) + p->xspeed;
|
2015-10-02 00:15:23 +00:00
|
|
|
|
|
|
|
p->alive = p->y >= 0 && p->y < (int)zui->height && p->x >= 0 && p->x < (int)zui->width;
|
|
|
|
}
|
|
|
|
else if (max_gen > 0 && timeout <= 0)
|
|
|
|
{
|
|
|
|
p->xspeed = randf(-0.2, 0.2);
|
|
|
|
p->yspeed = randf(1, 2);
|
|
|
|
p->y = 0;
|
|
|
|
p->x = rand() % (int)zui->width;
|
2015-10-04 04:36:36 +00:00
|
|
|
p->alpha = (float)rand() / (float)RAND_MAX;
|
2015-10-02 00:15:23 +00:00
|
|
|
p->alive = true;
|
|
|
|
|
|
|
|
max_gen--;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if (max_gen == 0)
|
|
|
|
timeout = 3;
|
|
|
|
else
|
|
|
|
timeout--;
|
|
|
|
|
|
|
|
for (i = 0; i < NPARTICLES; ++i)
|
|
|
|
{
|
2015-10-10 09:10:59 +00:00
|
|
|
unsigned j;
|
|
|
|
GLfloat alpha;
|
|
|
|
GLfloat colors[16];
|
2015-10-02 00:15:23 +00:00
|
|
|
part_t *p = &particles[i];
|
|
|
|
|
|
|
|
if (!p->alive)
|
|
|
|
continue;
|
|
|
|
|
2015-10-10 09:10:59 +00:00
|
|
|
alpha = randf(0, 100) > 90 ? p->alpha/2 : p->alpha;
|
|
|
|
|
|
|
|
for (j = 0; j < 16; j++)
|
|
|
|
{
|
|
|
|
colors[j] = 1;
|
|
|
|
if (j == 3 || j == 7 || j == 11 || j == 15)
|
|
|
|
colors[j] = alpha;
|
|
|
|
}
|
2015-10-04 04:36:36 +00:00
|
|
|
|
|
|
|
zui_push_quad(zui, colors, p->x-2, p->y-2, p->x+2, p->y+2);
|
2015-10-02 00:15:23 +00:00
|
|
|
|
|
|
|
j++;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
static bool zui_button_full(zui_t *zui, int x1, int y1, int x2, int y2, const char *label)
|
|
|
|
{
|
|
|
|
unsigned id = zui_hash(zui, label);
|
|
|
|
bool active = check_button_up(zui, id, x1, y1, x2, y2);
|
2015-10-04 04:36:36 +00:00
|
|
|
const GLfloat *bg = ZUI_BG_PANEL;
|
2015-10-02 00:15:23 +00:00
|
|
|
|
|
|
|
if (zui->item.active == id || zui->item.hot == id)
|
|
|
|
bg = ZUI_BG_HILITE;
|
|
|
|
|
|
|
|
zui_push_quad(zui, bg, x1, y1, x2, y2);
|
2015-10-04 05:46:37 +00:00
|
|
|
zui_draw_text(zui, ZUI_FG_NORMAL, x1+12, y1 + 41, label);
|
2015-10-02 00:15:23 +00:00
|
|
|
|
|
|
|
return active;
|
|
|
|
}
|
|
|
|
|
|
|
|
static bool zui_button(zui_t *zui, int x1, int y1, const char *label)
|
|
|
|
{
|
2015-10-04 05:46:37 +00:00
|
|
|
return zui_button_full(zui, x1, y1, x1 + zui_strwidth(zui->fb_buf, label, 1.0) + 24, y1 + 64, label);
|
2015-10-02 00:15:23 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
static bool zui_list_item(zui_t *zui, int x1, int y1, const char *label)
|
|
|
|
{
|
2015-10-06 10:30:10 +00:00
|
|
|
char title_buf[PATH_MAX_LENGTH];
|
|
|
|
unsigned ticker_size;
|
2015-10-24 03:57:19 +00:00
|
|
|
unsigned id = zui_hash(zui, label);
|
|
|
|
int x2 = x1 + zui->width - 290 - 40;
|
|
|
|
int y2 = y1 + 50;
|
|
|
|
bool active = check_button_up(zui, id, x1, y1, x2, y2);
|
|
|
|
const GLfloat *bg = ZUI_BG_PANEL;
|
2015-10-06 10:30:10 +00:00
|
|
|
uint64_t *frame_count = video_driver_get_frame_count();
|
2015-10-02 00:15:23 +00:00
|
|
|
|
|
|
|
if (zui->item.active == id || zui->item.hot == id)
|
|
|
|
bg = ZUI_BG_HILITE;
|
|
|
|
|
|
|
|
zui_push_quad(zui, bg, x1, y1, x2, y2);
|
2015-10-06 10:30:10 +00:00
|
|
|
|
|
|
|
ticker_size = x2 / 14;
|
|
|
|
|
|
|
|
menu_animation_ticker_str(title_buf,
|
|
|
|
ticker_size,
|
|
|
|
*frame_count / 50,
|
|
|
|
label,
|
|
|
|
(bg == ZUI_BG_HILITE));
|
|
|
|
|
|
|
|
zui_draw_text(zui, ZUI_FG_NORMAL, 12, y1 + 35, title_buf);
|
2015-10-02 00:15:23 +00:00
|
|
|
|
|
|
|
return active;
|
|
|
|
}
|
|
|
|
|
|
|
|
static void zui_tabbed_begin(zui_t *zui, zui_tabbed_t *tab, int x, int y)
|
|
|
|
{
|
|
|
|
tab->x = x;
|
|
|
|
tab->y = y;
|
2015-10-04 05:46:37 +00:00
|
|
|
tab->tabline_size = 60 + 4;
|
2015-10-02 00:15:23 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
static bool zui_tab(zui_t *zui, zui_tabbed_t *tab, const char *label)
|
|
|
|
{
|
2015-10-02 02:03:34 +00:00
|
|
|
bool active;
|
|
|
|
int x1, y1, x2, y2;
|
2015-10-24 03:57:19 +00:00
|
|
|
unsigned id = zui_hash(zui, label);
|
|
|
|
int width = tab->tab_width;
|
2015-10-04 04:36:36 +00:00
|
|
|
const GLfloat *bg = ZUI_BG_PANEL;
|
2015-10-02 00:15:23 +00:00
|
|
|
|
|
|
|
if (!width)
|
2015-10-04 05:46:37 +00:00
|
|
|
width = zui_strwidth(zui->fb_buf, label, 1.0) + 24;
|
2015-10-02 00:15:23 +00:00
|
|
|
|
2015-10-02 02:03:34 +00:00
|
|
|
x1 = tab->x;
|
|
|
|
y1 = tab->y;
|
|
|
|
x2 = x1 + width;
|
2015-10-04 05:46:37 +00:00
|
|
|
y2 = y1 + 60;
|
2015-10-02 00:15:23 +00:00
|
|
|
|
2015-10-02 02:03:34 +00:00
|
|
|
active = check_button_up(zui, id, x1, y1, x2, y2);
|
2015-10-02 00:15:23 +00:00
|
|
|
|
|
|
|
if (zui->item.active == id || tab->active == ~0)
|
|
|
|
tab->active = id;
|
|
|
|
|
|
|
|
if (tab->active == id || zui->item.active == id || zui->item.hot == id)
|
|
|
|
bg = ZUI_BG_HILITE;
|
|
|
|
|
|
|
|
zui_push_quad(zui, bg, x1+0, y1+0, x2, y2);
|
2015-10-04 05:46:37 +00:00
|
|
|
zui_draw_text(zui, ZUI_FG_NORMAL, x1+12, y1 + 41, label);
|
2015-10-02 00:15:23 +00:00
|
|
|
|
|
|
|
if (tab->vertical)
|
|
|
|
tab->y += y2 - y1;
|
|
|
|
else
|
|
|
|
tab->x = x2;
|
|
|
|
|
2015-10-02 02:03:34 +00:00
|
|
|
return (active || (tab->active == id));
|
2015-10-02 00:15:23 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2015-10-04 07:17:47 +00:00
|
|
|
static void render_lay_settings(zui_t *zui)
|
|
|
|
{
|
|
|
|
int width, x1, y1;
|
|
|
|
static zui_tabbed_t tabbed = {~0};
|
|
|
|
tabbed.vertical = true;
|
|
|
|
tabbed.tab_width = 100;
|
|
|
|
|
|
|
|
zui_tabbed_begin(zui, &tabbed, zui->width - 100, 20);
|
|
|
|
|
|
|
|
width = 290;
|
|
|
|
x1 = zui->width - width - 20;
|
|
|
|
y1 = 20;
|
|
|
|
|
|
|
|
y1 += 64;
|
|
|
|
|
|
|
|
if (zui_button_full(zui, x1, y1, x1 + width, y1 + 64, "Back"))
|
|
|
|
layout = LAY_HOME;
|
|
|
|
}
|
2015-10-02 00:15:23 +00:00
|
|
|
|
2015-10-24 04:40:39 +00:00
|
|
|
static int render_lay_root(zui_t *zui)
|
2015-10-02 00:15:23 +00:00
|
|
|
{
|
|
|
|
static zui_tabbed_t tabbed = {~0};
|
2015-10-02 02:03:34 +00:00
|
|
|
global_t *global = global_get_ptr();
|
|
|
|
|
2015-10-02 00:15:23 +00:00
|
|
|
zui_tabbed_begin(zui, &tabbed, 0, 0);
|
|
|
|
|
2015-10-04 05:46:37 +00:00
|
|
|
tabbed.width = zui->width - 290 - 40;
|
2015-10-02 00:15:23 +00:00
|
|
|
|
|
|
|
if (zui_tab(zui, &tabbed, "Recent"))
|
|
|
|
{
|
2015-10-24 04:36:13 +00:00
|
|
|
size_t end = menu_entries_get_end();
|
|
|
|
unsigned size = min(zui->height/30-2, end);
|
|
|
|
unsigned i = menu_entries_get_start();
|
2015-10-02 00:15:23 +00:00
|
|
|
|
2015-10-24 04:36:13 +00:00
|
|
|
for (; i < size; ++i)
|
2015-10-02 00:15:23 +00:00
|
|
|
{
|
2015-10-24 04:36:13 +00:00
|
|
|
menu_entry_t entry;
|
|
|
|
menu_entries_get(i, &entry);
|
2015-10-02 00:15:23 +00:00
|
|
|
|
2015-10-24 04:36:13 +00:00
|
|
|
if (zui_list_item(zui, 0, tabbed.tabline_size + i * 54, entry.path))
|
2015-10-06 14:07:02 +00:00
|
|
|
{
|
2015-10-24 04:40:39 +00:00
|
|
|
menu_entry_action(&entry, i, MENU_ACTION_OK);
|
|
|
|
return 1;
|
2015-10-06 14:07:02 +00:00
|
|
|
}
|
2015-10-02 00:15:23 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if (zui_tab(zui, &tabbed, "Load"))
|
|
|
|
{
|
2015-10-02 02:03:34 +00:00
|
|
|
unsigned cwd_offset;
|
|
|
|
|
2015-10-02 00:15:23 +00:00
|
|
|
if (!zui->load_cwd)
|
2015-10-02 04:19:43 +00:00
|
|
|
{
|
2015-10-02 00:15:23 +00:00
|
|
|
zui->load_cwd = strdup(zui->set->menu_content_directory);
|
2015-10-03 00:37:17 +00:00
|
|
|
if (zui->load_cwd[strlen(zui->load_cwd)-1] == '/'
|
2015-10-02 04:19:43 +00:00
|
|
|
#ifdef _WIN32
|
|
|
|
|| (zui->load_cwd[strlen(zui->load_cwd)-1] == '\\')
|
|
|
|
#endif
|
|
|
|
)
|
|
|
|
zui->load_cwd[strlen(zui->load_cwd)-1] = 0;
|
|
|
|
}
|
2015-10-02 00:15:23 +00:00
|
|
|
|
|
|
|
if (!zui->load_dlist)
|
|
|
|
{
|
|
|
|
zui->load_dlist = dir_list_new(zui->load_cwd, global->core_info.current->supported_extensions, true, true);
|
|
|
|
dir_list_sort(zui->load_dlist, true);
|
|
|
|
zui->load_dlist_first = 0;
|
|
|
|
}
|
|
|
|
|
2015-10-02 02:03:34 +00:00
|
|
|
cwd_offset = min(strlen(zui->load_cwd), 30);
|
2015-10-02 00:15:23 +00:00
|
|
|
|
2015-10-04 05:46:37 +00:00
|
|
|
zui_draw_text(zui, ZUI_FG_NORMAL, 15, tabbed.tabline_size + 5 + 41, &zui->load_cwd[strlen(zui->load_cwd) - cwd_offset]);
|
2015-10-02 00:15:23 +00:00
|
|
|
|
2015-10-04 05:46:37 +00:00
|
|
|
if (zui_button(zui, zui->width - 290 - 129, tabbed.tabline_size + 5, "Home"))
|
2015-10-02 00:15:23 +00:00
|
|
|
{
|
|
|
|
char tmp[PATH_MAX_LENGTH];
|
2015-10-02 02:03:34 +00:00
|
|
|
|
2015-10-02 00:15:23 +00:00
|
|
|
fill_pathname_expand_special(tmp, "~", sizeof(tmp));
|
|
|
|
|
|
|
|
free(zui->load_cwd);
|
|
|
|
zui->load_cwd = strdup(tmp);
|
|
|
|
|
|
|
|
dir_list_free(zui->load_dlist);
|
|
|
|
zui->load_dlist = NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (zui->load_dlist)
|
|
|
|
{
|
2015-10-04 05:46:37 +00:00
|
|
|
if (zui_list_item(zui, 0, tabbed.tabline_size + 73, "^ .."))
|
2015-10-02 00:15:23 +00:00
|
|
|
{
|
|
|
|
path_basedir(zui->load_cwd);
|
2015-10-03 00:37:17 +00:00
|
|
|
if (zui->load_cwd[strlen(zui->load_cwd)-1] == '/'
|
2015-10-02 04:19:43 +00:00
|
|
|
#ifdef _WIN32
|
|
|
|
|| (zui->load_cwd[strlen(zui->load_cwd)-1] == '\\')
|
|
|
|
#endif
|
|
|
|
)
|
2015-10-02 00:15:23 +00:00
|
|
|
zui->load_cwd[strlen(zui->load_cwd)-1] = 0;
|
|
|
|
|
|
|
|
dir_list_free(zui->load_dlist);
|
|
|
|
zui->load_dlist = NULL;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
unsigned size = zui->load_dlist->size;
|
|
|
|
unsigned i, j = 1;
|
|
|
|
unsigned skip = 0;
|
2015-10-24 03:57:19 +00:00
|
|
|
|
2015-10-02 00:15:23 +00:00
|
|
|
for (i = 0; i < size; ++i)
|
|
|
|
{
|
|
|
|
const char *basename = path_basename(zui->load_dlist->elems[i].data);
|
|
|
|
if (basename[0] == '.')
|
|
|
|
skip++;
|
|
|
|
else
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
zui->load_dlist_first += zui->mouse.wheel;
|
|
|
|
|
|
|
|
if (zui->load_dlist_first < 0)
|
|
|
|
zui->load_dlist_first = 0;
|
|
|
|
else if (zui->load_dlist_first > size - 5)
|
|
|
|
zui->load_dlist_first = size - 5;
|
|
|
|
|
|
|
|
zui->load_dlist_first = min(max(zui->load_dlist_first, 0), size - 5 - skip);
|
|
|
|
|
|
|
|
for (i = skip + zui->load_dlist_first; i < size; ++i)
|
|
|
|
{
|
2015-10-02 02:03:34 +00:00
|
|
|
char label[PATH_MAX_LENGTH];
|
|
|
|
const char *path = NULL;
|
|
|
|
const char *basename = NULL;
|
|
|
|
|
2015-10-02 00:15:23 +00:00
|
|
|
if (j > 10)
|
|
|
|
break;
|
|
|
|
|
2015-10-02 02:03:34 +00:00
|
|
|
path = zui->load_dlist->elems[i].data;
|
|
|
|
basename = path_basename(path);
|
2015-10-02 00:15:23 +00:00
|
|
|
|
|
|
|
*label = 0;
|
|
|
|
strncat(label, " ", sizeof(label)-1);
|
|
|
|
strncat(label, basename, sizeof(label)-1);
|
|
|
|
|
|
|
|
if (path_is_directory(path))
|
|
|
|
strncat(label, "/", sizeof(label)-1);
|
|
|
|
|
2015-10-04 05:46:37 +00:00
|
|
|
if (zui_list_item(zui, 0, tabbed.tabline_size + 73 + j * 54, label))
|
2015-10-02 00:15:23 +00:00
|
|
|
{
|
|
|
|
if (path_is_directory(path))
|
|
|
|
{
|
|
|
|
free(zui->load_cwd);
|
|
|
|
zui->load_cwd = strdup(path);
|
|
|
|
dir_list_free(zui->load_dlist);
|
|
|
|
zui->load_dlist = NULL;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
zui->pick_cores = NULL;
|
|
|
|
zui->pick_supported = 0;
|
|
|
|
strncpy(zui->pick_content, path, sizeof(zui->pick_content)-1);
|
|
|
|
core_info_list_get_supported_cores(global->core_info.list, path,
|
|
|
|
&zui->pick_cores, &zui->pick_supported);
|
|
|
|
layout = LAY_PICK_CORE;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
j++;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2015-10-04 07:10:25 +00:00
|
|
|
else if (zui->load_dlist)
|
|
|
|
{
|
|
|
|
dir_list_free(zui->load_dlist);
|
|
|
|
zui->load_dlist = NULL;
|
|
|
|
}
|
2015-10-04 07:08:27 +00:00
|
|
|
|
|
|
|
if (zui_tab(zui, &tabbed, "Collections"))
|
|
|
|
{
|
|
|
|
/* STUB/FIXME */
|
|
|
|
}
|
|
|
|
|
|
|
|
if (zui_tab(zui, &tabbed, "Download"))
|
|
|
|
{
|
|
|
|
/* STUB/FIXME */
|
|
|
|
}
|
|
|
|
|
2015-10-04 05:46:37 +00:00
|
|
|
zui_push_quad(zui, ZUI_BG_HILITE, 0, 60, zui->width - 290 - 40, 60+4);
|
2015-10-24 04:40:39 +00:00
|
|
|
|
|
|
|
return 0;
|
2015-10-02 00:15:23 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void render_sidebar(zui_t *zui)
|
|
|
|
{
|
2015-10-02 02:03:34 +00:00
|
|
|
int width, x1, y1;
|
2015-10-02 00:15:23 +00:00
|
|
|
static zui_tabbed_t tabbed = {~0};
|
|
|
|
tabbed.vertical = true;
|
|
|
|
tabbed.tab_width = 100;
|
|
|
|
|
2015-10-04 05:46:37 +00:00
|
|
|
zui_tabbed_begin(zui, &tabbed, zui->width - 100, 20);
|
2015-10-02 00:15:23 +00:00
|
|
|
|
2015-10-04 05:46:37 +00:00
|
|
|
width = 290;
|
|
|
|
x1 = zui->width - width - 20;
|
|
|
|
y1 = 20;
|
2015-10-02 00:15:23 +00:00
|
|
|
|
2015-10-04 05:46:37 +00:00
|
|
|
if (zui_button_full(zui, x1, y1, x1 + width, y1 + 64, "Settings"))
|
2015-10-02 00:15:23 +00:00
|
|
|
layout = LAY_SETTINGS;
|
|
|
|
|
2015-10-04 05:46:37 +00:00
|
|
|
y1 += 64;
|
2015-10-02 00:15:23 +00:00
|
|
|
|
2015-10-04 05:46:37 +00:00
|
|
|
if (zui_button_full(zui, x1, y1, x1 + width, y1 + 64, "Exit"))
|
2015-10-02 00:15:23 +00:00
|
|
|
exit(0);
|
|
|
|
}
|
|
|
|
|
2015-10-06 11:38:44 +00:00
|
|
|
static int zui_load_content(zui_t *zui, unsigned i)
|
|
|
|
{
|
2015-10-09 18:14:30 +00:00
|
|
|
int ret = menu_common_load_content(zui->pick_cores[i].path,
|
|
|
|
zui->pick_content, false, CORE_TYPE_PLAIN);
|
2015-10-06 11:38:44 +00:00
|
|
|
|
|
|
|
layout = LAY_HOME;
|
|
|
|
|
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
2015-10-04 01:19:53 +00:00
|
|
|
static void zui_render(void)
|
2015-10-02 00:15:23 +00:00
|
|
|
{
|
2015-10-04 01:19:53 +00:00
|
|
|
menu_handle_t *menu = menu_driver_get_ptr();
|
|
|
|
zui_t *zui = NULL;
|
|
|
|
|
|
|
|
if (!menu)
|
2015-10-02 00:15:23 +00:00
|
|
|
return;
|
|
|
|
|
2015-10-04 01:19:53 +00:00
|
|
|
zui = (zui_t*)menu->userdata;
|
|
|
|
|
|
|
|
if (!zui || zui->rendering)
|
|
|
|
return;
|
|
|
|
|
|
|
|
zui_begin();
|
2015-10-02 00:15:23 +00:00
|
|
|
|
|
|
|
zui_push_quad(zui, ZUI_BG_SCREEN, 0, 0, zui->width, zui->height);
|
|
|
|
zui_snow(zui);
|
|
|
|
|
|
|
|
|
2015-10-02 01:55:23 +00:00
|
|
|
switch (layout)
|
2015-10-02 00:15:23 +00:00
|
|
|
{
|
2015-10-02 01:55:23 +00:00
|
|
|
case LAY_HOME:
|
2015-10-04 07:17:47 +00:00
|
|
|
render_sidebar(zui);
|
2015-10-24 04:40:39 +00:00
|
|
|
if (render_lay_root(zui) == 1)
|
|
|
|
return;
|
2015-10-02 01:55:23 +00:00
|
|
|
break;
|
|
|
|
case LAY_SETTINGS:
|
2015-10-04 07:17:47 +00:00
|
|
|
render_lay_settings(zui);
|
2015-10-02 01:55:23 +00:00
|
|
|
break;
|
|
|
|
case LAY_PICK_CORE:
|
2015-10-04 07:17:47 +00:00
|
|
|
render_sidebar(zui);
|
2015-10-02 01:55:23 +00:00
|
|
|
if (zui->pick_supported == 1)
|
|
|
|
{
|
2015-10-06 11:38:44 +00:00
|
|
|
int ret =zui_load_content(zui, 0);
|
2015-10-09 18:14:30 +00:00
|
|
|
|
|
|
|
(void)ret;
|
|
|
|
|
2015-10-02 00:15:23 +00:00
|
|
|
layout = LAY_HOME;
|
2015-10-06 11:38:44 +00:00
|
|
|
zui->time_to_exit = true;
|
|
|
|
return;
|
2015-10-02 01:55:23 +00:00
|
|
|
}
|
|
|
|
else
|
2015-10-02 00:15:23 +00:00
|
|
|
{
|
2015-10-02 01:55:23 +00:00
|
|
|
zui_draw_text(zui, ~0, 8, 18, "Select a core: ");
|
2015-10-02 00:15:23 +00:00
|
|
|
|
2015-10-02 01:55:23 +00:00
|
|
|
if (zui_button(zui, 0, 18 + zui->font_size, "<- Back"))
|
|
|
|
layout = LAY_HOME;
|
|
|
|
|
|
|
|
if (zui->pick_supported)
|
2015-10-02 00:15:23 +00:00
|
|
|
{
|
2015-10-02 01:55:23 +00:00
|
|
|
unsigned i, j = 0;
|
|
|
|
zui->pick_first += zui->mouse.wheel;
|
2015-10-24 02:15:58 +00:00
|
|
|
|
2015-10-02 01:55:23 +00:00
|
|
|
zui->pick_first = min(max(zui->pick_first, 0), zui->pick_supported - 5);
|
2015-10-02 00:15:23 +00:00
|
|
|
|
2015-10-02 01:55:23 +00:00
|
|
|
for (i = zui->pick_first; i < zui->pick_supported; ++i)
|
2015-10-02 00:15:23 +00:00
|
|
|
{
|
2015-10-02 01:55:23 +00:00
|
|
|
if (j > 10)
|
|
|
|
break;
|
|
|
|
|
2015-10-04 05:46:37 +00:00
|
|
|
if (zui_list_item(zui, 0, 54 + j * 54, zui->pick_cores[i].display_name))
|
2015-10-02 01:55:23 +00:00
|
|
|
{
|
2015-10-06 11:38:44 +00:00
|
|
|
int ret =zui_load_content(zui, i);
|
2015-10-09 18:14:30 +00:00
|
|
|
|
|
|
|
(void)ret;
|
|
|
|
|
2015-10-02 01:55:23 +00:00
|
|
|
layout = LAY_HOME;
|
2015-10-06 11:38:44 +00:00
|
|
|
|
|
|
|
zui->time_to_exit = true;
|
2015-10-02 01:55:23 +00:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
j++;
|
2015-10-02 00:15:23 +00:00
|
|
|
}
|
2015-10-02 01:55:23 +00:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2015-10-04 05:46:37 +00:00
|
|
|
zui_list_item(zui, 0, 54, "Content unsupported");
|
2015-10-02 00:15:23 +00:00
|
|
|
}
|
|
|
|
}
|
2015-10-02 01:55:23 +00:00
|
|
|
break;
|
2015-10-02 00:15:23 +00:00
|
|
|
}
|
|
|
|
|
2015-10-09 16:29:24 +00:00
|
|
|
zui_finish(zui, 0, 0, zui->width, zui->height, true, zui->textures.white);
|
2015-10-02 00:15:23 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
static void zarch_draw_cursor(gl_t *gl, float x, float y)
|
|
|
|
{
|
|
|
|
}
|
2015-10-24 03:57:19 +00:00
|
|
|
|
2015-10-02 00:15:23 +00:00
|
|
|
static void zarch_get_message(const char *message)
|
|
|
|
{
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
static void zarch_render(void)
|
|
|
|
{
|
|
|
|
int bottom;
|
|
|
|
unsigned width, height;
|
2015-10-02 02:03:34 +00:00
|
|
|
zui_t *zarch = NULL;
|
2015-10-02 00:15:23 +00:00
|
|
|
menu_handle_t *menu = menu_driver_get_ptr();
|
|
|
|
settings_t *settings = config_get_ptr();
|
|
|
|
|
|
|
|
if (!menu || !menu->userdata)
|
|
|
|
return;
|
2015-10-04 19:57:16 +00:00
|
|
|
|
|
|
|
(void)settings;
|
|
|
|
(void)bottom;
|
|
|
|
(void)zarch;
|
2015-10-02 00:15:23 +00:00
|
|
|
|
|
|
|
video_driver_get_size(&width, &height);
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
static void zarch_frame(void)
|
|
|
|
{
|
2015-10-02 03:34:12 +00:00
|
|
|
unsigned i;
|
|
|
|
GRfloat coord_color[16];
|
|
|
|
GRfloat coord_color2[16];
|
2015-10-24 03:57:19 +00:00
|
|
|
zui_t *zui = NULL;
|
2015-10-04 00:26:06 +00:00
|
|
|
driver_t *driver = driver_get_ptr();
|
|
|
|
settings_t *settings = config_get_ptr();
|
|
|
|
menu_handle_t *menu = menu_driver_get_ptr();
|
2015-10-24 03:57:19 +00:00
|
|
|
gl_t *gl = (gl_t*)video_driver_get_ptr(NULL);
|
2015-10-04 00:26:06 +00:00
|
|
|
|
2015-10-24 03:57:19 +00:00
|
|
|
if (!menu || !gl)
|
2015-10-04 00:26:06 +00:00
|
|
|
return;
|
2015-10-02 00:15:23 +00:00
|
|
|
|
2015-10-04 19:57:16 +00:00
|
|
|
(void)driver;
|
2015-10-04 00:26:06 +00:00
|
|
|
|
2015-10-02 00:15:23 +00:00
|
|
|
zui = (zui_t*)menu->userdata;
|
|
|
|
zui->set = config_get_ptr();
|
|
|
|
zui->menu = menu;
|
|
|
|
|
|
|
|
video_driver_get_size(&zui->width, &zui->height);
|
|
|
|
|
2015-10-02 03:17:40 +00:00
|
|
|
menu_display_ctl(MENU_DISPLAY_CTL_SET_VIEWPORT, NULL);
|
2015-10-02 00:15:23 +00:00
|
|
|
menu_display_ctl(MENU_DISPLAY_CTL_FONT_BUF, &zui->fb_buf);
|
|
|
|
|
2015-10-02 03:34:12 +00:00
|
|
|
for (i = 0; i < 16; i++)
|
|
|
|
{
|
|
|
|
coord_color[i] = 0;
|
|
|
|
coord_color2[i] = 2.0f;
|
|
|
|
|
|
|
|
if (i == 3 || i == 7 || i == 11 || i == 15)
|
|
|
|
{
|
|
|
|
coord_color[i] = 0.10f;
|
|
|
|
coord_color2[i] = 0.10f;
|
|
|
|
}
|
|
|
|
}
|
2015-10-04 01:19:53 +00:00
|
|
|
zui_render();
|
2015-10-02 00:15:23 +00:00
|
|
|
|
|
|
|
/* fetch it again in case the pointer was invalidated by a core load */
|
2015-10-04 01:19:53 +00:00
|
|
|
gl = (gl_t*)video_driver_get_ptr(NULL);
|
2015-10-02 00:15:23 +00:00
|
|
|
|
|
|
|
if (zui->set->menu.mouse.enable)
|
2015-10-23 07:22:59 +00:00
|
|
|
zarch_draw_cursor(gl, menu_input_mouse_state(MENU_MOUSE_X_AXIS), menu_input_mouse_state(MENU_MOUSE_Y_AXIS));
|
2015-10-02 00:15:23 +00:00
|
|
|
|
2015-10-18 05:43:27 +00:00
|
|
|
menu_display_frame_background(menu, settings,
|
2015-10-02 03:34:12 +00:00
|
|
|
gl, zui->width, zui->height,
|
|
|
|
zui->textures.bg.id, 0.75f, false,
|
|
|
|
&coord_color[0], &coord_color2[0],
|
|
|
|
&zarch_vertexes[0], &zarch_tex_coords[0]);
|
|
|
|
|
2015-10-04 01:19:53 +00:00
|
|
|
if (gl && gl->shader && gl->shader->use)
|
|
|
|
gl->shader->use(gl, GL_SHADER_STOCK_BLEND);
|
2015-10-02 00:15:23 +00:00
|
|
|
|
2015-10-02 03:17:40 +00:00
|
|
|
menu_display_ctl(MENU_DISPLAY_CTL_UNSET_VIEWPORT, NULL);
|
2015-10-02 00:15:23 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
static void *zarch_init(void)
|
|
|
|
{
|
2015-10-02 02:03:34 +00:00
|
|
|
int tmpi;
|
|
|
|
zui_t *zui = NULL;
|
2015-10-02 00:15:23 +00:00
|
|
|
const video_driver_t *video_driver = NULL;
|
|
|
|
menu_handle_t *menu = NULL;
|
|
|
|
settings_t *settings = config_get_ptr();
|
|
|
|
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;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (settings->menu.mouse.enable)
|
|
|
|
{
|
|
|
|
RARCH_WARN("Forcing menu_mouse_enable=false\n");
|
|
|
|
settings->menu.mouse.enable = false;
|
|
|
|
}
|
|
|
|
|
|
|
|
menu = (menu_handle_t*)calloc(1, sizeof(*menu));
|
|
|
|
|
|
|
|
if (!menu)
|
|
|
|
goto error;
|
|
|
|
|
|
|
|
menu->userdata = (zui_t*)calloc(1, sizeof(zui_t));
|
|
|
|
|
|
|
|
if (!menu->userdata)
|
|
|
|
goto error;
|
|
|
|
|
|
|
|
zui = (zui_t*)menu->userdata;
|
|
|
|
|
|
|
|
tmpi = 1000;
|
|
|
|
menu_display_ctl(MENU_DISPLAY_CTL_SET_HEADER_HEIGHT, &tmpi);
|
|
|
|
|
2015-10-04 05:46:37 +00:00
|
|
|
tmpi = 28;
|
2015-10-02 00:15:23 +00:00
|
|
|
menu_display_ctl(MENU_DISPLAY_CTL_SET_FONT_SIZE, &tmpi);
|
|
|
|
|
2015-10-02 02:03:34 +00:00
|
|
|
zui->header_height = 1000; /* dpi / 3; */
|
2015-10-04 05:46:37 +00:00
|
|
|
zui->font_size = 28;
|
2015-10-02 00:15:23 +00:00
|
|
|
|
|
|
|
if (settings->menu.wallpaper[0] != '\0')
|
|
|
|
rarch_main_data_msg_queue_push(DATA_TYPE_IMAGE,
|
|
|
|
settings->menu.wallpaper, "cb_menu_wallpaper", 0, 1, true);
|
|
|
|
|
|
|
|
zui->ca.allocated = 0;
|
|
|
|
|
|
|
|
matrix_4x4_ortho(&zui->mvp, 0, 1, 1, 0, 0, 1);
|
|
|
|
|
2015-10-04 05:46:37 +00:00
|
|
|
zui_font(menu);
|
|
|
|
|
2015-10-02 00:15:23 +00:00
|
|
|
return menu;
|
|
|
|
error:
|
|
|
|
if (menu)
|
|
|
|
free(menu);
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
static void zarch_free(void *data)
|
|
|
|
{
|
|
|
|
menu_handle_t *menu = (menu_handle_t*)data;
|
|
|
|
driver_t *driver = driver_get_ptr();
|
2015-10-24 03:57:19 +00:00
|
|
|
zui_t *zarch = (zui_t*)menu->userdata;
|
2015-10-24 04:56:08 +00:00
|
|
|
const struct font_renderer *font_driver =
|
|
|
|
(const struct font_renderer*)driver->font_osd_driver;
|
2015-10-02 00:15:23 +00:00
|
|
|
|
|
|
|
if (!zarch || !menu)
|
|
|
|
return;
|
|
|
|
|
|
|
|
gfx_coord_array_free(&zarch->tmp_block.carr);
|
|
|
|
|
2015-10-24 04:56:08 +00:00
|
|
|
if (menu->userdata)
|
|
|
|
free(menu->userdata);
|
|
|
|
menu->userdata = NULL;
|
2015-10-02 00:15:23 +00:00
|
|
|
|
2015-10-24 04:56:08 +00:00
|
|
|
if (font_driver->bind_block)
|
2015-10-02 00:15:23 +00:00
|
|
|
font_driver->bind_block(driver->font_osd_data, NULL);
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
static void zarch_context_bg_destroy(zui_t *zarch)
|
|
|
|
{
|
2015-10-24 04:56:08 +00:00
|
|
|
if (zarch->textures.bg.id)
|
|
|
|
glDeleteTextures(1, (const GLuint*)&zarch->textures.bg.id);
|
2015-10-02 00:15:23 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
static void zarch_context_destroy(void)
|
|
|
|
{
|
|
|
|
menu_handle_t *menu = menu_driver_get_ptr();
|
|
|
|
driver_t *driver = driver_get_ptr();
|
2015-10-24 04:56:08 +00:00
|
|
|
zui_t *zarch = menu ? (zui_t*)menu->userdata : NULL;
|
2015-10-02 00:15:23 +00:00
|
|
|
|
2015-10-24 04:56:08 +00:00
|
|
|
if (!menu || !zarch || !driver)
|
2015-10-02 00:15:23 +00:00
|
|
|
return;
|
|
|
|
|
|
|
|
menu_display_free_main_font();
|
|
|
|
|
|
|
|
zarch_context_bg_destroy(zarch);
|
|
|
|
}
|
|
|
|
|
2015-10-02 03:34:12 +00:00
|
|
|
static void zarch_allocate_white_texture(zui_t *zarch)
|
|
|
|
{
|
|
|
|
struct texture_image ti;
|
|
|
|
static const uint8_t white_data[] = { 0xff, 0xff, 0xff, 0xff };
|
|
|
|
|
|
|
|
ti.width = 1;
|
|
|
|
ti.height = 1;
|
|
|
|
ti.pixels = (uint32_t*)&white_data;
|
|
|
|
|
|
|
|
zarch->textures.white = video_texture_load(&ti,
|
|
|
|
TEXTURE_BACKEND_OPENGL, TEXTURE_FILTER_NEAREST);
|
|
|
|
}
|
|
|
|
|
|
|
|
static bool zarch_load_image(void *data, menu_image_type_t type)
|
2015-10-02 00:15:23 +00:00
|
|
|
{
|
2015-10-24 03:57:19 +00:00
|
|
|
zui_t *zarch = NULL;
|
2015-10-02 00:15:23 +00:00
|
|
|
menu_handle_t *menu = menu_driver_get_ptr();
|
|
|
|
|
2015-10-24 04:56:08 +00:00
|
|
|
if (!menu)
|
2015-10-02 00:15:23 +00:00
|
|
|
return false;
|
|
|
|
|
|
|
|
zarch = (zui_t*)menu->userdata;
|
|
|
|
|
2015-10-24 04:56:08 +00:00
|
|
|
if (!zarch || !data)
|
|
|
|
return false;
|
|
|
|
|
|
|
|
switch (type)
|
|
|
|
{
|
|
|
|
case MENU_IMAGE_NONE:
|
|
|
|
break;
|
|
|
|
case MENU_IMAGE_WALLPAPER:
|
|
|
|
zarch_context_bg_destroy(zarch);
|
|
|
|
zarch->textures.bg.id = video_texture_load(data,
|
|
|
|
TEXTURE_BACKEND_OPENGL, TEXTURE_FILTER_MIPMAP_LINEAR);
|
|
|
|
zarch_allocate_white_texture(zarch);
|
|
|
|
break;
|
|
|
|
case MENU_IMAGE_BOXART:
|
|
|
|
break;
|
|
|
|
}
|
2015-10-02 00:15:23 +00:00
|
|
|
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
static void zarch_context_reset(void)
|
|
|
|
{
|
2015-10-24 03:57:19 +00:00
|
|
|
zui_t *zui = NULL;
|
2015-10-02 00:15:23 +00:00
|
|
|
menu_handle_t *menu = menu_driver_get_ptr();
|
|
|
|
settings_t *settings = config_get_ptr();
|
|
|
|
const char *font_path = NULL;
|
|
|
|
|
|
|
|
if (!menu || !menu->userdata || !settings)
|
|
|
|
return;
|
|
|
|
|
|
|
|
zui = (zui_t*)menu->userdata;
|
|
|
|
font_path = settings->video.font_enable ? settings->video.font_path : NULL;
|
|
|
|
|
|
|
|
if (!menu_display_init_main_font(menu, font_path, zui->font_size))
|
|
|
|
RARCH_WARN("Failed to load font.");
|
|
|
|
|
|
|
|
zarch_context_bg_destroy(zui);
|
2015-10-02 03:34:12 +00:00
|
|
|
zarch_allocate_white_texture(zui);
|
2015-10-02 00:15:23 +00:00
|
|
|
|
|
|
|
rarch_main_data_msg_queue_push(DATA_TYPE_IMAGE,
|
|
|
|
settings->menu.wallpaper, "cb_menu_wallpaper", 0, 1, true);
|
2015-10-04 05:46:37 +00:00
|
|
|
|
|
|
|
menu_display_ctl(MENU_DISPLAY_CTL_SET_FONT_SIZE, &zui->font_size);
|
|
|
|
zui_font(menu);
|
2015-10-02 00:15:23 +00:00
|
|
|
}
|
|
|
|
|
2015-10-11 10:58:21 +00:00
|
|
|
static int zarch_iterate(enum menu_action action)
|
2015-10-03 03:24:03 +00:00
|
|
|
{
|
2015-10-06 11:38:44 +00:00
|
|
|
zui_t *zui = NULL;
|
|
|
|
menu_handle_t *menu = menu_driver_get_ptr();
|
2015-10-03 03:24:03 +00:00
|
|
|
|
|
|
|
if (!menu)
|
|
|
|
return 0;
|
|
|
|
|
2015-10-06 11:38:44 +00:00
|
|
|
zui = (zui_t*)menu->userdata;
|
|
|
|
|
|
|
|
if (!zui)
|
|
|
|
return -1;
|
|
|
|
|
2015-10-11 10:58:21 +00:00
|
|
|
BIT64_SET(menu->state, MENU_STATE_RENDER_FRAMEBUFFER);
|
|
|
|
BIT64_SET(menu->state, MENU_STATE_BLIT);
|
2015-10-03 03:24:03 +00:00
|
|
|
|
2015-10-06 13:57:24 +00:00
|
|
|
switch (action)
|
|
|
|
{
|
|
|
|
case MENU_ACTION_UP:
|
|
|
|
zui->load_dlist_first--;
|
|
|
|
break;
|
|
|
|
case MENU_ACTION_DOWN:
|
|
|
|
zui->load_dlist_first++;
|
|
|
|
break;
|
|
|
|
case MENU_ACTION_LEFT:
|
|
|
|
zui->load_dlist_first -= 5;
|
|
|
|
break;
|
|
|
|
case MENU_ACTION_RIGHT:
|
|
|
|
zui->load_dlist_first += 5;
|
|
|
|
break;
|
2015-10-06 14:07:02 +00:00
|
|
|
default:
|
|
|
|
break;
|
2015-10-06 13:57:24 +00:00
|
|
|
}
|
|
|
|
|
2015-10-06 11:38:44 +00:00
|
|
|
if (zui->time_to_exit)
|
|
|
|
{
|
|
|
|
RARCH_LOG("Gets here.\n");
|
|
|
|
zui->time_to_exit = false;
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
2015-10-24 04:36:13 +00:00
|
|
|
|
2015-10-03 03:24:03 +00:00
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2015-10-24 04:36:13 +00:00
|
|
|
static bool zarch_menu_init_list(void *data)
|
|
|
|
{
|
|
|
|
int ret;
|
|
|
|
menu_displaylist_info_t info = {0};
|
|
|
|
file_list_t *menu_stack = menu_entries_get_menu_stack_ptr();
|
|
|
|
file_list_t *selection_buf = menu_entries_get_selection_buf_ptr();
|
|
|
|
|
|
|
|
strlcpy(info.label, menu_hash_to_str(MENU_VALUE_HISTORY_TAB), sizeof(info.label));
|
|
|
|
|
|
|
|
menu_entries_push(menu_stack, info.path, info.label, info.type, info.flags, 0);
|
|
|
|
|
|
|
|
event_command(EVENT_CMD_HISTORY_INIT);
|
|
|
|
|
|
|
|
info.list = selection_buf;
|
|
|
|
menu_displaylist_push_list(&info, DISPLAYLIST_HISTORY);
|
|
|
|
|
|
|
|
info.need_push = true;
|
|
|
|
|
|
|
|
(void)ret;
|
|
|
|
|
|
|
|
menu_displaylist_push_list_process(&info);
|
|
|
|
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
2015-10-02 00:15:23 +00:00
|
|
|
menu_ctx_driver_t menu_ctx_zarch = {
|
|
|
|
NULL,
|
|
|
|
zarch_get_message,
|
2015-10-03 03:24:03 +00:00
|
|
|
zarch_iterate,
|
2015-10-02 00:15:23 +00:00
|
|
|
zarch_render,
|
|
|
|
zarch_frame,
|
|
|
|
zarch_init,
|
|
|
|
zarch_free,
|
|
|
|
zarch_context_reset,
|
|
|
|
zarch_context_destroy,
|
|
|
|
NULL,
|
|
|
|
NULL,
|
|
|
|
NULL,
|
|
|
|
NULL,
|
|
|
|
NULL,
|
|
|
|
NULL,
|
|
|
|
NULL,
|
|
|
|
NULL,
|
|
|
|
NULL,
|
2015-10-24 04:36:13 +00:00
|
|
|
zarch_menu_init_list,
|
2015-10-02 00:15:23 +00:00
|
|
|
NULL,
|
|
|
|
NULL,
|
|
|
|
NULL,
|
|
|
|
NULL,
|
|
|
|
NULL,
|
|
|
|
NULL,
|
|
|
|
NULL,
|
|
|
|
NULL,
|
|
|
|
NULL,
|
2015-10-22 02:12:32 +00:00
|
|
|
NULL,
|
2015-10-02 03:34:12 +00:00
|
|
|
zarch_load_image,
|
2015-10-02 00:15:23 +00:00
|
|
|
"zarch",
|
|
|
|
MENU_VIDEO_DRIVER_OPENGL,
|
|
|
|
NULL,
|
|
|
|
};
|