all repos — mgba @ f84aadffd2d02827f095c58bce224172875393f1

mGBA Game Boy Advance Emulator

GBA: Support for VBA-style cheat codes
Jeffrey Pfau jeffrey@endrift.com
Sat, 26 Dec 2015 22:25:50 -0500
commit

f84aadffd2d02827f095c58bce224172875393f1

parent

bbe10619efaf5c691e57747101029b3d194add3b

5 files changed, 71 insertions(+), 9 deletions(-)

jump to
M CHANGESCHANGES

@@ -7,6 +7,7 @@ - Customization of GIF recording

- Libretro: Cheat code support - Support for GLSL shaders - ROM information view + - Support for VBA-style cheat codes Bugfixes: - Util: Fix PowerPC PNG read/write pixel order - VFS: Fix VFileReadline and remove _vfdReadline
M src/gba/cheats.csrc/gba/cheats.c

@@ -359,26 +359,67 @@ }

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) { uint32_t op1; uint16_t op2; uint16_t op3; - line = hex32(line, &op1); - if (!line) { + const char* lineNext = hex32(line, &op1); + if (!lineNext) { return false; } - while (isspace((int) line[0])) { - ++line; + if (lineNext[0] == ':') { + return GBACheatAddVBALine(cheats, line); + } + while (isspace((int) lineNext[0])) { + ++lineNext; } - line = hex16(line, &op2); - if (!line) { + lineNext = hex16(lineNext, &op2); + if (!lineNext) { return false; } - if (!line[0] || isspace((int) line[0])) { + if (!lineNext[0] || isspace((int) lineNext[0])) { return GBACheatAddCodeBreaker(cheats, op1, op2); } - line = hex16(line, &op3); - if (!line) { + lineNext = hex16(lineNext, &op3); + if (!lineNext) { return false; } uint32_t realOp2 = op2;
M src/gba/cheats.hsrc/gba/cheats.h

@@ -211,6 +211,8 @@

bool GBACheatAddProActionReplay(struct GBACheatSet*, uint32_t op1, uint32_t op2); 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 GBACheatParseFile(struct GBACheatDevice*, struct VFile*);
M src/util/string.csrc/util/string.c

@@ -276,3 +276,20 @@ }

*out = value; 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; +}
M src/util/string.hsrc/util/string.h

@@ -27,5 +27,6 @@

int hexDigit(char digit); const char* hex32(const char* line, uint32_t* out); const char* hex16(const char* line, uint16_t* out); +const char* hex8(const char* line, uint8_t* out); #endif