diff --git a/src/gb/core.c b/src/gb/core.c index e9a2ac08c..a78caac8e 100644 --- a/src/gb/core.c +++ b/src/gb/core.c @@ -9,6 +9,7 @@ #include "gb/gb.h" #include "gb/renderers/software.h" #include "util/memory.h" +#include "util/patch.h" struct GBCore { struct mCore d; @@ -97,11 +98,15 @@ static bool _GBCoreLoadSave(struct mCore* core, struct VFile* vf) { } static bool _GBCoreLoadPatch(struct mCore* core, struct VFile* vf) { - // TODO - UNUSED(core); - UNUSED(vf); - mLOG(GB, STUB, "Patches are not yet supported"); - return false; + if (!vf) { + return false; + } + struct Patch patch; + if (!loadPatch(vf, &patch)) { + return false; + } + GBApplyPatch(core->board, &patch); + return true; } static void _GBCoreUnloadROM(struct mCore* core) { diff --git a/src/gb/gb.c b/src/gb/gb.c index 16c20240a..6d5518290 100644 --- a/src/gb/gb.c +++ b/src/gb/gb.c @@ -126,6 +126,24 @@ void GBUnloadROM(struct GB* gb) { gb->memory.sram = 0; } +void GBApplyPatch(struct GB* gb, struct Patch* patch) { + size_t patchedSize = patch->outputSize(patch, gb->memory.romSize); + if (!patchedSize) { + return; + } + if (patchedSize > 0x400000) { + patchedSize = 0x400000; + } + gb->memory.rom = anonymousMemoryMap(0x400000); + if (!patch->applyPatch(patch, gb->pristineRom, gb->pristineRomSize, gb->memory.rom, patchedSize)) { + mappedMemoryFree(gb->memory.rom, patchedSize); + gb->memory.rom = gb->pristineRom; + return; + } + gb->memory.romSize = patchedSize; + gb->romCrc32 = doCrc32(gb->memory.rom, gb->memory.romSize); +} + void GBDestroy(struct GB* gb) { GBUnloadROM(gb);