[Scummvm-cvs-logs] SF.net SVN: scummvm:[45562] scummvm/trunk/engines/sci

m_kiewitz at users.sourceforge.net m_kiewitz at users.sourceforge.net
Sat Oct 31 15:38:26 CET 2009


Revision: 45562
          http://scummvm.svn.sourceforge.net/scummvm/?rev=45562&view=rev
Author:   m_kiewitz
Date:     2009-10-31 14:38:25 +0000 (Sat, 31 Oct 2009)

Log Message:
-----------
SCI/newgui: UpscaledHires implemented including undithering support, cleanup

Modified Paths:
--------------
    scummvm/trunk/engines/sci/gui/gui_cursor.cpp
    scummvm/trunk/engines/sci/gui/gui_cursor.h
    scummvm/trunk/engines/sci/gui/gui_screen.cpp
    scummvm/trunk/engines/sci/gui/gui_screen.h
    scummvm/trunk/engines/sci/sci.cpp
    scummvm/trunk/engines/sci/sci.h

Modified: scummvm/trunk/engines/sci/gui/gui_cursor.cpp
===================================================================
--- scummvm/trunk/engines/sci/gui/gui_cursor.cpp	2009-10-31 13:43:46 UTC (rev 45561)
+++ scummvm/trunk/engines/sci/gui/gui_cursor.cpp	2009-10-31 14:38:25 UTC (rev 45562)
@@ -39,8 +39,9 @@
 SciGuiCursor::SciGuiCursor(ResourceManager *resMan, SciGuiPalette *palette, SciGuiScreen *screen)
 	: _resMan(resMan), _palette(palette), _screen(screen) {
 
-	setPosition(Common::Point(160, 150));
-	setMoveZone(Common::Rect(0, 0, _screen->_displayWidth, _screen->_displayHeight));
+	_upscaledHires = _screen->getUpscaledHires();
+	setPosition(Common::Point(160, 150));		// TODO: how is that different in 640x400 games?
+	setMoveZone(Common::Rect(0, 0, 320, 200));	// TODO: hires games
 }
 
 SciGuiCursor::~SciGuiCursor() {
@@ -157,24 +158,21 @@
 }
 
 void SciGuiCursor::setPosition(Common::Point pos) {
-	int scaleFactor = _screen->getScaleFactor();
-
-	if (scaleFactor == 1)
+	if (!_upscaledHires) {
 		g_system->warpMouse(pos.x, pos.y);
-	else
-		g_system->warpMouse(pos.x * scaleFactor, pos.y * scaleFactor);
+	} else {
+		g_system->warpMouse(pos.x * 2, pos.y * 2);
+	}
 }
 
 Common::Point SciGuiCursor::getPosition() {
-	int scaleFactor = _screen->getScaleFactor();
-	Common::Point pos = g_system->getEventManager()->getMousePos();
-
-	if (scaleFactor != 1) {
-		pos.x /= scaleFactor;
-		pos.y /= scaleFactor;
+	if (!_upscaledHires) {
+		return g_system->getEventManager()->getMousePos();
+	} else {
+		Common::Point mousePos = g_system->getEventManager()->getMousePos();
+		mousePos.x /= 2; mousePos.y /= 2;
+		return mousePos;
 	}
-
-	return pos;
 }
 
 void SciGuiCursor::refreshPosition() {
@@ -199,7 +197,7 @@
 
 	// FIXME: Do this only when mouse is grabbed?
 	if (clipped)
-		setPosition(mousePoint);
+		g_system->warpMouse(mousePoint.x, mousePoint.y);
 }
 
 } // End of namespace Sci

Modified: scummvm/trunk/engines/sci/gui/gui_cursor.h
===================================================================
--- scummvm/trunk/engines/sci/gui/gui_cursor.h	2009-10-31 13:43:46 UTC (rev 45561)
+++ scummvm/trunk/engines/sci/gui/gui_cursor.h	2009-10-31 14:38:25 UTC (rev 45562)
@@ -69,6 +69,8 @@
 	SciGuiScreen *_screen;
 	SciGuiPalette *_palette;
 
+	bool _upscaledHires;
+
 	Common::Rect _moveZone; // Rectangle in which the pointer can move
 
 	CursorCache _cachedCursors;

