[Scummvm-cvs-logs] SF.net SVN: scummvm: [24367] scummvm/trunk/engines/scumm

fingolfin at users.sourceforge.net fingolfin at users.sourceforge.net
Wed Oct 18 16:01:35 CEST 2006


Revision: 24367
          http://svn.sourceforge.net/scummvm/?rev=24367&view=rev
Author:   fingolfin
Date:     2006-10-18 07:01:28 -0700 (Wed, 18 Oct 2006)

Log Message:
-----------
SCUMM: reordered contents of actor.cpp, grouping methods in a hopefully somewhat more logical fashion

Modified Paths:
--------------
    scummvm/trunk/engines/scumm/actor.cpp
    scummvm/trunk/engines/scumm/scumm.h

Modified: scummvm/trunk/engines/scumm/actor.cpp
===================================================================
--- scummvm/trunk/engines/scumm/actor.cpp	2006-10-18 14:01:06 UTC (rev 24366)
+++ scummvm/trunk/engines/scumm/actor.cpp	2006-10-18 14:01:28 UTC (rev 24367)
@@ -159,6 +159,54 @@
 	_vm->_classData[_number] = (_vm->_game.version >= 7) ? _vm->_classData[0] : 0;
 }
 
+void Actor::setBox(int box) {
+	_walkbox = box;
+	setupActorScale();
+}
+
+void Actor::setupActorScale() {
+
+	if (_vm->_game.features & GF_NO_SCALING) {
+		_scalex = 0xFF;
+		_scaley = 0xFF;
+		return;
+	}
+
+	if (_ignoreBoxes)
+		return;
+
+	// For some boxes, we ignore the scaling and use whatever values the
+	// scripts set. This is used e.g. in the Mystery Vortex in Sam&Max.
+	// Older games used the flag 0x20 differently, though.
+	if (_vm->_game.id == GID_SAMNMAX && (_vm->getBoxFlags(_walkbox) & kBoxIgnoreScale))
+		return;
+
+	_boxscale = _vm->getBoxScale(_walkbox);
+
+	uint16 scale = _vm->getScale(_walkbox, _pos.x, _pos.y);
+	assert(scale <= 0xFF);
+
+	_scalex = _scaley = (byte)scale;
+}
+
+
+#pragma mark -
+#pragma mark --- Actor walking ---
+#pragma mark -
+
+
+void ScummEngine::walkActors() {
+	int i;
+
+	for (i = 1; i < _numActors; i++) {
+		if (_actors[i].isInCurrentRoom())
+			if (_game.version <= 3)
+				_actors[i].walkActorOld();
+			else
+				_actors[i].walkActor();
+	}
+}
+
 void Actor::stopActorMoving() {
 	if (_walkScript)
 		_vm->stopScript(_walkScript);
@@ -177,8 +225,8 @@
 	}
 }
 
