diff options
Diffstat (limited to 'engines')
-rw-r--r-- | engines/gob/inter_v7.cpp | 32 | ||||
-rw-r--r-- | engines/gob/surface.cpp | 99 | ||||
-rw-r--r-- | engines/gob/surface.h | 24 |
3 files changed, 152 insertions, 3 deletions
diff --git a/engines/gob/inter_v7.cpp b/engines/gob/inter_v7.cpp index 17f2411c8b..e2668dff6a 100644 --- a/engines/gob/inter_v7.cpp +++ b/engines/gob/inter_v7.cpp @@ -30,6 +30,7 @@ #include "gob/gob.h" #include "gob/global.h" +#include "gob/dataio.h" #include "gob/inter.h" #include "gob/game.h" #include "gob/script.h" @@ -364,10 +365,35 @@ void Inter_v7::o7_loadImage() { int16 y = _vm->_game->_script->readValExpr(); int16 transp = _vm->_game->_script->readValExpr(); - // Supported formats: TGA, LBM, BRC, BMP or JPEG + if (spriteIndex > 100) + spriteIndex -= 80; - warning("Addy Stub: Load image \"%s\", sprite %d, %dx%d+%d+%d @ %d+%d (%d)", - file.c_str(), spriteIndex, width, height, left, top, x, y, transp); + if ((spriteIndex < 0) || (spriteIndex >= Draw::kSpriteCount)) { + warning("o7_loadImage(): Sprite %d out of range", spriteIndex); + return; + } + + SurfacePtr destSprite = _vm->_draw->_spritesArray[spriteIndex]; + if (!destSprite) { + warning("o7_loadImage(): Sprite %d does not exist", spriteIndex); + return; + } + + Common::SeekableReadStream *imageFile = _vm->_dataIO->getFile(file); + if (!imageFile) { + warning("o7_loadImage(): No such file \"%s\"", file.c_str()); + return; + } + + SurfacePtr image = _vm->_video->initSurfDesc(1, 1); + if (!image->loadImage(*imageFile)) { + warning("o7_loadImage(): Failed to load image \"%s\"", file.c_str()); + return; + } + + int16 right = left + width - 1; + int16 bottom = top + height - 1; + destSprite->blit(*image, left, top, right, bottom, x, y, transp); } void Inter_v7::o7_setVolume() { diff --git a/engines/gob/surface.cpp b/engines/gob/surface.cpp index 58482a6424..b68617277f 100644 --- a/engines/gob/surface.cpp +++ b/engines/gob/surface.cpp @@ -26,6 +26,7 @@ #include "gob/surface.h" #include "common/system.h" +#include "common/stream.h" #include "common/util.h" #include "common/frac.h" @@ -681,4 +682,102 @@ void Surface::blitToScreen(uint16 left, uint16 top, uint16 right, uint16 bottom, g_system->copyRectToScreen(src, _width * _bpp, x, y, width, height); } +bool Surface::loadImage(Common::SeekableReadStream &stream) { + ImageType type = identifyImage(stream); + if (type == kImageTypeNone) + return false; + + return loadImage(stream, type); +} + +bool Surface::loadImage(Common::SeekableReadStream &stream, ImageType type) { + if (type == kImageTypeNone) + return false; + + switch (type) { + case kImageTypeTGA: + return loadTGA(stream); + case kImageTypeLBM: + return loadLBM(stream); + case kImageTypeBRC: + return loadBRC(stream); + case kImageTypeBMP: + return loadBMP(stream); + case kImageTypeJPEG: + return loadJPEG(stream); + + default: + warning("Surface::loadImage(): Unknown image type: %d", (int) type); + return false; + } + + return false; +} + +ImageType Surface::identifyImage(Common::SeekableReadStream &stream) { + uint32 startPos = stream.pos(); + + if ((stream.size() - startPos) < 17) + return kImageTypeNone; + + char buffer[4]; + if (!stream.read(buffer, 4)) + return kImageTypeNone; + + stream.seek(startPos); + + if (!strncmp(buffer, "FORM", 4)) + return kImageTypeLBM; + if (!strncmp(buffer, "JFIF", 4)) + return kImageTypeJPEG; + if (!strncmp(buffer, "BRC" , 3)) + return kImageTypeBRC; + if (!strncmp(buffer, "BM" , 2)) + return kImageTypeBMP; + + // Try to determine if it's maybe a TGA + + stream.skip(12); + uint16 width = stream.readUint16LE(); + uint16 height = stream.readUint16LE(); + uint8 bpp = stream.readByte(); + + // Check width, height and bpp for sane values + if ((width == 0) || (height == 0) || (bpp == 0)) + return kImageTypeNone; + if ((width > 800) || (height > 600)) + return kImageTypeNone; + if ((bpp != 8) && (bpp != 16) && (bpp != 24) && (bpp != 32)) + return kImageTypeNone; + + // This might be a TGA + return kImageTypeTGA; +} + + +bool Surface::loadTGA(Common::SeekableReadStream &stream) { + warning("TODO: Surface::loadTGA()"); + return false; +} + +bool Surface::loadLBM(Common::SeekableReadStream &stream) { + warning("TODO: Surface::loadLBM()"); + return false; +} + +bool Surface::loadBRC(Common::SeekableReadStream &stream) { + warning("TODO: Surface::loadBRC()"); + return false; +} + +bool Surface::loadBMP(Common::SeekableReadStream &stream) { + warning("TODO: Surface::loadBMP()"); + return false; +} + +bool Surface::loadJPEG(Common::SeekableReadStream &stream) { + warning("TODO: Surface::loadJPEG()"); + return false; +} + } // End of namespace Gob diff --git a/engines/gob/surface.h b/engines/gob/surface.h index a8d52c7b36..c5a364eb7f 100644 --- a/engines/gob/surface.h +++ b/engines/gob/surface.h @@ -30,8 +30,21 @@ #include "common/ptr.h" #include "common/rational.h" +namespace Common { + class SeekableReadStream; +} + namespace Gob { +enum ImageType { + kImageTypeNone = -1, + kImageTypeTGA = 0, + kImageTypeLBM, + kImageTypeBRC, + kImageTypeBMP, + kImageTypeJPEG +}; + /** An iterator over a surface's image data, automatically handles different color depths. */ class Pixel { public: @@ -123,6 +136,11 @@ public: void blitToScreen(uint16 left, uint16 top, uint16 right, uint16 bottom, uint16 x, uint16 y) const; + bool loadImage(Common::SeekableReadStream &stream); + bool loadImage(Common::SeekableReadStream &stream, ImageType type); + + static ImageType identifyImage(Common::SeekableReadStream &stream); + private: uint16 _width; uint16 _height; @@ -133,6 +151,12 @@ private: static bool clipBlitRect(int16 &left, int16 &top, int16 &right, int16 &bottom, int16 &x, int16 &y, uint16 dWidth, uint16 dHeight, uint16 sWidth, uint16 sHeight); + + bool loadTGA (Common::SeekableReadStream &stream); + bool loadLBM (Common::SeekableReadStream &stream); + bool loadBRC (Common::SeekableReadStream &stream); + bool loadBMP (Common::SeekableReadStream &stream); + bool loadJPEG(Common::SeekableReadStream &stream); }; typedef Common::SharedPtr<Surface> SurfacePtr; |