aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--engines/kyra/detection.cpp20
-rw-r--r--engines/metaengine.h20
-rw-r--r--gui/launcher.cpp43
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();
}