diff --git a/CHANGES b/CHANGES index 9db0feba6..9d3a35474 100644 --- a/CHANGES +++ b/CHANGES @@ -3,6 +3,7 @@ Bugfixes: - GBA Video: Force align 256-color tiles - GBA DMA: ROM reads are forced to increment - GB Video: Only trigger STAT write IRQs when screen is on (fixes mgba.io/i/912) + - GBA Cheats: Fix PARv3 slide codes (fixes mgba.io/i/919) 0.6.1: (2017-10-01) Bugfixes: diff --git a/src/gba/cheats/parv3.c b/src/gba/cheats/parv3.c index 4def9171c..37a04a7dc 100644 --- a/src/gba/cheats/parv3.c +++ b/src/gba/cheats/parv3.c @@ -203,7 +203,7 @@ static bool _addPAR3Special(struct GBACheatSet* cheats, uint32_t op2) { case PAR3_OTHER_FILL_4: cheat = mCheatListAppend(&cheats->d.list); cheat->address = _parAddr(op2); - cheat->width = 3; + cheat->width = 4; cheats->incompleteCheat = mCheatListIndex(&cheats->d.list, cheat); break; } @@ -219,7 +219,7 @@ bool GBACheatAddProActionReplayRaw(struct GBACheatSet* cheats, uint32_t op1, uin if (cheats->incompleteCheat != COMPLETE) { struct mCheat* incompleteCheat = mCheatListGetPointer(&cheats->d.list, cheats->incompleteCheat); incompleteCheat->operand = op1 & (0xFFFFFFFFU >> ((4 - incompleteCheat->width) * 8)); - incompleteCheat->addressOffset = op2 >> 24; + incompleteCheat->operandOffset = op2 >> 24; incompleteCheat->repeat = (op2 >> 16) & 0xFF; incompleteCheat->addressOffset = (op2 & 0xFFFF) * incompleteCheat->width; cheats->incompleteCheat = COMPLETE; diff --git a/src/gba/test/cheats.c b/src/gba/test/cheats.c index ddde81f89..cdf1175e6 100644 --- a/src/gba/test/cheats.c +++ b/src/gba/test/cheats.c @@ -75,6 +75,93 @@ M_TEST_DEFINE(doPARv3Assign) { set->deinit(set); } +M_TEST_DEFINE(doPARv3Slide1) { + 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, "00000000 80300000", GBA_CHEAT_PRO_ACTION_REPLAY)); + assert_true(set->addLine(set, "00000001 01020002", 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), 1); + assert_int_equal(core->rawRead8(core, 0x03000001, -1), 0); + assert_int_equal(core->rawRead8(core, 0x03000002, -1), 2); + 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); + + set->deinit(set); +} + +M_TEST_DEFINE(doPARv3Slide2) { + 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, "00000000 82300000", GBA_CHEAT_PRO_ACTION_REPLAY)); + assert_true(set->addLine(set, "00000001 01020002", GBA_CHEAT_PRO_ACTION_REPLAY)); + + core->reset(core); + assert_int_equal(core->rawRead16(core, 0x03000000, -1), 0); + assert_int_equal(core->rawRead16(core, 0x03000002, -1), 0); + assert_int_equal(core->rawRead16(core, 0x03000004, -1), 0); + assert_int_equal(core->rawRead16(core, 0x03000006, -1), 0); + assert_int_equal(core->rawRead16(core, 0x03000008, -1), 0); + assert_int_equal(core->rawRead16(core, 0x0300000A, -1), 0); + + mCheatRefresh(device, set); + assert_int_equal(core->rawRead16(core, 0x03000000, -1), 1); + assert_int_equal(core->rawRead16(core, 0x03000002, -1), 0); + assert_int_equal(core->rawRead16(core, 0x03000004, -1), 2); + assert_int_equal(core->rawRead16(core, 0x03000006, -1), 0); + assert_int_equal(core->rawRead16(core, 0x03000008, -1), 0); + assert_int_equal(core->rawRead16(core, 0x0300000A, -1), 0); + + set->deinit(set); +} + +M_TEST_DEFINE(doPARv3Slide4) { + 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, "00000000 84300000", GBA_CHEAT_PRO_ACTION_REPLAY)); + assert_true(set->addLine(set, "00000001 01020002", GBA_CHEAT_PRO_ACTION_REPLAY)); + + core->reset(core); + assert_int_equal(core->rawRead32(core, 0x03000000, -1), 0); + assert_int_equal(core->rawRead32(core, 0x03000004, -1), 0); + assert_int_equal(core->rawRead32(core, 0x03000008, -1), 0); + assert_int_equal(core->rawRead32(core, 0x0300000C, -1), 0); + assert_int_equal(core->rawRead32(core, 0x03000010, -1), 0); + assert_int_equal(core->rawRead32(core, 0x03000014, -1), 0); + + mCheatRefresh(device, set); + assert_int_equal(core->rawRead16(core, 0x03000000, -1), 1); + assert_int_equal(core->rawRead16(core, 0x03000004, -1), 0); + assert_int_equal(core->rawRead16(core, 0x03000008, -1), 2); + assert_int_equal(core->rawRead16(core, 0x0300000C, -1), 0); + assert_int_equal(core->rawRead16(core, 0x03000010, -1), 0); + assert_int_equal(core->rawRead16(core, 0x03000014, -1), 0); + + set->deinit(set); +} + M_TEST_DEFINE(doPARv3If1) { struct mCore* core = *state; struct mCheatDevice* device = core->cheatDevice(core); @@ -927,6 +1014,9 @@ M_TEST_SUITE_DEFINE_SETUP_TEARDOWN(GBACheats, cmocka_unit_test(createSet), cmocka_unit_test(addRawPARv3), cmocka_unit_test(doPARv3Assign), + cmocka_unit_test(doPARv3Slide1), + cmocka_unit_test(doPARv3Slide2), + cmocka_unit_test(doPARv3Slide4), cmocka_unit_test(doPARv3If1), cmocka_unit_test(doPARv3If1x1), cmocka_unit_test(doPARv3If2),