diff options
Diffstat (limited to 'engines/sword25/kernel')
-rw-r--r-- | engines/sword25/kernel/inputpersistenceblock.cpp | 33 | ||||
-rw-r--r-- | engines/sword25/kernel/inputpersistenceblock.h | 7 | ||||
-rw-r--r-- | engines/sword25/kernel/outputpersistenceblock.cpp | 12 | ||||
-rw-r--r-- | engines/sword25/kernel/persistenceblock.h | 42 | ||||
-rw-r--r-- | engines/sword25/kernel/persistenceservice.cpp | 32 | ||||
-rw-r--r-- | engines/sword25/kernel/persistenceservice.h | 1 |
6 files changed, 54 insertions, 73 deletions
diff --git a/engines/sword25/kernel/inputpersistenceblock.cpp b/engines/sword25/kernel/inputpersistenceblock.cpp index c1cd771e39..cdce539c31 100644 --- a/engines/sword25/kernel/inputpersistenceblock.cpp +++ b/engines/sword25/kernel/inputpersistenceblock.cpp @@ -35,9 +35,10 @@ namespace Sword25 { -InputPersistenceBlock::InputPersistenceBlock(const void *data, uint dataLength) : +InputPersistenceBlock::InputPersistenceBlock(const void *data, uint dataLength, int version) : _data(static_cast<const byte *>(data), dataLength), - _errorState(NONE) { + _errorState(NONE), + _version(version) { _iter = _data.begin(); } @@ -54,8 +55,8 @@ void InputPersistenceBlock::read(int16 &value) { void InputPersistenceBlock::read(signed int &value) { if (checkMarker(SINT_MARKER)) { - rawRead(&value, sizeof(signed int)); - value = convertEndianessFromStorageToSystem(value); + value = (int32)READ_LE_UINT32(_iter); + _iter += 4; } else { value = 0; } @@ -63,8 +64,8 @@ void InputPersistenceBlock::read(signed int &value) { void InputPersistenceBlock::read(uint &value) { if (checkMarker(UINT_MARKER)) { - rawRead(&value, sizeof(uint)); - value = convertEndianessFromStorageToSystem(value); + value = READ_LE_UINT32(_iter); + _iter += 4; } else { value = 0; } @@ -72,8 +73,10 @@ void InputPersistenceBlock::read(uint &value) { void InputPersistenceBlock::read(float &value) { if (checkMarker(FLOAT_MARKER)) { - rawRead(&value, sizeof(float)); - value = convertEndianessFromStorageToSystem(value); + uint32 tmp[1]; + tmp[0] = READ_LE_UINT32(_iter); + value = ((float *)tmp)[0]; + _iter += 4; } else { value = 0.0f; } @@ -81,12 +84,11 @@ void InputPersistenceBlock::read(float &value) { void InputPersistenceBlock::read(bool &value) { if (checkMarker(BOOL_MARKER)) { - uint uintBool; - rawRead(&uintBool, sizeof(float)); - uintBool = convertEndianessFromStorageToSystem(uintBool); + uint uintBool = READ_LE_UINT32(_iter); + _iter += 4; value = uintBool == 0 ? false : true; } else { - value = 0.0f; + value = false; } } @@ -116,13 +118,6 @@ void InputPersistenceBlock::readByteArray(Common::Array<byte> &value) { } } -void InputPersistenceBlock::rawRead(void *destPtr, size_t size) { - if (checkBlockSize(size)) { - memcpy(destPtr, &*_iter, size); - _iter += size; - } -} - bool InputPersistenceBlock::checkBlockSize(int size) { if (_data.end() - _iter >= size) { return true; diff --git a/engines/sword25/kernel/inputpersistenceblock.h b/engines/sword25/kernel/inputpersistenceblock.h index f643b06bc1..2518d7e32c 100644 --- a/engines/sword25/kernel/inputpersistenceblock.h +++ b/engines/sword25/kernel/inputpersistenceblock.h @@ -46,7 +46,7 @@ public: OUT_OF_SYNC }; - InputPersistenceBlock(const void *data, uint dataLength); + InputPersistenceBlock(const void *data, uint dataLength, int version); virtual ~InputPersistenceBlock(); void read(int16 &value); @@ -64,14 +64,17 @@ public: return _errorState; } + int getVersion() const { return _version; } + private: bool checkMarker(byte marker); bool checkBlockSize(int size); - void rawRead(void *destPtr, size_t size); Common::Array<byte> _data; Common::Array<byte>::const_iterator _iter; ErrorState _errorState; + + int _version; }; } // End of namespace Sword25 diff --git a/engines/sword25/kernel/outputpersistenceblock.cpp b/engines/sword25/kernel/outputpersistenceblock.cpp index cf28ea401f..e29d956e5f 100644 --- a/engines/sword25/kernel/outputpersistenceblock.cpp +++ b/engines/sword25/kernel/outputpersistenceblock.cpp @@ -43,19 +43,23 @@ OutputPersistenceBlock::OutputPersistenceBlock() { void OutputPersistenceBlock::write(signed int value) { writeMarker(SINT_MARKER); - value = convertEndianessFromSystemToStorage(value); + value = TO_LE_32(value); rawWrite(&value, sizeof(value)); } void OutputPersistenceBlock::write(uint value) { writeMarker(UINT_MARKER); - value = convertEndianessFromSystemToStorage(value); + value = TO_LE_32(value); rawWrite(&value, sizeof(value)); } void OutputPersistenceBlock::write(float value) { writeMarker(FLOAT_MARKER); - value = convertEndianessFromSystemToStorage(value); + uint32 tmp[1]; + + ((float *)tmp)[0] = value; + tmp[0] = TO_LE_32(tmp[0]); + rawWrite(&value, sizeof(value)); } @@ -63,7 +67,7 @@ void OutputPersistenceBlock::write(bool value) { writeMarker(BOOL_MARKER); uint uintBool = value ? 1 : 0; - uintBool = convertEndianessFromSystemToStorage(uintBool); + uintBool = TO_LE_32(uintBool); rawWrite(&uintBool, sizeof(uintBool)); } diff --git a/engines/sword25/kernel/persistenceblock.h b/engines/sword25/kernel/persistenceblock.h index d8440faa50..8ac3e84a41 100644 --- a/engines/sword25/kernel/persistenceblock.h +++ b/engines/sword25/kernel/persistenceblock.h @@ -64,48 +64,6 @@ protected: BLOCK_MARKER }; - // ----------------------------------------------------------------------------- - // Endianess Conversions - // ----------------------------------------------------------------------------- - // - // Everything is stored in Little Endian - // Big Endian Systems will need to be byte swapped during both saving and reading of saved values - // - - template<typename T> - static T convertEndianessFromSystemToStorage(T value) { - if (isBigEndian()) - reverseByteOrder(&value); - return value; - } - - template<typename T> - static T convertEndianessFromStorageToSystem(T value) { - if (isBigEndian()) - reverseByteOrder(&value); - return value; - } - -private: - static bool isBigEndian() { - uint dummy = 1; - byte *dummyPtr = reinterpret_cast<byte *>(&dummy); - return dummyPtr[0] == 0; - } - - template<typename T> - static void swap(T &one, T &two) { - T temp = one; - one = two; - two = temp; - } - - static void reverseByteOrder(void *ptr) { - // Reverses the byte order of the 32-bit word pointed to by Ptr - byte *charPtr = static_cast<byte *>(ptr); - swap(charPtr[0], charPtr[3]); - swap(charPtr[1], charPtr[2]); - } }; #define CTASSERT(ex) typedef char ctassert_type[(ex) ? 1 : -1] diff --git a/engines/sword25/kernel/persistenceservice.cpp b/engines/sword25/kernel/persistenceservice.cpp index 17e9199b5c..27d669caa1 100644 --- a/engines/sword25/kernel/persistenceservice.cpp +++ b/engines/sword25/kernel/persistenceservice.cpp @@ -50,7 +50,9 @@ static const char *SAVEGAME_DIRECTORY = "saves"; static const char *FILE_MARKER = "BS25SAVEGAME"; static const uint SLOT_COUNT = 18; static const uint FILE_COPY_BUFFER_SIZE = 1024 * 10; -static const char *VERSIONID = "SCUMMVM1"; +static const char *VERSIONIDOLD = "SCUMMVM1"; +static const char *VERSIONID = "SCUMMVM2"; +static const int VERSIONNUM = 2; #define MAX_SAVEGAME_SIZE 100 @@ -99,6 +101,7 @@ struct SavegameInformation { bool isOccupied; bool isCompatible; Common::String description; + int version; uint gamedataLength; uint gamedataOffset; uint gamedataUncompressedLength; @@ -147,9 +150,15 @@ struct PersistenceService::Impl { // Read in the header Common::String storedMarker = loadString(file); Common::String storedVersionID = loadString(file); + if (storedVersionID == VERSIONIDOLD) { + curSavegameInfo.version = 1; + } else { + Common::String versionNum = loadString(file); + curSavegameInfo.version = atoi(versionNum.c_str()); + } Common::String gameDescription = loadString(file); - Common::String gameDataLength = loadString(file); - curSavegameInfo.gamedataLength = atoi(gameDataLength.c_str()); + Common::String gamedataLength = loadString(file); + curSavegameInfo.gamedataLength = atoi(gamedataLength.c_str()); Common::String gamedataUncompressedLength = loadString(file); curSavegameInfo.gamedataUncompressedLength = atoi(gamedataUncompressedLength.c_str()); @@ -158,7 +167,7 @@ struct PersistenceService::Impl { // The slot is marked as occupied. curSavegameInfo.isOccupied = true; // Check if the saved game is compatible with the current engine version. - curSavegameInfo.isCompatible = (storedVersionID == Common::String(VERSIONID)); + curSavegameInfo.isCompatible = (curSavegameInfo.version <= VERSIONNUM); // Load the save game description. curSavegameInfo.description = gameDescription; // The offset to the stored save game data within the file. @@ -199,7 +208,7 @@ Common::String PersistenceService::getSavegameDirectory() { // Try and return the path using the savegame subfolder. But if doesn't exist, fall back on the data directory if (childNode.exists()) return childNode.getPath(); - + return node.getPath(); } @@ -242,6 +251,12 @@ Common::String &PersistenceService::getSavegameFilename(uint slotID) { return result; } +int PersistenceService::getSavegameVersion(uint slotID) { + if (!checkslotID(slotID)) + return -1; + return _impl->_savegameInformations[slotID].version; +} + bool PersistenceService::saveGame(uint slotID, const Common::String &screenshotFilename) { // FIXME: This code is a hack which bypasses the savefile API, // and should eventually be removed. @@ -264,6 +279,11 @@ bool PersistenceService::saveGame(uint slotID, const Common::String &screenshotF file->writeString(VERSIONID); file->writeByte(0); + char buf[20]; + snprintf(buf, 20, "%d", VERSIONNUM); + file->writeString(buf); + file->writeByte(0); + TimeDate dt; g_system->getTimeAndDate(dt); file->writeString(formatTimestamp(dt)); @@ -385,7 +405,7 @@ bool PersistenceService::loadGame(uint slotID) { memcpy(uncompressedDataBuffer, compressedDataBuffer, uncompressedBufferSize); } - InputPersistenceBlock reader(&uncompressedDataBuffer[0], curSavegameInfo.gamedataUncompressedLength); + InputPersistenceBlock reader(&uncompressedDataBuffer[0], curSavegameInfo.gamedataUncompressedLength, curSavegameInfo.version); // Einzelne Engine-Module depersistieren. bool success = true; diff --git a/engines/sword25/kernel/persistenceservice.h b/engines/sword25/kernel/persistenceservice.h index f73962892c..59e0a3661d 100644 --- a/engines/sword25/kernel/persistenceservice.h +++ b/engines/sword25/kernel/persistenceservice.h @@ -57,6 +57,7 @@ public: void reloadSlots(); bool isSlotOccupied(uint slotID); bool isSavegameCompatible(uint slotID); + int getSavegameVersion(uint slotID); Common::String &getSavegameDescription(uint slotID); Common::String &getSavegameFilename(uint slotID); |