[Scummvm-cvs-logs] scummvm master -> 6780c63e538d28c13a5fc1db8c282d00a95bcaaa

dreammaster dreammaster at scummvm.org
Thu Jun 11 02:55:17 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:
6780c63e53 SHERLOCK: Implemented more support methods for RT map


Commit: 6780c63e538d28c13a5fc1db8c282d00a95bcaaa
    https://github.com/scummvm/scummvm/commit/6780c63e538d28c13a5fc1db8c282d00a95bcaaa
Author: Paul Gilbert (dreammaster at scummvm.org)
Date: 2015-06-10T20:54:05-04:00

Commit Message:
SHERLOCK: Implemented more support methods for RT map

Changed paths:
    engines/sherlock/fonts.h
    engines/sherlock/screen.h
    engines/sherlock/surface.h
    engines/sherlock/tattoo/tattoo_map.cpp
    engines/sherlock/tattoo/tattoo_map.h



diff --git a/engines/sherlock/fonts.h b/engines/sherlock/fonts.h
index 50d89f3..0c8c51c 100644
--- a/engines/sherlock/fonts.h
+++ b/engines/sherlock/fonts.h
@@ -82,7 +82,7 @@ public:
 	 */
 	int fontHeight() const { return _fontHeight; }
 
-
+	int fontNumber() const { return _fontNumber; }
 };
 
 } // End of namespace Sherlock
