aboutsummaryrefslogtreecommitdiff
path: root/engines/cge2/saveload.cpp
diff options
context:
space:
mode:
authoruruk2014-06-29 22:52:03 +0200
committeruruk2014-06-29 22:52:03 +0200
commitade740de1098930d5b9827b98c844d300ded04b8 (patch)
treef4a6139171a7f3df25cbfb4783b31a97fab75c03 /engines/cge2/saveload.cpp
parentb6d4281917d10effdd3890f8d1f740558da409c4 (diff)
downloadscummvm-rg350-ade740de1098930d5b9827b98c844d300ded04b8.tar.gz
scummvm-rg350-ade740de1098930d5b9827b98c844d300ded04b8.tar.bz2
scummvm-rg350-ade740de1098930d5b9827b98c844d300ded04b8.zip
CGE2: Implement saving.
Diffstat (limited to 'engines/cge2/saveload.cpp')
-rw-r--r--engines/cge2/saveload.cpp123
1 files changed, 117 insertions, 6 deletions
diff --git a/engines/cge2/saveload.cpp b/engines/cge2/saveload.cpp
index ac059e5d8f..971b044e35 100644
--- a/engines/cge2/saveload.cpp
+++ b/engines/cge2/saveload.cpp
@@ -36,9 +36,13 @@
#include "cge2/events.h"
#include "cge2/snail.h"
#include "cge2/hero.h"
+#include "cge2/text.h"
namespace CGE2 {
+#define kSavegameCheckSum (1997 + _now + _music + kWorldHeight)
+#define kBadSVG 99
+
struct SavegameHeader {
uint8 version;
Common::String saveName;
@@ -123,11 +127,6 @@ SaveStateDescriptor CGE2MetaEngine::querySaveMetaInfos(const char *target, int s
desc.setSaveDate(header.saveYear, header.saveMonth, header.saveDay);
desc.setSaveTime(header.saveHour, header.saveMinutes);
- // Slot 0 is used for the 'automatic save on exit' save in Soltys, thus
- // we prevent it from being deleted or overwritten by accident.
- desc.setDeletableFlag(slot != 0);
- desc.setWriteProtectedFlag(slot == 0);
-
return desc;
}
}
@@ -185,10 +184,122 @@ bool CGE2Engine::canLoadGameStateCurrently() {
}
Common::Error CGE2Engine::saveGameState(int slot, const Common::String &desc) {
- warning("STUB: CGE2Engine::saveGameState()");
+ // Set up the serializer
+ Common::String slotName = generateSaveName(slot);
+ Common::OutSaveFile *saveFile = g_system->getSavefileManager()->openForSaving(slotName);
+
+ // Write out the ScummVM savegame header
+ SavegameHeader header;
+ header.saveName = desc;
+ header.version = kSavegameVersion;
+ writeSavegameHeader(saveFile, header);
+
+ // Write out the data of the savegame
+ syncGame(NULL, saveFile);
+
+ // Finish writing out game data
+ saveFile->finalize();
+ delete saveFile;
+
return Common::kNoError;
}
+/**
+* Support method that generates a savegame name
+* @param slot Slot number
+*/
+Common::String CGE2Engine::generateSaveName(int slot) {
+ return Common::String::format("%s.%03d", _targetName.c_str(), slot);
+}
+
+void CGE2Engine::writeSavegameHeader(Common::OutSaveFile *out, SavegameHeader &header) {
+ // Write out a savegame header
+ out->write(kSavegameStr, kSavegameStrSize + 1);
+
+ out->writeByte(kSavegameVersion);
+
+ // Write savegame name
+ out->write(header.saveName.c_str(), header.saveName.size() + 1);
+
+ // Get the active palette
+ uint8 thumbPalette[256 * 3];
+ g_system->getPaletteManager()->grabPalette(thumbPalette, 0, 256);
+
+ // Create a thumbnail and save it
+ Graphics::Surface *thumb = new Graphics::Surface();
+ Graphics::Surface *s = _vga->_page[0];
+ ::createThumbnail(thumb, (const byte *)s->getPixels(), kScrWidth, kScrHeight, thumbPalette);
+ Graphics::saveThumbnail(*out, *thumb);
+ thumb->free();
+ delete thumb;
+
+ // Write out the save date/time
+ TimeDate td;
+ g_system->getTimeAndDate(td);
+ out->writeSint16LE(td.tm_year + 1900);
+ out->writeSint16LE(td.tm_mon + 1);
+ out->writeSint16LE(td.tm_mday);
+ out->writeSint16LE(td.tm_hour);
+ out->writeSint16LE(td.tm_min);
+}
+
+void CGE2Engine::syncGame(Common::SeekableReadStream *readStream, Common::WriteStream *writeStream) {
+ Common::Serializer s(readStream, writeStream);
+
+ // Synchronise header data
+ syncHeader(s);
+
+ if (s.isSaving()) {
+ for (int i = 0; i < kSceneMax; i++)
+ _eyeTab[i]->sync(s);
+
+ _spare->sync(s);
+
+ // The references of the items in the heroes pockets:
+ for (int i = 0; i < 2; i++) {
+ for (int j = 0; j < kPocketMax; j++) {
+ Sprite *spr = _heroTab[i]->_pocket[j];
+ int ref = (spr) ? spr->_ref : -1;
+ s.syncAsSint16LE(ref);
+ }
+ }
+
+ for (int i = 0; i < kMaxPoint; i++)
+ _point[i]->sync(s);
+ } else {
+ // Loading game
+ }
+}
+
+void CGE2Engine::syncHeader(Common::Serializer &s) {
+ s.syncAsUint16LE(_now);
+ s.syncAsUint16LE(_sex);
+ s.syncAsUint16LE(_music);
+ s.syncAsUint16LE(_waitSeq);
+ s.syncAsUint16LE(_waitRef);
+ s.syncAsUint16LE(_sayCap);
+ s.syncAsUint16LE(_sayVox);
+ for (int i = 0; i < 4; i++)
+ s.syncAsUint16LE(_flag[i]);
+
+ if (s.isLoading()) {
+ // Reset scene values
+ //initSceneValues();
+ }
+
+ if (s.isSaving()) {
+ // Write checksum
+ int checksum = kSavegameCheckSum;
+ s.syncAsUint16LE(checksum);
+ } else {
+ // Read checksum and validate it
+ uint16 checksum = 0;
+ s.syncAsUint16LE(checksum);
+ if (checksum != kSavegameCheckSum)
+ error("%s", _text->getText(kBadSVG));
+ }
+}
+
Common::Error CGE2Engine::loadGameState(int slot) {
warning("STUB: CGE2Engine::loadGameState()");
return Common::kNoError;