mirror of https://github.com/mgba-emu/mgba.git
GBA: Support for VBA-style cheat codes
This commit is contained in:
parent
bbe10619ef
commit
f84aadffd2
1
CHANGES
1
CHANGES
|
@ -7,6 +7,7 @@ Features:
|
|||
- 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
|
||||
|
|
|
@ -359,26 +359,67 @@ bool GBACheatSaveFile(struct GBACheatDevice* device, struct VFile* vf) {
|
|||
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);
|
||||
}
|
||||
line = hex16(line, &op2);
|
||||
if (!line) {
|
||||
while (isspace((int) lineNext[0])) {
|
||||
++lineNext;
|
||||
}
|
||||
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;
|
||||
|
|
|
@ -211,6 +211,8 @@ bool GBACheatAddGameSharkLine(struct GBACheatSet*, const char* line);
|
|||
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*);
|
||||
|
|
|
@ -276,3 +276,20 @@ const char* hex16(const char* line, uint16_t* out) {
|
|||
*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;
|
||||
}
|
||||
|
|
|
@ -27,5 +27,6 @@ uint32_t utf16Char(const uint16_t** unicode, size_t* length);
|
|||
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
|
||||
|
|
Loading…
Reference in New Issue