From 2b345b8d48148eec139d67e535a4467db06c267a Mon Sep 17 00:00:00 2001 From: Andre Leiradella Date: Sun, 13 Nov 2016 20:58:09 +0000 Subject: [PATCH 1/2] Fixed math to translate a physical address to the memory descriptor index + offset --- cheevos.c | 352 +++++++++++++++++++++++++++++++----------------------- core.h | 14 ++- dynamic.c | 79 ++++++------ 3 files changed, 255 insertions(+), 190 deletions(-) diff --git a/cheevos.c b/cheevos.c index 43525407d1..3622aa241f 100644 --- a/cheevos.c +++ b/cheevos.c @@ -58,20 +58,27 @@ /* Define this macro to get extra-verbose log for cheevos. */ #undef CHEEVOS_VERBOSE -#define JSON_KEY_GAMEID 0xb4960eecU -#define JSON_KEY_ACHIEVEMENTS 0x69749ae1U -#define JSON_KEY_ID 0x005973f2U -#define JSON_KEY_MEMADDR 0x1e76b53fU -#define JSON_KEY_TITLE 0x0e2a9a07U -#define JSON_KEY_DESCRIPTION 0xe61a1f69U -#define JSON_KEY_POINTS 0xca8fce22U -#define JSON_KEY_AUTHOR 0xa804edb8U -#define JSON_KEY_MODIFIED 0xdcea4fe6U -#define JSON_KEY_CREATED 0x3a84721dU -#define JSON_KEY_BADGENAME 0x887685d9U -#define JSON_KEY_CONSOLE_ID 0x071656e5U -#define JSON_KEY_TOKEN 0x0e2dbd26U -#define JSON_KEY_FLAGS 0x0d2e96b2U +/* Define this macro to load a JSON file from disk instead of downloading + * from retroachievements.org. */ +#undef CHEEVOS_JSON_OVERRIDE + +enum +{ + CHEEVOS_JSON_KEY_GAMEID = 0xb4960eecU, + CHEEVOS_JSON_KEY_ACHIEVEMENTS = 0x69749ae1U, + CHEEVOS_JSON_KEY_ID = 0x005973f2U, + CHEEVOS_JSON_KEY_MEMADDR = 0x1e76b53fU, + CHEEVOS_JSON_KEY_TITLE = 0x0e2a9a07U, + CHEEVOS_JSON_KEY_DESCRIPTION = 0xe61a1f69U, + CHEEVOS_JSON_KEY_POINTS = 0xca8fce22U, + CHEEVOS_JSON_KEY_AUTHOR = 0xa804edb8U, + CHEEVOS_JSON_KEY_MODIFIED = 0xdcea4fe6U, + CHEEVOS_JSON_KEY_CREATED = 0x3a84721dU, + CHEEVOS_JSON_KEY_BADGENAME = 0x887685d9U, + CHEEVOS_JSON_KEY_CONSOLE_ID = 0x071656e5U, + CHEEVOS_JSON_KEY_TOKEN = 0x0e2dbd26U, + CHEEVOS_JSON_KEY_FLAGS = 0x0d2e96b2U +}; enum { @@ -184,10 +191,14 @@ typedef struct { cheevos_cond_t *conds; unsigned count; - - const char* expression; } cheevos_condset_t; +typedef struct +{ + cheevos_condset_t *condsets; + unsigned count; +} cheevos_condition_t; + typedef struct { unsigned id; @@ -201,8 +212,7 @@ typedef struct int last; int modified; - cheevos_condset_t *condsets; - unsigned count; + cheevos_condition_t condition; } cheevo_t; typedef struct @@ -406,7 +416,7 @@ static void cheevos_log_cheevo(const cheevo_t* cheevo, RARCH_LOG("CHEEVOS author: %s\n", cheevo->author); RARCH_LOG("CHEEVOS badge: %s\n", cheevo->badge); RARCH_LOG("CHEEVOS points: %u\n", cheevo->points); - RARCH_LOG("CHEEVOS sets: %u\n", cheevo->count); + RARCH_LOG("CHEEVOS sets: TBD\n"); RARCH_LOG("CHEEVOS memaddr: %s\n", memaddr); } @@ -458,16 +468,36 @@ static void cheevos_add_var_size(char** aux, size_t* left, } } -static void cheevos_post_log_cheevo(const cheevo_t* cheevo) +static void cheevos_add_var(const cheevos_var_t* var, char** memaddr, + size_t *left) +{ + if ( var->type == CHEEVOS_VAR_TYPE_ADDRESS + || var->type == CHEEVOS_VAR_TYPE_DELTA_MEM) + { + if (var->type == CHEEVOS_VAR_TYPE_DELTA_MEM) + cheevos_add_char(memaddr, left, 'd'); + + cheevos_add_string(memaddr, left, "0x"); + cheevos_add_var_size(memaddr, left, var); + cheevos_add_hex(memaddr, left, var->value); + } + else if (var->type == CHEEVOS_VAR_TYPE_VALUE_COMP) + { + cheevos_add_uint(memaddr, left, var->value); + } +} + +static void cheevos_build_memaddr(const cheevos_condition_t* condition, + char* memaddr, size_t left) { - char memaddr[256]; char *aux = memaddr; - size_t left = sizeof(memaddr); const cheevos_condset_t* condset; const cheevos_cond_t* cond; size_t i, j; - for (i = 0, condset = cheevo->condsets; i < cheevo->count; i++, condset++) + left--; /* reserve one char for the null terminator */ + + for (i = 0, condset = condition->condsets; i < condition->count; i++, condset++) { if (i != 0) cheevos_add_char(&aux, &left, 'S'); @@ -482,20 +512,7 @@ static void cheevos_post_log_cheevo(const cheevo_t* cheevo) else if (cond->type == CHEEVOS_COND_TYPE_PAUSE_IF) cheevos_add_string(&aux, &left, "P:"); - if ( cond->source.type == CHEEVOS_VAR_TYPE_ADDRESS - || cond->source.type == CHEEVOS_VAR_TYPE_DELTA_MEM) - { - if (cond->source.type == CHEEVOS_VAR_TYPE_DELTA_MEM) - cheevos_add_char(&aux, &left, 'd'); - - cheevos_add_string(&aux, &left, "0x"); - cheevos_add_var_size(&aux, &left, &cond->source); - cheevos_add_hex(&aux, &left, cond->source.value); - } - else if (cond->source.type == CHEEVOS_VAR_TYPE_VALUE_COMP) - { - cheevos_add_uint(&aux, &left, cond->source.value); - } + cheevos_add_var(&cond->source, &aux, &left); switch (cond->op) { @@ -519,20 +536,7 @@ static void cheevos_post_log_cheevo(const cheevo_t* cheevo) break; } - if ( cond->target.type == CHEEVOS_VAR_TYPE_ADDRESS - || cond->target.type == CHEEVOS_VAR_TYPE_DELTA_MEM) - { - if (cond->target.type == CHEEVOS_VAR_TYPE_DELTA_MEM) - cheevos_add_char(&aux, &left, 'd'); - - cheevos_add_string(&aux, &left, "0x"); - cheevos_add_var_size(&aux, &left, &cond->target); - cheevos_add_hex(&aux, &left, cond->target.value); - } - else if (cond->target.type == CHEEVOS_VAR_TYPE_VALUE_COMP) - { - cheevos_add_uint(&aux, &left, cond->target.value); - } + cheevos_add_var(&cond->target, &aux, &left); if (cond->req_hits > 0) { @@ -543,9 +547,13 @@ static void cheevos_post_log_cheevo(const cheevo_t* cheevo) } } - cheevos_add_char(&aux, &left, 0); - memaddr[sizeof(memaddr) - 1] = 0; + *aux = 0; +} +static void cheevos_post_log_cheevo(const cheevo_t* cheevo) +{ + char memaddr[256]; + cheevos_build_memaddr(&cheevo->condition, memaddr, sizeof(memaddr)); RARCH_LOG("CHEEVOS memaddr (computed): %s\n", memaddr); } #endif @@ -706,7 +714,7 @@ static int cheevos_count__json_key(void *userdata, cheevos_countud_t* ud = (cheevos_countud_t*)userdata; ud->field_hash = cheevos_djb2(name, length); - if (ud->field_hash == JSON_KEY_ACHIEVEMENTS) + if (ud->field_hash == CHEEVOS_JSON_KEY_ACHIEVEMENTS) ud->in_cheevos = 1; return 0; @@ -717,21 +725,14 @@ static int cheevos_count__json_number(void *userdata, { cheevos_countud_t* ud = (cheevos_countud_t*)userdata; - if (ud->in_cheevos && ud->field_hash == JSON_KEY_FLAGS) + if (ud->in_cheevos && ud->field_hash == CHEEVOS_JSON_KEY_FLAGS) { long flags = strtol(number, NULL, 10); - switch (flags) - { - case 3: /* Core achievements */ - ud->core_count++; - break; - case 5: /* Unofficial achievements */ - ud->unofficial_count++; - break; - default: - break; - } + if (flags == 3) + ud->core_count++; /* Core achievements */ + else if (flags == 5) + ud->unofficial_count++; /* Unofficial achievements */ } return 0; @@ -878,6 +879,29 @@ static unsigned cheevos_parse_operator(const char **memaddr) return op; } +static size_t cheevos_reduce(size_t addr, size_t mask) +{ + while (mask) + { + size_t tmp = (mask - 1) & ~mask; + addr = (addr & tmp) | ((addr >> 1) & ~tmp); + mask = (mask & (mask - 1)) >> 1; + } + + return addr; +} + +static size_t cheevos_highest_bit(size_t n) +{ + n |= n >> 1; + n |= n >> 2; + n |= n >> 4; + n |= n >> 8; + n |= n >> 16; + + return n ^ (n >> 1); +} + void cheevos_parse_guest_addr(cheevos_var_t *var, unsigned value) { rarch_system_info_t *system; @@ -892,8 +916,8 @@ void cheevos_parse_guest_addr(cheevos_var_t *var, unsigned value) if (system->mmaps.num_descriptors != 0) { - const struct retro_memory_descriptor *desc = NULL; - const struct retro_memory_descriptor *end = NULL; + const rarch_memory_descriptor_t *desc = NULL; + const rarch_memory_descriptor_t *end = NULL; switch (cheevos_locals.console_id) { @@ -917,10 +941,17 @@ void cheevos_parse_guest_addr(cheevos_var_t *var, unsigned value) for (; desc < end; desc++) { - if ((var->value & desc->select) == desc->start) + if (((desc->core.start ^ var->value) & desc->core.select) == 0) { var->bank_id = desc - system->mmaps.descriptors; - var->value = var->value - desc->start + desc->offset; + var->value = cheevos_reduce( + (var->value - desc->core.start) & desc->disconnect_mask, + desc->core.disconnect); + + if (var->value >= desc->core.len) + var->value -= cheevos_highest_bit(var->value); + + var->value += desc->core.offset; break; } } @@ -1118,9 +1149,52 @@ static void cheevos_parse_memaddr(cheevos_cond_t *cond, const char *memaddr, uns memaddr++; } +} - if (*memaddr != '"') - RARCH_LOG("CHEEVOS error parsing memaddr\n"); +static int cheevos_parse_condition(cheevos_condition_t *condition, const char* memaddr) +{ + condition->count = cheevos_count_cond_sets(memaddr); + + if (condition->count) + { + unsigned set = 0; + cheevos_condset_t *condset = NULL; + cheevos_condset_t *conds = (cheevos_condset_t*) + calloc(condition->count, sizeof(cheevos_condset_t)); + const cheevos_condset_t* end; + + if (!conds) + return -1; + + condition->condsets = conds; + end = condition->condsets + condition->count; + + for (condset = condition->condsets; condset < end; condset++, set++) + { + condset->count = + cheevos_count_conds_in_set(memaddr, set); + condset->conds = NULL; + +#ifdef CHEEVOS_VERBOSE + RARCH_LOG("CHEEVOS set %p (index=%u)\n", condset, set); + RARCH_LOG("CHEEVOS conds: %u\n", condset->count); +#endif + + if (condset->count) + { + cheevos_cond_t *conds = (cheevos_cond_t*) + calloc(condset->count, sizeof(cheevos_cond_t)); + + if (!conds) + return -1; + + condset->conds = conds; + cheevos_parse_memaddr(condset->conds, memaddr, set); + } + } + } + + return 0; } /***************************************************************************** @@ -1163,51 +1237,12 @@ static int cheevos_new_cheevo(cheevos_readud_t *ud) if (!cheevo->title || !cheevo->description || !cheevo->author || !cheevo->badge) goto error; - cheevo->count = cheevos_count_cond_sets(ud->memaddr.string); - #ifdef CHEEVOS_VERBOSE cheevos_log_cheevo(cheevo, &ud->memaddr); #endif - if (cheevo->count) - { - unsigned set = 0; - cheevos_condset_t *condset = NULL; - cheevos_condset_t *conds = (cheevos_condset_t*) - calloc(cheevo->count, sizeof(cheevos_condset_t)); - const cheevos_condset_t* end; - - if (!conds) - return -1; - - cheevo->condsets = conds; - end = cheevo->condsets + cheevo->count; - - for (condset = cheevo->condsets; condset < end; condset++, set++) - { - condset->count = - cheevos_count_conds_in_set(ud->memaddr.string, set); - condset->conds = NULL; - -#ifdef CHEEVOS_VERBOSE - RARCH_LOG("CHEEVOS set %p (index=%u)\n", condset, set); - RARCH_LOG("CHEEVOS conds: %u\n", condset->count); -#endif - - if (condset->count) - { - cheevos_cond_t *conds = (cheevos_cond_t*) - calloc(condset->count, sizeof(cheevos_cond_t)); - - if (!conds) - return -1; - - condset->conds = conds; - condset->expression = cheevos_dupstr(&ud->memaddr); - cheevos_parse_memaddr(condset->conds, ud->memaddr.string, set); - } - } - } + if (cheevos_parse_condition(&cheevo->condition, ud->memaddr.string)) + goto error; #ifdef CHEEVOS_VERBOSE cheevos_post_log_cheevo(cheevo); @@ -1233,49 +1268,49 @@ static int cheevos_read__json_key( void *userdata, switch (hash) { - case JSON_KEY_ACHIEVEMENTS: - ud->in_cheevos = 1; + case CHEEVOS_JSON_KEY_ACHIEVEMENTS: + ud->in_cheevos = 1; break; - case JSON_KEY_CONSOLE_ID: + case CHEEVOS_JSON_KEY_CONSOLE_ID: ud->is_console_id = 1; break; - case JSON_KEY_ID: + case CHEEVOS_JSON_KEY_ID: if (ud->in_cheevos) ud->field = &ud->id; break; - case JSON_KEY_MEMADDR: + case CHEEVOS_JSON_KEY_MEMADDR: if (ud->in_cheevos) ud->field = &ud->memaddr; break; - case JSON_KEY_TITLE: + case CHEEVOS_JSON_KEY_TITLE: if (ud->in_cheevos) ud->field = &ud->title; break; - case JSON_KEY_DESCRIPTION: + case CHEEVOS_JSON_KEY_DESCRIPTION: if (ud->in_cheevos) ud->field = &ud->desc; break; - case JSON_KEY_POINTS: + case CHEEVOS_JSON_KEY_POINTS: if (ud->in_cheevos) ud->field = &ud->points; break; - case JSON_KEY_AUTHOR: + case CHEEVOS_JSON_KEY_AUTHOR: if (ud->in_cheevos) ud->field = &ud->author; break; - case JSON_KEY_MODIFIED: + case CHEEVOS_JSON_KEY_MODIFIED: if (ud->in_cheevos) ud->field = &ud->modified; break; - case JSON_KEY_CREATED: + case CHEEVOS_JSON_KEY_CREATED: if (ud->in_cheevos) ud->field = &ud->created; break; - case JSON_KEY_BADGENAME: + case CHEEVOS_JSON_KEY_BADGENAME: if (ud->in_cheevos) ud->field = &ud->badge; break; - case JSON_KEY_FLAGS: + case CHEEVOS_JSON_KEY_FLAGS: if (ud->in_cheevos) ud->field = &ud->flags; break; @@ -1355,25 +1390,28 @@ static int cheevos_parse(const char *json) }; unsigned core_count, unofficial_count; + int res; cheevos_readud_t ud; - settings_t *settings = config_get_ptr(); + settings_t *settings = config_get_ptr(); /* Just return OK if cheevos are disabled. */ if (!settings->cheevos.enable) return 0; /* Count the number of achievements in the JSON file. */ - if (cheevos_count_cheevos(json, &core_count, &unofficial_count) != JSONSAX_OK) + res = cheevos_count_cheevos(json, &core_count, &unofficial_count); + + if (res != JSONSAX_OK) return -1; /* Allocate the achievements. */ cheevos_locals.core.cheevos = (cheevo_t*) - malloc(core_count * sizeof(cheevo_t)); + calloc(core_count, sizeof(cheevo_t)); cheevos_locals.core.count = core_count; cheevos_locals.unofficial.cheevos = (cheevo_t*) - malloc(unofficial_count * sizeof(cheevo_t)); + calloc(unofficial_count, sizeof(cheevo_t)); cheevos_locals.unofficial.count = unofficial_count; if (!cheevos_locals.core.cheevos || !cheevos_locals.unofficial.cheevos) @@ -1385,11 +1423,6 @@ static int cheevos_parse(const char *json) return -1; } - memset((void*)cheevos_locals.core.cheevos, - 0, core_count * sizeof(cheevo_t)); - memset((void*)cheevos_locals.unofficial.cheevos, - 0, unofficial_count * sizeof(cheevo_t)); - /* Load the achievements. */ ud.in_cheevos = 0; ud.is_console_id = 0; @@ -1420,7 +1453,7 @@ uint8_t *cheevos_get_memory(const cheevos_var_t *var) runloop_ctl(RUNLOOP_CTL_SYSTEM_INFO_GET, &system); if (system->mmaps.num_descriptors != 0) - return (uint8_t *)system->mmaps.descriptors[var->bank_id].ptr + var->value; + return (uint8_t *)system->mmaps.descriptors[var->bank_id].core.ptr + var->value; return (uint8_t *)cheevos_locals.meminfo[var->bank_id].data + var->value; } @@ -1626,9 +1659,9 @@ static int cheevos_test_cheevo(cheevo_t *cheevo) int dirty_conds = 0; int reset_conds = 0; int ret_val = 0; - int ret_val_sub_cond = cheevo->count == 1; - cheevos_condset_t *condset = cheevo->condsets; - const cheevos_condset_t *end = condset + cheevo->count; + int ret_val_sub_cond = cheevo->condition.count == 1; + cheevos_condset_t *condset = cheevo->condition.condsets; + const cheevos_condset_t *end = condset + cheevo->condition.count; if (condset < end) { @@ -1649,7 +1682,7 @@ static int cheevos_test_cheevo(cheevo_t *cheevo) { dirty = 0; - for (condset = cheevo->condsets; condset < end; condset++) + for (condset = cheevo->condition.condsets; condset < end; condset++) dirty |= cheevos_reset_cond_set(condset, 0); if (dirty) @@ -1733,12 +1766,12 @@ static int cheevos_login(retro_time_t *timeout) request[sizeof(request) - 1] = 0; #ifdef CHEEVOS_LOG_URLS - RARCH_LOG("CHEEVOS url to login: %s.\n", request); + RARCH_LOG("CHEEVOS url to login: %s\n", request); #endif if (!cheevos_http_get(&json, NULL, request, timeout)) { - res = cheevos_get_value(json, JSON_KEY_TOKEN, + res = cheevos_get_value(json, CHEEVOS_JSON_KEY_TOKEN, cheevos_locals.token, sizeof(cheevos_locals.token)); free((void*)json); @@ -1770,7 +1803,7 @@ static void cheevos_make_unlock_url(const cheevo_t *cheevo, char* url, size_t ur url[url_size - 1] = 0; #ifdef CHEEVOS_LOG_URLS - RARCH_LOG("CHEEVOS url to award the cheevo: %s.\n", url); + RARCH_LOG("CHEEVOS url to award the cheevo: %s\n", url); #endif } @@ -1852,7 +1885,7 @@ static void cheevos_free_cheevo(const cheevo_t *cheevo) free((void*)cheevo->description); free((void*)cheevo->author); free((void*)cheevo->badge); - cheevos_free_condset(cheevo->condsets); + cheevos_free_condset(cheevo->condition.condsets); } static void cheevos_free_cheevo_set(const cheevoset_t *set) @@ -1894,7 +1927,7 @@ static int cheevos_get_by_game_id(const char **json, request[sizeof(request) - 1] = 0; #ifdef CHEEVOS_LOG_URLS - RARCH_LOG("CHEEVOS url to get the list of cheevos: %s.\n", request); + RARCH_LOG("CHEEVOS url to get the list of cheevos: %s\n", request); #endif if (!cheevos_http_get(json, NULL, request, timeout)) @@ -1939,12 +1972,12 @@ static unsigned cheevos_get_game_id(unsigned char *hash, retro_time_t *timeout) request[sizeof(request) - 1] = 0; #ifdef CHEEVOS_LOG_URLS - RARCH_LOG("CHEEVOS url to get the game's id: %s.\n", request); + RARCH_LOG("CHEEVOS url to get the game's id: %s\n", request); #endif if (!cheevos_http_get(&json, NULL, request, timeout)) { - res = cheevos_get_value(json, JSON_KEY_GAMEID, + res = cheevos_get_value(json, CHEEVOS_JSON_KEY_GAMEID, game_id, sizeof(game_id)); free((void*)json); @@ -1973,7 +2006,7 @@ static void cheevos_make_playing_url(unsigned game_id, char* url, size_t url_siz url[url_size - 1] = 0; #ifdef CHEEVOS_LOG_URLS - RARCH_LOG("CHEEVOS url to post the 'playing' activity: %s.\n", url); + RARCH_LOG("CHEEVOS url to post the 'playing' activity: %s\n", url); #endif } @@ -2100,7 +2133,7 @@ static int cheevos_deactivate_unlocks(unsigned game_id, retro_time_t *timeout) request[sizeof(request) - 1] = 0; #ifdef CHEEVOS_LOG_URLS - RARCH_LOG("CHEEVOS url to get the list of unlocked cheevos in softcore: %s.\n", request); + RARCH_LOG("CHEEVOS url to get the list of unlocked cheevos in softcore: %s\n", request); #endif if (!cheevos_http_get(&json, NULL, request, timeout)) @@ -2129,7 +2162,7 @@ static int cheevos_deactivate_unlocks(unsigned game_id, retro_time_t *timeout) request[sizeof(request) - 1] = 0; #ifdef CHEEVOS_LOG_URLS - RARCH_LOG("CHEEVOS url to get the list of unlocked cheevos in hardcore: %s.\n", request); + RARCH_LOG("CHEEVOS url to get the list of unlocked cheevos in hardcore: %s\n", request); #endif if (!cheevos_http_get(&json, NULL, request, timeout)) @@ -2525,7 +2558,24 @@ bool cheevos_load(const void *data) return false; found: +#ifdef CHEEVOS_JSON_OVERRIDE + { + FILE* file; + size_t size; + + file = fopen(CHEEVOS_JSON_OVERRIDE, "rb"); + fseek(file, 0, SEEK_END); + size = ftell(file); + fseek(file, 0, SEEK_SET); + + json = (const char*)malloc(size); + fread((void*)json, 1, size, file); + + fclose(file); + } +#else if (!cheevos_get_by_game_id(&json, game_id, &timeout)) +#endif { if (!cheevos_parse(json)) { @@ -2748,6 +2798,8 @@ bool cheevos_test(void) if (settings->cheevos.test_unofficial) cheevos_test_cheevo_set(&cheevos_locals.unofficial); + + //cheevos_test_leaderboards(); } return true; diff --git a/core.h b/core.h index 7afbaa0fa3..340d9f4191 100644 --- a/core.h +++ b/core.h @@ -43,6 +43,18 @@ enum POLL_TYPE_LATE }; +typedef struct rarch_memory_descriptor +{ + struct retro_memory_descriptor core; + size_t disconnect_mask; +} rarch_memory_descriptor_t; + +typedef struct rarch_memory_map +{ + rarch_memory_descriptor_t *descriptors; + unsigned num_descriptors; +} rarch_memory_map_t; + typedef struct rarch_system_info { struct retro_system_info info; @@ -68,7 +80,7 @@ typedef struct rarch_system_info unsigned size; } ports; - struct retro_memory_map mmaps; + rarch_memory_map_t mmaps; } rarch_system_info_t; typedef struct retro_ctx_input_state_info diff --git a/dynamic.c b/dynamic.c index 0089749a29..eb2e964ffa 100644 --- a/dynamic.c +++ b/dynamic.c @@ -778,52 +778,51 @@ static size_t mmap_highest_bit(size_t n) return n ^ (n >> 1); } -static bool mmap_preprocess_descriptors(struct retro_memory_descriptor *first, unsigned count) +static bool mmap_preprocess_descriptors(rarch_memory_descriptor_t *first, unsigned count) { - size_t disconnect_mask; - size_t top_addr = 1; - struct retro_memory_descriptor *desc = NULL; - const struct retro_memory_descriptor *end = first + count; + size_t top_addr = 1; + rarch_memory_descriptor_t *desc = NULL; + const rarch_memory_descriptor_t *end = first + count; for (desc = first; desc < end; desc++) { - if (desc->select != 0) - top_addr |= desc->select; + if (desc->core.select != 0) + top_addr |= desc->core.select; else - top_addr |= desc->start + desc->len - 1; + top_addr |= desc->core.start + desc->core.len - 1; } top_addr = mmap_add_bits_down(top_addr); for (desc = first; desc < end; desc++) { - if (desc->select == 0) + if (desc->core.select == 0) { - if (desc->len == 0) + if (desc->core.len == 0) return false; - if ((desc->len & (desc->len - 1)) != 0) + if ((desc->core.len & (desc->core.len - 1)) != 0) return false; - desc->select = top_addr & ~mmap_inflate(mmap_add_bits_down(desc->len - 1), desc->disconnect); + desc->core.select = top_addr & ~mmap_inflate(mmap_add_bits_down(desc->core.len - 1), desc->core.disconnect); } - if (desc->len == 0) - desc->len = mmap_add_bits_down(mmap_reduce(top_addr & ~desc->select, desc->disconnect)) + 1; + if (desc->core.len == 0) + desc->core.len = mmap_add_bits_down(mmap_reduce(top_addr & ~desc->core.select, desc->core.disconnect)) + 1; - if (desc->start & ~desc->select) + if (desc->core.start & ~desc->core.select) return false; - while (mmap_reduce(top_addr & ~desc->select, desc->disconnect) >> 1 > desc->len - 1) - desc->disconnect |= mmap_highest_bit(top_addr & ~desc->select & ~desc->disconnect); + while (mmap_reduce(top_addr & ~desc->core.select, desc->core.disconnect) >> 1 > desc->core.len - 1) + desc->core.disconnect |= mmap_highest_bit(top_addr & ~desc->core.select & ~desc->core.disconnect); - disconnect_mask = mmap_add_bits_down(desc->len - 1); - desc->disconnect &= disconnect_mask; + desc->disconnect_mask = mmap_add_bits_down(desc->core.len - 1); + desc->core.disconnect &= desc->disconnect_mask; - while ((~disconnect_mask) >> 1 & desc->disconnect) + while ((~desc->disconnect_mask) >> 1 & desc->core.disconnect) { - disconnect_mask >>= 1; - desc->disconnect &= disconnect_mask; + desc->disconnect_mask >>= 1; + desc->core.disconnect &= desc->disconnect_mask; } } @@ -1486,22 +1485,24 @@ bool rarch_environment_cb(unsigned cmd, void *data) unsigned i; const struct retro_memory_map *mmaps = (const struct retro_memory_map*)data; - struct retro_memory_descriptor *descriptors = NULL; + rarch_memory_descriptor_t *descriptors = NULL; RARCH_LOG("Environ SET_MEMORY_MAPS.\n"); free((void*)system->mmaps.descriptors); system->mmaps.num_descriptors = 0; - descriptors = (struct retro_memory_descriptor*) + descriptors = (rarch_memory_descriptor_t*) calloc(mmaps->num_descriptors, - sizeof(*system->mmaps.descriptors)); + sizeof(*descriptors)); if (!descriptors) return false; system->mmaps.descriptors = descriptors; - memcpy((void*)system->mmaps.descriptors, mmaps->descriptors, - mmaps->num_descriptors * sizeof(*system->mmaps.descriptors)); system->mmaps.num_descriptors = mmaps->num_descriptors; + + for (i = 0; i < mmaps->num_descriptors; i++) + system->mmaps.descriptors[i].core = mmaps->descriptors[i]; + mmap_preprocess_descriptors(descriptors, mmaps->num_descriptors); if (sizeof(void *) == 8) @@ -1511,38 +1512,38 @@ bool rarch_environment_cb(unsigned cmd, void *data) for (i = 0; i < system->mmaps.num_descriptors; i++) { - const struct retro_memory_descriptor *desc = + const rarch_memory_descriptor_t *desc = &system->mmaps.descriptors[i]; char flags[7]; flags[0] = 'M'; - if ((desc->flags & RETRO_MEMDESC_MINSIZE_8) == RETRO_MEMDESC_MINSIZE_8) + if ((desc->core.flags & RETRO_MEMDESC_MINSIZE_8) == RETRO_MEMDESC_MINSIZE_8) flags[1] = '8'; - else if ((desc->flags & RETRO_MEMDESC_MINSIZE_4) == RETRO_MEMDESC_MINSIZE_4) + else if ((desc->core.flags & RETRO_MEMDESC_MINSIZE_4) == RETRO_MEMDESC_MINSIZE_4) flags[1] = '4'; - else if ((desc->flags & RETRO_MEMDESC_MINSIZE_2) == RETRO_MEMDESC_MINSIZE_2) + else if ((desc->core.flags & RETRO_MEMDESC_MINSIZE_2) == RETRO_MEMDESC_MINSIZE_2) flags[1] = '2'; else flags[1] = '1'; flags[2] = 'A'; - if ((desc->flags & RETRO_MEMDESC_ALIGN_8) == RETRO_MEMDESC_ALIGN_8) + if ((desc->core.flags & RETRO_MEMDESC_ALIGN_8) == RETRO_MEMDESC_ALIGN_8) flags[3] = '8'; - else if ((desc->flags & RETRO_MEMDESC_ALIGN_4) == RETRO_MEMDESC_ALIGN_4) + else if ((desc->core.flags & RETRO_MEMDESC_ALIGN_4) == RETRO_MEMDESC_ALIGN_4) flags[3] = '4'; - else if ((desc->flags & RETRO_MEMDESC_ALIGN_2) == RETRO_MEMDESC_ALIGN_2) + else if ((desc->core.flags & RETRO_MEMDESC_ALIGN_2) == RETRO_MEMDESC_ALIGN_2) flags[3] = '2'; else flags[3] = '1'; - flags[4] = (desc->flags & RETRO_MEMDESC_BIGENDIAN) ? 'B' : 'b'; - flags[5] = (desc->flags & RETRO_MEMDESC_CONST) ? 'C' : 'c'; + flags[4] = (desc->core.flags & RETRO_MEMDESC_BIGENDIAN) ? 'B' : 'b'; + flags[5] = (desc->core.flags & RETRO_MEMDESC_CONST) ? 'C' : 'c'; flags[6] = 0; RARCH_LOG(" %03u %s %p %08X %08X %08X %08X %08X %s\n", - i + 1, flags, desc->ptr, desc->offset, desc->start, - desc->select, desc->disconnect, desc->len, - desc->addrspace ? desc->addrspace : ""); + i + 1, flags, desc->core.ptr, desc->core.offset, desc->core.start, + desc->core.select, desc->core.disconnect, desc->core.len, + desc->core.addrspace ? desc->core.addrspace : ""); } } else From 170c98b59393bac40a410cf25fc69a2053066c7b Mon Sep 17 00:00:00 2001 From: Andre Leiradella Date: Sun, 13 Nov 2016 23:20:11 +0000 Subject: [PATCH 2/2] Changed how bit values are calculated; seems to fix achievement 24594, Hungriest Runner (Win all three races in the Gourmet Race Grand Prix.), for Kirby Super Star. --- cheevos.c | 65 +++++++++++++++++++++++++++++++++++-------------------- 1 file changed, 41 insertions(+), 24 deletions(-) diff --git a/cheevos.c b/cheevos.c index 3622aa241f..8842881094 100644 --- a/cheevos.c +++ b/cheevos.c @@ -1477,31 +1477,48 @@ static unsigned cheevos_get_var_value(cheevos_var_t *var) { live_val = memory[0]; - if (var->size > CHEEVOS_VAR_SIZE_BIT_0 - && var->size <= CHEEVOS_VAR_SIZE_BIT_7) - live_val = (live_val & - (1 << (var->size - CHEEVOS_VAR_SIZE_BIT_0))) != 0; - else + switch (var->size) { - switch (var->size) - { - case CHEEVOS_VAR_SIZE_NIBBLE_LOWER: - live_val &= 0x0f; - break; - case CHEEVOS_VAR_SIZE_NIBBLE_UPPER: - live_val = (live_val >> 4) & 0x0f; - break; - case CHEEVOS_VAR_SIZE_EIGHT_BITS: - break; - case CHEEVOS_VAR_SIZE_SIXTEEN_BITS: - live_val |= memory[1] << 8; - break; - case CHEEVOS_VAR_SIZE_THIRTYTWO_BITS: - live_val |= memory[1] << 8; - live_val |= memory[2] << 16; - live_val |= memory[3] << 24; - break; - } + case CHEEVOS_VAR_SIZE_BIT_0: + live_val &= 1; + break; + case CHEEVOS_VAR_SIZE_BIT_1: + live_val = (live_val >> 1) & 1; + break; + case CHEEVOS_VAR_SIZE_BIT_2: + live_val = (live_val >> 2) & 1; + break; + case CHEEVOS_VAR_SIZE_BIT_3: + live_val = (live_val >> 3) & 1; + break; + case CHEEVOS_VAR_SIZE_BIT_4: + live_val = (live_val >> 4) & 1; + break; + case CHEEVOS_VAR_SIZE_BIT_5: + live_val = (live_val >> 5) & 1; + break; + case CHEEVOS_VAR_SIZE_BIT_6: + live_val = (live_val >> 6) & 1; + break; + case CHEEVOS_VAR_SIZE_BIT_7: + live_val = (live_val >> 7) & 1; + break; + case CHEEVOS_VAR_SIZE_NIBBLE_LOWER: + live_val &= 0x0f; + break; + case CHEEVOS_VAR_SIZE_NIBBLE_UPPER: + live_val = (live_val >> 4) & 0x0f; + break; + case CHEEVOS_VAR_SIZE_EIGHT_BITS: + break; + case CHEEVOS_VAR_SIZE_SIXTEEN_BITS: + live_val |= memory[1] << 8; + break; + case CHEEVOS_VAR_SIZE_THIRTYTWO_BITS: + live_val |= memory[1] << 8; + live_val |= memory[2] << 16; + live_val |= memory[3] << 24; + break; } }