all repos — mgba @ 3b1d3292dd69864591fec6517eb4fa9cbc941852

mGBA Game Boy Advance Emulator

GBA Cheats: Fix holding onto pointers that may get invalidated
Jeffrey Pfau jeffrey@endrift.com
Tue, 20 Sep 2016 12:09:28 -0700
commit

3b1d3292dd69864591fec6517eb4fa9cbc941852

parent

1cb054ec67ea7b1e7e9162c1e74bd4ab254efb74

M CHANGESCHANGES

@@ -2,6 +2,7 @@ 0.6.0: (Future)

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
M src/gba/cheats.csrc/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.hsrc/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.csrc/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.csrc/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.csrc/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; }