aboutsummaryrefslogtreecommitdiff
path: root/engines/gob
diff options
context:
space:
mode:
authorSven Hesse2011-02-02 16:50:57 +0000
committerSven Hesse2011-02-02 16:50:57 +0000
commit63c6d4432c2e7a032875c9b82a798f45314350ee (patch)
tree0bba8d79cc1fb7ac0712edcc2c955c8e02724fed /engines/gob
parent729be647a03970710d8dc15f3105f581abb4bb27 (diff)
downloadscummvm-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.cpp114
-rw-r--r--engines/gob/surface.h28
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: