aboutsummaryrefslogtreecommitdiff
path: root/engines/scumm
diff options
context:
space:
mode:
Diffstat (limited to 'engines/scumm')
-rw-r--r--engines/scumm/actor.cpp725
-rw-r--r--engines/scumm/actor.h49
-rw-r--r--engines/scumm/boxes.cpp24
-rw-r--r--engines/scumm/cdda.cpp2
-rw-r--r--engines/scumm/detection.cpp5
-rw-r--r--engines/scumm/detection_tables.h16
-rw-r--r--engines/scumm/dialogs.cpp6
-rw-r--r--engines/scumm/file.cpp26
-rw-r--r--engines/scumm/input.cpp12
-rw-r--r--engines/scumm/resource_v2.cpp10
-rw-r--r--engines/scumm/room.cpp9
-rw-r--r--engines/scumm/saveload.cpp7
-rw-r--r--engines/scumm/saveload.h2
-rw-r--r--engines/scumm/script.cpp6
-rw-r--r--engines/scumm/script_v0.cpp34
-rw-r--r--engines/scumm/script_v2.cpp9
-rw-r--r--engines/scumm/script_v5.cpp4
-rw-r--r--engines/scumm/scumm-md5.h42
-rw-r--r--engines/scumm/scumm.cpp16
-rw-r--r--engines/scumm/scumm.h4
-rw-r--r--engines/scumm/scumm_v0.h8
-rw-r--r--engines/scumm/sound.cpp4
-rw-r--r--engines/scumm/vars.cpp2
-rw-r--r--engines/scumm/verbs.cpp57
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();