GBA Cheats: Fix holding onto pointers that may get invalidated

This commit is contained in:
Jeffrey Pfau 2016-09-20 12:09:28 -07:00
parent 1cb054ec67
commit 3b1d3292dd
6 changed files with 42 additions and 35 deletions

View File

@ -2,6 +2,7 @@
Bugfixes:
- GB MBC: Fix MBC7 when size is incorrectly specified
- GB Video: Setting LYC=LY during mode 2 should trigger an IRQ
- GBA Cheats: Fix holding onto pointers that may get invalidated
Misc:
- All: Only update version info if needed

View File

@ -75,9 +75,9 @@ static struct mCheatSet* GBACheatSetCreate(struct mCheatDevice* device, const ch
UNUSED(device);
struct GBACheatSet* set = malloc(sizeof(*set));
mCheatSetInit(&set->d, name);
set->incompleteCheat = 0;
set->incompleteCheat = -1;
set->incompletePatch = 0;
set->currentBlock = 0;
set->currentBlock = -1;
set->gsaVersion = 0;
set->cbRngState = 0;
set->cbMaster = 0;

View File

@ -12,6 +12,7 @@
#include "core/cheats.h"
#define MAX_ROM_PATCHES 4
#define COMPLETE ((size_t) -1)
enum GBACheatType {
GBA_CHEAT_AUTODETECT,
@ -143,9 +144,9 @@ struct GBACheatSet {
bool exists;
} romPatches[MAX_ROM_PATCHES];
struct mCheat* incompleteCheat;
size_t incompleteCheat;
struct GBACheatPatch* incompletePatch;
struct mCheat* currentBlock;
size_t currentBlock;
int gsaVersion;
uint32_t gsaSeeds[4];

View File

@ -197,11 +197,12 @@ bool GBACheatAddCodeBreaker(struct GBACheatSet* cheats, uint32_t op1, uint16_t o
enum GBACodeBreakerType type = op1 >> 28;
struct mCheat* cheat = NULL;
if (cheats->incompleteCheat) {
cheats->incompleteCheat->repeat = op1 & 0xFFFF;
cheats->incompleteCheat->addressOffset = op2;
cheats->incompleteCheat->operandOffset = 0;
cheats->incompleteCheat = 0;
if (cheats->incompleteCheat != COMPLETE) {
struct mCheat* incompleteCheat = mCheatListGetPointer(&cheats->d.list, cheats->incompleteCheat);
incompleteCheat->repeat = op1 & 0xFFFF;
incompleteCheat->addressOffset = op2;
incompleteCheat->operandOffset = 0;
cheats->incompleteCheat = COMPLETE;
return true;
}
@ -233,7 +234,7 @@ bool GBACheatAddCodeBreaker(struct GBACheatSet* cheats, uint32_t op1, uint16_t o
cheat = mCheatListAppend(&cheats->d.list);
cheat->type = CHEAT_ASSIGN;
cheat->width = 2;
cheats->incompleteCheat = cheat;
cheats->incompleteCheat = mCheatListIndex(&cheats->d.list, cheat);
break;
case CB_FILL_8:
mLOG(CHEATS, STUB, "CodeBreaker code %08X %04X not supported", op1, op2);

View File

@ -91,13 +91,14 @@ bool GBACheatAddGameSharkRaw(struct GBACheatSet* cheats, uint32_t op1, uint32_t
enum GBAGameSharkType type = op1 >> 28;
struct mCheat* cheat = 0;
if (cheats->incompleteCheat) {
if (cheats->incompleteCheat != COMPLETE) {
struct mCheat* incompleteCheat = mCheatListGetPointer(&cheats->d.list, cheats->incompleteCheat);
if (cheats->remainingAddresses > 0) {
cheat = mCheatListAppend(&cheats->d.list);
cheat->type = CHEAT_ASSIGN;
cheat->width = 4;
cheat->address = op1;
cheat->operand = cheats->incompleteCheat->operand;
cheat->operand = incompleteCheat->operand;
cheat->repeat = 1;
--cheats->remainingAddresses;
}
@ -106,12 +107,12 @@ bool GBACheatAddGameSharkRaw(struct GBACheatSet* cheats, uint32_t op1, uint32_t
cheat->type = CHEAT_ASSIGN;
cheat->width = 4;
cheat->address = op2;
cheat->operand = cheats->incompleteCheat->operand;
cheat->operand = incompleteCheat->operand;
cheat->repeat = 1;
--cheats->remainingAddresses;
}
if (cheats->remainingAddresses == 0) {
cheats->incompleteCheat = 0;
cheats->incompleteCheat = COMPLETE;
}
return true;
}
@ -141,7 +142,7 @@ bool GBACheatAddGameSharkRaw(struct GBACheatSet* cheats, uint32_t op1, uint32_t
cheat->type = CHEAT_ASSIGN;
cheat->width = 4;
cheat->address = op2;
cheats->incompleteCheat = cheat;
cheats->incompleteCheat = mCheatListIndex(&cheats->d.list, cheat);
break;
case GSA_PATCH:
cheats->romPatches[0].address = (op1 & 0xFFFFFF) << 1;

View File

@ -53,18 +53,20 @@ static uint32_t _parAddr(uint32_t x) {
}
static void _parEndBlock(struct GBACheatSet* cheats) {
size_t size = mCheatListSize(&cheats->d.list) - mCheatListIndex(&cheats->d.list, cheats->currentBlock);
if (cheats->currentBlock->repeat) {
cheats->currentBlock->negativeRepeat = size - cheats->currentBlock->repeat;
size_t size = mCheatListSize(&cheats->d.list) - cheats->currentBlock;
struct mCheat* currentBlock = mCheatListGetPointer(&cheats->d.list, cheats->currentBlock);
if (currentBlock->repeat) {
currentBlock->negativeRepeat = size - currentBlock->repeat;
} else {
cheats->currentBlock->repeat = size;
currentBlock->repeat = size;
}
cheats->currentBlock = 0;
cheats->currentBlock = COMPLETE;
}
static void _parElseBlock(struct GBACheatSet* cheats) {
size_t size = mCheatListSize(&cheats->d.list) - mCheatListIndex(&cheats->d.list, cheats->currentBlock);
cheats->currentBlock->repeat = size;
size_t size = mCheatListSize(&cheats->d.list) - cheats->currentBlock;
struct mCheat* currentBlock = mCheatListGetPointer(&cheats->d.list, cheats->currentBlock);
currentBlock->repeat = size;
}
static bool _addPAR3Cond(struct GBACheatSet* cheats, uint32_t op1, uint32_t op2) {
@ -98,10 +100,10 @@ static bool _addPAR3Cond(struct GBACheatSet* cheats, uint32_t op1, uint32_t op2)
case PAR3_ACTION_BLOCK:
cheat->repeat = 0;
cheat->negativeRepeat = 0;
if (cheats->currentBlock) {
if (cheats->currentBlock != COMPLETE) {
_parEndBlock(cheats);
}
cheats->currentBlock = cheat;
cheats->currentBlock = mCheatListIndex(&cheats->d.list, cheat);
break;
}
@ -175,13 +177,13 @@ static bool _addPAR3Special(struct GBACheatSet* cheats, uint32_t op2) {
cheats->incompletePatch = &cheats->romPatches[3];
break;
case PAR3_OTHER_ENDIF:
if (cheats->currentBlock) {
if (cheats->currentBlock != COMPLETE) {
_parEndBlock(cheats);
return true;
}
return false;
case PAR3_OTHER_ELSE:
if (cheats->currentBlock) {
if (cheats->currentBlock != COMPLETE) {
_parElseBlock(cheats);
return true;
}
@ -190,19 +192,19 @@ static bool _addPAR3Special(struct GBACheatSet* cheats, uint32_t op2) {
cheat = mCheatListAppend(&cheats->d.list);
cheat->address = _parAddr(op2);
cheat->width = 1;
cheats->incompleteCheat = cheat;
cheats->incompleteCheat = mCheatListIndex(&cheats->d.list, cheat);
break;
case PAR3_OTHER_FILL_2:
cheat = mCheatListAppend(&cheats->d.list);
cheat->address = _parAddr(op2);
cheat->width = 2;
cheats->incompleteCheat = cheat;
cheats->incompleteCheat = mCheatListIndex(&cheats->d.list, cheat);
break;
case PAR3_OTHER_FILL_4:
cheat = mCheatListAppend(&cheats->d.list);
cheat->address = _parAddr(op2);
cheat->width = 3;
cheats->incompleteCheat = cheat;
cheats->incompleteCheat = mCheatListIndex(&cheats->d.list, cheat);
break;
}
return true;
@ -214,12 +216,13 @@ bool GBACheatAddProActionReplayRaw(struct GBACheatSet* cheats, uint32_t op1, uin
cheats->incompletePatch = 0;
return true;
}
if (cheats->incompleteCheat) {
cheats->incompleteCheat->operand = op1 & (0xFFFFFFFFU >> ((4 - cheats->incompleteCheat->width) * 8));
cheats->incompleteCheat->addressOffset = op2 >> 24;
cheats->incompleteCheat->repeat = (op2 >> 16) & 0xFF;
cheats->incompleteCheat->addressOffset = (op2 & 0xFFFF) * cheats->incompleteCheat->width;
cheats->incompleteCheat = 0;
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->repeat = (op2 >> 16) & 0xFF;
incompleteCheat->addressOffset = (op2 & 0xFFFF) * incompleteCheat->width;
cheats->incompleteCheat = COMPLETE;
return true;
}