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
- 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:

View File

@ -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;
}
}

View File

@ -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;

View File

@ -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)) {