diff --git a/engines/voyeur/files.cpp b/engines/voyeur/files.cpp index ee23855cbf7..6f2ef5c2880 100644 --- a/engines/voyeur/files.cpp +++ b/engines/voyeur/files.cpp @@ -510,6 +510,7 @@ PictureResource::PictureResource(BoltFilesState &state, const byte *src) { _maskData = READ_LE_UINT32(&src[14]); _imgData = NULL; + _secondPicture = NULL; int nbytes = _bounds.width() * _bounds.height(); if (_flags & 0x20) { @@ -683,9 +684,10 @@ void ViewPortResource::setupViewPort(PictureResource *page, Common::Rect *clipRe if (yDiff > 0) r.setHeight(yDiff <= r.height() ? r.height() - yDiff : 0); } - +// clip = (0x20, 0x14, width: 0x140, height: 0C8h _activePage = page; _field18 = 0; + _clipRect = r; _setupFn = setupFn; _addFn = addFn; _restoreFn = restoreFn; diff --git a/engines/voyeur/files.h b/engines/voyeur/files.h index 228b5093bba..57fbb0f8805 100644 --- a/engines/voyeur/files.h +++ b/engines/voyeur/files.h @@ -204,6 +204,13 @@ public: uint _planeSize; byte *_imgData; + + // TODO: Investigate further just why/how pictuers are chained + PictureResource *_secondPicture; + // TODO: Figure out if the following data is part of all pictures, or if + // only for certain types (when flags & 0x8000 != 0) + Common::Rect _bounds2; + Field86MethodPtr _field86; public: PictureResource(BoltFilesState &state, const byte *src); virtual ~PictureResource(); diff --git a/engines/voyeur/graphics.cpp b/engines/voyeur/graphics.cpp index 33391703d3f..006aca12b37 100644 --- a/engines/voyeur/graphics.cpp +++ b/engines/voyeur/graphics.cpp @@ -31,8 +31,11 @@ namespace Voyeur { GraphicsManager::GraphicsManager() { _SVGAPage = 0; _SVGAMode = 0; + _SVGAReset = 0; + _screenOffset = 0; _palFlag = false; _MCGAMode = false; + _saveBack = false; _clipPtr = NULL; } @@ -76,7 +79,7 @@ void GraphicsManager::setupMCGASaveRect(ViewPortResource *viewPort) { Common::Rect *clipRect = _clipPtr; _clipPtr = &viewPort->_clipRect; - sDrawPic(viewPort->_activePage, viewPort->_picResource, viewPort, NULL); + sDrawPic(viewPort->_activePage, viewPort->_picResource, Common::Point(), NULL); _clipPtr = clipRect; } @@ -96,8 +99,178 @@ void GraphicsManager::addRectNoSaveBack(ViewPortResource *viewPort, void *v2, vo } -void GraphicsManager::sDrawPic(PictureResource *pic, PictureResource *pic2, ViewPortResource *viewPort, void *v3) { +void GraphicsManager::sDrawPic(PictureResource *srcPic, PictureResource *destPic, + const Common::Point &offset, void *v3) { + int var4C = 0; + int width1, width2; + int widthDiff, widthDiff2; + int height1; + int srcOffset; + int screenOffset; + int flags1, flags2; + PictureResource *saveddestPic = NULL; + Common::Rect newBounds; + Common::Rect backBounds; + int var24; + bool isClipped = false; + int var52; + int var20, var22; + int var26; + byte *imgData1, *imgData2; + byte *srcP, *destP; + if (srcPic->_flags & 0x8000) { + srcPic = srcPic->_secondPicture; + warning("TODO: Particularly validate 'extended' pictures"); + } + if (destPic->_flags & 0x8000) { + saveddestPic = destPic; + destPic = destPic->_secondPicture; + warning("TODO: Particularly validate 'extended' pictures"); + } + + Common::Point ofs = Common::Point(offset.x + srcPic->_bounds.left - destPic->_bounds.left, + offset.y + srcPic->_bounds.top - destPic->_bounds.top); + width1 = width2 = srcPic->_bounds.width(); + height1 = srcPic->_bounds.height(); + srcOffset = 0; + flags1 = srcPic->_flags; + flags2 = destPic->_flags; + + if (flags1 & 1) { + if (_clipPtr) { + int xs = _clipPtr->left - srcPic->_bounds.left; + int ys = _clipPtr->top - srcPic->_bounds.top; + newBounds = Common::Rect(xs, ys, xs + _clipPtr->width(), ys + _clipPtr->height()); + } else if (saveddestPic) { + int xs = saveddestPic->_bounds2.left - destPic->_bounds.left; + int ys = saveddestPic->_bounds2.top - destPic->_bounds.top; + newBounds = Common::Rect(xs, ys, xs + destPic->_bounds2.width(), ys + destPic->_bounds2.height()); + } else { + newBounds = Common::Rect(0, 0, destPic->_bounds.width(), destPic->_bounds.height()); + } + + var24 = ofs.y - newBounds.top; + if (var24 < 0) { + var52 = width2; + srcOffset -= var24 * var52; + height1 += var24; + ofs.y = newBounds.top; + + if (height1 <= 0) + return; + + isClipped = true; + } + + var20 = newBounds.bottom - (ofs.y + height1); + if (var20 < 0) { + height1 += var20; + if (height1 <= 0) + return; + } + + var22 = ofs.x - newBounds.left; + if (var22 < 0) { + srcOffset -= var22; + width2 += var22; + ofs.x = newBounds.left; + + if (width2 <= 0) + return; + + isClipped = true; + } + + var26 = newBounds.right - (ofs.x + width2); + if (var26 < 0) { + width2 += var26; + if (width2 <= 0) + return; + + isClipped = true; + } + } + + screenOffset = ofs.y * destPic->_bounds.width() + ofs.x; + widthDiff = width1 - width2; + widthDiff2 = destPic->_bounds.width() - width2; + + if (saveddestPic) { + error("TODO: Examine further when it's actually used"); + if (!_saveBack || ((srcPic->_flags & 0x800) != 0)) { + // TODO + } else if (!saveddestPic->_field86) { + // TODO + } else { + int xs = ofs.x + destPic->_bounds.left; + int ys = ofs.y + destPic->_bounds.top; + backBounds = Common::Rect(xs, ys, xs + width2, ys + height1); + + (this->*saveddestPic->_field86)(saveddestPic, saveddestPic->_bounds.top, backBounds); + } + } + + if (flags1 & 0x1000) { + imgData1 = srcPic->_imgData + (var4C << 14) + _screenOffset; + for (uint idx = 0; idx < srcPic->_maskData; ++idx) { + if (var4C < 4) { + EMSMapPageHandle(srcPic->_planeSize, srcPic->_imgData[idx], var4C); + ++var4C; + } + } + } else { + imgData1 = srcPic->_imgData; + } + if (flags2 & 0x1000) { + imgData2 = destPic->_imgData + (var4C << 14) + _screenOffset; + for (uint idx = 0; idx < srcPic->_maskData; ++idx) { + if (var4C < 4) { + EMSMapPageHandle(destPic->_planeSize, destPic->_imgData[idx], var4C); + ++var4C; + } + } + } else { + imgData2 = destPic->_imgData; + } + + _SVGAPage = _SVGAReset; + if (srcPic->_select != 0xff) + return; + + if (srcPic->_pick == 0xff) { + if (flags1 & 8) { + error("TODO: sDrawPic"); + } else { + srcP = imgData1 + srcOffset; + + if (flags2 & 8) { + error("TODO: sDrawPic"); + } else { + destP = imgData2 + screenOffset; + + if (flags1 & 2) { + error("TODO: sDrawPic"); + } else { + if (flags1 & 0x100) { + error("TODO: sDrawPic"); + } else { + for (int yp = 0; yp < height1; ++yp) { + Common::copy(srcP, srcP + width2, destP); + destP += width2 + widthDiff2; + srcP += width2 + widthDiff; + } + } + } + } + } + } else { + error("TODO: sDrawPic"); + } +} + +void GraphicsManager::EMSMapPageHandle(int v1, int v2, int v3) { + // TODO } } // End of namespace Voyeur diff --git a/engines/voyeur/graphics.h b/engines/voyeur/graphics.h index ce89621e670..d17b18d3b00 100644 --- a/engines/voyeur/graphics.h +++ b/engines/voyeur/graphics.h @@ -45,6 +45,7 @@ typedef void (GraphicsManager::*GraphicMethodPtr)(); typedef void (GraphicsManager::*ViewPortSetupPtr)(ViewPortResource *); typedef void (GraphicsManager::*ViewPortAddPtr)(ViewPortResource *, void *v2, void *v3); typedef void (GraphicsManager::*ViewPortRestorePtr)(ViewPortResource *); +typedef void (GraphicsManager::*Field86MethodPtr)(void *pic, int y, Common::Rect &bounds); class GraphicsManager { public: @@ -55,9 +56,12 @@ public: PictureResource *_backgroundPage; int _SVGAPage; int _SVGAMode; + int _SVGAReset; ViewPortResource *_vPort; bool _MCGAMode; + bool _saveBack; Common::Rect *_clipPtr; + int _screenOffset; private: static void fadeIntFunc(); static void vDoFadeInt(); @@ -77,7 +81,8 @@ public: void restoreMCGASaveRect(ViewPortResource *viewPort); void addRectNoSaveBack(ViewPortResource *viewPort, void *v2, void *v3); - void sDrawPic(PictureResource *pic, PictureResource *pic2, ViewPortResource *viewPort, void *v3); + void EMSMapPageHandle(int v1, int v2, int v3); + void sDrawPic(PictureResource *srcPic, PictureResource *destPic, const Common::Point &offset, void *v3); }; } // End of namespace Voyeur