Implemented temp buffer saving/loading ("SAVE.TMP") in Woodruff.

Objects you take from or leave in screens are remembered correctly now.

svn-id: r32030
This commit is contained in:
Sven Hesse 2008-05-11 18:55:40 +00:00
parent 4b21c2958d
commit c5498a69bf
5 changed files with 212 additions and 2 deletions

View File

@ -433,6 +433,115 @@ bool StagedSave::read() {
}
PagedBuffer::PagedBuffer(uint32 pageSize) {
_size = 0;
_pageSize = pageSize;
}
PagedBuffer::~PagedBuffer() {
clear();
}
bool PagedBuffer::empty() const {
return _pages.empty();
}
uint32 PagedBuffer::getSize() const {
return _size;
}
void PagedBuffer::clear() {
for (uint i = 0; i < _pages.size(); i++)
delete[] _pages[i];
_pages.clear();
_size = 0;
}
bool PagedBuffer::write(const byte *buffer, uint32 size, uint32 offset) {
grow(size, offset);
uint page = offset / _pageSize;
while (size > 0) {
if (!_pages[page])
_pages[page] = new byte[_pageSize];
uint32 pStart = offset % _pageSize;
uint32 n = MIN(size, _pageSize - pStart);
memcpy(_pages[page] + pStart, buffer, n);
buffer += n;
offset += n;
size -= n;
page++;
}
return true;
}
bool PagedBuffer::read(byte *buffer, uint32 size, uint32 offset) const {
uint page = offset / _pageSize;
while (size > 0) {
if (offset >= _size) {
memset(buffer, 0, size);
break;
}
uint32 pStart = offset % _pageSize;
uint32 n = MIN(MIN(size, _pageSize - pStart), _size - offset);
if (_pages[page])
memcpy(buffer, _pages[page] + pStart, n);
else
memset(buffer, 0, n);
buffer += n;
offset += n;
size -= n;
page++;
}
return true;
}
uint32 PagedBuffer::writeToStream(Common::WriteStream &out) const {
for (uint i = 0; i < _pages.size(); i++) {
if (!_pages[i]) {
for (uint32 j = 0; j < _pageSize; j++)
out.writeByte(0);
} else
out.write(_pages[i], _pageSize);
}
return _size;
}
uint32 PagedBuffer::readFromStream(Common::ReadStream &in) {
clear();
while (!in.eos()) {
byte *buffer = new byte[_pageSize];
_size += in.read(buffer, _pageSize);
_pages.push_back(buffer);
}
return _size;
}
void PagedBuffer::grow(uint32 size, uint32 offset) {
uint32 eSize = offset + size;
while (_size < eSize) {
_pages.push_back(0);
_size += MIN(_pageSize, eSize - _size);
}
}
SaveLoad::SaveLoad(GobEngine *vm, const char *targetName) : _vm(vm) {
_targetName = new char[strlen(targetName) + 1];

View File

@ -121,6 +121,30 @@ private:
bool read();
};
class PagedBuffer {
public:
PagedBuffer(uint32 pageSize = 1024);
~PagedBuffer();
bool empty() const;
uint32 getSize() const;
void clear();
bool write(const byte *buffer, uint32 size, uint32 offset);
bool read(byte *buffer, uint32 size, uint32 offset) const;
uint32 writeToStream(Common::WriteStream &out) const;
uint32 readFromStream(Common::ReadStream &in);
private:
uint32 _size;
uint32 _pageSize;
Common::Array<byte *> _pages;
void grow(uint32 size, uint32 offset);
};
class SaveLoad {
public:
enum SaveMode {
@ -310,7 +334,8 @@ protected:
class SaveLoad_v4 : public SaveLoad {
public:
enum SaveType {
kSaveNone
kSaveNone,
kSaveTempBuffer
};
SaveLoad_v4(GobEngine *vm, const char *targetName);
@ -330,12 +355,20 @@ protected:
int32 _varSize;
PagedBuffer _tmpBuffer;
virtual int getSaveType(const char *fileName);
virtual int32 getSizeVersioned(int type);
virtual bool loadVersioned(int type, int16 dataVar, int32 size, int32 offset);
virtual bool saveVersioned(int type, int16 dataVar, int32 size, int32 offset);
int32 getSizeTempBuffer(SaveFile &saveFile);
bool loadTempBuffer(SaveFile &saveFile, int16 dataVar, int32 size, int32 offset);
bool saveTempBuffer(SaveFile &saveFile, int16 dataVar, int32 size, int32 offset);
void assertInited();
};

View File

@ -62,6 +62,8 @@ SaveLoad_v2::~SaveLoad_v2() {
}
SaveLoad::SaveMode SaveLoad_v2::getSaveMode(const char *fileName) {
fileName = stripPath(fileName);
for (int i = 0; i < ARRAYSIZE(_saveFiles); i++)
if (!scumm_stricmp(fileName, _saveFiles[i].sourceName))
return _saveFiles[i].mode;

View File

@ -75,6 +75,8 @@ SaveLoad_v3::~SaveLoad_v3() {
}
SaveLoad::SaveMode SaveLoad_v3::getSaveMode(const char *fileName) {
fileName = stripPath(fileName);
for (int i = 0; i < ARRAYSIZE(_saveFiles); i++)
if (!scumm_stricmp(fileName, _saveFiles[i].sourceName))
return _saveFiles[i].mode;

View File

@ -27,12 +27,13 @@
#include "gob/gob.h"
#include "gob/saveload.h"
#include "gob/global.h"
#include "gob/game.h"
namespace Gob {
SaveLoad_v4::SaveFile SaveLoad_v4::_saveFiles[] = {
{ "", 0, kSaveModeNone, kSaveNone }
{ "save.tmp", 0, kSaveModeSave, kSaveTempBuffer }
};
SaveLoad_v4::SaveLoad_v4(GobEngine *vm, const char *targetName) :
@ -45,31 +46,94 @@ SaveLoad_v4::~SaveLoad_v4() {
}
SaveLoad::SaveMode SaveLoad_v4::getSaveMode(const char *fileName) {
fileName = stripPath(fileName);
for (int i = 0; i < ARRAYSIZE(_saveFiles); i++)
if (!scumm_stricmp(fileName, _saveFiles[i].sourceName))
return _saveFiles[i].mode;
return kSaveModeNone;
}
int SaveLoad_v4::getSaveType(const char *fileName) {
for (int i = 0; i < ARRAYSIZE(_saveFiles); i++)
if (!scumm_stricmp(fileName, _saveFiles[i].sourceName))
return i;
return -1;
}
int32 SaveLoad_v4::getSizeVersioned(int type) {
assertInited();
switch (_saveFiles[type].type) {
case kSaveTempBuffer:
return getSizeTempBuffer(_saveFiles[type]);
default:
break;
}
return -1;
}
bool SaveLoad_v4::loadVersioned(int type, int16 dataVar, int32 size, int32 offset) {
assertInited();
switch (_saveFiles[type].type) {
case kSaveTempBuffer:
if (loadTempBuffer(_saveFiles[type], dataVar, size, offset))
return true;
warning("While loading from the tempBuffer");
break;
default:
break;
}
return false;
}
bool SaveLoad_v4::saveVersioned(int type, int16 dataVar, int32 size, int32 offset) {
assertInited();
switch (_saveFiles[type].type) {
case kSaveTempBuffer:
if (saveTempBuffer(_saveFiles[type], dataVar, size, offset))
return true;
warning("While saving to the tempBuffer");
break;
default:
break;
}
return false;
}
int32 SaveLoad_v4::getSizeTempBuffer(SaveFile &saveFile) {
return _tmpBuffer.getSize();
}
bool SaveLoad_v4::loadTempBuffer(SaveFile &saveFile,
int16 dataVar, int32 size, int32 offset) {
debugC(3, kDebugSaveLoad, "Loading from the temporary buffer (%d, %d, %d)",
dataVar, size, offset);
return _tmpBuffer.read(_vm->_global->_inter_variables + dataVar, size, offset);
}
bool SaveLoad_v4::saveTempBuffer(SaveFile &saveFile,
int16 dataVar, int32 size, int32 offset) {
debugC(3, kDebugSaveLoad, "Saving to the temporary buffer (%d, %d, %d)",
dataVar, size, offset);
return _tmpBuffer.write(_vm->_global->_inter_variables + dataVar, size, offset);
}
void SaveLoad_v4::assertInited() {
if (_varSize > 0)
return;