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)
- 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

View File

@ -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 @@ struct GBACheatHook {
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;

View File

@ -13,6 +13,8 @@
#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 @@ static struct mCheatSet* GBACheatSetCreate(struct mCheatDevice* device, const ch
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 @@ static void GBACheatSetDeinit(struct mCheatSet* set) {
free(gbaset->hook);
}
}
GBACheatPatchListDeinit(&gbaset->romPatches);
}
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) {
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 @@ bool GBACheatAddGameSharkRaw(struct GBACheatSet* cheats, uint32_t op1, uint32_t
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) {

View File

@ -230,16 +230,10 @@ static bool _addPAR3Special(struct GBACheatSet* cheats, uint32_t op2) {
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;
}