mirror of
https://github.com/libretro/RetroArch
synced 2025-03-24 04:44:02 +00:00
Merge pull request #8677 from jdgleaver/rgui-performance
(RGUI) Further performance optimisations
This commit is contained in:
commit
1d1cc87c4f
@ -72,6 +72,8 @@
|
|||||||
#define RGUI_TERM_HEIGHT(fb_height) rgui_term_layout.height
|
#define RGUI_TERM_HEIGHT(fb_height) rgui_term_layout.height
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#define MAX_FB_WIDTH 426
|
||||||
|
|
||||||
#define RGUI_ENTRY_VALUE_MAXLEN 19
|
#define RGUI_ENTRY_VALUE_MAXLEN 19
|
||||||
|
|
||||||
#define RGUI_TICKER_SPACER " | "
|
#define RGUI_TICKER_SPACER " | "
|
||||||
@ -926,75 +928,213 @@ static uint16_t argb32_to_rgba4444(uint32_t col)
|
|||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
static uint16_t INLINE rgui_bg_filler(rgui_t *rgui, unsigned x, unsigned y)
|
|
||||||
{
|
|
||||||
unsigned shift = (rgui->bg_thickness ? 1 : 0);
|
|
||||||
unsigned select = ((x >> shift) + (y >> shift)) & 1;
|
|
||||||
return (select == 0) ? rgui->colors.bg_dark_color : rgui->colors.bg_light_color;
|
|
||||||
}
|
|
||||||
|
|
||||||
static uint16_t INLINE rgui_border_filler(rgui_t *rgui, unsigned x, unsigned y)
|
|
||||||
{
|
|
||||||
unsigned shift = (rgui->border_thickness ? 1 : 0);
|
|
||||||
unsigned select = ((x >> shift) + (y >> shift)) & 1;
|
|
||||||
return (select == 0) ? rgui->colors.border_dark_color : rgui->colors.border_light_color;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void rgui_fill_rect(
|
static void rgui_fill_rect(
|
||||||
rgui_t *rgui,
|
|
||||||
uint16_t *data,
|
uint16_t *data,
|
||||||
size_t pitch,
|
unsigned fb_width, unsigned fb_height,
|
||||||
unsigned x, unsigned y,
|
unsigned x, unsigned y,
|
||||||
unsigned width, unsigned height,
|
unsigned width, unsigned height,
|
||||||
uint16_t (*col)(rgui_t *rgui, unsigned x, unsigned y))
|
uint16_t dark_color, uint16_t light_color,
|
||||||
|
bool thickness)
|
||||||
{
|
{
|
||||||
unsigned i, j;
|
unsigned x_index, y_index;
|
||||||
|
unsigned x_start = x <= fb_width ? x : fb_width;
|
||||||
|
unsigned y_start = y <= fb_height ? y : fb_height;
|
||||||
|
unsigned x_end = x + width;
|
||||||
|
unsigned y_end = y + height;
|
||||||
|
size_t x_size;
|
||||||
|
uint16_t scanline_even[MAX_FB_WIDTH]; /* Initial values don't matter here */
|
||||||
|
uint16_t scanline_odd[MAX_FB_WIDTH];
|
||||||
|
|
||||||
for (j = y; j < y + height; j++)
|
/* Note: unlike rgui_color_rect() and rgui_draw_particle(),
|
||||||
for (i = x; i < x + width; i++)
|
* this function is frequently used to fill large areas.
|
||||||
data[j * (pitch >> 1) + i] = col(rgui, i, j);
|
* We therefore gain significant performance benefits
|
||||||
|
* from using memcpy() tricks... */
|
||||||
|
|
||||||
|
x_end = x_end <= fb_width ? x_end : fb_width;
|
||||||
|
y_end = y_end <= fb_height ? y_end : fb_height;
|
||||||
|
x_size = (x_end - x_start) * sizeof(uint16_t);
|
||||||
|
|
||||||
|
/* Sanity check */
|
||||||
|
if (x_size == 0)
|
||||||
|
return;
|
||||||
|
|
||||||
|
/* If dark_color and light_color are the same,
|
||||||
|
* perform a solid fill */
|
||||||
|
if (dark_color == light_color)
|
||||||
|
{
|
||||||
|
uint16_t *src = scanline_even + x_start;
|
||||||
|
uint16_t *dst = data + x_start;
|
||||||
|
|
||||||
|
/* Populate source array */
|
||||||
|
for (x_index = x_start; x_index < x_end; x_index++)
|
||||||
|
*(scanline_even + x_index) = dark_color;
|
||||||
|
|
||||||
|
/* Fill destination array */
|
||||||
|
for (y_index = y_start; y_index < y_end; y_index++)
|
||||||
|
memcpy(dst + (y_index * fb_width), src, x_size);
|
||||||
|
}
|
||||||
|
else if (thickness)
|
||||||
|
{
|
||||||
|
uint16_t *src_a = NULL;
|
||||||
|
uint16_t *src_b = NULL;
|
||||||
|
uint16_t *src_c = NULL;
|
||||||
|
uint16_t *src_d = NULL;
|
||||||
|
uint16_t *dst = data + x_start;
|
||||||
|
|
||||||
|
/* Determine in which order the source arrays
|
||||||
|
* should be copied */
|
||||||
|
switch (y_start & 0x3)
|
||||||
|
{
|
||||||
|
case 0x1:
|
||||||
|
src_a = scanline_even + x_start;
|
||||||
|
src_b = scanline_odd + x_start;
|
||||||
|
src_c = src_b;
|
||||||
|
src_d = src_a;
|
||||||
|
break;
|
||||||
|
case 0x2:
|
||||||
|
src_a = scanline_odd + x_start;
|
||||||
|
src_b = src_a;
|
||||||
|
src_c = scanline_even + x_start;
|
||||||
|
src_d = src_c;
|
||||||
|
break;
|
||||||
|
case 0x3:
|
||||||
|
src_a = scanline_odd + x_start;
|
||||||
|
src_b = scanline_even + x_start;
|
||||||
|
src_c = src_b;
|
||||||
|
src_d = src_a;
|
||||||
|
break;
|
||||||
|
case 0x0:
|
||||||
|
default:
|
||||||
|
src_a = scanline_even + x_start;
|
||||||
|
src_b = src_a;
|
||||||
|
src_c = scanline_odd + x_start;
|
||||||
|
src_d = src_c;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Populate source arrays */
|
||||||
|
for (x_index = x_start; x_index < x_end; x_index++)
|
||||||
|
{
|
||||||
|
bool x_is_even = (((x_index >> 1) & 1) == 0);
|
||||||
|
*(scanline_even + x_index) = x_is_even ? dark_color : light_color;
|
||||||
|
*(scanline_odd + x_index) = x_is_even ? light_color : dark_color;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Fill destination array */
|
||||||
|
for (y_index = y_start ; y_index < y_end; y_index += 4)
|
||||||
|
memcpy(dst + (y_index * fb_width), src_a, x_size);
|
||||||
|
|
||||||
|
for (y_index = y_start + 1; y_index < y_end; y_index += 4)
|
||||||
|
memcpy(dst + (y_index * fb_width), src_b, x_size);
|
||||||
|
|
||||||
|
for (y_index = y_start + 2; y_index < y_end; y_index += 4)
|
||||||
|
memcpy(dst + (y_index * fb_width), src_c, x_size);
|
||||||
|
|
||||||
|
for (y_index = y_start + 3; y_index < y_end; y_index += 4)
|
||||||
|
memcpy(dst + (y_index * fb_width), src_d, x_size);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
uint16_t *src_a = NULL;
|
||||||
|
uint16_t *src_b = NULL;
|
||||||
|
uint16_t *dst = data + x_start;
|
||||||
|
|
||||||
|
/* Determine in which order the source arrays
|
||||||
|
* should be copied */
|
||||||
|
if ((y_start & 1) == 0)
|
||||||
|
{
|
||||||
|
src_a = scanline_even + x_start;
|
||||||
|
src_b = scanline_odd + x_start;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
src_a = scanline_odd + x_start;
|
||||||
|
src_b = scanline_even + x_start;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Populate source arrays */
|
||||||
|
for (x_index = x_start; x_index < x_end; x_index++)
|
||||||
|
{
|
||||||
|
bool x_is_even = ((x_index & 1) == 0);
|
||||||
|
*(scanline_even + x_index) = x_is_even ? dark_color : light_color;
|
||||||
|
*(scanline_odd + x_index) = x_is_even ? light_color : dark_color;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Fill destination array */
|
||||||
|
for (y_index = y_start ; y_index < y_end; y_index += 2)
|
||||||
|
memcpy(dst + (y_index * fb_width), src_a, x_size);
|
||||||
|
|
||||||
|
for (y_index = y_start + 1; y_index < y_end; y_index += 2)
|
||||||
|
memcpy(dst + (y_index * fb_width), src_b, x_size);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void rgui_color_rect(
|
static void rgui_color_rect(
|
||||||
uint16_t *data,
|
uint16_t *data,
|
||||||
size_t pitch,
|
|
||||||
unsigned fb_width, unsigned fb_height,
|
unsigned fb_width, unsigned fb_height,
|
||||||
unsigned x, unsigned y,
|
unsigned x, unsigned y,
|
||||||
unsigned width, unsigned height,
|
unsigned width, unsigned height,
|
||||||
uint16_t color)
|
uint16_t color)
|
||||||
{
|
{
|
||||||
unsigned i, j;
|
unsigned x_index, y_index;
|
||||||
|
unsigned x_start = x <= fb_width ? x : fb_width;
|
||||||
|
unsigned y_start = y <= fb_height ? y : fb_height;
|
||||||
|
unsigned x_end = x + width;
|
||||||
|
unsigned y_end = y + height;
|
||||||
|
|
||||||
for (j = y; j < y + height; j++)
|
x_end = x_end <= fb_width ? x_end : fb_width;
|
||||||
for (i = x; i < x + width; i++)
|
y_end = y_end <= fb_height ? y_end : fb_height;
|
||||||
if (i < fb_width && j < fb_height)
|
|
||||||
data[j * (pitch >> 1) + i] = color;
|
for (y_index = y_start; y_index < y_end; y_index++)
|
||||||
|
{
|
||||||
|
uint16_t *data_ptr = data + (y_index * fb_width);
|
||||||
|
for (x_index = x_start; x_index < x_end; x_index++)
|
||||||
|
*(data_ptr + x_index) = color;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void rgui_render_border(rgui_t *rgui, uint16_t *data,
|
static void rgui_render_border(rgui_t *rgui, uint16_t *data,
|
||||||
size_t fb_pitch, unsigned fb_width, unsigned fb_height)
|
unsigned fb_width, unsigned fb_height)
|
||||||
{
|
{
|
||||||
|
uint16_t dark_color;
|
||||||
|
uint16_t light_color;
|
||||||
|
bool thickness;
|
||||||
|
|
||||||
/* Sanity check */
|
/* Sanity check */
|
||||||
if (!rgui || !data)
|
if (!rgui || !data)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
dark_color = rgui->colors.border_dark_color;
|
||||||
|
light_color = rgui->colors.border_light_color;
|
||||||
|
thickness = rgui->border_thickness;
|
||||||
|
|
||||||
/* Draw border */
|
/* Draw border */
|
||||||
rgui_fill_rect(rgui, data, fb_pitch, 5, 5, fb_width - 10, 5, rgui_border_filler);
|
rgui_fill_rect(data, fb_width, fb_height,
|
||||||
rgui_fill_rect(rgui, data, fb_pitch, 5, fb_height - 10, fb_width - 10, 5, rgui_border_filler);
|
5, 5, fb_width - 10, 5,
|
||||||
rgui_fill_rect(rgui, data, fb_pitch, 5, 5, 5, fb_height - 10, rgui_border_filler);
|
dark_color, light_color, thickness);
|
||||||
rgui_fill_rect(rgui, data, fb_pitch, fb_width - 10, 5, 5, fb_height - 10, rgui_border_filler);
|
rgui_fill_rect(data, fb_width, fb_height,
|
||||||
|
5, fb_height - 10, fb_width - 10, 5,
|
||||||
|
dark_color, light_color, thickness);
|
||||||
|
rgui_fill_rect(data, fb_width, fb_height,
|
||||||
|
5, 5, 5, fb_height - 10,
|
||||||
|
dark_color, light_color, thickness);
|
||||||
|
rgui_fill_rect(data, fb_width, fb_height,
|
||||||
|
fb_width - 10, 5, 5, fb_height - 10,
|
||||||
|
dark_color, light_color, thickness);
|
||||||
|
|
||||||
/* Draw drop shadow, if required */
|
/* Draw drop shadow, if required */
|
||||||
if (rgui->shadow_enable)
|
if (rgui->shadow_enable)
|
||||||
{
|
{
|
||||||
rgui_color_rect(data, fb_pitch, fb_width, fb_height,
|
uint16_t shadow_color = rgui->colors.shadow_color;
|
||||||
10, 10, 1, fb_height - 20, rgui->colors.shadow_color);
|
|
||||||
rgui_color_rect(data, fb_pitch, fb_width, fb_height,
|
rgui_color_rect(data, fb_width, fb_height,
|
||||||
10, 10, fb_width - 20, 1, rgui->colors.shadow_color);
|
10, 10, 1, fb_height - 20, shadow_color);
|
||||||
rgui_color_rect(data, fb_pitch, fb_width, fb_height,
|
rgui_color_rect(data, fb_width, fb_height,
|
||||||
fb_width - 5, 6, 1, fb_height - 10, rgui->colors.shadow_color);
|
10, 10, fb_width - 20, 1, shadow_color);
|
||||||
rgui_color_rect(data, fb_pitch, fb_width, fb_height,
|
rgui_color_rect(data, fb_width, fb_height,
|
||||||
6, fb_height - 5, fb_width - 10, 1, rgui->colors.shadow_color);
|
fb_width - 5, 6, 1, fb_height - 10, shadow_color);
|
||||||
|
rgui_color_rect(data, fb_width, fb_height,
|
||||||
|
6, fb_height - 5, fb_width - 10, 1, shadow_color);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1025,9 +1165,12 @@ static bool INLINE rgui_draw_particle(
|
|||||||
y_end = y_end > 0 ? y_end : 0;
|
y_end = y_end > 0 ? y_end : 0;
|
||||||
y_end = y_end <= fb_height ? y_end : fb_height;
|
y_end = y_end <= fb_height ? y_end : fb_height;
|
||||||
|
|
||||||
for (x_index = (unsigned)x_start; x_index < (unsigned)x_end; x_index++)
|
|
||||||
for (y_index = (unsigned)y_start; y_index < (unsigned)y_end; y_index++)
|
for (y_index = (unsigned)y_start; y_index < (unsigned)y_end; y_index++)
|
||||||
data[(y_index * fb_width) + x_index] = color;
|
{
|
||||||
|
uint16_t *data_ptr = data + (y_index * fb_width);
|
||||||
|
for (x_index = (unsigned)x_start; x_index < (unsigned)x_end; x_index++)
|
||||||
|
*(data_ptr + x_index) = color;
|
||||||
|
}
|
||||||
|
|
||||||
return (x_end > x_start) && (y_end > y_start);
|
return (x_end > x_start) && (y_end > y_start);
|
||||||
}
|
}
|
||||||
@ -1072,7 +1215,7 @@ static void rgui_init_particle_effect(rgui_t *rgui)
|
|||||||
8, 8, 8,
|
8, 8, 8,
|
||||||
9, 9,
|
9, 9,
|
||||||
10};
|
10};
|
||||||
unsigned num_drops = (unsigned)(0.85f * ((float)fb_width / 426.0f) * (float)NUM_PARTICLES);
|
unsigned num_drops = (unsigned)(0.85f * ((float)fb_width / (float)MAX_FB_WIDTH) * (float)NUM_PARTICLES);
|
||||||
|
|
||||||
num_drops = num_drops < NUM_PARTICLES ? num_drops : NUM_PARTICLES;
|
num_drops = num_drops < NUM_PARTICLES ? num_drops : NUM_PARTICLES;
|
||||||
|
|
||||||
@ -1232,7 +1375,7 @@ static void rgui_render_particle_effect(rgui_t *rgui)
|
|||||||
8, 8, 8,
|
8, 8, 8,
|
||||||
9, 9,
|
9, 9,
|
||||||
10};
|
10};
|
||||||
unsigned num_drops = (unsigned)(0.85f * ((float)fb_width / 426.0f) * (float)NUM_PARTICLES);
|
unsigned num_drops = (unsigned)(0.85f * ((float)fb_width / (float)MAX_FB_WIDTH) * (float)NUM_PARTICLES);
|
||||||
bool on_screen;
|
bool on_screen;
|
||||||
|
|
||||||
num_drops = num_drops < NUM_PARTICLES ? num_drops : NUM_PARTICLES;
|
num_drops = num_drops < NUM_PARTICLES ? num_drops : NUM_PARTICLES;
|
||||||
@ -1382,7 +1525,7 @@ static void rgui_render_particle_effect(rgui_t *rgui)
|
|||||||
* particle effect
|
* particle effect
|
||||||
* (Wastes CPU cycles, but nothing we can do about it...) */
|
* (Wastes CPU cycles, but nothing we can do about it...) */
|
||||||
if (rgui->border_enable && !rgui->show_wallpaper)
|
if (rgui->border_enable && !rgui->show_wallpaper)
|
||||||
rgui_render_border(rgui, rgui_frame_buf.data, fb_pitch, fb_width, fb_height);
|
rgui_render_border(rgui, rgui_frame_buf.data, fb_width, fb_height);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void request_wallpaper(const char *path)
|
static void request_wallpaper(const char *path)
|
||||||
@ -1755,12 +1898,7 @@ static void rgui_render_fs_thumbnail(rgui_t *rgui)
|
|||||||
shadow_x = fb_x_offset + fs_thumbnail.width;
|
shadow_x = fb_x_offset + fs_thumbnail.width;
|
||||||
shadow_y = fb_y_offset + 2;
|
shadow_y = fb_y_offset + 2;
|
||||||
|
|
||||||
/* Super paranoid safety check...
|
rgui_color_rect(rgui_frame_buf.data, fb_width, fb_height,
|
||||||
* (This is not required at all, but terrible things
|
|
||||||
* will happen if we ever go out of bounds...) */
|
|
||||||
if (((shadow_x + shadow_width) <= fb_width) &&
|
|
||||||
((shadow_y + shadow_height) <= fb_height))
|
|
||||||
rgui_color_rect(rgui_frame_buf.data, fb_pitch, fb_width, fb_height,
|
|
||||||
shadow_x, shadow_y, shadow_width, shadow_height, rgui->colors.shadow_color);
|
shadow_x, shadow_y, shadow_width, shadow_height, rgui->colors.shadow_color);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1774,12 +1912,7 @@ static void rgui_render_fs_thumbnail(rgui_t *rgui)
|
|||||||
shadow_x = fb_x_offset + 2;
|
shadow_x = fb_x_offset + 2;
|
||||||
shadow_y = fb_y_offset + fs_thumbnail.height;
|
shadow_y = fb_y_offset + fs_thumbnail.height;
|
||||||
|
|
||||||
/* Super paranoid safety check...
|
rgui_color_rect(rgui_frame_buf.data, fb_width, fb_height,
|
||||||
* (This is not required at all, but terrible things
|
|
||||||
* will happen if we ever go out of bounds...) */
|
|
||||||
if (((shadow_x + shadow_width) <= fb_width) &&
|
|
||||||
((shadow_y + shadow_height) <= fb_height))
|
|
||||||
rgui_color_rect(rgui_frame_buf.data, fb_pitch, fb_width, fb_height,
|
|
||||||
shadow_x, shadow_y, shadow_width, shadow_height, rgui->colors.shadow_color);
|
shadow_x, shadow_y, shadow_width, shadow_height, rgui->colors.shadow_color);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1847,9 +1980,9 @@ static void rgui_render_mini_thumbnail(rgui_t *rgui, thumbnail_t *thumbnail, enu
|
|||||||
/* Draw drop shadow, if required */
|
/* Draw drop shadow, if required */
|
||||||
if (rgui->shadow_enable)
|
if (rgui->shadow_enable)
|
||||||
{
|
{
|
||||||
rgui_color_rect(rgui_frame_buf.data, fb_pitch, fb_width, fb_height,
|
rgui_color_rect(rgui_frame_buf.data, fb_width, fb_height,
|
||||||
fb_x_offset + thumbnail->width, fb_y_offset + 1, 1, thumbnail->height, rgui->colors.shadow_color);
|
fb_x_offset + thumbnail->width, fb_y_offset + 1, 1, thumbnail->height, rgui->colors.shadow_color);
|
||||||
rgui_color_rect(rgui_frame_buf.data, fb_pitch, fb_width, fb_height,
|
rgui_color_rect(rgui_frame_buf.data, fb_width, fb_height,
|
||||||
fb_x_offset + 1, fb_y_offset + thumbnail->height, thumbnail->width, 1, rgui->colors.shadow_color);
|
fb_x_offset + 1, fb_y_offset + thumbnail->height, thumbnail->width, 1, rgui->colors.shadow_color);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -2067,8 +2200,7 @@ static void rgui_cache_background(rgui_t *rgui)
|
|||||||
if (rgui->show_wallpaper)
|
if (rgui->show_wallpaper)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
menu_display_get_fb_size(&fb_width, &fb_height,
|
menu_display_get_fb_size(&fb_width, &fb_height, &fb_pitch);
|
||||||
&fb_pitch);
|
|
||||||
|
|
||||||
/* Sanity check */
|
/* Sanity check */
|
||||||
if ((fb_width != rgui_background_buf.width) ||
|
if ((fb_width != rgui_background_buf.width) ||
|
||||||
@ -2077,24 +2209,14 @@ static void rgui_cache_background(rgui_t *rgui)
|
|||||||
!rgui_background_buf.data)
|
!rgui_background_buf.data)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
/* Fill last 4 lines of background buffer with standard
|
/* Fill background buffer with standard chequer pattern */
|
||||||
* chequer pattern */
|
rgui_fill_rect(rgui_background_buf.data, fb_width, fb_height,
|
||||||
rgui_fill_rect(rgui, rgui_background_buf.data, fb_pitch, 0, fb_height, fb_width, 4, rgui_bg_filler);
|
0, 0, fb_width, fb_height,
|
||||||
|
rgui->colors.bg_dark_color, rgui->colors.bg_light_color, rgui->bg_thickness);
|
||||||
/* Copy chequer pattern to rest of background buffer */
|
|
||||||
pitch_in_pixels = fb_pitch >> 1;
|
|
||||||
size = fb_pitch * 4;
|
|
||||||
src = rgui_background_buf.data + pitch_in_pixels * fb_height;
|
|
||||||
dst = rgui_background_buf.data;
|
|
||||||
|
|
||||||
while (dst < src)
|
|
||||||
{
|
|
||||||
memcpy(dst, src, size);
|
|
||||||
dst += pitch_in_pixels * 4;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
/* Draw border, if required */
|
||||||
if (rgui->border_enable)
|
if (rgui->border_enable)
|
||||||
rgui_render_border(rgui, rgui_background_buf.data, fb_pitch, fb_width, fb_height);
|
rgui_render_border(rgui, rgui_background_buf.data, fb_width, fb_height);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void prepare_rgui_colors(rgui_t *rgui, settings_t *settings)
|
static void prepare_rgui_colors(rgui_t *rgui, settings_t *settings)
|
||||||
@ -2548,7 +2670,13 @@ static void rgui_render_messagebox(rgui_t *rgui, const char *message)
|
|||||||
|
|
||||||
if (rgui_frame_buf.data)
|
if (rgui_frame_buf.data)
|
||||||
{
|
{
|
||||||
rgui_fill_rect(rgui, rgui_frame_buf.data, fb_pitch, x + 5, y + 5, width - 10, height - 10, rgui_bg_filler);
|
uint16_t border_dark_color = rgui->colors.border_dark_color;
|
||||||
|
uint16_t border_light_color = rgui->colors.border_light_color;
|
||||||
|
bool border_thickness = rgui->border_thickness;
|
||||||
|
|
||||||
|
rgui_fill_rect(rgui_frame_buf.data, fb_width, fb_height,
|
||||||
|
x + 5, y + 5, width - 10, height - 10,
|
||||||
|
rgui->colors.bg_dark_color, rgui->colors.bg_light_color, rgui->bg_thickness);
|
||||||
|
|
||||||
/* Note: We draw borders around message boxes regardless
|
/* Note: We draw borders around message boxes regardless
|
||||||
* of the rgui->border_enable setting, because they look
|
* of the rgui->border_enable setting, because they look
|
||||||
@ -2557,21 +2685,31 @@ static void rgui_render_messagebox(rgui_t *rgui, const char *message)
|
|||||||
/* Draw drop shadow, if required */
|
/* Draw drop shadow, if required */
|
||||||
if (rgui->shadow_enable)
|
if (rgui->shadow_enable)
|
||||||
{
|
{
|
||||||
rgui_color_rect(rgui_frame_buf.data, fb_pitch, fb_width, fb_height,
|
uint16_t shadow_color = rgui->colors.shadow_color;
|
||||||
x + 5, y + 5, 1, height - 5, rgui->colors.shadow_color);
|
|
||||||
rgui_color_rect(rgui_frame_buf.data, fb_pitch, fb_width, fb_height,
|
rgui_color_rect(rgui_frame_buf.data, fb_width, fb_height,
|
||||||
x + 5, y + 5, width - 5, 1, rgui->colors.shadow_color);
|
x + 5, y + 5, 1, height - 5, shadow_color);
|
||||||
rgui_color_rect(rgui_frame_buf.data, fb_pitch, fb_width, fb_height,
|
rgui_color_rect(rgui_frame_buf.data, fb_width, fb_height,
|
||||||
x + width, y + 1, 1, height, rgui->colors.shadow_color);
|
x + 5, y + 5, width - 5, 1, shadow_color);
|
||||||
rgui_color_rect(rgui_frame_buf.data, fb_pitch, fb_width, fb_height,
|
rgui_color_rect(rgui_frame_buf.data, fb_width, fb_height,
|
||||||
x + 1, y + height, width, 1, rgui->colors.shadow_color);
|
x + width, y + 1, 1, height, shadow_color);
|
||||||
|
rgui_color_rect(rgui_frame_buf.data, fb_width, fb_height,
|
||||||
|
x + 1, y + height, width, 1, shadow_color);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Draw border */
|
/* Draw border */
|
||||||
rgui_fill_rect(rgui, rgui_frame_buf.data, fb_pitch, x, y, width - 5, 5, rgui_border_filler);
|
rgui_fill_rect(rgui_frame_buf.data, fb_width, fb_height,
|
||||||
rgui_fill_rect(rgui, rgui_frame_buf.data, fb_pitch, x + width - 5, y, 5, height - 5, rgui_border_filler);
|
x, y, width - 5, 5,
|
||||||
rgui_fill_rect(rgui, rgui_frame_buf.data, fb_pitch, x + 5, y + height - 5, width - 5, 5, rgui_border_filler);
|
border_dark_color, border_light_color, border_thickness);
|
||||||
rgui_fill_rect(rgui, rgui_frame_buf.data, fb_pitch, x, y + 5, 5, height - 5, rgui_border_filler);
|
rgui_fill_rect(rgui_frame_buf.data, fb_width, fb_height,
|
||||||
|
x + width - 5, y, 5, height - 5,
|
||||||
|
border_dark_color, border_light_color, border_thickness);
|
||||||
|
rgui_fill_rect(rgui_frame_buf.data, fb_width, fb_height,
|
||||||
|
x + 5, y + height - 5, width - 5, 5,
|
||||||
|
border_dark_color, border_light_color, border_thickness);
|
||||||
|
rgui_fill_rect(rgui_frame_buf.data, fb_width, fb_height,
|
||||||
|
x, y + 5, 5, height - 5,
|
||||||
|
border_dark_color, border_light_color, border_thickness);
|
||||||
}
|
}
|
||||||
|
|
||||||
for (i = 0; i < list->size; i++)
|
for (i = 0; i < list->size; i++)
|
||||||
@ -2601,8 +2739,8 @@ static void rgui_blit_cursor(void)
|
|||||||
|
|
||||||
if (rgui_frame_buf.data)
|
if (rgui_frame_buf.data)
|
||||||
{
|
{
|
||||||
rgui_color_rect(rgui_frame_buf.data, fb_pitch, fb_width, fb_height, x, y - 5, 1, 11, 0xFFFF);
|
rgui_color_rect(rgui_frame_buf.data, fb_width, fb_height, x, y - 5, 1, 11, 0xFFFF);
|
||||||
rgui_color_rect(rgui_frame_buf.data, fb_pitch, fb_width, fb_height, x - 5, y, 11, 1, 0xFFFF);
|
rgui_color_rect(rgui_frame_buf.data, fb_width, fb_height, x - 5, y, 11, 1, 0xFFFF);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2676,41 +2814,53 @@ static void rgui_render_osk(rgui_t *rgui, menu_animation_ctx_ticker_t *ticker)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Draw background */
|
/* Draw background */
|
||||||
rgui_fill_rect(rgui, rgui_frame_buf.data, fb_pitch,
|
rgui_fill_rect(rgui_frame_buf.data, fb_width, fb_height,
|
||||||
osk_x + 5, osk_y + 5, osk_width - 10, osk_height - 10, rgui_bg_filler);
|
osk_x + 5, osk_y + 5, osk_width - 10, osk_height - 10,
|
||||||
|
rgui->colors.bg_dark_color, rgui->colors.bg_light_color, rgui->bg_thickness);
|
||||||
|
|
||||||
/* Draw border */
|
/* Draw border */
|
||||||
if (rgui->border_enable)
|
if (rgui->border_enable)
|
||||||
{
|
{
|
||||||
|
uint16_t border_dark_color = rgui->colors.border_dark_color;
|
||||||
|
uint16_t border_light_color = rgui->colors.border_light_color;
|
||||||
|
bool border_thickness = rgui->border_thickness;
|
||||||
|
|
||||||
/* Draw drop shadow, if required */
|
/* Draw drop shadow, if required */
|
||||||
if (rgui->shadow_enable)
|
if (rgui->shadow_enable)
|
||||||
{
|
{
|
||||||
|
uint16_t shadow_color = rgui->colors.shadow_color;
|
||||||
|
|
||||||
/* Frame */
|
/* Frame */
|
||||||
rgui_color_rect(rgui_frame_buf.data, fb_pitch, fb_width, fb_height,
|
rgui_color_rect(rgui_frame_buf.data, fb_width, fb_height,
|
||||||
osk_x + 5, osk_y + 5, osk_width - 10, 1, rgui->colors.shadow_color);
|
osk_x + 5, osk_y + 5, osk_width - 10, 1, shadow_color);
|
||||||
rgui_color_rect(rgui_frame_buf.data, fb_pitch, fb_width, fb_height,
|
rgui_color_rect(rgui_frame_buf.data, fb_width, fb_height,
|
||||||
osk_x + osk_width, osk_y + 1, 1, osk_height, rgui->colors.shadow_color);
|
osk_x + osk_width, osk_y + 1, 1, osk_height, shadow_color);
|
||||||
rgui_color_rect(rgui_frame_buf.data, fb_pitch, fb_width, fb_height,
|
rgui_color_rect(rgui_frame_buf.data, fb_width, fb_height,
|
||||||
osk_x + 1, osk_y + osk_height, osk_width, 1, rgui->colors.shadow_color);
|
osk_x + 1, osk_y + osk_height, osk_width, 1, shadow_color);
|
||||||
rgui_color_rect(rgui_frame_buf.data, fb_pitch, fb_width, fb_height,
|
rgui_color_rect(rgui_frame_buf.data, fb_width, fb_height,
|
||||||
osk_x + 5, osk_y + 5, 1, osk_height - 10, rgui->colors.shadow_color);
|
osk_x + 5, osk_y + 5, 1, osk_height - 10, shadow_color);
|
||||||
/* Divider */
|
/* Divider */
|
||||||
rgui_color_rect(rgui_frame_buf.data, fb_pitch, fb_width, fb_height,
|
rgui_color_rect(rgui_frame_buf.data, fb_width, fb_height,
|
||||||
osk_x + 5, osk_y + keyboard_offset_y - 5, osk_width - 10, 1, rgui->colors.shadow_color);
|
osk_x + 5, osk_y + keyboard_offset_y - 5, osk_width - 10, 1, shadow_color);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Frame */
|
/* Frame */
|
||||||
rgui_fill_rect(rgui, rgui_frame_buf.data, fb_pitch,
|
rgui_fill_rect(rgui_frame_buf.data, fb_width, fb_height,
|
||||||
osk_x, osk_y, osk_width - 5, 5, rgui_border_filler);
|
osk_x, osk_y, osk_width - 5, 5,
|
||||||
rgui_fill_rect(rgui, rgui_frame_buf.data, fb_pitch,
|
border_dark_color, border_light_color, border_thickness);
|
||||||
osk_x + osk_width - 5, osk_y, 5, osk_height - 5, rgui_border_filler);
|
rgui_fill_rect(rgui_frame_buf.data, fb_width, fb_height,
|
||||||
rgui_fill_rect(rgui, rgui_frame_buf.data, fb_pitch,
|
osk_x + osk_width - 5, osk_y, 5, osk_height - 5,
|
||||||
osk_x + 5, osk_y + osk_height - 5, osk_width - 5, 5, rgui_border_filler);
|
border_dark_color, border_light_color, border_thickness);
|
||||||
rgui_fill_rect(rgui, rgui_frame_buf.data, fb_pitch,
|
rgui_fill_rect(rgui_frame_buf.data, fb_width, fb_height,
|
||||||
osk_x, osk_y + 5, 5, osk_height - 5, rgui_border_filler);
|
osk_x + 5, osk_y + osk_height - 5, osk_width - 5, 5,
|
||||||
|
border_dark_color, border_light_color, border_thickness);
|
||||||
|
rgui_fill_rect(rgui_frame_buf.data, fb_width, fb_height,
|
||||||
|
osk_x, osk_y + 5, 5, osk_height - 5,
|
||||||
|
border_dark_color, border_light_color, border_thickness);
|
||||||
/* Divider */
|
/* Divider */
|
||||||
rgui_fill_rect(rgui, rgui_frame_buf.data, fb_pitch,
|
rgui_fill_rect(rgui_frame_buf.data, fb_width, fb_height,
|
||||||
osk_x + 5, osk_y + keyboard_offset_y - 10, osk_width - 10, 5, rgui_border_filler);
|
osk_x + 5, osk_y + keyboard_offset_y - 10, osk_width - 10, 5,
|
||||||
|
border_dark_color, border_light_color, border_thickness);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Draw input label text */
|
/* Draw input label text */
|
||||||
@ -2827,24 +2977,24 @@ static void rgui_render_osk(rgui_t *rgui, menu_animation_ctx_ticker_t *ticker)
|
|||||||
/* Draw drop shadow, if required */
|
/* Draw drop shadow, if required */
|
||||||
if (rgui->shadow_enable)
|
if (rgui->shadow_enable)
|
||||||
{
|
{
|
||||||
rgui_color_rect(rgui_frame_buf.data, fb_pitch, fb_width, fb_height,
|
rgui_color_rect(rgui_frame_buf.data, fb_width, fb_height,
|
||||||
osk_ptr_x + 1, osk_ptr_y + 1, 1, ptr_height, rgui->colors.shadow_color);
|
osk_ptr_x + 1, osk_ptr_y + 1, 1, ptr_height, rgui->colors.shadow_color);
|
||||||
rgui_color_rect(rgui_frame_buf.data, fb_pitch, fb_width, fb_height,
|
rgui_color_rect(rgui_frame_buf.data, fb_width, fb_height,
|
||||||
osk_ptr_x + 1, osk_ptr_y + 1, ptr_width, 1, rgui->colors.shadow_color);
|
osk_ptr_x + 1, osk_ptr_y + 1, ptr_width, 1, rgui->colors.shadow_color);
|
||||||
rgui_color_rect(rgui_frame_buf.data, fb_pitch, fb_width, fb_height,
|
rgui_color_rect(rgui_frame_buf.data, fb_width, fb_height,
|
||||||
osk_ptr_x + ptr_width, osk_ptr_y + 1, 1, ptr_height, rgui->colors.shadow_color);
|
osk_ptr_x + ptr_width, osk_ptr_y + 1, 1, ptr_height, rgui->colors.shadow_color);
|
||||||
rgui_color_rect(rgui_frame_buf.data, fb_pitch, fb_width, fb_height,
|
rgui_color_rect(rgui_frame_buf.data, fb_width, fb_height,
|
||||||
osk_ptr_x + 1, osk_ptr_y + ptr_height, ptr_width, 1, rgui->colors.shadow_color);
|
osk_ptr_x + 1, osk_ptr_y + ptr_height, ptr_width, 1, rgui->colors.shadow_color);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Draw selection rectangle */
|
/* Draw selection rectangle */
|
||||||
rgui_color_rect(rgui_frame_buf.data, fb_pitch, fb_width, fb_height,
|
rgui_color_rect(rgui_frame_buf.data, fb_width, fb_height,
|
||||||
osk_ptr_x, osk_ptr_y, 1, ptr_height, rgui->colors.hover_color);
|
osk_ptr_x, osk_ptr_y, 1, ptr_height, rgui->colors.hover_color);
|
||||||
rgui_color_rect(rgui_frame_buf.data, fb_pitch, fb_width, fb_height,
|
rgui_color_rect(rgui_frame_buf.data, fb_width, fb_height,
|
||||||
osk_ptr_x, osk_ptr_y, ptr_width, 1, rgui->colors.hover_color);
|
osk_ptr_x, osk_ptr_y, ptr_width, 1, rgui->colors.hover_color);
|
||||||
rgui_color_rect(rgui_frame_buf.data, fb_pitch, fb_width, fb_height,
|
rgui_color_rect(rgui_frame_buf.data, fb_width, fb_height,
|
||||||
osk_ptr_x + ptr_width - 1, osk_ptr_y, 1, ptr_height, rgui->colors.hover_color);
|
osk_ptr_x + ptr_width - 1, osk_ptr_y, 1, ptr_height, rgui->colors.hover_color);
|
||||||
rgui_color_rect(rgui_frame_buf.data, fb_pitch, fb_width, fb_height,
|
rgui_color_rect(rgui_frame_buf.data, fb_width, fb_height,
|
||||||
osk_ptr_x, osk_ptr_y + ptr_height - 1, ptr_width, 1, rgui->colors.hover_color);
|
osk_ptr_x, osk_ptr_y + ptr_height - 1, ptr_width, 1, rgui->colors.hover_color);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -3026,8 +3176,9 @@ static void rgui_render(void *data, bool is_idle)
|
|||||||
title_x = RGUI_TERM_START_X(fb_width) + ((RGUI_TERM_WIDTH(fb_width) * FONT_WIDTH_STRIDE) - title_width) / 2;
|
title_x = RGUI_TERM_START_X(fb_width) + ((RGUI_TERM_WIDTH(fb_width) * FONT_WIDTH_STRIDE) - title_width) / 2;
|
||||||
|
|
||||||
/* Draw thumbnail title background */
|
/* Draw thumbnail title background */
|
||||||
rgui_fill_rect(rgui, rgui_frame_buf.data, fb_pitch,
|
rgui_fill_rect(rgui_frame_buf.data, fb_width, fb_height,
|
||||||
title_x - 5, 0, title_width + 10, FONT_HEIGHT_STRIDE, rgui_bg_filler);
|
title_x - 5, 0, title_width + 10, FONT_HEIGHT_STRIDE,
|
||||||
|
rgui->colors.bg_dark_color, rgui->colors.bg_light_color, rgui->bg_thickness);
|
||||||
|
|
||||||
/* Draw thumbnail title */
|
/* Draw thumbnail title */
|
||||||
blit_line((int)title_x, 0, thumbnail_title_buf,
|
blit_line((int)title_x, 0, thumbnail_title_buf,
|
||||||
@ -3177,21 +3328,19 @@ static void rgui_render(void *data, bool is_idle)
|
|||||||
for (i = new_start; i < end; i++, y += FONT_HEIGHT_STRIDE)
|
for (i = new_start; i < end; i++, y += FONT_HEIGHT_STRIDE)
|
||||||
{
|
{
|
||||||
char entry_value[255];
|
char entry_value[255];
|
||||||
char message[255];
|
|
||||||
char entry_title_buf[255];
|
char entry_title_buf[255];
|
||||||
char type_str_buf[255];
|
char type_str_buf[255];
|
||||||
menu_entry_t entry;
|
menu_entry_t entry;
|
||||||
size_t entry_title_max_len = 0;
|
size_t entry_title_max_len = 0;
|
||||||
size_t entry_title_buf_utf8len = 0;
|
|
||||||
size_t entry_title_buf_len = 0;
|
|
||||||
unsigned entry_value_len = 0;
|
unsigned entry_value_len = 0;
|
||||||
bool entry_selected = (i == selection);
|
bool entry_selected = (i == selection);
|
||||||
|
uint16_t entry_color = entry_selected ?
|
||||||
|
rgui->colors.hover_color : rgui->colors.normal_color;
|
||||||
|
|
||||||
if (i > (selection + 100))
|
if (i > (selection + 100))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
entry_value[0] = '\0';
|
entry_value[0] = '\0';
|
||||||
message[0] = '\0';
|
|
||||||
entry_title_buf[0] = '\0';
|
entry_title_buf[0] = '\0';
|
||||||
type_str_buf[0] = '\0';
|
type_str_buf[0] = '\0';
|
||||||
|
|
||||||
@ -3272,9 +3421,12 @@ static void rgui_render(void *data, bool is_idle)
|
|||||||
|
|
||||||
menu_animation_ticker(&ticker);
|
menu_animation_ticker(&ticker);
|
||||||
|
|
||||||
entry_title_buf_utf8len = utf8len(entry_title_buf);
|
/* Print entry title */
|
||||||
entry_title_buf_len = strlen(entry_title_buf);
|
blit_line(x + (2 * FONT_WIDTH_STRIDE), y,
|
||||||
|
entry_title_buf,
|
||||||
|
entry_color, rgui->colors.shadow_color);
|
||||||
|
|
||||||
|
/* Print entry value, if required */
|
||||||
if (entry_value_len > 0)
|
if (entry_value_len > 0)
|
||||||
{
|
{
|
||||||
/* Format entry value string */
|
/* Format entry value string */
|
||||||
@ -3284,28 +3436,16 @@ static void rgui_render(void *data, bool is_idle)
|
|||||||
|
|
||||||
menu_animation_ticker(&ticker);
|
menu_animation_ticker(&ticker);
|
||||||
|
|
||||||
/* Print entry title + value */
|
/* Print entry value */
|
||||||
snprintf(message, sizeof(message), "%c %-*.*s %-.*s",
|
blit_line(term_end_x - ((entry_value_len + 1) * FONT_WIDTH_STRIDE), y,
|
||||||
entry_selected ? '>' : ' ',
|
type_str_buf,
|
||||||
(int)(entry_title_max_len - entry_title_buf_utf8len + entry_title_buf_len),
|
entry_color, rgui->colors.shadow_color);
|
||||||
(int)(entry_title_max_len - entry_title_buf_utf8len + entry_title_buf_len),
|
|
||||||
entry_title_buf,
|
|
||||||
entry_value_len,
|
|
||||||
type_str_buf);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
/* No value - just print entry title */
|
|
||||||
snprintf(message, sizeof(message), "%c %-*.*s",
|
|
||||||
entry_selected ? '>' : ' ',
|
|
||||||
(int)(entry_title_max_len - entry_title_buf_utf8len + entry_title_buf_len),
|
|
||||||
(int)(entry_title_max_len - entry_title_buf_utf8len + entry_title_buf_len),
|
|
||||||
entry_title_buf);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
blit_line(x, y, message,
|
/* Print selection marker, if required */
|
||||||
entry_selected ? rgui->colors.hover_color : rgui->colors.normal_color,
|
if (entry_selected)
|
||||||
rgui->colors.shadow_color);
|
blit_line(x, y, ">",
|
||||||
|
entry_color, rgui->colors.shadow_color);
|
||||||
|
|
||||||
menu_entry_free(&entry);
|
menu_entry_free(&entry);
|
||||||
}
|
}
|
||||||
@ -3649,12 +3789,11 @@ static bool rgui_set_aspect_ratio(rgui_t *rgui, bool delay_update)
|
|||||||
rgui_term_layout.start_x = (rgui_frame_buf.width - (rgui_term_layout.width * FONT_WIDTH_STRIDE)) / 2;
|
rgui_term_layout.start_x = (rgui_frame_buf.width - (rgui_term_layout.width * FONT_WIDTH_STRIDE)) / 2;
|
||||||
rgui_term_layout.start_y = (rgui_frame_buf.height - (rgui_term_layout.height * FONT_HEIGHT_STRIDE)) / 2;
|
rgui_term_layout.start_y = (rgui_frame_buf.height - (rgui_term_layout.height * FONT_HEIGHT_STRIDE)) / 2;
|
||||||
|
|
||||||
/* Allocate background buffer
|
/* Allocate background buffer */
|
||||||
* (4 extra lines to store a copy of the chequered background) */
|
|
||||||
rgui_background_buf.width = rgui_frame_buf.width;
|
rgui_background_buf.width = rgui_frame_buf.width;
|
||||||
rgui_background_buf.height = rgui_frame_buf.height;
|
rgui_background_buf.height = rgui_frame_buf.height;
|
||||||
rgui_background_buf.data = (uint16_t*)calloc(
|
rgui_background_buf.data = (uint16_t*)calloc(
|
||||||
rgui_background_buf.width * (rgui_background_buf.height + 4), sizeof(uint16_t));
|
rgui_background_buf.width * rgui_background_buf.height, sizeof(uint16_t));
|
||||||
|
|
||||||
if (!rgui_background_buf.data)
|
if (!rgui_background_buf.data)
|
||||||
return false;
|
return false;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user