From 6aaee559dc7f26240678421043baa865608b7d58 Mon Sep 17 00:00:00 2001 From: Martin Kiewitz Date: Tue, 9 Jun 2015 23:22:52 +0200 Subject: SHERLOCK: 3DO intro: implement fade from white --- engines/sherlock/animation.cpp | 58 +++++++++++++++++++++++++----------- engines/sherlock/animation.h | 2 +- engines/sherlock/scalpel/scalpel.cpp | 29 ++++++++++-------- engines/sherlock/screen.cpp | 44 ++++++++++++++++++++++++++- engines/sherlock/screen.h | 2 ++ engines/sherlock/surface.cpp | 4 +++ engines/sherlock/surface.h | 2 ++ 7 files changed, 109 insertions(+), 32 deletions(-) diff --git a/engines/sherlock/animation.cpp b/engines/sherlock/animation.cpp index 3bd3137982..45cb6664cb 100644 --- a/engines/sherlock/animation.cpp +++ b/engines/sherlock/animation.cpp @@ -140,17 +140,23 @@ bool Animation::play(const Common::String &filename, bool intro, int minDelay, i return !skipped && !_vm->shouldQuit(); } -bool Animation::play3DO(const Common::String &filename, bool intro, int minDelay, int fade, +bool Animation::play3DO(const Common::String &filename, bool intro, int minDelay, bool fadeFromGrey, int speed) { Events &events = *_vm->_events; Screen &screen = *_vm->_screen; - Sound &sound = *_vm->_sound; + Sound &sound = *_vm->_sound; int soundNumber = 0; + bool fadeActive = false; + uint16 fadeLimitColor = 0; + uint16 fadeLimitColorRed = 0; + uint16 fadeLimitColorGreen = 0; + uint16 fadeLimitColorBlue = 0; + // Check for any any sound frames for the given animation const int *soundFrames = checkForSoundFrames(filename, intro); - // Add on the VDX extension + // Add the VDX extension Common::String indexName = "prologue/" + filename + ".3dx"; // Load the animation @@ -166,13 +172,11 @@ bool Animation::play3DO(const Common::String &filename, bool intro, int minDelay ImageFile3DO images(graphicsName, true); events.wait(minDelay); -// if (fade != 0 && fade != 255) -// screen.fadeToBlack(); -// if (setPalette) { -// if (fade != 255) -// screen.setPalette(images._palette); -// } + if (fadeFromGrey) { + fadeActive = true; + fadeLimitColor = 0xCE59; // RGB565: 25, 50, 25 -> "grey" + } int frameNumber = 0; Common::Point pt; @@ -196,18 +200,36 @@ bool Animation::play3DO(const Common::String &filename, bool intro, int minDelay // Draw the sprite. Note that we explicitly use the raw frame below, rather than the ImageFrame, // since we don't want the offsets in the image file to be used, just the explicit position we specify - screen.transBlitFromUnscaled3DO(images[imageFrame]._frame, pt); - //events.wait(1000); + if (!fadeActive) { + screen.transBlitFromUnscaled3DO(images[imageFrame]._frame, pt); + } else { + // Fade active, blit to backbuffer1 + screen._backBuffer1.transBlitFromUnscaled3DO(images[imageFrame]._frame, pt); + } } else { -#if 0 // At this point, either the sprites for the frame has been complete, or there weren't any sprites // at all to draw for the frame - //if (fade == 255) { - // // Gradual fade in - // if (screen.equalizePalette(images._palette) == 0) - // fade = 0; - //} -#endif + + if (fadeActive) { + // process fading + screen.blitFrom3DOcolorLimit(fadeLimitColor); + + if (!fadeLimitColor) { + // we are at the end, so stop + fadeActive = false; + } else { + // decrease limit color + fadeLimitColorRed = fadeLimitColor & 0xF800; + fadeLimitColorGreen = fadeLimitColor & 0x07E0; + fadeLimitColorBlue = fadeLimitColor & 0x001F; + if (fadeLimitColorRed) + fadeLimitColor -= 0x0800; + if (fadeLimitColorGreen) + fadeLimitColor -= 0x0040; // -2 because we are using RGB565, sherlock uses RGB555 + if (fadeLimitColorBlue) + fadeLimitColor -= 0x0001; + } + } // Check if we've reached a frame with sound if (frameNumber++ == *soundFrames) { diff --git a/engines/sherlock/animation.h b/engines/sherlock/animation.h index b6e1337975..f3c95d4027 100644 --- a/engines/sherlock/animation.h +++ b/engines/sherlock/animation.h @@ -78,7 +78,7 @@ public: */ bool play(const Common::String &filename, bool intro, int minDelay, int fade, bool setPalette, int speed); - bool play3DO(const Common::String &filename, bool intro, int minDelay, int fade, int speed); + bool play3DO(const Common::String &filename, bool intro, int minDelay, bool fadeFromGrey, int speed); }; } // End of namespace Sherlock diff --git a/engines/sherlock/scalpel/scalpel.cpp b/engines/sherlock/scalpel/scalpel.cpp index 2f802e2efb..9480bb4fc1 100644 --- a/engines/sherlock/scalpel/scalpel.cpp +++ b/engines/sherlock/scalpel/scalpel.cpp @@ -540,9 +540,10 @@ bool ScalpelEngine::show3DOSplash() { if (finished) { // EA logo movie Scalpel3DOMoviePlay("EAlogo.stream", Common::Point(20, 0)); - _screen->clear(); } + // Always clear screen + _screen->clear(); return finished; } @@ -552,13 +553,17 @@ bool ScalpelEngine::showCityCutscene3DO() { // Play intro music _music->playMusic("prolog"); + // Fade screen to grey + _screen->_backBuffer1.fill(0xCE59); // RGB565: 25, 50, 25 (grey) + _screen->fadeIntoScreen3DO(2); + // rain.aiff seems to be playing in an endless loop until // sherlock logo fades away TODO bool finished = _music->waitUntilMSec(3400, 0, 0, 3400); if (finished) - finished = _animation->play3DO("26open1", true, 1, 255, 2); + finished = _animation->play3DO("26open1", true, 1, true, 2); if (finished) { _screen->_backBuffer1.blitFrom(*_screen); // save into backbuffer 1, used for fade @@ -587,7 +592,7 @@ bool ScalpelEngine::showCityCutscene3DO() { } if (finished) - finished = _animation->play3DO("26open2", true, 1, 0, 2); + finished = _animation->play3DO("26open2", true, 1, false, 2); if (finished) { _screen->_backBuffer1.blitFrom(*_screen); // save into backbuffer 1, used for fade @@ -638,7 +643,7 @@ bool ScalpelEngine::showAlleyCutscene3DO() { bool finished = _music->waitUntilMSec(43500, 0, 0, 1000); if (finished) - finished = _animation->play3DO("27PRO1", true, 1, 3, 2); + finished = _animation->play3DO("27PRO1", true, 1, false, 2); if (finished) { // Fade out... @@ -649,7 +654,7 @@ bool ScalpelEngine::showAlleyCutscene3DO() { } if (finished) - finished = _animation->play3DO("27PRO2", true, 1, 0, 2); + finished = _animation->play3DO("27PRO2", true, 1, false, 2); if (finished) finished = _music->waitUntilMSec(76000, 0, 0, 1000); @@ -677,7 +682,7 @@ bool ScalpelEngine::showAlleyCutscene3DO() { } if (finished) - finished = _animation->play3DO("27PRO3", true, 1, 0, 2); + finished = _animation->play3DO("27PRO3", true, 1, false, 2); if (finished) { // Fade out @@ -710,10 +715,10 @@ bool ScalpelEngine::showStreetCutscene3DO() { finished = _music->waitUntilMSec(100300, 0, 0, 1000); } - finished = _animation->play3DO("14KICK", true, 1, 3, 2); + finished = _animation->play3DO("14KICK", true, 1, false, 2); if (finished) - finished = _animation->play3DO("14NOTE", true, 1, 0, 3); + finished = _animation->play3DO("14NOTE", true, 1, false, 3); if (finished) { // Fade out @@ -730,10 +735,10 @@ bool ScalpelEngine::showOfficeCutscene3DO() { finished = _music->waitUntilMSec(151000, 0, 0, 1000); if (finished) - _animation->play3DO("COFF1", true, 1, 3, 3); + _animation->play3DO("COFF1", true, 1, false, 3); if (finished) - finished = _animation->play3DO("COFF2", true, 1, 0, 3); + finished = _animation->play3DO("COFF2", true, 1, false, 3); if (finished) finished = _music->waitUntilMSec(182400, 0, 0, 1000); @@ -761,10 +766,10 @@ bool ScalpelEngine::showOfficeCutscene3DO() { finished = _music->waitUntilMSec(222200, 0, 0, 1000); if (finished) - finished = _animation->play3DO("COFF3", true, 1, 0, 3); + finished = _animation->play3DO("COFF3", true, 1, false, 3); if (finished) - finished = _animation->play3DO("COFF4", true, 1, 0, 3); + finished = _animation->play3DO("COFF4", true, 1, false, 3); return finished; } diff --git a/engines/sherlock/screen.cpp b/engines/sherlock/screen.cpp index de9bf51f46..99e09b4f8b 100644 --- a/engines/sherlock/screen.cpp +++ b/engines/sherlock/screen.cpp @@ -233,7 +233,6 @@ void Screen::verticalTransition() { void Screen::fadeIntoScreen3DO(int speed) { Events &events = *_vm->_events; - Common::Rect changedRect; uint16 *currentScreenBasePtr = (uint16 *)getPixels(); uint16 *targetScreenBasePtr = (uint16 *)_backBuffer->getPixels(); uint16 *currentScreenPtr = NULL; @@ -315,6 +314,49 @@ void Screen::fadeIntoScreen3DO(int speed) { } while ((pixelsChanged) && (!_vm->shouldQuit())); } +void Screen::blitFrom3DOcolorLimit(uint16 limitColor) { + uint16 *currentScreenPtr = (uint16 *)getPixels(); + uint16 *targetScreenPtr = (uint16 *)_backBuffer->getPixels(); + uint16 currentScreenPixel = 0; + + uint16 screenWidth = this->w(); + uint16 screenHeight = this->h(); + uint16 screenX = 0; + uint16 screenY = 0; + + uint16 currentScreenPixelRed = 0; + uint16 currentScreenPixelGreen = 0; + uint16 currentScreenPixelBlue = 0; + + uint16 limitPixelRed = limitColor & 0xF800; + uint16 limitPixelGreen = limitColor & 0x07E0; + uint16 limitPixelBlue = limitColor & 0x001F; + + for (screenY = 0; screenY < screenHeight; screenY++) { + for (screenX = 0; screenX < screenWidth; screenX++) { + currentScreenPixel = *targetScreenPtr; + + currentScreenPixelRed = currentScreenPixel & 0xF800; + currentScreenPixelGreen = currentScreenPixel & 0x07E0; + currentScreenPixelBlue = currentScreenPixel & 0x001F; + + if (currentScreenPixelRed < limitPixelRed) + currentScreenPixelRed = limitPixelRed; + if (currentScreenPixelGreen < limitPixelGreen) + currentScreenPixelGreen = limitPixelGreen; + if (currentScreenPixelBlue < limitPixelBlue) + currentScreenPixelBlue = limitPixelBlue; + + *currentScreenPtr = currentScreenPixelRed | currentScreenPixelGreen | currentScreenPixelBlue; + currentScreenPtr++; + targetScreenPtr++; + } + } + + // Too much considered dirty at the moment + addDirtyRect(Common::Rect(0, 0, screenWidth, screenHeight)); +} + void Screen::restoreBackground(const Common::Rect &r) { if (r.width() > 0 && r.height() > 0) { Common::Rect tempRect = r; diff --git a/engines/sherlock/screen.h b/engines/sherlock/screen.h index e4cc665b5f..661cc483fc 100644 --- a/engines/sherlock/screen.h +++ b/engines/sherlock/screen.h @@ -153,6 +153,8 @@ public: */ void fadeIntoScreen3DO(int speed); + void blitFrom3DOcolorLimit(uint16 color); + /** * Prints the text passed onto the back buffer at the given position and color. * The string is then blitted to the screen diff --git a/engines/sherlock/surface.cpp b/engines/sherlock/surface.cpp index 3bbaf4677e..0f6fa94c67 100644 --- a/engines/sherlock/surface.cpp +++ b/engines/sherlock/surface.cpp @@ -226,6 +226,10 @@ void Surface::fillRect(const Common::Rect &r, byte color) { addDirtyRect(r); } +void Surface::fill(uint16 color) { + _surface.fillRect(Common::Rect(_surface.w, _surface.h), color); +} + bool Surface::clip(Common::Rect &srcBounds, Common::Rect &destBounds) { if (destBounds.left >= _surface.w || destBounds.top >= _surface.h || destBounds.right <= 0 || destBounds.bottom <= 0) diff --git a/engines/sherlock/surface.h b/engines/sherlock/surface.h index 68108a6c16..dc2ba7b1d5 100644 --- a/engines/sherlock/surface.h +++ b/engines/sherlock/surface.h @@ -139,6 +139,8 @@ public: */ void fillRect(const Common::Rect &r, byte color); + void fill(uint16 color); + void maskArea(const ImageFrame &src, const Common::Point &pt, int scrollX); /** -- cgit v1.2.3