all repos — mgba @ 0cf138775b2169241c54447a75e6032c0d4684bb

mGBA Game Boy Advance Emulator

GBA Cheats: Allow unlimited ROM patch-type codes per set
Vicki Pfau vi@endrift.com
Fri, 18 Dec 2020 02:39:28 -0800
commit

0cf138775b2169241c54447a75e6032c0d4684bb

parent

4ecf64a41c15851ba8ffc60adcdd2ecf41316948

M CHANGESCHANGES

@@ -96,6 +96,7 @@ - GB: Add support for sleep and shutdown callbacks

- GB I/O: Implement preliminary support for PCM12/PCM34 (closes mgba.io/i/1468) - GBA: Allow pausing event loop while CPU is blocked - GBA BIOS: Division by zero should emit a FATAL error + - GBA Cheats: Allow unlimited ROM patch-type codes per set - GBA Video: Convert OpenGL VRAM texture to integer - GBA Video: Skip attempting to render offscreen sprites in OpenGL - GBA Video: New GL palette approach, no more batch splitting on palette edits
M include/mgba/internal/gba/cheats.hinclude/mgba/internal/gba/cheats.h

@@ -12,8 +12,8 @@ CXX_GUARD_START

#include <mgba/internal/arm/arm.h> #include <mgba/core/cheats.h> +#include <mgba-util/vector.h> -#define MAX_ROM_PATCHES 10 #define COMPLETE ((size_t) -1) enum GBACheatType {

@@ -134,17 +134,20 @@ size_t refs;

size_t reentries; }; +struct GBACheatPatch { + uint32_t address; + int16_t newValue; + int16_t oldValue; + bool applied; +}; + +DECLARE_VECTOR(GBACheatPatchList, struct GBACheatPatch); + struct GBACheatSet { struct mCheatSet d; struct GBACheatHook* hook; - struct GBACheatPatch { - uint32_t address; - int16_t newValue; - int16_t oldValue; - bool applied; - bool exists; - } romPatches[MAX_ROM_PATCHES]; + struct GBACheatPatchList romPatches; size_t incompleteCheat; struct GBACheatPatch* incompletePatch;
M src/gba/cheats.csrc/gba/cheats.c

@@ -13,6 +13,8 @@ #include "gba/cheats/parv3.h"

#define MAX_LINE_LENGTH 128 +DEFINE_VECTOR(GBACheatPatchList, struct GBACheatPatch); + static void _addBreakpoint(struct mCheatDevice* device, struct GBACheatSet* cheats) { if (!device->p || !cheats->hook) { return;

@@ -39,13 +41,14 @@ static void _patchROM(struct mCheatDevice* device, struct GBACheatSet* cheats) {

if (!device->p) { return; } - int i; - for (i = 0; i < MAX_ROM_PATCHES; ++i) { - if (!cheats->romPatches[i].exists || cheats->romPatches[i].applied) { + size_t i; + for (i = 0; i < GBACheatPatchListSize(&cheats->romPatches); ++i) { + struct GBACheatPatch* patch = GBACheatPatchListGetPointer(&cheats->romPatches, i); + if (patch->applied) { continue; } - GBAPatch16(device->p->cpu, cheats->romPatches[i].address, cheats->romPatches[i].newValue, &cheats->romPatches[i].oldValue); - cheats->romPatches[i].applied = true; + GBAPatch16(device->p->cpu, patch->address, patch->newValue, &patch->oldValue); + patch->applied = true; } }

@@ -53,13 +56,14 @@ static void _unpatchROM(struct mCheatDevice* device, struct GBACheatSet* cheats) {

if (!device->p) { return; } - int i; - for (i = 0; i < MAX_ROM_PATCHES; ++i) { - if (!cheats->romPatches[i].exists || !cheats->romPatches[i].applied) { + size_t i; + for (i = 0; i < GBACheatPatchListSize(&cheats->romPatches); ++i) { + struct GBACheatPatch* patch = GBACheatPatchListGetPointer(&cheats->romPatches, i); + if (!patch->applied) { continue; } - GBAPatch16(device->p->cpu, cheats->romPatches[i].address, cheats->romPatches[i].oldValue, 0); - cheats->romPatches[i].applied = false; + GBAPatch16(device->p->cpu, patch->address, patch->oldValue, NULL); + patch->applied = false; } }

@@ -97,10 +101,7 @@ set->d.dumpDirectives = GBACheatDumpDirectives;

set->d.refresh = GBACheatRefresh; - int i; - for (i = 0; i < MAX_ROM_PATCHES; ++i) { - set->romPatches[i].exists = false; - } + GBACheatPatchListInit(&set->romPatches, 4); return &set->d; }

@@ -119,6 +120,7 @@ if (gbaset->hook->refs == 0) {

free(gbaset->hook); } } + GBACheatPatchListDeinit(&gbaset->romPatches); } static void GBACheatAddSet(struct mCheatSet* cheats, struct mCheatDevice* device) {
M src/gba/cheats/gameshark.csrc/gba/cheats/gameshark.c

@@ -93,7 +93,7 @@

bool GBACheatAddGameSharkRaw(struct GBACheatSet* cheats, uint32_t op1, uint32_t op2) { enum GBAGameSharkType type = op1 >> 28; struct mCheat* cheat = 0; - int romPatch = 0; + struct GBACheatPatch* romPatch; if (cheats->incompleteCheat != COMPLETE) { struct mCheat* incompleteCheat = mCheatListGetPointer(&cheats->d.list, cheats->incompleteCheat);

@@ -149,16 +149,10 @@ cheat->address = op2;

cheats->incompleteCheat = mCheatListIndex(&cheats->d.list, cheat); break; case GSA_PATCH: - while (cheats->romPatches[romPatch].exists) { - ++romPatch; - if (romPatch >= MAX_ROM_PATCHES) { - break; - } - } - cheats->romPatches[romPatch].address = BASE_CART0 | ((op1 & 0xFFFFFF) << 1); - cheats->romPatches[romPatch].newValue = op2; - cheats->romPatches[romPatch].applied = false; - cheats->romPatches[romPatch].exists = true; + romPatch = GBACheatPatchListAppend(&cheats->romPatches); + romPatch->address = BASE_CART0 | ((op1 & 0xFFFFFF) << 1); + romPatch->newValue = op2; + romPatch->applied = false; return true; case GSA_BUTTON: switch (op1 & 0x00F00000) {
M src/gba/cheats/parv3.csrc/gba/cheats/parv3.c

@@ -230,16 +230,10 @@ cheats->incompleteCheat = mCheatListIndex(&cheats->d.list, cheat);

break; } if (romPatch >= 0) { - while (cheats->romPatches[romPatch].exists) { - ++romPatch; - if (romPatch >= MAX_ROM_PATCHES) { - break; - } - } - cheats->romPatches[romPatch].address = BASE_CART0 | ((op2 & 0xFFFFFF) << 1); - cheats->romPatches[romPatch].applied = false; - cheats->romPatches[romPatch].exists = true; - cheats->incompletePatch = &cheats->romPatches[romPatch]; + struct GBACheatPatch* patch = GBACheatPatchListAppend(&cheats->romPatches); + patch->address = BASE_CART0 | ((op2 & 0xFFFFFF) << 1); + patch->applied = false; + cheats->incompletePatch = patch; } return true; }