GBA: Support for VBA-style cheat codes

This commit is contained in:
Jeffrey Pfau 2015-12-26 22:25:50 -05:00
parent bbe10619ef
commit f84aadffd2
5 changed files with 71 additions and 9 deletions

View File

@ -7,6 +7,7 @@ Features:
- Libretro: Cheat code support - Libretro: Cheat code support
- Support for GLSL shaders - Support for GLSL shaders
- ROM information view - ROM information view
- Support for VBA-style cheat codes
Bugfixes: Bugfixes:
- Util: Fix PowerPC PNG read/write pixel order - Util: Fix PowerPC PNG read/write pixel order
- VFS: Fix VFileReadline and remove _vfdReadline - VFS: Fix VFileReadline and remove _vfdReadline

View File

@ -359,26 +359,67 @@ bool GBACheatSaveFile(struct GBACheatDevice* device, struct VFile* vf) {
return true; return true;
} }
bool GBACheatAddVBALine(struct GBACheatSet* cheats, const char* line) {
uint32_t address;
uint8_t op;
uint32_t value = 0;
int width = 0;
const char* lineNext = hex32(line, &address);
if (!lineNext) {
return false;
}
if (lineNext[0] != ':') {
return false;
}
++lineNext;
while (width < 4) {
lineNext = hex8(lineNext, &op);
if (!lineNext) {
break;
}
value <<= 8;
value |= op;
++width;
}
if (width == 0 || width == 3) {
return false;
}
struct GBACheat* cheat = GBACheatListAppend(&cheats->list);
cheat->address = address;
cheat->operandOffset = 0;
cheat->addressOffset = 0;
cheat->repeat = 1;
cheat->type = CHEAT_ASSIGN;
cheat->width = width;
cheat->operand = value;
GBACheatRegisterLine(cheats, line);
return true;
}
bool GBACheatAddLine(struct GBACheatSet* cheats, const char* line) { bool GBACheatAddLine(struct GBACheatSet* cheats, const char* line) {
uint32_t op1; uint32_t op1;
uint16_t op2; uint16_t op2;
uint16_t op3; uint16_t op3;
line = hex32(line, &op1); const char* lineNext = hex32(line, &op1);
if (!line) { if (!lineNext) {
return false; return false;
} }
while (isspace((int) line[0])) { if (lineNext[0] == ':') {
++line; return GBACheatAddVBALine(cheats, line);
} }
line = hex16(line, &op2); while (isspace((int) lineNext[0])) {
if (!line) { ++lineNext;
}
lineNext = hex16(lineNext, &op2);
if (!lineNext) {
return false; return false;
} }
if (!line[0] || isspace((int) line[0])) { if (!lineNext[0] || isspace((int) lineNext[0])) {
return GBACheatAddCodeBreaker(cheats, op1, op2); return GBACheatAddCodeBreaker(cheats, op1, op2);
} }
line = hex16(line, &op3); lineNext = hex16(lineNext, &op3);
if (!line) { if (!lineNext) {
return false; return false;
} }
uint32_t realOp2 = op2; uint32_t realOp2 = op2;

View File

@ -211,6 +211,8 @@ bool GBACheatAddGameSharkLine(struct GBACheatSet*, const char* line);
bool GBACheatAddProActionReplay(struct GBACheatSet*, uint32_t op1, uint32_t op2); bool GBACheatAddProActionReplay(struct GBACheatSet*, uint32_t op1, uint32_t op2);
bool GBACheatAddProActionReplayLine(struct GBACheatSet*, const char* line); bool GBACheatAddProActionReplayLine(struct GBACheatSet*, const char* line);
bool GBACheatAddVBALine(struct GBACheatSet*, const char* line);
bool GBACheatAddAutodetect(struct GBACheatSet*, uint32_t op1, uint32_t op2); bool GBACheatAddAutodetect(struct GBACheatSet*, uint32_t op1, uint32_t op2);
bool GBACheatParseFile(struct GBACheatDevice*, struct VFile*); bool GBACheatParseFile(struct GBACheatDevice*, struct VFile*);

View File

@ -276,3 +276,20 @@ const char* hex16(const char* line, uint16_t* out) {
*out = value; *out = value;
return line; return line;
} }
const char* hex8(const char* line, uint8_t* out) {
uint8_t value = 0;
*out = 0;
int i;
for (i = 0; i < 2; ++i, ++line) {
char digit = *line;
value <<= 4;
int nybble = hexDigit(digit);
if (nybble < 0) {
return 0;
}
value |= nybble;
}
*out = value;
return line;
}

View File

@ -27,5 +27,6 @@ uint32_t utf16Char(const uint16_t** unicode, size_t* length);
int hexDigit(char digit); int hexDigit(char digit);
const char* hex32(const char* line, uint32_t* out); const char* hex32(const char* line, uint32_t* out);
const char* hex16(const char* line, uint16_t* out); const char* hex16(const char* line, uint16_t* out);
const char* hex8(const char* line, uint8_t* out);
#endif #endif