SCUMM: Properly fix bug #813

Verified for the disasms of v3-v6 and HE
This commit is contained in:
AndywinXp
2023-01-14 11:53:50 +01:00
parent 9831b91c1d
commit 546fd42749
2 changed files with 38 additions and 24 deletions
+29 -13
View File
@@ -1527,6 +1527,10 @@ void Actor::setDirection(int direction) {
if (_costume == 0)
return;
// Verified for v3-v6 and HE
if (!isInCurrentRoom() && _vm->_game.version >= 3 && _vm->_game.version <= 6)
return;
// Update the costume for the new direction (and mark the actor for redraw)
aMask = 0x8000;
for (i = 0; i < 16; i++, aMask >>= 1) {
@@ -2612,37 +2616,49 @@ void Actor_v0::startAnimActor(int f) {
}
void Actor::animateActor(int anim) {
int cmd, dir;
int chore, dir;
if (_vm->_game.version >= 7 && !((_vm->_game.id == GID_FT) && (_vm->_game.features & GF_DEMO) && (_vm->_game.platform == Common::kPlatformDOS))) {
if (anim == 0xFF)
anim = 2000;
cmd = anim / 1000;
chore = anim / 1000;
dir = anim % 1000;
} else {
// Format of the input parameter:
// - The 2 least significant bits are the direction
// - The rest is the chore command to execute
chore = anim >> 2;
dir = oldDirToNewDir(anim & 3);
cmd = anim / 4;
dir = oldDirToNewDir(anim % 4);
// Convert into old cmd code
cmd = 0x3F - cmd + 2;
// Convert into old chore code
chore = 0x3F - chore + 2;
}
switch (cmd) {
switch (chore) {
case 2: // stop walking
startAnimActor(_standFrame);
stopActorMoving();
if (isInCurrentRoom() ||
!(_vm->_game.version >= 3 && _vm->_game.version <= 6)) {
startAnimActor(_standFrame);
stopActorMoving();
}
break;
case 3: // change direction immediatly
_moving &= ~MF_TURN;
if (isInCurrentRoom() ||
!(_vm->_game.version >= 3 && _vm->_game.version <= 6)) {
_moving &= ~MF_TURN;
}
setDirection(dir);
break;
case 4: // turn to new direction
turnToDirection(dir);
if (isInCurrentRoom() ||
!(_vm->_game.version >= 3 && _vm->_game.version <= 6)) {
turnToDirection(dir);
}
break;
case 64:
if (_vm->_game.version == 0) {
@@ -2653,7 +2669,7 @@ void Actor::animateActor(int anim) {
// fall through
default:
if (_vm->_game.version <= 2)
startAnimActor(anim / 4);
startAnimActor(chore);
else
startAnimActor(anim);
}
+9 -11
View File
@@ -1203,15 +1203,7 @@ void ScummEngine_v6::o6_faceActor() {
void ScummEngine_v6::o6_animateActor() {
int anim = pop();
int act = pop();
if (_game.id == GID_TENTACLE && _roomResource == 57 &&
vm.slot[_currentScript].number == 19 && act == 593) {
// WORKAROUND bug #813: This very odd case (animateActor(593,250))
// occurs in DOTT, in the cutscene after George cuts down the "cherry
// tree" and the tree Laverne is trapped in vanishes...
// Not sure if this means animateActor somehow also must work for objects
// (593 is the time machine in room 57), or if this is simply a script bug.
act = 6;
}
if (_game.id == GID_SAMNMAX && _roomResource == 35 &&
vm.slot[_currentScript].number == 202 && act == 4 && anim == 14) {
// WORKAROUND bug #2068 (Animation glitch at World of Fish).
@@ -1221,6 +1213,7 @@ void ScummEngine_v6::o6_animateActor() {
stopTalk();
}
}
if (_game.id == GID_SAMNMAX && _roomResource == 47 && vm.slot[_currentScript].number == 202 &&
act == 2 && anim == 249 && _enableEnhancements) {
// WORKAROUND for bug #3832: parts of Bruno are left on the screen when he
@@ -1232,8 +1225,13 @@ void ScummEngine_v6::o6_animateActor() {
a->putActor(0, 0, 0);
}
Actor *a = derefActor(act, "o6_animateActor");
a->animateActor(anim);
// Since there have been cases of the scripts sending garbage data
// as the actor number (see bug #813), we handle these cases cleanly
// by not crashing ScummVM and returning a nullptr Actor instead.
Actor *a = derefActorSafe(act, "o6_animateActor");
if (a) {
a->animateActor(anim);
}
}
void ScummEngine_v6::o6_doSentence() {