Permalink
Browse files

GBA Cheats: Fix PARv3 multiline blocks (fixes #889)

  • Loading branch information...
endrift committed Sep 30, 2017
1 parent 845ecfe commit bf0081e9b4c2c3b3faef6bfbfd93ac46066684e5
Showing with 973 additions and 20 deletions.
  1. +1 −0 CHANGES
  2. +27 −18 src/core/cheats.c
  3. +2 −2 src/gba/cheats/parv3.c
  4. +943 −0 src/gba/test/cheats.c
View
@@ -46,6 +46,7 @@ Bugfixes:
- GBA Savedata: Fix size of SRAM saves (fixes mgba.io/i/883)
- GB: Revamp IRQ handling based on new information
- GB Video: Fix read mode when enabling LCD
+ - GBA Cheats: Fix PARv3 multiline blocks (fixes mgba.io/i/889)
Misc:
- GBA Timer: Use global cycles for timers
- GBA: Extend oddly-sized ROMs to full address space (fixes mgba.io/i/722)
View
@@ -256,35 +256,23 @@ void mCheatRefresh(struct mCheatDevice* device, struct mCheatSet* cheats) {
if (!cheats->enabled) {
return;
}
- bool condition = true;
- int conditionRemaining = 0;
- int negativeConditionRemaining = 0;
cheats->refresh(cheats, device);
+ size_t elseLoc = 0;
+ size_t endLoc = 0;
size_t nCodes = mCheatListSize(&cheats->list);
size_t i;
for (i = 0; i < nCodes; ++i) {
- if (conditionRemaining > 0) {
- --conditionRemaining;
- if (!condition) {
- continue;
- }
- } else if (negativeConditionRemaining > 0) {
- conditionRemaining = negativeConditionRemaining - 1;
- negativeConditionRemaining = 0;
- condition = !condition;
- if (!condition) {
- continue;
- }
- } else {
- condition = true;
- }
struct mCheat* cheat = mCheatListGetPointer(&cheats->list, i);
int32_t value = 0;
int32_t operand = cheat->operand;
uint32_t operationsRemaining = cheat->repeat;
uint32_t address = cheat->address;
bool performAssignment = false;
+ bool condition = true;
+ int conditionRemaining = 0;
+ int negativeConditionRemaining = 0;
+
for (; operationsRemaining; --operationsRemaining) {
switch (cheat->type) {
case CHEAT_ASSIGN:
@@ -312,46 +300,55 @@ void mCheatRefresh(struct mCheatDevice* device, struct mCheatSet* cheats) {
condition = _readMem(device->p, address, cheat->width) == operand;
conditionRemaining = cheat->repeat;
negativeConditionRemaining = cheat->negativeRepeat;
+ operationsRemaining = 1;
break;
case CHEAT_IF_NE:
condition = _readMem(device->p, address, cheat->width) != operand;
conditionRemaining = cheat->repeat;
negativeConditionRemaining = cheat->negativeRepeat;
+ operationsRemaining = 1;
break;
case CHEAT_IF_LT:
condition = _readMem(device->p, address, cheat->width) < operand;
conditionRemaining = cheat->repeat;
negativeConditionRemaining = cheat->negativeRepeat;
+ operationsRemaining = 1;
break;
case CHEAT_IF_GT:
condition = _readMem(device->p, address, cheat->width) > operand;
conditionRemaining = cheat->repeat;
negativeConditionRemaining = cheat->negativeRepeat;
+ operationsRemaining = 1;
break;
case CHEAT_IF_ULT:
condition = (uint32_t) _readMem(device->p, address, cheat->width) < (uint32_t) operand;
conditionRemaining = cheat->repeat;
negativeConditionRemaining = cheat->negativeRepeat;
+ operationsRemaining = 1;
break;
case CHEAT_IF_UGT:
condition = (uint32_t) _readMem(device->p, address, cheat->width) > (uint32_t) operand;
conditionRemaining = cheat->repeat;
negativeConditionRemaining = cheat->negativeRepeat;
+ operationsRemaining = 1;
break;
case CHEAT_IF_AND:
condition = _readMem(device->p, address, cheat->width) & operand;
conditionRemaining = cheat->repeat;
negativeConditionRemaining = cheat->negativeRepeat;
+ operationsRemaining = 1;
break;
case CHEAT_IF_LAND:
condition = _readMem(device->p, address, cheat->width) && operand;
conditionRemaining = cheat->repeat;
negativeConditionRemaining = cheat->negativeRepeat;
+ operationsRemaining = 1;
break;
case CHEAT_IF_NAND:
condition = !(_readMem(device->p, address, cheat->width) & operand);
conditionRemaining = cheat->repeat;
negativeConditionRemaining = cheat->negativeRepeat;
+ operationsRemaining = 1;
break;
}
@@ -362,6 +359,18 @@ void mCheatRefresh(struct mCheatDevice* device, struct mCheatSet* cheats) {
address += cheat->addressOffset;
operand += cheat->operandOffset;
}
+
+
+ if (elseLoc && i == elseLoc) {
+ i = endLoc;
+ endLoc = 0;
+ }
+ if (conditionRemaining > 0 && !condition) {
+ i += conditionRemaining;
+ } else if (negativeConditionRemaining > 0) {
+ elseLoc = i + conditionRemaining;
+ endLoc = elseLoc + negativeConditionRemaining;
+ }
}
}
View
@@ -53,7 +53,7 @@ static uint32_t _parAddr(uint32_t x) {
}
static void _parEndBlock(struct GBACheatSet* cheats) {
- size_t size = mCheatListSize(&cheats->d.list) - cheats->currentBlock;
+ size_t size = mCheatListSize(&cheats->d.list) - cheats->currentBlock - 1;
struct mCheat* currentBlock = mCheatListGetPointer(&cheats->d.list, cheats->currentBlock);
if (currentBlock->repeat) {
currentBlock->negativeRepeat = size - currentBlock->repeat;
@@ -64,7 +64,7 @@ static void _parEndBlock(struct GBACheatSet* cheats) {
}
static void _parElseBlock(struct GBACheatSet* cheats) {
- size_t size = mCheatListSize(&cheats->d.list) - cheats->currentBlock;
+ size_t size = mCheatListSize(&cheats->d.list) - cheats->currentBlock - 1;
struct mCheat* currentBlock = mCheatListGetPointer(&cheats->d.list, cheats->currentBlock);
currentBlock->repeat = size;
}
Oops, something went wrong.

0 comments on commit bf0081e

Please sign in to comment.