diff --git a/CHANGES b/CHANGES index 8147d2c1f..7bef44056 100644 --- a/CHANGES +++ b/CHANGES @@ -37,6 +37,7 @@ Misc: - CMake: Fix CPack dependencies for libpng 1.6 - Qt: Allow overrides to be saved before a game is loaded - VFS: Make VFile.truncate work growing files on PSV (fixes mgba.io/i/885) + - GBA Cheats: Improve detection of raw cheats 0.6.0: (2017-07-16) Features: diff --git a/src/gba/cheats.c b/src/gba/cheats.c index c8a8f2c82..6e799aae4 100644 --- a/src/gba/cheats.c +++ b/src/gba/cheats.c @@ -139,7 +139,8 @@ static bool GBACheatAddAutodetect(struct GBACheatSet* set, uint32_t op1, uint32_ char line[18] = "XXXXXXXX XXXXXXXX"; snprintf(line, sizeof(line), "%08X %08X", op1, op2); - int gsaP, parP; + int gsaP, rgsaP, parP, rparP; + int maxProbability = INT_MIN; switch (set->gsaVersion) { case 0: // Try to detect GameShark version @@ -147,27 +148,42 @@ static bool GBACheatAddAutodetect(struct GBACheatSet* set, uint32_t op1, uint32_ gsaP = GBACheatGameSharkProbability(o1, o2); o1 = op1; o2 = op2; + if (gsaP > maxProbability) { + maxProbability = gsaP; + GBACheatSetGameSharkVersion(set, 1); + } + GBACheatDecryptGameShark(&o1, &o2, GBACheatProActionReplaySeeds); parP = GBACheatProActionReplayProbability(o1, o2); - o1 = op1; - o2 = op2; - if (gsaP > parP) { - GBACheatSetGameSharkVersion(set, 1); - GBACheatDecryptGameShark(&o1, &o2, set->gsaSeeds); - return GBACheatAddGameSharkRaw(set, o1, o2); - } else { - // If probabilities are equal, assume PARv3 + if (parP > maxProbability) { + maxProbability = parP; GBACheatSetGameSharkVersion(set, 3); - GBACheatDecryptGameShark(&o1, &o2, set->gsaSeeds); - return GBACheatAddProActionReplayRaw(set, o1, o2); + } + + rgsaP = GBACheatGameSharkProbability(op1, op1); + if (rgsaP > maxProbability) { + maxProbability = rgsaP; + GBACheatSetGameSharkVersion(set, 2); + } + + rparP = GBACheatProActionReplayProbability(op1, op1); + if (rparP > maxProbability) { + maxProbability = rparP; + GBACheatSetGameSharkVersion(set, 4); + } + + if (set->gsaVersion < 3) { + return GBACheatAddGameShark(set, op1, op2); + } else { + return GBACheatAddProActionReplay(set, op1, op2); } break; case 1: - GBACheatDecryptGameShark(&o1, &o2, set->gsaSeeds); - return GBACheatAddGameSharkRaw(set, o1, o2); + case 2: + return GBACheatAddGameShark(set, o1, o2); case 3: - GBACheatDecryptGameShark(&o1, &o2, set->gsaSeeds); - return GBACheatAddProActionReplayRaw(set, o1, o2); + case 4: + return GBACheatAddProActionReplay(set, o1, o2); } return false; } @@ -291,10 +307,18 @@ static void GBACheatParseDirectives(struct mCheatSet* set, const struct StringLi GBACheatSetGameSharkVersion(cheats, 1); continue; } + if (strcmp(directive, "GSAv1 raw") == 0) { + GBACheatSetGameSharkVersion(cheats, 2); + continue; + } if (strcmp(directive, "PARv3") == 0) { GBACheatSetGameSharkVersion(cheats, 3); continue; } + if (strcmp(directive, "PARv3 raw") == 0) { + GBACheatSetGameSharkVersion(cheats, 4); + continue; + } } } @@ -311,15 +335,21 @@ static void GBACheatDumpDirectives(struct mCheatSet* set, struct StringList* dir char** directive; switch (cheats->gsaVersion) { case 1: - case 2: directive = StringListAppend(directives); *directive = strdup("GSAv1"); break; + case 2: + directive = StringListAppend(directives); + *directive = strdup("GSAv1 raw"); + break; case 3: - case 4: directive = StringListAppend(directives); *directive = strdup("PARv3"); break; + case 4: + directive = StringListAppend(directives); + *directive = strdup("PARv3 raw"); + break; } } diff --git a/src/gba/cheats/gameshark.c b/src/gba/cheats/gameshark.c index 1fc476aff..0c4270ee6 100644 --- a/src/gba/cheats/gameshark.c +++ b/src/gba/cheats/gameshark.c @@ -203,8 +203,9 @@ bool GBACheatAddGameShark(struct GBACheatSet* set, uint32_t op1, uint32_t op2) { GBACheatSetGameSharkVersion(set, 1); // Fall through case 1: - case 2: GBACheatDecryptGameShark(&o1, &o2, set->gsaSeeds); + // Fall through + case 2: return GBACheatAddGameSharkRaw(set, o1, o2); } return false; diff --git a/src/gba/cheats/parv3.c b/src/gba/cheats/parv3.c index ccd6c34b0..63d2d2685 100644 --- a/src/gba/cheats/parv3.c +++ b/src/gba/cheats/parv3.c @@ -303,8 +303,9 @@ bool GBACheatAddProActionReplay(struct GBACheatSet* set, uint32_t op1, uint32_t GBACheatSetGameSharkVersion(set, 3); // Fall through case 3: - case 4: GBACheatDecryptGameShark(&o1, &o2, set->gsaSeeds); + // Fall through + case 4: return GBACheatAddProActionReplayRaw(set, o1, o2); } return false; @@ -370,7 +371,7 @@ int GBACheatProActionReplayProbability(uint32_t op1, uint32_t op2) { int width = ((op1 & PAR3_WIDTH) >> (PAR3_WIDTH_BASE - 3)); if (op1 & PAR3_COND) { probability += 0x20; - if (width == 32) { + if (width >= 24) { return 0; } if (op2 & ~((1 << width) - 1)) {