aboutsummaryrefslogtreecommitdiff
path: root/engines/scumm/saveload.cpp
diff options
context:
space:
mode:
authorMax Horn2009-03-16 04:45:12 +0000
committerMax Horn2009-03-16 04:45:12 +0000
commite44f07f988ee6a2a7574a42169d08b3d7a112eba (patch)
tree56ba5688d855def4850a890029ef1805db9cc576 /engines/scumm/saveload.cpp
parentffa97e6626e43adf9c94de9a7322138e46436af4 (diff)
downloadscummvm-rg350-e44f07f988ee6a2a7574a42169d08b3d7a112eba.tar.gz
scummvm-rg350-e44f07f988ee6a2a7574a42169d08b3d7a112eba.tar.bz2
scummvm-rg350-e44f07f988ee6a2a7574a42169d08b3d7a112eba.zip
SCUMM: Modified version of patch #1687041 (Scumm: Load-/Save-support for the original save-dialog)
svn-id: r39438
Diffstat (limited to 'engines/scumm/saveload.cpp')
-rw-r--r--engines/scumm/saveload.cpp124
1 files changed, 112 insertions, 12 deletions
diff --git a/engines/scumm/saveload.cpp b/engines/scumm/saveload.cpp
index 577c465bdd..55880766d9 100644
--- a/engines/scumm/saveload.cpp
+++ b/engines/scumm/saveload.cpp
@@ -28,6 +28,7 @@
#include "common/config-manager.h"
#include "common/savefile.h"
#include "common/system.h"
+#include "common/zlib.h"
#include "scumm/actor.h"
#include "scumm/charset.h"
@@ -129,10 +130,27 @@ static bool saveSaveGameHeader(Common::OutSaveFile *out, SaveGameHeader &hdr) {
return true;
}
+bool ScummEngine::saveState(Common::OutSaveFile *out, bool writeHeader) {
+ SaveGameHeader hdr;
+
+ if (writeHeader) {
+ memcpy(hdr.name, _saveLoadName, sizeof(hdr.name));
+ saveSaveGameHeader(out, hdr);
+ }
+#if !defined(__DS__)
+ Graphics::saveThumbnail(*out);
+#endif
+ saveInfos(out);
+
+ Serializer ser(0, out, CURRENT_VER);
+ saveOrLoad(&ser);
+ return true;
+}
+
bool ScummEngine::saveState(int slot, bool compat) {
+ bool saveFailed;
Common::String filename;
Common::OutSaveFile *out;
- SaveGameHeader hdr;
if (_saveLoadSlot == 255) {
// Allow custom filenames for save game system in HE Games
@@ -143,26 +161,108 @@ bool ScummEngine::saveState(int slot, bool compat) {
if (!(out = _saveFileMan->openForSaving(filename.c_str())))
return false;
- memcpy(hdr.name, _saveLoadName, sizeof(hdr.name));
- saveSaveGameHeader(out, hdr);
-#if !defined(__DS__)
- Graphics::saveThumbnail(*out);
-#endif
- saveInfos(out);
+ saveFailed = false;
+ if (!saveState(out))
+ saveFailed = true;
- Serializer ser(0, out, CURRENT_VER);
- saveOrLoad(&ser);
out->finalize();
- if (out->err()) {
- delete out;
+ if (out->err())
+ saveFailed = true;
+ delete out;
+
+ if (saveFailed) {
debug(1, "State save as '%s' FAILED", filename.c_str());
return false;
}
- delete out;
debug(1, "State saved as '%s'", filename.c_str());
return true;
}
+
+void ScummEngine_v3::prepareSavegame() {
+ Common::MemoryWriteStreamDynamic *memStream;
+ Common::WriteStream *writeStream;
+
+ // free memory of the last prepared savegame
+ delete _savePreparedSavegame;
+ _savePreparedSavegame = NULL;
+
+ // store headerless savegame in a compressed memory stream
+ memStream = new Common::MemoryWriteStreamDynamic();
+ writeStream = Common::wrapCompressedWriteStream(memStream);
+ if (saveState(writeStream, false)) {
+ // we have to finalize the compression-stream first, otherwise the internal
+ // memory-stream pointer will be zero (Important: flush() does not work here!).
+ writeStream->finalize();
+ if (!writeStream->err()) {
+ // wrap uncompressing MemoryReadStream around the savegame data
+ _savePreparedSavegame = Common::wrapCompressedReadStream(
+ new Common::MemoryReadStream(memStream->getData(), memStream->size(), true));
+ }
+ }
+ // free the CompressedWriteStream and MemoryWriteStreamDynamic
+ // but not the memory stream's internal buffer
+ delete writeStream;
+}
+
+bool ScummEngine_v3::savePreparedSavegame(int slot, char *desc) {
+ bool success;
+ Common::String filename;
+ Common::OutSaveFile *out;
+ SaveGameHeader hdr;
+ uint32 nread, nwritten;
+
+ out = 0;
+ success = true;
+
+ // check if savegame was successfully stored in memory
+ if (!_savePreparedSavegame)
+ success = false;
+
+ // open savegame file
+ if (success) {
+ filename = makeSavegameName(slot, false);
+ if (!(out = _saveFileMan->openForSaving(filename.c_str()))) {
+ success = false;
+ }
+ }
+
+ // write header to file
+ if (success) {
+ memset(hdr.name, 0, sizeof(hdr.name));
+ strncpy(hdr.name, desc, sizeof(hdr.name)-1);
+ success = saveSaveGameHeader(out, hdr);
+ }
+
+ // copy savegame from memory-stream to file
+ if (success) {
+ _savePreparedSavegame->seek(0, SEEK_SET);
+ byte buffer[1024];
+ while ((nread = _savePreparedSavegame->read(buffer, sizeof(buffer)))) {
+ nwritten = out->write(buffer, nread);
+ if (nwritten < nread) {
+ success = false;
+ break;
+ }
+ }
+ }
+
+ if (out) {
+ out->finalize();
+ if (out->err())
+ success = false;
+ delete out;
+ }
+
+ if (!success) {
+ debug(1, "State save as '%s' FAILED", filename.c_str());
+ return false;
+ } else {
+ debug(1, "State saved as '%s'", filename.c_str());
+ return true;
+ }
+}
+
static bool loadSaveGameHeader(Common::SeekableReadStream *in, SaveGameHeader &hdr) {
hdr.type = in->readUint32BE();
hdr.size = in->readUint32LE();