PINK: add savestate metadata support

This commit is contained in:
whiterandrek 2018-05-28 18:57:36 +03:00 committed by Eugene Sandulenko
parent 90864279f4
commit e7a7d6960d
3 changed files with 81 additions and 8 deletions

View File

@ -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);

View File

@ -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;
}
}

View File

@ -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