/* 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/graphics.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, int flags) { _penColor = penColor; _pos = pos; _flags = flags; } /*------------------------------------------------------------------------*/ GraphicsManager::GraphicsManager(): _defaultDrawInfo(1, Common::Point(), 0), _drawPtr(&_defaultDrawInfo) { _SVGAPage = 0; _SVGAMode = 0; _SVGAReset = 0; _screenOffset = 0; _planeSelect = 0; _sImageShift = 3; _palFlag = false; _MCGAMode = false; _saveBack = true; _drawTextPermFlag = false; _clipPtr = NULL; _viewPortListPtr = NULL; _backgroundPage = NULL; _vPort = NULL; _fontPtr = NULL; Common::fill(&_VGAColors[0], &_VGAColors[PALETTE_SIZE], 0); _fontChar = new PictureResource(0, 0xff, 0xff, 0, 0, Common::Rect(), 0, NULL, 0); } void GraphicsManager::sInitGraphics() { initGraphics(SCREEN_WIDTH, SCREEN_HEIGHT, false); _screenSurface.create(SCREEN_WIDTH, SCREEN_HEIGHT, Graphics::PixelFormat::createFormatCLUT8()); clearPalette(); } GraphicsManager::~GraphicsManager() { _screenSurface.free(); delete _fontChar; } void GraphicsManager::setupMCGASaveRect(ViewPortResource *viewPort) { _MCGAMode = true; if (viewPort->_activePage) { viewPort->_activePage->_flags |= 1; Common::Rect *clipRect = _clipPtr; _clipPtr = &viewPort->_clipRect; sDrawPic(viewPort->_activePage, viewPort->_currentPic, Common::Point()); _clipPtr = clipRect; } viewPort->_rectListCount[1] = -1; } void GraphicsManager::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 GraphicsManager::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 GraphicsManager::addRectNoSaveBack(ViewPortResource *viewPort, int idx, const Common::Rect &bounds) { // Stubbed/dummy method in the original. } void GraphicsManager::sDrawPic(DisplayResource *srcDisplay, DisplayResource *destDisplay, const Common::Point &initialOffset) { int var4C = 0; 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 var22 = 0; int var24 = 0; bool isClipped = false; int var26; byte pixel = 0; int runLength; byte *srcImgData, *destImgData; byte *srcP, *destP; byte byteVal, byteVal2; // Get the picture parameters, or deference viewport pointers to get their pictures PictureResource *srcPic = (PictureResource *)srcDisplay; PictureResource *destPic = (PictureResource *)destDisplay; if (srcDisplay->_flags & DISPFLAG_VIEWPORT) { // A viewport was passed, not a picture srcPic = ((ViewPortResource *)srcDisplay)->_currentPic; } if (destDisplay->_flags & DISPFLAG_VIEWPORT) { destViewPort = (ViewPortResource *)destDisplay; destPic = destViewPort->_currentPic; } 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 & 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()); } var24 = offset.y - newBounds.top; if (var24 < 0) { srcOffset -= var24 * width2; height1 += var24; offset.y = newBounds.top; if (height1 <= 0) return; isClipped = true; } int var20 = newBounds.bottom - (offset.y + height1); if (var20 < 0) { height1 += var20; if (height1 <= 0) return; } var22 = offset.x - newBounds.left; if (var22 < 0) { srcOffset -= var22; width2 += var22; offset.x = newBounds.left; if (width2 <= 0) return; isClipped = true; } var26 = newBounds.right - (offset.x + width2); if (var26 < 0) { width2 += var26; 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) != 0)) { 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) { srcImgData = 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 { srcImgData = srcPic->_imgData; } if (destFlags & DISPFLAG_1000) { destImgData = 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 { destImgData = destPic->_imgData; } _SVGAPage = _SVGAReset; 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 = (byte *)_screenSurface.getPixels() + srcOffset; for (int yp = 0; yp < height1; ++yp) { for (int xp = 0; xp < width2; ++width2, ++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 *)_screenSurface.getPixels() + screenOffset; for (int yp = 0; yp < height1; ++yp) { Common::copy(srcP, srcP + width2, destP); srcP += width2 + widthDiff; destP += width2 + widthDiff2; } } } } else { // loc_25D40 if (srcFlags & DISPFLAG_100) { // loc_25D4A error("TODO: sDrawPic variation"); } else { // loc_2606D destP = (byte *)_screenSurface.getPixels() + screenOffset; for (int yp = 0; yp < height1; ++yp) { Common::copy(srcP, srcP + width2, destP); destP += width2 + widthDiff2; srcP += width2 + widthDiff; } } } } else { // loc_2615E destP = destImgData + screenOffset; if (srcFlags & DISPFLAG_2) { // loc_2617e if (srcFlags & DISPFLAG_100) { // loc_26188 srcP = srcImgData; if (isClipped) { // loc_26199 var22 = (var22 < 0) ? -var22 : 0; var26 = var22 + width2; var24 = (var24 < 0) ? -var24 : 0; width2 = srcPic->_bounds.width(); height1 = var24 + 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 >= var24 && xp >= var22 && xp < var26) { if (pixel > 0) *destP = pixel; ++destP; } } if (yp >= var24) 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 & 0x100) { // Simple run-length encoded image srcP = srcImgData; if (isClipped) { // loc_26424 var22 = (var22 < 0) ? -var22 : 0; var26 = var22 + width2; var24 = (var24 < 0) ? -var24 : 0; width2 = srcPic->_bounds.width(); height1 = var24 + 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 >= var24 && xp >= var22 && xp < var26) { *destP++ = pixel; } } if (yp >= var24) destP += widthDiff2; } } else { // loc_26543 for (int yp = 0; yp < height1; ++yp) { int runLength = 0; for (int xp = 0; xp < width2; ++xp, --runLength) { if (runLength <= 0) { // Start of run length, so get pixel and repeat length pixel = *srcP++; if (pixel & 0x80) { pixel &= 0x7f; runLength = *srcP++; if (runLength == 0) runLength = 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 *)_screenSurface.getPixels() + screenOffset; for (int yp = 0; yp < height1; ++yp) { Common::fill(destP, destP + width2, onOff); destP += width2 + widthDiff2; } } 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 int pick = srcPic->_pick; int onOff = srcPic->_onOff; if (!(srcFlags & PICFLAG_PIC_OFFSET)) { srcP = srcImgData += srcOffset; int pixel = 0; if (destFlags & PICFLAG_PIC_OFFSET) { destP = destImgData + screenOffset; if (srcFlags & PICFLAG_2) { if (srcFlags & PICFLAG_100) { if (isClipped) { // loc_266E3 destP = (byte *)_screenSurface.getPixels() + screenOffset; var22 = (var22 < 0) ? -var22 : 0; var26 = var22 + width2; var24 = (var24 < 0) ? -var24 : 0; pick = 0x7F; width2 = srcPic->_bounds.width(); height1 = var24 + height1; for (int yp = 0; yp < height1; ++yp) { int 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 >= var24 && xp >= var22 && xp < var26) { if (pixel) { *destP = (pixel & pick) ^ onOff; } ++destP; } } if (yp >= var24) destP += widthDiff2; } } else { // loc_26815 destP = (byte *)_screenSurface.getPixels() + screenOffset; for (int yp = 0; yp < height1; ++yp) { for (int xp = 0; xp < width2; ++xp, ++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; } } } else { // Direct screen write destP = (byte *)_screenSurface.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; } } } else if (srcFlags & PICFLAG_100) { srcP = srcImgData; if (isClipped) { // loc_269FD var22 = (var22 < 0) ? -var22 : 0; var26 = var22 + width2; var24 = (var24 < 0) ? -var24 : 0; width2 = srcPic->_bounds.width(); height1 = var24 + 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 >= var24 && xp >= var22 && xp < var26) { *destP++ = (pixel & 0x80) ^ onOff; } } } } else { // loc_26BD5 destP = (byte *)_screenSurface.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; } } } else { // loc_26C9A destP = (byte *)_screenSurface.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; } } } else { // loc_26D2F destP = destImgData + screenOffset; if (srcFlags & PICFLAG_2) { // loc_26D4F if (srcFlags & PICFLAG_100) { srcP = srcImgData; if (isClipped) { // loc_26D6A var22 = (var22 < 0) ? -var22 : 0; var26 = var22 + width2; var24 = (var24 < 0) ? -var24 : 0; width2 = srcPic->_bounds.width(); height1 = var24 + 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 >= var24 && xp >= var22 && xp < var26) { if (pixel) *destP = (pixel & pick) ^ onOff; ++destP; } } if (yp >= var24) 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 var22 = (var22 < 0) ? -var22 : 0; var26 = var22 + width2; var24 = (var24 < 0) ? -var24 : 0; width2 = srcPic->_bounds.width(); height1 = var24 + 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 >= var24 && xp >= var22 && xp < var26) { *destP++ = (pixel & pick) ^ onOff; } } if (yp >= var24) 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); delete[] cursorData; } } void GraphicsManager::drawANumber(DisplayResource *display, int num, const Common::Point &pt) { PictureResource *pic = _vm->_bVoy->boltEntry(num + 261)._picResource; sDrawPic(pic, display, pt); } void GraphicsManager::fillPic(DisplayResource *display, byte onOff) { PictureResource *pic; if (display->_flags & DISPFLAG_VIEWPORT) { pic = ((ViewPortResource *)display)->_currentPic; } else { pic = (PictureResource *)display; } PictureResource picResource; picResource._flags = 0; 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 GraphicsManager::sDisplayPic(PictureResource *pic) { _vm->_eventsManager._intPtr._flipWait = true; } void GraphicsManager::flipPage() { Common::Array &viewPorts = _viewPortListPtr->_entries; bool flipFlag = false; for (uint idx = 0; idx < viewPorts.size(); ++idx) { if (viewPorts[idx]->_flags & DISPFLAG_20) { if ((viewPorts[idx]->_flags & (DISPFLAG_8 || DISPFLAG_1)) == (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 GraphicsManager::restoreBack(Common::Array &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 GraphicsManager::clearPalette() { byte palette[768]; Common::fill(&palette[0], &palette[768], 0); g_system->getPaletteManager()->setPalette(&palette[0], 0, 256); } void GraphicsManager::setPalette(const byte *palette, int start, int count) { g_system->getPaletteManager()->setPalette(palette, start, count); _vm->_eventsManager._gameData._hasPalette = false; } void GraphicsManager::setPalette128(const byte *palette, int start, int count) { byte rgb[3]; g_system->getPaletteManager()->grabPalette(&rgb[0], 128, 1); g_system->getPaletteManager()->setPalette(palette, start, count); g_system->getPaletteManager()->setPalette(&rgb[0], 128, 1); } void GraphicsManager::resetPalette() { for (int i = 0; i < 256; ++i) setColor(i, 0, 0, 0); _vm->_eventsManager._intPtr._hasPalette = true; } void GraphicsManager::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 GraphicsManager::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 GraphicsManager::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 GraphicsManager::screenReset() { resetPalette(); _backgroundPage = NULL; (*_vPort)->setupViewPort(NULL); fillPic(*_vPort, 0); _vm->flipPageAndWait(); } void GraphicsManager::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 GraphicsManager::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 GraphicsManager::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 GraphicsManager::drawDot() { for (int y = 0; y < 9; ++y) { byte *pDest = (byte *)_screenSurface.getPixels() + DOT_LINE_START[y] + DOT_LINE_OFFSET[y]; Common::fill(pDest, pDest + DOT_LINE_LENGTH[y], 0x80); } } void GraphicsManager::synchronize(Common::Serializer &s) { s.syncBytes(&_VGAColors[0], PALETTE_SIZE); } } // End of namespace Voyeur