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
|
- 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
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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*);
|
||||||
|
|
|
@ -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;
|
||||||
|
}
|
||||||
|
|
|
@ -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
|
||||||
|
|
Loading…
Reference in New Issue