diff options
author | Robert Crossfield | 2012-01-24 23:23:19 +1100 |
---|---|---|
committer | Tobias Gunkel | 2012-02-11 08:29:22 +0100 |
commit | 65fb1f9a09b3460eebaf7d033990fe9e778070f4 (patch) | |
tree | 69f3537196fcb679adfb301d24be960c215d3874 /engines/scumm/actor.cpp | |
parent | e3f9a09d49aaeb4657862ca734d20279e75c869f (diff) | |
download | scummvm-rg350-65fb1f9a09b3460eebaf7d033990fe9e778070f4.tar.gz scummvm-rg350-65fb1f9a09b3460eebaf7d033990fe9e778070f4.tar.bz2 scummvm-rg350-65fb1f9a09b3460eebaf7d033990fe9e778070f4.zip |
SCUMM: Fix the animation system, rename the Limb Frame Repeat variable
Diffstat (limited to 'engines/scumm/actor.cpp')
-rw-r--r-- | engines/scumm/actor.cpp | 259 |
1 files changed, 191 insertions, 68 deletions
diff --git a/engines/scumm/actor.cpp b/engines/scumm/actor.cpp index 3a4f72181b..2d0e498f48 100644 --- a/engines/scumm/actor.cpp +++ b/engines/scumm/actor.cpp @@ -42,6 +42,14 @@ namespace Scumm { byte Actor::kInvalidBox = 0; +static const byte v0ActorTalkArray[0x19] = { + 0x00, 0x06, 0x06, 0x06, 0x06, + 0x06, 0x06, 0x00, 0x46, 0x06, + 0x06, 0x06, 0x06, 0xFF, 0xFF, + 0x06, 0xC0, 0x06, 0x06, 0x00, + 0xC0, 0xC0, 0x00, 0x06, 0x06 +}; + Actor::Actor(ScummEngine *scumm, int id) : _vm(scumm), _number(id) { assert(_vm != 0); @@ -226,11 +234,6 @@ void Actor::stopActorMoving() { if (_walkScript) _vm->stopScript(_walkScript); - // V0 Games will walk on the spot if the actor is stopped mid-walk - // So we must set the stand still frame - if (_vm->_game.version == 0) - startWalkAnim(3, -1); - _moving = 0; } @@ -320,11 +323,12 @@ int Actor::actorWalkStep() { int nextFacing; if( _vm->_game.version == 0 ) - ((ActorC64*) this)->_byte_FD0A = -1; + ((ActorC64*) this)->_AnimFrameRepeat = -1; _needRedraw = true; - nextFacing = updateActorDirection(true); + nextFacing = updateActorDirection(true);; + if (!(_moving & MF_IN_LEG) || _facing != nextFacing) { if (_walkFrame != _frame || _facing != nextFacing) { startWalkAnim(1, nextFacing); @@ -364,6 +368,7 @@ int Actor::actorWalkStep() { _moving &= ~MF_IN_LEG; return 0; } + return 1; } @@ -415,6 +420,9 @@ void Actor::startWalkActor(int destX, int destY, int dir) { } } + if( _vm->_game.version == 0 ) + ((ActorC64*) this)->animateActor(dir); + _walkdata.dest.x = abr.x; _walkdata.dest.y = abr.y; _walkdata.destbox = abr.box; @@ -545,17 +553,18 @@ void Actor_v2::walkActor() { if (_moving & MF_TURN) { new_dir = updateActorDirection(false); - // FIXME: is this correct? + if (_facing != new_dir) { - // Actor never stops walking when an object has been selected without this - if (_vm->_game.version ==0) - _moving = 0; - - setDirection(new_dir); + if( _vm->_game.version != 0 ) + setDirection(new_dir); - } else + } else { _moving = 0; + } + + if( _vm->_game.version == 0 ) + ((ActorC64*)this)->setCmdFromDirection( newDirToOldDir(new_dir) ); return; } @@ -564,6 +573,8 @@ void Actor_v2::walkActor() { if (_moving & MF_IN_LEG) { actorWalkStep(); + if( _vm->_game.version == 0 ) + ((ActorC64*) this)->animateActor( newDirToOldDir( _facing ) ); } else { if (_moving & MF_LAST_LEG) { _moving = 0; @@ -850,7 +861,7 @@ void Actor::setDirection(int direction) { direction = 90; // Do nothing if actor is already facing in the given direction - if (_vm->_game.version != 0 && _facing == direction) + if (_facing == direction) return; // Normalize the angle @@ -872,25 +883,45 @@ void Actor::setDirection(int direction) { _needRedraw = true; } -void ActorC64::setDirection(int direction) { +void ActorC64::setDirection(int cmd) { // Normalize the angle - _facing = normalizeAngle(direction); - - // 0x2C17 - // _byte_FDE8 = -1; + _facing = normalizeAngle( cmd ); // If there is no costume set for this actor, we are finished if (_costume == 0) return; +} - if (_moving) - _vm->_costumeLoader->costumeDecodeData(this, _walkFrame, 0); - else { - _vm->_costumeLoader->costumeDecodeData(this, _standFrame, 0); - } +// based on 0x2BCA, doesn't match disassembly because 'oldDir' variable +// is not the same value as stored in the original interpreter +int ActorC64::setCmdFromDirection(int direction) { + int res = 0; - _needRedraw = true; + switch (direction) { + case 0: + res = 4; // Left + break; + + case 1: + res = 5; // Right + break; + + case 2: + res = 6; // Face Away + break; + + default: + res = 7; // Face Camera + break; + } + + + _AnimFrameRepeat = -1; + animateActor(res); + animateCostume(); + + return res; } void Actor::faceToObject(int obj) { @@ -961,10 +992,12 @@ void Actor::putActor(int dstX, int dstY, int newRoom) { if (_visible) { if (isInCurrentRoom()) { + if (_moving) { stopActorMoving(); startAnimActor(_standFrame); } + adjustActorPos(); } else { #ifdef ENABLE_HE @@ -1228,6 +1261,8 @@ void Actor::adjustActorPos() { if (flags & 7) { turnToDirection(_facing); } + if (_vm->_game.version == 0) + ((ActorC64*)this)->setCmdFromDirection( newDirToOldDir(_facing) ); } } @@ -1300,12 +1335,21 @@ void Actor::showActor() { _vm->ensureResourceLoaded(rtCostume, _costume); if (_vm->_game.version == 0) { + ActorC64 *a = ((ActorC64*) this); + + a->_costCommand = a->_costCommandNew = 0xFF; + + for( int i = 0; i < 8; ++i ) { + a->_limbFrameRepeatNew[i] = 0; + + } // 0x39DF - ((ActorC64*) this)->_byte_FDE8 = 1; + a->_AnimFrameRepeat = 1; _cost.reset(); - startAnimActor(_standFrame); + a->setCmdFromDirection( newDirToOldDir(_facing) ); + } else if (_vm->_game.version <= 2) { _cost.reset(); startAnimActor(_standFrame); @@ -1817,6 +1861,27 @@ void Actor::startAnimActor(int f) { } } +void ActorC64::startAnimActor(int f) { + if (f == _talkStartFrame) { + if (v0ActorTalkArray[_number] & 0x40) + return; + + _speaking = 1; + return; + } + + if (f == _talkStopFrame) { + + _speaking = 0; + return; + } + + if( f == _standFrame ) + setCmdFromDirection( newDirToOldDir(_facing) ); + else + animateActor( newDirToOldDir(_facing) ); +} + void Actor::animateActor(int anim) { int cmd, dir; @@ -1878,6 +1943,65 @@ void Actor::animateCostume() { } } +void ActorC64::limbFrameCheck() { + if (_cost.frame[_limb_current] == 0xFFFF ) + return; + + if (_cost.start[_limb_current] == _cost.frame[_limb_current] ) + return; + + // 0x25A4 + _cost.start[_limb_current] = _cost.frame[_limb_current]; + + _limbFrameRepeat[_limb_current] = _limbFrameRepeatNew[_limb_current]; + + _cost.active[_limb_current] = _cost.frame[_limb_current]; + _cost.curpos[_limb_current] = 0; + + _needRedraw = true; +} + +void ActorC64::animateCostume() { + + // Sound + if (_moving && _vm->_currentRoom != 1 && _vm->_currentRoom != 44) { + if (_cost.soundPos == 0) + _cost.soundCounter++; + + // Is this the correct location? + // 0x073C + if (v0ActorTalkArray[_number] & 0x3F) + _cost.soundPos = (_cost.soundPos + 1) % 3; + } + + _vm->_costumeLoader->loadCostume(_costume); + + speakCheck(); + + for( _limb_current = 0; _limb_current < 8; ++_limb_current ) { + limbFrameCheck(); + + if (_vm->_costumeLoader->increaseAnims(this)) + _needRedraw = true; + } +} + +void ActorC64::speakCheck() { + + if (v0ActorTalkArray[_number] & 0x80) + return; + + int cmd = newDirToOldDir( _facing ); + + if (_speaking & 0x80) + cmd += 0x0C; + else + cmd += 0x10; + + _AnimFrameRepeat = -1; + animateActor( cmd ); +} + #ifdef ENABLE_SCUMM_7_8 void Actor::animateLimb(int limb, int f) { // This methods is very similiar to animateCostume(). @@ -2661,42 +2785,43 @@ void ScummEngine_v71he::queueAuxEntry(int actorNum, int subIndex) { #endif void ActorC64::animateActor(int anim) { - int dir = oldDirToNewDir(anim % 4); - - if( this->isInCurrentRoom() ) { - - // this->_costCommandNew = anim; - - // 0x273A - /*switch( anim ) { - case 4: - dir = 1; - break; - case 5: - dir = 0; - break; - case 6: - dir = 0x80; - break; - case 7: - dir = 0x81; - break; - - default: - return; - }*/ - - - this->_byte_FD0A = this->_byte_FDE8; - - this->setDirection( dir ); - - } else { - - if( anim > 4 ) { - if( anim <= 7 ) - this->setDirection( dir ); - } + int dir = -1; + + switch( anim ) { + case 0x04: + dir = 0; + break; + + case 0x05: + dir = 1; + break; + + case 0x06: + dir = 2; + break; + + case 0x07: + dir = 3; + break; + + default: + break; + } + + if( isInCurrentRoom() ) { + + _costCommandNew = anim; + _vm->_costumeLoader->costumeDecodeData(this, 0, 0); + + if( dir == -1 ) + return; + + setDirection( oldDirToNewDir(dir) ); + + } else { + + if( anim > 4 && anim <= 7 ) + setDirection( oldDirToNewDir(dir) ); } } @@ -2708,10 +2833,8 @@ void ActorC64::saveLoadWithSerializer(Serializer *ser) { MKLINE(ActorC64, _costFrame, sleByte, VER(84)), MKLINE(ActorC64, _miscflags, sleByte, VER(84)), MKLINE(ActorC64, _speaking, sleByte, VER(84)), - MKLINE(ActorC64, _speakingPrev, sleByte, VER(84)), - MKLINE(ActorC64, _byte_FD0A, sleByte, VER(89)), - MKLINE(ActorC64, _byte_FDE8, sleByte, VER(89)), - MKARRAY(ActorC64, _byte_FCE2[0], sleInt8, 8, VER(89)), + MKLINE(ActorC64, _AnimFrameRepeat, sleByte, VER(89)), + MKARRAY(ActorC64, _limbFrameRepeatNew[0], sleInt8, 8, VER(89)), MKEND() }; |