diff --git a/engines/sherlock/screen.h b/engines/sherlock/screen.h
index 9d3ed0c..c660fef 100644
--- a/engines/sherlock/screen.h
+++ b/engines/sherlock/screen.h
@@ -37,6 +37,7 @@ namespace Sherlock {
 #define BG_GREYSCALE_RANGE_END 229
 
 enum {
+	BLACK				= 0,
 	INFO_BLACK			= 1,
 	INFO_FOREGROUND		= 11,
 	INFO_BACKGROUND		= 1,
@@ -52,7 +53,8 @@ enum {
 	BUTTON_BOTTOM		= 248,
 	TALK_FOREGROUND		= 12,
 	TALK_NULL			= 16,
-	PEN_COLOR			= 250
+	PEN_COLOR			= 250,
+	MAP_NAME_COLOR		= 131
 };
 
 class SherlockEngine;
@@ -77,11 +79,6 @@ private:
 	 * Returns the union of two dirty area rectangles
 	 */
 	bool unionRectangle(Common::Rect &destRect, const Common::Rect &src1, const Common::Rect &src2);
-
-	/**
-	 * Draws the given string into the back buffer using the images stored in _font
-	 */
-	virtual void writeString(const Common::String &str, const Common::Point &pt, byte overrideColor);
 protected:
 	/**
 	 * Adds a rectangle to the list of modified areas of the screen during the
@@ -244,13 +241,17 @@ public:
 	 */
 	Common::Rect getDisplayBounds();
 
-	int fontNumber() const { return _fontNumber; }
-
 	/**
 	 * Synchronize the data for a savegame
 	 */
 	void synchronize(Serializer &s);
 
+	/**
+	 * Draws the given string into the back buffer using the images stored in _font
+	 */
+	virtual void writeString(const Common::String &str, const Common::Point &pt, byte overrideColor);
+
+
 	// Rose Tattoo specific methods
 	void initPaletteFade(int bytesToRead);
 
diff --git a/engines/sherlock/surface.h b/engines/sherlock/surface.h
index d42dd5c..49726d5 100644
--- a/engines/sherlock/surface.h
+++ b/engines/sherlock/surface.h
@@ -71,11 +71,6 @@ protected:
 	Graphics::Surface _surface;
 
 	virtual void addDirtyRect(const Common::Rect &r) {}
-
-	/**
-	 * Draws the given string into the back buffer using the images stored in _font
-	 */
-	virtual void writeString(const Common::String &str, const Common::Point &pt, byte overrideColor);
 public:
 	Surface(uint16 width, uint16 height, Common::Platform platform);
 	Surface();
@@ -164,6 +159,11 @@ public:
 	 */
 	void setPixels(byte *pixels, int width, int height);
 
+	/**
+	 * Draws the given string into the back buffer using the images stored in _font
+	 */
+	virtual void writeString(const Common::String &str, const Common::Point &pt, byte overrideColor);
+
 	inline uint16 w() const { return _surface.w; }
 	inline uint16 h() const { return _surface.h; }
 	inline const byte *getPixels() const { return (const byte *)_surface.getPixels(); }
diff --git a/engines/sherlock/tattoo/tattoo_map.cpp b/engines/sherlock/tattoo/tattoo_map.cpp
index 3a02d5b..57c10ca 100644
--- a/engines/sherlock/tattoo/tattoo_map.cpp
+++ b/engines/sherlock/tattoo/tattoo_map.cpp
@@ -35,6 +35,10 @@ void MapEntry::clear() {
 /*-------------------------------------------------------------------------*/
 
 TattooMap::TattooMap(SherlockEngine *vm) : Map(vm) {
+	_iconImages = nullptr;
+	_bgFound = _oldBgFound = 0;
+	_textBuffer = nullptr;
+
 	loadData();
 }
 
@@ -104,6 +108,264 @@ void TattooMap::loadData() {
 	} while (stream->pos() < stream->size());
 }
 
+void TattooMap::drwaMapIcons() {
+	Screen &screen = *_vm->_screen;
+	
+	for (uint idx = 0; idx < _data.size(); ++idx) {
+		if (_data[idx]._iconNum != -1 && _vm->readFlags(idx + 1)) {
+			MapEntry &mapEntry = _data[idx];
+			ImageFrame &img = (*_iconImages)[mapEntry._iconNum];
+			screen._backBuffer1.transBlitFrom(img._frame, Common::Point(mapEntry.x - img._width / 2,
+				mapEntry.y - img._height / 2));
+		}
+	}
+}
+
+void TattooMap::checkMapNames(bool slamIt) {
+	Events &events = *_vm->_events;
+	Screen &screen = *_vm->_screen;
+	Common::Point mousePos = events.mousePos();
+	int dif = 10000;
+
+	// See if the mouse is pointing at any of the map locations
+	_bgFound = -1;
+
+	for (uint idx = 0; idx < _data.size(); ++idx) {
+		if (_data[idx]._iconNum != -1 && _vm->readFlags(idx + 1)) {
+			MapEntry &mapEntry = _data[idx];
+			ImageFrame &img = (*_iconImages)[mapEntry._iconNum];
+			Common::Rect r(mapEntry.x - img._width / 2, mapEntry.y - img._height / 2,
+				mapEntry.x + img._width / 2, mapEntry.y + img._height / 2);
+
+			if (r.contains(mousePos)) {
+				_bgFound = idx;
+				break;
+			}
+		}
+	}
+
+	// Store the previous bounds that were drawn
+	_oldTextBounds = _textBounds;
+
+	// See if thay are pointing at a different location and we need to change the display
+	if (_bgFound != _oldBgFound || (_bgFound != -1 && _textBuffer == nullptr)) {
+		// See if there is a new image to be displayed
+		if (_bgFound != -1 && (_bgFound != _oldBgFound || _textBuffer == nullptr)) {
+			const Common::String &desc = _data[_bgFound]._description;
+			const char *space = nullptr;
+			int width = screen.stringWidth(desc) + 2;
+			int height = 0;
+
+			// See if we need to split it into two lines
+			if (width > 150) {
+				const char *s = desc.c_str();
+
+				for (;;) {
+					// Move to end of next word
+					s = strchr(s, ' ');
+
+					if (s == nullptr) {
+						// Reached end of description
+						if (space == nullptr) {
+							height = screen.stringHeight(desc) + 2;
+						} else {
+							Common::String line1(desc.c_str(), space);
+							Common::String line2(space + 1);
+
+							height = screen.stringHeight(line1) + screen.stringHeight(line2);
+						}
+						break;
+					} else {
+						// Reached space separating words within the description
+						// Get width before and after word
+						int width1 = screen.stringWidth(Common::String(desc.c_str(), s));
+						int width2 = screen.stringWidth(Common::String(s + 1));
+
+						if (ABS(width1 - width2) < dif) {
+							space = s;
+							dif = ABS(width1 - width2);
+							width = MAX(width1, width) + 2;
+						}
+
+						++s;
+					}
+				}
+			} else {
+				height = screen.stringHeight(desc) + 2;
+			}
+
+			// Delete any previous saved area
+			delete _textBuffer;
+
+			// Allocate a new surface
+			_textBuffer = new Surface(width, height, _vm->getPlatform());
+
+			_textBuffer->fillRect(Common::Rect(0, 0, width, height), 255);
+			if (space == nullptr) {
+				// The whole text can be drawn on a single line
+				_textBuffer->writeString(desc, Common::Point(0, 0), BLACK);
+				_textBuffer->writeString(desc, Common::Point(1, 0), BLACK);
+				_textBuffer->writeString(desc, Common::Point(2, 0), BLACK);
+				_textBuffer->writeString(desc, Common::Point(0, 1), BLACK);
+				_textBuffer->writeString(desc, Common::Point(2, 1), BLACK);
+				_textBuffer->writeString(desc, Common::Point(0, 2), BLACK);
+				_textBuffer->writeString(desc, Common::Point(1, 2), BLACK);
+				_textBuffer->writeString(desc, Common::Point(2, 2), BLACK);
+				_textBuffer->writeString(desc, Common::Point(1, 1), MAP_NAME_COLOR);
+			} else {
+				// The text needs to be split up over two lines
+				Common::String line1(desc.c_str(), space);
+				Common::String line2(space + 1);
+				int xp, yp;
+
+				// Draw the first line
+				xp = (width - screen.stringWidth(desc)) / 2;
+				_textBuffer->writeString(line1, Common::Point(xp + 0, 0), BLACK);
+				_textBuffer->writeString(line1, Common::Point(xp + 1, 0), BLACK);
+				_textBuffer->writeString(line1, Common::Point(xp + 2, 0), BLACK);
+				_textBuffer->writeString(line1, Common::Point(xp + 0, 1), BLACK);
+				_textBuffer->writeString(line1, Common::Point(xp + 2, 1), BLACK);
+				_textBuffer->writeString(line1, Common::Point(xp + 0, 2), BLACK);
+				_textBuffer->writeString(line1, Common::Point(xp + 1, 2), BLACK);
+				_textBuffer->writeString(line1, Common::Point(xp + 2, 2), BLACK);
+				_textBuffer->writeString(line1, Common::Point(xp + 1, 1), MAP_NAME_COLOR);
+
+				yp = screen.stringHeight(line2);
+				xp = (width - screen.stringWidth(line2)) / 2;
+				_textBuffer->writeString(line2, Common::Point(xp + 0, 0), BLACK);
+				_textBuffer->writeString(line2, Common::Point(xp + 1, 0), BLACK);
+				_textBuffer->writeString(line2, Common::Point(xp + 2, 0), BLACK);
+				_textBuffer->writeString(line2, Common::Point(xp + 0, 1), BLACK);
+				_textBuffer->writeString(line2, Common::Point(xp + 2, 1), BLACK);
+				_textBuffer->writeString(line2, Common::Point(xp + 0, 2), BLACK);
+				_textBuffer->writeString(line2, Common::Point(xp + 1, 2), BLACK);
+				_textBuffer->writeString(line2, Common::Point(xp + 2, 2), BLACK);
+				_textBuffer->writeString(line2, Common::Point(xp + 1, 1), MAP_NAME_COLOR);
+			}
+
+			// Set the position of the Text Tag
+			// TODO: take current scroll into account
+			int xp = (mousePos.x - width / 2);
+			int yp = (mousePos.y - height / 2);
+
+			_textBounds = Common::Rect(xp, yp, xp + width, yp + height);
+		} else if (_bgFound == -1 && _oldBgFound != -1) {
+			// We need to clear a currently displayed name
+			delete _textBuffer;
+		}
+	
+		_oldBgFound = _bgFound;
+	} else {
+		// Set the new text position
+		// TODO: take current scroll into account
+		int xp = (mousePos.x - _textBounds.width() / 2);
+		int yp = (mousePos.y - _textBounds.height() / 2);
+
+		_textBounds.moveTo(xp, yp);
+	}
+
+	// If the text tag was displayed, restore the graphics underneath it
+	if (_oldTextBounds.width() > 0)
+		screen._backBuffer1.blitFrom(screen._backBuffer2, Common::Point(_oldTextBounds.left, _oldTextBounds.top), _oldTextBounds);
+
+	// See if we need to draw a Text Tag floating with the cursor
+	if (_textBuffer != nullptr)
+		screen.transBlitFrom(*_textBuffer, Common::Point(_textBounds.left, _textBounds.top));
+
+	// See if we need to flush the areas associated with the text
+	if (_oldTextBounds.width() > 0) {
+		if (slamIt)
+			// TODO: Take into account scroll
+			screen.slamRect(_oldTextBounds);
+
+		// If there's no text to display, reset the tag and old tag bounds
+		if (_textBuffer == nullptr) {
+			_textBounds.left = _textBounds.top = _textBounds.right = _textBounds.bottom = 0;
+			_oldTextBounds.left = _oldTextBounds.top = _oldTextBounds.right = _oldTextBounds.bottom = 0;
+		}
+	}
+
+	// If there's a text to display, then copy the drawn area to the screen
+	if (_textBuffer != nullptr && slamIt)
+		// TODO: Handle scroll
+		screen.slamRect(_textBounds);
+}
+
+void TattooMap::restoreArea(const Common::Rect &bounds) {
+	Screen &screen = *_vm->_screen;
+
+	Common::Rect r = bounds;
+	r.clip(Common::Rect(0, 0, screen._backBuffer1.w(), screen._backBuffer1.h()));
+
+	if (!r.isEmpty())
+		screen._backBuffer1.blitFrom(screen._backBuffer2, Common::Point(r.left, r.top), r);
+}
+
+void TattooMap::showCloseUp(int closeUpNum) {
+	Screen &screen = *_vm->_screen;
+
+	// Get the closeup images
+	Common::String fname = Common::String::format("res%02d.vgs", closeUpNum + 1);
+	ImageFile pic(fname);
+
+	Common::Point closeUp(_data[closeUpNum].x * 100, _data[closeUpNum].y * 100);
+	Common::Point delta((SHERLOCK_SCREEN_WIDTH / 2 - closeUp.x / 100) * 100 / CLOSEUP_STEPS,
+		(SHERLOCK_SCREEN_HEIGHT / 2 - closeUp.y / 100) * 100 / CLOSEUP_STEPS);
+	Common::Rect oldBounds(closeUp.x / 100, closeUp.y / 100, closeUp.x / 100 + 1, closeUp.y / 100 + 1);
+	int size = 64;
+	int n = 256;
+	int deltaVal = 512;
+	bool minimize = false;
+	int scaleVal, newSize;
+
+	do
+	{
+		scaleVal = n;
+		newSize = pic[0].sDrawXSize(n);
+
+		if (newSize > size) {
+			if (minimize)
+				deltaVal /= 2;
+			n += deltaVal;
+		} else {
+			minimize = true;
+			deltaVal /= 2;
+			n -= deltaVal;
+			if (n < 1)
+				n = 1;
+		}
+	} while (deltaVal && size != newSize);
+
+	int deltaScale = (SCALE_THRESHOLD - scaleVal) / CLOSEUP_STEPS;
+
+	for (int step = 0; step < CLOSEUP_STEPS; ++step) {
+		Common::Point picSize(pic[0].sDrawXSize(scaleVal), pic[0].sDrawYSize(scaleVal));
+		Common::Point pt(closeUp.x / 100 - picSize.x, closeUp.y / 100 - picSize.y);
+
+		restoreArea(oldBounds);
+		screen._backBuffer1.transBlitFrom(pic[0], pt, false, 0, scaleVal);
+
+		// TODO: handle scrolling
+		screen.slamRect(_oldTextBounds);
+		screen.slamArea(pt.x, pt.y, picSize.x, picSize.y);
+
+		oldBounds = Common::Rect(pt.x, pt.y, pt.x + picSize.x + 1, pt.y + picSize.y + 1);
+		closeUp += delta;
+		scaleVal += deltaScale;
+	}
+
+	// Handle final drawing of closeup
+	// TODO: Handle scrolling
+	Common::Rect r(SHERLOCK_SCREEN_WIDTH / 2 - pic[0]._width / 2, SHERLOCK_SCREEN_HEIGHT / 2 - pic[0]._height / 2,
+		SHERLOCK_SCREEN_WIDTH / 2 + pic[0]._width / 2 + pic[0]._width,
+		SHERLOCK_SCREEN_HEIGHT / 2 + pic[0]._height / 2 + pic[0]._height);
+
+	restoreArea(oldBounds);
+	screen._backBuffer1.transBlitFrom(pic[0], Common::Point(r.left, r.top));
+	screen.slamRect(oldBounds);
+	screen.slamRect(r);
+}
+
 } // End of namespace Tattoo
 
 } // End of namespace Sherlock
