aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSven Hesse2008-05-11 18:55:40 +0000
committerSven Hesse2008-05-11 18:55:40 +0000
commitc5498a69bfaee74e2b5b046b36512c8a5d4785f9 (patch)
tree5af2b119460ce499b4e36cbb6195e688849c2f54
parent4b21c2958ddf3cf1e69f427c715406d76712bed1 (diff)
downloadscummvm-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.cpp109
-rw-r--r--engines/gob/saveload.h35
-rw-r--r--engines/gob/saveload_v2.cpp2
-rw-r--r--engines/gob/saveload_v3.cpp2
-rw-r--r--engines/gob/saveload_v4.cpp66
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;