From 3ccfce260f738ca15a660810ca9584c52c8231e1 Mon Sep 17 00:00:00 2001 From: Filippos Karapetis Date: Mon, 10 Nov 2008 14:11:30 +0000 Subject: SAGA save games now contain thumbnails and creation date/time (visible from the GMM save/load screens) svn-id: r34986 --- engines/saga/detection.cpp | 84 +++++++++++++++++++++++++++++++++++++++++++++- engines/saga/saga.h | 2 ++ engines/saga/saveload.cpp | 34 ++++++++++++++++--- 3 files changed, 115 insertions(+), 5 deletions(-) (limited to 'engines') diff --git a/engines/saga/detection.cpp b/engines/saga/detection.cpp index f114fa31b7..5ca5d842c3 100644 --- a/engines/saga/detection.cpp +++ b/engines/saga/detection.cpp @@ -32,6 +32,7 @@ #include "common/config-manager.h" #include "common/advancedDetector.h" #include "common/system.h" +#include "graphics/thumbnail.h" #include "saga/animation.h" #include "saga/displayinfo.h" @@ -153,13 +154,17 @@ public: virtual SaveStateList listSaves(const char *target) const; virtual int getMaximumSaveSlot() const; virtual void removeSaveState(const char *target, int slot) const; + SaveStateDescriptor querySaveMetaInfos(const char *target, int slot) const; }; bool SagaMetaEngine::hasFeature(MetaEngineFeature f) const { return (f == kSupportsListSaves) || (f == kSupportsLoadingDuringStartup) || - (f == kSupportsDeleteSave); + (f == kSupportsDeleteSave) || + (f == kSavesSupportMetaInfo) || + (f == kSavesSupportThumbnail) || + (f == kSavesSupportCreationDate); } bool Saga::SagaEngine::hasFeature(EngineFeature f) const { @@ -220,6 +225,83 @@ void SagaMetaEngine::removeSaveState(const char *target, int slot) const { g_system->getSavefileManager()->removeSavefile(filename.c_str()); } +SaveStateDescriptor SagaMetaEngine::querySaveMetaInfos(const char *target, int slot) const { + static char fileName[MAX_FILE_NAME]; + sprintf(fileName, "%s.s%02d", target, slot); + char title[TITLESIZE]; + Graphics::Surface *thumbnail; + + Common::InSaveFile *in = g_system->getSavefileManager()->openForLoading(fileName); + + if (in) { + uint32 type = in->readUint32BE(); + in->readUint32LE(); // size + uint32 version = in->readUint32LE(); + char name[SAVE_TITLE_SIZE]; + in->read(name, sizeof(name)); + + SaveStateDescriptor desc(slot, name); + + // Some older saves were not written in an endian safe fashion. + // We try to detect this here by checking for extremly high version values. + // If found, we retry with the data swapped. + if (version > 0xFFFFFF) { + warning("This savegame is not endian safe, retrying with the data swapped"); + version = SWAP_BYTES_32(version); + } + + debug(2, "Save version: %x", version); + + if (version < 4) + warning("This savegame is not endian-safe. There may be problems"); + + if (type != MKID_BE('SAGA')) { + error("SagaEngine::load wrong save game format"); + } + + if (version > 4) { + in->read(title, TITLESIZE); + debug(0, "Save is for: %s", title); + } + + desc.setDeletableFlag(true); + desc.setWriteProtectedFlag(false); + + if (version >= 6) { + thumbnail = new Graphics::Surface(); + assert(thumbnail); + if (!Graphics::loadThumbnail(*in, *thumbnail)) { + delete thumbnail; + thumbnail = 0; + } + + desc.setThumbnail(thumbnail); + + uint32 saveDate = in->readUint32BE(); + uint16 saveTime = in->readUint16BE(); + + int day = (saveDate >> 24) & 0xFF; + int month = (saveDate >> 16) & 0xFF; + int year = saveDate & 0xFFFF; + + desc.setSaveDate(year, month, day); + + int hour = (saveTime >> 8) & 0xFF; + int minutes = saveTime & 0xFF; + + desc.setSaveTime(hour, minutes); + + // TODO: played time + } + + delete in; + + return desc; + } + + return SaveStateDescriptor(); +} + #if PLUGIN_ENABLED_DYNAMIC(SAGA) REGISTER_PLUGIN_DYNAMIC(SAGA, PLUGIN_TYPE_ENGINE, SagaMetaEngine); #else diff --git a/engines/saga/saga.h b/engines/saga/saga.h index 592336fe98..cf1c4302da 100644 --- a/engines/saga/saga.h +++ b/engines/saga/saga.h @@ -73,6 +73,7 @@ using Common::MemoryReadStreamEndian; // preserve savegame backwards compatibility. We only check // for IHNM's save title during text input #define SAVE_TITLE_SIZE 28 +#define TITLESIZE 80 #define IHNM_SAVE_TITLE_SIZE 22 #define MAX_SAVES 96 #define MAX_FILE_NAME 256 @@ -469,6 +470,7 @@ struct SaveGameHeader { uint32 size; uint32 version; char name[SAVE_TITLE_SIZE]; + Graphics::Surface *thumbnail; }; inline int objectTypeId(uint16 objectId) { diff --git a/engines/saga/saveload.cpp b/engines/saga/saveload.cpp index 8d00f9d2d0..d5ccb32921 100644 --- a/engines/saga/saveload.cpp +++ b/engines/saga/saveload.cpp @@ -23,12 +23,13 @@ * */ - +#include // for extended infos #include "common/config-manager.h" #include "common/savefile.h" #include "common/system.h" #include "common/file.h" +#include "graphics/thumbnail.h" #include "saga/saga.h" #include "saga/actor.h" @@ -40,7 +41,7 @@ #include "saga/scene.h" #include "saga/script.h" -#define CURRENT_SAGA_VER 5 +#define CURRENT_SAGA_VER 6 namespace Saga { @@ -156,8 +157,6 @@ void SagaEngine::fillSaveList() { } } - -#define TITLESIZE 80 void SagaEngine::save(const char *fileName, const char *saveName) { Common::OutSaveFile *out; char title[TITLESIZE]; @@ -184,6 +183,20 @@ void SagaEngine::save(const char *fileName, const char *saveName) { strncpy(title, _gameTitle.c_str(), TITLESIZE); out->write(title, TITLESIZE); + // Thumbnail + Graphics::saveThumbnail(*out); + + // Date / time + tm curTime; + _system->getTimeAndDate(curTime); + + uint32 saveDate = (curTime.tm_mday & 0xFF) << 24 | ((curTime.tm_mon + 1) & 0xFF) << 16 | (curTime.tm_year + 1900) & 0xFFFF; + uint16 saveTime = (curTime.tm_hour & 0xFF) << 8 | (curTime.tm_min) & 0xFF; + + out->writeUint32BE(saveDate); + out->writeUint16BE(saveTime); + // TODO: played time + // Surrounding scene out->writeSint32LE(_scene->getOutsetSceneNumber()); if (getGameType() != GType_ITE) { @@ -260,6 +273,19 @@ void SagaEngine::load(const char *fileName) { debug(0, "Save is for: %s", title); } + if (_saveHeader.version >= 6) { + _saveHeader.thumbnail = new Graphics::Surface(); + assert(_saveHeader.thumbnail); + if (!Graphics::loadThumbnail(*in, *_saveHeader.thumbnail)) { + delete _saveHeader.thumbnail; + _saveHeader.thumbnail = 0; + } + + in->readUint32BE(); // save date + in->readUint16BE(); // save time + // TODO: played time + } + // Surrounding scene sceneNumber = in->readSint32LE(); if (getGameType() != GType_ITE) { -- cgit v1.2.3