diff --git a/base/commandLine.cpp b/base/commandLine.cpp index 39d4028e423..da8356acff8 100644 --- a/base/commandLine.cpp +++ b/base/commandLine.cpp @@ -663,9 +663,6 @@ bool processSettings(Common::String &command, Common::StringMap &settings) { // Handle commands passed via the command line (like --list-targets and // --list-games). This must be done after the config file and the plugins // have been loaded. - // FIXME: The way are are doing this is rather arbitrary at this time. - // E.g. --version and --help are very similar, but are still handled - // inside parseCommandLine. This should be unified. if (command == "list-targets") { listTargets(); return false; diff --git a/base/game.cpp b/base/game.cpp index 9aaaf3a6af6..a79cfddec9b 100644 --- a/base/game.cpp +++ b/base/game.cpp @@ -25,6 +25,8 @@ #include "base/game.h" #include "base/plugins.h" +#include "graphics/surface.h" + const PlainGameDescriptor *findPlainGameDescriptor(const char *gameid, const PlainGameDescriptor *list) { const PlainGameDescriptor *g = list; @@ -66,6 +68,15 @@ void GameDescriptor::updateDesc(const char *extra) { } } +void SaveStateDescriptor::setThumbnail(Graphics::Surface *t) { + if (_thumbnail && _thumbnail != t) { + _thumbnail->free(); + delete _thumbnail; + } + _thumbnail = t; +} + + namespace Base { // TODO: Find a better name & place for this function. diff --git a/base/game.h b/base/game.h index 0764b7fbaca..64e14c52dce 100644 --- a/base/game.h +++ b/base/game.h @@ -30,6 +30,10 @@ #include "common/array.h" #include "common/hash-str.h" +namespace Graphics { + class Surface; +} + /** * A simple structure used to map gameids (like "monkey", "sword1", ...) to * nice human readable and descriptive game titles (like "The Secret of Monkey Island"). @@ -67,7 +71,7 @@ public: setVal("description", pgd.description); } - GameDescriptor(Common::String g, Common::String d, Common::Language l = Common::UNK_LANG, + GameDescriptor(const Common::String &g, const Common::String &d, Common::Language l = Common::UNK_LANG, Common::Platform p = Common::kPlatformUnknown) { setVal("gameid", g); setVal("description", d); @@ -103,6 +107,61 @@ public: } }; +/** + * A hashmap describing details about a given save state. + * TODO + * Guaranteed to contain save_slot and description values. + * Additional ideas: Playtime, creation date, thumbnail, ... + */ +class SaveStateDescriptor : public Common::StringMap { +protected: + Graphics::Surface *_thumbnail; // can be NULL +public: + SaveStateDescriptor() : _thumbnail(0) { + setVal("save_slot", "-1"); // FIXME: default to 0 (first slot) or to -1 (invalid slot) ? + setVal("description", ""); + } + + SaveStateDescriptor(const Common::String &s, const Common::String &d) : _thumbnail(0) { + setVal("save_slot", s); + setVal("description", d); + } + + ~SaveStateDescriptor() { + setThumbnail(0); + } + + /** The saveslot id, as it would be passed to the "-x" command line switch. */ + Common::String &slot() { return getVal("save_slot"); } + + /** The saveslot id, as it would be passed to the "-x" command line switch (read-only variant). */ + const Common::String &slot() const { return getVal("save_slot"); } + + /** A human readable description of the save state. */ + Common::String &description() { return getVal("description"); } + + /** A human readable description of the save state (read-only variant). */ + const Common::String &description() const { return getVal("description"); } + + /** + * Return a thumbnail graphics surface representing the savestate visually + * This is usually a scaled down version of the game graphics. The size + * should be either 160x100 or 160x120 pixels, depending on the aspect + * ratio of the game. If another ratio is required, contact the core team. + * + * TODO: it is probably a bad idea to read this for *all* games at once, + * at least on low-end devices. So this info should probably normally only + * be included optionally. I.e. only upon a query for a specific savegame... + * To this end, add a getFullSaveStateInfo(target, slot) to the plugin API. + */ + const Graphics::Surface *getThumbnail() const { return _thumbnail; } + + + void setThumbnail(Graphics::Surface *t); +}; + +/** List of savestates. */ +typedef Common::Array SaveStateList; class Plugin; diff --git a/base/plugins.cpp b/base/plugins.cpp index 7ccd99ce34a..1ef475778ca 100644 --- a/base/plugins.cpp +++ b/base/plugins.cpp @@ -62,6 +62,11 @@ public: assert(_plugin->_df); return (*_plugin->_df)(fslist); } + + SaveStateList listSaves(const char *target) const { + assert(_plugin->_lsf); + return (*_plugin->_lsf)(target); + } }; class StaticPluginProvider : public PluginProvider { diff --git a/base/plugins.h b/base/plugins.h index 23a28b745c3..a67fd8297de 100644 --- a/base/plugins.h +++ b/base/plugins.h @@ -59,6 +59,7 @@ class Plugin { public: virtual ~Plugin() {} +// virtual bool isLoaded() const = 0; // TODO virtual bool loadPlugin() = 0; virtual void unloadPlugin() = 0; @@ -70,6 +71,8 @@ public: virtual GameDescriptor findGame(const char *gameid) const = 0; virtual GameList detectGames(const FSList &fslist) const = 0; + virtual SaveStateList listSaves(const char *target) const = 0; + virtual PluginError createInstance(OSystem *syst, Engine **engine) const = 0; }; @@ -106,7 +109,8 @@ public: Engine_##ID##_gameIDList(), \ Engine_##ID##_findGameID, \ Engine_##ID##_create, \ - Engine_##ID##_detectGames \ + Engine_##ID##_detectGames, \ + Engine_##ID##_listSaves \ );\ } \ void dummyFuncToAllowTrailingSemicolon() @@ -119,6 +123,7 @@ public: PLUGIN_EXPORT GameDescriptor PLUGIN_findGameID(const char *gameid) { return Engine_##ID##_findGameID(gameid); } \ PLUGIN_EXPORT PluginError PLUGIN_createEngine(OSystem *syst, Engine **engine) { return Engine_##ID##_create(syst, engine); } \ PLUGIN_EXPORT GameList PLUGIN_detectGames(const FSList &fslist) { return Engine_##ID##_detectGames(fslist); } \ + PLUGIN_EXPORT SaveStateList PLUGIN_listSaves(const char *target) { return Engine_##ID##_listSaves(target); } \ } \ void dummyFuncToAllowTrailingSemicolon() #endif @@ -134,6 +139,7 @@ public: typedef GameDescriptor (*GameIDQueryFunc)(const char *gameid); typedef PluginError (*EngineFactory)(OSystem *syst, Engine **engine); typedef GameList (*DetectFunc)(const FSList &fslist); + typedef SaveStateList (*ListSavesFunc)(const char *target); protected: const char *_name; @@ -141,11 +147,12 @@ protected: GameIDQueryFunc _qf; EngineFactory _ef; DetectFunc _df; + ListSavesFunc _lsf; GameList _games; public: - PluginRegistrator(const char *name, const char *copyright, GameList games, GameIDQueryFunc qf, EngineFactory ef, DetectFunc df) - : _name(name), _copyright(copyright), _qf(qf), _ef(ef), _df(df), _games(games) {} + PluginRegistrator(const char *name, const char *copyright, GameList games, GameIDQueryFunc qf, EngineFactory ef, DetectFunc df, ListSavesFunc lsf) + : _name(name), _copyright(copyright), _qf(qf), _ef(ef), _df(df), _lsf(lsf), _games(games) {} }; #endif