diff options
author | uruk | 2014-06-29 22:52:03 +0200 |
---|---|---|
committer | uruk | 2014-06-29 22:52:03 +0200 |
commit | ade740de1098930d5b9827b98c844d300ded04b8 (patch) | |
tree | f4a6139171a7f3df25cbfb4783b31a97fab75c03 /engines/cge2/saveload.cpp | |
parent | b6d4281917d10effdd3890f8d1f740558da409c4 (diff) | |
download | scummvm-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.cpp | 123 |
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; |