aboutsummaryrefslogtreecommitdiff
path: root/engines/voyeur/screen.cpp
diff options
context:
space:
mode:
authorPaul Gilbert2016-03-10 21:53:14 -0500
committerPaul Gilbert2016-03-14 20:56:30 -0400
commitc05a09d33717d1b2c41b258013be589fa63a7097 (patch)
tree00ad9e4dfa42e965341e27c15410d01826f7c329 /engines/voyeur/screen.cpp
parent077250acfb09afb67a445fad30aef6af2e2af014 (diff)
downloadscummvm-rg350-c05a09d33717d1b2c41b258013be589fa63a7097.tar.gz
scummvm-rg350-c05a09d33717d1b2c41b258013be589fa63a7097.tar.bz2
scummvm-rg350-c05a09d33717d1b2c41b258013be589fa63a7097.zip
VOYEUR: Changed engine to use Graphics::ManagedSurface
Diffstat (limited to 'engines/voyeur/screen.cpp')
-rw-r--r--engines/voyeur/screen.cpp1074
1 files changed, 1074 insertions, 0 deletions
diff --git a/engines/voyeur/screen.cpp b/engines/voyeur/screen.cpp
new file mode 100644
index 0000000000..62f609c5c7
--- /dev/null
+++ b/engines/voyeur/screen.cpp
@@ -0,0 +1,1074 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+#include "voyeur/screen.h"
+#include "voyeur/voyeur.h"
+#include "voyeur/staticres.h"
+#include "engines/util.h"
+#include "graphics/palette.h"
+#include "graphics/surface.h"
+
+namespace Voyeur {
+
+/*------------------------------------------------------------------------*/
+
+DrawInfo::DrawInfo(int penColor, const Common::Point &pos) {
+ _penColor = penColor;
+ _pos = pos;
+}
+
+/*------------------------------------------------------------------------*/
+
+Screen::Screen(VoyeurEngine *vm) : Graphics::Screen(), _vm(vm), _drawPtr(&_defaultDrawInfo),
+ _defaultDrawInfo(1, Common::Point()) {
+ _SVGAMode = 0;
+ _planeSelect = 0;
+ _saveBack = true;
+ _clipPtr = NULL;
+ _viewPortListPtr = NULL;
+ _backgroundPage = NULL;
+ _vPort = NULL;
+ _fontPtr = NULL;
+ Common::fill(&_VGAColors[0], &_VGAColors[PALETTE_SIZE], 0);
+ _fontChar = new PictureResource(DISPFLAG_NONE, 0xff, 0xff, 0, Common::Rect(), 0, NULL, 0);
+ _backColors = nullptr;
+}
+
+void Screen::sInitGraphics() {
+ initGraphics(SCREEN_WIDTH, SCREEN_HEIGHT, false);
+ create(SCREEN_WIDTH, SCREEN_HEIGHT);
+ clearPalette();
+}
+
+Screen::~Screen() {
+ delete _fontChar;
+}
+
+void Screen::setupMCGASaveRect(ViewPortResource *viewPort) {
+ if (viewPort->_activePage) {
+ viewPort->_activePage->_flags |= DISPFLAG_1;
+ Common::Rect *clipRect = _clipPtr;
+ _clipPtr = &viewPort->_clipRect;
+
+ sDrawPic(viewPort->_activePage, viewPort->_currentPic, Common::Point());
+
+ _clipPtr = clipRect;
+ }
+
+ viewPort->_rectListCount[1] = -1;
+}
+
+void Screen::addRectOptSaveRect(ViewPortResource *viewPort, int idx, const Common::Rect &bounds) {
+ if (viewPort->_rectListCount[idx] == -1)
+ return;
+
+ // TODO: Lots of code in original, which I suspect may be overlapping rect merging
+ viewPort->_rectListPtr[idx]->push_back(bounds);
+ ++viewPort->_rectListCount[idx];
+}
+
+void Screen::restoreMCGASaveRect(ViewPortResource *viewPort) {
+ if (viewPort->_rectListCount[0] != -1) {
+ for (int i = 0; i < viewPort->_rectListCount[0]; ++i) {
+ addRectOptSaveRect(viewPort, 1, (*viewPort->_rectListPtr[0])[i]);
+ }
+ } else {
+ viewPort->_rectListCount[1] = -1;
+ }
+
+ restoreBack(*viewPort->_rectListPtr[1], viewPort->_rectListCount[1], viewPort->_pages[0],
+ viewPort->_pages[1]);
+
+ int count = viewPort->_rectListCount[0];
+ restoreBack(*viewPort->_rectListPtr[0], viewPort->_rectListCount[0],
+ viewPort->_activePage, viewPort->_currentPic);
+
+ SWAP(viewPort->_rectListPtr[0], viewPort->_rectListPtr[1]);
+ viewPort->_rectListCount[1] = count;
+}
+
+void Screen::addRectNoSaveBack(ViewPortResource *viewPort, int idx, const Common::Rect &bounds) {
+ // Stubbed/dummy method in the original.
+}
+
+void Screen::sDrawPic(DisplayResource *srcDisplay, DisplayResource *destDisplay,
+ const Common::Point &initialOffset) {
+ int width1, width2;
+ int widthDiff, widthDiff2;
+ int height1;
+ int srcOffset;
+ int screenOffset;
+ int srcFlags, destFlags;
+ ViewPortResource *destViewPort = NULL;
+ Common::Rect newBounds;
+ Common::Rect backBounds;
+ int tmpWidth = 0;
+ int tmpHeight = 0;
+ bool isClipped = false;
+ byte pixel = 0;
+ int runLength;
+
+ byte *srcImgData, *destImgData;
+ const byte *srcP;
+ byte *destP;
+ byte byteVal, byteVal2;
+
+ PictureResource *srcPic;
+ PictureResource *destPic;
+
+ // Get the picture parameters, or deference viewport pointers to get their pictures
+ if (srcDisplay->_flags & DISPFLAG_VIEWPORT) {
+ // A viewport was passed, not a picture
+ srcPic = ((ViewPortResource *)srcDisplay)->_currentPic;
+ } else {
+ srcPic = (PictureResource *)srcDisplay;
+ }
+
+ if (destDisplay->_flags & DISPFLAG_VIEWPORT) {
+ // A viewport was passed, not a picture
+ destViewPort = (ViewPortResource *)destDisplay;
+ destPic = destViewPort->_currentPic;
+ } else {
+ destPic = (PictureResource *)destDisplay;
+ }
+
+ Common::Point offset = Common::Point(initialOffset.x + srcPic->_bounds.left - destPic->_bounds.left,
+ initialOffset.y + srcPic->_bounds.top - destPic->_bounds.top);
+ width1 = width2 = srcPic->_bounds.width();
+ height1 = srcPic->_bounds.height();
+ srcOffset = 0;
+ srcFlags = srcPic->_flags;
+ destFlags = destPic->_flags;
+ byte *cursorData = NULL;
+
+ if (srcFlags & DISPFLAG_1) {
+ if (_clipPtr) {
+ int xs = _clipPtr->left - destPic->_bounds.left;
+ int ys = _clipPtr->top - destPic->_bounds.top;
+ newBounds = Common::Rect(xs, ys, xs + _clipPtr->width(), ys + _clipPtr->height());
+ } else if (destViewPort) {
+ int xs = destViewPort->_clipRect.left - destPic->_bounds.left;
+ int ys = destViewPort->_clipRect.top - destPic->_bounds.top;
+ newBounds = Common::Rect(xs, ys, xs + destViewPort->_clipRect.width(),
+ ys + destViewPort->_clipRect.height());
+ } else {
+ newBounds = Common::Rect(0, 0, destPic->_bounds.width(), destPic->_bounds.height());
+ }
+
+ tmpHeight = offset.y - newBounds.top;
+ if (tmpHeight < 0) {
+ srcOffset -= tmpHeight * width2;
+ height1 += tmpHeight;
+ offset.y = newBounds.top;
+
+ if (height1 <= 0)
+ return;
+
+ isClipped = true;
+ }
+
+ int yMin = newBounds.bottom - (offset.y + height1);
+ if (yMin < 0) {
+ height1 += yMin;
+ if (height1 <= 0)
+ return;
+ }
+
+ tmpWidth = offset.x - newBounds.left;
+ if (tmpWidth < 0) {
+ srcOffset -= tmpWidth;
+ width2 += tmpWidth;
+ offset.x = newBounds.left;
+
+ if (width2 <= 0)
+ return;
+
+ isClipped = true;
+ }
+
+ int xMin = newBounds.right - (offset.x + width2);
+ if (xMin < 0) {
+ width2 += xMin;
+ if (width2 <= 0)
+ return;
+
+ isClipped = true;
+ }
+ }
+
+ screenOffset = offset.y * destPic->_bounds.width() + offset.x;
+ widthDiff = width1 - width2;
+ widthDiff2 = destPic->_bounds.width() - width2;
+
+ if (destViewPort) {
+ if (!_saveBack || (srcPic->_flags & DISPFLAG_800)) {
+ backBounds.left = destPic->_bounds.left + offset.x;
+ backBounds.top = destPic->_bounds.top + offset.y;
+ backBounds.setWidth(width2);
+ backBounds.setHeight(height1);
+ addRectOptSaveRect(destViewPort, 1, backBounds);
+
+ } else if (!destViewPort->_addFn) {
+ if (destViewPort->_rectListCount[destViewPort->_pageIndex] < -1) {
+ Common::Rect r;
+ r.left = destPic->_bounds.left + offset.x;
+ r.top = destPic->_bounds.top + offset.y;
+ r.setWidth(width2);
+ r.setHeight(height1);
+
+ (*destViewPort->_rectListPtr[destViewPort->_pageIndex]).push_back(r);
+ ++destViewPort->_rectListCount[destViewPort->_pageIndex];
+ }
+ } else {
+ int xs = offset.x + destPic->_bounds.left;
+ int ys = offset.y + destPic->_bounds.top;
+ backBounds = Common::Rect(xs, ys, xs + width2, ys + height1);
+
+ (this->*destViewPort->_addFn)(destViewPort, destViewPort->_bounds.top, backBounds);
+ }
+ }
+
+ if (srcFlags & DISPFLAG_1000) {
+ int imageDataShift = 0;
+ srcImgData = srcPic->_imgData + (imageDataShift << 14);
+ for (uint idx = 0; idx < srcPic->_maskData; ++idx) {
+ if (imageDataShift < 4)
+ ++imageDataShift;
+ }
+
+ destImgData = destPic->_imgData + (imageDataShift << 14);
+ for (uint idx = 0; idx < srcPic->_maskData; ++idx) {
+ if (imageDataShift < 4)
+ ++imageDataShift;
+ }
+ } else {
+ srcImgData = srcPic->_imgData;
+ destImgData = destPic->_imgData;
+ }
+
+ if (srcPic->_select != 0xff)
+ return;
+
+ if (destFlags & DISPFLAG_CURSOR) {
+ cursorData = new byte[width2 * height1];
+ Common::fill(cursorData, cursorData + width2 * height1, 0);
+ destImgData = cursorData;
+ }
+
+ if (srcPic->_pick == 0xff) {
+ if (srcFlags & DISPFLAG_8) {
+ error("TODO: sDrawPic variation");
+ } else {
+ // loc_258B8
+ srcP = srcImgData + srcOffset;
+
+ if (destFlags & DISPFLAG_8) {
+ // loc_258D8
+ destP = destImgData + screenOffset;
+
+ if (srcFlags & DISPFLAG_2) {
+ // loc_25652
+ srcP = srcImgData + srcOffset;
+
+ if (destFlags & DISPFLAG_8) {
+ // loc_2566F
+ if (srcFlags & DISPFLAG_2) {
+ // loc_256FA
+ srcP = (const byte *)getPixels() + srcOffset;
+
+ for (int yp = 0; yp < height1; ++yp) {
+ for (int xp = 0; xp < width2; ++xp, ++srcP, ++destP) {
+ pixel = *srcP;
+ if (pixel)
+ *destP = pixel;
+ }
+
+ srcP += widthDiff;
+ destP += widthDiff2;
+ }
+ } else {
+ // loc_25706
+ for (int yp = 0; yp < height1; ++yp) {
+ Common::copy(srcP, srcP + width2, destP);
+ srcP += width2 + widthDiff;
+ destP += width2 + widthDiff2;
+ }
+ }
+ } else {
+ // loc_25773
+ destP = destImgData + screenOffset;
+
+ if (srcFlags & DISPFLAG_2) {
+ // loc_25793
+ for (int yp = 0; yp < height1; ++yp) {
+ Common::copy(srcP, srcP + width2, destP);
+ srcP += width2 + widthDiff;
+ destP += width2 + widthDiff2;
+ }
+ } else {
+ // loc_25829
+ destP = (byte *)getPixels() + screenOffset;
+
+ for (int yp = 0; yp < height1; ++yp) {
+ Common::copy(srcP, srcP + width2, destP);
+ srcP += width2 + widthDiff;
+ destP += width2 + widthDiff2;
+ }
+
+ addDirtyRect(Common::Rect(offset.x, offset.y, offset.x + width2,
+ offset.y + height1));
+ }
+ }
+ } else {
+ // loc_25D40
+ if (srcFlags & DISPFLAG_100) {
+ // loc_25D4A
+ error("TODO: sDrawPic variation");
+ } else {
+ // loc_2606D
+ destP = (byte *)getPixels() + screenOffset;
+
+ for (int yp = 0; yp < height1; ++yp) {
+ Common::copy(srcP, srcP + width2, destP);
+ destP += width2 + widthDiff2;
+ srcP += width2 + widthDiff;
+ }
+
+ addDirtyRect(Common::Rect(offset.x, offset.y, offset.x + width2,
+ offset.y + height1));
+ }
+ }
+ } else {
+ // loc_2615E
+ destP = destImgData + screenOffset;
+
+ if (srcFlags & DISPFLAG_2) {
+ // loc_2617e
+ if (srcFlags & DISPFLAG_100) {
+ // loc_26188
+ srcP = srcImgData;
+ if (isClipped) {
+ // loc_26199
+ tmpWidth = (tmpWidth < 0) ? -tmpWidth : 0;
+ int xMax = tmpWidth + width2;
+ tmpHeight = (tmpHeight < 0) ? -tmpHeight : 0;
+
+ width2 = srcPic->_bounds.width();
+ height1 = tmpHeight + height1;
+
+ for (int yp = 0; yp < height1; ++yp) {
+ runLength = 0;
+
+ for (int xp = 0; xp < width2; ++xp, --runLength) {
+ if (runLength <= 0) {
+ pixel = *srcP++;
+ if (pixel & 0x80) {
+ pixel &= 0x7f;
+ runLength = *srcP++;
+ if (!runLength)
+ runLength = width2;
+ }
+ }
+
+ if (yp >= tmpHeight && xp >= tmpWidth && xp < xMax) {
+ if (pixel > 0)
+ *destP = pixel;
+ ++destP;
+ }
+ }
+
+ if (yp >= tmpHeight)
+ destP += widthDiff2;
+ }
+ } else {
+ // loc_262BE
+ byteVal = 0;
+ for (int yp = 0; yp < height1; ++yp) {
+ for (int xp = 0; xp < width2; ++xp) {
+ byteVal2 = 0;
+ if (!byteVal2) {
+ byteVal = *++srcP;
+ if (byteVal & 0x80) {
+ byteVal &= 0x7f;
+ byteVal2 = *srcP++;
+
+ if (!byteVal2)
+ byteVal2 = width2;
+ }
+ }
+
+ if (byteVal > 0)
+ *destP = byteVal;
+
+ ++destP;
+ --byteVal2;
+ }
+
+ destP += widthDiff2;
+ }
+ }
+ } else {
+ // loc_2637F
+ // Copy with transparency
+ for (int yp = 0; yp < height1; ++yp) {
+ for (int xp = 0; xp < width2; ++xp, ++srcP, ++destP) {
+ if (*srcP != 0)
+ *destP = *srcP;
+ }
+
+ destP += widthDiff2;
+ srcP += widthDiff;
+ }
+ }
+ } else {
+ if (srcFlags & DISPFLAG_100) {
+ // Simple run-length encoded image
+ srcP = srcImgData;
+
+ if (isClipped) {
+ // loc_26424
+ tmpWidth = (tmpWidth < 0) ? -tmpWidth : 0;
+ int xMax = tmpWidth + width2;
+ tmpHeight = (tmpHeight < 0) ? -tmpHeight : 0;
+ width2 = srcPic->_bounds.width();
+ height1 = tmpHeight + height1;
+
+ for (int yp = 0; yp < height1; ++yp) {
+ runLength = 0;
+ for (int xp = 0; xp < width2; ++xp, --runLength) {
+ if (runLength <= 0) {
+ pixel = *srcP++;
+ if (pixel & 0x80) {
+ pixel &= 0x7F;
+ runLength = *srcP++;
+
+ if (!runLength)
+ runLength = width2;
+ }
+ }
+
+ if (yp >= tmpHeight && xp >= tmpWidth && xp < xMax) {
+ *destP++ = pixel;
+ }
+ }
+
+ if (yp >= tmpHeight)
+ destP += widthDiff2;
+ }
+ } else {
+ // loc_26543
+ for (int yp = 0; yp < height1; ++yp) {
+ int runLen = 0;
+ for (int xp = 0; xp < width2; ++xp, --runLen) {
+ if (runLen <= 0) {
+ // Start of run length, so get pixel and repeat length
+ pixel = *srcP++;
+ if (pixel & 0x80) {
+ pixel &= 0x7f;
+ runLen = *srcP++;
+ if (runLen == 0)
+ runLen = width2;
+ }
+ }
+
+ // Copy pixel to output
+ *destP++ = pixel;
+ }
+
+ destP += widthDiff2;
+ }
+ }
+ } else {
+ for (int yp = 0; yp < height1; ++yp) {
+ Common::copy(srcP, srcP + width2, destP);
+ destP += width2 + widthDiff2;
+ srcP += width2 + widthDiff;
+ }
+ }
+ }
+ }
+ }
+ } else {
+ // loc_26666
+ if (srcPic->_pick == 0) {
+ // loc_2727A
+ byte onOff = srcPic->_onOff;
+
+ if (srcFlags & DISPFLAG_2) {
+ if (!(srcFlags & DISPFLAG_8)) {
+ srcP = srcImgData + srcOffset;
+
+ if (destFlags & DISPFLAG_8) {
+ // loc_272C3
+ error("TODO: sDrawPic variation");
+ } else {
+ destP = destImgData + screenOffset;
+ for (int yp = 0; yp < height1; ++yp) {
+ for (int xp = 0; xp < width2; ++xp, ++destP) {
+ if ((int8)*srcP++ < 0)
+ *destP = onOff;
+ }
+
+ destP += widthDiff2;
+ srcP += widthDiff;
+ }
+ }
+ }
+ } else {
+ // loc_27477
+ if (destFlags & DISPFLAG_8) {
+ // loc_27481
+ destP = (byte *)getPixels() + screenOffset;
+ for (int yp = 0; yp < height1; ++yp) {
+ Common::fill(destP, destP + width2, onOff);
+ destP += width2 + widthDiff2;
+ }
+
+ addDirtyRect(Common::Rect(offset.x, offset.y, offset.x + width2,
+ offset.y + height1));
+ } else {
+ // loc_2753C
+ destP = destImgData + screenOffset;
+
+ for (int yp = 0; yp < height1; ++yp) {
+ Common::fill(destP, destP + width2, onOff);
+ destP += width2 + widthDiff2;
+ }
+ }
+ }
+
+ } else {
+ // loc_26673
+ byte pick = srcPic->_pick;
+ byte onOff = srcPic->_onOff;
+
+ if (!(srcFlags & PICFLAG_PIC_OFFSET)) {
+ srcP = srcImgData += srcOffset;
+ pixel = 0;
+
+ if (destFlags & PICFLAG_PIC_OFFSET) {
+ destP = destImgData + screenOffset;
+ if (srcFlags & PICFLAG_2) {
+ if (srcFlags & PICFLAG_100) {
+ if (isClipped) {
+ // loc_266E3
+ destP = (byte *)getPixels() + screenOffset;
+ tmpWidth = (tmpWidth < 0) ? -tmpWidth : 0;
+ int xMax = tmpWidth + width2;
+ tmpHeight = (tmpHeight < 0) ? -tmpHeight : 0;
+ pick = 0x7F;
+ width2 = srcPic->_bounds.width();
+ height1 = tmpHeight + height1;
+
+ for (int yp = 0; yp < height1; ++yp) {
+ int runLen = 0;
+ for (int xp = 0; xp < width2; ++xp, --runLen) {
+ if (runLen <= 0) {
+ pixel = *srcP++;
+ if (pixel & 0x80) {
+ pixel &= 0x7F;
+ runLen = *srcP++;
+ if (!runLen)
+ runLen = width2;
+ }
+ }
+
+ if (yp >= tmpHeight && xp >= tmpWidth && xp < xMax) {
+ if (pixel) {
+ *destP = (pixel & pick) ^ onOff;
+ }
+ ++destP;
+ }
+ }
+ if (yp >= tmpHeight)
+ destP += widthDiff2;
+ }
+
+ addDirtyRect(Common::Rect(offset.x, offset.y, offset.x + width2,
+ offset.y + height1));
+ } else {
+ // loc_26815
+ destP = (byte *)getPixels() + screenOffset;
+
+ for (int yp = 0; yp < height1; ++yp) {
+ for (int xi = 0; xi < width2; ++xi, ++destP) {
+ byteVal2 = 0;
+ for (int xp = 0; xp < width2; ++xp, ++destP, --byteVal2) {
+ if (!byteVal2) {
+ pixel = *srcP++;
+ if (pixel & 0x80) {
+ pixel &= 0x7F;
+ byteVal2 = *srcP++;
+ if (!byteVal2) {
+ byteVal2 = width2;
+ }
+ }
+ }
+
+ if (pixel)
+ *destP = (pixel & pick) ^ onOff;
+ }
+ }
+
+ destP += widthDiff2;
+ }
+
+ addDirtyRect(Common::Rect(offset.x, offset.y, offset.x + width2,
+ offset.y + height1));
+ }
+ } else {
+ // Direct screen write
+ destP = (byte *)getPixels() + screenOffset;
+
+ for (int yp = 0; yp < height1; ++yp) {
+ for (int xp = 0; xp < width2; ++xp, ++srcP, ++destP) {
+ if (*srcP)
+ *destP = (*srcP & pick) ^ onOff;
+ }
+ destP += widthDiff2;
+ srcP += widthDiff;
+ }
+
+ addDirtyRect(Common::Rect(offset.x, offset.y, offset.x + width2,
+ offset.y + height1));
+ }
+ } else if (srcFlags & PICFLAG_100) {
+ srcP = srcImgData;
+ if (isClipped) {
+ // loc_269FD
+ tmpWidth = (tmpWidth < 0) ? -tmpWidth : 0;
+ int xMax = tmpWidth + width2;
+ tmpHeight = (tmpHeight < 0) ? -tmpHeight : 0;
+ width2 = srcPic->_bounds.width();
+ height1 = tmpHeight + height1;
+
+ for (int yp = 0; yp < height1; ++yp) {
+ runLength = 0;
+ for (int xp = 0; xp < width2; ++xp, --runLength) {
+ if (runLength <= 0) {
+ pixel = *srcP++;
+ if (pixel & 0x80) {
+ pixel &= 0x7F;
+ runLength = *srcP++;
+
+ if (!runLength)
+ runLength = width2;
+ }
+ }
+
+ if (yp >= tmpHeight && xp >= tmpWidth && xp < xMax) {
+ *destP++ = (pixel & 0x80) ^ onOff;
+ }
+ }
+ }
+ } else {
+ // loc_26BD5
+ destP = (byte *)getPixels() + screenOffset;
+
+ for (int yp = 0; yp < height1; ++yp) {
+ byteVal2 = 0;
+
+ for (int xp = 0; xp < width2; ++xp, ++destP) {
+ if (!byteVal2) {
+ pixel = *srcP++;
+ if (pixel & 0x80) {
+ pixel &= 0x7F;
+ byteVal2 = *srcP++;
+ if (!byteVal2)
+ byteVal2 = width2;
+ }
+ }
+
+ *destP = (pixel & pick) ^ onOff;
+ }
+
+ destP += widthDiff2;
+ }
+
+ addDirtyRect(Common::Rect(offset.x, offset.y, offset.x + width2,
+ offset.y + height1));
+ }
+ } else {
+ // loc_26C9A
+ destP = (byte *)getPixels() + screenOffset;
+
+ for (int yp = 0; yp < height1; ++yp) {
+ for (int xp = 0; xp < width2; ++xp, ++srcP, ++destP) {
+ *destP = (*srcP & pick) ^ onOff;
+ }
+ destP += widthDiff2;
+ srcP += widthDiff;
+ }
+
+ addDirtyRect(Common::Rect(offset.x, offset.y, offset.x + width2,
+ offset.y + height1));
+ }
+ } else {
+ // loc_26D2F
+ destP = destImgData + screenOffset;
+
+ if (srcFlags & PICFLAG_2) {
+ // loc_26D4F
+ if (srcFlags & PICFLAG_100) {
+ srcP = srcImgData;
+
+ if (isClipped) {
+ // loc_26D6A
+ tmpWidth = (tmpWidth < 0) ? -tmpWidth : 0;
+ int xMax = tmpWidth + width2;
+ tmpHeight = (tmpHeight < 0) ? -tmpHeight : 0;
+ width2 = srcPic->_bounds.width();
+ height1 = tmpHeight + height1;
+
+ for (int yp = 0; yp < height1; ++yp) {
+ runLength = 0;
+
+ for (int xp = 0; xp < width2; ++xp, --runLength) {
+ if (runLength <= 0) {
+ pixel = *srcP++;
+ if (pixel & 0x80) {
+ pixel &= 0x7F;
+ runLength = *srcP++;
+ if (!runLength)
+ runLength = width2;
+ }
+ }
+
+ if (yp >= tmpHeight && xp >= tmpWidth && xp < xMax) {
+ if (pixel)
+ *destP = (pixel & pick) ^ onOff;
+
+ ++destP;
+ }
+ }
+
+ if (yp >= tmpHeight)
+ destP += widthDiff2;
+ }
+ } else {
+ // loc_26E95
+ for (int yp = 0; yp < height1; ++yp) {
+ byteVal2 = 0;
+ for (int xp = 0; xp < width2; ++xp, ++destP, --byteVal2) {
+ if (!byteVal2) {
+ pixel = *srcP++;
+ if (pixel & 0x80) {
+ pixel &= 0x7F;
+ byteVal2 = *srcP++;
+ if (!byteVal2)
+ byteVal2 = width2;
+ }
+ }
+
+ if (pixel)
+ *destP = (pixel & pick) ^ onOff;
+ }
+
+ destP += widthDiff2;
+ }
+ }
+ } else {
+ // loc_26F5D
+ for (int yp = 0; yp < height1; ++yp) {
+ for (int xp = 0; xp < width2; ++xp, ++srcP, ++destP) {
+ if (*srcP)
+ *destP = (*srcP & pick) ^ onOff;
+ }
+ destP += widthDiff2;
+ srcP += widthDiff;
+ }
+ }
+ } else {
+ // loc_26FEF
+ if (srcFlags & PICFLAG_100) {
+ // loc_26FF9
+ for (int yp = 0; yp < height1; ++yp) {
+ for (int xp = 0; xp < width2; ++xp, ++srcP, ++destP) {
+ *destP = (*srcP & pick) ^ onOff;
+ }
+ destP += widthDiff2;
+ srcP += widthDiff;
+ }
+ } else {
+ // loc_271F0
+ srcP = srcImgData;
+
+ if (isClipped) {
+ // loc_2700A
+ tmpWidth = (tmpWidth < 0) ? -tmpWidth : 0;
+ int xMax = tmpWidth + width2;
+ tmpHeight = (tmpHeight < 0) ? -tmpHeight : 0;
+ width2 = srcPic->_bounds.width();
+ height1 = tmpHeight + height1;
+
+ for (int yp = 0; yp < height1; ++yp) {
+ runLength = 0;
+
+ for (int xp = 0; xp < width2; ++xp, --runLength) {
+ if (runLength <= 0) {
+ pixel = *srcP++;
+ if (pixel & 0x80) {
+ pixel &= 0x7F;
+ runLength = *srcP++;
+ if (!runLength)
+ runLength = width2;
+ }
+ }
+
+ if (yp >= tmpHeight && xp >= tmpWidth && xp < xMax) {
+ *destP++ = (pixel & pick) ^ onOff;
+ }
+ }
+
+ if (yp >= tmpHeight)
+ destP += widthDiff2;
+ }
+ } else {
+ // loc_2712F
+ for (int yp = 0; yp < height1; ++yp) {
+ byteVal2 = 0;
+ for (int xp = 0; xp < width2; ++xp, ++destP, --byteVal2) {
+ if (!byteVal2) {
+ pixel = *srcP++;
+ if (pixel & 0x80) {
+ pixel &= 0x7F;
+ byteVal2 = *srcP++;
+ if (!byteVal2)
+ byteVal2 = width2;
+ }
+ }
+
+ *destP = (*srcP & pick) ^ onOff;
+ }
+ destP += widthDiff2;
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+
+ if (cursorData) {
+ _vm->_eventsManager->setCursor(cursorData, width2, height1, srcPic->_keyColor);
+ delete[] cursorData;
+ }
+}
+
+void Screen::drawANumber(DisplayResource *display, int num, const Common::Point &pt) {
+ PictureResource *pic = _vm->_bVoy->boltEntry(num + 261)._picResource;
+ sDrawPic(pic, display, pt);
+}
+
+void Screen::fillPic(DisplayResource *display, byte onOff) {
+ PictureResource *pic;
+ if (display->_flags & DISPFLAG_VIEWPORT) {
+ pic = ((ViewPortResource *)display)->_currentPic;
+ } else {
+ pic = (PictureResource *)display;
+ }
+
+ PictureResource picResource;
+ picResource._flags = DISPFLAG_NONE;
+ picResource._select = 0xff;
+ picResource._pick = 0;
+ picResource._onOff = onOff;
+ picResource._bounds = pic->_bounds;
+
+ sDrawPic(&picResource, display, Common::Point());
+}
+
+/**
+ * Queues the given picture for display
+ */
+void Screen::sDisplayPic(PictureResource *pic) {
+ _vm->_eventsManager->_intPtr._flipWait = true;
+}
+
+void Screen::flipPage() {
+ Common::Array<ViewPortResource *> &viewPorts = _viewPortListPtr->_entries;
+ bool flipFlag = false;
+
+ for (uint idx = 0; idx < viewPorts.size(); ++idx) {
+ if ((viewPorts[idx]->_flags & (DISPFLAG_20 | DISPFLAG_8 | DISPFLAG_1)) == (DISPFLAG_20 | DISPFLAG_8 | DISPFLAG_1)) {
+ if (_planeSelect == idx)
+ sDisplayPic(viewPorts[idx]->_currentPic);
+ flipFlag = true;
+ }
+
+ if (flipFlag) {
+ ViewPortResource &viewPort = *viewPorts[idx];
+
+ viewPort._lastPage = viewPort._pageIndex;
+ ++viewPort._pageIndex;
+
+ if (viewPort._pageIndex >= viewPort._pageCount)
+ viewPort._pageIndex = 0;
+
+ assert(viewPort._pageIndex < 2);
+ viewPort._currentPic = viewPort._pages[viewPort._pageIndex];
+ viewPort._flags = (viewPort._flags & ~DISPFLAG_8) | DISPFLAG_40;
+ }
+ }
+}
+
+void Screen::restoreBack(Common::Array<Common::Rect> &rectList, int rectListCount,
+ PictureResource *srcPic, PictureResource *destPic) {
+ // WORKAROUND: Since _backgroundPage can point to a resource freed at the end of display methods,
+ // I'm now explicitly resetting it to null in screenReset(), so at this point it can be null
+ if (!srcPic)
+ return;
+
+ bool saveBack = _saveBack;
+ _saveBack = false;
+
+ if (rectListCount == -1) {
+ sDrawPic(srcPic, destPic, Common::Point());
+ } else {
+ for (int i = rectListCount - 1; i >= 0; --i) {
+ _clipPtr = &rectList[i];
+ sDrawPic(srcPic, destPic, Common::Point());
+ }
+ }
+
+ _saveBack = saveBack;
+}
+
+void Screen::setPalette(const byte *palette, int start, int count) {
+ Graphics::Screen::setPalette(palette, start, count);
+ _vm->_eventsManager->_gameData._hasPalette = false;
+}
+
+void Screen::setPalette128(const byte *palette, int start, int count) {
+ byte rgb[3];
+ getPalette(&rgb[0], 128, 1);
+ Graphics::Screen::setPalette(palette, start, count);
+ Graphics::Screen::setPalette(&rgb[0], 128, 1);
+}
+
+void Screen::resetPalette() {
+ for (int i = 0; i < 256; ++i)
+ setColor(i, 0, 0, 0);
+
+ _vm->_eventsManager->_intPtr._hasPalette = true;
+}
+
+void Screen::setColor(int idx, byte r, byte g, byte b) {
+ byte *vgaP = &_VGAColors[idx * 3];
+ vgaP[0] = r;
+ vgaP[1] = g;
+ vgaP[2] = b;
+
+ _vm->_eventsManager->_intPtr._palStartIndex = MIN(_vm->_eventsManager->_intPtr._palStartIndex, idx);
+ _vm->_eventsManager->_intPtr._palEndIndex = MAX(_vm->_eventsManager->_intPtr._palEndIndex, idx);
+}
+
+void Screen::setOneColor(int idx, byte r, byte g, byte b) {
+ byte palEntry[3];
+ palEntry[0] = r;
+ palEntry[1] = g;
+ palEntry[2] = b;
+ g_system->getPaletteManager()->setPalette(&palEntry[0], idx, 1);
+}
+
+void Screen::setColors(int start, int count, const byte *pal) {
+ for (int i = 0; i < count; ++i) {
+ if ((i + start) != 128) {
+ const byte *rgb = pal + i * 3;
+ setColor(i + start, rgb[0], rgb[1], rgb[2]);
+ }
+ }
+
+ _vm->_eventsManager->_intPtr._hasPalette = true;
+}
+
+void Screen::screenReset() {
+ resetPalette();
+
+ _backgroundPage = NULL;
+ _vPort->setupViewPort(NULL);
+ fillPic(_vPort, 0);
+
+ _vm->flipPageAndWait();
+}
+
+void Screen::fadeDownICF1(int steps) {
+ if (steps > 0) {
+ int stepAmount = _vm->_voy->_fadingAmount2 / steps;
+
+ for (int idx = 0; idx < steps; ++idx) {
+ _vm->_voy->_fadingAmount2 -= stepAmount;
+ _vm->_eventsManager->delay(1);
+ }
+ }
+
+ _vm->_voy->_fadingAmount2 = 0;
+}
+
+void Screen::fadeUpICF1(int steps) {
+ if (steps > 0) {
+ int stepAmount = (63 - _vm->_voy->_fadingAmount2) / steps;
+
+ for (int idx = 0; idx < steps; ++idx) {
+ _vm->_voy->_fadingAmount2 += stepAmount;
+ _vm->_eventsManager->delay(1);
+ }
+ }
+
+ _vm->_voy->_fadingAmount2 = 63;
+}
+
+void Screen::fadeDownICF(int steps) {
+ if (steps > 0) {
+ _vm->_eventsManager->hideCursor();
+ int stepAmount1 = _vm->_voy->_fadingAmount1 / steps;
+ int stepAmount2 = _vm->_voy->_fadingAmount2 / steps;
+
+ for (int idx = 0; idx < steps; ++idx) {
+ _vm->_voy->_fadingAmount1 -= stepAmount1;
+ _vm->_voy->_fadingAmount2 -= stepAmount2;
+ _vm->_eventsManager->delay(1);
+ }
+ }
+
+ _vm->_voy->_fadingAmount1 = 0;
+ _vm->_voy->_fadingAmount2 = 0;
+}
+
+void Screen::drawDot() {
+ for (int idx = 0; idx < 9; ++idx) {
+ uint offset = DOT_LINE_START[idx] + DOT_LINE_OFFSET[idx];
+ int xp = offset % SCREEN_WIDTH;
+ int yp = offset / SCREEN_WIDTH;
+
+ byte *pDest = (byte *)getPixels() + offset;
+ Common::fill(pDest, pDest + DOT_LINE_LENGTH[idx], 0x80);
+ addDirtyRect(Common::Rect(xp, yp, xp + DOT_LINE_LENGTH[idx], yp + 1));
+ }
+}
+
+void Screen::synchronize(Common::Serializer &s) {
+ s.syncBytes(&_VGAColors[0], PALETTE_SIZE);
+}
+
+} // End of namespace Voyeur