[Scummvm-cvs-logs] scummvm master -> dcd0f597e6026e248ff6e2db0224f3f60626cdca
Kirben
kirben at optusnet.com.au
Sun Dec 7 05:10:33 CET 2014
This automated email contains information about 5 new commits which have been
pushed to the 'scummvm' repo located at https://github.com/scummvm/scummvm .
Summary:
2dbd99d572 SCUMM: Maniac V0: Implement the original Walk Code (to fix some anim glitches), fix opcode to use _moving correctly (as
29d46e8a10 SCUMM: Maniac V0: If boxes are neighbors, walk directly to the new box. Remove extra call to 'animateCostume'. Remove no
814d9b1153 SCUMM: Maniac V0: Correctly handle 'slanted' walk-boxes, Add new variables to save-games, Bump the SaveGame Version numb
4b1b9ec66f SCUMM: Maniac V0: Remove workaround for bug #2971126 (this issue no longer occurs as walking is handled the same as the
dcd0f597e6 Merge pull request #539 from segrax/master
Commit: 2dbd99d57264bab012cebd064eadfc34050832b1
https://github.com/scummvm/scummvm/commit/2dbd99d57264bab012cebd064eadfc34050832b1
Author: Robert Crossfield (robcrossfield at gmail.com)
Date: 2014-11-28T22:24:45+11:00
Commit Message:
SCUMM: Maniac V0: Implement the original Walk Code (to fix some anim glitches), fix opcode to use _moving correctly (as V0 is different)
Changed paths:
engines/scumm/actor.cpp
engines/scumm/actor.h
engines/scumm/script.cpp
engines/scumm/script_v0.cpp
engines/scumm/verbs.cpp
diff --git a/engines/scumm/actor.cpp b/engines/scumm/actor.cpp
index 116a953..1ea1f6e 100644
--- a/engines/scumm/actor.cpp
+++ b/engines/scumm/actor.cpp
@@ -250,8 +250,11 @@ void Actor::stopActorMoving() {
_vm->stopScript(_walkScript);
_moving = 0;
- if (_vm->_game.version == 0)
+
+ if (_vm->_game.version == 0) {
+ _moving = 2;
setDirection(_facing);
+ }
}
void Actor::setActorWalkSpeed(uint newSpeedX, uint newSpeedY) {
@@ -447,7 +450,11 @@ void Actor::startWalkActor(int destX, int destY, int dir) {
_walkdata.dest.y = abr.y;
_walkdata.destbox = abr.box;
_walkdata.destdir = dir;
- _moving = (_moving & MF_IN_LEG) | MF_NEW_LEG;
+ if(_vm->_game.version != 0 ) {
+ _moving = (_moving & MF_IN_LEG) | MF_NEW_LEG;
+ } else {
+ ((Actor_v0*)this)->unk_FDE1 = 1;
+ }
_walkdata.point3.x = 32000;
_walkdata.curbox = _walkbox;
@@ -651,6 +658,403 @@ bool Actor_v0::checkWalkboxesHaveDirectPath(Common::Point &foundPath) {
return false;
}
+bool Actor_v0::sub_2F6F() {
+ _walkDirX = 0;
+ _walkDirY = 0;
+ _walkYCountGreaterThanXCount = 0;
+ uint16 A = 0;
+
+ if (_CurrentWalkTo.x >= _tmp_Dest.x ) {
+ A = _CurrentWalkTo.x - _tmp_Dest.x;
+ _walkDirX = 1;
+ } else {
+ A = _tmp_Dest.x - _CurrentWalkTo.x;
+ }
+
+ _walkXCountInc = A;
+
+ if (_CurrentWalkTo.y >= _tmp_Dest.y ) {
+ A = _CurrentWalkTo.y - _tmp_Dest.y;
+ _walkDirY = 1;
+ } else {
+ A = _tmp_Dest.y - _CurrentWalkTo.y;
+ }
+
+ _walkYCountInc = A;
+ if ( !_walkXCountInc && !_walkYCountInc )
+ return true;
+
+ if( _walkXCountInc <= _walkYCountInc )
+ _walkYCountGreaterThanXCount = 1;
+
+ // 2FCC
+ A = _walkXCountInc;
+ if( A <= _walkYCountInc )
+ A = _walkYCountInc;
+
+ _walkMaxXYCountInc = A;
+ _walkXCount = _walkXCountInc;
+ _walkYCount = _walkYCountInc;
+ _walkCountModulo = _walkMaxXYCountInc;
+
+ return false;
+}
+
+byte Actor_v0::updateWalkbox() {
+ if( _vm->checkXYInBoxBounds( _walkbox, _pos.x, _pos.y ) )
+ return 0;
+
+ int numBoxes = _vm->getNumBoxes() - 1;
+ for (int i = 0; i <= numBoxes; i++) {
+ if (_vm->checkXYInBoxBounds( i, _pos.x, _pos.y ) == true ) {
+ if (_walkdata.curbox == i ) {
+ setBox(i);
+
+ unk_FDE1 = 1;
+ return i;
+ }
+ }
+ }
+
+ return 0xFF;
+}
+
+void Actor_v0::setTmpFromActor() {
+ _tmp_Pos = _pos;
+ _pos = _tmp_Dest;
+ _tmp_WalkBox = _walkbox;
+ _tmp_CB5F = unk_FDE1;
+}
+
+void Actor_v0::setActorFromTmp() {
+ _pos = _tmp_Pos;
+ _tmp_Dest = _tmp_Pos;
+ _walkbox = _tmp_WalkBox;
+ unk_FDE1 = _tmp_CB5F;
+}
+
+byte Actor_v0::actorWalkX() {
+ byte A = _walkXCount;
+ A += _walkXCountInc;
+ if (A >= _walkCountModulo) {
+ if (!_walkDirX ) {
+ _tmp_Dest.x--;
+ } else {
+ _tmp_Dest.x++;
+ }
+
+ A -= _walkCountModulo;
+ }
+ // 2EAC
+ _walkXCount = A;
+ setTmpFromActor();
+ if( updateWalkbox() == 0xFF ) {
+ // 2EB9
+ setActorFromTmp();
+
+ return 3;
+ }
+ // 2EBF
+ if( _tmp_Dest.x == _CurrentWalkTo.x )
+ return 1;
+
+ return 0;
+}
+
+byte Actor_v0::actorWalkY() {
+
+ byte A = _walkYCount;
+ A += _walkYCountInc;
+ if (A >= _walkCountModulo) {
+ if (!_walkDirY ) {
+ _tmp_Dest.y--;
+ } else {
+ _tmp_Dest.y++;
+ }
+
+ A -= _walkCountModulo;
+ }
+ // 2EEB
+ _walkYCount = A;
+ setTmpFromActor();
+ if (updateWalkbox() == 0xFF) {
+ // 2EF8
+ setActorFromTmp();
+ return 4;
+ }
+
+ // 2EFE
+ if (_walkYCountInc != 0) {
+ if (_walkYCountInc == 0xFF ) {
+ setActorFromTmp();
+ return 4;
+ }
+ }
+
+ // 2F0D
+ if (_CurrentWalkTo.y == _tmp_Dest.y)
+ return 1;
+
+ return 0;
+}
+
+byte Actor_v0::walkboxFindTarget() {
+ return 0xff;
+}
+
+void Actor_v0::actorSetWalkTo() {
+
+ if (unk_FDE1 == 0 )
+ return;
+
+ unk_FDE1 = 0;
+ byte nextBox = _vm->getNextBox(_walkbox, _walkdata.destbox);
+
+ if (nextBox != 0xFF && nextBox != _walkbox ) {
+ Common::Point tmp;
+ _walkdata.curbox = nextBox;
+
+ getClosestPtOnBox(_vm->getBoxCoordinates(nextBox), _pos.x, _pos.y, _NewWalkTo.x, _NewWalkTo.y);
+ //getClosestPtOnBox(_vm->getBoxCoordinates(_walkbox), tmp.x, tmp.y, _NewWalkTo.x, _NewWalkTo.y);
+
+
+ } else {
+ if( _walkdata.dest.x == -1 )
+ _NewWalkTo = _CurrentWalkTo;
+ else
+ _NewWalkTo = _walkdata.dest;
+ }
+}
+
+void Actor_v0::walkActor() {
+ actorSetWalkTo();
+
+ _needRedraw = true;
+ if (_NewWalkTo != _CurrentWalkTo) {
+
+ // 2A27
+ _CurrentWalkTo = _NewWalkTo;
+
+loc_2A33:;
+ _moving &= 0xF0;
+ _tmp_Dest = _pos;
+
+ byte tmp = sub_2F6F();
+ _moving &= 0xF0;
+ _moving |= tmp;
+
+ if (!_walkYCountGreaterThanXCount) {
+ if (_walkDirX) {
+ _targetFacing = getAngleFromPos(V12_X_MULTIPLIER*1, V12_Y_MULTIPLIER*0, false);
+ } else {
+ _targetFacing = getAngleFromPos(V12_X_MULTIPLIER*-1, V12_Y_MULTIPLIER*0, false);
+ }
+ } else {
+ if (_walkDirY) {
+ _targetFacing = getAngleFromPos(V12_X_MULTIPLIER*0, V12_Y_MULTIPLIER*1, false);
+ } else {
+ _targetFacing = getAngleFromPos(V12_X_MULTIPLIER*0, V12_Y_MULTIPLIER*-1, false);
+ }
+ }
+
+ directionUpdate();
+
+ if (_moving & 0x80 )
+ return;
+
+ animateActor(newDirToOldDir(_facing));
+
+ } else {
+ // 2A0A
+ if ((_moving & 0x7F) != 1) {
+
+ if (_NewWalkTo == _pos) {
+ return;
+ }
+ }
+ }
+
+
+ // 2A9A
+ if (_moving == 2 )
+ return;
+
+ if ((_moving & 0x0F) == 1 )
+ return stopActorMoving();
+
+ // 2AAD
+ if (_moving & 0x80) {
+ directionUpdate();
+
+ if ((_moving & 0x80) )
+ return;
+
+ // 2AC2
+ animateActor(newDirToOldDir(_facing));
+ }
+
+ // 2ACE
+ if ((_moving & 0x0F) == 3 ) {
+loc_2C36:;
+ // 2C36
+ setTmpFromActor();
+
+ if (!_walkDirX ) {
+ _pos.x--;
+ } else {
+ _pos.x++;
+ }
+
+ // 2C51
+ if (updateWalkbox() != 0xFF) {
+ //2C66
+ setActorFromTmp();
+ goto loc_2A33;
+ }
+
+ // 2C6C
+ setActorFromTmp();
+
+ if (_CurrentWalkTo.y == _tmp_Dest.y) {
+ stopActorMoving();
+ return;
+ }
+
+ if (!_walkDirY) {
+ _tmp_Dest.y--;
+ } else {
+ _tmp_Dest.y++;
+ }
+ setTmpFromActor();
+ //2C8B
+ byte A = updateWalkbox();
+ if (A == 0xFF) {
+ setActorFromTmp();
+ stopActorMoving();
+ return;
+ }
+ // 2C98: Yes, an exact copy of what just occured.. the original does this, so im doing it...
+ // Just to keep me sane when going over it :)
+ if (A == 0xFF) {
+ setActorFromTmp();
+ stopActorMoving();
+ return;
+ }
+ return;
+ }
+
+ // 2ADA
+ if ((_moving & 0x0F) == 4 ) {
+ // 2CA3
+loc_2CA3:;
+ setTmpFromActor();
+
+ if (!_walkDirY) {
+ _pos.y--;
+ } else {
+ _pos.y++;
+ }
+ if (updateWalkbox() == 0xFF ) {
+ // 2CC7
+ setActorFromTmp();
+ if( _CurrentWalkTo.x == _tmp_Dest.x ) {
+ stopActorMoving();
+ return;
+ }
+ // 2CD5
+ if (!_walkDirX ) {
+ _tmp_Dest.x--;
+ } else {
+ _tmp_Dest.x++;
+ }
+ setTmpFromActor();
+
+ if (updateWalkbox() == 0xFF ) {
+ setActorFromTmp();
+ stopActorMoving();
+ }
+
+ return;
+ } else {
+ setActorFromTmp();
+ goto loc_2A33;
+ }
+ }
+
+ if ((_moving & 0x0F) == 0 ) {
+ // 2AE8
+ byte A = actorWalkX();
+
+ if( A == 1 ) {
+ A = actorWalkY();
+ if( A == 1 ) {
+ // 2AF6
+ _moving &= 0xF0;
+ _moving |= A;
+ } else {
+ // 2B04
+ if( A == 4 )
+ stopActorMoving();
+ }
+
+ return;
+
+ } else {
+ // 2B0C
+ if (A == 3) {
+ _moving &= 0xF0;
+ _moving |= A;
+
+ if (_walkDirY) {
+ _targetFacing = getAngleFromPos(V12_X_MULTIPLIER*0, V12_Y_MULTIPLIER*1, false);
+ } else {
+ _targetFacing = getAngleFromPos(V12_X_MULTIPLIER*0, V12_Y_MULTIPLIER*-1, false);
+ }
+
+ directionUpdate();
+ animateActor(newDirToOldDir(_facing));
+ goto loc_2C36;
+
+ } else {
+ // 2B39
+ A = actorWalkY();
+ if (A != 4 )
+ return;
+
+ // 2B46
+ _moving &= 0xF0;
+ _moving |= A;
+
+ if (_walkDirX) {
+ _targetFacing = getAngleFromPos(V12_X_MULTIPLIER*1, V12_Y_MULTIPLIER*0, false);
+ } else {
+ _targetFacing = getAngleFromPos(V12_X_MULTIPLIER*-1, V12_Y_MULTIPLIER*0, false);
+ }
+
+ directionUpdate();
+ animateActor(newDirToOldDir(_facing));
+ goto loc_2CA3;
+ }
+ }
+ }
+}
+
+void Actor_v0::directionUpdate() {
+
+ int nextFacing = updateActorDirection(true);
+ if (_facing != nextFacing) {
+ // 2A89
+ setDirection(nextFacing);
+
+ if (_facing != _targetFacing ) {
+ _moving |= 0x80;
+ } else {
+ _moving &= ~0x80;
+ }
+ } else
+ _moving &= ~0x80;
+}
+
void Actor_v2::walkActor() {
Common::Point foundPath, tmp;
int new_dir, next_box;
@@ -985,18 +1389,16 @@ void Actor_v0::setDirection(int direction) {
break;
case 2:
- res = 6; // Face Away
+ res = 6; // Face Camera
break;
default:
- res = 7; // Face Camera
+ res = 7; // Face Away
break;
}
_animFrameRepeat = -1;
animateActor(res);
- if (_moving)
- animateCostume();
}
void Actor::faceToObject(int obj) {
@@ -1017,8 +1419,14 @@ void Actor::turnToDirection(int newdir) {
return;
if (_vm->_game.version <= 6) {
- _moving = MF_TURN;
_targetFacing = newdir;
+
+ if (_vm->_game.version == 0 ) {
+ setDirection( newdir );
+ return;
+ }
+ _moving = MF_TURN;
+
} else {
_moving &= ~MF_TURN;
if (newdir != _facing) {
@@ -1085,8 +1493,14 @@ void Actor::putActor(int dstX, int dstY, int newRoom) {
}
// V0 always sets the actor to face the camera upon entering a room
- if (_vm->_game.version == 0)
+ if (_vm->_game.version == 0) {
+ _walkdata.dest = _pos;
+
+ ((Actor_v0*)this)->unk_FDE1 = 1;
+ ((Actor_v0*)this)->_CurrentWalkTo = _pos;
+
setDirection(oldDirToNewDir(2));
+ }
}
static bool inBoxQuickReject(const BoxCoords &box, int x, int y, int threshold) {
@@ -1410,6 +1824,7 @@ void Actor::showActor() {
Actor_v0 *a = ((Actor_v0 *)this);
a->_costCommand = a->_costCommandNew = 0xFF;
+
for (int i = 0; i < 8; ++i) {
a->_limbFrameRepeat[i] = 0;
@@ -1659,8 +2074,15 @@ void ScummEngine::processActors() {
// would hence cause regressions. See also the other big
// comment further up in this method for some details.
if (a->_costume) {
+
+ if (_game.version == 0)
+ a->animateCostume();
+
a->drawActorCostume();
- a->animateCostume();
+
+ if (_game.version != 0)
+ a->animateCostume();
+
}
}
}
diff --git a/engines/scumm/actor.h b/engines/scumm/actor.h
index 46dc7d0..b2245da 100644
--- a/engines/scumm/actor.h
+++ b/engines/scumm/actor.h
@@ -354,6 +354,27 @@ public:
byte _miscflags;
byte _speaking;
+ Common::Point _CurrentWalkTo, _NewWalkTo;
+
+ byte _walkDirX;
+ byte _walkDirY;
+
+ byte _walkYCountGreaterThanXCount;
+ byte _walkXCount;
+ byte _walkXCountInc;
+ byte _walkYCount;
+ byte _walkYCountInc;
+ byte _walkCountModulo;
+
+ byte _walkMaxXYCountInc;
+
+ byte unk_FDE1;
+
+ Common::Point _tmp_Pos;
+ Common::Point _tmp_Dest;
+ byte _tmp_WalkBox;
+ byte _tmp_CB5F;
+
int8 _animFrameRepeat;
int8 _limbFrameRepeatNew[8];
int8 _limbFrameRepeat[8];
@@ -363,16 +384,27 @@ public:
public:
Actor_v0(ScummEngine *scumm, int id) : Actor_v2(scumm, id) {}
- virtual void initActor(int mode);
- virtual void animateActor(int anim);
- virtual void animateCostume();
+ void initActor(int mode);
+ void animateActor(int anim);
+ void animateCostume();
void limbFrameCheck(int limb);
+ void directionUpdate();
void speakCheck();
- virtual void setDirection(int direction);
+ void setDirection(int direction);
void startAnimActor(int f);
+ bool sub_2F6F();
+ void walkActor();
+ void actorSetWalkTo();
+ byte actorWalkX();
+ byte actorWalkY();
+ byte updateWalkbox();
+ byte walkboxFindTarget();
+ void setTmpFromActor();
+ void setActorFromTmp();
+
// Used by the save/load system:
virtual void saveLoadWithSerializer(Serializer *ser);
diff --git a/engines/scumm/script.cpp b/engines/scumm/script.cpp
index 2fe5333..efd5e7b 100644
--- a/engines/scumm/script.cpp
+++ b/engines/scumm/script.cpp
@@ -1179,7 +1179,7 @@ bool ScummEngine_v0::checkPendingWalkAction() {
Actor_v0 *a = (Actor_v0 *)derefActor(actor, "checkPendingWalkAction");
// wait until walking or turning action is finished
- if (a->_moving)
+ if (a->_moving!=2)
return true;
// after walking and turning finally execute the script
diff --git a/engines/scumm/script_v0.cpp b/engines/scumm/script_v0.cpp
index af39fda..6cbfbf4 100644
--- a/engines/scumm/script_v0.cpp
+++ b/engines/scumm/script_v0.cpp
@@ -589,9 +589,9 @@ void ScummEngine_v0::o_loadRoomWithEgo() {
return;
}
- // The original interpreter sets the actors new room X/Y to the last rooms X/Y
- // This fixes a problem with MM: script 158 in room 12, the 'Oomph!' script
- // This scripts runs before the actor position is set to the correct room entry location
+ // The original interpreter seems to set the actors new room X/Y to the last rooms X/Y
+ // This fixes a problem with MM: script 158 in room 12, the 'Oompf!' script
+ // This scripts runs before the actor position is set to the correct location
a->putActor(a->getPos().x, a->getPos().y, room);
_egoPositioned = false;
@@ -714,10 +714,8 @@ void ScummEngine_v0::o_getActorMoving() {
getResultPos();
int act = getVarOrDirectByte(PARAM_1);
Actor *a = derefActor(act, "o_getActorMoving");
- if (a->_moving)
- setResult(1);
- else
- setResult(2);
+
+ setResult(a->_moving);
}
void ScummEngine_v0::o_putActorAtObject() {
diff --git a/engines/scumm/verbs.cpp b/engines/scumm/verbs.cpp
index fdb98a8..c1bafe1 100644
--- a/engines/scumm/verbs.cpp
+++ b/engines/scumm/verbs.cpp
@@ -717,7 +717,6 @@ void ScummEngine_v0::verbExec() {
if (a->_miscflags & kActorMiscFlagFreeze)
return;
- a->stopActorMoving();
a->startWalkActor(VAR(6), VAR(7), -1);
}
Commit: 29d46e8a10b7fae45d833bee0e7d3e4e62d75c5c
https://github.com/scummvm/scummvm/commit/29d46e8a10b7fae45d833bee0e7d3e4e62d75c5c
Author: Robert Crossfield (robcrossfield at gmail.com)
Date: 2014-11-29T09:07:10+11:00
Commit Message:
SCUMM: Maniac V0: If boxes are neighbors, walk directly to the new box. Remove extra call to 'animateCostume'. Remove now unnecessary V0 walk calc functions
Changed paths:
engines/scumm/actor.cpp
engines/scumm/actor.h
engines/scumm/boxes.cpp
engines/scumm/script_v0.cpp
engines/scumm/scumm_v0.h
engines/scumm/verbs.cpp
diff --git a/engines/scumm/actor.cpp b/engines/scumm/actor.cpp
index 1ea1f6e..636f718 100644
--- a/engines/scumm/actor.cpp
+++ b/engines/scumm/actor.cpp
@@ -33,6 +33,7 @@
#include "scumm/resource.h"
#include "scumm/saveload.h"
#include "scumm/scumm_v7.h"
+#include "scumm/scumm_v0.h"
#include "scumm/he/sound_he.h"
#include "scumm/he/sprite_he.h"
#include "scumm/usage_bits.h"
@@ -453,7 +454,7 @@ void Actor::startWalkActor(int destX, int destY, int dir) {
if(_vm->_game.version != 0 ) {
_moving = (_moving & MF_IN_LEG) | MF_NEW_LEG;
} else {
- ((Actor_v0*)this)->unk_FDE1 = 1;
+ ((Actor_v0*)this)->_newWalkBoxEntered = 1;
}
_walkdata.point3.x = 32000;
@@ -574,91 +575,7 @@ void Actor::walkActor() {
calcMovementFactor(_walkdata.dest);
}
-bool Actor_v2::checkWalkboxesHaveDirectPath(Common::Point &foundPath) {
- // only MM v0 supports walking in direct line between walkboxes.
- // MM v1 already does not support it anymore.
- return false;
-}
-
-bool Actor_v0::intersectLineSegments(const Common::Point &line1Start, const Common::Point &line1End,
- const Common::Point &line2Start, const Common::Point &line2End, Common::Point &result)
-{
- const Common::Point v1 = line1End - line1Start; // line1(n1) = line1Start + n1 * v1
- const Common::Point v2 = line2End - line2Start; // line2(n2) = line2Start + n2 * v2
-
- double det = v2.x * v1.y - v1.x * v2.y;
- if (det == 0)
- return false;
-
- double n1 = ((double)v2.x * (line2Start.y - line1Start.y) -
- (double)v2.y * (line2Start.x - line1Start.x)) / det;
- double n2 = ((double)v1.x * (line2Start.y - line1Start.y) -
- (double)v1.y * (line2Start.x - line1Start.x)) / det;
-
- // both coefficients have to be in [0, 1], otherwise the intersection is
- // not inside of at least one of the two line segments
- if (n1 < 0.0 || n1 > 1.0 || n2 < 0.0 || n2 > 1.0)
- return false;
-
- result.x = line1Start.x + (int)(n1 * v1.x);
- result.y = line1Start.y + (int)(n1 * v1.y);
- return true;
-}
-
-/*
- * MM v0 allows the actor to walk in a direct line between boxes to the target
- * if actor and target share a horizontal or vertical corridor.
- * If such a corridor is found the actor is not forced to go horizontally or
- * vertically from one box to the next but can also walk diagonally.
- *
- * Note: the original v0 interpreter sets the target destination for diagonal
- * walking only once and then rechecks whenever the actor reaches a new box if the
- * walk destination is still suitable for the current box.
- * ScummVM does not perform such a check, so it is possible to leave the walkboxes
- * in some cases, for example L-shaped rooms like the swimming pool (actor walks over water)
- * or the medical room (actor walks over examination table).
- * To solve this we intersect the new walk destination with the actor's walkbox borders,
- * so a recheck is done when the actor leaves his box. This is done by the
- * intersectLineSegments() routine calls.
- */
-bool Actor_v0::checkWalkboxesHaveDirectPath(Common::Point &foundPath) {
- BoxCoords boxCoords = _vm->getBoxCoordinates(_walkbox);
- BoxCoords curBoxCoords = _vm->getBoxCoordinates(_walkdata.curbox);
-
- // check if next walkbox is left or right to actor's box
- if (boxCoords.ll.x > curBoxCoords.lr.x || boxCoords.lr.x < curBoxCoords.ll.x) {
- // determine horizontal corridor gates
- int gateUpper = MAX(boxCoords.ul.y, curBoxCoords.ul.y);
- int gateLower = MIN(boxCoords.ll.y, curBoxCoords.ll.y);
-
- // check if actor and target are in the same horizontal corridor between the boxes
- if ((_pos.y >= gateUpper && _pos.y <= gateLower) &&
- (_walkdata.dest.y >= gateUpper && _walkdata.dest.y <= gateLower)) {
- if (boxCoords.ll.x > curBoxCoords.lr.x) // next box is left
- return intersectLineSegments(_pos, _walkdata.dest, boxCoords.ll, boxCoords.ul, foundPath);
- else // next box is right
- return intersectLineSegments(_pos, _walkdata.dest, boxCoords.lr, boxCoords.ur, foundPath);
- }
- // check if next walkbox is above or below actor's box
- } else if (boxCoords.ul.y > curBoxCoords.ll.y || boxCoords.ll.y < curBoxCoords.ul.y) {
- // determine vertical corridor gates
- int gateLeft = MAX(boxCoords.ll.x, curBoxCoords.ll.x);
- int gateRight = MIN(boxCoords.lr.x, curBoxCoords.lr.x);
-
- // check if actor and target are in the same vertical corridor between the boxes
- if ((_pos.x >= gateLeft && _pos.x <= gateRight) &&
- (_walkdata.dest.x >= gateLeft && _walkdata.dest.x <= gateRight)) {
- if (boxCoords.ul.y > curBoxCoords.ll.y) // next box is above
- return intersectLineSegments(_pos, _walkdata.dest, boxCoords.ul, boxCoords.ur, foundPath);
- else // next box is below
- return intersectLineSegments(_pos, _walkdata.dest, boxCoords.ll, boxCoords.lr, foundPath);
- }
- }
-
- return false;
-}
-
-bool Actor_v0::sub_2F6F() {
+bool Actor_v0::calcWalkDistances() {
_walkDirX = 0;
_walkDirY = 0;
_walkYCountGreaterThanXCount = 0;
@@ -710,7 +627,7 @@ byte Actor_v0::updateWalkbox() {
if (_walkdata.curbox == i ) {
setBox(i);
- unk_FDE1 = 1;
+ _newWalkBoxEntered = 1;
return i;
}
}
@@ -723,14 +640,14 @@ void Actor_v0::setTmpFromActor() {
_tmp_Pos = _pos;
_pos = _tmp_Dest;
_tmp_WalkBox = _walkbox;
- _tmp_CB5F = unk_FDE1;
+ _tmp_NewWalkBoxEntered = _newWalkBoxEntered;
}
void Actor_v0::setActorFromTmp() {
_pos = _tmp_Pos;
_tmp_Dest = _tmp_Pos;
_walkbox = _tmp_WalkBox;
- unk_FDE1 = _tmp_CB5F;
+ _newWalkBoxEntered = _tmp_NewWalkBoxEntered;
}
byte Actor_v0::actorWalkX() {
@@ -748,21 +665,20 @@ byte Actor_v0::actorWalkX() {
// 2EAC
_walkXCount = A;
setTmpFromActor();
- if( updateWalkbox() == 0xFF ) {
+ if (updateWalkbox() == 0xFF) {
// 2EB9
setActorFromTmp();
return 3;
}
// 2EBF
- if( _tmp_Dest.x == _CurrentWalkTo.x )
+ if (_tmp_Dest.x == _CurrentWalkTo.x)
return 1;
return 0;
}
byte Actor_v0::actorWalkY() {
-
byte A = _walkYCount;
A += _walkYCountInc;
if (A >= _walkCountModulo) {
@@ -782,15 +698,13 @@ byte Actor_v0::actorWalkY() {
setActorFromTmp();
return 4;
}
-
// 2EFE
if (_walkYCountInc != 0) {
- if (_walkYCountInc == 0xFF ) {
+ if (_walkYCountInc == 0xFF) {
setActorFromTmp();
return 4;
}
}
-
// 2F0D
if (_CurrentWalkTo.y == _tmp_Dest.y)
return 1;
@@ -798,31 +712,33 @@ byte Actor_v0::actorWalkY() {
return 0;
}
-byte Actor_v0::walkboxFindTarget() {
- return 0xff;
-}
+void Actor_v0::directionUpdate() {
+
+ int nextFacing = updateActorDirection(true);
+ if (_facing != nextFacing) {
+ // 2A89
+ setDirection(nextFacing);
+
+ // Still need to turn?
+ if (_facing != _targetFacing ) {
+ _moving |= 0x80;
+ return;
+ }
+ }
+
+ _moving &= ~0x80;
+}
void Actor_v0::actorSetWalkTo() {
- if (unk_FDE1 == 0 )
+ if (_newWalkBoxEntered == 0)
return;
- unk_FDE1 = 0;
- byte nextBox = _vm->getNextBox(_walkbox, _walkdata.destbox);
+ _newWalkBoxEntered = 0;
- if (nextBox != 0xFF && nextBox != _walkbox ) {
- Common::Point tmp;
+ int nextBox = ((ScummEngine_v0*)_vm)->walkboxFindTarget( this, _walkdata.destbox, _walkdata.dest );
+ if (nextBox != 0xFF) {
_walkdata.curbox = nextBox;
-
- getClosestPtOnBox(_vm->getBoxCoordinates(nextBox), _pos.x, _pos.y, _NewWalkTo.x, _NewWalkTo.y);
- //getClosestPtOnBox(_vm->getBoxCoordinates(_walkbox), tmp.x, tmp.y, _NewWalkTo.x, _NewWalkTo.y);
-
-
- } else {
- if( _walkdata.dest.x == -1 )
- _NewWalkTo = _CurrentWalkTo;
- else
- _NewWalkTo = _walkdata.dest;
}
}
@@ -839,7 +755,7 @@ loc_2A33:;
_moving &= 0xF0;
_tmp_Dest = _pos;
- byte tmp = sub_2F6F();
+ byte tmp = calcWalkDistances();
_moving &= 0xF0;
_moving |= tmp;
@@ -859,7 +775,7 @@ loc_2A33:;
directionUpdate();
- if (_moving & 0x80 )
+ if (_moving & 0x80)
return;
animateActor(newDirToOldDir(_facing));
@@ -876,17 +792,17 @@ loc_2A33:;
// 2A9A
- if (_moving == 2 )
+ if (_moving == 2)
return;
- if ((_moving & 0x0F) == 1 )
+ if ((_moving & 0x0F) == 1)
return stopActorMoving();
// 2AAD
if (_moving & 0x80) {
directionUpdate();
- if ((_moving & 0x80) )
+ if (_moving & 0x80)
return;
// 2AC2
@@ -899,7 +815,7 @@ loc_2C36:;
// 2C36
setTmpFromActor();
- if (!_walkDirX ) {
+ if (!_walkDirX) {
_pos.x--;
} else {
_pos.x++;
@@ -944,7 +860,7 @@ loc_2C36:;
}
// 2ADA
- if ((_moving & 0x0F) == 4 ) {
+ if ((_moving & 0x0F) == 4) {
// 2CA3
loc_2CA3:;
setTmpFromActor();
@@ -954,22 +870,22 @@ loc_2CA3:;
} else {
_pos.y++;
}
- if (updateWalkbox() == 0xFF ) {
+ if (updateWalkbox() == 0xFF) {
// 2CC7
setActorFromTmp();
- if( _CurrentWalkTo.x == _tmp_Dest.x ) {
+ if( _CurrentWalkTo.x == _tmp_Dest.x) {
stopActorMoving();
return;
}
// 2CD5
- if (!_walkDirX ) {
+ if (!_walkDirX) {
_tmp_Dest.x--;
} else {
_tmp_Dest.x++;
}
setTmpFromActor();
- if (updateWalkbox() == 0xFF ) {
+ if (updateWalkbox() == 0xFF) {
setActorFromTmp();
stopActorMoving();
}
@@ -981,19 +897,19 @@ loc_2CA3:;
}
}
- if ((_moving & 0x0F) == 0 ) {
+ if ((_moving & 0x0F) == 0) {
// 2AE8
byte A = actorWalkX();
- if( A == 1 ) {
+ if (A == 1) {
A = actorWalkY();
- if( A == 1 ) {
+ if (A == 1) {
// 2AF6
_moving &= 0xF0;
_moving |= A;
} else {
// 2B04
- if( A == 4 )
+ if (A == 4)
stopActorMoving();
}
@@ -1018,7 +934,7 @@ loc_2CA3:;
} else {
// 2B39
A = actorWalkY();
- if (A != 4 )
+ if (A != 4)
return;
// 2B46
@@ -1039,22 +955,6 @@ loc_2CA3:;
}
}
-void Actor_v0::directionUpdate() {
-
- int nextFacing = updateActorDirection(true);
- if (_facing != nextFacing) {
- // 2A89
- setDirection(nextFacing);
-
- if (_facing != _targetFacing ) {
- _moving |= 0x80;
- } else {
- _moving &= ~0x80;
- }
- } else
- _moving &= ~0x80;
-}
-
void Actor_v2::walkActor() {
Common::Point foundPath, tmp;
int new_dir, next_box;
@@ -1101,10 +1001,8 @@ void Actor_v2::walkActor() {
_walkdata.curbox = next_box;
- if (!checkWalkboxesHaveDirectPath(foundPath)) {
- getClosestPtOnBox(_vm->getBoxCoordinates(_walkdata.curbox), _pos.x, _pos.y, tmp.x, tmp.y);
- getClosestPtOnBox(_vm->getBoxCoordinates(_walkbox), tmp.x, tmp.y, foundPath.x, foundPath.y);
- }
+ getClosestPtOnBox(_vm->getBoxCoordinates(_walkdata.curbox), _pos.x, _pos.y, tmp.x, tmp.y);
+ getClosestPtOnBox(_vm->getBoxCoordinates(_walkbox), tmp.x, tmp.y, foundPath.x, foundPath.y);
}
calcMovementFactor(foundPath);
}
@@ -1496,7 +1394,7 @@ void Actor::putActor(int dstX, int dstY, int newRoom) {
if (_vm->_game.version == 0) {
_walkdata.dest = _pos;
- ((Actor_v0*)this)->unk_FDE1 = 1;
+ ((Actor_v0*)this)->_newWalkBoxEntered = 1;
((Actor_v0*)this)->_CurrentWalkTo = _pos;
setDirection(oldDirToNewDir(2));
@@ -2075,14 +1973,15 @@ void ScummEngine::processActors() {
// comment further up in this method for some details.
if (a->_costume) {
- if (_game.version == 0)
+ // Unfortunately in V0, the 'animateCostume' call happens right after the call to 'walkActor', before drawing the actor... doing it the
+ // other way with V0, causes graphic glitches
+ if (_game.version == 0) {
a->animateCostume();
-
- a->drawActorCostume();
-
- if (_game.version != 0)
+ a->drawActorCostume();
+ } else {
+ a->drawActorCostume();
a->animateCostume();
-
+ }
}
}
}
diff --git a/engines/scumm/actor.h b/engines/scumm/actor.h
index b2245da..c554cad 100644
--- a/engines/scumm/actor.h
+++ b/engines/scumm/actor.h
@@ -333,7 +333,6 @@ public:
protected:
virtual bool isPlayer();
virtual void prepareDrawActorCostume(BaseCostumeRenderer *bcr);
- virtual bool checkWalkboxesHaveDirectPath(Common::Point &foundPath);
};
enum ActorV0MiscFlags {
@@ -349,12 +348,15 @@ enum ActorV0MiscFlags {
class Actor_v0 : public Actor_v2 {
public:
+ Common::Point _CurrentWalkTo, _NewWalkTo;
+
byte _costCommandNew;
byte _costCommand;
byte _miscflags;
byte _speaking;
- Common::Point _CurrentWalkTo, _NewWalkTo;
+ byte _walkCountModulo;
+ byte _newWalkBoxEntered;
byte _walkDirX;
byte _walkDirY;
@@ -364,16 +366,13 @@ public:
byte _walkXCountInc;
byte _walkYCount;
byte _walkYCountInc;
- byte _walkCountModulo;
byte _walkMaxXYCountInc;
- byte unk_FDE1;
-
Common::Point _tmp_Pos;
Common::Point _tmp_Dest;
byte _tmp_WalkBox;
- byte _tmp_CB5F;
+ byte _tmp_NewWalkBoxEntered;
int8 _animFrameRepeat;
int8 _limbFrameRepeatNew[8];
@@ -395,23 +394,18 @@ public:
void setDirection(int direction);
void startAnimActor(int f);
- bool sub_2F6F();
+ bool calcWalkDistances();
void walkActor();
void actorSetWalkTo();
byte actorWalkX();
byte actorWalkY();
byte updateWalkbox();
- byte walkboxFindTarget();
+
void setTmpFromActor();
void setActorFromTmp();
// Used by the save/load system:
virtual void saveLoadWithSerializer(Serializer *ser);
-
-protected:
- bool intersectLineSegments(const Common::Point &line1Start, const Common::Point &line1End,
- const Common::Point &line2Start, const Common::Point &line2End, Common::Point &result);
- virtual bool checkWalkboxesHaveDirectPath(Common::Point &foundPath);
};
diff --git a/engines/scumm/boxes.cpp b/engines/scumm/boxes.cpp
index 70c8f2e..087d842 100644
--- a/engines/scumm/boxes.cpp
+++ b/engines/scumm/boxes.cpp
@@ -1158,6 +1158,30 @@ bool ScummEngine::areBoxesNeighbors(int box1nr, int box2nr) {
return false;
}
+byte ScummEngine_v0::walkboxFindTarget(Actor *a, int destbox, Common::Point walkdest) {
+ Actor_v0 *Actor = (Actor_v0*)a;
+
+ byte nextBox = getNextBox(a->_walkbox, destbox);
+
+ if (nextBox != 0xFF && nextBox == destbox && areBoxesNeighbors(a->_walkbox, nextBox)) {
+
+ Actor->_NewWalkTo = walkdest;
+ return nextBox;
+ }
+
+ if (nextBox != 0xFF && nextBox != a->_walkbox) {
+
+ getClosestPtOnBox(getBoxCoordinates(nextBox), a->getPos().x, a->getPos().y, Actor->_NewWalkTo.x, Actor->_NewWalkTo.y);
+
+ } else {
+ if (walkdest.x == -1)
+ Actor->_NewWalkTo = Actor->_CurrentWalkTo;
+ else
+ Actor->_NewWalkTo = walkdest;
+ }
+ return nextBox;
+}
+
bool ScummEngine_v0::areBoxesNeighbors(int box1nr, int box2nr) {
int i;
const int numOfBoxes = getNumBoxes();
diff --git a/engines/scumm/script_v0.cpp b/engines/scumm/script_v0.cpp
index 6cbfbf4..9029153 100644
--- a/engines/scumm/script_v0.cpp
+++ b/engines/scumm/script_v0.cpp
@@ -589,9 +589,9 @@ void ScummEngine_v0::o_loadRoomWithEgo() {
return;
}
- // The original interpreter seems to set the actors new room X/Y to the last rooms X/Y
- // This fixes a problem with MM: script 158 in room 12, the 'Oompf!' script
- // This scripts runs before the actor position is set to the correct location
+ // The original interpreter sets the actors new room X/Y to the last rooms X/Y
+ // This fixes a problem with MM: script 158 in room 12, the 'Oomph!' script
+ // This scripts runs before the actor position is set to the correct room entry location
a->putActor(a->getPos().x, a->getPos().y, room);
_egoPositioned = false;
@@ -707,7 +707,6 @@ void ScummEngine_v0::o_animateActor() {
}
a->animateActor(anim);
- a->animateCostume();
}
void ScummEngine_v0::o_getActorMoving() {
diff --git a/engines/scumm/scumm_v0.h b/engines/scumm/scumm_v0.h
index 80d047a..83e0e32 100644
--- a/engines/scumm/scumm_v0.h
+++ b/engines/scumm/scumm_v0.h
@@ -67,6 +67,8 @@ public:
virtual void resetScumm();
+ byte walkboxFindTarget(Actor *a, int destbox, Common::Point walkdest);
+
protected:
virtual void resetRoomObject(ObjectData *od, const byte *room, const byte *searchptr = NULL);
@@ -116,7 +118,7 @@ protected:
void resetSentence();
- virtual bool areBoxesNeighbors(int box1nr, int box2nr);
+ bool areBoxesNeighbors(int box1nr, int box2nr);
bool ifEqualActiveObject2Common(bool checkType);
diff --git a/engines/scumm/verbs.cpp b/engines/scumm/verbs.cpp
index c1bafe1..bf0a693 100644
--- a/engines/scumm/verbs.cpp
+++ b/engines/scumm/verbs.cpp
@@ -708,7 +708,6 @@ void ScummEngine_v0::verbExec() {
Actor_v0 *a = (Actor_v0 *)derefActor(VAR(VAR_EGO), "verbExec");
int x = _virtualMouse.x / V12_X_MULTIPLIER;
int y = _virtualMouse.y / V12_Y_MULTIPLIER;
- //actorSetPosInBox();
// 0xB31
VAR(6) = x;
Commit: 814d9b1153df417c184be2b1a9072d0c7b37b201
https://github.com/scummvm/scummvm/commit/814d9b1153df417c184be2b1a9072d0c7b37b201
Author: Robert Crossfield (robcrossfield at gmail.com)
Date: 2014-12-02T16:25:03+11:00
Commit Message:
SCUMM: Maniac V0: Correctly handle 'slanted' walk-boxes, Add new variables to save-games, Bump the SaveGame Version number, remove obsolete V0 code in V2 functions
Changed paths:
engines/scumm/actor.cpp
engines/scumm/actor.h
engines/scumm/saveload.h
engines/scumm/script.cpp
diff --git a/engines/scumm/actor.cpp b/engines/scumm/actor.cpp
index 636f718..90ee5bf 100644
--- a/engines/scumm/actor.cpp
+++ b/engines/scumm/actor.cpp
@@ -51,6 +51,12 @@ static const byte v0ActorTalkArray[0x19] = {
0xC0, 0xC0, 0x00, 0x06, 0x06
};
+static const byte v0WalkboxSlantedModifier[0x16] = {
+ 0x00,0x01,0x02,0x03,0x03,0x04,0x05,0x06,
+ 0x06,0x07,0x08,0x09,0x09,0x0A,0x0B,
+ 0x0C,0x0C,0x0D,0x0E,0x0F,0x10,0x10
+};
+
Actor::Actor(ScummEngine *scumm, int id) :
_vm(scumm), _number(id) {
assert(_vm != 0);
@@ -183,6 +189,20 @@ void Actor_v0::initActor(int mode) {
_costCommand = 0xFF;
_miscflags = 0;
_speaking = 0;
+
+ _walkCountModulo = 0;
+ _newWalkBoxEntered = false;
+ _walkDirX = 0;
+ _walkDirY = 0;
+ _walkYCountGreaterThanXCount = 0;
+ _walkXCount = 0;
+ _walkXCountInc = 0;
+ _walkYCount = 0;
+ _walkYCountInc = 0;
+ _walkMaxXYCountInc = 0;
+
+ _tmp_WalkBox = 0;
+ _tmp_NewWalkBoxEntered = 0;
_animFrameRepeat = 0;
for (int i = 0; i < 8; ++i) {
@@ -250,11 +270,11 @@ void Actor::stopActorMoving() {
if (_walkScript)
_vm->stopScript(_walkScript);
- _moving = 0;
-
if (_vm->_game.version == 0) {
_moving = 2;
setDirection(_facing);
+ } else {
+ _moving = 0;
}
}
@@ -343,9 +363,6 @@ int Actor::actorWalkStep() {
int distX, distY;
int nextFacing;
- if (_vm->_game.version == 0)
- ((Actor_v0 *)this)->_animFrameRepeat = -1;
-
_needRedraw = true;
nextFacing = updateActorDirection(true);
@@ -354,10 +371,6 @@ int Actor::actorWalkStep() {
startWalkAnim(1, nextFacing);
}
_moving |= MF_IN_LEG;
-
- // V0: Don't move during the turn
- if (_vm->_game.version == 0)
- return 0;
}
if (_walkbox != _walkdata.curbox && _vm->checkXYInBoxBounds(_walkdata.curbox, _pos.x, _pos.y)) {
@@ -393,12 +406,113 @@ int Actor::actorWalkStep() {
return 0;
}
- if (_vm->_game.version == 0)
- ((Actor_v0 *)this)->animateActor(newDirToOldDir(_facing));
-
return 1;
}
+bool Actor_v0::calcWalkDistances() {
+ _walkDirX = 0;
+ _walkDirY = 0;
+ _walkYCountGreaterThanXCount = 0;
+ uint16 A = 0;
+
+ if (_CurrentWalkTo.x >= _tmp_Dest.x ) {
+ A = _CurrentWalkTo.x - _tmp_Dest.x;
+ _walkDirX = 1;
+ } else {
+ A = _tmp_Dest.x - _CurrentWalkTo.x;
+ }
+
+ _walkXCountInc = A;
+
+ if (_CurrentWalkTo.y >= _tmp_Dest.y ) {
+ A = _CurrentWalkTo.y - _tmp_Dest.y;
+ _walkDirY = 1;
+ } else {
+ A = _tmp_Dest.y - _CurrentWalkTo.y;
+ }
+
+ _walkYCountInc = A;
+ if ( !_walkXCountInc && !_walkYCountInc )
+ return true;
+
+ if( _walkXCountInc <= _walkYCountInc )
+ _walkYCountGreaterThanXCount = 1;
+
+ // 2FCC
+ A = _walkXCountInc;
+ if( A <= _walkYCountInc )
+ A = _walkYCountInc;
+
+ _walkMaxXYCountInc = A;
+ _walkXCount = _walkXCountInc;
+ _walkYCount = _walkYCountInc;
+ _walkCountModulo = _walkMaxXYCountInc;
+
+ return false;
+}
+
+byte Actor_v0::actorWalkX() {
+ byte A = _walkXCount;
+ A += _walkXCountInc;
+ if (A >= _walkCountModulo) {
+ if (!_walkDirX ) {
+ _tmp_Dest.x--;
+ } else {
+ _tmp_Dest.x++;
+ }
+
+ A -= _walkCountModulo;
+ }
+ // 2EAC
+ _walkXCount = A;
+ setTmpFromActor();
+ if (updateWalkbox() == kInvalidBox) {
+ // 2EB9
+ setActorFromTmp();
+
+ return 3;
+ }
+ // 2EBF
+ if (_tmp_Dest.x == _CurrentWalkTo.x)
+ return 1;
+
+ return 0;
+}
+
+byte Actor_v0::actorWalkY() {
+ byte A = _walkYCount;
+ A += _walkYCountInc;
+ if (A >= _walkCountModulo) {
+ if (!_walkDirY ) {
+ _tmp_Dest.y--;
+ } else {
+ _tmp_Dest.y++;
+ }
+
+ A -= _walkCountModulo;
+ }
+ // 2EEB
+ _walkYCount = A;
+ setTmpFromActor();
+ if (updateWalkbox() == kInvalidBox) {
+ // 2EF8
+ setActorFromTmp();
+ return 4;
+ }
+ // 2EFE
+ if (_walkYCountInc != 0) {
+ if (_walkYCountInc == 0xFF) {
+ setActorFromTmp();
+ return 4;
+ }
+ }
+ // 2F0D
+ if (_CurrentWalkTo.y == _tmp_Dest.y)
+ return 1;
+
+ return 0;
+}
+
void Actor::startWalkActor(int destX, int destY, int dir) {
AdjustBoxResult abr;
@@ -451,14 +565,14 @@ void Actor::startWalkActor(int destX, int destY, int dir) {
_walkdata.dest.y = abr.y;
_walkdata.destbox = abr.box;
_walkdata.destdir = dir;
- if(_vm->_game.version != 0 ) {
- _moving = (_moving & MF_IN_LEG) | MF_NEW_LEG;
- } else {
- ((Actor_v0*)this)->_newWalkBoxEntered = 1;
- }
_walkdata.point3.x = 32000;
-
_walkdata.curbox = _walkbox;
+
+ if(_vm->_game.version == 0 ) {
+ ((Actor_v0*)this)->_newWalkBoxEntered = true;
+ } else {
+ _moving = (_moving & MF_IN_LEG) | MF_NEW_LEG;
+ }
}
void Actor::startWalkAnim(int cmd, int angle) {
@@ -575,183 +689,14 @@ void Actor::walkActor() {
calcMovementFactor(_walkdata.dest);
}
-bool Actor_v0::calcWalkDistances() {
- _walkDirX = 0;
- _walkDirY = 0;
- _walkYCountGreaterThanXCount = 0;
- uint16 A = 0;
-
- if (_CurrentWalkTo.x >= _tmp_Dest.x ) {
- A = _CurrentWalkTo.x - _tmp_Dest.x;
- _walkDirX = 1;
- } else {
- A = _tmp_Dest.x - _CurrentWalkTo.x;
- }
-
- _walkXCountInc = A;
-
- if (_CurrentWalkTo.y >= _tmp_Dest.y ) {
- A = _CurrentWalkTo.y - _tmp_Dest.y;
- _walkDirY = 1;
- } else {
- A = _tmp_Dest.y - _CurrentWalkTo.y;
- }
-
- _walkYCountInc = A;
- if ( !_walkXCountInc && !_walkYCountInc )
- return true;
-
- if( _walkXCountInc <= _walkYCountInc )
- _walkYCountGreaterThanXCount = 1;
-
- // 2FCC
- A = _walkXCountInc;
- if( A <= _walkYCountInc )
- A = _walkYCountInc;
-
- _walkMaxXYCountInc = A;
- _walkXCount = _walkXCountInc;
- _walkYCount = _walkYCountInc;
- _walkCountModulo = _walkMaxXYCountInc;
-
- return false;
-}
-
-byte Actor_v0::updateWalkbox() {
- if( _vm->checkXYInBoxBounds( _walkbox, _pos.x, _pos.y ) )
- return 0;
-
- int numBoxes = _vm->getNumBoxes() - 1;
- for (int i = 0; i <= numBoxes; i++) {
- if (_vm->checkXYInBoxBounds( i, _pos.x, _pos.y ) == true ) {
- if (_walkdata.curbox == i ) {
- setBox(i);
-
- _newWalkBoxEntered = 1;
- return i;
- }
- }
- }
-
- return 0xFF;
-}
-
-void Actor_v0::setTmpFromActor() {
- _tmp_Pos = _pos;
- _pos = _tmp_Dest;
- _tmp_WalkBox = _walkbox;
- _tmp_NewWalkBoxEntered = _newWalkBoxEntered;
-}
-
-void Actor_v0::setActorFromTmp() {
- _pos = _tmp_Pos;
- _tmp_Dest = _tmp_Pos;
- _walkbox = _tmp_WalkBox;
- _newWalkBoxEntered = _tmp_NewWalkBoxEntered;
-}
-
-byte Actor_v0::actorWalkX() {
- byte A = _walkXCount;
- A += _walkXCountInc;
- if (A >= _walkCountModulo) {
- if (!_walkDirX ) {
- _tmp_Dest.x--;
- } else {
- _tmp_Dest.x++;
- }
-
- A -= _walkCountModulo;
- }
- // 2EAC
- _walkXCount = A;
- setTmpFromActor();
- if (updateWalkbox() == 0xFF) {
- // 2EB9
- setActorFromTmp();
-
- return 3;
- }
- // 2EBF
- if (_tmp_Dest.x == _CurrentWalkTo.x)
- return 1;
-
- return 0;
-}
-
-byte Actor_v0::actorWalkY() {
- byte A = _walkYCount;
- A += _walkYCountInc;
- if (A >= _walkCountModulo) {
- if (!_walkDirY ) {
- _tmp_Dest.y--;
- } else {
- _tmp_Dest.y++;
- }
-
- A -= _walkCountModulo;
- }
- // 2EEB
- _walkYCount = A;
- setTmpFromActor();
- if (updateWalkbox() == 0xFF) {
- // 2EF8
- setActorFromTmp();
- return 4;
- }
- // 2EFE
- if (_walkYCountInc != 0) {
- if (_walkYCountInc == 0xFF) {
- setActorFromTmp();
- return 4;
- }
- }
- // 2F0D
- if (_CurrentWalkTo.y == _tmp_Dest.y)
- return 1;
-
- return 0;
-}
-
-void Actor_v0::directionUpdate() {
-
- int nextFacing = updateActorDirection(true);
- if (_facing != nextFacing) {
- // 2A89
- setDirection(nextFacing);
-
- // Still need to turn?
- if (_facing != _targetFacing ) {
- _moving |= 0x80;
- return;
- }
- }
-
- _moving &= ~0x80;
-}
-
-void Actor_v0::actorSetWalkTo() {
-
- if (_newWalkBoxEntered == 0)
- return;
-
- _newWalkBoxEntered = 0;
-
- int nextBox = ((ScummEngine_v0*)_vm)->walkboxFindTarget( this, _walkdata.destbox, _walkdata.dest );
- if (nextBox != 0xFF) {
- _walkdata.curbox = nextBox;
- }
-}
-
void Actor_v0::walkActor() {
actorSetWalkTo();
_needRedraw = true;
if (_NewWalkTo != _CurrentWalkTo) {
-
- // 2A27
_CurrentWalkTo = _NewWalkTo;
-loc_2A33:;
+L2A33:;
_moving &= 0xF0;
_tmp_Dest = _pos;
@@ -784,13 +729,11 @@ loc_2A33:;
// 2A0A
if ((_moving & 0x7F) != 1) {
- if (_NewWalkTo == _pos) {
+ if (_NewWalkTo == _pos)
return;
- }
}
}
-
// 2A9A
if (_moving == 2)
return;
@@ -805,14 +748,11 @@ loc_2A33:;
if (_moving & 0x80)
return;
- // 2AC2
animateActor(newDirToOldDir(_facing));
}
- // 2ACE
if ((_moving & 0x0F) == 3 ) {
-loc_2C36:;
- // 2C36
+L2C36:;
setTmpFromActor();
if (!_walkDirX) {
@@ -822,13 +762,12 @@ loc_2C36:;
}
// 2C51
- if (updateWalkbox() != 0xFF) {
- //2C66
+ if (updateWalkbox() != kInvalidBox) {
+
setActorFromTmp();
- goto loc_2A33;
+ goto L2A33;
}
- // 2C6C
setActorFromTmp();
if (_CurrentWalkTo.y == _tmp_Dest.y) {
@@ -841,8 +780,9 @@ loc_2C36:;
} else {
_tmp_Dest.y++;
}
+
setTmpFromActor();
- //2C8B
+
byte A = updateWalkbox();
if (A == 0xFF) {
setActorFromTmp();
@@ -861,8 +801,7 @@ loc_2C36:;
// 2ADA
if ((_moving & 0x0F) == 4) {
- // 2CA3
-loc_2CA3:;
+L2CA3:;
setTmpFromActor();
if (!_walkDirY) {
@@ -870,14 +809,14 @@ loc_2CA3:;
} else {
_pos.y++;
}
- if (updateWalkbox() == 0xFF) {
+ if (updateWalkbox() == kInvalidBox) {
// 2CC7
setActorFromTmp();
if( _CurrentWalkTo.x == _tmp_Dest.x) {
stopActorMoving();
return;
}
- // 2CD5
+
if (!_walkDirX) {
_tmp_Dest.x--;
} else {
@@ -885,7 +824,7 @@ loc_2CA3:;
}
setTmpFromActor();
- if (updateWalkbox() == 0xFF) {
+ if (updateWalkbox() == kInvalidBox) {
setActorFromTmp();
stopActorMoving();
}
@@ -893,22 +832,20 @@ loc_2CA3:;
return;
} else {
setActorFromTmp();
- goto loc_2A33;
+ goto L2A33;
}
}
if ((_moving & 0x0F) == 0) {
- // 2AE8
+ // 2AE8
byte A = actorWalkX();
if (A == 1) {
A = actorWalkY();
- if (A == 1) {
- // 2AF6
+ if (A == 1) {
_moving &= 0xF0;
_moving |= A;
} else {
- // 2B04
if (A == 4)
stopActorMoving();
}
@@ -929,7 +866,7 @@ loc_2CA3:;
directionUpdate();
animateActor(newDirToOldDir(_facing));
- goto loc_2C36;
+ goto L2C36;
} else {
// 2B39
@@ -937,7 +874,6 @@ loc_2CA3:;
if (A != 4)
return;
- // 2B46
_moving &= 0xF0;
_moving |= A;
@@ -949,7 +885,7 @@ loc_2CA3:;
directionUpdate();
animateActor(newDirToOldDir(_facing));
- goto loc_2CA3;
+ goto L2CA3;
}
}
}
@@ -1394,7 +1330,7 @@ void Actor::putActor(int dstX, int dstY, int newRoom) {
if (_vm->_game.version == 0) {
_walkdata.dest = _pos;
- ((Actor_v0*)this)->_newWalkBoxEntered = 1;
+ ((Actor_v0*)this)->_newWalkBoxEntered = true;
((Actor_v0*)this)->_CurrentWalkTo = _pos;
setDirection(oldDirToNewDir(2));
@@ -1512,6 +1448,59 @@ static int checkXYInBoxBounds(int boxnum, int x, int y, int &destX, int &destY)
return dist;
}
+AdjustBoxResult Actor_v0::adjustPosInBorderWalkbox(AdjustBoxResult box) {
+ AdjustBoxResult Result = box;
+ BoxCoords BoxCoord = _vm->getBoxCoordinates(box.box);
+
+ byte boxMask = _vm->getMaskFromBox(box.box);
+ if (!(boxMask & 0x80))
+ return Result;
+
+ char A;
+ boxMask &= 0x7C;
+ if (boxMask == 0x0C)
+ A = 2;
+ else {
+ if (boxMask != 0x08)
+ return Result;
+
+ A = 1;
+ }
+
+ // 1BC6
+ byte Modifier = box.y - BoxCoord.ul.y;
+ assert(Modifier < 0x16);
+
+ if (A == 1) {
+ // 1BCF
+ A = BoxCoord.ur.x - v0WalkboxSlantedModifier[ Modifier ];
+ if (A < box.x)
+ return box;
+
+ if (A < 0xA0 || A == 0xA0)
+ A = 0;
+
+ Result.x = A;
+ } else {
+ // 1BED
+ A = BoxCoord.ul.x + v0WalkboxSlantedModifier[ Modifier ];
+
+ if (A < box.x || A == box.x)
+ Result.x = A;
+ }
+
+ return Result;
+}
+
+AdjustBoxResult Actor_v0::adjustXYToBeInBox(int dstX, int dstY) {
+ AdjustBoxResult Result = Actor_v2::adjustXYToBeInBox(dstX, dstY);
+
+ if( Result.box == kInvalidBox )
+ return Result;
+
+ return adjustPosInBorderWalkbox(Result);
+}
+
AdjustBoxResult Actor_v2::adjustXYToBeInBox(const int dstX, const int dstY) {
AdjustBoxResult abr;
@@ -1722,7 +1711,7 @@ void Actor::showActor() {
Actor_v0 *a = ((Actor_v0 *)this);
a->_costCommand = a->_costCommandNew = 0xFF;
-
+ _walkdata.dest = a->_CurrentWalkTo;
for (int i = 0; i < 8; ++i) {
a->_limbFrameRepeat[i] = 0;
@@ -1955,7 +1944,7 @@ void ScummEngine::processActors() {
continue;
// Sound
- if (a0->_moving && _currentRoom != 1 && _currentRoom != 44) {
+ if (a0->_moving != 2 && _currentRoom != 1 && _currentRoom != 44) {
if (a0->_cost.soundPos == 0)
a0->_cost.soundCounter++;
@@ -1973,8 +1962,9 @@ void ScummEngine::processActors() {
// comment further up in this method for some details.
if (a->_costume) {
- // Unfortunately in V0, the 'animateCostume' call happens right after the call to 'walkActor', before drawing the actor... doing it the
- // other way with V0, causes graphic glitches
+ // Unfortunately in V0, the 'animateCostume' call happens right after the call to 'walkActor' (which is before drawing the actor)...
+ // doing it the other way with V0, causes animation glitches (when beginnning to walk, as the costume hasnt been updated).
+ // Updating the costume directly after 'walkActor' and again, after drawing... causes frame skipping
if (_game.version == 0) {
a->animateCostume();
a->drawActorCostume();
@@ -3218,6 +3208,70 @@ void Actor_v0::animateActor(int anim) {
}
}
+byte Actor_v0::updateWalkbox() {
+ if( _vm->checkXYInBoxBounds( _walkbox, _pos.x, _pos.y ) )
+ return 0;
+
+ int numBoxes = _vm->getNumBoxes() - 1;
+ for (int i = 0; i <= numBoxes; i++) {
+ if (_vm->checkXYInBoxBounds( i, _pos.x, _pos.y ) == true ) {
+ if (_walkdata.curbox == i) {
+ setBox(i);
+ directionUpdate();
+
+ _newWalkBoxEntered = true;
+ return i;
+ }
+ }
+ }
+
+ return kInvalidBox;
+}
+
+void Actor_v0::directionUpdate() {
+
+ int nextFacing = updateActorDirection(true);
+ if (_facing != nextFacing) {
+ // 2A89
+ setDirection(nextFacing);
+
+ // Still need to turn?
+ if (_facing != _targetFacing) {
+ _moving |= 0x80;
+ return;
+ }
+ }
+
+ _moving &= ~0x80;
+}
+
+void Actor_v0::setTmpFromActor() {
+ _tmp_Pos = _pos;
+ _pos = _tmp_Dest;
+ _tmp_WalkBox = _walkbox;
+ _tmp_NewWalkBoxEntered = _newWalkBoxEntered;
+}
+
+void Actor_v0::setActorFromTmp() {
+ _pos = _tmp_Pos;
+ _tmp_Dest = _tmp_Pos;
+ _walkbox = _tmp_WalkBox;
+ _newWalkBoxEntered = _tmp_NewWalkBoxEntered;
+}
+
+void Actor_v0::actorSetWalkTo() {
+
+ if (_newWalkBoxEntered == false)
+ return;
+
+ _newWalkBoxEntered = false;
+
+ int nextBox = ((ScummEngine_v0*)_vm)->walkboxFindTarget(this, _walkdata.destbox, _walkdata.dest);
+ if (nextBox != kInvalidBox) {
+ _walkdata.curbox = nextBox;
+ }
+}
+
void Actor_v0::saveLoadWithSerializer(Serializer *ser) {
Actor::saveLoadWithSerializer(ser);
@@ -3231,6 +3285,20 @@ void Actor_v0::saveLoadWithSerializer(Serializer *ser) {
MKLINE(Actor_v0, _animFrameRepeat, sleByte, VER(89)),
MKARRAY(Actor_v0, _limbFrameRepeatNew[0], sleInt8, 8, VER(89)),
MKARRAY(Actor_v0, _limbFrameRepeat[0], sleInt8, 8, VER(90)),
+ MKLINE(Actor_v0, _CurrentWalkTo.x, sleInt16, VER(97)),
+ MKLINE(Actor_v0, _CurrentWalkTo.y, sleInt16, VER(97)),
+ MKLINE(Actor_v0, _NewWalkTo.x, sleInt16, VER(97)),
+ MKLINE(Actor_v0, _NewWalkTo.y, sleInt16, VER(97)),
+ MKLINE(Actor_v0, _walkCountModulo, sleInt8, VER(97)),
+ MKLINE(Actor_v0, _newWalkBoxEntered, sleByte, VER(97)),
+ MKLINE(Actor_v0, _walkDirX, sleByte, VER(97)),
+ MKLINE(Actor_v0, _walkDirY, sleByte, VER(97)),
+ MKLINE(Actor_v0, _walkYCountGreaterThanXCount, sleByte, VER(97)),
+ MKLINE(Actor_v0, _walkXCount, sleByte, VER(97)),
+ MKLINE(Actor_v0, _walkXCountInc, sleByte, VER(97)),
+ MKLINE(Actor_v0, _walkYCount, sleByte, VER(97)),
+ MKLINE(Actor_v0, _walkYCountInc, sleByte, VER(97)),
+ MKLINE(Actor_v0, _walkMaxXYCountInc, sleByte, VER(97)),
MKEND()
};
diff --git a/engines/scumm/actor.h b/engines/scumm/actor.h
index c554cad..c1a3f23 100644
--- a/engines/scumm/actor.h
+++ b/engines/scumm/actor.h
@@ -356,7 +356,7 @@ public:
byte _speaking;
byte _walkCountModulo;
- byte _newWalkBoxEntered;
+ bool _newWalkBoxEntered;
byte _walkDirX;
byte _walkDirY;
@@ -372,7 +372,7 @@ public:
Common::Point _tmp_Pos;
Common::Point _tmp_Dest;
byte _tmp_WalkBox;
- byte _tmp_NewWalkBoxEntered;
+ bool _tmp_NewWalkBoxEntered;
int8 _animFrameRepeat;
int8 _limbFrameRepeatNew[8];
@@ -401,6 +401,9 @@ public:
byte actorWalkY();
byte updateWalkbox();
+ AdjustBoxResult adjustXYToBeInBox(int dstX, int dstY);
+ AdjustBoxResult adjustPosInBorderWalkbox(AdjustBoxResult box);
+
void setTmpFromActor();
void setActorFromTmp();
diff --git a/engines/scumm/saveload.h b/engines/scumm/saveload.h
index 01ed21e..753287e 100644
--- a/engines/scumm/saveload.h
+++ b/engines/scumm/saveload.h
@@ -47,7 +47,7 @@ namespace Scumm {
* only saves/loads those which are valid for the version of the savegame
* which is being loaded/saved currently.
*/
-#define CURRENT_VER 96
+#define CURRENT_VER 97
/**
* An auxillary macro, used to specify savegame versions. We use this instead
diff --git a/engines/scumm/script.cpp b/engines/scumm/script.cpp
index efd5e7b..c9b37d4 100644
--- a/engines/scumm/script.cpp
+++ b/engines/scumm/script.cpp
@@ -1164,8 +1164,10 @@ void ScummEngine_v0::walkToActorOrObject(int object) {
VAR(7) = y;
// actor must not move if frozen
- if (a->_miscflags & kActorMiscFlagFreeze)
+ if (a->_miscflags & kActorMiscFlagFreeze) {
a->stopActorMoving();
+ a->_newWalkBoxEntered = false;
+ }
}
bool ScummEngine_v0::checkPendingWalkAction() {
@@ -1179,7 +1181,7 @@ bool ScummEngine_v0::checkPendingWalkAction() {
Actor_v0 *a = (Actor_v0 *)derefActor(actor, "checkPendingWalkAction");
// wait until walking or turning action is finished
- if (a->_moving!=2)
+ if (a->_moving != 2)
return true;
// after walking and turning finally execute the script
Commit: 4b1b9ec66f5889fd20d88f8f7f565e8448ac8389
https://github.com/scummvm/scummvm/commit/4b1b9ec66f5889fd20d88f8f7f565e8448ac8389
Author: Robert Crossfield (robcrossfield at gmail.com)
Date: 2014-12-02T16:40:46+11:00
Commit Message:
SCUMM: Maniac V0: Remove workaround for bug #2971126 (this issue no longer occurs as walking is handled the same as the original)
Changed paths:
engines/scumm/script_v5.cpp
diff --git a/engines/scumm/script_v5.cpp b/engines/scumm/script_v5.cpp
index 91afa85..4a53ca3 100644
--- a/engines/scumm/script_v5.cpp
+++ b/engines/scumm/script_v5.cpp
@@ -2497,10 +2497,6 @@ void ScummEngine_v5::walkActorToActor(int actor, int toActor, int dist) {
y = abr.y;
}
a->startWalkActor(x, y, -1);
-
- // WORKAROUND: See bug #2971126 for details on why this is here.
- if (_game.version == 0)
- o5_breakHere();
}
void ScummEngine_v5::o5_walkActorToActor() {
Commit: dcd0f597e6026e248ff6e2db0224f3f60626cdca
https://github.com/scummvm/scummvm/commit/dcd0f597e6026e248ff6e2db0224f3f60626cdca
Author: Kirben (kirben at optusnet.com.au)
Date: 2014-12-07T15:09:36+11:00
Commit Message:
Merge pull request #539 from segrax/master
SCUMM: Maniac V0: Original Walk Code Implementation
Changed paths:
engines/scumm/actor.cpp
engines/scumm/actor.h
engines/scumm/boxes.cpp
engines/scumm/saveload.h
engines/scumm/script.cpp
engines/scumm/script_v0.cpp
engines/scumm/script_v5.cpp
engines/scumm/scumm_v0.h
engines/scumm/verbs.cpp
More information about the Scummvm-git-logs
mailing list