GBA Cheats: Fix PARv3 multiline blocks (fixes #889)
Vicki Pfau vi@endrift.com
Sat, 30 Sep 2017 10:25:35 -0700
4 files changed,
973 insertions(+),
20 deletions(-)
M
CHANGES
→
CHANGES
@@ -30,6 +30,7 @@ - GBA Video: Fix broken sprite blending hack (fixes mgba.io/i/532)
- 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
M
src/core/cheats.c
→
src/core/cheats.c
@@ -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 @@ case CHEAT_IF_EQ:
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; }@@ -361,6 +358,18 @@ }
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; } } }
M
src/gba/cheats/parv3.c
→
src/gba/cheats/parv3.c
@@ -53,7 +53,7 @@ return (x & 0xFFFFF) | ((x << 4) & 0x0F000000);
} 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 @@ cheats->currentBlock = COMPLETE;
} 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; }
A
src/gba/test/cheats.c
@@ -0,0 +1,943 @@
+/* Copyright (c) 2013-2017 Jeffrey Pfau + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ +#include "util/test/suite.h" + +#include <mgba/core/cheats.h> +#include <mgba/core/core.h> +#include <mgba/gba/core.h> +#include <mgba/internal/gba/cheats.h> + +#include "gba/cheats/parv3.h" +#include "gba/cheats/gameshark.h" + +M_TEST_SUITE_SETUP(GBACheats) { + struct mCore* core = GBACoreCreate(); + core->init(core); + core->cheatDevice(core); + *state = core; + return 0; +} + +M_TEST_SUITE_TEARDOWN(GBACheats) { + if (!*state) { + return 0; + } + struct mCore* core = *state; + core->deinit(core); + return 0; +} + +M_TEST_DEFINE(createSet) { + struct mCore* core = *state; + struct mCheatDevice* device = core->cheatDevice(core); + assert_non_null(device); + struct mCheatSet* set = device->createSet(device, NULL); + assert_non_null(set); + set->deinit(set); +} + +M_TEST_DEFINE(addRawPARv3) { + struct mCore* core = *state; + struct mCheatDevice* device = core->cheatDevice(core); + assert_non_null(device); + struct mCheatSet* set = device->createSet(device, NULL); + assert_non_null(set); + GBACheatSetGameSharkVersion((struct GBACheatSet*) set, GBA_GS_PARV3_RAW); + assert_true(set->addLine(set, "80000000 00000000", GBA_CHEAT_PRO_ACTION_REPLAY)); + assert_false(set->addLine(set, "43000000 00000000", GBA_CHEAT_PRO_ACTION_REPLAY)); + set->deinit(set); +} + +M_TEST_DEFINE(doPARv3Assign) { + struct mCore* core = *state; + struct mCheatDevice* device = core->cheatDevice(core); + assert_non_null(device); + struct mCheatSet* set = device->createSet(device, NULL); + assert_non_null(set); + GBACheatSetGameSharkVersion((struct GBACheatSet*) set, GBA_GS_PARV3_RAW); + assert_true(set->addLine(set, "00300000 00000078", GBA_CHEAT_PRO_ACTION_REPLAY)); + assert_true(set->addLine(set, "02300002 00005678", GBA_CHEAT_PRO_ACTION_REPLAY)); + assert_true(set->addLine(set, "04300004 12345678", GBA_CHEAT_PRO_ACTION_REPLAY)); + + core->reset(core); + assert_int_equal(core->rawRead8(core, 0x03000000, -1), 0); + assert_int_equal(core->rawRead16(core, 0x03000002, -1), 0); + assert_int_equal(core->rawRead32(core, 0x03000004, -1), 0); + + mCheatRefresh(device, set); + assert_int_equal(core->rawRead8(core, 0x03000000, -1), 0x78); + assert_int_equal(core->rawRead16(core, 0x03000002, -1), 0x5678); + assert_int_equal(core->rawRead32(core, 0x03000004, -1), 0x12345678); + + set->deinit(set); +} + +M_TEST_DEFINE(doPARv3If1) { + struct mCore* core = *state; + struct mCheatDevice* device = core->cheatDevice(core); + assert_non_null(device); + struct mCheatSet* set = device->createSet(device, NULL); + assert_non_null(set); + GBACheatSetGameSharkVersion((struct GBACheatSet*) set, GBA_GS_PARV3_RAW); + assert_true(set->addLine(set, "00300001 00000011", GBA_CHEAT_PRO_ACTION_REPLAY)); + assert_true(set->addLine(set, "08300000 00000000", GBA_CHEAT_PRO_ACTION_REPLAY)); + assert_true(set->addLine(set, "00300001 00000012", GBA_CHEAT_PRO_ACTION_REPLAY)); + assert_true(set->addLine(set, "00300000 00000001", GBA_CHEAT_PRO_ACTION_REPLAY)); + + core->reset(core); + assert_int_equal(core->rawRead8(core, 0x03000000, -1), 0); + assert_int_equal(core->rawRead8(core, 0x03000001, -1), 0); + + mCheatRefresh(device, set); + assert_int_equal(core->rawRead8(core, 0x03000000, -1), 0x1); + assert_int_equal(core->rawRead8(core, 0x03000001, -1), 0x12); + + core->reset(core); + core->rawWrite8(core, 0x03000000, -1, 0x1); + mCheatRefresh(device, set); + assert_int_equal(core->rawRead8(core, 0x03000000, -1), 0x1); + assert_int_equal(core->rawRead8(core, 0x03000001, -1), 0x11); + + set->deinit(set); +} + +M_TEST_DEFINE(doPARv3If1x1) { + struct mCore* core = *state; + struct mCheatDevice* device = core->cheatDevice(core); + assert_non_null(device); + struct mCheatSet* set = device->createSet(device, NULL); + assert_non_null(set); + GBACheatSetGameSharkVersion((struct GBACheatSet*) set, GBA_GS_PARV3_RAW); + assert_true(set->addLine(set, "00300002 00000021", GBA_CHEAT_PRO_ACTION_REPLAY)); + assert_true(set->addLine(set, "00300003 00000031", GBA_CHEAT_PRO_ACTION_REPLAY)); + assert_true(set->addLine(set, "08300000 00000000", GBA_CHEAT_PRO_ACTION_REPLAY)); + assert_true(set->addLine(set, "00300002 00000022", GBA_CHEAT_PRO_ACTION_REPLAY)); + assert_true(set->addLine(set, "08300001 00000000", GBA_CHEAT_PRO_ACTION_REPLAY)); + assert_true(set->addLine(set, "00300003 00000032", GBA_CHEAT_PRO_ACTION_REPLAY)); + assert_true(set->addLine(set, "00300000 00000001", GBA_CHEAT_PRO_ACTION_REPLAY)); + + core->reset(core); + assert_int_equal(core->rawRead8(core, 0x03000000, -1), 0); + assert_int_equal(core->rawRead8(core, 0x03000001, -1), 0); + assert_int_equal(core->rawRead8(core, 0x03000002, -1), 0); + assert_int_equal(core->rawRead8(core, 0x03000003, -1), 0); + + mCheatRefresh(device, set); + assert_int_equal(core->rawRead8(core, 0x03000000, -1), 0x1); + assert_int_equal(core->rawRead8(core, 0x03000001, -1), 0); + assert_int_equal(core->rawRead8(core, 0x03000002, -1), 0x22); + assert_int_equal(core->rawRead8(core, 0x03000003, -1), 0x32); + + core->reset(core); + core->rawWrite8(core, 0x03000000, -1, 0x1); + mCheatRefresh(device, set); + assert_int_equal(core->rawRead8(core, 0x03000000, -1), 0x1); + assert_int_equal(core->rawRead8(core, 0x03000001, -1), 0); + assert_int_equal(core->rawRead8(core, 0x03000002, -1), 0x21); + assert_int_equal(core->rawRead8(core, 0x03000003, -1), 0x32); + + core->reset(core); + core->rawWrite8(core, 0x03000001, -1, 0x1); + mCheatRefresh(device, set); + assert_int_equal(core->rawRead8(core, 0x03000000, -1), 0x1); + assert_int_equal(core->rawRead8(core, 0x03000001, -1), 0x1); + assert_int_equal(core->rawRead8(core, 0x03000002, -1), 0x22); + assert_int_equal(core->rawRead8(core, 0x03000003, -1), 0x31); + + core->reset(core); + core->rawWrite8(core, 0x03000000, -1, 0x1); + core->rawWrite8(core, 0x03000001, -1, 0x1); + mCheatRefresh(device, set); + assert_int_equal(core->rawRead8(core, 0x03000000, -1), 0x1); + assert_int_equal(core->rawRead8(core, 0x03000001, -1), 0x1); + assert_int_equal(core->rawRead8(core, 0x03000002, -1), 0x21); + assert_int_equal(core->rawRead8(core, 0x03000003, -1), 0x31); + + set->deinit(set); +} + +M_TEST_DEFINE(doPARv3If2) { + struct mCore* core = *state; + struct mCheatDevice* device = core->cheatDevice(core); + assert_non_null(device); + struct mCheatSet* set = device->createSet(device, NULL); + assert_non_null(set); + GBACheatSetGameSharkVersion((struct GBACheatSet*) set, GBA_GS_PARV3_RAW); + assert_true(set->addLine(set, "00300001 00000011", GBA_CHEAT_PRO_ACTION_REPLAY)); + assert_true(set->addLine(set, "00300002 00000021", GBA_CHEAT_PRO_ACTION_REPLAY)); + assert_true(set->addLine(set, "48300000 00000000", GBA_CHEAT_PRO_ACTION_REPLAY)); + assert_true(set->addLine(set, "00300001 00000012", GBA_CHEAT_PRO_ACTION_REPLAY)); + assert_true(set->addLine(set, "00300002 00000022", GBA_CHEAT_PRO_ACTION_REPLAY)); + assert_true(set->addLine(set, "00300000 00000001", GBA_CHEAT_PRO_ACTION_REPLAY)); + + core->reset(core); + assert_int_equal(core->rawRead8(core, 0x03000000, -1), 0); + assert_int_equal(core->rawRead8(core, 0x03000001, -1), 0); + assert_int_equal(core->rawRead8(core, 0x03000002, -1), 0); + + mCheatRefresh(device, set); + assert_int_equal(core->rawRead8(core, 0x03000000, -1), 0x1); + assert_int_equal(core->rawRead8(core, 0x03000001, -1), 0x12); + assert_int_equal(core->rawRead8(core, 0x03000002, -1), 0x22); + + core->reset(core); + core->rawWrite8(core, 0x03000000, -1, 0x1); + mCheatRefresh(device, set); + assert_int_equal(core->rawRead8(core, 0x03000000, -1), 0x1); + assert_int_equal(core->rawRead8(core, 0x03000001, -1), 0x11); + assert_int_equal(core->rawRead8(core, 0x03000002, -1), 0x21); + + set->deinit(set); +} + +M_TEST_DEFINE(doPARv3If2x2) { + struct mCore* core = *state; + struct mCheatDevice* device = core->cheatDevice(core); + assert_non_null(device); + struct mCheatSet* set = device->createSet(device, NULL); + assert_non_null(set); + GBACheatSetGameSharkVersion((struct GBACheatSet*) set, GBA_GS_PARV3_RAW); + assert_true(set->addLine(set, "00300002 00000021", GBA_CHEAT_PRO_ACTION_REPLAY)); + assert_true(set->addLine(set, "00300003 00000031", GBA_CHEAT_PRO_ACTION_REPLAY)); + assert_true(set->addLine(set, "00300004 00000041", GBA_CHEAT_PRO_ACTION_REPLAY)); + assert_true(set->addLine(set, "00300005 00000051", GBA_CHEAT_PRO_ACTION_REPLAY)); + assert_true(set->addLine(set, "48300000 00000000", GBA_CHEAT_PRO_ACTION_REPLAY)); + assert_true(set->addLine(set, "00300002 00000022", GBA_CHEAT_PRO_ACTION_REPLAY)); + assert_true(set->addLine(set, "00300003 00000032", GBA_CHEAT_PRO_ACTION_REPLAY)); + assert_true(set->addLine(set, "48300001 00000000", GBA_CHEAT_PRO_ACTION_REPLAY)); + assert_true(set->addLine(set, "00300004 00000042", GBA_CHEAT_PRO_ACTION_REPLAY)); + assert_true(set->addLine(set, "00300005 00000052", GBA_CHEAT_PRO_ACTION_REPLAY)); + assert_true(set->addLine(set, "00300000 00000001", GBA_CHEAT_PRO_ACTION_REPLAY)); + + core->reset(core); + assert_int_equal(core->rawRead8(core, 0x03000000, -1), 0); + assert_int_equal(core->rawRead8(core, 0x03000001, -1), 0); + assert_int_equal(core->rawRead8(core, 0x03000002, -1), 0); + assert_int_equal(core->rawRead8(core, 0x03000003, -1), 0); + assert_int_equal(core->rawRead8(core, 0x03000004, -1), 0); + assert_int_equal(core->rawRead8(core, 0x03000005, -1), 0); + + mCheatRefresh(device, set); + assert_int_equal(core->rawRead8(core, 0x03000000, -1), 0x1); + assert_int_equal(core->rawRead8(core, 0x03000001, -1), 0); + assert_int_equal(core->rawRead8(core, 0x03000002, -1), 0x22); + assert_int_equal(core->rawRead8(core, 0x03000003, -1), 0x32); + assert_int_equal(core->rawRead8(core, 0x03000004, -1), 0x42); + assert_int_equal(core->rawRead8(core, 0x03000005, -1), 0x52); + + core->reset(core); + core->rawWrite8(core, 0x03000000, -1, 0x1); + mCheatRefresh(device, set); + assert_int_equal(core->rawRead8(core, 0x03000000, -1), 0x1); + assert_int_equal(core->rawRead8(core, 0x03000001, -1), 0); + assert_int_equal(core->rawRead8(core, 0x03000002, -1), 0x21); + assert_int_equal(core->rawRead8(core, 0x03000003, -1), 0x31); + assert_int_equal(core->rawRead8(core, 0x03000004, -1), 0x42); + assert_int_equal(core->rawRead8(core, 0x03000005, -1), 0x52); + + core->reset(core); + core->rawWrite8(core, 0x03000001, -1, 0x1); + mCheatRefresh(device, set); + assert_int_equal(core->rawRead8(core, 0x03000000, -1), 0x1); + assert_int_equal(core->rawRead8(core, 0x03000001, -1), 0x1); + assert_int_equal(core->rawRead8(core, 0x03000002, -1), 0x22); + assert_int_equal(core->rawRead8(core, 0x03000003, -1), 0x32); + assert_int_equal(core->rawRead8(core, 0x03000004, -1), 0x41); + assert_int_equal(core->rawRead8(core, 0x03000005, -1), 0x51); + + core->reset(core); + core->rawWrite8(core, 0x03000000, -1, 0x1); + core->rawWrite8(core, 0x03000001, -1, 0x1); + mCheatRefresh(device, set); + assert_int_equal(core->rawRead8(core, 0x03000000, -1), 0x1); + assert_int_equal(core->rawRead8(core, 0x03000001, -1), 0x1); + assert_int_equal(core->rawRead8(core, 0x03000002, -1), 0x21); + assert_int_equal(core->rawRead8(core, 0x03000003, -1), 0x31); + assert_int_equal(core->rawRead8(core, 0x03000004, -1), 0x41); + assert_int_equal(core->rawRead8(core, 0x03000005, -1), 0x51); + set->deinit(set); +} + +M_TEST_DEFINE(doPARv3If2Contain1) { + struct mCore* core = *state; + struct mCheatDevice* device = core->cheatDevice(core); + assert_non_null(device); + struct mCheatSet* set = device->createSet(device, NULL); + assert_non_null(set); + GBACheatSetGameSharkVersion((struct GBACheatSet*) set, GBA_GS_PARV3_RAW); + assert_true(set->addLine(set, "00300002 00000021", GBA_CHEAT_PRO_ACTION_REPLAY)); + assert_true(set->addLine(set, "48300000 00000000", GBA_CHEAT_PRO_ACTION_REPLAY)); + assert_true(set->addLine(set, "08300001 00000000", GBA_CHEAT_PRO_ACTION_REPLAY)); + assert_true(set->addLine(set, "00300002 00000022", GBA_CHEAT_PRO_ACTION_REPLAY)); + assert_true(set->addLine(set, "00300000 00000001", GBA_CHEAT_PRO_ACTION_REPLAY)); + + core->reset(core); + assert_int_equal(core->rawRead8(core, 0x03000000, -1), 0); + assert_int_equal(core->rawRead8(core, 0x03000001, -1), 0); + assert_int_equal(core->rawRead8(core, 0x03000002, -1), 0); + + mCheatRefresh(device, set); + assert_int_equal(core->rawRead8(core, 0x03000000, -1), 0x1); + assert_int_equal(core->rawRead8(core, 0x03000001, -1), 0); + assert_int_equal(core->rawRead8(core, 0x03000002, -1), 0x22); + + core->reset(core); + core->rawWrite8(core, 0x03000000, -1, 0x1); + mCheatRefresh(device, set); + assert_int_equal(core->rawRead8(core, 0x03000000, -1), 0x1); + assert_int_equal(core->rawRead8(core, 0x03000001, -1), 0); + assert_int_equal(core->rawRead8(core, 0x03000002, -1), 0x21); + + core->reset(core); + core->rawWrite8(core, 0x03000001, -1, 0x1); + mCheatRefresh(device, set); + assert_int_equal(core->rawRead8(core, 0x03000000, -1), 0x1); + assert_int_equal(core->rawRead8(core, 0x03000001, -1), 0x1); + assert_int_equal(core->rawRead8(core, 0x03000002, -1), 0x21); + + core->reset(core); + core->rawWrite8(core, 0x03000000, -1, 0x1); + core->rawWrite8(core, 0x03000001, -1, 0x1); + mCheatRefresh(device, set); + assert_int_equal(core->rawRead8(core, 0x03000000, -1), 0x1); + assert_int_equal(core->rawRead8(core, 0x03000001, -1), 0x1); + assert_int_equal(core->rawRead8(core, 0x03000002, -1), 0x21); + set->deinit(set); +} + +M_TEST_DEFINE(doPARv3IfX) { + struct mCore* core = *state; + struct mCheatDevice* device = core->cheatDevice(core); + assert_non_null(device); + struct mCheatSet* set = device->createSet(device, NULL); + assert_non_null(set); + GBACheatSetGameSharkVersion((struct GBACheatSet*) set, GBA_GS_PARV3_RAW); + assert_true(set->addLine(set, "00300001 00000011", GBA_CHEAT_PRO_ACTION_REPLAY)); + assert_true(set->addLine(set, "88300000 00000000", GBA_CHEAT_PRO_ACTION_REPLAY)); + assert_true(set->addLine(set, "00300001 00000012", GBA_CHEAT_PRO_ACTION_REPLAY)); + assert_true(set->addLine(set, "00000000 40000000", GBA_CHEAT_PRO_ACTION_REPLAY)); + assert_true(set->addLine(set, "00300000 00000001", GBA_CHEAT_PRO_ACTION_REPLAY)); + + core->reset(core); + assert_int_equal(core->rawRead8(core, 0x03000000, -1), 0); + assert_int_equal(core->rawRead8(core, 0x03000001, -1), 0); + + mCheatRefresh(device, set); + assert_int_equal(core->rawRead8(core, 0x03000000, -1), 0x1); + assert_int_equal(core->rawRead8(core, 0x03000001, -1), 0x12); + + core->reset(core); + core->rawWrite8(core, 0x03000000, -1, 0x1); + mCheatRefresh(device, set); + assert_int_equal(core->rawRead8(core, 0x03000000, -1), 0x1); + assert_int_equal(core->rawRead8(core, 0x03000001, -1), 0x11); +} + +M_TEST_DEFINE(doPARv3IfXxX) { + struct mCore* core = *state; + struct mCheatDevice* device = core->cheatDevice(core); + assert_non_null(device); + struct mCheatSet* set = device->createSet(device, NULL); + assert_non_null(set); + GBACheatSetGameSharkVersion((struct GBACheatSet*) set, GBA_GS_PARV3_RAW); + assert_true(set->addLine(set, "00300002 00000021", GBA_CHEAT_PRO_ACTION_REPLAY)); + assert_true(set->addLine(set, "00300003 00000031", GBA_CHEAT_PRO_ACTION_REPLAY)); + assert_true(set->addLine(set, "00300004 00000041", GBA_CHEAT_PRO_ACTION_REPLAY)); + assert_true(set->addLine(set, "88300000 00000000", GBA_CHEAT_PRO_ACTION_REPLAY)); + assert_true(set->addLine(set, "00300002 00000022", GBA_CHEAT_PRO_ACTION_REPLAY)); + assert_true(set->addLine(set, "00000000 40000000", GBA_CHEAT_PRO_ACTION_REPLAY)); + assert_true(set->addLine(set, "00300003 00000032", GBA_CHEAT_PRO_ACTION_REPLAY)); + assert_true(set->addLine(set, "88300001 00000000", GBA_CHEAT_PRO_ACTION_REPLAY)); + assert_true(set->addLine(set, "00300004 00000042", GBA_CHEAT_PRO_ACTION_REPLAY)); + assert_true(set->addLine(set, "00000000 40000000", GBA_CHEAT_PRO_ACTION_REPLAY)); + assert_true(set->addLine(set, "00300000 00000001", GBA_CHEAT_PRO_ACTION_REPLAY)); + + core->reset(core); + assert_int_equal(core->rawRead8(core, 0x03000000, -1), 0); + assert_int_equal(core->rawRead8(core, 0x03000001, -1), 0); + assert_int_equal(core->rawRead8(core, 0x03000002, -1), 0); + assert_int_equal(core->rawRead8(core, 0x03000003, -1), 0); + assert_int_equal(core->rawRead8(core, 0x03000004, -1), 0); + + mCheatRefresh(device, set); + assert_int_equal(core->rawRead8(core, 0x03000000, -1), 0x1); + assert_int_equal(core->rawRead8(core, 0x03000001, -1), 0); + assert_int_equal(core->rawRead8(core, 0x03000002, -1), 0x22); + assert_int_equal(core->rawRead8(core, 0x03000003, -1), 0x32); + assert_int_equal(core->rawRead8(core, 0x03000004, -1), 0x42); + + core->reset(core); + core->rawWrite8(core, 0x03000000, -1, 0x1); + mCheatRefresh(device, set); + assert_int_equal(core->rawRead8(core, 0x03000000, -1), 0x1); + assert_int_equal(core->rawRead8(core, 0x03000001, -1), 0); + assert_int_equal(core->rawRead8(core, 0x03000002, -1), 0x21); + assert_int_equal(core->rawRead8(core, 0x03000003, -1), 0x32); + assert_int_equal(core->rawRead8(core, 0x03000004, -1), 0x42); + + core->reset(core); + core->rawWrite8(core, 0x03000001, -1, 0x1); + mCheatRefresh(device, set); + assert_int_equal(core->rawRead8(core, 0x03000000, -1), 0x1); + assert_int_equal(core->rawRead8(core, 0x03000001, -1), 0x1); + assert_int_equal(core->rawRead8(core, 0x03000002, -1), 0x22); + assert_int_equal(core->rawRead8(core, 0x03000003, -1), 0x32); + assert_int_equal(core->rawRead8(core, 0x03000004, -1), 0x41); + + core->reset(core); + core->rawWrite8(core, 0x03000000, -1, 0x1); + core->rawWrite8(core, 0x03000001, -1, 0x1); + mCheatRefresh(device, set); + assert_int_equal(core->rawRead8(core, 0x03000000, -1), 0x1); + assert_int_equal(core->rawRead8(core, 0x03000001, -1), 0x1); + assert_int_equal(core->rawRead8(core, 0x03000002, -1), 0x21); + assert_int_equal(core->rawRead8(core, 0x03000003, -1), 0x32); + assert_int_equal(core->rawRead8(core, 0x03000004, -1), 0x41); +} + +M_TEST_DEFINE(doPARv3IfXElse) { + struct mCore* core = *state; + struct mCheatDevice* device = core->cheatDevice(core); + assert_non_null(device); + struct mCheatSet* set = device->createSet(device, NULL); + assert_non_null(set); + GBACheatSetGameSharkVersion((struct GBACheatSet*) set, GBA_GS_PARV3_RAW); + assert_true(set->addLine(set, "00300001 00000011", GBA_CHEAT_PRO_ACTION_REPLAY)); + assert_true(set->addLine(set, "00300002 00000021", GBA_CHEAT_PRO_ACTION_REPLAY)); + assert_true(set->addLine(set, "88300000 00000000", GBA_CHEAT_PRO_ACTION_REPLAY)); + assert_true(set->addLine(set, "00300001 00000012", GBA_CHEAT_PRO_ACTION_REPLAY)); + assert_true(set->addLine(set, "00000000 60000000", GBA_CHEAT_PRO_ACTION_REPLAY)); + assert_true(set->addLine(set, "00300002 00000022", GBA_CHEAT_PRO_ACTION_REPLAY)); + assert_true(set->addLine(set, "00000000 40000000", GBA_CHEAT_PRO_ACTION_REPLAY)); + assert_true(set->addLine(set, "00300000 00000001", GBA_CHEAT_PRO_ACTION_REPLAY)); + + core->reset(core); + assert_int_equal(core->rawRead8(core, 0x03000000, -1), 0); + assert_int_equal(core->rawRead8(core, 0x03000001, -1), 0); + assert_int_equal(core->rawRead8(core, 0x03000002, -1), 0); + + mCheatRefresh(device, set); + assert_int_equal(core->rawRead8(core, 0x03000000, -1), 0x1); + assert_int_equal(core->rawRead8(core, 0x03000001, -1), 0x12); + assert_int_equal(core->rawRead8(core, 0x03000002, -1), 0x21); + + core->reset(core); + core->rawWrite8(core, 0x03000000, -1, 0x1); + mCheatRefresh(device, set); + assert_int_equal(core->rawRead8(core, 0x03000000, -1), 0x1); + assert_int_equal(core->rawRead8(core, 0x03000001, -1), 0x11); + assert_int_equal(core->rawRead8(core, 0x03000002, -1), 0x22); +} + +M_TEST_DEFINE(doPARv3IfXElsexX) { + struct mCore* core = *state; + struct mCheatDevice* device = core->cheatDevice(core); + assert_non_null(device); + struct mCheatSet* set = device->createSet(device, NULL); + assert_non_null(set); + GBACheatSetGameSharkVersion((struct GBACheatSet*) set, GBA_GS_PARV3_RAW); + assert_true(set->addLine(set, "00300002 00000021", GBA_CHEAT_PRO_ACTION_REPLAY)); + assert_true(set->addLine(set, "00300003 00000031", GBA_CHEAT_PRO_ACTION_REPLAY)); + assert_true(set->addLine(set, "00300004 00000041", GBA_CHEAT_PRO_ACTION_REPLAY)); + assert_true(set->addLine(set, "00300005 00000051", GBA_CHEAT_PRO_ACTION_REPLAY)); + assert_true(set->addLine(set, "88300000 00000000", GBA_CHEAT_PRO_ACTION_REPLAY)); + assert_true(set->addLine(set, "00300002 00000022", GBA_CHEAT_PRO_ACTION_REPLAY)); + assert_true(set->addLine(set, "00000000 60000000", GBA_CHEAT_PRO_ACTION_REPLAY)); + assert_true(set->addLine(set, "00300003 00000032", GBA_CHEAT_PRO_ACTION_REPLAY)); + assert_true(set->addLine(set, "00000000 40000000", GBA_CHEAT_PRO_ACTION_REPLAY)); + assert_true(set->addLine(set, "00300004 00000042", GBA_CHEAT_PRO_ACTION_REPLAY)); + assert_true(set->addLine(set, "88300001 00000000", GBA_CHEAT_PRO_ACTION_REPLAY)); + assert_true(set->addLine(set, "00300005 00000052", GBA_CHEAT_PRO_ACTION_REPLAY)); + assert_true(set->addLine(set, "00000000 40000000", GBA_CHEAT_PRO_ACTION_REPLAY)); + assert_true(set->addLine(set, "00300000 00000001", GBA_CHEAT_PRO_ACTION_REPLAY)); + + core->reset(core); + assert_int_equal(core->rawRead8(core, 0x03000000, -1), 0); + assert_int_equal(core->rawRead8(core, 0x03000001, -1), 0); + assert_int_equal(core->rawRead8(core, 0x03000002, -1), 0); + assert_int_equal(core->rawRead8(core, 0x03000003, -1), 0); + assert_int_equal(core->rawRead8(core, 0x03000004, -1), 0); + assert_int_equal(core->rawRead8(core, 0x03000005, -1), 0); + + mCheatRefresh(device, set); + assert_int_equal(core->rawRead8(core, 0x03000000, -1), 0x1); + assert_int_equal(core->rawRead8(core, 0x03000001, -1), 0); + assert_int_equal(core->rawRead8(core, 0x03000002, -1), 0x22); + assert_int_equal(core->rawRead8(core, 0x03000003, -1), 0x31); + assert_int_equal(core->rawRead8(core, 0x03000004, -1), 0x42); + assert_int_equal(core->rawRead8(core, 0x03000005, -1), 0x52); + + core->reset(core); + core->rawWrite8(core, 0x03000000, -1, 0x1); + mCheatRefresh(device, set); + assert_int_equal(core->rawRead8(core, 0x03000000, -1), 0x1); + assert_int_equal(core->rawRead8(core, 0x03000001, -1), 0); + assert_int_equal(core->rawRead8(core, 0x03000002, -1), 0x21); + assert_int_equal(core->rawRead8(core, 0x03000003, -1), 0x32); + assert_int_equal(core->rawRead8(core, 0x03000004, -1), 0x42); + assert_int_equal(core->rawRead8(core, 0x03000005, -1), 0x52); + + core->reset(core); + core->rawWrite8(core, 0x03000001, -1, 0x1); + mCheatRefresh(device, set); + assert_int_equal(core->rawRead8(core, 0x03000000, -1), 0x1); + assert_int_equal(core->rawRead8(core, 0x03000001, -1), 0x1); + assert_int_equal(core->rawRead8(core, 0x03000002, -1), 0x22); + assert_int_equal(core->rawRead8(core, 0x03000003, -1), 0x31); + assert_int_equal(core->rawRead8(core, 0x03000004, -1), 0x42); + assert_int_equal(core->rawRead8(core, 0x03000005, -1), 0x51); + + core->reset(core); + core->rawWrite8(core, 0x03000000, -1, 0x1); + core->rawWrite8(core, 0x03000001, -1, 0x1); + mCheatRefresh(device, set); + assert_int_equal(core->rawRead8(core, 0x03000000, -1), 0x1); + assert_int_equal(core->rawRead8(core, 0x03000001, -1), 0x1); + assert_int_equal(core->rawRead8(core, 0x03000002, -1), 0x21); + assert_int_equal(core->rawRead8(core, 0x03000003, -1), 0x32); + assert_int_equal(core->rawRead8(core, 0x03000004, -1), 0x42); + assert_int_equal(core->rawRead8(core, 0x03000005, -1), 0x51); +} + +M_TEST_DEFINE(doPARv3IfXElsexXElse) { + struct mCore* core = *state; + struct mCheatDevice* device = core->cheatDevice(core); + assert_non_null(device); + struct mCheatSet* set = device->createSet(device, NULL); + assert_non_null(set); + GBACheatSetGameSharkVersion((struct GBACheatSet*) set, GBA_GS_PARV3_RAW); + assert_true(set->addLine(set, "00300002 00000021", GBA_CHEAT_PRO_ACTION_REPLAY)); + assert_true(set->addLine(set, "00300003 00000031", GBA_CHEAT_PRO_ACTION_REPLAY)); + assert_true(set->addLine(set, "00300004 00000041", GBA_CHEAT_PRO_ACTION_REPLAY)); + assert_true(set->addLine(set, "00300005 00000051", GBA_CHEAT_PRO_ACTION_REPLAY)); + assert_true(set->addLine(set, "00300006 00000061", GBA_CHEAT_PRO_ACTION_REPLAY)); + assert_true(set->addLine(set, "88300000 00000000", GBA_CHEAT_PRO_ACTION_REPLAY)); + assert_true(set->addLine(set, "00300002 00000022", GBA_CHEAT_PRO_ACTION_REPLAY)); + assert_true(set->addLine(set, "00000000 60000000", GBA_CHEAT_PRO_ACTION_REPLAY)); + assert_true(set->addLine(set, "00300003 00000032", GBA_CHEAT_PRO_ACTION_REPLAY)); + assert_true(set->addLine(set, "00000000 40000000", GBA_CHEAT_PRO_ACTION_REPLAY)); + assert_true(set->addLine(set, "00300004 00000042", GBA_CHEAT_PRO_ACTION_REPLAY)); + assert_true(set->addLine(set, "88300001 00000000", GBA_CHEAT_PRO_ACTION_REPLAY)); + assert_true(set->addLine(set, "00300005 00000052", GBA_CHEAT_PRO_ACTION_REPLAY)); + assert_true(set->addLine(set, "00000000 60000000", GBA_CHEAT_PRO_ACTION_REPLAY)); + assert_true(set->addLine(set, "00300006 00000062", GBA_CHEAT_PRO_ACTION_REPLAY)); + assert_true(set->addLine(set, "00000000 40000000", GBA_CHEAT_PRO_ACTION_REPLAY)); + assert_true(set->addLine(set, "00300000 00000001", GBA_CHEAT_PRO_ACTION_REPLAY)); + + core->reset(core); + assert_int_equal(core->rawRead8(core, 0x03000000, -1), 0); + assert_int_equal(core->rawRead8(core, 0x03000001, -1), 0); + assert_int_equal(core->rawRead8(core, 0x03000002, -1), 0); + assert_int_equal(core->rawRead8(core, 0x03000003, -1), 0); + assert_int_equal(core->rawRead8(core, 0x03000004, -1), 0); + assert_int_equal(core->rawRead8(core, 0x03000005, -1), 0); + assert_int_equal(core->rawRead8(core, 0x03000006, -1), 0); + + mCheatRefresh(device, set); + assert_int_equal(core->rawRead8(core, 0x03000000, -1), 0x1); + assert_int_equal(core->rawRead8(core, 0x03000001, -1), 0); + assert_int_equal(core->rawRead8(core, 0x03000002, -1), 0x22); + assert_int_equal(core->rawRead8(core, 0x03000003, -1), 0x31); + assert_int_equal(core->rawRead8(core, 0x03000004, -1), 0x42); + assert_int_equal(core->rawRead8(core, 0x03000005, -1), 0x52); + + core->reset(core); + core->rawWrite8(core, 0x03000000, -1, 0x1); + mCheatRefresh(device, set); + assert_int_equal(core->rawRead8(core, 0x03000000, -1), 0x1); + assert_int_equal(core->rawRead8(core, 0x03000001, -1), 0); + assert_int_equal(core->rawRead8(core, 0x03000002, -1), 0x21); + assert_int_equal(core->rawRead8(core, 0x03000003, -1), 0x32); + assert_int_equal(core->rawRead8(core, 0x03000004, -1), 0x42); + assert_int_equal(core->rawRead8(core, 0x03000005, -1), 0x52); + assert_int_equal(core->rawRead8(core, 0x03000006, -1), 0x61); + + core->reset(core); + core->rawWrite8(core, 0x03000001, -1, 0x1); + mCheatRefresh(device, set); + assert_int_equal(core->rawRead8(core, 0x03000000, -1), 0x1); + assert_int_equal(core->rawRead8(core, 0x03000001, -1), 0x1); + assert_int_equal(core->rawRead8(core, 0x03000002, -1), 0x22); + assert_int_equal(core->rawRead8(core, 0x03000003, -1), 0x31); + assert_int_equal(core->rawRead8(core, 0x03000004, -1), 0x42); + assert_int_equal(core->rawRead8(core, 0x03000005, -1), 0x51); + assert_int_equal(core->rawRead8(core, 0x03000006, -1), 0x62); + + core->reset(core); + core->rawWrite8(core, 0x03000000, -1, 0x1); + core->rawWrite8(core, 0x03000001, -1, 0x1); + mCheatRefresh(device, set); + assert_int_equal(core->rawRead8(core, 0x03000000, -1), 0x1); + assert_int_equal(core->rawRead8(core, 0x03000001, -1), 0x1); + assert_int_equal(core->rawRead8(core, 0x03000002, -1), 0x21); + assert_int_equal(core->rawRead8(core, 0x03000003, -1), 0x32); + assert_int_equal(core->rawRead8(core, 0x03000004, -1), 0x42); + assert_int_equal(core->rawRead8(core, 0x03000005, -1), 0x51); + assert_int_equal(core->rawRead8(core, 0x03000006, -1), 0x62); +} + +M_TEST_DEFINE(doPARv3IfXContain1) { + struct mCore* core = *state; + struct mCheatDevice* device = core->cheatDevice(core); + assert_non_null(device); + struct mCheatSet* set = device->createSet(device, NULL); + assert_non_null(set); + GBACheatSetGameSharkVersion((struct GBACheatSet*) set, GBA_GS_PARV3_RAW); + assert_true(set->addLine(set, "00300002 00000021", GBA_CHEAT_PRO_ACTION_REPLAY)); + assert_true(set->addLine(set, "00300003 00000031", GBA_CHEAT_PRO_ACTION_REPLAY)); + assert_true(set->addLine(set, "00300004 00000041", GBA_CHEAT_PRO_ACTION_REPLAY)); + assert_true(set->addLine(set, "88300000 00000000", GBA_CHEAT_PRO_ACTION_REPLAY)); + assert_true(set->addLine(set, "00300002 00000022", GBA_CHEAT_PRO_ACTION_REPLAY)); + assert_true(set->addLine(set, "08300001 00000000", GBA_CHEAT_PRO_ACTION_REPLAY)); + assert_true(set->addLine(set, "00300003 00000032", GBA_CHEAT_PRO_ACTION_REPLAY)); + assert_true(set->addLine(set, "00300004 00000042", GBA_CHEAT_PRO_ACTION_REPLAY)); + assert_true(set->addLine(set, "00000000 40000000", GBA_CHEAT_PRO_ACTION_REPLAY)); + assert_true(set->addLine(set, "00300000 00000001", GBA_CHEAT_PRO_ACTION_REPLAY)); + + core->reset(core); + assert_int_equal(core->rawRead8(core, 0x03000000, -1), 0); + assert_int_equal(core->rawRead8(core, 0x03000001, -1), 0); + assert_int_equal(core->rawRead8(core, 0x03000002, -1), 0); + assert_int_equal(core->rawRead8(core, 0x03000003, -1), 0); + assert_int_equal(core->rawRead8(core, 0x03000004, -1), 0); + + mCheatRefresh(device, set); + assert_int_equal(core->rawRead8(core, 0x03000000, -1), 0x1); + assert_int_equal(core->rawRead8(core, 0x03000001, -1), 0); + assert_int_equal(core->rawRead8(core, 0x03000002, -1), 0x22); + assert_int_equal(core->rawRead8(core, 0x03000003, -1), 0x32); + assert_int_equal(core->rawRead8(core, 0x03000004, -1), 0x42); + + core->reset(core); + core->rawWrite8(core, 0x03000000, -1, 0x1); + mCheatRefresh(device, set); + assert_int_equal(core->rawRead8(core, 0x03000000, -1), 0x1); + assert_int_equal(core->rawRead8(core, 0x03000001, -1), 0); + assert_int_equal(core->rawRead8(core, 0x03000002, -1), 0x21); + assert_int_equal(core->rawRead8(core, 0x03000003, -1), 0x31); + assert_int_equal(core->rawRead8(core, 0x03000004, -1), 0x41); + + core->reset(core); + core->rawWrite8(core, 0x03000001, -1, 0x1); + mCheatRefresh(device, set); + assert_int_equal(core->rawRead8(core, 0x03000000, -1), 0x1); + assert_int_equal(core->rawRead8(core, 0x03000001, -1), 0x1); + assert_int_equal(core->rawRead8(core, 0x03000002, -1), 0x22); + assert_int_equal(core->rawRead8(core, 0x03000003, -1), 0x31); + assert_int_equal(core->rawRead8(core, 0x03000004, -1), 0x42); + + core->reset(core); + core->rawWrite8(core, 0x03000000, -1, 0x1); + core->rawWrite8(core, 0x03000001, -1, 0x1); + mCheatRefresh(device, set); + assert_int_equal(core->rawRead8(core, 0x03000000, -1), 0x1); + assert_int_equal(core->rawRead8(core, 0x03000001, -1), 0x1); + assert_int_equal(core->rawRead8(core, 0x03000002, -1), 0x21); + assert_int_equal(core->rawRead8(core, 0x03000003, -1), 0x31); + assert_int_equal(core->rawRead8(core, 0x03000004, -1), 0x41); +} + +M_TEST_DEFINE(doPARv3IfXContain1Else) { + struct mCore* core = *state; + struct mCheatDevice* device = core->cheatDevice(core); + assert_non_null(device); + struct mCheatSet* set = device->createSet(device, NULL); + assert_non_null(set); + GBACheatSetGameSharkVersion((struct GBACheatSet*) set, GBA_GS_PARV3_RAW); + assert_true(set->addLine(set, "00300002 00000021", GBA_CHEAT_PRO_ACTION_REPLAY)); + assert_true(set->addLine(set, "00300003 00000031", GBA_CHEAT_PRO_ACTION_REPLAY)); + assert_true(set->addLine(set, "00300004 00000041", GBA_CHEAT_PRO_ACTION_REPLAY)); + assert_true(set->addLine(set, "00300005 00000051", GBA_CHEAT_PRO_ACTION_REPLAY)); + assert_true(set->addLine(set, "88300000 00000000", GBA_CHEAT_PRO_ACTION_REPLAY)); + assert_true(set->addLine(set, "00300002 00000022", GBA_CHEAT_PRO_ACTION_REPLAY)); + assert_true(set->addLine(set, "08300001 00000000", GBA_CHEAT_PRO_ACTION_REPLAY)); + assert_true(set->addLine(set, "00300003 00000032", GBA_CHEAT_PRO_ACTION_REPLAY)); + assert_true(set->addLine(set, "00300004 00000042", GBA_CHEAT_PRO_ACTION_REPLAY)); + assert_true(set->addLine(set, "00000000 60000000", GBA_CHEAT_PRO_ACTION_REPLAY)); + assert_true(set->addLine(set, "00300005 00000052", GBA_CHEAT_PRO_ACTION_REPLAY)); + assert_true(set->addLine(set, "00000000 40000000", GBA_CHEAT_PRO_ACTION_REPLAY)); + assert_true(set->addLine(set, "00300000 00000001", GBA_CHEAT_PRO_ACTION_REPLAY)); + + core->reset(core); + assert_int_equal(core->rawRead8(core, 0x03000000, -1), 0); + assert_int_equal(core->rawRead8(core, 0x03000001, -1), 0); + assert_int_equal(core->rawRead8(core, 0x03000002, -1), 0); + assert_int_equal(core->rawRead8(core, 0x03000003, -1), 0); + assert_int_equal(core->rawRead8(core, 0x03000004, -1), 0); + assert_int_equal(core->rawRead8(core, 0x03000005, -1), 0); + + mCheatRefresh(device, set); + assert_int_equal(core->rawRead8(core, 0x03000000, -1), 0x1); + assert_int_equal(core->rawRead8(core, 0x03000001, -1), 0); + assert_int_equal(core->rawRead8(core, 0x03000002, -1), 0x22); + assert_int_equal(core->rawRead8(core, 0x03000003, -1), 0x32); + assert_int_equal(core->rawRead8(core, 0x03000004, -1), 0x42); + assert_int_equal(core->rawRead8(core, 0x03000005, -1), 0x51); + + core->reset(core); + core->rawWrite8(core, 0x03000000, -1, 0x1); + mCheatRefresh(device, set); + assert_int_equal(core->rawRead8(core, 0x03000000, -1), 0x1); + assert_int_equal(core->rawRead8(core, 0x03000001, -1), 0); + assert_int_equal(core->rawRead8(core, 0x03000002, -1), 0x21); + assert_int_equal(core->rawRead8(core, 0x03000003, -1), 0x31); + assert_int_equal(core->rawRead8(core, 0x03000004, -1), 0x41); + assert_int_equal(core->rawRead8(core, 0x03000005, -1), 0x52); + + core->reset(core); + core->rawWrite8(core, 0x03000001, -1, 0x1); + mCheatRefresh(device, set); + assert_int_equal(core->rawRead8(core, 0x03000000, -1), 0x1); + assert_int_equal(core->rawRead8(core, 0x03000001, -1), 0x1); + assert_int_equal(core->rawRead8(core, 0x03000002, -1), 0x22); + assert_int_equal(core->rawRead8(core, 0x03000003, -1), 0x31); + assert_int_equal(core->rawRead8(core, 0x03000004, -1), 0x42); + assert_int_equal(core->rawRead8(core, 0x03000005, -1), 0x51); + + core->reset(core); + core->rawWrite8(core, 0x03000000, -1, 0x1); + core->rawWrite8(core, 0x03000001, -1, 0x1); + mCheatRefresh(device, set); + assert_int_equal(core->rawRead8(core, 0x03000000, -1), 0x1); + assert_int_equal(core->rawRead8(core, 0x03000001, -1), 0x1); + assert_int_equal(core->rawRead8(core, 0x03000002, -1), 0x21); + assert_int_equal(core->rawRead8(core, 0x03000003, -1), 0x31); + assert_int_equal(core->rawRead8(core, 0x03000004, -1), 0x41); + assert_int_equal(core->rawRead8(core, 0x03000005, -1), 0x52); +} + +M_TEST_DEFINE(doPARv3IfXElseContain1) { + struct mCore* core = *state; + struct mCheatDevice* device = core->cheatDevice(core); + assert_non_null(device); + struct mCheatSet* set = device->createSet(device, NULL); + assert_non_null(set); + GBACheatSetGameSharkVersion((struct GBACheatSet*) set, GBA_GS_PARV3_RAW); + assert_true(set->addLine(set, "00300002 00000021", GBA_CHEAT_PRO_ACTION_REPLAY)); + assert_true(set->addLine(set, "00300003 00000031", GBA_CHEAT_PRO_ACTION_REPLAY)); + assert_true(set->addLine(set, "00300004 00000041", GBA_CHEAT_PRO_ACTION_REPLAY)); + assert_true(set->addLine(set, "00300005 00000051", GBA_CHEAT_PRO_ACTION_REPLAY)); + assert_true(set->addLine(set, "88300000 00000000", GBA_CHEAT_PRO_ACTION_REPLAY)); + assert_true(set->addLine(set, "00300002 00000022", GBA_CHEAT_PRO_ACTION_REPLAY)); + assert_true(set->addLine(set, "00000000 60000000", GBA_CHEAT_PRO_ACTION_REPLAY)); + assert_true(set->addLine(set, "00300003 00000032", GBA_CHEAT_PRO_ACTION_REPLAY)); + assert_true(set->addLine(set, "08300001 00000000", GBA_CHEAT_PRO_ACTION_REPLAY)); + assert_true(set->addLine(set, "00300004 00000042", GBA_CHEAT_PRO_ACTION_REPLAY)); + assert_true(set->addLine(set, "00300005 00000052", GBA_CHEAT_PRO_ACTION_REPLAY)); + assert_true(set->addLine(set, "00000000 40000000", GBA_CHEAT_PRO_ACTION_REPLAY)); + assert_true(set->addLine(set, "00300000 00000001", GBA_CHEAT_PRO_ACTION_REPLAY)); + + core->reset(core); + assert_int_equal(core->rawRead8(core, 0x03000000, -1), 0); + assert_int_equal(core->rawRead8(core, 0x03000001, -1), 0); + assert_int_equal(core->rawRead8(core, 0x03000002, -1), 0); + assert_int_equal(core->rawRead8(core, 0x03000003, -1), 0); + assert_int_equal(core->rawRead8(core, 0x03000004, -1), 0); + assert_int_equal(core->rawRead8(core, 0x03000005, -1), 0); + + mCheatRefresh(device, set); + assert_int_equal(core->rawRead8(core, 0x03000000, -1), 0x1); + assert_int_equal(core->rawRead8(core, 0x03000001, -1), 0); + assert_int_equal(core->rawRead8(core, 0x03000002, -1), 0x22); + assert_int_equal(core->rawRead8(core, 0x03000003, -1), 0x31); + assert_int_equal(core->rawRead8(core, 0x03000004, -1), 0x41); + assert_int_equal(core->rawRead8(core, 0x03000005, -1), 0x51); + + core->reset(core); + core->rawWrite8(core, 0x03000000, -1, 0x1); + mCheatRefresh(device, set); + assert_int_equal(core->rawRead8(core, 0x03000000, -1), 0x1); + assert_int_equal(core->rawRead8(core, 0x03000001, -1), 0); + assert_int_equal(core->rawRead8(core, 0x03000002, -1), 0x21); + assert_int_equal(core->rawRead8(core, 0x03000003, -1), 0x32); + assert_int_equal(core->rawRead8(core, 0x03000004, -1), 0x42); + assert_int_equal(core->rawRead8(core, 0x03000005, -1), 0x52); + + core->reset(core); + core->rawWrite8(core, 0x03000001, -1, 0x1); + mCheatRefresh(device, set); + assert_int_equal(core->rawRead8(core, 0x03000000, -1), 0x1); + assert_int_equal(core->rawRead8(core, 0x03000001, -1), 0x1); + assert_int_equal(core->rawRead8(core, 0x03000002, -1), 0x22); + assert_int_equal(core->rawRead8(core, 0x03000003, -1), 0x31); + assert_int_equal(core->rawRead8(core, 0x03000004, -1), 0x41); + assert_int_equal(core->rawRead8(core, 0x03000005, -1), 0x51); + + core->reset(core); + core->rawWrite8(core, 0x03000000, -1, 0x1); + core->rawWrite8(core, 0x03000001, -1, 0x1); + mCheatRefresh(device, set); + assert_int_equal(core->rawRead8(core, 0x03000000, -1), 0x1); + assert_int_equal(core->rawRead8(core, 0x03000001, -1), 0x1); + assert_int_equal(core->rawRead8(core, 0x03000002, -1), 0x21); + assert_int_equal(core->rawRead8(core, 0x03000003, -1), 0x32); + assert_int_equal(core->rawRead8(core, 0x03000004, -1), 0x41); + assert_int_equal(core->rawRead8(core, 0x03000005, -1), 0x52); +} + +M_TEST_DEFINE(doPARv3IfXContain1ElseContain1) { + struct mCore* core = *state; + struct mCheatDevice* device = core->cheatDevice(core); + assert_non_null(device); + struct mCheatSet* set = device->createSet(device, NULL); + assert_non_null(set); + GBACheatSetGameSharkVersion((struct GBACheatSet*) set, GBA_GS_PARV3_RAW); + assert_true(set->addLine(set, "00300003 00000031", GBA_CHEAT_PRO_ACTION_REPLAY)); + assert_true(set->addLine(set, "00300004 00000041", GBA_CHEAT_PRO_ACTION_REPLAY)); + assert_true(set->addLine(set, "00300005 00000051", GBA_CHEAT_PRO_ACTION_REPLAY)); + assert_true(set->addLine(set, "00300006 00000061", GBA_CHEAT_PRO_ACTION_REPLAY)); + assert_true(set->addLine(set, "00300007 00000071", GBA_CHEAT_PRO_ACTION_REPLAY)); + assert_true(set->addLine(set, "00300008 00000081", GBA_CHEAT_PRO_ACTION_REPLAY)); + assert_true(set->addLine(set, "88300000 00000000", GBA_CHEAT_PRO_ACTION_REPLAY)); + assert_true(set->addLine(set, "00300003 00000032", GBA_CHEAT_PRO_ACTION_REPLAY)); + assert_true(set->addLine(set, "08300001 00000000", GBA_CHEAT_PRO_ACTION_REPLAY)); + assert_true(set->addLine(set, "00300004 00000042", GBA_CHEAT_PRO_ACTION_REPLAY)); + assert_true(set->addLine(set, "00300005 00000052", GBA_CHEAT_PRO_ACTION_REPLAY)); + assert_true(set->addLine(set, "00000000 60000000", GBA_CHEAT_PRO_ACTION_REPLAY)); + assert_true(set->addLine(set, "00300006 00000062", GBA_CHEAT_PRO_ACTION_REPLAY)); + assert_true(set->addLine(set, "08300002 00000000", GBA_CHEAT_PRO_ACTION_REPLAY)); + assert_true(set->addLine(set, "00300007 00000072", GBA_CHEAT_PRO_ACTION_REPLAY)); + assert_true(set->addLine(set, "00300008 00000082", GBA_CHEAT_PRO_ACTION_REPLAY)); + assert_true(set->addLine(set, "00000000 40000000", GBA_CHEAT_PRO_ACTION_REPLAY)); + assert_true(set->addLine(set, "00300000 00000001", GBA_CHEAT_PRO_ACTION_REPLAY)); + + core->reset(core); + assert_int_equal(core->rawRead8(core, 0x03000000, -1), 0); + assert_int_equal(core->rawRead8(core, 0x03000001, -1), 0); + assert_int_equal(core->rawRead8(core, 0x03000002, -1), 0); + assert_int_equal(core->rawRead8(core, 0x03000003, -1), 0); + assert_int_equal(core->rawRead8(core, 0x03000004, -1), 0); + assert_int_equal(core->rawRead8(core, 0x03000005, -1), 0); + assert_int_equal(core->rawRead8(core, 0x03000006, -1), 0); + assert_int_equal(core->rawRead8(core, 0x03000007, -1), 0); + assert_int_equal(core->rawRead8(core, 0x03000008, -1), 0); + + mCheatRefresh(device, set); + assert_int_equal(core->rawRead8(core, 0x03000000, -1), 0x1); + assert_int_equal(core->rawRead8(core, 0x03000001, -1), 0); + assert_int_equal(core->rawRead8(core, 0x03000002, -1), 0); + assert_int_equal(core->rawRead8(core, 0x03000003, -1), 0x32); + assert_int_equal(core->rawRead8(core, 0x03000004, -1), 0x42); + assert_int_equal(core->rawRead8(core, 0x03000005, -1), 0x52); + assert_int_equal(core->rawRead8(core, 0x03000006, -1), 0x61); + assert_int_equal(core->rawRead8(core, 0x03000007, -1), 0x71); + assert_int_equal(core->rawRead8(core, 0x03000008, -1), 0x81); + + core->reset(core); + core->rawWrite8(core, 0x03000000, -1, 0x1); + mCheatRefresh(device, set); + assert_int_equal(core->rawRead8(core, 0x03000000, -1), 0x1); + assert_int_equal(core->rawRead8(core, 0x03000001, -1), 0); + assert_int_equal(core->rawRead8(core, 0x03000002, -1), 0); + assert_int_equal(core->rawRead8(core, 0x03000003, -1), 0x31); + assert_int_equal(core->rawRead8(core, 0x03000004, -1), 0x41); + assert_int_equal(core->rawRead8(core, 0x03000005, -1), 0x51); + assert_int_equal(core->rawRead8(core, 0x03000006, -1), 0x62); + assert_int_equal(core->rawRead8(core, 0x03000007, -1), 0x72); + assert_int_equal(core->rawRead8(core, 0x03000008, -1), 0x82); + + core->reset(core); + core->rawWrite8(core, 0x03000001, -1, 0x1); + mCheatRefresh(device, set); + assert_int_equal(core->rawRead8(core, 0x03000000, -1), 0x1); + assert_int_equal(core->rawRead8(core, 0x03000001, -1), 0x1); + assert_int_equal(core->rawRead8(core, 0x03000002, -1), 0); + assert_int_equal(core->rawRead8(core, 0x03000003, -1), 0x32); + assert_int_equal(core->rawRead8(core, 0x03000004, -1), 0x41); + assert_int_equal(core->rawRead8(core, 0x03000005, -1), 0x52); + assert_int_equal(core->rawRead8(core, 0x03000006, -1), 0x61); + assert_int_equal(core->rawRead8(core, 0x03000007, -1), 0x71); + assert_int_equal(core->rawRead8(core, 0x03000008, -1), 0x81); + + core->reset(core); + core->rawWrite8(core, 0x03000002, -1, 0x1); + mCheatRefresh(device, set); + assert_int_equal(core->rawRead8(core, 0x03000000, -1), 0x1); + assert_int_equal(core->rawRead8(core, 0x03000001, -1), 0); + assert_int_equal(core->rawRead8(core, 0x03000002, -1), 0x1); + assert_int_equal(core->rawRead8(core, 0x03000003, -1), 0x32); + assert_int_equal(core->rawRead8(core, 0x03000004, -1), 0x42); + assert_int_equal(core->rawRead8(core, 0x03000005, -1), 0x52); + assert_int_equal(core->rawRead8(core, 0x03000006, -1), 0x61); + assert_int_equal(core->rawRead8(core, 0x03000007, -1), 0x71); + assert_int_equal(core->rawRead8(core, 0x03000008, -1), 0x81); + + core->reset(core); + core->rawWrite8(core, 0x03000000, -1, 0x1); + core->rawWrite8(core, 0x03000001, -1, 0x1); + mCheatRefresh(device, set); + assert_int_equal(core->rawRead8(core, 0x03000000, -1), 0x1); + assert_int_equal(core->rawRead8(core, 0x03000001, -1), 0x1); + assert_int_equal(core->rawRead8(core, 0x03000002, -1), 0); + assert_int_equal(core->rawRead8(core, 0x03000003, -1), 0x31); + assert_int_equal(core->rawRead8(core, 0x03000004, -1), 0x41); + assert_int_equal(core->rawRead8(core, 0x03000005, -1), 0x51); + assert_int_equal(core->rawRead8(core, 0x03000006, -1), 0x62); + assert_int_equal(core->rawRead8(core, 0x03000007, -1), 0x72); + assert_int_equal(core->rawRead8(core, 0x03000008, -1), 0x82); + + core->reset(core); + core->rawWrite8(core, 0x03000000, -1, 0x1); + core->rawWrite8(core, 0x03000002, -1, 0x1); + mCheatRefresh(device, set); + assert_int_equal(core->rawRead8(core, 0x03000000, -1), 0x1); + assert_int_equal(core->rawRead8(core, 0x03000001, -1), 0); + assert_int_equal(core->rawRead8(core, 0x03000002, -1), 0x1); + assert_int_equal(core->rawRead8(core, 0x03000003, -1), 0x31); + assert_int_equal(core->rawRead8(core, 0x03000004, -1), 0x41); + assert_int_equal(core->rawRead8(core, 0x03000005, -1), 0x51); + assert_int_equal(core->rawRead8(core, 0x03000006, -1), 0x62); + assert_int_equal(core->rawRead8(core, 0x03000007, -1), 0x71); + assert_int_equal(core->rawRead8(core, 0x03000008, -1), 0x82); + + core->reset(core); + core->rawWrite8(core, 0x03000001, -1, 0x1); + core->rawWrite8(core, 0x03000002, -1, 0x1); + mCheatRefresh(device, set); + assert_int_equal(core->rawRead8(core, 0x03000000, -1), 0x1); + assert_int_equal(core->rawRead8(core, 0x03000001, -1), 0x1); + assert_int_equal(core->rawRead8(core, 0x03000002, -1), 0x1); + assert_int_equal(core->rawRead8(core, 0x03000003, -1), 0x32); + assert_int_equal(core->rawRead8(core, 0x03000004, -1), 0x41); + assert_int_equal(core->rawRead8(core, 0x03000005, -1), 0x52); + assert_int_equal(core->rawRead8(core, 0x03000006, -1), 0x61); + assert_int_equal(core->rawRead8(core, 0x03000007, -1), 0x71); + assert_int_equal(core->rawRead8(core, 0x03000008, -1), 0x81); + + core->reset(core); + core->rawWrite8(core, 0x03000000, -1, 0x1); + core->rawWrite8(core, 0x03000001, -1, 0x1); + core->rawWrite8(core, 0x03000002, -1, 0x1); + mCheatRefresh(device, set); + assert_int_equal(core->rawRead8(core, 0x03000000, -1), 0x1); + assert_int_equal(core->rawRead8(core, 0x03000001, -1), 0x1); + assert_int_equal(core->rawRead8(core, 0x03000002, -1), 0x1); + assert_int_equal(core->rawRead8(core, 0x03000003, -1), 0x31); + assert_int_equal(core->rawRead8(core, 0x03000004, -1), 0x41); + assert_int_equal(core->rawRead8(core, 0x03000005, -1), 0x51); + assert_int_equal(core->rawRead8(core, 0x03000006, -1), 0x62); + assert_int_equal(core->rawRead8(core, 0x03000007, -1), 0x71); + assert_int_equal(core->rawRead8(core, 0x03000008, -1), 0x82); +} + +M_TEST_SUITE_DEFINE_SETUP_TEARDOWN(GBACheats, + cmocka_unit_test(createSet), + cmocka_unit_test(addRawPARv3), + cmocka_unit_test(doPARv3Assign), + cmocka_unit_test(doPARv3If1), + cmocka_unit_test(doPARv3If1x1), + cmocka_unit_test(doPARv3If2), + cmocka_unit_test(doPARv3If2x2), + cmocka_unit_test(doPARv3If2Contain1), + cmocka_unit_test(doPARv3IfX), + cmocka_unit_test(doPARv3IfXxX), + cmocka_unit_test(doPARv3IfXElse), + cmocka_unit_test(doPARv3IfXElsexX), + cmocka_unit_test(doPARv3IfXElsexXElse), + cmocka_unit_test(doPARv3IfXContain1), + cmocka_unit_test(doPARv3IfXContain1Else), + cmocka_unit_test(doPARv3IfXElseContain1), + cmocka_unit_test(doPARv3IfXContain1ElseContain1))