diff options
author | Thierry Crozat | 2018-12-28 19:02:45 +0100 |
---|---|---|
committer | Thierry Crozat | 2018-12-28 20:40:27 +0100 |
commit | 287f40358e0cf43335b2727d4e2c5573d4c89246 (patch) | |
tree | a543ac27a0d73fcde78b5f05196d9c749fc9b240 /engines/supernova | |
parent | 2d75c6b271e71168bb42024606f4b7fc510d1751 (diff) | |
download | scummvm-rg350-287f40358e0cf43335b2727d4e2c5573d4c89246.tar.gz scummvm-rg350-287f40358e0cf43335b2727d4e2c5573d4c89246.tar.bz2 scummvm-rg350-287f40358e0cf43335b2727d4e2c5573d4c89246.zip |
SUPERNOVA: Save sleep savegame at end of normal saves
This replaces using slot 999 to save this savegame and allows
to properly handle having several playthroughs with a different
state when going to sleep. This is also similar to what the
original engine was doing.
Diffstat (limited to 'engines/supernova')
-rw-r--r-- | engines/supernova/supernova.cpp | 93 | ||||
-rw-r--r-- | engines/supernova/supernova.h | 10 |
2 files changed, 83 insertions, 20 deletions
diff --git a/engines/supernova/supernova.cpp b/engines/supernova/supernova.cpp index 51512af7e6..74d815a347 100644 --- a/engines/supernova/supernova.cpp +++ b/engines/supernova/supernova.cpp @@ -80,10 +80,12 @@ SupernovaEngine::SupernovaEngine(OSystem *syst) , _sound(nullptr) , _resMan(nullptr) , _screen(nullptr) - , _delay(33) - , _textSpeed(kTextSpeed[2]) , _allowLoadGame(true) - , _allowSaveGame(true) { + , _allowSaveGame(true) + , _sleepAutoSave(nullptr) + , _sleepAuoSaveVersion(-1) + , _delay(33) + , _textSpeed(kTextSpeed[2]) { if (ConfMan.hasKey("textspeed")) _textSpeed = ConfMan.getInt("textspeed"); @@ -93,6 +95,7 @@ SupernovaEngine::SupernovaEngine(OSystem *syst) SupernovaEngine::~SupernovaEngine() { DebugMan.clearAllDebugChannels(); + delete _sleepAutoSave; delete _console; delete _gm; delete _sound; @@ -470,10 +473,46 @@ Common::Error SupernovaEngine::saveGameState(int slot, const Common::String &des return (saveGame(slot, desc) ? Common::kNoError : Common::kWritingFailed); } +bool SupernovaEngine::serialize(Common::WriteStream *out) { + if (!_gm->serialize(out)) + return false; + out->writeByte(_screen->getGuiBrightness()); + out->writeByte(_screen->getViewportBrightness()); + return true; +} + +bool SupernovaEngine::deserialize(Common::ReadStream *in, int version) { + if (!_gm->deserialize(in, version)) + return false; + if (version >= 5) { + _screen->setGuiBrightness(in->readByte()); + _screen->setViewportBrightness(in->readByte()); + } else { + _screen->setGuiBrightness(255); + _screen->setViewportBrightness(255); + } + return true; +} + bool SupernovaEngine::loadGame(int slot) { if (slot < 0) return false; + // Make sure no message is displayed as this would otherwise delay the + // switch to the new location until a mouse click. + removeMessage(); + + if (slot == kSleepAutosaveSlot) { + if (_sleepAutoSave != nullptr && deserialize(_sleepAutoSave, _sleepAuoSaveVersion)) { + // We no longer need the sleep autosave + delete _sleepAutoSave; + _sleepAutoSave = nullptr; + return true; + } + // Old version used to save it literally in the kSleepAutosaveSlot, so + // continue to try to load it from there. + } + Common::String filename = Common::String::format("msn_save.%03d", slot); Common::InSaveFile *savefile = _saveFileMan->openForLoading(filename); if (!savefile) @@ -494,23 +533,29 @@ bool SupernovaEngine::loadGame(int slot) { return false; //Common::kUnknownError; } - // Make sure no message is displayed as this would otherwise delay the - // switch to the new location until a mouse click. - removeMessage(); - int descriptionSize = savefile->readSint16LE(); savefile->skip(descriptionSize); savefile->skip(6); setTotalPlayTime(savefile->readUint32LE() * 1000); Graphics::skipThumbnail(*savefile); - _gm->deserialize(savefile, saveVersion); - - if (saveVersion >= 5) { - _screen->setGuiBrightness(savefile->readByte()); - _screen->setViewportBrightness(savefile->readByte()); - } else { - _screen->setGuiBrightness(255); - _screen->setViewportBrightness(255); + if (!deserialize(savefile, saveVersion)) { + delete savefile; + return false; + }; + + // With version 9 onward the sleep auto-save is save at the end of a normal save. + delete _sleepAutoSave; + _sleepAutoSave = nullptr; + if (saveVersion >= 9) { + _sleepAuoSaveVersion = saveVersion; + byte hasAutoSave = savefile->readByte(); + if (hasAutoSave) { + _sleepAutoSave = new Common::MemoryReadWriteStream(DisposeAfterUse::YES); + uint nb; + char buf[4096]; + while ((nb = savefile->read(buf, 4096)) > 0) + _sleepAutoSave->write(buf, nb); + } } delete savefile; @@ -522,6 +567,14 @@ bool SupernovaEngine::saveGame(int slot, const Common::String &description) { if (slot < 0) return false; + if (slot == kSleepAutosaveSlot) { + delete _sleepAutoSave; + _sleepAutoSave = new Common::MemoryReadWriteStream(DisposeAfterUse::YES); + _sleepAuoSaveVersion = SAVEGAME_VERSION; + serialize(_sleepAutoSave); + return true; + } + Common::String filename = Common::String::format("msn_save.%03d", slot); Common::OutSaveFile *savefile = _saveFileMan->openForSaving(filename); if (!savefile) @@ -541,10 +594,14 @@ bool SupernovaEngine::saveGame(int slot, const Common::String &description) { savefile->writeUint16LE(saveTime); savefile->writeUint32LE(getTotalPlayTime() / 1000); Graphics::saveThumbnail(*savefile); - _gm->serialize(savefile); + serialize(savefile); - savefile->writeByte(_screen->getGuiBrightness()); - savefile->writeByte(_screen->getViewportBrightness()); + if (_sleepAutoSave == nullptr) + savefile->writeByte(0); + else { + savefile->writeByte(1); + savefile->write(_sleepAutoSave->getData(), _sleepAutoSave->size()); + } savefile->finalize(); delete savefile; diff --git a/engines/supernova/supernova.h b/engines/supernova/supernova.h index 132e25deeb..b4af8b4394 100644 --- a/engines/supernova/supernova.h +++ b/engines/supernova/supernova.h @@ -29,7 +29,6 @@ #include "common/scummsys.h" #include "engines/engine.h" #include "common/file.h" -#include "common/memstream.h" #include "supernova/console.h" #include "supernova/graphics.h" @@ -37,11 +36,14 @@ #include "supernova/rooms.h" #include "supernova/sound.h" +namespace Common { + class MemoryReadWriteStream; +} namespace Supernova { #define SAVEGAME_HEADER MKTAG('M','S','N','1') -#define SAVEGAME_VERSION 8 +#define SAVEGAME_VERSION 9 #define SUPERNOVA_DAT "supernova.dat" #define SUPERNOVA_DAT_VERSION 1 @@ -75,6 +77,8 @@ public: bool _allowSaveGame; Common::StringArray _gameStrings; Common::String _nullString; + int _sleepAuoSaveVersion; + Common::MemoryReadWriteStream* _sleepAutoSave; uint _delay; int _textSpeed; @@ -83,6 +87,8 @@ public: void init(); bool loadGame(int slot); bool saveGame(int slot, const Common::String &description); + bool serialize(Common::WriteStream *out); + bool deserialize(Common::ReadStream *in, int version); bool quitGameDialog(); void errorTempSave(bool saving); void setTextSpeed(); |