Permalink
Browse files

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

  • Loading branch information...
endrift committed Sep 30, 2017
1 parent be59a22 commit 745f5af1c8bbdcc3ea5c25d07d096212fcf01736
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
@@ -30,6 +30,7 @@ Bugfixes:
- GBA I/O: Fix reading from a few invalid I/O registers (fixes mgba.io/i/876)
- GBA Savedata: Fix size of SRAM saves (fixes mgba.io/i/883)
- GB Video: Fix read mode when enabling LCD
+ - GBA Cheats: Fix PARv3 multiline blocks (fixes mgba.io/i/889)
Misc:
- Qt: Don't rebuild library view if style hasn't changed
- SDL: Fix 2.0.5 build on macOS under some circumstances
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 745f5af

Please sign in to comment.