scummvm/engines/voyeur/screen.cpp
Colin Snover 432fd522d2 ENGINES: Remove default1x scaler flag
This flag is removed for a few reasons:

* Engines universally set this flag to true for widths > 320,
  which made it redundant everywhere;
* This flag functioned primarily as a "force 1x scaler" flag,
  since its behaviour was almost completely undocumented and users
  would need to figure out that they'd need an explicit non-default
  scaler set to get a scaler to operate at widths > 320;
* (Most importantly) engines should not be in the business of
  deciding how the backend may choose to render its virtual screen.
  The choice of rendering behaviour belongs to the user, and the
  backend, in that order.

A nearby future commit restores the default1x scaler behaviour in
the SDL backend code for the moment, but in the future it is my
hope that there will be a better configuration UI to allow users
to specify how they want scaling to work for high resolutions.
2017-10-07 12:30:29 -05:00

1078 lines
28 KiB
C++

/* 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);
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) {
flipFlag = false;
if ((viewPorts[idx]->_flags & DISPFLAG_8) && (viewPorts[idx]->_flags & 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