mirror of https://github.com/mgba-emu/mgba.git
GBA Cheats: Allow unlimited ROM patch-type codes per set
This commit is contained in:
parent
4ecf64a41c
commit
0cf138775b
1
CHANGES
1
CHANGES
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue