diff --git a/cheevos/cheevos.c b/cheevos/cheevos.c index 9256f37ef2..ac9de0344e 100644 --- a/cheevos/cheevos.c +++ b/cheevos/cheevos.c @@ -2214,10 +2214,43 @@ static int rcheevos_iterate(rcheevos_coro_t* coro) } #endif -#ifdef HAVE_MENU - rcheevos_menu_reset_badges(); -#endif + /* make sure the directory exists */ + coro->badge_fullpath[0] = '\0'; + fill_pathname_application_special(coro->badge_fullpath, + sizeof(coro->badge_fullpath), + APPLICATION_SPECIAL_DIRECTORY_THUMBNAILS_CHEEVOS_BADGES); + if (!path_is_directory(coro->badge_fullpath)) + path_mkdir(coro->badge_fullpath); + + /* fetch the placeholder image */ + strlcpy(coro->badge_name, "00000" FILE_PATH_PNG_EXTENSION, + sizeof(coro->badge_name)); + fill_pathname_join(coro->badge_fullpath, coro->badge_fullpath, + coro->badge_name, sizeof(coro->badge_fullpath)); + + if (!path_is_valid(coro->badge_fullpath)) + { +#ifdef CHEEVOS_LOG_BADGES + CHEEVOS_LOG(RCHEEVOS_TAG "downloading badge %s\n", + coro->badge_fullpath); +#endif + snprintf(coro->url, sizeof(coro->url), + FILE_PATH_RETROACHIEVEMENTS_URL "/Badge/%s", coro->badge_name); + + CORO_GOSUB(RCHEEVOS_HTTP_GET); + + if (coro->json) + { + if (!filestream_write_file(coro->badge_fullpath, coro->json, coro->k)) + CHEEVOS_ERR(RCHEEVOS_TAG "Error writing badge %s\n", coro->badge_fullpath); + + CHEEVOS_FREE(coro->json); + coro->json = NULL; + } + } + + /* fetch the game images */ for (coro->i = 0; coro->i < 2; coro->i++) { if (coro->i == 0) @@ -2233,24 +2266,13 @@ static int rcheevos_iterate(rcheevos_coro_t* coro) for (; coro->cheevo < coro->cheevo_end; coro->cheevo++) { - if (!coro->cheevo->badge[0]) + if (!coro->cheevo->badge || !coro->cheevo->badge[0]) continue; for (coro->j = 0 ; coro->j < 2; coro->j++) { - coro->badge_fullpath[0] = '\0'; - fill_pathname_application_special( - coro->badge_fullpath, - sizeof(coro->badge_fullpath), - APPLICATION_SPECIAL_DIRECTORY_THUMBNAILS_CHEEVOS_BADGES); - - if (!path_is_directory(coro->badge_fullpath)) - path_mkdir(coro->badge_fullpath); CORO_YIELD(); - if (!coro->cheevo->badge || !coro->cheevo->badge[0]) - continue; - if (coro->j == 0) snprintf(coro->badge_name, sizeof(coro->badge_name), @@ -2262,6 +2284,11 @@ static int rcheevos_iterate(rcheevos_coro_t* coro) "%s_lock" FILE_PATH_PNG_EXTENSION, coro->cheevo->badge); + coro->badge_fullpath[0] = '\0'; + fill_pathname_application_special(coro->badge_fullpath, + sizeof(coro->badge_fullpath), + APPLICATION_SPECIAL_DIRECTORY_THUMBNAILS_CHEEVOS_BADGES); + fill_pathname_join( coro->badge_fullpath, coro->badge_fullpath, @@ -2287,11 +2314,9 @@ static int rcheevos_iterate(rcheevos_coro_t* coro) if (!filestream_write_file(coro->badge_fullpath, coro->json, coro->k)) CHEEVOS_ERR(RCHEEVOS_TAG "Error writing badge %s\n", coro->badge_fullpath); - else - { - CHEEVOS_FREE(coro->json); - coro->json = NULL; - } + + CHEEVOS_FREE(coro->json); + coro->json = NULL; } } } diff --git a/cheevos/cheevos_locals.h b/cheevos/cheevos_locals.h index 2ae62ed220..9f3bd08577 100644 --- a/cheevos/cheevos_locals.h +++ b/cheevos/cheevos_locals.h @@ -155,4 +155,4 @@ rcheevos_locals_t* get_rcheevos_locals(); RETRO_END_DECLS -#endif +#endif /* __RARCH_CHEEVOS_LOCALS_H */ diff --git a/cheevos/cheevos_menu.c b/cheevos/cheevos_menu.c index 68f9f3a8da..6ab695ba02 100644 --- a/cheevos/cheevos_menu.c +++ b/cheevos/cheevos_menu.c @@ -15,12 +15,15 @@ #include "cheevos_locals.h" +#include "../gfx/gfx_display.h" + #ifdef HAVE_MENU #include "cheevos.h" #include "../deps/rcheevos/include/rc_runtime_types.h" +#include "../file_path_special.h" #include "../menu/menu_driver.h" #include "../menu/menu_entries.h" @@ -203,7 +206,7 @@ static rcheevos_menuitem_t* rcheevos_menu_allocate( else { /* realloc failed */ - CHEEVOS_ERR(RCHEEVOS_TAG " could not allocate space for %u menu items", + CHEEVOS_ERR(RCHEEVOS_TAG " could not allocate space for %u menu items\n", rcheevos_locals->menuitem_capacity); rcheevos_locals->menuitem_capacity -= 32; return NULL; @@ -218,7 +221,7 @@ static rcheevos_menuitem_t* rcheevos_menu_allocate( if (!rcheevos_locals->menuitems) { /* malloc failed */ - CHEEVOS_ERR(RCHEEVOS_TAG " could not allocate space for %u menu items", + CHEEVOS_ERR(RCHEEVOS_TAG " could not allocate space for %u menu items\n", rcheevos_locals->menuitem_capacity); rcheevos_locals->menuitem_capacity = 0; return NULL; @@ -240,6 +243,53 @@ static void rcheevos_menu_append_header(rcheevos_locals_t* rcheevos_locals, menuitem->state_label_idx = label; } +static void rcheevos_menu_update_badge(rcheevos_racheevo_t* cheevo) +{ + bool badge_grayscale = false; + switch (cheevo->menu_bucket) + { + case RCHEEVOS_MENUITEM_BUCKET_LOCKED: + case RCHEEVOS_MENUITEM_BUCKET_UNSUPPORTED: + case RCHEEVOS_MENUITEM_BUCKET_ALMOST_THERE: + case RCHEEVOS_MENUITEM_BUCKET_ACTIVE_CHALLENGE: + badge_grayscale = true; + break; + + default: + badge_grayscale = false; + break; + } + + if (!cheevo->menu_badge_texture || cheevo->menu_badge_grayscale != badge_grayscale) + { + uintptr_t new_badge_texture = + rcheevos_get_badge_texture(cheevo->badge, badge_grayscale); + + if (new_badge_texture) + { + if (cheevo->menu_badge_texture) + video_driver_texture_unload(&cheevo->menu_badge_texture); + + cheevo->menu_badge_texture = new_badge_texture; + cheevo->menu_badge_grayscale = badge_grayscale; + } + /* menu_badge_grayscale is overloaded such that any value greater than 1 indicates + * the server default image is being used */ + else if (cheevo->menu_badge_grayscale < 2) + { + if (cheevo->menu_badge_texture) + video_driver_texture_unload(&cheevo->menu_badge_texture); + + /* requested badge is not available, check for server default */ + cheevo->menu_badge_texture = + rcheevos_get_badge_texture("00000", false); + + if (cheevo->menu_badge_texture) + cheevo->menu_badge_grayscale = 2; + } + } +} + static void rcheevos_menu_append_items(rcheevos_locals_t* rcheevos_locals, bool cheevos_test_unofficial, enum rcheevos_menuitem_bucket bucket) { @@ -314,30 +364,7 @@ static void rcheevos_menu_append_items(rcheevos_locals_t* rcheevos_locals, if (cheevo->badge && cheevo->badge[0] && settings && settings->bools.cheevos_badges_enable) { - bool badge_grayscale = false; - switch (bucket) - { - case RCHEEVOS_MENUITEM_BUCKET_LOCKED: - case RCHEEVOS_MENUITEM_BUCKET_UNSUPPORTED: - case RCHEEVOS_MENUITEM_BUCKET_ALMOST_THERE: - case RCHEEVOS_MENUITEM_BUCKET_ACTIVE_CHALLENGE: - badge_grayscale = true; - break; - - default: - badge_grayscale = false; - break; - } - - if (!cheevo->menu_badge_texture || cheevo->menu_badge_grayscale != badge_grayscale) - { - if (cheevo->menu_badge_texture) - video_driver_texture_unload(&cheevo->menu_badge_texture); - - cheevo->menu_badge_texture = - rcheevos_get_badge_texture(cheevo->badge, badge_grayscale); - cheevo->menu_badge_grayscale = badge_grayscale; - } + rcheevos_menu_update_badge(cheevo); } } @@ -350,9 +377,22 @@ uintptr_t rcheevos_menu_get_badge_texture(unsigned menu_offset) const rcheevos_locals_t* rcheevos_locals = get_rcheevos_locals(); if (menu_offset < rcheevos_locals->menuitem_count) { - const rcheevos_racheevo_t* cheevo = rcheevos_locals->menuitems[menu_offset].cheevo; + rcheevos_racheevo_t* cheevo = rcheevos_locals->menuitems[menu_offset].cheevo; if (cheevo) + { + /* if we're using the placeholder badge, check to see if the real badge + * has become available (do this roughly once a second) */ + if (cheevo->menu_badge_grayscale >= 2) + { + if (++cheevo->menu_badge_grayscale == 64) + { + cheevo->menu_badge_grayscale = 2; + rcheevos_menu_update_badge(cheevo); + } + } + return cheevo->menu_badge_texture; + } } return 0; diff --git a/cheevos/cheevos_menu.h b/cheevos/cheevos_menu.h index fc6a774e25..73a764b383 100644 --- a/cheevos/cheevos_menu.h +++ b/cheevos/cheevos_menu.h @@ -45,4 +45,4 @@ RETRO_END_DECLS #endif /* HAVE_MENU */ -#endif /* __RARCH_CHEEVOS_CHEEVOS_H */ +#endif /* __RARCH_CHEEVOS_MENU_H */ diff --git a/menu/drivers/ozone/ozone_texture.c b/menu/drivers/ozone/ozone_texture.c index 376b9291a2..425d04351d 100644 --- a/menu/drivers/ozone/ozone_texture.c +++ b/menu/drivers/ozone/ozone_texture.c @@ -464,11 +464,17 @@ uintptr_t ozone_entries_icon_get_texture(ozone_handle_t *ozone, (type < MENU_SETTINGS_NETPLAY_ROOMS_START) ) { + char buffer[64]; int index = type - MENU_SETTINGS_CHEEVOS_START; uintptr_t badge_texture = rcheevos_menu_get_badge_texture(index); if (badge_texture) return badge_texture; - /* Should be replaced with placeholder badge icon. */ + + /* no state means its a header - show the info icon */ + if (!rcheevos_menu_get_state(index, buffer, sizeof(buffer))) + return ozone->icons_textures[OZONE_ENTRIES_ICONS_TEXTURE_INFO]; + + /* placeholder badge image was not found, show generic menu icon */ return ozone->icons_textures[OZONE_ENTRIES_ICONS_TEXTURE_ACHIEVEMENTS]; } #endif diff --git a/menu/drivers/xmb.c b/menu/drivers/xmb.c index 7385de29f0..94d14143af 100644 --- a/menu/drivers/xmb.c +++ b/menu/drivers/xmb.c @@ -2905,11 +2905,17 @@ static uintptr_t xmb_icon_get_id(xmb_handle_t *xmb, (type < MENU_SETTINGS_NETPLAY_ROOMS_START) ) { + char buffer[64]; int index = type - MENU_SETTINGS_CHEEVOS_START; uintptr_t badge_texture = rcheevos_menu_get_badge_texture(index); if (badge_texture) return badge_texture; - /* Should be replaced with placeholder badge icon. */ + + /* no state means its a header - show the info icon */ + if (!rcheevos_menu_get_state(index, buffer, sizeof(buffer))) + return xmb->textures.list[XMB_TEXTURE_INFO]; + + /* placeholder badge image was not found, show generic menu icon */ return xmb->textures.list[XMB_TEXTURE_ACHIEVEMENTS]; } #endif