menu widgets: add first achievement notification widget

This commit is contained in:
natinusala 2019-04-11 16:46:29 +02:00
parent 942d228e3a
commit f941d4e625
8 changed files with 278 additions and 38 deletions

View File

@ -67,7 +67,8 @@
"menu_input_dialog.h": "c", "menu_input_dialog.h": "c",
"menu_filebrowser.h": "c", "menu_filebrowser.h": "c",
"ozone_sidebar.h": "c", "ozone_sidebar.h": "c",
"menu_thumbnail_path.h": "c" "menu_thumbnail_path.h": "c",
"badges.h": "c"
}, },
"C_Cpp.dimInactiveRegions": false, "C_Cpp.dimInactiveRegions": false,
} }

View File

@ -35,6 +35,9 @@
#ifdef HAVE_MENU #ifdef HAVE_MENU
#include "../menu/menu_driver.h" #include "../menu/menu_driver.h"
#include "../menu/menu_entries.h" #include "../menu/menu_entries.h"
#ifdef HAVE_MENU_WIDGETS
#include "../menu/widgets/menu_widgets.h"
#endif
#endif #endif
#ifdef HAVE_THREADS #ifdef HAVE_THREADS
@ -492,9 +495,14 @@ static void cheevos_award(cheevos_cheevo_t* cheevo, int mode)
cheevo->active &= ~CHEEVOS_ACTIVE_SOFTCORE; cheevo->active &= ~CHEEVOS_ACTIVE_SOFTCORE;
/* Show the OSD message. */ /* Show the OSD message. */
snprintf(buffer, sizeof(buffer), "Achievement Unlocked: %s", cheevo->info->title); #if defined(HAVE_MENU) && defined(HAVE_MENU_WIDGETS)
runloop_msg_queue_push(buffer, 0, 2 * 60, false, NULL, MESSAGE_QUEUE_ICON_DEFAULT, MESSAGE_QUEUE_CATEGORY_INFO); if (!video_driver_has_widgets() || !menu_widgets_push_achievement(cheevo->title, cheevo->badge))
runloop_msg_queue_push(cheevo->info->description, 0, 3 * 60, false, NULL, MESSAGE_QUEUE_ICON_DEFAULT, MESSAGE_QUEUE_CATEGORY_INFO); #endif
{
snprintf(buffer, sizeof(buffer), "Achievement Unlocked: %s", cheevo->info->title);
runloop_msg_queue_push(buffer, 0, 2 * 60, false, NULL, MESSAGE_QUEUE_ICON_DEFAULT, MESSAGE_QUEUE_CATEGORY_INFO);
runloop_msg_queue_push(cheevo->info->description, 0, 3 * 60, false, NULL, MESSAGE_QUEUE_ICON_DEFAULT, MESSAGE_QUEUE_CATEGORY_INFO);
}
/* Start the award task. */ /* Start the award task. */
if ((mode & CHEEVOS_ACTIVE_HARDCORE) != 0) if ((mode & CHEEVOS_ACTIVE_HARDCORE) != 0)
@ -1676,6 +1684,9 @@ found:
badges_ctx = new_badges_ctx; badges_ctx = new_badges_ctx;
#ifdef HAVE_MENU_WIDGETS
if (false) /* we always want badges if menu widgets are enabled */
#endif
{ {
settings_t *settings = config_get_ptr(); settings_t *settings = config_get_ptr();
if (!( if (!(

View File

@ -36,6 +36,9 @@
#ifdef HAVE_MENU #ifdef HAVE_MENU
#include "../menu/menu_driver.h" #include "../menu/menu_driver.h"
#include "../menu/menu_entries.h" #include "../menu/menu_entries.h"
#ifdef HAVE_MENU_WIDGETS
#include "../menu/widgets/menu_widgets.h"
#endif
#endif #endif
#ifdef HAVE_THREADS #ifdef HAVE_THREADS
@ -1643,9 +1646,8 @@ static void cheevos_test_cheevo_set(const cheevoset_t *set)
} }
else if (valid) else if (valid)
{ {
char msg[256];
char url[256]; char url[256];
msg[0] = url[0] = '\0'; url[0] = '\0';
cheevo->active &= ~mode; cheevo->active &= ~mode;
@ -1655,11 +1657,18 @@ static void cheevos_test_cheevo_set(const cheevoset_t *set)
CHEEVOS_LOG("[CHEEVOS]: awarding cheevo %u: %s (%s).\n", CHEEVOS_LOG("[CHEEVOS]: awarding cheevo %u: %s (%s).\n",
cheevo->id, cheevo->title, cheevo->description); cheevo->id, cheevo->title, cheevo->description);
snprintf(msg, sizeof(msg), "Achievement Unlocked: %s", #if defined(HAVE_MENU) && defined(HAVE_MENU_WIDGETS)
cheevo->title); if (!video_driver_has_widgets() || !menu_widgets_push_achievement(cheevo->title, cheevo->badge))
msg[sizeof(msg) - 1] = 0; #endif
runloop_msg_queue_push(msg, 0, 2 * 60, false, NULL, MESSAGE_QUEUE_ICON_DEFAULT, MESSAGE_QUEUE_CATEGORY_INFO); {
runloop_msg_queue_push(cheevo->description, 0, 3 * 60, false, NULL, MESSAGE_QUEUE_ICON_DEFAULT, MESSAGE_QUEUE_CATEGORY_INFO); char msg[256];
msg[0] = '\0';
snprintf(msg, sizeof(msg), "Achievement Unlocked: %s",
cheevo->title);
msg[sizeof(msg) - 1] = 0;
runloop_msg_queue_push(msg, 0, 2 * 60, false, NULL, MESSAGE_QUEUE_ICON_DEFAULT, MESSAGE_QUEUE_CATEGORY_INFO);
runloop_msg_queue_push(cheevo->description, 0, 3 * 60, false, NULL, MESSAGE_QUEUE_ICON_DEFAULT, MESSAGE_QUEUE_CATEGORY_INFO);
}
cheevos_make_unlock_url(cheevo, url, sizeof(url)); cheevos_make_unlock_url(cheevo, url, sizeof(url));
task_push_http_transfer(url, true, NULL, task_push_http_transfer(url, true, NULL,
@ -3195,6 +3204,9 @@ found:
badges_ctx = new_badges_ctx; badges_ctx = new_badges_ctx;
#ifdef HAVE_MENU_WIDGETS
if (false) /* we always want badges if menu widgets are enabled */
#endif
{ {
settings_t *settings = config_get_ptr(); settings_t *settings = config_get_ptr();
if (!( if (!(

View File

@ -1074,6 +1074,8 @@ int font_driver_get_message_width(void *font_data,
const char *msg, unsigned len, float scale) const char *msg, unsigned len, float scale)
{ {
font_data_t *font = (font_data_t*)(font_data ? font_data : video_font_driver); font_data_t *font = (font_data_t*)(font_data ? font_data : video_font_driver);
if (len == 0 && msg)
len = (unsigned)strlen(msg);
if (font && font->renderer && font->renderer->get_message_width) if (font && font->renderer && font->renderer->get_message_width)
return font->renderer->get_message_width(font->renderer_data, msg, len, scale); return font->renderer->get_message_width(font->renderer_data, msg, len, scale);
return -1; return -1;

View File

@ -4882,6 +4882,10 @@ MSG_HASH(
MSG_SCREENSHOT_SAVED, MSG_SCREENSHOT_SAVED,
"Screenshot saved" "Screenshot saved"
) )
MSG_HASH(
MSG_ACHIEVEMENT_UNLOCKED,
"Achievement Unlocked"
)
MSG_HASH( MSG_HASH(
MSG_CHANGE_THUMBNAIL_TYPE, MSG_CHANGE_THUMBNAIL_TYPE,
"Change thumbnail type" "Change thumbnail type"

View File

@ -38,8 +38,9 @@
#define PI 3.14159265359f #define PI 3.14159265359f
/* TODO: Fix context reset freezing everything in place (probably kills animations when it shouldn't anymore) */ #define max(x, y) x >= y ? x : y
/* TODO: Fix context reset freezing everything in place (probably kills animations when it shouldn't anymore) */
static float msg_queue_background[16] = COLOR_HEX_TO_FLOAT(0x3A3A3A, 1.0f); static float msg_queue_background[16] = COLOR_HEX_TO_FLOAT(0x3A3A3A, 1.0f);
static float msg_queue_info[16] = COLOR_HEX_TO_FLOAT(0x12ACF8, 1.0f); static float msg_queue_info[16] = COLOR_HEX_TO_FLOAT(0x12ACF8, 1.0f);
@ -79,6 +80,17 @@ static float menu_widgets_pure_white[16] = {
1.00, 1.00, 1.00, 1.00, 1.00, 1.00, 1.00, 1.00,
}; };
/* Achievement notification */
static char *cheevo_title = NULL;
static char *cheevo_badge = NULL;
static float cheevo_unfold = 0.0f;
static menu_timer_t cheevo_timer;
static float cheevo_y = 0.0f;
static unsigned cheevo_width = 0;
static unsigned cheevo_height = 0;
/* Load content animation */ /* Load content animation */
#define ANIMATION_LOAD_CONTENT_DURATION 333 #define ANIMATION_LOAD_CONTENT_DURATION 333
@ -98,7 +110,7 @@ static float load_content_animation_final_fade_alpha;
static menu_timer_t load_content_animation_end_timer; static menu_timer_t load_content_animation_end_timer;
static float menu_widgets_backdrop_orig[16] = { static float menu_widgets_backdrop_orig[16] = {
0.00, 0.00, 0.00, 0.75, 0.00, 0.00, 0.00, 0.75,
0.00, 0.00, 0.00, 0.75, 0.00, 0.00, 0.00, 0.75,
0.00, 0.00, 0.00, 0.75, 0.00, 0.00, 0.00, 0.75,
@ -188,7 +200,9 @@ enum menu_widgets_icon
MENU_WIDGETS_ICON_INFO, MENU_WIDGETS_ICON_INFO,
MENU_WIDGETS_ICON_LAST MENU_WIDGETS_ICON_ACHIEVEMENT,
MENU_WIDGETS_ICON_LAST,
}; };
static char *menu_widgets_icons_names[MENU_WIDGETS_ICON_LAST] = { static char *menu_widgets_icons_names[MENU_WIDGETS_ICON_LAST] = {
@ -205,7 +219,9 @@ static char *menu_widgets_icons_names[MENU_WIDGETS_ICON_LAST] = {
"menu_hourglass.png", "menu_hourglass.png",
"menu_check.png", "menu_check.png",
"menu_info.png" "menu_info.png",
"menu_achievements.png"
}; };
static menu_texture_item menu_widgets_icons_textures[MENU_WIDGETS_ICON_LAST] = {0}; static menu_texture_item menu_widgets_icons_textures[MENU_WIDGETS_ICON_LAST] = {0};
@ -1211,7 +1227,7 @@ static void menu_widgets_draw_regular_msg(menu_widget_msg_t *msg, video_frame_in
icon, msg_queue_spacing + msg_queue_internal_icon_offset, video_info->height - msg->offset_y - msg_queue_icon_offset_y + msg_queue_internal_icon_offset, icon, msg_queue_spacing + msg_queue_internal_icon_offset, video_info->height - msg->offset_y - msg_queue_icon_offset_y + msg_queue_internal_icon_offset,
video_info->width, video_info->height, video_info->width, video_info->height,
0, 1, menu_widgets_pure_white); 0, 1, menu_widgets_pure_white);
menu_display_blend_end(video_info); menu_display_blend_end(video_info);
} }
} }
@ -1305,21 +1321,21 @@ void menu_widgets_frame(video_frame_info_t *video_info)
menu_display_set_alpha(menu_widgets_backdrop_orig, DEFAULT_BACKDROP); menu_display_set_alpha(menu_widgets_backdrop_orig, DEFAULT_BACKDROP);
menu_display_draw_quad(video_info, menu_display_draw_quad(video_info,
0, screenshot_y, 0, screenshot_y,
screenshot_width, screenshot_height, screenshot_width, screenshot_height,
video_info->width, video_info->height, video_info->width, video_info->height,
menu_widgets_backdrop_orig menu_widgets_backdrop_orig
); );
menu_display_set_alpha(menu_widgets_pure_white, 1.0f); menu_display_set_alpha(menu_widgets_pure_white, 1.0f);
menu_widgets_draw_icon(video_info, menu_widgets_draw_icon(video_info,
screenshot_thumbnail_width, screenshot_thumbnail_height, screenshot_thumbnail_width, screenshot_thumbnail_height,
screenshot_texture, screenshot_texture,
0, screenshot_y, 0, screenshot_y,
video_info->width, video_info->height, video_info->width, video_info->height,
0, 1, menu_widgets_pure_white 0, 1, menu_widgets_pure_white
); );
menu_display_draw_text(font_regular, menu_display_draw_text(font_regular,
msg_hash_to_str(MSG_SCREENSHOT_SAVED), msg_hash_to_str(MSG_SCREENSHOT_SAVED),
screenshot_thumbnail_width + simple_widget_padding, settings->floats.video_font_size * 1.9f + screenshot_y, screenshot_thumbnail_width + simple_widget_padding, settings->floats.video_font_size * 1.9f + screenshot_y,
@ -1347,6 +1363,86 @@ void menu_widgets_frame(video_frame_info_t *video_info)
); );
} }
/* Achievement notification */
if (cheevo_title)
{
unsigned unfold_offet = ((1.0f-cheevo_unfold) * cheevo_width/2);
menu_display_set_alpha(menu_widgets_backdrop_orig, DEFAULT_BACKDROP);
/* Default icon */
if (!cheevo_badge)
{
/* Backdrop */
menu_display_draw_quad(video_info,
0, (int)cheevo_y,
cheevo_height, cheevo_height,
video_info->width, video_info->height,
menu_widgets_backdrop_orig);
/* Icon */
if (menu_widgets_icons_textures[MENU_WIDGETS_ICON_ACHIEVEMENT])
{
menu_display_blend_begin(video_info);
menu_display_set_alpha(menu_widgets_pure_white, 1.0f);
menu_widgets_draw_icon(video_info,
cheevo_height, cheevo_height,
menu_widgets_icons_textures[MENU_WIDGETS_ICON_ACHIEVEMENT], 0, cheevo_y,
video_info->width, video_info->height, 0, 1, menu_widgets_pure_white);
menu_display_blend_end(video_info);
}
}
/* Badge */
else
{
/* TODO: Display the badge */
}
if (cheevo_unfold != 1.0f)
{
menu_display_scissor_begin(video_info,
cheevo_height, 0,
(unsigned)((float)(cheevo_width) * cheevo_unfold), cheevo_height);
}
/* Backdrop */
menu_display_draw_quad(video_info,
cheevo_height, (int)cheevo_y,
cheevo_width, cheevo_height,
video_info->width, video_info->height,
menu_widgets_backdrop_orig);
/* Title */
menu_display_draw_text(font_regular,
msg_hash_to_str(MSG_ACHIEVEMENT_UNLOCKED),
cheevo_height + simple_widget_padding - unfold_offet, settings->floats.video_font_size * 1.9f + cheevo_y,
video_info->width, video_info->height,
text_color_faint,
TEXT_ALIGN_LEFT,
1, false, 0, true
);
/* Title */
/* TODO: is a ticker necessary ? */
menu_display_draw_text(font_regular,
cheevo_title,
cheevo_height + simple_widget_padding - unfold_offet, settings->floats.video_font_size * 2.9f + cheevo_y,
video_info->width, video_info->height,
text_color_info,
TEXT_ALIGN_LEFT,
1, false, 0, true
);
if (cheevo_unfold != 1.0f)
{
font_driver_flush(video_info->width, video_info->height, font_regular, video_info);
font_raster_regular.carr.coords.vertices = 0;
menu_display_scissor_end(video_info);
}
}
/* Volume */ /* Volume */
if (volume_alpha > 0.0f) if (volume_alpha > 0.0f)
{ {
@ -1700,9 +1796,9 @@ void menu_widgets_context_reset(bool is_threaded)
} }
/* Metrics */ /* Metrics */
simple_widget_padding = settings->floats.video_font_size * 2/3; simple_widget_padding = settings->floats.video_font_size * 2/3;
simple_widget_height = settings->floats.video_font_size + simple_widget_padding; simple_widget_height = settings->floats.video_font_size + simple_widget_padding;
glyph_width = font_driver_get_message_width(font_regular, "a", 1, 1); glyph_width = font_driver_get_message_width(font_regular, "a", 1, 1);
msg_queue_height = settings->floats.video_font_size * 2.5f; msg_queue_height = settings->floats.video_font_size * 2.5f;
@ -1772,6 +1868,21 @@ void menu_widgets_context_destroy(void)
font_bold = NULL; font_bold = NULL;
} }
static void menu_widgets_achievement_free(void *userdata)
{
if (cheevo_title)
{
free(cheevo_title);
cheevo_title = NULL;
}
if (cheevo_badge)
{
free(cheevo_badge);
cheevo_badge = NULL;
}
}
void menu_widgets_free(void) void menu_widgets_free(void)
{ {
int i; int i;
@ -1802,7 +1913,7 @@ void menu_widgets_free(void)
} }
/* Purge everything from the list */ /* Purge everything from the list */
if (current_msgs) if (current_msgs)
{ {
for (i = 0; i < current_msgs->size; i++) for (i = 0; i < current_msgs->size; i++)
{ {
@ -1813,6 +1924,10 @@ void menu_widgets_free(void)
file_list_free(current_msgs); file_list_free(current_msgs);
} }
/* Achievement notification */
menu_widgets_achievement_free(NULL);
/* Screenshot texture */
video_driver_texture_unload(&screenshot_texture); video_driver_texture_unload(&screenshot_texture);
/* Font */ /* Font */
@ -1859,15 +1974,6 @@ bool menu_widgets_volume_update_and_show(void)
volume_text_alpha = 1.0f; volume_text_alpha = 1.0f;
volume_mute = mute; volume_mute = mute;
/* TODO/FIXME - natinusula -
*
menu/widgets/menu_widgets.c: In function 'menu_widgets_volume_update_and_show':
menu/widgets/menu_widgets.c:1859:19: warning: assignment to 'tween_cb' {aka 'void (*)(void *)'} from incompatible pointer type 'void (*)(void)' [-Wincompatible-pointer-types]
entry.cb = menu_widgets_volume_timer_end;
^
*
*
*/
entry.cb = menu_widgets_volume_timer_end; entry.cb = menu_widgets_volume_timer_end;
entry.duration = VOLUME_DURATION; entry.duration = VOLUME_DURATION;
entry.userdata = NULL; entry.userdata = NULL;
@ -1951,7 +2057,6 @@ void menu_widgets_screenshot_taken(const char *shotname, const char *filename)
strlcpy(screenshot_shotname, shotname, sizeof(screenshot_shotname)); strlcpy(screenshot_shotname, shotname, sizeof(screenshot_shotname));
} }
bool menu_widgets_task_msg_queue_push(retro_task_t *task, bool menu_widgets_task_msg_queue_push(retro_task_t *task,
const char *msg, const char *msg,
unsigned prio, unsigned duration, unsigned prio, unsigned duration,
@ -2080,6 +2185,107 @@ void menu_widgets_start_load_content_animation(const char *content_name, bool re
load_content_animation_running = true; load_content_animation_running = true;
} }
static void menu_widgets_achievement_dismiss(void *userdata)
{
menu_animation_ctx_entry_t entry;
/* Slide up animation */
entry.cb = menu_widgets_achievement_free;
entry.duration = MSG_QUEUE_ANIMATION_DURATION;
entry.easing_enum = EASING_OUT_QUAD;
entry.subject = &cheevo_y;
entry.tag = generic_tag;
entry.target_value = (float)(-(int)(cheevo_height));
entry.userdata = NULL;
menu_animation_push(&entry);
}
static void menu_widgets_achievement_fold(void *userdata)
{
menu_animation_ctx_entry_t entry;
/* Fold */
entry.cb = menu_widgets_achievement_dismiss;
entry.duration = MSG_QUEUE_ANIMATION_DURATION;
entry.easing_enum = EASING_OUT_QUAD;
entry.subject = &cheevo_unfold;
entry.tag = generic_tag;
entry.target_value = 0.0f;
entry.userdata = NULL;
menu_animation_push(&entry);
}
static void menu_widgets_achievement_unfold(void *userdata)
{
menu_animation_ctx_entry_t entry;
menu_timer_ctx_entry_t timer;
/* Unfold */
entry.cb = NULL;
entry.duration = MSG_QUEUE_ANIMATION_DURATION;
entry.easing_enum = EASING_OUT_QUAD;
entry.subject = &cheevo_unfold;
entry.tag = generic_tag;
entry.target_value = 1.0f;
entry.userdata = NULL;
menu_animation_push(&entry);
/* Wait before dismissing */
timer.cb = menu_widgets_achievement_fold;
timer.duration = MSG_QUEUE_ANIMATION_DURATION + CHEEVO_NOTIFICATION_DURATION;
timer.userdata = NULL;
menu_timer_start(&cheevo_timer, &timer);
}
static void menu_widgets_start_achievement_notification()
{
settings_t *settings = config_get_ptr();
menu_animation_ctx_entry_t entry;
cheevo_height = settings->floats.video_font_size * 4;
cheevo_width = max(
font_driver_get_message_width(font_regular, msg_hash_to_str(MSG_ACHIEVEMENT_UNLOCKED), 0, 1),
font_driver_get_message_width(font_regular, cheevo_title, 0, 1)
);
cheevo_width += simple_widget_padding * 2;
cheevo_y = (float)(-(int)cheevo_height);
cheevo_unfold = 0.0f;
/* Slide down animation */
entry.cb = menu_widgets_achievement_unfold;
entry.duration = MSG_QUEUE_ANIMATION_DURATION;
entry.easing_enum = EASING_OUT_QUAD;
entry.subject = &cheevo_y;
entry.tag = generic_tag;
entry.target_value = 0.0f;
entry.userdata = NULL;
menu_animation_push(&entry);
}
bool menu_widgets_push_achievement(const char *title, const char *badge)
{
if (!menu_widgets_inited)
return false;
menu_widgets_achievement_free(NULL);
/* TODO: Make a queue of notifications to display */
cheevo_title = strdup(title);
/* TODO: Check if badge exists before copying it */
/* cheevo_badge = strdup(badge); */
cheevo_badge = NULL;
menu_widgets_start_achievement_notification();
return true;
}
bool menu_widgets_ready(void) bool menu_widgets_ready(void)
{ {
return menu_widgets_inited; return menu_widgets_inited;

View File

@ -31,6 +31,7 @@
#define SCREENSHOT_DURATION_IN 66 #define SCREENSHOT_DURATION_IN 66
#define SCREENSHOT_DURATION_OUT SCREENSHOT_DURATION_IN*10 #define SCREENSHOT_DURATION_OUT SCREENSHOT_DURATION_IN*10
#define SCREENSHOT_NOTIFICATION_DURATION 4000 #define SCREENSHOT_NOTIFICATION_DURATION 4000
#define CHEEVO_NOTIFICATION_DURATION 4000
#define TASK_FINISHED_DURATION 3000 #define TASK_FINISHED_DURATION 3000
#define HOURGLASS_INTERVAL 5000 #define HOURGLASS_INTERVAL 5000
#define HOURGLASS_DURATION 1000 #define HOURGLASS_DURATION 1000
@ -69,8 +70,10 @@ void menu_widgets_context_reset(bool is_threaded);
void menu_widgets_context_destroy(void); void menu_widgets_context_destroy(void);
bool menu_widgets_push_achievement(const char *title, const char *badge);
/* All the functions below should be called in /* All the functions below should be called in
* the video driver - once they are all added, set * the video driver - once they are all added, set
* enable_menu_widgets to true for that driver */ * enable_menu_widgets to true for that driver */
void menu_widgets_frame(video_frame_info_t *video_info); void menu_widgets_frame(video_frame_info_t *video_info);

View File

@ -347,6 +347,7 @@ enum msg_hash_enums
MSG_MOVIE_PLAYBACK_ENDED, MSG_MOVIE_PLAYBACK_ENDED,
MSG_TAKING_SCREENSHOT, MSG_TAKING_SCREENSHOT,
MSG_SCREENSHOT_SAVED, MSG_SCREENSHOT_SAVED,
MSG_ACHIEVEMENT_UNLOCKED,
MSG_CHANGE_THUMBNAIL_TYPE, MSG_CHANGE_THUMBNAIL_TYPE,
MSG_NO_THUMBNAIL_AVAILABLE, MSG_NO_THUMBNAIL_AVAILABLE,
MSG_PRESS_AGAIN_TO_QUIT, MSG_PRESS_AGAIN_TO_QUIT,