diff options
author | Sven Hesse | 2011-02-02 16:50:57 +0000 |
---|---|---|
committer | Sven Hesse | 2011-02-02 16:50:57 +0000 |
commit | 63c6d4432c2e7a032875c9b82a798f45314350ee (patch) | |
tree | 0bba8d79cc1fb7ac0712edcc2c955c8e02724fed /engines/gob | |
parent | 729be647a03970710d8dc15f3105f581abb4bb27 (diff) | |
download | scummvm-rg350-63c6d4432c2e7a032875c9b82a798f45314350ee.tar.gz scummvm-rg350-63c6d4432c2e7a032875c9b82a798f45314350ee.tar.bz2 scummvm-rg350-63c6d4432c2e7a032875c9b82a798f45314350ee.zip |
GOB: Implement LBM loading
svn-id: r55732
Diffstat (limited to 'engines/gob')
-rw-r--r-- | engines/gob/surface.cpp | 114 | ||||
-rw-r--r-- | engines/gob/surface.h | 28 |
2 files changed, 140 insertions, 2 deletions
diff --git a/engines/gob/surface.cpp b/engines/gob/surface.cpp index b68617277f..5f4c3a6ead 100644 --- a/engines/gob/surface.cpp +++ b/engines/gob/surface.cpp @@ -34,6 +34,105 @@ namespace Gob { +LBMLoader::LBMLoader(Common::SeekableReadStream &stream) : _parser(&stream), + _hasHeader(false), _palette(0), _image(0) { + +} + +bool LBMLoader::loadHeader(Graphics::BMHD &header) { + if (!readHeader()) + return false; + + header = _decoder._header; + return true; +} + +bool LBMLoader::loadPalette(byte *palette) { + assert(!_palette); + assert(palette); + + _palette = palette; + + Common::Functor1Mem<Common::IFFChunk&, bool, LBMLoader> c(this, &LBMLoader::callbackPalette); + _parser.parse(c); + + if (!_palette) + return false; + + _palette = 0; + return true; +} + +bool LBMLoader::loadImage(byte *image) { + assert(!_image); + assert(image); + + if (!readHeader()) + return false; + + _image = image; + + Common::Functor1Mem<Common::IFFChunk&, bool, LBMLoader> c(this, &LBMLoader::callbackImage); + _parser.parse(c); + + if (!_image) + return false; + + _image = 0; + return true; +} + +bool LBMLoader::callbackHeader(Common::IFFChunk &chunk) { + if (chunk._type == ID_BMHD) { + if (chunk._size == sizeof(Graphics::BMHD)) { + _decoder.loadHeader(chunk._stream); + _hasHeader = true; + } + + return true; // Stop the IFF parser + } + + return false; +} + +bool LBMLoader::callbackPalette(Common::IFFChunk &chunk) { + assert(_palette); + + if (chunk._type == ID_CMAP) { + if (chunk._size == 768) { + if (chunk._stream->read(_palette, chunk._size) != chunk._size) + _palette = 0; + } else + _palette = 0; + + return true; // Stop the IFF parser + } + + return false; +} + +bool LBMLoader::callbackImage(Common::IFFChunk &chunk) { + assert(_image); + + if (chunk._type == ID_BODY) { + _decoder.loadBitmap(Graphics::ILBMDecoder::ILBM_UNPACK_PLANES, _image, chunk._stream); + return true; + } + + return false; +} + +bool LBMLoader::readHeader() { + if (_hasHeader) + return true; + + Common::Functor1Mem<Common::IFFChunk&, bool, LBMLoader> c(this, &LBMLoader::callbackHeader); + _parser.parse(c); + + return _hasHeader; +} + + static void plotPixel(int x, int y, int color, void *data) { Surface *dest = (Surface *)data; @@ -761,8 +860,19 @@ bool Surface::loadTGA(Common::SeekableReadStream &stream) { } bool Surface::loadLBM(Common::SeekableReadStream &stream) { - warning("TODO: Surface::loadLBM()"); - return false; + + LBMLoader loader(stream); + + Graphics::BMHD header; + loader.loadHeader(header); + + if (header.depth != 8) + // Only 8bpp LBMs supported for now + return false; + + resize(header.width, header.height); + + return loader.loadImage(_vidMem); } bool Surface::loadBRC(Common::SeekableReadStream &stream) { diff --git a/engines/gob/surface.h b/engines/gob/surface.h index c5a364eb7f..3dea18e36e 100644 --- a/engines/gob/surface.h +++ b/engines/gob/surface.h @@ -29,6 +29,9 @@ #include "common/scummsys.h" #include "common/ptr.h" #include "common/rational.h" +#include "common/iff_container.h" + +#include "graphics/iff.h" namespace Common { class SeekableReadStream; @@ -45,6 +48,31 @@ enum ImageType { kImageTypeJPEG }; +class LBMLoader { +public: + LBMLoader(Common::SeekableReadStream &stream); + + bool loadHeader (Graphics::BMHD &header); + bool loadPalette(byte *palette); + bool loadImage (byte *image); + +private: + Common::IFFParser _parser; + + bool _hasHeader; + + Graphics::ILBMDecoder _decoder; + + byte *_palette; + byte *_image; + + bool callbackHeader (Common::IFFChunk &chunk); + bool callbackPalette(Common::IFFChunk &chunk); + bool callbackImage (Common::IFFChunk &chunk); + + bool readHeader(); +}; + /** An iterator over a surface's image data, automatically handles different color depths. */ class Pixel { public: |