RetroArch/menu/drivers/zarch.c

1358 lines
34 KiB
C
Raw Normal View History

/* RetroArch - A frontend for libretro.
* Copyright (C) 2011-2016 - Higor Euripedes
2016-01-10 03:06:50 +00:00
* Copyright (C) 2011-2016 - 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 <gfx/math/matrix_4x4.h>
#include <string/stdstring.h>
#include <formats/image.h>
2015-10-26 20:59:26 +00:00
#include <compat/strl.h>
#include <retro_stat.h>
2015-10-03 01:15:47 +00:00
#include "menu_generic.h"
#include "../../config.def.h"
2015-10-26 20:59:26 +00:00
#include "../../dir_list_special.h"
2015-12-06 16:55:27 +00:00
#include "../menu_driver.h"
#include "../menu_animation.h"
#include "../menu_entry.h"
#include "../menu_display.h"
2015-12-09 08:53:43 +00:00
#include "../menu_navigation.h"
#include "../menu_hash.h"
#include "../../gfx/font_driver.h"
#include "../../core_info.h"
#include "../../configuration.h"
#include "../../runloop.h"
2015-11-23 11:03:38 +00:00
#include "../../verbosity.h"
#include "../../tasks/tasks_internal.h"
#define ZUI_FG_NORMAL (~0)
2016-02-27 15:44:22 +00:00
#define ZUI_ITEM_SIZE_PX 54
2016-02-26 22:31:34 +00:00
#define NPARTICLES 100
2016-02-26 21:57:04 +00:00
enum zarch_zui_input_state
{
MENU_ZARCH_MOUSE_X = 0,
MENU_ZARCH_MOUSE_Y,
MENU_POINTER_ZARCH_X,
MENU_POINTER_ZARCH_Y,
MENU_ZARCH_PRESSED
};
enum zarch_layout_type
{
LAY_HOME = 0,
LAY_PICK_CORE,
LAY_SETTINGS
};
static const float zui_bg_panel[] = {
0, 0, 0, 0.25,
0, 0, 0, 0.25,
0, 0, 0, 0.25,
0, 0, 0, 0.25,
};
static const float zui_bg_screen[] = {
2015-10-24 23:27:18 +00:00
0.07, 0.19, 0.26, 0.75,
0.07, 0.19, 0.26, 0.75,
0.15, 0.31, 0.47, 0.75,
0.15, 0.31, 0.47, 0.75,
};
static const float 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,
};
static const float zui_bg_pad_hilite[] = {
2015-10-24 19:11:07 +00:00
0.30, 0.76, 0.93, 1,
0.30, 0.76, 0.93, 1,
0.30, 0.76, 0.93, 1,
0.30, 0.76, 0.93, 1,
};
typedef struct zarch_handle
{
enum menu_action action;
bool rendering;
math_matrix_4x4 mvp;
unsigned width;
unsigned height;
gfx_font_raster_block_t tmp_block;
unsigned hash;
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
{
2015-11-10 00:58:05 +00:00
uintptr_t id;
2015-10-02 03:34:12 +00:00
char path[PATH_MAX_LENGTH];
} bg;
2015-10-24 22:55:02 +00:00
2015-11-10 00:58:05 +00:00
uintptr_t white;
2015-10-02 03:34:12 +00:00
} textures;
/* LAY_ROOT's "Recent" */
int recent_dlist_first;
/* 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;
int font_size;
int header_height;
2015-10-27 05:11:51 +00:00
unsigned next_id;
unsigned prev_id;
bool next_selection_set;
} zui_t;
2016-02-29 01:48:29 +00:00
struct zui_tabbed
2015-10-02 02:03:34 +00:00
{
2015-10-27 04:23:45 +00:00
unsigned prev_id;
unsigned active_id;
unsigned next_id;
2015-10-02 02:03:34 +00:00
int x, y;
int width;
int height; /* unused */
int tabline_size;
bool update_width;
bool vertical;
int tab_width;
unsigned tab_selection;
2015-10-27 05:22:50 +00:00
bool inited;
2016-02-29 01:48:29 +00:00
};
2015-10-02 02:03:34 +00:00
2016-02-29 01:48:29 +00:00
struct zui_part
2015-10-02 02:03:34 +00:00
{
float x, y;
float xspeed, yspeed;
float alpha;
2015-10-02 02:03:34 +00:00
bool alive;
2016-02-29 01:48:29 +00:00
};
2015-10-02 02:03:34 +00:00
2016-02-26 21:57:04 +00:00
static enum zarch_layout_type zarch_layout;
2015-10-02 02:03:34 +00:00
2015-12-10 14:44:26 +00:00
static void zarch_zui_font(void)
{
int font_size;
char mediapath[PATH_MAX_LENGTH], fontpath[PATH_MAX_LENGTH];
2016-02-09 00:24:35 +00:00
menu_display_ctx_font_t font_info;
settings_t *settings = config_get_ptr();
menu_display_ctl(MENU_DISPLAY_CTL_FONT_SIZE, &font_size);
2016-02-21 08:51:16 +00:00
fill_pathname_join(mediapath,
settings->assets_directory, "zarch", sizeof(mediapath));
fill_pathname_join(fontpath,
mediapath, "Roboto-Condensed.ttf", sizeof(fontpath));
2016-02-09 00:24:35 +00:00
font_info.path = fontpath;
font_info.size = font_size;
if (!menu_display_ctl(MENU_DISPLAY_CTL_FONT_MAIN_INIT, &font_info))
RARCH_WARN("Failed to load font.");
}
2015-10-25 01:19:26 +00:00
static float zarch_zui_strwidth(void *fb_buf, const char *text, float scale)
{
2015-12-05 11:17:58 +00:00
return font_driver_get_message_width(fb_buf, text, strlen(text), scale);
}
2015-10-25 02:49:35 +00:00
static int16_t zarch_zui_input_state(zui_t *zui, enum zarch_zui_input_state state)
2015-10-25 02:49:35 +00:00
{
switch (state)
{
2015-10-25 03:08:51 +00:00
case MENU_ZARCH_MOUSE_X:
return menu_input_mouse_state(MENU_MOUSE_X_AXIS);
case MENU_ZARCH_MOUSE_Y:
return menu_input_mouse_state(MENU_MOUSE_Y_AXIS);
case MENU_POINTER_ZARCH_X:
return menu_input_pointer_state(MENU_POINTER_X_AXIS);
case MENU_POINTER_ZARCH_Y:
return menu_input_pointer_state(MENU_POINTER_Y_AXIS);
2015-10-25 02:49:35 +00:00
case MENU_ZARCH_PRESSED:
2016-02-21 08:51:16 +00:00
if ( menu_input_mouse_state(MENU_MOUSE_LEFT_BUTTON)
|| menu_input_pointer_state(MENU_POINTER_PRESSED))
2015-10-25 02:49:35 +00:00
return 1;
2016-02-28 16:45:14 +00:00
if (zui->action == MENU_ACTION_OK)
return 1;
2015-10-25 02:49:35 +00:00
break;
}
return 0;
}
2016-02-21 08:51:16 +00:00
static bool zarch_zui_check_button_down(zui_t *zui,
unsigned id, int x1, int y1, int x2, int y2)
{
menu_input_ctx_hitbox_t hitbox;
bool result = false;
hitbox.x1 = x1;
hitbox.x2 = x2;
hitbox.y1 = y1;
hitbox.y2 = y2;
if (menu_input_ctl(MENU_INPUT_CTL_CHECK_INSIDE_HITBOX, &hitbox))
zui->item.hot = id;
2016-02-21 08:51:16 +00:00
if ( zui->item.hot == id
&& zarch_zui_input_state(zui, MENU_ZARCH_PRESSED))
{
result = true;
zui->item.active = id;
}
return result;
}
2016-02-21 08:51:16 +00:00
static bool zarch_zui_check_button_up(zui_t *zui,
unsigned id, int x1, int y1, int x2, int y2)
{
menu_input_ctx_hitbox_t hitbox;
bool result = false;
hitbox.x1 = x1;
hitbox.x2 = x2;
hitbox.y1 = y1;
hitbox.y2 = y2;
if (menu_input_ctl(MENU_INPUT_CTL_CHECK_INSIDE_HITBOX, &hitbox))
zui->item.hot = id;
2016-02-21 08:51:16 +00:00
if ( zui->item.active == id
&& !zarch_zui_input_state(zui, MENU_ZARCH_PRESSED))
{
if (zui->item.hot == id)
result = true;
zui->item.active = 0;
}
2015-10-25 01:19:26 +00:00
zarch_zui_check_button_down(zui, id, x1, y1, x2, y2);
return result;
}
2015-10-25 01:19:26 +00:00
static unsigned zarch_zui_hash(zui_t *zui, const char *s)
{
unsigned hval = zui->hash;
2015-10-02 02:03:34 +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;
}
2016-02-21 08:51:16 +00:00
static void zarch_zui_draw_text(zui_t *zui,
uint32_t color, int x, int y, const char *text)
{
struct font_params params;
if (!zui || !zui->fb_buf || string_is_empty(text))
return;
2015-11-02 21:11:01 +00:00
/* need to use height-y because the font renderer
* uses a different model-view-projection (MVP). */
params.x = x / (float)zui->width;
params.y = (zui->height - y) / (float)zui->height;
params.scale = 1.0f;
params.drop_mod = 0.0f;
params.drop_x = 0.0f;
params.drop_y = 0.0f;
params.color = color;
params.full_screen = true;
params.text_align = TEXT_ALIGN_LEFT;
video_driver_set_osd_msg(text, &params, zui->fb_buf);
}
2015-10-26 04:30:41 +00:00
static void zarch_zui_push_quad(unsigned width, unsigned height,
2015-11-10 00:58:05 +00:00
const float *colors, gfx_coord_array_t *ca, int x1, int y1,
int x2, int y2)
{
2016-02-09 03:49:47 +00:00
menu_display_ctx_coord_draw_t coord_draw;
2015-10-04 00:34:18 +00:00
gfx_coords_t coords;
2015-11-10 00:58:05 +00:00
float vertex[8];
2015-10-04 00:34:18 +00:00
2015-10-26 04:28:08 +00:00
vertex[0] = x1 / (float)width;
vertex[1] = y1 / (float)height;
vertex[2] = x2 / (float)width;
vertex[3] = y1 / (float)height;
vertex[4] = x1 / (float)width;
vertex[5] = y2 / (float)height;
vertex[6] = x2 / (float)width;
vertex[7] = y2 / (float)height;
2015-10-04 00:34:18 +00:00
2016-02-09 03:49:47 +00:00
coord_draw.ptr = NULL;
menu_display_ctl(MENU_DISPLAY_CTL_TEX_COORDS_GET, &coord_draw);
coords.color = colors;
coords.vertex = vertex;
2016-02-09 03:49:47 +00:00
coords.tex_coord = coord_draw.ptr;
coords.lut_tex_coord = coord_draw.ptr;
coords.vertices = 3;
2015-10-26 04:30:41 +00:00
gfx_coord_array_add(ca, &coords, 3);
coords.color += 4;
coords.vertex += 2;
coords.tex_coord += 2;
coords.lut_tex_coord += 2;
2015-10-26 04:30:41 +00:00
gfx_coord_array_add(ca, &coords, 3);
}
2015-10-25 01:19:26 +00:00
static float zarch_zui_randf(float min, float max)
{
return (rand() * ((max - min) / RAND_MAX)) + min;
}
2016-02-21 08:51:16 +00:00
static float zarch_zui_scalef(float val,
float oldmin, float oldmax, float newmin, float newmax)
{
return (((val - oldmin) * (newmax - newmin)) / (oldmax - oldmin)) + newmin;
}
2016-02-21 08:51:16 +00:00
static void zarch_zui_snow(zui_t *zui, gfx_coord_array_t *ca,
int width, int height)
{
2016-02-29 01:48:29 +00:00
static struct zui_part particles[NPARTICLES];
static bool initialized = false;
2015-10-02 02:03:34 +00:00
static int timeout = 0;
2016-02-21 08:51:16 +00:00
unsigned i, max_gen = 2;
if (!initialized)
{
memset(particles, 0, sizeof(particles));
initialized = true;
}
for (i = 0; i < NPARTICLES; ++i)
{
2016-02-29 01:48:29 +00:00
struct zui_part *p = (struct zui_part*)&particles[i];
if (!p)
return;
2015-10-02 02:03:34 +00:00
if (p->alive)
{
int16_t mouse_x = zarch_zui_input_state(zui, MENU_ZARCH_MOUSE_X);
2015-10-25 01:22:00 +00:00
p->y += p->yspeed;
2016-02-21 08:51:16 +00:00
p->x += zarch_zui_scalef(mouse_x, 0, width, -0.3, 0.3);
p->x += p->xspeed;
2015-10-25 03:04:46 +00:00
2016-02-21 08:51:16 +00:00
p->alive = p->y >= 0 && p->y < height
&& p->x >= 0 && p->x < width;
}
else if (max_gen > 0 && timeout <= 0)
{
2015-10-25 01:19:26 +00:00
p->xspeed = zarch_zui_randf(-0.2, 0.2);
p->yspeed = zarch_zui_randf(1, 2);
2015-10-25 01:22:00 +00:00
p->y = 0;
2015-10-26 04:28:08 +00:00
p->x = rand() % width;
2015-10-25 01:22:00 +00:00
p->alpha = (float)rand() / (float)RAND_MAX;
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;
2015-11-10 00:58:05 +00:00
float alpha;
float colors[16];
2016-02-29 01:48:29 +00:00
struct zui_part *p = &particles[i];
if (!p)
return;
if (!p->alive)
continue;
2015-10-25 01:19:26 +00:00
alpha = zarch_zui_randf(0, 100) > 90 ? p->alpha/2 : p->alpha;
2015-10-10 09:10:59 +00:00
for (j = 0; j < 16; j++)
{
colors[j] = 1;
if (j == 3 || j == 7 || j == 11 || j == 15)
colors[j] = alpha;
}
2016-02-21 08:51:16 +00:00
zarch_zui_push_quad(width, height,
colors, ca, p->x-2, p->y-2, p->x+2, p->y+2);
j++;
}
}
2016-02-21 08:51:16 +00:00
static bool zarch_zui_button_full(zui_t *zui,
int x1, int y1, int x2, int y2, const char *label)
{
2015-10-25 01:19:26 +00:00
unsigned id = zarch_zui_hash(zui, label);
bool active = zarch_zui_check_button_up(zui, id, x1, y1, x2, y2);
const float *bg = zui_bg_panel;
if (zui->item.active == id || zui->item.hot == id)
bg = zui_bg_hilite;
2015-10-26 04:30:41 +00:00
zarch_zui_push_quad(zui->width, zui->height, bg, &zui->ca, x1, y1, x2, y2);
2015-10-25 01:19:26 +00:00
zarch_zui_draw_text(zui, ZUI_FG_NORMAL, x1+12, y1 + 41, label);
return active;
}
2015-10-25 01:19:26 +00:00
static bool zarch_zui_button(zui_t *zui, int x1, int y1, const char *label)
{
if (!zui || !zui->fb_buf)
return false;
2016-02-21 08:51:16 +00:00
return zarch_zui_button_full(zui, x1, y1, x1
+ zarch_zui_strwidth(zui->fb_buf, label, 1.0) + 24, y1 + 64, label);
}
2016-02-29 01:48:29 +00:00
static bool zarch_zui_list_item(zui_t *zui, struct zui_tabbed *tab, int x1, int y1,
2016-02-28 15:44:41 +00:00
const char *label, unsigned item_id, const char *entry, bool selected)
{
2016-02-25 14:19:33 +00:00
menu_animation_ctx_ticker_t ticker;
char title_buf[PATH_MAX_LENGTH];
unsigned ticker_size;
2016-02-25 14:19:33 +00:00
uint64_t *frame_count = NULL;
2015-10-25 01:19:26 +00:00
unsigned id = zarch_zui_hash(zui, label);
2015-10-24 03:57:19 +00:00
int x2 = x1 + zui->width - 290 - 40;
int y2 = y1 + 50;
2015-10-25 01:19:26 +00:00
bool active = zarch_zui_check_button_up(zui, id, x1, y1, x2, y2);
const float *bg = zui_bg_panel;
video_driver_ctl(RARCH_DISPLAY_CTL_GET_FRAME_COUNT, &frame_count);
2015-10-27 04:23:45 +00:00
if (tab->active_id != tab->prev_id)
{
2015-10-27 04:45:24 +00:00
tab->prev_id = tab->active_id;
}
2016-02-28 15:44:41 +00:00
if (selected)
{
2016-02-28 15:44:41 +00:00
zui->next_id = item_id;
zui->next_selection_set = true;
2016-02-27 01:51:29 +00:00
}
/* Set background color */
if (zui->item.active == id || zui->item.hot == id)
bg = zui_bg_hilite;
2016-02-28 15:44:41 +00:00
else if (selected)
bg = zui_bg_pad_hilite;
ticker_size = x2 / 14;
2016-02-25 14:19:33 +00:00
ticker.s = title_buf;
ticker.len = ticker_size;
ticker.idx = *frame_count / 50;
ticker.str = label;
ticker.selected = (bg == zui_bg_hilite || bg == zui_bg_pad_hilite);
2016-02-25 14:19:33 +00:00
menu_animation_ctl(MENU_ANIMATION_CTL_TICKER, &ticker);
2015-10-26 04:30:41 +00:00
zarch_zui_push_quad(zui->width, zui->height, bg, &zui->ca, x1, y1, x2, y2);
2015-10-25 01:19:26 +00:00
zarch_zui_draw_text(zui, ZUI_FG_NORMAL, 12, y1 + 35, title_buf);
2015-10-25 06:50:13 +00:00
if (entry)
zarch_zui_draw_text(zui, ZUI_FG_NORMAL, x2 - 200, y1 + 35, entry);
return active;
}
2016-02-29 01:48:29 +00:00
static void zarch_zui_tabbed_begin(zui_t *zui, struct zui_tabbed *tab, int x, int y)
{
2015-10-25 01:22:00 +00:00
tab->x = x;
tab->y = y;
tab->tabline_size = 60 + 4;
}
2016-02-29 01:48:29 +00:00
static bool zarch_zui_tab(zui_t *zui, struct zui_tabbed *tab,
2016-02-21 08:51:16 +00:00
const char *label, unsigned tab_id)
{
2015-10-02 02:03:34 +00:00
bool active;
int x1, y1, x2, y2;
2015-10-25 01:19:26 +00:00
unsigned id = zarch_zui_hash(zui, label);
2015-10-24 03:57:19 +00:00
int width = tab->tab_width;
const float *bg = zui_bg_panel;
bool selected = tab->tab_selection == tab_id; /* TODO/FIXME */
if (!zui || !tab )
return false;
if (!width)
{
if (!zui->fb_buf)
return false;
2015-10-25 01:19:26 +00:00
width = zarch_zui_strwidth(zui->fb_buf, label, 1.0) + 24;
}
x1 = tab->x;
y1 = tab->y;
x2 = x1 + width;
y2 = y1 + 60;
2015-10-25 01:19:26 +00:00
active = zarch_zui_check_button_up(zui, id, x1, y1, x2, y2);
2015-10-27 04:23:45 +00:00
tab->prev_id = tab->active_id;
2015-11-19 12:55:38 +00:00
if (zui->item.active == id || tab->active_id == ~0U || !tab->inited)
2015-10-27 04:23:45 +00:00
tab->active_id = id;
2015-10-27 05:22:50 +00:00
else if (id > tab->active_id)
{
tab->next_id = id;
}
2015-10-27 06:05:07 +00:00
if (!tab->inited)
tab->inited = true;
2015-10-27 04:23:45 +00:00
if (tab->active_id == id || zui->item.active == id || zui->item.hot == id)
bg = zui_bg_hilite;
else if (selected)
bg = zui_bg_pad_hilite;
2015-10-26 04:30:41 +00:00
zarch_zui_push_quad(zui->width, zui->height, bg, &zui->ca, x1+0, y1+0, x2, y2);
2015-10-25 01:19:26 +00:00
zarch_zui_draw_text(zui, ZUI_FG_NORMAL, x1+12, y1 + 41, label);
if (tab->vertical)
tab->y += y2 - y1;
else
tab->x = x2;
2015-10-27 04:23:45 +00:00
return active || (tab->active_id == id);
}
2015-10-25 01:19:26 +00:00
static void zarch_zui_render_lay_settings(zui_t *zui)
{
int width, x1, y1;
2016-02-29 01:48:29 +00:00
static struct zui_tabbed tabbed = {~0U};
2015-10-27 05:22:50 +00:00
2015-10-25 01:22:00 +00:00
tabbed.vertical = true;
tabbed.tab_width = 100;
2015-10-25 01:19:26 +00:00
zarch_zui_tabbed_begin(zui, &tabbed, zui->width - 100, 20);
2015-10-25 01:22:00 +00:00
width = 290;
x1 = zui->width - width - 20;
y1 = 20;
y1 += 64;
2015-10-25 01:19:26 +00:00
if (zarch_zui_button_full(zui, x1, y1, x1 + width, y1 + 64, "Back"))
2016-02-26 21:57:04 +00:00
zarch_layout = LAY_HOME;
}
2016-02-29 01:52:00 +00:00
static bool zarch_zui_gamepad_input(zui_t *zui,
int *gamepad_index, int *list_first,
2016-02-28 16:33:56 +00:00
unsigned skip)
{
unsigned size = menu_entries_get_size();
unsigned cutoff_point = size - 5;
2016-02-28 15:49:46 +00:00
switch (zui->action)
{
case MENU_ACTION_LEFT:
if (*gamepad_index == 0)
break;
2016-02-28 15:44:41 +00:00
2016-02-28 15:49:46 +00:00
*gamepad_index = *gamepad_index - 5;
2016-02-28 15:44:41 +00:00
2016-02-28 15:49:46 +00:00
if (*gamepad_index < 0)
*gamepad_index = 0;
return true;
case MENU_ACTION_RIGHT:
2016-02-28 21:49:52 +00:00
if (*gamepad_index == (signed)(size-1))
break;
2016-02-28 15:44:41 +00:00
2016-02-28 15:49:46 +00:00
*gamepad_index = *gamepad_index + 5;
2016-02-28 21:49:52 +00:00
if (*gamepad_index > (signed)(size-1))
2016-02-28 15:49:46 +00:00
*gamepad_index = (size -1);
2016-02-28 15:49:46 +00:00
return true;
case MENU_ACTION_UP:
*gamepad_index = *gamepad_index - 1;
if (*gamepad_index < 0) /* and wraparound enabled */
*gamepad_index = size -1;
2016-02-28 21:49:52 +00:00
else if (*gamepad_index >= (signed)cutoff_point) /* if greater than cutoff point,
don't scroll */
return false;
2016-02-28 15:49:46 +00:00
return true;
case MENU_ACTION_DOWN:
*gamepad_index = *gamepad_index + 1;
2016-02-28 21:49:52 +00:00
if (*gamepad_index > (signed)(size - 1)) /* and wraparound enabled */
2016-02-28 15:49:46 +00:00
*gamepad_index = 0;
2016-02-28 21:49:52 +00:00
else if (*gamepad_index >= (signed)cutoff_point) /* if greater than cutoff point,
don't scroll */
return false;
2016-02-28 15:49:46 +00:00
return true;
default:
{
*list_first += zui->mouse.wheel;
if (*list_first < 0)
*list_first = 0;
if (*list_first > (int)cutoff_point)
*list_first = cutoff_point;
2016-02-28 16:33:56 +00:00
*list_first = min(max(*list_first, 0), cutoff_point - skip);
2016-02-28 15:49:46 +00:00
}
return false;
}
2016-02-28 15:44:41 +00:00
2016-02-28 15:49:46 +00:00
return false;
}
2016-02-28 15:44:41 +00:00
2016-02-29 01:48:29 +00:00
static int zarch_zui_render_lay_root_recent(zui_t *zui, struct zui_tabbed *tabbed)
2016-02-28 15:49:46 +00:00
{
if (zarch_zui_tab(zui, tabbed, "Recent", 0))
{
static int gamepad_index = 0;
unsigned size = menu_entries_get_size();
unsigned i, j = 0;
2016-02-28 15:44:41 +00:00
if (zarch_zui_gamepad_input(zui, &gamepad_index,
2016-02-28 16:33:56 +00:00
&zui->recent_dlist_first, 0))
2016-02-28 15:49:46 +00:00
zui->recent_dlist_first = gamepad_index;
for (i = zui->recent_dlist_first; i < size; ++i)
{
menu_entry_t entry;
2015-10-25 06:50:13 +00:00
2015-10-27 10:42:54 +00:00
menu_entry_get(&entry, 0, i, NULL, true);
if (zarch_zui_list_item(zui, tabbed, 0,
tabbed->tabline_size + j * ZUI_ITEM_SIZE_PX,
2016-02-28 21:49:52 +00:00
entry.path, i, entry.value, gamepad_index == (signed)i))
{
2016-02-28 17:35:34 +00:00
if (menu_entry_action(&entry, i, MENU_ACTION_OK))
return 1;
}
j++;
}
}
return 0;
}
2015-10-26 21:13:30 +00:00
static void zarch_zui_render_lay_root_load_free(zui_t *zui)
{
if (!zui)
return;
free(zui->load_cwd);
dir_list_free(zui->load_dlist);
zui->load_cwd = NULL;
zui->load_dlist = NULL;
}
2016-02-21 08:51:16 +00:00
static void zarch_zui_render_lay_root_load_set_new_path(zui_t *zui,
const char *newpath)
2015-10-26 21:29:21 +00:00
{
if (!zui)
return;
free(zui->load_cwd);
zui->load_cwd = strdup(newpath);
dir_list_free(zui->load_dlist);
zui->load_dlist = NULL;
}
2016-02-29 01:48:29 +00:00
static int zarch_zui_render_lay_root_load(zui_t *zui,
struct zui_tabbed *tabbed)
{
2015-10-26 20:59:26 +00:00
char parent_dir[PATH_MAX_LENGTH];
2015-12-11 12:51:17 +00:00
settings_t *settings = config_get_ptr();
core_info_list_t *list = NULL;
if (zarch_zui_tab(zui, tabbed, "Load", 1))
{
2015-10-02 02:03:34 +00:00
unsigned cwd_offset;
if (!zui->load_cwd)
2015-10-24 05:00:51 +00:00
zui->load_cwd = strdup(settings->menu_content_directory);
if (!zui->load_dlist)
{
core_info_t *core_info = NULL;
2016-02-07 01:37:57 +00:00
core_info_ctl(CORE_INFO_CTL_CURRENT_CORE_GET, &core_info);
2016-02-21 08:51:16 +00:00
zui->load_dlist = dir_list_new(zui->load_cwd,
core_info->supported_extensions, true, true);
dir_list_sort(zui->load_dlist, true);
2015-10-26 21:29:21 +00:00
zui->load_dlist_first = 0;
}
2015-10-26 20:59:26 +00:00
cwd_offset = min(strlen(zui->load_cwd), 60);
2016-02-21 08:51:16 +00:00
zarch_zui_draw_text(zui, ZUI_FG_NORMAL, 15,
tabbed->tabline_size + 5 + 41,
&zui->load_cwd[strlen(zui->load_cwd) - cwd_offset]);
2016-02-21 08:51:16 +00:00
if (zarch_zui_button(zui, zui->width - 290 - 129,
tabbed->tabline_size + 5, "Home"))
2015-10-26 21:13:30 +00:00
zarch_zui_render_lay_root_load_free(zui);
if (zui->load_dlist)
{
2016-02-21 08:51:16 +00:00
fill_pathname_parent_dir(parent_dir,
zui->load_cwd, sizeof(parent_dir));
if (!string_is_empty(parent_dir) &&
2016-02-21 08:51:16 +00:00
zarch_zui_list_item(zui, tabbed, 0,
2016-02-28 15:44:41 +00:00
tabbed->tabline_size + 73, " ..", 0, NULL, false /* TODO/FIXME */))
{
2015-10-26 21:29:21 +00:00
zarch_zui_render_lay_root_load_set_new_path(zui, parent_dir);
}
else
{
2016-02-28 16:33:56 +00:00
static int gamepad_index = 0;
unsigned size = zui->load_dlist->size;
unsigned i, j = 1;
unsigned skip = 0;
2015-10-24 03:57:19 +00:00
for (i = 0; i < size; ++i)
{
2016-02-21 08:51:16 +00:00
const char *basename =
path_basename(zui->load_dlist->elems[i].data);
2015-10-26 21:13:30 +00:00
if (basename[0] != '.')
break;
2015-10-26 21:13:30 +00:00
skip++;
}
2016-02-28 16:33:56 +00:00
if (zarch_zui_gamepad_input(zui, &gamepad_index,
&zui->load_dlist_first, skip))
zui->load_dlist_first = gamepad_index;
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;
if (j > 10)
break;
2015-10-02 02:03:34 +00:00
path = zui->load_dlist->elems[i].data;
basename = path_basename(path);
*label = 0;
strncat(label, " ", sizeof(label)-1);
strncat(label, basename, sizeof(label)-1);
if (path_is_directory(path))
strncat(label, "/", sizeof(label)-1);
2016-02-21 08:51:16 +00:00
if (zarch_zui_list_item(zui, tabbed, 0,
2016-02-27 15:44:22 +00:00
tabbed->tabline_size + 73 + j * ZUI_ITEM_SIZE_PX,
2016-02-28 21:49:52 +00:00
label, i, NULL, gamepad_index == (signed)(i-skip)))
{
if (path_is_directory(path))
{
2015-10-26 21:29:21 +00:00
zarch_zui_render_lay_root_load_set_new_path(zui, path);
break;
}
2015-10-26 21:29:21 +00:00
zui->pick_cores = NULL;
zui->pick_supported = 0;
strlcpy(zui->pick_content,
path, sizeof(zui->pick_content));
2015-12-11 12:51:17 +00:00
2016-02-07 01:37:57 +00:00
core_info_ctl(CORE_INFO_CTL_LIST_GET, &list);
2015-12-11 12:51:17 +00:00
core_info_list_get_supported_cores(list, path,
2015-10-26 21:29:21 +00:00
&zui->pick_cores, &zui->pick_supported);
2016-02-26 21:57:04 +00:00
zarch_layout = LAY_PICK_CORE;
2015-10-26 21:29:21 +00:00
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;
}
return 0;
}
2016-02-21 08:51:16 +00:00
static int zarch_zui_render_lay_root_collections(
2016-02-29 01:48:29 +00:00
zui_t *zui, struct zui_tabbed *tabbed)
{
if (zarch_zui_tab(zui, tabbed, "Collections", 2))
{
/* STUB/FIXME */
}
return 0;
}
2016-02-21 08:51:16 +00:00
static int zarch_zui_render_lay_root_downloads(
2016-02-29 01:48:29 +00:00
zui_t *zui, struct zui_tabbed *tabbed)
{
if (zarch_zui_tab(zui, tabbed, "Download", 3))
{
/* STUB/FIXME */
}
return 0;
}
2015-10-25 01:19:26 +00:00
static int zarch_zui_render_lay_root(zui_t *zui)
{
char item[PATH_MAX_LENGTH];
2016-02-29 01:48:29 +00:00
static struct zui_tabbed tabbed = {~0U};
2015-10-25 01:19:26 +00:00
zarch_zui_tabbed_begin(zui, &tabbed, 0, 0);
tabbed.width = zui->width - 290 - 40;
zui->next_selection_set = false;
2016-02-29 01:09:10 +00:00
if (!zui)
return 1;
2015-10-25 01:19:26 +00:00
if (zarch_zui_render_lay_root_recent(zui, &tabbed))
return 0;
2015-10-25 01:19:26 +00:00
if (zarch_zui_render_lay_root_load (zui, &tabbed))
return 0;
2015-10-25 01:19:26 +00:00
if (zarch_zui_render_lay_root_collections(zui, &tabbed))
return 0;
2015-10-25 01:19:26 +00:00
if (zarch_zui_render_lay_root_downloads(zui, &tabbed))
return 0;
(void)item;
2015-10-27 06:56:32 +00:00
#ifdef ZARCH_DEBUG
snprintf(item, sizeof(item), "item id: %d\n", zui->active_id);
2015-10-27 06:56:32 +00:00
zarch_zui_draw_text(zui, ZUI_FG_NORMAL, 1600 +12, 300 + 41, item);
snprintf(item, sizeof(item), "tab idx: %d\n", tabbed.active_id);
zarch_zui_draw_text(zui, ZUI_FG_NORMAL, 1600 +12, 300 + 81, item);
2015-10-27 10:52:12 +00:00
snprintf(item, sizeof(item), "item hot idx: %d\n", zui->item.hot);
zarch_zui_draw_text(zui, ZUI_FG_NORMAL, 1600 +12, 300 + 111, item);
#endif
2016-02-21 08:51:16 +00:00
zarch_zui_push_quad(zui->width, zui->height,
zui_bg_hilite, &zui->ca, 0, 60, zui->width - 290 - 40, 60+4);
return 0;
}
2015-10-25 02:11:26 +00:00
static int zarch_zui_render_sidebar(zui_t *zui)
{
2015-10-02 02:03:34 +00:00
int width, x1, y1;
2016-02-29 01:48:29 +00:00
static struct zui_tabbed tabbed = {~0U};
tabbed.vertical = true;
tabbed.tab_width = 100;
2015-10-25 01:19:26 +00:00
zarch_zui_tabbed_begin(zui, &tabbed, zui->width - 100, 20);
width = 290;
x1 = zui->width - width - 20;
y1 = 20;
2015-10-25 01:19:26 +00:00
if (zarch_zui_button_full(zui, x1, y1, x1 + width, y1 + 64, "Settings"))
2016-02-26 21:57:04 +00:00
zarch_layout = LAY_SETTINGS;
y1 += 64;
2015-10-25 01:19:26 +00:00
if (zarch_zui_button_full(zui, x1, y1, x1 + width, y1 + 64, "Exit"))
2015-10-25 02:11:26 +00:00
{
2016-02-10 18:56:35 +00:00
menu_driver_ctl(RARCH_MENU_CTL_SET_PENDING_SHUTDOWN, NULL);
2015-10-25 02:11:26 +00:00
return 1;
}
return 0;
}
2015-10-25 01:19:26 +00:00
static int zarch_zui_load_content(zui_t *zui, unsigned i)
{
rarch_task_push_content_load_default(zui->pick_cores[i].path,
zui->pick_content, false, CORE_TYPE_PLAIN, NULL, NULL);
2016-02-26 21:57:04 +00:00
zarch_layout = LAY_HOME;
return 0;
}
static void zarch_zui_draw_cursor(float x, float y)
{
2015-10-24 21:48:53 +00:00
}
static int zarch_zui_render_pick_core(zui_t *zui)
{
2016-02-29 01:48:29 +00:00
static struct zui_tabbed tabbed = {~0U};
unsigned i, j = 0;
if (zui->pick_supported == 1)
{
int ret = zarch_zui_load_content(zui, 0);
(void)ret;
2016-02-26 21:57:04 +00:00
zarch_layout = LAY_HOME;
menu_driver_ctl(RARCH_MENU_CTL_SET_PENDING_QUIT, NULL);
return 1;
}
zarch_zui_draw_text(zui, ~0, 8, 18, "Select a core: ");
if (zarch_zui_button(zui, 0, 18 + zui->font_size, "<- Back"))
2016-02-26 21:57:04 +00:00
zarch_layout = LAY_HOME;
if (!zui->pick_supported)
{
2016-02-27 15:44:22 +00:00
zarch_zui_list_item(zui, &tabbed, 0, ZUI_ITEM_SIZE_PX,
2016-02-28 15:44:41 +00:00
"Content unsupported", 0, NULL, false /* TODO/FIXME */);
return 1;
}
zui->pick_first += zui->mouse.wheel;
zui->pick_first = min(max(zui->pick_first, 0), zui->pick_supported - 5);
for (i = zui->pick_first; i < zui->pick_supported; ++i)
{
if (j > 10)
break;
2016-02-27 15:44:22 +00:00
if (zarch_zui_list_item(zui, &tabbed, 0, ZUI_ITEM_SIZE_PX + j * ZUI_ITEM_SIZE_PX,
2016-02-28 15:44:41 +00:00
zui->pick_cores[i].display_name, i, NULL, false))
{
int ret = zarch_zui_load_content(zui, i);
(void)ret;
2016-02-26 21:57:04 +00:00
zarch_layout = LAY_HOME;
menu_driver_ctl(RARCH_MENU_CTL_SET_PENDING_QUIT, NULL);
break;
}
j++;
}
return 0;
}
2015-12-10 14:44:26 +00:00
static void zarch_frame(void *data)
2015-10-24 21:48:53 +00:00
{
unsigned i;
2015-11-10 00:58:05 +00:00
float coord_color[16];
float coord_color2[16];
menu_display_ctx_draw_t draw;
2016-02-09 03:49:47 +00:00
menu_display_ctx_coord_draw_t coord_draw;
2015-10-24 21:48:53 +00:00
settings_t *settings = config_get_ptr();
2015-12-10 15:10:21 +00:00
zui_t *zui = (zui_t*)data;
2015-12-10 14:12:47 +00:00
2015-12-10 14:44:26 +00:00
if (!zui)
return;
2015-10-24 21:48:53 +00:00
video_driver_get_size(&zui->width, &zui->height);
menu_display_ctl(MENU_DISPLAY_CTL_SET_VIEWPORT, NULL);
menu_display_ctl(MENU_DISPLAY_CTL_FONT_BUF, &zui->fb_buf);
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-24 21:34:59 +00:00
zui->rendering = true;
zui->hash = 0;
zui->item.hot = 0;
/* why do i need this? */
zui->mouse.wheel = menu_input_mouse_state(MENU_MOUSE_WHEEL_DOWN) -
menu_input_mouse_state(MENU_MOUSE_WHEEL_UP);
zui->ca.coords.vertices = 0;
zui->tmp_block.carr.coords.vertices = 0;
2015-10-25 02:20:37 +00:00
2016-02-08 23:57:10 +00:00
menu_display_ctl(MENU_DISPLAY_CTL_FONT_BIND_BLOCK, &zui->tmp_block);
zarch_zui_push_quad(zui->width, zui->height, zui_bg_screen,
2016-02-21 08:51:16 +00:00
&zui->ca, 0, 0, zui->width, zui->height);
zarch_zui_snow(zui, &zui->ca, zui->width, zui->height);
2016-02-26 21:57:04 +00:00
switch (zarch_layout)
{
2015-10-02 01:55:23 +00:00
case LAY_HOME:
2015-10-25 02:27:00 +00:00
if (zarch_zui_render_sidebar(zui))
2015-10-25 02:11:26 +00:00
return;
2015-10-25 02:27:00 +00:00
if (zarch_zui_render_lay_root(zui))
return;
2015-10-02 01:55:23 +00:00
break;
case LAY_SETTINGS:
2015-10-25 01:19:26 +00:00
zarch_zui_render_lay_settings(zui);
2015-10-02 01:55:23 +00:00
break;
case LAY_PICK_CORE:
2015-10-25 02:27:00 +00:00
if (zarch_zui_render_sidebar(zui))
2015-10-25 02:11:26 +00:00
return;
if (zarch_zui_render_pick_core(zui))
return;
2015-10-02 01:55:23 +00:00
break;
}
2015-10-24 05:00:51 +00:00
if (settings->menu.mouse.enable)
zarch_zui_draw_cursor(
zarch_zui_input_state(zui, MENU_ZARCH_MOUSE_X),
zarch_zui_input_state(zui, MENU_ZARCH_MOUSE_Y));
2015-10-25 03:08:51 +00:00
if (!zarch_zui_input_state(zui, MENU_ZARCH_PRESSED))
zui->item.active = 0;
else if (zui->item.active == 0)
zui->item.active = -1;
menu_display_ctl(MENU_DISPLAY_CTL_BLEND_BEGIN, NULL);
draw.x = 0;
draw.y = 0;
draw.width = zui->width;
draw.height = zui->height;
draw.coords = (struct gfx_coords*)&zui->ca;
draw.matrix_data = &zui->mvp;
draw.texture = zui->textures.white;
draw.prim_type = MENU_DISPLAY_PRIM_TRIANGLES;
menu_display_ctl(MENU_DISPLAY_CTL_DRAW, &draw);
2015-10-24 21:37:59 +00:00
menu_display_ctl(MENU_DISPLAY_CTL_BLEND_END, NULL);
memset(&draw, 0, sizeof(menu_display_ctx_draw_t));
2016-02-09 03:49:47 +00:00
coord_draw.ptr = NULL;
menu_display_ctl(MENU_DISPLAY_CTL_TEX_COORDS_GET, &coord_draw);
draw.width = zui->width;
draw.height = zui->height;
draw.texture = zui->textures.bg.id;
draw.handle_alpha = 0.75f;
draw.force_transparency = false;
draw.color = &coord_color[0];
draw.color2 = &coord_color2[0];
draw.vertex = NULL;
2016-02-09 03:49:47 +00:00
draw.tex_coord = coord_draw.ptr;
draw.vertex_count = 4;
draw.prim_type = MENU_DISPLAY_PRIM_TRIANGLESTRIP;
menu_display_ctl(MENU_DISPLAY_CTL_DRAW_BG, &draw);
2015-10-24 21:44:34 +00:00
2015-10-24 21:37:59 +00:00
zui->rendering = false;
2015-10-24 21:21:18 +00:00
menu_display_ctl(MENU_DISPLAY_CTL_FONT_FLUSH_BLOCK, NULL);
2015-10-02 03:17:40 +00:00
menu_display_ctl(MENU_DISPLAY_CTL_UNSET_VIEWPORT, NULL);
}
static void *zarch_init(void **userdata)
{
2015-10-25 02:14:08 +00:00
int unused;
2015-10-02 02:03:34 +00:00
zui_t *zui = NULL;
settings_t *settings = config_get_ptr();
2016-02-21 08:51:16 +00:00
menu_handle_t *menu = (menu_handle_t*)
calloc(1, sizeof(*menu));
if (!menu)
goto error;
if (!menu_display_ctl(MENU_DISPLAY_CTL_INIT_FIRST_DRIVER, NULL))
goto error;
2015-12-11 13:55:04 +00:00
zui = (zui_t*)calloc(1, sizeof(zui_t));
2015-12-11 13:55:04 +00:00
if (!zui)
goto error;
*userdata = zui;
if (settings->menu.mouse.enable)
{
RARCH_WARN("Forcing menu_mouse_enable=false\n");
settings->menu.mouse.enable = false;
}
2015-10-25 02:14:08 +00:00
unused = 1000;
menu_display_ctl(MENU_DISPLAY_CTL_SET_HEADER_HEIGHT, &unused);
2015-10-25 02:14:08 +00:00
unused = 28;
menu_display_ctl(MENU_DISPLAY_CTL_SET_FONT_SIZE, &unused);
(void)unused;
2015-10-02 02:03:34 +00:00
zui->header_height = 1000; /* dpi / 3; */
zui->font_size = 28;
if (!string_is_empty(settings->menu.wallpaper))
2015-11-23 03:17:27 +00:00
rarch_task_push_image_load(settings->menu.wallpaper,
2016-02-21 08:51:16 +00:00
"cb_menu_wallpaper",
menu_display_handle_wallpaper_upload, NULL);
zui->ca.allocated = 0;
matrix_4x4_ortho(&zui->mvp, 0, 1, 1, 0, 0, 1);
2015-12-10 14:44:26 +00:00
zarch_zui_font();
return menu;
error:
if (menu)
free(menu);
return NULL;
}
static void zarch_free(void *data)
{
zui_t *zui = (zui_t*)data;
if (zui)
{
gfx_coord_array_free(&zui->ca);
gfx_coord_array_free(&zui->tmp_block.carr);
}
2015-12-05 10:34:56 +00:00
font_driver_bind_block(NULL, NULL);
}
2016-02-09 00:24:35 +00:00
static void zarch_context_bg_destroy(void *data)
{
2016-02-09 00:24:35 +00:00
zui_t *zui = (zui_t*)data;
if (!zui)
return;
2016-02-16 19:24:00 +00:00
video_driver_texture_unload(&zui->textures.bg.id);
video_driver_texture_unload(&zui->textures.white);
}
static void zarch_context_destroy(void *data)
{
2016-02-09 00:24:35 +00:00
menu_display_ctl(MENU_DISPLAY_CTL_FONT_MAIN_DEINIT, NULL);
zarch_context_bg_destroy(data);
}
2015-12-10 15:51:59 +00:00
static bool zarch_load_image(void *userdata,
void *data, enum menu_image_type type)
{
2015-12-10 15:51:59 +00:00
zui_t *zui = (zui_t*)userdata;
2015-10-27 11:19:41 +00:00
if (!zui || !data)
return false;
switch (type)
{
case MENU_IMAGE_NONE:
break;
case MENU_IMAGE_WALLPAPER:
2015-10-27 11:19:41 +00:00
zarch_context_bg_destroy(zui);
video_driver_texture_load(data,
TEXTURE_FILTER_MIPMAP_LINEAR,
2016-02-16 19:24:00 +00:00
&zui->textures.bg.id);
break;
case MENU_IMAGE_BOXART:
break;
}
return true;
}
2015-10-24 22:55:02 +00:00
static void zarch_allocate_white_texture(zui_t *zui)
{
struct texture_image ti;
static const uint32_t data = UINT32_MAX;
ti.width = 1;
ti.height = 1;
ti.pixels = (uint32_t*)&data;
video_driver_texture_load(&ti,
TEXTURE_FILTER_NEAREST,
2016-02-16 19:24:00 +00:00
&zui->textures.white);
2015-10-24 22:55:02 +00:00
}
2015-12-10 16:01:06 +00:00
static void zarch_context_reset(void *data)
{
2016-02-09 00:24:35 +00:00
menu_display_ctx_font_t font_info;
settings_t *settings = config_get_ptr();
2015-12-10 16:01:06 +00:00
zui_t *zui = (zui_t*)data;
2015-12-10 16:01:06 +00:00
if (!zui || !settings)
return;
2016-02-09 00:24:35 +00:00
font_info.path = NULL;
font_info.size = zui->font_size;
if (settings->video.font_enable)
font_info.path = settings->video.font_path;
2016-02-09 00:24:35 +00:00
if (!menu_display_ctl(MENU_DISPLAY_CTL_FONT_MAIN_INIT, &font_info))
RARCH_WARN("Failed to load font.");
zarch_context_bg_destroy(zui);
2015-11-23 03:17:27 +00:00
rarch_task_push_image_load(settings->menu.wallpaper,
"cb_menu_wallpaper", menu_display_handle_wallpaper_upload, NULL);
2015-10-24 22:55:02 +00:00
zarch_allocate_white_texture(zui);
menu_display_ctl(MENU_DISPLAY_CTL_SET_FONT_SIZE, &zui->font_size);
2015-12-10 14:44:26 +00:00
zarch_zui_font();
}
2015-12-10 18:38:46 +00:00
static int zarch_iterate(void *data, void *userdata, enum menu_action action)
2015-10-03 03:24:03 +00:00
{
int ret;
size_t selection;
menu_entry_t entry;
2015-12-10 18:38:46 +00:00
zui_t *zui = (zui_t*)userdata;
2015-10-03 03:24:03 +00:00
if (!zui)
return -1;
if (!menu_navigation_ctl(MENU_NAVIGATION_CTL_GET_SELECTION, &selection))
return 0;
menu_entry_get(&entry, 0, selection, NULL, false);
2016-02-28 17:35:34 +00:00
zui->action = action;
ret = menu_entry_action(&entry, selection, action);
if (ret)
return -1;
return 0;
2015-10-03 03:24:03 +00:00
}
static bool zarch_menu_init_list(void *data)
{
menu_displaylist_info_t info = {0};
file_list_t *menu_stack = menu_entries_get_menu_stack_ptr(0);
file_list_t *selection_buf = menu_entries_get_selection_buf_ptr(0);
2016-02-21 08:51:16 +00:00
strlcpy(info.label,
menu_hash_to_str(MENU_VALUE_HISTORY_TAB), sizeof(info.label));
2016-02-21 08:51:16 +00:00
menu_entries_push(menu_stack,
info.path, info.label, info.type, info.flags, 0);
event_cmd_ctl(EVENT_CMD_HISTORY_INIT, NULL);
info.list = selection_buf;
2016-02-24 22:19:53 +00:00
if (menu_displaylist_ctl(DISPLAYLIST_HISTORY, &info))
{
info.need_push = true;
return menu_displaylist_ctl(DISPLAYLIST_PROCESS, &info);
}
2016-02-24 22:19:53 +00:00
return false;
}
menu_ctx_driver_t menu_ctx_zarch = {
NULL,
2015-12-10 13:40:56 +00:00
NULL,
2015-10-03 03:24:03 +00:00
zarch_iterate,
NULL,
zarch_frame,
zarch_init,
zarch_free,
zarch_context_reset,
zarch_context_destroy,
NULL,
NULL,
NULL,
NULL,
NULL,
NULL,
NULL,
NULL,
NULL,
zarch_menu_init_list,
NULL,
NULL,
NULL,
NULL,
NULL,
NULL,
NULL,
NULL,
NULL,
NULL,
2015-10-02 03:34:12 +00:00
zarch_load_image,
"zarch",
NULL,
NULL,
};