diff options
author | Sven Hesse | 2011-01-21 19:15:10 +0000 |
---|---|---|
committer | Sven Hesse | 2011-01-21 19:15:10 +0000 |
commit | 9e338a170f8253fea2accf2b95f44806dfdf24f8 (patch) | |
tree | e759a9c97e30fbe123112639a881ef0a3b6d1981 /engines/gob | |
parent | 0e33dd91645bb26c51731cc79b2f142b3883047c (diff) | |
download | scummvm-rg350-9e338a170f8253fea2accf2b95f44806dfdf24f8.tar.gz scummvm-rg350-9e338a170f8253fea2accf2b95f44806dfdf24f8.tar.bz2 scummvm-rg350-9e338a170f8253fea2accf2b95f44806dfdf24f8.zip |
GOB: Add support for saving true color sprites
Not exactly the "nice", since up-depthing the sprite data to 24bit
happens after it has been adapted to the current system's color
format, so we're going to gradually lose precision when the save
gets passed around different systems. Still, this is the least
headachy solution, I guess...
svn-id: r55383
Diffstat (limited to 'engines/gob')
-rw-r--r-- | engines/gob/save/savefile.cpp | 104 | ||||
-rw-r--r-- | engines/gob/save/savefile.h | 12 | ||||
-rw-r--r-- | engines/gob/save/savehandler.cpp | 44 | ||||
-rw-r--r-- | engines/gob/save/savehandler.h | 7 | ||||
-rw-r--r-- | engines/gob/save/saveload_inca2.cpp | 2 | ||||
-rw-r--r-- | engines/gob/save/saveload_v3.cpp | 2 |
6 files changed, 126 insertions, 45 deletions
diff --git a/engines/gob/save/savefile.cpp b/engines/gob/save/savefile.cpp index 3869ea2def..d472ef600b 100644 --- a/engines/gob/save/savefile.cpp +++ b/engines/gob/save/savefile.cpp @@ -85,6 +85,16 @@ bool SaveHeader::verify(Common::ReadStream &stream) const { return !stream.err(); } +bool SaveHeader::operator==(const SaveHeader &header) const { + return (_type == header._type) && + (_version == header._version) && + (_size == header._size); +} + +bool SaveHeader::operator!=(const SaveHeader &header) const { + return !(*this == header); +} + bool SaveHeader::verifyReadSize(Common::ReadStream &stream) { // Compare the header with the stream's content, expect for the size @@ -263,21 +273,29 @@ bool SavePartVars::writeInto(uint32 var, uint32 offset, uint32 size) const { return true; } -SavePartSprite::SavePartSprite(uint32 width, uint32 height) { +SavePartSprite::SavePartSprite(uint32 width, uint32 height, bool trueColor) { assert((width > 0) && (height > 0)); _width = width; _height = height; + _oldFormat = false; + _trueColor = trueColor; + _header.setType(kID); _header.setVersion(kVersion); - // width + height + sprite + palette - _header.setSize(4 + 4 + _width * _height + 768); - _dataSprite = new byte[_width * _height]; + _spriteSize = _width * _height; + if (_trueColor) + _spriteSize *= 3; + + // width + height + color + sprite + palette + _header.setSize(4 + 4 + 1 + _spriteSize + 768); + + _dataSprite = new byte[_spriteSize]; _dataPalette = new byte[768]; - memset(_dataSprite, 0, _width * _height); + memset(_dataSprite, 0, _spriteSize); memset(_dataPalette, 0, 768); } @@ -287,8 +305,28 @@ SavePartSprite::~SavePartSprite() { } bool SavePartSprite::read(Common::ReadStream &stream) { - if (!_header.verify(stream)) - return false; + SaveHeader header; + header.read(stream); + + if (_header != header) { + if (!_trueColor) { + // Header validation failed, trying again with the old version + + _header.setVersion(1); + _header.setSize(_header.getSize() - 1); + + if (_header != header) + // Nope, isn't it either + return false; + + _oldFormat = true; + + _header.setVersion(kVersion); + _header.setSize(_header.getSize() + 1); + + } else + return false; + } // The sprite's dimensions have to fit if (stream.readUint32LE() != _width) @@ -296,8 +334,13 @@ bool SavePartSprite::read(Common::ReadStream &stream) { if (stream.readUint32LE() != _height) return false; + // If it's in the current format, the true color flag has to be the same too + if (!_oldFormat) + if (stream.readByte() != _trueColor) + return false; + // Sprite data - if (stream.read(_dataSprite, _width * _height) != (_width * _height)) + if (stream.read(_dataSprite, _spriteSize) != _spriteSize) return false; // Palette data @@ -314,9 +357,10 @@ bool SavePartSprite::write(Common::WriteStream &stream) const { // The sprite's dimensions stream.writeUint32LE(_width); stream.writeUint32LE(_height); + stream.writeByte(_trueColor); // Sprite data - if (stream.write(_dataSprite, _width * _height) != (_width * _height)) + if (stream.write(_dataSprite, _spriteSize) != _spriteSize) return false; // Palette data @@ -339,17 +383,29 @@ bool SavePartSprite::readSprite(const Surface &sprite) { if (((uint32)sprite.getHeight()) != _height) return false; - // Only 8bit sprites supported for now - if (sprite.getBPP() != 1) - return false; + if (_trueColor) { + if (sprite.getBPP() <= 1) + return false; - memcpy(_dataSprite, sprite.getData(), _width * _height); + Graphics::PixelFormat pixelFormat = g_system->getScreenFormat(); + + byte *data = _dataSprite; + ConstPixel pixel = sprite.get(); + for (uint32 i = 0; i < (_width * _height); i++, ++pixel, data += 3) + pixelFormat.colorToRGB(pixel.get(), data[0], data[1], data[2]); + + } else { + if (sprite.getBPP() != 1) + return false; + + memcpy(_dataSprite, sprite.getData(), _width * _height); + } return true; } bool SavePartSprite::readSpriteRaw(const byte *data, uint32 size) { - if (size != (_width * _height)) + if (size != _spriteSize) return false; memcpy(_dataSprite, data, size); @@ -369,11 +425,23 @@ bool SavePartSprite::writeSprite(Surface &sprite) const { if (((uint32)sprite.getHeight()) != _height) return false; - // Only 8bit sprites supported for now - if (sprite.getBPP() != 1) - return false; + if (_trueColor) { + if (sprite.getBPP() <= 1) + return false; + + Graphics::PixelFormat pixelFormat = g_system->getScreenFormat(); - memcpy(sprite.getData(), _dataSprite, _width * _height); + const byte *data = _dataSprite; + Pixel pixel = sprite.get(); + for (uint32 i = 0; i < (_width * _height); i++, ++pixel, data += 3) + pixel.set(pixelFormat.RGBToColor(data[0], data[1], data[2])); + + } else { + if (sprite.getBPP() != 1) + return false; + + memcpy(sprite.getData(), _dataSprite, _spriteSize); + } return true; } diff --git a/engines/gob/save/savefile.h b/engines/gob/save/savefile.h index 980616bb74..eeee03847a 100644 --- a/engines/gob/save/savefile.h +++ b/engines/gob/save/savefile.h @@ -53,6 +53,9 @@ public: SaveHeader(uint32 type = 0, uint32 version = 0, uint32 size = 0); + bool operator==(const SaveHeader &header) const; + bool operator!=(const SaveHeader &header) const; + /** Read the header out of a stream into this class. */ bool read(Common::ReadStream &stream); /** Read the header out of a stream and checks it against this class's contents. */ @@ -151,10 +154,10 @@ private: /** A save part holding a sprite. */ class SavePartSprite : public SavePart { public: - static const uint32 kVersion = 1; + static const uint32 kVersion = 2; static const uint32 kID = MKID_BE('SPRT'); - SavePartSprite(uint32 width, uint32 height); + SavePartSprite(uint32 width, uint32 height, bool trueColor = false); ~SavePartSprite(); bool read(Common::ReadStream &stream); @@ -177,6 +180,11 @@ private: uint32 _width; uint32 _height; + uint32 _spriteSize; + + bool _oldFormat; + bool _trueColor; + byte *_dataSprite; byte *_dataPalette; }; diff --git a/engines/gob/save/savehandler.cpp b/engines/gob/save/savehandler.cpp index 8a20665140..848578abce 100644 --- a/engines/gob/save/savehandler.cpp +++ b/engines/gob/save/savehandler.cpp @@ -279,12 +279,11 @@ bool TempSpriteHandler::load(int16 dataVar, int32 size, int32 offset) { } bool TempSpriteHandler::save(int16 dataVar, int32 size, int32 offset) { - SurfacePtr sprite; - if (isDummy(size)) return true; - if (!createSprite(dataVar, size, offset, &sprite)) + SurfacePtr sprite = createSprite(dataVar, size, offset); + if (!sprite) return false; // Save the sprite @@ -292,42 +291,47 @@ bool TempSpriteHandler::save(int16 dataVar, int32 size, int32 offset) { return false; // Handle palette - if (usesPalette(size)) { + if (usesPalette(size)) if (!_sprite->readPalette((const byte *)_vm->_global->_pPaletteDesc->vgaPal)) return false; - } return true; } -bool TempSpriteHandler::createSprite(int16 dataVar, int32 size, - int32 offset, SurfacePtr *sprite) { - +bool TempSpriteHandler::create(uint32 width, uint32 height, bool trueColor) { delete _sprite; _sprite = 0; + // Create a new temporary sprite + _sprite = new SavePartSprite(width, height, trueColor); + + return true; +} + +bool TempSpriteHandler::createFromSprite(int16 dataVar, int32 size, int32 offset) { + return createSprite(dataVar, size, offset) != 0; +} + +SurfacePtr TempSpriteHandler::createSprite(int16 dataVar, int32 size, int32 offset) { + SurfacePtr sprt; + // Sprite requested? if (!isSprite(size)) - return false; + return sprt; // Index sane? int index = getIndex(size); if ((index < 0) || (index >= SPRITES_COUNT)) - return false; - - SurfacePtr sprt = _vm->_draw->_spritesArray[index]; + return sprt; // Sprite exists? - if (!sprt) - return false; + if (!(sprt = _vm->_draw->_spritesArray[index])) + return sprt; - // Create a new temporary sprite - _sprite = new SavePartSprite(sprt->getWidth(), sprt->getHeight()); + if (!create(sprt->getWidth(), sprt->getHeight(), sprt->getBPP() > 1)) + sprt.reset(); - if (sprite) - *sprite = sprt; - - return true; + return sprt; } // A size of 0 means no proper sprite should be saved/loaded, diff --git a/engines/gob/save/savehandler.h b/engines/gob/save/savehandler.h index c6370947e2..51fbad0b98 100644 --- a/engines/gob/save/savehandler.h +++ b/engines/gob/save/savehandler.h @@ -140,9 +140,8 @@ public: bool load(int16 dataVar, int32 size, int32 offset); bool save(int16 dataVar, int32 size, int32 offset); - /** Create a fitting sprite. */ - bool createSprite(int16 dataVar, int32 size, - int32 offset, SurfacePtr *sprite = 0); + bool create(uint32 width, uint32 height, bool trueColor); + bool createFromSprite(int16 dataVar, int32 size, int32 offset); protected: SavePartSprite *_sprite; @@ -155,6 +154,8 @@ protected: static int getIndex(int32 size); /** Determine whether the palette should be used too. */ static bool usesPalette(int32 size); + + SurfacePtr createSprite(int16 dataVar, int32 size, int32 offset); }; /** A handler for notes. */ diff --git a/engines/gob/save/saveload_inca2.cpp b/engines/gob/save/saveload_inca2.cpp index e32c4fd25c..68c76c3f2b 100644 --- a/engines/gob/save/saveload_inca2.cpp +++ b/engines/gob/save/saveload_inca2.cpp @@ -322,7 +322,7 @@ bool SaveLoad_Inca2::ScreenshotHandler::load(int16 dataVar, int32 size, int32 of return false; } - if (!TempSpriteHandler::createSprite(dataVar, size, offset)) + if (!TempSpriteHandler::createFromSprite(dataVar, size, offset)) return false; if (!_gameHandler->loadScreenshot(slot, _sprite)) diff --git a/engines/gob/save/saveload_v3.cpp b/engines/gob/save/saveload_v3.cpp index bb60f94725..098b8e1160 100644 --- a/engines/gob/save/saveload_v3.cpp +++ b/engines/gob/save/saveload_v3.cpp @@ -439,7 +439,7 @@ bool SaveLoad_v3::ScreenshotHandler::load(int16 dataVar, int32 size, int32 offse if ((slot >= kSlotCount) || (slotRem != 0)) return false; - if (!TempSpriteHandler::createSprite(dataVar, size, offset)) + if (!TempSpriteHandler::createFromSprite(dataVar, size, offset)) return false; if (!_gameHandler->loadScreenshot(slot, _sprite)) |