mirror of
https://github.com/libretro/Mesen.git
synced 2024-12-14 04:48:42 +00:00
122 lines
2.7 KiB
C++
122 lines
2.7 KiB
C++
#include "stdafx.h"
|
|
#include <algorithm>
|
|
#include "Snapshotable.h"
|
|
#include "SaveStateManager.h"
|
|
|
|
void Snapshotable::StreamStartBlock()
|
|
{
|
|
if(_inBlock) {
|
|
throw new std::runtime_error("Cannot start a new block before ending the last block");
|
|
}
|
|
|
|
if(!_saving) {
|
|
InternalStream(_blockSize);
|
|
_blockSize = std::min(_blockSize, (uint32_t)0xFFFFF);
|
|
_blockBuffer = new uint8_t[_blockSize];
|
|
ArrayInfo<uint8_t> arrayInfo = { _blockBuffer, _blockSize };
|
|
InternalStream(arrayInfo);
|
|
} else {
|
|
_blockSize = 0x100;
|
|
_blockBuffer = new uint8_t[_blockSize];
|
|
}
|
|
_blockPosition = 0;
|
|
_inBlock = true;
|
|
}
|
|
|
|
void Snapshotable::StreamEndBlock()
|
|
{
|
|
_inBlock = false;
|
|
if(_saving) {
|
|
InternalStream(_blockPosition);
|
|
ArrayInfo<uint8_t> arrayInfo = { _blockBuffer, _blockPosition };
|
|
InternalStream(arrayInfo);
|
|
}
|
|
|
|
delete[] _blockBuffer;
|
|
_blockBuffer = nullptr;
|
|
}
|
|
|
|
void Snapshotable::Stream(Snapshotable* snapshotable)
|
|
{
|
|
stringstream stream;
|
|
if(_saving) {
|
|
snapshotable->SaveSnapshot(&stream);
|
|
uint32_t size = (uint32_t)stream.tellp();
|
|
stream.seekg(0, ios::beg);
|
|
stream.seekp(0, ios::beg);
|
|
|
|
uint8_t *buffer = new uint8_t[size];
|
|
stream.read((char*)buffer, size);
|
|
InternalStream(size);
|
|
ArrayInfo<uint8_t> arrayInfo = { buffer, size };
|
|
InternalStream(arrayInfo);
|
|
delete[] buffer;
|
|
} else {
|
|
uint32_t size = 0;
|
|
InternalStream(size);
|
|
|
|
uint8_t *buffer = new uint8_t[size];
|
|
ArrayInfo<uint8_t> arrayInfo = { buffer, size };
|
|
InternalStream(arrayInfo);
|
|
|
|
stream.write((char*)buffer, size);
|
|
stream.seekg(0, ios::beg);
|
|
stream.seekp(0, ios::beg);
|
|
snapshotable->LoadSnapshot(&stream, _stateVersion);
|
|
delete[] buffer;
|
|
}
|
|
}
|
|
|
|
void Snapshotable::SaveSnapshot(ostream* file)
|
|
{
|
|
_stateVersion = SaveStateManager::FileFormatVersion;
|
|
|
|
_streamSize = 0x1000;
|
|
_stream = new uint8_t[_streamSize];
|
|
_position = 0;
|
|
_saving = true;
|
|
|
|
StreamState(_saving);
|
|
file->write((char*)&_position, sizeof(_position));
|
|
file->write((char*)_stream, _position);
|
|
|
|
delete[] _stream;
|
|
|
|
if(_blockBuffer) {
|
|
throw new std::runtime_error("A call to StreamEndBlock is missing.");
|
|
}
|
|
}
|
|
|
|
void Snapshotable::LoadSnapshot(istream* file, uint32_t stateVersion)
|
|
{
|
|
_stateVersion = stateVersion;
|
|
|
|
_position = 0;
|
|
_saving = false;
|
|
|
|
file->read((char*)&_streamSize, sizeof(_streamSize));
|
|
_stream = new uint8_t[_streamSize];
|
|
file->read((char*)_stream, _streamSize);
|
|
StreamState(_saving);
|
|
|
|
AfterLoadState();
|
|
|
|
delete[] _stream;
|
|
|
|
if(_blockBuffer) {
|
|
throw new std::runtime_error("A call to StreamEndBlock is missing.");
|
|
}
|
|
}
|
|
|
|
void Snapshotable::WriteEmptyBlock(ostream* file)
|
|
{
|
|
int blockSize = 0;
|
|
file->write((char*)&blockSize, sizeof(blockSize));
|
|
}
|
|
|
|
void Snapshotable::SkipBlock(istream* file)
|
|
{
|
|
int blockSize = 0;
|
|
file->read((char*)&blockSize, sizeof(blockSize));
|
|
file->seekg(blockSize, ios::cur);
|
|
} |