GBA Cheats: Fix holding onto pointers that may get invalidated
Jeffrey Pfau jeffrey@endrift.com
Tue, 20 Sep 2016 12:09:28 -0700
6 files changed,
42 insertions(+),
35 deletions(-)
M
src/gba/cheats.c
→
src/gba/cheats.c
@@ -75,9 +75,9 @@ static struct mCheatSet* GBACheatSetCreate(struct mCheatDevice* device, const char* name) {
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;
M
src/gba/cheats.h
→
src/gba/cheats.h
@@ -12,6 +12,7 @@ #include "arm/arm.h"
#include "core/cheats.h" #define MAX_ROM_PATCHES 4 +#define COMPLETE ((size_t) -1) enum GBACheatType { GBA_CHEAT_AUTODETECT,@@ -143,9 +144,9 @@ bool applied;
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];
M
src/gba/cheats/codebreaker.c
→
src/gba/cheats/codebreaker.c
@@ -197,11 +197,12 @@
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 @@ case CB_FILL:
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);
M
src/gba/cheats/gameshark.c
→
src/gba/cheats/gameshark.c
@@ -91,13 +91,14 @@ bool GBACheatAddGameSharkRaw(struct GBACheatSet* cheats, uint32_t op1, uint32_t op2) {
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 @@ cheat = mCheatListAppend(&cheats->d.list);
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 @@ cheat = mCheatListAppend(&cheats->d.list);
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;
M
src/gba/cheats/parv3.c
→
src/gba/cheats/parv3.c
@@ -53,18 +53,20 @@ return (x & 0xFFFFF) | ((x << 4) & 0x0F000000);
} 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 @@ break;
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 @@ cheats->romPatches[3].exists = true;
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 @@ case PAR3_OTHER_FILL_1:
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 @@ cheats->incompletePatch->newValue = op1;
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; }