Fix #165
This commit is contained in:
parent
7fc3de69da
commit
274760746e
@ -95,7 +95,7 @@ void GB_init(GB_gameboy_t *gb, GB_model_t model)
|
||||
memset(gb, 0, sizeof(*gb));
|
||||
gb->model = model;
|
||||
if (GB_is_cgb(gb)) {
|
||||
gb->ram = malloc(gb->ram_size = 0x2000 * 8);
|
||||
gb->ram = malloc(gb->ram_size = 0x1000 * 8);
|
||||
gb->vram = malloc(gb->vram_size = 0x2000 * 2);
|
||||
}
|
||||
else {
|
||||
@ -632,7 +632,7 @@ void GB_reset(GB_gameboy_t *gb)
|
||||
gb->io_registers[GB_IO_JOYP] = 0xF;
|
||||
gb->mbc_ram_size = mbc_ram_size;
|
||||
if (GB_is_cgb(gb)) {
|
||||
gb->ram_size = 0x2000 * 8;
|
||||
gb->ram_size = 0x1000 * 8;
|
||||
gb->vram_size = 0x2000 * 2;
|
||||
memset(gb->vram, 0, gb->vram_size);
|
||||
gb->cgb_mode = true;
|
||||
@ -703,7 +703,7 @@ void GB_switch_model_and_reset(GB_gameboy_t *gb, GB_model_t model)
|
||||
{
|
||||
gb->model = model;
|
||||
if (GB_is_cgb(gb)) {
|
||||
gb->ram = realloc(gb->ram, gb->ram_size = 0x2000 * 8);
|
||||
gb->ram = realloc(gb->ram, gb->ram_size = 0x1000 * 8);
|
||||
gb->vram = realloc(gb->vram, gb->vram_size = 0x2000 * 2);
|
||||
}
|
||||
else {
|
||||
|
@ -333,6 +333,7 @@ struct GB_gameboy_internal_s {
|
||||
bool infrared_input;
|
||||
GB_printer_t printer;
|
||||
uint8_t extra_oam[0xff00 - 0xfea0];
|
||||
uint32_t ram_size; // Different between CGB and DMG
|
||||
);
|
||||
|
||||
/* DMA and HDMA */
|
||||
@ -593,7 +594,6 @@ struct GB_gameboy_internal_s {
|
||||
bool turbo;
|
||||
bool turbo_dont_skip;
|
||||
bool disable_rendering;
|
||||
uint32_t ram_size; // Different between CGB and DMG
|
||||
uint8_t boot_rom[0x900];
|
||||
bool vblank_just_occured; // For slow operations involving syscalls; these should only run once per vblank
|
||||
uint8_t cycles_since_run; // How many cycles have passed since the last call to GB_run(), in 8MHz units
|
||||
|
@ -156,11 +156,6 @@ static bool verify_state_compatibility(GB_gameboy_t *gb, GB_gameboy_t *save)
|
||||
return false;
|
||||
}
|
||||
|
||||
if (gb->ram_size != save->ram_size) {
|
||||
GB_log(gb, "The save state has non-matching RAM size. Try changing the emulated model.\n");
|
||||
return false;
|
||||
}
|
||||
|
||||
if (gb->vram_size != save->vram_size) {
|
||||
GB_log(gb, "The save state has non-matching VRAM size. Try changing the emulated model.\n");
|
||||
return false;
|
||||
@ -171,6 +166,17 @@ static bool verify_state_compatibility(GB_gameboy_t *gb, GB_gameboy_t *save)
|
||||
return false;
|
||||
}
|
||||
|
||||
if (gb->ram_size != save->ram_size) {
|
||||
if (gb->ram_size == 0x1000 * 8 && save->ram_size == 0x2000 * 8) {
|
||||
/* A bug in versions prior to 0.12 made CGB instances allocate twice the ammount of RAM.
|
||||
Ignore this issue to retain compatibility with older, 0.11, save states. */
|
||||
}
|
||||
else {
|
||||
GB_log(gb, "The save state has non-matching RAM size. Try changing the emulated model.\n");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -182,6 +188,8 @@ int GB_load_state(GB_gameboy_t *gb, const char *path)
|
||||
|
||||
/* Every unread value should be kept the same. */
|
||||
memcpy(&save, gb, sizeof(save));
|
||||
/* ...Except ram size, we use it to detect old saves with incorrect ram sizes */
|
||||
save.ram_size = 0;
|
||||
|
||||
FILE *f = fopen(path, "rb");
|
||||
if (!f) {
|
||||
@ -199,6 +207,17 @@ int GB_load_state(GB_gameboy_t *gb, const char *path)
|
||||
if (!READ_SECTION(&save, f, rtc )) goto error;
|
||||
if (!READ_SECTION(&save, f, video )) goto error;
|
||||
|
||||
if (save.ram_size == 0) {
|
||||
/* Save doesn't have ram size specified, it's a pre 0.12 save state with potentially
|
||||
incorrect RAM amount if it's a CGB instance */
|
||||
if (GB_is_cgb(&save)) {
|
||||
save.ram_size = 0x2000 * 8; // Incorrect RAM size
|
||||
}
|
||||
else {
|
||||
save.ram_size = gb->ram_size;
|
||||
}
|
||||
}
|
||||
|
||||
if (!verify_state_compatibility(gb, &save)) {
|
||||
errno = -1;
|
||||
goto error;
|
||||
@ -219,12 +238,18 @@ int GB_load_state(GB_gameboy_t *gb, const char *path)
|
||||
return EIO;
|
||||
}
|
||||
|
||||
/* Fix for 0.11 save states that allocate twice the amount of RAM in CGB instances */
|
||||
fseek(f, save.ram_size - gb->ram_size, SEEK_CUR);
|
||||
|
||||
if (fread(gb->vram, 1, gb->vram_size, f) != gb->vram_size) {
|
||||
fclose(f);
|
||||
return EIO;
|
||||
}
|
||||
|
||||
size_t orig_ram_size = gb->ram_size;
|
||||
memcpy(gb, &save, sizeof(save));
|
||||
gb->ram_size = orig_ram_size;
|
||||
|
||||
errno = 0;
|
||||
|
||||
if (gb->cartridge_type->has_rumble && gb->rumble_callback) {
|
||||
@ -324,6 +349,10 @@ int GB_load_state_from_buffer(GB_gameboy_t *gb, const uint8_t *buffer, size_t le
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* Fix for 0.11 save states that allocate twice the amount of RAM in CGB instances */
|
||||
buffer += save.ram_size - gb->ram_size;
|
||||
length -= save.ram_size - gb->ram_size;
|
||||
|
||||
memcpy(gb, &save, sizeof(save));
|
||||
|
||||
if (gb->cartridge_type->has_rumble && gb->rumble_callback) {
|
||||
|
Loading…
Reference in New Issue
Block a user