queue multiple popups

This commit is contained in:
Jamiras 2020-02-28 08:49:00 -07:00
parent 385b0b71e7
commit daad8bcca0
2 changed files with 176 additions and 79 deletions

View File

@ -28,6 +28,13 @@ static uintptr_t cheevos_badge_menu_texture_list[CHEEVOS_MENU_BADGE_LIMIT] = { 0
void cheevos_reset_menu_badges(void) void cheevos_reset_menu_badges(void)
{ {
int index;
for (index = 0; index < CHEEVOS_MENU_BADGE_LIMIT; ++index)
{
if (cheevos_badge_menu_texture_list[index])
video_driver_texture_unload(&cheevos_badge_menu_texture_list[index]);
}
memset(&cheevos_badge_menu_texture_list, 0, sizeof(cheevos_badge_menu_texture_list)); memset(&cheevos_badge_menu_texture_list, 0, sizeof(cheevos_badge_menu_texture_list));
} }

View File

@ -24,6 +24,15 @@
#include <string/stdstring.h> #include <string/stdstring.h>
#include <retro_math.h> #include <retro_math.h>
#ifdef HAVE_THREADS
#include <rthreads/rthreads.h>
#define SLOCK_LOCK(x) slock_lock(x)
#define SLOCK_UNLOCK(x) slock_unlock(x)
#else
#define SLOCK_LOCK(x)
#define SLOCK_UNLOCK(x)
#endif
#include "gfx_widgets.h" #include "gfx_widgets.h"
#include "gfx_animation.h" #include "gfx_animation.h"
@ -85,15 +94,29 @@ static char gfx_widgets_fps_text[255] = {0};
#ifdef HAVE_CHEEVOS #ifdef HAVE_CHEEVOS
/* Achievement notification */ /* Achievement notification */
static char *cheevo_title = NULL; typedef struct cheevo_popup
static uintptr_t cheevo_badge = 0; {
static float cheevo_unfold = 0.0f; char* title;
uintptr_t badge;
} cheevo_popup;
#define CHEEVO_QUEUE_SIZE 8
static cheevo_popup cheevo_popup_queue[CHEEVO_QUEUE_SIZE];
static int cheevo_popup_queue_read_index = -1;
static int cheevo_popup_queue_write_index = 0;
#ifdef HAVE_THREADS
slock_t* cheevo_popup_queue_lock = NULL;
#endif
static float cheevo_unfold = 0.0f;
static gfx_timer_t cheevo_timer; static gfx_timer_t cheevo_timer;
static float cheevo_y = 0.0f; static float cheevo_y = 0.0f;
static unsigned cheevo_width = 0; static unsigned cheevo_width = 0;
static unsigned cheevo_height = 0; static unsigned cheevo_height = 0;
static void gfx_widgets_start_achievement_notification(void);
#endif #endif
#ifdef HAVE_MENU #ifdef HAVE_MENU
@ -1572,88 +1595,95 @@ void gfx_widgets_frame(void *data)
#ifdef HAVE_CHEEVOS #ifdef HAVE_CHEEVOS
/* Achievement notification */ /* Achievement notification */
if (cheevo_title) if (cheevo_popup_queue_read_index >= 0 && cheevo_popup_queue[cheevo_popup_queue_read_index].title)
{ {
unsigned unfold_offet = ((1.0f-cheevo_unfold) * cheevo_width/2); SLOCK_LOCK(cheevo_popup_queue_lock);
gfx_display_set_alpha(gfx_widgets_backdrop_orig, DEFAULT_BACKDROP); if (cheevo_popup_queue[cheevo_popup_queue_read_index].title)
gfx_display_set_alpha(gfx_widgets_pure_white, 1.0f);
/* Default icon */
if (!cheevo_badge)
{ {
/* Backdrop */ unsigned unfold_offet = ((1.0f - cheevo_unfold) * cheevo_width / 2);
gfx_display_draw_quad(video_info,
0, (int)cheevo_y,
cheevo_height, cheevo_height,
video_info->width, video_info->height,
gfx_widgets_backdrop_orig);
/* Icon */ gfx_display_set_alpha(gfx_widgets_backdrop_orig, DEFAULT_BACKDROP);
if (gfx_widgets_icons_textures[MENU_WIDGETS_ICON_ACHIEVEMENT]) gfx_display_set_alpha(gfx_widgets_pure_white, 1.0f);
/* Default icon */
if (!cheevo_popup_queue[cheevo_popup_queue_read_index].badge)
{
/* Backdrop */
gfx_display_draw_quad(video_info,
0, (int)cheevo_y,
cheevo_height, cheevo_height,
video_info->width, video_info->height,
gfx_widgets_backdrop_orig);
/* Icon */
if (gfx_widgets_icons_textures[MENU_WIDGETS_ICON_ACHIEVEMENT])
{
gfx_display_blend_begin(video_info);
gfx_widgets_draw_icon(video_info,
cheevo_height, cheevo_height,
gfx_widgets_icons_textures[MENU_WIDGETS_ICON_ACHIEVEMENT], 0, cheevo_y,
video_info->width, video_info->height, 0, 1, gfx_widgets_pure_white);
gfx_display_blend_end(video_info);
}
}
/* Badge */
else
{ {
gfx_display_blend_begin(video_info);
gfx_widgets_draw_icon(video_info, gfx_widgets_draw_icon(video_info,
cheevo_height, cheevo_height, cheevo_height, cheevo_height,
gfx_widgets_icons_textures[MENU_WIDGETS_ICON_ACHIEVEMENT], 0, cheevo_y, cheevo_popup_queue[cheevo_popup_queue_read_index].badge, 0, cheevo_y,
video_info->width, video_info->height, 0, 1, gfx_widgets_pure_white); video_info->width, video_info->height, 0, 1, gfx_widgets_pure_white);
gfx_display_blend_end(video_info);
} }
}
/* Badge */
else
{
gfx_widgets_draw_icon(video_info,
cheevo_height, cheevo_height,
cheevo_badge, 0, cheevo_y,
video_info->width, video_info->height, 0, 1, gfx_widgets_pure_white);
}
/* I _think_ cheevo_unfold changes in another thread */ /* I _think_ cheevo_unfold changes in another thread */
scissor_me_timbers = (fabs(cheevo_unfold - 1.0f) > 0.01); scissor_me_timbers = (fabs(cheevo_unfold - 1.0f) > 0.01);
if (scissor_me_timbers) if (scissor_me_timbers)
gfx_display_scissor_begin(video_info, gfx_display_scissor_begin(video_info,
cheevo_height, 0, cheevo_height, 0,
(unsigned)((float)(cheevo_width) * cheevo_unfold), (unsigned)((float)(cheevo_width)*cheevo_unfold),
cheevo_height); cheevo_height);
/* Backdrop */ /* Backdrop */
gfx_display_draw_quad(video_info, gfx_display_draw_quad(video_info,
cheevo_height, (int)cheevo_y, cheevo_height, (int)cheevo_y,
cheevo_width, cheevo_height, cheevo_width, cheevo_height,
video_info->width, video_info->height, video_info->width, video_info->height,
gfx_widgets_backdrop_orig); gfx_widgets_backdrop_orig);
/* Title */ /* Title */
gfx_display_draw_text(font_regular, gfx_display_draw_text(font_regular,
msg_hash_to_str(MSG_ACHIEVEMENT_UNLOCKED), msg_hash_to_str(MSG_ACHIEVEMENT_UNLOCKED),
cheevo_height + simple_widget_padding - unfold_offet, cheevo_height + simple_widget_padding - unfold_offet,
widget_font_size * 1.9f + cheevo_y, widget_font_size * 1.9f + cheevo_y,
video_info->width, video_info->height, video_info->width, video_info->height,
TEXT_COLOR_FAINT, TEXT_COLOR_FAINT,
TEXT_ALIGN_LEFT, TEXT_ALIGN_LEFT,
1, false, 0, true 1, false, 0, true
); );
/* Title */ /* Title */
/* TODO: is a ticker necessary ? */ /* TODO: is a ticker necessary ? */
gfx_display_draw_text(font_regular, gfx_display_draw_text(font_regular,
cheevo_title, cheevo_popup_queue[cheevo_popup_queue_read_index].title,
cheevo_height + simple_widget_padding - unfold_offet, widget_font_size * 2.9f + cheevo_y, cheevo_height + simple_widget_padding - unfold_offet, widget_font_size * 2.9f + cheevo_y,
video_info->width, video_info->height, video_info->width, video_info->height,
TEXT_COLOR_INFO, TEXT_COLOR_INFO,
TEXT_ALIGN_LEFT, TEXT_ALIGN_LEFT,
1, false, 0, true 1, false, 0, true
); );
if (scissor_me_timbers) if (scissor_me_timbers)
{ {
font_driver_flush(video_info->width, video_info->height, font_regular, video_info); font_driver_flush(video_info->width, video_info->height, font_regular, video_info);
font_raster_regular.carr.coords.vertices = 0; font_raster_regular.carr.coords.vertices = 0;
gfx_display_scissor_end(video_info); gfx_display_scissor_end(video_info);
}
} }
SLOCK_UNLOCK(cheevo_popup_queue_lock);
} }
#endif #endif
@ -2148,15 +2178,34 @@ static void gfx_widgets_context_destroy(void)
} }
#ifdef HAVE_CHEEVOS #ifdef HAVE_CHEEVOS
static void gfx_widgets_achievement_free(void *userdata) static void gfx_widgets_achievement_free_current(void)
{ {
if (cheevo_title) if (cheevo_popup_queue[cheevo_popup_queue_read_index].title)
free(cheevo_title); {
cheevo_title = NULL; free(cheevo_popup_queue[cheevo_popup_queue_read_index].title);
cheevo_popup_queue[cheevo_popup_queue_read_index].title = NULL;
}
if (cheevo_badge) if (cheevo_popup_queue[cheevo_popup_queue_read_index].badge)
video_driver_texture_unload(&cheevo_badge); {
cheevo_badge = 0; video_driver_texture_unload(&cheevo_popup_queue[cheevo_popup_queue_read_index].badge);
cheevo_popup_queue[cheevo_popup_queue_read_index].badge = 0;
}
cheevo_popup_queue_read_index = (cheevo_popup_queue_read_index + 1) % CHEEVO_QUEUE_SIZE;
}
static void gfx_widgets_achievement_next(void* userdata)
{
SLOCK_LOCK(cheevo_popup_queue_lock);
gfx_widgets_achievement_free_current();
/* start the next popup (if present) */
if (cheevo_popup_queue[cheevo_popup_queue_read_index].title)
gfx_widgets_start_achievement_notification();
SLOCK_UNLOCK(cheevo_popup_queue_lock);
} }
#endif #endif
@ -2206,7 +2255,15 @@ void gfx_widgets_free(void)
#ifdef HAVE_CHEEVOS #ifdef HAVE_CHEEVOS
/* Achievement notification */ /* Achievement notification */
gfx_widgets_achievement_free(NULL); if (cheevo_popup_queue_read_index >= 0)
{
SLOCK_LOCK(cheevo_popup_queue_lock);
while (cheevo_popup_queue[cheevo_popup_queue_read_index].title)
gfx_widgets_achievement_free_current();
SLOCK_UNLOCK(cheevo_popup_queue_lock);
}
#endif #endif
/* Font */ /* Font */
@ -2484,7 +2541,7 @@ static void gfx_widgets_achievement_dismiss(void *userdata)
gfx_animation_ctx_entry_t entry; gfx_animation_ctx_entry_t entry;
/* Slide up animation */ /* Slide up animation */
entry.cb = gfx_widgets_achievement_free; entry.cb = gfx_widgets_achievement_next;
entry.duration = MSG_QUEUE_ANIMATION_DURATION; entry.duration = MSG_QUEUE_ANIMATION_DURATION;
entry.easing_enum = EASING_OUT_QUAD; entry.easing_enum = EASING_OUT_QUAD;
entry.subject = &cheevo_y; entry.subject = &cheevo_y;
@ -2541,7 +2598,7 @@ static void gfx_widgets_start_achievement_notification(void)
cheevo_height = widget_font_size * 4; cheevo_height = widget_font_size * 4;
cheevo_width = MAX( 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, msg_hash_to_str(MSG_ACHIEVEMENT_UNLOCKED), 0, 1),
font_driver_get_message_width(font_regular, cheevo_title, 0, 1) font_driver_get_message_width(font_regular, cheevo_popup_queue[cheevo_popup_queue_read_index].title, 0, 1)
); );
cheevo_width += simple_widget_padding * 2; cheevo_width += simple_widget_padding * 2;
cheevo_y = (float)(-(int)cheevo_height); cheevo_y = (float)(-(int)cheevo_height);
@ -2561,14 +2618,47 @@ static void gfx_widgets_start_achievement_notification(void)
void gfx_widgets_push_achievement(const char *title, const char *badge) void gfx_widgets_push_achievement(const char *title, const char *badge)
{ {
gfx_widgets_achievement_free(NULL); int start_notification = 1;
/* TODO: Make a queue of notifications to display */ if (cheevo_popup_queue_read_index < 0)
{
/* queue uninitialized */
memset(&cheevo_popup_queue, 0, sizeof(cheevo_popup_queue));
cheevo_popup_queue_read_index = 0;
cheevo_title = strdup(title); #ifdef HAVE_THREADS
cheevo_badge = cheevos_get_badge_texture(badge, 0); cheevo_popup_queue_lock = slock_new();
#endif
}
gfx_widgets_start_achievement_notification(); SLOCK_LOCK(cheevo_popup_queue_lock);
if (cheevo_popup_queue_write_index == cheevo_popup_queue_read_index)
{
if (cheevo_popup_queue[cheevo_popup_queue_write_index].title)
{
/* queue full */
SLOCK_UNLOCK(cheevo_popup_queue_lock);
return;
}
/* queue empty */
}
else
{
/* notification already being displayed */
start_notification = 0;
}
cheevo_popup_queue[cheevo_popup_queue_write_index].badge = cheevos_get_badge_texture(badge, 0);
cheevo_popup_queue[cheevo_popup_queue_write_index].title = strdup(title);
cheevo_popup_queue_write_index = (cheevo_popup_queue_write_index + 1) % CHEEVO_QUEUE_SIZE;
if (start_notification)
gfx_widgets_start_achievement_notification();
SLOCK_UNLOCK(cheevo_popup_queue_lock);
} }
#endif #endif