diff options
-rw-r--r-- | backends/dc/vmsave.cpp | 42 | ||||
-rw-r--r-- | common/stream.h | 6 | ||||
-rw-r--r-- | scumm/saveload.cpp | 6 |
3 files changed, 43 insertions, 11 deletions
diff --git a/backends/dc/vmsave.cpp b/backends/dc/vmsave.cpp index 16ea470a53..1ce7c55306 100644 --- a/backends/dc/vmsave.cpp +++ b/backends/dc/vmsave.cpp @@ -258,20 +258,25 @@ public: class OutVMSave : public Common::OutSaveFile { private: char *buffer; - int pos, size; + int pos, size, committed; char filename[16]; + bool iofailed; +public: uint32 write(const void *buf, uint32 cnt); -public: OutVMSave(const char *_filename) - : pos(0) + : pos(0), committed(-1), iofailed(false) { strncpy(filename, _filename, 16); buffer = new char[size = MAX_SAVE_SIZE]; } ~OutVMSave(); + + bool ioFailed() const { return iofailed; } + void clearIOFailed() { iofailed = false; } + void flush(); }; class VMSaveManager : public Common::SaveFileManager { @@ -295,23 +300,38 @@ public: virtual void listSavefiles(const char *prefix, bool *marks, int num); }; -OutVMSave::~OutVMSave() +void OutVMSave::flush() { extern const char *gGameName; extern Icon icon; + if(committed >= pos) + return; + + char *data = buffer, *compbuf = NULL; + int len = pos; + if(pos) { // Try compression - char *compbuf = new char[pos]; + compbuf = new char[pos]; unsigned long destlen = pos; if(!compress((Bytef*)compbuf, &destlen, (Bytef*)buffer, pos)) { - delete[] buffer; - buffer = compbuf; - pos = destlen; - } else delete[] compbuf; + data = compbuf; + len = destlen; + } } - displaySaveResult(writeSaveGame(gGameName, buffer, - pos, filename, icon)); + vmsaveResult r = writeSaveGame(gGameName, data, len, filename, icon); + committed = pos; + if(compbuf != NULL) + delete[] compbuf; + if(r != VMSAVE_OK) + iofailed = true; + displaySaveResult(r); +} + +OutVMSave::~OutVMSave() +{ + flush(); delete[] buffer; } diff --git a/common/stream.h b/common/stream.h index a89e5475dd..32688e08ff 100644 --- a/common/stream.h +++ b/common/stream.h @@ -67,6 +67,12 @@ public: */ virtual uint32 write(const void *dataPtr, uint32 dataSize) = 0; + /** + * Commit any buffered data to the underlying channel or + * storage medium; unbuffered streams can use the default + * implementation. + */ + virtual void flush() {} // The remaining methods all have default implementations; subclasses // need not (and should not) overload them. diff --git a/scumm/saveload.cpp b/scumm/saveload.cpp index 5252402ec8..3b426358c7 100644 --- a/scumm/saveload.cpp +++ b/scumm/saveload.cpp @@ -109,6 +109,12 @@ bool ScummEngine::saveState(int slot, bool compat) { Serializer ser(0, out, CURRENT_VER); saveOrLoad(&ser, CURRENT_VER); + out->flush(); + if(out->ioFailed()) { + delete out; + debug(1, "State save as '%s' FAILED", filename); + return false; + } delete out; debug(1, "State saved as '%s'", filename); return true; |