diff options
-rw-r--r-- | engines/kyra/detection.cpp | 20 | ||||
-rw-r--r-- | engines/metaengine.h | 20 | ||||
-rw-r--r-- | gui/launcher.cpp | 43 |
3 files changed, 78 insertions, 5 deletions
diff --git a/engines/kyra/detection.cpp b/engines/kyra/detection.cpp index 834f9f70c6..06d96d57bb 100644 --- a/engines/kyra/detection.cpp +++ b/engines/kyra/detection.cpp @@ -1068,6 +1068,7 @@ public: bool createInstance(OSystem *syst, Engine **engine, const Common::ADGameDescription *desc) const; SaveStateList listSaves(const char *target) const; void removeSaveState(const char *target, int slot) const; + Graphics::Surface *loadThumbnailFromSlot(const char *target, int slot) const; }; bool KyraMetaEngine::hasFeature(MetaEngineFeature f) const { @@ -1075,7 +1076,8 @@ bool KyraMetaEngine::hasFeature(MetaEngineFeature f) const { (f == kSupportsRTL) || (f == kSupportsListSaves) || (f == kSupportsDirectLoad) || - (f == kSupportsDeleteSave); + (f == kSupportsDeleteSave) || + (f == kSupportsThumbnails); } bool KyraMetaEngine::createInstance(OSystem *syst, Engine **engine, const Common::ADGameDescription *desc) const { @@ -1201,6 +1203,22 @@ void KyraMetaEngine::removeSaveState(const char *target, int slot) const { } +Graphics::Surface *KyraMetaEngine::loadThumbnailFromSlot(const char *target, int slot) const { + char extension[6]; + snprintf(extension, sizeof(extension), ".%03d", slot); + + Common::String filename = target; + filename += extension; + + Common::InSaveFile *in = g_system->getSavefileManager()->openForLoading(filename.c_str()); + Kyra::KyraEngine_v1::SaveHeader header; + + if (in && Kyra::KyraEngine_v1::readSaveHeader(in, true, header) == Kyra::KyraEngine_v1::kRSHENoError) + return header.thumbnail; + + return 0; +} + #if PLUGIN_ENABLED_DYNAMIC(KYRA) REGISTER_PLUGIN_DYNAMIC(KYRA, PLUGIN_TYPE_ENGINE, KyraMetaEngine); #else diff --git a/engines/metaengine.h b/engines/metaengine.h index b6fa21fd5f..f9a6c42cbc 100644 --- a/engines/metaengine.h +++ b/engines/metaengine.h @@ -106,6 +106,18 @@ public: */ virtual void removeSaveState(const char *target, int slot) const {}; + /** + * Loads a thumbnail from the specified save state. + * + * This can return '0' to indicate that no thumbnail was found. + * If it returns a valid Graphics::Surface object, it must be the same + * format as the overlay. + * + * @param target name of a config manager target + * @param slot slot number of the save state + */ + virtual Graphics::Surface *loadThumbnailFromSlot(const char *target, int slot) const { return 0; } + /** @name MetaEngineFeature flags */ //@{ @@ -131,7 +143,13 @@ public: * Deleting Saves from the Launcher (i.e. implements the * removeSaveState() method) */ - kSupportsDeleteSave = 3 + kSupportsDeleteSave = 3, + + /** + * Features a thumbnail in savegames (i.e. implements the + * loadThumbnailFromSlot method) + */ + kSupportsThumbnails = 4 }; /** diff --git a/gui/launcher.cpp b/gui/launcher.cpp index bb4a9dcb3c..3674da5a97 100644 --- a/gui/launcher.cpp +++ b/gui/launcher.cpp @@ -46,6 +46,7 @@ #include "gui/TabWidget.h" #include "gui/PopUpWidget.h" #include "graphics/cursorman.h" +#include "graphics/scaler.h" #include "sound/mididrv.h" @@ -539,6 +540,7 @@ int SaveLoadChooser::runModal(const EnginePlugin *plugin, const String &target) _plugin = plugin; _target = target; _delSupport = (*_plugin)->hasFeature(MetaEngine::kSupportsDeleteSave); + reflowLayout(); updateSaveList(); int ret = Dialog::runModal(); @@ -601,13 +603,48 @@ void SaveLoadChooser::handleCommand(CommandSender *sender, uint32 cmd, uint32 da } void SaveLoadChooser::reflowLayout() { - _container->setFlags(GUI::WIDGET_INVISIBLE); - _gfxWidget->setFlags(GUI::WIDGET_INVISIBLE); + if (g_gui.evaluator()->getVar("scummsaveload_extinfo.visible") == 1 && (_plugin && (*_plugin)->hasFeature(MetaEngine::kSupportsThumbnails))) { + int thumbX = g_gui.evaluator()->getVar("scummsaveload_thumbnail.x"); + int thumbY = g_gui.evaluator()->getVar("scummsaveload_thumbnail.y"); + int hPad = g_gui.evaluator()->getVar("scummsaveload_thumbnail.hPad"); + int vPad = g_gui.evaluator()->getVar("scummsaveload_thumbnail.vPad"); + int thumbH = ((g_system->getHeight() % 200 && g_system->getHeight() != 350) ? kThumbnailHeight2 : kThumbnailHeight1); + + _container->resize(thumbX - hPad, thumbY - vPad, kThumbnailWidth + hPad * 2, thumbH + vPad * 2/* + kLineHeight * 4*/); + + // Add the thumbnail display + _gfxWidget->resize(thumbX, thumbY, kThumbnailWidth, thumbH); + + _container->clearFlags(GUI::WIDGET_INVISIBLE); + _gfxWidget->clearFlags(GUI::WIDGET_INVISIBLE); + + _fillR = g_gui.evaluator()->getVar("scummsaveload_thumbnail.fillR"); + _fillG = g_gui.evaluator()->getVar("scummsaveload_thumbnail.fillG"); + _fillB = g_gui.evaluator()->getVar("scummsaveload_thumbnail.fillB"); + updateInfos(false); + } else { + _container->setFlags(GUI::WIDGET_INVISIBLE); + _gfxWidget->setFlags(GUI::WIDGET_INVISIBLE); + } + Dialog::reflowLayout(); } void SaveLoadChooser::updateInfos(bool redraw) { - _gfxWidget->setGfx(-1, -1, _fillR, _fillG, _fillB); + int selItem = _list->getSelected(); + Graphics::Surface *thumb = 0; + if (selItem >= 0 && !_list->getSelectedString().empty()) + thumb = (*_plugin)->loadThumbnailFromSlot(_target.c_str(), atoi(_saveList[selItem].save_slot().c_str())); + + if (thumb) { + _gfxWidget->setGfx(thumb); + _gfxWidget->useAlpha(256); + thumb->free(); + delete thumb; + } else { + _gfxWidget->setGfx(-1, -1, _fillR, _fillG, _fillB); + } + if (redraw) _gfxWidget->draw(); } |