scummvm/engines/sludge/transition.cpp

232 lines
6.2 KiB
C++
Raw Normal View History

/* 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 3 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, see <http://www.gnu.org/licenses/>.
*
*/
2017-06-05 17:10:47 +00:00
2021-05-16 14:38:26 +00:00
#include "common/textconsole.h"
#include "sludge/graphics.h"
2017-05-26 19:25:11 +00:00
namespace Sludge {
extern float snapTexW, snapTexH;
void GraphicsManager::setBrightnessLevel(int brightnessLevel) {
2021-05-16 16:51:49 +00:00
_brightnessLevel = CLIP(brightnessLevel, 0, 255);
}
//----------------------------------------------------
// PROPER BRIGHTNESS FADING
//----------------------------------------------------
unsigned lastFrom, lastTo;
2021-05-14 21:58:32 +00:00
void GraphicsManager::transitionFader() {
blendColor(&_renderSurface, TS_ARGB(255 - _brightnessLevel, 0, 0, 0), Graphics::BLEND_NORMAL);
}
void GraphicsManager::transitionCrossFader() {
if (!_snapshotSurface.getPixels())
return;
2021-05-16 16:51:49 +00:00
if (_brightnessLevel == 255)
return;
Graphics::TransparentSurface tmp(_snapshotSurface, false);
tmp.blit(_renderSurface, 0, 0, Graphics::FLIP_NONE, nullptr, TS_ARGB(255 - _brightnessLevel, 0xff, 0xff, 0xff));
}
void GraphicsManager::transitionSnapshotBox() {
if (!_snapshotSurface.getPixels())
return;
if (_brightnessLevel == 255)
return;
uint32 xScale = (255 - _brightnessLevel) * _winWidth / 255;
uint32 yScale = (255 - _brightnessLevel) * _winHeight / 255;
Graphics::Surface *surf = _snapshotSurface.scale(xScale, yScale);
_renderSurface.copyRectToSurface(surf->getPixels(), surf->pitch, (_winWidth - xScale) / 2, (_winHeight - yScale) / 2, xScale, yScale);
}
//----------------------------------------------------
// FAST PSEUDO-RANDOM NUMBER STUFF FOR DISOLVE EFFECT
//----------------------------------------------------
void GraphicsManager::resetRandW() {
2017-07-13 16:43:24 +00:00
int32 seed = 12345;
2021-05-16 14:38:26 +00:00
for (int i = 0; i < RANDKK; i++) {
for (int j = 0; j < 2; j++) {
seed = seed * 2891336453u + 1;
2021-05-16 14:38:26 +00:00
_randbuffer[i][j] = seed;
}
}
2021-05-16 14:38:26 +00:00
_randp1 = 0;
_randp2 = 10;
}
2021-05-16 14:38:26 +00:00
void GraphicsManager::reserveTransitionTexture() {
_transitionTexture = new Graphics::TransparentSurface;
2021-05-16 14:38:26 +00:00
_transitionTexture->create(256, 256, _transitionTexture->getSupportedPixelFormat());
}
2021-05-16 14:38:26 +00:00
void GraphicsManager::transitionDisolve() {
if (!_transitionTexture)
reserveTransitionTexture();
2021-05-16 14:38:26 +00:00
if (!_brightnessLevel) {
transitionFader();
return;
}
2021-05-16 14:38:26 +00:00
byte *toScreen = (byte *)_transitionTexture->getPixels();
byte *end = (byte *)_transitionTexture->getBasePtr(255, 255);
do {
// generate next number
2021-05-16 14:38:26 +00:00
uint32 n = _randbuffer[_randp1][1];
uint32 y = (n << 27) | ((n >> (32 - 27)) + _randbuffer[_randp2][1]);
2021-05-16 14:38:26 +00:00
n = _randbuffer[_randp1][0];
_randbuffer[_randp1][1] = (n << 19) | ((n >> (32 - 19)) + _randbuffer[_randp2][0]);
_randbuffer[_randp1][0] = y;
// rotate list pointers
2021-05-16 14:38:26 +00:00
if (!_randp1--)
_randp1 = RANDKK - 1;
if (!_randp2--)
_randp2 = RANDKK - 1;
if ((y & 0xff) > _brightnessLevel) {
toScreen[0] = 255;
toScreen[1] = toScreen[2] = toScreen[3] = 0;
} else {
toScreen[0] = toScreen[1] = toScreen[2] = toScreen[3] = 0;
}
toScreen += 4;
2021-05-16 14:38:26 +00:00
} while (toScreen < end);
2021-05-16 14:38:26 +00:00
// The original stretched the texture, we just tile it
2021-05-16 16:51:49 +00:00
for (uint y = 0; y < _sceneHeight; y += _transitionTexture->h)
for (uint x = 0; x < _sceneWidth; x += _transitionTexture->w)
2021-05-16 14:38:26 +00:00
_transitionTexture->blit(_renderSurface, x, y);
}
2021-05-16 14:43:31 +00:00
void GraphicsManager::transitionTV() {
if (!_transitionTexture)
reserveTransitionTexture();
2021-05-16 14:43:31 +00:00
byte *toScreen = (byte *)_transitionTexture->getPixels();
byte *end = (byte *)_transitionTexture->getBasePtr(255, 255);
do {
// generate next number
2021-05-16 14:43:31 +00:00
uint32 n = _randbuffer[_randp1][1];
uint32 y = (n << 27) | ((n >> (32 - 27)) + _randbuffer[_randp2][1]);
2021-05-16 14:38:26 +00:00
n = _randbuffer[_randp1][0];
_randbuffer[_randp1][1] = (n << 19) | ((n >> (32 - 19)) + _randbuffer[_randp2][0]);
_randbuffer[_randp1][0] = y;
// rotate list pointers
2021-05-16 14:38:26 +00:00
if (!_randp1--)
_randp1 = RANDKK - 1;
if (!_randp2--)
_randp2 = RANDKK - 1;
2021-05-16 14:43:31 +00:00
if ((y & 255u) > _brightnessLevel) {
toScreen[0] = (n & 255);
toScreen[1] = toScreen[2] = toScreen[3] = (n & 255);
} else {
toScreen[0] = toScreen[1] = toScreen[2] = toScreen[3] = 0;
}
toScreen += 4;
2021-05-16 14:43:31 +00:00
} while (toScreen < end);
2021-05-16 14:43:31 +00:00
// The original stretched the texture, we just tile it
2021-05-16 16:51:49 +00:00
for (uint y = 0; y < _sceneHeight; y += _transitionTexture->h)
for (uint x = 0; x < _sceneWidth; x += _transitionTexture->w)
2021-05-16 14:43:31 +00:00
_transitionTexture->blit(_renderSurface, x, y);
}
2021-05-16 15:07:56 +00:00
void GraphicsManager::transitionBlinds() {
if (!_transitionTexture)
reserveTransitionTexture();
2021-05-16 15:07:56 +00:00
int level = _brightnessLevel / 16;
for (int b = 0; b < 16; b++) {
byte *toScreen = (byte *)_transitionTexture->getBasePtr(0, b * 16);
if (level)
memset(toScreen, 0, 256 * 4 * level);
if (level < 32) {
for (int y = 0; y < 16 - level; y++) {
toScreen = (byte *)_transitionTexture->getBasePtr(0, b * 16 + y);
for (int i = 0; i < 256; i++) {
toScreen[0] = 0xff;
toScreen[1] = toScreen[2] = toScreen[3] = 0;
toScreen += 4;
}
}
}
}
2021-05-16 16:51:49 +00:00
// The original stretched the texture, we just tile it
for (uint y = 0; y < _sceneHeight; y += _transitionTexture->h)
for (uint x = 0; x < _sceneWidth; x += _transitionTexture->w)
_transitionTexture->blit(_renderSurface, x, y);
}
//----------------------------------------------------
void GraphicsManager::fixBrightness() {
switch (_fadeMode) {
case 0:
transitionFader();
break;
case 1:
resetRandW();
// Fall through!
case 2:
transitionDisolve();
break;
case 3:
transitionTV();
break;
case 4:
transitionBlinds();
break;
case 5:
transitionCrossFader();
break;
case 6:
transitionSnapshotBox();
break;
default:
break;
}
}
2017-05-26 19:25:11 +00:00
} // End of namespace Sludge