aboutsummaryrefslogtreecommitdiff
path: root/engines
diff options
context:
space:
mode:
authorPaul Gilbert2015-09-13 12:22:31 -0400
committerPaul Gilbert2015-09-13 12:22:31 -0400
commitbb01b27777bea9531cae117659d14d3d33f44c8a (patch)
tree3e04c6c399b623cd206c38f140ef955c62de7a60 /engines
parentdce5c96cc22ab406e371d7313a26d6d77e25187f (diff)
downloadscummvm-rg350-bb01b27777bea9531cae117659d14d3d33f44c8a.tar.gz
scummvm-rg350-bb01b27777bea9531cae117659d14d3d33f44c8a.tar.bz2
scummvm-rg350-bb01b27777bea9531cae117659d14d3d33f44c8a.zip
SHERLOCK: 3DO: Implementing high-resolution mode for 3DO version
This will allow us to play the portrait movies at full resolution, and better display the fonts, which dont look good at low resolution
Diffstat (limited to 'engines')
-rw-r--r--engines/sherlock/animation.cpp3
-rw-r--r--engines/sherlock/events.cpp8
-rw-r--r--engines/sherlock/scalpel/scalpel.cpp76
-rw-r--r--engines/sherlock/scalpel/scalpel_screen.cpp204
-rw-r--r--engines/sherlock/scalpel/scalpel_screen.h40
-rw-r--r--engines/sherlock/scene.cpp3
-rw-r--r--engines/sherlock/screen.cpp136
-rw-r--r--engines/sherlock/screen.h14
-rw-r--r--engines/sherlock/surface.cpp18
-rw-r--r--engines/sherlock/surface.h26
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); }