GBA Cheats: Allow unlimited ROM patch-type codes per set

This commit is contained in:
Vicki Pfau 2020-12-18 02:39:28 -08:00
parent 4ecf64a41c
commit 0cf138775b
5 changed files with 37 additions and 43 deletions

View File

@ -96,6 +96,7 @@ Misc:
- GB I/O: Implement preliminary support for PCM12/PCM34 (closes mgba.io/i/1468) - GB I/O: Implement preliminary support for PCM12/PCM34 (closes mgba.io/i/1468)
- GBA: Allow pausing event loop while CPU is blocked - GBA: Allow pausing event loop while CPU is blocked
- GBA BIOS: Division by zero should emit a FATAL error - 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: Convert OpenGL VRAM texture to integer
- GBA Video: Skip attempting to render offscreen sprites in OpenGL - GBA Video: Skip attempting to render offscreen sprites in OpenGL
- GBA Video: New GL palette approach, no more batch splitting on palette edits - GBA Video: New GL palette approach, no more batch splitting on palette edits

View File

@ -12,8 +12,8 @@ CXX_GUARD_START
#include <mgba/internal/arm/arm.h> #include <mgba/internal/arm/arm.h>
#include <mgba/core/cheats.h> #include <mgba/core/cheats.h>
#include <mgba-util/vector.h>
#define MAX_ROM_PATCHES 10
#define COMPLETE ((size_t) -1) #define COMPLETE ((size_t) -1)
enum GBACheatType { enum GBACheatType {
@ -134,17 +134,20 @@ struct GBACheatHook {
size_t reentries; size_t reentries;
}; };
struct GBACheatPatch {
uint32_t address;
int16_t newValue;
int16_t oldValue;
bool applied;
};
DECLARE_VECTOR(GBACheatPatchList, struct GBACheatPatch);
struct GBACheatSet { struct GBACheatSet {
struct mCheatSet d; struct mCheatSet d;
struct GBACheatHook* hook; struct GBACheatHook* hook;
struct GBACheatPatch { struct GBACheatPatchList romPatches;
uint32_t address;
int16_t newValue;
int16_t oldValue;
bool applied;
bool exists;
} romPatches[MAX_ROM_PATCHES];
size_t incompleteCheat; size_t incompleteCheat;
struct GBACheatPatch* incompletePatch; struct GBACheatPatch* incompletePatch;

View File

@ -13,6 +13,8 @@
#define MAX_LINE_LENGTH 128 #define MAX_LINE_LENGTH 128
DEFINE_VECTOR(GBACheatPatchList, struct GBACheatPatch);
static void _addBreakpoint(struct mCheatDevice* device, struct GBACheatSet* cheats) { static void _addBreakpoint(struct mCheatDevice* device, struct GBACheatSet* cheats) {
if (!device->p || !cheats->hook) { if (!device->p || !cheats->hook) {
return; return;
@ -39,13 +41,14 @@ static void _patchROM(struct mCheatDevice* device, struct GBACheatSet* cheats) {
if (!device->p) { if (!device->p) {
return; return;
} }
int i; size_t i;
for (i = 0; i < MAX_ROM_PATCHES; ++i) { for (i = 0; i < GBACheatPatchListSize(&cheats->romPatches); ++i) {
if (!cheats->romPatches[i].exists || cheats->romPatches[i].applied) { struct GBACheatPatch* patch = GBACheatPatchListGetPointer(&cheats->romPatches, i);
if (patch->applied) {
continue; continue;
} }
GBAPatch16(device->p->cpu, cheats->romPatches[i].address, cheats->romPatches[i].newValue, &cheats->romPatches[i].oldValue); GBAPatch16(device->p->cpu, patch->address, patch->newValue, &patch->oldValue);
cheats->romPatches[i].applied = true; patch->applied = true;
} }
} }
@ -53,13 +56,14 @@ static void _unpatchROM(struct mCheatDevice* device, struct GBACheatSet* cheats)
if (!device->p) { if (!device->p) {
return; return;
} }
int i; size_t i;
for (i = 0; i < MAX_ROM_PATCHES; ++i) { for (i = 0; i < GBACheatPatchListSize(&cheats->romPatches); ++i) {
if (!cheats->romPatches[i].exists || !cheats->romPatches[i].applied) { struct GBACheatPatch* patch = GBACheatPatchListGetPointer(&cheats->romPatches, i);
if (!patch->applied) {
continue; continue;
} }
GBAPatch16(device->p->cpu, cheats->romPatches[i].address, cheats->romPatches[i].oldValue, 0); GBAPatch16(device->p->cpu, patch->address, patch->oldValue, NULL);
cheats->romPatches[i].applied = false; patch->applied = false;
} }
} }
@ -97,10 +101,7 @@ static struct mCheatSet* GBACheatSetCreate(struct mCheatDevice* device, const ch
set->d.refresh = GBACheatRefresh; set->d.refresh = GBACheatRefresh;
int i; GBACheatPatchListInit(&set->romPatches, 4);
for (i = 0; i < MAX_ROM_PATCHES; ++i) {
set->romPatches[i].exists = false;
}
return &set->d; return &set->d;
} }
@ -119,6 +120,7 @@ static void GBACheatSetDeinit(struct mCheatSet* set) {
free(gbaset->hook); free(gbaset->hook);
} }
} }
GBACheatPatchListDeinit(&gbaset->romPatches);
} }
static void GBACheatAddSet(struct mCheatSet* cheats, struct mCheatDevice* device) { static void GBACheatAddSet(struct mCheatSet* cheats, struct mCheatDevice* device) {

View File

@ -93,7 +93,7 @@ void GBACheatSetGameSharkVersion(struct GBACheatSet* cheats, enum GBACheatGameSh
bool GBACheatAddGameSharkRaw(struct GBACheatSet* cheats, uint32_t op1, uint32_t op2) { bool GBACheatAddGameSharkRaw(struct GBACheatSet* cheats, uint32_t op1, uint32_t op2) {
enum GBAGameSharkType type = op1 >> 28; enum GBAGameSharkType type = op1 >> 28;
struct mCheat* cheat = 0; struct mCheat* cheat = 0;
int romPatch = 0; struct GBACheatPatch* romPatch;
if (cheats->incompleteCheat != COMPLETE) { if (cheats->incompleteCheat != COMPLETE) {
struct mCheat* incompleteCheat = mCheatListGetPointer(&cheats->d.list, cheats->incompleteCheat); struct mCheat* incompleteCheat = mCheatListGetPointer(&cheats->d.list, cheats->incompleteCheat);
@ -149,16 +149,10 @@ bool GBACheatAddGameSharkRaw(struct GBACheatSet* cheats, uint32_t op1, uint32_t
cheats->incompleteCheat = mCheatListIndex(&cheats->d.list, cheat); cheats->incompleteCheat = mCheatListIndex(&cheats->d.list, cheat);
break; break;
case GSA_PATCH: case GSA_PATCH:
while (cheats->romPatches[romPatch].exists) { romPatch = GBACheatPatchListAppend(&cheats->romPatches);
++romPatch; romPatch->address = BASE_CART0 | ((op1 & 0xFFFFFF) << 1);
if (romPatch >= MAX_ROM_PATCHES) { romPatch->newValue = op2;
break; romPatch->applied = false;
}
}
cheats->romPatches[romPatch].address = BASE_CART0 | ((op1 & 0xFFFFFF) << 1);
cheats->romPatches[romPatch].newValue = op2;
cheats->romPatches[romPatch].applied = false;
cheats->romPatches[romPatch].exists = true;
return true; return true;
case GSA_BUTTON: case GSA_BUTTON:
switch (op1 & 0x00F00000) { switch (op1 & 0x00F00000) {

View File

@ -230,16 +230,10 @@ static bool _addPAR3Special(struct GBACheatSet* cheats, uint32_t op2) {
break; break;
} }
if (romPatch >= 0) { if (romPatch >= 0) {
while (cheats->romPatches[romPatch].exists) { struct GBACheatPatch* patch = GBACheatPatchListAppend(&cheats->romPatches);
++romPatch; patch->address = BASE_CART0 | ((op2 & 0xFFFFFF) << 1);
if (romPatch >= MAX_ROM_PATCHES) { patch->applied = false;
break; cheats->incompletePatch = patch;
}
}
cheats->romPatches[romPatch].address = BASE_CART0 | ((op2 & 0xFFFFFF) << 1);
cheats->romPatches[romPatch].applied = false;
cheats->romPatches[romPatch].exists = true;
cheats->incompletePatch = &cheats->romPatches[romPatch];
} }
return true; return true;
} }