diff options
Diffstat (limited to 'engines/scumm')
-rw-r--r-- | engines/scumm/actor.cpp | 725 | ||||
-rw-r--r-- | engines/scumm/actor.h | 49 | ||||
-rw-r--r-- | engines/scumm/boxes.cpp | 24 | ||||
-rw-r--r-- | engines/scumm/cdda.cpp | 2 | ||||
-rw-r--r-- | engines/scumm/detection.cpp | 5 | ||||
-rw-r--r-- | engines/scumm/detection_tables.h | 16 | ||||
-rw-r--r-- | engines/scumm/dialogs.cpp | 6 | ||||
-rw-r--r-- | engines/scumm/file.cpp | 26 | ||||
-rw-r--r-- | engines/scumm/input.cpp | 12 | ||||
-rw-r--r-- | engines/scumm/resource_v2.cpp | 10 | ||||
-rw-r--r-- | engines/scumm/room.cpp | 9 | ||||
-rw-r--r-- | engines/scumm/saveload.cpp | 7 | ||||
-rw-r--r-- | engines/scumm/saveload.h | 2 | ||||
-rw-r--r-- | engines/scumm/script.cpp | 6 | ||||
-rw-r--r-- | engines/scumm/script_v0.cpp | 34 | ||||
-rw-r--r-- | engines/scumm/script_v2.cpp | 9 | ||||
-rw-r--r-- | engines/scumm/script_v5.cpp | 4 | ||||
-rw-r--r-- | engines/scumm/scumm-md5.h | 42 | ||||
-rw-r--r-- | engines/scumm/scumm.cpp | 16 | ||||
-rw-r--r-- | engines/scumm/scumm.h | 4 | ||||
-rw-r--r-- | engines/scumm/scumm_v0.h | 8 | ||||
-rw-r--r-- | engines/scumm/sound.cpp | 4 | ||||
-rw-r--r-- | engines/scumm/vars.cpp | 2 | ||||
-rw-r--r-- | engines/scumm/verbs.cpp | 57 |
24 files changed, 864 insertions, 215 deletions
diff --git a/engines/scumm/actor.cpp b/engines/scumm/actor.cpp index 116a953b0b..0d7ea39ec2 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" @@ -42,12 +43,66 @@ 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 +static const byte v0ActorDemoTalk[25] = { + 0x00, + 0x06, // Syd + 0x06, // Razor + 0x06, // Dave + 0x06, // Michael + 0x06, // Bernard + 0x06, // Wendy + 0x00, // Jeff + 0x46, // Radiation Suit + 0x06, // Dr Fred + 0x06, // Nurse Edna + 0x06, // Weird Ed + 0x06, // Dead Cousin Ted + 0xE2, // Purple Tentacle + 0xE2, // Green Tentacle + 0x06, // Meteor police + 0xC0, // Meteor + 0x06, // Mark Eteer + 0x06, // Talkshow Host + 0x00, // Plant + 0xC0, // Meteor Radiation + 0xC0, // Edsel (small, outro) + 0x00, // Meteor (small, intro) + 0x06, // Sandy (Lab) + 0x06, // Sandy (Cut-Scene) +}; + +static const byte v0ActorTalk[25] = { + 0x00, + 0x06, // Syd + 0x06, // Razor + 0x06, // Dave + 0x06, // Michael + 0x06, // Bernard + 0x06, // Wendy + 0x00, // Jeff + 0x46, // Radiation Suit + 0x06, // Dr Fred + 0x06, // Nurse Edna + 0x06, // Weird Ed + 0x06, // Dead Cousin Ted + 0xFF, // Purple Tentacle + 0xFF, // Green Tentacle + 0x06, // Meteor police + 0xC0, // Meteor + 0x06, // Mark Eteer + 0x06, // Talkshow Host + 0x00, // Plant + 0xC0, // Meteor Radiation + 0xC0, // Edsel (small, outro) + 0x00, // Meteor (small, intro) + 0x06, // Sandy (Lab) + 0x06, // Sandy (Cut-Scene) +}; + +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) : @@ -182,6 +237,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) { @@ -189,6 +258,12 @@ void Actor_v0::initActor(int mode) { _limbFrameRepeat[i] = 0; _limb_flipped[i] = false; } + + if (_vm->_game.features & GF_DEMO) { + _sound[0] = v0ActorDemoTalk[_number]; + } else { + _sound[0] = v0ActorTalk[_number]; + } } void Actor::setBox(int box) { @@ -249,9 +324,12 @@ void Actor::stopActorMoving() { if (_walkScript) _vm->stopScript(_walkScript); - _moving = 0; - if (_vm->_game.version == 0) + if (_vm->_game.version == 0) { + _moving = 2; setDirection(_facing); + } else { + _moving = 0; + } } void Actor::setActorWalkSpeed(uint newSpeedX, uint newSpeedY) { @@ -339,9 +417,6 @@ int Actor::actorWalkStep() { int distX, distY; int nextFacing; - if (_vm->_game.version == 0) - ((Actor_v0 *)this)->_animFrameRepeat = -1; - _needRedraw = true; nextFacing = updateActorDirection(true); @@ -350,10 +425,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)) { @@ -368,13 +439,28 @@ int Actor::actorWalkStep() { return 0; } - tmpX = (_pos.x << 16) + _walkdata.xfrac + (_walkdata.deltaXFactor >> 8) * _scalex; - _walkdata.xfrac = (uint16)tmpX; - _pos.x = (tmpX >> 16); + if (_vm->_game.version <= 2) { + if (_walkdata.deltaXFactor != 0) { + if (_walkdata.deltaXFactor > 0) + _pos.x += 1; + else + _pos.x -= 1; + } + if (_walkdata.deltaYFactor != 0) { + if (_walkdata.deltaYFactor > 0) + _pos.y += 1; + else + _pos.y -= 1; + } + } else { + tmpX = (_pos.x << 16) + _walkdata.xfrac + (_walkdata.deltaXFactor >> 8) * _scalex; + _walkdata.xfrac = (uint16)tmpX; + _pos.x = (tmpX >> 16); - tmpY = (_pos.y << 16) + _walkdata.yfrac + (_walkdata.deltaYFactor >> 8) * _scaley; - _walkdata.yfrac = (uint16)tmpY; - _pos.y = (tmpY >> 16); + tmpY = (_pos.y << 16) + _walkdata.yfrac + (_walkdata.deltaYFactor >> 8) * _scaley; + _walkdata.yfrac = (uint16)tmpY; + _pos.y = (tmpY >> 16); + } if (ABS(_pos.x - _walkdata.cur.x) > distX) { _pos.x = _walkdata.next.x; @@ -384,17 +470,118 @@ int Actor::actorWalkStep() { _pos.y = _walkdata.next.y; } - if (_vm->_game.version >= 4 && _vm->_game.version <= 6 && _pos == _walkdata.next) { + if ((_vm->_game.version <= 2 || (_vm->_game.version >= 4 && _vm->_game.version <= 6)) && _pos == _walkdata.next) { _moving &= ~MF_IN_LEG; 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; @@ -447,9 +634,16 @@ 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; - _walkdata.point3.x = 32000; + + if (_vm->_game.version == 0) { + ((Actor_v0*)this)->_newWalkBoxEntered = true; + } else if (_vm->_game.version <= 2) { + _moving = (_moving & ~(MF_LAST_LEG | MF_IN_LEG)) | MF_NEW_LEG; + } else { + _moving = (_moving & MF_IN_LEG) | MF_NEW_LEG; + } + _walkdata.point3.x = 32000; _walkdata.curbox = _walkbox; } @@ -567,88 +761,206 @@ 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; -} +void Actor_v0::walkActor() { + actorSetWalkTo(); -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 + _needRedraw = true; + if (_NewWalkTo != _CurrentWalkTo) { + _CurrentWalkTo = _NewWalkTo; - double det = v2.x * v1.y - v1.x * v2.y; - if (det == 0) - return false; +L2A33:; + _moving &= 0xF0; + _tmp_Dest = _pos; - 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; + byte tmp = calcWalkDistances(); + _moving &= 0xF0; + _moving |= tmp; - // 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; + 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); + } + } - result.x = line1Start.x + (int)(n1 * v1.x); - result.y = line1Start.y + (int)(n1 * v1.y); - return true; -} + directionUpdate(); + + if (_moving & 0x80) + return; -/* - * 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); + animateActor(newDirToOldDir(_facing)); + + } else { + // 2A0A + if ((_moving & 0x7F) != 1) { + + if (_NewWalkTo == _pos) + return; } } - return false; + // 2A9A + if (_moving == 2) + return; + + if ((_moving & 0x0F) == 1) + return stopActorMoving(); + + // 2AAD + if (_moving & 0x80) { + directionUpdate(); + + if (_moving & 0x80) + return; + + animateActor(newDirToOldDir(_facing)); + } + + if ((_moving & 0x0F) == 3) { +L2C36:; + setTmpFromActor(); + + if (!_walkDirX) { + _pos.x--; + } else { + _pos.x++; + } + + // 2C51 + if (updateWalkbox() != kInvalidBox) { + + setActorFromTmp(); + goto L2A33; + } + + setActorFromTmp(); + + if (_CurrentWalkTo.y == _tmp_Dest.y) { + stopActorMoving(); + return; + } + + if (!_walkDirY) { + _tmp_Dest.y--; + } else { + _tmp_Dest.y++; + } + + setTmpFromActor(); + + 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) { +L2CA3:; + setTmpFromActor(); + + if (!_walkDirY) { + _pos.y--; + } else { + _pos.y++; + } + if (updateWalkbox() == kInvalidBox) { + // 2CC7 + setActorFromTmp(); + if (_CurrentWalkTo.x == _tmp_Dest.x) { + stopActorMoving(); + return; + } + + if (!_walkDirX) { + _tmp_Dest.x--; + } else { + _tmp_Dest.x++; + } + setTmpFromActor(); + + if (updateWalkbox() == kInvalidBox) { + setActorFromTmp(); + stopActorMoving(); + } + + return; + } else { + setActorFromTmp(); + goto L2A33; + } + } + + if ((_moving & 0x0F) == 0) { + // 2AE8 + byte A = actorWalkX(); + + if (A == 1) { + A = actorWalkY(); + if (A == 1) { + _moving &= 0xF0; + _moving |= A; + } else { + 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 L2C36; + + } else { + // 2B39 + A = actorWalkY(); + if (A != 4) + return; + + _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 L2CA3; + } + } + } } void Actor_v2::walkActor() { @@ -697,10 +1009,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); } @@ -972,7 +1282,7 @@ void Actor::setDirection(int direction) { } void Actor_v0::setDirection(int direction) { - int dir = newDirToOldDir( direction ); + int dir = newDirToOldDir(direction); int res = 0; switch (dir) { @@ -985,18 +1295,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 +1325,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 +1399,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)->_newWalkBoxEntered = true; + ((Actor_v0*)this)->_CurrentWalkTo = _pos; + setDirection(oldDirToNewDir(2)); + } } static bool inBoxQuickReject(const BoxCoords &box, int x, int y, int threshold) { @@ -1200,6 +1520,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; + + int16 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; @@ -1410,6 +1783,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; @@ -1451,34 +1825,6 @@ void ScummEngine::showActors() { } } -// bits 0..5: sound, bit 6: ??? -static const byte v0ActorSounds[24] = { - 0x06, // Syd - 0x06, // Razor - 0x06, // Dave - 0x06, // Michael - 0x06, // Bernard - 0x06, // Wendy - 0x00, // Jeff - 0x46, // Radiation Suit - 0x06, // Dr Fred - 0x06, // Nurse Edna - 0x06, // Weird Ed - 0x06, // Dead Cousin Ted - 0xFF, // Purple Tentacle - 0xFF, // Green Tentacle - 0x06, // Meteor police - 0xC0, // Meteor - 0x06, // Mark Eteer - 0x06, // Talkshow Host - 0x00, // Plant - 0xC0, // Meteor Radiation - 0xC0, // Edsel (small, outro) - 0x00, // Meteor (small, intro) - 0x06, // Sandy (Lab) - 0x06, // Sandy (Cut-Scene) -}; - /* Used in Scumm v5 only. Play sounds associated with actors */ void ScummEngine::playActorSounds() { int i, j; @@ -1488,7 +1834,7 @@ void ScummEngine::playActorSounds() { if (_actors[i]->_cost.soundCounter && _actors[i]->isInCurrentRoom()) { _currentScript = 0xFF; if (_game.version == 0) { - sound = v0ActorSounds[i - 1] & 0x3F; + sound = _actors[i]->_sound[0] & 0x3F; } else { sound = _actors[i]->_sound[0]; } @@ -1642,13 +1988,13 @@ 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++; // Is this the correct location? // 0x073C - if (v0ActorTalkArray[a0->_number] & 0x3F) + if (a0->_sound[0] & 0x3F) a0->_cost.soundPos = (a0->_cost.soundPos + 1) % 3; } } @@ -1659,8 +2005,17 @@ void ScummEngine::processActors() { // would hence cause regressions. See also the other big // comment further up in this method for some details. if (a->_costume) { - a->drawActorCostume(); - a->animateCostume(); + + // 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(); + } else { + a->drawActorCostume(); + a->animateCostume(); + } } } } @@ -1948,7 +2303,7 @@ void Actor::startAnimActor(int f) { void Actor_v0::startAnimActor(int f) { if (f == _talkStartFrame) { - if (v0ActorTalkArray[_number] & 0x40) + if (_sound[0] & 0x40) return; _speaking = 1; @@ -2054,7 +2409,7 @@ void Actor_v0::animateCostume() { } void Actor_v0::speakCheck() { - if (v0ActorTalkArray[_number] & 0x80) + if (_sound[0] & 0x80) return; int cmd = newDirToOldDir(_facing); @@ -2897,6 +3252,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); @@ -2910,6 +3329,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 46dc7d0295..c1a3f23318 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,11 +348,32 @@ enum ActorV0MiscFlags { class Actor_v0 : public Actor_v2 { public: + Common::Point _CurrentWalkTo, _NewWalkTo; + byte _costCommandNew; byte _costCommand; byte _miscflags; byte _speaking; + byte _walkCountModulo; + bool _newWalkBoxEntered; + + byte _walkDirX; + byte _walkDirY; + + byte _walkYCountGreaterThanXCount; + byte _walkXCount; + byte _walkXCountInc; + byte _walkYCount; + byte _walkYCountInc; + + byte _walkMaxXYCountInc; + + Common::Point _tmp_Pos; + Common::Point _tmp_Dest; + byte _tmp_WalkBox; + bool _tmp_NewWalkBoxEntered; + int8 _animFrameRepeat; int8 _limbFrameRepeatNew[8]; int8 _limbFrameRepeat[8]; @@ -363,23 +383,32 @@ 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 calcWalkDistances(); + void walkActor(); + void actorSetWalkTo(); + byte actorWalkX(); + byte actorWalkY(); + byte updateWalkbox(); + + AdjustBoxResult adjustXYToBeInBox(int dstX, int dstY); + AdjustBoxResult adjustPosInBorderWalkbox(AdjustBoxResult box); + + 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 70c8f2e032..087d8425ac 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/cdda.cpp b/engines/scumm/cdda.cpp index adb414ecce..d797712a31 100644 --- a/engines/scumm/cdda.cpp +++ b/engines/scumm/cdda.cpp @@ -46,7 +46,7 @@ private: public: CDDAStream(Common::SeekableReadStream *stream, DisposeAfterUse::Flag disposeAfterUse); virtual ~CDDAStream(); - + int readBuffer(int16 *buffer, const int numSamples); bool isStereo() const { return true; } int getRate() const { return 44100; } diff --git a/engines/scumm/detection.cpp b/engines/scumm/detection.cpp index a7922b232e..45647c9bed 100644 --- a/engines/scumm/detection.cpp +++ b/engines/scumm/detection.cpp @@ -244,7 +244,7 @@ static Common::String generateFilenameForDetection(const char *pattern, Filename case kGenRoomNum: result = Common::String::format(pattern, 0); break; - + case kGenDiskNumSteam: case kGenRoomNumSteam: { const SteamIndexFile *indexFile = lookUpSteamIndexFile(pattern, platform); @@ -323,6 +323,8 @@ static BaseScummFile *openDiskImage(const Common::FSNode &node, const GameFilena gs.gameid = gfp->gameid; gs.id = (Common::String(gfp->gameid) == "maniac" ? GID_MANIAC : GID_ZAK); gs.platform = gfp->platform; + if (strcmp(gfp->pattern, "maniacdemo.d64") == 0) + gs.features |= GF_DEMO; // determine second disk file name Common::String disk2(disk1); @@ -502,6 +504,7 @@ static void computeGameSettingsFromMD5(const Common::FSList &fslist, const GameF // (since they have identical MD5): if (dr.game.id == GID_MANIAC && !strcmp(gfp->pattern, "%02d.MAN")) { dr.extra = "V1 Demo"; + dr.game.features = GF_DEMO; } // HACK: Try to detect languages for translated games diff --git a/engines/scumm/detection_tables.h b/engines/scumm/detection_tables.h index 791963e237..82a8b4452b 100644 --- a/engines/scumm/detection_tables.h +++ b/engines/scumm/detection_tables.h @@ -207,6 +207,7 @@ static const Engines::ObsoleteGameID obsoleteGameIDsTable[] = { static const GameSettings gameVariantsTable[] = { {"maniac", "Apple II", 0, GID_MANIAC, 0, 0, MDT_APPLEIIGS, 0, Common::kPlatformApple2GS, GUIO2(GUIO_NOSPEECH, GUIO_NOMIDI)}, {"maniac", "C64", 0, GID_MANIAC, 0, 0, MDT_C64, 0, Common::kPlatformC64, GUIO2(GUIO_NOSPEECH, GUIO_NOMIDI) }, + {"maniac", "C64 Demo", 0, GID_MANIAC, 0, 0, MDT_C64, GF_DEMO, Common::kPlatformC64, GUIO2(GUIO_NOSPEECH, GUIO_NOMIDI) }, {"maniac", "V1", "v1", GID_MANIAC, 1, 0, MDT_PCSPK | MDT_PCJR, 0, Common::kPlatformDOS, GUIO2(GUIO_NOSPEECH, GUIO_NOMIDI)}, {"maniac", "V1 Demo", "v1", GID_MANIAC, 1, 0, MDT_PCSPK | MDT_PCJR, GF_DEMO, Common::kPlatformDOS, GUIO2(GUIO_NOSPEECH, GUIO_NOMIDI)}, {"maniac", "NES", 0, GID_MANIAC, 1, 0, MDT_NONE, 0, Common::kPlatformNES, GUIO3(GUIO_NOSPEECH, GUIO_NOMIDI, GUIO_NOASPECT)}, @@ -448,6 +449,7 @@ static const GameFilenamePattern gameFilenamesTable[] = { { "maniac", "%02d.MAN", kGenRoomNum, UNK_LANG, UNK, "V1 Demo" }, { "maniac", "maniac1.d64", kGenUnchanged, UNK_LANG, Common::kPlatformC64, "C64" }, // ... and maniac2.d64 { "maniac", "maniac1.dsk", kGenUnchanged, UNK_LANG, Common::kPlatformApple2GS, "Apple II" }, // ... and maniac2.dsk + { "maniac", "maniacdemo.d64", kGenUnchanged, UNK_LANG, Common::kPlatformC64, "C64 Demo" }, { "maniac", "Maniac Mansion (E).prg", kGenUnchanged, Common::EN_GRB, Common::kPlatformNES, "NES" }, { "maniac", "Maniac Mansion (F).prg", kGenUnchanged, Common::FR_FRA, Common::kPlatformNES, "NES" }, { "maniac", "Maniac Mansion (SW).prg", kGenUnchanged, Common::SE_SWE, Common::kPlatformNES, "NES" }, @@ -664,6 +666,7 @@ static const GameFilenamePattern gameFilenamesTable[] = { { "dog", "Springparadijs", kGenHEMac, Common::NL_NLD, Common::kPlatformMacintosh, 0 }, { "farm", "farm", kGenHEPC, UNK_LANG, UNK, 0 }, + { "farm", "farm", kGenHEMac, UNK_LANG, Common::kPlatformMacintosh, 0 }, { "farm", "farmdemo", kGenHEPC, UNK_LANG, UNK, 0 }, { "farm", "Farm Demo", kGenHEMac, UNK_LANG, Common::kPlatformMacintosh, 0 }, @@ -680,12 +683,13 @@ static const GameFilenamePattern gameFilenamesTable[] = { { "freddi", "Freddi Demo", kGenHEMac, UNK_LANG, Common::kPlatformMacintosh, 0 }, { "freddi", "Freddi Fish", kGenHEMac, UNK_LANG, Common::kPlatformMacintosh, 0 }, { "freddi", "FreddiD", kGenHEPC, Common::NL_NLD, UNK, 0 }, + { "freddi", "FreddiE", kGenHEPC, UNK_LANG, UNK, 0 }, { "freddi", "Freddi Fisk", kGenHEMac, Common::SE_SWE, Common::kPlatformMacintosh, 0 }, { "freddi", "FRITZI", kGenHEPC, Common::DE_DEU, UNK, 0 }, { "freddi", "Marine Malice", kGenHEMac, Common::FR_FRA, Common::kPlatformMacintosh, 0 }, { "freddi", "MM-DEMO", kGenHEPC, UNK_LANG, UNK, 0 }, - { "freddi2", "freddi2", kGenHEPC, UNK_LANG, UNK, 0 }, + { "freddi2", "freddi2", kGenHEPC, UNK_LANG, Common::kPlatformWindows, 0 }, { "freddi2", "FF2-demo", kGenHEMac, UNK_LANG, Common::kPlatformMacintosh, 0 }, { "freddi2", "ff2-demo", kGenHEPC, UNK_LANG, Common::kPlatformWindows, 0 }, { "freddi2", "FFHSDemo", kGenHEMac, UNK_LANG, Common::kPlatformMacintosh, 0 }, @@ -747,7 +751,7 @@ static const GameFilenamePattern gameFilenamesTable[] = { { "lost", "lost", kGenHEPC, UNK_LANG, UNK, 0 }, { "lost", "Lost and Found", kGenHEMac, UNK_LANG, Common::kPlatformMacintosh, 0 }, { "lost", "smaller", kGenHEPC, UNK_LANG, UNK, 0 }, - { "lost", "verloren", kGenHEPC, Common::NL_NLD, UNK, 0 }, + { "lost", "verloren", kGenHEPC, Common::NL_NLD, Common::kPlatformWindows, 0 }, { "lost", "Verloren", kGenHEMac, Common::NL_NLD, Common::kPlatformMacintosh, 0 }, { "maze", "maze", kGenHEPC, UNK_LANG, UNK, 0 }, @@ -792,7 +796,7 @@ static const GameFilenamePattern gameFilenamesTable[] = { { "pajama2", "PJ2 Demo", kGenHEMac, Common::NL_NLD, Common::kPlatformMacintosh, 0 }, { "pajama2", "PS2DEMO", kGenHEPC, Common::HE_ISR, UNK, 0 }, - { "pajama3", "pajama3", kGenHEPC, UNK_LANG, UNK, 0 }, + { "pajama3", "pajama3", kGenHEPC, UNK_LANG, Common::kPlatformWindows, 0 }, { "pajama3", "FPJ3Demo", kGenHEPC, Common::FR_FRA, UNK, 0 }, { "pajama3", "GPJ3Demo", kGenHEPC, Common::DE_DEU, UNK, 0 }, { "pajama3", "PajamaHTF", kGenHEMac, UNK_LANG, Common::kPlatformMacintosh, 0 }, @@ -854,7 +858,7 @@ static const GameFilenamePattern gameFilenamesTable[] = { { "putttime", "PuttTijd", kGenHEMac, Common::NL_NLD, Common::kPlatformMacintosh, 0 }, { "putttime", "Putt Time", kGenHEMac, UNK_LANG, Common::kPlatformMacintosh, 0 }, { "putttime", "PuttTTT", kGenHEMac, UNK_LANG, Common::kPlatformMacintosh, 0 }, - { "putttime", "PuttTTT", kGenHEPC, UNK_LANG, UNK, 0 }, + { "putttime", "PuttTTT", kGenHEPC, UNK_LANG, Common::kPlatformWindows, 0 }, { "putttime", "TIJDDEMO", kGenHEPC, Common::NL_NLD, Common::kPlatformWindows, 0 }, { "putttime", "TijdDemo", kGenHEMac, Common::NL_NLD, Common::kPlatformMacintosh, 0 }, { "putttime", "timedemo", kGenHEPC, UNK_LANG, UNK, 0 }, @@ -891,7 +895,7 @@ static const GameFilenamePattern gameFilenamesTable[] = { { "socks", "socks", kGenHEPC, UNK_LANG, UNK, 0 }, { "socks", "SockWorks", kGenHEMac, UNK_LANG, Common::kPlatformMacintosh, 0 }, - { "socks", "SokkenSoep", kGenHEPC, Common::NL_NLD, UNK, 0 }, + { "socks", "SokkenSoep", kGenHEPC, Common::NL_NLD, Common::kPlatformWindows, 0 }, { "socks", "SokkenSoep", kGenHEMac, Common::NL_NLD, Common::kPlatformMacintosh, 0 }, { "spyfox", "spyfox", kGenHEPC, UNK_LANG, Common::kPlatformWindows, 0 }, @@ -916,7 +920,7 @@ static const GameFilenamePattern gameFilenamesTable[] = { { "spyfox", "JR-Demo", kGenHEMac, Common::FR_FRA, Common::kPlatformMacintosh, 0 }, { "spyfox", "game", kGenHEIOS, Common::EN_ANY, Common::kPlatformIOS, 0 }, - { "spyfox2", "spyfox2", kGenHEPC, UNK_LANG, UNK, 0 }, + { "spyfox2", "spyfox2", kGenHEPC, UNK_LANG, Common::kPlatformWindows, 0 }, { "spyfox2", "sf2-demo", kGenHEPC, UNK_LANG, UNK, 0 }, { "spyfox2", "sf2demo", kGenHEPC, UNK_LANG, Common::kPlatformWindows, 0 }, { "spyfox2", "Sf2demo", kGenHEMac, UNK_LANG, Common::kPlatformMacintosh, 0 }, diff --git a/engines/scumm/dialogs.cpp b/engines/scumm/dialogs.cpp index 52120949cc..c22525b6f2 100644 --- a/engines/scumm/dialogs.cpp +++ b/engines/scumm/dialogs.cpp @@ -180,9 +180,9 @@ static const ResString string_map_table_v345[] = { // I18N: You may specify 'Yes' symbol at the end of the line, like this: // "Moechten Sie wirklich neu starten? (J/N)J" // Will react to J as 'Yes' - {5, _s("Are you sure you want to restart? (Y/N)")}, + {5, _s("Are you sure you want to restart? (Y/N)Y")}, // I18N: you may specify 'Yes' symbol at the end of the line. See previous comment - {6, _s("Are you sure you want to quit? (Y/N)")}, + {6, _s("Are you sure you want to quit? (Y/N)Y")}, // Added in SCUMM4 {7, _s("Save")}, @@ -460,7 +460,7 @@ const Common::String InfoDialog::queryResString(int stringno) { tmp += chr; } } - return tmp; + return _(tmp); } #pragma mark - diff --git a/engines/scumm/file.cpp b/engines/scumm/file.cpp index 475ffa3238..96b46aa21a 100644 --- a/engines/scumm/file.cpp +++ b/engines/scumm/file.cpp @@ -221,6 +221,15 @@ static const int maniacResourcesPerFile[55] = { 3, 10, 1, 0, 0 }; +static const int maniacDemoResourcesPerFile[55] = { + 0, 12, 0, 2, 1, 12, 1, 13, 6, 0, + 31, 0, 1, 0, 0, 0, 0, 1, 1, 1, + 0, 1, 0, 0, 2, 0, 0, 1, 0, 0, + 2, 7, 1, 11, 0, 0, 5, 1, 0, 0, + 1, 0, 1, 3, 4, 3, 1, 0, 0, 1, + 2, 2, 0, 0, 0 +}; + static const int zakResourcesPerFile[59] = { 0, 29, 12, 14, 13, 4, 4, 10, 7, 4, 14, 19, 5, 4, 7, 6, 11, 9, 4, 4, @@ -253,9 +262,17 @@ ScummDiskImage::ScummDiskImage(const char *disk1, const char *disk2, GameSetting _numGlobalObjects = 256; _numRooms = 55; _numCostumes = 25; - _numScripts = 160; - _numSounds = 70; - _resourcesPerFile = maniacResourcesPerFile; + + if (_game.features & GF_DEMO) { + _numScripts = 55; + _numSounds = 40; + _resourcesPerFile = maniacDemoResourcesPerFile; + } else { + _numScripts = 160; + _numSounds = 70; + _resourcesPerFile = maniacResourcesPerFile; + } + } else { _numGlobalObjects = 775; _numRooms = 59; @@ -327,6 +344,9 @@ bool ScummDiskImage::open(const Common::String &filename) { extractIndex(0); // Fill in resource arrays + if (_game.features & GF_DEMO) + return true; + openDisk(2); if (_game.platform == Common::kPlatformApple2GS) { diff --git a/engines/scumm/input.cpp b/engines/scumm/input.cpp index 824dfec144..86048af57c 100644 --- a/engines/scumm/input.cpp +++ b/engines/scumm/input.cpp @@ -452,8 +452,16 @@ void ScummEngine_v2::processKeyboard(Common::KeyState lastKeyHit) { lastKeyHit = Common::KeyState(Common::KEYCODE_ESCAPE); // F7 is used to skip cutscenes in the Commodote 64 version of Maniac Mansion } else if (_game.id == GID_MANIAC &&_game.platform == Common::kPlatformC64) { - if (lastKeyHit.keycode == Common::KEYCODE_F7 && lastKeyHit.hasFlags(0)) - lastKeyHit = Common::KeyState(Common::KEYCODE_ESCAPE); + // Demo always F7 to be pressed to restart + if (_game.features & GF_DEMO) { + if (_roomResource != 0x2D && lastKeyHit.keycode == Common::KEYCODE_F7 && lastKeyHit.hasFlags(0)) { + restart(); + return; + } + } else { + if (lastKeyHit.keycode == Common::KEYCODE_F7 && lastKeyHit.hasFlags(0)) + lastKeyHit = Common::KeyState(Common::KEYCODE_ESCAPE); + } // 'B' is used to skip cutscenes in the NES version of Maniac Mansion } else if (_game.id == GID_MANIAC &&_game.platform == Common::kPlatformNES) { if (lastKeyHit.keycode == Common::KEYCODE_b && lastKeyHit.hasFlags(Common::KBD_SHIFT)) diff --git a/engines/scumm/resource_v2.cpp b/engines/scumm/resource_v2.cpp index 7ccdfa4780..87dc132ff0 100644 --- a/engines/scumm/resource_v2.cpp +++ b/engines/scumm/resource_v2.cpp @@ -34,8 +34,14 @@ void ScummEngine_v2::readClassicIndexFile() { _numGlobalObjects = 256; _numRooms = 55; _numCostumes = 25; - _numScripts = 160; - _numSounds = 70; + if (_game.features & GF_DEMO) { + _numScripts = 55; + _numSounds = 40; + } else { + _numScripts = 160; + _numSounds = 70; + } + } else if (_game.platform == Common::kPlatformNES) { _numGlobalObjects = 775; _numRooms = 55; diff --git a/engines/scumm/room.cpp b/engines/scumm/room.cpp index 3828629997..4b59e22408 100644 --- a/engines/scumm/room.cpp +++ b/engines/scumm/room.cpp @@ -614,6 +614,15 @@ void ScummEngine_v3old::setupRoomSubBlocks() { } } else { _roomWidth = READ_LE_UINT16(&(rmhd->old.width)); + + // WORKAROUND: Fix bad width value for room 64 (book of maps) in + // Indy3. A specific version of this game (DOS/EGA v1.0, according to + // scumm-md5.txt) has a wrong width of 1793 stored in the data files, + // which causes a strange situation in which the book view may scroll + // towards the right depending on Indy's position from the previous room. + // Fixes bug #6679. + if (_game.id == GID_INDY3 && _roomResource == 64 && _roomWidth == 1793) + _roomWidth = 320; _roomHeight = READ_LE_UINT16(&(rmhd->old.height)); } _numObjectsInRoom = roomptr[20]; diff --git a/engines/scumm/saveload.cpp b/engines/scumm/saveload.cpp index 7eadb042fb..0c0f6be73b 100644 --- a/engines/scumm/saveload.cpp +++ b/engines/scumm/saveload.cpp @@ -109,7 +109,12 @@ Common::Error ScummEngine::saveGameState(int slot, const Common::String &desc) { } bool ScummEngine::canSaveGameStateCurrently() { - // FIXME: For now always allow loading in V0-V3 games + // Disallow saving in v0-v3 games when a 'prequel' to a cutscene is shown. + // This is a blank screen with text, and while this is shown, saving should + // be disabled, as no room is set. + if (_game.version <= 3 && _currentScript == 0xFF && _roomResource == 0 && _currentRoom == 0) + return false; + // TODO: Should we disallow saving in some more places, // e.g. when a SAN movie is playing? Not sure whether the // original EXE allowed this. diff --git a/engines/scumm/saveload.h b/engines/scumm/saveload.h index 01ed21ece5..753287e217 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 2fe5333bfc..c9b37d43b1 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) + 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 a7999a2695..609cbd1e89 100644 --- a/engines/scumm/script_v0.cpp +++ b/engines/scumm/script_v0.cpp @@ -172,7 +172,7 @@ void ScummEngine_v0::setupOpcodes() { /* 6C */ OPCODE(0x6c, o_stopCurrentScript); OPCODE(0x6d, o2_putActorInRoom); - OPCODE(0x6e, o2_dummy); + OPCODE(0x6e, o_screenPrepare); OPCODE(0x6f, o2_ifState08); /* 70 */ OPCODE(0x70, o_lights); @@ -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; @@ -633,12 +633,21 @@ void ScummEngine_v0::setMode(byte mode) { switch (_currentMode) { case kModeCutscene: + if (_game.features & GF_DEMO) { + if (VAR(11) != 0) + _drawDemo = true; + } _redrawSentenceLine = false; // Note: do not change freeze state here state = USERSTATE_SET_IFACE | USERSTATE_SET_CURSOR; + break; case kModeKeypad: + if (_game.features & GF_DEMO) { + if (VAR(11) != 0) + _drawDemo = true; + } _redrawSentenceLine = false; state = USERSTATE_SET_IFACE | USERSTATE_SET_CURSOR | USERSTATE_CURSOR_ON | @@ -646,6 +655,12 @@ void ScummEngine_v0::setMode(byte mode) { break; case kModeNormal: case kModeNoNewKid: + if (_game.features & GF_DEMO) { + resetVerbs(); + _activeVerb = kVerbWalkTo; + _redrawSentenceLine = true; + _drawDemo = false; + } state = USERSTATE_SET_IFACE | USERSTATE_IFACE_ALL | USERSTATE_SET_CURSOR | USERSTATE_CURSOR_ON | USERSTATE_SET_FREEZE; @@ -707,17 +722,14 @@ void ScummEngine_v0::o_animateActor() { } a->animateActor(anim); - a->animateCostume(); } 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() { @@ -970,6 +982,10 @@ void ScummEngine_v0::o_setOwnerOf() { setOwnerOf(obj, owner); } +void ScummEngine_v0::o_screenPrepare() { + +} + void ScummEngine_v0::resetSentence() { _activeVerb = kVerbWalkTo; _activeObject = 0; diff --git a/engines/scumm/script_v2.cpp b/engines/scumm/script_v2.cpp index 74d0aa2483..a7ec2e644f 100644 --- a/engines/scumm/script_v2.cpp +++ b/engines/scumm/script_v2.cpp @@ -1390,7 +1390,14 @@ void ScummEngine_v2::o2_loadRoomWithEgo() { a = derefActor(VAR(VAR_EGO), "o2_loadRoomWithEgo"); - a->putActor(0, 0, room); + // The original interpreter sets the actors new room X/Y to the last rooms X/Y + // This fixes a problem with MM: script 161 in room 12, the 'Oomph!' script + // This scripts runs before the actor position is set to the correct room entry location + if ((_game.id == GID_MANIAC) && (_game.platform != Common::kPlatformNES)) { + a->putActor(a->getPos().x, a->getPos().y, room); + } else { + a->putActor(0, 0, room); + } _egoPositioned = false; x = (int8)fetchScriptByte(); diff --git a/engines/scumm/script_v5.cpp b/engines/scumm/script_v5.cpp index 91afa859a9..4a53ca3fed 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() { diff --git a/engines/scumm/scumm-md5.h b/engines/scumm/scumm-md5.h index 0eeff57ff7..5be18fb990 100644 --- a/engines/scumm/scumm-md5.h +++ b/engines/scumm/scumm-md5.h @@ -1,5 +1,5 @@ /* - This file was generated by the md5table tool on Wed Jun 25 10:34:07 2014 + This file was generated by the md5table tool on Sun Dec 7 23:09:10 2014 DO NOT EDIT MANUALLY! */ @@ -20,7 +20,7 @@ static const MD5Table md5table[] = { { "0354ee0d14cde1264ec762261c04c14a", "loom", "Steam", "Steam", 585728, Common::EN_ANY, Common::kPlatformWindows }, { "035deab53b47bc43abc763560d0f8d4b", "atlantis", "Floppy", "Demo", -1, Common::EN_ANY, Common::kPlatformDOS }, { "037385a953789190298494d92b89b3d0", "catalog", "HE 72", "Demo", -1, Common::EN_ANY, Common::kPlatformWindows }, - { "03d3b18ee3fd68114e2a687c871e38d5", "freddi4", "HE 99", "Mini Game", -1, Common::EN_USA, Common::kPlatformWindows }, + { "03d3b18ee3fd68114e2a687c871e38d5", "freddi4", "HE 99", "Mini Game", 13609, Common::EN_USA, Common::kPlatformWindows }, { "0425954a9db5c340861672892c3e678d", "samnmax", "", "Demo", -1, Common::EN_ANY, Common::kPlatformUnknown }, { "04401d747f1a2c1c4b388daff71ed378", "ft", "", "", 535405461, Common::DE_DEU, Common::kPlatformMacintosh }, { "04687cdf7f975a89d2474929f7b80946", "indy3", "FM-TOWNS", "", 7552, Common::EN_ANY, Common::kPlatformFMTowns }, @@ -28,7 +28,7 @@ static const MD5Table md5table[] = { { "055ffe4f47753e47594ac67823220c54", "puttrace", "HE 99", "", -1, Common::DE_DEU, Common::kPlatformUnknown }, { "057c9b456dedcc4d71b991a3072a20b3", "monkey", "SEGA", "", 9465, Common::JA_JPN, Common::kPlatformSegaCD }, { "06b187468113f9ae5a400b148a847fac", "atlantis", "Floppy", "Floppy", 12075, Common::EN_ANY, Common::kPlatformMacintosh }, - { "06c3cf4f31daad8b1cd93153491db9e6", "pajama3", "", "", -1, Common::NL_NLD, Common::kPlatformMacintosh }, + { "06c3cf4f31daad8b1cd93153491db9e6", "pajama3", "", "", 79382, Common::NL_NLD, Common::kPlatformUnknown }, { "07433205acdca3bc553d0e731588b35f", "airport", "", "", -1, Common::EN_ANY, Common::kPlatformWindows }, { "07a1eefd8ca95d77310311446c0f53d0", "brstorm", "", "", 5433, Common::EN_ANY, Common::kPlatformUnknown }, { "07b810e37be7489263f7bc7627d4765d", "freddi4", "unenc", "Unencrypted", -1, Common::RU_RUS, Common::kPlatformWindows }, @@ -37,10 +37,11 @@ static const MD5Table md5table[] = { { "08656dd9698ddf1023ba9bf8a195e37b", "monkey", "VGA", "VGA", -1, Common::EN_ANY, Common::kPlatformDOS }, { "08cc5c3eedaf72ebe12734eee94f7fa2", "balloon", "HE 80", "", -1, Common::EN_ANY, Common::kPlatformUnknown }, { "09820417db26687bb7fe0c83cc4c553b", "ft", "", "Version A", 19697, Common::EN_ANY, Common::kPlatformUnknown }, + { "09b0be55c16cd9e88b5080bf89ff281d", "freddi4", "HE 99", "Mini Game", 13609, Common::DE_DEU, Common::kPlatformWindows }, { "0a212fa35fa8421f31c1f3961272caf0", "monkey", "VGA", "VGA", -1, Common::DE_DEU, Common::kPlatformAmiga }, { "0a295b80f9a9edf818e8e161a0e83830", "freddi2", "HE 80", "", -1, Common::FR_FRA, Common::kPlatformUnknown }, { "0a41311d462b6639fc45297b9044bf16", "monkey", "No AdLib", "EGA", -1, Common::ES_ESP, Common::kPlatformAtariST }, - { "0a6d7b81b850ed4a77811c60c9b5c555", "PuttTime", "HE 99", "Mini Game", -1, Common::EN_USA, Common::kPlatformWindows }, + { "0a6d7b81b850ed4a77811c60c9b5c555", "PuttTime", "HE 99", "Mini Game", 18458, Common::EN_USA, Common::kPlatformWindows }, { "0aa050f4ad79402fbe9c4f78fb8ac494", "loom", "PC-Engine", "", 6532, Common::EN_ANY, Common::kPlatformPCEngine }, { "0ab19be9e2a3f6938226638b2a3744fe", "PuttTime", "HE 100", "Demo", -1, Common::EN_USA, Common::kPlatformUnknown }, { "0ac41e2e3d2174e5a042a6b565328dba", "puttrace", "HE 98", "Demo", 13110, Common::EN_USA, Common::kPlatformUnknown }, @@ -112,12 +113,14 @@ static const MD5Table md5table[] = { { "2108d83dcf09f8adb4bc524669c8cf51", "PuttTime", "HE 99", "Updated", -1, Common::EN_USA, Common::kPlatformUnknown }, { "21a6592322f92550f144f68a8a4e685e", "dig", "", "", -1, Common::FR_FRA, Common::kPlatformMacintosh }, { "21abe302e1b1e2b66d6f5c12e241ebfd", "freddicove", "unenc", "Unencrypted", -1, Common::RU_RUS, Common::kPlatformWindows }, - { "2232b0b9411575b1f9961713ebc9de61", "balloon", "HE 80", "", -1, Common::UNK_LANG, Common::kPlatformWindows }, + { "2232b0b9411575b1f9961713ebc9de61", "balloon", "HE 80", "", -1, Common::NL_NLD, Common::kPlatformWindows }, { "225e18566e810c634bf7de63e7568e3e", "mustard", "", "", -1, Common::EN_USA, Common::kPlatformUnknown }, + { "22c7432dc97a821fcfccd480e93e3911", "spyfox2", "", "Mini Game", 14689, Common::NL_NLD, Common::kPlatformWindows }, { "22c9eb04455440131ffc157aeb8d40a8", "fbear", "HE 70", "Demo", -1, Common::EN_ANY, Common::kPlatformWindows }, { "22de86b2f7ec6e5db745ed1123310b44", "spyfox2", "", "Demo", 15832, Common::FR_FRA, Common::kPlatformWindows }, { "22f4ea88a09da12df9308ba30bcb7d0f", "loom", "EGA", "EGA", -1, Common::EN_ANY, Common::kPlatformDOS }, { "23394c8d29cc63c61313959431a12476", "spyfox", "HE 100", "Updated", -1, Common::EN_ANY, Common::kPlatformWindows }, + { "24942a4200d99bdb4bdb78f9c7e07027", "pajama3", "", "Mini Game", 13911, Common::NL_NLD, Common::kPlatformWindows }, { "254fede2f15dbb32a23760d601b01816", "zak", "V1", "", -1, Common::EN_ANY, Common::kPlatformC64 }, { "2723fea3dae0cb47768c424b145ae0e7", "tentacle", "Floppy", "Floppy", 7932, Common::EN_ANY, Common::kPlatformDOS }, { "27b2ef1653089fe5b897d9cc89ce784f", "balloon", "HE 80", "", -1, Common::RU_RUS, Common::kPlatformWindows }, @@ -132,6 +135,7 @@ static const MD5Table md5table[] = { { "2a446817ffcabfef8716e0c456ecaf81", "puttzoo", "", "Demo", -1, Common::DE_DEU, Common::kPlatformWindows }, { "2a8658dbd13d84d1bce64a71a35995eb", "pajama2", "HE 99", "Demo", -1, Common::HE_ISR, Common::kPlatformWindows }, { "2c04aacffb8428f30ccf4f734fbe3adc", "activity", "", "", -1, Common::EN_ANY, Common::kPlatformDOS }, + { "2cb46375dd5cdfd023e2f07e0a21b530", "maniac", "C64", "Demo", -1, Common::EN_ANY, Common::kPlatformC64 }, { "2ccd8891ce4d3f1a334d21bff6a88ca2", "monkey", "CD", "", 9455, Common::EN_ANY, Common::kPlatformMacintosh }, { "2d1e891fe52df707c30185e52c50cd92", "monkey", "CD", "CD", 8955, Common::EN_ANY, Common::kPlatformDOS }, { "2d388339d6050d8ccaa757b64633954e", "indyloom", "FM-TOWNS", "Demo", 7520, Common::EN_ANY, Common::kPlatformFMTowns }, @@ -230,7 +234,7 @@ static const MD5Table md5table[] = { { "4f580a021eee026f3b4589e17d130d78", "freddi4", "", "", -1, Common::UNK_LANG, Common::kPlatformUnknown }, { "4fa6870d9bc8c313b65d54b1da5a1891", "pajama", "", "", -1, Common::NL_NLD, Common::kPlatformUnknown }, { "4fbbe9f64b8bc547503a379a301183ce", "tentacle", "", "CD", -1, Common::IT_ITA, Common::kPlatformUnknown }, - { "4fe6a2e8df3c4536b278fdd2fbcb181e", "pajama3", "", "Mini Game", -1, Common::EN_ANY, Common::kPlatformWindows }, + { "4fe6a2e8df3c4536b278fdd2fbcb181e", "pajama3", "", "Mini Game", 13911, Common::EN_ANY, Common::kPlatformWindows }, { "5057fb0e99e5aa29df1836329232f101", "freddi2", "HE 80", "", -1, Common::UNK_LANG, Common::kPlatformWindows }, { "507bb360688dc4180fdf0d7597352a69", "freddi", "HE 73", "", 26402, Common::SE_SWE, Common::kPlatformWindows }, { "50b831f11b8c4b83784cf81f4dcc69ea", "spyfox", "HE 101", "", -1, Common::EN_ANY, Common::kPlatformWii }, @@ -302,6 +306,7 @@ static const MD5Table md5table[] = { { "6a60d395b78b205c93a956100b1bf5ae", "pajama2", "HE 98.5", "", -1, Common::DE_DEU, Common::kPlatformUnknown }, { "6a8133b63d46f6663fbcbb49d5a2edb1", "atlantis", "Steam", "Steam", 520548, Common::EN_ANY, Common::kPlatformMacintosh }, { "6af2419fe3db5c2fdb091ae4e5833770", "puttrace", "HE 98.5", "Demo", -1, Common::NL_NLD, Common::kPlatformUnknown }, + { "6b10c9977cad9de503642059359792b1", "spyfox2", "", "Mini Game", 14689, Common::FR_FRA, Common::kPlatformWindows }, { "6b19d0e25cbf720d05822379b8b90ed9", "PuttTime", "HE 90", "Demo", -1, Common::NL_NLD, Common::kPlatformUnknown }, { "6b257bb2827dd894b8109a50a1a18b5a", "freddicove", "HE 100", "Demo", -1, Common::NL_NLD, Common::kPlatformUnknown }, { "6b27dbcd8d5697d5c918eeca0f68ef6a", "puttrace", "HE CUP", "Preview", 3901484, Common::UNK_LANG, Common::kPlatformUnknown }, @@ -310,7 +315,8 @@ static const MD5Table md5table[] = { { "6bca7a1a96d16e52b8f3c42b50dbdca3", "fbear", "HE 62", "", -1, Common::JA_JPN, Common::kPlatform3DO }, { "6bf70eee5de3d24d2403e0dd3d267e8a", "spyfox", "", "", 49221, Common::UNK_LANG, Common::kPlatformWindows }, { "6c2bff0e327f2962e809c2e1a82d7309", "monkey", "VGA", "VGA", -1, Common::EN_ANY, Common::kPlatformAmiga }, - { "6d1baa1065ac5f7b210be8ebe4235e49", "freddi", "HE 73", "", -1, Common::NL_NLD, Common::kPlatformMacintosh }, + { "6c375c2236d99f56e6c2cf540e74e474", "farm", "", "Demo", 34333, Common::NL_NLD, Common::kPlatformWindows }, + { "6d1baa1065ac5f7b210be8ebe4235e49", "freddi", "HE 73", "", 26384, Common::NL_NLD, Common::kPlatformMacintosh }, { "6dead580b0ff14d5f7b33b4219f04159", "samnmax", "", "Demo", 16556335, Common::EN_ANY, Common::kPlatformMacintosh }, { "6df20c50c1ab19799de9be7ae7716881", "fbear", "HE 62", "Demo", -1, Common::EN_ANY, Common::kPlatformMacintosh }, { "6e959d65358eedf9b68b81e304b97fa4", "tentacle", "", "CD", 7932, Common::DE_DEU, Common::kPlatformUnknown }, @@ -324,7 +330,7 @@ static const MD5Table md5table[] = { { "70b0719ac3a5b47ae233c561823d5b96", "puttzoo", "", "", -1, Common::NL_NLD, Common::kPlatformMacintosh }, { "71523b539491527d9860f4407faf0411", "monkey", "Demo", "EGA Demo", 7607, Common::EN_ANY, Common::kPlatformDOS }, { "71d384e7676c53d513ddd333eae1d82c", "Blues123time", "", "", -1, Common::EN_ANY, Common::kPlatformUnknown }, - { "71fe97c3108678cf604f14abe342341b", "spyfox2", "", "", -1, Common::NL_NLD, Common::kPlatformWindows }, + { "71fe97c3108678cf604f14abe342341b", "spyfox2", "", "", 51286, Common::NL_NLD, Common::kPlatformUnknown }, { "7222f260253f325c21fcfa68b5bfab67", "spyfox2", "", "Demo", -1, Common::EN_USA, Common::kPlatformUnknown }, { "72ac6bc980d5101c2142189d746bd62f", "spyfox", "HE 99", "", -1, Common::RU_RUS, Common::kPlatformWindows }, { "732845548b1d6c2da572cb6a1bf81b07", "spyfox2", "", "Demo", -1, Common::DE_DEU, Common::kPlatformUnknown }, @@ -348,6 +354,7 @@ static const MD5Table md5table[] = { { "78c07ca088526d8d4446a4c2cb501203", "freddi3", "HE 99", "", -1, Common::FR_FRA, Common::kPlatformUnknown }, { "7974365d3dc0f43a2748c975f91ff042", "monkey2", "", "", -1, Common::ES_ESP, Common::kPlatformDOS }, { "79b05f628586837e7166e82b2279bb50", "loom", "PC-Engine", "", -1, Common::JA_JPN, Common::kPlatformPCEngine }, + { "7a2b6d8e8a645c9d534c8c4edc38a9c9", "freddi4", "HE 99", "Mini Game", 13609, Common::IT_ITA, Common::kPlatformWindows }, { "7b4ee071eecadc2d8cd0c3509110825c", "puttzoo", "HE 100", "Remastered", -1, Common::EN_ANY, Common::kPlatformWindows }, { "7bad72e332a59f9fcc1d437f4edad32a", "puttcircus", "", "", -1, Common::RU_RUS, Common::kPlatformUnknown }, { "7c2e76087027eeee9c8f8985f93a1cc5", "freddi4", "", "Demo", 13584, Common::EN_ANY, Common::kPlatformUnknown }, @@ -357,6 +364,7 @@ static const MD5Table md5table[] = { { "7e151c17adf624f1966c8fc5827c95e9", "puttputt", "HE 61", "", -1, Common::EN_ANY, Common::kPlatform3DO }, { "7ea2da67ebabea4ac20cee9f4f9d2934", "airport", "", "Demo", -1, Common::EN_ANY, Common::kPlatformMacintosh }, { "7edd665bbede7ea8b7233f8e650be6f8", "samnmax", "", "CD", -1, Common::FR_FRA, Common::kPlatformUnknown }, + { "7f2578d8d33a9ff525488a2d9ba617e4", "spyfox2", "", "Mini Game", 14689, Common::DE_DEU, Common::kPlatformWindows }, { "7f45ddd6dbfbf8f80c0c0efea4c295bc", "maniac", "V1", "V1", 1972, Common::EN_ANY, Common::kPlatformDOS }, { "7f945525abcd48015adf1632637a44a1", "pajama", "", "Demo", -1, Common::FR_FRA, Common::kPlatformUnknown }, { "7fbcff27c323499beaedd605e1ebd47d", "indy3", "Steam", "Steam", 561152, Common::EN_ANY, Common::kPlatformWindows }, @@ -389,13 +397,15 @@ static const MD5Table md5table[] = { { "8afb3cf9f95abf208358e984f0c9e738", "funpack", "", "", -1, Common::EN_ANY, Common::kPlatform3DO }, { "8bdb0bf87b5e303dd35693afb9351215", "ft", "", "", -1, Common::DE_DEU, Common::kPlatformUnknown }, { "8d479e36f35e80257dfc102cf4b8a912", "farm", "HE 72", "Demo", 34333, Common::EN_ANY, Common::kPlatformWindows }, + { "8dd4d590685c19bf651b5016e749ead2", "PuttTime", "HE 99", "Mini Game", 18458, Common::FR_FRA, Common::kPlatformWindows }, { "8de13897f0121c79d29a2377159f9ad0", "socks", "HE 99", "Updated", -1, Common::EN_ANY, Common::kPlatformWindows }, { "8e3241ddd6c8dadf64305e8740d45e13", "balloon", "HE 100", "Updated", -1, Common::EN_ANY, Common::kPlatformUnknown }, { "8e4ee4db46954bfe2912e259a16fad82", "monkey2", "", "", -1, Common::FR_FRA, Common::kPlatformDOS }, { "8e9417564f33790815445b2136efa667", "atlantis", "", "CD", 11915, Common::JA_JPN, Common::kPlatformMacintosh }, - { "8e9830a6f2702be5b22c8fa0a6aaf977", "freddi2", "HE 80", "", -1, Common::NL_NLD, Common::kPlatformMacintosh }, + { "8e9830a6f2702be5b22c8fa0a6aaf977", "freddi2", "HE 80", "", 65305, Common::NL_NLD, Common::kPlatformUnknown }, { "8eb84cee9b429314c7f0bdcf560723eb", "monkey", "FM-TOWNS", "", 9925, Common::EN_ANY, Common::kPlatformFMTowns }, { "8ee63cafb1fe9d62aa0d5a23117e70e7", "freddi2", "HE 100", "Updated", -1, Common::EN_USA, Common::kPlatformUnknown }, + { "8f345db2f3f5a25ed6305001957e6f72", "freddicove", "HE 100", "", 41182, Common::NL_NLD, Common::kPlatformUnknown }, { "8f3758ff98c9c5d78e5d635222cad026", "atlantis", "Floppy", "Floppy", -1, Common::IT_ITA, Common::kPlatformDOS }, { "8fec68383202d38c0d25e9e3b757c5df", "comi", "Demo", "Demo", 18041, Common::UNK_LANG, Common::kPlatformWindows }, { "8ffd618a776a4c0d8922bb28b09f8ce8", "airport", "", "Demo", -1, Common::EN_ANY, Common::kPlatformWindows }, @@ -409,11 +419,13 @@ static const MD5Table md5table[] = { { "92b078d9d6d9d751da9c26b8b3075779", "tentacle", "Floppy", "Floppy", -1, Common::FR_FRA, Common::kPlatformDOS }, { "92e7727e67f5cd979d8a1070e4eb8cb3", "puttzoo", "HE 98.5", "Updated", -1, Common::EN_ANY, Common::kPlatformUnknown }, { "92fc0073a4cf259ff36070ecb8628ba8", "thinkerk", "", "", -1, Common::EN_USA, Common::kPlatformUnknown }, + { "9340b552b0f2dffe6d4f3d13ebebe832", "freddi4", "HE 99", "Mini Game", 13609, Common::NL_NLD, Common::kPlatformWindows }, { "94aaedbb8f26d71ed3ad6dd34490e29e", "tentacle", "Floppy", "Floppy", -1, Common::FR_FRA, Common::kPlatformDOS }, { "94db6519da85b8d08c976d8e9a858ea7", "baseball", "HE CUP", "Preview", 10044774, Common::UNK_LANG, Common::kPlatformUnknown }, { "95818b178d473c989ac753574e8892aa", "readtime", "", "Demo", -1, Common::EN_ANY, Common::kPlatformUnknown }, { "95b3806e043be08668c54c3ffe98650f", "BluesABCTime", "", "", -1, Common::EN_ANY, Common::kPlatformUnknown }, { "95be99181bd0f10fef4872c2d4a771cb", "zak", "V1", "", -1, Common::DE_DEU, Common::kPlatformC64 }, + { "9684c161258d68e0d464d6cab7024b9c", "spyfox2", "", "Mini Game", 14689, Common::IT_ITA, Common::kPlatformWindows }, { "96a3069a3c63caa7329588ce1fef41ee", "spyozon", "", "", -1, Common::RU_RUS, Common::kPlatformUnknown }, { "9708cf716ed8bcc9ff3fcfc69413b746", "puttputt", "HE 62", "", -1, Common::EN_ANY, Common::kPlatformDOS }, { "9778341eefc6feb447ca07e7be21791c", "puttrace", "HE 99", "Demo", -1, Common::IT_ITA, Common::kPlatformWindows }, @@ -459,9 +471,11 @@ static const MD5Table md5table[] = { { "a59a438cb182124c30c4447d8ed469e9", "freddi", "HE 100", "", 34837, Common::NB_NOR, Common::kPlatformWii }, { "a5c5388da9bf0e6662fdca8813a79d13", "farm", "", "", 86962, Common::EN_ANY, Common::kPlatformWindows }, { "a654fb60c3b67d6317a7894ffd9f25c5", "pajama3", "", "Demo", -1, Common::EN_USA, Common::kPlatformUnknown }, + { "a71014c53a6d18c66ef2ea0ee42328e9", "PuttTime", "HE 99", "Mini Game", 18458, Common::NL_NLD, Common::kPlatformWindows }, { "a7cacad9c40c4dc9e1812abf6c8af9d5", "puttcircus", "", "Demo", -1, Common::EN_ANY, Common::kPlatformUnknown }, { "a85856675429fe88051744f755b72f93", "farm", "", "", -1, Common::EN_ANY, Common::kPlatformWindows }, { "a86f9c49355579c30d4a55b477c0d869", "baseball2001", "", "", -1, Common::EN_ANY, Common::kPlatformUnknown }, + { "a8fcc3084ad5e3e569722755f205b1ef", "pajama3", "", "Mini Game", 13911, Common::DE_DEU, Common::kPlatformWindows }, { "a9543ef0d79bcb47cd76ec197ad0a967", "puttmoon", "", "", -1, Common::EN_ANY, Common::kPlatform3DO }, { "a99c39ba65b6086be28aef576da69595", "spyozon", "", "Demo", -1, Common::FR_FRA, Common::kPlatformWindows }, { "a9f2f04b1ecaab9495b59befffe9bf88", "pajama3", "", "Demo", -1, Common::EN_USA, Common::kPlatformUnknown }, @@ -478,6 +492,7 @@ static const MD5Table md5table[] = { { "acad97ab1c6fc2a5b2d98abf6db4a190", "tentacle", "Floppy", "Floppy", -1, Common::EN_ANY, Common::kPlatformUnknown }, { "ae94f110a14ce71fc515d5b648827a8f", "tentacle", "Floppy", "Floppy", -1, Common::ES_ESP, Common::kPlatformDOS }, { "aeec382acef62e122bf0d5b14581cfa4", "zak", "V1", "", -1, Common::IT_ITA, Common::kPlatformC64 }, + { "aef415cc5dc063e3668359c2657169f3", "PuttTime", "HE 99", "Mini Game", 18458, Common::DE_DEU, Common::kPlatformWindows }, { "aefa244ea034b7cd2041f0a44be7d9ba", "pajama3", "", "", -1, Common::EN_ANY, Common::kPlatformMacintosh }, { "af2bd1a43b50b55915d87994e093203d", "freddi", "HE 99", "Updated", 34829, Common::DE_DEU, Common::kPlatformWindows }, { "b100abf7ff83146df50db78dbd5e9cfa", "freddicove", "HE 100", "", -1, Common::FR_FRA, Common::kPlatformUnknown }, @@ -505,7 +520,7 @@ static const MD5Table md5table[] = { { "be83e882b44f2767bc08d4f766ebc347", "maniac", "V2", "V2", -1, Common::DE_DEU, Common::kPlatformAtariST }, { "bf8b52fdd9a69c67f34e8e9fec72661c", "farm", "HE 71", "Demo", -1, Common::EN_ANY, Common::kPlatformWindows }, { "bfdf584b01503f0762baded581f6a0a2", "SoccerMLS", "", "", -1, Common::EN_ANY, Common::kPlatformWindows }, - { "c0039ad982999c92d0de81910d640fa0", "freddi", "HE 71", "", -1, Common::NL_NLD, Common::kPlatformWindows }, + { "c0039ad982999c92d0de81910d640fa0", "freddi", "HE 71", "", 26159, Common::NL_NLD, Common::kPlatformWindows }, { "c13225cb1bbd3bc9fe578301696d8021", "monkey", "SEGA", "", -1, Common::EN_ANY, Common::kPlatformSegaCD }, { "c20848f53c2d48bfacdc840993843765", "freddi2", "HE 80", "Demo", -1, Common::NL_NLD, Common::kPlatformUnknown }, { "c225bec1b6c0798a2b8c89ac226dc793", "pajama", "HE 101", "", -1, Common::EN_ANY, Common::kPlatformWii }, @@ -516,6 +531,7 @@ static const MD5Table md5table[] = { { "c3b22fa4654bb580b20325ebf4174841", "puttzoo", "", "", -1, Common::NL_NLD, Common::kPlatformWindows }, { "c3df37df9d3b481b45f75283a9907c47", "loom", "EGA", "EGA", -1, Common::IT_ITA, Common::kPlatformDOS }, { "c4787c3e8b5e2dfda90850ee800af00f", "zak", "V2", "V2", -1, Common::FR_FRA, Common::kPlatformDOS }, + { "c486e4cfa7bd6f8efcd0740f96f7dde3", "freddi4", "HE 99", "Mini Game", 13609, Common::FR_FRA, Common::kPlatformWindows }, { "c4ffae9fac495475d6bc3343ccc8faf9", "Soccer2004", "", "", -1, Common::EN_ANY, Common::kPlatformUnknown }, { "c5cc7cba02a2fbd539c4439e775b0536", "puttzoo", "HE 99", "Updated", 43470, Common::DE_DEU, Common::kPlatformWindows }, { "c5d10e190d4b4d59114b824f2fdbd00e", "loom", "FM-TOWNS", "", 7540, Common::EN_ANY, Common::kPlatformFMTowns }, @@ -555,6 +571,7 @@ static const MD5Table md5table[] = { { "d06fbe28818fef7bfc45c2cdf0c0849d", "zak", "V2", "V2", -1, Common::DE_DEU, Common::kPlatformDOS }, { "d0ad929def3e9cfe39dea55bd12098d4", "puttcircus", "", "", -1, Common::FR_FRA, Common::kPlatformWindows }, { "d0b531227a27c6662018d2bd05aac52a", "monkey", "VGA", "VGA", 8357, Common::DE_DEU, Common::kPlatformDOS }, + { "d1a73e87564477c7c2dcc2b8f616ad0b", "pajama3", "", "Mini Game", 13911, Common::IT_ITA, Common::kPlatformWindows }, { "d220d154aafbfa12bd6f3ab1b2dae420", "puttzoo", "", "Demo", -1, Common::DE_DEU, Common::kPlatformMacintosh }, { "d2cc8e31bce61e6cf2951249e10638fe", "basketball", "", "", -1, Common::EN_ANY, Common::kPlatformUnknown }, { "d37c55388294b66e53e7ced3af88fa68", "freddi2", "HE 100", "Updated Demo", -1, Common::EN_ANY, Common::kPlatformUnknown }, @@ -602,7 +619,7 @@ static const MD5Table md5table[] = { { "e534d29afb3c6e0ee9dc3d53c5956714", "atlantis", "Floppy", "Floppy", -1, Common::DE_DEU, Common::kPlatformAmiga }, { "e5563c8358443c4352fcddf7402a5e0a", "pajama2", "HE 98.5", "", -1, Common::FR_FRA, Common::kPlatformWindows }, { "e5c112140ad6574997de033a8e2a2964", "readtime", "", "", -1, Common::EN_ANY, Common::kPlatformUnknown }, - { "e62056ba675ad65d8854ab3c5ad4b3c0", "spyfox2", "", "Mini Game", -1, Common::EN_ANY, Common::kPlatformWindows }, + { "e62056ba675ad65d8854ab3c5ad4b3c0", "spyfox2", "", "Mini Game", 14689, Common::EN_ANY, Common::kPlatformWindows }, { "e63a0b9249b5ca4cc4d3ac34305ae360", "freddi", "HE 99", "", -1, Common::NB_NOR, Common::kPlatformWindows }, { "e689bdf67f98b1d760ce4487ec0e8d06", "indy3", "EGA", "EGA", -1, Common::FR_FRA, Common::kPlatformAmiga }, { "e6cd81b25ab1453a8a6d3482118c391e", "pass", "", "", 7857, Common::EN_ANY, Common::kPlatformDOS }, @@ -624,7 +641,9 @@ static const MD5Table md5table[] = { { "edfdb24a499d92c59f824c52987c0eec", "atlantis", "Floppy", "Floppy", -1, Common::FR_FRA, Common::kPlatformDOS }, { "ee41f6afbc5b26fa475754b56fe92048", "puttputt", "HE 61", "", 8032, Common::JA_JPN, Common::kPlatform3DO }, { "ee785fe2569bc9965526e774f7ab86f1", "spyfox", "HE 99", "", -1, Common::FR_FRA, Common::kPlatformMacintosh }, + { "ee8cfeb76e55d43a01c25e0865a9db76", "puttrace", "HE 98", "Demo", 13135, Common::NL_NLD, Common::kPlatformMacintosh }, { "eea4d9ac2fb6f145945a308e8866915b", "maniac", "C64", "", -1, Common::EN_ANY, Common::kPlatformC64 }, + { "eeb606c2d2ec877a712a9f20c10bcdda", "farm", "", "", 87034, Common::NL_NLD, Common::kPlatformMacintosh }, { "ef347474f3c7be3b29584eaa133cca05", "samnmax", "Floppy", "Floppy", -1, Common::FR_FRA, Common::kPlatformDOS }, { "ef71a322b6530ac45b1a070f7c0795f7", "moonbase", "Demo", "Demo", -1, Common::EN_ANY, Common::kPlatformWindows }, { "ef74d9071d4e564b037cb44bd6774de7", "fbear", "HE 62", "", -1, Common::HE_ISR, Common::kPlatformDOS }, @@ -649,6 +668,7 @@ static const MD5Table md5table[] = { { "fa30c4a7a806629626269b6dcab59a15", "BluesBirthday", "HE CUP", "Preview", 7819264, Common::UNK_LANG, Common::kPlatformUnknown }, { "fa3cb1541f9d7cf99ccbae6249bc150c", "maniac", "NES", "", -1, Common::IT_ITA, Common::kPlatformNES }, { "fa84cb1018103a4ee4e5fa8041c1d0d1", "freddi4", "", "Demo", 13609, Common::DE_DEU, Common::kPlatformWindows }, + { "faa89ab5e67ba4eebb4399f584f7490c", "pajama3", "", "Mini Game", 13911, Common::FR_FRA, Common::kPlatformWindows }, { "fb66aa42de21675116346213f176a366", "monkey", "VGA", "VGA", -1, Common::IT_ITA, Common::kPlatformAmiga }, { "fbb697d89d2beca87360a145f467bdae", "PuttTime", "HE 90", "Demo", -1, Common::DE_DEU, Common::kPlatformUnknown }, { "fbbbb38a81fc9d6a61d509278390a290", "farm", "", "", -1, Common::EN_ANY, Common::kPlatformMacintosh }, diff --git a/engines/scumm/scumm.cpp b/engines/scumm/scumm.cpp index 475b146a7b..6040344c2c 100644 --- a/engines/scumm/scumm.cpp +++ b/engines/scumm/scumm.cpp @@ -716,7 +716,7 @@ ScummEngine_v2::ScummEngine_v2(OSystem *syst, const DetectorResult &dr) ScummEngine_v0::ScummEngine_v0(OSystem *syst, const DetectorResult &dr) : ScummEngine_v2(syst, dr) { - + _drawDemo = false; _currentMode = 0; _currentLights = 0; @@ -731,6 +731,9 @@ ScummEngine_v0::ScummEngine_v0(OSystem *syst, const DetectorResult &dr) VAR_ACTIVE_OBJECT2 = 0xFF; VAR_IS_SOUND_RUNNING = 0xFF; VAR_ACTIVE_VERB = 0xFF; + + if (strcmp(dr.fp.pattern, "maniacdemo.d64") == 0 ) + _game.features |= GF_DEMO; } ScummEngine_v6::ScummEngine_v6(OSystem *syst, const DetectorResult &dr) @@ -1091,8 +1094,13 @@ Common::Error ScummEngine::init() { const char *tmpBuf1, *tmpBuf2; assert(_game.id == GID_MANIAC || _game.id == GID_ZAK); if (_game.id == GID_MANIAC) { - tmpBuf1 = "maniac1.d64"; - tmpBuf2 = "maniac2.d64"; + if (_game.features & GF_DEMO) { + tmpBuf1 = "maniacdemo.d64"; + tmpBuf2 = "maniacdemo.d64"; + } else { + tmpBuf1 = "maniac1.d64"; + tmpBuf2 = "maniac2.d64"; + } } else { tmpBuf1 = "zak1.d64"; tmpBuf2 = "zak2.d64"; @@ -2572,7 +2580,7 @@ void ScummEngine::runBootscript() { int args[NUM_SCRIPT_LOCAL]; memset(args, 0, sizeof(args)); args[0] = _bootParam; - if (_game.id == GID_MANIAC && (_game.features & GF_DEMO)) + if (_game.id == GID_MANIAC && (_game.features & GF_DEMO) && (_game.platform != Common::kPlatformC64)) runScript(9, 0, 0, args); else runScript(1, 0, 0, args); diff --git a/engines/scumm/scumm.h b/engines/scumm/scumm.h index af118a89a1..967909e505 100644 --- a/engines/scumm/scumm.h +++ b/engines/scumm/scumm.h @@ -642,7 +642,7 @@ protected: byte _opcode; byte _currentScript; int _scummStackPos; - int _vmStack[150]; + int _vmStack[256]; OpcodeEntry _opcodes[256]; @@ -1362,7 +1362,7 @@ public: byte VAR_SCRIPT_CYCLE; // Used in runScript()/runObjectScript() byte VAR_NUM_SCRIPT_CYCLES; // Used in runAllScripts() - + byte VAR_QUIT_SCRIPT; // Used in confirmExitDialog() // Exists both in V7 and in V72HE: diff --git a/engines/scumm/scumm_v0.h b/engines/scumm/scumm_v0.h index 80d047ab9f..4098d639c4 100644 --- a/engines/scumm/scumm_v0.h +++ b/engines/scumm/scumm_v0.h @@ -46,6 +46,7 @@ protected: }; protected: + bool _drawDemo; byte _currentMode; byte _currentLights; @@ -67,6 +68,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); @@ -99,6 +102,8 @@ protected: virtual void handleMouseOver(bool updateInventory); int verbPrepIdType(int verbid); void resetVerbs(); + void verbDemoMode(); + void verbDrawDemoString(int VerbDemoNumber); void clearSentenceLine(); void flushSentenceLine(); @@ -116,7 +121,7 @@ protected: void resetSentence(); - virtual bool areBoxesNeighbors(int box1nr, int box2nr); + bool areBoxesNeighbors(int box1nr, int box2nr); bool ifEqualActiveObject2Common(bool checkType); @@ -161,6 +166,7 @@ protected: void o_cutscene(); void o_endCutscene(); void o_setOwnerOf(); + void o_screenPrepare(); byte VAR_ACTIVE_OBJECT2; byte VAR_IS_SOUND_RUNNING; diff --git a/engines/scumm/sound.cpp b/engines/scumm/sound.cpp index cb428d1c15..84d2b37f96 100644 --- a/engines/scumm/sound.cpp +++ b/engines/scumm/sound.cpp @@ -1066,9 +1066,9 @@ void Sound::playCDTrackInternal(int track, int numLoops, int startFrame, int dur Common::File *cddaFile = new Common::File(); if (cddaFile->open("CDDA.SOU")) { Audio::Timestamp start = Audio::Timestamp(0, startFrame, 75); - Audio::Timestamp end = Audio::Timestamp(0, startFrame + duration, 75); + Audio::Timestamp end = Audio::Timestamp(0, startFrame + duration, 75); Audio::SeekableAudioStream *stream = makeCDDAStream(cddaFile, DisposeAfterUse::YES); - + _mixer->playStream(Audio::Mixer::kMusicSoundType, &_loomSteamCDAudioHandle, Audio::makeLoopingAudioStream(stream, start, end, (numLoops < 1) ? numLoops + 1 : numLoops)); } else { diff --git a/engines/scumm/vars.cpp b/engines/scumm/vars.cpp index a903ac5804..a6be5c3f3a 100644 --- a/engines/scumm/vars.cpp +++ b/engines/scumm/vars.cpp @@ -715,7 +715,7 @@ void ScummEngine_v99he::resetScummVars() { VAR(140) = 0; #endif } - + if (_game.id == GID_PUTTZOO && _game.heversion == 100 && _game.platform == Common::kPlatformWindows) { // Specific to Nimbus Games version. VAR(156) = 1; diff --git a/engines/scumm/verbs.cpp b/engines/scumm/verbs.cpp index fdb98a8019..fe936b550c 100644 --- a/engines/scumm/verbs.cpp +++ b/engines/scumm/verbs.cpp @@ -80,6 +80,19 @@ static const VerbSettings v0VerbTable_German[] = { {kVerbWhatIs, 13, 2, "Was ist"} }; +struct VerbDemo { + int color; + const char *str; +}; +static VerbDemo v0DemoStr[] = { + {7, " MANIAC MANSION DEMO DISK "}, + {5, " from Lucasfilm Games "}, + {5, " Copyright = 1987 by Lucasfilm Ltd. "}, + {5, " All Rights Reserved. "}, + {0, " "}, + {16, " Press F7 to return to menu. "} +}; + int ScummEngine_v0::verbPrepIdType(int verbid) { switch (verbid) { case kVerbUse: // depends on object1 @@ -93,6 +106,44 @@ int ScummEngine_v0::verbPrepIdType(int verbid) { } } +void ScummEngine_v0::verbDemoMode() { + int i; + + for (i = 1; i < 16; i++) + killVerb(i); + + for (i = 0; i < 6; i++) { + verbDrawDemoString(i); + } +} + +void ScummEngine_v0::verbDrawDemoString(int VerbDemoNumber) { + byte string[80]; + const char *ptr = v0DemoStr[VerbDemoNumber].str; + int i = 0, len = 0; + + // Maximum length of printable characters + int maxChars = 40; + while (*ptr) { + if (*ptr != '@') + len++; + if (len > maxChars) { + break; + } + + string[i++] = *ptr++; + + } + string[i] = 0; + + _string[2].charset = 1; + _string[2].ypos = _virtscr[kVerbVirtScreen].topline + (8 * VerbDemoNumber); + _string[2].xpos = 0; + _string[2].right = _virtscr[kVerbVirtScreen].w - 1; + _string[2].color = v0DemoStr[VerbDemoNumber].color; + drawString(2, (byte *)string); +} + void ScummEngine_v0::resetVerbs() { VirtScreen *virt = &_virtscr[kVerbVirtScreen]; VerbSlot *vs; @@ -708,7 +759,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; @@ -717,7 +767,6 @@ void ScummEngine_v0::verbExec() { if (a->_miscflags & kActorMiscFlagFreeze) return; - a->stopActorMoving(); a->startWalkActor(VAR(6), VAR(7), -1); } @@ -856,6 +905,10 @@ void ScummEngine_v0::checkExecVerbs() { } } } + + if (_drawDemo && _game.features & GF_DEMO) { + verbDemoMode(); + } if (_redrawSentenceLine) drawSentenceLine(); |