all repos — mgba @ 872c3ceba33da0686754101b37e44174d25e8fa9

mGBA Game Boy Advance Emulator

Savestate game checks
Jeffrey Pfau jeffrey@endrift.com
Mon, 20 Jan 2014 17:18:12 -0800
commit

872c3ceba33da0686754101b37e44174d25e8fa9

parent

26c1fbd48f574c700ae993eda7de8f37e08c1174

5 files changed, 28 insertions(+), 4 deletions(-)

jump to
M src/gba/gba-serialize.csrc/gba/gba-serialize.c

@@ -13,6 +13,9 @@ const uint32_t GBA_SAVESTATE_MAGIC = 0x01000000;

void GBASerialize(struct GBA* gba, struct GBASerializedState* state) { state->versionMagic = GBA_SAVESTATE_MAGIC; + state->biosChecksum = gba->biosChecksum; + state->id = ((struct GBACartridge*) gba->memory.rom)->id; + memcpy(state->title, ((struct GBACartridge*) gba->memory.rom)->title, sizeof(state->title)); memcpy(state->cpu.gprs, gba->cpu.gprs, sizeof(state->cpu.gprs)); state->cpu.cpsr = gba->cpu.cpsr;

@@ -28,6 +31,18 @@ GBAVideoSerialize(&gba->video, state);

} void GBADeserialize(struct GBA* gba, struct GBASerializedState* state) { + if (state->versionMagic != GBA_SAVESTATE_MAGIC) { + GBALog(gba, GBA_LOG_WARN, "Invalid or too new savestate"); + return; + } + if (state->biosChecksum != gba->biosChecksum) { + GBALog(gba, GBA_LOG_WARN, "Savestate created using a different version of the BIOS"); + return; + } + if (state->id != ((struct GBACartridge*) gba->memory.rom)->id || memcmp(state->title, ((struct GBACartridge*) gba->memory.rom)->title, sizeof(state->title))) { + GBALog(gba, GBA_LOG_WARN, "Savestate is for a different game"); + return; + } memcpy(gba->cpu.gprs, state->cpu.gprs, sizeof(gba->cpu.gprs)); gba->cpu.cpsr = state->cpu.cpsr; gba->cpu.spsr = state->cpu.spsr;
M src/gba/gba.csrc/gba/gba.c

@@ -133,6 +133,8 @@ gba->rumble = 0;

gba->logLevel = GBA_LOG_INFO | GBA_LOG_WARN | GBA_LOG_ERROR; + gba->biosChecksum = GBAChecksum(gba->memory.bios, SIZE_BIOS); + ARMReset(&gba->cpu); }

@@ -371,6 +373,7 @@ GBALog(gba, GBA_LOG_INFO, "Official GBA (DS) BIOS detected");

} else { GBALog(gba, GBA_LOG_WARN, "BIOS checksum incorrect"); } + gba->biosChecksum = checksum; if ((gba->cpu.gprs[ARM_PC] >> BASE_OFFSET) == BASE_BIOS) { gba->memory.d.setActiveRegion(&gba->memory.d, gba->cpu.gprs[ARM_PC]); }
M src/gba/gba.hsrc/gba/gba.h

@@ -86,6 +86,7 @@ unsigned enable : 1;

} timers[4]; int springIRQ; + uint32_t biosChecksum; int* keySource; struct GBARotationSource* rotationSource; struct GBARumble* rumble;
M src/gba/hle-bios.csrc/gba/hle-bios.c

@@ -1,7 +1,9 @@

#include "hle-bios.h" -const unsigned int hleBiosLength = 196; -const unsigned char hleBios[] = { +#include "gba-memory.h" + +const size_t hleBiosLength = 196; +const uint8_t hleBios[SIZE_BIOS] = { 0x06, 0x00, 0x00, 0xea, 0xfe, 0xff, 0xff, 0xea, 0x05, 0x00, 0x00, 0xea, 0xfe, 0xff, 0xff, 0xea, 0xfe, 0xff, 0xff, 0xea, 0x00, 0x00, 0xa0, 0xe1, 0x0e, 0x00, 0x00, 0xea, 0xfe, 0xff, 0xff, 0xea, 0x02, 0xf3, 0xa0, 0xe3,
M src/gba/hle-bios.hsrc/gba/hle-bios.h

@@ -1,7 +1,10 @@

#ifndef HLE_BIOS_H #define HLE_BIOS_H -extern const unsigned int hleBiosLength; -extern const unsigned char hleBios[]; +#include <stdint.h> +#include <string.h> + +extern const size_t hleBiosLength; +extern const uint8_t hleBios[]; #endif