From 921030f4ef9ff41ff3387ac8c61ffd1f6e709611 Mon Sep 17 00:00:00 2001 From: md5 Date: Thu, 5 May 2011 18:33:22 +0300 Subject: SWORD25: Initial code for showing savegame thumbnails There is currently a bug and only the thumbnail of the first save slot is shown --- engines/sword25/gfx/graphicengine.cpp | 8 ++-- engines/sword25/kernel/persistenceservice.cpp | 8 ---- engines/sword25/package/packagemanager.cpp | 57 +++++++++++++++++++++++++++ 3 files changed, 62 insertions(+), 11 deletions(-) diff --git a/engines/sword25/gfx/graphicengine.cpp b/engines/sword25/gfx/graphicengine.cpp index 2772401c6a..371df7ac0f 100644 --- a/engines/sword25/gfx/graphicengine.cpp +++ b/engines/sword25/gfx/graphicengine.cpp @@ -266,8 +266,9 @@ Resource *GraphicEngine::loadResource(const Common::String &filename) { return pResource; } - // Load sprite image - if (filename.hasSuffix(".png") || filename.hasSuffix(".b25s")) { + // Load sprite image. Savegame thumbnails are also loaded here. + if (filename.hasSuffix(".png") || filename.hasSuffix(".b25s") || + filename.hasPrefix("/saves")) { bool result = false; RenderedImage *pImage = new RenderedImage(filename, result); if (!result) { @@ -354,7 +355,8 @@ bool GraphicEngine::canLoadResource(const Common::String &filename) { filename.hasSuffix("_ani.xml") || filename.hasSuffix("_fnt.xml") || filename.hasSuffix(".swf") || - filename.hasSuffix(".b25s"); + filename.hasSuffix(".b25s") || + filename.hasPrefix("/saves"); } void GraphicEngine::updateLastFrameDuration() { diff --git a/engines/sword25/kernel/persistenceservice.cpp b/engines/sword25/kernel/persistenceservice.cpp index 8d54c24918..500703befb 100644 --- a/engines/sword25/kernel/persistenceservice.cpp +++ b/engines/sword25/kernel/persistenceservice.cpp @@ -134,14 +134,6 @@ struct PersistenceService::Impl { // Iterate through all the saved games, and read their thumbnails. for (uint i = 0; i < SLOT_COUNT; ++i) { readSlotSavegameInformation(i); - // TODO: This function is supposed to load savegame screenshots - // into an appropriate array (or the header struct of each saved - // game). Currently, it's a stub. For each slot, we should skip - // the header plus gameDataLength bytes and read the screenshot - // data. Then, these screenshots should be used for the save list - // screen. The thumbnail code seems to be missing completely, - // though (unless I'm mistaken), so these thumbnails aren't used - // anywhere currently. } } diff --git a/engines/sword25/package/packagemanager.cpp b/engines/sword25/package/packagemanager.cpp index 7a64fe2e29..7c6343a18f 100644 --- a/engines/sword25/package/packagemanager.cpp +++ b/engines/sword25/package/packagemanager.cpp @@ -141,6 +141,29 @@ bool PackageManager::loadDirectoryAsPackage(const Common::String &directoryName, } } +// Duplicated from kernel/persistenceservice.cpp +static Common::String generateSavegameFilename(uint slotID) { + char buffer[100]; + // NOTE: This is hardcoded to sword25 + snprintf(buffer, 100, "%s.%.3d", "sword25", slotID); + return Common::String(buffer); +} + +// Duplicated from kernel/persistenceservice.cpp +static Common::String loadString(Common::InSaveFile *in, uint maxSize = 999) { + Common::String result; + + char ch = (char)in->readByte(); + while (ch != '\0') { + result += ch; + if (result.size() >= maxSize) + break; + ch = (char)in->readByte(); + } + + return result; +} + byte *PackageManager::getFile(const Common::String &fileName, uint *fileSizePtr) { const Common::String B25S_EXTENSION(".b25s"); Common::SeekableReadStream *in; @@ -165,6 +188,40 @@ byte *PackageManager::getFile(const Common::String &fileName, uint *fileSizePtr) return buffer; } + if (fileName.hasPrefix("/saves")) { + // A savegame thumbnail + Common::SaveFileManager *sfm = g_system->getSavefileManager(); + int slotNum = atoi(fileName.c_str() + fileName.size() - 3); + Common::InSaveFile *file = sfm->openForLoading(generateSavegameFilename(slotNum)); + + if (file) { + loadString(file); // storedMarker + loadString(file); // storedVersionID + loadString(file); // gameDescription + int gameDataLength = atoi(loadString(file).c_str()); + loadString(file); // gamedataUncompressedLength + // Skip the savegame data + file->skip(gameDataLength); + + int thumbnailSize = file->size() - file->pos(); + + if (thumbnailSize <= 0) { + warning("Saved game at slot %d does not contain a thumbnail", slotNum); + delete file; + return 0; + } + + if (fileSizePtr) + *fileSizePtr = thumbnailSize; + + byte *thumbnail = new byte[thumbnailSize]; + file->read(thumbnail, thumbnailSize); + + delete file; + return thumbnail; + } + } + Common::ArchiveMemberPtr fileNode = getArchiveMember(normalizePath(fileName, _currentDirectory)); if (!fileNode) return 0; -- cgit v1.2.3