diff --git a/CHANGES.md b/CHANGES.md index c825908cf1..17bb6ec41b 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -1,4 +1,5 @@ # 1.7.0 (future) +- CHEEVOS: Add badges # 1.6.9 - COMMON: Small memory leak. diff --git a/Makefile.common b/Makefile.common index 95012320df..7aeea49c68 100644 --- a/Makefile.common +++ b/Makefile.common @@ -1476,6 +1476,7 @@ ifeq ($(HAVE_NETWORKING), 1) OBJ += cheevos/cheevos.o \ cheevos/var.o \ cheevos/cond.o \ + cheevos/badges.o \ $(LIBRETRO_COMM_DIR)/utils/md5.o endif diff --git a/cheevos/badges.c b/cheevos/badges.c new file mode 100644 index 0000000000..961fbc600e --- /dev/null +++ b/cheevos/badges.c @@ -0,0 +1,54 @@ +#include +#include +#include + +#include "../file_path_special.h" +#include "../configuration.h" +#include "../verbosity.h" +#include "../network/net_http_special.h" + +#include "badges.h" + +badges_ctx_t badges_ctx; + +bool badge_exists(const char* filepath) +{ + if(path_file_exists(filepath)) + return true; + else + return false; +} + +void set_badge_menu_texture(badges_ctx_t * badges, int i) +{ + const char * locked_suffix = (badges->badge_locked[i] == true) ? "_lock.png" : ".png"; + + unsigned int bufferSize = 16; + char badge_file[bufferSize]; + + snprintf(badge_file, bufferSize, "%s", badges->badge_id_list[i]); + strcat(badge_file, locked_suffix); + + char fullpath[PATH_MAX_LENGTH]; + fill_pathname_application_special(fullpath, + PATH_MAX_LENGTH * sizeof(char), + APPLICATION_SPECIAL_DIRECTORY_THUMBNAILS_CHEEVOS_BADGES); + + menu_display_reset_textures_list(badge_file, fullpath, &badges->menu_texture_list[i],TEXTURE_FILTER_MIPMAP_LINEAR); +} + +void set_badge_info (badges_ctx_t *badge_struct, int id, const char *badge_id, bool active) +{ + badge_struct->badge_id_list[id] = badge_id; + badge_struct->badge_locked[id] = active; + set_badge_menu_texture(badge_struct, id); +} + +menu_texture_item get_badge_texture (int id) +{ + settings_t *settings = config_get_ptr(); + if (!settings->bools.cheevos_badges_enable) + return (menu_texture_item)NULL; + + return badges_ctx.menu_texture_list[id]; +} diff --git a/cheevos/badges.h b/cheevos/badges.h new file mode 100644 index 0000000000..57a8de6ed2 --- /dev/null +++ b/cheevos/badges.h @@ -0,0 +1,29 @@ +#ifndef __RARCH_BADGE_H +#define __RARCH_BADGE_H + +#include "../menu/menu_driver.h" + +#include + +RETRO_BEGIN_DECLS + +#define CHEEVOS_BADGE_LIMIT 256 + +typedef struct +{ + bool badge_locked[CHEEVOS_BADGE_LIMIT]; + const char * badge_id_list[CHEEVOS_BADGE_LIMIT]; + menu_texture_item menu_texture_list[CHEEVOS_BADGE_LIMIT]; +} badges_ctx_t; + +bool badge_exists(const char* filepath); +void set_badge_menu_texture(badges_ctx_t * badges, int i); +extern void set_badge_info (badges_ctx_t *badge_struct, int id, const char *badge_id, bool active); +extern menu_texture_item get_badge_texture(int id); + +extern badges_ctx_t badges_ctx; +static badges_ctx_t new_badges_ctx; + +RETRO_END_DECLS + +#endif diff --git a/cheevos/cheevos.c b/cheevos/cheevos.c index 8e61133e59..725c2b8edb 100644 --- a/cheevos/cheevos.c +++ b/cheevos/cheevos.c @@ -16,6 +16,8 @@ #include #include +#include +#include #include #include #include @@ -35,10 +37,12 @@ #include "../menu/menu_entries.h" #endif +#include "badges.h" #include "cheevos.h" #include "var.h" #include "cond.h" +#include "../file_path_special.h" #include "../command.h" #include "../dynamic.h" #include "../configuration.h" @@ -76,6 +80,9 @@ * THE USER'S PASSWORD, TAKE CARE! */ #undef CHEEVOS_LOG_PASSWORD +/* Define this macro to log downloaded badge images. */ +#undef CHEEVOS_LOG_BADGES + /* C89 wants only int values in enums. */ #define CHEEVOS_JSON_KEY_GAMEID 0xb4960eecU #define CHEEVOS_JSON_KEY_ACHIEVEMENTS 0x69749ae1U @@ -2170,6 +2177,7 @@ void cheevos_populate_menu(void *data, bool hardcore) MENU_SETTINGS_CHEEVOS_START + i, 0, 0); items_found++; } + set_badge_info(&badges_ctx, i, cheevo->badge, (cheevo->active & CHEEVOS_ACTIVE_SOFTCORE)); } else { @@ -2187,6 +2195,7 @@ void cheevos_populate_menu(void *data, bool hardcore) MENU_SETTINGS_CHEEVOS_START + i, 0, 0); items_found++; } + set_badge_info(&badges_ctx, i, cheevo->badge, (cheevo->active & CHEEVOS_ACTIVE_HARDCORE)); } } @@ -2522,37 +2531,47 @@ typedef struct char url[256]; \ struct http_connection_t *conn; \ struct http_t *http; \ - retro_time_t t0; + retro_time_t t0; \ + char badge_basepath[PATH_MAX_LENGTH]; \ + char badge_fullpath[PATH_MAX_LENGTH]; \ + char badge_name[16]; \ + cheevo_t *cheevo; \ + const cheevo_t *cheevo_end; #include "coro.h" -#define CHEEVOS_VAR_INFO CORO_VAR(info) -#define CHEEVOS_VAR_DATA CORO_VAR(data) -#define CHEEVOS_VAR_LEN CORO_VAR(len) -#define CHEEVOS_VAR_PATH CORO_VAR(path) -#define CHEEVOS_VAR_SETTINGS CORO_VAR(settings) -#define CHEEVOS_VAR_SYSINFO CORO_VAR(sysinfo) -#define CHEEVOS_VAR_I CORO_VAR(i) -#define CHEEVOS_VAR_J CORO_VAR(j) -#define CHEEVOS_VAR_K CORO_VAR(k) -#define CHEEVOS_VAR_EXT CORO_VAR(ext) -#define CHEEVOS_VAR_MD5 CORO_VAR(md5) -#define CHEEVOS_VAR_HASH CORO_VAR(hash) -#define CHEEVOS_VAR_GAMEID CORO_VAR(gameid) -#define CHEEVOS_VAR_JSON CORO_VAR(json) -#define CHEEVOS_VAR_COUNT CORO_VAR(count) -#define CHEEVOS_VAR_OFFSET CORO_VAR(offset) -#define CHEEVOS_VAR_HEADER CORO_VAR(header) -#define CHEEVOS_VAR_ROMSIZE CORO_VAR(romsize) -#define CHEEVOS_VAR_BYTES CORO_VAR(bytes) -#define CHEEVOS_VAR_MAPPER CORO_VAR(mapper) -#define CHEEVOS_VAR_ROUND CORO_VAR(round) -#define CHEEVOS_VAR_STREAM CORO_VAR(stream) -#define CHEEVOS_VAR_SIZE CORO_VAR(size) -#define CHEEVOS_VAR_URL CORO_VAR(url) -#define CHEEVOS_VAR_CONN CORO_VAR(conn) -#define CHEEVOS_VAR_HTTP CORO_VAR(http) -#define CHEEVOS_VAR_T0 CORO_VAR(t0) +#define CHEEVOS_VAR_INFO CORO_VAR(info) +#define CHEEVOS_VAR_DATA CORO_VAR(data) +#define CHEEVOS_VAR_LEN CORO_VAR(len) +#define CHEEVOS_VAR_PATH CORO_VAR(path) +#define CHEEVOS_VAR_SETTINGS CORO_VAR(settings) +#define CHEEVOS_VAR_SYSINFO CORO_VAR(sysinfo) +#define CHEEVOS_VAR_I CORO_VAR(i) +#define CHEEVOS_VAR_J CORO_VAR(j) +#define CHEEVOS_VAR_K CORO_VAR(k) +#define CHEEVOS_VAR_EXT CORO_VAR(ext) +#define CHEEVOS_VAR_MD5 CORO_VAR(md5) +#define CHEEVOS_VAR_HASH CORO_VAR(hash) +#define CHEEVOS_VAR_GAMEID CORO_VAR(gameid) +#define CHEEVOS_VAR_JSON CORO_VAR(json) +#define CHEEVOS_VAR_COUNT CORO_VAR(count) +#define CHEEVOS_VAR_OFFSET CORO_VAR(offset) +#define CHEEVOS_VAR_HEADER CORO_VAR(header) +#define CHEEVOS_VAR_ROMSIZE CORO_VAR(romsize) +#define CHEEVOS_VAR_BYTES CORO_VAR(bytes) +#define CHEEVOS_VAR_MAPPER CORO_VAR(mapper) +#define CHEEVOS_VAR_ROUND CORO_VAR(round) +#define CHEEVOS_VAR_STREAM CORO_VAR(stream) +#define CHEEVOS_VAR_SIZE CORO_VAR(size) +#define CHEEVOS_VAR_URL CORO_VAR(url) +#define CHEEVOS_VAR_CONN CORO_VAR(conn) +#define CHEEVOS_VAR_HTTP CORO_VAR(http) +#define CHEEVOS_VAR_T0 CORO_VAR(t0) +#define CHEEVOS_VAR_BADGE_PATH CORO_VAR(badge_fullpath) +#define CHEEVOS_VAR_BADGE_BASE_PATH CORO_VAR(badge_fullpath) +#define CHEEVOS_VAR_BADGE_NAME CORO_VAR(badge_name) +#define CHEEVOS_VAR_CHEEVO_CURR CORO_VAR(cheevo) +#define CHEEVOS_VAR_CHEEVO_END CORO_VAR(cheevo_end) static int cheevos_iterate(coro_t* coro) { @@ -2573,11 +2592,12 @@ static int cheevos_iterate(coro_t* coro) FILL_MD5 = -7, GET_GAMEID = -8, GET_CHEEVOS = -9, - LOGIN = -10, - HTTP_GET = -11, - DEACTIVATE = -12, - PLAYING = -13, - DELAY = -14 + GET_BADGES = -10, + LOGIN = -11, + HTTP_GET = -12, + DEACTIVATE = -13, + PLAYING = -14, + DELAY = -15 }; static const uint32_t genesis_exts[] = @@ -2817,6 +2837,7 @@ static int cheevos_iterate(coro_t* coro) if ((void*)CHEEVOS_VAR_JSON) free((void*)CHEEVOS_VAR_JSON); + cheevos_loaded = true; /* @@ -2860,6 +2881,8 @@ static int cheevos_iterate(coro_t* coro) } + CORO_GOSUB(GET_BADGES); + CORO_STOP(); /************************************************************************** @@ -3133,14 +3156,12 @@ static int cheevos_iterate(coro_t* coro) *************************************************************************/ CORO_SUB(GET_CHEEVOS) - CORO_GOSUB(LOGIN); + CORO_GOSUB(LOGIN); - snprintf( - CHEEVOS_VAR_URL, sizeof(CHEEVOS_VAR_URL), - "http://retroachievements.org/dorequest.php?r=patch&u=%s&g=%u&f=3&l=1&t=%s", - CHEEVOS_VAR_SETTINGS->arrays.cheevos_username, - CHEEVOS_VAR_GAMEID, cheevos_locals.token - ); + snprintf(CHEEVOS_VAR_URL, sizeof(CHEEVOS_VAR_URL), + "http://retroachievements.org/dorequest.php?r=patch&u=%s&g=%u&f=3&l=1&t=%s", + CHEEVOS_VAR_SETTINGS->arrays.cheevos_username, + CHEEVOS_VAR_GAMEID, cheevos_locals.token); CHEEVOS_VAR_URL[sizeof(CHEEVOS_VAR_URL) - 1] = 0; @@ -3159,6 +3180,62 @@ static int cheevos_iterate(coro_t* coro) RARCH_LOG("[CHEEVOS]: got achievements for game id %u.\n", CHEEVOS_VAR_GAMEID); CORO_RET(); + /************************************************************************** + * Info Gets the achievements from Retro Achievements + * Inputs CHEEVOS_VAR_GAMEID + * Outputs CHEEVOS_VAR_JSON + *************************************************************************/ + CORO_SUB(GET_BADGES) + + badges_ctx = new_badges_ctx; + + settings_t *settings = config_get_ptr(); + if (!string_is_equal(settings->arrays.menu_driver, "xmb") || + !settings->bools.cheevos_badges_enable) + CORO_RET(); + + CHEEVOS_VAR_CHEEVO_CURR = cheevos_locals.core.cheevos; + CHEEVOS_VAR_CHEEVO_END = cheevos_locals.core.cheevos + cheevos_locals.core.count; + + for (; CHEEVOS_VAR_CHEEVO_CURR < CHEEVOS_VAR_CHEEVO_END ; CHEEVOS_VAR_CHEEVO_CURR++) + { + for (CHEEVOS_VAR_J = 0 ; CHEEVOS_VAR_J < 2; CHEEVOS_VAR_J++) + { + CHEEVOS_VAR_BADGE_PATH[0] = '\0'; + fill_pathname_application_special(CHEEVOS_VAR_BADGE_BASE_PATH, sizeof(CHEEVOS_VAR_BADGE_BASE_PATH), + APPLICATION_SPECIAL_DIRECTORY_THUMBNAILS_CHEEVOS_BADGES); + + if (!path_is_directory(CHEEVOS_VAR_BADGE_BASE_PATH)) + path_mkdir(CHEEVOS_VAR_BADGE_BASE_PATH); + CORO_YIELD(); + if (CHEEVOS_VAR_J == 0) + snprintf(CHEEVOS_VAR_BADGE_NAME, sizeof(CHEEVOS_VAR_BADGE_NAME), "%s.png", CHEEVOS_VAR_CHEEVO_CURR->badge); + else + snprintf(CHEEVOS_VAR_BADGE_NAME, sizeof(CHEEVOS_VAR_BADGE_NAME), "%s_lock.png", CHEEVOS_VAR_CHEEVO_CURR->badge); + + fill_pathname_join(CHEEVOS_VAR_BADGE_PATH, CHEEVOS_VAR_BADGE_BASE_PATH, CHEEVOS_VAR_BADGE_NAME, sizeof(CHEEVOS_VAR_BADGE_PATH)); + + if (!badge_exists(CHEEVOS_VAR_BADGE_PATH)) + { +#ifdef CHEEVOS_LOG_BADGES + RARCH_LOG("[CHEEVOS]: downloading badge %s\n", CHEEVOS_VAR_BADGE_PATH); +#endif + snprintf(CHEEVOS_VAR_URL, sizeof(CHEEVOS_VAR_URL), "http://i.retroachievements.org/Badge/%s", CHEEVOS_VAR_BADGE_NAME); + + CORO_GOSUB(HTTP_GET); + if (CHEEVOS_VAR_JSON != NULL) + { + if (!filestream_write_file(CHEEVOS_VAR_BADGE_PATH, CHEEVOS_VAR_JSON, CHEEVOS_VAR_K)) + RARCH_ERR("[CHEEVOS]: error writing badge %s\n", CHEEVOS_VAR_BADGE_PATH); + else + free(CHEEVOS_VAR_JSON); + } + } + } + } + + CORO_RET(); + /************************************************************************** * Info Logs in the user at Retro Achievements *************************************************************************/ @@ -3300,6 +3377,7 @@ static int cheevos_iterate(coro_t* coro) CHEEVOS_VAR_JSON[length] = 0; } + CHEEVOS_VAR_K = length; net_http_delete(CHEEVOS_VAR_HTTP); net_http_connection_free(CHEEVOS_VAR_CONN); CORO_RET(); diff --git a/configuration.c b/configuration.c index 21ce17f95d..513d9a6f0c 100644 --- a/configuration.c +++ b/configuration.c @@ -1255,6 +1255,9 @@ static struct config_bool_setting *populate_settings_bool(settings_t *settings, SETTING_BOOL("cheevos_test_unofficial", &settings->bools.cheevos_test_unofficial, true, false, false); SETTING_BOOL("cheevos_hardcore_mode_enable", &settings->bools.cheevos_hardcore_mode_enable, true, false, false); SETTING_BOOL("cheevos_leaderboards_enable", &settings->bools.cheevos_leaderboards_enable, true, false, false); +#ifdef HAVE_XMB + SETTING_BOOL("cheevos_badges_enable", &settings->bools.cheevos_badges_enable, true, false, false); +#endif SETTING_BOOL("cheevos_verbose_enable", &settings->bools.cheevos_verbose_enable, true, false, false); #endif #ifdef HAVE_OVERLAY @@ -1864,7 +1867,7 @@ static void config_set_defaults(void) temp_str[0] = '\0'; fill_pathname_expand_special(temp_str, - g_defaults.path.config, + g_defaults.path.config, PATH_MAX_LENGTH * sizeof(char)); path_set(RARCH_PATH_CONFIG, temp_str); free(temp_str); diff --git a/configuration.h b/configuration.h index ee2d29d5f7..7dd74b9282 100644 --- a/configuration.h +++ b/configuration.h @@ -184,6 +184,7 @@ typedef struct settings bool cheevos_test_unofficial; bool cheevos_hardcore_mode_enable; bool cheevos_leaderboards_enable; + bool cheevos_badges_enable; bool cheevos_verbose_enable; /* Camera */ diff --git a/file_path_special.c b/file_path_special.c index 3d5231a63f..b6ac69470e 100644 --- a/file_path_special.c +++ b/file_path_special.c @@ -1,6 +1,6 @@ /* RetroArch - A frontend for libretro. * Copyright (C) 2011-2017 - Daniel De Matteis - * + * * RetroArch is free software: you can redistribute it and/or modify it under the terms * of the GNU General Public License as published by the Free Software Found- * ation, either version 3 of the License, or (at your option) any later version. @@ -119,7 +119,7 @@ void fill_pathname_abbreviate_special(char *out_path, * Keep application dir in front of home, moving app dir to a * new location inside home would break otherwise. */ - /* ugly hack - use application_dir pointer + /* ugly hack - use application_dir pointer * before filling it in. C89 reasons */ candidates[0] = application_dir; candidates[1] = home; @@ -129,23 +129,23 @@ void fill_pathname_abbreviate_special(char *out_path, notations [1] = "~"; notations [2] = NULL; - fill_pathname_application_path(application_dir, + fill_pathname_application_path(application_dir, PATH_MAX_LENGTH * sizeof(char)); path_basedir_wrapper(application_dir); - + for (i = 0; candidates[i]; i++) { - if (!string_is_empty(candidates[i]) && + if (!string_is_empty(candidates[i]) && strstr(in_path, candidates[i]) == in_path) { size_t src_size = strlcpy(out_path, notations[i], size); retro_assert(src_size < size); - + out_path += src_size; size -= src_size; in_path += strlen(candidates[i]); - + if (!path_char_is_slash(*in_path)) { retro_assert(strlcpy(out_path, @@ -242,7 +242,7 @@ void fill_pathname_application_path(char *s, size_t len) CFStringGetCString(bundle_path, s, len, kCFStringEncodingUTF8); CFRelease(bundle_path); CFRelease(bundle_url); - + retro_assert(strlcat(s, "nobin", len) < len); return; } @@ -269,7 +269,7 @@ void fill_pathname_application_path(char *s, size_t len) char link_path[255]; link_path[0] = *s = '\0'; - pid = getpid(); + pid = getpid(); /* Linux, BSD and Solaris paths. Not standardized. */ for (i = 0; i < ARRAY_SIZE(exts); i++) @@ -287,7 +287,7 @@ void fill_pathname_application_path(char *s, size_t len) } } } - + RARCH_ERR("Cannot resolve application path! This should not happen.\n"); #endif } @@ -335,7 +335,7 @@ void fill_pathname_application_special(char *s, char *s1 = (char*)malloc(PATH_MAX_LENGTH * sizeof(char)); s1[0] = '\0'; - fill_pathname_application_special(s1, + fill_pathname_application_special(s1, PATH_MAX_LENGTH * sizeof(char), APPLICATION_SPECIAL_DIRECTORY_ASSETS_ZARCH); fill_pathname_join(s, @@ -349,7 +349,7 @@ void fill_pathname_application_special(char *s, #ifdef HAVE_ZARCH { settings_t *settings = config_get_ptr(); - fill_pathname_join(s, + fill_pathname_join(s, settings->paths.directory_assets, "zarch", len); @@ -501,6 +501,31 @@ void fill_pathname_application_special(char *s, } #endif break; + case APPLICATION_SPECIAL_DIRECTORY_THUMBNAILS_CHEEVOS_BADGES: + { + char *s1 = (char*)malloc(PATH_MAX_LENGTH * sizeof(char)); + char *s2 = (char*)malloc(PATH_MAX_LENGTH * sizeof(char)); + settings_t *settings = config_get_ptr(); + + s1[0] = s2[0] = '\0'; + + fill_pathname_join(s1, + settings->paths.directory_thumbnails, + "cheevos", + len); + fill_pathname_join(s2, + s1, "badges", + PATH_MAX_LENGTH * sizeof(char) + ); + fill_pathname_slash(s2, + PATH_MAX_LENGTH * sizeof(char) + ); + strlcpy(s, s2, len); + free(s1); + free(s2); + } + break; + case APPLICATION_SPECIAL_NONE: default: break; diff --git a/file_path_special.h b/file_path_special.h index e763f78a7f..4d959e1899 100644 --- a/file_path_special.h +++ b/file_path_special.h @@ -1,7 +1,7 @@ /* RetroArch - A frontend for libretro. * Copyright (C) 2010-2014 - Hans-Kristian Arntzen * Copyright (C) 2011-2016 - Daniel De Matteis - * + * * RetroArch is free software: you can redistribute it and/or modify it under the terms * of the GNU General Public License as published by the Free Software Found- * ation, either version 3 of the License, or (at your option) any later version. @@ -104,7 +104,8 @@ enum application_special_type APPLICATION_SPECIAL_DIRECTORY_ASSETS_XMB_FONT, APPLICATION_SPECIAL_DIRECTORY_ASSETS_ZARCH, APPLICATION_SPECIAL_DIRECTORY_ASSETS_ZARCH_FONT, - APPLICATION_SPECIAL_DIRECTORY_ASSETS_ZARCH_ICONS + APPLICATION_SPECIAL_DIRECTORY_ASSETS_ZARCH_ICONS, + APPLICATION_SPECIAL_DIRECTORY_THUMBNAILS_CHEEVOS_BADGES }; /** diff --git a/griffin/griffin.c b/griffin/griffin.c index 9b4a08f305..b65934f365 100644 --- a/griffin/griffin.c +++ b/griffin/griffin.c @@ -151,6 +151,7 @@ ACHIEVEMENTS #include "../libretro-common/formats/json/jsonsax.c" #include "../network/net_http_special.c" #include "../cheevos/cheevos.c" +#include "../cheevos/badges.c" #include "../cheevos/var.c" #include "../cheevos/cond.c" #endif diff --git a/intl/msg_hash_lbl.h b/intl/msg_hash_lbl.h index fbf28f4ca6..6cc3ee5313 100644 --- a/intl/msg_hash_lbl.h +++ b/intl/msg_hash_lbl.h @@ -136,6 +136,8 @@ MSG_HASH(MENU_ENUM_LABEL_CHEEVOS_HARDCORE_MODE_ENABLE, "cheevos_hardcore_mode_enable") MSG_HASH(MENU_ENUM_LABEL_CHEEVOS_LEADERBOARDS_ENABLE, "cheevos_leaderboards_enable") +MSG_HASH(MENU_ENUM_LABEL_CHEEVOS_BADGES_ENABLE, + "cheevos_badges_enable") MSG_HASH(MENU_ENUM_LABEL_CHEEVOS_LOCKED_ACHIEVEMENTS, "cheevos_locked_achievements") MSG_HASH(MENU_ENUM_LABEL_CHEEVOS_LOCKED_ENTRY, diff --git a/intl/msg_hash_us.h b/intl/msg_hash_us.h index a7f516c586..dbe83d50ba 100644 --- a/intl/msg_hash_us.h +++ b/intl/msg_hash_us.h @@ -434,6 +434,10 @@ MSG_HASH( MENU_ENUM_LABEL_VALUE_CHEEVOS_LEADERBOARDS_ENABLE, "Leaderboards" ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_CHEEVOS_BADGES_ENABLE, + "Achievement Badges" + ) MSG_HASH( MENU_ENUM_LABEL_VALUE_CHEEVOS_LOCKED_ACHIEVEMENTS, "Locked Achievements:" @@ -1791,6 +1795,8 @@ MSG_HASH(MENU_ENUM_SUBLABEL_CHEEVOS_HARDCORE_MODE_ENABLE, "Enable or disable savestates, cheats, rewind, fast-forward, pause, and slow-motion for all games.") MSG_HASH(MENU_ENUM_SUBLABEL_CHEEVOS_LEADERBOARDS_ENABLE, "Enable or disable in-game leaderboards. Has no effect if Hardcore Mode is disabled.") +MSG_HASH(MENU_ENUM_SUBLABEL_CHEEVOS_BADGES_ENABLE, + "Enable or disable badge display in Achievement List.") MSG_HASH(MENU_ENUM_SUBLABEL_CHEEVOS_VERBOSE_ENABLE, "Enable or disable OSD verbosity for achievements.") MSG_HASH(MENU_ENUM_SUBLABEL_DRIVER_SETTINGS, diff --git a/menu/cbs/menu_cbs_sublabel.c b/menu/cbs/menu_cbs_sublabel.c index 9b1013905a..db388d9def 100644 --- a/menu/cbs/menu_cbs_sublabel.c +++ b/menu/cbs/menu_cbs_sublabel.c @@ -63,6 +63,7 @@ default_sublabel_macro(action_bind_sublabel_cheevos_enable, MENU_ default_sublabel_macro(action_bind_sublabel_cheevos_test_unofficial, MENU_ENUM_SUBLABEL_CHEEVOS_TEST_UNOFFICIAL) default_sublabel_macro(action_bind_sublabel_cheevos_hardcore_mode_enable, MENU_ENUM_SUBLABEL_CHEEVOS_HARDCORE_MODE_ENABLE) default_sublabel_macro(action_bind_sublabel_cheevos_leaderboards_enable, MENU_ENUM_SUBLABEL_CHEEVOS_LEADERBOARDS_ENABLE) +default_sublabel_macro(action_bind_sublabel_cheevos_badges_enable, MENU_ENUM_SUBLABEL_CHEEVOS_BADGES_ENABLE) default_sublabel_macro(action_bind_sublabel_cheevos_verbose_enable, MENU_ENUM_SUBLABEL_CHEEVOS_VERBOSE_ENABLE) default_sublabel_macro(action_bind_sublabel_menu_views_settings_list, MENU_ENUM_SUBLABEL_MENU_VIEWS_SETTINGS) default_sublabel_macro(action_bind_sublabel_quick_menu_views_settings_list, MENU_ENUM_SUBLABEL_QUICK_MENU_VIEWS_SETTINGS) @@ -1266,6 +1267,9 @@ int menu_cbs_init_bind_sublabel(menu_file_list_cbs_t *cbs, case MENU_ENUM_LABEL_CHEEVOS_LEADERBOARDS_ENABLE: BIND_ACTION_SUBLABEL(cbs, action_bind_sublabel_cheevos_leaderboards_enable); break; + case MENU_ENUM_LABEL_CHEEVOS_BADGES_ENABLE: + BIND_ACTION_SUBLABEL(cbs, action_bind_sublabel_cheevos_badges_enable); + break; case MENU_ENUM_LABEL_CHEEVOS_VERBOSE_ENABLE: BIND_ACTION_SUBLABEL(cbs, action_bind_sublabel_cheevos_verbose_enable); break; diff --git a/menu/drivers/xmb.c b/menu/drivers/xmb.c index c1d5dac42e..7dc700b29e 100755 --- a/menu/drivers/xmb.c +++ b/menu/drivers/xmb.c @@ -61,6 +61,8 @@ #include "../../tasks/tasks_internal.h" +#include "../../cheevos/badges.h" + #define XMB_RIBBON_ROWS 64 #define XMB_RIBBON_COLS 64 #define XMB_RIBBON_VERTICES 2*XMB_RIBBON_COLS*XMB_RIBBON_ROWS-2*XMB_RIBBON_COLS @@ -2239,6 +2241,18 @@ static uintptr_t xmb_icon_get_id(xmb_handle_t *xmb, #endif } +#ifdef HAVE_CHEEVOS + if ((type >= MENU_SETTINGS_CHEEVOS_START) && + (type < MENU_SETTINGS_NETPLAY_ROOMS_START)) + { + int new_id = type - MENU_SETTINGS_CHEEVOS_START; + if ( get_badge_texture(new_id) != 0 ) + return get_badge_texture( new_id ); + else + return xmb->textures.list[XMB_TEXTURE_SUBSETTING]; // Should be replaced with placeholder badge icon. + } +#endif + return xmb->textures.list[XMB_TEXTURE_SUBSETTING]; } diff --git a/menu/menu_displaylist.c b/menu/menu_displaylist.c index e4dd8450d1..03290e1d8b 100644 --- a/menu/menu_displaylist.c +++ b/menu/menu_displaylist.c @@ -1572,7 +1572,7 @@ static int menu_displaylist_parse_playlist(menu_displaylist_info_t *info, free(tmp); } } - + free(path_short); } @@ -3495,7 +3495,7 @@ static int menu_displaylist_parse_options_remappings( } #ifdef HAVE_KEYMAPPER if (system) - { + { settings_t *settings = config_get_ptr(); unsigned device = settings->uints.input_libretro_device[settings->uints.keymapper_port]; @@ -3514,13 +3514,13 @@ static int menu_displaylist_parse_options_remappings( keybind = &input_config_binds[settings->uints.keymapper_port][retro_id]; auto_bind = (const struct retro_keybind*) input_config_get_bind_auto(settings->uints.keymapper_port, retro_id); - + input_config_get_bind_string(descriptor, keybind, auto_bind, sizeof(descriptor)); if(!strstr(descriptor, "Auto")) { - const struct retro_keybind *keyptr = + const struct retro_keybind *keyptr = &input_config_binds[settings->uints.keymapper_port][retro_id]; strlcpy(descriptor, msg_hash_to_str(keyptr->enum_idx), sizeof(descriptor)); @@ -3860,7 +3860,7 @@ static int menu_displaylist_parse_cores( malloc(PATH_MAX_LENGTH * sizeof(char)); char *display_name = (char*) malloc(PATH_MAX_LENGTH * sizeof(char)); - core_path[0] = + core_path[0] = display_name[0] = '\0'; fill_pathname_join(core_path, dir, path, @@ -4180,7 +4180,7 @@ static void menu_displaylist_parse_playlist_generic( { playlist_t *playlist = NULL; char *path_playlist = NULL; - + menu_displaylist_set_new_playlist(menu, playlist_path); menu_driver_ctl(RARCH_MENU_CTL_PLAYLIST_GET, &playlist); @@ -5615,6 +5615,12 @@ bool menu_displaylist_ctl(enum menu_displaylist_ctl_state type, void *data) menu_displaylist_parse_settings_enum(menu, info, MENU_ENUM_LABEL_CHEEVOS_LEADERBOARDS_ENABLE, PARSE_ONLY_BOOL, false); + if (string_is_equal_fast(settings->arrays.menu_driver, "xmb", 3)) + { + menu_displaylist_parse_settings_enum(menu, info, + MENU_ENUM_LABEL_CHEEVOS_BADGES_ENABLE, + PARSE_ONLY_BOOL, false); + } menu_displaylist_parse_settings_enum(menu, info, MENU_ENUM_LABEL_CHEEVOS_TEST_UNOFFICIAL, PARSE_ONLY_BOOL, false); diff --git a/menu/menu_setting.c b/menu/menu_setting.c index 168dd8bc5f..bb39557308 100644 --- a/menu/menu_setting.c +++ b/menu/menu_setting.c @@ -917,7 +917,7 @@ int menu_setting_set(unsigned type, const char *label, int ret = 0; file_list_t *selection_buf = menu_entries_get_selection_buf_ptr(0); size_t selection = menu_navigation_get_selection(); - menu_file_list_cbs_t *cbs = selection_buf ? + menu_file_list_cbs_t *cbs = selection_buf ? (menu_file_list_cbs_t*)file_list_get_actiondata_at_offset(selection_buf, selection) : NULL; if (!cbs) @@ -1446,7 +1446,7 @@ static int setting_action_ok_bind_defaults(void *data, bool wraparound) return 0; } -static void +static void setting_get_string_representation_st_float_video_refresh_rate_auto( void *data, char *s, size_t len) { @@ -6461,6 +6461,22 @@ static bool setting_append_list( SD_FLAG_NONE ); + CONFIG_BOOL( + list, list_info, + &settings->bools.cheevos_badges_enable, + MENU_ENUM_LABEL_CHEEVOS_BADGES_ENABLE, + MENU_ENUM_LABEL_VALUE_CHEEVOS_BADGES_ENABLE, + false, + MENU_ENUM_LABEL_VALUE_OFF, + MENU_ENUM_LABEL_VALUE_ON, + &group_info, + &subgroup_info, + parent_group, + general_write_handler, + general_read_handler, + SD_FLAG_NONE + ); + CONFIG_BOOL( list, list_info, &settings->bools.cheevos_verbose_enable, diff --git a/msg_hash.h b/msg_hash.h index 25f83229b8..b6a63286f0 100644 --- a/msg_hash.h +++ b/msg_hash.h @@ -853,6 +853,7 @@ enum msg_hash_enums MENU_LABEL(ACCOUNTS_CHEEVOS_USERNAME), MENU_LABEL(CHEEVOS_HARDCORE_MODE_ENABLE), MENU_LABEL(CHEEVOS_LEADERBOARDS_ENABLE), + MENU_LABEL(CHEEVOS_BADGES_ENABLE), MENU_LABEL(CHEEVOS_TEST_UNOFFICIAL), MENU_LABEL(CHEEVOS_VERBOSE_ENABLE), MENU_LABEL(CHEEVOS_ENABLE),