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

spalek at users.sourceforge.net spalek at users.sourceforge.net
Sun Nov 1 13:57:07 CET 2009


Revision: 45597
          http://scummvm.svn.sourceforge.net/scummvm/?rev=45597&view=rev
Author:   spalek
Date:     2009-11-01 12:57:06 +0000 (Sun, 01 Nov 2009)

Log Message:
-----------
Debugged computation and displaying of optimal walking paths

Modified Paths:
--------------
    scummvm/trunk/engines/draci/animation.cpp
    scummvm/trunk/engines/draci/animation.h
    scummvm/trunk/engines/draci/draci.cpp
    scummvm/trunk/engines/draci/game.cpp
    scummvm/trunk/engines/draci/game.h
    scummvm/trunk/engines/draci/walking.cpp
    scummvm/trunk/engines/draci/walking.h

Modified: scummvm/trunk/engines/draci/animation.cpp
===================================================================
--- scummvm/trunk/engines/draci/animation.cpp	2009-11-01 10:58:34 UTC (rev 45596)
+++ scummvm/trunk/engines/draci/animation.cpp	2009-11-01 12:57:06 UTC (rev 45597)
@@ -163,6 +163,11 @@
 	_samples.push_back(sample);
 }
 
+void Animation::replaceFrame(int i, Drawable *frame, const SoundSample *sample) {
+	_frames[i] = frame;
+	_samples[i] = sample;
+}
+
 Drawable *Animation::getCurrentFrame() {
 	// If there are no frames stored, return NULL
 	return _frames.size() > 0 ? _frames[_currentFrame] : NULL;

Modified: scummvm/trunk/engines/draci/animation.h
===================================================================
--- scummvm/trunk/engines/draci/animation.h	2009-11-01 10:58:34 UTC (rev 45596)
+++ scummvm/trunk/engines/draci/animation.h	2009-11-01 12:57:06 UTC (rev 45597)
@@ -38,12 +38,14 @@
 enum {
 	kOverlayImage = -1,
 	kWalkingMapOverlay = -2,
-	kTitleText = -3,
-	kSpeechText = -4,
-	kInventorySprite = -5,
-	kDialogueLinesID = -6,
-	kUnused = -10,
-	kInventoryItemsID = -11
+	kWalkingShortestPathOverlay = -3,
+	kWalkingObliquePathOverlay = -4,
+	kTitleText = -5,
+	kSpeechText = -6,
+	kInventorySprite = -7,
+	kDialogueLinesID = -8,
+	kUnused = -12,
+	kInventoryItemsID = -13
 };
 
 /**
@@ -72,6 +74,7 @@
 	void drawFrame(Surface *surface);
 
 	void addFrame(Drawable *frame, const SoundSample *sample);
+	void replaceFrame(int i, Drawable *frame, const SoundSample *sample);
 	Drawable *getCurrentFrame();
 	Drawable *getFrame(int frameNum);
 	void setCurrentFrame(uint frame);

Modified: scummvm/trunk/engines/draci/draci.cpp
===================================================================
--- scummvm/trunk/engines/draci/draci.cpp	2009-11-01 10:58:34 UTC (rev 45596)
+++ scummvm/trunk/engines/draci/draci.cpp	2009-11-01 12:57:06 UTC (rev 45597)
@@ -263,6 +263,15 @@
 			case Common::KEYCODE_w:
 				// Show walking map toggle
 				_showWalkingMap = !_showWalkingMap;
+				if (_showWalkingMap) {
+					_anims->play(kWalkingMapOverlay);
+					_anims->play(kWalkingShortestPathOverlay);
+					_anims->play(kWalkingObliquePathOverlay);
+				} else {
+					_anims->stop(kWalkingMapOverlay);
+					_anims->stop(kWalkingShortestPathOverlay);
+					_anims->stop(kWalkingObliquePathOverlay);
+				}
 				break;
 			case Common::KEYCODE_q:
 				_game->setWantQuickHero(!_game->getWantQuickHero());
@@ -286,15 +295,6 @@
 			_mouse->handleEvent(event);
 		}
 	}
-
-	// Show walking map overlay
-	// If the walking map overlay is already in the wanted state don't
-	// start / stop it constantly
-	if (_showWalkingMap && !_anims->getAnimation(kWalkingMapOverlay)->isPlaying()) {
-		_anims->play(kWalkingMapOverlay);
-	} else if (!_showWalkingMap && _anims->getAnimation(kWalkingMapOverlay)->isPlaying()) {
-		_anims->stop(kWalkingMapOverlay);
-	}
 }
 
 DraciEngine::~DraciEngine() {

Modified: scummvm/trunk/engines/draci/game.cpp
===================================================================
--- scummvm/trunk/engines/draci/game.cpp	2009-11-01 10:58:34 UTC (rev 45596)
+++ scummvm/trunk/engines/draci/game.cpp	2009-11-01 12:57:06 UTC (rev 45597)
@@ -39,6 +39,12 @@
 
 static double real_to_double(byte real[6]);
 
+enum {
+	kWalkingMapOverlayColour = 2,
+	kWalkingShortestPathOverlayColour = 120,
+	kWalkingObliquePathOverlayColour = 73
+};
+
 Game::Game(DraciEngine *vm) : _vm(vm) {
 	uint i;
 
@@ -932,6 +938,14 @@
 	_vm->_anims->play(animID);
 }
 
+void Game::redrawWalkingPath(int id, byte colour, const WalkingMap::Path &path) {
+	Animation *anim = _vm->_anims->getAnimation(id);
+	Sprite *ov = _walkingMap.newOverlayFromPath(path, colour);
+	delete anim->getFrame(0);
+	anim->replaceFrame(0, ov, NULL);
+	anim->markDirtyRect(_vm->_screen->getSurface());
+}
+
 void Game::walkHero(int x, int y, SightDirection dir) {
 	// Needed for the map room with empty walking map.  For some reason,
 	// findNearestWalkable() takes several seconds with 100% CPU to finish
@@ -939,11 +953,20 @@
 	if (!_currentRoom._heroOn)
 		return;
 
+	Common::Point oldHero = _hero;
 	Surface *surface = _vm->_screen->getSurface();
 	_hero = _walkingMap.findNearestWalkable(x, y, surface->getDimensions());
 	debugC(3, kDraciLogicDebugLevel, "Walk to x: %d y: %d", _hero.x, _hero.y);
 	// FIXME: Need to add proper walking (this only warps the dragon to position)
 
+	// Compute the shortest and obliqued path.
+	WalkingMap::Path shortestPath, obliquePath;
+	_walkingMap.findShortestPath(oldHero.x, oldHero.y, _hero.x, _hero.y, &shortestPath);
+	_walkingMap.obliquePath(shortestPath, &obliquePath);
+
+	redrawWalkingPath(kWalkingShortestPathOverlay, kWalkingShortestPathOverlayColour, shortestPath);
+	redrawWalkingPath(kWalkingObliquePathOverlay, kWalkingObliquePathOverlayColour, obliquePath);
+
 	Movement movement = kStopRight;
 	switch (dir) {
 	case kDirectionLeft:
@@ -1060,6 +1083,19 @@
 	// Load the walking map
 	loadWalkingMap(getMapID());
 
+	// Add overlays for the walking map and shortest/obliqued paths.
+	Animation *map = _vm->_anims->addAnimation(kWalkingMapOverlay, 256, _vm->_showWalkingMap);
+	Sprite *ov = _walkingMap.newOverlayFromMap(kWalkingMapOverlayColour);
+	map->addFrame(ov, NULL);
+
+	Animation *sPath = _vm->_anims->addAnimation(kWalkingShortestPathOverlay, 257, _vm->_showWalkingMap);
+	Animation *oPath = _vm->_anims->addAnimation(kWalkingObliquePathOverlay, 258, _vm->_showWalkingMap);
+	WalkingMap::Path emptyPath;
+	ov = _walkingMap.newOverlayFromPath(emptyPath, 0);
+	sPath->addFrame(ov, NULL);
+	ov = _walkingMap.newOverlayFromPath(emptyPath, 0);
+	oPath->addFrame(ov, NULL);
+
 	// Load the room's objects
 	for (uint i = 0; i < _info._numObjects; ++i) {
 		debugC(7, kDraciLogicDebugLevel,
@@ -1095,10 +1131,6 @@
 	// Set room palette
 	f = _vm->_paletteArchive->getFile(_currentRoom._palette);
 	_vm->_screen->setPalette(f->_data, 0, kNumColours);
-
-	Animation *map = _vm->_anims->addAnimation(kWalkingMapOverlay, 255, false);
-	Sprite *ov = _walkingMap.newOverlayFromMap();
-	map->addFrame(ov, NULL);
 }
 
 int Game::loadAnimation(uint animNum, uint z) {
@@ -1284,6 +1316,8 @@
 
 	// Delete walking map testing overlay
 	_vm->_anims->deleteAnimation(kWalkingMapOverlay);
+	_vm->_anims->deleteAnimation(kWalkingShortestPathOverlay);
+	_vm->_anims->deleteAnimation(kWalkingObliquePathOverlay);
 
 	// TODO: Make objects capable of stopping their own animations
 	const GameObject *dragon = getObject(kDragonObject);

Modified: scummvm/trunk/engines/draci/game.h
===================================================================
--- scummvm/trunk/engines/draci/game.h	2009-11-01 10:58:34 UTC (rev 45596)
+++ scummvm/trunk/engines/draci/game.h	2009-11-01 12:57:06 UTC (rev 45597)
@@ -321,6 +321,7 @@
 	void enterNewRoom(bool force_reload);
 	void loadRoom(int roomNum);
 	void runGateProgram(int gate);
+	void redrawWalkingPath(int id, byte colour, const WalkingMap::Path &path);
 
 	DraciEngine *_vm;
 

Modified: scummvm/trunk/engines/draci/walking.cpp
===================================================================
--- scummvm/trunk/engines/draci/walking.cpp	2009-11-01 10:58:34 UTC (rev 45596)
+++ scummvm/trunk/engines/draci/walking.cpp	2009-11-01 12:57:06 UTC (rev 45597)
@@ -57,7 +57,7 @@
 	return getPixel(x / _deltaX, y / _deltaY);
 }
 
-Sprite *WalkingMap::newOverlayFromMap() const {
+Sprite *WalkingMap::newOverlayFromMap(byte colour) const {
 	// HACK: Create a visible overlay from the walking map so we can test it
 	byte *wlk = new byte[_realWidth * _realHeight];
 	memset(wlk, 255, _realWidth * _realHeight);
@@ -65,7 +65,7 @@
 	for (int i = 0; i < _mapWidth; ++i) {
 		for (int j = 0; j < _mapHeight; ++j) {
 			if (getPixel(i, j)) {
-				drawOverlayRectangle(i, j, 2, wlk);
+				drawOverlayRectangle(i, j, colour, wlk);
 			}
 		}
 	}
@@ -274,6 +274,9 @@
 void WalkingMap::obliquePath(const WalkingMap::Path& path, WalkingMap::Path *obliquedPath) const {
 	// Prune the path to only contain vertices where the direction is changing.
 	obliquedPath->clear();
+	if (path.empty()) {
+		return;
+	}
 	obliquedPath->push_back(path[0]);
 	uint index = 1;
 	while (index < path.size()) {
@@ -315,8 +318,8 @@
 		bool allPointsOk = true;
 		// Testing only points between (i.e., without the end-points) is OK.
 		for (int step = 1; step < steps; ++step) {
-			const int x = (v1.x * (steps-step) + v3.x * step) / steps;
-			const int y = (v1.y * (steps-step) + v3.y * step) / steps;
+			const int x = (v1.x * (steps-step) + v3.x * step + steps/2) / steps;
+			const int y = (v1.y * (steps-step) + v3.y * step + steps/2) / steps;
 			if (!getPixel(x, y)) {
 				allPointsOk = false;
 				break;
@@ -340,15 +343,17 @@
 		// Draw only points in the interval [v1, v2).  These half-open
 		// half-closed intervals connect all the way to the last point.
 		for (int step = 0; step < steps; ++step) {
-			const int x = (v1.x * (steps-step) + v2.x * step) / steps;
-			const int y = (v1.y * (steps-step) + v2.y * step) / steps;
+			const int x = (v1.x * (steps-step) + v2.x * step + steps/2) / steps;
+			const int y = (v1.y * (steps-step) + v2.y * step + steps/2) / steps;
 			drawOverlayRectangle(x, y, colour, wlk);
 		}
 	}
 	// Draw the last point.  This works also when the path has no segment,
 	// but just one point.
-	const PathVertex &vLast = path[path.size()-1];
-	drawOverlayRectangle(vLast.x, vLast.y, colour, wlk);
+	if (path.size() > 0) {
+		const PathVertex &vLast = path[path.size()-1];
+		drawOverlayRectangle(vLast.x, vLast.y, colour, wlk);
+	}
 
 	Sprite *ov = new Sprite(_realWidth, _realHeight, wlk, 0, 0, false);
 	// ov has taken the ownership of wlk.

Modified: scummvm/trunk/engines/draci/walking.h
===================================================================
--- scummvm/trunk/engines/draci/walking.h	2009-11-01 10:58:34 UTC (rev 45596)
+++ scummvm/trunk/engines/draci/walking.h	2009-11-01 12:57:06 UTC (rev 45597)
@@ -49,7 +49,7 @@
 	bool getPixel(int x, int y) const;
 	bool isWalkable(int x, int y) const;
 
-	Sprite *newOverlayFromMap() const;
+	Sprite *newOverlayFromMap(byte colour) const;
 	Common::Point findNearestWalkable(int x, int y, Common::Rect searchRect) const;
 
 	typedef Common::Array<PathVertex> Path;


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