static bool zarch_zui_list_item(zui_t *zui, zui_tabbed_t *tab, int x1, int y1, const char *label, unsigned item_id, const char *entry) { char title_buf[PATH_MAX_LENGTH]; unsigned ticker_size; bool set_active_id = false; unsigned id = zarch_zui_hash(zui, label); int x2 = x1 + zui->width - 290 - 40; int y2 = y1 + 50; bool active = zarch_zui_check_button_up(zui, id, x1, y1, x2, y2); const float *bg = ZUI_BG_PANEL; uint64_t *frame_count = video_driver_get_frame_count(); if (tab->active_id != tab->prev_id) { set_active_id = true; tab->prev_id = tab->active_id; } if (zui->pending_selection == -1) { if (item_id < zui->active_id) zui->prev_id = item_id; if (item_id > zui->active_id && !zui->next_selection_set) { zui->next_id = item_id; zui->next_selection_set = true; } } else { if (zui->active_id != item_id && zui->pending_selection == item_id) set_active_id = true; } if (set_active_id) zui->active_id = item_id; if (zui->item.active == id || zui->item.hot == id) bg = ZUI_BG_HILITE; else if (zui->active_id == item_id) bg = ZUI_BG_PAD_HILITE; ticker_size = x2 / 14; menu_animation_ticker_str(title_buf, ticker_size, *frame_count / 50, label, (bg == ZUI_BG_HILITE || bg == ZUI_BG_PAD_HILITE)); zarch_zui_push_quad(zui->width, zui->height, bg, &zui->ca, x1, y1, x2, y2); zarch_zui_draw_text(zui, ZUI_FG_NORMAL, 12, y1 + 35, title_buf); if (entry) zarch_zui_draw_text(zui, ZUI_FG_NORMAL, x2 - 200, y1 + 35, entry); return active; }
static int zarch_zui_render_lay_root(zui_t *zui) { char item[PATH_MAX_LENGTH]; static zui_tabbed_t tabbed = {~0}; zarch_zui_tabbed_begin(zui, &tabbed, 0, 0); tabbed.width = zui->width - 290 - 40; zui->next_selection_set = false; if (zarch_zui_render_lay_root_recent(zui, &tabbed)) return 0; if (zarch_zui_render_lay_root_load (zui, &tabbed)) return 0; if (zarch_zui_render_lay_root_collections(zui, &tabbed)) return 0; if (zarch_zui_render_lay_root_downloads(zui, &tabbed)) return 0; (void)item; #ifdef ZARCH_DEBUG snprintf(item, sizeof(item), "item id: %d\n", zui->active_id); 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); 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 if (zui->pending_selection == -1) { switch (zui->action) { case MENU_ACTION_UP: if (zui->prev_id != -1 && zui->prev_id != zui->active_id) { if (zui->prev_id < zui->active_id) zui->pending_selection = zui->prev_id; } break; case MENU_ACTION_DOWN: if (zui->next_id != -1 && zui->next_id != zui->active_id) { if (zui->next_id > zui->active_id) zui->pending_selection = zui->next_id; } break; default: break; } } else zui->pending_selection = -1; zarch_zui_push_quad(zui->width, zui->height, ZUI_BG_HILITE, &zui->ca, 0, 60, zui->width - 290 - 40, 60+4); return 0; }
static bool zarch_zui_tab(zui_t *zui, struct zui_tabbed *tab, const char *label, unsigned tab_id) { bool active; int x1, y1, x2, y2; unsigned id = zarch_zui_hash(zui, label); 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; width = zarch_zui_strwidth(zui->fb_buf, label, 1.0) + 24; } x1 = tab->x; y1 = tab->y; x2 = x1 + width; y2 = y1 + 60; active = zarch_zui_check_button_up(zui, id, x1, y1, x2, y2); tab->prev_id = tab->active_id; if (zui->item.active == id || tab->active_id == ~0U || !tab->inited) tab->active_id = id; else if (id > tab->active_id) { tab->next_id = id; } if (!tab->inited) tab->inited = true; 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; zarch_zui_push_quad(zui->width, zui->height, bg, &zui->ca, x1+0, y1+0, x2, y2); zarch_zui_draw_text(zui, ZUI_FG_NORMAL, x1+12, y1 + 41, label); if (tab->vertical) tab->y += y2 - y1; else tab->x = x2; return active || (tab->active_id == id); }
static bool zarch_zui_list_item(zui_t *zui, struct zui_tabbed *tab, int x1, int y1, const char *label, unsigned item_id, const char *entry, bool selected) { menu_animation_ctx_ticker_t ticker; char title_buf[PATH_MAX_LENGTH]; unsigned ticker_size; uint64_t *frame_count = NULL; unsigned id = zarch_zui_hash(zui, label); int x2 = x1 + zui->width - 290 - 40; int y2 = y1 + 50; 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); if (tab->active_id != tab->prev_id) { tab->prev_id = tab->active_id; } if (selected) { zui->next_id = item_id; zui->next_selection_set = true; } /* Set background color */ if (zui->item.active == id || zui->item.hot == id) bg = zui_bg_hilite; else if (selected) bg = zui_bg_pad_hilite; ticker_size = x2 / 14; 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); menu_animation_ctl(MENU_ANIMATION_CTL_TICKER, &ticker); zarch_zui_push_quad(zui->width, zui->height, bg, &zui->ca, x1, y1, x2, y2); zarch_zui_draw_text(zui, ZUI_FG_NORMAL, 12, y1 + 35, title_buf); if (entry) zarch_zui_draw_text(zui, ZUI_FG_NORMAL, x2 - 200, y1 + 35, entry); return active; }
static bool zarch_zui_button_full(zui_t *zui, int x1, int y1, int x2, int y2, const char *label) { 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; zarch_zui_push_quad(zui->width, zui->height, bg, &zui->ca, x1, y1, x2, y2); zarch_zui_draw_text(zui, ZUI_FG_NORMAL, x1+12, y1 + 41, label); return active; }
static int zarch_zui_render_lay_root(zui_t *zui) { char item[PATH_MAX_LENGTH]; static struct zui_tabbed tabbed = {~0U}; zarch_zui_tabbed_begin(zui, &tabbed, 0, 0); tabbed.width = zui->width - 290 - 40; zui->next_selection_set = false; if (!zui) return 1; if (zarch_zui_render_lay_root_recent(zui, &tabbed)) return 0; if (zarch_zui_render_lay_root_load (zui, &tabbed)) return 0; if (zarch_zui_render_lay_root_collections(zui, &tabbed)) return 0; if (zarch_zui_render_lay_root_downloads(zui, &tabbed)) return 0; (void)item; #ifdef ZARCH_DEBUG snprintf(item, sizeof(item), "item id: %d\n", zui->active_id); 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); 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 zarch_zui_push_quad(zui->width, zui->height, zui_bg_hilite, &zui->ca, 0, 60, zui->width - 290 - 40, 60+4); return 0; }
static void zarch_frame(void *data) { unsigned i; float coord_color[16]; float coord_color2[16]; menu_display_ctx_draw_t draw; menu_display_ctx_coord_draw_t coord_draw; settings_t *settings = config_get_ptr(); zui_t *zui = (zui_t*)data; if (!zui) return; 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; } } 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; menu_display_ctl(MENU_DISPLAY_CTL_FONT_BIND_BLOCK, &zui->tmp_block); zarch_zui_push_quad(zui->width, zui->height, zui_bg_screen, &zui->ca, 0, 0, zui->width, zui->height); zarch_zui_snow(zui, &zui->ca, zui->width, zui->height); switch (zarch_layout) { case LAY_HOME: if (zarch_zui_render_sidebar(zui)) return; if (zarch_zui_render_lay_root(zui)) return; break; case LAY_SETTINGS: zarch_zui_render_lay_settings(zui); break; case LAY_PICK_CORE: if (zarch_zui_render_sidebar(zui)) return; if (zarch_zui_render_pick_core(zui)) return; break; } 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)); 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); menu_display_ctl(MENU_DISPLAY_CTL_BLEND_END, NULL); memset(&draw, 0, sizeof(menu_display_ctx_draw_t)); 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; draw.handle_alpha = 0.75f; draw.force_transparency = false; draw.color = &coord_color[0]; draw.color2 = &coord_color2[0]; draw.vertex = NULL; 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); zui->rendering = false; menu_display_ctl(MENU_DISPLAY_CTL_FONT_FLUSH_BLOCK, NULL); menu_display_ctl(MENU_DISPLAY_CTL_UNSET_VIEWPORT, NULL); }
static void zarch_zui_snow(zui_t *zui, gfx_coord_array_t *ca, int width, int height) { static struct zui_part particles[NPARTICLES]; static bool initialized = false; static int timeout = 0; unsigned i, max_gen = 2; if (!initialized) { memset(particles, 0, sizeof(particles)); initialized = true; } for (i = 0; i < NPARTICLES; ++i) { struct zui_part *p = (struct zui_part*)&particles[i]; if (!p) return; if (p->alive) { int16_t mouse_x = zarch_zui_input_state(zui, MENU_ZARCH_MOUSE_X); p->y += p->yspeed; p->x += zarch_zui_scalef(mouse_x, 0, width, -0.3, 0.3); p->x += p->xspeed; p->alive = p->y >= 0 && p->y < height && p->x >= 0 && p->x < width; } else if (max_gen > 0 && timeout <= 0) { p->xspeed = zarch_zui_randf(-0.2, 0.2); p->yspeed = zarch_zui_randf(1, 2); p->y = 0; p->x = rand() % width; 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) { unsigned j; float alpha; float colors[16]; struct zui_part *p = &particles[i]; if (!p) return; if (!p->alive) continue; alpha = zarch_zui_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; } zarch_zui_push_quad(width, height, colors, ca, p->x-2, p->y-2, p->x+2, p->y+2); j++; } }
static void zarch_frame(void) { unsigned i; float coord_color[16]; float coord_color2[16]; zui_t *zui = NULL; const struct font_renderer *font_driver = NULL; driver_t *driver = driver_get_ptr(); settings_t *settings = config_get_ptr(); menu_handle_t *menu = menu_driver_get_ptr(); if (!menu) return; (void)driver; zui = (zui_t*)menu->userdata; zui->menu = menu; 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; } } 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; font_driver = driver->font_osd_driver; menu_display_font_bind_block(zui->menu, font_driver, &zui->tmp_block); zarch_zui_push_quad(zui->width, zui->height, ZUI_BG_SCREEN, &zui->ca, 0, 0, zui->width, zui->height); zarch_zui_snow(zui, &zui->ca, zui->width, zui->height); switch (layout) { case LAY_HOME: if (zarch_zui_render_sidebar(zui)) return; if (zarch_zui_render_lay_root(zui)) return; break; case LAY_SETTINGS: zarch_zui_render_lay_settings(zui); break; case LAY_PICK_CORE: if (zarch_zui_render_sidebar(zui)) return; if (zarch_zui_render_pick_core(zui)) return; break; } 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)); 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_blend_begin(); menu_display_draw( 0, 0, zui->width, zui->height, (struct gfx_coords*)&zui->ca, &zui->mvp, zui->textures.white, MENU_DISPLAY_PRIM_TRIANGLES); menu_display_blend_end(); menu_display_draw_bg( zui->width, zui->height, zui->textures.bg.id, 0.75f, false, &coord_color[0], &coord_color2[0], NULL, menu_display_get_tex_coords(), 4, MENU_DISPLAY_PRIM_TRIANGLESTRIP); menu_display_font_flush_block(zui->menu, driver->font_osd_driver); zui->rendering = false; menu_display_ctl(MENU_DISPLAY_CTL_UNSET_VIEWPORT, NULL); }