Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions CHANGES
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ Features:
- New option to lock the maximum frame size
- Memory access and information logging
- Cheats: Add support for CodeBreaker 5XXXXXXX "Super" codes
- Cheats: Add support for additional, undocumented GameShark IF code types
- 3DS: Add faster "loose" sync mode, default enabled
- Vita: Allow using rear touch pads as L2/L3/R2/R3
- Scripting: New `input` API for getting raw keyboard/mouse/controller state
Expand Down
2 changes: 2 additions & 0 deletions include/mgba/core/cheats.h
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,8 @@ enum mCheatType {
CHEAT_IF_NE,
CHEAT_IF_LT,
CHEAT_IF_GT,
CHEAT_IF_LE,
CHEAT_IF_GE,
CHEAT_IF_ULT,
CHEAT_IF_UGT,
CHEAT_IF_AND,
Expand Down
11 changes: 9 additions & 2 deletions include/mgba/internal/gba/cheats.h
Original file line number Diff line number Diff line change
Expand Up @@ -50,11 +50,18 @@ enum GBAGameSharkType {
GSA_ASSIGN_LIST = 0x3,
GSA_PATCH = 0x6,
GSA_BUTTON = 0x8,
GSA_IF_EQ = 0xD,
GSA_IF_EQ_RANGE = 0xE,
GSA_IF = 0xD,
GSA_IF_RANGE = 0xE,
GSA_HOOK = 0xF
};

enum GBAGameSharkIfType {
GSA_IF_EQ = 0,
GSA_IF_NE = 1,
GSA_IF_LE = 2,
GSA_IF_GE = 3,
};

enum GBAActionReplay3Condition {
PAR3_COND_OTHER = 0x00000000,
PAR3_COND_EQ = 0x08000000,
Expand Down
12 changes: 12 additions & 0 deletions src/core/cheats.c
Original file line number Diff line number Diff line change
Expand Up @@ -713,6 +713,18 @@ void mCheatRefresh(struct mCheatDevice* device, struct mCheatSet* cheats) {
negativeConditionRemaining = cheat->negativeRepeat;
operationsRemaining = 1;
break;
case CHEAT_IF_LE:
condition = _readMem(device->p, address, cheat->width) <= operand;
conditionRemaining = cheat->repeat;
negativeConditionRemaining = cheat->negativeRepeat;
operationsRemaining = 1;
break;
case CHEAT_IF_GE:
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;
Expand Down
41 changes: 34 additions & 7 deletions src/gba/cheats/gameshark.c
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,17 @@ static const uint8_t _gsa1T2[256] = {
};

// http://en.wikipedia.org/wiki/Tiny_Encryption_Algorithm
void GBACheatEncryptGameShark(uint32_t* op1, uint32_t* op2, const uint32_t* seeds) {
uint32_t sum = 0;
int i;
for (i = 0; i < 32; ++i) {
sum += 0x9E3779B9;
*op1 += ((*op2 << 4) + seeds[0]) ^ (*op2 + sum) ^ ((*op2 >> 5) + seeds[1]);
*op2 += ((*op1 << 4) + seeds[2]) ^ (*op1 + sum) ^ ((*op1 >> 5) + seeds[3]);
}
sum += 0xC6EF3720;
}

void GBACheatDecryptGameShark(uint32_t* op1, uint32_t* op2, const uint32_t* seeds) {
uint32_t sum = 0xC6EF3720;
int i;
Expand Down Expand Up @@ -183,17 +194,33 @@ bool GBACheatAddGameSharkRaw(struct GBACheatSet* cheats, uint32_t op1, uint32_t
return false;
}
break;
case GSA_IF_EQ:
case GSA_IF:
if (op1 == 0xDEADFACE) {
GBACheatReseedGameShark(cheats->gsaSeeds, op2, _gsa1T1, _gsa1T2);
return true;
}
cheat = mCheatListAppend(&cheats->d.list);
cheat->type = CHEAT_IF_EQ;
switch (op2 >> 20) {
case GSA_IF_EQ:
cheat->type = CHEAT_IF_EQ;
break;
case GSA_IF_NE:
cheat->type = CHEAT_IF_NE;
break;
case GSA_IF_LE:
cheat->type = CHEAT_IF_LE;
break;
case GSA_IF_GE:
cheat->type = CHEAT_IF_GE;
break;
}
cheat->width = 2;
cheat->repeat = 1;
cheat->negativeRepeat = 0;
cheat->address = op1 & 0x0FFFFFFF;
break;
case GSA_IF_EQ_RANGE:
cheat->operand = op2 & 0xFFFF;
return true;
case GSA_IF_RANGE:
cheat = mCheatListAppend(&cheats->d.list);
cheat->type = CHEAT_IF_EQ;
cheat->width = 2;
Expand Down Expand Up @@ -291,14 +318,14 @@ int GBACheatGameSharkProbability(uint32_t op1, uint32_t op2) {
case GSA_BUTTON:
probability += 0x10;
break;
case GSA_IF_EQ:
case GSA_IF:
probability += 0x20;
if (op2 & 0xFFFF0000) {
if (op2 & 0xFFCF0000) {
probability -= 0x10;
}
probability += GBACheatAddressIsReal(address);
break;
case GSA_IF_EQ_RANGE:
case GSA_IF_RANGE:
probability += 0x20;
probability += GBACheatAddressIsReal(op2);
if (op1 & 0x0F000000) {
Expand Down
1 change: 1 addition & 0 deletions src/gba/cheats/gameshark.h
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ enum GBACheatGameSharkVersion {
};

struct GBACheatSet;
void GBACheatEncryptGameShark(uint32_t* op1, uint32_t* op2, const uint32_t* seeds);
void GBACheatDecryptGameShark(uint32_t* op1, uint32_t* op2, const uint32_t* seeds);
void GBACheatReseedGameShark(uint32_t* seeds, uint16_t params, const uint8_t* t1, const uint8_t* t2);
void GBACheatSetGameSharkVersion(struct GBACheatSet* cheats, enum GBACheatGameSharkVersion version);
Expand Down