158 lines
3.5 KiB
C++
158 lines
3.5 KiB
C++
// serialize.cpp : save states
|
|
#include "serialize.h"
|
|
#include "types.h"
|
|
#include "hw/aica/aica_if.h"
|
|
#include "hw/holly/sb.h"
|
|
#include "hw/flashrom/nvmem.h"
|
|
#include "hw/gdrom/gdrom_if.h"
|
|
#include "hw/maple/maple_cfg.h"
|
|
#include "hw/modem/modem.h"
|
|
#include "hw/pvr/pvr.h"
|
|
#include "hw/sh4/sh4_sched.h"
|
|
#include "hw/sh4/sh4_mmr.h"
|
|
#include "reios/gdrom_hle.h"
|
|
#include "hw/naomi/naomi.h"
|
|
#include "hw/naomi/naomi_cart.h"
|
|
#include "hw/bba/bba.h"
|
|
#include "cfg/option.h"
|
|
#include "imgread/common.h"
|
|
#include "achievements/achievements.h"
|
|
|
|
void dc_serialize(Serializer& ser)
|
|
{
|
|
aica::serialize(ser);
|
|
|
|
sb_serialize(ser);
|
|
|
|
nvmem::serialize(ser);
|
|
|
|
gdrom::serialize(ser);
|
|
|
|
mcfg_SerializeDevices(ser);
|
|
|
|
pvr::serialize(ser);
|
|
|
|
sh4::serialize(ser);
|
|
|
|
ser << config::EmulateBBA.get();
|
|
if (config::EmulateBBA)
|
|
bba_Serialize(ser);
|
|
ModemSerialize(ser);
|
|
|
|
sh4::serialize2(ser);
|
|
|
|
libGDR_serialize(ser);
|
|
|
|
naomi_Serialize(ser);
|
|
|
|
ser << config::Broadcast.get();
|
|
ser << config::Cable.get();
|
|
ser << config::Region.get();
|
|
|
|
naomi_cart_serialize(ser);
|
|
gd_hle_state.Serialize(ser);
|
|
achievements::serialize(ser);
|
|
|
|
DEBUG_LOG(SAVESTATE, "Saved %d bytes", (u32)ser.size());
|
|
}
|
|
|
|
void dc_deserialize(Deserializer& deser)
|
|
{
|
|
DEBUG_LOG(SAVESTATE, "Loading state version %d", deser.version());
|
|
|
|
aica::deserialize(deser);
|
|
|
|
sb_deserialize(deser);
|
|
|
|
nvmem::deserialize(deser);
|
|
|
|
gdrom::deserialize(deser);
|
|
|
|
mcfg_DeserializeDevices(deser);
|
|
|
|
pvr::deserialize(deser);
|
|
|
|
sh4::deserialize(deser);
|
|
|
|
deser >> config::EmulateBBA.get();
|
|
if (config::EmulateBBA)
|
|
bba_Deserialize(deser);
|
|
ModemDeserialize(deser);
|
|
|
|
sh4::deserialize2(deser);
|
|
|
|
libGDR_deserialize(deser);
|
|
|
|
naomi_Deserialize(deser);
|
|
|
|
deser >> config::Broadcast.get();
|
|
verify(config::Broadcast >= 0 && config::Broadcast <= 4);
|
|
deser >> config::Cable.get();
|
|
verify(config::Cable >= 0 && config::Cable <= 3);
|
|
deser >> config::Region.get();
|
|
verify(config::Region >= 0 && config::Region <= 3);
|
|
|
|
naomi_cart_deserialize(deser);
|
|
gd_hle_state.Deserialize(deser);
|
|
achievements::deserialize(deser);
|
|
sh4_sched_ffts();
|
|
|
|
DEBUG_LOG(SAVESTATE, "Loaded %d bytes", (u32)deser.size());
|
|
}
|
|
|
|
Deserializer::Deserializer(const void *data, size_t limit, bool rollback)
|
|
: SerializeBase(limit, rollback), data((const u8 *)data)
|
|
{
|
|
if (!memcmp(data, "RASTATE\001", 8))
|
|
{
|
|
// RetroArch savestates now have several sections: MEM, ACHV, RPLY, etc.
|
|
const u8 *p = this->data + 8;
|
|
limit -= 8;
|
|
while (limit > 8)
|
|
{
|
|
const u8 *section = p;
|
|
u32 sectionSize = *(const u32 *)&p[4];
|
|
p += 8;
|
|
limit -= 8;
|
|
if (!memcmp(section, "MEM ", 4))
|
|
{
|
|
// That's the part we're interested in
|
|
this->data = p;
|
|
this->limit = sectionSize;
|
|
break;
|
|
}
|
|
sectionSize = (sectionSize + 7) & ~7; // align to 8 bytes
|
|
if (limit < sectionSize) {
|
|
limit = 0;
|
|
break;
|
|
}
|
|
p += sectionSize;
|
|
limit -= sectionSize;
|
|
}
|
|
if (limit <= 8)
|
|
throw Exception("Can't find MEM section in RetroArch savestate");
|
|
}
|
|
deserialize(_version);
|
|
if (_version < V16)
|
|
throw Exception("Unsupported version");
|
|
if (_version > Current)
|
|
throw Exception("Version too recent");
|
|
|
|
if(_version >= V42 && settings.platform.isConsole())
|
|
{
|
|
u32 ramSize;
|
|
deserialize(ramSize);
|
|
if (ramSize != settings.platform.ram_size)
|
|
throw Exception("Selected RAM Size doesn't match Save State");
|
|
}
|
|
}
|
|
|
|
Serializer::Serializer(void *data, size_t limit, bool rollback)
|
|
: SerializeBase(limit, rollback), data((u8 *)data)
|
|
{
|
|
Version v = Current;
|
|
serialize(v);
|
|
if (settings.platform.isConsole())
|
|
serialize(settings.platform.ram_size);
|
|
}
|