[Scummvm-cvs-logs] scummvm master -> bb01b27777bea9531cae117659d14d3d33f44c8a

dreammaster dreammaster at scummvm.org
Sun Sep 13 18:23:27 CEST 2015


This automated email contains information about 1 new commit which have been
pushed to the 'scummvm' repo located at https://github.com/scummvm/scummvm .

Summary:
bb01b27777 SHERLOCK: 3DO: Implementing high-resolution mode for 3DO version


Commit: bb01b27777bea9531cae117659d14d3d33f44c8a
    https://github.com/scummvm/scummvm/commit/bb01b27777bea9531cae117659d14d3d33f44c8a
Author: Paul Gilbert (dreammaster at scummvm.org)
Date: 2015-09-13T12:22:31-04:00

Commit Message:
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

Changed paths:
    engines/sherlock/animation.cpp
    engines/sherlock/events.cpp
    engines/sherlock/scalpel/scalpel.cpp
    engines/sherlock/scalpel/scalpel_screen.cpp
    engines/sherlock/scalpel/scalpel_screen.h
    engines/sherlock/scene.cpp
    engines/sherlock/screen.cpp
    engines/sherlock/screen.h
    engines/sherlock/surface.cpp
    engines/sherlock/surface.h



diff --git a/engines/sherlock/animation.cpp b/engines/sherlock/animation.cpp
index bbf7c91..468d61a 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 e4fe3fb..89d7de9 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 aef9dfd..7b64ca3 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 44113b2..df1a9d4 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 0277bcd..b1be121 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 4e40032..d3f5ade 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 a524152..208487d 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 43e6ea8..04a0c1e 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 2090a33..d7d5cd9 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 64b57f6..378c9be 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); }






More information about the Scummvm-git-logs mailing list