diff --git a/cheevos/cheevos.c b/cheevos/cheevos.c index 017199aa8a..c5aca66d00 100644 --- a/cheevos/cheevos.c +++ b/cheevos/cheevos.c @@ -99,27 +99,6 @@ #define CHEEVOS_EIGHT_MB ( 8 * 1024 * 1024) #define CHEEVOS_SIZE_LIMIT (64 * 1024 * 1024) -enum -{ - CHEEVOS_DIRTY_TITLE = 1 << 0, - CHEEVOS_DIRTY_DESC = 1 << 1, - CHEEVOS_DIRTY_POINTS = 1 << 2, - CHEEVOS_DIRTY_AUTHOR = 1 << 3, - CHEEVOS_DIRTY_ID = 1 << 4, - CHEEVOS_DIRTY_BADGE = 1 << 5, - CHEEVOS_DIRTY_CONDITIONS = 1 << 6, - CHEEVOS_DIRTY_VOTES = 1 << 7, - CHEEVOS_DIRTY_DESCRIPTION = 1 << 8, - - CHEEVOS_DIRTY_ALL = (1 << 9) - 1 -}; - -enum -{ - CHEEVOS_ACTIVE_SOFTCORE = 1 << 0, - CHEEVOS_ACTIVE_HARDCORE = 1 << 1 -}; - typedef struct { cheevos_cond_t *conds; @@ -208,18 +187,21 @@ typedef struct typedef struct { cheevos_var_t var; - int multiplier; + double multiplier; + bool compare_next; } cheevos_term_t; typedef struct { cheevos_term_t *terms; unsigned count; + unsigned compare_count; } cheevos_expr_t; typedef struct { unsigned id; + unsigned format; const char *title; const char *description; int active; @@ -231,6 +213,42 @@ typedef struct cheevos_expr_t value; } cheevos_leaderboard_t; +/* +typedef struct +{ + bool is_lookup; + char* prestring; + cheevos_expr_t expression; +} cheevos_rps_element_t; + +typedef struct +{ + char* name; + unsigned type; +} cheevos_rps_format_t; + +typedef struct +{ + unsigned compare; + char* result; +} cheevos_rps_lookup_value; + +typedef struct +{ + char* name; + cheevos_rps_lookup_value* values; +} cheevos_rps_lookup_t; + +typedef struct +{ + cheevos_rps_element_t* elements; + cheevos_rps_format_t* formats; + unsigned format_count; + cheevos_rps_lookup_t* lookups; + unsigned lookup_count; +} cheevos_rps_t; +*/ + typedef struct { int console_id; @@ -912,7 +930,6 @@ static int cheevos_parse_condition(cheevos_condition_t *condition, const char* m return 0; } -#ifdef CHEEVOS_ENABLE_LBOARDS static void cheevos_free_condition(cheevos_condition_t* condition) { unsigned i; @@ -925,49 +942,88 @@ static void cheevos_free_condition(cheevos_condition_t* condition) free((void*)condition->condsets); } } -#endif /***************************************************************************** Parse the Mem field of leaderboards. *****************************************************************************/ -#ifdef CHEEVOS_ENABLE_LBOARDS static int cheevos_parse_expression(cheevos_expr_t *expr, const char* mem) { const char* aux; char* end; unsigned i; expr->count = 1; + expr->compare_count = 1; for (aux = mem; *aux != '"'; aux++) - { expr->count += *aux == '_'; - } expr->terms = (cheevos_term_t*)calloc(expr->count, sizeof(cheevos_term_t)); if (!expr->terms) return -1; - for (i = 0, aux = mem; i < expr->count; i++) + for (i = 0; i < expr->count; i++) + { + expr->terms[i].compare_next = false; + expr->terms[i].multiplier = 1; + } + + for (i = 0, aux = mem; i < expr->count;) { cheevos_var_parse(&expr->terms[i].var, &aux); if (*aux != '*') { - free((void*)expr->terms); - return -1; + /* expression has no multiplier */ + if (*aux == '_') + { + aux++; + i++; + } + else if (*aux == '$') + { + expr->terms[i].compare_next = true; + expr->compare_count++; + aux++; + i++; + } + + /* no multiplier at end of string */ + else if (*aux == '\0' || *aux == '"' || *aux == ',') + return 0; + + /* invalid character in expression */ + else + { + free((void*)expr->terms); + return -1; + } } + else + { + if(aux[1] == 'h' || aux[1] == 'H') + expr->terms[i].multiplier = (double)strtol(aux + 2, &end, 16); + else + expr->terms[i].multiplier = strtod(aux + 1, &end); + aux = end; - expr->terms[i].multiplier = (int)strtol(aux + 1, &end, 10); - aux = end + 1; + if(*aux == '$') + { + aux++; + expr->terms[i].compare_next = true; + expr->compare_count++; + } + else + expr->terms[i].compare_next = false; + + aux++; + i++; + } } - return 0; } -#endif -#ifdef CHEEVOS_ENABLE_LBOARDS static int cheevos_parse_mem(cheevos_leaderboard_t *lb, const char* mem) { lb->start.condsets = NULL; @@ -1019,7 +1075,6 @@ error: free((void*)lb->value.terms); return -1; } -#endif /***************************************************************************** Load achievements from a JSON string. @@ -1082,12 +1137,81 @@ error: return -1; } -#ifdef CHEEVOS_ENABLE_LBOARDS +/***************************************************************************** +Helper functions for displaying leaderboard values. +*****************************************************************************/ + +static void cheevos_format_value(const unsigned value, const unsigned type, + char* formatted_value, size_t formatted_size) +{ + unsigned mins, secs, millis; + + switch(type) + { + case CHEEVOS_FORMAT_VALUE: + snprintf(formatted_value, formatted_size, "%u", value); + break; + + case CHEEVOS_FORMAT_SCORE: + snprintf(formatted_value, formatted_size, "%06upts", value); + break; + + case CHEEVOS_FORMAT_FRAMES: + mins = value / 3600; + secs = (value % 3600) / 60; + millis = (int) (value % 60) * (10.00 / 6.00); + snprintf(formatted_value, formatted_size, "%02u:%02u.%02u", mins, secs, millis); + break; + + case CHEEVOS_FORMAT_MILLIS: + mins = value / 6000; + secs = (value % 6000) / 100; + millis = (int) (value % 100); + snprintf(formatted_value, formatted_size, "%02u:%02u.%02u", mins, secs, millis); + break; + + case CHEEVOS_FORMAT_SECS: + mins = value / 60; + secs = value % 60; + snprintf(formatted_value, formatted_size, "%02u:%02u", mins, secs); + break; + + default: + snprintf(formatted_value, formatted_size, "%u (?)", value); + } +} + +unsigned cheevos_parse_format(cheevos_field_t* format) +{ + /* Most likely */ + if (strncmp(format->string, "VALUE", format->length) == 0) + return CHEEVOS_FORMAT_VALUE; + else if (strncmp(format->string, "TIME", format->length) == 0) + return CHEEVOS_FORMAT_FRAMES; + else if (strncmp(format->string, "SCORE", format->length) == 0) + return CHEEVOS_FORMAT_SCORE; + + /* Less likely */ + else if (strncmp(format->string, "MILLISECS", format->length) == 0) + return CHEEVOS_FORMAT_MILLIS; + else if (strncmp(format->string, "TIMESECS", format->length) == 0) + return CHEEVOS_FORMAT_SECS; + + /* Rare (RPS only) */ + else if (strncmp(format->string, "POINTS", format->length) == 0) + return CHEEVOS_FORMAT_SCORE; + else if (strncmp(format->string, "FRAMES", format->length) == 0) + return CHEEVOS_FORMAT_FRAMES; + else + return CHEEVOS_FORMAT_OTHER; +} + static int cheevos_new_lboard(cheevos_readud_t *ud) { cheevos_leaderboard_t *lboard = cheevos_locals.leaderboards + ud->lboard_count++; lboard->id = strtol(ud->id.string, NULL, 10); + lboard->format = cheevos_parse_format(&ud->format); lboard->title = cheevos_dupstr(&ud->title); lboard->description = cheevos_dupstr(&ud->desc); @@ -1108,7 +1232,6 @@ error: free((void*)lboard->description); return -1; } -#endif static int cheevos_read__json_key( void *userdata, const char *name, size_t length) @@ -1224,10 +1347,8 @@ static int cheevos_read__json_end_object(void *userdata) if (ud->in_cheevos) return cheevos_new_cheevo(ud); -#ifdef CHEEVOS_ENABLE_LBOARDS else if (ud->in_lboards) return cheevos_new_lboard(ud); -#endif return 0; } @@ -1632,8 +1753,11 @@ static void cheevos_test_cheevo_set(const cheevoset_t *set) RARCH_LOG("[CHEEVOS]: awarding cheevo %u: %s (%s).\n", cheevo->id, cheevo->title, cheevo->description); - runloop_msg_queue_push(cheevo->title, 0, 3 * 60, false); - runloop_msg_queue_push(cheevo->description, 0, 5 * 60, false); + char msg[256]; + snprintf(msg, sizeof(msg), "Achievement Unlocked: %s", cheevo->title); + msg[sizeof(msg) - 1] = 0; + runloop_msg_queue_push(msg, 0, 2 * 60, false); + runloop_msg_queue_push(cheevo->description, 0, 3 * 60, false); cheevos_make_unlock_url(cheevo, url, sizeof(url)); task_push_http_transfer(url, true, NULL, cheevos_unlocked, cheevo); @@ -1644,7 +1768,6 @@ static void cheevos_test_cheevo_set(const cheevoset_t *set) } } -#ifdef CHEEVOS_ENABLE_LBOARDS static int cheevos_test_lboard_condition(const cheevos_condition_t* condition) { int dirty_conds = 0; @@ -1679,14 +1802,28 @@ static int cheevos_expr_value(cheevos_expr_t* expr) { cheevos_term_t* term = expr->terms; unsigned i; - int value = 0; + + /* Separate possible values with '$' operator, submit the largest */ + unsigned current_value = 0; + int values[expr->compare_count]; + memset(values, 0, sizeof values); for (i = expr->count; i != 0; i--, term++) { - value += cheevos_var_get_value(&term->var) * term->multiplier; + values[current_value] += cheevos_var_get_value(&term->var) * term->multiplier; + if (term->compare_next) + current_value++; } - return value; + if (expr->compare_count > 1) + { + int maximum = values[0]; + for (unsigned j = 1; j < expr->compare_count; j++) + maximum = values[j] > maximum ? values[j] : maximum; + + return maximum; + } + else return values[0]; } static void cheevos_make_lboard_url(const cheevos_leaderboard_t *lboard, @@ -1699,7 +1836,7 @@ static void cheevos_make_lboard_url(const cheevos_leaderboard_t *lboard, hash[0] = '\0'; - snprintf(signature, sizeof(signature), "%u%s%u", lboard->id, + snprintf(signature, sizeof(signature), "%u%s%u", lboard->id, settings->arrays.cheevos_username, lboard->id); @@ -1727,9 +1864,7 @@ static void cheevos_make_lboard_url(const cheevos_leaderboard_t *lboard, cheevos_log_url("[CHEEVOS]: url to submit the leaderboard: %s\n", url); #endif } -#endif -#ifdef CHEEVOS_ENABLE_LBOARDS static void cheevos_lboard_submit(void *task_data, void *user_data, const char *error) { cheevos_leaderboard_t *lboard = (cheevos_leaderboard_t *)user_data; @@ -1752,9 +1887,7 @@ static void cheevos_lboard_submit(void *task_data, void *user_data, const char * } #endif } -#endif -#ifdef CHEEVOS_ENABLE_LBOARDS static void cheevos_test_leaderboards(void) { cheevos_leaderboard_t* lboard = cheevos_locals.leaderboards; @@ -1776,18 +1909,35 @@ static void cheevos_test_leaderboards(void) if (cheevos_test_lboard_condition(&lboard->submit)) { - char url[256]; + lboard->active = 0; - cheevos_make_lboard_url(lboard, url, sizeof(url)); - task_push_http_transfer(url, true, NULL, cheevos_lboard_submit, lboard); + /* failsafe for improper LBs */ + if (value == 0) + { + RARCH_LOG("[CHEEVOS]: error: lboard %s tried to submit 0\n", lboard->title); + runloop_msg_queue_push("Leaderboard attempt cancelled!", 0, 2 * 60, false); + } + else + { + char url[256]; + cheevos_make_lboard_url(lboard, url, sizeof(url)); + task_push_http_transfer(url, true, NULL, cheevos_lboard_submit, lboard); + RARCH_LOG("[CHEEVOS]: submit lboard %s\n", lboard->title); - RARCH_LOG("[CHEEVOS]: submit lboard %s\n", lboard->title); + char msg[256]; + char formatted_value[16]; + cheevos_format_value(value, lboard->format, formatted_value, sizeof(formatted_value)); + snprintf(msg, sizeof(msg), "Submitted %s for %s", formatted_value, lboard->title); + msg[sizeof(msg) - 1] = 0; + runloop_msg_queue_push(msg, 0, 2 * 60, false); + } } if (cheevos_test_lboard_condition(&lboard->cancel)) { RARCH_LOG("[CHEEVOS]: cancel lboard %s\n", lboard->title); lboard->active = 0; + runloop_msg_queue_push("Leaderboard attempt cancelled!", 0, 2 * 60, false); } } else @@ -1797,11 +1947,16 @@ static void cheevos_test_leaderboards(void) RARCH_LOG("[CHEEVOS]: start lboard %s\n", lboard->title); lboard->active = 1; lboard->last_value = -1; + + char msg[256]; + snprintf(msg, sizeof(msg), "Leaderboard Active: %s", lboard->title); + msg[sizeof(msg) - 1] = 0; + runloop_msg_queue_push(msg, 0, 2 * 60, false); + runloop_msg_queue_push(lboard->description, 0, 3*60, false); } } } } -#endif /***************************************************************************** Free the loaded achievements. @@ -2130,7 +2285,7 @@ static void cheevos_patch_addresses(cheevoset_t* set) case CHEEVOS_VAR_TYPE_DELTA_MEM: cheevos_var_patch_addr(&cond->source, cheevos_locals.console_id); #ifdef CHEEVOS_DUMP_ADDRS - RARCH_LOG("[CHEEVOS]: var %03d:%08X\n", cond->source.bank_id + 1, cond->source.value); + RARCH_LOG("[CHEEVOS]: s-var %03d:%08X\n", cond->source.bank_id + 1, cond->source.value); #endif break; @@ -2144,7 +2299,7 @@ static void cheevos_patch_addresses(cheevoset_t* set) case CHEEVOS_VAR_TYPE_DELTA_MEM: cheevos_var_patch_addr(&cond->target, cheevos_locals.console_id); #ifdef CHEEVOS_DUMP_ADDRS - RARCH_LOG("[CHEEVOS]: var %03d:%08X\n", cond->target.bank_id + 1, cond->target.value); + RARCH_LOG("[CHEEVOS]: t-var %03d:%08X\n", cond->target.bank_id + 1, cond->target.value); #endif break; @@ -2156,6 +2311,85 @@ static void cheevos_patch_addresses(cheevoset_t* set) } } +static void cheevos_patch_lb_conditions(cheevos_condition_t* condition) +{ + unsigned i, j; + cheevos_condset_t* condset = condition->condsets; + + for (i = condition->count; i != 0; i--, condset++) + { + cheevos_cond_t* cond = condset->conds; + + for (j = condset->count; j != 0; j--, cond++) + { + switch (cond->source.type) + { + case CHEEVOS_VAR_TYPE_ADDRESS: + case CHEEVOS_VAR_TYPE_DELTA_MEM: + cheevos_var_patch_addr(&cond->source, cheevos_locals.console_id); +#ifdef CHEEVOS_DUMP_ADDRS + RARCH_LOG("[CHEEVOS]: s-var %03d:%08X\n", cond->source.bank_id + 1, cond->source.value); +#endif + break; + default: + break; + } + switch (cond->target.type) + { + case CHEEVOS_VAR_TYPE_ADDRESS: + case CHEEVOS_VAR_TYPE_DELTA_MEM: + cheevos_var_patch_addr(&cond->target, cheevos_locals.console_id); +#ifdef CHEEVOS_DUMP_ADDRS + RARCH_LOG("[CHEEVOS]: t-var %03d:%08X\n", cond->target.bank_id + 1, cond->target.value); +#endif + break; + default: + break; + } + } + } +} + +static void cheevos_patch_lb_expressions(cheevos_expr_t* expression) +{ + unsigned i; + cheevos_term_t* term = expression->terms; + + for (i = expression->count; i != 0; i--, term++) + { + switch (term->var.type) + { + case CHEEVOS_VAR_TYPE_ADDRESS: + case CHEEVOS_VAR_TYPE_DELTA_MEM: + cheevos_var_patch_addr(&term->var, cheevos_locals.console_id); +#ifdef CHEEVOS_DUMP_ADDRS + RARCH_LOG("[CHEEVOS]: s-var %03d:%08X\n", term->var.bank_id + 1, term->var.value); +#endif + break; + default: + break; + } + } +} + +static void cheevos_patch_lbs(cheevos_leaderboard_t *leaderboard) +{ + unsigned i; + + for(i = 0; i < cheevos_locals.lboard_count; i++) + { + cheevos_condition_t* start = &leaderboard[i].start; + cheevos_condition_t* cancel = &leaderboard[i].cancel; + cheevos_condition_t* submit = &leaderboard[i].submit; + cheevos_expr_t* value = &leaderboard[i].value; + + cheevos_patch_lb_conditions(start); + cheevos_patch_lb_conditions(cancel); + cheevos_patch_lb_conditions(submit); + cheevos_patch_lb_expressions(value); + } +} + void cheevos_test(void) { settings_t *settings = config_get_ptr(); @@ -2164,6 +2398,7 @@ void cheevos_test(void) { cheevos_patch_addresses(&cheevos_locals.core); cheevos_patch_addresses(&cheevos_locals.unofficial); + cheevos_patch_lbs(cheevos_locals.leaderboards); cheevos_locals.addrs_patched = true; } @@ -2173,9 +2408,8 @@ void cheevos_test(void) if (settings->bools.cheevos_test_unofficial) cheevos_test_cheevo_set(&cheevos_locals.unofficial); -#ifdef CHEEVOS_ENABLE_LBOARDS - cheevos_test_leaderboards(); -#endif + if (settings->bools.cheevos_hardcore_mode_enable && settings->bools.cheevos_leaderboards_enable) + cheevos_test_leaderboards(); } bool cheevos_set_cheats(void) diff --git a/cheevos/cheevos.h b/cheevos/cheevos.h index 359d8a541b..dedc017ec3 100644 --- a/cheevos/cheevos.h +++ b/cheevos/cheevos.h @@ -60,10 +60,59 @@ typedef enum CHEEVOS_CONSOLE_SEGA_CD = 9, CHEEVOS_CONSOLE_SEGA_32X = 10, CHEEVOS_CONSOLE_MASTER_SYSTEM = 11, - CHEEVOS_CONSOLE_XBOX_360 = 12, - CHEEVOS_CONSOLE_ATARI_LYNX = 13 + CHEEVOS_CONSOLE_PLAYSTATION = 12, + CHEEVOS_CONSOLE_ATARI_LYNX = 13, + CHEEVOS_CONSOLE_NEOGEO = 14, + CHEEVOS_CONSOLE_XBOX_360 = 15, + CHEEVOS_CONSOLE_GAMECUBE = 16, + CHEEVOS_CONSOLE_ATARI_JAGUAR = 17, + CHEEVOS_CONSOLE_NINTENDO_DS = 18, + CHEEVOS_CONSOLE_WII = 19, + CHEEVOS_CONSOLE_WII_U = 20, + CHEEVOS_CONSOLE_PLAYSTATION_2 = 21, + CHEEVOS_CONSOLE_XBOX = 22, + CHEEVOS_CONSOLE_SKYNET = 23, + CHEEVOS_CONSOLE_XBOX_ONE = 24, + CHEEVOS_CONSOLE_ATARI_2600 = 25, + CHEEVOS_CONSOLE_MS_DOS = 26, + CHEEVOS_CONSOLE_ARCADE = 27, + CHEEVOS_CONSOLE_VIRTUAL_BOY = 28, + CHEEVOS_CONSOLE_MSX = 29, + CHEEVOS_CONSOLE_COMMODORE_64 = 30, + CHEEVOS_CONSOLE_ZX81 = 31 } cheevos_console_t; +enum +{ + CHEEVOS_DIRTY_TITLE = 1 << 0, + CHEEVOS_DIRTY_DESC = 1 << 1, + CHEEVOS_DIRTY_POINTS = 1 << 2, + CHEEVOS_DIRTY_AUTHOR = 1 << 3, + CHEEVOS_DIRTY_ID = 1 << 4, + CHEEVOS_DIRTY_BADGE = 1 << 5, + CHEEVOS_DIRTY_CONDITIONS = 1 << 6, + CHEEVOS_DIRTY_VOTES = 1 << 7, + CHEEVOS_DIRTY_DESCRIPTION = 1 << 8, + + CHEEVOS_DIRTY_ALL = (1 << 9) - 1 +}; + +enum +{ + CHEEVOS_ACTIVE_SOFTCORE = 1 << 0, + CHEEVOS_ACTIVE_HARDCORE = 1 << 1 +}; + +enum +{ + CHEEVOS_FORMAT_FRAMES = 0, + CHEEVOS_FORMAT_SECS, + CHEEVOS_FORMAT_MILLIS, + CHEEVOS_FORMAT_SCORE, + CHEEVOS_FORMAT_VALUE, + CHEEVOS_FORMAT_OTHER +}; + bool cheevos_load(const void *data); void cheevos_reset_game(void); diff --git a/configuration.c b/configuration.c index 8af969924f..21ce17f95d 100644 --- a/configuration.c +++ b/configuration.c @@ -1254,6 +1254,7 @@ static struct config_bool_setting *populate_settings_bool(settings_t *settings, SETTING_BOOL("cheevos_enable", &settings->bools.cheevos_enable, true, cheevos_enable, false); 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); SETTING_BOOL("cheevos_verbose_enable", &settings->bools.cheevos_verbose_enable, true, false, false); #endif #ifdef HAVE_OVERLAY diff --git a/configuration.h b/configuration.h index 5cb68b115e..ee2d29d5f7 100644 --- a/configuration.h +++ b/configuration.h @@ -183,6 +183,7 @@ typedef struct settings bool cheevos_enable; bool cheevos_test_unofficial; bool cheevos_hardcore_mode_enable; + bool cheevos_leaderboards_enable; bool cheevos_verbose_enable; /* Camera */ diff --git a/intl/msg_hash_lbl.h b/intl/msg_hash_lbl.h index f454ba44d6..cfe8f4f569 100644 --- a/intl/msg_hash_lbl.h +++ b/intl/msg_hash_lbl.h @@ -134,6 +134,8 @@ MSG_HASH(MENU_ENUM_LABEL_CHEEVOS_ENABLE, "cheevos_enable") 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_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 7ba572c5ca..f66cb7cf77 100644 --- a/intl/msg_hash_us.h +++ b/intl/msg_hash_us.h @@ -176,7 +176,7 @@ MSG_HASH( ) MSG_HASH( MENU_ENUM_LABEL_VALUE_ACCOUNTS_RETRO_ACHIEVEMENTS, - "Retro Achievements" + "RetroAchievements" ) MSG_HASH( MENU_ENUM_LABEL_VALUE_ACHIEVEMENT_LIST, @@ -430,6 +430,10 @@ MSG_HASH( MENU_ENUM_LABEL_VALUE_CHEEVOS_HARDCORE_MODE_ENABLE, "Achievements Hardcore Mode" ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_CHEEVOS_LEADERBOARDS_ENABLE, + "Leaderboards" + ) MSG_HASH( MENU_ENUM_LABEL_VALUE_CHEEVOS_LOCKED_ACHIEVEMENTS, "Locked Achievements:" @@ -440,16 +444,12 @@ MSG_HASH( ) MSG_HASH( MENU_ENUM_LABEL_VALUE_CHEEVOS_SETTINGS, - "Retro Achievements" + "RetroAchievements" ) MSG_HASH( MENU_ENUM_LABEL_VALUE_CHEEVOS_TEST_UNOFFICIAL, "Test Unofficial Achievements" ) -MSG_HASH( - MENU_ENUM_LABEL_VALUE_CHEEVOS_VERBOSE_ENABLE, - "Achievements Verbose Mode" - ) MSG_HASH( MENU_ENUM_LABEL_VALUE_CHEEVOS_UNLOCKED_ACHIEVEMENTS, "Unlocked Achievements:" @@ -458,6 +458,10 @@ MSG_HASH( MENU_ENUM_LABEL_VALUE_CHEEVOS_UNLOCKED_ENTRY, "Unlocked" ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_CHEEVOS_VERBOSE_ENABLE, + "Achievements Verbose Mode" + ) MSG_HASH( MENU_ENUM_LABEL_VALUE_CLOSE_CONTENT, "Close Content" @@ -1781,6 +1785,8 @@ MSG_HASH(MENU_ENUM_SUBLABEL_CHEEVOS_TEST_UNOFFICIAL, "Enable or disable unofficial achievements and/or beta features for testing purposes.") 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_VERBOSE_ENABLE, "Enable or disable OSD verbosity for achievements.") MSG_HASH(MENU_ENUM_SUBLABEL_DRIVER_SETTINGS, @@ -2495,9 +2501,9 @@ MSG_HASH(MENU_ENUM_SUBLABEL_VIDEO_SMOOTH, MSG_HASH(MENU_ENUM_SUBLABEL_VIDEO_FILTER, "Apply a CPU-powered video filter. NOTE: Might come at a high performance cost. Some video filters might only work for cores that use 32bit or 16bit color.") MSG_HASH(MENU_ENUM_SUBLABEL_CHEEVOS_USERNAME, - "Input the username of your Retro Achievements account.") + "Input the username of your RetroAchievements account.") MSG_HASH(MENU_ENUM_SUBLABEL_CHEEVOS_PASSWORD, - "Input the password of your Retro Achievements account.") + "Input the password of your RetroAchievements account.") MSG_HASH(MENU_ENUM_SUBLABEL_NETPLAY_NICKNAME, "Input your user name here. This will be used for netplay sessions, among other things.") MSG_HASH(MENU_ENUM_SUBLABEL_VIDEO_POST_FILTER_RECORD, @@ -2860,7 +2866,7 @@ MSG_HASH(MENU_ENUM_SUBLABEL_UNDO_SAVE_STATE, "If a state was overwritten, it will roll back to the previous save state.") MSG_HASH( MENU_ENUM_SUBLABEL_ACCOUNTS_RETRO_ACHIEVEMENTS, - "Retro Achievements service. For more information, visit http://retroachievements.org" + "RetroAchievements service. For more information, visit http://retroachievements.org" ) MSG_HASH( MENU_ENUM_SUBLABEL_ACCOUNTS_LIST, diff --git a/menu/cbs/menu_cbs_sublabel.c b/menu/cbs/menu_cbs_sublabel.c index 49994a53df..9b1013905a 100644 --- a/menu/cbs/menu_cbs_sublabel.c +++ b/menu/cbs/menu_cbs_sublabel.c @@ -62,6 +62,7 @@ default_sublabel_macro(action_bind_sublabel_information_list_list, MENU_ default_sublabel_macro(action_bind_sublabel_cheevos_enable, MENU_ENUM_SUBLABEL_CHEEVOS_ENABLE) 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_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) @@ -1262,6 +1263,9 @@ int menu_cbs_init_bind_sublabel(menu_file_list_cbs_t *cbs, case MENU_ENUM_LABEL_CHEEVOS_HARDCORE_MODE_ENABLE: BIND_ACTION_SUBLABEL(cbs, action_bind_sublabel_cheevos_hardcore_mode_enable); break; + case MENU_ENUM_LABEL_CHEEVOS_LEADERBOARDS_ENABLE: + BIND_ACTION_SUBLABEL(cbs, action_bind_sublabel_cheevos_leaderboards_enable); + break; case MENU_ENUM_LABEL_CHEEVOS_VERBOSE_ENABLE: BIND_ACTION_SUBLABEL(cbs, action_bind_sublabel_cheevos_verbose_enable); break; diff --git a/menu/menu_displaylist.c b/menu/menu_displaylist.c index 37a7f724a5..34bce396ea 100644 --- a/menu/menu_displaylist.c +++ b/menu/menu_displaylist.c @@ -5602,10 +5602,13 @@ bool menu_displaylist_ctl(enum menu_displaylist_ctl_state type, void *data) MENU_ENUM_LABEL_CHEEVOS_PASSWORD, PARSE_ONLY_STRING, false); menu_displaylist_parse_settings_enum(menu, info, - MENU_ENUM_LABEL_CHEEVOS_TEST_UNOFFICIAL, + MENU_ENUM_LABEL_CHEEVOS_HARDCORE_MODE_ENABLE, PARSE_ONLY_BOOL, false); menu_displaylist_parse_settings_enum(menu, info, - MENU_ENUM_LABEL_CHEEVOS_HARDCORE_MODE_ENABLE, + MENU_ENUM_LABEL_CHEEVOS_LEADERBOARDS_ENABLE, + PARSE_ONLY_BOOL, false); + menu_displaylist_parse_settings_enum(menu, info, + MENU_ENUM_LABEL_CHEEVOS_TEST_UNOFFICIAL, PARSE_ONLY_BOOL, false); menu_displaylist_parse_settings_enum(menu, info, MENU_ENUM_LABEL_CHEEVOS_VERBOSE_ENABLE, diff --git a/menu/menu_setting.c b/menu/menu_setting.c index 76f57f5a89..168dd8bc5f 100644 --- a/menu/menu_setting.c +++ b/menu/menu_setting.c @@ -6445,6 +6445,22 @@ static bool setting_append_list( SD_FLAG_ADVANCED ); + CONFIG_BOOL( + list, list_info, + &settings->bools.cheevos_leaderboards_enable, + MENU_ENUM_LABEL_CHEEVOS_LEADERBOARDS_ENABLE, + MENU_ENUM_LABEL_VALUE_CHEEVOS_LEADERBOARDS_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 e15745a6b3..cf03f09a43 100644 --- a/msg_hash.h +++ b/msg_hash.h @@ -849,6 +849,7 @@ enum msg_hash_enums MENU_LABEL(ACCOUNTS_CHEEVOS_USERNAME), MENU_LABEL(CHEEVOS_HARDCORE_MODE_ENABLE), + MENU_LABEL(CHEEVOS_LEADERBOARDS_ENABLE), MENU_LABEL(CHEEVOS_TEST_UNOFFICIAL), MENU_LABEL(CHEEVOS_VERBOSE_ENABLE), MENU_LABEL(CHEEVOS_ENABLE),