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_filebrowser.h": "c",
"ozone_sidebar.h": "c",
"menu_thumbnail_path.h": "c"
"menu_thumbnail_path.h": "c",
"badges.h": "c"
},
"C_Cpp.dimInactiveRegions": false,
}

View File

@ -35,6 +35,9 @@
#ifdef HAVE_MENU
#include "../menu/menu_driver.h"
#include "../menu/menu_entries.h"
#ifdef HAVE_MENU_WIDGETS
#include "../menu/widgets/menu_widgets.h"
#endif
#endif
#ifdef HAVE_THREADS
@ -492,9 +495,14 @@ static void cheevos_award(cheevos_cheevo_t* cheevo, int mode)
cheevo->active &= ~CHEEVOS_ACTIVE_SOFTCORE;
/* Show the OSD message. */
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);
#if defined(HAVE_MENU) && defined(HAVE_MENU_WIDGETS)
if (!video_driver_has_widgets() || !menu_widgets_push_achievement(cheevo->title, cheevo->badge))
#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. */
if ((mode & CHEEVOS_ACTIVE_HARDCORE) != 0)
@ -1676,6 +1684,9 @@ found:
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();
if (!(

View File

@ -36,6 +36,9 @@
#ifdef HAVE_MENU
#include "../menu/menu_driver.h"
#include "../menu/menu_entries.h"
#ifdef HAVE_MENU_WIDGETS
#include "../menu/widgets/menu_widgets.h"
#endif
#endif
#ifdef HAVE_THREADS
@ -1643,9 +1646,8 @@ static void cheevos_test_cheevo_set(const cheevoset_t *set)
}
else if (valid)
{
char msg[256];
char url[256];
msg[0] = url[0] = '\0';
url[0] = '\0';
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",
cheevo->id, cheevo->title, cheevo->description);
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);
#if defined(HAVE_MENU) && defined(HAVE_MENU_WIDGETS)
if (!video_driver_has_widgets() || !menu_widgets_push_achievement(cheevo->title, cheevo->badge))
#endif
{
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));
task_push_http_transfer(url, true, NULL,
@ -3195,6 +3204,9 @@ found:
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();
if (!(

View File

@ -1074,6 +1074,8 @@ int font_driver_get_message_width(void *font_data,
const char *msg, unsigned len, float scale)
{
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)
return font->renderer->get_message_width(font->renderer_data, msg, len, scale);
return -1;

View File

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

View File

@ -38,8 +38,9 @@
#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_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,
};
/* 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 */
#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 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,
@ -188,7 +200,9 @@ enum menu_widgets_icon
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] = {
@ -205,7 +219,9 @@ static char *menu_widgets_icons_names[MENU_WIDGETS_ICON_LAST] = {
"menu_hourglass.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};
@ -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,
video_info->width, video_info->height,
0, 1, menu_widgets_pure_white);
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_draw_quad(video_info,
0, screenshot_y,
0, screenshot_y,
screenshot_width, screenshot_height,
video_info->width, video_info->height,
menu_widgets_backdrop_orig
);
menu_display_set_alpha(menu_widgets_pure_white, 1.0f);
menu_widgets_draw_icon(video_info,
screenshot_thumbnail_width, screenshot_thumbnail_height,
screenshot_texture,
0, screenshot_y,
video_info->width, video_info->height,
menu_widgets_draw_icon(video_info,
screenshot_thumbnail_width, screenshot_thumbnail_height,
screenshot_texture,
0, screenshot_y,
video_info->width, video_info->height,
0, 1, menu_widgets_pure_white
);
menu_display_draw_text(font_regular,
msg_hash_to_str(MSG_SCREENSHOT_SAVED),
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 */
if (volume_alpha > 0.0f)
{
@ -1700,9 +1796,9 @@ void menu_widgets_context_reset(bool is_threaded)
}
/* Metrics */
simple_widget_padding = settings->floats.video_font_size * 2/3;
simple_widget_height = settings->floats.video_font_size + simple_widget_padding;
glyph_width = font_driver_get_message_width(font_regular, "a", 1, 1);
simple_widget_padding = settings->floats.video_font_size * 2/3;
simple_widget_height = settings->floats.video_font_size + simple_widget_padding;
glyph_width = font_driver_get_message_width(font_regular, "a", 1, 1);
msg_queue_height = settings->floats.video_font_size * 2.5f;
@ -1772,6 +1868,21 @@ void menu_widgets_context_destroy(void)
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)
{
int i;
@ -1802,7 +1913,7 @@ void menu_widgets_free(void)
}
/* Purge everything from the list */
if (current_msgs)
if (current_msgs)
{
for (i = 0; i < current_msgs->size; i++)
{
@ -1813,6 +1924,10 @@ void menu_widgets_free(void)
file_list_free(current_msgs);
}
/* Achievement notification */
menu_widgets_achievement_free(NULL);
/* Screenshot texture */
video_driver_texture_unload(&screenshot_texture);
/* Font */
@ -1859,15 +1974,6 @@ bool menu_widgets_volume_update_and_show(void)
volume_text_alpha = 1.0f;
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.duration = VOLUME_DURATION;
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));
}
bool menu_widgets_task_msg_queue_push(retro_task_t *task,
const char *msg,
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;
}
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)
{
return menu_widgets_inited;

View File

@ -31,6 +31,7 @@
#define SCREENSHOT_DURATION_IN 66
#define SCREENSHOT_DURATION_OUT SCREENSHOT_DURATION_IN*10
#define SCREENSHOT_NOTIFICATION_DURATION 4000
#define CHEEVO_NOTIFICATION_DURATION 4000
#define TASK_FINISHED_DURATION 3000
#define HOURGLASS_INTERVAL 5000
#define HOURGLASS_DURATION 1000
@ -69,8 +70,10 @@ void menu_widgets_context_reset(bool is_threaded);
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
* 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 */
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_TAKING_SCREENSHOT,
MSG_SCREENSHOT_SAVED,
MSG_ACHIEVEMENT_UNLOCKED,
MSG_CHANGE_THUMBNAIL_TYPE,
MSG_NO_THUMBNAIL_AVAILABLE,
MSG_PRESS_AGAIN_TO_QUIT,