void ToucheEngine::op_fadePalette() { debugC(9, kDebugOpcodes, "ToucheEngine::op_fadePalette()"); int16 fadeOut = _script.readNextWord(); int colorsCount = 240; // Workaround for bug #1751149. Script triggers a palette fading, but some // of the room graphics use palette colors >= 240. if (_currentEpisodeNum == 104 && _currentRoomNum == 68) { colorsCount = 256; } if (fadeOut) { fadePalette(0, colorsCount, 255, -2, 128); } else { fadePalette(0, colorsCount, 0, 2, 128); } }
void Screen::updateScreen() { if (Logic::_scriptVars[NEW_PALETTE]) { _fadingStep = 1; _fadingDirection = FADE_UP; _updatePalette = true; Logic::_scriptVars[NEW_PALETTE] = 0; } if (_updatePalette) { fnSetPalette(0, 184, _roomDefTable[_currentScreen].palettes[0], false); fnSetPalette(184, 72, _roomDefTable[_currentScreen].palettes[1], false); _updatePalette = false; } if (_fadingStep) { fadePalette(); _system->getPaletteManager()->setPalette(_currentPalette, 0, 256); } uint16 scrlX = (uint16)Logic::_scriptVars[SCROLL_OFFSET_X]; uint16 scrlY = (uint16)Logic::_scriptVars[SCROLL_OFFSET_Y]; if (_fullRefresh) { _fullRefresh = false; uint16 copyWidth = SCREEN_WIDTH; uint16 copyHeight = SCREEN_DEPTH; if (scrlX + copyWidth > _scrnSizeX) copyWidth = _scrnSizeX - scrlX; if (scrlY + copyHeight > _scrnSizeY) copyHeight = _scrnSizeY - scrlY; _system->copyRectToScreen(_screenBuf + scrlY * _scrnSizeX + scrlX, _scrnSizeX, 0, 40, copyWidth, copyHeight); } else { // partial screen update only. The screen coordinates probably won't fit to the // grid holding the informations on which blocks have to be updated. // as the grid will be X pixel higher and Y pixel more to the left, this can be cured // by first checking the top border, then the left column and then the remaining (aligned) part. uint8 *gridPos = _screenGrid + (scrlX / SCRNGRID_X) + (scrlY / SCRNGRID_Y) * _gridSizeX; uint8 *scrnBuf = _screenBuf + scrlY * _scrnSizeX + scrlX; uint8 diffX = (uint8)(scrlX % SCRNGRID_X); uint8 diffY = (uint8)(scrlY % SCRNGRID_Y); uint16 gridW = SCREEN_WIDTH / SCRNGRID_X; uint16 gridH = SCREEN_DEPTH / SCRNGRID_Y; if (diffY) { diffY = SCRNGRID_Y - diffY; uint16 cpWidth = 0; for (uint16 cntx = 0; cntx < gridW; cntx++) if (gridPos[cntx]) { gridPos[cntx] >>= 1; cpWidth++; } else if (cpWidth) { int16 xPos = (cntx - cpWidth) * SCRNGRID_X - diffX; if (xPos < 0) xPos = 0; _system->copyRectToScreen(scrnBuf + xPos, _scrnSizeX, xPos, 40, cpWidth * SCRNGRID_X, diffY); cpWidth = 0; } if (cpWidth) { int16 xPos = (gridW - cpWidth) * SCRNGRID_X - diffX; if (xPos < 0) xPos = 0; _system->copyRectToScreen(scrnBuf + xPos, _scrnSizeX, xPos, 40, SCREEN_WIDTH - xPos, diffY); } scrlY += diffY; } // okay, y scrolling is compensated. check x now. gridPos = _screenGrid + (scrlX / SCRNGRID_X) + (scrlY / SCRNGRID_Y) * _gridSizeX; scrnBuf = _screenBuf + scrlY * _scrnSizeX + scrlX; if (diffX) { diffX = SCRNGRID_X - diffX; uint16 cpHeight = 0; for (uint16 cnty = 0; cnty < gridH; cnty++) { if (*gridPos) { *gridPos >>= 1; cpHeight++; } else if (cpHeight) { uint16 yPos = (cnty - cpHeight) * SCRNGRID_Y; _system->copyRectToScreen(scrnBuf + yPos * _scrnSizeX, _scrnSizeX, 0, yPos + diffY + 40, diffX, cpHeight * SCRNGRID_Y); cpHeight = 0; } gridPos += _gridSizeX; } if (cpHeight) { uint16 yPos = (gridH - cpHeight) * SCRNGRID_Y; _system->copyRectToScreen(scrnBuf + yPos * _scrnSizeX, _scrnSizeX, 0, yPos + diffY + 40, diffX, SCREEN_DEPTH - (yPos + diffY)); } scrlX += diffX; }