aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorWalter van Niftrik2016-03-02 21:56:06 +0100
committerWalter van Niftrik2016-03-09 10:03:13 +0100
commit84a9f6ce95822efd2c2e0600daf2aeb27a841106 (patch)
treee6342bb1d439ae0563fc646e3d8201f5e47a4028
parentbaa2410a1cbe34606cbb6c0939a800edb09dfc65 (diff)
downloadscummvm-rg350-84a9f6ce95822efd2c2e0600daf2aeb27a841106.tar.gz
scummvm-rg350-84a9f6ce95822efd2c2e0600daf2aeb27a841106.tar.bz2
scummvm-rg350-84a9f6ce95822efd2c2e0600daf2aeb27a841106.zip
ADL: Add save game meta info support
-rw-r--r--engines/adl/adl.cpp73
-rw-r--r--engines/adl/adl.h2
-rw-r--r--engines/adl/detection.cpp70
3 files changed, 110 insertions, 35 deletions
diff --git a/engines/adl/adl.cpp b/engines/adl/adl.cpp
index 8ffb929e7a..633705f2db 100644
--- a/engines/adl/adl.cpp
+++ b/engines/adl/adl.cpp
@@ -33,6 +33,7 @@
#include "engines/util.h"
#include "graphics/palette.h"
+#include "graphics/thumbnail.h"
#include "adl/adl.h"
#include "adl/display.h"
@@ -86,7 +87,7 @@ Common::Error AdlEngine::run() {
int saveSlot = ConfMan.getInt("save_slot");
if (saveSlot >= 0) {
- if (!loadState(saveSlot))
+ if (loadGameState(saveSlot).getCode() != Common::kNoError)
error("Failed to load save game from slot %i", saveSlot);
_display->setCursorPos(Common::Point(0, 23));
_isRestoring = true;
@@ -297,11 +298,11 @@ void AdlEngine::doActions(const Command &command, byte noun, byte offset) {
++offset;
break;
case IDO_ACT_SAVE:
- saveState(0);
+ saveGameState(0, "");
++offset;
break;
case IDO_ACT_LOAD:
- loadState(0);
+ loadGameState(0);
++offset;
// Original engine continues processing here (?)
break;
@@ -528,13 +529,13 @@ void AdlEngine::showRoom() {
printMessage(curRoom().description, false);
}
-bool AdlEngine::saveState(uint slot, const Common::String *description) {
+Common::Error AdlEngine::saveGameState(int slot, const Common::String &desc) {
Common::String fileName = Common::String::format("%s.s%02d", _targetName.c_str(), slot);
Common::OutSaveFile *outFile = getSaveFileManager()->openForSaving(fileName);
if (!outFile) {
warning("Failed to open file '%s'", fileName.c_str());
- return false;
+ return Common::kUnknownError;
}
outFile->writeUint32BE(MKTAG('A', 'D', 'L', ':'));
@@ -542,8 +543,8 @@ bool AdlEngine::saveState(uint slot, const Common::String *description) {
char name[SAVEGAME_NAME_LEN] = { };
- if (description)
- strncpy(name, description->c_str(), sizeof(name) - 1);
+ if (!desc.empty())
+ strncpy(name, desc.c_str(), sizeof(name) - 1);
else {
Common::String defaultName("Save ");
defaultName += 'A' + slot;
@@ -552,6 +553,20 @@ bool AdlEngine::saveState(uint slot, const Common::String *description) {
outFile->write(name, sizeof(name));
+ TimeDate t;
+ g_system->getTimeAndDate(t);
+
+ outFile->writeUint16BE(t.tm_year);
+ outFile->writeByte(t.tm_mon);
+ outFile->writeByte(t.tm_mday);
+ outFile->writeByte(t.tm_hour);
+ outFile->writeByte(t.tm_min);
+
+ uint32 playTime = getTotalPlayTime();
+ outFile->writeUint32BE(playTime);
+
+ Graphics::saveThumbnail(*outFile);
+
outFile->writeByte(_state.room);
outFile->writeByte(_state.moves);
outFile->writeByte(_state.isDark);
@@ -580,38 +595,45 @@ bool AdlEngine::saveState(uint slot, const Common::String *description) {
if (outFile->err()) {
delete outFile;
warning("Failed to save game '%s'", fileName.c_str());
- return false;
+ return Common::kUnknownError;
}
delete outFile;
- return true;
+ return Common::kNoError;
}
-bool AdlEngine::loadState(uint slot) {
+Common::Error AdlEngine::loadGameState(int slot) {
Common::String fileName = Common::String::format("%s.s%02d", _targetName.c_str(), slot);
Common::InSaveFile *inFile = getSaveFileManager()->openForLoading(fileName);
if (!inFile) {
warning("Failed to open file '%s'", fileName.c_str());
- return false;
+ return Common::kUnknownError;
}
if (inFile->readUint32BE() != MKTAG('A', 'D', 'L', ':')) {
warning("No header found in '%s'", fileName.c_str());
delete inFile;
- return false;
+ return Common::kUnknownError;
}
byte saveVersion = inFile->readByte();
if (saveVersion != SAVEGAME_VERSION) {
warning("Save game version %i not supported", saveVersion);
delete inFile;
- return false;
+ return Common::kUnknownError;
}
- initState();
-
+ // Skip description
inFile->seek(SAVEGAME_NAME_LEN, SEEK_CUR);
+ // Skip save time
+ inFile->seek(6, SEEK_CUR);
+
+ uint32 playTime = inFile->readUint32BE();
+
+ Graphics::skipThumbnail(*inFile);
+
+ initState();
_state.room = inFile->readByte();
_state.moves = inFile->readByte();
@@ -649,7 +671,10 @@ bool AdlEngine::loadState(uint slot) {
error("Failed to load game '%s'", fileName.c_str());
delete inFile;
- return true;
+
+ setTotalPlayTime(playTime);
+
+ return Common::kNoError;
}
Room &AdlEngine::room(uint i) {
@@ -930,22 +955,6 @@ void AdlEngine::delay(uint32 ms) {
}
}
-Common::Error AdlEngine::loadGameState(int slot) {
- if (loadState(slot)) {
- _isRestoring = true;
- return Common::kNoError;
- }
-
- return Common::kUnknownError;
-}
-
-Common::Error AdlEngine::saveGameState(int slot, const Common::String &desc) {
- if (saveState(slot, &desc))
- return Common::kNoError;
-
- return Common::kUnknownError;
-}
-
AdlEngine *AdlEngine::create(GameType type, OSystem *syst, const AdlGameDescription *gd) {
switch(type) {
case kGameTypeHires1:
diff --git a/engines/adl/adl.h b/engines/adl/adl.h
index 4d160f08b0..f8b2dca1b7 100644
--- a/engines/adl/adl.h
+++ b/engines/adl/adl.h
@@ -237,8 +237,6 @@ protected:
private:
void printEngineMessage(EngineMessage);
- bool saveState(uint slot, const Common::String *description = nullptr);
- bool loadState(uint slot);
Common::String getTargetName() { return _targetName; }
byte convertKey(uint16 ascii);
diff --git a/engines/adl/detection.cpp b/engines/adl/detection.cpp
index 5fe469d20f..27ce5939a3 100644
--- a/engines/adl/detection.cpp
+++ b/engines/adl/detection.cpp
@@ -23,6 +23,8 @@
#include "common/system.h"
#include "common/savefile.h"
+#include "graphics/thumbnail.h"
+
#include "engines/advancedDetector.h"
#include "adl/adl.h"
@@ -73,8 +75,10 @@ public:
}
bool hasFeature(MetaEngineFeature f) const;
- int getMaximumSaveSlot() const { return 15; }
+ SaveStateDescriptor querySaveMetaInfos(const char *target, int slot) const;
+ int getMaximumSaveSlot() const { return 'O' - 'A'; }
SaveStateList listSaves(const char *target) const;
+ void removeSaveState(const char *target, int slot) const;
bool createInstance(OSystem *syst, Engine **engine, const ADGameDescription *gd) const;
};
@@ -83,17 +87,76 @@ bool AdlMetaEngine::hasFeature(MetaEngineFeature f) const {
switch(f) {
case kSupportsListSaves:
case kSupportsLoadingDuringStartup:
+ case kSupportsDeleteSave:
+ case kSavesSupportMetaInfo:
+ case kSavesSupportThumbnail:
+ case kSavesSupportCreationDate:
+ case kSavesSupportPlayTime:
return true;
default:
return false;
}
}
+SaveStateDescriptor AdlMetaEngine::querySaveMetaInfos(const char *target, int slot) const {
+ Common::String fileName = Common::String::format("%s.s%02d", target, slot);
+ Common::InSaveFile *inFile = g_system->getSavefileManager()->openForLoading(fileName);
+
+ if (!inFile)
+ return SaveStateDescriptor();
+
+ if (inFile->readUint32BE() != MKTAG('A', 'D', 'L', ':')) {
+ delete inFile;
+ return SaveStateDescriptor();
+ }
+
+ byte saveVersion = inFile->readByte();
+ if (saveVersion != SAVEGAME_VERSION) {
+ delete inFile;
+ return SaveStateDescriptor();
+ }
+
+ char name[SAVEGAME_NAME_LEN] = { };
+ inFile->read(name, sizeof(name) - 1);
+ inFile->readByte();
+
+ if (inFile->eos() || inFile->err()) {
+ delete inFile;
+ return SaveStateDescriptor();
+ }
+
+ SaveStateDescriptor sd(slot, name);
+
+ int year = inFile->readUint16BE();
+ int month = inFile->readByte();
+ int day = inFile->readByte();
+ sd.setSaveDate(year + 1900, month + 1, day);
+
+ int hour = inFile->readByte();
+ int minutes = inFile->readByte();
+ sd.setSaveTime(hour, minutes);
+
+ uint32 playTime = inFile->readUint32BE();
+ sd.setPlayTime(playTime);
+
+ if (inFile->eos() || inFile->err()) {
+ delete inFile;
+ return SaveStateDescriptor();
+ }
+
+ Graphics::Surface *const thumbnail = Graphics::loadThumbnail(*inFile);
+ sd.setThumbnail(thumbnail);
+
+ delete inFile;
+ return sd;
+}
+
SaveStateList AdlMetaEngine::listSaves(const char *target) const {
Common::SaveFileManager *saveFileMan = g_system->getSavefileManager();
Common::StringArray files = saveFileMan->listSavefiles(Common::String(target) + ".s##");
SaveStateList saveList;
+
for (uint i = 0; i < files.size(); ++i) {
const Common::String &fileName = files[i];
Common::InSaveFile *inFile = saveFileMan->openForLoading(fileName);
@@ -129,6 +192,11 @@ SaveStateList AdlMetaEngine::listSaves(const char *target) const {
return saveList;
}
+void AdlMetaEngine::removeSaveState(const char *target, int slot) const {
+ Common::String fileName = Common::String::format("%s.s%02d", target, slot);
+ g_system->getSavefileManager()->removeSavefile(fileName);
+}
+
bool AdlMetaEngine::createInstance(OSystem *syst, Engine **engine, const ADGameDescription *gd) const {
if (gd)
*engine = AdlEngine::create(((const AdlGameDescription *)gd)->gameType, syst, (const AdlGameDescription *)gd);