mirror of https://github.com/mgba-emu/mgba.git
GBA Cheats: Implement "never" type codes (closes #915)
This commit is contained in:
parent
7d71396968
commit
64d8dd1b69
1
CHANGES
1
CHANGES
|
@ -48,6 +48,7 @@ Misc:
|
|||
- GB Video: Add default SGB border
|
||||
- GBA: Automatically skip BIOS if ROM has invalid logo
|
||||
- GBA: Refine multiboot detection (fixes mgba.io/i/2192)
|
||||
- GBA Cheats: Implement "never" type codes (closes mgba.io/i/915)
|
||||
- GBA DMA: Enhanced logging (closes mgba.io/i/2454)
|
||||
- GBA Video: Implement layer placement for OpenGL renderer (fixes mgba.io/i/1962)
|
||||
- mGUI: Add margin to right-aligned menu text (fixes mgba.io/i/871)
|
||||
|
|
|
@ -31,6 +31,7 @@ enum mCheatType {
|
|||
CHEAT_IF_LAND,
|
||||
CHEAT_IF_NAND,
|
||||
CHEAT_IF_BUTTON,
|
||||
CHEAT_NEVER,
|
||||
};
|
||||
|
||||
struct mCheat {
|
||||
|
|
|
@ -741,6 +741,12 @@ void mCheatRefresh(struct mCheatDevice* device, struct mCheatSet* cheats) {
|
|||
negativeConditionRemaining = cheat->negativeRepeat;
|
||||
operationsRemaining = 1;
|
||||
break;
|
||||
case CHEAT_NEVER:
|
||||
condition = false;
|
||||
conditionRemaining = cheat->repeat;
|
||||
negativeConditionRemaining = cheat->negativeRepeat;
|
||||
operationsRemaining = 1;
|
||||
break;
|
||||
}
|
||||
|
||||
if (performAssignment) {
|
||||
|
|
|
@ -72,12 +72,9 @@ static void _parElseBlock(struct GBACheatSet* cheats) {
|
|||
static bool _addPAR3Cond(struct GBACheatSet* cheats, uint32_t op1, uint32_t op2) {
|
||||
enum GBAActionReplay3Condition condition = op1 & PAR3_COND;
|
||||
int width = 1 << ((op1 & PAR3_WIDTH) >> PAR3_WIDTH_BASE);
|
||||
if (width > 4) {
|
||||
// TODO: Always false conditions
|
||||
return false;
|
||||
}
|
||||
if ((op1 & PAR3_ACTION) == PAR3_ACTION_DISABLE) {
|
||||
// TODO: Codes that disable
|
||||
mLOG(CHEATS, STUB, "Disable-type PARv3 codes not yet supported");
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -136,6 +133,11 @@ static bool _addPAR3Cond(struct GBACheatSet* cheats, uint32_t op1, uint32_t op2)
|
|||
cheat->type = CHEAT_IF_AND;
|
||||
break;
|
||||
}
|
||||
|
||||
if (width > 4) {
|
||||
cheat->width = 0;
|
||||
cheat->type = CHEAT_NEVER;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
|
@ -1051,6 +1051,133 @@ M_TEST_DEFINE(doPARv3IfButton) {
|
|||
mCheatSetDeinit(set);
|
||||
}
|
||||
|
||||
M_TEST_DEFINE(doPARv3Never1) {
|
||||
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, "0E300000 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), 0x11);
|
||||
|
||||
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);
|
||||
|
||||
mCheatSetDeinit(set);
|
||||
}
|
||||
|
||||
M_TEST_DEFINE(doPARv3Never2) {
|
||||
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, "4E300000 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), 0x11);
|
||||
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), 0x21);
|
||||
|
||||
mCheatSetDeinit(set);
|
||||
}
|
||||
|
||||
M_TEST_DEFINE(doPARv3NeverX) {
|
||||
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, "8E300000 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), 0x11);
|
||||
|
||||
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);
|
||||
mCheatSetDeinit(set);
|
||||
}
|
||||
|
||||
M_TEST_DEFINE(doPARv3NeverXElse) {
|
||||
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, "8E300000 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), 0x11);
|
||||
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), 0x22);
|
||||
mCheatSetDeinit(set);
|
||||
}
|
||||
|
||||
M_TEST_SUITE_DEFINE(GBACheats,
|
||||
cmocka_unit_test_setup_teardown(createSet, cheatsSetup, cheatsTeardown),
|
||||
cmocka_unit_test_setup_teardown(addRawPARv3, cheatsSetup, cheatsTeardown),
|
||||
|
@ -1072,4 +1199,8 @@ M_TEST_SUITE_DEFINE(GBACheats,
|
|||
cmocka_unit_test_setup_teardown(doPARv3IfXContain1Else, cheatsSetup, cheatsTeardown),
|
||||
cmocka_unit_test_setup_teardown(doPARv3IfXElseContain1, cheatsSetup, cheatsTeardown),
|
||||
cmocka_unit_test_setup_teardown(doPARv3IfXContain1ElseContain1, cheatsSetup, cheatsTeardown),
|
||||
cmocka_unit_test_setup_teardown(doPARv3IfButton, cheatsSetup, cheatsTeardown))
|
||||
cmocka_unit_test_setup_teardown(doPARv3IfButton, cheatsSetup, cheatsTeardown),
|
||||
cmocka_unit_test_setup_teardown(doPARv3Never1, cheatsSetup, cheatsTeardown),
|
||||
cmocka_unit_test_setup_teardown(doPARv3Never2, cheatsSetup, cheatsTeardown),
|
||||
cmocka_unit_test_setup_teardown(doPARv3NeverX, cheatsSetup, cheatsTeardown),
|
||||
cmocka_unit_test_setup_teardown(doPARv3NeverXElse, cheatsSetup, cheatsTeardown))
|
||||
|
|
Loading…
Reference in New Issue