aboutsummaryrefslogtreecommitdiff
path: root/engines/supernova
diff options
context:
space:
mode:
authorThierry Crozat2018-12-28 19:02:45 +0100
committerThierry Crozat2018-12-28 20:40:27 +0100
commit287f40358e0cf43335b2727d4e2c5573d4c89246 (patch)
treea543ac27a0d73fcde78b5f05196d9c749fc9b240 /engines/supernova
parent2d75c6b271e71168bb42024606f4b7fc510d1751 (diff)
downloadscummvm-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.cpp93
-rw-r--r--engines/supernova/supernova.h10
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();