diff options
author | Sven Hesse | 2008-05-11 18:55:40 +0000 |
---|---|---|
committer | Sven Hesse | 2008-05-11 18:55:40 +0000 |
commit | c5498a69bfaee74e2b5b046b36512c8a5d4785f9 (patch) | |
tree | 5af2b119460ce499b4e36cbb6195e688849c2f54 | |
parent | 4b21c2958ddf3cf1e69f427c715406d76712bed1 (diff) | |
download | scummvm-rg350-c5498a69bfaee74e2b5b046b36512c8a5d4785f9.tar.gz scummvm-rg350-c5498a69bfaee74e2b5b046b36512c8a5d4785f9.tar.bz2 scummvm-rg350-c5498a69bfaee74e2b5b046b36512c8a5d4785f9.zip |
Implemented temp buffer saving/loading ("SAVE.TMP") in Woodruff.
Objects you take from or leave in screens are remembered correctly now.
svn-id: r32030
-rw-r--r-- | engines/gob/saveload.cpp | 109 | ||||
-rw-r--r-- | engines/gob/saveload.h | 35 | ||||
-rw-r--r-- | engines/gob/saveload_v2.cpp | 2 | ||||
-rw-r--r-- | engines/gob/saveload_v3.cpp | 2 | ||||
-rw-r--r-- | engines/gob/saveload_v4.cpp | 66 |
5 files changed, 212 insertions, 2 deletions
diff --git a/engines/gob/saveload.cpp b/engines/gob/saveload.cpp index e0854151a0..50f41db47e 100644 --- a/engines/gob/saveload.cpp +++ b/engines/gob/saveload.cpp @@ -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]; diff --git a/engines/gob/saveload.h b/engines/gob/saveload.h index 9b032cc73f..d13bd2c15f 100644 --- a/engines/gob/saveload.h +++ b/engines/gob/saveload.h @@ -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(); }; diff --git a/engines/gob/saveload_v2.cpp b/engines/gob/saveload_v2.cpp index 2754646198..153b6dc2cd 100644 --- a/engines/gob/saveload_v2.cpp +++ b/engines/gob/saveload_v2.cpp @@ -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; diff --git a/engines/gob/saveload_v3.cpp b/engines/gob/saveload_v3.cpp index ae8d160eb2..d8eadd5677 100644 --- a/engines/gob/saveload_v3.cpp +++ b/engines/gob/saveload_v3.cpp @@ -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; diff --git a/engines/gob/saveload_v4.cpp b/engines/gob/saveload_v4.cpp index 2235b4834e..75e44cc1bc 100644 --- a/engines/gob/saveload_v4.cpp +++ b/engines/gob/saveload_v4.cpp @@ -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; |