[Scummvm-cvs-logs] SF.net SVN: scummvm:[33296] scummvm/trunk/engines/parallaction

peres001 at users.sourceforge.net peres001 at users.sourceforge.net
Sat Jul 26 06:01:12 CEST 2008


Revision: 33296
          http://scummvm.svn.sourceforge.net/scummvm/?rev=33296&view=rev
Author:   peres001
Date:     2008-07-26 04:01:11 +0000 (Sat, 26 Jul 2008)

Log Message:
-----------
* Added walk calculations to BRA (doesn't walk yet, though).
* Adapted Character and Animation to handle both versions of the engine.

Modified Paths:
--------------
    scummvm/trunk/engines/parallaction/objects.cpp
    scummvm/trunk/engines/parallaction/parallaction.cpp
    scummvm/trunk/engines/parallaction/parallaction.h
    scummvm/trunk/engines/parallaction/walk.cpp
    scummvm/trunk/engines/parallaction/walk.h

Modified: scummvm/trunk/engines/parallaction/objects.cpp
===================================================================
--- scummvm/trunk/engines/parallaction/objects.cpp	2008-07-26 02:09:50 UTC (rev 33295)
+++ scummvm/trunk/engines/parallaction/objects.cpp	2008-07-26 04:01:11 UTC (rev 33296)
@@ -60,14 +60,14 @@
 uint16 Animation::width() const {
 	if (!gfxobj) return 0;
 	Common::Rect r;
-	gfxobj->getRect(0, r);
+	gfxobj->getRect(_frame, r);
 	return r.width();
 }
 
 uint16 Animation::height() const {
 	if (!gfxobj) return 0;
 	Common::Rect r;
-	gfxobj->getRect(0, r);
+	gfxobj->getRect(_frame, r);
 	return r.height();
 }
 

Modified: scummvm/trunk/engines/parallaction/parallaction.cpp
===================================================================
--- scummvm/trunk/engines/parallaction/parallaction.cpp	2008-07-26 02:09:50 UTC (rev 33295)
+++ scummvm/trunk/engines/parallaction/parallaction.cpp	2008-07-26 04:01:11 UTC (rev 33296)
@@ -497,7 +497,7 @@
 const char Character::_empty[] = "\0";
 
 
-Character::Character(Parallaction *vm) : _vm(vm), _ani(new Animation), _builder(_ani) {
+Character::Character(Parallaction *vm) : _vm(vm), _ani(new Animation) {
 	_talk = NULL;
 	_head = NULL;
 	_objs = NULL;
@@ -516,25 +516,63 @@
 	_ani->_flags = kFlagsActive | kFlagsNoName;
 	_ani->_type = kZoneYou;
 	strncpy(_ani->_name, "yourself", ZONENAME_LENGTH);
+
+	// TODO: move creation into Parallaction. Needs to make Character a pointer first.
+	if (_vm->getGameType() == GType_Nippon)
+		_builder = new PathBuilder_NS(this);
+	else
+		_builder = new PathBuilder_BR(this);
 }
 
+Character::~Character() {
+	delete _builder;
+	_builder = 0;
+
+	free();
+}
+
 void Character::getFoot(Common::Point &foot) {
-	foot.x = _ani->_left + _ani->width() / 2;
-	foot.y = _ani->_top + _ani->height();
+	Common::Rect rect;
+	_ani->gfxobj->getRect(_ani->_frame, rect);
+
+	foot.x = _ani->_left + (rect.left + rect.width() / 2);
+	foot.y = _ani->_top + (rect.top + rect.height());
 }
 
 void Character::setFoot(const Common::Point &foot) {
-	_ani->_left = foot.x - _ani->width() / 2;
-	_ani->_top = foot.y - _ani->height();
+	Common::Rect rect;
+	_ani->gfxobj->getRect(_ani->_frame, rect);
+
+	_ani->_left = foot.x - (rect.left + rect.width() / 2);
+	_ani->_top = foot.y - (rect.top + rect.height());
 }
 
+#if 0
+void dumpPath(PointList *list, const char* text) {
+	for (PointList::iterator it = list->begin(); it != list->end(); it++)
+		printf("node (%i, %i)\n", it->x, it->y);
+
+	return;
+}
+#endif
+
 void Character::scheduleWalk(int16 x, int16 y) {
 	if ((_ani->_flags & kFlagsRemove) || (_ani->_flags & kFlagsActive) == 0) {
 		return;
 	}
 
-	_walkPath = _builder.buildPath(x, y);
-	_engineFlags |= kEngineWalking;
+	_walkPath = _builder->buildPath(x, y);
+#if 0
+	dumpPath(_walkPath, _name);
+#endif
+
+	if (_vm->getGameType() == GType_Nippon) {
+		_engineFlags |= kEngineWalking;
+	} else {
+		// BRA can't walk yet!
+		delete _walkPath;
+		_walkPath = 0;
+	}
 }
 
 void Character::free() {

Modified: scummvm/trunk/engines/parallaction/parallaction.h
===================================================================
--- scummvm/trunk/engines/parallaction/parallaction.h	2008-07-26 02:09:50 UTC (rev 33295)
+++ scummvm/trunk/engines/parallaction/parallaction.h	2008-07-26 04:01:11 UTC (rev 33296)
@@ -198,10 +198,12 @@
 	GfxObj			*_head;
 	GfxObj			*_talk;
 	GfxObj			*_objs;
-	PathBuilder		_builder;
+	PathBuilder		*_builder;
 	PointList		*_walkPath;
 
 	Character(Parallaction *vm);
+	~Character();
+
 	void getFoot(Common::Point &foot);
 	void setFoot(const Common::Point &foot);
 	void scheduleWalk(int16 x, int16 y);
@@ -379,6 +381,7 @@
 	void		beep();
 
 	ZonePtr		_zoneTrap;
+	PathBuilder* getPathBuilder(Character *ch);
 
 public:
 //	const char **_zoneFlagNamesRes;

Modified: scummvm/trunk/engines/parallaction/walk.cpp
===================================================================
--- scummvm/trunk/engines/parallaction/walk.cpp	2008-07-26 02:09:50 UTC (rev 33295)
+++ scummvm/trunk/engines/parallaction/walk.cpp	2008-07-26 04:01:11 UTC (rev 33296)
@@ -28,15 +28,29 @@
 namespace Parallaction {
 
 
+
 inline byte PathBuffer::getValue(uint16 x, uint16 y) {
 	byte m = data[(x >> 3) + y * internalWidth];
-	uint n = (_vm->getPlatform() == Common::kPlatformPC) ? (x & 7) : (7 - (x & 7));
-	return ((1 << n) & m) >> n;
+	uint bit = 0;
+	switch (_vm->getGameType()) {
+	case GType_Nippon:
+		bit = (_vm->getPlatform() == Common::kPlatformPC) ? (x & 7) : (7 - (x & 7));
+		break;
+
+	case GType_BRA:
+		// Amiga and PC versions pack the path bits the same way in BRA
+		bit = 7 - (x & 7);
+		break;
+
+	default:
+		error("path mask not yet implemented for this game type");
+	}
+	return ((1 << bit) & m) >> bit;
 }
 
 // adjusts position towards nearest walkable point
 //
-void PathBuilder::correctPathPoint(Common::Point &to) {
+void PathBuilder_NS::correctPathPoint(Common::Point &to) {
 
 	if (_vm->_pathBuffer->getValue(to.x, to.y)) return;
 
@@ -84,7 +98,7 @@
 
 }
 
-uint32 PathBuilder::buildSubPath(const Common::Point& pos, const Common::Point& stop) {
+uint32 PathBuilder_NS::buildSubPath(const Common::Point& pos, const Common::Point& stop) {
 
 	uint32 v28 = 0;
 	uint32 v2C = 0;
@@ -128,19 +142,11 @@
 	return v34;
 
 }
-#if 0
-void printNodes(WalkNodeList *list, const char* text) {
-	printf("%s\n-------------------\n", text);
-	for (WalkNodeList::iterator it = list->begin(); it != list->end(); it++)
-		printf("node [%p] (%i, %i)\n", *it, (*it)->_x, (*it)->_y);
 
-	return;
-}
-#endif
 //
 //	x, y: mouse click (foot) coordinates
 //
-PointList *PathBuilder::buildPath(uint16 x, uint16 y) {
+PointList *PathBuilder_NS::buildPath(uint16 x, uint16 y) {
 	debugC(1, kDebugWalk, "PathBuilder::buildPath to (%i, %i)", x, y);
 
 	Common::Point to(x, y);
@@ -169,7 +175,7 @@
 
 	Common::Point stop(v48.x, v48.y);
 	Common::Point pos;
-	_vm->_char.getFoot(pos);
+	_ch->getFoot(pos);
 
 	uint32 v34 = buildSubPath(pos, stop);
 	if (v38 != 0 && v34 > v38) {
@@ -201,14 +207,14 @@
 //	1 : Point reachable in a straight line
 //	other values: square distance to target (point not reachable in a straight line)
 //
-uint16 PathBuilder::walkFunc1(int16 x, int16 y, Common::Point& node) {
+uint16 PathBuilder_NS::walkFunc1(int16 x, int16 y, Common::Point& node) {
 
 	Common::Point arg(x, y);
 
 	Common::Point v4(0, 0);
 
 	Common::Point foot;
-	_vm->_char.getFoot(foot);
+	_ch->getFoot(foot);
 
 	Common::Point v8(foot);
 
@@ -364,8 +370,85 @@
 
 
 
-PathBuilder::PathBuilder(AnimationPtr anim) : _anim(anim), _list(0) {
+PathBuilder_NS::PathBuilder_NS(Character *ch) : PathBuilder(ch), _list(0) {
 }
 
+#define isPositionOnPath(x,y) _vm->_pathBuffer->getValue((x), (y))
 
+
+bool PathBuilder_BR::directPathExists(const Common::Point &from, const Common::Point &to) {
+
+	Common::Point copy(from);
+	Common::Point p(copy);
+
+	while (p != to) {
+
+		if (p.x < to.x && isPositionOnPath(p.x + 1, p.y)) p.x++;
+		if (p.x > to.x && isPositionOnPath(p.x - 1, p.y)) p.x--;
+		if (p.y < to.y && isPositionOnPath(p.x, p.y + 1)) p.y++;
+		if (p.y > to.y && isPositionOnPath(p.x, p.y - 1)) p.y--;
+
+		if (p == copy && p != to) {
+			return false;
+		}
+
+		copy = p;
+	}
+
+	return true;
+}
+
+PointList* PathBuilder_BR::buildPath(uint16 x, uint16 y) {
+	Common::Point foot;
+	_ch->getFoot(foot);
+
+	debugC(1, kDebugWalk, "buildPath: from (%i, %i) to (%i, %i)", foot.x, foot.y, x, y);
+
+	PointList *list = new PointList;
+
+	// look for easy path first
+	Common::Point dest(x, y);
+	if (directPathExists(foot, dest)) {
+		list->push_back(dest);
+		debugC(3, kDebugWalk, "buildPath: direct path found");
+		return list;
+	}
+
+	// look for short circuit cases
+	ZonePtr z0 = _vm->hitZone(kZonePath, x, y);
+	if (z0 == nullZonePtr) {
+		list->push_back(dest);
+		debugC(3, kDebugWalk, "buildPath: corner case 0");
+		return list;
+	}
+	ZonePtr z1 = _vm->hitZone(kZonePath, foot.x, foot.y);
+	if (z1 == nullZonePtr || z1 == z0) {
+		list->push_back(dest);
+		debugC(3, kDebugWalk, "buildPath: corner case 1");
+		return list;
+	}
+
+	// build complex path
+	int id = atoi(z0->_name);
+
+	if (z1->u.path->_lists[id].empty()) {
+		list->clear();
+		debugC(3, kDebugWalk, "buildPath: no path");
+		return list;
+	}
+
+	PointList::iterator b = z1->u.path->_lists[id].begin();
+	PointList::iterator e = z1->u.path->_lists[id].end();
+	for ( ; b != e; b++) {
+		list->push_front(*b);
+	}
+	list->push_back(dest);
+	debugC(3, kDebugWalk, "buildPath: complex path");
+
+	return list;
+}
+
+PathBuilder_BR::PathBuilder_BR(Character *ch) : PathBuilder(ch) {
+}
+
 } // namespace Parallaction

Modified: scummvm/trunk/engines/parallaction/walk.h
===================================================================
--- scummvm/trunk/engines/parallaction/walk.h	2008-07-26 02:09:50 UTC (rev 33295)
+++ scummvm/trunk/engines/parallaction/walk.h	2008-07-26 04:01:11 UTC (rev 33296)
@@ -31,12 +31,26 @@
 
 #include "parallaction/objects.h"
 
+
 namespace Parallaction {
 
+struct Character;
+
 class PathBuilder {
 
-	AnimationPtr	_anim;
+protected:
+	Character *_ch;
 
+public:
+	PathBuilder(Character *ch) : _ch(ch) { }
+	virtual ~PathBuilder() { }
+
+	virtual PointList* buildPath(uint16 x, uint16 y) = 0;
+};
+
+
+class PathBuilder_NS : public PathBuilder {
+
 	PointList	*_list;
 	PointList	_subPath;
 
@@ -45,9 +59,18 @@
 	uint16 walkFunc1(int16 x, int16 y, Common::Point& node);
 
 public:
-	PathBuilder(AnimationPtr anim);
+	PathBuilder_NS(Character *ch);
 	PointList* buildPath(uint16 x, uint16 y);
+};
 
+
+class PathBuilder_BR : public PathBuilder {
+
+	bool directPathExists(const Common::Point &from, const Common::Point &to);
+
+public:
+	PathBuilder_BR(Character *ch);
+	PointList* buildPath(uint16 x, uint16 y);
 };
 
 


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