diff options
Diffstat (limited to 'kyra/screen.cpp')
-rw-r--r-- | kyra/screen.cpp | 2084 |
1 files changed, 0 insertions, 2084 deletions
diff --git a/kyra/screen.cpp b/kyra/screen.cpp deleted file mode 100644 index 4bf2d8da75..0000000000 --- a/kyra/screen.cpp +++ /dev/null @@ -1,2084 +0,0 @@ -/* ScummVM - Scumm Interpreter - * Copyright (C) 2004-2006 The ScummVM project - * - * 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. - * - * $URL$ - * $Id$ - * - */ - -#include "common/stdafx.h" -#include "common/system.h" -#include "kyra/screen.h" -#include "kyra/kyra.h" - -namespace Kyra { - -#define BITBLIT_RECTS 10 - -Screen::Screen(KyraEngine *vm, OSystem *system) - : _system(system), _vm(vm) { - _curPage = 0; - for (int pageNum = 0; pageNum < SCREEN_PAGE_NUM; pageNum += 2) { - uint8 *pagePtr = (uint8 *)malloc(SCREEN_PAGE_SIZE); - if (pagePtr) { - memset(pagePtr, 0, SCREEN_PAGE_SIZE); - _pagePtrs[pageNum] = _pagePtrs[pageNum + 1] = pagePtr; - } - } - memset(_shapePages, 0, sizeof(_shapePages)); - _currentPalette = (uint8 *)malloc(768); - if (_currentPalette) { - memset(_currentPalette, 0, 768); - } - _screenPalette = (uint8 *)malloc(768); - if (_screenPalette) { - memset(_screenPalette, 0, 768); - } - for (int i = 0; i < 3; ++i) { - _palettes[i] = (uint8 *)malloc(768); - if (_palettes[i]) { - memset(_palettes[i], 0, 768); - } - } - _curDim = &_screenDimTable[0]; - _charWidth = 0; - _charOffset = 0; - memset(_fonts, 0, sizeof(_fonts)); - for (int i = 0; i < ARRAYSIZE(_textColorsMap); ++i) { - _textColorsMap[i] = i; - } - _decodeShapeBuffer = NULL; - _decodeShapeBufferSize = 0; - _animBlockPtr = NULL; - _animBlockSize = 0; - _mouseLockCount = 0; - - _bitBlitRects = new Rect[BITBLIT_RECTS]; - assert(_bitBlitRects); - memset(_bitBlitRects, 0, sizeof(Rect)*BITBLIT_RECTS); - _bitBlitNum = 0; - memset(_saveLoadPage, 0, sizeof(_saveLoadPage)); - - _unkPtr1 = (uint8*)malloc(getRectSize(1, 144)); - memset(_unkPtr1, 0, getRectSize(1, 144)); - _unkPtr2 = (uint8*)malloc(getRectSize(1, 144)); - memset(_unkPtr2, 0, getRectSize(1, 144)); -} - -Screen::~Screen() { - for (int pageNum = 0; pageNum < SCREEN_PAGE_NUM; pageNum += 2) { - free(_pagePtrs[pageNum]); - _pagePtrs[pageNum] = _pagePtrs[pageNum + 1] = 0; - } - for (int f = 0; f < ARRAYSIZE(_fonts); ++f) { - delete[] _fonts[f].fontData; - _fonts[f].fontData = NULL; - } - free(_currentPalette); - free(_screenPalette); - free(_decodeShapeBuffer); - free(_animBlockPtr); - for (int i = 0; i < 3; ++i) { - free(_palettes[i]); - } - delete [] _bitBlitRects; - for (int i = 0; i < ARRAYSIZE(_saveLoadPage); ++i) { - delete [] _saveLoadPage[i]; - _saveLoadPage[i] = 0; - } - - free(_unkPtr1); - free(_unkPtr2); -} - -void Screen::updateScreen() { - debug(9, "Screen::updateScreen()"); - _system->copyRectToScreen(getPagePtr(0), SCREEN_W, 0, 0, SCREEN_W, SCREEN_H); - //for debug reasons (needs 640x200 screen) - //_system->copyRectToScreen(getPagePtr(2), SCREEN_W, 320, 0, SCREEN_W, SCREEN_H); - _system->updateScreen(); -} - -uint8 *Screen::getPagePtr(int pageNum) { - debug(9, "Screen::getPagePtr(%d)", pageNum); - assert(pageNum < SCREEN_PAGE_NUM); - return _pagePtrs[pageNum]; -} - -void Screen::clearPage(int pageNum) { - debug(9, "Screen::clearPage(%d)", pageNum); - assert(pageNum < SCREEN_PAGE_NUM); - memset(getPagePtr(pageNum), 0, SCREEN_PAGE_SIZE); -} - -int Screen::setCurPage(int pageNum) { - debug(9, "Screen::setCurPage(%d)", pageNum); - assert(pageNum < SCREEN_PAGE_NUM); - int previousPage = _curPage; - _curPage = pageNum; - return previousPage; -} - -void Screen::clearCurPage() { - debug(9, "Screen::clearCurPage()"); - memset(getPagePtr(_curPage), 0, SCREEN_PAGE_SIZE); -} - -uint8 Screen::getPagePixel(int pageNum, int x, int y) { - debug(9, "Screen::getPagePixel(%d, %d, %d)", pageNum, x, y); - assert(pageNum < SCREEN_PAGE_NUM); - assert(x >= 0 && x < SCREEN_W && y >= 0 && y < SCREEN_H); - return _pagePtrs[pageNum][y * SCREEN_W + x]; -} - -void Screen::setPagePixel(int pageNum, int x, int y, uint8 color) { - debug(9, "Screen::setPagePixel(%d, %d, %d, %d)", pageNum, x, y, color); - assert(pageNum < SCREEN_PAGE_NUM); - assert(x >= 0 && x < SCREEN_W && y >= 0 && y < SCREEN_H); - _pagePtrs[pageNum][y * SCREEN_W + x] = color; -} - -void Screen::fadeFromBlack() { - debug(9, "Screen::fadeFromBlack()"); - fadePalette(_currentPalette, 0x54); -} - -void Screen::fadeToBlack() { - debug(9, "Screen::fadeToBlack()"); - uint8 blackPal[768]; - memset(blackPal, 0, 768); - fadePalette(blackPal, 0x54); -} - -void Screen::fadeSpecialPalette(int palIndex, int startIndex, int size, int fadeTime) { - debug(9, "fadeSpecialPalette(%d, %d, %d, %d)", palIndex, startIndex, size, fadeTime); - assert(_vm->palTable1()[palIndex]); - assert(_currentPalette); - uint8 tempPal[768]; - memcpy(tempPal, _currentPalette, 768); - memcpy(&tempPal[startIndex*3], _vm->palTable1()[palIndex], size*3); - fadePalette(tempPal, fadeTime*18); - memcpy(&_currentPalette[startIndex*3], &tempPal[startIndex*3], size*3); - setScreenPalette(_currentPalette); - _system->updateScreen(); -} - -void Screen::fadePalette(const uint8 *palData, int delay) { - debug(9, "Screen::fadePalette(0x%X, %d)", palData, delay); - uint8 fadePal[768]; - memcpy(fadePal, _screenPalette, 768); - uint8 diff, maxDiff = 0; - for (int i = 0; i < 768; ++i) { - diff = ABS(palData[i] - fadePal[i]); - if (diff > maxDiff) { - maxDiff = diff; - } - } - int16 delayInc = delay << 8; - if (maxDiff != 0) { - delayInc /= maxDiff; - } - delay = delayInc; - for (diff = 1; diff <= maxDiff; ++diff) { - if (delayInc >= 512) { - break; - } - delayInc += delay; - } - int delayAcc = 0; - while (1) { - delayAcc += delayInc; - bool needRefresh = false; - for (int i = 0; i < 768; ++i) { - int c1 = palData[i]; - int c2 = fadePal[i]; - if (c1 != c2) { - needRefresh = true; - if (c1 > c2) { - c2 += diff; - if (c1 < c2) { - c2 = c1; - } - } - if (c1 < c2) { - c2 -= diff; - if (c1 > c2) { - c2 = c1; - } - } - fadePal[i] = (uint8)c2; - } - } - if (!needRefresh) { - break; - } - setScreenPalette(fadePal); - _system->updateScreen(); - //_system->delayMillis((delayAcc >> 8) * 1000 / 60); - _vm->delay((delayAcc >> 8) * 1000 / 60); - delayAcc &= 0xFF; - } -} - -void Screen::setScreenPalette(const uint8 *palData) { - debug(9, "Screen::setScreenPalette(0x%X)", palData); - memcpy(_screenPalette, palData, 768); - uint8 screenPal[256 * 4]; - for (int i = 0; i < 256; ++i) { - screenPal[4 * i + 0] = (palData[0] << 2) | (palData[0] & 3); - screenPal[4 * i + 1] = (palData[1] << 2) | (palData[1] & 3); - screenPal[4 * i + 2] = (palData[2] << 2) | (palData[2] & 3); - screenPal[4 * i + 3] = 0; - palData += 3; - } - _system->setPalette(screenPal, 0, 256); -} - -void Screen::copyToPage0(int y, int h, uint8 page, uint8 *seqBuf) { - debug(9, "Screen::copyToPage0(%d, %d, %d, 0x%X)", y, h, page, seqBuf); - assert(y + h <= SCREEN_H); - const uint8 *src = getPagePtr(page) + y * SCREEN_W; - uint8 *dstPage = getPagePtr(0) + y * SCREEN_W; - for (int i = 0; i < h; ++i) { - for (int x = 0; x < SCREEN_W; ++x) { - if (seqBuf[x] != src[x]) { - seqBuf[x] = src[x]; - dstPage[x] = src[x]; - } - } - src += SCREEN_W; - seqBuf += SCREEN_W; - dstPage += SCREEN_W; - } -} - -void Screen::copyRegion(int x1, int y1, int x2, int y2, int w, int h, int srcPage, int dstPage, int flags) { - debug(9, "Screen::copyRegion(%d, %d, %d, %d, %d, %d, %d, %d, %d)", x1, y1, x2, y2, w, h, srcPage, dstPage, flags); - - if (flags & CR_CLIPPED) { - if (x2 < 0) { - if (x2 <= -w) - return; - w += x2; - x1 -= x2; - x2 = 0; - } else if (x2 + w >= SCREEN_W) { - if (x2 > SCREEN_W) - return; - w = SCREEN_W - x2; - } - - if (y2 < 0) { - if (y2 <= -h ) - return; - h += y2; - y1 -= y2; - y2 = 0; - } else if (y2 + h >= SCREEN_H) { - if (y2 > SCREEN_H) - return; - h = SCREEN_H - y2; - } - } - - assert(x1 + w <= SCREEN_W && y1 + h <= SCREEN_H); - const uint8 *src = getPagePtr(srcPage) + y1 * SCREEN_W + x1; - assert(x2 + w <= SCREEN_W && y2 + h <= SCREEN_H); - uint8 *dst = getPagePtr(dstPage) + y2 * SCREEN_W + x2; - - if (flags & CR_X_FLIPPED) { - while (h--) { - for (int i = 0; i < w; ++i) { - if (src[i]) { - dst[w-i] = src[i]; - } - } - src += SCREEN_W; - dst += SCREEN_W; - } - } else { - while (h--) { - for (int i = 0; i < w; ++i) { - if (src[i]) { - dst[i] = src[i]; - } - } - src += SCREEN_W; - dst += SCREEN_W; - } - } -} - -void Screen::copyRegionToBuffer(int pageNum, int x, int y, int w, int h, uint8 *dest) { - debug(9, "Screen::copyRegionToBuffer(%d, %d, %d, %d, %d)", pageNum, x, y, w, h); - assert(x >= 0 && x < Screen::SCREEN_W && y >= 0 && y < Screen::SCREEN_H && dest); - uint8 *pagePtr = getPagePtr(pageNum); - for (int i = y; i < y + h; i++) { - memcpy(dest + (i - y) * w, pagePtr + i * SCREEN_W + x, w); - } -} - -void Screen::copyBlockToPage(int pageNum, int x, int y, int w, int h, const uint8 *src) { - debug(9, "Screen::copyBlockToPage(%d, %d, %d, %d, %d, 0x%X)", pageNum, x, y, w, h, src); - assert(x >= 0 && x < Screen::SCREEN_W && y >= 0 && y < Screen::SCREEN_H); - uint8 *dst = getPagePtr(pageNum) + y * SCREEN_W + x; - while (h--) { - memcpy(dst, src, w); - dst += SCREEN_W; - src += w; - } -} - -void Screen::copyFromCurPageBlock(int x, int y, int w, int h, const uint8 *src) { - debug(9, "Screen::copyFromCurPageBlock(%d, %d, %d, %d, 0x%X)", x, y, w, h, src); - if (x < 0) { - x = 0; - } else if (x >= 40) { - return; - } - if (x + w > 40) { - w = 40 - x; - } - if (y < 0) { - y = 0; - } else if (y >= 200) { - return; - } - if (y + h > 200) { - h = 200 - y; - } - uint8 *dst = getPagePtr(_curPage) + y * SCREEN_W + x * 8; - while (h--) { - memcpy(dst, src, w*8); - dst += SCREEN_W; - src += w*8; - } -} - -void Screen::copyCurPageBlock(int x, int y, int w, int h, uint8 *dst) { - debug(9, "Screen::copyCurPageBlock(%d, %d, %d, %d, 0x%X)", x, y, w, h, dst); - assert(dst); - if (x < 0) { - x = 0; - } else if (x >= 40) { - return; - } - if (x + w > 40) { - w = 40 - x; - } - if (y < 0) { - y = 0; - } else if (y >= 200) { - return; - } - if (y + h > 200) { - h = 200 - y; - } - const uint8 *src = getPagePtr(_curPage) + y * SCREEN_W + x * 8; - while (h--) { - memcpy(dst, src, w*8); - dst += w*8; - src += SCREEN_W; - } -} - -void Screen::shuffleScreen(int sx, int sy, int w, int h, int srcPage, int dstPage, int ticks, bool transparent) { - debug(9, "Screen::shuffleScreen(%d, %d, %d, %d, %d, %d, %d, %d)", sx, sy, w, h, srcPage, dstPage, ticks, transparent); - assert(sx >= 0 && w <= SCREEN_W); - int x; - uint16 x_offs[SCREEN_W]; - for (x = 0; x < SCREEN_W; ++x) { - x_offs[x] = x; - } - for (x = 0; x < w; ++x) { - int i = _vm->_rnd.getRandomNumber(w - 1); - SWAP(x_offs[x], x_offs[i]); - } - - assert(sy >= 0 && h <= SCREEN_H); - int y; - uint8 y_offs[SCREEN_H]; - for (y = 0; y < SCREEN_H; ++y) { - y_offs[y] = y; - } - for (y = 0; y < h; ++y) { - int i = _vm->_rnd.getRandomNumber(h - 1); - SWAP(y_offs[y], y_offs[i]); - } - - int32 start, now; - int wait; - for (y = 0; y < h; ++y) { - start = (int32)_system->getMillis(); - int y_cur = y; - for (x = 0; x < w; ++x) { - int i = sx + x_offs[x]; - int j = sy + y_offs[y_cur]; - ++y_cur; - if (y_cur >= h) { - y_cur = 0; - } - uint8 color = getPagePixel(srcPage, i, j); - if (!transparent || color != 0) { - setPagePixel(dstPage, i, j, color); - } - } - updateScreen(); - now = (int32)_system->getMillis(); - wait = ticks * _vm->tickLength() - (now - start); - if (wait > 0) { - _vm->delay(wait); - } - } -} - -void Screen::fillRect(int x1, int y1, int x2, int y2, uint8 color, int pageNum) { - debug(9, "Screen::fillRect(%d, %d, %d, %d, %d, %d)", x1, y1, x2, y2, color, pageNum); - assert(x2 < SCREEN_W && y2 < SCREEN_H); - if (pageNum == -1) { - pageNum = _curPage; - } - uint8 *dst = getPagePtr(pageNum) + y1 * SCREEN_W + x1; - for (; y1 <= y2; ++y1) { - memset(dst, color, x2 - x1 + 1); - dst += SCREEN_W; - } -} - -void Screen::drawBox(int x1, int y1, int x2, int y2, int color) { - debug(9, "Screen::drawBox(%i, %i, %i, %i, %i)", x1, y1, x2, y2, color); - - drawClippedLine(x1, y1, x2, y1, color); - drawClippedLine(x1, y1, x1, y2, color); - drawClippedLine(x2, y1, x2, y2, color); - drawClippedLine(x1, y2, x2, y2, color); -} - -void Screen::drawShadedBox(int x1, int y1, int x2, int y2, int color1, int color2) { - debug(9, "Screen::drawShadedBox(%i, %i, %i, %i, %i, %i)", x1, y1, x2, y2, color1, color2); - assert(x1 > 0 && y1 > 0); - hideMouse(); - - fillRect(x1, y1, x2, y1 + 1, color1); - fillRect(x2 - 1, y1, x2, y2, color1); - - drawClippedLine(x1, y1, x1, y2, color2); - drawClippedLine(x1 + 1, y1 + 1, x1 + 1, y2 - 1, color2); - drawClippedLine(x1, y2, x2, y2, color2); - drawClippedLine(x1, y2 - 1, x2 - 1, y2 - 1, color2); - - showMouse(); -} - -void Screen::drawClippedLine(int x1, int y1, int x2, int y2, int color) { - debug(9, "Screen::drawClippedLine(%i, %i, %i, %i, %i)", x1, y1, x2, y2, color); - - if (x1 < 0) - x1 = 0; - else if (x1 > 319) - x1 = 319; - - if (x2 < 0) - x2 = 0; - else if (x2 > 319) - x2 = 319; - - if (y1 < 0) - y1 = 0; - else if (y1 > 199) - y1 = 199; - - if (y2 < 0) - y2 = 0; - else if (y2 > 199) - y2 = 199; - - if (x1 == x2) - if (y1 > y2) - drawLine(true, x1, y2, y1 - y2 + 1, color); - else - drawLine(true, x1, y1, y2 - y1 + 1, color); - else - if (x1 > x2) - drawLine(false, x2, y1, x1 - x2 + 1, color); - else - drawLine(false, x1, y1, x2 - x1 + 1, color); -} - -void Screen::drawLine(bool horizontal, int x, int y, int length, int color) { - debug(9, "Screen::drawLine(%i, %i, %i, %i, %i)", horizontal, x, y, length, color); - - uint8 *ptr = getPagePtr(_curPage) + y * SCREEN_W + x; - - if (horizontal) { - assert((y + length) <= SCREEN_H); - int currLine = 0; - while (currLine < length) { - *ptr = color; - ptr += SCREEN_W; - currLine++; - } - } else { - assert((x + length) <= SCREEN_W); - memset(ptr, color, length); - } -} - -void Screen::setAnimBlockPtr(int size) { - debug(9, "Screen::setAnimBlockPtr(%d)", size); - free(_animBlockPtr); - _animBlockPtr = (uint8 *)malloc(size); - assert(_animBlockPtr); - memset(_animBlockPtr, 0, size); - _animBlockSize = size; -} - -void Screen::setTextColorMap(const uint8 *cmap) { - debug(9, "Screen::setTextColorMap(0x%X)", cmap); - setTextColor(cmap, 0, 11); -} - -void Screen::setTextColor(const uint8 *cmap, int a, int b) { - debug(9, "Screen::setTextColor(0x%X, %d, %d)", cmap, a, b); - for (int i = a; i <= b; ++i) { - _textColorsMap[i] = *cmap++; - } -} - -void Screen::loadFont(FontId fontId, uint8 *fontData) { - debug(9, "Screen::loadFont(%d, 0x%X)", fontId, fontData); - Font *fnt = &_fonts[fontId]; - assert(fontData && !fnt->fontData); - fnt->fontData = fontData; - uint16 fontSig = READ_LE_UINT16(fontData + 2); - if (fontSig != 0x500) { - error("Invalid font data"); - } - fnt->charWidthTable = fontData + READ_LE_UINT16(fontData + 8); - fnt->charBoxHeight = READ_LE_UINT16(fontData + 4); - fnt->charBitmapOffset = READ_LE_UINT16(fontData + 6); - fnt->charWidthTableOffset = READ_LE_UINT16(fontData + 8); - fnt->charHeightTableOffset = READ_LE_UINT16(fontData + 0xC); -} - -Screen::FontId Screen::setFont(FontId fontId) { - debug(9, "Screen::setFont(%d)", fontId); - FontId prev = _currentFont; - _currentFont = fontId; - return prev; -} - -int Screen::getCharWidth(uint8 c) const { - debug(9, "Screen::getCharWidth('%c')", c); - return (int)_fonts[_currentFont].charWidthTable[c] + _charWidth; -} - -int Screen::getTextWidth(const char *str) const { - debug(9, "Screen::getTextWidth('%s')", str); - int curLineLen = 0; - int maxLineLen = 0; - while (1) { - char c = *str++; - if (c == 0) { - break; - } else if (c == '\r') { - if (curLineLen > maxLineLen) { - maxLineLen = curLineLen; - } else { - curLineLen = 0; - } - } else { - curLineLen += getCharWidth(c); - } - } - return MAX(curLineLen, maxLineLen); -} - -void Screen::printText(const char *str, int x, int y, uint8 color1, uint8 color2) { - debug(9, "Screen::printText('%s', %d, %d, 0x%X, 0x%X)", str, x, y, color1, color2); - uint8 cmap[2]; - cmap[0] = color2; - cmap[1] = color1; - setTextColor(cmap, 0, 1); - - Font *fnt = &_fonts[_currentFont]; - uint8 charHeight = *(fnt->fontData + fnt->charBoxHeight + 4); - - if (x < 0) { - x = 0; - } else if (x >= SCREEN_W) { - return; - } - int x_start = x; - if (y < 0) { - y = 0; - } else if (y >= SCREEN_H) { - return; - } - - while (1) { - char c = *str++; - if (c == 0) { - break; - } else if (c == '\r') { - x = x_start; - y += charHeight + _charOffset; - } else { - int charWidth = getCharWidth(c); - if (x + charWidth > SCREEN_W) { - x = x_start; - y += charHeight + _charOffset; - if (y >= SCREEN_H) { - break; - } - } - drawChar(c, x, y); - x += charWidth; - } - } -} - -void Screen::drawChar(uint8 c, int x, int y) { - debug(9, "Screen::drawChar('%c', %d, %d)", c, x, y); - Font *fnt = &_fonts[_currentFont]; - uint8 *dst = getPagePtr(_curPage) + y * SCREEN_W + x; - uint16 bitmapOffset = READ_LE_UINT16(fnt->fontData + fnt->charBitmapOffset + c * 2); - if (bitmapOffset == 0) { - return; - } - uint8 charWidth = *(fnt->fontData + fnt->charWidthTableOffset + c); - if (charWidth + x > SCREEN_W) { - return; - } - uint8 charH0 = *(fnt->fontData + fnt->charBoxHeight + 4); - if (charH0 + y > SCREEN_H) { - return; - } - uint8 charH1 = *(fnt->fontData + fnt->charHeightTableOffset + c * 2); - uint8 charH2 = *(fnt->fontData + fnt->charHeightTableOffset + c * 2 + 1); - charH0 -= charH1 + charH2; - - const uint8 *src = fnt->fontData + bitmapOffset; - const int pitch = SCREEN_W - charWidth; - - while (charH1--) { - uint8 col = _textColorsMap[0]; - for (int i = 0; i < charWidth; ++i) { - if (col != 0) { - *dst = col; - } - ++dst; - } - dst += pitch; - } - - while (charH2--) { - uint8 b = 0; - for (int i = 0; i < charWidth; ++i) { - uint8 col; - if (i & 1) { - col = _textColorsMap[b >> 4]; - } else { - b = *src++; - col = _textColorsMap[b & 0xF]; - } - if (col != 0) { - *dst = col; - } - ++dst; - } - dst += pitch; - } - - while (charH0--) { - uint8 col = _textColorsMap[0]; - for (int i = 0; i < charWidth; ++i) { - if (col != 0) { - *dst = col; - } - ++dst; - } - dst += pitch; - } -} - -void Screen::setScreenDim(int dim) { - debug(9, "setScreenDim(%d)", dim); - assert(dim < _screenDimTableCount); - _curDim = &_screenDimTable[dim]; - // XXX -} - -void Screen::drawShape(uint8 pageNum, const uint8 *shapeData, int x, int y, int sd, int flags, ...) { - debug(9, "Screen::drawShape(%d, 0x%X, %d, %d, %d, 0x%.04X, ...)", pageNum, shapeData, x, y, sd, flags); - if (!shapeData) - return; - va_list args; - va_start(args, flags); - - static int drawShapeVar1 = 0; - static int drawShapeVar2[] = { - 1, 3, 2, 5, 4, 3, 2, 1 - }; - static int drawShapeVar3 = 1; - static int drawShapeVar4 = 0; - static int drawShapeVar5 = 0; - - uint8 *table = 0; - int tableLoopCount = 0; - int drawLayer = 0; - uint8 *table2 = 0; - uint8 *table3 = 0; - uint8 *table4 = 0; - - if (flags & 0x8000) { - table2 = va_arg(args, uint8*); - } - if (flags & 0x100) { - table = va_arg(args, uint8*); - tableLoopCount = va_arg(args, int); - if (!tableLoopCount) - flags &= 0xFFFFFEFF; - } - if (flags & 0x1000) { - table3 = va_arg(args, uint8*); - table4 = va_arg(args, uint8*); - } - if (flags & 0x200) { - drawShapeVar1 += 1; - drawShapeVar1 &= 7; - drawShapeVar3 = drawShapeVar2[drawShapeVar1]; - drawShapeVar4 = 0; - drawShapeVar5 = 256; - } - if (flags & 0x4000) { - drawShapeVar5 = va_arg(args, int); - } - if (flags & 0x800) { - drawLayer = va_arg(args, int); - } - int scale_w, scale_h; - if (flags & DSF_SCALE) { - scale_w = va_arg(args, int); - scale_h = va_arg(args, int); - } else { - scale_w = 0x100; - scale_h = 0x100; - } - - int ppc = (flags >> 8) & 0x3F; - - const uint8 *src = shapeData; - if (_vm->features() & GF_TALKIE) { - src += 2; - } - uint16 shapeFlags = READ_LE_UINT16(src); src += 2; - - int shapeHeight = *src++; - int scaledShapeHeight = (shapeHeight * scale_h) >> 8; - if (scaledShapeHeight == 0) { - va_end(args); - return; - } - - int shapeWidth = READ_LE_UINT16(src); src += 2; - int scaledShapeWidth = (shapeWidth * scale_w) >> 8; - if (scaledShapeWidth == 0) { - va_end(args); - return; - } - - if (flags & DSF_CENTER) { - x -= scaledShapeWidth >> 1; - y -= scaledShapeHeight >> 1; - } - - src += 3; - - uint16 frameSize = READ_LE_UINT16(src); src += 2; - if ((shapeFlags & 1) || (flags & 0x400)) { - src += 0x10; - } - if (!(shapeFlags & 2)) { - decodeFrame4(src, _animBlockPtr, frameSize); - src = _animBlockPtr; - } - - int shapeSize = shapeWidth * shapeHeight; - if (_decodeShapeBufferSize < shapeSize) { - free(_decodeShapeBuffer); - _decodeShapeBuffer = (uint8 *)malloc(shapeSize); - _decodeShapeBufferSize = shapeSize; - } - if (!_decodeShapeBuffer) { - _decodeShapeBufferSize = 0; - va_end(args); - return; - } - memset(_decodeShapeBuffer, 0, _decodeShapeBufferSize); - uint8 *decodedShapeFrame = _decodeShapeBuffer; - - // only used if shapeFlag & 1 is NOT zero - const uint8 *colorTable = shapeData + 10; - if (_vm->features() & GF_TALKIE) { - colorTable += 2; - } - - for (int j = 0; j < shapeHeight; ++j) { - uint8 *dsbNextLine = decodedShapeFrame + shapeWidth; - int count = shapeWidth; - while (count > 0) { - uint8 code = *src++; - if (code != 0) { - // this is guessed - if (shapeFlags & 1) { - if (code < 16) { - *decodedShapeFrame++ = colorTable[code]; - } - } else { - *decodedShapeFrame++ = code; - } - --count; - } else { - code = *src++; - decodedShapeFrame += code; - count -= code; - } - } - decodedShapeFrame = dsbNextLine; - } - - uint16 sx1 = _screenDimTable[sd].sx * 8; - uint16 sy1 = _screenDimTable[sd].sy; - uint16 sx2 = sx1 + _screenDimTable[sd].w * 8; - uint16 sy2 = sy1 + _screenDimTable[sd].h; - if (flags & DSF_WND_COORDS) { - x += sx1; - y += sy1; - } - - int x1, x2; - if (x >= 0) { - x1 = 0; - if (x + scaledShapeWidth < sx2) { - x2 = scaledShapeWidth; - } else { - x2 = sx2 - x; - } - } else { - x2 = scaledShapeWidth; - x1 = -x; - x = 0; - if (x2 > sx2) { - x2 = sx2; - } - } - - int y1, y2; - if (y >= 0) { - y1 = 0; - if (y + scaledShapeHeight < sy2) { - y2 = scaledShapeHeight; - } else { - y2 = sy2 - y; - } - } else { - y2 = scaledShapeHeight; - y1 = -y; - y = 0; - if (y2 > sy2) { - y2 = sy2; - } - } - - uint8 *dst = getPagePtr(pageNum) + y * SCREEN_W + x; - uint8 *dstStart = getPagePtr(pageNum); - - int scaleYTable[SCREEN_H]; - assert(y1 >= 0 && y2 < SCREEN_H); - for (y = y1; y < y2; ++y) { - scaleYTable[y] = (y << 8) / scale_h; - } - int scaleXTable[SCREEN_W]; - assert(x1 >= 0 && x2 < SCREEN_W); - for (x = x1; x < x2; ++x) { - scaleXTable[x] = (x << 8) / scale_w; - } - - const uint8 *shapeBuffer = _decodeShapeBuffer; - if (flags & DSF_Y_FLIPPED) { - shapeBuffer += shapeWidth * (shapeHeight - 1); - } - if (flags & DSF_X_FLIPPED) { - shapeBuffer += shapeWidth - 1; - } - - for (y = y1; y < y2; ++y) { - uint8 *dstNextLine = dst + SCREEN_W; - int j = scaleYTable[y]; - if (flags & DSF_Y_FLIPPED) { - j = -j; - } - for (x = x1; x < x2; ++x) { - int xpos = scaleXTable[x]; - if (flags & DSF_X_FLIPPED) { - xpos = -xpos; - } - uint8 color = shapeBuffer[j * shapeWidth + xpos]; - if (color != 0) { - switch (ppc) { - case 0: - *dst = color; - break; - - case 1: - for (int i = 0; i < tableLoopCount; ++i) { - color = table[color]; - } - break; - - case 2: { - int temp = drawShapeVar4 + drawShapeVar5; - if (temp & 0xFF00) { - drawShapeVar4 = temp & 0xFF; - dst += drawShapeVar3; - color = *dst; - dst -= drawShapeVar3; - } else { - drawShapeVar4 = temp; - } - } break; - - case 7: - case 3: - color = *dst; - for (int i = 0; i < tableLoopCount; ++i) { - color = table[color]; - } - break; - - case 4: - color = table2[color]; - break; - - case 5: - color = table2[color]; - for (int i = 0; i < tableLoopCount; ++i) { - color = table[color]; - } - break; - - case 6: { - int temp = drawShapeVar4 + drawShapeVar5; - if (temp & 0xFF00) { - drawShapeVar4 = temp & 0xFF; - dst += drawShapeVar3; - color = *dst; - dst -= drawShapeVar3; - } else { - drawShapeVar4 = temp; - color = table2[color]; - } - } break; - - case 8: { - int offset = dst - dstStart; - uint8 pixel = *(_shapePages[0] + offset); - pixel &= 0x7F; - pixel &= 0x87; - if (drawLayer < pixel) { - color = *(_shapePages[1] + offset); - } - } break; - - case 9: { - int offset = dst - dstStart; - uint8 pixel = *(_shapePages[0] + offset); - pixel &= 0x7F; - pixel &= 0x87; - if (drawLayer < pixel) { - color = *(_shapePages[1] + offset); - } else { - for (int i = 0; i < tableLoopCount; ++i) { - color = table[color]; - } - } - } break; - - case 10: { - int offset = dst - dstStart; - uint8 pixel = *(_shapePages[0] + offset); - pixel &= 0x7F; - pixel &= 0x87; - if (drawLayer < pixel) { - color = *(_shapePages[1] + offset); - drawShapeVar4 = pixel; - } else { - int temp = drawShapeVar4 + drawShapeVar5; - if (temp & 0xFF00) { - dst += drawShapeVar3; - color = *dst; - dst -= drawShapeVar3; - } - drawShapeVar4 = temp & 0xFF; - } - } break; - - case 15: - case 11: { - int offset = dst - dstStart; - uint8 pixel = *(_shapePages[0] + offset); - pixel &= 0x7F; - pixel &= 0x87; - if (drawLayer < pixel) { - color = *(_shapePages[1] + offset); - } else { - color = *dst; - for (int i = 0; i < tableLoopCount; ++i) { - color = table[color]; - } - } - } break; - - case 12: { - int offset = dst - dstStart; - uint8 pixel = *(_shapePages[0] + offset); - pixel &= 0x7F; - pixel &= 0x87; - if (drawLayer < pixel) { - color = *(_shapePages[1] + offset); - } else { - color = table2[color]; - } - } break; - - case 13: { - int offset = dst - dstStart; - uint8 pixel = *(_shapePages[0] + offset); - pixel &= 0x7F; - pixel &= 0x87; - if (drawLayer < pixel) { - color = *(_shapePages[1] + offset); - } else { - color = table2[color]; - for (int i = 0; i < tableLoopCount; ++i) { - color = table[color]; - } - } - } break; - - case 14: { - int offset = dst - dstStart; - uint8 pixel = *(_shapePages[0] + offset); - pixel &= 0x7F; - pixel &= 0x87; - if (drawLayer < pixel) { - color = *(_shapePages[1] + offset); - drawShapeVar4 = pixel; - } else { - int temp = drawShapeVar4 + drawShapeVar5; - if (temp & 0xFF00) { - dst += drawShapeVar3; - color = *dst; - dst -= drawShapeVar3; - drawShapeVar4 = temp % 0xFF; - } else { - drawShapeVar4 = temp; - color = table2[color]; - } - } - } break; - - case 16: { - uint8 newColor = table3[color]; - if (!(newColor & 0x80)) { - color = *dst; - color = table4[color + (newColor << 8)]; - } - } break; - - case 17: { - for (int i = 0; i < tableLoopCount; ++i) { - color = table[color]; - } - uint8 newColor = table3[color]; - if (!(newColor & 0x80)) { - color = *dst; - color = table4[color + (newColor << 8)]; - } - } break; - - case 18: { - int temp = drawShapeVar4 + drawShapeVar5; - if (temp & 0xFF00) { - drawShapeVar4 = temp & 0xFF; - dst += drawShapeVar3; - color = *dst; - dst -= drawShapeVar3; - uint8 newColor = table3[color]; - if (!(newColor & 0x80)) { - color = *dst; - color = table4[color + (newColor << 8)]; - } - } else { - drawShapeVar4 = temp; - } - } break; - - case 23: - case 19: { - color = *dst; - for (int i = 0; i < tableLoopCount; ++i) { - color = table[color]; - } - uint8 newColor = table3[color]; - if (!(newColor & 0x80)) { - color = *dst; - color = table4[color + (newColor << 8)]; - } - } break; - - case 20: { - color = table2[color]; - uint8 newColor = table3[color]; - if (!(newColor & 0x80)) { - color = *dst; - color = table4[color + (newColor << 8)]; - } - } break; - - case 21: { - color = table2[color]; - for (int i = 0; i < tableLoopCount; ++i) { - color = table[color]; - } - uint8 newColor = table3[color]; - if (!(newColor & 0x80)) { - color = *dst; - color = table4[color + (newColor << 8)]; - } - } break; - - case 22: { - int temp = drawShapeVar4 + drawShapeVar5; - if (temp & 0xFF00) { - drawShapeVar4 = temp & 0xFF; - dst += drawShapeVar3; - color = *dst; - dst -= drawShapeVar3; - uint8 newColor = table3[color]; - if (!(newColor & 0x80)) { - color = *dst; - color = table4[color + (newColor << 8)]; - } - } else { - drawShapeVar4 = temp; - color = table2[color]; - uint8 newColor = table3[color]; - if (!(newColor & 0x80)) { - color = *dst; - color = table4[color + (newColor << 8)]; - } - } - } break; - - case 24: { - int offset = dst - dstStart; - uint8 pixel = *(_shapePages[0] + offset); - pixel &= 0x7F; - pixel &= 0x87; - if (drawLayer < pixel) { - color = *(_shapePages[1] + offset); - } - uint8 newColor = table3[color]; - if (!(newColor & 0x80)) { - color = *dst; - color = table4[color + (newColor << 8)]; - } - } break; - - default: - warning("unhandled ppc: %d", ppc); - break; - } - *dst = color; - } - ++dst; - } - dst = dstNextLine; - } - va_end(args); -} - -void Screen::decodeFrame3(const uint8 *src, uint8 *dst, uint32 size) { - debug(9, "Screen::decodeFrame3(0x%X, 0x%X, %d)", src, dst, size); - const uint8 *dstEnd = dst + size; - while (dst < dstEnd) { - int8 code = *src++; - if (code == 0) { - uint16 sz = READ_BE_UINT16(src); - src += 2; - memset(dst, *src++, sz); - dst += sz; - } else if (code < 0) { - memset(dst, *src++, -code); - dst -= code; - } else { - memcpy(dst, src, code); - dst += code; - src += code; - } - } -} - -void Screen::decodeFrame4(const uint8 *src, uint8 *dst, uint32 dstSize) { - debug(9, "Screen::decodeFrame4(0x%X, 0x%X, %d)", src, dst, dstSize); - uint8 *dstOrig = dst; - uint8 *dstEnd = dst + dstSize; - while (1) { - int count = dstEnd - dst; - if (count == 0) { - break; - } - uint8 code = *src++; - if (!(code & 0x80)) { - int len = MIN(count, (code >> 4) + 3); - int offs = ((code & 0xF) << 8) | *src++; - const uint8 *dstOffs = dst - offs; - while (len--) { - *dst++ = *dstOffs++; - } - } else if (code & 0x40) { - int len = (code & 0x3F) + 3; - if (code == 0xFE) { - len = READ_LE_UINT16(src); src += 2; - if (len > count) { - len = count; - } - memset(dst, *src++, len); dst += len; - } else { - if (code == 0xFF) { - len = READ_LE_UINT16(src); src += 2; - } - int offs = READ_LE_UINT16(src); src += 2; - if (len > count) { - len = count; - } - const uint8 *dstOffs = dstOrig + offs; - while (len--) { - *dst++ = *dstOffs++; - } - } - } else if (code != 0x80) { - int len = MIN(count, code & 0x3F); - while (len--) { - *dst++ = *src++; - } - } else { - break; - } - } -} - -void Screen::decodeFrameDelta(uint8 *dst, const uint8 *src) { - debug(9, "Screen::decodeFrameDelta(0x%X, 0x%X)", dst, src); - while (1) { - uint8 code = *src++; - if (code == 0) { - uint8 len = *src++; - code = *src++; - while (len--) { - *dst++ ^= code; - } - } else if (code & 0x80) { - code -= 0x80; - if (code != 0) { - dst += code; - } else { - uint16 subcode = READ_LE_UINT16(src); src += 2; - if (subcode == 0) { - break; - } else if (subcode & 0x8000) { - subcode -= 0x8000; - if (subcode & 0x4000) { - uint16 len = subcode - 0x4000; - code = *src++; - while (len--) { - *dst++ ^= code; - } - } else { - while (subcode--) { - *dst++ ^= *src++; - } - } - } else { - dst += subcode; - } - } - } else { - while (code--) { - *dst++ ^= *src++; - } - } - } -} - -void Screen::decodeFrameDeltaPage(uint8 *dst, const uint8 *src, int pitch, int noXor) { - debug(9, "Screen::decodeFrameDeltaPage(0x%X, 0x%X, %d, %d)", dst, src, pitch, noXor); - int count = 0; - uint8 *dstNext = dst; - while (1) { - uint8 code = *src++; - if (code == 0) { - uint8 len = *src++; - code = *src++; - while (len--) { - if (noXor) { - *dst++ = code; - } else { - *dst++ ^= code; - } - if (++count == pitch) { - count = 0; - dstNext += SCREEN_W; - dst = dstNext; - } - } - } else if (code & 0x80) { - code -= 0x80; - if (code != 0) { - dst += code; - - count += code; - while (count >= pitch) { - count -= pitch; - dstNext += SCREEN_W; - dst = dstNext + count; - } - } else { - uint16 subcode = READ_LE_UINT16(src); src += 2; - if (subcode == 0) { - break; - } else if (subcode & 0x8000) { - subcode -= 0x8000; - if (subcode & 0x4000) { - uint16 len = subcode - 0x4000; - code = *src++; - while (len--) { - if (noXor) { - *dst++ = code; - } else { - *dst++ ^= code; - } - if (++count == pitch) { - count = 0; - dstNext += SCREEN_W; - dst = dstNext; - } - } - } else { - while (subcode--) { - if (noXor) { - *dst++ = *src++; - } else { - *dst++ ^= *src++; - } - if (++count == pitch) { - count = 0; - dstNext += SCREEN_W; - dst = dstNext; - } - } - } - } else { - dst += subcode; - - count += subcode; - while (count >= pitch) { - count -= pitch; - dstNext += SCREEN_W; - dst = dstNext + count; - } - - } - } - } else { - while (code--) { - if (noXor) { - *dst++ = *src++; - } else { - *dst++ ^= *src++; - } - if (++count == pitch) { - count = 0; - dstNext += SCREEN_W; - dst = dstNext; - } - } - } - } -} - -uint8 *Screen::encodeShape(int x, int y, int w, int h, int flags) { - debug(9, "Screen::encodeShape(%d, %d, %d, %d, %d)", x, y, w, h, flags); - uint8 *srcPtr = &_pagePtrs[_curPage][y * SCREEN_W + x]; - int16 shapeSize = 0; - uint8 *tmp = srcPtr; - int xpos = w; - - for (int i = h; i > 0; --i) { - uint8 *start = tmp; - shapeSize += w; - xpos = w; - while (xpos) { - uint8 value = *tmp++; - --xpos; - - if (!value) { - shapeSize += 2; - int16 curX = xpos; - bool skip = false; - - while (xpos) { - value = *tmp++; - --xpos; - - if (value) { - skip = true; - break; - } - } - - if (!skip) - ++curX; - - curX -= xpos; - shapeSize -= curX; - - while (curX > 0xFF) { - curX -= 0xFF; - shapeSize += 2; - } - } - } - - tmp = start + SCREEN_W; - } - - int16 shapeSize2 = shapeSize; - if (_vm->features() & GF_TALKIE) { - shapeSize += 12; - } else { - shapeSize += 10; - } - if (flags & 1) - shapeSize += 16; - - static uint8 table[274]; - int tableIndex = 0; - - uint8 *newShape = NULL; - newShape = (uint8*)malloc(shapeSize+16); - assert(newShape); - - byte *dst = newShape; - if (_vm->features() & GF_TALKIE) - dst += 2; - WRITE_LE_UINT16(dst, (flags & 3)); dst += 2; - *dst = h; dst += 1; - WRITE_LE_UINT16(dst, w); dst += 2; - *dst = h; dst += 1; - WRITE_LE_UINT16(dst, shapeSize); dst += 2; - WRITE_LE_UINT16(dst, shapeSize2); dst += 2; - - byte *src = srcPtr; - if (flags & 1) { - dst += 16; - memset(table, 0, sizeof(uint8)*274); - tableIndex = 1; - } - - for (int ypos = h; ypos > 0; --ypos) { - uint8 *srcBackUp = src; - xpos = w; - while (xpos) { - uint8 value = *src++; - if (value) { - if (flags & 1) { - if (!table[value]) { - if (tableIndex == 16) { - value = 1; - } else { - table[0x100+tableIndex] = value; - table[value] = tableIndex; - ++tableIndex; - value = table[value]; - } - } else { - value = table[value]; - } - } - --xpos; - *dst++ = value; - } else { - int16 temp = 1; - --xpos; - - while (xpos) { - if (*src) - break; - ++src; - ++temp; - --xpos; - } - - while (temp > 0xFF) { - *dst++ = 0; - *dst++ = 0xFF; - temp -= 0xFF; - } - - if (temp & 0xFF) { - *dst++ = 0; - *dst++ = temp & 0xFF; - } - } - } - src = srcBackUp + SCREEN_W; - } - - if (!(flags & 2)) { - if (shapeSize > _animBlockSize) { - dst = newShape; - if (_vm->features() & GF_TALKIE) { - dst += 2; - } - flags = READ_LE_UINT16(dst); - flags |= 2; - WRITE_LE_UINT16(dst, flags); - } else { - src = newShape; - if (_vm->features() & GF_TALKIE) { - src += 2; - } - if (flags & 1) { - src += 16; - } - src += 10; - uint8 *shapePtrBackUp = src; - dst = _animBlockPtr; - memcpy(dst, src, shapeSize2); - - int16 size = encodeShapeAndCalculateSize(_animBlockPtr, shapePtrBackUp, shapeSize2); - if (size > shapeSize2) { - shapeSize -= shapeSize2 - size; - newShape = (uint8*)realloc(newShape, shapeSize); - assert(newShape); - } else { - dst = shapePtrBackUp; - src = _animBlockPtr; - memcpy(dst, src, shapeSize2); - dst = newShape; - flags = READ_LE_UINT16(dst); - flags |= 2; - WRITE_LE_UINT16(dst, flags); - } - } - } - - dst = newShape; - if (_vm->features() & GF_TALKIE) { - dst += 2; - } - WRITE_LE_UINT16((dst + 6), shapeSize); - - if (flags & 1) { - dst = newShape + 10; - if (_vm->features() & GF_TALKIE) { - dst += 2; - } - src = &table[0x100]; - memcpy(dst, src, sizeof(uint8)*16); - } - - return newShape; -} - -int16 Screen::encodeShapeAndCalculateSize(uint8 *from, uint8 *to, int size_to) { - debug(9, "Screen::encodeShapeAndCalculateSize(0x%X, 0x%X, %d)", from, to, size_to); - byte *fromPtrEnd = from + size_to; - bool skipPixel = true; - byte *tempPtr = 0; - byte *toPtr = to; - byte *fromPtr = from; - byte *toPtr2 = to; - - *to++ = 0x81; - *to++ = *from++; - - while (from < fromPtrEnd) { - byte *curToPtr = to; - to = fromPtr; - int size = 1; - - while (true) { - byte curPixel = *from; - if (curPixel == *(from+0x40)) { - byte *toBackUp = to; - to = from; - - for (int i = 0; i < (fromPtrEnd - from); ++i) { - if (*to++ != curPixel) - break; - } - --to; - uint16 diffSize = (to - from); - if (diffSize >= 0x41) { - skipPixel = false; - from = to; - to = curToPtr; - *to++ = 0xFE; - WRITE_LE_UINT16(to, diffSize); to += 2; - *to++ = (size >> 8) & 0xFF; - curToPtr = to; - to = toBackUp; - continue; - } else { - to = toBackUp; - } - } - - bool breakLoop = false; - while (true) { - if ((from - to) == 0) { - breakLoop = true; - break; - } - for (int i = 0; i < (from - to); ++i) { - if (*to++ == curPixel) - break; - } - if (*to == curPixel) { - if (*(from+size-1) == *(to+size-2)) - break; - - byte *fromBackUp = from; - byte *toBackUp = to; - --to; - for (int i = 0; i < (fromPtrEnd - from); ++i) { - if (*from++ != *to++) - break; - } - if (*(from - 1) == *(to - 1)) - ++to; - from = fromBackUp; - int temp = to - toBackUp; - to = toBackUp; - if (temp >= size) { - size = temp; - tempPtr = toBackUp - 1; - } - break; - } else { - breakLoop = true; - break; - } - } - - if (breakLoop) - break; - } - - to = curToPtr; - if (size > 2) { - uint16 word = 0; - if (size <= 0x0A) { - uint16 diffSize = from - tempPtr; - if (size <= 0x0FFF) { - byte highByte = ((diffSize & 0xFF00) >> 8) + (((size & 0xFF) - 3) << 4); - word = ((diffSize & 0xFF) << 8) | highByte; - WRITE_LE_UINT16(to, word); to += 2; - from += size; - skipPixel = false; - continue; - } - } - - if (size > 0x40) { - *to++ = 0xFF; - WRITE_LE_UINT16(to, size); to += 2; - } else { - *to++ = ((size & 0xFF) - 3) | 0xC0; - } - - word = tempPtr - fromPtr; - WRITE_LE_UINT16(to, word); to += 2; - from += size; - skipPixel = false; - } else { - if (!skipPixel) { - toPtr2 = to; - *to++ = 0x80; - } - - if (*toPtr2 == 0xBF) { - toPtr2 = to; - *to++ = 0x80; - } - - ++(*toPtr2); - *to++ = *from++; - skipPixel = true; - } - } - *to++ = 0x80; - - return (to - toPtr); -} - -int Screen::getRectSize(int x, int y) { - if (x < 1) { - x = 1; - } else if (x > 40) { - x = 40; - } - - if (y < 1) { - y = 1; - } else if (y > 200) { - y = 200; - } - - return ((x*y) << 3); -} - -void Screen::hideMouse() { - debug(9, "Screen::hideMouse()"); - ++_mouseLockCount; - _system->showMouse(false); -} - -void Screen::showMouse() { - debug(9, "Screen::showMouse()"); - - if (_mouseLockCount == 1) - _system->showMouse(true); - - if (_mouseLockCount > 0) - _mouseLockCount--; - -} - -void Screen::setShapePages(int page1, int page2) { - debug(9, "Screen::setShapePages(%d, %d)", page1, page2); - _shapePages[0] = _pagePtrs[page1]; - _shapePages[1] = _pagePtrs[page2]; -} - -void Screen::setMouseCursor(int x, int y, byte *shape) { - debug(9, "Screen::setMouseCursor(%d, %d, 0x%X)", x, y, shape); - if (!shape) - return; - // if mouseDisabled - // return _mouseShape - - if (_vm->features() & GF_TALKIE) - shape += 2; - - int mouseHeight = *(shape+2); - int mouseWidth = (READ_LE_UINT16(shape + 3)) + 2; - - if (_vm->features() & GF_TALKIE) - shape -= 2; - - uint8 *cursor = (uint8 *)malloc(mouseHeight * mouseWidth); - fillRect(0, 0, mouseWidth, mouseHeight, 0, 8); - drawShape(8, shape, 0, 0, 0, 0); - - _system->showMouse(false); - copyRegionToBuffer(8, 0, 0, mouseWidth, mouseHeight, cursor); - _system->setMouseCursor(cursor, mouseWidth, mouseHeight, x, y, 0); - _system->showMouse(true); - free(cursor); - - return; - -} - -void Screen::copyScreenFromRect(int x, int y, int w, int h, uint8 *ptr) { - debug(9, "Screen::copyScreenFromRect(%d, %d, %d, %d, 0x%X)", x, y, w, h, ptr); - x <<= 3; w <<= 3; - uint8 *src = ptr; - uint8 *dst = &_pagePtrs[0][y * SCREEN_W + x]; - for (int i = 0; i < h; ++i) { - memcpy(dst, src, w); - src += w; - dst += SCREEN_W; - } -} - -void Screen::copyScreenToRect(int x, int y, int w, int h, uint8 *ptr) { - debug(9, "Screen::copyScreenToRect(%d, %d, %d, %d, 0x%X)", x, y, w, h, ptr); - x <<= 3; w <<= 3; - uint8 *src = &_pagePtrs[0][y * SCREEN_W + x]; - uint8 *dst = ptr; - for (int i = 0; i < h; ++i) { - memcpy(dst, src, w); - dst += w; - src += SCREEN_W; - } -} - -uint8 *Screen::getPalette(int num) { - debug(9, "Screen::getPalette(%d)", num); - assert(num >= 0 && num < 4); - if (num == 0) { - return _screenPalette; - } - - return _palettes[num-1]; -} - -byte Screen::getShapeFlag1(int x, int y) { - debug(9, "Screen::getShapeFlag1(%d, %d)", x, y); - uint8 color = _shapePages[0][y * SCREEN_W + x]; - color &= 0x80; - color ^= 0x80; - - if (color & 0x80) { - return 1; - } - return 0; -} - -byte Screen::getShapeFlag2(int x, int y) { - debug(9, "Screen::getShapeFlag2(%d, %d)", x, y); - uint8 color = _shapePages[0][y * SCREEN_W + x]; - color &= 0x7F; - color &= 0x87; - return color; -} - -int Screen::setNewShapeHeight(uint8 *shape, int height) { - debug(9, "Screen::setNewShapeHeight(0x%X, %d)", shape, height); - if (_vm->features() & GF_TALKIE) - shape += 2; - int oldHeight = shape[2]; - shape[2] = height; - return oldHeight; -} - -int Screen::resetShapeHeight(uint8 *shape) { - debug(9, "Screen::setNewShapeHeight(0x%X)", shape); - if (_vm->features() & GF_TALKIE) - shape += 2; - int oldHeight = shape[2]; - shape[2] = shape[5]; - return oldHeight; -} - -void Screen::addBitBlitRect(int x, int y, int w, int h) { - debug(9, "Screen::addBitBlitRects(%d, %d, %d, %d)", x, y, w, h); - if (_bitBlitNum >= BITBLIT_RECTS) { - error("too many bit blit rects"); - } - _bitBlitRects[_bitBlitNum].x = x; - _bitBlitRects[_bitBlitNum].y = y; - _bitBlitRects[_bitBlitNum].x2 = w; - _bitBlitRects[_bitBlitNum].y2 = h; - ++_bitBlitNum; -} - -void Screen::bitBlitRects() { - debug(9, "Screen::bitBlitRects()"); - Rect *cur = _bitBlitRects; - while (_bitBlitNum) { - _bitBlitNum--; - copyRegion(cur->x, cur->y, cur->x, cur->y, cur->x2, cur->y2, 2, 0); - ++cur; - } -} - -void Screen::savePageToDisk(const char *file, int page) { - debug(9, "Screen::savePageToDisk('%s', %d)", file, page); - if (!_saveLoadPage[page/2]) { - _saveLoadPage[page/2] = new uint8[SCREEN_W * SCREEN_H]; - assert(_saveLoadPage[page/2]); - } - memcpy(_saveLoadPage[page/2], getPagePtr(page), SCREEN_W * SCREEN_H); -} - -void Screen::loadPageFromDisk(const char *file, int page) { - debug(9, "Screen::loadPageFromDisk('%s', %d)", file, page); - copyBlockToPage(page, 0, 0, SCREEN_W, SCREEN_H, _saveLoadPage[page/2]); - delete [] _saveLoadPage[page/2]; - _saveLoadPage[page/2] = 0; -} - -void Screen::deletePageFromDisk(int page) { - debug(9, "Screen::deletePageFromDisk(%d)", page); - delete [] _saveLoadPage[page/2]; - _saveLoadPage[page/2] = 0; -} - -void Screen::blockInRegion(int x, int y, int width, int height) { - debug(9, "Screen::blockInRegion(%d, %d, %d, %d)", x, y, width, height); - assert(_shapePages[0]); - byte *toPtr = _shapePages[0] + (y * 320 + x); - for (int i = 0; i < height; ++i) { - byte *backUpTo = toPtr; - for (int i2 = 0; i2 < width; ++i2) { - *toPtr++ &= 0x7F; - } - toPtr = (backUpTo + 320); - } -} - -void Screen::blockOutRegion(int x, int y, int width, int height) { - debug(9, "Screen::blockOutRegion(%d, %d, %d, %d)", x, y, width, height); - assert(_shapePages[0]); - byte *toPtr = _shapePages[0] + (y * 320 + x); - for (int i = 0; i < height; ++i) { - byte *backUpTo = toPtr; - for (int i2 = 0; i2 < width; ++i2) { - *toPtr++ |= 0x80; - } - toPtr = (backUpTo + 320); - } -} - -void Screen::rectClip(int &x, int &y, int w, int h) { - if (x < 0) { - x = 0; - } else if (x + w >= 320) { - x = 320 - w; - } - if (y < 0) { - y = 0; - } else if (y + h >= 200) { - y = 200 - h; - } -} - -void Screen::backUpRect0(int xpos, int ypos) { - debug(9, "Screen::backUpRect0(%d, %d)", xpos, ypos); - rectClip(xpos, ypos, 3<<3, 24); - copyRegionToBuffer(_curPage, xpos, ypos, 3<<3, 24, _vm->shapes()[0]); -} - -void Screen::restoreRect0(int xpos, int ypos) { - debug(9, "Screen::restoreRect0(%d, %d)", xpos, ypos); - rectClip(xpos, ypos, 3<<3, 24); - copyBlockToPage(_curPage, xpos, ypos, 3<<3, 24, _vm->shapes()[0]); -} - -void Screen::backUpRect1(int xpos, int ypos) { - debug(9, "Screen::backUpRect1(%d, %d)", xpos, ypos); - rectClip(xpos, ypos, 4<<3, 32); - copyRegionToBuffer(_curPage, xpos, ypos, 4<<3, 32, _vm->shapes()[1]); -} - -void Screen::restoreRect1(int xpos, int ypos) { - debug(9, "Screen::restoreRect1(%d, %d)", xpos, ypos); - rectClip(xpos, ypos, 4<<3, 32); - copyBlockToPage(_curPage, xpos, ypos, 4<<3, 32, _vm->shapes()[1]); -} - -int Screen::getDrawLayer(int x, int y) { - debug(9, "Screen::getDrawLayer(%d, %d)", x, y); - int xpos = x - 8; - int ypos = y - 1; - int layer = 1; - for (int curX = xpos; curX < xpos + 16; ++curX) { - int tempLayer = getShapeFlag2(curX, ypos); - if (layer < tempLayer) { - layer = tempLayer; - } - if (layer >= 7) { - return 7; - } - } - return layer; -} - -int Screen::getDrawLayer2(int x, int y, int height) { - debug(9, "Screen::getDrawLayer2(%d, %d, %d)", x, y, height); - int xpos = x - 8; - int ypos = y - 1; - int layer = 1; - - for (int useX = xpos; useX < xpos + 16; ++useX) { - for (int useY = ypos - height; useY < ypos; ++useY) { - int tempLayer = getShapeFlag2(useX, useY); - if (tempLayer > layer) { - layer = tempLayer; - } - - if (tempLayer >= 7) { - return 7; - } - } - } - return layer; -} - -void Screen::copyBackgroundBlock(int x, int page, int flag) { - debug(9, "Screen::copyBackgroundBlock(%d, %d, %d)", x, page, flag); - - if (x < 1) - return; - - int height = 128; - if (flag) - height += 8; - if (!(x & 1)) - ++x; - if (x == 19) - x = 17; - uint8 *ptr1 = _unkPtr1; - uint8 *ptr2 = _unkPtr2; - int oldVideoPage = _curPage; - _curPage = page; - - int curX = x; - hideMouse(); - copyRegionToBuffer(_curPage, 8, 8, 8, height, ptr2); - for (int i = 0; i < 19; ++i) { - int tempX = curX + 1; - copyRegionToBuffer(_curPage, tempX<<3, 8, 8, height, ptr1); - copyBlockToPage(_curPage, tempX<<3, 8, 8, height, ptr2); - int newXPos = curX + x; - if (newXPos > 37) { - newXPos = newXPos % 38; - } - tempX = newXPos + 1; - copyRegionToBuffer(_curPage, tempX<<3, 8, 8, height, ptr2); - copyBlockToPage(_curPage, tempX<<3, 8, 8, height, ptr1); - curX += x*2; - if (curX > 37) { - curX = curX % 38; - } - } - showMouse(); - _curPage = oldVideoPage; -} - -void Screen::copyBackgroundBlock2(int x) { - copyBackgroundBlock(x, 4, 1); -} - -} // End of namespace Kyra |