mirror of
https://github.com/libretro/RetroArch.git
synced 2024-11-27 10:10:57 +00:00
Smooth line ticker - replace scissor operation with fade in/out animation
This commit is contained in:
parent
daeff97f7e
commit
35f7110c41
@ -3038,42 +3038,57 @@ static int xmb_draw_item(
|
||||
&& !string_is_empty(entry->sublabel))
|
||||
{
|
||||
char entry_sublabel[MENU_SUBLABEL_MAX_LENGTH];
|
||||
char entry_sublabel_top_fade[MENU_SUBLABEL_MAX_LENGTH >> 2];
|
||||
char entry_sublabel_bottom_fade[MENU_SUBLABEL_MAX_LENGTH >> 2];
|
||||
menu_animation_ctx_line_ticker_t line_ticker;
|
||||
menu_animation_ctx_line_ticker_smooth_t line_ticker_smooth = {0};
|
||||
unsigned ticker_line_height = 0;
|
||||
unsigned ticker_num_lines = 0;
|
||||
float ticker_y_offset = 0.0f;
|
||||
bool do_scissor = false;
|
||||
float sublabel_x = 0.0f;
|
||||
float sublabel_y = 0.0f;
|
||||
menu_animation_ctx_line_ticker_smooth_t line_ticker_smooth;
|
||||
float ticker_y_offset = 0.0f;
|
||||
float ticker_top_fade_y_offset = 0.0f;
|
||||
float ticker_bottom_fade_y_offset = 0.0f;
|
||||
float ticker_top_fade_alpha = 0.0f;
|
||||
float ticker_bottom_fade_alpha = 0.0f;
|
||||
float sublabel_x = node->x + xmb->margins_screen_left +
|
||||
xmb->icon_spacing_horizontal + xmb->margins_label_left;
|
||||
float sublabel_y = xmb->margins_screen_top +
|
||||
node->y + (xmb->margins_label_top * 3.5f);
|
||||
|
||||
entry_sublabel[0] = '\0';
|
||||
entry_sublabel[0] = '\0';
|
||||
entry_sublabel_top_fade[0] = '\0';
|
||||
entry_sublabel_bottom_fade[0] = '\0';
|
||||
|
||||
if (use_smooth_ticker)
|
||||
{
|
||||
line_ticker_smooth.scissor_enabled = true;
|
||||
line_ticker_smooth.type_enum = (enum menu_animation_ticker_type)settings->uints.menu_ticker_type;
|
||||
line_ticker_smooth.idx = menu_animation_get_ticker_pixel_idx();
|
||||
line_ticker_smooth.fade_enabled = true;
|
||||
line_ticker_smooth.type_enum = (enum menu_animation_ticker_type)settings->uints.menu_ticker_type;
|
||||
line_ticker_smooth.idx = menu_animation_get_ticker_pixel_idx();
|
||||
|
||||
line_ticker_smooth.font = xmb->font2;
|
||||
line_ticker_smooth.font_scale = 1.0f;
|
||||
line_ticker_smooth.font = xmb->font2;
|
||||
line_ticker_smooth.font_scale = 1.0f;
|
||||
|
||||
line_ticker_smooth.field_width = (unsigned)(xmb->font2_size * 0.6f * line_ticker_width);
|
||||
line_ticker_smooth.field_width = (unsigned)(xmb->font2_size * 0.6f * line_ticker_width);
|
||||
/* The calculation here is incredibly obtuse. I think
|
||||
* this is correct... (c.f. xmb_item_y()) */
|
||||
line_ticker_smooth.field_height = (unsigned)(
|
||||
line_ticker_smooth.field_height = (unsigned)(
|
||||
(xmb->icon_spacing_vertical * ((1 + xmb->under_item_offset) - xmb->active_item_factor)) -
|
||||
(xmb->margins_label_top * 4.0f)); /* Should be 3.5f, but prefer the extra padding */
|
||||
(xmb->margins_label_top * 3.5f) -
|
||||
xmb->under_item_offset); /* This last one is just a little extra padding (seems to help) */
|
||||
|
||||
line_ticker_smooth.src_str = entry->sublabel;
|
||||
line_ticker_smooth.dst_str = entry_sublabel;
|
||||
line_ticker_smooth.dst_str_len = sizeof(entry_sublabel);
|
||||
line_ticker_smooth.src_str = entry->sublabel;
|
||||
line_ticker_smooth.dst_str = entry_sublabel;
|
||||
line_ticker_smooth.dst_str_len = sizeof(entry_sublabel);
|
||||
line_ticker_smooth.y_offset = &ticker_y_offset;
|
||||
|
||||
line_ticker_smooth.line_height = &ticker_line_height;
|
||||
line_ticker_smooth.num_lines = &ticker_num_lines;
|
||||
line_ticker_smooth.y_offset = &ticker_y_offset;
|
||||
line_ticker_smooth.top_fade_str = entry_sublabel_top_fade;
|
||||
line_ticker_smooth.top_fade_str_len = sizeof(entry_sublabel_top_fade);
|
||||
line_ticker_smooth.top_fade_y_offset = &ticker_top_fade_y_offset;
|
||||
line_ticker_smooth.top_fade_alpha = &ticker_top_fade_alpha;
|
||||
|
||||
do_scissor = menu_animation_line_ticker_smooth(&line_ticker_smooth);
|
||||
line_ticker_smooth.bottom_fade_str = entry_sublabel_bottom_fade;
|
||||
line_ticker_smooth.bottom_fade_str_len = sizeof(entry_sublabel_bottom_fade);
|
||||
line_ticker_smooth.bottom_fade_y_offset = &ticker_bottom_fade_y_offset;
|
||||
line_ticker_smooth.bottom_fade_alpha = &ticker_bottom_fade_alpha;
|
||||
|
||||
menu_animation_line_ticker_smooth(&line_ticker_smooth);
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -3096,67 +3111,28 @@ static int xmb_draw_item(
|
||||
|
||||
label_offset = - xmb->margins_label_top;
|
||||
|
||||
/* Base draw position */
|
||||
sublabel_x = node->x + xmb->margins_screen_left +
|
||||
xmb->icon_spacing_horizontal + xmb->margins_label_left;
|
||||
sublabel_y = xmb->margins_screen_top +
|
||||
node->y + (xmb->margins_label_top * 3.5f);
|
||||
|
||||
if (do_scissor)
|
||||
{
|
||||
/* We are currently 'blending', so stop */
|
||||
menu_display_blend_end(video_info);
|
||||
/* These font shenanigans seem to be requied before
|
||||
* calling menu_display_scissor_begin() */
|
||||
font_driver_flush(video_info->width, video_info->height, xmb->font2, video_info);
|
||||
xmb->raster_block2.carr.coords.vertices = 0;
|
||||
/* TODO/FIXME
|
||||
* Okay, font handling in RetroArch sucks...
|
||||
* - It seems that text is drawn relative to the baseline,
|
||||
* which kinda-sorta makes sense...
|
||||
* - But there's no way to extract any useful font metrics
|
||||
* such as descender/ascender height and baseline position
|
||||
* So basically, when drawing text you pick a y postion and
|
||||
* hope for the best - the text will appear somewhere near the
|
||||
* place you want it to, but not quite, and trying to clip text
|
||||
* to a specified draw area is basically impossible.
|
||||
* The *correct* way to implement a font library/handler is to
|
||||
* deal with all font metrics internally such that the y draw
|
||||
* position is the vertical centre of the line. Since you know
|
||||
* the line height, this makes all layout operations trivial.
|
||||
* This should be done at some point, but I don't have time
|
||||
* to rewrite all of the font handling code for the sake of a
|
||||
* single line ticker, so for now we'll just make do...
|
||||
* So here it is: we want to clip the scrolling text such that
|
||||
* it fills a vertical region eqivalent to the maximum number
|
||||
* of static sublabel lines that can be shown. Since we don't
|
||||
* know any font metrics, we have to use a fudge factor for
|
||||
* the scissor start position (the 0.75 comes from the fact that
|
||||
* for a typical font, the descender is ~20-30% of the line
|
||||
* height). *This is not robust*, but it works well enough for
|
||||
* all existing XMB themes */
|
||||
menu_display_scissor_begin(
|
||||
video_info, (int)sublabel_x, (int)((float)sublabel_y - ((float)ticker_line_height * 0.75f)),
|
||||
(unsigned)((float)video_info->width - sublabel_x),
|
||||
ticker_num_lines * ticker_line_height);
|
||||
}
|
||||
|
||||
/* Only apply ticker y offset when actually
|
||||
* drawing the text */
|
||||
/* Draw sublabel */
|
||||
xmb_draw_text(video_info, xmb, entry_sublabel,
|
||||
sublabel_x, ticker_y_offset + sublabel_y,
|
||||
1, node->label_alpha, TEXT_ALIGN_LEFT,
|
||||
width, height, xmb->font2);
|
||||
|
||||
if (do_scissor)
|
||||
/* Draw top/bottom line fade effect, if required */
|
||||
if (use_smooth_ticker)
|
||||
{
|
||||
/* These font shenanigans seem to be requied before
|
||||
* calling menu_display_scissor_end() */
|
||||
font_driver_flush(video_info->width, video_info->height, xmb->font2, video_info);
|
||||
xmb->raster_block2.carr.coords.vertices = 0;
|
||||
menu_display_scissor_end(video_info);
|
||||
/* Resume 'blending' */
|
||||
menu_display_blend_begin(video_info);
|
||||
if (!string_is_empty(entry_sublabel_top_fade) &&
|
||||
ticker_top_fade_alpha > 0.0f)
|
||||
xmb_draw_text(video_info, xmb, entry_sublabel_top_fade,
|
||||
sublabel_x, ticker_top_fade_y_offset + sublabel_y,
|
||||
1, ticker_top_fade_alpha * node->label_alpha, TEXT_ALIGN_LEFT,
|
||||
width, height, xmb->font2);
|
||||
|
||||
if (!string_is_empty(entry_sublabel_bottom_fade) &&
|
||||
ticker_bottom_fade_alpha > 0.0f)
|
||||
xmb_draw_text(video_info, xmb, entry_sublabel_bottom_fade,
|
||||
sublabel_x, ticker_bottom_fade_y_offset + sublabel_y,
|
||||
1, ticker_bottom_fade_alpha * node->label_alpha, TEXT_ALIGN_LEFT,
|
||||
width, height, xmb->font2);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -846,10 +846,53 @@ static size_t get_line_smooth_scroll_ticks(size_t line_len)
|
||||
return (size_t)(line_duration / ticker_pixel_period);
|
||||
}
|
||||
|
||||
static void set_line_smooth_fade_parameters(
|
||||
bool scroll_up, size_t scroll_ticks, size_t line_phase, size_t line_height,
|
||||
size_t num_lines, size_t num_display_lines, size_t line_offset, float y_offset,
|
||||
size_t *top_fade_line_offset, float *top_fade_y_offset, float *top_fade_alpha,
|
||||
size_t *bottom_fade_line_offset, float *bottom_fade_y_offset, float *bottom_fade_alpha)
|
||||
{
|
||||
float fade_out_alpha = 0.0f;
|
||||
float fade_in_alpha = 0.0f;
|
||||
|
||||
/* When a line fades out, alpha transitions from
|
||||
* 1 to 0 over the course of one half of the
|
||||
* scrolling line height. When a line fades in,
|
||||
* it's the other way around */
|
||||
fade_out_alpha = ((float)scroll_ticks - ((float)line_phase * 2.0f)) / (float)scroll_ticks;
|
||||
fade_in_alpha = -1.0f * fade_out_alpha;
|
||||
fade_out_alpha = (fade_out_alpha < 0.0f) ? 0.0f : fade_out_alpha;
|
||||
fade_in_alpha = (fade_in_alpha < 0.0f) ? 0.0f : fade_in_alpha;
|
||||
|
||||
*top_fade_line_offset = (line_offset > 0) ? line_offset - 1 : num_lines;
|
||||
*top_fade_y_offset = y_offset - (float)line_height;
|
||||
*top_fade_alpha = scroll_up ? fade_out_alpha : fade_in_alpha;
|
||||
|
||||
*bottom_fade_line_offset = line_offset + num_display_lines;
|
||||
*bottom_fade_y_offset = y_offset + (float)(line_height * num_display_lines);
|
||||
*bottom_fade_alpha = scroll_up ? fade_in_alpha : fade_out_alpha;
|
||||
}
|
||||
|
||||
static void set_line_smooth_fade_parameters_default(
|
||||
size_t *top_fade_line_offset, float *top_fade_y_offset, float *top_fade_alpha,
|
||||
size_t *bottom_fade_line_offset, float *bottom_fade_y_offset, float *bottom_fade_alpha)
|
||||
{
|
||||
*top_fade_line_offset = 0;
|
||||
*top_fade_y_offset = 0.0f;
|
||||
*top_fade_alpha = 0.0f;
|
||||
|
||||
*bottom_fade_line_offset = 0;
|
||||
*bottom_fade_y_offset = 0.0f;
|
||||
*bottom_fade_alpha = 0.0f;
|
||||
}
|
||||
|
||||
static void menu_animation_line_ticker_smooth_generic(uint64_t idx,
|
||||
bool scissor_enabled, size_t line_len, size_t line_height,
|
||||
bool fade_enabled, size_t line_len, size_t line_height,
|
||||
size_t max_display_lines, size_t num_lines,
|
||||
size_t *num_display_lines, size_t *line_offset, float *y_offset)
|
||||
size_t *num_display_lines, size_t *line_offset, float *y_offset,
|
||||
bool *fade_active,
|
||||
size_t *top_fade_line_offset, float *top_fade_y_offset, float *top_fade_alpha,
|
||||
size_t *bottom_fade_line_offset, float *bottom_fade_y_offset, float *bottom_fade_alpha)
|
||||
{
|
||||
size_t scroll_ticks = get_line_smooth_scroll_ticks(line_len);
|
||||
/* Note: This function is only called if num_lines > max_display_lines */
|
||||
@ -880,72 +923,96 @@ static void menu_animation_line_ticker_smooth_generic(uint64_t idx,
|
||||
phase -= (excess_lines + 1) * scroll_ticks;
|
||||
}
|
||||
|
||||
/* If we are currently paused, can use static offsets */
|
||||
if (pause)
|
||||
line_phase = phase % scroll_ticks;
|
||||
|
||||
if (pause || (line_phase == 0))
|
||||
{
|
||||
/* Static display of max_display_lines
|
||||
* (no animation) */
|
||||
*num_display_lines = max_display_lines;
|
||||
*line_offset = scroll_up ? 0 : excess_lines;
|
||||
*y_offset = 0.0f;
|
||||
*y_offset = 0.0f;
|
||||
*fade_active = false;
|
||||
|
||||
if (pause)
|
||||
*line_offset = scroll_up ? 0 : excess_lines;
|
||||
else
|
||||
*line_offset = scroll_up ? (phase / scroll_ticks) : (excess_lines - (phase / scroll_ticks));
|
||||
}
|
||||
else
|
||||
{
|
||||
line_phase = phase % scroll_ticks;
|
||||
/* Scroll animation is active */
|
||||
*num_display_lines = max_display_lines - 1;
|
||||
*fade_active = fade_enabled;
|
||||
|
||||
if (scissor_enabled)
|
||||
if (scroll_up)
|
||||
{
|
||||
*num_display_lines = max_display_lines + 1;
|
||||
|
||||
if (scroll_up)
|
||||
{
|
||||
*line_offset = phase / scroll_ticks;
|
||||
*y_offset = (float)line_height * (((float)(scroll_ticks - line_phase) / (float)scroll_ticks) - 1.0f);
|
||||
}
|
||||
else
|
||||
{
|
||||
*line_offset = (excess_lines - 1) - (phase / scroll_ticks);
|
||||
*y_offset = (float)line_height * ((1.0f - (float)(scroll_ticks - line_phase) / (float)scroll_ticks) - 1.0f);
|
||||
}
|
||||
*line_offset = (phase / scroll_ticks) + 1;
|
||||
*y_offset = (float)line_height * (float)(scroll_ticks - line_phase) / (float)scroll_ticks;
|
||||
}
|
||||
else
|
||||
{
|
||||
*num_display_lines = max_display_lines - 1;
|
||||
|
||||
if (scroll_up)
|
||||
{
|
||||
*line_offset = (phase / scroll_ticks) + 1;
|
||||
*y_offset = (float)line_height * (float)(scroll_ticks - line_phase) / (float)scroll_ticks;
|
||||
}
|
||||
else
|
||||
{
|
||||
*line_offset = excess_lines - (phase / scroll_ticks);
|
||||
*y_offset = (float)line_height * (1.0f - (float)(scroll_ticks - line_phase) / (float)scroll_ticks);
|
||||
}
|
||||
*line_offset = excess_lines - (phase / scroll_ticks);
|
||||
*y_offset = (float)line_height * (1.0f - (float)(scroll_ticks - line_phase) / (float)scroll_ticks);
|
||||
}
|
||||
|
||||
/* Set fade parameters if fade animation is active */
|
||||
if (*fade_active)
|
||||
set_line_smooth_fade_parameters(
|
||||
scroll_up, scroll_ticks, line_phase, line_height,
|
||||
num_lines, *num_display_lines, *line_offset, *y_offset,
|
||||
top_fade_line_offset, top_fade_y_offset, top_fade_alpha,
|
||||
bottom_fade_line_offset, bottom_fade_y_offset, bottom_fade_alpha);
|
||||
}
|
||||
|
||||
/* Set 'default' fade parameters if fade animation
|
||||
* is inactive */
|
||||
if (!*fade_active)
|
||||
set_line_smooth_fade_parameters_default(
|
||||
top_fade_line_offset, top_fade_y_offset, top_fade_alpha,
|
||||
bottom_fade_line_offset, bottom_fade_y_offset, bottom_fade_alpha);
|
||||
}
|
||||
|
||||
static void menu_animation_line_ticker_smooth_loop(uint64_t idx,
|
||||
bool scissor_enabled, size_t line_len, size_t line_height,
|
||||
bool fade_enabled, size_t line_len, size_t line_height,
|
||||
size_t max_display_lines, size_t num_lines,
|
||||
size_t *num_display_lines, size_t *line_offset, float *y_offset)
|
||||
size_t *num_display_lines, size_t *line_offset, float *y_offset,
|
||||
bool *fade_active,
|
||||
size_t *top_fade_line_offset, float *top_fade_y_offset, float *top_fade_alpha,
|
||||
size_t *bottom_fade_line_offset, float *bottom_fade_y_offset, float *bottom_fade_alpha)
|
||||
{
|
||||
size_t scroll_ticks = get_line_smooth_scroll_ticks(line_len);
|
||||
size_t ticker_period = (num_lines + 1) * scroll_ticks;
|
||||
size_t phase = idx % ticker_period;
|
||||
size_t line_phase = phase % scroll_ticks;
|
||||
|
||||
*line_offset = phase / scroll_ticks;
|
||||
*line_offset = phase / scroll_ticks;
|
||||
|
||||
if (scissor_enabled)
|
||||
if (line_phase == (scroll_ticks - 1))
|
||||
{
|
||||
*num_display_lines = max_display_lines + 1;
|
||||
*y_offset = (float)line_height * (((float)(scroll_ticks - line_phase) / (float)scroll_ticks) - 1.0f);
|
||||
/* Static display of max_display_lines
|
||||
* (no animation) */
|
||||
*num_display_lines = max_display_lines;
|
||||
*fade_active = false;
|
||||
}
|
||||
else
|
||||
{
|
||||
*num_display_lines = max_display_lines - 1;
|
||||
*y_offset = (float)line_height * (float)(scroll_ticks - line_phase) / (float)scroll_ticks;
|
||||
*fade_active = fade_enabled;
|
||||
}
|
||||
|
||||
*y_offset = (float)line_height * (float)(scroll_ticks - line_phase) / (float)scroll_ticks;
|
||||
|
||||
/* Set fade parameters */
|
||||
if (*fade_active)
|
||||
set_line_smooth_fade_parameters(
|
||||
true, scroll_ticks, line_phase, line_height,
|
||||
num_lines, *num_display_lines, *line_offset, *y_offset,
|
||||
top_fade_line_offset, top_fade_y_offset, top_fade_alpha,
|
||||
bottom_fade_line_offset, bottom_fade_y_offset, bottom_fade_alpha);
|
||||
else
|
||||
set_line_smooth_fade_parameters_default(
|
||||
top_fade_line_offset, top_fade_y_offset, top_fade_alpha,
|
||||
bottom_fade_line_offset, bottom_fade_y_offset, bottom_fade_alpha);
|
||||
}
|
||||
|
||||
static void menu_delayed_animation_cb(void *userdata)
|
||||
@ -1898,16 +1965,19 @@ end:
|
||||
|
||||
bool menu_animation_line_ticker_smooth(menu_animation_ctx_line_ticker_smooth_t *line_ticker)
|
||||
{
|
||||
char *wrapped_str = NULL;
|
||||
struct string_list *lines = NULL;
|
||||
int glyph_width = 0;
|
||||
int glyph_height = 0;
|
||||
size_t line_len = 0;
|
||||
size_t max_display_lines = 0;
|
||||
size_t num_display_lines = 0;
|
||||
size_t line_offset = 0;
|
||||
bool success = false;
|
||||
bool is_active = false;
|
||||
char *wrapped_str = NULL;
|
||||
struct string_list *lines = NULL;
|
||||
int glyph_width = 0;
|
||||
int glyph_height = 0;
|
||||
size_t line_len = 0;
|
||||
size_t max_display_lines = 0;
|
||||
size_t num_display_lines = 0;
|
||||
size_t line_offset = 0;
|
||||
size_t top_fade_line_offset = 0;
|
||||
size_t bottom_fade_line_offset = 0;
|
||||
bool fade_active = false;
|
||||
bool success = false;
|
||||
bool is_active = false;
|
||||
|
||||
/* Sanity check */
|
||||
if (!line_ticker)
|
||||
@ -1941,8 +2011,6 @@ bool menu_animation_line_ticker_smooth(menu_animation_ctx_line_ticker_smooth_t *
|
||||
if (glyph_height < 0)
|
||||
goto end;
|
||||
|
||||
*line_ticker->line_height = (unsigned)glyph_height;
|
||||
|
||||
/* Determine line wrap parameters */
|
||||
line_len = (size_t)(line_ticker->field_width / glyph_width);
|
||||
max_display_lines = (size_t)(line_ticker->field_height / glyph_height);
|
||||
@ -1974,14 +2042,28 @@ bool menu_animation_line_ticker_smooth(menu_animation_ctx_line_ticker_smooth_t *
|
||||
if (lines->size <= max_display_lines)
|
||||
{
|
||||
strlcpy(line_ticker->dst_str, wrapped_str, line_ticker->dst_str_len);
|
||||
*line_ticker->num_lines = (unsigned)lines->size;
|
||||
*line_ticker->y_offset = 0.0f;
|
||||
|
||||
/* No fade animation is required */
|
||||
if (line_ticker->fade_enabled)
|
||||
{
|
||||
if (line_ticker->top_fade_str_len > 0)
|
||||
line_ticker->top_fade_str[0] = '\0';
|
||||
|
||||
if (line_ticker->bottom_fade_str_len > 0)
|
||||
line_ticker->bottom_fade_str[0] = '\0';
|
||||
|
||||
*line_ticker->top_fade_y_offset = 0.0f;
|
||||
*line_ticker->bottom_fade_y_offset = 0.0f;
|
||||
|
||||
*line_ticker->top_fade_alpha = 0.0f;
|
||||
*line_ticker->bottom_fade_alpha = 0.0f;
|
||||
}
|
||||
|
||||
success = true;
|
||||
goto end;
|
||||
}
|
||||
|
||||
*line_ticker->num_lines = (unsigned)max_display_lines;
|
||||
|
||||
/* Determine which lines should be shown, along with
|
||||
* y axis draw offset */
|
||||
switch (line_ticker->type_enum)
|
||||
@ -1990,14 +2072,13 @@ bool menu_animation_line_ticker_smooth(menu_animation_ctx_line_ticker_smooth_t *
|
||||
{
|
||||
menu_animation_line_ticker_smooth_loop(
|
||||
line_ticker->idx,
|
||||
line_ticker->scissor_enabled,
|
||||
line_len,
|
||||
(size_t)glyph_height,
|
||||
max_display_lines,
|
||||
lines->size,
|
||||
&num_display_lines,
|
||||
&line_offset,
|
||||
line_ticker->y_offset);
|
||||
line_ticker->fade_enabled,
|
||||
line_len, (size_t)glyph_height,
|
||||
max_display_lines, lines->size,
|
||||
&num_display_lines, &line_offset, line_ticker->y_offset,
|
||||
&fade_active,
|
||||
&top_fade_line_offset, line_ticker->top_fade_y_offset, line_ticker->top_fade_alpha,
|
||||
&bottom_fade_line_offset, line_ticker->bottom_fade_y_offset, line_ticker->bottom_fade_alpha);
|
||||
|
||||
break;
|
||||
}
|
||||
@ -2006,14 +2087,13 @@ bool menu_animation_line_ticker_smooth(menu_animation_ctx_line_ticker_smooth_t *
|
||||
{
|
||||
menu_animation_line_ticker_smooth_generic(
|
||||
line_ticker->idx,
|
||||
line_ticker->scissor_enabled,
|
||||
line_len,
|
||||
(size_t)glyph_height,
|
||||
max_display_lines,
|
||||
lines->size,
|
||||
&num_display_lines,
|
||||
&line_offset,
|
||||
line_ticker->y_offset);
|
||||
line_ticker->fade_enabled,
|
||||
line_len, (size_t)glyph_height,
|
||||
max_display_lines, lines->size,
|
||||
&num_display_lines, &line_offset, line_ticker->y_offset,
|
||||
&fade_active,
|
||||
&top_fade_line_offset, line_ticker->top_fade_y_offset, line_ticker->top_fade_alpha,
|
||||
&bottom_fade_line_offset, line_ticker->bottom_fade_y_offset, line_ticker->bottom_fade_alpha);
|
||||
|
||||
break;
|
||||
}
|
||||
@ -2021,8 +2101,23 @@ bool menu_animation_line_ticker_smooth(menu_animation_ctx_line_ticker_smooth_t *
|
||||
|
||||
/* Build output string from required lines */
|
||||
build_line_ticker_string(
|
||||
num_display_lines, line_offset, lines,
|
||||
line_ticker->dst_str, line_ticker->dst_str_len);
|
||||
num_display_lines, line_offset, lines,
|
||||
line_ticker->dst_str, line_ticker->dst_str_len);
|
||||
|
||||
/* Extract top/bottom fade strings, if required */
|
||||
if (fade_active)
|
||||
{
|
||||
/* We waste a handful of clock cycles by using
|
||||
* build_line_ticker_string() here, but it saves
|
||||
* rewriting a heap of code... */
|
||||
build_line_ticker_string(
|
||||
1, top_fade_line_offset, lines,
|
||||
line_ticker->top_fade_str, line_ticker->top_fade_str_len);
|
||||
|
||||
build_line_ticker_string(
|
||||
1, bottom_fade_line_offset, lines,
|
||||
line_ticker->bottom_fade_str, line_ticker->bottom_fade_str_len);
|
||||
}
|
||||
|
||||
success = true;
|
||||
is_active = true;
|
||||
@ -2043,9 +2138,23 @@ end:
|
||||
}
|
||||
|
||||
if (!success)
|
||||
{
|
||||
if (line_ticker->dst_str_len > 0)
|
||||
line_ticker->dst_str[0] = '\0';
|
||||
|
||||
if (line_ticker->fade_enabled)
|
||||
{
|
||||
if (line_ticker->top_fade_str_len > 0)
|
||||
line_ticker->top_fade_str[0] = '\0';
|
||||
|
||||
if (line_ticker->bottom_fade_str_len > 0)
|
||||
line_ticker->bottom_fade_str[0] = '\0';
|
||||
|
||||
*line_ticker->top_fade_alpha = 0.0f;
|
||||
*line_ticker->bottom_fade_alpha = 0.0f;
|
||||
}
|
||||
}
|
||||
|
||||
return is_active;
|
||||
}
|
||||
|
||||
|
@ -158,7 +158,7 @@ typedef struct menu_animation_ctx_line_ticker
|
||||
|
||||
typedef struct menu_animation_ctx_line_ticker_smooth
|
||||
{
|
||||
bool scissor_enabled;
|
||||
bool fade_enabled;
|
||||
font_data_t *font;
|
||||
float font_scale;
|
||||
unsigned field_width;
|
||||
@ -168,9 +168,15 @@ typedef struct menu_animation_ctx_line_ticker_smooth
|
||||
const char *src_str;
|
||||
char *dst_str;
|
||||
size_t dst_str_len;
|
||||
unsigned *line_height;
|
||||
unsigned *num_lines;
|
||||
float *y_offset;
|
||||
char *top_fade_str;
|
||||
size_t top_fade_str_len;
|
||||
float *top_fade_y_offset;
|
||||
float *top_fade_alpha;
|
||||
char *bottom_fade_str;
|
||||
size_t bottom_fade_str_len;
|
||||
float *bottom_fade_y_offset;
|
||||
float *bottom_fade_alpha;
|
||||
} menu_animation_ctx_line_ticker_smooth_t;
|
||||
|
||||
typedef float menu_timer_t;
|
||||
@ -200,16 +206,6 @@ bool menu_animation_ticker_smooth(menu_animation_ctx_ticker_smooth_t *ticker);
|
||||
|
||||
bool menu_animation_line_ticker(menu_animation_ctx_line_ticker_t *line_ticker);
|
||||
|
||||
/* Note: When line_ticker->scissor_enabled is true,
|
||||
* resultant string must be drawn in conjunction with
|
||||
* menu_display_scissor_*()
|
||||
* i.e. draw area must be scissored vertically by
|
||||
* (line_ticker->line_height * line_ticker->num_lines),
|
||||
* with a scissor y start position of text y postion
|
||||
* (ignoring line_ticker->y_offset) *minus*
|
||||
* (line_ticker->line_height - font_descender_size).
|
||||
* font_descender_size is typically 20-30% of the line
|
||||
* height... */
|
||||
bool menu_animation_line_ticker_smooth(menu_animation_ctx_line_ticker_smooth_t *line_ticker);
|
||||
|
||||
float menu_animation_get_delta_time(void);
|
||||
|
Loading…
Reference in New Issue
Block a user