diff --git a/engines/sherlock/tattoo/tattoo_map.h b/engines/sherlock/tattoo/tattoo_map.h
index b0c1a3f..079aa46 100644
--- a/engines/sherlock/tattoo/tattoo_map.h
+++ b/engines/sherlock/tattoo/tattoo_map.h
@@ -25,6 +25,8 @@
 
 #include "common/scummsys.h"
 #include "sherlock/map.h"
+#include "sherlock/resources.h"
+#include "sherlock/surface.h"
 
 namespace Sherlock {
 
@@ -32,6 +34,8 @@ class SherlockEngine;
 
 namespace Tattoo {
 
+#define CLOSEUP_STEPS 30
+
 struct MapEntry : Common::Point {
 	int _iconNum;
 	Common::String _description;
@@ -44,11 +48,35 @@ struct MapEntry : Common::Point {
 class TattooMap : public Map {
 private:
 	Common::Array<MapEntry> _data;
+	ImageFile *_iconImages;
+	int _bgFound, _oldBgFound;
+	Surface *_textBuffer;
+	Common::Rect _textBounds, _oldTextBounds;
 	
 	/**
 	 * Load data  needed for the map
 	 */
 	void loadData();
+
+	/**
+	 * Draws all available location icons onto the back buffer
+	 */
+	void drwaMapIcons();
+
+	/**
+	 * Draws the location names of whatever the mouse moves over on the map
+	 */
+	void checkMapNames(bool slamIt);
+
+	/**
+	 * Restores an area of the map background
+	 */
+	void restoreArea(const Common::Rect &bounds);
+
+	/**
+	 * This will load a specified close up and zoom it up to the middle of the screen
+	 */
+	void showCloseUp(int closeUpNum);
 public:
 	TattooMap(SherlockEngine *vm);
 	virtual ~TattooMap() {}






More information about the Scummvm-git-logs mailing list