diff options
author | Paul Gilbert | 2010-08-01 11:02:24 +0000 |
---|---|---|
committer | Eugene Sandulenko | 2010-10-12 22:20:41 +0000 |
commit | fab86ba22250c282139fb0c94a250499abdc875f (patch) | |
tree | ead53adf84dc47cfb85c39c9c06cab99069c7867 | |
parent | b9044a6a27dc9f3549047898ea6b88d2c291a420 (diff) | |
download | scummvm-rg350-fab86ba22250c282139fb0c94a250499abdc875f.tar.gz scummvm-rg350-fab86ba22250c282139fb0c94a250499abdc875f.tar.bz2 scummvm-rg350-fab86ba22250c282139fb0c94a250499abdc875f.zip |
SWORD25: Converted Savegame Load/Save code
In addition to converting the loading/saving of savefiles to use the SaveFileManager interface, also converted the date/time code to use the ScummVM TimeDate structure.
svn-id: r53202
-rw-r--r-- | engines/sword25/kernel/filesystemutil.cpp | 6 | ||||
-rw-r--r-- | engines/sword25/kernel/filesystemutil.h | 5 | ||||
-rw-r--r-- | engines/sword25/kernel/persistenceservice.cpp | 360 |
3 files changed, 178 insertions, 193 deletions
diff --git a/engines/sword25/kernel/filesystemutil.cpp b/engines/sword25/kernel/filesystemutil.cpp index d716bc036e..831efc6add 100644 --- a/engines/sword25/kernel/filesystemutil.cpp +++ b/engines/sword25/kernel/filesystemutil.cpp @@ -102,11 +102,13 @@ public: return size; } - virtual time_t GetFileTime(const Common::String &Filename) { + virtual TimeDate GetFileTime(const Common::String &Filename) { // TODO: There isn't any way in ScummVM to get a file's modified date/time. We will need to check // what code makes use of it. If it's only the save game code, for example, we may be able to // encode the date/time inside the savegame files themselves. - return 0; + TimeDate result; + g_system->getTimeAndDate(result); + return result; } virtual bool FileExists(const Common::String &Filename) { diff --git a/engines/sword25/kernel/filesystemutil.h b/engines/sword25/kernel/filesystemutil.h index 2ac8ce9e75..828ff31922 100644 --- a/engines/sword25/kernel/filesystemutil.h +++ b/engines/sword25/kernel/filesystemutil.h @@ -48,6 +48,7 @@ // Includes // ----------------------------------------------------------------------------- +#include "common/system.h" #include "common/str.h" #include "common/str-array.h" #include "sword25/kernel/common.h" @@ -83,9 +84,9 @@ public: virtual int64 GetFileSize(const Common::String &Filename) = 0; /** * @param Filename The path to a file. - * @return Returns the timestamp of the specified file. On error it returns 0 + * @return Returns the timestamp of the specified file. */ - virtual time_t GetFileTime(const Common::String &Filename) = 0; + virtual TimeDate GetFileTime(const Common::String &Filename) = 0; /** * @param Filename The path to a file. * @return Returns true if the file exists. diff --git a/engines/sword25/kernel/persistenceservice.cpp b/engines/sword25/kernel/persistenceservice.cpp index 0369f2a56c..faf450d880 100644 --- a/engines/sword25/kernel/persistenceservice.cpp +++ b/engines/sword25/kernel/persistenceservice.cpp @@ -36,6 +36,7 @@ // Includes // ----------------------------------------------------------------------------- +#include "common/savefile.h" #include "sword25/kernel/kernel.h" #include "sword25/kernel/persistenceservice.h" #include "sword25/kernel/inputpersistenceblock.h" @@ -48,23 +49,15 @@ #include "sword25/script/script.h" #include <zlib.h> -#include "sword25/kernel/memlog_off.h" -#include <sstream> -#include <fstream> -#include <algorithm> -#include <locale> -#include "sword25/kernel/memlog_on.h" - using namespace std; #define BS_LOG_PREFIX "PERSISTENCESERVICE" // ----------------------------------------------------------------------------- -// Konstanten und Hilfsfunktionen +// Constants and utility functions // ----------------------------------------------------------------------------- -namespace -{ +namespace Sword25 { const char * SAVEGAME_EXTENSION = ".b25s"; const char * SAVEGAME_DIRECTORY = "saves"; const char * FILE_MARKER = "BS25SAVEGAME"; @@ -74,60 +67,72 @@ namespace // ------------------------------------------------------------------------- - string GenerateSavegameFilename(unsigned int SlotID) - { - ostringstream oss; - oss << SlotID << SAVEGAME_EXTENSION; - return oss.str(); + Common::String GenerateSavegameFilename(unsigned int SlotID) { + Common::String oss; + oss += SlotID; + oss += SAVEGAME_EXTENSION; + return oss; } // ------------------------------------------------------------------------- - string GenerateSavegamePath(unsigned int SlotID) - { - ostringstream oss; - oss << BS_PersistenceService::GetSavegameDirectory() << BS_FileSystemUtil::GetInstance().GetPathSeparator() << GenerateSavegameFilename(SlotID); - return oss.str(); + Common::String GenerateSavegamePath(unsigned int SlotID) { + Common::String oss; + oss = BS_PersistenceService::GetSavegameDirectory(); + oss += BS_FileSystemUtil::GetInstance().GetPathSeparator(); + oss += GenerateSavegameFilename(SlotID); + return oss; } // ------------------------------------------------------------------------- - string FormatTimestamp(time_t Time) - { - // Zeitstempel in Einzelkomponenten auflösen. - tm * Timeinfo = localtime(&Time); - - // Zeitangabe im lokalen Format in einen String-Stream schreiben. - locale Locale(""); - ostringstream StringBuilder; - StringBuilder.imbue(Locale); - char * Pattern = "%x %X"; - use_facet<time_put<char> >(Locale).put(StringBuilder, - StringBuilder, StringBuilder.fill(), Timeinfo, Pattern, Pattern + strlen(Pattern)); - - // Formatierten String zurückgeben. - return StringBuilder.str(); + Common::String FormatTimestamp(TimeDate Time) { + // In the original BS2.5 engine, this used a local object to show the date/time as as a string. + // For now in ScummVM it's being hardcoded to 'dd-MON-yyyy hh:mm:ss' + Common::String monthList[12] = { + "Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec" + }; + char buffer[100]; + snprintf(buffer, 100, "%.2d-%s-%.4d %.2d:%.2d:%.2d", + Time.tm_mday, monthList[Time.tm_mon].c_str(), Time.tm_year, + Time.tm_hour, Time.tm_min, Time.tm_sec + ); + + return Common::String(buffer); + } + + // ------------------------------------------------------------------------- + + Common::String LoadString(Common::InSaveFile *In, uint MaxSize = 999) { + Common::String Result; + char ch; + while ((ch = (char)In->readByte()) != '\0') { + Result += ch; + if (Result.size() >= MaxSize) break; + } + + return Result; } } +namespace Sword25 { + // ----------------------------------------------------------------------------- -// Private Implementation (Pimpl-Pattern) +// Private Implementation // ----------------------------------------------------------------------------- -struct SavegameInformation -{ +struct SavegameInformation { bool IsOccupied; bool IsCompatible; - string Description; - string Filename; + Common::String Description; + Common::String Filename; unsigned int GamedataLength; unsigned int GamedataOffset; unsigned int GamedataUncompressedLength; SavegameInformation() { Clear(); } - void Clear() - { + void Clear() { IsOccupied = false; IsCompatible = false; Description = ""; @@ -138,64 +143,61 @@ struct SavegameInformation } }; -struct BS_PersistenceService::Impl -{ +struct BS_PersistenceService::Impl { SavegameInformation m_SavegameInformations[SLOT_COUNT]; // ----------------------------------------------------------------------------- - Impl() - { + Impl() { ReloadSlots(); } // ----------------------------------------------------------------------------- - void ReloadSlots() - { + void ReloadSlots() { // Über alle Spielstanddateien iterieren und deren Infos einlesen. - for (unsigned int i = 0; i < SLOT_COUNT; ++i) - { + for (unsigned int i = 0; i < SLOT_COUNT; ++i) { ReadSlotSavegameInformation(i); } } - void ReadSlotSavegameInformation(unsigned int SlotID) - { + void ReadSlotSavegameInformation(unsigned int SlotID) { // Aktuelle Slotinformationen in den Ausgangszustand versetzen, er wird im Folgenden neu gefüllt. SavegameInformation & CurSavegameInfo = m_SavegameInformations[SlotID]; CurSavegameInfo.Clear(); // Den Dateinamen für den Spielstand des Slots generieren. - string Filename = GenerateSavegamePath(SlotID); + Common::String Filename = GenerateSavegamePath(SlotID); // Feststellen, ob eine Spielstanddatei dieses Namens existiert. - if (BS_FileSystemUtil::GetInstance().FileExists(Filename)) - { - // Die Spielstanddatei öffnen. - ifstream File(Filename.c_str(), ifstream::binary); - if (File.good() && File.is_open()) - { - // Die Headerdaten einlesen. - string StoredMarker, StoredVersionID; - File >> StoredMarker >> StoredVersionID >> CurSavegameInfo.GamedataLength >> CurSavegameInfo.GamedataUncompressedLength; - - // Falls die Headerdaten gelesen werden konnten und der Marker stimmt, nehmen wir an eine gültige Spielstanddatei zu haben. - if (File.good() && StoredMarker == FILE_MARKER) - { + if (BS_FileSystemUtil::GetInstance().FileExists(Filename)) { + // Read in the game + Common::SaveFileManager *sfm = g_system->getSavefileManager(); + Common::InSaveFile *File = sfm->openForLoading(Filename); + + if (File) { + // Read in the header + Common::String StoredMarker = LoadString(File); + Common::String StoredVersionID = LoadString(File); + CurSavegameInfo.GamedataLength = File->readUint32LE(); + CurSavegameInfo.GamedataUncompressedLength = File->readUint32LE(); + + // If the header can be read in and is detected to be valid, we will have a valid file + if (StoredMarker == FILE_MARKER) { // Der Slot wird als belegt markiert. CurSavegameInfo.IsOccupied = true; // Speichern, ob der Spielstand kompatibel mit der aktuellen Engine-Version ist. - CurSavegameInfo.IsCompatible = (StoredVersionID == string(VERSIONID)); + CurSavegameInfo.IsCompatible = (StoredVersionID == Common::String(VERSIONID)); // Dateinamen des Spielstandes speichern. CurSavegameInfo.Filename = GenerateSavegameFilename(SlotID); // Die Beschreibung des Spielstandes besteht aus einer textuellen Darstellung des Änderungsdatums der Spielstanddatei. CurSavegameInfo.Description = FormatTimestamp(BS_FileSystemUtil::GetInstance().GetFileTime(Filename)); // Den Offset zu den gespeicherten Spieldaten innerhalb der Datei speichern. // Dieses entspricht der aktuellen Position + 1, da nach der letzten Headerinformation noch ein Leerzeichen als trenner folgt. - CurSavegameInfo.GamedataOffset = static_cast<unsigned int>(File.tellg()) + 1; + CurSavegameInfo.GamedataOffset = static_cast<unsigned int>(File->pos()) + 1; } + delete File; } } } @@ -205,22 +207,19 @@ struct BS_PersistenceService::Impl // Construction / Destruction // ----------------------------------------------------------------------------- -BS_PersistenceService & BS_PersistenceService::GetInstance() -{ +BS_PersistenceService & BS_PersistenceService::GetInstance() { static BS_PersistenceService Instance; return Instance; } // ----------------------------------------------------------------------------- -BS_PersistenceService::BS_PersistenceService() : m_impl(new Impl) -{ +BS_PersistenceService::BS_PersistenceService() : m_impl(new Impl) { } // ----------------------------------------------------------------------------- -BS_PersistenceService::~BS_PersistenceService() -{ +BS_PersistenceService::~BS_PersistenceService() { delete m_impl; } @@ -228,39 +227,31 @@ BS_PersistenceService::~BS_PersistenceService() // Implementation // ----------------------------------------------------------------------------- -void BS_PersistenceService::ReloadSlots() -{ +void BS_PersistenceService::ReloadSlots() { m_impl->ReloadSlots(); } // ----------------------------------------------------------------------------- -unsigned int BS_PersistenceService::GetSlotCount() -{ +unsigned int BS_PersistenceService::GetSlotCount() { return SLOT_COUNT; } // ----------------------------------------------------------------------------- -std::string BS_PersistenceService::GetSavegameDirectory() -{ +Common::String BS_PersistenceService::GetSavegameDirectory() { return BS_FileSystemUtil::GetInstance().GetUserdataDirectory() + BS_FileSystemUtil::GetInstance().GetPathSeparator() + SAVEGAME_DIRECTORY; } // ----------------------------------------------------------------------------- -namespace -{ - bool CheckSlotID(unsigned int SlotID) - { +namespace { + bool CheckSlotID(unsigned int SlotID) { // Überprüfen, ob die Slot-ID zulässig ist. - if (SlotID >= SLOT_COUNT) - { + if (SlotID >= SLOT_COUNT) { BS_LOG_ERRORLN("Tried to access an invalid slot (%d). Only slot ids from 0 to %d are allowed.", SlotID, SLOT_COUNT - 1); return false; - } - else - { + } else { return true; } } @@ -268,130 +259,116 @@ namespace // ----------------------------------------------------------------------------- -bool BS_PersistenceService::IsSlotOccupied(unsigned int SlotID) -{ +bool BS_PersistenceService::IsSlotOccupied(unsigned int SlotID) { if (!CheckSlotID(SlotID)) return false; return m_impl->m_SavegameInformations[SlotID].IsOccupied; } // ----------------------------------------------------------------------------- -bool BS_PersistenceService::IsSavegameCompatible(unsigned int SlotID) -{ +bool BS_PersistenceService::IsSavegameCompatible(unsigned int SlotID) { if (!CheckSlotID(SlotID)) return false; return m_impl->m_SavegameInformations[SlotID].IsCompatible; } // ----------------------------------------------------------------------------- -string & BS_PersistenceService::GetSavegameDescription(unsigned int SlotID) -{ - static string EmptyString; +Common::String &BS_PersistenceService::GetSavegameDescription(unsigned int SlotID) { + static Common::String EmptyString; if (!CheckSlotID(SlotID)) return EmptyString; return m_impl->m_SavegameInformations[SlotID].Description; } // ----------------------------------------------------------------------------- -string & BS_PersistenceService::GetSavegameFilename(unsigned int SlotID) -{ - static string EmptyString; +Common::String &BS_PersistenceService::GetSavegameFilename(unsigned int SlotID) { + static Common::String EmptyString; if (!CheckSlotID(SlotID)) return EmptyString; return m_impl->m_SavegameInformations[SlotID].Filename; } // ----------------------------------------------------------------------------- -bool BS_PersistenceService::SaveGame(unsigned int SlotID, const std::string & ScreenshotFilename) -{ +bool BS_PersistenceService::SaveGame(unsigned int SlotID, const Common::String &ScreenshotFilename) { // Überprüfen, ob die Slot-ID zulässig ist. - if (SlotID >= SLOT_COUNT) - { + if (SlotID >= SLOT_COUNT) { BS_LOG_ERRORLN("Tried to save to an invalid slot (%d). Only slot ids form 0 to %d are allowed.", SlotID, SLOT_COUNT - 1); return false; } // Dateinamen erzeugen. - string Filename = GenerateSavegamePath(SlotID).c_str(); + Common::String Filename = GenerateSavegamePath(SlotID).c_str(); - try - { - // Sicherstellen, dass das Verzeichnis für die Spielstanddateien existiert. - BS_FileSystemUtil::GetInstance().CreateDirectory(GetSavegameDirectory()); + // Sicherstellen, dass das Verzeichnis für die Spielstanddateien existiert. + BS_FileSystemUtil::GetInstance().CreateDirectory(GetSavegameDirectory()); - // Spielstanddatei öffnen und die Headerdaten schreiben. - ofstream File(Filename.c_str(), ofstream::binary); - File << string(FILE_MARKER) << " " << string(VERSIONID) << " "; - if (!File.good()) - { - BS_LOG_ERRORLN("Unable to write header data to savegame file \"%s\".", Filename.c_str()); - throw 0; - } + // Spielstanddatei öffnen und die Headerdaten schreiben. + Common::SaveFileManager *sfm = g_system->getSavefileManager(); + Common::OutSaveFile *File = sfm->openForSaving(Filename); - // Alle notwendigen Module persistieren. - BS_OutputPersistenceBlock Writer; - bool Success = true; - Success &= BS_Kernel::GetInstance()->GetScript()->Persist(Writer); - Success &= BS_RegionRegistry::GetInstance().Persist(Writer); - Success &= BS_Kernel::GetInstance()->GetGfx()->Persist(Writer); - Success &= BS_Kernel::GetInstance()->GetSfx()->Persist(Writer); - Success &= BS_Kernel::GetInstance()->GetInput()->Persist(Writer); - if (!Success) - { - BS_LOG_ERRORLN("Unable to persist modules for savegame file \"%s\".", Filename.c_str()); - throw 0; - } + File->writeString(FILE_MARKER); + File->writeByte(' '); + File->writeString(VERSIONID); + File->writeByte(' '); - // Daten komprimieren. - vector<unsigned char> CompressionBuffer(Writer.GetDataSize() + (Writer.GetDataSize() + 500) / 1000 + 12); - uLongf CompressedLength = CompressionBuffer.size(); - if (compress2(&CompressionBuffer[0], &CompressedLength, reinterpret_cast<const Bytef *>(Writer.GetData()), Writer.GetDataSize(), 6) != Z_OK) - { - BS_LOG_ERRORLN("Unable to compress savegame data in savegame file \"%s\".", Filename.c_str()); - throw 0; - } + if (File->err()) { + error("Unable to write header data to savegame file \"%s\".", Filename.c_str()); + } - // Länge der komprimierten Daten und der unkomprimierten Daten in die Datei schreiben. - File << CompressedLength << " " << Writer.GetDataSize() << " "; + // Alle notwendigen Module persistieren. + BS_OutputPersistenceBlock Writer; + bool Success = true; + Success &= BS_Kernel::GetInstance()->GetScript()->Persist(Writer); + Success &= BS_RegionRegistry::GetInstance().Persist(Writer); + Success &= BS_Kernel::GetInstance()->GetGfx()->Persist(Writer); + Success &= BS_Kernel::GetInstance()->GetSfx()->Persist(Writer); + Success &= BS_Kernel::GetInstance()->GetInput()->Persist(Writer); + if (!Success) { + error("Unable to persist modules for savegame file \"%s\".", Filename.c_str()); + } - // Komprimierte Daten in die Datei schreiben. - File.write(reinterpret_cast<char *>(&CompressionBuffer[0]), CompressedLength); - if (!File.good()) - { - BS_LOG_ERRORLN("Unable to write game data to savegame file \"%s\".", Filename.c_str()); - throw 0; - } + // Daten komprimieren. + uLongf CompressedLength = Writer.GetDataSize() + (Writer.GetDataSize() + 500) / 1000 + 12; + Bytef *CompressionBuffer = new Bytef[CompressedLength]; + + if (compress2(&CompressionBuffer[0], &CompressedLength, reinterpret_cast<const Bytef *>(Writer.GetData()), Writer.GetDataSize(), 6) != Z_OK) { + error("Unable to compress savegame data in savegame file \"%s\".", Filename.c_str()); + } - // Screenshotdatei an die Datei anfügen. - if (BS_FileSystemUtil::GetInstance().FileExists(ScreenshotFilename)) - { - ifstream ScreenshotFile(ScreenshotFilename.c_str(), ifstream::binary); + // Länge der komprimierten Daten und der unkomprimierten Daten in die Datei schreiben. + char sBuffer[10]; + ltoa(CompressedLength, sBuffer, 10); + File->writeString(sBuffer); + File->writeByte(' '); + ltoa(Writer.GetDataSize(), sBuffer, 10); + File->writeString(sBuffer); + File->writeByte(' '); + + // Komprimierte Daten in die Datei schreiben. + File->write(reinterpret_cast<char *>(&CompressionBuffer[0]), CompressedLength); + if (File->err()) { + error("Unable to write game data to savegame file \"%s\".", Filename.c_str()); + } - vector<char> Buffer(FILE_COPY_BUFFER_SIZE); - while (ScreenshotFile.good()) - { - ScreenshotFile.read(&Buffer[0], Buffer.size()); - File.write(&Buffer[0], ScreenshotFile.gcount()); - } - } - else - { - BS_LOG_WARNINGLN("The screenshot file \"%s\" does not exist. Savegame is written without a screenshot.", Filename.c_str()); - } + // Screenshotdatei an die Datei anfügen. + if (BS_FileSystemUtil::GetInstance().FileExists(ScreenshotFilename)) { + Common::File ScreenshotFile; + if (!ScreenshotFile.open(ScreenshotFilename.c_str())) + error("Unable to load screenshot file"); - // Savegameinformationen für diesen Slot aktualisieren. - m_impl->ReadSlotSavegameInformation(SlotID); + byte *Buffer = new Byte[FILE_COPY_BUFFER_SIZE]; + while (!ScreenshotFile.eos()) { + int bytesRead = ScreenshotFile.read(&Buffer[0], FILE_COPY_BUFFER_SIZE); + File->write(&Buffer[0], bytesRead); + } + } else { + BS_LOG_WARNINGLN("The screenshot file \"%s\" does not exist. Savegame is written without a screenshot.", Filename.c_str()); } - catch(...) - { - BS_LOG_ERRORLN("An error occured while create savegame file \"%s\".", Filename.c_str()); - // Es ist ein Fehler aufgetreten, die Spielstanddatei wird gelöscht, da sie keinen konsistenten Zustand besitzt. - ::remove(Filename.c_str()); + // Savegameinformationen für diesen Slot aktualisieren. + m_impl->ReadSlotSavegameInformation(SlotID); - // Misserfolg signalisieren. - return false; - } + delete[] CompressionBuffer; // Erfolg signalisieren. return true; @@ -399,11 +376,12 @@ bool BS_PersistenceService::SaveGame(unsigned int SlotID, const std::string & Sc // ----------------------------------------------------------------------------- -bool BS_PersistenceService::LoadGame(unsigned int SlotID) -{ +bool BS_PersistenceService::LoadGame(unsigned int SlotID) { + Common::SaveFileManager *sfm = g_system->getSavefileManager(); + Common::InSaveFile *File; + // Überprüfen, ob die Slot-ID zulässig ist. - if (SlotID >= SLOT_COUNT) - { + if (SlotID >= SLOT_COUNT) { BS_LOG_ERRORLN("Tried to load from an invalid slot (%d). Only slot ids form 0 to %d are allowed.", SlotID, SLOT_COUNT - 1); return false; } @@ -411,8 +389,7 @@ bool BS_PersistenceService::LoadGame(unsigned int SlotID) SavegameInformation & CurSavegameInfo = m_impl->m_SavegameInformations[SlotID]; // Überprüfen, ob der Slot belegt ist. - if (!CurSavegameInfo.IsOccupied) - { + if (!CurSavegameInfo.IsOccupied) { BS_LOG_ERRORLN("Tried to load from an empty slot (%d).", SlotID); return false; } @@ -428,32 +405,33 @@ bool BS_PersistenceService::LoadGame(unsigned int SlotID) } #endif - vector<unsigned char> UncompressedDataBuffer(CurSavegameInfo.GamedataUncompressedLength); + Bytef *UncompressedDataBuffer = new Bytef[CurSavegameInfo.GamedataUncompressedLength]; { // Komprimierte gespeicherte Spieldaten laden. vector<unsigned char> CompressedDataBuffer(CurSavegameInfo.GamedataLength); { - ifstream File(GenerateSavegamePath(SlotID).c_str(), ifstream::binary); - File.seekg(CurSavegameInfo.GamedataOffset); - File.read(reinterpret_cast<char *>(&CompressedDataBuffer[0]), CurSavegameInfo.GamedataLength); - if (!File.good()) - { + File = sfm->openForLoading(GenerateSavegamePath(SlotID)); + + File->seek(CurSavegameInfo.GamedataOffset); + File->read(reinterpret_cast<char *>(&CompressedDataBuffer[0]), CurSavegameInfo.GamedataLength); + if (File->err()) { BS_LOG_ERRORLN("Unable to load the gamedata from the savegame file \"%s\".", CurSavegameInfo.Filename.c_str()); return false; } } // Spieldaten dekomprimieren. - uLongf UncompressedBufferSize = UncompressedDataBuffer.size(); + uLongf UncompressedBufferSize = CurSavegameInfo.GamedataUncompressedLength; if (uncompress(reinterpret_cast<Bytef *>(&UncompressedDataBuffer[0]), &UncompressedBufferSize, - reinterpret_cast<Bytef *>(&CompressedDataBuffer[0]), CompressedDataBuffer.size()) != Z_OK) - { + reinterpret_cast<Bytef *>(&CompressedDataBuffer[0]), CompressedDataBuffer.size()) != Z_OK) { BS_LOG_ERRORLN("Unable to decompress the gamedata from savegame file \"%s\".", CurSavegameInfo.Filename.c_str()); + delete[] UncompressedDataBuffer; + delete File; return false; } } - BS_InputPersistenceBlock Reader(&UncompressedDataBuffer[0], UncompressedDataBuffer.size()); + BS_InputPersistenceBlock Reader(&UncompressedDataBuffer[0], CurSavegameInfo.GamedataUncompressedLength); // Einzelne Engine-Module depersistieren. bool Success = true; @@ -464,11 +442,15 @@ bool BS_PersistenceService::LoadGame(unsigned int SlotID) Success &= BS_Kernel::GetInstance()->GetSfx()->Unpersist(Reader); Success &= BS_Kernel::GetInstance()->GetInput()->Unpersist(Reader); - if (!Success) - { + delete[] UncompressedDataBuffer; + delete File; + + if (!Success) { BS_LOG_ERRORLN("Unable to unpersist the gamedata from savegame file \"%s\".", CurSavegameInfo.Filename.c_str()); return false; } return true; } + +} // End of namespace Sword25 |