aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorwhiterandrek2018-05-28 18:57:36 +0300
committerEugene Sandulenko2018-06-28 23:51:32 +0200
commite7a7d6960d605b668da0332ee75605d52d0c7543 (patch)
tree1a7c5a02af437ca613feb234a51e9d578959abb5
parent90864279f4a0761ff43fc9c412b6c76d98a0a019 (diff)
downloadscummvm-rg350-e7a7d6960d605b668da0332ee75605d52d0c7543.tar.gz
scummvm-rg350-e7a7d6960d605b668da0332ee75605d52d0c7543.tar.bz2
scummvm-rg350-e7a7d6960d605b668da0332ee75605d52d0c7543.zip
PINK: add savestate metadata support
-rw-r--r--engines/pink/detection.cpp20
-rw-r--r--engines/pink/pink.cpp68
-rw-r--r--engines/pink/pink.h1
3 files changed, 81 insertions, 8 deletions
diff --git a/engines/pink/detection.cpp b/engines/pink/detection.cpp
index 619bf5d227..71b353526f 100644
--- a/engines/pink/detection.cpp
+++ b/engines/pink/detection.cpp
@@ -50,7 +50,7 @@ public:
virtual int getMaximumSaveSlot() const { return 99; }
virtual SaveStateList listSaves(const char *target) const;
virtual void removeSaveState(const char *target, int slot) const;
- //virtual SaveStateDescriptor querySaveMetaInfos(const char *target, int slot) const;
+ virtual SaveStateDescriptor querySaveMetaInfos(const char *target, int slot) const;
virtual bool createInstance(OSystem *syst, Engine **engine, const ADGameDescription *desc) const;
};
@@ -58,6 +58,10 @@ bool PinkMetaEngine::hasFeature(MetaEngineFeature f) const {
return
(f == kSupportsListSaves) ||
(f == kSupportsDeleteSave) ||
+ (f == kSavesSupportMetaInfo) ||
+ (f == kSavesSupportThumbnail) ||
+ (f == kSavesSupportCreationDate) ||
+ (f == kSavesSupportPlayTime) ||
(f == kSupportsLoadingDuringStartup) ||
(f == kSimpleSavesNames);
}
@@ -90,6 +94,20 @@ void PinkMetaEngine::removeSaveState(const char *target, int slot) const {
g_system->getSavefileManager()->removeSavefile(Pink::generateSaveName(slot, target));
}
+SaveStateDescriptor PinkMetaEngine::querySaveMetaInfos(const char *target, int slot) const {
+ Common::ScopedPtr<Common::InSaveFile> f(g_system->getSavefileManager()->openForLoading(Pink::generateSaveName(slot, target)));
+
+ if (f) {
+ SaveStateDescriptor desc;
+ if (!Pink::readSaveHeader(*f.get(), desc))
+ return SaveStateDescriptor();
+
+ return desc;
+ }
+
+ return SaveStateDescriptor();
+}
+
bool PinkMetaEngine::createInstance(OSystem *syst, Engine **engine, const ADGameDescription *desc) const {
if (desc)
*engine = new Pink::PinkEngine(syst, desc);
diff --git a/engines/pink/pink.cpp b/engines/pink/pink.cpp
index d886c77863..01f9ad1632 100644
--- a/engines/pink/pink.cpp
+++ b/engines/pink/pink.cpp
@@ -20,6 +20,8 @@
*
*/
+#include <graphics/thumbnail.h>
+#include <graphics/surface.h>
#include "common/debug-channels.h"
#include "common/winexe_pe.h"
#include "common/config-manager.h"
@@ -247,11 +249,15 @@ void PinkEngine::setCursor(uint cursorIndex) {
}
Common::Error PinkEngine::loadGameState(int slot) {
- Common::SeekableReadStream *stream = _saveFileMan->openForLoading(generateSaveName(slot, _desc.gameId));
- if (!stream)
+ Common::SeekableReadStream *in = _saveFileMan->openForLoading(generateSaveName(slot, _desc.gameId));
+ if (!in)
return Common::kNoGameDataFoundError;
- Archive archive(stream);
+ SaveStateDescriptor desc;
+ if (!readSaveHeader(*in, desc))
+ return Common::kUnknownError;
+
+ Archive archive(in);
_variables.deserialize(archive);
_nextModule = archive.readString();
_nextPage = archive.readString();
@@ -265,11 +271,26 @@ bool PinkEngine::canLoadGameStateCurrently() {
}
Common::Error PinkEngine::saveGameState(int slot, const Common::String &desc) {
- Common::WriteStream *stream = _saveFileMan->openForSaving(generateSaveName(slot, _desc.gameId));
- if (!stream)
+ Common::OutSaveFile *out = _saveFileMan->openForSaving(generateSaveName(slot, _desc.gameId));
+ if (!out)
+ return Common::kUnknownError;
+
+ Archive archive(out);
+
+ out->write("pink", 4);
+ archive.writeString(desc);
+
+ TimeDate curTime;
+ _system->getTimeAndDate(curTime);
+
+ out->writeUint32LE(((curTime.tm_mday & 0xFF) << 24) | (((curTime.tm_mon + 1) & 0xFF) << 16) | ((curTime.tm_year + 1900) & 0xFFFF));
+ out->writeUint16LE(((curTime.tm_hour & 0xFF) << 8) | ((curTime.tm_min) & 0xFF));
+
+ out->writeUint32LE(getTotalPlayTime() / 1000);
+
+ if (!Graphics::saveThumbnail(*out))
return Common::kUnknownError;
- Archive archive(stream);
_variables.serialize(archive);
archive.writeString(_nextModule);
archive.writeString(_nextPage);
@@ -277,7 +298,7 @@ Common::Error PinkEngine::saveGameState(int slot, const Common::String &desc) {
archive.writeString(_module->getName());
_module->saveState(archive);
- delete stream;
+ delete out;
return Common::kNoError;
}
@@ -303,4 +324,37 @@ Common::String generateSaveName(int slot, const char *gameId) {
return Common::String::format("%s.s%02d", gameId, slot);
}
+bool readSaveHeader(Common::InSaveFile &in, SaveStateDescriptor &desc) {
+ char pink[4];
+ in.read(&pink, 4);
+ if (strcmp(pink, "pink"))
+ return false;
+
+ const Common::String description = in.readPascalString();
+ uint32 date = in.readUint32LE();
+ uint16 time = in.readUint16LE();
+ uint32 playTime = in.readUint32LE();
+ if (!Graphics::checkThumbnailHeader(in))
+ return false;
+
+ Graphics::Surface *thumbnail;
+ if (!Graphics::loadThumbnail(in, thumbnail))
+ return false;
+
+ int day = (date >> 24) & 0xFF;
+ int month = (date >> 16) & 0xFF;
+ int year = date & 0xFFFF;
+
+ int hour = (time >> 8) & 0xFF;
+ int minutes = time & 0xFF;
+
+ desc.setSaveDate(year, month, day);
+ desc.setSaveTime(hour, minutes);
+ desc.setPlayTime(playTime * 1000);
+ desc.setDescription(description);
+ desc.setThumbnail(thumbnail);
+
+ return true;
+}
+
}
diff --git a/engines/pink/pink.h b/engines/pink/pink.h
index 1e0f703ec5..e6e698ed38 100644
--- a/engines/pink/pink.h
+++ b/engines/pink/pink.h
@@ -141,6 +141,7 @@ private:
const ADGameDescription _desc;
};
+bool readSaveHeader(Common::InSaveFile &in, SaveStateDescriptor &desc);
Common::String generateSaveName(int slot, const char *gameId);
} // End of namespace Pink