Added "querySaveMetaInfos" to MetaEngine.
-> Allows easy addition of save state specific infos like playtime, save date atc. -> Removed MetaEngine::loadThumbnailFromSlot, superseded by meta infos -> Changed SCUMM / KYRA to implement the newly added functionallity -> Removed hack in KYRAs listSavefiles, which is now handled via meta infos svn-id: r34581
This commit is contained in:
parent
9d96d9d380
commit
259d87a8a6
9 changed files with 170 additions and 76 deletions
|
@ -69,9 +69,30 @@ void GameDescriptor::updateDesc(const char *extra) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void SaveStateDescriptor::setThumbnail(Graphics::Surface *t) {
|
void SaveStateDescriptor::setThumbnail(Graphics::Surface *t) {
|
||||||
if (_thumbnail && _thumbnail != t) {
|
if (_thumbnail.get() == t)
|
||||||
_thumbnail->free();
|
return;
|
||||||
delete _thumbnail;
|
|
||||||
}
|
_thumbnail = Common::SharedPtr<Graphics::Surface>(t, Graphics::SharedPtrSurfaceDeleter());
|
||||||
_thumbnail = t;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool SaveStateDescriptor::getBool(const Common::String &key) const {
|
||||||
|
if (contains(key)) {
|
||||||
|
Common::String value = getVal(key);
|
||||||
|
if (value.equalsIgnoreCase("true") ||
|
||||||
|
value.equalsIgnoreCase("yes") ||
|
||||||
|
value.equals("1"))
|
||||||
|
return true;
|
||||||
|
if (value.equalsIgnoreCase("false") ||
|
||||||
|
value.equalsIgnoreCase("no") ||
|
||||||
|
value.equals("0"))
|
||||||
|
return false;
|
||||||
|
error("SaveStateDescriptor: %s '%s' has unknown value '%s' for boolean '%s'",
|
||||||
|
save_slot().c_str(), description().c_str(), value.c_str(), key.c_str());
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
void SaveStateDescriptor::setDeletableFlag(bool state) {
|
||||||
|
setVal("is_deletable", state ? "true" : "false");
|
||||||
|
}
|
||||||
|
|
||||||
|
|
39
base/game.h
39
base/game.h
|
@ -29,6 +29,7 @@
|
||||||
#include "common/str.h"
|
#include "common/str.h"
|
||||||
#include "common/array.h"
|
#include "common/array.h"
|
||||||
#include "common/hash-str.h"
|
#include "common/hash-str.h"
|
||||||
|
#include "common/ptr.h"
|
||||||
|
|
||||||
namespace Graphics {
|
namespace Graphics {
|
||||||
struct Surface;
|
struct Surface;
|
||||||
|
@ -119,15 +120,16 @@ public:
|
||||||
*/
|
*/
|
||||||
class SaveStateDescriptor : public Common::StringMap {
|
class SaveStateDescriptor : public Common::StringMap {
|
||||||
protected:
|
protected:
|
||||||
Graphics::Surface *_thumbnail; // can be NULL
|
Common::SharedPtr<Graphics::Surface> _thumbnail; // can be 0
|
||||||
|
|
||||||
public:
|
public:
|
||||||
SaveStateDescriptor() : _thumbnail(0) {
|
SaveStateDescriptor() : _thumbnail() {
|
||||||
setVal("save_slot", "-1"); // FIXME: default to 0 (first slot) or to -1 (invalid slot) ?
|
setVal("save_slot", "-1"); // FIXME: default to 0 (first slot) or to -1 (invalid slot) ?
|
||||||
setVal("description", "");
|
setVal("description", "");
|
||||||
setVal("filename", "");
|
setVal("filename", "");
|
||||||
}
|
}
|
||||||
|
|
||||||
SaveStateDescriptor(int s, const Common::String &d, const Common::String &f) : _thumbnail(0) {
|
SaveStateDescriptor(int s, const Common::String &d, const Common::String &f) : _thumbnail() {
|
||||||
char buf[16];
|
char buf[16];
|
||||||
sprintf(buf, "%d", s);
|
sprintf(buf, "%d", s);
|
||||||
setVal("save_slot", buf);
|
setVal("save_slot", buf);
|
||||||
|
@ -135,16 +137,12 @@ public:
|
||||||
setVal("filename", f);
|
setVal("filename", f);
|
||||||
}
|
}
|
||||||
|
|
||||||
SaveStateDescriptor(const Common::String &s, const Common::String &d, const Common::String &f) : _thumbnail(0) {
|
SaveStateDescriptor(const Common::String &s, const Common::String &d, const Common::String &f) : _thumbnail() {
|
||||||
setVal("save_slot", s);
|
setVal("save_slot", s);
|
||||||
setVal("description", d);
|
setVal("description", d);
|
||||||
setVal("filename", f);
|
setVal("filename", f);
|
||||||
}
|
}
|
||||||
|
|
||||||
~SaveStateDescriptor() {
|
|
||||||
setThumbnail(0);
|
|
||||||
}
|
|
||||||
|
|
||||||
/** The saveslot id, as it would be passed to the "-x" command line switch. */
|
/** The saveslot id, as it would be passed to the "-x" command line switch. */
|
||||||
Common::String &save_slot() { return getVal("save_slot"); }
|
Common::String &save_slot() { return getVal("save_slot"); }
|
||||||
|
|
||||||
|
@ -163,19 +161,30 @@ public:
|
||||||
/** The filename of the savestate, for use with the SaveFileManager API (read-only variant). */
|
/** The filename of the savestate, for use with the SaveFileManager API (read-only variant). */
|
||||||
const Common::String &filename() const { return getVal("filename"); }
|
const Common::String &filename() const { return getVal("filename"); }
|
||||||
|
|
||||||
|
/** Optional entries only included when querying via MetaEngine::querySaveMetaInfo */
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the value of a given key as boolean.
|
||||||
|
* It accepts 'true', 'yes' and '1' for true and
|
||||||
|
* 'false', 'no' and '0' for false.
|
||||||
|
* (FIXME:) On unknown value it errors out ScummVM.
|
||||||
|
* On unknown key it returns false as default.
|
||||||
|
*/
|
||||||
|
bool getBool(const Common::String &key) const;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the 'is_deletable' key, which indicates, if the
|
||||||
|
* given savestate is safe for deletion.
|
||||||
|
*/
|
||||||
|
void setDeletableFlag(bool state);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Return a thumbnail graphics surface representing the savestate visually
|
* Return a thumbnail graphics surface representing the savestate visually
|
||||||
* This is usually a scaled down version of the game graphics. The size
|
* This is usually a scaled down version of the game graphics. The size
|
||||||
* should be either 160x100 or 160x120 pixels, depending on the aspect
|
* should be either 160x100 or 160x120 pixels, depending on the aspect
|
||||||
* ratio of the game. If another ratio is required, contact the core team.
|
* 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; }
|
const Graphics::Surface *getThumbnail() const { return _thumbnail.get(); }
|
||||||
|
|
||||||
|
|
||||||
void setThumbnail(Graphics::Surface *t);
|
void setThumbnail(Graphics::Surface *t);
|
||||||
};
|
};
|
||||||
|
|
|
@ -1068,7 +1068,7 @@ public:
|
||||||
bool createInstance(OSystem *syst, Engine **engine, const Common::ADGameDescription *desc) const;
|
bool createInstance(OSystem *syst, Engine **engine, const Common::ADGameDescription *desc) const;
|
||||||
SaveStateList listSaves(const char *target) const;
|
SaveStateList listSaves(const char *target) const;
|
||||||
void removeSaveState(const char *target, int slot) const;
|
void removeSaveState(const char *target, int slot) const;
|
||||||
Graphics::Surface *loadThumbnailFromSlot(const char *target, int slot) const;
|
SaveStateDescriptor querySaveMetaInfos(const char *target, int slot) const;
|
||||||
};
|
};
|
||||||
|
|
||||||
bool KyraMetaEngine::hasFeature(MetaEngineFeature f) const {
|
bool KyraMetaEngine::hasFeature(MetaEngineFeature f) const {
|
||||||
|
@ -1077,6 +1077,7 @@ bool KyraMetaEngine::hasFeature(MetaEngineFeature f) const {
|
||||||
(f == kSupportsListSaves) ||
|
(f == kSupportsListSaves) ||
|
||||||
(f == kSupportsDirectLoad) ||
|
(f == kSupportsDirectLoad) ||
|
||||||
(f == kSupportsDeleteSave) ||
|
(f == kSupportsDeleteSave) ||
|
||||||
|
(f == kSupportsMetaInfos) ||
|
||||||
(f == kSupportsThumbnails);
|
(f == kSupportsThumbnails);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1137,10 +1138,7 @@ SaveStateList KyraMetaEngine::listSaves(const char *target) const {
|
||||||
// Obtain the last 3 digits of the filename, since they correspond to the save slot
|
// Obtain the last 3 digits of the filename, since they correspond to the save slot
|
||||||
int slotNum = atoi(file->c_str() + file->size() - 3);
|
int slotNum = atoi(file->c_str() + file->size() - 3);
|
||||||
|
|
||||||
// HACK: Until we have a way to check whether a save is deletable in our launcher delete savegame dialog.
|
if (slotNum >= 0 && slotNum <= 999) {
|
||||||
// We do not list slot 0 here, since it's for restarting the game and it should never be deleted.
|
|
||||||
// The downside of it is of course we can not load it via the menu and it isn't listed via --list-saves.
|
|
||||||
if (slotNum > 0 && slotNum <= 999) {
|
|
||||||
Common::InSaveFile *in = saveFileMan->openForLoading(file->c_str());
|
Common::InSaveFile *in = saveFileMan->openForLoading(file->c_str());
|
||||||
if (in) {
|
if (in) {
|
||||||
if (Kyra::KyraEngine_v1::readSaveHeader(in, false, header) == Kyra::KyraEngine_v1::kRSHENoError) {
|
if (Kyra::KyraEngine_v1::readSaveHeader(in, false, header) == Kyra::KyraEngine_v1::kRSHENoError) {
|
||||||
|
@ -1194,16 +1192,28 @@ void KyraMetaEngine::removeSaveState(const char *target, int slot) const {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Graphics::Surface *KyraMetaEngine::loadThumbnailFromSlot(const char *target, int slot) const {
|
SaveStateDescriptor KyraMetaEngine::querySaveMetaInfos(const char *target, int slot) const {
|
||||||
Common::String filename = Kyra::KyraEngine_v1::getSavegameFilename(target, slot);
|
Common::String filename = Kyra::KyraEngine_v1::getSavegameFilename(target, slot);
|
||||||
|
|
||||||
Common::InSaveFile *in = g_system->getSavefileManager()->openForLoading(filename.c_str());
|
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)
|
if (in) {
|
||||||
return header.thumbnail;
|
Kyra::KyraEngine_v1::SaveHeader header;
|
||||||
|
Kyra::KyraEngine_v1::kReadSaveHeaderError error;
|
||||||
|
|
||||||
|
error = Kyra::KyraEngine_v1::readSaveHeader(in, true, header);
|
||||||
|
delete in;
|
||||||
|
|
||||||
|
if (error == Kyra::KyraEngine_v1::kRSHENoError) {
|
||||||
|
SaveStateDescriptor desc(slot, header.description, filename);
|
||||||
|
|
||||||
|
desc.setDeletableFlag(slot != 0);
|
||||||
|
desc.setThumbnail(header.thumbnail);
|
||||||
|
|
||||||
|
return desc;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return 0;
|
return SaveStateDescriptor();
|
||||||
}
|
}
|
||||||
|
|
||||||
#if PLUGIN_ENABLED_DYNAMIC(KYRA)
|
#if PLUGIN_ENABLED_DYNAMIC(KYRA)
|
||||||
|
|
|
@ -107,18 +107,16 @@ public:
|
||||||
virtual void removeSaveState(const char *target, int slot) const {};
|
virtual void removeSaveState(const char *target, int slot) const {};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Loads a thumbnail from the specified save state.
|
* Returns meta infos from the specified save state.
|
||||||
*
|
*
|
||||||
* This can return '0' to indicate that no thumbnail was found.
|
* Depending on the MetaEngineFeatures set this can include
|
||||||
* If it returns a valid Graphics::Surface object, it must be the same
|
* thumbnails, save date / time, play time.
|
||||||
* format as the overlay.
|
|
||||||
*
|
*
|
||||||
* @param target name of a config manager target
|
* @param target name of a config manager target
|
||||||
* @param slot slot number of the save state
|
* @param slot slot number of the save state
|
||||||
*/
|
*/
|
||||||
virtual Graphics::Surface *loadThumbnailFromSlot(const char *target, int slot) const { return 0; }
|
virtual SaveStateDescriptor querySaveMetaInfos(const char *target, int slot) const { return SaveStateDescriptor(); }
|
||||||
|
|
||||||
|
|
||||||
/** @name MetaEngineFeature flags */
|
/** @name MetaEngineFeature flags */
|
||||||
//@{
|
//@{
|
||||||
|
|
||||||
|
@ -146,10 +144,17 @@ public:
|
||||||
kSupportsDeleteSave = 3,
|
kSupportsDeleteSave = 3,
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Features a thumbnail in savegames (i.e. implements the
|
* Features meta infos for savestates (i.e. implements the
|
||||||
* loadThumbnailFromSlot method)
|
* querySaveMetaInfos method properly)
|
||||||
*/
|
*/
|
||||||
kSupportsThumbnails = 4
|
kSupportsMetaInfos = 4,
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Features a thumbnail in savegames (i.e. includes a thumbnail
|
||||||
|
* in savestates returned via querySaveMetaInfo). This flag may
|
||||||
|
* only be set when 'kSupportsMetaInfos' is set.
|
||||||
|
*/
|
||||||
|
kSupportsThumbnails = 5
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -683,7 +683,7 @@ public:
|
||||||
|
|
||||||
virtual SaveStateList listSaves(const char *target) const;
|
virtual SaveStateList listSaves(const char *target) const;
|
||||||
virtual void removeSaveState(const char *target, int slot) const;
|
virtual void removeSaveState(const char *target, int slot) const;
|
||||||
virtual Graphics::Surface *loadThumbnailFromSlot(const char *target, int slot) const;
|
virtual SaveStateDescriptor querySaveMetaInfos(const char *target, int slot) const;
|
||||||
};
|
};
|
||||||
|
|
||||||
bool ScummMetaEngine::hasFeature(MetaEngineFeature f) const {
|
bool ScummMetaEngine::hasFeature(MetaEngineFeature f) const {
|
||||||
|
@ -692,6 +692,7 @@ bool ScummMetaEngine::hasFeature(MetaEngineFeature f) const {
|
||||||
(f == kSupportsListSaves) ||
|
(f == kSupportsListSaves) ||
|
||||||
(f == kSupportsDirectLoad) ||
|
(f == kSupportsDirectLoad) ||
|
||||||
(f == kSupportsDeleteSave) ||
|
(f == kSupportsDeleteSave) ||
|
||||||
|
(f == kSupportsMetaInfos) ||
|
||||||
(f == kSupportsThumbnails);
|
(f == kSupportsThumbnails);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -983,8 +984,25 @@ void ScummMetaEngine::removeSaveState(const char *target, int slot) const {
|
||||||
g_system->getSavefileManager()->removeSavefile(filename.c_str());
|
g_system->getSavefileManager()->removeSavefile(filename.c_str());
|
||||||
}
|
}
|
||||||
|
|
||||||
Graphics::Surface *ScummMetaEngine::loadThumbnailFromSlot(const char *target, int slot) const {
|
SaveStateDescriptor ScummMetaEngine::querySaveMetaInfos(const char *target, int slot) const {
|
||||||
return ScummEngine::loadThumbnailFromSlot(target, slot);
|
Common::String filename = ScummEngine::makeSavegameName(target, slot, false);
|
||||||
|
Common::InSaveFile *in = g_system->getSavefileManager()->openForLoading(filename.c_str());
|
||||||
|
|
||||||
|
if (!in)
|
||||||
|
return SaveStateDescriptor();
|
||||||
|
|
||||||
|
Common::String saveDesc;
|
||||||
|
Scumm::getSavegameName(in, saveDesc, 0); // FIXME: heversion?!?
|
||||||
|
delete in;
|
||||||
|
|
||||||
|
// TODO: Cleanup
|
||||||
|
Graphics::Surface *thumbnail = ScummEngine::loadThumbnailFromSlot(target, slot);
|
||||||
|
|
||||||
|
SaveStateDescriptor desc(slot, saveDesc, filename);
|
||||||
|
desc.setDeletableFlag(true);
|
||||||
|
desc.setThumbnail(thumbnail);
|
||||||
|
|
||||||
|
return desc;
|
||||||
}
|
}
|
||||||
|
|
||||||
#if PLUGIN_ENABLED_DYNAMIC(SCUMM)
|
#if PLUGIN_ENABLED_DYNAMIC(SCUMM)
|
||||||
|
|
|
@ -66,6 +66,11 @@ void Surface::free() {
|
||||||
bytesPerPixel = 0;
|
bytesPerPixel = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Surface::copyFrom(const Surface &surf) {
|
||||||
|
create(surf.w, surf.h, surf.bytesPerPixel);
|
||||||
|
memcpy(pixels, surf.pixels, h * pitch);
|
||||||
|
}
|
||||||
|
|
||||||
void Surface::hLine(int x, int y, int x2, uint32 color) {
|
void Surface::hLine(int x, int y, int x2, uint32 color) {
|
||||||
// Clipping
|
// Clipping
|
||||||
if (y < 0 || y >= h)
|
if (y < 0 || y >= h)
|
||||||
|
|
|
@ -30,7 +30,6 @@
|
||||||
|
|
||||||
namespace Graphics {
|
namespace Graphics {
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* An arbitrary graphics surface, which can be the target (or source) of blit
|
* An arbitrary graphics surface, which can be the target (or source) of blit
|
||||||
* operations, font rendering, etc.
|
* operations, font rendering, etc.
|
||||||
|
@ -67,6 +66,12 @@ struct Surface {
|
||||||
*/
|
*/
|
||||||
void free();
|
void free();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Copies data from another Surface, this calls *free* on the current surface, to assure
|
||||||
|
* it being clean.
|
||||||
|
*/
|
||||||
|
void copyFrom(const Surface &surf);
|
||||||
|
|
||||||
void drawLine(int x0, int y0, int x1, int y1, uint32 color);
|
void drawLine(int x0, int y0, int x1, int y1, uint32 color);
|
||||||
void hLine(int x, int y, int x2, uint32 color);
|
void hLine(int x, int y, int x2, uint32 color);
|
||||||
void vLine(int x, int y, int y2, uint32 color);
|
void vLine(int x, int y, int y2, uint32 color);
|
||||||
|
@ -76,6 +81,18 @@ struct Surface {
|
||||||
void move(int dx, int dy, int height);
|
void move(int dx, int dy, int height);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* For safe deletion of surface with SharedPtr.
|
||||||
|
* The deleter assures Surface::free is called on
|
||||||
|
* deletion.
|
||||||
|
*/
|
||||||
|
struct SharedPtrSurfaceDeleter {
|
||||||
|
void operator()(Surface *ptr) {
|
||||||
|
ptr->free();
|
||||||
|
delete ptr;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
} // End of namespace Graphics
|
} // End of namespace Graphics
|
||||||
|
|
||||||
|
|
|
@ -477,7 +477,6 @@ class SaveLoadChooser : public GUI::Dialog {
|
||||||
typedef Common::String String;
|
typedef Common::String String;
|
||||||
typedef Common::StringList StringList;
|
typedef Common::StringList StringList;
|
||||||
protected:
|
protected:
|
||||||
bool _delSupport;
|
|
||||||
GUI::ListWidget *_list;
|
GUI::ListWidget *_list;
|
||||||
GUI::ButtonWidget *_chooseButton;
|
GUI::ButtonWidget *_chooseButton;
|
||||||
GUI::ButtonWidget *_deleteButton;
|
GUI::ButtonWidget *_deleteButton;
|
||||||
|
@ -485,13 +484,16 @@ protected:
|
||||||
GUI::ContainerWidget *_container;
|
GUI::ContainerWidget *_container;
|
||||||
|
|
||||||
const EnginePlugin *_plugin;
|
const EnginePlugin *_plugin;
|
||||||
|
bool _delSupport;
|
||||||
|
bool _metaInfoSupport;
|
||||||
|
bool _thumbnailSupport;
|
||||||
String _target;
|
String _target;
|
||||||
SaveStateList _saveList;
|
SaveStateList _saveList;
|
||||||
|
|
||||||
uint8 _fillR, _fillG, _fillB;
|
uint8 _fillR, _fillG, _fillB;
|
||||||
|
|
||||||
void updateSaveList();
|
void updateSaveList();
|
||||||
void updateInfos(bool redraw);
|
void updateSelection(bool redraw);
|
||||||
public:
|
public:
|
||||||
SaveLoadChooser(const String &title, const String &buttonLabel);
|
SaveLoadChooser(const String &title, const String &buttonLabel);
|
||||||
~SaveLoadChooser();
|
~SaveLoadChooser();
|
||||||
|
@ -528,6 +530,8 @@ SaveLoadChooser::SaveLoadChooser(const String &title, const String &buttonLabel)
|
||||||
|
|
||||||
_deleteButton = new GUI::ButtonWidget(this, "scummsaveload_delete", "Delete", kDelCmd, 0);
|
_deleteButton = new GUI::ButtonWidget(this, "scummsaveload_delete", "Delete", kDelCmd, 0);
|
||||||
_deleteButton->setEnabled(false);
|
_deleteButton->setEnabled(false);
|
||||||
|
|
||||||
|
_delSupport = _metaInfoSupport = _thumbnailSupport = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
SaveLoadChooser::~SaveLoadChooser() {
|
SaveLoadChooser::~SaveLoadChooser() {
|
||||||
|
@ -540,6 +544,8 @@ int SaveLoadChooser::runModal(const EnginePlugin *plugin, const String &target)
|
||||||
_plugin = plugin;
|
_plugin = plugin;
|
||||||
_target = target;
|
_target = target;
|
||||||
_delSupport = (*_plugin)->hasFeature(MetaEngine::kSupportsDeleteSave);
|
_delSupport = (*_plugin)->hasFeature(MetaEngine::kSupportsDeleteSave);
|
||||||
|
_metaInfoSupport = (*_plugin)->hasFeature(MetaEngine::kSupportsMetaInfos);
|
||||||
|
_thumbnailSupport = _metaInfoSupport && (*_plugin)->hasFeature(MetaEngine::kSupportsThumbnails);
|
||||||
reflowLayout();
|
reflowLayout();
|
||||||
updateSaveList();
|
updateSaveList();
|
||||||
|
|
||||||
|
@ -566,16 +572,7 @@ void SaveLoadChooser::handleCommand(CommandSender *sender, uint32 cmd, uint32 da
|
||||||
close();
|
close();
|
||||||
break;
|
break;
|
||||||
case GUI::kListSelectionChangedCmd: {
|
case GUI::kListSelectionChangedCmd: {
|
||||||
if (_gfxWidget)
|
updateSelection(true);
|
||||||
updateInfos(true);
|
|
||||||
|
|
||||||
// Disable these buttons if nothing is selected, or if an empty
|
|
||||||
// list item is selected.
|
|
||||||
_chooseButton->setEnabled(selItem >= 0 && (!_list->getSelectedString().empty()));
|
|
||||||
_chooseButton->draw();
|
|
||||||
// Delete will always be disabled if the engine doesn't support it.
|
|
||||||
_deleteButton->setEnabled(_delSupport && (selItem >= 0) && (!_list->getSelectedString().empty()));
|
|
||||||
_deleteButton->draw();
|
|
||||||
} break;
|
} break;
|
||||||
case kDelCmd:
|
case kDelCmd:
|
||||||
if (selItem >= 0 && _delSupport) {
|
if (selItem >= 0 && _delSupport) {
|
||||||
|
@ -588,10 +585,7 @@ void SaveLoadChooser::handleCommand(CommandSender *sender, uint32 cmd, uint32 da
|
||||||
_list->setSelected(-1);
|
_list->setSelected(-1);
|
||||||
|
|
||||||
updateSaveList();
|
updateSaveList();
|
||||||
|
updateSelection(true);
|
||||||
// Disable these buttons again after deleteing a selection
|
|
||||||
_chooseButton->setEnabled(false);
|
|
||||||
_deleteButton->setEnabled(false);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
@ -603,7 +597,7 @@ void SaveLoadChooser::handleCommand(CommandSender *sender, uint32 cmd, uint32 da
|
||||||
}
|
}
|
||||||
|
|
||||||
void SaveLoadChooser::reflowLayout() {
|
void SaveLoadChooser::reflowLayout() {
|
||||||
if (g_gui.evaluator()->getVar("scummsaveload_extinfo.visible") == 1 && (_plugin && (*_plugin)->hasFeature(MetaEngine::kSupportsThumbnails))) {
|
if (g_gui.evaluator()->getVar("scummsaveload_extinfo.visible") == 1 && _thumbnailSupport) {
|
||||||
int thumbX = g_gui.evaluator()->getVar("scummsaveload_thumbnail.x");
|
int thumbX = g_gui.evaluator()->getVar("scummsaveload_thumbnail.x");
|
||||||
int thumbY = g_gui.evaluator()->getVar("scummsaveload_thumbnail.y");
|
int thumbY = g_gui.evaluator()->getVar("scummsaveload_thumbnail.y");
|
||||||
int hPad = g_gui.evaluator()->getVar("scummsaveload_thumbnail.hPad");
|
int hPad = g_gui.evaluator()->getVar("scummsaveload_thumbnail.hPad");
|
||||||
|
@ -621,7 +615,7 @@ void SaveLoadChooser::reflowLayout() {
|
||||||
_fillR = g_gui.evaluator()->getVar("scummsaveload_thumbnail.fillR");
|
_fillR = g_gui.evaluator()->getVar("scummsaveload_thumbnail.fillR");
|
||||||
_fillG = g_gui.evaluator()->getVar("scummsaveload_thumbnail.fillG");
|
_fillG = g_gui.evaluator()->getVar("scummsaveload_thumbnail.fillG");
|
||||||
_fillB = g_gui.evaluator()->getVar("scummsaveload_thumbnail.fillB");
|
_fillB = g_gui.evaluator()->getVar("scummsaveload_thumbnail.fillB");
|
||||||
updateInfos(false);
|
updateSelection(false);
|
||||||
} else {
|
} else {
|
||||||
_container->setFlags(GUI::WIDGET_INVISIBLE);
|
_container->setFlags(GUI::WIDGET_INVISIBLE);
|
||||||
_gfxWidget->setFlags(GUI::WIDGET_INVISIBLE);
|
_gfxWidget->setFlags(GUI::WIDGET_INVISIBLE);
|
||||||
|
@ -630,23 +624,39 @@ void SaveLoadChooser::reflowLayout() {
|
||||||
Dialog::reflowLayout();
|
Dialog::reflowLayout();
|
||||||
}
|
}
|
||||||
|
|
||||||
void SaveLoadChooser::updateInfos(bool redraw) {
|
void SaveLoadChooser::updateSelection(bool redraw) {
|
||||||
int selItem = _list->getSelected();
|
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) {
|
bool isDeletable = _delSupport;
|
||||||
_gfxWidget->setGfx(thumb);
|
|
||||||
_gfxWidget->useAlpha(256);
|
if (selItem >= 0 && !_list->getSelectedString().empty() && _metaInfoSupport) {
|
||||||
thumb->free();
|
SaveStateDescriptor desc = (*_plugin)->querySaveMetaInfos(_target.c_str(), atoi(_saveList[selItem].save_slot().c_str()));
|
||||||
delete thumb;
|
|
||||||
} else {
|
isDeletable = desc.getBool("is_deletable") && _delSupport;
|
||||||
_gfxWidget->setGfx(-1, -1, _fillR, _fillG, _fillB);
|
|
||||||
|
if (_thumbnailSupport) {
|
||||||
|
const Graphics::Surface *thumb = desc.getThumbnail();
|
||||||
|
if (thumb) {
|
||||||
|
_gfxWidget->setGfx(thumb);
|
||||||
|
_gfxWidget->useAlpha(256);
|
||||||
|
} else {
|
||||||
|
_gfxWidget->setGfx(-1, -1, _fillR, _fillG, _fillB);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (redraw)
|
|
||||||
|
// Disable these buttons if nothing is selected, or if an empty
|
||||||
|
// list item is selected.
|
||||||
|
_chooseButton->setEnabled(selItem >= 0 && (!_list->getSelectedString().empty()));
|
||||||
|
// Delete will always be disabled if the engine doesn't support it.
|
||||||
|
_deleteButton->setEnabled(isDeletable && (selItem >= 0) && (!_list->getSelectedString().empty()));
|
||||||
|
|
||||||
|
if (redraw) {
|
||||||
_gfxWidget->draw();
|
_gfxWidget->draw();
|
||||||
|
_chooseButton->draw();
|
||||||
|
_deleteButton->draw();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void SaveLoadChooser::close() {
|
void SaveLoadChooser::close() {
|
||||||
|
|
|
@ -363,8 +363,7 @@ void GraphicsWidget::setGfx(const Graphics::Surface *gfx) {
|
||||||
return;
|
return;
|
||||||
|
|
||||||
// TODO: add conversion to OverlayColor
|
// TODO: add conversion to OverlayColor
|
||||||
_gfx.create(gfx->w, gfx->h, gfx->bytesPerPixel);
|
_gfx.copyFrom(*gfx);
|
||||||
memcpy(_gfx.pixels, gfx->pixels, gfx->h * gfx->pitch);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void GraphicsWidget::setGfx(int w, int h, int r, int g, int b) {
|
void GraphicsWidget::setGfx(int w, int h, int r, int g, int b) {
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue