(RGUI) Add 'particle effect' animation system
This commit is contained in:
parent
0984a13665
commit
ecdb5383ba
|
@ -398,7 +398,7 @@ static bool rgui_full_width_layout = true;
|
|||
static unsigned rgui_aspect = RGUI_ASPECT_RATIO_4_3;
|
||||
static unsigned rgui_aspect_lock = RGUI_ASPECT_RATIO_LOCK_NONE;
|
||||
static bool rgui_shadows = false;
|
||||
static bool rgui_snow = false;
|
||||
static unsigned rgui_particle_effect = RGUI_PARTICLE_EFFECT_NONE;
|
||||
static bool rgui_extended_ascii = false;
|
||||
|
||||
#else
|
||||
|
|
|
@ -1519,7 +1519,6 @@ static struct config_bool_setting *populate_settings_bool(settings_t *settings,
|
|||
SETTING_BOOL("rgui_border_filler_thickness_enable", &settings->bools.menu_rgui_border_filler_thickness_enable, true, true, false);
|
||||
SETTING_BOOL("rgui_border_filler_enable", &settings->bools.menu_rgui_border_filler_enable, true, true, false);
|
||||
SETTING_BOOL("menu_rgui_shadows", &settings->bools.menu_rgui_shadows, true, rgui_shadows, false);
|
||||
SETTING_BOOL("menu_rgui_snow", &settings->bools.menu_rgui_snow, true, rgui_snow, false);
|
||||
SETTING_BOOL("menu_rgui_full_width_layout", &settings->bools.menu_rgui_full_width_layout, true, rgui_full_width_layout, false);
|
||||
SETTING_BOOL("rgui_inline_thumbnails", &settings->bools.menu_rgui_inline_thumbnails, true, rgui_inline_thumbnails, false);
|
||||
SETTING_BOOL("rgui_swap_thumbnails", &settings->bools.menu_rgui_swap_thumbnails, true, rgui_swap_thumbnails, false);
|
||||
|
@ -1716,6 +1715,7 @@ static struct config_uint_setting *populate_settings_uint(settings_t *settings,
|
|||
SETTING_UINT("rgui_internal_upscale_level", &settings->uints.menu_rgui_internal_upscale_level, true, rgui_internal_upscale_level, false);
|
||||
SETTING_UINT("rgui_aspect_ratio", &settings->uints.menu_rgui_aspect_ratio, true, rgui_aspect, false);
|
||||
SETTING_UINT("rgui_aspect_ratio_lock", &settings->uints.menu_rgui_aspect_ratio_lock, true, rgui_aspect_lock, false);
|
||||
SETTING_UINT("rgui_particle_effect", &settings->uints.menu_rgui_particle_effect, true, rgui_particle_effect, false);
|
||||
#endif
|
||||
#ifdef HAVE_LIBNX
|
||||
SETTING_UINT("split_joycon_p1", &settings->uints.input_split_joycon[0], true, 0, false);
|
||||
|
|
|
@ -173,7 +173,6 @@ typedef struct settings
|
|||
bool menu_rgui_border_filler_enable;
|
||||
bool menu_rgui_full_width_layout;
|
||||
bool menu_rgui_shadows;
|
||||
bool menu_rgui_snow;
|
||||
bool menu_rgui_inline_thumbnails;
|
||||
bool menu_rgui_swap_thumbnails;
|
||||
bool menu_rgui_extended_ascii;
|
||||
|
@ -455,6 +454,7 @@ typedef struct settings
|
|||
unsigned menu_rgui_internal_upscale_level;
|
||||
unsigned menu_rgui_aspect_ratio;
|
||||
unsigned menu_rgui_aspect_ratio_lock;
|
||||
unsigned menu_rgui_particle_effect;
|
||||
unsigned menu_ticker_type;
|
||||
|
||||
unsigned playlist_show_inline_core_name;
|
||||
|
|
|
@ -1627,8 +1627,8 @@ MSG_HASH(MENU_ENUM_LABEL_MENU_RGUI_FULL_WIDTH_LAYOUT,
|
|||
"menu_rgui_full_width_layout")
|
||||
MSG_HASH(MENU_ENUM_LABEL_MENU_RGUI_SHADOWS,
|
||||
"menu_rgui_shadows")
|
||||
MSG_HASH(MENU_ENUM_LABEL_MENU_RGUI_SNOW,
|
||||
"menu_rgui_snow")
|
||||
MSG_HASH(MENU_ENUM_LABEL_MENU_RGUI_PARTICLE_EFFECT,
|
||||
"rgui_particle_effect")
|
||||
MSG_HASH(MENU_ENUM_LABEL_MENU_RGUI_EXTENDED_ASCII,
|
||||
"rgui_extended_ascii")
|
||||
MSG_HASH(MENU_ENUM_LABEL_CONTENT_SHOW_REWIND,
|
||||
|
|
|
@ -6959,13 +6959,37 @@ MSG_HASH(
|
|||
"Enable drop shadows for menu text, borders and thumbnails. Has a modest performance impact."
|
||||
)
|
||||
MSG_HASH(
|
||||
MENU_ENUM_LABEL_VALUE_MENU_RGUI_SNOW,
|
||||
"Snow"
|
||||
MENU_ENUM_LABEL_VALUE_MENU_RGUI_PARTICLE_EFFECT,
|
||||
"Background Animation"
|
||||
)
|
||||
MSG_HASH(
|
||||
MENU_ENUM_SUBLABEL_MENU_RGUI_SNOW,
|
||||
"Enable snow, forces menu to update every frame"
|
||||
MENU_ENUM_SUBLABEL_MENU_RGUI_PARTICLE_EFFECT,
|
||||
"Enable background particle animation effect. Has a significant performance impact."
|
||||
)
|
||||
MSG_HASH(
|
||||
MENU_ENUM_LABEL_VALUE_RGUI_PARTICLE_EFFECT_NONE,
|
||||
"OFF"
|
||||
)
|
||||
MSG_HASH(
|
||||
MENU_ENUM_LABEL_VALUE_RGUI_PARTICLE_EFFECT_SNOW,
|
||||
"Snow (Light)"
|
||||
)
|
||||
MSG_HASH(
|
||||
MENU_ENUM_LABEL_VALUE_RGUI_PARTICLE_EFFECT_SNOW_ALT,
|
||||
"Snow (Heavy)"
|
||||
)
|
||||
MSG_HASH(
|
||||
MENU_ENUM_LABEL_VALUE_RGUI_PARTICLE_EFFECT_RAIN,
|
||||
"Rain"
|
||||
)
|
||||
MSG_HASH(
|
||||
MENU_ENUM_LABEL_VALUE_RGUI_PARTICLE_EFFECT_VORTEX,
|
||||
"Vortex"
|
||||
)
|
||||
MSG_HASH(
|
||||
MENU_ENUM_LABEL_VALUE_RGUI_PARTICLE_EFFECT_STARFIELD,
|
||||
"Star Field"
|
||||
)
|
||||
MSG_HASH(
|
||||
MENU_ENUM_LABEL_VALUE_MENU_RGUI_EXTENDED_ASCII,
|
||||
"Extended ASCII Support"
|
||||
|
|
|
@ -535,7 +535,7 @@ default_sublabel_macro(action_bind_sublabel_menu_rgui_aspect_ratio_lock,
|
|||
default_sublabel_macro(action_bind_sublabel_rgui_menu_color_theme, MENU_ENUM_SUBLABEL_RGUI_MENU_COLOR_THEME)
|
||||
default_sublabel_macro(action_bind_sublabel_rgui_menu_theme_preset, MENU_ENUM_SUBLABEL_RGUI_MENU_THEME_PRESET)
|
||||
default_sublabel_macro(action_bind_sublabel_menu_rgui_shadows, MENU_ENUM_SUBLABEL_MENU_RGUI_SHADOWS)
|
||||
default_sublabel_macro(action_bind_sublabel_menu_rgui_snow, MENU_ENUM_SUBLABEL_MENU_RGUI_SNOW)
|
||||
default_sublabel_macro(action_bind_sublabel_menu_rgui_particle_effect, MENU_ENUM_SUBLABEL_MENU_RGUI_PARTICLE_EFFECT)
|
||||
default_sublabel_macro(action_bind_sublabel_menu_rgui_inline_thumbnails, MENU_ENUM_SUBLABEL_MENU_RGUI_INLINE_THUMBNAILS)
|
||||
default_sublabel_macro(action_bind_sublabel_menu_rgui_swap_thumbnails, MENU_ENUM_SUBLABEL_MENU_RGUI_SWAP_THUMBNAILS)
|
||||
default_sublabel_macro(action_bind_sublabel_menu_rgui_thumbnail_downscaler, MENU_ENUM_SUBLABEL_MENU_RGUI_THUMBNAIL_DOWNSCALER)
|
||||
|
@ -2452,8 +2452,8 @@ int menu_cbs_init_bind_sublabel(menu_file_list_cbs_t *cbs,
|
|||
case MENU_ENUM_LABEL_MENU_RGUI_SHADOWS:
|
||||
BIND_ACTION_SUBLABEL(cbs, action_bind_sublabel_menu_rgui_shadows);
|
||||
break;
|
||||
case MENU_ENUM_LABEL_MENU_RGUI_SNOW:
|
||||
BIND_ACTION_SUBLABEL(cbs, action_bind_sublabel_menu_rgui_snow);
|
||||
case MENU_ENUM_LABEL_MENU_RGUI_PARTICLE_EFFECT:
|
||||
BIND_ACTION_SUBLABEL(cbs, action_bind_sublabel_menu_rgui_particle_effect);
|
||||
break;
|
||||
case MENU_ENUM_LABEL_MENU_RGUI_INLINE_THUMBNAILS:
|
||||
BIND_ACTION_SUBLABEL(cbs, action_bind_sublabel_menu_rgui_inline_thumbnails);
|
||||
|
|
|
@ -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(
|
||||
|
|
|
@ -267,6 +267,17 @@ enum rgui_aspect_ratio_lock
|
|||
RGUI_ASPECT_RATIO_LOCK_LAST
|
||||
};
|
||||
|
||||
enum rgui_particle_animation_effect
|
||||
{
|
||||
RGUI_PARTICLE_EFFECT_NONE = 0,
|
||||
RGUI_PARTICLE_EFFECT_SNOW,
|
||||
RGUI_PARTICLE_EFFECT_SNOW_ALT,
|
||||
RGUI_PARTICLE_EFFECT_RAIN,
|
||||
RGUI_PARTICLE_EFFECT_VORTEX,
|
||||
RGUI_PARTICLE_EFFECT_STARFIELD,
|
||||
RGUI_PARTICLE_EFFECT_LAST
|
||||
};
|
||||
|
||||
enum menu_action
|
||||
{
|
||||
MENU_ACTION_NOOP = 0,
|
||||
|
|
|
@ -4306,7 +4306,7 @@ unsigned menu_displaylist_build_list(file_list_t *list, enum menu_displaylist_ct
|
|||
{MENU_ENUM_LABEL_RGUI_MENU_COLOR_THEME, PARSE_ONLY_UINT},
|
||||
{MENU_ENUM_LABEL_RGUI_MENU_THEME_PRESET, PARSE_ONLY_PATH},
|
||||
{MENU_ENUM_LABEL_MENU_RGUI_SHADOWS, PARSE_ONLY_BOOL},
|
||||
{MENU_ENUM_LABEL_MENU_RGUI_SNOW, PARSE_ONLY_BOOL},
|
||||
{MENU_ENUM_LABEL_MENU_RGUI_PARTICLE_EFFECT, PARSE_ONLY_UINT},
|
||||
{MENU_ENUM_LABEL_DPI_OVERRIDE_ENABLE, PARSE_ONLY_BOOL},
|
||||
{MENU_ENUM_LABEL_DPI_OVERRIDE_VALUE, PARSE_ONLY_UINT},
|
||||
{MENU_ENUM_LABEL_XMB_ALPHA_FACTOR, PARSE_ONLY_UINT},
|
||||
|
|
|
@ -970,6 +970,54 @@ static void setting_get_string_representation_uint_rgui_aspect_ratio_lock(
|
|||
}
|
||||
}
|
||||
|
||||
static void setting_get_string_representation_uint_rgui_particle_effect(
|
||||
rarch_setting_t *setting,
|
||||
char *s, size_t len)
|
||||
{
|
||||
if (!setting)
|
||||
return;
|
||||
|
||||
switch (*setting->value.target.unsigned_integer)
|
||||
{
|
||||
case RGUI_PARTICLE_EFFECT_NONE:
|
||||
strlcpy(s,
|
||||
msg_hash_to_str(
|
||||
MENU_ENUM_LABEL_VALUE_RGUI_PARTICLE_EFFECT_NONE),
|
||||
len);
|
||||
break;
|
||||
case RGUI_PARTICLE_EFFECT_SNOW:
|
||||
strlcpy(s,
|
||||
msg_hash_to_str(
|
||||
MENU_ENUM_LABEL_VALUE_RGUI_PARTICLE_EFFECT_SNOW),
|
||||
len);
|
||||
break;
|
||||
case RGUI_PARTICLE_EFFECT_SNOW_ALT:
|
||||
strlcpy(s,
|
||||
msg_hash_to_str(
|
||||
MENU_ENUM_LABEL_VALUE_RGUI_PARTICLE_EFFECT_SNOW_ALT),
|
||||
len);
|
||||
break;
|
||||
case RGUI_PARTICLE_EFFECT_RAIN:
|
||||
strlcpy(s,
|
||||
msg_hash_to_str(
|
||||
MENU_ENUM_LABEL_VALUE_RGUI_PARTICLE_EFFECT_RAIN),
|
||||
len);
|
||||
break;
|
||||
case RGUI_PARTICLE_EFFECT_VORTEX:
|
||||
strlcpy(s,
|
||||
msg_hash_to_str(
|
||||
MENU_ENUM_LABEL_VALUE_RGUI_PARTICLE_EFFECT_VORTEX),
|
||||
len);
|
||||
break;
|
||||
case RGUI_PARTICLE_EFFECT_STARFIELD:
|
||||
strlcpy(s,
|
||||
msg_hash_to_str(
|
||||
MENU_ENUM_LABEL_VALUE_RGUI_PARTICLE_EFFECT_STARFIELD),
|
||||
len);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static void setting_get_string_representation_uint_menu_ticker_type(
|
||||
rarch_setting_t *setting,
|
||||
char *s, size_t len)
|
||||
|
@ -8599,20 +8647,22 @@ static bool setting_append_list(
|
|||
general_read_handler,
|
||||
SD_FLAG_NONE);
|
||||
|
||||
CONFIG_BOOL(
|
||||
CONFIG_UINT(
|
||||
list, list_info,
|
||||
&settings->bools.menu_rgui_snow,
|
||||
MENU_ENUM_LABEL_MENU_RGUI_SNOW,
|
||||
MENU_ENUM_LABEL_VALUE_MENU_RGUI_SNOW,
|
||||
rgui_snow,
|
||||
MENU_ENUM_LABEL_VALUE_OFF,
|
||||
MENU_ENUM_LABEL_VALUE_ON,
|
||||
&settings->uints.menu_rgui_particle_effect,
|
||||
MENU_ENUM_LABEL_MENU_RGUI_PARTICLE_EFFECT,
|
||||
MENU_ENUM_LABEL_VALUE_MENU_RGUI_PARTICLE_EFFECT,
|
||||
rgui_particle_effect,
|
||||
&group_info,
|
||||
&subgroup_info,
|
||||
parent_group,
|
||||
general_write_handler,
|
||||
general_read_handler,
|
||||
SD_FLAG_NONE);
|
||||
general_read_handler);
|
||||
(*list)[list_info->index - 1].action_ok = &setting_action_ok_uint;
|
||||
(*list)[list_info->index - 1].get_string_representation =
|
||||
&setting_get_string_representation_uint_rgui_particle_effect;
|
||||
menu_settings_list_current_add_range(list, list_info, 0, RGUI_PARTICLE_EFFECT_LAST-1, 1, true, true);
|
||||
(*list)[list_info->index - 1].ui_type = ST_UI_TYPE_UINT_COMBOBOX;
|
||||
|
||||
CONFIG_BOOL(
|
||||
list, list_info,
|
||||
|
|
|
@ -873,7 +873,7 @@ enum msg_hash_enums
|
|||
MENU_LABEL(MENU_RGUI_ASPECT_RATIO_LOCK),
|
||||
MENU_LABEL(MENU_RGUI_FULL_WIDTH_LAYOUT),
|
||||
MENU_LABEL(MENU_RGUI_SHADOWS),
|
||||
MENU_LABEL(MENU_RGUI_SNOW),
|
||||
MENU_LABEL(MENU_RGUI_PARTICLE_EFFECT),
|
||||
MENU_LABEL(MENU_RGUI_EXTENDED_ASCII),
|
||||
MENU_LABEL(MENU_LINEAR_FILTER),
|
||||
MENU_LABEL(MENU_HORIZONTAL_ANIMATION),
|
||||
|
@ -2016,6 +2016,13 @@ enum msg_hash_enums
|
|||
MENU_ENUM_LABEL_VALUE_RGUI_ASPECT_RATIO_LOCK_FIT_SCREEN,
|
||||
MENU_ENUM_LABEL_VALUE_RGUI_ASPECT_RATIO_LOCK_INTEGER,
|
||||
|
||||
MENU_ENUM_LABEL_VALUE_RGUI_PARTICLE_EFFECT_NONE,
|
||||
MENU_ENUM_LABEL_VALUE_RGUI_PARTICLE_EFFECT_SNOW,
|
||||
MENU_ENUM_LABEL_VALUE_RGUI_PARTICLE_EFFECT_SNOW_ALT,
|
||||
MENU_ENUM_LABEL_VALUE_RGUI_PARTICLE_EFFECT_RAIN,
|
||||
MENU_ENUM_LABEL_VALUE_RGUI_PARTICLE_EFFECT_VORTEX,
|
||||
MENU_ENUM_LABEL_VALUE_RGUI_PARTICLE_EFFECT_STARFIELD,
|
||||
|
||||
/* Callback strings */
|
||||
MENU_ENUM_LABEL_CB_CORE_CONTENT_DIRS_LIST,
|
||||
MENU_ENUM_LABEL_CB_CORE_CONTENT_DOWNLOAD,
|
||||
|
|
Loading…
Reference in New Issue