-int ScummEngine::getAngleFromPos(int x, int y) const {
-	if (_game.id == GID_DIG || _game.id == GID_CMI) {
+int getAngleFromPos(int x, int y, bool useATAN) {
+	if (useATAN) {
 		double temp = atan2((double)x, (double)-y);
 		return normalizeAngle((int)(temp * 180 / PI));
 	} else {
@@ -236,11 +284,396 @@
 	_walkdata.xfrac = 0;
 	_walkdata.yfrac = 0;
 
-	_targetFacing = _vm->getAngleFromPos(deltaXFactor, deltaYFactor);
+	_targetFacing = getAngleFromPos(deltaXFactor, deltaYFactor, (_vm->_game.id == GID_DIG || _vm->_game.id == GID_CMI));
 
 	return actorWalkStep();
 }
 
+int Actor::actorWalkStep() {
+	int tmpX, tmpY;
+	Common::Point _actorPos;
+	int distX, distY;
+	int nextFacing;
+
+	_needRedraw = true;
+
+	nextFacing = updateActorDirection(true);
+	if (!(_moving & MF_IN_LEG) || _facing != nextFacing) {
+		if (_walkFrame != _frame || _facing != nextFacing) {
+			startWalkAnim(1, nextFacing);
+		}
+		_moving |= MF_IN_LEG;
+	}
+
+	_actorPos = _pos;
+
+	if (_walkbox != _walkdata.curbox && _vm->checkXYInBoxBounds(_walkdata.curbox, _actorPos.x, _actorPos.y)) {
+		setBox(_walkdata.curbox);
+	}
+
+	distX = ABS(_walkdata.next.x - _walkdata.cur.x);
+	distY = ABS(_walkdata.next.y - _walkdata.cur.y);
+
+	if (ABS(_actorPos.x - _walkdata.cur.x) >= distX && ABS(_actorPos.y - _walkdata.cur.y) >= distY) {
+		_moving &= ~MF_IN_LEG;
+		return 0;
+	}
+
+	tmpX = (_actorPos.x << 16) + _walkdata.xfrac + (_walkdata.deltaXFactor >> 8) * _scalex;
+	_walkdata.xfrac = (uint16)tmpX;
+	_actorPos.x = (tmpX >> 16);
+
+	tmpY = (_actorPos.y << 16) + _walkdata.yfrac + (_walkdata.deltaYFactor >> 8) * _scaley;
+	_walkdata.yfrac = (uint16)tmpY;
+	_actorPos.y = (tmpY >> 16);
+
+	if (ABS(_actorPos.x - _walkdata.cur.x) > distX) {
+		_actorPos.x = _walkdata.next.x;
+	}
+
+	if (ABS(_actorPos.y - _walkdata.cur.y) > distY) {
+		_actorPos.y = _walkdata.next.y;
+	}
+
+	_pos = _actorPos;
+
+	if (_vm->_game.version >= 4 && _vm->_game.version <= 6 && _pos == _walkdata.next) {
+		_moving &= ~MF_IN_LEG;
+		return 0;
+	}
+	return 1;
+}
+
+void Actor::startWalkActor(int destX, int destY, int dir) {
+	AdjustBoxResult abr;
+
+	if (!isInCurrentRoom() && _vm->_game.version >= 7) {
+		debugC(DEBUG_ACTORS, "startWalkActor: attempting to walk actor %d who is not in this room", _number);
+		return;
+	}
+
+	if (_vm->_game.version <= 4) {
+		abr.x = destX;
+		abr.y = destY;
+	} else {
+		abr = adjustXYToBeInBox(destX, destY);
+	}
+
+	if (!isInCurrentRoom() && _vm->_game.version <= 6) {
+		_pos.x = abr.x;
+		_pos.y = abr.y;
+		if (!_ignoreTurns && dir != -1)
+			_facing = dir;
+		return;
+	}
+
+	if (_ignoreBoxes) {
+		abr.box = kInvalidBox;
+		_walkbox = kInvalidBox;
+	} else {
+		if (_vm->checkXYInBoxBounds(_walkdata.destbox, abr.x, abr.y)) {
+			abr.box = _walkdata.destbox;
+		} else {
+			abr = adjustXYToBeInBox(abr.x, abr.y);
+		}
+		if (_moving && _walkdata.destdir == dir && _walkdata.dest.x == abr.x && _walkdata.dest.y == abr.y)
+			return;
+	}
+
+	if (_pos.x == abr.x && _pos.y == abr.y) {
+		if (dir != _facing)
+			turnToDirection(dir);
+		return;
+	}
+
+	_walkdata.dest.x = abr.x;
+	_walkdata.dest.y = abr.y;
+	_walkdata.destbox = abr.box;
+	_walkdata.destdir = dir;
+	_moving = (_moving & MF_IN_LEG) | MF_NEW_LEG;
+	_walkdata.point3.x = 32000;
+
+	_walkdata.curbox = _walkbox;
+}
+
+void Actor::startWalkAnim(int cmd, int angle) {
+	if (angle == -1)
+		angle = _facing;
+
+	/* Note: walk scripts aren't required to make the Dig
+	 * work as usual
+	 */
+	if (_walkScript) {
+		int args[16];
+		memset(args, 0, sizeof(args));
+		args[0] = _number;
+		args[1] = cmd;
+		args[2] = angle;
+		_vm->runScript(_walkScript, 1, 0, args);
+	} else {
+		switch (cmd) {
+		case 1:										/* start walk */
+			setDirection(angle);
+			startAnimActor(_walkFrame);
+			break;
+		case 2:										/* change dir only */
+			setDirection(angle);
+			break;
+		case 3:										/* stop walk */
+			turnToDirection(angle);
+			startAnimActor(_standFrame);
+			break;
+		}
+	}
+}
+
+void Actor::walkActor() {
+	int new_dir, next_box;
+	Common::Point foundPath;
+
+	if (_vm->_game.version >= 7) {
+		if (_moving & MF_FROZEN) {
+			if (_moving & MF_TURN) {
+				new_dir = updateActorDirection(false);
+				if (_facing != new_dir)
+					setDirection(new_dir);
+				else
+					_moving &= ~MF_TURN;
+			}
+			return;
+		}
+	}
+
+	if (!_moving)
+		return;
+
+	if (!(_moving & MF_NEW_LEG)) {
+		if (_moving & MF_IN_LEG && actorWalkStep())
+			return;
+
+		if (_moving & MF_LAST_LEG) {
+			_moving = 0;
+			setBox(_walkdata.destbox);
+			if (_vm->_game.version <= 6) {
+				startAnimActor(_standFrame);
+				if (_targetFacing != _walkdata.destdir)
+					turnToDirection(_walkdata.destdir);
+			} else {
+				startWalkAnim(3, _walkdata.destdir);
+			}
+			return;
+		}
+
+		if (_moving & MF_TURN) {
+			new_dir = updateActorDirection(false);
+			if (_facing != new_dir)
+				setDirection(new_dir);
+			else
+				_moving = 0;
+			return;
+		}
+
+		setBox(_walkdata.curbox);
+		_moving &= MF_IN_LEG;
+	}
+
+	_moving &= ~MF_NEW_LEG;
+	do {
+
+		if (_walkbox == kInvalidBox) {
+			setBox(_walkdata.destbox);
+			_walkdata.curbox = _walkdata.destbox;
+			break;
+		}
+
+		if (_walkbox == _walkdata.destbox)
+			break;
+
+		next_box = _vm->getPathToDestBox(_walkbox, _walkdata.destbox);
+		if (next_box < 0) {
+			_walkdata.destbox = _walkbox;
+			_moving |= MF_LAST_LEG;
+			return;
+		}
+
+		_walkdata.curbox = next_box;
+
+		if (findPathTowards(_walkbox, next_box, _walkdata.destbox, foundPath))
+			break;
+
+		if (calcMovementFactor(foundPath))
+			return;
+
+		setBox(_walkdata.curbox);
+	} while (1);
+
+	_moving |= MF_LAST_LEG;
+	calcMovementFactor(_walkdata.dest);
+}
+
+/*
+void Actor::walkActorV12() {
+	Common::Point foundPath, tmp;
+	int new_dir, next_box;
+
+	if (_moving & MF_TURN) {
+		new_dir = updateActorDirection(false);
+		if (_facing != new_dir)
+			setDirection(new_dir);
+		else
+			_moving = 0;
+		return;
+	}
+
+	if (!_moving)
+		return;
+
+	if (_moving & MF_IN_LEG) {
+		actorWalkStep();
+	} else {
+		if (_moving & MF_LAST_LEG) {
+			_moving = 0;
+			startAnimActor(_standFrame);
+			if (_targetFacing != _walkdata.destdir)
+				turnToDirection(_walkdata.destdir);
+		} else {
+			setBox(_walkdata.curbox);
+			if (_walkbox == _walkdata.destbox) {
+				foundPath = _walkdata.dest;
+				_moving |= MF_LAST_LEG;
+			} else {
+				next_box = _vm->getPathToDestBox(_walkbox, _walkdata.destbox);
+				if (next_box < 0) {
+					_moving |= MF_LAST_LEG;
+					return;
+				}
+
+				// Can't walk through locked boxes
+				int flags = _vm->getBoxFlags(next_box);
+				if (flags & kBoxLocked && !(flags & kBoxPlayerOnly && !isPlayer())) {
+					_moving |= MF_LAST_LEG;
+				}
+
+				_walkdata.curbox = next_box;
+
+				getClosestPtOnBox(_vm->getBoxCoordinates(_walkdata.curbox), x, y, tmp.x, tmp.y);
+				getClosestPtOnBox(_vm->getBoxCoordinates(_walkbox), tmp.x, tmp.y, foundPath.x, foundPath.y);
+			}
+			calcMovementFactor(foundPath);
+		}
+	}
+}
+*/
+
+void Actor::walkActorOld() {
+	Common::Point p2, p3;	// Gate locations
+	int new_dir, next_box;
+
+	if (!_moving)
+		return;
+
+	if (!(_moving & MF_NEW_LEG)) {
+		if (_moving & MF_IN_LEG && actorWalkStep())
+			return;
+
+		if (_moving & MF_LAST_LEG) {
+			_moving = 0;
+			startAnimActor(_standFrame);
+			if (_targetFacing != _walkdata.destdir)
+				turnToDirection(_walkdata.destdir);
+			return;
+		}
+
+		if (_moving & MF_TURN) {
+			new_dir = updateActorDirection(false);
+			if (_facing != new_dir)
+				setDirection(new_dir);
+			else
+				_moving = 0;
+			return;
+		}
+
+		if (_walkdata.point3.x != 32000) {
+			if (calcMovementFactor(_walkdata.point3)) {
+				_walkdata.point3.x = 32000;
+				return;
+			}
+			_walkdata.point3.x = 32000;
+		}
+
+		setBox(_walkdata.curbox);
+		_moving &= MF_IN_LEG;
+	}
+
+	_moving &= ~MF_NEW_LEG;
+	do {
+		if (_walkbox == kInvalidBox) {
+			setBox(_walkdata.destbox);
+			_walkdata.curbox = _walkdata.destbox;
+			break;
+		}
+
+		if (_walkbox == _walkdata.destbox)
+			break;
+
+		next_box = _vm->getPathToDestBox(_walkbox, _walkdata.destbox);
+
+		// WORKAROUND: To fully fix bug #774783, we add a special case
+		// here, resulting in a different next_box value for Hitler.
+		if ((_vm->_game.id == GID_INDY3) && _vm->_roomResource == 46 && _walkbox == 1 && _walkdata.destbox == 0 && _number == 9)
+			next_box = 1;
+
+		if (next_box < 0) {
+			_moving |= MF_LAST_LEG;
+			return;
+		}
+
+		// Can't walk through locked boxes
+		int flags = _vm->getBoxFlags(next_box);
+		if (flags & kBoxLocked && !(flags & kBoxPlayerOnly && !isPlayer())) {
+			_moving |= MF_LAST_LEG;
+// FIXME: Work in progress
+//			_walkdata.destdir = _facing;
+			return;
+		}
+
+		_walkdata.curbox = next_box;
+
+		if (_vm->_game.version <= 2) {
+			getClosestPtOnBox(_vm->getBoxCoordinates(_walkdata.curbox), _pos.x, _pos.y, p2.x, p2.y);
+			getClosestPtOnBox(_vm->getBoxCoordinates(_walkbox), p2.x, p2.y, p3.x, p3.y);
+// FIXME: Work in progress
+//			calcMovementFactor(p3);
+//			return;
+		} else {
+			findPathTowardsOld(_walkbox, next_box, _walkdata.destbox, p2, p3);
+			if (p2.x == 32000 && p3.x == 32000) {
+				break;
+			}
+
+			if (p2.x != 32000) {
+				if (calcMovementFactor(p2)) {
+					_walkdata.point3 = p3;
+					return;
+				}
+			}
+		}
+		if (calcMovementFactor(p3))
+			return;
+
+		setBox(_walkdata.destbox);
+	} while (1);
+
+	_moving |= MF_LAST_LEG;
+	calcMovementFactor(_walkdata.dest);
+}
+
+
+#pragma mark -
+#pragma mark --- Actor direction ---
+#pragma mark -
+
+
 int Actor::remapDirection(int dir, bool is_walking) {
 	int specdir;
 	byte flags;
@@ -370,198 +803,6 @@
 	return dir;
 }
 
-void Actor::setBox(int box) {
-	_walkbox = box;
-	setupActorScale();
-}
-
-int Actor::actorWalkStep() {
-	int tmpX, tmpY;
-	Common::Point _actorPos;
-	int distX, distY;
-	int nextFacing;
-
-	_needRedraw = true;
-
-	nextFacing = updateActorDirection(true);
-	if (!(_moving & MF_IN_LEG) || _facing != nextFacing) {
-		if (_walkFrame != _frame || _facing != nextFacing) {
-			startWalkAnim(1, nextFacing);
-		}
-		_moving |= MF_IN_LEG;
-	}
-
-	_actorPos = _pos;
-
-	if (_walkbox != _walkdata.curbox && _vm->checkXYInBoxBounds(_walkdata.curbox, _actorPos.x, _actorPos.y)) {
-		setBox(_walkdata.curbox);
-	}
-
-	distX = ABS(_walkdata.next.x - _walkdata.cur.x);
-	distY = ABS(_walkdata.next.y - _walkdata.cur.y);
-
-	if (ABS(_actorPos.x - _walkdata.cur.x) >= distX && ABS(_actorPos.y - _walkdata.cur.y) >= distY) {
-		_moving &= ~MF_IN_LEG;
-		return 0;
-	}
-
-	tmpX = (_actorPos.x << 16) + _walkdata.xfrac + (_walkdata.deltaXFactor >> 8) * _scalex;
-	_walkdata.xfrac = (uint16)tmpX;
-	_actorPos.x = (tmpX >> 16);
-
-	tmpY = (_actorPos.y << 16) + _walkdata.yfrac + (_walkdata.deltaYFactor >> 8) * _scaley;
-	_walkdata.yfrac = (uint16)tmpY;
-	_actorPos.y = (tmpY >> 16);
-
-	if (ABS(_actorPos.x - _walkdata.cur.x) > distX) {
-		_actorPos.x = _walkdata.next.x;
-	}
-
-	if (ABS(_actorPos.y - _walkdata.cur.y) > distY) {
-		_actorPos.y = _walkdata.next.y;
-	}
-
-	_pos = _actorPos;
-
-	if (_vm->_game.version >= 4 && _vm->_game.version <= 6 && _pos == _walkdata.next) {
-		_moving &= ~MF_IN_LEG;
-		return 0;
-	}
-	return 1;
-}
-
-
-void Actor::setupActorScale() {
-
-	if (_vm->_game.features & GF_NO_SCALING) {
-		_scalex = 0xFF;
-		_scaley = 0xFF;
-		return;
-	}
-
-	if (_ignoreBoxes)
-		return;
-
-	// For some boxes, we ignore the scaling and use whatever values the
-	// scripts set. This is used e.g. in the Mystery Vortex in Sam&Max.
-	// Older games used the flag 0x20 differently, though.
-	if (_vm->_game.id == GID_SAMNMAX && (_vm->getBoxFlags(_walkbox) & kBoxIgnoreScale))
-		return;
-
-	_boxscale = _vm->getBoxScale(_walkbox);
-
-	uint16 scale = _vm->getScale(_walkbox, _pos.x, _pos.y);
-	assert(scale <= 0xFF);
-
-	_scalex = _scaley = (byte)scale;
-}
-
-void Actor::startAnimActor(int f) {
-	if (_vm->_game.version >= 7 && !((_vm->_game.id == GID_FT) && (_vm->_game.features & GF_DEMO) && (_vm->_game.platform == Common::kPlatformPC))) {
-		switch (f) {
-		case 1001:
-			f = _initFrame;
-			break;
-		case 1002:
-			f = _walkFrame;
-			break;
-		case 1003:
-			f = _standFrame;
-			break;
-		case 1004:
-			f = _talkStartFrame;
-			break;
-		case 1005:
-			f = _talkStopFrame;
-			break;
-		}
-
-		if (_costume != 0) {
-			_animProgress = 0;
-			_needRedraw = true;
-			if (f == _initFrame)
-				_cost.reset();
-			_vm->_costumeLoader->costumeDecodeData(this, f, (uint) - 1);
-			_frame = f;
-		}
-	} else {
-		switch (f) {
-		case 0x38:
-			f = _initFrame;
-			break;
-		case 0x39:
-			f = _walkFrame;
-			break;
-		case 0x3A:
-			f = _standFrame;
-			break;
-		case 0x3B:
-			f = _talkStartFrame;
-			break;
-		case 0x3C:
-			f = _talkStopFrame;
-			break;
-		}
-
-		assert(f != 0x3E);
-
-		if (isInCurrentRoom() && _costume != 0) {
-			_animProgress = 0;
-			_cost.animCounter = 0;
-			_needRedraw = true;
-			// V1 - V2 games don't seem to need a _cost.reset() at this point.
-			// Causes Zak to lose his body in several scenes, see bug #771508
-			if (_vm->_game.version >= 3 && f == _initFrame) {
-				_cost.reset();
-				_auxBlock.reset();
-			}
-			_vm->_costumeLoader->costumeDecodeData(this, f, (uint) - 1);
-			_frame = f;
-		}
-	}
-}
-
-void Actor::animateActor(int anim) {
-	int cmd, dir;
-
-	if (_vm->_game.version >= 7 && !((_vm->_game.id == GID_FT) && (_vm->_game.features & GF_DEMO) && (_vm->_game.platform == Common::kPlatformPC))) {
-
-		if (anim == 0xFF)
-			anim = 2000;
-
-		cmd = anim / 1000;
-		dir = anim % 1000;
-
-	} else {
-
-		cmd = anim / 4;
-		dir = oldDirToNewDir(anim % 4);
-
-		// Convert into old cmd code
-		cmd = 0x3F - cmd + 2;
-
-	}
-
-	switch (cmd) {
-	case 2:				// stop walking
-		startAnimActor(_standFrame);
-		stopActorMoving();
-		break;
-	case 3:				// change direction immediatly
-		_moving &= ~MF_TURN;
-		setDirection(dir);
-		break;
-	case 4:				// turn to new direction
-		turnToDirection(dir);
-		break;
-	default:
-		if (_vm->_game.version <= 2)
-			startAnimActor(anim / 4);
-		else
-			startAnimActor(anim);
-	}
-}
-
 void Actor::setDirection(int direction) {
 	uint aMask;
 	int i;
@@ -590,29 +831,52 @@
 	_needRedraw = true;
 }
 
-void Actor::drawActorToBackBuf(int x, int y) {
-	int curTop = _top;
-	int curBottom = _bottom;
+void Actor::faceToObject(int obj) {
+	int x2, y2, dir;
 
-	_pos.x = x;
-	_pos.y = y;
+	if (!isInCurrentRoom())
+		return;
 
-	_drawToBackBuf = true;
-	_needRedraw = true;
-	drawActorCostume();
+	if (_vm->getObjectOrActorXY(obj, x2, y2) == -1)
+		return;
 
-	_drawToBackBuf = false;
-	_needRedraw = true;
-	drawActorCostume();
-	_needRedraw = false;
+	dir = (x2 > _pos.x) ? 90 : 270;
+	turnToDirection(dir);
+}
 
-	if (_top > curTop)
-		_top = curTop;
-	if (_bottom < curBottom)
-		_bottom = curBottom;
+void Actor::turnToDirection(int newdir) {
+	if (newdir == -1 || _ignoreTurns)
+		return;
+
+	if (_vm->_game.version <= 6) {
+		_moving = MF_TURN;
+		_targetFacing = newdir;
+	} else {
+		_moving &= ~MF_TURN;
+		if (newdir != _facing) {
+			_moving |= MF_TURN;
+			_targetFacing = newdir;
+		}
+	}
 }
 
 
+#pragma mark -
+#pragma mark --- Actor position ---
+#pragma mark -
+
+
+void ScummEngine::putActors() {
+	Actor *a;
+	int i;
+
+	for (i = 1; i < _numActors; i++) {
+		a = &_actors[i];
+		if (a && a->isInCurrentRoom())
+			a->putActor(a->_pos.x, a->_pos.y, a->_room);
+	}
+}
+
 void Actor::putActor(int dstX, int dstY, byte newRoom) {
 	if (_visible && _vm->_currentRoom != newRoom && _vm->getTalkingActor() == _number) {
 		_vm->stopTalk();
@@ -766,35 +1030,48 @@
 	}
 }
 
-void Actor::faceToObject(int obj) {
-	int x2, y2, dir;
+int ScummEngine::getActorFromPos(int x, int y) {
+	int i;
 
-	if (!isInCurrentRoom())
-		return;
+	if (!testGfxAnyUsageBits(x / 8))
+		return 0;
 
-	if (_vm->getObjectOrActorXY(obj, x2, y2) == -1)
-		return;
+	for (i = 1; i < _numActors; i++) {
+		if (testGfxUsageBit(x / 8, i) && !getClass(i, kObjectClassUntouchable)
+			&& y >= _actors[i]._top && y <= _actors[i]._bottom) {
+			if (_game.version > 2 || i != VAR(VAR_EGO))
+				return i;
+		}
+	}
 
-	dir = (x2 > _pos.x) ? 90 : 270;
-	turnToDirection(dir);
+	return 0;
 }
 
-void Actor::turnToDirection(int newdir) {
-	if (newdir == -1 || _ignoreTurns)
-		return;
+#ifndef DISABLE_HE
+int ScummEngine_v70he::getActorFromPos(int x, int y) {
+	int curActor, i;
 
-	if (_vm->_game.version <= 6) {
-		_moving = MF_TURN;
-		_targetFacing = newdir;
-	} else {
-		_moving &= ~MF_TURN;
-		if (newdir != _facing) {
-			_moving |= MF_TURN;
-			_targetFacing = newdir;
-		}
+	if (!testGfxAnyUsageBits(x / 8))
+		return 0;
+
+	curActor = 0;
+	for (i = 1; i < _numActors; i++) {
+		if (testGfxUsageBit(x / 8, i) && !getClass(i, kObjectClassUntouchable)
+			&& y >= _actors[i]._top && y <= _actors[i]._bottom
+			&& (_actors[i]._pos.y > _actors[curActor]._pos.y || curActor == 0))
+				curActor = i;
 	}
+
+	return curActor;
 }
+#endif
 
+
+#pragma mark -
+#pragma mark --- TODO ---
+#pragma mark -
+
+
 void Actor::hideActor() {
 	if (!_visible)
 		return;
@@ -835,67 +1112,6 @@
 	_needRedraw = true;
 }
 
-// V1 Maniac doesn't have a ScummVar for VAR_TALK_ACTOR, and just uses
-// an internal variable. Emulate this to prevent overwriting script vars...
-// Maniac NES (V1), however, DOES have a ScummVar for VAR_TALK_ACTOR
-int ScummEngine::getTalkingActor() {
-	if (_game.id == GID_MANIAC && _game.version <= 1 && !(_game.platform == Common::kPlatformNES))
-		return _V1TalkingActor;
-	else
-		return VAR(VAR_TALK_ACTOR);
-}
-
-void ScummEngine::setTalkingActor(int value) {
-
-	if (value == 255) {
-		_system->clearFocusRectangle();
-	} else {
-		// Work out the screen co-ordinates of the actor
-		int x = _actors[value]._pos.x - (camera._cur.x - (_screenWidth >> 1));
-		int y = _actors[value]._top - (camera._cur.y - (_screenHeight >> 1));
-		
-		// Set the focus area to the calculated position
-		// TODO: Make the size adjust depending on what it's focusing on.
-		Common::Rect rect(x - 96, y - 64, x + 96, y + 64);
-		_system->setFocusRectangle(rect);
-	}
-
-	if (_game.id == GID_MANIAC && _game.version <= 1 && !(_game.platform == Common::kPlatformNES))
-		_V1TalkingActor = value;
-	else
-		VAR(VAR_TALK_ACTOR) = value;
-}
-
-void ScummEngine::putActors() {
-	Actor *a;
-	int i;
-
-	for (i = 1; i < _numActors; i++) {
-		a = &_actors[i];
-		if (a && a->isInCurrentRoom())
-			a->putActor(a->_pos.x, a->_pos.y, a->_room);
-	}
-}
-
-static const int c64MMActorTalkColor[25] = {
-	1, 7, 2, 14, 8, 15, 3, 7, 7, 15, 1, 13, 1, 4, 5, 5, 4, 3, 1, 5, 1, 1, 1, 1, 7
-};
-static const int v1MMActorTalkColor[25] = {
-	1, 7, 2, 14, 8, 1, 3, 7, 7, 12, 1, 13, 1, 4, 5, 5, 4, 3, 1, 5, 1, 1, 1, 7, 7
-};
-
-void ScummEngine::resetV1ActorTalkColor() {
-	int i;
-
-	for (i = 1; i < _numActors; i++) {
-		if (_game.platform == Common::kPlatformC64) {
-			_actors[i]._talkColor = c64MMActorTalkColor[i];
-		} else {
-			_actors[i]._talkColor = v1MMActorTalkColor[i];
-		}
-	}
-}
-
 void ScummEngine::showActors() {
 	int i;
 
@@ -905,18 +1121,6 @@
 	}
 }
 
-void ScummEngine::walkActors() {
-	int i;
-
-	for (i = 1; i < _numActors; i++) {
-		if (_actors[i].isInCurrentRoom())
-			if (_game.version <= 3)
-				_actors[i].walkActorOld();
-			else
-				_actors[i].walkActor();
-	}
-}
-
 /* Used in Scumm v5 only. Play sounds associated with actors */
 void ScummEngine::playActorSounds() {
 	int i;
@@ -964,6 +1168,12 @@
 	return &_actors[id];
 }
 
+
+#pragma mark -
+#pragma mark --- Actor drawing ---
+#pragma mark -
+
+
 void ScummEngine::processActors() {
 	int numactors = 0;
 
@@ -1220,6 +1430,112 @@
 }
 #endif
 
+void Actor::startAnimActor(int f) {
+	if (_vm->_game.version >= 7 && !((_vm->_game.id == GID_FT) && (_vm->_game.features & GF_DEMO) && (_vm->_game.platform == Common::kPlatformPC))) {
+		switch (f) {
+		case 1001:
+			f = _initFrame;
+			break;
+		case 1002:
+			f = _walkFrame;
+			break;
+		case 1003:
+			f = _standFrame;
+			break;
+		case 1004:
+			f = _talkStartFrame;
+			break;
+		case 1005:
+			f = _talkStopFrame;
+			break;
+		}
+
+		if (_costume != 0) {
+			_animProgress = 0;
+			_needRedraw = true;
+			if (f == _initFrame)
+				_cost.reset();
+			_vm->_costumeLoader->costumeDecodeData(this, f, (uint) - 1);
+			_frame = f;
+		}
+	} else {
+		switch (f) {
+		case 0x38:
+			f = _initFrame;
+			break;
+		case 0x39:
+			f = _walkFrame;
+			break;
+		case 0x3A:
+			f = _standFrame;
+			break;
+		case 0x3B:
+			f = _talkStartFrame;
+			break;
+		case 0x3C:
+			f = _talkStopFrame;
+			break;
+		}
+
+		assert(f != 0x3E);
+
+		if (isInCurrentRoom() && _costume != 0) {
+			_animProgress = 0;
+			_cost.animCounter = 0;
+			_needRedraw = true;
+			// V1 - V2 games don't seem to need a _cost.reset() at this point.
+			// Causes Zak to lose his body in several scenes, see bug #771508
+			if (_vm->_game.version >= 3 && f == _initFrame) {
+				_cost.reset();
+				_auxBlock.reset();
+			}
+			_vm->_costumeLoader->costumeDecodeData(this, f, (uint) - 1);
+			_frame = f;
+		}
+	}
+}
+
+void Actor::animateActor(int anim) {
+	int cmd, dir;
+
+	if (_vm->_game.version >= 7 && !((_vm->_game.id == GID_FT) && (_vm->_game.features & GF_DEMO) && (_vm->_game.platform == Common::kPlatformPC))) {
+
+		if (anim == 0xFF)
+			anim = 2000;
+
+		cmd = anim / 1000;
+		dir = anim % 1000;
+
+	} else {
+
+		cmd = anim / 4;
+		dir = oldDirToNewDir(anim % 4);
+
+		// Convert into old cmd code
+		cmd = 0x3F - cmd + 2;
+
+	}
+
+	switch (cmd) {
+	case 2:				// stop walking
+		startAnimActor(_standFrame);
+		stopActorMoving();
+		break;
+	case 3:				// change direction immediatly
+		_moving &= ~MF_TURN;
+		setDirection(dir);
+		break;
+	case 4:				// turn to new direction
+		turnToDirection(dir);
+		break;
+	default:
+		if (_vm->_game.version <= 2)
+			startAnimActor(anim / 4);
+		else
+			startAnimActor(anim);
+	}
+}
+
 void Actor::animateCostume() {
 	if (_costume == 0)
 		return;
@@ -1329,41 +1645,84 @@
 	}
 }
 
-int ScummEngine::getActorFromPos(int x, int y) {
-	int i;
+// HE specific
+void Actor::drawActorToBackBuf(int x, int y) {
+	int curTop = _top;
+	int curBottom = _bottom;
 
-	if (!testGfxAnyUsageBits(x / 8))
-		return 0;
+	_pos.x = x;
+	_pos.y = y;
 
-	for (i = 1; i < _numActors; i++) {
-		if (testGfxUsageBit(x / 8, i) && !getClass(i, kObjectClassUntouchable)
-			&& y >= _actors[i]._top && y <= _actors[i]._bottom) {
-			if (_game.version > 2 || i != VAR(VAR_EGO))
-				return i;
-		}
+	_drawToBackBuf = true;
+	_needRedraw = true;
+	drawActorCostume();
+
+	_drawToBackBuf = false;
+	_needRedraw = true;
+	drawActorCostume();
+	_needRedraw = false;
+
+	if (_top > curTop)
+		_top = curTop;
+	if (_bottom < curBottom)
+		_bottom = curBottom;
+}
+
+
+#pragma mark -
+#pragma mark --- Actor talking ---
+#pragma mark -
+
+
+// V1 Maniac doesn't have a ScummVar for VAR_TALK_ACTOR, and just uses
+// an internal variable. Emulate this to prevent overwriting script vars...
+// Maniac NES (V1), however, DOES have a ScummVar for VAR_TALK_ACTOR
+int ScummEngine::getTalkingActor() {
+	if (_game.id == GID_MANIAC && _game.version <= 1 && !(_game.platform == Common::kPlatformNES))
+		return _V1TalkingActor;
+	else
+		return VAR(VAR_TALK_ACTOR);
+}
+
+void ScummEngine::setTalkingActor(int value) {
+
+	if (value == 255) {
+		_system->clearFocusRectangle();
+	} else {
+		// Work out the screen co-ordinates of the actor
+		int x = _actors[value]._pos.x - (camera._cur.x - (_screenWidth >> 1));
+		int y = _actors[value]._top - (camera._cur.y - (_screenHeight >> 1));
+		
+		// Set the focus area to the calculated position
+		// TODO: Make the size adjust depending on what it's focusing on.
+		Common::Rect rect(x - 96, y - 64, x + 96, y + 64);
+		_system->setFocusRectangle(rect);
 	}
 
-	return 0;
+	if (_game.id == GID_MANIAC && _game.version <= 1 && !(_game.platform == Common::kPlatformNES))
+		_V1TalkingActor = value;
+	else
+		VAR(VAR_TALK_ACTOR) = value;
 }
 
-#ifndef DISABLE_HE
-int ScummEngine_v70he::getActorFromPos(int x, int y) {
-	int curActor, i;
+static const int c64MMActorTalkColor[25] = {
+	1, 7, 2, 14, 8, 15, 3, 7, 7, 15, 1, 13, 1, 4, 5, 5, 4, 3, 1, 5, 1, 1, 1, 1, 7
+};
+static const int v1MMActorTalkColor[25] = {
+	1, 7, 2, 14, 8, 1, 3, 7, 7, 12, 1, 13, 1, 4, 5, 5, 4, 3, 1, 5, 1, 1, 1, 7, 7
+};
 
-	if (!testGfxAnyUsageBits(x / 8))
-		return 0;
+void ScummEngine::resetV1ActorTalkColor() {
+	int i;
 
-	curActor = 0;
 	for (i = 1; i < _numActors; i++) {
-		if (testGfxUsageBit(x / 8, i) && !getClass(i, kObjectClassUntouchable)
-			&& y >= _actors[i]._top && y <= _actors[i]._bottom
-			&& (_actors[i]._pos.y > _actors[curActor]._pos.y || curActor == 0))
-				curActor = i;
+		if (_game.platform == Common::kPlatformC64) {
+			_actors[i]._talkColor = c64MMActorTalkColor[i];
+		} else {
+			_actors[i]._talkColor = v1MMActorTalkColor[i];
+		}
 	}
-
-	return curActor;
 }
-#endif
 
 #ifndef DISABLE_SCUMM_7_8
 void ScummEngine_v7::actorTalk(const byte *msg) {
@@ -1523,6 +1882,12 @@
 	}
 }
 
+
+#pragma mark -
+#pragma mark --- TODO ---
+#pragma mark -
+
+
 void Actor::setActorCostume(int c) {
 	int i;
 
@@ -1600,330 +1965,6 @@
 	}
 }
 
-void Actor::startWalkActor(int destX, int destY, int dir) {
-	AdjustBoxResult abr;
-
-	if (!isInCurrentRoom() && _vm->_game.version >= 7) {
-		debugC(DEBUG_ACTORS, "startWalkActor: attempting to walk actor %d who is not in this room", _number);
-		return;
-	}
-
-	if (_vm->_game.version <= 4) {
-		abr.x = destX;
-		abr.y = destY;
-	} else {
-		abr = adjustXYToBeInBox(destX, destY);
-	}
-
-	if (!isInCurrentRoom() && _vm->_game.version <= 6) {
-		_pos.x = abr.x;
-		_pos.y = abr.y;
-		if (!_ignoreTurns && dir != -1)
-			_facing = dir;
-		return;
-	}
-
-	if (_ignoreBoxes) {
-		abr.box = kInvalidBox;
-		_walkbox = kInvalidBox;
-	} else {
-		if (_vm->checkXYInBoxBounds(_walkdata.destbox, abr.x, abr.y)) {
-			abr.box = _walkdata.destbox;
-		} else {
-			abr = adjustXYToBeInBox(abr.x, abr.y);
-		}
-		if (_moving && _walkdata.destdir == dir && _walkdata.dest.x == abr.x && _walkdata.dest.y == abr.y)
-			return;
-	}
-
-	if (_pos.x == abr.x && _pos.y == abr.y) {
-		if (dir != _facing)
-			turnToDirection(dir);
-		return;
-	}
-
-	_walkdata.dest.x = abr.x;
-	_walkdata.dest.y = abr.y;
-	_walkdata.destbox = abr.box;
-	_walkdata.destdir = dir;
-	_moving = (_moving & MF_IN_LEG) | MF_NEW_LEG;
-	_walkdata.point3.x = 32000;
-
-	_walkdata.curbox = _walkbox;
-}
-
-void Actor::startWalkAnim(int cmd, int angle) {
-	if (angle == -1)
-		angle = _facing;
-
-	/* Note: walk scripts aren't required to make the Dig
-	 * work as usual
-	 */
-	if (_walkScript) {
-		int args[16];
-		memset(args, 0, sizeof(args));
-		args[0] = _number;
-		args[1] = cmd;
-		args[2] = angle;
-		_vm->runScript(_walkScript, 1, 0, args);
-	} else {
-		switch (cmd) {
-		case 1:										/* start walk */
-			setDirection(angle);
-			startAnimActor(_walkFrame);
-			break;
-		case 2:										/* change dir only */
-			setDirection(angle);
-			break;
-		case 3:										/* stop walk */
-			turnToDirection(angle);
-			startAnimActor(_standFrame);
-			break;
-		}
-	}
-}
-
-void Actor::walkActor() {
-	int new_dir, next_box;
-	Common::Point foundPath;
-
-	if (_vm->_game.version >= 7) {
-		if (_moving & MF_FROZEN) {
-			if (_moving & MF_TURN) {
-				new_dir = updateActorDirection(false);
-				if (_facing != new_dir)
-					setDirection(new_dir);
-				else
-					_moving &= ~MF_TURN;
-			}
-			return;
-		}
-	}
-
-	if (!_moving)
-		return;
-
-	if (!(_moving & MF_NEW_LEG)) {
-		if (_moving & MF_IN_LEG && actorWalkStep())
-			return;
-
-		if (_moving & MF_LAST_LEG) {
-			_moving = 0;
-			setBox(_walkdata.destbox);
-			if (_vm->_game.version <= 6) {
-				startAnimActor(_standFrame);
-				if (_targetFacing != _walkdata.destdir)
-					turnToDirection(_walkdata.destdir);
-			} else {
-				startWalkAnim(3, _walkdata.destdir);
-			}
-			return;
-		}
-
-		if (_moving & MF_TURN) {
-			new_dir = updateActorDirection(false);
-			if (_facing != new_dir)
-				setDirection(new_dir);
-			else
-				_moving = 0;
-			return;
-		}
-
-		setBox(_walkdata.curbox);
-		_moving &= MF_IN_LEG;
-	}
-
-	_moving &= ~MF_NEW_LEG;
-	do {
-
-		if (_walkbox == kInvalidBox) {
-			setBox(_walkdata.destbox);
-			_walkdata.curbox = _walkdata.destbox;
-			break;
-		}
-
-		if (_walkbox == _walkdata.destbox)
-			break;
-
-		next_box = _vm->getPathToDestBox(_walkbox, _walkdata.destbox);
-		if (next_box < 0) {
-			_walkdata.destbox = _walkbox;
-			_moving |= MF_LAST_LEG;
-			return;
-		}
-
-		_walkdata.curbox = next_box;
-
-		if (findPathTowards(_walkbox, next_box, _walkdata.destbox, foundPath))
-			break;
-
-		if (calcMovementFactor(foundPath))
-			return;
-
-		setBox(_walkdata.curbox);
-	} while (1);
-
-	_moving |= MF_LAST_LEG;
-	calcMovementFactor(_walkdata.dest);
-}
-
-/*
-void Actor::walkActorV12() {
-	Common::Point foundPath, tmp;
-	int new_dir, next_box;
-
-	if (_moving & MF_TURN) {
-		new_dir = updateActorDirection(false);
-		if (_facing != new_dir)
-			setDirection(new_dir);
-		else
-			_moving = 0;
-		return;
-	}
-
-	if (!_moving)
-		return;
-
-	if (_moving & MF_IN_LEG) {
-		actorWalkStep();
-	} else {
-		if (_moving & MF_LAST_LEG) {
-			_moving = 0;
-			startAnimActor(_standFrame);
-			if (_targetFacing != _walkdata.destdir)
-				turnToDirection(_walkdata.destdir);
-		} else {
-			setBox(_walkdata.curbox);
-			if (_walkbox == _walkdata.destbox) {
-				foundPath = _walkdata.dest;
-				_moving |= MF_LAST_LEG;
-			} else {
-				next_box = _vm->getPathToDestBox(_walkbox, _walkdata.destbox);
-				if (next_box < 0) {
-					_moving |= MF_LAST_LEG;
-					return;
-				}
-
-				// Can't walk through locked boxes
-				int flags = _vm->getBoxFlags(next_box);
-				if (flags & kBoxLocked && !(flags & kBoxPlayerOnly && !isPlayer())) {
-					_moving |= MF_LAST_LEG;
-				}
-
-				_walkdata.curbox = next_box;
-
-				getClosestPtOnBox(_vm->getBoxCoordinates(_walkdata.curbox), x, y, tmp.x, tmp.y);
-				getClosestPtOnBox(_vm->getBoxCoordinates(_walkbox), tmp.x, tmp.y, foundPath.x, foundPath.y);
-			}
-			calcMovementFactor(foundPath);
-		}
-	}
-}
-*/
-
-void Actor::walkActorOld() {
-	Common::Point p2, p3;	// Gate locations
-	int new_dir, next_box;
-
-	if (!_moving)
-		return;
-
-	if (!(_moving & MF_NEW_LEG)) {
-		if (_moving & MF_IN_LEG && actorWalkStep())
-			return;
-
-		if (_moving & MF_LAST_LEG) {
-			_moving = 0;
-			startAnimActor(_standFrame);
-			if (_targetFacing != _walkdata.destdir)
-				turnToDirection(_walkdata.destdir);
-			return;
-		}
-
-		if (_moving & MF_TURN) {
-			new_dir = updateActorDirection(false);
-			if (_facing != new_dir)
-				setDirection(new_dir);
-			else
-				_moving = 0;
-			return;
-		}
-
-		if (_walkdata.point3.x != 32000) {
-			if (calcMovementFactor(_walkdata.point3)) {
-				_walkdata.point3.x = 32000;
-				return;
-			}
-			_walkdata.point3.x = 32000;
-		}
-
-		setBox(_walkdata.curbox);
-		_moving &= MF_IN_LEG;
-	}
-
-	_moving &= ~MF_NEW_LEG;
-	do {
-		if (_walkbox == kInvalidBox) {
-			setBox(_walkdata.destbox);
-			_walkdata.curbox = _walkdata.destbox;
-			break;
-		}
-
-		if (_walkbox == _walkdata.destbox)
-			break;
-
-		next_box = _vm->getPathToDestBox(_walkbox, _walkdata.destbox);
-
-		// WORKAROUND: To fully fix bug #774783, we add a special case
-		// here, resulting in a different next_box value for Hitler.
-		if ((_vm->_game.id == GID_INDY3) && _vm->_roomResource == 46 && _walkbox == 1 && _walkdata.destbox == 0 && _number == 9)
-			next_box = 1;
-
-		if (next_box < 0) {
-			_moving |= MF_LAST_LEG;
-			return;
-		}
-
-		// Can't walk through locked boxes
-		int flags = _vm->getBoxFlags(next_box);
-		if (flags & kBoxLocked && !(flags & kBoxPlayerOnly && !isPlayer())) {
-			_moving |= MF_LAST_LEG;
-// FIXME: Work in progress
-//			_walkdata.destdir = _facing;
-			return;
-		}
-
-		_walkdata.curbox = next_box;
-
-		if (_vm->_game.version <= 2) {
-			getClosestPtOnBox(_vm->getBoxCoordinates(_walkdata.curbox), _pos.x, _pos.y, p2.x, p2.y);
-			getClosestPtOnBox(_vm->getBoxCoordinates(_walkbox), p2.x, p2.y, p3.x, p3.y);
-// FIXME: Work in progress
-//			calcMovementFactor(p3);
-//			return;
-		} else {
-			findPathTowardsOld(_walkbox, next_box, _walkdata.destbox, p2, p3);
-			if (p2.x == 32000 && p3.x == 32000) {
-				break;
-			}
-
-			if (p2.x != 32000) {
-				if (calcMovementFactor(p2)) {
-					_walkdata.point3 = p3;
-					return;
-				}
-			}
-		}
-		if (calcMovementFactor(p3))
-			return;
-
-		setBox(_walkdata.destbox);
-	} while (1);
-
-	_moving |= MF_LAST_LEG;
-	calcMovementFactor(_walkdata.dest);
-}
-
 byte *Actor::getActorName() {
 	byte *ptr = _vm->getResourceAddress(rtActorName, _number);
 	if (ptr == NULL) {

Modified: scummvm/trunk/engines/scumm/scumm.h
===================================================================
--- scummvm/trunk/engines/scumm/scumm.h	2006-10-18 14:01:06 UTC (rev 24366)
+++ scummvm/trunk/engines/scumm/scumm.h	2006-10-18 14:01:28 UTC (rev 24367)
@@ -897,8 +897,6 @@
 	Actor *derefActor(int id, const char *errmsg = 0) const;
 	Actor *derefActorSafe(int id, const char *errmsg) const;
 
-	int getAngleFromPos(int x, int y) const;
-
 protected:
 	void walkActors();
 	void playActorSounds();


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