From 6562c2cd95ea1c4db04bd80f3e514512b8a27e8a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jean-Andr=C3=A9=20Santoni?= Date: Mon, 20 Oct 2014 19:51:00 +0200 Subject: [PATCH 1/6] Add file_list_copy function --- file_list.c | 23 +++++++++++++++++++++++ file_list.h | 1 + 2 files changed, 24 insertions(+) diff --git a/file_list.c b/file_list.c index 18621a10d5..7117f0b8e5 100644 --- a/file_list.c +++ b/file_list.c @@ -100,6 +100,29 @@ void file_list_clear(file_list_t *list) list->size = 0; } +void file_list_copy(file_list_t *list, file_list_t *list_old) +{ + size_t i; + + list_old->size = list->size; + list_old->capacity = list->capacity; + + list_old->list = (struct item_file*)realloc(list_old->list, + list_old->capacity * sizeof(struct item_file)); + + for (i = 0; i < list->size; i++) + { + list_old->list[i].path = strdup(list->list[i].path); + list_old->list[i].label = strdup(list->list[i].label); + if (list->list[i].alt) + list_old->list[i].alt = strdup(list->list[i].alt); + list_old->list[i].type = list->list[i].type; + list_old->list[i].directory_ptr = list->list[i].directory_ptr; + list_old->list[i].userdata = list->list[i].userdata; + list_old->list[i].actiondata = list->list[i].actiondata; + } +} + void file_list_set_label_at_offset(file_list_t *list, size_t index, const char *label) { diff --git a/file_list.h b/file_list.h index 875a429eb4..4f604cf0fe 100644 --- a/file_list.h +++ b/file_list.h @@ -55,6 +55,7 @@ void file_list_push(file_list_t *userdata, const char *path, const char *label, unsigned type, size_t current_directory_ptr); void file_list_pop(file_list_t *list, size_t *directory_ptr); void file_list_clear(file_list_t *list); +void file_list_copy(file_list_t *list, file_list_t *list_old); void file_list_get_last(const file_list_t *list, const char **path, const char **label, From 2f988c300b1785f12f32635ba7808109120329fb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jean-Andr=C3=A9=20Santoni?= Date: Mon, 20 Oct 2014 19:54:55 +0200 Subject: [PATCH 2/6] (Menu) Make disp_set_label work with any file_list --- frontend/menu/disp/glui.c | 2 +- frontend/menu/disp/rgui.c | 2 +- frontend/menu/disp/shared.h | 5 +++-- 3 files changed, 5 insertions(+), 4 deletions(-) diff --git a/frontend/menu/disp/glui.c b/frontend/menu/disp/glui.c index 60d4be154a..1790938225 100644 --- a/frontend/menu/disp/glui.c +++ b/frontend/menu/disp/glui.c @@ -303,7 +303,7 @@ static void glui_frame(void) driver.menu->menu_list->selection_buf->list[i].label); (void)setting; - disp_set_label(&w, type, i, label, + disp_set_label(driver.menu->menu_list->selection_buf, &w, type, i, label, type_str, sizeof(type_str), entry_label, path, path_buf, sizeof(path_buf)); diff --git a/frontend/menu/disp/rgui.c b/frontend/menu/disp/rgui.c index 5364e48457..9e6e9a53b9 100644 --- a/frontend/menu/disp/rgui.c +++ b/frontend/menu/disp/rgui.c @@ -352,7 +352,7 @@ static void rgui_render(void) driver.menu->menu_list->selection_buf->list[i].label); (void)setting; - disp_set_label(&w, type, i, label, + disp_set_label(driver.menu->menu_list->selection_buf, &w, type, i, label, type_str, sizeof(type_str), entry_label, path, path_buf, sizeof(path_buf)); diff --git a/frontend/menu/disp/shared.h b/frontend/menu/disp/shared.h index fabacb042c..4da4dce9dc 100644 --- a/frontend/menu/disp/shared.h +++ b/frontend/menu/disp/shared.h @@ -129,7 +129,8 @@ static void get_title(const char *label, const char *dir, } } -static void disp_set_label(unsigned *w, unsigned type, unsigned i, +static void disp_set_label(file_list_t* list, + unsigned *w, unsigned type, unsigned i, const char *label, char *type_str, size_t type_str_size, const char *entry_label, @@ -148,7 +149,7 @@ static void disp_set_label(unsigned *w, unsigned type, unsigned i, if (type == MENU_FILE_CORE) { strlcpy(type_str, "(CORE)", type_str_size); - menu_list_get_alt_at_offset(driver.menu->menu_list->selection_buf, i, &path); + menu_list_get_alt_at_offset(list, i, &path); *w = 6; } else if (type == MENU_FILE_PLAIN) From 4bdc3a28182ead18ff77ecb1ac1954d216d0e8a8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jean-Andr=C3=A9=20Santoni?= Date: Mon, 20 Oct 2014 19:56:18 +0200 Subject: [PATCH 3/6] (Menu) Add cache for selection_ptr --- frontend/menu/menu_driver.h | 1 + 1 file changed, 1 insertion(+) diff --git a/frontend/menu/menu_driver.h b/frontend/menu/menu_driver.h index 413413a550..6a19411faa 100644 --- a/frontend/menu/menu_driver.h +++ b/frontend/menu/menu_driver.h @@ -81,6 +81,7 @@ typedef struct menu_list_t *menu_list; size_t selection_ptr; + size_t selection_ptr_old; bool need_refresh; bool msg_force; bool push_start_screen; From 0227602ce50834fcc797408ab91ba223d2d62161 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jean-Andr=C3=A9=20Santoni?= Date: Mon, 20 Oct 2014 19:56:50 +0200 Subject: [PATCH 4/6] (Menu) Add cache for selection_buf and menu_stack --- frontend/menu/menu_list.c | 2 ++ frontend/menu/menu_list.h | 2 ++ 2 files changed, 4 insertions(+) diff --git a/frontend/menu/menu_list.c b/frontend/menu/menu_list.c index 6469a67f06..101a4a8341 100644 --- a/frontend/menu/menu_list.c +++ b/frontend/menu/menu_list.c @@ -57,6 +57,8 @@ void *menu_list_new(void) list->menu_stack = (file_list_t*)calloc(1, sizeof(file_list_t)); list->selection_buf = (file_list_t*)calloc(1, sizeof(file_list_t)); + list->menu_stack_old = (file_list_t*)calloc(1, sizeof(file_list_t)); + list->selection_buf_old = (file_list_t*)calloc(1, sizeof(file_list_t)); if (!list->menu_stack || !list->selection_buf) { diff --git a/frontend/menu/menu_list.h b/frontend/menu/menu_list.h index 692cdc95ea..6a11687645 100644 --- a/frontend/menu/menu_list.h +++ b/frontend/menu/menu_list.h @@ -26,7 +26,9 @@ extern "C" { typedef struct menu_list { file_list_t *menu_stack; + file_list_t *menu_stack_old; file_list_t *selection_buf; + file_list_t *selection_buf_old; } menu_list_t; void menu_list_free(menu_list_t *menu_list); From d1df2828a753ffcc3f662a131b13586867843f48 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jean-Andr=C3=A9=20Santoni?= Date: Mon, 20 Oct 2014 20:00:10 +0200 Subject: [PATCH 5/6] (Menu) Cache the lists and pointers on OK and CANCEL --- frontend/menu/backend/menu_common_backend.c | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/frontend/menu/backend/menu_common_backend.c b/frontend/menu/backend/menu_common_backend.c index f8cafa1d66..fc4caaaa4a 100644 --- a/frontend/menu/backend/menu_common_backend.c +++ b/frontend/menu/backend/menu_common_backend.c @@ -223,6 +223,11 @@ static int menu_settings_iterate(unsigned action, break; case MENU_ACTION_CANCEL: +#ifdef HAVE_XMB + file_list_copy(driver.menu->menu_list->selection_buf, driver.menu->menu_list->selection_buf_old); + file_list_copy(driver.menu->menu_list->menu_stack, driver.menu->menu_list->menu_stack_old); + driver.menu->selection_ptr_old = driver.menu->selection_ptr; +#endif apply_deferred_settings(); menu_list_pop_stack(driver.menu->menu_list); break; @@ -231,6 +236,11 @@ static int menu_settings_iterate(unsigned action, 0, driver.menu->selection_ptr); break; case MENU_ACTION_OK: +#ifdef HAVE_XMB + file_list_copy(driver.menu->menu_list->selection_buf, driver.menu->menu_list->selection_buf_old); + file_list_copy(driver.menu->menu_list->menu_stack, driver.menu->menu_list->menu_stack_old); + driver.menu->selection_ptr_old = driver.menu->selection_ptr; +#endif if (cbs && cbs->action_ok) return cbs->action_ok(path, label, type, driver.menu->selection_ptr); /* fall-through */ @@ -635,10 +645,20 @@ static int menu_common_iterate(unsigned action) break; case MENU_ACTION_CANCEL: +#ifdef HAVE_XMB + file_list_copy(driver.menu->menu_list->selection_buf, driver.menu->menu_list->selection_buf_old); + file_list_copy(driver.menu->menu_list->menu_stack, driver.menu->menu_list->menu_stack_old); + driver.menu->selection_ptr_old = driver.menu->selection_ptr; +#endif menu_list_pop_stack(driver.menu->menu_list); break; case MENU_ACTION_OK: +#ifdef HAVE_XMB + file_list_copy(driver.menu->menu_list->selection_buf, driver.menu->menu_list->selection_buf_old); + file_list_copy(driver.menu->menu_list->menu_stack, driver.menu->menu_list->menu_stack_old); + driver.menu->selection_ptr_old = driver.menu->selection_ptr; +#endif ret = menu_action_ok(cbs); break; From 630b5fa3204ddbae07cf8718ea7f110a7dd22eec Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jean-Andr=C3=A9=20Santoni?= Date: Mon, 20 Oct 2014 20:00:39 +0200 Subject: [PATCH 6/6] (XMB) Horizontal animations --- frontend/menu/disp/xmb.c | 290 ++++++++++++++++++++++++++------------- 1 file changed, 194 insertions(+), 96 deletions(-) diff --git a/frontend/menu/disp/xmb.c b/frontend/menu/disp/xmb.c index 9025984d78..741f9b5501 100644 --- a/frontend/menu/disp/xmb.c +++ b/frontend/menu/disp/xmb.c @@ -43,7 +43,9 @@ typedef struct { float alpha; + float label_alpha; float zoom; + float x; float y; } xmb_node_t; @@ -84,6 +86,7 @@ typedef struct xmb_handle int icon_size; float x; float alpha; + float arrow_alpha; float hspacing; float vspacing; float font_size; @@ -371,9 +374,13 @@ static void xmb_selection_pointer_changed(void) if (!node) continue; - iy = (i < current) ? xmb->vspacing * - (i - current + xmb->above_item_offset) : - xmb->vspacing * (i - current + xmb->under_item_offset); + if (i < current) + if (xmb->depth > 1) + iy = xmb->vspacing * (i - (int)current + xmb->above_subitem_offset); + else + iy = xmb->vspacing * (i - (int)current + xmb->above_item_offset); + else + iy = xmb->vspacing * (i - (int)current + xmb->under_item_offset); if (i == current) { @@ -383,11 +390,86 @@ static void xmb_selection_pointer_changed(void) } add_tween(XMB_DELAY, ia, &node->alpha, &inOutQuad, NULL); + add_tween(XMB_DELAY, ia, &node->label_alpha, &inOutQuad, NULL); add_tween(XMB_DELAY, iz, &node->zoom, &inOutQuad, NULL); add_tween(XMB_DELAY, iy, &node->y, &inOutQuad, NULL); } } +static void xmb_list_open_old(file_list_t *list, int dir, size_t current) +{ + xmb_handle_t *xmb = (xmb_handle_t*)driver.menu->userdata; + + if (!xmb) + return; + + int i; + for (i = 0; i < file_list_get_size(list); i++) + { + xmb_node_t *node = NULL; + node = (xmb_node_t*)file_list_get_userdata_at_offset(list, i); + float ia = i == current ? xmb->i_active_alpha : 0; + if (dir == -1) ia = 0; + add_tween(XMB_DELAY, ia, &node->alpha, &inOutQuad, NULL); + add_tween(XMB_DELAY, 0, &node->label_alpha, &inOutQuad, NULL); + //if (i == current) + add_tween(XMB_DELAY, xmb->icon_size*dir*-2, &node->x, &inOutQuad, NULL); + //else + // add_tween(XMB_DELAY, xmb->icon_size*dir*-1, &node->x, &inOutQuad, NULL); + } +} + +static void xmb_list_open_new(file_list_t *list, int dir, size_t current) +{ + xmb_handle_t *xmb = (xmb_handle_t*)driver.menu->userdata; + + if (!xmb) + return; + + int i; + for (i = 0; i < file_list_get_size(list); i++) + { + xmb_node_t *node = NULL; + node = (xmb_node_t*)file_list_get_userdata_at_offset(list, i); + node->label_alpha = 0; + if (dir == 1 || (dir == -1 && i != current)) + node->alpha = 0; + //if (dir == 1 || (dir == -1 && i == current)) + node->x = xmb->icon_size*dir*2; + //else + // node->x = xmb->icon_size*dir; + + float iy = 0; + + if (i < current) + if (xmb->depth > 1) + iy = xmb->vspacing * (i - (int)current + xmb->above_subitem_offset); + else + iy = xmb->vspacing * (i - (int)current + xmb->above_item_offset); + else + iy = xmb->vspacing * (i - (int)current + xmb->under_item_offset); + + if (i == current) + iy = xmb->vspacing * xmb->active_item_factor; + + node->y = iy; + + if (i == current) + node->zoom = 1; + } + for (i = 0; i < file_list_get_size(list); i++) + { + xmb_node_t *node = NULL; + node = (xmb_node_t*)file_list_get_userdata_at_offset(list, i); + float ia = i == current ? 1.0 : 0.5; + add_tween(XMB_DELAY, ia, &node->alpha, &inOutQuad, NULL); + add_tween(XMB_DELAY, ia, &node->label_alpha, &inOutQuad, NULL); + add_tween(XMB_DELAY, 0, &node->x, &inOutQuad, NULL); + } + + xmb->old_depth = xmb->depth; +} + static void xmb_populate_entries(void *data, const char *path, const char *label, unsigned j) { @@ -397,45 +479,110 @@ static void xmb_populate_entries(void *data, const char *path, if (!xmb) return; - xmb->depth = menu_list_get_stack_size(driver.menu->menu_list); + xmb->depth = file_list_get_size(driver.menu->menu_list->menu_stack); - if (xmb->depth != xmb->old_depth) - add_tween(XMB_DELAY, xmb->x + (xmb->depth-xmb->old_depth)*-20, - &xmb->x, &inOutQuad, NULL); + int dir = 0; + if (xmb->depth > xmb->old_depth) + dir = 1; + else if (xmb->depth < xmb->old_depth) + dir = -1; - current = driver.menu->selection_ptr; - end = menu_list_get_size(driver.menu->menu_list); + xmb_list_open_old(driver.menu->menu_list->selection_buf_old, dir, driver.menu->selection_ptr_old); + xmb_list_open_new(driver.menu->menu_list->selection_buf, dir, driver.menu->selection_ptr); - for (i = 0; i < end; i++) - { - xmb_node_t *node = (xmb_node_t*)file_list_get_userdata_at_offset( - driver.menu->menu_list->selection_buf, i); + if (xmb->depth == 1 || xmb->depth == 2) + add_tween(XMB_DELAY, xmb->icon_size*-(xmb->depth*2-2), &xmb->x, &inOutQuad, NULL); - if (!node) - continue; + if (xmb->depth == 1) + add_tween(XMB_DELAY, 0, &xmb->arrow_alpha, &inOutQuad, NULL); - node->alpha = xmb->i_passive_alpha; - node->zoom = xmb->i_passive_zoom; - node->y = (i < current) ? xmb->vspacing * - (i - current + xmb->above_item_offset) : - xmb->vspacing * (i - current + xmb->under_item_offset); - - if (i == current) - { - node->alpha = xmb->i_active_alpha; - node->zoom = xmb->i_active_zoom; - node->y = xmb->vspacing * xmb->active_item_factor; - } - } + if (xmb->depth == 2) + add_tween(XMB_DELAY, 1, &xmb->arrow_alpha, &inOutQuad, NULL); xmb->old_depth = xmb->depth; } +static void xmb_draw_items(file_list_t *list, file_list_t *stack, size_t current) +{ + int i; + const char *dir = NULL; + const char *label = NULL; + unsigned menu_type = 0; + size_t end = file_list_get_size(list); + + xmb_handle_t *xmb = (xmb_handle_t*)driver.menu->userdata; + if (!xmb || !list->size) + return; + + file_list_get_last(stack, &dir, &label, &menu_type); + + for (i = 0; i < end; i++) + { + char val_buf[PATH_MAX], path_buf[PATH_MAX]; + char name[256], value[256]; + const char *path = NULL, *entry_label = NULL; + unsigned type = 0, w = 0; + xmb_node_t *node = NULL; + + menu_list_get_at_offset(list, i, &path, &entry_label, &type); + node = (xmb_node_t*)file_list_get_userdata_at_offset(list, i); + + disp_set_label(list, &w, type, i, label, + val_buf, sizeof(val_buf), + entry_label, path, + path_buf, sizeof(path_buf)); + + GLuint icon = 0; + switch(type) + { + case MENU_FILE_DIRECTORY: + icon = xmb->textures[XMB_TEXTURE_FOLDER].id; + break; + case MENU_FILE_PLAIN: + icon = xmb->textures[XMB_TEXTURE_FILE].id; + break; + case MENU_FILE_CARCHIVE: + icon = xmb->textures[XMB_TEXTURE_ZIP].id; + break; + case MENU_FILE_CORE: + icon = xmb->textures[XMB_TEXTURE_CORE].id; + break; + default: + icon = xmb->textures[XMB_TEXTURE_SETTING].id; + break; + } + + xmb_draw_icon(icon, + node->x + xmb->margin_left + xmb->hspacing - xmb->icon_size/2.0, + xmb->margin_top + node->y + xmb->icon_size/2.0, + node->alpha, + 0, + node->zoom); + + menu_ticker_line(name, 35, g_extern.frame_count / 20, path_buf, + (i == current)); + + xmb_draw_text(name, + node->x + xmb->margin_left + xmb->hspacing + xmb->label_margin_left, + xmb->margin_top + node->y + xmb->label_margin_top, + 1, + node->label_alpha); + + menu_ticker_line(value, 35, g_extern.frame_count / 20, val_buf, + (i == current)); + + xmb_draw_text(value, + node->x + xmb->margin_left + xmb->hspacing + + xmb->label_margin_left + xmb->setting_margin_left, + xmb->margin_top + node->y + xmb->label_margin_top, + 1, + node->label_alpha); + } +} + static void xmb_frame(void) { - int i, current; char title_msg[64]; - size_t end; const char *dir = NULL; const char *label = NULL; unsigned menu_type = 0; @@ -476,73 +623,21 @@ static void xmb_frame(void) xmb_draw_text(title_msg, xmb->title_margin_left, gl->win_height - xmb->title_margin_bottom, 1, 1); - end = menu_list_get_size(driver.menu->menu_list); - current = driver.menu->selection_ptr; + xmb_draw_icon(xmb->textures[XMB_TEXTURE_ARROW].id, + xmb->x + xmb->margin_left + xmb->hspacing - xmb->icon_size/2.0 + xmb->icon_size, + xmb->margin_top + xmb->icon_size/2.0 + xmb->vspacing * xmb->active_item_factor, + xmb->arrow_alpha, + 0, + 1); - for (i = 0; i < end; i++) - { - char val_buf[PATH_MAX], path_buf[PATH_MAX]; - char name[256], value[256]; - const char *path = NULL, *entry_label = NULL; - unsigned type = 0, w = 0; - xmb_node_t *node = NULL; - - menu_list_get_at_offset(driver.menu->menu_list->selection_buf, i, &path, - &entry_label, &type); - node = (xmb_node_t*)file_list_get_userdata_at_offset( - driver.menu->menu_list->selection_buf, i); - - disp_set_label(&w, type, i, label, - val_buf, sizeof(val_buf), - entry_label, path, - path_buf, sizeof(path_buf)); - - GLuint icon = 0; - switch(type) - { - case MENU_FILE_DIRECTORY: - icon = xmb->textures[XMB_TEXTURE_FOLDER].id; - break; - case MENU_FILE_PLAIN: - icon = xmb->textures[XMB_TEXTURE_FILE].id; - break; - case MENU_FILE_CARCHIVE: - icon = xmb->textures[XMB_TEXTURE_ZIP].id; - break; - case MENU_FILE_CORE: - icon = xmb->textures[XMB_TEXTURE_CORE].id; - break; - default: - icon = xmb->textures[XMB_TEXTURE_SETTING].id; - break; - } - - xmb_draw_icon(icon, - xmb->x + xmb->margin_left + xmb->hspacing - xmb->icon_size/2.0, - xmb->margin_top + node->y + xmb->icon_size/2.0, - node->alpha, - 0, - node->zoom); - - menu_ticker_line(name, 35, g_extern.frame_count / 20, path_buf, - (i == current)); - - xmb_draw_text(name, - xmb->x + xmb->margin_left + xmb->hspacing + xmb->label_margin_left, - xmb->margin_top + node->y + xmb->label_margin_top, - 1, - node->alpha); - - menu_ticker_line(value, 35, g_extern.frame_count / 20, val_buf, - (i == current)); - - xmb_draw_text(value, - xmb->x + xmb->margin_left + xmb->hspacing + - xmb->label_margin_left + xmb->setting_margin_left, - xmb->margin_top + node->y + xmb->label_margin_top, - 1, - node->alpha); - } + xmb_draw_items( + driver.menu->menu_list->selection_buf_old, + driver.menu->menu_list->menu_stack_old, + driver.menu->selection_ptr_old); + xmb_draw_items( + driver.menu->menu_list->selection_buf, + driver.menu->menu_list->menu_stack, + driver.menu->selection_ptr); xmb_draw_icon(xmb->textures[XMB_TEXTURE_SETTINGS].id, xmb->x + xmb->margin_left + xmb->hspacing - xmb->icon_size / 2.0, @@ -629,6 +724,7 @@ static void *xmb_init(void) xmb->x = 0; xmb->alpha = 1.0f; + xmb->arrow_alpha = 0; xmb->depth = 1; xmb->old_depth = 1; @@ -910,8 +1006,10 @@ static void xmb_list_insert(void *data, iy = xmb->vspacing * xmb->active_item_factor; node->alpha = (i == current) ? xmb->i_active_alpha : xmb->i_passive_alpha; + node->label_alpha = node->alpha; node->zoom = (i == current) ? xmb->i_active_zoom : xmb->i_passive_zoom; node->y = iy; + node->x = 0; } static void xmb_list_delete(void *data, size_t index,