GBA Cheats: Allow unlimited ROM patch-type codes per set
Vicki Pfau vi@endrift.com
Fri, 18 Dec 2020 02:39:28 -0800
5 files changed,
37 insertions(+),
43 deletions(-)
M
CHANGES
→
CHANGES
@@ -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.h
→
include/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.c
→
src/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.c
→
src/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.c
→
src/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; }