aboutsummaryrefslogtreecommitdiff
path: root/engines
diff options
context:
space:
mode:
Diffstat (limited to 'engines')
-rw-r--r--engines/dreamweb/detection.cpp70
-rw-r--r--engines/dreamweb/dreamweb.h4
-rw-r--r--engines/dreamweb/saveload.cpp53
3 files changed, 123 insertions, 4 deletions
diff --git a/engines/dreamweb/detection.cpp b/engines/dreamweb/detection.cpp
index db2155fc4c..b3483f9248 100644
--- a/engines/dreamweb/detection.cpp
+++ b/engines/dreamweb/detection.cpp
@@ -25,7 +25,10 @@
#include "common/algorithm.h"
#include "common/system.h"
+#include "graphics/thumbnail.h"
+
#include "dreamweb/dreamweb.h"
+#include "dreamweb/structs.h"
static const PlainGameDescriptor dreamWebGames[] = {
{ "dreamweb", "DreamWeb" },
@@ -56,6 +59,7 @@ 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 DreamWebMetaEngine::hasFeature(MetaEngineFeature f) const {
@@ -63,6 +67,10 @@ bool DreamWebMetaEngine::hasFeature(MetaEngineFeature f) const {
case kSupportsListSaves:
case kSupportsLoadingDuringStartup:
case kSupportsDeleteSave:
+ case kSavesSupportMetaInfo:
+ case kSavesSupportThumbnail:
+ case kSavesSupportCreationDate:
+ case kSavesSupportPlayTime:
return true;
default:
return false;
@@ -120,6 +128,68 @@ void DreamWebMetaEngine::removeSaveState(const char *target, int slot) const {
g_system->getSavefileManager()->removeSavefile(fileName);
}
+SaveStateDescriptor DreamWebMetaEngine::querySaveMetaInfos(const char *target, int slot) const {
+ Common::String filename = Common::String::format("DREAMWEB.D%02d", slot);
+ Common::InSaveFile *in = g_system->getSavefileManager()->openForLoading(filename.c_str());
+
+ if (in) {
+ DreamGen::FileHeader header;
+ in->read((uint8 *)&header, sizeof(DreamGen::FileHeader));
+
+ Common::String saveName;
+ byte descSize = header.len(0);
+ byte i;
+
+ for (i = 0; i < descSize; i++)
+ saveName += (char)in->readByte();
+
+ SaveStateDescriptor desc(slot, saveName);
+ desc.setDeletableFlag(true);
+ desc.setWriteProtectedFlag(false);
+
+ // Check if there is a ScummVM data block
+ if (header.len(6) == SCUMMVM_BLOCK_MAGIC_SIZE) {
+ // Skip the game data
+ for (i = 1; i <= 5; i++)
+ in->skip(header.len(i));
+
+ uint32 tag = in->readUint32BE();
+ if (tag != SCUMMVM_HEADER) {
+ warning("ScummVM data block found, but the block header is incorrect - skipping");
+ delete in;
+ return desc;
+ }
+
+ byte version = in->readByte();
+ if (version > SAVEGAME_VERSION) {
+ warning("ScummVM data block found, but it has been saved with a newer version of ScummVM - skipping");
+ delete in;
+ return desc;
+ }
+
+ uint32 saveDate = in->readUint32LE();
+ uint32 saveTime = in->readUint32LE();
+ uint32 playTime = in->readUint32LE();
+ Graphics::Surface *thumbnail = Graphics::loadThumbnail(*in);
+
+ int day = (saveDate >> 24) & 0xFF;
+ int month = (saveDate >> 16) & 0xFF;
+ int year = saveDate & 0xFFFF;
+ int hour = (saveTime >> 16) & 0xFF;
+ int minutes = (saveTime >> 8) & 0xFF;
+
+ desc.setSaveDate(year, month, day);
+ desc.setSaveTime(hour, minutes);
+ desc.setPlayTime(playTime * 1000);
+ desc.setThumbnail(thumbnail);
+ }
+
+ return desc;
+ }
+
+ return SaveStateDescriptor();
+} // End of namespace Toltecs
+
#if PLUGIN_ENABLED_DYNAMIC(DREAMWEB)
REGISTER_PLUGIN_DYNAMIC(DREAMWEB, PLUGIN_TYPE_ENGINE, DreamWebMetaEngine);
#else
diff --git a/engines/dreamweb/dreamweb.h b/engines/dreamweb/dreamweb.h
index 7ff0005fa4..4d7bf5f0e4 100644
--- a/engines/dreamweb/dreamweb.h
+++ b/engines/dreamweb/dreamweb.h
@@ -42,6 +42,10 @@
#include "dreamweb/structs.h"
+#define SCUMMVM_HEADER MKTAG('S', 'C', 'V', 'M')
+#define SCUMMVM_BLOCK_MAGIC_SIZE 0x1234
+#define SAVEGAME_VERSION 1
+
namespace DreamGen {
// These are for ReelRoutine::reelPointer, which is a callback field.
diff --git a/engines/dreamweb/saveload.cpp b/engines/dreamweb/saveload.cpp
index 9cf3ea2c63..599ef45c66 100644
--- a/engines/dreamweb/saveload.cpp
+++ b/engines/dreamweb/saveload.cpp
@@ -22,6 +22,7 @@
#include "dreamweb/dreamweb.h"
#include "engines/metaengine.h"
+#include "graphics/thumbnail.h"
#include "gui/saveload.h"
#include "common/config-manager.h"
#include "common/translation.h"
@@ -216,7 +217,6 @@ void DreamGenContext::saveGame() {
descbuf[++desclen] = 0;
while (desclen < 16)
descbuf[++desclen] = 1;
- savePosition(savegameId, descbuf);
// TODO: The below is copied from actualsave
getRidOfTemp();
@@ -225,6 +225,12 @@ void DreamGenContext::saveGame() {
data.word(kTextaddressy) = 182;
data.byte(kTextlen) = 240;
redrawMainScrn();
+ workToScreenCPP(); // show the main screen without the mouse pointer
+
+ // We need to save after the scene has been redrawn, to capture the
+ // correct screen thumbnail
+ savePosition(savegameId, descbuf);
+
workToScreenM();
data.byte(kGetback) = 4;
}
@@ -387,9 +393,6 @@ void DreamGenContext::savePosition(unsigned int slot, const char *descbuf) {
madeUpRoom.facing = data.byte(kFacing);
madeUpRoom.b27 = 255;
-
- engine->processEvents(); // TODO: Is this necessary?
-
Common::String filename = engine->getSavegameFilename(slot);
debug(1, "savePosition: slot %d filename %s", slot, filename.c_str());
Common::OutSaveFile *outSaveFile = engine->getSaveFileManager()->openForSaving(filename);
@@ -412,6 +415,11 @@ void DreamGenContext::savePosition(unsigned int slot, const char *descbuf) {
for (int i = 0; i < 6; ++i)
header.setLen(i, len[i]);
+ // Write a new section with data that we need for ScummVM (version,
+ // thumbnail, played time etc). We don't really care for its size,
+ // so we just set it to a magic number.
+ header.setLen(6, SCUMMVM_BLOCK_MAGIC_SIZE);
+
outSaveFile->write((const uint8 *)&header, sizeof(FileHeader));
outSaveFile->write(descbuf, len[0]);
outSaveFile->write(data.ptr(kStartvars, len[1]), len[1]);
@@ -429,6 +437,19 @@ void DreamGenContext::savePosition(unsigned int slot, const char *descbuf) {
}
outSaveFile->write(data.ptr(kReelroutines, len[5]), len[5]);
+ // ScummVM data block
+ outSaveFile->writeUint32BE(SCUMMVM_HEADER);
+ outSaveFile->writeByte(SAVEGAME_VERSION);
+ TimeDate curTime;
+ g_system->getTimeAndDate(curTime);
+ uint32 saveDate = ((curTime.tm_mday & 0xFF) << 24) | (((curTime.tm_mon + 1) & 0xFF) << 16) | ((curTime.tm_year + 1900) & 0xFFFF);
+ uint32 saveTime = ((curTime.tm_hour & 0xFF) << 16) | (((curTime.tm_min) & 0xFF) << 8) | ((curTime.tm_sec) & 0xFF);
+ uint32 playTime = g_engine->getTotalPlayTime() / 1000;
+ outSaveFile->writeUint32LE(saveDate);
+ outSaveFile->writeUint32LE(saveTime);
+ outSaveFile->writeUint32LE(playTime);
+ Graphics::saveThumbnail(*outSaveFile);
+
outSaveFile->finalize();
if (outSaveFile->err()) {
// TODO: Do proper error handling
@@ -482,6 +503,30 @@ void DreamGenContext::loadPosition(unsigned int slot) {
syncReelRoutine(s, (ReelRoutine*)data.ptr(kReelroutines + 8*i, 8));
}
+ // Check if there's a ScummVM data block
+ if (header.len(6) == SCUMMVM_BLOCK_MAGIC_SIZE) {
+ uint32 tag = inSaveFile->readUint32BE();
+ if (tag != SCUMMVM_HEADER) {
+ warning("ScummVM data block found, but the block header is incorrect - skipping");
+ delete inSaveFile;
+ return;
+ }
+
+ byte version = inSaveFile->readByte();
+ if (version > SAVEGAME_VERSION) {
+ warning("ScummVM data block found, but it has been saved with a newer version of ScummVM - skipping");
+ delete inSaveFile;
+ return;
+ }
+
+ inSaveFile->skip(4); // saveDate
+ inSaveFile->skip(4); // saveTime
+ uint32 playTime = inSaveFile->readUint32LE();
+ g_engine->setTotalPlayTime(playTime * 1000);
+
+ // The thumbnail data follows, but we don't need it here
+ }
+
delete inSaveFile;
}