GBA Cheats: Improve detection of raw cheats

This commit is contained in:
Vicki Pfau 2017-09-27 23:17:48 -07:00
parent 18ac94be81
commit 1f771ca390
4 changed files with 53 additions and 20 deletions

View File

@ -37,6 +37,7 @@ Misc:
- CMake: Fix CPack dependencies for libpng 1.6 - CMake: Fix CPack dependencies for libpng 1.6
- Qt: Allow overrides to be saved before a game is loaded - 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) - 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) 0.6.0: (2017-07-16)
Features: Features:

View File

@ -139,7 +139,8 @@ static bool GBACheatAddAutodetect(struct GBACheatSet* set, uint32_t op1, uint32_
char line[18] = "XXXXXXXX XXXXXXXX"; char line[18] = "XXXXXXXX XXXXXXXX";
snprintf(line, sizeof(line), "%08X %08X", op1, op2); snprintf(line, sizeof(line), "%08X %08X", op1, op2);
int gsaP, parP; int gsaP, rgsaP, parP, rparP;
int maxProbability = INT_MIN;
switch (set->gsaVersion) { switch (set->gsaVersion) {
case 0: case 0:
// Try to detect GameShark version // Try to detect GameShark version
@ -147,27 +148,42 @@ static bool GBACheatAddAutodetect(struct GBACheatSet* set, uint32_t op1, uint32_
gsaP = GBACheatGameSharkProbability(o1, o2); gsaP = GBACheatGameSharkProbability(o1, o2);
o1 = op1; o1 = op1;
o2 = op2; o2 = op2;
if (gsaP > maxProbability) {
maxProbability = gsaP;
GBACheatSetGameSharkVersion(set, 1);
}
GBACheatDecryptGameShark(&o1, &o2, GBACheatProActionReplaySeeds); GBACheatDecryptGameShark(&o1, &o2, GBACheatProActionReplaySeeds);
parP = GBACheatProActionReplayProbability(o1, o2); parP = GBACheatProActionReplayProbability(o1, o2);
o1 = op1; if (parP > maxProbability) {
o2 = op2; maxProbability = parP;
if (gsaP > parP) {
GBACheatSetGameSharkVersion(set, 1);
GBACheatDecryptGameShark(&o1, &o2, set->gsaSeeds);
return GBACheatAddGameSharkRaw(set, o1, o2);
} else {
// If probabilities are equal, assume PARv3
GBACheatSetGameSharkVersion(set, 3); 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; break;
case 1: case 1:
GBACheatDecryptGameShark(&o1, &o2, set->gsaSeeds); case 2:
return GBACheatAddGameSharkRaw(set, o1, o2); return GBACheatAddGameShark(set, o1, o2);
case 3: case 3:
GBACheatDecryptGameShark(&o1, &o2, set->gsaSeeds); case 4:
return GBACheatAddProActionReplayRaw(set, o1, o2); return GBACheatAddProActionReplay(set, o1, o2);
} }
return false; return false;
} }
@ -291,10 +307,18 @@ static void GBACheatParseDirectives(struct mCheatSet* set, const struct StringLi
GBACheatSetGameSharkVersion(cheats, 1); GBACheatSetGameSharkVersion(cheats, 1);
continue; continue;
} }
if (strcmp(directive, "GSAv1 raw") == 0) {
GBACheatSetGameSharkVersion(cheats, 2);
continue;
}
if (strcmp(directive, "PARv3") == 0) { if (strcmp(directive, "PARv3") == 0) {
GBACheatSetGameSharkVersion(cheats, 3); GBACheatSetGameSharkVersion(cheats, 3);
continue; 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; char** directive;
switch (cheats->gsaVersion) { switch (cheats->gsaVersion) {
case 1: case 1:
case 2:
directive = StringListAppend(directives); directive = StringListAppend(directives);
*directive = strdup("GSAv1"); *directive = strdup("GSAv1");
break; break;
case 2:
directive = StringListAppend(directives);
*directive = strdup("GSAv1 raw");
break;
case 3: case 3:
case 4:
directive = StringListAppend(directives); directive = StringListAppend(directives);
*directive = strdup("PARv3"); *directive = strdup("PARv3");
break; break;
case 4:
directive = StringListAppend(directives);
*directive = strdup("PARv3 raw");
break;
} }
} }

View File

@ -203,8 +203,9 @@ bool GBACheatAddGameShark(struct GBACheatSet* set, uint32_t op1, uint32_t op2) {
GBACheatSetGameSharkVersion(set, 1); GBACheatSetGameSharkVersion(set, 1);
// Fall through // Fall through
case 1: case 1:
case 2:
GBACheatDecryptGameShark(&o1, &o2, set->gsaSeeds); GBACheatDecryptGameShark(&o1, &o2, set->gsaSeeds);
// Fall through
case 2:
return GBACheatAddGameSharkRaw(set, o1, o2); return GBACheatAddGameSharkRaw(set, o1, o2);
} }
return false; return false;

View File

@ -303,8 +303,9 @@ bool GBACheatAddProActionReplay(struct GBACheatSet* set, uint32_t op1, uint32_t
GBACheatSetGameSharkVersion(set, 3); GBACheatSetGameSharkVersion(set, 3);
// Fall through // Fall through
case 3: case 3:
case 4:
GBACheatDecryptGameShark(&o1, &o2, set->gsaSeeds); GBACheatDecryptGameShark(&o1, &o2, set->gsaSeeds);
// Fall through
case 4:
return GBACheatAddProActionReplayRaw(set, o1, o2); return GBACheatAddProActionReplayRaw(set, o1, o2);
} }
return false; return false;
@ -370,7 +371,7 @@ int GBACheatProActionReplayProbability(uint32_t op1, uint32_t op2) {
int width = ((op1 & PAR3_WIDTH) >> (PAR3_WIDTH_BASE - 3)); int width = ((op1 & PAR3_WIDTH) >> (PAR3_WIDTH_BASE - 3));
if (op1 & PAR3_COND) { if (op1 & PAR3_COND) {
probability += 0x20; probability += 0x20;
if (width == 32) { if (width >= 24) {
return 0; return 0;
} }
if (op2 & ~((1 << width) - 1)) { if (op2 & ~((1 << width) - 1)) {