diff options
Diffstat (limited to 'engines')
-rw-r--r-- | engines/sherlock/animation.cpp | 3 | ||||
-rw-r--r-- | engines/sherlock/events.cpp | 8 | ||||
-rw-r--r-- | engines/sherlock/scalpel/scalpel.cpp | 76 | ||||
-rw-r--r-- | engines/sherlock/scalpel/scalpel_screen.cpp | 204 | ||||
-rw-r--r-- | engines/sherlock/scalpel/scalpel_screen.h | 40 | ||||
-rw-r--r-- | engines/sherlock/scene.cpp | 3 | ||||
-rw-r--r-- | engines/sherlock/screen.cpp | 136 | ||||
-rw-r--r-- | engines/sherlock/screen.h | 14 | ||||
-rw-r--r-- | engines/sherlock/surface.cpp | 18 | ||||
-rw-r--r-- | engines/sherlock/surface.h | 26 |
10 files changed, 331 insertions, 197 deletions
diff --git a/engines/sherlock/animation.cpp b/engines/sherlock/animation.cpp index bbf7c913b7..468d61a7b2 100644 --- a/engines/sherlock/animation.cpp +++ b/engines/sherlock/animation.cpp @@ -22,6 +22,7 @@ #include "sherlock/animation.h" #include "sherlock/sherlock.h" +#include "sherlock/scalpel/scalpel_screen.h" #include "common/algorithm.h" namespace Sherlock { @@ -212,7 +213,7 @@ bool Animation::play3DO(const Common::String &filename, bool intro, int minDelay if (fadeActive) { // process fading - screen.blitFrom3DOcolorLimit(fadeLimitColor); + static_cast<Scalpel::Scalpel3DOScreen *>(_vm->_screen)->blitFrom3DOcolorLimit(fadeLimitColor); if (!fadeLimitColor) { // we are at the end, so stop diff --git a/engines/sherlock/events.cpp b/engines/sherlock/events.cpp index e4fe3fb6d6..89d7de98f5 100644 --- a/engines/sherlock/events.cpp +++ b/engines/sherlock/events.cpp @@ -176,6 +176,8 @@ void Events::pollEvents() { Common::Event event; while (g_system->getEventManager()->pollEvent(event)) { _mousePos = event.mouse; + if (IS_3DO) + _mousePos = Common::Point(_mousePos.x / 2, _mousePos.y / 2); // Handle events switch (event.type) { @@ -219,7 +221,11 @@ void Events::pollEventsAndWait() { } void Events::warpMouse(const Common::Point &pt) { - _mousePos = pt - _vm->_screen->_currentScroll; + Common::Point pos = pt; + if (IS_3DO) + pos = Common::Point(pt.x / 2, pt.y); + + _mousePos = pos - _vm->_screen->_currentScroll; g_system->warpMouse(_mousePos.x, _mousePos.y); } diff --git a/engines/sherlock/scalpel/scalpel.cpp b/engines/sherlock/scalpel/scalpel.cpp index aef9dfd4f2..7b64ca379b 100644 --- a/engines/sherlock/scalpel/scalpel.cpp +++ b/engines/sherlock/scalpel/scalpel.cpp @@ -28,6 +28,7 @@ #include "sherlock/scalpel/scalpel_map.h" #include "sherlock/scalpel/scalpel_people.h" #include "sherlock/scalpel/scalpel_scene.h" +#include "sherlock/scalpel/scalpel_screen.h" #include "sherlock/scalpel/tsage/logo.h" #include "sherlock/sherlock.h" #include "sherlock/music.h" @@ -251,8 +252,8 @@ void ScalpelEngine::initialize() { if (getPlatform() == Common::kPlatform3DO) { const Graphics::PixelFormat pixelFormatRGB565 = Graphics::PixelFormat(2, 5, 6, 5, 0, 11, 5, 0, 0); - // 320x200 16-bit RGB565 for 3DO support - initGraphics(320, 200, false, &pixelFormatRGB565); + // 16-bit RGB565 for 3DO support + initGraphics(640, 400, true, &pixelFormatRGB565); } else { // 320x200 palettized initGraphics(320, 200, false); @@ -668,9 +669,10 @@ bool ScalpelEngine::show3DOSplash() { } bool ScalpelEngine::showCityCutscene3DO() { + Scalpel3DOScreen &screen = *(Scalpel3DOScreen *)_screen; _animation->_soundLibraryFilename = "TITLE.SND"; - _screen->clear(); + screen.clear(); bool finished = _events->delay(2500, true); // rain.aiff seems to be playing in an endless loop until @@ -683,8 +685,8 @@ bool ScalpelEngine::showCityCutscene3DO() { _music->loadSong("prolog"); // Fade screen to grey - _screen->_backBuffer1.fill(0xCE59); // RGB565: 25, 50, 25 (grey) - _screen->fadeIntoScreen3DO(2); + screen._backBuffer1.fill(0xCE59); // RGB565: 25, 50, 25 (grey) + screen.fadeIntoScreen3DO(2); } if (finished) { @@ -692,27 +694,27 @@ bool ScalpelEngine::showCityCutscene3DO() { } if (finished) { - _screen->_backBuffer1.fill(0); // fill backbuffer with black to avoid issues during fade from white + screen._backBuffer1.fill(0); // fill backbuffer with black to avoid issues during fade from white finished = _animation->play3DO("26open1", true, 1, true, 2); } if (finished) { - _screen->_backBuffer1.blitFrom(*_screen); // save into backbuffer 1, used for fade - _screen->_backBuffer2.blitFrom(*_screen); // save into backbuffer 2, for restoring later + screen._backBuffer1.blitFrom(*_screen); // save into backbuffer 1, used for fade + screen._backBuffer2.blitFrom(*_screen); // save into backbuffer 2, for restoring later // "London, England" ImageFile3DO titleImage_London("title2a.cel", kImageFile3DOType_Cel); - _screen->_backBuffer1.transBlitFrom(titleImage_London[0]._frame, Common::Point(30, 50)); + screen._backBuffer1.transBlitFrom(titleImage_London[0]._frame, Common::Point(30, 50)); - _screen->fadeIntoScreen3DO(1); + screen.fadeIntoScreen3DO(1); finished = _events->delay(1500, true); if (finished) { // "November, 1888" ImageFile3DO titleImage_November("title2b.cel", kImageFile3DOType_Cel); - _screen->_backBuffer1.transBlitFrom(titleImage_November[0]._frame, Common::Point(100, 100)); + screen._backBuffer1.transBlitFrom(titleImage_November[0]._frame, Common::Point(100, 100)); - _screen->fadeIntoScreen3DO(1); + screen.fadeIntoScreen3DO(1); finished = _music->waitUntilMSec(14700, 0, 0, 5000); } @@ -726,21 +728,21 @@ bool ScalpelEngine::showCityCutscene3DO() { finished = _animation->play3DO("26open2", true, 1, false, 2); if (finished) { - _screen->_backBuffer1.blitFrom(*_screen); // save into backbuffer 1, used for fade + screen._backBuffer1.blitFrom(screen); // save into backbuffer 1, used for fade // "Sherlock Holmes" (title) ImageFile3DO titleImage_SherlockHolmesTitle("title1ab.cel", kImageFile3DOType_Cel); - _screen->_backBuffer1.transBlitFrom(titleImage_SherlockHolmesTitle[0]._frame, Common::Point(34, 5)); + screen._backBuffer1.transBlitFrom(titleImage_SherlockHolmesTitle[0]._frame, Common::Point(34, 5)); // Blend in - _screen->fadeIntoScreen3DO(2); + screen.fadeIntoScreen3DO(2); finished = _events->delay(500, true); // Title should fade in, Copyright should be displayed a bit after that if (finished) { ImageFile3DO titleImage_Copyright("title1c.cel", kImageFile3DOType_Cel); - _screen->transBlitFrom(titleImage_Copyright[0]._frame, Common::Point(20, 190)); + screen.transBlitFrom(titleImage_Copyright[0]._frame, Common::Point(20, 190)); finished = _events->delay(3500, true); } } @@ -750,27 +752,28 @@ bool ScalpelEngine::showCityCutscene3DO() { if (finished) { // Fade to black - _screen->_backBuffer1.clear(); - _screen->fadeIntoScreen3DO(3); + screen._backBuffer1.clear(); + screen.fadeIntoScreen3DO(3); } if (finished) { // "In the alley behind the Regency Theatre..." ImageFile3DO titleImage_InTheAlley("title1d.cel", kImageFile3DOType_Cel); - _screen->_backBuffer1.transBlitFrom(titleImage_InTheAlley[0]._frame, Common::Point(72, 51)); + screen._backBuffer1.transBlitFrom(titleImage_InTheAlley[0]._frame, Common::Point(72, 51)); // Fade in - _screen->fadeIntoScreen3DO(4); + screen.fadeIntoScreen3DO(4); finished = _music->waitUntilMSec(39900, 0, 0, 2500); // Fade out - _screen->_backBuffer1.clear(); - _screen->fadeIntoScreen3DO(4); + screen._backBuffer1.clear(); + screen.fadeIntoScreen3DO(4); } return finished; } bool ScalpelEngine::showAlleyCutscene3DO() { + Scalpel3DOScreen &screen = *(Scalpel3DOScreen *)_screen; bool finished = _music->waitUntilMSec(43500, 0, 0, 1000); if (finished) @@ -778,8 +781,8 @@ bool ScalpelEngine::showAlleyCutscene3DO() { if (finished) { // Fade out... - _screen->_backBuffer1.clear(); - _screen->fadeIntoScreen3DO(3); + screen._backBuffer1.clear(); + screen.fadeIntoScreen3DO(3); finished = _music->waitUntilMSec(67100, 0, 0, 1000); // 66700 } @@ -794,8 +797,8 @@ bool ScalpelEngine::showAlleyCutscene3DO() { // Show screaming victim ImageFile3DO titleImage_ScreamingVictim("scream.cel", kImageFile3DOType_Cel); - _screen->clear(); - _screen->transBlitFrom(titleImage_ScreamingVictim[0]._frame, Common::Point(0, 0)); + screen.clear(); + screen.transBlitFrom(titleImage_ScreamingVictim[0]._frame, Common::Point(0, 0)); // Play "scream.aiff" if (_sound->_voices) @@ -806,8 +809,8 @@ bool ScalpelEngine::showAlleyCutscene3DO() { if (finished) { // Fade out - _screen->_backBuffer1.clear(); - _screen->fadeIntoScreen3DO(5); + screen._backBuffer1.clear(); + screen.fadeIntoScreen3DO(5); finished = _music->waitUntilMSec(84400, 0, 0, 2000); } @@ -817,17 +820,17 @@ bool ScalpelEngine::showAlleyCutscene3DO() { if (finished) { // Fade out - _screen->_backBuffer1.clear(); - _screen->fadeIntoScreen3DO(5); + screen._backBuffer1.clear(); + screen.fadeIntoScreen3DO(5); } if (finished) { // "Early the following morning on Baker Street..." ImageFile3DO titleImage_EarlyTheFollowingMorning("title3.cel", kImageFile3DOType_Cel); - _screen->_backBuffer1.transBlitFrom(titleImage_EarlyTheFollowingMorning[0]._frame, Common::Point(35, 51)); + screen._backBuffer1.transBlitFrom(titleImage_EarlyTheFollowingMorning[0]._frame, Common::Point(35, 51)); // Fade in - _screen->fadeIntoScreen3DO(4); + screen.fadeIntoScreen3DO(4); finished = _music->waitUntilMSec(96700, 0, 0, 3000); } @@ -835,12 +838,13 @@ bool ScalpelEngine::showAlleyCutscene3DO() { } bool ScalpelEngine::showStreetCutscene3DO() { + Scalpel3DOScreen &screen = *(Scalpel3DOScreen *)_screen; bool finished = true; if (finished) { // fade out "Early the following morning..." - _screen->_backBuffer1.clear(); - _screen->fadeIntoScreen3DO(4); + screen._backBuffer1.clear(); + screen.fadeIntoScreen3DO(4); // wait for music a bit finished = _music->waitUntilMSec(100300, 0, 0, 1000); @@ -859,8 +863,8 @@ bool ScalpelEngine::showStreetCutscene3DO() { if (finished) { // Fade out - _screen->_backBuffer1.clear(); - _screen->fadeIntoScreen3DO(4); + screen._backBuffer1.clear(); + screen.fadeIntoScreen3DO(4); } return finished; diff --git a/engines/sherlock/scalpel/scalpel_screen.cpp b/engines/sherlock/scalpel/scalpel_screen.cpp index 44113b2a5d..df1a9d4306 100644 --- a/engines/sherlock/scalpel/scalpel_screen.cpp +++ b/engines/sherlock/scalpel/scalpel_screen.cpp @@ -88,6 +88,210 @@ void ScalpelScreen::makeField(const Common::Rect &r) { _backBuffer->vLine(r.right - 1, r.top + 1, r.bottom - 2, BUTTON_TOP); } +/*----------------------------------------------------------------*/ + +void Scalpel3DOScreen::blitFrom(const Graphics::Surface &src, const Common::Point &pt, const Common::Rect &srcBounds) { + Common::Rect srcRect = srcBounds; + Common::Rect destRect(pt.x, pt.y, pt.x + srcRect.width(), pt.y + srcRect.height()); + + if (!srcRect.isValidRect() || !clip(srcRect, destRect)) + return; + + // Add dirty area remapped to the 640x200 surface + addDirtyRect(Common::Rect(destRect.left * 2, destRect.top * 2, destRect.right * 2, destRect.bottom * 2)); + + // Transfer the area, doubling each pixel + for (int yp = 0; yp < srcRect.height(); ++yp) { + const uint16 *srcP = (const uint16 *)src.getBasePtr(srcRect.left, srcRect.top + yp); + uint16 *destP = (uint16 *)getBasePtr(destRect.left * 2, (destRect.top + yp) * 2); + + for (int xp = srcRect.left; xp < srcRect.right; ++xp, ++srcP, destP += 2) { + *destP = *srcP; + *(destP + 1) = *srcP; + *(destP + 640) = *srcP; + *(destP + 640 + 1) = *srcP; + } + } +} + +void Scalpel3DOScreen::transBlitFromUnscaled(const Graphics::Surface &src, const Common::Point &pt, + bool flipped, int overrideColor) { + Common::Rect drawRect(0, 0, src.w, src.h); + Common::Rect destRect(pt.x, pt.y, pt.x + src.w, pt.y + src.h); + + // Clip the display area to on-screen + if (!clip(drawRect, destRect)) + // It's completely off-screen + return; + + if (flipped) + drawRect = Common::Rect(src.w - drawRect.right, src.h - drawRect.bottom, + src.w - drawRect.left, src.h - drawRect.top); + + Common::Point destPt(destRect.left, destRect.top); + addDirtyRect(Common::Rect(destPt.x * 2, destPt.y * 2, (destPt.x + drawRect.width()) * 2, + (destPt.y + drawRect.height()) * 2)); + + assert(src.format.bytesPerPixel == 2 && _surface.format.bytesPerPixel == 2); + + for (int yp = 0; yp < drawRect.height(); ++yp) { + const uint16 *srcP = (const uint16 *)src.getBasePtr( + flipped ? drawRect.right - 1 : drawRect.left, drawRect.top + yp); + uint16 *destP = (uint16 *)getBasePtr(destPt.x * 2, (destPt.y + yp) * 2); + + for (int xp = 0; xp < drawRect.width(); ++xp, destP += 2) { + // RGB 0, 0, 0 -> transparent on 3DO + if (*srcP) { + *destP = *srcP; + *(destP + 1) = *srcP; + *(destP + 640) = *srcP; + *(destP + 640 + 1) = *srcP; + } + + srcP = flipped ? srcP - 1 : srcP + 1; + } + } +} + +void Scalpel3DOScreen::fillRect(const Common::Rect &r, uint color) { + Screen::fillRect(Common::Rect(r.left * 2, r.top * 2, r.right * 2, r.bottom * 2), color); +} + +void Scalpel3DOScreen::fadeIntoScreen3DO(int speed) { + Events &events = *_vm->_events; + uint16 *currentScreenBasePtr = (uint16 *)getPixels(); + uint16 *targetScreenBasePtr = (uint16 *)_backBuffer->getPixels(); + uint16 currentScreenPixel = 0; + uint16 targetScreenPixel = 0; + + uint16 currentScreenPixelRed = 0; + uint16 currentScreenPixelGreen = 0; + uint16 currentScreenPixelBlue = 0; + + uint16 targetScreenPixelRed = 0; + uint16 targetScreenPixelGreen = 0; + uint16 targetScreenPixelBlue = 0; + + uint16 screenWidth = SHERLOCK_SCREEN_WIDTH; + uint16 screenHeight = SHERLOCK_SCREEN_HEIGHT; + uint16 screenX = 0; + uint16 screenY = 0; + uint16 pixelsChanged = 0; + + clearDirtyRects(); + + do { + pixelsChanged = 0; + uint16 *currentScreenPtr = currentScreenBasePtr; + uint16 *targetScreenPtr = targetScreenBasePtr; + + for (screenY = 0; screenY < screenHeight; screenY++, currentScreenPtr += 640) { + for (screenX = 0; screenX < screenWidth; screenX++) { + currentScreenPixel = *currentScreenPtr; + targetScreenPixel = *targetScreenPtr; + + if (currentScreenPixel != targetScreenPixel) { + // pixel doesn't match, adjust accordingly + currentScreenPixelRed = currentScreenPixel & 0xF800; + currentScreenPixelGreen = currentScreenPixel & 0x07E0; + currentScreenPixelBlue = currentScreenPixel & 0x001F; + targetScreenPixelRed = targetScreenPixel & 0xF800; + targetScreenPixelGreen = targetScreenPixel & 0x07E0; + targetScreenPixelBlue = targetScreenPixel & 0x001F; + + if (currentScreenPixelRed != targetScreenPixelRed) { + if (currentScreenPixelRed < targetScreenPixelRed) { + currentScreenPixelRed += 0x0800; + } else { + currentScreenPixelRed -= 0x0800; + } + } + if (currentScreenPixelGreen != targetScreenPixelGreen) { + // Adjust +2/-2 because we are running RGB555 at RGB565 + if (currentScreenPixelGreen < targetScreenPixelGreen) { + currentScreenPixelGreen += 0x0040; + } else { + currentScreenPixelGreen -= 0x0040; + } + } + if (currentScreenPixelBlue != targetScreenPixelBlue) { + if (currentScreenPixelBlue < targetScreenPixelBlue) { + currentScreenPixelBlue += 0x0001; + } else { + currentScreenPixelBlue -= 0x0001; + } + } + + uint16 v = currentScreenPixelRed | currentScreenPixelGreen | currentScreenPixelBlue; + *currentScreenPtr = v; + *(currentScreenPtr + 1) = v; + *(currentScreenPtr + 640) = v; + *(currentScreenPtr + 640 + 1) = v; + + pixelsChanged++; + } + + currentScreenPtr += 2; + targetScreenPtr++; + } + } + + // Too much considered dirty at the moment + addDirtyRect(Common::Rect(0, 0, screenWidth * 2, screenHeight * 2)); + + events.pollEvents(); + events.delay(10 * speed); + } while ((pixelsChanged) && (!_vm->shouldQuit())); +} + +void Scalpel3DOScreen::blitFrom3DOcolorLimit(uint16 limitColor) { + uint16 *currentScreenPtr = (uint16 *)getPixels(); + uint16 *targetScreenPtr = (uint16 *)_backBuffer->getPixels(); + uint16 currentScreenPixel = 0; + + uint16 screenWidth = SHERLOCK_SCREEN_WIDTH; + uint16 screenHeight = SHERLOCK_SCREEN_HEIGHT; + 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++, currentScreenPtr += 640) { + 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; + + uint16 v = currentScreenPixelRed | currentScreenPixelGreen | currentScreenPixelBlue; + *currentScreenPtr = v; + *(currentScreenPtr + 1) = v; + *(currentScreenPtr + 640) = v; + *(currentScreenPtr + 640 + 1) = v; + + currentScreenPtr += 2; + targetScreenPtr++; + } + } + + // Too much considered dirty at the moment + addDirtyRect(Common::Rect(0, 0, screenWidth * 2, screenHeight * 2)); +} + } // End of namespace Scalpel } // End of namespace Sherlock diff --git a/engines/sherlock/scalpel/scalpel_screen.h b/engines/sherlock/scalpel/scalpel_screen.h index 0277bcd16f..b1be1210e0 100644 --- a/engines/sherlock/scalpel/scalpel_screen.h +++ b/engines/sherlock/scalpel/scalpel_screen.h @@ -59,6 +59,46 @@ public: void makeField(const Common::Rect &r); }; +class Scalpel3DOScreen : public ScalpelScreen { +protected: + /** + * Draws a sub-section of a surface at a given position within this surface + * Overriden for the 3DO to automatically double the size of everything to the underlying 640x400 surface + */ + virtual void blitFrom(const Graphics::Surface &src, const Common::Point &pt, const Common::Rect &srcBounds); + + /** + * Draws a surface at a given position within this surface with transparency + */ + virtual void transBlitFromUnscaled(const Graphics::Surface &src, const Common::Point &pt, bool flipped, + int overrideColor); +public: + Scalpel3DOScreen(SherlockEngine *vm) : ScalpelScreen(vm) {} + virtual ~Scalpel3DOScreen() {} + + /** + * Draws a sub-section of a surface at a given position within this surface + */ + void rawBlitFrom(const Graphics::Surface &src, const Common::Point &pt, const Common::Rect &srcBounds) { + ScalpelScreen::blitFrom(src, pt, srcBounds); + } + + /** + * Fade backbuffer 1 into screen (3DO RGB!) + */ + void fadeIntoScreen3DO(int speed); + + void blitFrom3DOcolorLimit(uint16 color); + + /** + * Fill a given area of the surface with a given color + */ + virtual void fillRect(const Common::Rect &r, uint color); + + inline virtual uint16 w() const { return _surface.w / 2; } + inline virtual uint16 h() const { return _surface.h / 2; } +}; + } // End of namespace Scalpel } // End of namespace Sherlock diff --git a/engines/sherlock/scene.cpp b/engines/sherlock/scene.cpp index 4e40032df9..d3f5ade0b1 100644 --- a/engines/sherlock/scene.cpp +++ b/engines/sherlock/scene.cpp @@ -26,6 +26,7 @@ #include "sherlock/scalpel/scalpel.h" #include "sherlock/scalpel/scalpel_people.h" #include "sherlock/scalpel/scalpel_scene.h" +#include "sherlock/scalpel/scalpel_screen.h" #include "sherlock/tattoo/tattoo.h" #include "sherlock/tattoo/tattoo_scene.h" #include "sherlock/tattoo/tattoo_user_interface.h" @@ -1282,7 +1283,7 @@ void Scene::transitionToScene() { } else { // fade in for 3DO screen.clear(); - screen.fadeIntoScreen3DO(3); + static_cast<Scalpel::Scalpel3DOScreen *>(_vm->_screen)->fadeIntoScreen3DO(3); } } else { screen.slamArea(screen._currentScroll.x, screen._currentScroll.y, SHERLOCK_SCREEN_WIDTH, SHERLOCK_SCREEN_HEIGHT); diff --git a/engines/sherlock/screen.cpp b/engines/sherlock/screen.cpp index a5241524ef..208487d0ca 100644 --- a/engines/sherlock/screen.cpp +++ b/engines/sherlock/screen.cpp @@ -30,15 +30,17 @@ namespace Sherlock { Screen *Screen::init(SherlockEngine *vm) { - if (vm->getGameID() == GType_SerratedScalpel) - return new Scalpel::ScalpelScreen(vm); - else + if (vm->getGameID() == GType_RoseTattoo) return new Screen(vm); + else if (vm->getPlatform() == Common::kPlatform3DO) + return new Scalpel::Scalpel3DOScreen(vm); + else + return new Scalpel::ScalpelScreen(vm); } Screen::Screen(SherlockEngine *vm) : Surface(g_system->getWidth(), g_system->getHeight()), _vm(vm), - _backBuffer1(g_system->getWidth(), g_system->getHeight()), - _backBuffer2(g_system->getWidth(), g_system->getHeight()), + _backBuffer1(vm->getGameID() == GType_RoseTattoo ? 640 : 320, vm->getGameID() == GType_RoseTattoo ? 480 : 200), + _backBuffer2(vm->getGameID() == GType_RoseTattoo ? 640 : 320, vm->getGameID() == GType_RoseTattoo ? 480 : 200), _backBuffer(&_backBuffer1) { _transitionSeed = 1; _fadeStyle = false; @@ -219,130 +221,6 @@ void Screen::verticalTransition() { } } -void Screen::fadeIntoScreen3DO(int speed) { - Events &events = *_vm->_events; - uint16 *currentScreenBasePtr = (uint16 *)getPixels(); - uint16 *targetScreenBasePtr = (uint16 *)_backBuffer->getPixels(); - uint16 currentScreenPixel = 0; - uint16 targetScreenPixel = 0; - - uint16 currentScreenPixelRed = 0; - uint16 currentScreenPixelGreen = 0; - uint16 currentScreenPixelBlue = 0; - - uint16 targetScreenPixelRed = 0; - uint16 targetScreenPixelGreen = 0; - uint16 targetScreenPixelBlue = 0; - - uint16 screenWidth = this->w(); - uint16 screenHeight = this->h(); - uint16 screenX = 0; - uint16 screenY = 0; - uint16 pixelsChanged = 0; - - _dirtyRects.clear(); - - do { - pixelsChanged = 0; - uint16 *currentScreenPtr = currentScreenBasePtr; - uint16 *targetScreenPtr = targetScreenBasePtr; - - for (screenY = 0; screenY < screenHeight; screenY++) { - for (screenX = 0; screenX < screenWidth; screenX++) { - currentScreenPixel = *currentScreenPtr; - targetScreenPixel = *targetScreenPtr; - - if (currentScreenPixel != targetScreenPixel) { - // pixel doesn't match, adjust accordingly - currentScreenPixelRed = currentScreenPixel & 0xF800; - currentScreenPixelGreen = currentScreenPixel & 0x07E0; - currentScreenPixelBlue = currentScreenPixel & 0x001F; - targetScreenPixelRed = targetScreenPixel & 0xF800; - targetScreenPixelGreen = targetScreenPixel & 0x07E0; - targetScreenPixelBlue = targetScreenPixel & 0x001F; - - if (currentScreenPixelRed != targetScreenPixelRed) { - if (currentScreenPixelRed < targetScreenPixelRed) { - currentScreenPixelRed += 0x0800; - } else { - currentScreenPixelRed -= 0x0800; - } - } - if (currentScreenPixelGreen != targetScreenPixelGreen) { - // Adjust +2/-2 because we are running RGB555 at RGB565 - if (currentScreenPixelGreen < targetScreenPixelGreen) { - currentScreenPixelGreen += 0x0040; - } else { - currentScreenPixelGreen -= 0x0040; - } - } - if (currentScreenPixelBlue != targetScreenPixelBlue) { - if (currentScreenPixelBlue < targetScreenPixelBlue) { - currentScreenPixelBlue += 0x0001; - } else { - currentScreenPixelBlue -= 0x0001; - } - } - *currentScreenPtr = currentScreenPixelRed | currentScreenPixelGreen | currentScreenPixelBlue; - pixelsChanged++; - } - - currentScreenPtr++; - targetScreenPtr++; - } - } - - // Too much considered dirty at the moment - addDirtyRect(Common::Rect(0, 0, screenWidth, screenHeight)); - - events.pollEvents(); - events.delay(10 * 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) _backBuffer1.blitFrom(_backBuffer2, Common::Point(r.left, r.top), r); diff --git a/engines/sherlock/screen.h b/engines/sherlock/screen.h index 43e6ea883f..04a0c1e505 100644 --- a/engines/sherlock/screen.h +++ b/engines/sherlock/screen.h @@ -62,6 +62,11 @@ protected: SherlockEngine *_vm; /** + * Clear the current dirty rects list + */ + void clearDirtyRects() { _dirtyRects.clear(); } + + /** * Adds a rectangle to the list of modified areas of the screen during the * current frame */ @@ -86,7 +91,7 @@ public: void update(); /** - * Makes the whole screen dirty, Hack for 3DO movie playing + * Makes the whole screen dirty */ void makeAllDirty(); @@ -126,13 +131,6 @@ public: void verticalTransition(); /** - * Fade backbuffer 1 into screen (3DO RGB!) - */ - 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 2090a334a1..d7d5cd95e8 100644 --- a/engines/sherlock/surface.cpp +++ b/engines/sherlock/surface.cpp @@ -211,23 +211,23 @@ void Surface::fillRect(const Common::Rect &r, uint color) { } void Surface::fill(uint color) { - _surface.fillRect(Common::Rect(_surface.w, _surface.h), color); + 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 || + if (destBounds.left >= w() || destBounds.top >= h() || destBounds.right <= 0 || destBounds.bottom <= 0) return false; // Clip the bounds if necessary to fit on-screen - if (destBounds.right > _surface.w) { - srcBounds.right -= destBounds.right - _surface.w; - destBounds.right = _surface.w; + if (destBounds.right > w()) { + srcBounds.right -= destBounds.right - w(); + destBounds.right = w(); } - if (destBounds.bottom > _surface.h) { - srcBounds.bottom -= destBounds.bottom - _surface.h; - destBounds.bottom = _surface.h; + if (destBounds.bottom > h()) { + srcBounds.bottom -= destBounds.bottom - h(); + destBounds.bottom = h(); } if (destBounds.top < 0) { @@ -244,7 +244,7 @@ bool Surface::clip(Common::Rect &srcBounds, Common::Rect &destBounds) { } void Surface::clear() { - fillRect(Common::Rect(0, 0, _surface.w, _surface.h), 0); + fillRect(Common::Rect(0, 0, w(), h()), 0); } void Surface::free() { diff --git a/engines/sherlock/surface.h b/engines/sherlock/surface.h index 64b57f644a..378c9be9cd 100644 --- a/engines/sherlock/surface.h +++ b/engines/sherlock/surface.h @@ -40,30 +40,32 @@ private: bool _freePixels; /** + * Copy a surface into this one + */ + void blitFrom(const Graphics::Surface &src); +protected: + Graphics::Surface _surface; + + /** * Clips the given source bounds so the passed destBounds will be entirely on-screen */ bool clip(Common::Rect &srcBounds, Common::Rect &destBounds); /** - * Copy a surface into this one + * Base method stub for signalling dirty rect areas */ - void blitFrom(const Graphics::Surface &src); + virtual void addDirtyRect(const Common::Rect &r) {} /** * Draws a sub-section of a surface at a given position within this surface */ - void blitFrom(const Graphics::Surface &src, const Common::Point &pt, const Common::Rect &srcBounds); + virtual void blitFrom(const Graphics::Surface &src, const Common::Point &pt, const Common::Rect &srcBounds); /** * Draws a surface at a given position within this surface with transparency */ - void transBlitFromUnscaled(const Graphics::Surface &src, const Common::Point &pt, bool flipped, + virtual void transBlitFromUnscaled(const Graphics::Surface &src, const Common::Point &pt, bool flipped, int overrideColor); - -protected: - Graphics::Surface _surface; - - virtual void addDirtyRect(const Common::Rect &r) {} public: Surface(uint16 width, uint16 height); Surface(); @@ -138,7 +140,7 @@ public: /** * Fill a given area of the surface with a given color */ - void fillRect(const Common::Rect &r, uint color); + virtual void fillRect(const Common::Rect &r, uint color); void fill(uint color); @@ -168,8 +170,8 @@ public: virtual void writeString(const Common::String &str, const Common::Point &pt, uint overrideColor); void writeFancyString(const Common::String &str, const Common::Point &pt, uint overrideColor1, uint overrideColor2); - inline uint16 w() const { return _surface.w; } - inline uint16 h() const { return _surface.h; } + inline virtual uint16 w() const { return _surface.w; } + inline virtual uint16 h() const { return _surface.h; } inline const byte *getPixels() const { return (const byte *)_surface.getPixels(); } inline byte *getPixels() { return (byte *)_surface.getPixels(); } inline byte *getBasePtr(int x, int y) { return (byte *)_surface.getBasePtr(x, y); } |