Modified: scummvm/trunk/engines/sci/gui/gui_screen.cpp
===================================================================
--- scummvm/trunk/engines/sci/gui/gui_screen.cpp	2009-10-31 13:43:46 UTC (rev 45561)
+++ scummvm/trunk/engines/sci/gui/gui_screen.cpp	2009-10-31 14:38:25 UTC (rev 45562)
@@ -33,16 +33,17 @@
 
 namespace Sci {
 
-SciGuiScreen::SciGuiScreen(ResourceManager *resMan, int16 width, int16 height, int16 scaleFactor) : 
-	_resMan(resMan), _width(width), _height(height), _scaleFactor(scaleFactor) {
+SciGuiScreen::SciGuiScreen(ResourceManager *resMan, int16 width, int16 height, bool upscaledHires) : 
+	_resMan(resMan), _width(width), _height(height), _upscaledHires(upscaledHires) {
 
 	_pixels = _width * _height;
 
-	if (scaleFactor != 1 && scaleFactor != 2)
-		error("Only scaling factors of 1 or 2 are supported");
-
-	_displayWidth = _width * scaleFactor;
-	_displayHeight = _height * scaleFactor;
+	_displayWidth = _width;
+	_displayHeight = _height;
+	if (_upscaledHires) {
+		_displayWidth *= 2;
+		_displayHeight *= 2;
+	}
 	_displayPixels = _displayWidth * _displayHeight;
 
 	_visualScreen = (byte *)calloc(_pixels, 1);
@@ -90,11 +91,19 @@
 }
 
 void SciGuiScreen::copyRectToScreen(const Common::Rect &rect) {
-	g_system->copyRectToScreen(_activeScreen + rect.top * _displayWidth + rect.left, _displayWidth, rect.left, rect.top, rect.width(), rect.height());
+	if (!_upscaledHires)  {
+		g_system->copyRectToScreen(_activeScreen + rect.top * _displayWidth + rect.left, _displayWidth, rect.left, rect.top, rect.width(), rect.height());
+	} else {
+		g_system->copyRectToScreen(_activeScreen + rect.top * 2 * _displayWidth + rect.left * 2, _displayWidth, rect.left * 2, rect.top * 2, rect.width() * 2, rect.height() * 2);
+	}
 }
 
 void SciGuiScreen::copyRectToScreen(const Common::Rect &rect, int16 x, int16 y) {
-	g_system->copyRectToScreen(_activeScreen + rect.top * _displayWidth + rect.left, _displayWidth, x, y, rect.width(), rect.height());
+	if (!_upscaledHires)  {
+		g_system->copyRectToScreen(_activeScreen + rect.top * _displayWidth + rect.left, _displayWidth, x, y, rect.width(), rect.height());
+	} else {
+		g_system->copyRectToScreen(_activeScreen + rect.top * 2 * _displayWidth + rect.left * 2, _displayWidth, x * 2, y * 2, rect.width() * 2, rect.height() * 2);
+	}
 }
 
 byte SciGuiScreen::getDrawingMask(byte color, byte prio, byte control) {
@@ -108,26 +117,20 @@
 	return flag;
 }
 
-Common::Rect SciGuiScreen::getScaledRect(Common::Rect rect) {
-	return Common::Rect(
-		rect.left * _scaleFactor, rect.top * _scaleFactor, 
-		rect.left * _scaleFactor + rect.width() * _scaleFactor,
-		rect.top * _scaleFactor + rect.height() * _scaleFactor);
-}
-
 void SciGuiScreen::putPixel(int x, int y, byte drawMask, byte color, byte priority, byte control) {
 	int offset = y * _width + x;
+	int displayOffset;
 
 	if (drawMask & SCI_SCREEN_MASK_VISUAL) {
 		_visualScreen[offset] = color;
-
-		if (_scaleFactor == 1) {
+		if (!_upscaledHires) {
 			_displayScreen[offset] = color;
 		} else {
-			_displayScreen[y * _displayWidth * 2 + x * 2] = color;				// the actual pixel
-			_displayScreen[(y + 1) * _displayWidth * 2 + x * 2] = color;		// one pixel down
-			_displayScreen[y * _displayWidth * 2 + (x * 2) + 1] = color;		// one pixel right
-			_displayScreen[(y + 1) * _displayWidth * 2 + (x * 2) + 1] = color;	// one pixel down and right
+			displayOffset = y * 2 * _displayWidth + x * 2;
+			_displayScreen[displayOffset] = color;
+			_displayScreen[displayOffset + 1] = color;
+			_displayScreen[displayOffset + _displayWidth] = color;
+			_displayScreen[displayOffset + _displayWidth + 1] = color;
 		}
 	}
 	if (drawMask & SCI_SCREEN_MASK_PRIORITY)
@@ -136,6 +139,13 @@
 		_controlScreen[offset] = control;
 }
 
+// This will just change a pixel directly on displayscreen. Its supposed to get only used on upscaled-Hires games where
+//  hires content needs to get drawn ONTO the upscaled display screen (like japanese fonts, hires portraits, etc.)
+void SciGuiScreen::putPixelOnDisplay(int x, int y, byte color) {
+	int offset = y * _width + x;
+	_displayScreen[offset] = color;
+}
+
 // Sierra's Bresenham line drawing
 // WARNING: Do not just blindly replace this with Graphics::drawLine(), as it seems to create issues with flood fill
 void SciGuiScreen::drawLine(Common::Point startPoint, Common::Point endPoint, byte color, byte priority, byte control) {
@@ -228,11 +238,13 @@
 int SciGuiScreen::bitsGetDataSize(Common::Rect rect, byte mask) {
 	int byteCount = sizeof(rect) + sizeof(mask);
 	int pixels = rect.width() * rect.height();
-	Common::Rect scaledRect = getScaledRect(rect);
-	int scaledPixels = scaledRect.width() * scaledRect.height();
 	if (mask & SCI_SCREEN_MASK_VISUAL) {
 		byteCount += pixels; // _visualScreen
-		byteCount += scaledPixels; // _displayScreen
+		if (!_upscaledHires) {
+			byteCount += pixels; // _displayScreen
+		} else {
+			byteCount += pixels * 4; // _displayScreen (upscaled hires)
+		}
 	}
 	if (mask & SCI_SCREEN_MASK_PRIORITY) {
 		byteCount += pixels; // _priorityScreen
@@ -250,7 +262,7 @@
 
 	if (mask & SCI_SCREEN_MASK_VISUAL) {
 		bitsSaveScreen(rect, _visualScreen, memoryPtr);
-		bitsSaveScreen(getScaledRect(rect), _displayScreen, memoryPtr);
+		bitsSaveDisplayScreen(rect, memoryPtr);
 	}
 	if (mask & SCI_SCREEN_MASK_PRIORITY) {
 		bitsSaveScreen(rect, _priorityScreen, memoryPtr);
@@ -272,6 +284,25 @@
 	}
 }
 
+void SciGuiScreen::bitsSaveDisplayScreen(Common::Rect rect, byte *&memoryPtr) {
+	byte *screen = _displayScreen;
+	int width = rect.width();
+	int y;
+
+	if (!_upscaledHires) {
+		screen += (rect.top * _displayWidth) + rect.left;
+	} else {
+		screen += (rect.top * 2 * _displayWidth) + rect.left * 2;
+		width *= 2;
+		rect.top *= 2; rect.bottom *= 2;
+	}
+
+	for (y = rect.top; y < rect.bottom; y++) {
+		memcpy(memoryPtr, (void*)screen, width); memoryPtr += width;
+		screen += _displayWidth;
+	}
+}
+
 void SciGuiScreen::bitsGetRect(byte *memoryPtr, Common::Rect *destRect) {
 	memcpy((void *)destRect, memoryPtr, sizeof(Common::Rect));
 }
@@ -285,7 +316,7 @@
 
 	if (mask & SCI_SCREEN_MASK_VISUAL) {
 		bitsRestoreScreen(rect, memoryPtr, _visualScreen);
-		bitsRestoreScreen(getScaledRect(rect), memoryPtr, _displayScreen);
+		bitsRestoreDisplayScreen(rect, memoryPtr);
 	}
 	if (mask & SCI_SCREEN_MASK_PRIORITY) {
 		bitsRestoreScreen(rect, memoryPtr, _priorityScreen);
@@ -307,6 +338,25 @@
 	}
 }
 
+void SciGuiScreen::bitsRestoreDisplayScreen(Common::Rect rect, byte *&memoryPtr) {
+	byte *screen = _displayScreen;
+	int width = rect.width();
+	int y;
+
+	if (!_upscaledHires) {
+		screen += (rect.top * _displayWidth) + rect.left;
+	} else {
+		screen += (rect.top * 2 * _displayWidth) + rect.left * 2;
+		width *= 2;
+		rect.top *= 2; rect.bottom *= 2;
+	}
+
+	for (y = rect.top; y < rect.bottom; y++) {
+		memcpy((void*) screen, memoryPtr, width); memoryPtr += width;
+		screen += _displayWidth;
+	}
+}
+
 void SciGuiScreen::setPalette(GuiPalette*pal) {
 	// just copy palette to system
 	byte bpal[4 * 256];
@@ -324,28 +374,40 @@
 }
 
 void SciGuiScreen::setVerticalShakePos(uint16 shakePos) {
-	g_system->setShakePos(shakePos);
+	if (!_upscaledHires)
+		g_system->setShakePos(shakePos);
+	else
+		g_system->setShakePos(shakePos * 2);
 }
 
-// Currently not really done, its supposed to be possible to only dither _visualScreen
 void SciGuiScreen::dither(bool addToFlag) {
 	int y, x;
-	byte color;
-	byte *screenPtr = _visualScreen;
+	byte color, ditheredColor;
+	byte *visualPtr = _visualScreen;
 	byte *displayPtr = _displayScreen;
 
 	if (!_unditherState) {
 		// Do dithering on visual and display-screen
 		for (y = 0; y < _height; y++) {
 			for (x = 0; x < _width; x++) {
-				color = *screenPtr;
+				color = *visualPtr;
 				if (color & 0xF0) {
 					color ^= color << 4;
 					color = ((x^y) & 1) ? color >> 4 : color & 0x0F;
-					*screenPtr = color; *displayPtr = color;
+					*displayPtr = color;
+					if (_upscaledHires) {
+						*(displayPtr + 1) = color;
+						*(displayPtr + _displayWidth) = color;
+						*(displayPtr + _displayWidth + 1) = color;
+					}
+					*visualPtr = color;
 				}
-				screenPtr++; displayPtr++;
+				visualPtr++; displayPtr++;
+				if (_upscaledHires)
+					displayPtr++;
 			}
+			if (_upscaledHires)
+				displayPtr += _displayWidth;
 		}
 	} else {
 		if (!addToFlag)
@@ -353,7 +415,7 @@
 		// Do dithering on visual screen and put decoded but undithered byte onto display-screen
 		for (y = 0; y < _height; y++) {
 			for (x = 0; x < _width; x++) {
-				color = *screenPtr;
+				color = *visualPtr;
 				if (color & 0xF0) {
 					color ^= color << 4;
 					// remember dither combination for cel-undithering
@@ -361,15 +423,25 @@
 					// if decoded color wants do dither with black on left side, we turn it around
 					//  otherwise the normal ega color would get used for display
 					if (color & 0xF0) {
-						*displayPtr = color;
+						ditheredColor = color;
 					}	else {
-						*displayPtr = color << 4;
+						ditheredColor = color << 4;
 					}
+					*displayPtr = ditheredColor;
+					if (_upscaledHires) {
+						*(displayPtr + 1) = ditheredColor;
+						*(displayPtr + _displayWidth) = ditheredColor;
+						*(displayPtr + _displayWidth + 1) = ditheredColor;
+					}
 					color = ((x^y) & 1) ? color >> 4 : color & 0x0F;
-					*screenPtr = color;
+					*visualPtr = color;
 				}
-				screenPtr++; displayPtr++;
+				visualPtr++; displayPtr++;
+				if (_upscaledHires)
+					displayPtr++;
 			}
+			if (_upscaledHires)
+				displayPtr += _displayWidth;
 		}
 	}
 }
@@ -386,6 +458,10 @@
 }
 
 void SciGuiScreen::debugShowMap(int mapNo) {
+	// We cannot really support changing maps when in upscaledHires mode
+	if (_upscaledHires)
+		return;
+
 	switch (mapNo) {
 	case 0:
 		_activeScreen = _visualScreen;

Modified: scummvm/trunk/engines/sci/gui/gui_screen.h
===================================================================
--- scummvm/trunk/engines/sci/gui/gui_screen.h	2009-10-31 13:43:46 UTC (rev 45561)
+++ scummvm/trunk/engines/sci/gui/gui_screen.h	2009-10-31 14:38:25 UTC (rev 45562)
@@ -42,7 +42,7 @@
 
 class SciGuiScreen {
 public:
-	SciGuiScreen(ResourceManager *resMan, int16 width = 320, int16 height = 200, int16 scaleFactor = 1);
+	SciGuiScreen(ResourceManager *resMan, int16 width = 320, int16 height = 200, bool upscaledHires = false);
 	~SciGuiScreen();
 
 	void copyToScreen();
@@ -52,10 +52,14 @@
 
 	byte getDrawingMask(byte color, byte prio, byte control);
 	void putPixel(int x, int y, byte drawMask, byte color, byte prio, byte control);
+	void putPixelOnDisplay(int x, int y, byte color);
 	void drawLine(Common::Point startPoint, Common::Point endPoint, byte color, byte prio, byte control);
 	void drawLine(int16 left, int16 top, int16 right, int16 bottom, byte color, byte prio, byte control) {
 		drawLine(Common::Point(left, top), Common::Point(right, bottom), color, prio, control);
 	}
+	bool getUpscaledHires() {
+		return _upscaledHires;
+	}
 	byte getVisual(int x, int y);
 	byte getPriority(int x, int y);
 	byte getControl(int x, int y);
@@ -76,8 +80,6 @@
 
 	void debugShowMap(int mapNo);
 
-	int getScaleFactor() { return _scaleFactor; }
-
 	uint16 _width;
 	uint16 _height;
 	uint _pixels;
@@ -92,7 +94,9 @@
 
 private:
 	void bitsRestoreScreen(Common::Rect rect, byte *&memoryPtr, byte *screen);
+	void bitsRestoreDisplayScreen(Common::Rect rect, byte *&memoryPtr);
 	void bitsSaveScreen(Common::Rect rect, byte *screen, byte *&memoryPtr);
+	void bitsSaveDisplayScreen(Common::Rect rect, byte *&memoryPtr);
 
 	bool _unditherState;
 	int16 _unditherMemorial[SCI_SCREEN_UNDITHERMEMORIAL_SIZE];
@@ -114,7 +118,7 @@
 
 	// this is a pointer to the currently active screen (changing it only required for debug purposes)
 	byte *_activeScreen;
-	int _scaleFactor;
+	bool _upscaledHires;
 };
 
 } // End of namespace Sci

Modified: scummvm/trunk/engines/sci/sci.cpp
===================================================================
--- scummvm/trunk/engines/sci/sci.cpp	2009-10-31 13:43:46 UTC (rev 45561)
+++ scummvm/trunk/engines/sci/sci.cpp	2009-10-31 14:38:25 UTC (rev 45562)
@@ -105,14 +105,17 @@
 		return Common::kNoGameDataFoundError;
 	}
 
-	int scaleFactor = 1;
+	bool upscaledHires = false;
 
 	// Scale the screen, if needed
 	if (!strcmp(getGameID(), "kq6") && getPlatform() == Common::kPlatformWindows)
-		scaleFactor = 2;
+		upscaledHires = true;
 
+	// TODO: Detect japanese editions and set upscaledHires on those as well
+	// TODO: Possibly look at first picture resource and determine if its hires or not
+
 	// Initialize graphics-related parts
-	SciGuiScreen *screen = new SciGuiScreen(_resMan, 320, 200, scaleFactor);	// invokes initGraphics()
+	SciGuiScreen *screen = new SciGuiScreen(_resMan, 320, 200, upscaledHires);	// invokes initGraphics()
 	SciGuiPalette *palette = new SciGuiPalette(_resMan, screen);
 	SciGuiCursor *cursor = new SciGuiCursor(_resMan, palette, screen);
 
@@ -130,8 +133,8 @@
 
 #ifdef INCLUDE_OLDGFX
 	// Gui change
-	//_gamestate->_gui = new SciGui(_gamestate, screen, palette, cursor);    // new
-	_gamestate->_gui = new SciGui32(_gamestate, screen, palette, cursor);  // old
+	_gamestate->_gui = new SciGui(_gamestate, screen, palette, cursor);    // new
+	//_gamestate->_gui = new SciGui32(_gamestate, screen, palette, cursor);  // old
 #else
 	_gamestate->_gui = new SciGui(_gamestate, screen, palette, cursor);
 #endif

Modified: scummvm/trunk/engines/sci/sci.h
===================================================================
--- scummvm/trunk/engines/sci/sci.h	2009-10-31 13:43:46 UTC (rev 45561)
+++ scummvm/trunk/engines/sci/sci.h	2009-10-31 14:38:25 UTC (rev 45562)
@@ -31,7 +31,7 @@
 
 namespace Sci {
 
-#define INCLUDE_OLDGFX
+//#define INCLUDE_OLDGFX
 
 class Console;
 struct EngineState;


This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.




More information about the Scummvm-git-logs mailing list