Skip to content

Commit 3bfb001

Browse files
committed
delay popup if image not available
1 parent 92b668d commit 3bfb001

3 files changed

Lines changed: 116 additions & 22 deletions

File tree

cheevos/cheevos.c

Lines changed: 92 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -305,6 +305,74 @@ static void rcheevos_show_subset_completion_placard(const rc_client_subset_t* su
305305
rcheevos_show_completion_placard(subset->title, subset->badge_name);
306306
}
307307

308+
#if defined(HAVE_GFX_WIDGETS)
309+
310+
static void rcheevos_show_achievement_popup(const rc_client_achievement_t* cheevo, float rarity)
311+
{
312+
char title[128], subtitle[96];
313+
314+
if (rarity >= 10.0)
315+
snprintf(title, sizeof(title), "%s - %0.2f%%",
316+
msg_hash_to_str(MSG_ACHIEVEMENT_UNLOCKED), rarity);
317+
else if (rarity > 0.0)
318+
snprintf(title, sizeof(title), "%s - %0.2f%%",
319+
msg_hash_to_str(MSG_RARE_ACHIEVEMENT_UNLOCKED), rarity);
320+
else
321+
strlcpy(title,
322+
msg_hash_to_str(MSG_ACHIEVEMENT_UNLOCKED), sizeof(title));
323+
324+
snprintf(subtitle, sizeof(subtitle), "%s (%lu)", cheevo->title, (unsigned long)cheevo->points);
325+
326+
gfx_widgets_push_achievement(title, subtitle, cheevo->badge_name);
327+
328+
/* if all badges haven't been loaded, preload the next one assuming it will be the next needed */
329+
if (!rcheevos_locals.badges_loaded)
330+
{
331+
const rc_client_achievement_t* next_locked_achievement =
332+
rc_client_get_next_achievement_info(rcheevos_locals.client, cheevo, RC_CLIENT_ACHIEVEMENT_BUCKET_LOCKED);
333+
if (next_locked_achievement)
334+
rcheevos_client_download_badge_from_url(next_locked_achievement->badge_url, next_locked_achievement->badge_name);
335+
}
336+
}
337+
338+
struct rcheevos_retry_achievement_info_t
339+
{
340+
uint32_t achievement_id;
341+
float rarity;
342+
};
343+
344+
static void rcheevos_retry_achievement_popup(retro_task_t* task)
345+
{
346+
struct rcheevos_retry_achievement_info_t* info = (struct rcheevos_retry_achievement_info_t*)task->user_data;
347+
const rc_client_achievement_t* cheevo = rc_client_get_achievement_info(rcheevos_locals.client, info->achievement_id);
348+
if (!cheevo)
349+
{
350+
/* achievement not found, assume game unloaded and don't show the popup */
351+
}
352+
else if (task->progress > 4 || rcheevos_is_badge_available(cheevo->badge_name, false))
353+
{
354+
/* badge is available now, or we've reached the retry limit. show the popup */
355+
rcheevos_show_achievement_popup(cheevo, info->rarity);
356+
}
357+
else
358+
{
359+
/* second retry in 200ms, third is 400ms, fourth in 800ms. if not available after 1500ms
360+
* (100+200+400+800), then just show the popup with the placeholder. */
361+
task->progress <<= 1;
362+
task->when = cpu_features_get_time_usec() + 100000 * task->progress; /* first retry in 100ms */
363+
return;
364+
}
365+
366+
/* cleanup the user data */
367+
task->user_data = NULL;
368+
free(info);
369+
370+
/* mark task as complete so it will get cleaned up */
371+
task_set_flags(task, RETRO_TASK_FLG_FINISHED, true);
372+
}
373+
374+
#endif /* HAVE_GFX_WIDGETS */
375+
308376
static void rcheevos_award_achievement(const rc_client_achievement_t* cheevo)
309377
{
310378
const settings_t* settings = config_get_ptr();
@@ -318,31 +386,37 @@ static void rcheevos_award_achievement(const rc_client_achievement_t* cheevo)
318386
#if defined(HAVE_GFX_WIDGETS)
319387
if (gfx_widgets_ready())
320388
{
321-
char title[128], subtitle[96];
322389
float rarity = rc_client_get_hardcore_enabled(rcheevos_locals.client) ?
323390
cheevo->rarity_hardcore : cheevo->rarity;
324391

325-
if (rarity >= 10.0)
326-
snprintf(title, sizeof(title), "%s - %0.2f%%",
327-
msg_hash_to_str(MSG_ACHIEVEMENT_UNLOCKED), rarity);
328-
else if (rarity > 0.0)
329-
snprintf(title, sizeof(title), "%s - %0.2f%%",
330-
msg_hash_to_str(MSG_RARE_ACHIEVEMENT_UNLOCKED), rarity);
392+
if (rcheevos_locals.badges_loaded || rcheevos_is_badge_available(cheevo->badge_name, false))
393+
{
394+
rcheevos_show_achievement_popup(cheevo, rarity);
395+
}
331396
else
332-
strlcpy(title,
333-
msg_hash_to_str(MSG_ACHIEVEMENT_UNLOCKED), sizeof(title));
397+
{
398+
retro_task_t* task;
399+
rcheevos_client_download_badge_from_url(cheevo->badge_url, cheevo->badge_name);
334400

335-
snprintf(subtitle, sizeof(subtitle), "%s (%lu)", cheevo->title, (unsigned long)cheevo->points);
401+
task = task_init();
402+
if (!task)
403+
{
404+
rcheevos_show_achievement_popup(cheevo, rarity);
405+
}
406+
else
407+
{
408+
struct rcheevos_retry_achievement_info_t* info;
409+
info = (struct rcheevos_retry_achievement_info_t*)malloc(sizeof(*info));
410+
info->achievement_id = cheevo->id;
411+
info->rarity = rarity;
336412

337-
gfx_widgets_push_achievement(title, subtitle, cheevo->badge_name);
413+
task->handler = rcheevos_retry_achievement_popup;
414+
task->user_data = info;
415+
task->progress = 1;
416+
task->when = cpu_features_get_time_usec() + 100000; /* first retry in 100ms */
338417

339-
/* if all badges haven't been loaded, preload the next one assuming it will be the next needed */
340-
if (!rcheevos_locals.badges_loaded)
341-
{
342-
const rc_client_achievement_t* next_locked_achievement =
343-
rc_client_get_next_achievement_info(rcheevos_locals.client, cheevo, RC_CLIENT_ACHIEVEMENT_BUCKET_LOCKED);
344-
if (next_locked_achievement)
345-
rcheevos_client_download_badge_from_url(next_locked_achievement->badge_url, next_locked_achievement->badge_name);
418+
task_queue_push(task);
419+
}
346420
}
347421
}
348422
else

cheevos/cheevos.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,7 @@ const char* rcheevos_get_hash(void);
5959
int rcheevos_get_richpresence(char *s, size_t len);
6060
int rcheevos_get_game_badge_url(char *s, size_t len);
6161
uintptr_t rcheevos_get_badge_texture(const char* badge, bool locked, bool download_if_missing);
62+
bool rcheevos_is_badge_available(const char* badge, bool locked);
6263

6364
uint8_t* rcheevos_patch_address(unsigned address);
6465

cheevos/cheevos_menu.c

Lines changed: 23 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -614,9 +614,30 @@ static void rcheevos_client_download_achievement_badge(const char* badge_name, b
614614
}
615615
}
616616

617+
static void rcheevos_get_local_badge_filename(char badge_file[], size_t badge_file_size, const char* badge, bool locked)
618+
{
619+
size_t _len = strlcpy(badge_file, badge, badge_file_size);
620+
if (locked)
621+
_len += strlcpy(badge_file + _len, "_lock", badge_file_size - _len);
622+
strlcpy(badge_file + _len, FILE_PATH_PNG_EXTENSION, badge_file_size - _len);
623+
}
624+
625+
bool rcheevos_is_badge_available(const char* badge, bool locked)
626+
{
627+
char badge_file[24];
628+
char fullpath[PATH_MAX_LENGTH];
629+
630+
rcheevos_get_local_badge_filename(badge_file, sizeof(badge_file), badge, locked);
631+
632+
fill_pathname_application_special(fullpath, sizeof(fullpath),
633+
APPLICATION_SPECIAL_DIRECTORY_THUMBNAILS_CHEEVOS_BADGES);
634+
fill_pathname_join(fullpath, fullpath, badge_file, sizeof(fullpath));
635+
636+
return path_is_valid(fullpath);
637+
}
638+
617639
uintptr_t rcheevos_get_badge_texture(const char* badge, bool locked, bool download_if_missing)
618640
{
619-
size_t _len;
620641
char badge_file[24];
621642
char fullpath[PATH_MAX_LENGTH];
622643
uintptr_t tex = 0;
@@ -634,9 +655,7 @@ uintptr_t rcheevos_get_badge_texture(const char* badge, bool locked, bool downlo
634655
return 0;
635656
#endif
636657

637-
_len = strlcpy(badge_file, badge, sizeof(badge_file));
638-
_len += strlcpy(badge_file + _len, locked ? "_lock" : "", sizeof(badge_file) - _len);
639-
strlcpy(badge_file + _len, FILE_PATH_PNG_EXTENSION, sizeof(badge_file) - _len);
658+
rcheevos_get_local_badge_filename(badge_file, sizeof(badge_file), badge, locked);
640659

641660
fill_pathname_application_special(fullpath, sizeof(fullpath),
642661
APPLICATION_SPECIAL_DIRECTORY_THUMBNAILS_CHEEVOS_BADGES);

0 commit comments

Comments
 (0)