|
|
|
@ -80,6 +80,12 @@
|
|
|
|
|
#define NUM_FONT_GLYPHS_REGULAR 128
|
|
|
|
|
#define NUM_FONT_GLYPHS_EXTENDED 256
|
|
|
|
|
|
|
|
|
|
#define NUM_PARTICLES 256
|
|
|
|
|
|
|
|
|
|
#ifndef PI
|
|
|
|
|
#define PI 3.14159265359f
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
typedef struct
|
|
|
|
|
{
|
|
|
|
|
unsigned start_x;
|
|
|
|
@ -101,6 +107,7 @@ typedef struct
|
|
|
|
|
uint32_t border_dark_color;
|
|
|
|
|
uint32_t border_light_color;
|
|
|
|
|
uint32_t shadow_color;
|
|
|
|
|
uint32_t particle_color;
|
|
|
|
|
} rgui_theme_t;
|
|
|
|
|
|
|
|
|
|
static const rgui_theme_t rgui_theme_classic_red = {
|
|
|
|
@ -111,7 +118,8 @@ static const rgui_theme_t rgui_theme_classic_red = {
|
|
|
|
|
0xC0404040, /* bg_light_color */
|
|
|
|
|
0xC08C0000, /* border_dark_color */
|
|
|
|
|
0xC0CC0E03, /* border_light_color */
|
|
|
|
|
0xC0000000 /* shadow_color */
|
|
|
|
|
0xC0000000, /* shadow_color */
|
|
|
|
|
0xC09E8686 /* particle_color */
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
static const rgui_theme_t rgui_theme_classic_orange = {
|
|
|
|
@ -122,7 +130,8 @@ static const rgui_theme_t rgui_theme_classic_orange = {
|
|
|
|
|
0xC0404040, /* bg_light_color */
|
|
|
|
|
0xC0962800, /* border_dark_color */
|
|
|
|
|
0xC0E46C03, /* border_light_color */
|
|
|
|
|
0xC0000000 /* shadow_color */
|
|
|
|
|
0xC0000000, /* shadow_color */
|
|
|
|
|
0xC09E9286 /* particle_color */
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
static const rgui_theme_t rgui_theme_classic_yellow = {
|
|
|
|
@ -133,7 +142,8 @@ static const rgui_theme_t rgui_theme_classic_yellow = {
|
|
|
|
|
0xC0404040, /* bg_light_color */
|
|
|
|
|
0xC0AC7800, /* border_dark_color */
|
|
|
|
|
0xC0F3C60D, /* border_light_color */
|
|
|
|
|
0xC0000000 /* shadow_color */
|
|
|
|
|
0xC0000000, /* shadow_color */
|
|
|
|
|
0xC0999581 /* particle_color */
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
static const rgui_theme_t rgui_theme_classic_green = {
|
|
|
|
@ -144,7 +154,8 @@ static const rgui_theme_t rgui_theme_classic_green = {
|
|
|
|
|
0xC0404040, /* bg_light_color */
|
|
|
|
|
0xC0204020, /* border_dark_color */
|
|
|
|
|
0xC0408040, /* border_light_color */
|
|
|
|
|
0xC0000000 /* shadow_color */
|
|
|
|
|
0xC0000000, /* shadow_color */
|
|
|
|
|
0xC0879E87 /* particle_color */
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
static const rgui_theme_t rgui_theme_classic_blue = {
|
|
|
|
@ -155,7 +166,8 @@ static const rgui_theme_t rgui_theme_classic_blue = {
|
|
|
|
|
0xC0404040, /* bg_light_color */
|
|
|
|
|
0xC0005BA6, /* border_dark_color */
|
|
|
|
|
0xC02E94E2, /* border_light_color */
|
|
|
|
|
0xC0000000 /* shadow_color */
|
|
|
|
|
0xC0000000, /* shadow_color */
|
|
|
|
|
0xC086949E /* particle_color */
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
static const rgui_theme_t rgui_theme_classic_violet = {
|
|
|
|
@ -166,7 +178,8 @@ static const rgui_theme_t rgui_theme_classic_violet = {
|
|
|
|
|
0xC0404040, /* bg_light_color */
|
|
|
|
|
0xC04C0A60, /* border_dark_color */
|
|
|
|
|
0xC0842DCE, /* border_light_color */
|
|
|
|
|
0xC0000000 /* shadow_color */
|
|
|
|
|
0xC0000000, /* shadow_color */
|
|
|
|
|
0xC08E8299 /* particle_color */
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
static const rgui_theme_t rgui_theme_classic_grey = {
|
|
|
|
@ -177,7 +190,8 @@ static const rgui_theme_t rgui_theme_classic_grey = {
|
|
|
|
|
0xC0404040, /* bg_light_color */
|
|
|
|
|
0xC0505050, /* border_dark_color */
|
|
|
|
|
0xC0798A99, /* border_light_color */
|
|
|
|
|
0xC0000000 /* shadow_color */
|
|
|
|
|
0xC0000000, /* shadow_color */
|
|
|
|
|
0xC078828A /* particle_color */
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
static const rgui_theme_t rgui_theme_legacy_red = {
|
|
|
|
@ -188,7 +202,8 @@ static const rgui_theme_t rgui_theme_legacy_red = {
|
|
|
|
|
0xC0B34B41, /* bg_light_color */
|
|
|
|
|
0xC0BF5E58, /* border_dark_color */
|
|
|
|
|
0xC0F27A6F, /* border_light_color */
|
|
|
|
|
0xC01F0C0A /* shadow_color */
|
|
|
|
|
0xC01F0C0A, /* shadow_color */
|
|
|
|
|
0xC0F75431 /* particle_color */
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
static const rgui_theme_t rgui_theme_dark_purple = {
|
|
|
|
@ -199,7 +214,8 @@ static const rgui_theme_t rgui_theme_dark_purple = {
|
|
|
|
|
0xC0663A66, /* bg_light_color */
|
|
|
|
|
0xC0885783, /* border_dark_color */
|
|
|
|
|
0xC0A675A1, /* border_light_color */
|
|
|
|
|
0xC0140A14 /* shadow_color */
|
|
|
|
|
0xC0140A14, /* shadow_color */
|
|
|
|
|
0xC09786A0 /* particle_color */
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
static const rgui_theme_t rgui_theme_midnight_blue = {
|
|
|
|
@ -210,7 +226,8 @@ static const rgui_theme_t rgui_theme_midnight_blue = {
|
|
|
|
|
0xC03C4D5E, /* bg_light_color */
|
|
|
|
|
0xC046586A, /* border_dark_color */
|
|
|
|
|
0xC06D7F91, /* border_light_color */
|
|
|
|
|
0xC00A0F14 /* shadow_color */
|
|
|
|
|
0xC00A0F14, /* shadow_color */
|
|
|
|
|
0xC084849E /* particle_color */
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
static const rgui_theme_t rgui_theme_golden = {
|
|
|
|
@ -219,9 +236,10 @@ static const rgui_theme_t rgui_theme_golden = {
|
|
|
|
|
0xFFFFCC00, /* title_color */
|
|
|
|
|
0xC0B88D0B, /* bg_dark_color */
|
|
|
|
|
0xC0BF962B, /* bg_light_color */
|
|
|
|
|
0xC0e1ad21, /* border_dark_color */
|
|
|
|
|
0xC0E1AD21, /* border_dark_color */
|
|
|
|
|
0xC0FCC717, /* border_light_color */
|
|
|
|
|
0xC0382B03 /* shadow_color */
|
|
|
|
|
0xC0382B03, /* shadow_color */
|
|
|
|
|
0xC0F7D15E /* particle_color */
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
static const rgui_theme_t rgui_theme_electric_blue = {
|
|
|
|
@ -232,7 +250,8 @@ static const rgui_theme_t rgui_theme_electric_blue = {
|
|
|
|
|
0xC0007FFF, /* bg_light_color */
|
|
|
|
|
0xC034A5D8, /* border_dark_color */
|
|
|
|
|
0xC070C9FF, /* border_light_color */
|
|
|
|
|
0xC012294D /* shadow_color */
|
|
|
|
|
0xC012294D, /* shadow_color */
|
|
|
|
|
0xC080C7E6 /* particle_color */
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
static const rgui_theme_t rgui_theme_apple_green = {
|
|
|
|
@ -243,7 +262,8 @@ static const rgui_theme_t rgui_theme_apple_green = {
|
|
|
|
|
0xC0688539, /* bg_light_color */
|
|
|
|
|
0xC0608E3A, /* border_dark_color */
|
|
|
|
|
0xC09AB973, /* border_light_color */
|
|
|
|
|
0xC01F2E19 /* shadow_color */
|
|
|
|
|
0xC01F2E19, /* shadow_color */
|
|
|
|
|
0xC0A3C44E /* particle_color */
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
static const rgui_theme_t rgui_theme_volcanic_red = {
|
|
|
|
@ -254,7 +274,8 @@ static const rgui_theme_t rgui_theme_volcanic_red = {
|
|
|
|
|
0xC0BD0F1E, /* bg_light_color */
|
|
|
|
|
0xC0CE2029, /* border_dark_color */
|
|
|
|
|
0xC0FF0000, /* border_light_color */
|
|
|
|
|
0xC0330D0D /* shadow_color */
|
|
|
|
|
0xC0330D0D, /* shadow_color */
|
|
|
|
|
0xC0E67D45 /* particle_color */
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
static const rgui_theme_t rgui_theme_lagoon = {
|
|
|
|
@ -265,7 +286,8 @@ static const rgui_theme_t rgui_theme_lagoon = {
|
|
|
|
|
0xC0526778, /* bg_light_color */
|
|
|
|
|
0xC058848F, /* border_dark_color */
|
|
|
|
|
0xC060909C, /* border_light_color */
|
|
|
|
|
0xC01C2329 /* shadow_color */
|
|
|
|
|
0xC01C2329, /* shadow_color */
|
|
|
|
|
0xC09FB1C7 /* particle_color */
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
static const rgui_theme_t rgui_theme_brogrammer = {
|
|
|
|
@ -276,7 +298,8 @@ static const rgui_theme_t rgui_theme_brogrammer = {
|
|
|
|
|
0xC0242424, /* bg_light_color */
|
|
|
|
|
0xC0E74C3C, /* border_dark_color */
|
|
|
|
|
0xC0E74C3C, /* border_light_color */
|
|
|
|
|
0xC0000000 /* shadow_color */
|
|
|
|
|
0xC0000000, /* shadow_color */
|
|
|
|
|
0xC0606060 /* particle_color */
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
static const rgui_theme_t rgui_theme_dracula = {
|
|
|
|
@ -287,7 +310,8 @@ static const rgui_theme_t rgui_theme_dracula = {
|
|
|
|
|
0xC02F3240, /* bg_light_color */
|
|
|
|
|
0xC06272A4, /* border_dark_color */
|
|
|
|
|
0xC06272A4, /* border_light_color */
|
|
|
|
|
0xC00F0F0F /* shadow_color */
|
|
|
|
|
0xC00F0F0F, /* shadow_color */
|
|
|
|
|
0xC06272A4 /* particle_color */
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
static const rgui_theme_t rgui_theme_fairyfloss = {
|
|
|
|
@ -298,7 +322,8 @@ static const rgui_theme_t rgui_theme_fairyfloss = {
|
|
|
|
|
0xC0675F87, /* bg_light_color */
|
|
|
|
|
0xC08077A8, /* border_dark_color */
|
|
|
|
|
0xC08077A8, /* border_light_color */
|
|
|
|
|
0xC0262433 /* shadow_color */
|
|
|
|
|
0xC0262433, /* shadow_color */
|
|
|
|
|
0xC0C5A3FF /* particle_color */
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
static const rgui_theme_t rgui_theme_flatui = {
|
|
|
|
@ -309,7 +334,8 @@ static const rgui_theme_t rgui_theme_flatui = {
|
|
|
|
|
0xE0ECF0F1, /* bg_light_color */
|
|
|
|
|
0xE095A5A6, /* border_dark_color */
|
|
|
|
|
0xE095A5A6, /* border_light_color */
|
|
|
|
|
0xE0C3DBDE /* shadow_color */
|
|
|
|
|
0xE0C3DBDE, /* shadow_color */
|
|
|
|
|
0xE0B3DFFF /* particle_color */
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
static const rgui_theme_t rgui_theme_gruvbox_dark = {
|
|
|
|
@ -320,7 +346,8 @@ static const rgui_theme_t rgui_theme_gruvbox_dark = {
|
|
|
|
|
0xC03D3D3D, /* bg_light_color */
|
|
|
|
|
0xC099897A, /* border_dark_color */
|
|
|
|
|
0xC099897A, /* border_light_color */
|
|
|
|
|
0xC0000000 /* shadow_color */
|
|
|
|
|
0xC0000000, /* shadow_color */
|
|
|
|
|
0xC098971A /* particle_color */
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
static const rgui_theme_t rgui_theme_gruvbox_light = {
|
|
|
|
@ -331,7 +358,8 @@ static const rgui_theme_t rgui_theme_gruvbox_light = {
|
|
|
|
|
0xE0FBEBC7, /* bg_light_color */
|
|
|
|
|
0xE0928374, /* border_dark_color */
|
|
|
|
|
0xE0928374, /* border_light_color */
|
|
|
|
|
0xE0D5C4A1 /* shadow_color */
|
|
|
|
|
0xE0D5C4A1, /* shadow_color */
|
|
|
|
|
0xE0D5C4A1 /* particle_color */
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
static const rgui_theme_t rgui_theme_hacking_the_kernel = {
|
|
|
|
@ -342,7 +370,8 @@ static const rgui_theme_t rgui_theme_hacking_the_kernel = {
|
|
|
|
|
0xC0000000, /* bg_light_color */
|
|
|
|
|
0xC0036303, /* border_dark_color */
|
|
|
|
|
0xC0036303, /* border_light_color */
|
|
|
|
|
0xC0154D2B /* shadow_color */
|
|
|
|
|
0xC0154D2B, /* shadow_color */
|
|
|
|
|
0xC0008C00 /* particle_color */
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
static const rgui_theme_t rgui_theme_nord = {
|
|
|
|
@ -353,7 +382,8 @@ static const rgui_theme_t rgui_theme_nord = {
|
|
|
|
|
0xC0363C4F, /* bg_light_color */
|
|
|
|
|
0xC04E596E, /* border_dark_color */
|
|
|
|
|
0xC04E596E, /* border_light_color */
|
|
|
|
|
0xC0040505 /* shadow_color */
|
|
|
|
|
0xC0040505, /* shadow_color */
|
|
|
|
|
0xC05E81AC /* particle_color */
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
static const rgui_theme_t rgui_theme_nova = {
|
|
|
|
@ -364,7 +394,8 @@ static const rgui_theme_t rgui_theme_nova = {
|
|
|
|
|
0xC0485B66, /* bg_light_color */
|
|
|
|
|
0xC0627985, /* border_dark_color */
|
|
|
|
|
0xC0627985, /* border_light_color */
|
|
|
|
|
0xC01E272C /* shadow_color */
|
|
|
|
|
0xC01E272C, /* shadow_color */
|
|
|
|
|
0xC0889BA7 /* particle_color */
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
static const rgui_theme_t rgui_theme_one_dark = {
|
|
|
|
@ -375,7 +406,8 @@ static const rgui_theme_t rgui_theme_one_dark = {
|
|
|
|
|
0xC02D323B, /* bg_light_color */
|
|
|
|
|
0xC0495162, /* border_dark_color */
|
|
|
|
|
0xC0495162, /* border_light_color */
|
|
|
|
|
0xC007080A /* shadow_color */
|
|
|
|
|
0xC007080A, /* shadow_color */
|
|
|
|
|
0xC05F697A /* particle_color */
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
static const rgui_theme_t rgui_theme_palenight = {
|
|
|
|
@ -386,7 +418,8 @@ static const rgui_theme_t rgui_theme_palenight = {
|
|
|
|
|
0xC02F3347, /* bg_light_color */
|
|
|
|
|
0xC0697098, /* border_dark_color */
|
|
|
|
|
0xC0697098, /* border_light_color */
|
|
|
|
|
0xC00D0E14 /* shadow_color */
|
|
|
|
|
0xC00D0E14, /* shadow_color */
|
|
|
|
|
0xC0697098 /* particle_color */
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
static const rgui_theme_t rgui_theme_solarized_dark = {
|
|
|
|
@ -397,7 +430,8 @@ static const rgui_theme_t rgui_theme_solarized_dark = {
|
|
|
|
|
0xC0003542, /* bg_light_color */
|
|
|
|
|
0xC093A1A1, /* border_dark_color */
|
|
|
|
|
0xC093A1A1, /* border_light_color */
|
|
|
|
|
0xC000141A /* shadow_color */
|
|
|
|
|
0xC000141A, /* shadow_color */
|
|
|
|
|
0xC0586E75 /* particle_color */
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
static const rgui_theme_t rgui_theme_solarized_light = {
|
|
|
|
@ -408,7 +442,8 @@ static const rgui_theme_t rgui_theme_solarized_light = {
|
|
|
|
|
0xE0FDEDDF, /* bg_light_color */
|
|
|
|
|
0xE093A1A1, /* border_dark_color */
|
|
|
|
|
0xE093A1A1, /* border_light_color */
|
|
|
|
|
0xE0E0DBC9 /* shadow_color */
|
|
|
|
|
0xE0E0DBC9, /* shadow_color */
|
|
|
|
|
0xE0FFC5AD /* particle_color */
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
static const rgui_theme_t rgui_theme_tango_dark = {
|
|
|
|
@ -419,7 +454,8 @@ static const rgui_theme_t rgui_theme_tango_dark = {
|
|
|
|
|
0xC0384042, /* bg_light_color */
|
|
|
|
|
0xC06A767A, /* border_dark_color */
|
|
|
|
|
0xC06A767A, /* border_light_color */
|
|
|
|
|
0xC01A1A1A /* shadow_color */
|
|
|
|
|
0xC01A1A1A, /* shadow_color */
|
|
|
|
|
0xC0C4A000 /* particle_color */
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
static const rgui_theme_t rgui_theme_tango_light = {
|
|
|
|
@ -430,7 +466,8 @@ static const rgui_theme_t rgui_theme_tango_light = {
|
|
|
|
|
0xE0EEEEEC, /* bg_light_color */
|
|
|
|
|
0xE0C7C7C7, /* border_dark_color */
|
|
|
|
|
0xE0C7C7C7, /* border_light_color */
|
|
|
|
|
0xE0D3D7CF /* shadow_color */
|
|
|
|
|
0xE0D3D7CF, /* shadow_color */
|
|
|
|
|
0xE0FFCA78 /* particle_color */
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
static const rgui_theme_t rgui_theme_zenburn = {
|
|
|
|
@ -441,7 +478,8 @@ static const rgui_theme_t rgui_theme_zenburn = {
|
|
|
|
|
0xC04F4F4F, /* bg_light_color */
|
|
|
|
|
0xC0636363, /* border_dark_color */
|
|
|
|
|
0xC0636363, /* border_light_color */
|
|
|
|
|
0xC01F1F1F /* shadow_color */
|
|
|
|
|
0xC01F1F1F, /* shadow_color */
|
|
|
|
|
0xC0AC7373 /* particle_color */
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
static const rgui_theme_t rgui_theme_anti_zenburn = {
|
|
|
|
@ -452,7 +490,8 @@ static const rgui_theme_t rgui_theme_anti_zenburn = {
|
|
|
|
|
0xE0C0C0C0, /* bg_light_color */
|
|
|
|
|
0xE0A0A0A0, /* border_dark_color */
|
|
|
|
|
0xE0A0A0A0, /* border_light_color */
|
|
|
|
|
0xE0B0B0B0 /* shadow_color */
|
|
|
|
|
0xE0B0B0B0, /* shadow_color */
|
|
|
|
|
0xE0B090B0 /* particle_color */
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
typedef struct
|
|
|
|
@ -465,6 +504,7 @@ typedef struct
|
|
|
|
|
uint16_t border_dark_color;
|
|
|
|
|
uint16_t border_light_color;
|
|
|
|
|
uint16_t shadow_color;
|
|
|
|
|
uint16_t particle_color;
|
|
|
|
|
} rgui_colors_t;
|
|
|
|
|
|
|
|
|
|
typedef struct
|
|
|
|
@ -484,7 +524,7 @@ typedef struct
|
|
|
|
|
bool border_thickness;
|
|
|
|
|
bool border_enable;
|
|
|
|
|
bool shadow_enable;
|
|
|
|
|
bool snow_enable;
|
|
|
|
|
unsigned particle_effect;
|
|
|
|
|
bool extended_ascii_enable;
|
|
|
|
|
float scroll_y;
|
|
|
|
|
char *msgbox;
|
|
|
|
@ -519,7 +559,24 @@ static unsigned mini_thumbnail_max_height = 0;
|
|
|
|
|
|
|
|
|
|
static bool font_lut[NUM_FONT_GLYPHS_EXTENDED][FONT_WIDTH * FONT_HEIGHT];
|
|
|
|
|
|
|
|
|
|
float snowflakes[1024];
|
|
|
|
|
/* A 'particle' is just 4 float variables that can
|
|
|
|
|
* be used for any purpose - e.g.:
|
|
|
|
|
* > a = x pos
|
|
|
|
|
* > b = y pos
|
|
|
|
|
* > c = x velocity
|
|
|
|
|
* or:
|
|
|
|
|
* > a = radius
|
|
|
|
|
* > b = theta
|
|
|
|
|
* etc. */
|
|
|
|
|
typedef struct
|
|
|
|
|
{
|
|
|
|
|
float a;
|
|
|
|
|
float b;
|
|
|
|
|
float c;
|
|
|
|
|
float d;
|
|
|
|
|
} rgui_particle_t;
|
|
|
|
|
|
|
|
|
|
static rgui_particle_t particles[NUM_PARTICLES] = {{ 0.0f }};
|
|
|
|
|
|
|
|
|
|
/* ==============================
|
|
|
|
|
* Custom Symbols (glyphs) START
|
|
|
|
@ -835,6 +892,420 @@ static void rgui_color_rect(
|
|
|
|
|
data[j * (pitch >> 1) + i] = color;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void rgui_render_border(rgui_t *rgui, uint16_t *data,
|
|
|
|
|
size_t fb_pitch, unsigned fb_width, unsigned fb_height)
|
|
|
|
|
{
|
|
|
|
|
/* Sanity check */
|
|
|
|
|
if (!rgui || !data)
|
|
|
|
|
return;
|
|
|
|
|
|
|
|
|
|
/* Draw border */
|
|
|
|
|
rgui_fill_rect(rgui, data, fb_pitch, 5, 5, fb_width - 10, 5, rgui_border_filler);
|
|
|
|
|
rgui_fill_rect(rgui, data, fb_pitch, 5, fb_height - 10, fb_width - 10, 5, rgui_border_filler);
|
|
|
|
|
rgui_fill_rect(rgui, data, fb_pitch, 5, 5, 5, fb_height - 10, rgui_border_filler);
|
|
|
|
|
rgui_fill_rect(rgui, data, fb_pitch, fb_width - 10, 5, 5, fb_height - 10, rgui_border_filler);
|
|
|
|
|
|
|
|
|
|
/* Draw drop shadow, if required */
|
|
|
|
|
if (rgui->shadow_enable)
|
|
|
|
|
{
|
|
|
|
|
rgui_color_rect(data, fb_pitch, fb_width, fb_height,
|
|
|
|
|
10, 10, 1, fb_height - 20, rgui->colors.shadow_color);
|
|
|
|
|
rgui_color_rect(data, fb_pitch, fb_width, fb_height,
|
|
|
|
|
10, 10, fb_width - 20, 1, rgui->colors.shadow_color);
|
|
|
|
|
rgui_color_rect(data, fb_pitch, fb_width, fb_height,
|
|
|
|
|
fb_width - 5, 6, 1, fb_height - 10, rgui->colors.shadow_color);
|
|
|
|
|
rgui_color_rect(data, fb_pitch, fb_width, fb_height,
|
|
|
|
|
6, fb_height - 5, fb_width - 10, 1, rgui->colors.shadow_color);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* Returns true if particle is on screen */
|
|
|
|
|
static bool INLINE rgui_draw_particle(
|
|
|
|
|
uint16_t *data,
|
|
|
|
|
unsigned fb_width, unsigned fb_height,
|
|
|
|
|
int x, int y,
|
|
|
|
|
unsigned width, unsigned height,
|
|
|
|
|
uint16_t color)
|
|
|
|
|
{
|
|
|
|
|
unsigned x_index, y_index;
|
|
|
|
|
|
|
|
|
|
/* This great convoluted mess just saves us
|
|
|
|
|
* having to perform comparisons on every
|
|
|
|
|
* iteration of the for loops... */
|
|
|
|
|
int x_start = x > 0 ? x : 0;
|
|
|
|
|
int y_start = y > 0 ? y : 0;
|
|
|
|
|
int x_end = x + width;
|
|
|
|
|
int y_end = y + height;
|
|
|
|
|
|
|
|
|
|
x_start = x_start <= fb_width ? x_start : fb_width;
|
|
|
|
|
y_start = y_start <= fb_height ? y_start : fb_height;
|
|
|
|
|
|
|
|
|
|
x_end = x_end > 0 ? x_end : 0;
|
|
|
|
|
x_end = x_end <= fb_width ? x_end : fb_width;
|
|
|
|
|
|
|
|
|
|
y_end = y_end > 0 ? y_end : 0;
|
|
|
|
|
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++)
|
|
|
|
|
data[(y_index * fb_width) + x_index] = color;
|
|
|
|
|
|
|
|
|
|
return (x_end > x_start) && (y_end > y_start);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void rgui_init_particle_effect(rgui_t *rgui)
|
|
|
|
|
{
|
|
|
|
|
size_t fb_pitch;
|
|
|
|
|
unsigned fb_width, fb_height;
|
|
|
|
|
size_t i;
|
|
|
|
|
|
|
|
|
|
/* Sanity check */
|
|
|
|
|
if (!rgui)
|
|
|
|
|
return;
|
|
|
|
|
|
|
|
|
|
menu_display_get_fb_size(&fb_width, &fb_height, &fb_pitch);
|
|
|
|
|
|
|
|
|
|
switch (rgui->particle_effect)
|
|
|
|
|
{
|
|
|
|
|
case RGUI_PARTICLE_EFFECT_SNOW:
|
|
|
|
|
case RGUI_PARTICLE_EFFECT_SNOW_ALT:
|
|
|
|
|
{
|
|
|
|
|
for (i = 0; i < NUM_PARTICLES; i++)
|
|
|
|
|
{
|
|
|
|
|
rgui_particle_t *particle = &particles[i];
|
|
|
|
|
|
|
|
|
|
particle->a = (float)(rand() % fb_width);
|
|
|
|
|
particle->b = (float)(rand() % fb_height);
|
|
|
|
|
particle->c = (float)(rand() % 64 - 16) * 0.1f;
|
|
|
|
|
particle->d = (float)(rand() % 64 - 48) * 0.1f;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
break;
|
|
|
|
|
case RGUI_PARTICLE_EFFECT_RAIN:
|
|
|
|
|
{
|
|
|
|
|
uint8_t weights[] = { /* 60 entries */
|
|
|
|
|
2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
|
|
|
|
|
3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
|
|
|
|
|
4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
|
|
|
|
|
5, 5, 5, 5, 5, 5, 5, 5,
|
|
|
|
|
6, 6, 6, 6, 6, 6,
|
|
|
|
|
7, 7, 7, 7,
|
|
|
|
|
8, 8, 8,
|
|
|
|
|
9, 9,
|
|
|
|
|
10};
|
|
|
|
|
unsigned num_drops = (unsigned)(0.85f * ((float)fb_width / 426.0f) * (float)NUM_PARTICLES);
|
|
|
|
|
|
|
|
|
|
num_drops = num_drops < NUM_PARTICLES ? num_drops : NUM_PARTICLES;
|
|
|
|
|
|
|
|
|
|
for (i = 0; i < num_drops; i++)
|
|
|
|
|
{
|
|
|
|
|
rgui_particle_t *particle = &particles[i];
|
|
|
|
|
|
|
|
|
|
/* x pos */
|
|
|
|
|
particle->a = (float)(rand() % (fb_width / 3)) * 3.0f;
|
|
|
|
|
/* y pos */
|
|
|
|
|
particle->b = (float)(rand() % fb_height);
|
|
|
|
|
/* drop length */
|
|
|
|
|
particle->c = (float)weights[(unsigned)(rand() % 61)];
|
|
|
|
|
/* drop speed (larger drops fall faster) */
|
|
|
|
|
particle->d = (particle->c / 12.0f) * (0.5f + ((float)(rand() % 150) / 200.0f));
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
break;
|
|
|
|
|
case RGUI_PARTICLE_EFFECT_VORTEX:
|
|
|
|
|
{
|
|
|
|
|
float max_radius = (float)sqrt((double)((fb_width * fb_width) + (fb_height * fb_height))) / 2.0f;
|
|
|
|
|
float one_degree_radians = PI / 360.0f;
|
|
|
|
|
|
|
|
|
|
for (i = 0; i < NUM_PARTICLES; i++)
|
|
|
|
|
{
|
|
|
|
|
rgui_particle_t *particle = &particles[i];
|
|
|
|
|
|
|
|
|
|
/* radius */
|
|
|
|
|
particle->a = 1.0f + (((float)rand() / (float)RAND_MAX) * max_radius);
|
|
|
|
|
/* theta */
|
|
|
|
|
particle->b = ((float)rand() / (float)RAND_MAX) * 2.0f * PI;
|
|
|
|
|
/* radial speed */
|
|
|
|
|
particle->c = (float)((rand() % 100) + 1) * 0.001f;
|
|
|
|
|
/* rotational speed */
|
|
|
|
|
particle->d = (((float)((rand() % 50) + 1) / 200.0f) + 0.1f) * one_degree_radians;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
break;
|
|
|
|
|
case RGUI_PARTICLE_EFFECT_STARFIELD:
|
|
|
|
|
{
|
|
|
|
|
float min_depth = (float)fb_width / 12.0f;
|
|
|
|
|
|
|
|
|
|
for (i = 0; i < NUM_PARTICLES; i++)
|
|
|
|
|
{
|
|
|
|
|
rgui_particle_t *particle = &particles[i];
|
|
|
|
|
|
|
|
|
|
/* x pos */
|
|
|
|
|
particle->a = (float)(rand() % fb_width);
|
|
|
|
|
/* y pos */
|
|
|
|
|
particle->b = (float)(rand() % fb_height);
|
|
|
|
|
/* depth */
|
|
|
|
|
particle->c = (float)fb_width;
|
|
|
|
|
/* speed */
|
|
|
|
|
particle->d = 1.0f + ((float)(rand() % 20) * 0.01f);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
break;
|
|
|
|
|
default:
|
|
|
|
|
/* Do nothing... */
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void rgui_render_particle_effect(rgui_t *rgui)
|
|
|
|
|
{
|
|
|
|
|
size_t fb_pitch;
|
|
|
|
|
unsigned fb_width, fb_height;
|
|
|
|
|
size_t i;
|
|
|
|
|
|
|
|
|
|
/* Sanity check */
|
|
|
|
|
if (!rgui || !rgui_frame_buf.data)
|
|
|
|
|
return;
|
|
|
|
|
|
|
|
|
|
menu_display_get_fb_size(&fb_width, &fb_height, &fb_pitch);
|
|
|
|
|
|
|
|
|
|
/* Note: It would be more elegant to have 'update' and 'draw'
|
|
|
|
|
* as separate functions, since 'update' is the part that
|
|
|
|
|
* varies with particle effect whereas 'draw' is always
|
|
|
|
|
* pretty much the same. However, this has the following
|
|
|
|
|
* disadvantages:
|
|
|
|
|
* - It means we have to loop through all particles twice,
|
|
|
|
|
* and given that we're already using a heap of CPU cycles
|
|
|
|
|
* to draw these effects any further performance overheads
|
|
|
|
|
* are to be avoided
|
|
|
|
|
* - It locks us into a particular draw style. e.g. What if
|
|
|
|
|
* an effect calls for round particles, instead of square
|
|
|
|
|
* ones? This would make a mess of any 'standardised'
|
|
|
|
|
* drawing
|
|
|
|
|
* So we go with the simple option of having the entire
|
|
|
|
|
* update/draw sequence here. This results in some code
|
|
|
|
|
* repetition, but it has better performance and allows for
|
|
|
|
|
* complete flexibility */
|
|
|
|
|
|
|
|
|
|
switch (rgui->particle_effect)
|
|
|
|
|
{
|
|
|
|
|
case RGUI_PARTICLE_EFFECT_SNOW:
|
|
|
|
|
case RGUI_PARTICLE_EFFECT_SNOW_ALT:
|
|
|
|
|
{
|
|
|
|
|
unsigned particle_size;
|
|
|
|
|
bool on_screen;
|
|
|
|
|
|
|
|
|
|
for (i = 0; i < NUM_PARTICLES; i++)
|
|
|
|
|
{
|
|
|
|
|
rgui_particle_t *particle = &particles[i];
|
|
|
|
|
|
|
|
|
|
/* Update particle 'speed' */
|
|
|
|
|
particle->c = particle->c + (float)(rand() % 16 - 9) * 0.01f;
|
|
|
|
|
particle->d = particle->d + (float)(rand() % 16 - 7) * 0.01f;
|
|
|
|
|
|
|
|
|
|
particle->c = (particle->c < -0.4f) ? -0.4f : particle->c;
|
|
|
|
|
particle->c = (particle->c > 0.1f) ? 0.1f : particle->c;
|
|
|
|
|
|
|
|
|
|
particle->d = (particle->d < -0.1f) ? -0.1f : particle->d;
|
|
|
|
|
particle->d = (particle->d > 0.4f) ? 0.4f : particle->d;
|
|
|
|
|
|
|
|
|
|
/* Update particle location */
|
|
|
|
|
particle->a = fmod(particle->a + particle->c, fb_width);
|
|
|
|
|
particle->b = fmod(particle->b + particle->d, fb_height);
|
|
|
|
|
|
|
|
|
|
/* Get particle size */
|
|
|
|
|
particle_size = 1;
|
|
|
|
|
if (rgui->particle_effect == RGUI_PARTICLE_EFFECT_SNOW_ALT)
|
|
|
|
|
{
|
|
|
|
|
/* Gives the following distribution:
|
|
|
|
|
* 1x1: 32
|
|
|
|
|
* 2x2: 128
|
|
|
|
|
* 3x3: 32 */
|
|
|
|
|
if (!(i & 0x2))
|
|
|
|
|
particle_size = 2;
|
|
|
|
|
else if ((i & 0x7) == 0x7)
|
|
|
|
|
particle_size = 3;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* Draw particle */
|
|
|
|
|
on_screen = rgui_draw_particle(rgui_frame_buf.data, fb_width, fb_height,
|
|
|
|
|
(int)particle->a, (int)particle->b,
|
|
|
|
|
particle_size, particle_size, rgui->colors.particle_color);
|
|
|
|
|
|
|
|
|
|
/* Reset particle if it has fallen off screen */
|
|
|
|
|
if (!on_screen)
|
|
|
|
|
{
|
|
|
|
|
particle->a = (particle->a < 0.0f) ? (particle->a + (float)fb_width) : particle->a;
|
|
|
|
|
particle->b = (particle->b < 0.0f) ? (particle->b + (float)fb_height) : particle->b;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
break;
|
|
|
|
|
case RGUI_PARTICLE_EFFECT_RAIN:
|
|
|
|
|
{
|
|
|
|
|
uint8_t weights[] = { /* 60 entries */
|
|
|
|
|
2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
|
|
|
|
|
3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
|
|
|
|
|
4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
|
|
|
|
|
5, 5, 5, 5, 5, 5, 5, 5,
|
|
|
|
|
6, 6, 6, 6, 6, 6,
|
|
|
|
|
7, 7, 7, 7,
|
|
|
|
|
8, 8, 8,
|
|
|
|
|
9, 9,
|
|
|
|
|
10};
|
|
|
|
|
unsigned num_drops = (unsigned)(0.85f * ((float)fb_width / 426.0f) * (float)NUM_PARTICLES);
|
|
|
|
|
bool on_screen;
|
|
|
|
|
|
|
|
|
|
num_drops = num_drops < NUM_PARTICLES ? num_drops : NUM_PARTICLES;
|
|
|
|
|
|
|
|
|
|
for (i = 0; i < num_drops; i++)
|
|
|
|
|
{
|
|
|
|
|
rgui_particle_t *particle = &particles[i];
|
|
|
|
|
|
|
|
|
|
/* Draw particle */
|
|
|
|
|
on_screen = rgui_draw_particle(rgui_frame_buf.data, fb_width, fb_height,
|
|
|
|
|
(int)particle->a, (int)particle->b,
|
|
|
|
|
2, (unsigned)particle->c, rgui->colors.particle_color);
|
|
|
|
|
|
|
|
|
|
/* Update y pos */
|
|
|
|
|
particle->b += particle->d;
|
|
|
|
|
|
|
|
|
|
/* Reset particle if it has fallen off the bottom of the screen */
|
|
|
|
|
if (!on_screen)
|
|
|
|
|
{
|
|
|
|
|
/* x pos */
|
|
|
|
|
particle->a = (float)(rand() % (fb_width / 3)) * 3.0f;
|
|
|
|
|
/* y pos */
|
|
|
|
|
particle->b = 0.0f;
|
|
|
|
|
/* drop length */
|
|
|
|
|
particle->c = (float)weights[(unsigned)(rand() % 61)];
|
|
|
|
|
/* drop speed (larger drops fall faster) */
|
|
|
|
|
particle->d = (particle->c / 12.0f) * (0.5f + ((float)(rand() % 150) / 200.0f));
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
break;
|
|
|
|
|
case RGUI_PARTICLE_EFFECT_VORTEX:
|
|
|
|
|
{
|
|
|
|
|
float max_radius = (float)sqrt((double)((fb_width * fb_width) + (fb_height * fb_height))) / 2.0f;
|
|
|
|
|
float one_degree_radians = PI / 360.0f;
|
|
|
|
|
int x_centre = (int)(fb_width >> 1);
|
|
|
|
|
int y_centre = (int)(fb_height >> 1);
|
|
|
|
|
unsigned particle_size;
|
|
|
|
|
float r_speed, theta_speed;
|
|
|
|
|
int x, y;
|
|
|
|
|
|
|
|
|
|
for (i = 0; i < NUM_PARTICLES; i++)
|
|
|
|
|
{
|
|
|
|
|
rgui_particle_t *particle = &particles[i];
|
|
|
|
|
|
|
|
|
|
/* Get particle location */
|
|
|
|
|
x = (int)(particle->a * cos(particle->b)) + x_centre;
|
|
|
|
|
y = (int)(particle->a * sin(particle->b)) + y_centre;
|
|
|
|
|
|
|
|
|
|
/* Get particle size */
|
|
|
|
|
particle_size = 1 + (unsigned)(((1.0f - ((max_radius - particle->a) / max_radius)) * 3.5f) + 0.5f);
|
|
|
|
|
|
|
|
|
|
/* Draw particle */
|
|
|
|
|
rgui_draw_particle(rgui_frame_buf.data, fb_width, fb_height,
|
|
|
|
|
x, y, particle_size, particle_size, rgui->colors.particle_color);
|
|
|
|
|
|
|
|
|
|
/* Update particle speed */
|
|
|
|
|
r_speed = particle->c;
|
|
|
|
|
theta_speed = particle->d;
|
|
|
|
|
if ((particle->a > 0.0f) && (particle->a < (float)fb_height))
|
|
|
|
|
{
|
|
|
|
|
float base_scale_factor = ((float)fb_height - particle->a) / (float)fb_height;
|
|
|
|
|
r_speed *= 1.0f + (base_scale_factor * 8.0f);
|
|
|
|
|
theta_speed *= 1.0f + (base_scale_factor * base_scale_factor * 6.0f);
|
|
|
|
|
}
|
|
|
|
|
particle->a -= r_speed;
|
|
|
|
|
particle->b += theta_speed;
|
|
|
|
|
|
|
|
|
|
/* Reset particle if it has reached the centre of the screen */
|
|
|
|
|
if (particle->a < 0.0f)
|
|
|
|
|
{
|
|
|
|
|
/* radius
|
|
|
|
|
* Note: In theory, this should be:
|
|
|
|
|
* > particle->a = max_radius;
|
|
|
|
|
* ...but it turns out that spawning new particles at random
|
|
|
|
|
* locations produces a more visually appealing result... */
|
|
|
|
|
particle->a = 1.0f + (((float)rand() / (float)RAND_MAX) * max_radius);
|
|
|
|
|
/* theta */
|
|
|
|
|
particle->b = ((float)rand() / (float)RAND_MAX) * 2.0f * PI;
|
|
|
|
|
/* radial speed */
|
|
|
|
|
particle->c = (float)((rand() % 100) + 1) * 0.001f;
|
|
|
|
|
/* rotational speed */
|
|
|
|
|
particle->d = (((float)((rand() % 50) + 1) / 200.0f) + 0.1f) * one_degree_radians;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
break;
|
|
|
|
|
case RGUI_PARTICLE_EFFECT_STARFIELD:
|
|
|
|
|
{
|
|
|
|
|
float focal_length = (float)fb_width * 2.0f;
|
|
|
|
|
int x_centre = (int)(fb_width >> 1);
|
|
|
|
|
int y_centre = (int)(fb_height >> 1);
|
|
|
|
|
unsigned particle_size;
|
|
|
|
|
int x, y;
|
|
|
|
|
bool on_screen;
|
|
|
|
|
|
|
|
|
|
/* Based on an example found here:
|
|
|
|
|
* https://codepen.io/nodws/pen/pejBNb */
|
|
|
|
|
for (i = 0; i < NUM_PARTICLES; i++)
|
|
|
|
|
{
|
|
|
|
|
rgui_particle_t *particle = &particles[i];
|
|
|
|
|
|
|
|
|
|
/* Get particle location */
|
|
|
|
|
x = (int)((particle->a - (float)x_centre) * (focal_length / particle->c));
|
|
|
|
|
x += x_centre;
|
|
|
|
|
|
|
|
|
|
y = (int)((particle->b - (float)y_centre) * (focal_length / particle->c));
|
|
|
|
|
y += y_centre;
|
|
|
|
|
|
|
|
|
|
/* Get particle size */
|
|
|
|
|
particle_size = (unsigned)(focal_length / (2.0f * particle->c));
|
|
|
|
|
|
|
|
|
|
/* Draw particle */
|
|
|
|
|
on_screen = rgui_draw_particle(rgui_frame_buf.data, fb_width, fb_height,
|
|
|
|
|
x, y, particle_size, particle_size, rgui->colors.particle_color);
|
|
|
|
|
|
|
|
|
|
/* Update depth */
|
|
|
|
|
particle->c -= particle->d;
|
|
|
|
|
|
|
|
|
|
/* Reset particle if it has:
|
|
|
|
|
* - Dropped off the edge of the screen
|
|
|
|
|
* - Reached the screen depth
|
|
|
|
|
* - Grown larger than 16 pixels across
|
|
|
|
|
* (this is an arbitrary limit, set to reduce overall
|
|
|
|
|
* performance impact - i.e. larger particles are slower
|
|
|
|
|
* to draw, and without setting a limit they can fill the screen...) */
|
|
|
|
|
if (!on_screen || (particle->c <= 0.0f) || particle_size > 16)
|
|
|
|
|
{
|
|
|
|
|
/* x pos */
|
|
|
|
|
particle->a = (float)(rand() % fb_width);
|
|
|
|
|
/* y pos */
|
|
|
|
|
particle->b = (float)(rand() % fb_height);
|
|
|
|
|
/* depth */
|
|
|
|
|
particle->c = (float)fb_width;
|
|
|
|
|
/* speed */
|
|
|
|
|
particle->d = 1.0f + ((float)(rand() % 20) * 0.01f);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
break;
|
|
|
|
|
default:
|
|
|
|
|
/* Do nothing... */
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* If border is enabled, it must be drawn *above*
|
|
|
|
|
* particle effect
|
|
|
|
|
* (Wastes CPU cycles, but nothing we can do about it...) */
|
|
|
|
|
if (rgui->border_enable && !rgui->show_wallpaper)
|
|
|
|
|
rgui_render_border(rgui, rgui_frame_buf.data, fb_pitch, fb_width, fb_height);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void request_wallpaper(const char *path)
|
|
|
|
|
{
|
|
|
|
|
/* Ensure that path is valid... */
|
|
|
|
@ -1385,7 +1856,7 @@ static void load_custom_theme(rgui_t *rgui, rgui_theme_t *theme_colors, const ch
|
|
|
|
|
unsigned normal_color, hover_color, title_color,
|
|
|
|
|
bg_dark_color, bg_light_color,
|
|
|
|
|
border_dark_color, border_light_color,
|
|
|
|
|
shadow_color;
|
|
|
|
|
shadow_color, particle_color;
|
|
|
|
|
char wallpaper_file[PATH_MAX_LENGTH];
|
|
|
|
|
config_file_t *conf = NULL;
|
|
|
|
|
char *wallpaper_key = NULL;
|
|
|
|
@ -1450,6 +1921,12 @@ static void load_custom_theme(rgui_t *rgui, rgui_theme_t *theme_colors, const ch
|
|
|
|
|
if(!config_get_hex(conf, "rgui_shadow_color", &shadow_color))
|
|
|
|
|
shadow_color = 0xFF000000;
|
|
|
|
|
|
|
|
|
|
/* Make particle colour optional too (fallback to normal
|
|
|
|
|
* rgb with bg_light alpha) */
|
|
|
|
|
if(!config_get_hex(conf, "rgui_particle_color", &particle_color))
|
|
|
|
|
particle_color = (normal_color & 0x00FFFFFF) |
|
|
|
|
|
(bg_light_color & 0xFF000000);
|
|
|
|
|
|
|
|
|
|
config_get_array(conf, wallpaper_key,
|
|
|
|
|
wallpaper_file, sizeof(wallpaper_file));
|
|
|
|
|
|
|
|
|
@ -1467,6 +1944,7 @@ end:
|
|
|
|
|
theme_colors->border_dark_color = (uint32_t)border_dark_color;
|
|
|
|
|
theme_colors->border_light_color = (uint32_t)border_light_color;
|
|
|
|
|
theme_colors->shadow_color = (uint32_t)shadow_color;
|
|
|
|
|
theme_colors->particle_color = (uint32_t)particle_color;
|
|
|
|
|
|
|
|
|
|
/* Load wallpaper, if required */
|
|
|
|
|
if (!string_is_empty(wallpaper_file))
|
|
|
|
@ -1489,6 +1967,7 @@ end:
|
|
|
|
|
theme_colors->border_dark_color = rgui_theme_classic_green.border_dark_color;
|
|
|
|
|
theme_colors->border_light_color = rgui_theme_classic_green.border_light_color;
|
|
|
|
|
theme_colors->shadow_color = rgui_theme_classic_green.shadow_color;
|
|
|
|
|
theme_colors->particle_color = rgui_theme_classic_green.particle_color;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (conf)
|
|
|
|
@ -1536,35 +2015,7 @@ static void rgui_cache_background(rgui_t *rgui)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (rgui->border_enable)
|
|
|
|
|
{
|
|
|
|
|
/* Draw border */
|
|
|
|
|
rgui_fill_rect(rgui, rgui_background_buf.data, fb_pitch, 5, 5, fb_width - 10, 5, rgui_border_filler);
|
|
|
|
|
rgui_fill_rect(rgui, rgui_background_buf.data, fb_pitch, 5, fb_height - 10, fb_width - 10, 5, rgui_border_filler);
|
|
|
|
|
rgui_fill_rect(rgui, rgui_background_buf.data, fb_pitch, 5, 5, 5, fb_height - 10, rgui_border_filler);
|
|
|
|
|
rgui_fill_rect(rgui, rgui_background_buf.data, fb_pitch, fb_width - 10, 5, 5, fb_height - 10, rgui_border_filler);
|
|
|
|
|
|
|
|
|
|
/* Draw drop shadow, if required */
|
|
|
|
|
if (rgui->shadow_enable)
|
|
|
|
|
{
|
|
|
|
|
rgui_color_rect(rgui_background_buf.data, fb_pitch, fb_width, fb_height,
|
|
|
|
|
10, 10, 1, fb_height - 20, rgui->colors.shadow_color);
|
|
|
|
|
rgui_color_rect(rgui_background_buf.data, fb_pitch, fb_width, fb_height,
|
|
|
|
|
10, 10, fb_width - 20, 1, rgui->colors.shadow_color);
|
|
|
|
|
rgui_color_rect(rgui_background_buf.data, fb_pitch, fb_width, fb_height,
|
|
|
|
|
fb_width - 5, 6, 1, fb_height - 10, rgui->colors.shadow_color);
|
|
|
|
|
rgui_color_rect(rgui_background_buf.data, fb_pitch, fb_width, fb_height,
|
|
|
|
|
6, fb_height - 5, fb_width - 10, 1, rgui->colors.shadow_color);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
if (rgui->snow_enable) {
|
|
|
|
|
size_t i = 0;
|
|
|
|
|
for (i = 0; i < 1024; i += 4) {
|
|
|
|
|
snowflakes[i ] = rand()%fb_width;
|
|
|
|
|
snowflakes[i + 1] = rand()%fb_height;
|
|
|
|
|
snowflakes[i + 2] = (rand()%64 - 16)*.1;
|
|
|
|
|
snowflakes[i + 3] = (rand()%64 - 48)*.1;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
rgui_render_border(rgui, rgui_background_buf.data, fb_pitch, fb_width, fb_height);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void prepare_rgui_colors(rgui_t *rgui, settings_t *settings)
|
|
|
|
@ -1590,6 +2041,7 @@ static void prepare_rgui_colors(rgui_t *rgui, settings_t *settings)
|
|
|
|
|
theme_colors.border_dark_color = current_theme->border_dark_color;
|
|
|
|
|
theme_colors.border_light_color = current_theme->border_light_color;
|
|
|
|
|
theme_colors.shadow_color = current_theme->shadow_color;
|
|
|
|
|
theme_colors.particle_color = current_theme->particle_color;
|
|
|
|
|
}
|
|
|
|
|
rgui->colors.hover_color = argb32_to_pixel_platform_format(theme_colors.hover_color);
|
|
|
|
|
rgui->colors.normal_color = argb32_to_pixel_platform_format(theme_colors.normal_color);
|
|
|
|
@ -1599,6 +2051,7 @@ static void prepare_rgui_colors(rgui_t *rgui, settings_t *settings)
|
|
|
|
|
rgui->colors.border_dark_color = argb32_to_pixel_platform_format(theme_colors.border_dark_color);
|
|
|
|
|
rgui->colors.border_light_color = argb32_to_pixel_platform_format(theme_colors.border_light_color);
|
|
|
|
|
rgui->colors.shadow_color = argb32_to_pixel_platform_format(theme_colors.shadow_color);
|
|
|
|
|
rgui->colors.particle_color = argb32_to_pixel_platform_format(theme_colors.particle_color);
|
|
|
|
|
|
|
|
|
|
rgui->bg_modified = true;
|
|
|
|
|
rgui->force_redraw = true;
|
|
|
|
@ -2006,8 +2459,10 @@ static void rgui_render_messagebox(rgui_t *rgui, const char *message)
|
|
|
|
|
{
|
|
|
|
|
rgui_fill_rect(rgui, rgui_frame_buf.data, fb_pitch, x + 5, y + 5, width - 10, height - 10, rgui_bg_filler);
|
|
|
|
|
|
|
|
|
|
if (rgui->border_enable)
|
|
|
|
|
{
|
|
|
|
|
/* Note: We draw borders around message boxes regardless
|
|
|
|
|
* of the rgui->border_enable setting, because they look
|
|
|
|
|
* ridiculous without... */
|
|
|
|
|
|
|
|
|
|
/* Draw drop shadow, if required */
|
|
|
|
|
if (rgui->shadow_enable)
|
|
|
|
|
{
|
|
|
|
@ -2027,20 +2482,6 @@ static void rgui_render_messagebox(rgui_t *rgui, const char *message)
|
|
|
|
|
rgui_fill_rect(rgui, rgui_frame_buf.data, fb_pitch, x + 5, y + height - 5, width - 5, 5, rgui_border_filler);
|
|
|
|
|
rgui_fill_rect(rgui, rgui_frame_buf.data, fb_pitch, x, y + 5, 5, height - 5, rgui_border_filler);
|
|
|
|
|
}
|
|
|
|
|
else if (rgui->shadow_enable)
|
|
|
|
|
{
|
|
|
|
|
/* Without a border, this is a bit silly...
|
|
|
|
|
* All we can do is draw a sort of frame... */
|
|
|
|
|
rgui_color_rect(rgui_frame_buf.data, fb_pitch, fb_width, fb_height,
|
|
|
|
|
x + 4, y + 4, 1, height - 8, rgui->colors.shadow_color);
|
|
|
|
|
rgui_color_rect(rgui_frame_buf.data, fb_pitch, fb_width, fb_height,
|
|
|
|
|
x + 5, y + 4, width - 10, 1, rgui->colors.shadow_color);
|
|
|
|
|
rgui_color_rect(rgui_frame_buf.data, fb_pitch, fb_width, fb_height,
|
|
|
|
|
x + width - 5, y + 4, 1, height - 8, rgui->colors.shadow_color);
|
|
|
|
|
rgui_color_rect(rgui_frame_buf.data, fb_pitch, fb_width, fb_height,
|
|
|
|
|
x + 5, y + height - 5, width - 10, 1, rgui->colors.shadow_color);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
for (i = 0; i < list->size; i++)
|
|
|
|
|
{
|
|
|
|
@ -2328,6 +2769,7 @@ static void rgui_render(void *data, bool is_idle)
|
|
|
|
|
int bottom;
|
|
|
|
|
size_t entries_end = 0;
|
|
|
|
|
bool msg_force = false;
|
|
|
|
|
bool fb_size_changed = false;
|
|
|
|
|
settings_t *settings = config_get_ptr();
|
|
|
|
|
rgui_t *rgui = (rgui_t*)data;
|
|
|
|
|
|
|
|
|
@ -2364,10 +2806,17 @@ static void rgui_render(void *data, bool is_idle)
|
|
|
|
|
menu_display_get_fb_size(&fb_width, &fb_height,
|
|
|
|
|
&fb_pitch);
|
|
|
|
|
|
|
|
|
|
/* if the framebuffer changed size, recache the background */
|
|
|
|
|
if (rgui->bg_modified || rgui->last_width != fb_width || rgui->last_height != fb_height)
|
|
|
|
|
/* If the framebuffer changed size, or the background config has
|
|
|
|
|
* changed, recache the background buffer */
|
|
|
|
|
fb_size_changed = (rgui->last_width != fb_width) || (rgui->last_height != fb_height);
|
|
|
|
|
if (rgui->bg_modified || fb_size_changed)
|
|
|
|
|
{
|
|
|
|
|
rgui_cache_background(rgui);
|
|
|
|
|
|
|
|
|
|
/* Reinitialise particle effect, if required */
|
|
|
|
|
if (fb_size_changed && (rgui->particle_effect != RGUI_PARTICLE_EFFECT_NONE))
|
|
|
|
|
rgui_init_particle_effect(rgui);
|
|
|
|
|
|
|
|
|
|
rgui->last_width = fb_width;
|
|
|
|
|
rgui->last_height = fb_height;
|
|
|
|
|
}
|
|
|
|
@ -2441,22 +2890,9 @@ static void rgui_render(void *data, bool is_idle)
|
|
|
|
|
/* Render background */
|
|
|
|
|
rgui_render_background();
|
|
|
|
|
|
|
|
|
|
/* Snow */
|
|
|
|
|
if (rgui->snow_enable && rgui_frame_buf.data) {
|
|
|
|
|
for (i = 0; i < 1024; i += 4) {
|
|
|
|
|
snowflakes[i + 2] = snowflakes[i + 2] + (rand()%16 - 9)*.01;
|
|
|
|
|
snowflakes[i + 3] = snowflakes[i + 3] + (rand()%16 - 7)*.01;
|
|
|
|
|
if (snowflakes[i + 2] < -0.4) snowflakes[i + 2] = -0.4;
|
|
|
|
|
if (snowflakes[i + 2] > 0.1) snowflakes[i + 2] = 0.1;
|
|
|
|
|
if (snowflakes[i + 3] < -0.1) snowflakes[i + 3] = -0.1;
|
|
|
|
|
if (snowflakes[i + 3] > 0.4) snowflakes[i + 3] = 0.4;
|
|
|
|
|
snowflakes[i ] = fmod(snowflakes[i ] + snowflakes[i + 2], fb_width);
|
|
|
|
|
snowflakes[i + 1] = fmod(snowflakes[i + 1] + snowflakes[i + 3], fb_height);
|
|
|
|
|
if (snowflakes[i ] < 0) snowflakes[i ] += fb_width;
|
|
|
|
|
if (snowflakes[i + 1] < 0) snowflakes[i + 1] += fb_height;
|
|
|
|
|
rgui_frame_buf.data[ (int) snowflakes[i+1] * (fb_pitch >> 1) + (int) snowflakes[i]] = rgui->colors.normal_color;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
/* Render particle effect, if required */
|
|
|
|
|
if (rgui->particle_effect != RGUI_PARTICLE_EFFECT_NONE)
|
|
|
|
|
rgui_render_particle_effect(rgui);
|
|
|
|
|
|
|
|
|
|
/* We use a single ticker for all text animations,
|
|
|
|
|
* with the following configuration: */
|
|
|
|
@ -3172,12 +3608,16 @@ static void *rgui_init(void **userdata, bool video_is_threaded)
|
|
|
|
|
rgui->border_thickness = settings->bools.menu_rgui_border_filler_thickness_enable;
|
|
|
|
|
rgui->border_enable = settings->bools.menu_rgui_border_filler_enable;
|
|
|
|
|
rgui->shadow_enable = settings->bools.menu_rgui_shadows;
|
|
|
|
|
rgui->snow_enable = settings->bools.menu_rgui_snow;
|
|
|
|
|
rgui->particle_effect = settings->uints.menu_rgui_particle_effect;
|
|
|
|
|
rgui->extended_ascii_enable = settings->bools.menu_rgui_extended_ascii;
|
|
|
|
|
|
|
|
|
|
rgui->last_width = rgui_frame_buf.width;
|
|
|
|
|
rgui->last_height = rgui_frame_buf.height;
|
|
|
|
|
|
|
|
|
|
/* Initialise particle effect, if required */
|
|
|
|
|
if (rgui->particle_effect != RGUI_PARTICLE_EFFECT_NONE)
|
|
|
|
|
rgui_init_particle_effect(rgui);
|
|
|
|
|
|
|
|
|
|
/* Set initial 'blit_line/symbol' functions */
|
|
|
|
|
rgui_set_blit_functions(
|
|
|
|
|
settings->bools.menu_rgui_shadows, settings->bools.menu_rgui_extended_ascii);
|
|
|
|
@ -3667,8 +4107,6 @@ static void rgui_frame(void *data, video_frame_info_t *video_info)
|
|
|
|
|
{
|
|
|
|
|
rgui_t *rgui = (rgui_t*)data;
|
|
|
|
|
settings_t *settings = config_get_ptr();
|
|
|
|
|
if (rgui->snow_enable)
|
|
|
|
|
rgui->force_redraw = true;
|
|
|
|
|
|
|
|
|
|
if (settings->bools.menu_rgui_background_filler_thickness_enable != rgui->bg_thickness)
|
|
|
|
|
{
|
|
|
|
@ -3701,12 +4139,19 @@ static void rgui_frame(void *data, video_frame_info_t *video_info)
|
|
|
|
|
rgui->force_redraw = true;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (settings->bools.menu_rgui_snow != rgui->snow_enable)
|
|
|
|
|
if (settings->uints.menu_rgui_particle_effect != rgui->particle_effect)
|
|
|
|
|
{
|
|
|
|
|
rgui->snow_enable = settings->bools.menu_rgui_snow;
|
|
|
|
|
rgui->bg_modified = true;
|
|
|
|
|
rgui->particle_effect = settings->uints.menu_rgui_particle_effect;
|
|
|
|
|
|
|
|
|
|
if (rgui->particle_effect != RGUI_PARTICLE_EFFECT_NONE)
|
|
|
|
|
rgui_init_particle_effect(rgui);
|
|
|
|
|
|
|
|
|
|
rgui->force_redraw = true;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (rgui->particle_effect != RGUI_PARTICLE_EFFECT_NONE)
|
|
|
|
|
rgui->force_redraw = true;
|
|
|
|
|
|
|
|
|
|
if (settings->bools.menu_rgui_extended_ascii != rgui->extended_ascii_enable)
|
|
|
|
|
{
|
|
|
|
|
rgui_set_blit_functions(
|
|
|
|
|