diff --git a/cheevos-new/cheevos.c b/cheevos-new/cheevos.c index f488ebc099..eeef332e90 100644 --- a/cheevos-new/cheevos.c +++ b/cheevos-new/cheevos.c @@ -665,6 +665,20 @@ static unsigned rcheevos_peek(unsigned address, unsigned num_bytes, void* ud) return value; } +static int rcheevos_has_indirect_memref(const rc_memref_value_t* memrefs) +{ + const rc_memref_value_t* memref = memrefs; + while (memref != NULL) + { + if (memref->memref.is_indirect) + return 1; + + memref = memref->next; + } + + return 0; +} + static void rcheevos_test_cheevo_set(bool official) { settings_t *settings = config_get_ptr(); @@ -701,17 +715,26 @@ static void rcheevos_test_cheevo_set(bool official) /* if the we're still waiting for the trigger to stabilize, check to see if an error occurred */ if (rcheevos_locals.invalid_peek_address) { - /* could not map one or more addresses - disable the achievement */ - CHEEVOS_ERR(RCHEEVOS_TAG "Achievement disabled (invalid address): %s\n", cheevo->info->title); - cheevo->active = 0; - - /* clear out the trigger so it shows up as 'Unsupported' in the menu */ - CHEEVOS_FREE(cheevo->trigger); - cheevo->trigger = NULL; - /* reset the flag for the next achievement */ rcheevos_locals.invalid_peek_address = false; - continue; + + if (rcheevos_has_indirect_memref(cheevo->trigger->memrefs)) + { + /* ignore bad addresses possibly generated by AddAddress */ + CHEEVOS_LOG(RCHEEVOS_TAG "Ignoring invalid address in achievement with AddAddress: %s\n", cheevo->info->title); + } + else + { + /* could not map one or more addresses - disable the achievement */ + CHEEVOS_ERR(RCHEEVOS_TAG "Achievement disabled (invalid address): %s\n", cheevo->info->title); + cheevo->active = 0; + + /* clear out the trigger so it shows up as 'Unsupported' in the menu */ + CHEEVOS_FREE(cheevo->trigger); + cheevo->trigger = NULL; + + continue; + } } /* no error, reset any hit counts for the next check */ @@ -850,14 +873,17 @@ static void rcheevos_test_leaderboards(void) if (rcheevos_locals.invalid_peek_address) { - /* disable the leaderboard */ - CHEEVOS_FREE(lboard->lboard); - lboard->lboard = NULL; - - CHEEVOS_LOG(RCHEEVOS_TAG "Leaderboard disabled (invalid address): %s\n", lboard->info->title); - /* reset the flag for the next leaderboard */ rcheevos_locals.invalid_peek_address = false; + + if (!rcheevos_has_indirect_memref(lboard->lboard->memrefs)) + { + /* disable the leaderboard */ + CHEEVOS_FREE(lboard->lboard); + lboard->lboard = NULL; + + CHEEVOS_LOG(RCHEEVOS_TAG "Leaderboard disabled (invalid address): %s\n", lboard->info->title); + } } } } diff --git a/cheevos-new/fixup.c b/cheevos-new/fixup.c index 468a3c0ff7..8994c5e1ad 100644 --- a/cheevos-new/fixup.c +++ b/cheevos-new/fixup.c @@ -236,6 +236,7 @@ const uint8_t* rcheevos_patch_address(unsigned address, int console) else { unsigned i; + unsigned addr = address; for (i = 0; i < 4; i++) { @@ -259,9 +260,10 @@ const uint8_t* rcheevos_patch_address(unsigned address, int console) core_get_memory(&meminfo); - if (address < meminfo.size) + if (addr < meminfo.size) { pointer = meminfo.data; + address = addr; break; } @@ -270,14 +272,15 @@ const uint8_t* rcheevos_patch_address(unsigned address, int console) * it's size is not always set correctly in the core. */ if (i == 0 && console == RC_CONSOLE_NINTENDO) - address -= 0x6000; + addr -= 0x6000; else - address -= meminfo.size; + addr -= meminfo.size; } } if (pointer == NULL) { + CHEEVOS_LOG(RCHEEVOS_TAG "address %X not supported\n", address); return NULL; }