aboutsummaryrefslogtreecommitdiff
path: root/engines/drascula/detection.cpp
diff options
context:
space:
mode:
authorFilippos Karapetis2013-01-04 13:02:17 +0200
committerFilippos Karapetis2013-01-04 13:12:52 +0200
commit4adfdb17e3dc757c5b430898458c2e1875377843 (patch)
tree5ec48467fccee9db85078d9021dd574dfa9c9bc9 /engines/drascula/detection.cpp
parent532dd09b21510e100eec65a3fd29c9f507a16e58 (diff)
downloadscummvm-rg350-4adfdb17e3dc757c5b430898458c2e1875377843.tar.gz
scummvm-rg350-4adfdb17e3dc757c5b430898458c2e1875377843.tar.bz2
scummvm-rg350-4adfdb17e3dc757c5b430898458c2e1875377843.zip
DRASCULA: Add advanced savegame functionality
This cleans up the save/load code and resolves multiple issues with the original save/load screen. Save game timestamps and thumbnails are now implemented, together with the ability to load a game from the launcher. F7 is now mapped to the ScummVM load dialog, and F10 to the save dialog (if the user has selected to use the ScummVM save screen).
Diffstat (limited to 'engines/drascula/detection.cpp')
-rw-r--r--engines/drascula/detection.cpp153
1 files changed, 100 insertions, 53 deletions
diff --git a/engines/drascula/detection.cpp b/engines/drascula/detection.cpp
index 598af5acff..573cad09e0 100644
--- a/engines/drascula/detection.cpp
+++ b/engines/drascula/detection.cpp
@@ -21,10 +21,13 @@
*/
#include "base/plugins.h"
+#include "common/file.h"
+#include "common/translation.h"
#include "engines/advancedDetector.h"
#include "engines/savestate.h"
-#include "common/file.h"
+
+#include "graphics/thumbnail.h"
#include "drascula/drascula.h"
@@ -263,81 +266,123 @@ static const DrasculaGameDescription gameDescriptions[] = {
{ AD_TABLE_END_MARKER }
};
-} // End of namespace Drascula
+static const ExtraGuiOption drasculaExtraGuiOption = {
+ _s("Use original save/load screens"),
+ _s("Use the original save/load screens, instead of the ScummVM ones"),
+ "originalsaveload",
+ false
+};
+
+SaveStateDescriptor loadMetaData(Common::ReadStream *s, int slot);
class DrasculaMetaEngine : public AdvancedMetaEngine {
public:
DrasculaMetaEngine() : AdvancedMetaEngine(Drascula::gameDescriptions, sizeof(Drascula::DrasculaGameDescription), drasculaGames) {
_singleid = "drascula";
- _guioptions = GUIO2(GUIO_NOMIDI, GUIO_NOLAUNCHLOAD);
+ _guioptions = GUIO1(GUIO_NOMIDI);
+ }
+
+ virtual const char *getName() const {
+ return "Drascula";
}
- virtual bool hasFeature(MetaEngineFeature f) const {
- return (f == kSupportsListSaves);
+ virtual const char *getOriginalCopyright() const {
+ return "Drascula Engine (C) 2000 Alcachofa Soft, (C) 1996 Digital Dreams Multimedia, (C) 1994 Emilio de Paz";
}
- virtual SaveStateList listSaves(const char *target) const {
- Common::SaveFileManager *saveFileMan = g_system->getSavefileManager();
- Common::String pattern = Common::String::format("%s??", target);
+ virtual bool createInstance(OSystem *syst, Engine **engine, const ADGameDescription *gd) const;
+ virtual bool hasFeature(MetaEngineFeature f) const;
+ virtual const ExtraGuiOptions getExtraGuiOptions(const Common::String &target) const;
+ 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;
+};
- // Get list of savefiles for target game
- Common::StringArray filenames = saveFileMan->listSavefiles(pattern);
- Common::Array<int> slots;
- for (Common::StringArray::const_iterator file = filenames.begin(); file != filenames.end(); ++file) {
+bool DrasculaMetaEngine::hasFeature(MetaEngineFeature f) const {
+ return
+ (f == kSupportsListSaves) ||
+ (f == kSupportsLoadingDuringStartup) ||
+ (f == kSupportsDeleteSave) ||
+ (f == kSavesSupportMetaInfo) ||
+ (f == kSavesSupportThumbnail) ||
+ (f == kSavesSupportCreationDate) ||
+ (f == kSavesSupportPlayTime);
+}
- // Obtain the last 2 digits of the filename, since they correspond to the save slot
- int slotNum = atoi(file->c_str() + file->size() - 2);
+const ExtraGuiOptions DrasculaMetaEngine::getExtraGuiOptions(const Common::String &target) const {
+ ExtraGuiOptions options;
+ options.push_back(drasculaExtraGuiOption);
+ return options;
+}
- // Ensure save slot is within valid range
- if (slotNum >= 1 && slotNum <= 10) {
- slots.push_back(slotNum);
+SaveStateList DrasculaMetaEngine::listSaves(const char *target) const {
+ Common::SaveFileManager *saveFileMan = g_system->getSavefileManager();
+ Common::StringArray filenames;
+ Common::String pattern = target;
+ pattern += ".???";
+
+ filenames = saveFileMan->listSavefiles(pattern);
+ sort(filenames.begin(), filenames.end()); // Sort (hopefully ensuring we are sorted numerically..)
+
+ SaveStateList saveList;
+ int slotNum = 0;
+ for (Common::StringArray::const_iterator file = filenames.begin(); file != filenames.end(); ++file) {
+ // Obtain the last 3 digits of the filename, since they correspond to the save slot
+ slotNum = atoi(file->c_str() + file->size() - 3);
+
+ if (slotNum >= 0 && slotNum <= getMaximumSaveSlot()) {
+ Common::InSaveFile *in = saveFileMan->openForLoading(*file);
+ if (in) {
+ SaveStateDescriptor desc = loadMetaData(in, slotNum);
+ if (desc.getSaveSlot() != slotNum) {
+ // invalid
+ delete in;
+ continue;
+ }
+ saveList.push_back(desc);
+ delete in;
}
}
+ }
- // Sort save slot ids
- Common::sort<int>(slots.begin(), slots.end());
-
- // Load save index
- Common::String fileEpa = Common::String::format("%s.epa", target);
- Common::InSaveFile *epa = saveFileMan->openForLoading(fileEpa);
-
- // Get savegame names from index
- Common::String saveDesc;
- SaveStateList saveList;
- int line = 1;
- for (uint i = 0; i < slots.size(); i++) {
- // ignore lines corresponding to unused saveslots
- for (; line < slots[i]; line++)
- epa->readLine();
+ return saveList;
+}
- // copy the name in the line corresponding to the save slot and truncate to 22 characters
- saveDesc = Common::String(epa->readLine().c_str(), 22);
+SaveStateDescriptor DrasculaMetaEngine::querySaveMetaInfos(const char *target, int slot) const {
+ char fileName[MAXPATHLEN];
+ sprintf(fileName, "%s.%03d", target, slot);
- // handle cases where the save directory and save index are detectably out of sync
- if (saveDesc == "*")
- saveDesc = "No name specified.";
+ Common::InSaveFile *in = g_system->getSavefileManager()->openForLoading(fileName);
- // increment line number to keep it in sync with slot number
- line++;
+ SaveStateDescriptor desc;
+ // Do not allow save slot 0 (used for auto-saving) to be deleted or
+ // overwritten.
+ desc.setDeletableFlag(slot != 0);
+ desc.setWriteProtectedFlag(slot == 0);
- // Insert savegame name into list
- saveList.push_back(SaveStateDescriptor(slots[i], saveDesc));
+ if (in) {
+ desc = Drascula::loadMetaData(in, slot);
+ if (desc.getSaveSlot() != slot) {
+ delete in;
+ return SaveStateDescriptor();
}
- delete epa;
- return saveList;
- }
+ Graphics::Surface *const thumbnail = Graphics::loadThumbnail(*in);
+ desc.setThumbnail(thumbnail);
- virtual const char *getName() const {
- return "Drascula";
+ delete in;
}
- virtual const char *getOriginalCopyright() const {
- return "Drascula Engine (C) 2000 Alcachofa Soft, (C) 1996 Digital Dreams Multimedia, (C) 1994 Emilio de Paz";
- }
+ return desc;
+}
- virtual bool createInstance(OSystem *syst, Engine **engine, const ADGameDescription *desc) const;
-};
+int DrasculaMetaEngine::getMaximumSaveSlot() const { return 999; }
+
+void DrasculaMetaEngine::removeSaveState(const char *target, int slot) const {
+ Common::String fileName = Common::String::format("%s.%03d", target, slot);
+ g_system->getSavefileManager()->removeSavefile(fileName);
+}
bool DrasculaMetaEngine::createInstance(OSystem *syst, Engine **engine, const ADGameDescription *desc) const {
const Drascula::DrasculaGameDescription *gd = (const Drascula::DrasculaGameDescription *)desc;
@@ -347,8 +392,10 @@ bool DrasculaMetaEngine::createInstance(OSystem *syst, Engine **engine, const AD
return gd != 0;
}
+} // End of namespace Drascula
+
#if PLUGIN_ENABLED_DYNAMIC(DRASCULA)
- REGISTER_PLUGIN_DYNAMIC(DRASCULA, PLUGIN_TYPE_ENGINE, DrasculaMetaEngine);
+ REGISTER_PLUGIN_DYNAMIC(DRASCULA, PLUGIN_TYPE_ENGINE, Drascula::DrasculaMetaEngine);
#else
- REGISTER_PLUGIN_STATIC(DRASCULA, PLUGIN_TYPE_ENGINE, DrasculaMetaEngine);
+ REGISTER_PLUGIN_STATIC(DRASCULA, PLUGIN_TYPE_ENGINE, Drascula::DrasculaMetaEngine);
#endif