[Scummvm-cvs-logs] SF.net SVN: scummvm:[45510] scummvm/trunk/engines/draci

spalek at users.sourceforge.net spalek at users.sourceforge.net
Fri Oct 30 01:52:05 CET 2009


Revision: 45510
          http://scummvm.svn.sourceforge.net/scummvm/?rev=45510&view=rev
Author:   spalek
Date:     2009-10-30 00:52:05 +0000 (Fri, 30 Oct 2009)

Log Message:
-----------
Move WalkingMap into new module.

Also, fix a bug when loading the default walking map (wasn't implemented)
and setting font size.  The reason I move this code into a new module is
because I will augment it with other walking-related algorithms soon.

Modified Paths:
--------------
    scummvm/trunk/engines/draci/game.cpp
    scummvm/trunk/engines/draci/game.h
    scummvm/trunk/engines/draci/module.mk
    scummvm/trunk/engines/draci/script.cpp
    scummvm/trunk/engines/draci/sprite.cpp

Added Paths:
-----------
    scummvm/trunk/engines/draci/walking.cpp
    scummvm/trunk/engines/draci/walking.h

Modified: scummvm/trunk/engines/draci/game.cpp
===================================================================
--- scummvm/trunk/engines/draci/game.cpp	2009-10-29 21:07:24 UTC (rev 45509)
+++ scummvm/trunk/engines/draci/game.cpp	2009-10-30 00:52:05 UTC (rev 45510)
@@ -1044,9 +1044,7 @@
 	// Music will be played by the GPL2 command startMusic when needed.
 	setMusicTrack(roomReader.readByte());
 
-	int mapID = roomReader.readByte() - 1;
-	loadWalkingMap(mapID);
-
+	_currentRoom._mapID = roomReader.readByte() - 1;
 	_currentRoom._palette = roomReader.readByte() - 1;
 	_currentRoom._numOverlays = roomReader.readSint16LE();
 	_currentRoom._init = roomReader.readSint16LE();
@@ -1078,7 +1076,7 @@
 	_currentRoom._numGates = roomReader.readByte();
 
 	debugC(4, kDraciLogicDebugLevel, "Music: %d", getMusicTrack());
-	debugC(4, kDraciLogicDebugLevel, "Map: %d", mapID);
+	debugC(4, kDraciLogicDebugLevel, "Map: %d", _currentRoom._mapID);
 	debugC(4, kDraciLogicDebugLevel, "Palette: %d", _currentRoom._palette);
 	debugC(4, kDraciLogicDebugLevel, "Overlays: %d", _currentRoom._numOverlays);
 	debugC(4, kDraciLogicDebugLevel, "Init: %d", _currentRoom._init);
@@ -1096,13 +1094,14 @@
 	debugC(4, kDraciLogicDebugLevel, "Gates: %d", _currentRoom._numGates);
 
 	// Read in the gates' numbers
-
 	_currentRoom._gates.clear();
-
 	for (uint i = 0; i < _currentRoom._numGates; ++i) {
 		_currentRoom._gates.push_back(roomReader.readSint16LE());
 	}
 
+	// Load the walking map
+	loadWalkingMap(_currentRoom._mapID);
+
 	// Load the room's objects
 	for (uint i = 0; i < _info._numObjects; ++i) {
 		debugC(7, kDraciLogicDebugLevel,
@@ -1258,6 +1257,9 @@
 }
 
 void Game::loadWalkingMap(int mapID) {
+	if (mapID < 0) {
+		mapID = _currentRoom._mapID;
+	}
 	const BAFile *f;
 	f = _vm->_walkingMapsArchive->getFile(mapID);
 	_currentRoom._walkingMap.load(f->_data, f->_length);
@@ -1665,124 +1667,6 @@
 
 }
 
-bool WalkingMap::isWalkable(int x, int y) const {
-	// Convert to map pixels
-	x = x / _deltaX;
-	y = y / _deltaY;
-
-	int pixelIndex = _mapWidth * y + x;
-	int byteIndex = pixelIndex / 8;
-	int mapByte = _data[byteIndex];
-
-	return mapByte & (1 << pixelIndex % 8);
-}
-
-/**
- * @brief For a given point, find a nearest walkable point on the walking map
- *
- * @param startX    x coordinate of the point
- * @param startY    y coordinate of the point
- *
- * @return A Common::Point representing the nearest walkable point
- *
- *  The algorithm was copied from the original engine for exactness.
- *  TODO: Study this algorithm in more detail so it can be documented properly and
- *  possibly improved / simplified.
- */
-Common::Point WalkingMap::findNearestWalkable(int startX, int startY, Common::Rect searchRect) const {
-	// If the starting point is walkable, just return that
-	if (searchRect.contains(startX, startY) && isWalkable(startX, startY)) {
-		return Common::Point(startX, startY);
-	}
-
-	int signs[] = { 1, -1 };
-	const uint kSignsNum = 2;
-
-	int radius = 0;
-	int x, y;
-	int dx, dy;
-	int prediction;
-
-	// The place where, eventually, the result coordinates will be stored
-	int finalX, finalY;
-
-	// The algorithm appears to start off with an ellipse with the minor radius equal to
-	// zero and the major radius equal to the walking map delta (the number of pixels
-	// one map pixel represents). It then uses a heuristic to gradually reshape it into
-	// a circle (by shortening the major radius and lengthening the minor one). At each
-	// such resizing step, it checks some select points on the ellipse for walkability.
-	// It also does the same check for the ellipse perpendicular to it (rotated by 90 degrees).
-
-	while (1) {
-		// The default major radius
-		radius += _deltaX;
-
-		// The ellipse radii (minor, major) that get resized
-		x = 0;
-		y = radius;
-
-		// Heuristic variables
-		prediction = 1 - radius;
-		dx = 3;
-		dy = 2 * radius - 2;
-
-		do {
-			// The following two loops serve the purpose of checking the points on the two
-			// ellipses for walkability. The signs[] array is there to obliterate the need
-			// of writing out all combinations manually.
-
-			for (uint i = 0; i < kSignsNum; ++i) {
-				finalY = startY + y * signs[i];
-
-				for (uint j = 0; j < kSignsNum; ++j) {
-					finalX = startX + x * signs[j];
-
-					// If the current point is walkable, return it
-					if (searchRect.contains(finalX, finalY) && isWalkable(finalX, finalY)) {
-						return Common::Point(finalX, finalY);
-					}
-				}
-			}
-
-			if (x == y) {
-				// If the starting point is walkable, just return that
-				if (searchRect.contains(finalX, finalY) && isWalkable(finalX, finalY)) {
-					return Common::Point(finalX, finalY);
-				}
-			}
-
-			for (uint i = 0; i < kSignsNum; ++i) {
-				finalY = startY + x * signs[i];
-
-				for (uint j = 0; j < kSignsNum; ++j) {
-					finalX = startX + y * signs[j];
-
-					// If the current point is walkable, return it
-					if (searchRect.contains(finalX, finalY) && isWalkable(finalX, finalY)) {
-						return Common::Point(finalX, finalY);
-					}
-				}
-			}
-
-			// If prediction is non-negative, we need to decrease the major radius of the
-			// ellipse
-			if (prediction >= 0) {
-				prediction -= dy;
-				dy -= 2 * _deltaX;
-				y -= _deltaX;
-			}
-
-			// Increase the minor radius of the ellipse and update heuristic variables
-			prediction += dx;
-			dx += 2 * _deltaX;
-			x += _deltaX;
-
-		// If the current ellipse has been reshaped into a circle,
-		// end this loop and enlarge the radius
-		} while (x <= y);
-	}
-}
-
 static double real_to_double(byte real[6]) {
 	// Extract sign bit
 	int sign = real[0] & (1 << 7);

Modified: scummvm/trunk/engines/draci/game.h
===================================================================
--- scummvm/trunk/engines/draci/game.h	2009-10-29 21:07:24 UTC (rev 45509)
+++ scummvm/trunk/engines/draci/game.h	2009-10-30 00:52:05 UTC (rev 45510)
@@ -32,6 +32,7 @@
 #include "draci/script.h"
 #include "draci/animation.h"
 #include "draci/sprite.h"
+#include "draci/walking.h"
 
 namespace Draci {
 
@@ -64,13 +65,7 @@
 	kNoItem = -1
 };
 
-// Used as a default parameter in Game::loadWalkingMap() to specify that the default
-// walking map to the room is to be loaded.
 enum {
-	kDefaultRoomMap = -1
-};
-
-enum {
 	kNoDialogue = -1,
 	kDialogueLines = 4
 };
@@ -104,51 +99,6 @@
   kInventorySlots = kInventoryLines * kInventoryColumns
 };
 
-class WalkingMap {
-public:
-	WalkingMap() {
-		_realWidth = 0;
-		_realHeight = 0;
-		_mapWidth = 0;
-		_mapHeight = 0;
-		_byteWidth = 0;
-		_data = NULL;
-	}
-
-	void load(const byte *data, uint length) {
-		Common::MemoryReadStream mapReader(data, length);
-
-		_realWidth = mapReader.readUint16LE();
-		_realHeight = mapReader.readUint16LE();
-		_deltaX = mapReader.readUint16LE();
-		_deltaY = mapReader.readUint16LE();
-		_mapWidth = mapReader.readUint16LE();
-		_mapHeight = mapReader.readUint16LE();
-		_byteWidth = mapReader.readUint16LE();
-
-		// Set the data pointer to raw map data
-		_data = data + mapReader.pos();
-	}
-
-	bool isWalkable(int x, int y) const;
-	Common::Point findNearestWalkable(int x, int y, Common::Rect searchRect) const;
-
-private:
-	int _realWidth, _realHeight;
-	int _deltaX, _deltaY;
-	int _mapWidth, _mapHeight;
-	int _byteWidth;
-	const byte *_data;
-};
-
-/*
- * Enumerates the directions the dragon can look into when arrived.
- */
-enum SightDirection {
-	kDirectionLast, kDirectionMouse, kDirectionUnknown,
-	kDirectionRight, kDirectionLeft, kDirectionIntelligent
-};
-
 struct GameObject {
 	uint _init, _look, _use, _canUse;
 	bool _imInit, _imLook, _imUse;
@@ -201,6 +151,7 @@
 	int _roomNum;
 	byte _music;
 	WalkingMap _walkingMap;
+	int _mapID;
 	int _palette;
 	int _numOverlays;
 	int _init, _look, _use, _canUse;
@@ -227,18 +178,6 @@
 	kSubstatusStrange
 };
 
-/**
-  * Enumerates the animations for the dragon's movement.
-  */
-enum Movement {
-	kMoveUndefined = -1,
-	kMoveDown, kMoveUp, kMoveRight, kMoveLeft,
-	kMoveRightDown, kMoveRightUp, kMoveLeftDown, kMoveLeftUp,
-	kMoveDownRight, kMoveUpRight, kMoveDownLeft, kMoveUpLeft,
-	kMoveLeftRight, kMoveRightLeft, kMoveUpStopLeft, kMoveUpStopRight,
-	kSpeakRight, kSpeakLeft, kStopRight, kStopLeft
-};
-
 class Game {
 public:
 	Game(DraciEngine *vm);
@@ -281,7 +220,7 @@
 	int loadAnimation(uint animNum, uint z);
 	void loadOverlays();
 	void loadObject(uint numObj);
-	void loadWalkingMap(int mapID = kDefaultRoomMap);
+	void loadWalkingMap(int mapID);
 	void loadItem(int itemID);
 
 	uint getNumObjects() const;

Modified: scummvm/trunk/engines/draci/module.mk
===================================================================
--- scummvm/trunk/engines/draci/module.mk	2009-10-29 21:07:24 UTC (rev 45509)
+++ scummvm/trunk/engines/draci/module.mk	2009-10-30 00:52:05 UTC (rev 45510)
@@ -14,7 +14,8 @@
 	surface.o \
 	mouse.o \
 	game.o \
-	animation.o
+	animation.o \
+	walking.o
  
 MODULE_DIRS += \
 	engines/draci

Modified: scummvm/trunk/engines/draci/script.cpp
===================================================================
--- scummvm/trunk/engines/draci/script.cpp	2009-10-29 21:07:24 UTC (rev 45509)
+++ scummvm/trunk/engines/draci/script.cpp	2009-10-30 00:52:05 UTC (rev 45510)
@@ -728,10 +728,9 @@
 
 	// HACK: Some strings in the English data files are too long to fit the screen
 	// This is a temporary resolution.
+	speechFrame->setFont(_vm->_bigFont);
 	if (speechFrame->getWidth() >= kScreenWidth) {
 		speechFrame->setFont(_vm->_smallFont);
-	} else {
-		speechFrame->setFont(_vm->_bigFont);
 	}
 
 	// Set the loop substatus to an appropriate value
@@ -838,7 +837,7 @@
 
 void Script::roomMap(Common::Queue<int> &params) {
 	// Load the default walking map for the room
-	_vm->_game->loadWalkingMap();
+	_vm->_game->loadWalkingMap(-1);
 }
 
 void Script::disableQuickHero(Common::Queue<int> &params) {

Modified: scummvm/trunk/engines/draci/sprite.cpp
===================================================================
--- scummvm/trunk/engines/draci/sprite.cpp	2009-10-29 21:07:24 UTC (rev 45509)
+++ scummvm/trunk/engines/draci/sprite.cpp	2009-10-30 00:52:05 UTC (rev 45510)
@@ -341,6 +341,9 @@
 }
 
 void Text::setFont(const Font *font) {
+	if (font == _font) {
+		return;
+	}
 	_font = font;
 
 	_width = _font->getStringWidth(_text, _spacing);

Added: scummvm/trunk/engines/draci/walking.cpp
===================================================================
--- scummvm/trunk/engines/draci/walking.cpp	                        (rev 0)
+++ scummvm/trunk/engines/draci/walking.cpp	2009-10-30 00:52:05 UTC (rev 45510)
@@ -0,0 +1,165 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * $URL: https://scummvm.svn.sourceforge.net/svnroot/scummvm/scummvm/trunk/engines/draci/game.cpp $
+ * $Id: game.cpp 45505 2009-10-29 18:15:12Z eriktorbjorn $
+ *
+ */
+
+#include "common/stream.h"
+
+#include "draci/walking.h"
+
+namespace Draci {
+
+void WalkingMap::load(const byte *data, uint length) {
+	Common::MemoryReadStream mapReader(data, length);
+
+	_realWidth = mapReader.readUint16LE();
+	_realHeight = mapReader.readUint16LE();
+	_deltaX = mapReader.readUint16LE();
+	_deltaY = mapReader.readUint16LE();
+	_mapWidth = mapReader.readUint16LE();
+	_mapHeight = mapReader.readUint16LE();
+	_byteWidth = mapReader.readUint16LE();
+
+	// Set the data pointer to raw map data
+	_data = data + mapReader.pos();
+}
+
+bool WalkingMap::isWalkable(int x, int y) const {
+	// Convert to map pixels
+	x = x / _deltaX;
+	y = y / _deltaY;
+
+	int pixelIndex = _mapWidth * y + x;
+	int byteIndex = pixelIndex / 8;
+	int mapByte = _data[byteIndex];
+
+	return mapByte & (1 << pixelIndex % 8);
+}
+
+/**
+ * @brief For a given point, find a nearest walkable point on the walking map
+ *
+ * @param startX    x coordinate of the point
+ * @param startY    y coordinate of the point
+ *
+ * @return A Common::Point representing the nearest walkable point
+ *
+ *  The algorithm was copied from the original engine for exactness.
+ *  TODO: Study this algorithm in more detail so it can be documented properly and
+ *  possibly improved / simplified.
+ */
+Common::Point WalkingMap::findNearestWalkable(int startX, int startY, Common::Rect searchRect) const {
+	// If the starting point is walkable, just return that
+	if (searchRect.contains(startX, startY) && isWalkable(startX, startY)) {
+		return Common::Point(startX, startY);
+	}
+
+	int signs[] = { 1, -1 };
+	const uint kSignsNum = 2;
+
+	int radius = 0;
+	int x, y;
+	int dx, dy;
+	int prediction;
+
+	// The place where, eventually, the result coordinates will be stored
+	int finalX, finalY;
+
+	// The algorithm appears to start off with an ellipse with the minor radius equal to
+	// zero and the major radius equal to the walking map delta (the number of pixels
+	// one map pixel represents). It then uses a heuristic to gradually reshape it into
+	// a circle (by shortening the major radius and lengthening the minor one). At each
+	// such resizing step, it checks some select points on the ellipse for walkability.
+	// It also does the same check for the ellipse perpendicular to it (rotated by 90 degrees).
+
+	while (1) {
+		// The default major radius
+		radius += _deltaX;
+
+		// The ellipse radii (minor, major) that get resized
+		x = 0;
+		y = radius;
+
+		// Heuristic variables
+		prediction = 1 - radius;
+		dx = 3;
+		dy = 2 * radius - 2;
+
+		do {
+			// The following two loops serve the purpose of checking the points on the two
+			// ellipses for walkability. The signs[] array is there to obliterate the need
+			// of writing out all combinations manually.
+
+			for (uint i = 0; i < kSignsNum; ++i) {
+				finalY = startY + y * signs[i];
+
+				for (uint j = 0; j < kSignsNum; ++j) {
+					finalX = startX + x * signs[j];
+
+					// If the current point is walkable, return it
+					if (searchRect.contains(finalX, finalY) && isWalkable(finalX, finalY)) {
+						return Common::Point(finalX, finalY);
+					}
+				}
+			}
+
+			if (x == y) {
+				// If the starting point is walkable, just return that
+				if (searchRect.contains(finalX, finalY) && isWalkable(finalX, finalY)) {
+					return Common::Point(finalX, finalY);
+				}
+			}
+
+			for (uint i = 0; i < kSignsNum; ++i) {
+				finalY = startY + x * signs[i];
+
+				for (uint j = 0; j < kSignsNum; ++j) {
+					finalX = startX + y * signs[j];
+
+					// If the current point is walkable, return it
+					if (searchRect.contains(finalX, finalY) && isWalkable(finalX, finalY)) {
+						return Common::Point(finalX, finalY);
+					}
+				}
+			}
+
+			// If prediction is non-negative, we need to decrease the major radius of the
+			// ellipse
+			if (prediction >= 0) {
+				prediction -= dy;
+				dy -= 2 * _deltaX;
+				y -= _deltaX;
+			}
+
+			// Increase the minor radius of the ellipse and update heuristic variables
+			prediction += dx;
+			dx += 2 * _deltaX;
+			x += _deltaX;
+
+		// If the current ellipse has been reshaped into a circle,
+		// end this loop and enlarge the radius
+		} while (x <= y);
+	}
+}
+
+}


Property changes on: scummvm/trunk/engines/draci/walking.cpp
___________________________________________________________________
Added: svn:mime-type
   + text/plain
Added: svn:eol-style
   + native

Added: scummvm/trunk/engines/draci/walking.h
===================================================================
--- scummvm/trunk/engines/draci/walking.h	                        (rev 0)
+++ scummvm/trunk/engines/draci/walking.h	2009-10-30 00:52:05 UTC (rev 45510)
@@ -0,0 +1,71 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * $URL: https://scummvm.svn.sourceforge.net/svnroot/scummvm/scummvm/trunk/engines/draci/game.h $
+ * $Id: game.h 45501 2009-10-29 15:26:48Z spalek $
+ *
+ */
+
+#ifndef DRACI_WALKING_H
+#define DRACI_WALKING_H
+
+#include "common/rect.h"
+
+namespace Draci {
+
+class WalkingMap {
+public:
+	WalkingMap() : _realWidth(0), _realHeight(0), _mapWidth(0), _mapHeight(0), _byteWidth(0), _data(NULL) { }
+
+	void load(const byte *data, uint length);
+	bool isWalkable(int x, int y) const;
+	Common::Point findNearestWalkable(int x, int y, Common::Rect searchRect) const;
+
+private:
+	int _realWidth, _realHeight;
+	int _deltaX, _deltaY;
+	int _mapWidth, _mapHeight;
+	int _byteWidth;
+	const byte *_data;
+};
+
+/*
+ * Enumerates the directions the dragon can look into when arrived.
+ */
+enum SightDirection {
+	kDirectionLast, kDirectionMouse, kDirectionUnknown,
+	kDirectionRight, kDirectionLeft, kDirectionIntelligent
+};
+
+/**
+  * Enumerates the animations for the dragon's movement.
+  */
+enum Movement {
+	kMoveUndefined = -1,
+	kMoveDown, kMoveUp, kMoveRight, kMoveLeft,
+	kMoveRightDown, kMoveRightUp, kMoveLeftDown, kMoveLeftUp,
+	kMoveDownRight, kMoveUpRight, kMoveDownLeft, kMoveUpLeft,
+	kMoveLeftRight, kMoveRightLeft, kMoveUpStopLeft, kMoveUpStopRight,
+	kSpeakRight, kSpeakLeft, kStopRight, kStopLeft
+};
+
+} // End of namespace Draci
+
+#endif // DRACI_WALKING_H


Property changes on: scummvm/trunk/engines/draci/walking.h
___________________________________________________________________
Added: svn:mime-type
   + text/plain
Added: svn:eol-style
   + native


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