aboutsummaryrefslogtreecommitdiff
path: root/engines/neverhood
diff options
context:
space:
mode:
authorFilippos Karapetis2013-10-05 14:52:48 +0300
committerFilippos Karapetis2013-10-05 14:52:48 +0300
commitb408b94bf1e188da7202895eab547f08cfa30450 (patch)
tree2481c9409fc4ce595aa211ecfb02bf1fece25a59 /engines/neverhood
parentb963fcbfa8794c807d831ab3b117634ce7c8550e (diff)
downloadscummvm-rg350-b408b94bf1e188da7202895eab547f08cfa30450.tar.gz
scummvm-rg350-b408b94bf1e188da7202895eab547f08cfa30450.tar.bz2
scummvm-rg350-b408b94bf1e188da7202895eab547f08cfa30450.zip
NEVERHOOD: Split sprites from their scenes in module 1600
Diffstat (limited to 'engines/neverhood')
-rw-r--r--engines/neverhood/module.mk1
-rw-r--r--engines/neverhood/modules/module1600.cpp822
-rw-r--r--engines/neverhood/modules/module1600.h88
-rw-r--r--engines/neverhood/modules/module1600_sprites.cpp850
-rw-r--r--engines/neverhood/modules/module1600_sprites.h119
-rw-r--r--engines/neverhood/modules/module2500.cpp1
-rw-r--r--engines/neverhood/modules/module2500.h4
-rw-r--r--engines/neverhood/modules/module2700.cpp2
-rw-r--r--engines/neverhood/modules/module2700.h2
9 files changed, 977 insertions, 912 deletions
diff --git a/engines/neverhood/module.mk b/engines/neverhood/module.mk
index e49d9f6e31..cd0a9fa140 100644
--- a/engines/neverhood/module.mk
+++ b/engines/neverhood/module.mk
@@ -21,6 +21,7 @@ MODULE_OBJS = \
modules/module1400.o \
modules/module1500.o \
modules/module1600.o \
+ modules/module1600_sprites.o \
modules/module1700.o \
modules/module1700_sprites.o \
modules/module1800.o \
diff --git a/engines/neverhood/modules/module1600.cpp b/engines/neverhood/modules/module1600.cpp
index 631d90d7dc..165855a1b4 100644
--- a/engines/neverhood/modules/module1600.cpp
+++ b/engines/neverhood/modules/module1600.cpp
@@ -20,9 +20,10 @@
*
*/
-#include "neverhood/modules/module1600.h"
#include "neverhood/gamemodule.h"
#include "neverhood/modules/module1200.h"
+#include "neverhood/modules/module1600.h"
+#include "neverhood/modules/module1600_sprites.h"
#include "neverhood/modules/module2200_sprites.h"
#include "neverhood/modules/module3000_sprites.h"
@@ -184,825 +185,6 @@ void Module1600::updateScene() {
}
}
-AsCommonCar::AsCommonCar(NeverhoodEngine *vm, Scene *parentScene, int16 x, int16 y)
- : AnimatedSprite(vm, 1000), _parentScene(parentScene) {
-
- createSurface(200, 556, 328);
- _x = x;
- _y = y;
-
- _inMainArea = false;
- _exitDirection = 0;
- _currPointIndex = 0;
- _hasAgainDestPoint = false;
- _stepError = 0;
- _hasAgainDestPointIndex = false;
- _steps = 0;
- _isBraking = false;
- _yMoveTotalSteps = 0;
- _isBusy = false;
- _isIdle = false;
- _isMoving = true;
- _rectFlag = false;
- _newDeltaXType = -1;
- _soundCounter = 0;
- _pathPoints = NULL;
- _currMoveDirection = 0;
-
- startAnimation(0xD4220027, 0, -1);
- setDoDeltaX(getGlobalVar(V_CAR_DELTA_X));
-
- SetUpdateHandler(&AsCommonCar::update);
- SetMessageHandler(&AsCommonCar::handleMessage);
- SetSpriteUpdate(NULL);
-}
-
-AsCommonCar::~AsCommonCar() {
- if (_finalizeStateCb == AnimationCallback(&AsCommonCar::evTurnCarDone))
- setGlobalVar(V_CAR_DELTA_X, !getGlobalVar(V_CAR_DELTA_X));
-}
-
-void AsCommonCar::setPathPoints(NPointArray *pathPoints) {
- _pathPoints = pathPoints;
-}
-
-void AsCommonCar::update() {
- if (_newDeltaXType >= 0) {
- setDoDeltaX(_newDeltaXType);
- _newDeltaXType = -1;
- }
- AnimatedSprite::update();
- if (_hasAgainDestPoint && _yMoveTotalSteps == 0 && !_isBusy) {
- _hasAgainDestPoint = false;
- _hasAgainDestPointIndex = false;
- sendPointMessage(this, 0x2004, _againDestPoint);
- } else if (_hasAgainDestPointIndex && _yMoveTotalSteps == 0 && !_isBusy) {
- _hasAgainDestPointIndex = false;
- sendMessage(this, 0x2003, _againDestPointIndex);
- }
- updateMovement();
- updateSound();
-}
-
-void AsCommonCar::upIdle() {
- update();
- if (++_idleCounter >= _idleCounterMax)
- stIdleBlink();
- updateSound();
-}
-
-uint32 AsCommonCar::handleMessage(int messageNum, const MessageParam &param, Entity *sender) {
- uint32 messageResult = Sprite::handleMessage(messageNum, param, sender);
- switch (messageNum) {
- case 0x1019:
- SetSpriteUpdate(NULL);
- break;
- case 0x2002:
- // Set the current position without moving
- _currPointIndex = param.asInteger();
- _stepError = 0;
- _x = pathPoint(_currPointIndex).x;
- _y = pathPoint(_currPointIndex).y;
- break;
- case 0x2003:
- // Move to a point by its index
- {
- int newPointIndex = param.asInteger();
- if (_yMoveTotalSteps <= 0 && !_isBusy) {
- _destX = pathPoint(newPointIndex).x;
- _destY = pathPoint(newPointIndex).y;
- if (_currPointIndex < newPointIndex) {
- moveToNextPoint();
- } else if (_currPointIndex == newPointIndex && _stepError == 0) {
- if (_currPointIndex == 0) {
- _yMoveTotalSteps = 0;
- sendMessage(_parentScene, 0x2005, 0);
- } else if (_currPointIndex == (int)_pathPoints->size()) {
- _yMoveTotalSteps = 0;
- sendMessage(_parentScene, 0x2006, 0);
- }
- } else {
- moveToPrevPoint();
- }
- } else {
- _hasAgainDestPointIndex = true;
- _againDestPointIndex = newPointIndex;
- }
- }
- break;
- case 0x2004:
- // Move to the point closest to the parameter point
- {
- int minMatchIndex = -1;
- int minMatchDistance, distance;
- NPoint pt = param.asPoint();
- if (_yMoveTotalSteps <= 0 && !_isBusy) {
- // Check if we're already exiting (or something)
- if ((pt.x <= 20 && _exitDirection == 1) ||
- (pt.x >= 620 && _exitDirection == 3) ||
- (pt.y <= 20 && _exitDirection == 2) ||
- (pt.y >= 460 && _exitDirection == 4))
- break;
- _destX = pt.x;
- _destY = pt.y;
- minMatchDistance = calcDistance(_destX, _destY, _x, _y) + 1;
- for (int i = _currPointIndex + 1; i < (int)_pathPoints->size(); i++) {
- distance = calcDistance(_destX, _destY, pathPoint(i).x, pathPoint(i).y);
- if (distance >= minMatchDistance)
- break;
- minMatchDistance = distance;
- minMatchIndex = i;
- }
- for (int i = _currPointIndex; i >= 0; i--) {
- distance = calcDistance(_destX, _destY, pathPoint(i).x, pathPoint(i).y);
- if (distance >= minMatchDistance)
- break;
- minMatchDistance = distance;
- minMatchIndex = i;
- }
- if (minMatchIndex == -1) {
- if (_currPointIndex == 0)
- moveToPrevPoint();
- else
- SetSpriteUpdate(NULL);
- } else {
- if (minMatchIndex > _currPointIndex)
- moveToNextPoint();
- else
- moveToPrevPoint();
- }
- } else {
- _hasAgainDestPoint = true;
- _againDestPoint = pt;
- }
- }
- break;
- case 0x2007:
- _yMoveTotalSteps = param.asInteger();
- _steps = 0;
- _isBraking = false;
- _lastDistance = 640;
- SetSpriteUpdate(&AsCommonCar::suMoveToPrevPoint);
- break;
- case 0x2008:
- _yMoveTotalSteps = param.asInteger();
- _steps = 0;
- _isBraking = false;
- _lastDistance = 640;
- SetSpriteUpdate(&AsCommonCar::suMoveToNextPoint);
- break;
- case 0x2009:
- stEnterCar();
- break;
- case 0x200A:
- stLeaveCar();
- break;
- case 0x200E:
- stTurnCar();
- break;
- case 0x200F:
- stCarAtHome();
- _newDeltaXType = param.asInteger();
- break;
- }
- return messageResult;
-}
-
-uint32 AsCommonCar::hmAnimation(int messageNum, const MessageParam &param, Entity *sender) {
- uint32 messageResult = AsCommonCar::handleMessage(messageNum, param, sender);
- switch (messageNum) {
- case 0x100D:
- if (_isBusy && param.asInteger() == 0x025424A2)
- gotoNextState();
- break;
- case 0x3002:
- gotoNextState();
- break;
- }
- return messageResult;
-}
-
-uint32 AsCommonCar::hmLeaveCar(int messageNum, const MessageParam &param, Entity *sender) {
- switch (messageNum) {
- case 0x2009:
- stEnterCar();
- break;
- case 0x3002:
- sendMessage(_parentScene, 0x200A, 0);
- SetMessageHandler(&AsCommonCar::handleMessage);
- break;
- }
- return 0;
-}
-
-void AsCommonCar::stCarAtHome() {
- bool doDeltaX = _doDeltaX;
- SetSpriteUpdate(NULL);
- _hasAgainDestPoint = false;
- _hasAgainDestPointIndex = false;
- _isBraking = false;
- _isBusy = false;
- _isIdle = false;
- _isMoving = false;
- _rectFlag = false;
- NextState(&AsCommonCar::stLeanForwardIdle);
- startAnimation(0x35698F78, 0, -1);
- setDoDeltaX(doDeltaX ? 1 : 0);
- _currMoveDirection = 0;
- _newMoveDirection = 0;
- _steps = 0;
- _idleCounter = 0;
- _idleCounterMax = _vm->_rnd->getRandomNumber(64 - 1) + 24;
- SetUpdateHandler(&AsCommonCar::upIdle);
- SetMessageHandler(&AsCommonCar::handleMessage);
- FinalizeState(&AsCommonCar::evIdleDone);
-}
-
-void AsCommonCar::updateTurnMovement() {
- if (_turnMoveStatus == 1) {
- _lastDistance = 640;
- _isIdle = false;
- _isBraking = false;
- SetSpriteUpdate(&AsCommonCar::suMoveToNextPoint);
- } else if (_turnMoveStatus == 2) {
- _lastDistance = 640;
- _isIdle = false;
- _isBraking = false;
- SetSpriteUpdate(&AsCommonCar::suMoveToPrevPoint);
- }
-}
-
-void AsCommonCar::updateMovement() {
- if (_isBraking && !_isIdle && !_isBusy) {
- gotoNextState();
- _isMoving = false;
- _isIdle = true;
- startAnimation(0x192ADD30, 0, -1);
- SetUpdateHandler(&AsCommonCar::update);
- SetMessageHandler(&AsCommonCar::hmAnimation);
- NextState(&AsCommonCar::stLeanForwardIdle);
- } else if (!_isBraking && _steps && _isIdle) {
- gotoNextState();
- _isIdle = false;
- startAnimation(0x9966B138, 0, -1);
- SetUpdateHandler(&AsCommonCar::update);
- SetMessageHandler(&AsCommonCar::hmAnimation);
- NextState(&AsCommonCar::stUpdateMoveDirection);
- } else if (_newMoveDirection != _currMoveDirection && _isMoving && !_isBusy) {
- gotoNextState();
- _currMoveDirection = _newMoveDirection;
- stUpdateMoveDirection();
- }
-}
-
-void AsCommonCar::stEnterCar() {
- startAnimation(0xA86A9538, 0, -1);
- SetUpdateHandler(&AsCommonCar::update);
- SetMessageHandler(&AsCommonCar::hmAnimation);
- NextState(&AsCommonCar::stLeanForwardIdle);
-}
-
-void AsCommonCar::stLeaveCar() {
- startAnimation(0xA86A9538, -1, -1);
- _playBackwards = true;
- SetUpdateHandler(&AsCommonCar::update);
- SetMessageHandler(&AsCommonCar::hmLeaveCar);
-}
-
-void AsCommonCar::stLeanForwardIdle() {
- startAnimation(0x35698F78, 0, -1);
- _currMoveDirection = 0;
- _newMoveDirection = 0;
- _steps = 0;
- _idleCounter = 0;
- _idleCounterMax = _vm->_rnd->getRandomNumber(64 - 1) + 24;
- SetUpdateHandler(&AsCommonCar::upIdle);
- SetMessageHandler(&AsCommonCar::handleMessage);
- FinalizeState(&AsCommonCar::evIdleDone);
-}
-
-void AsCommonCar::evIdleDone() {
- SetUpdateHandler(&AsCommonCar::update);
-}
-
-void AsCommonCar::stIdleBlink() {
- startAnimation(0xB579A77C, 0, -1);
- _idleCounter = 0;
- _idleCounterMax = _vm->_rnd->getRandomNumber(64 - 1) + 24;
- SetUpdateHandler(&AsCommonCar::update);
- SetMessageHandler(&AsCommonCar::hmAnimation);
- NextState(&AsCommonCar::stLeanForwardIdle);
-}
-
-void AsCommonCar::stUpdateMoveDirection() {
- _isMoving = true;
- if (_currMoveDirection == 1)
- startAnimation(0xD4AA03A4, 0, -1);
- else if (_currMoveDirection == 3)
- startAnimation(0xD00A1364, 0, -1);
- else if ((_currMoveDirection == 2 && _doDeltaX) || (_currMoveDirection == 4 && !_doDeltaX))
- stTurnCar();
- else
- startAnimation(0xD4220027, 0, -1);
- setGlobalVar(V_CAR_DELTA_X, _doDeltaX ? 1 : 0);
-}
-
-void AsCommonCar::moveToNextPoint() {
- if (_currPointIndex >= (int)_pathPoints->size() - 1) {
- _yMoveTotalSteps = 0;
- sendMessage(this, 0x1019, 0);
- sendMessage(_parentScene, 0x2006, 0);
- } else {
- NPoint nextPt = pathPoint(_currPointIndex + 1);
- NPoint currPt = pathPoint(_currPointIndex);
- if (ABS(nextPt.y - currPt.y) <= ABS(nextPt.x - currPt.x) &&
- ((_currMoveDirection == 2 && nextPt.x < currPt.x) ||
- (_currMoveDirection == 4 && nextPt.x >= currPt.x))) {
- if (_currMoveDirection == 2)
- _currMoveDirection = 4;
- else if (_currMoveDirection == 4)
- _currMoveDirection = 2;
- if (_isIdle)
- stTurnCarMoveToNextPoint();
- else
- stBrakeMoveToNextPoint();
- } else {
- if (_steps == 0) {
- gotoNextState();
- _isIdle = false;
- startAnimation(0x9966B138, 0, -1);
- SetMessageHandler(&AsCommonCar::hmAnimation);
- SetUpdateHandler(&AsCommonCar::update);
- NextState(&AsCommonCar::stUpdateMoveDirection);
- }
- _isBraking = false;
- SetSpriteUpdate(&AsCommonCar::suMoveToNextPoint);
- _lastDistance = 640;
- }
- }
-}
-
-void AsCommonCar::stBrakeMoveToNextPoint() {
- gotoNextState();
- _isBusy = true;
- _isBraking = true;
- startAnimation(0x192ADD30, 0, -1);
- SetUpdateHandler(&AsCommonCar::update);
- SetMessageHandler(&AsCommonCar::hmAnimation);
- NextState(&AsCommonCar::stTurnCarMoveToNextPoint);
-}
-
-void AsCommonCar::stTurnCar() {
- // Turn to left/right #1
- gotoNextState();
- _isBusy = true;
- startAnimation(0xF46A0324, 0, -1);
- SetUpdateHandler(&AsCommonCar::update);
- SetMessageHandler(&AsCommonCar::hmAnimation);
- FinalizeState(&AsCommonCar::evTurnCarDone);
- _turnMoveStatus = 0;
- updateTurnMovement();
-}
-
-void AsCommonCar::stTurnCarMoveToNextPoint() {
- // Turn to left/right #2
- gotoNextState();
- _isBusy = true;
- startAnimation(0xF46A0324, 0, -1);
- SetUpdateHandler(&AsCommonCar::update);
- SetMessageHandler(&AsCommonCar::hmAnimation);
- FinalizeState(&AsCommonCar::evTurnCarDone);
- _turnMoveStatus = 1;
- updateTurnMovement();
-}
-
-void AsCommonCar::stTurnCarMoveToPrevPoint() {
- // Turn to left/right #3
- FinalizeState(NULL);
- _isBusy = true;
- startAnimation(0xF46A0324, 0, -1);
- SetUpdateHandler(&AsCommonCar::update);
- SetMessageHandler(&AsCommonCar::hmAnimation);
- FinalizeState(&AsCommonCar::evTurnCarDone);
- _turnMoveStatus = 2;
- updateTurnMovement();
-}
-
-void AsCommonCar::moveToPrevPoint() {
- if (_currPointIndex == 0 && _stepError == 0) {
- _yMoveTotalSteps = 0;
- sendMessage(this, 0x1019, 0);
- sendMessage(_parentScene, 0x2005, 0);
- } else {
- NPoint prevPt;
- NPoint currPt;
- if (_stepError == 0) {
- prevPt = pathPoint(_currPointIndex - 1);
- currPt = pathPoint(_currPointIndex);
- } else {
- prevPt = pathPoint(_currPointIndex);
- currPt = pathPoint(_currPointIndex + 1);
- }
- if (ABS(prevPt.y - currPt.y) <= ABS(prevPt.x - currPt.x) &&
- ((_currMoveDirection == 2 && prevPt.x < currPt.x) ||
- (_currMoveDirection == 4 && prevPt.x >= currPt.x))) {
- if (_currMoveDirection == 2)
- _currMoveDirection = 4;
- else if (_currMoveDirection == 4)
- _currMoveDirection = 2;
- if (_isIdle)
- stTurnCarMoveToPrevPoint();
- else
- stBrakeMoveToPrevPoint();
- } else {
- if (_steps == 0) {
- gotoNextState();
- _isIdle = false;
- startAnimation(0x9966B138, 0, -1);
- SetMessageHandler(&AsCommonCar::hmAnimation);
- SetUpdateHandler(&AsCommonCar::update);
- NextState(&AsCommonCar::stUpdateMoveDirection);
- }
- _isBraking = false;
- SetSpriteUpdate(&AsCommonCar::suMoveToPrevPoint);
- _lastDistance = 640;
- }
- }
-}
-
-void AsCommonCar::stBrakeMoveToPrevPoint() {
- FinalizeState(NULL);
- _isBusy = true;
- _isBraking = true;
- startAnimation(0x192ADD30, 0, -1);
- SetUpdateHandler(&AsCommonCar::update);
- SetMessageHandler(&AsCommonCar::hmAnimation);
- NextState(&AsCommonCar::stTurnCarMoveToPrevPoint);
-}
-
-void AsCommonCar::evTurnCarDone() {
- _isBusy = false;
- setDoDeltaX(2);
- _newMoveDirection = 0;
- stUpdateMoveDirection();
-}
-
-void AsCommonCar::suMoveToNextPoint() {
- int16 newX = _x, newY = _y;
-
- if (_currPointIndex >= (int)_pathPoints->size()) {
- _yMoveTotalSteps = 0;
- sendMessage(this, 0x1019, 0);
- sendMessage(_parentScene, 0x2006, 0);
- return;
- }
-
- if (_isBraking) {
- if (_steps <= 0) {
- sendMessage(this, 0x1019, 0);
- return;
- } else
- _steps--;
- } else if (_steps < 11)
- _steps++;
-
- bool firstTime = true;
- _ySteps = _steps;
- int stepsCtr = _steps;
-
- while (stepsCtr > 0) {
- NPoint pt1;
- NPoint pt2 = pathPoint(_currPointIndex);
- if (_currPointIndex + 1 >= (int)_pathPoints->size())
- pt1 = pathPoint(0);
- else
- pt1 = pathPoint(_currPointIndex + 1);
- int16 deltaX = ABS(pt1.x - pt2.x);
- int16 deltaY = ABS(pt1.y - pt2.y);
- if (deltaX >= deltaY) {
- _newMoveDirection = 2;
- if (pt1.x < pt2.x)
- _newMoveDirection = 4;
- if (stepsCtr + _stepError >= deltaX) {
- stepsCtr -= deltaX;
- stepsCtr += _stepError;
- _stepError = 0;
- _currPointIndex++;
- if (_currPointIndex == (int)_pathPoints->size() - 1)
- stepsCtr = 0;
- newX = pathPoint(_currPointIndex).x;
- newY = pathPoint(_currPointIndex).y;
- } else {
- _stepError += stepsCtr;
- if (pt1.x >= pt2.x)
- newX += stepsCtr;
- else
- newX -= stepsCtr;
- if (pt1.y >= pt2.y)
- newY = pt2.y + (deltaY * _stepError) / deltaX;
- else
- newY = pt2.y - (deltaY * _stepError) / deltaX;
- stepsCtr = 0;
- }
- } else {
- _newMoveDirection = 3;
- if (pt1.y < pt2.y)
- _newMoveDirection = 1;
- if (firstTime) {
- if (pt1.y >= pt2.y)
- stepsCtr += 7;
- else {
- stepsCtr -= 4;
- if (stepsCtr < 0)
- stepsCtr = 0;
- }
- _ySteps = stepsCtr;
- }
- if (stepsCtr + _stepError >= deltaY) {
- stepsCtr -= deltaY;
- stepsCtr += _stepError;
- _stepError = 0;
- _currPointIndex++;
- if (_currPointIndex == (int)_pathPoints->size() - 1)
- stepsCtr = 0;
- newX = pathPoint(_currPointIndex).x;
- newY = pathPoint(_currPointIndex).y;
- } else {
- _stepError += stepsCtr;
- if (pt1.x >= pt2.x)
- newX = pt2.x + (deltaX * _stepError) / deltaY;
- else
- newX = pt2.x - (deltaX * _stepError) / deltaY;
- if (pt1.y >= pt2.y)
- newY += stepsCtr;
- else
- newY -= stepsCtr;
- stepsCtr = 0;
- }
- }
- firstTime = false;
- }
-
- if (_yMoveTotalSteps != 0) {
- _x = newX;
- _y = newY;
- _yMoveTotalSteps -= _ySteps;
- if (_yMoveTotalSteps <= 0) {
- _isBraking = true;
- _yMoveTotalSteps = 0;
- }
- } else {
- int distance = calcDistance(_destX, _destY, _x, _y);
- _x = newX;
- _y = newY;
- if (newX > 20 && newX < 620 && newY > 20 && newY < 460) {
- _exitDirection = 0;
- _inMainArea = true;
- } else if (_inMainArea) {
- _destX = pathPoint(_pathPoints->size() - 1).x;
- _destY = pathPoint(_pathPoints->size() - 1).y;
- _inMainArea = false;
- if (_x <= 20)
- _exitDirection = 1;
- else if (_x >= 620)
- _exitDirection = 3;
- else if (_y <= 20)
- _exitDirection = 2;
- else if (_y >= 460)
- _exitDirection = 4;
- if (_exitDirection != 0 && _isBraking) {
- _isBraking = false;
- _steps = 11;
- }
- }
- if ((distance < 20 && _exitDirection == 0 && _lastDistance < distance) ||
- (_exitDirection == 0 && _lastDistance + 20 < distance))
- _isBraking = true;
- if (distance < _lastDistance)
- _lastDistance = distance;
- if (_currPointIndex == (int)_pathPoints->size() - 1) {
- _isBraking = true;
- _yMoveTotalSteps = 0;
- sendMessage(this, 0x1019, 0);
- sendMessage(_parentScene, 0x2006, 0);
- }
- }
-
-}
-
-void AsCommonCar::suMoveToPrevPoint() {
- int16 newX = _x, newY = _y;
-
- if (_currPointIndex == 0 && _stepError == 0) {
- _yMoveTotalSteps = 0;
- sendMessage(this, 0x1019, 0);
- sendMessage(_parentScene, 0x2005, 0);
- return;
- }
-
- if (_isBraking) {
- if (_steps <= 0) {
- sendMessage(this, 0x1019, 0);
- return;
- } else
- _steps--;
- } else if (_steps < 11)
- _steps++;
-
- bool firstTime = true;
- _ySteps = _steps;
- int stepsCtr = _steps;
-
- while (stepsCtr > 0) {
- if (_stepError == 0)
- _currPointIndex--;
- NPoint pt1;
- NPoint pt2 = pathPoint(_currPointIndex);
- if (_currPointIndex + 1 >= (int)_pathPoints->size())
- pt1 = pathPoint(0);
- else
- pt1 = pathPoint(_currPointIndex + 1);
- int16 deltaX = ABS(pt1.x - pt2.x);
- int16 deltaY = ABS(pt1.y - pt2.y);
- if (deltaX >= deltaY) {
- _newMoveDirection = 4;
- if (pt1.x < pt2.x)
- _newMoveDirection = 2;
- if (_stepError == 0)
- _stepError = deltaX;
- if (stepsCtr > _stepError) {
- stepsCtr -= _stepError;
- _stepError = 0;
- if (_currPointIndex == 0)
- stepsCtr = 0;
- newX = pathPoint(_currPointIndex).x;
- newY = pathPoint(_currPointIndex).y;
- } else {
- _stepError -= stepsCtr;
- if (pt1.x >= pt2.x)
- newX -= stepsCtr;
- else
- newX += stepsCtr;
- if (pt1.y >= pt2.y)
- newY = pt2.y + (deltaY * _stepError) / deltaX;
- else
- newY = pt2.y - (deltaY * _stepError) / deltaX;
- stepsCtr = 0;
- }
- } else {
- _newMoveDirection = 1;
- if (pt1.y < pt2.y)
- _newMoveDirection = 3;
- if (firstTime) {
- if (pt1.y >= pt2.y) {
- stepsCtr -= 4;
- if (stepsCtr < 0)
- stepsCtr = 0;
- } else {
- stepsCtr += 7;
- }
- _ySteps = stepsCtr;
- }
- if (_stepError == 0)
- _stepError = deltaY;
- if (stepsCtr > _stepError) {
- stepsCtr -= _stepError;
- _stepError = 0;
- if (_currPointIndex == 0)
- stepsCtr = 0;
- newX = pathPoint(_currPointIndex).x;
- newY = pathPoint(_currPointIndex).y;
- } else {
- _stepError -= stepsCtr;
- if (pt1.x >= pt2.x)
- newX = pt2.x + (deltaX * _stepError) / deltaY;
- else
- newX = pt2.x - (deltaX * _stepError) / deltaY;
- if (pt1.y >= pt2.y)
- newY -= stepsCtr;
- else
- newY += stepsCtr;
- stepsCtr = 0;
- }
- }
- firstTime = false;
- }
-
- if (_yMoveTotalSteps != 0) {
- _x = newX;
- _y = newY;
- _yMoveTotalSteps -= _ySteps;
- if (_yMoveTotalSteps <= 0) {
- _isBraking = true;
- _yMoveTotalSteps = 0;
- }
- } else {
- int distance = calcDistance(_destX, _destY, _x, _y);
- _x = newX;
- _y = newY;
- if (newX > 20 && newX < 620 && newY > 20 && newY < 460) {
- _exitDirection = 0;
- _inMainArea = true;
- } else if (_inMainArea) {
- _destX = pathPoint(0).x;
- _destY = pathPoint(0).y;
- _inMainArea = false;
- if (_x <= 20)
- _exitDirection = 1;
- else if (_x >= 620)
- _exitDirection = 3;
- else if (_y <= 20)
- _exitDirection = 2;
- else if (_y >= 460)
- _exitDirection = 4;
- if (_exitDirection != 0 && _isBraking) {
- _isBraking = false;
- _steps = 11;
- }
- }
- if ((distance < 20 && _exitDirection == 0 && _lastDistance < distance) ||
- (_exitDirection == 0 && _lastDistance + 20 < distance))
- _isBraking = true;
- if (distance < _lastDistance)
- _lastDistance = distance;
- if (_currPointIndex == 0 && _stepError == 0) {
- _isBraking = true;
- _yMoveTotalSteps = 0;
- sendMessage(this, 0x1019, 0);
- sendMessage(_parentScene, 0x2005, 0);
- }
- }
-
-}
-
-void AsCommonCar::updateSound() {
- int maxSoundCounter = 0;
- _soundCounter++;
- if (_steps != 0 && !_isIdle) {
- if (_currMoveDirection == 1)
- maxSoundCounter = 18 - _steps;
- else if (_currMoveDirection == 3) {
- maxSoundCounter = 5 - _steps;
- if (maxSoundCounter < 1)
- maxSoundCounter = 1;
- } else
- maxSoundCounter = 14 - _steps;
- } else
- maxSoundCounter = 21;
- if (_soundCounter >= maxSoundCounter) {
- sendMessage(_parentScene, 0x200D, 0);
- _soundCounter = 0;
- }
-}
-
-AsCommonIdleCarLower::AsCommonIdleCarLower(NeverhoodEngine *vm, int16 x, int16 y)
- : AnimatedSprite(vm, 0x1209E09F, 1100, x, y) {
-
- setDoDeltaX(1);
- startAnimation(0x1209E09F, 1, -1);
- _newStickFrameIndex = 1;
-}
-
-AsCommonIdleCarFull::AsCommonIdleCarFull(NeverhoodEngine *vm, int16 x, int16 y)
- : AnimatedSprite(vm, 0x1209E09F, 100, x, y) {
-
- setDoDeltaX(1);
- _newStickFrameIndex = 0;
-}
-
-AsCommonCarConnector::AsCommonCarConnector(NeverhoodEngine *vm, AsCommonCar *asCar)
- : AnimatedSprite(vm, 1100), _asCar(asCar) {
-
- createSurface1(0x60281C10, 150);
- startAnimation(0x60281C10, -1, -1);
- _newStickFrameIndex = STICK_LAST_FRAME;
- SetUpdateHandler(&AsCommonCarConnector::update);
-}
-
-void AsCommonCarConnector::update() {
- _x = _asCar->getX();
- _y = _asCar->getY();
- AnimatedSprite::update();
-}
-
-void Tracks::findTrackPoint(NPoint pt, int &minMatchTrackIndex, int &minMatchDistance,
- DataResource &dataResource) {
- const uint trackCount = size();
- minMatchTrackIndex = -1;
- minMatchDistance = 640;
- for (uint trackIndex = 0; trackIndex < trackCount; trackIndex++) {
- NPointArray *pointList = dataResource.getPointArray((*this)[trackIndex]->trackPointsName);
- for (uint pointIndex = 0; pointIndex < pointList->size(); pointIndex++) {
- NPoint testPt = (*pointList)[pointIndex];
- int distance = calcDistance(testPt.x, testPt.y, pt.x, pt.y);
- if (distance < minMatchDistance) {
- minMatchTrackIndex = trackIndex;
- minMatchDistance = distance;
- }
- }
- }
-}
-
Scene1608::Scene1608(NeverhoodEngine *vm, Module *parentModule, int which)
: Scene(vm, parentModule), _asCar(NULL), _countdown1(0) {
diff --git a/engines/neverhood/modules/module1600.h b/engines/neverhood/modules/module1600.h
index 0d1ceaa452..f08eaad8fc 100644
--- a/engines/neverhood/modules/module1600.h
+++ b/engines/neverhood/modules/module1600.h
@@ -26,12 +26,9 @@
#include "neverhood/neverhood.h"
#include "neverhood/module.h"
#include "neverhood/scene.h"
-#include "neverhood/console.h"
namespace Neverhood {
-// Module1600
-
class Module1600 : public Module {
public:
Module1600(NeverhoodEngine *vm, Module *parentModule, int which);
@@ -42,90 +39,7 @@ protected:
void updateScene();
};
-class AsCommonCar : public AnimatedSprite {
-public:
- AsCommonCar(NeverhoodEngine *vm, Scene *parentScene, int16 x, int16 y);
- ~AsCommonCar();
- void setPathPoints(NPointArray *pathPoints);
-protected:
- Scene *_parentScene;
- NPointArray *_pathPoints;
- int _newMoveDirection;
- int _currMoveDirection;
- int _exitDirection;
- int _currPointIndex;
- bool _hasAgainDestPoint;
- NPoint _againDestPoint;
- bool _hasAgainDestPointIndex;
- int _againDestPointIndex;
- bool _inMainArea;
- bool _isBraking;
- bool _isBusy;
- bool _isIdle;
- bool _isMoving;
- bool _rectFlag;
- int _idleCounter;
- int _idleCounterMax;
- int _steps;
- int _stepError;
- int _lastDistance;
- int _yMoveTotalSteps;
- int _ySteps;
- int _newDeltaXType;
- int _soundCounter;
- int _turnMoveStatus;
- int16 _destX, _destY;
- NPoint pathPoint(uint index) { return (*_pathPoints)[index]; }
- void update();
- void upIdle();
- uint32 handleMessage(int messageNum, const MessageParam &param, Entity *sender);
- uint32 hmAnimation(int messageNum, const MessageParam &param, Entity *sender);
- uint32 hmLeaveCar(int messageNum, const MessageParam &param, Entity *sender);
- void stCarAtHome();
- void updateTurnMovement();
- void updateMovement();
- void stEnterCar();
- void stLeaveCar();
- void stLeanForwardIdle();
- void evIdleDone();
- void stIdleBlink();
- void stUpdateMoveDirection();
- void stTurnCar();
- void moveToNextPoint();
- void stBrakeMoveToNextPoint();
- void stTurnCarMoveToNextPoint();
- void moveToPrevPoint();
- void stBrakeMoveToPrevPoint();
- void stTurnCarMoveToPrevPoint();
- void evTurnCarDone();
- void suMoveToNextPoint();
- void suMoveToPrevPoint();
- void updateSound();
-};
-
-class AsCommonIdleCarLower : public AnimatedSprite {
-public:
- AsCommonIdleCarLower(NeverhoodEngine *vm, int16 x, int16 y);
-};
-
-class AsCommonIdleCarFull : public AnimatedSprite {
-public:
- AsCommonIdleCarFull(NeverhoodEngine *vm, int16 x, int16 y);
-};
-
-class AsCommonCarConnector : public AnimatedSprite {
-public:
- AsCommonCarConnector(NeverhoodEngine *vm, AsCommonCar *asCar);
-protected:
- AsCommonCar *_asCar;
- void update();
-};
-
-class Tracks : public Common::Array<TrackInfo*> {
-public:
- void findTrackPoint(NPoint pt, int &minMatchTrackIndex, int &minMatchDistance,
- DataResource &dataResource);
-};
+class AsCommonCar;
class Scene1608 : public Scene {
public:
diff --git a/engines/neverhood/modules/module1600_sprites.cpp b/engines/neverhood/modules/module1600_sprites.cpp
new file mode 100644
index 0000000000..b12a070b0a
--- /dev/null
+++ b/engines/neverhood/modules/module1600_sprites.cpp
@@ -0,0 +1,850 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+#include "neverhood/gamemodule.h"
+#include "neverhood/modules/module1200.h"
+#include "neverhood/modules/module1600_sprites.h"
+#include "neverhood/modules/module2200_sprites.h"
+#include "neverhood/modules/module3000_sprites.h"
+
+namespace Neverhood {
+
+AsCommonCar::AsCommonCar(NeverhoodEngine *vm, Scene *parentScene, int16 x, int16 y)
+ : AnimatedSprite(vm, 1000), _parentScene(parentScene) {
+
+ createSurface(200, 556, 328);
+ _x = x;
+ _y = y;
+
+ _inMainArea = false;
+ _exitDirection = 0;
+ _currPointIndex = 0;
+ _hasAgainDestPoint = false;
+ _stepError = 0;
+ _hasAgainDestPointIndex = false;
+ _steps = 0;
+ _isBraking = false;
+ _yMoveTotalSteps = 0;
+ _isBusy = false;
+ _isIdle = false;
+ _isMoving = true;
+ _rectFlag = false;
+ _newDeltaXType = -1;
+ _soundCounter = 0;
+ _pathPoints = NULL;
+ _currMoveDirection = 0;
+
+ startAnimation(0xD4220027, 0, -1);
+ setDoDeltaX(getGlobalVar(V_CAR_DELTA_X));
+
+ SetUpdateHandler(&AsCommonCar::update);
+ SetMessageHandler(&AsCommonCar::handleMessage);
+ SetSpriteUpdate(NULL);
+}
+
+AsCommonCar::~AsCommonCar() {
+ if (_finalizeStateCb == AnimationCallback(&AsCommonCar::evTurnCarDone))
+ setGlobalVar(V_CAR_DELTA_X, !getGlobalVar(V_CAR_DELTA_X));
+}
+
+void AsCommonCar::setPathPoints(NPointArray *pathPoints) {
+ _pathPoints = pathPoints;
+}
+
+void AsCommonCar::update() {
+ if (_newDeltaXType >= 0) {
+ setDoDeltaX(_newDeltaXType);
+ _newDeltaXType = -1;
+ }
+ AnimatedSprite::update();
+ if (_hasAgainDestPoint && _yMoveTotalSteps == 0 && !_isBusy) {
+ _hasAgainDestPoint = false;
+ _hasAgainDestPointIndex = false;
+ sendPointMessage(this, 0x2004, _againDestPoint);
+ } else if (_hasAgainDestPointIndex && _yMoveTotalSteps == 0 && !_isBusy) {
+ _hasAgainDestPointIndex = false;
+ sendMessage(this, 0x2003, _againDestPointIndex);
+ }
+ updateMovement();
+ updateSound();
+}
+
+void AsCommonCar::upIdle() {
+ update();
+ if (++_idleCounter >= _idleCounterMax)
+ stIdleBlink();
+ updateSound();
+}
+
+uint32 AsCommonCar::handleMessage(int messageNum, const MessageParam &param, Entity *sender) {
+ uint32 messageResult = Sprite::handleMessage(messageNum, param, sender);
+ switch (messageNum) {
+ case 0x1019:
+ SetSpriteUpdate(NULL);
+ break;
+ case 0x2002:
+ // Set the current position without moving
+ _currPointIndex = param.asInteger();
+ _stepError = 0;
+ _x = pathPoint(_currPointIndex).x;
+ _y = pathPoint(_currPointIndex).y;
+ break;
+ case 0x2003:
+ // Move to a point by its index
+ {
+ int newPointIndex = param.asInteger();
+ if (_yMoveTotalSteps <= 0 && !_isBusy) {
+ _destX = pathPoint(newPointIndex).x;
+ _destY = pathPoint(newPointIndex).y;
+ if (_currPointIndex < newPointIndex) {
+ moveToNextPoint();
+ } else if (_currPointIndex == newPointIndex && _stepError == 0) {
+ if (_currPointIndex == 0) {
+ _yMoveTotalSteps = 0;
+ sendMessage(_parentScene, 0x2005, 0);
+ } else if (_currPointIndex == (int)_pathPoints->size()) {
+ _yMoveTotalSteps = 0;
+ sendMessage(_parentScene, 0x2006, 0);
+ }
+ } else {
+ moveToPrevPoint();
+ }
+ } else {
+ _hasAgainDestPointIndex = true;
+ _againDestPointIndex = newPointIndex;
+ }
+ }
+ break;
+ case 0x2004:
+ // Move to the point closest to the parameter point
+ {
+ int minMatchIndex = -1;
+ int minMatchDistance, distance;
+ NPoint pt = param.asPoint();
+ if (_yMoveTotalSteps <= 0 && !_isBusy) {
+ // Check if we're already exiting (or something)
+ if ((pt.x <= 20 && _exitDirection == 1) ||
+ (pt.x >= 620 && _exitDirection == 3) ||
+ (pt.y <= 20 && _exitDirection == 2) ||
+ (pt.y >= 460 && _exitDirection == 4))
+ break;
+ _destX = pt.x;
+ _destY = pt.y;
+ minMatchDistance = calcDistance(_destX, _destY, _x, _y) + 1;
+ for (int i = _currPointIndex + 1; i < (int)_pathPoints->size(); i++) {
+ distance = calcDistance(_destX, _destY, pathPoint(i).x, pathPoint(i).y);
+ if (distance >= minMatchDistance)
+ break;
+ minMatchDistance = distance;
+ minMatchIndex = i;
+ }
+ for (int i = _currPointIndex; i >= 0; i--) {
+ distance = calcDistance(_destX, _destY, pathPoint(i).x, pathPoint(i).y);
+ if (distance >= minMatchDistance)
+ break;
+ minMatchDistance = distance;
+ minMatchIndex = i;
+ }
+ if (minMatchIndex == -1) {
+ if (_currPointIndex == 0)
+ moveToPrevPoint();
+ else
+ SetSpriteUpdate(NULL);
+ } else {
+ if (minMatchIndex > _currPointIndex)
+ moveToNextPoint();
+ else
+ moveToPrevPoint();
+ }
+ } else {
+ _hasAgainDestPoint = true;
+ _againDestPoint = pt;
+ }
+ }
+ break;
+ case 0x2007:
+ _yMoveTotalSteps = param.asInteger();
+ _steps = 0;
+ _isBraking = false;
+ _lastDistance = 640;
+ SetSpriteUpdate(&AsCommonCar::suMoveToPrevPoint);
+ break;
+ case 0x2008:
+ _yMoveTotalSteps = param.asInteger();
+ _steps = 0;
+ _isBraking = false;
+ _lastDistance = 640;
+ SetSpriteUpdate(&AsCommonCar::suMoveToNextPoint);
+ break;
+ case 0x2009:
+ stEnterCar();
+ break;
+ case 0x200A:
+ stLeaveCar();
+ break;
+ case 0x200E:
+ stTurnCar();
+ break;
+ case 0x200F:
+ stCarAtHome();
+ _newDeltaXType = param.asInteger();
+ break;
+ }
+ return messageResult;
+}
+
+uint32 AsCommonCar::hmAnimation(int messageNum, const MessageParam &param, Entity *sender) {
+ uint32 messageResult = AsCommonCar::handleMessage(messageNum, param, sender);
+ switch (messageNum) {
+ case 0x100D:
+ if (_isBusy && param.asInteger() == 0x025424A2)
+ gotoNextState();
+ break;
+ case 0x3002:
+ gotoNextState();
+ break;
+ }
+ return messageResult;
+}
+
+uint32 AsCommonCar::hmLeaveCar(int messageNum, const MessageParam &param, Entity *sender) {
+ switch (messageNum) {
+ case 0x2009:
+ stEnterCar();
+ break;
+ case 0x3002:
+ sendMessage(_parentScene, 0x200A, 0);
+ SetMessageHandler(&AsCommonCar::handleMessage);
+ break;
+ }
+ return 0;
+}
+
+void AsCommonCar::stCarAtHome() {
+ bool doDeltaX = _doDeltaX;
+ SetSpriteUpdate(NULL);
+ _hasAgainDestPoint = false;
+ _hasAgainDestPointIndex = false;
+ _isBraking = false;
+ _isBusy = false;
+ _isIdle = false;
+ _isMoving = false;
+ _rectFlag = false;
+ NextState(&AsCommonCar::stLeanForwardIdle);
+ startAnimation(0x35698F78, 0, -1);
+ setDoDeltaX(doDeltaX ? 1 : 0);
+ _currMoveDirection = 0;
+ _newMoveDirection = 0;
+ _steps = 0;
+ _idleCounter = 0;
+ _idleCounterMax = _vm->_rnd->getRandomNumber(64 - 1) + 24;
+ SetUpdateHandler(&AsCommonCar::upIdle);
+ SetMessageHandler(&AsCommonCar::handleMessage);
+ FinalizeState(&AsCommonCar::evIdleDone);
+}
+
+void AsCommonCar::updateTurnMovement() {
+ if (_turnMoveStatus == 1) {
+ _lastDistance = 640;
+ _isIdle = false;
+ _isBraking = false;
+ SetSpriteUpdate(&AsCommonCar::suMoveToNextPoint);
+ } else if (_turnMoveStatus == 2) {
+ _lastDistance = 640;
+ _isIdle = false;
+ _isBraking = false;
+ SetSpriteUpdate(&AsCommonCar::suMoveToPrevPoint);
+ }
+}
+
+void AsCommonCar::updateMovement() {
+ if (_isBraking && !_isIdle && !_isBusy) {
+ gotoNextState();
+ _isMoving = false;
+ _isIdle = true;
+ startAnimation(0x192ADD30, 0, -1);
+ SetUpdateHandler(&AsCommonCar::update);
+ SetMessageHandler(&AsCommonCar::hmAnimation);
+ NextState(&AsCommonCar::stLeanForwardIdle);
+ } else if (!_isBraking && _steps && _isIdle) {
+ gotoNextState();
+ _isIdle = false;
+ startAnimation(0x9966B138, 0, -1);
+ SetUpdateHandler(&AsCommonCar::update);
+ SetMessageHandler(&AsCommonCar::hmAnimation);
+ NextState(&AsCommonCar::stUpdateMoveDirection);
+ } else if (_newMoveDirection != _currMoveDirection && _isMoving && !_isBusy) {
+ gotoNextState();
+ _currMoveDirection = _newMoveDirection;
+ stUpdateMoveDirection();
+ }
+}
+
+void AsCommonCar::stEnterCar() {
+ startAnimation(0xA86A9538, 0, -1);
+ SetUpdateHandler(&AsCommonCar::update);
+ SetMessageHandler(&AsCommonCar::hmAnimation);
+ NextState(&AsCommonCar::stLeanForwardIdle);
+}
+
+void AsCommonCar::stLeaveCar() {
+ startAnimation(0xA86A9538, -1, -1);
+ _playBackwards = true;
+ SetUpdateHandler(&AsCommonCar::update);
+ SetMessageHandler(&AsCommonCar::hmLeaveCar);
+}
+
+void AsCommonCar::stLeanForwardIdle() {
+ startAnimation(0x35698F78, 0, -1);
+ _currMoveDirection = 0;
+ _newMoveDirection = 0;
+ _steps = 0;
+ _idleCounter = 0;
+ _idleCounterMax = _vm->_rnd->getRandomNumber(64 - 1) + 24;
+ SetUpdateHandler(&AsCommonCar::upIdle);
+ SetMessageHandler(&AsCommonCar::handleMessage);
+ FinalizeState(&AsCommonCar::evIdleDone);
+}
+
+void AsCommonCar::evIdleDone() {
+ SetUpdateHandler(&AsCommonCar::update);
+}
+
+void AsCommonCar::stIdleBlink() {
+ startAnimation(0xB579A77C, 0, -1);
+ _idleCounter = 0;
+ _idleCounterMax = _vm->_rnd->getRandomNumber(64 - 1) + 24;
+ SetUpdateHandler(&AsCommonCar::update);
+ SetMessageHandler(&AsCommonCar::hmAnimation);
+ NextState(&AsCommonCar::stLeanForwardIdle);
+}
+
+void AsCommonCar::stUpdateMoveDirection() {
+ _isMoving = true;
+ if (_currMoveDirection == 1)
+ startAnimation(0xD4AA03A4, 0, -1);
+ else if (_currMoveDirection == 3)
+ startAnimation(0xD00A1364, 0, -1);
+ else if ((_currMoveDirection == 2 && _doDeltaX) || (_currMoveDirection == 4 && !_doDeltaX))
+ stTurnCar();
+ else
+ startAnimation(0xD4220027, 0, -1);
+ setGlobalVar(V_CAR_DELTA_X, _doDeltaX ? 1 : 0);
+}
+
+void AsCommonCar::moveToNextPoint() {
+ if (_currPointIndex >= (int)_pathPoints->size() - 1) {
+ _yMoveTotalSteps = 0;
+ sendMessage(this, 0x1019, 0);
+ sendMessage(_parentScene, 0x2006, 0);
+ } else {
+ NPoint nextPt = pathPoint(_currPointIndex + 1);
+ NPoint currPt = pathPoint(_currPointIndex);
+ if (ABS(nextPt.y - currPt.y) <= ABS(nextPt.x - currPt.x) &&
+ ((_currMoveDirection == 2 && nextPt.x < currPt.x) ||
+ (_currMoveDirection == 4 && nextPt.x >= currPt.x))) {
+ if (_currMoveDirection == 2)
+ _currMoveDirection = 4;
+ else if (_currMoveDirection == 4)
+ _currMoveDirection = 2;
+ if (_isIdle)
+ stTurnCarMoveToNextPoint();
+ else
+ stBrakeMoveToNextPoint();
+ } else {
+ if (_steps == 0) {
+ gotoNextState();
+ _isIdle = false;
+ startAnimation(0x9966B138, 0, -1);
+ SetMessageHandler(&AsCommonCar::hmAnimation);
+ SetUpdateHandler(&AsCommonCar::update);
+ NextState(&AsCommonCar::stUpdateMoveDirection);
+ }
+ _isBraking = false;
+ SetSpriteUpdate(&AsCommonCar::suMoveToNextPoint);
+ _lastDistance = 640;
+ }
+ }
+}
+
+void AsCommonCar::stBrakeMoveToNextPoint() {
+ gotoNextState();
+ _isBusy = true;
+ _isBraking = true;
+ startAnimation(0x192ADD30, 0, -1);
+ SetUpdateHandler(&AsCommonCar::update);
+ SetMessageHandler(&AsCommonCar::hmAnimation);
+ NextState(&AsCommonCar::stTurnCarMoveToNextPoint);
+}
+
+void AsCommonCar::stTurnCar() {
+ // Turn to left/right #1
+ gotoNextState();
+ _isBusy = true;
+ startAnimation(0xF46A0324, 0, -1);
+ SetUpdateHandler(&AsCommonCar::update);
+ SetMessageHandler(&AsCommonCar::hmAnimation);
+ FinalizeState(&AsCommonCar::evTurnCarDone);
+ _turnMoveStatus = 0;
+ updateTurnMovement();
+}
+
+void AsCommonCar::stTurnCarMoveToNextPoint() {
+ // Turn to left/right #2
+ gotoNextState();
+ _isBusy = true;
+ startAnimation(0xF46A0324, 0, -1);
+ SetUpdateHandler(&AsCommonCar::update);
+ SetMessageHandler(&AsCommonCar::hmAnimation);
+ FinalizeState(&AsCommonCar::evTurnCarDone);
+ _turnMoveStatus = 1;
+ updateTurnMovement();
+}
+
+void AsCommonCar::stTurnCarMoveToPrevPoint() {
+ // Turn to left/right #3
+ FinalizeState(NULL);
+ _isBusy = true;
+ startAnimation(0xF46A0324, 0, -1);
+ SetUpdateHandler(&AsCommonCar::update);
+ SetMessageHandler(&AsCommonCar::hmAnimation);
+ FinalizeState(&AsCommonCar::evTurnCarDone);
+ _turnMoveStatus = 2;
+ updateTurnMovement();
+}
+
+void AsCommonCar::moveToPrevPoint() {
+ if (_currPointIndex == 0 && _stepError == 0) {
+ _yMoveTotalSteps = 0;
+ sendMessage(this, 0x1019, 0);
+ sendMessage(_parentScene, 0x2005, 0);
+ } else {
+ NPoint prevPt;
+ NPoint currPt;
+ if (_stepError == 0) {
+ prevPt = pathPoint(_currPointIndex - 1);
+ currPt = pathPoint(_currPointIndex);
+ } else {
+ prevPt = pathPoint(_currPointIndex);
+ currPt = pathPoint(_currPointIndex + 1);
+ }
+ if (ABS(prevPt.y - currPt.y) <= ABS(prevPt.x - currPt.x) &&
+ ((_currMoveDirection == 2 && prevPt.x < currPt.x) ||
+ (_currMoveDirection == 4 && prevPt.x >= currPt.x))) {
+ if (_currMoveDirection == 2)
+ _currMoveDirection = 4;
+ else if (_currMoveDirection == 4)
+ _currMoveDirection = 2;
+ if (_isIdle)
+ stTurnCarMoveToPrevPoint();
+ else
+ stBrakeMoveToPrevPoint();
+ } else {
+ if (_steps == 0) {
+ gotoNextState();
+ _isIdle = false;
+ startAnimation(0x9966B138, 0, -1);
+ SetMessageHandler(&AsCommonCar::hmAnimation);
+ SetUpdateHandler(&AsCommonCar::update);
+ NextState(&AsCommonCar::stUpdateMoveDirection);
+ }
+ _isBraking = false;
+ SetSpriteUpdate(&AsCommonCar::suMoveToPrevPoint);
+ _lastDistance = 640;
+ }
+ }
+}
+
+void AsCommonCar::stBrakeMoveToPrevPoint() {
+ FinalizeState(NULL);
+ _isBusy = true;
+ _isBraking = true;
+ startAnimation(0x192ADD30, 0, -1);
+ SetUpdateHandler(&AsCommonCar::update);
+ SetMessageHandler(&AsCommonCar::hmAnimation);
+ NextState(&AsCommonCar::stTurnCarMoveToPrevPoint);
+}
+
+void AsCommonCar::evTurnCarDone() {
+ _isBusy = false;
+ setDoDeltaX(2);
+ _newMoveDirection = 0;
+ stUpdateMoveDirection();
+}
+
+void AsCommonCar::suMoveToNextPoint() {
+ int16 newX = _x, newY = _y;
+
+ if (_currPointIndex >= (int)_pathPoints->size()) {
+ _yMoveTotalSteps = 0;
+ sendMessage(this, 0x1019, 0);
+ sendMessage(_parentScene, 0x2006, 0);
+ return;
+ }
+
+ if (_isBraking) {
+ if (_steps <= 0) {
+ sendMessage(this, 0x1019, 0);
+ return;
+ } else
+ _steps--;
+ } else if (_steps < 11)
+ _steps++;
+
+ bool firstTime = true;
+ _ySteps = _steps;
+ int stepsCtr = _steps;
+
+ while (stepsCtr > 0) {
+ NPoint pt1;
+ NPoint pt2 = pathPoint(_currPointIndex);
+ if (_currPointIndex + 1 >= (int)_pathPoints->size())
+ pt1 = pathPoint(0);
+ else
+ pt1 = pathPoint(_currPointIndex + 1);
+ int16 deltaX = ABS(pt1.x - pt2.x);
+ int16 deltaY = ABS(pt1.y - pt2.y);
+ if (deltaX >= deltaY) {
+ _newMoveDirection = 2;
+ if (pt1.x < pt2.x)
+ _newMoveDirection = 4;
+ if (stepsCtr + _stepError >= deltaX) {
+ stepsCtr -= deltaX;
+ stepsCtr += _stepError;
+ _stepError = 0;
+ _currPointIndex++;
+ if (_currPointIndex == (int)_pathPoints->size() - 1)
+ stepsCtr = 0;
+ newX = pathPoint(_currPointIndex).x;
+ newY = pathPoint(_currPointIndex).y;
+ } else {
+ _stepError += stepsCtr;
+ if (pt1.x >= pt2.x)
+ newX += stepsCtr;
+ else
+ newX -= stepsCtr;
+ if (pt1.y >= pt2.y)
+ newY = pt2.y + (deltaY * _stepError) / deltaX;
+ else
+ newY = pt2.y - (deltaY * _stepError) / deltaX;
+ stepsCtr = 0;
+ }
+ } else {
+ _newMoveDirection = 3;
+ if (pt1.y < pt2.y)
+ _newMoveDirection = 1;
+ if (firstTime) {
+ if (pt1.y >= pt2.y)
+ stepsCtr += 7;
+ else {
+ stepsCtr -= 4;
+ if (stepsCtr < 0)
+ stepsCtr = 0;
+ }
+ _ySteps = stepsCtr;
+ }
+ if (stepsCtr + _stepError >= deltaY) {
+ stepsCtr -= deltaY;
+ stepsCtr += _stepError;
+ _stepError = 0;
+ _currPointIndex++;
+ if (_currPointIndex == (int)_pathPoints->size() - 1)
+ stepsCtr = 0;
+ newX = pathPoint(_currPointIndex).x;
+ newY = pathPoint(_currPointIndex).y;
+ } else {
+ _stepError += stepsCtr;
+ if (pt1.x >= pt2.x)
+ newX = pt2.x + (deltaX * _stepError) / deltaY;
+ else
+ newX = pt2.x - (deltaX * _stepError) / deltaY;
+ if (pt1.y >= pt2.y)
+ newY += stepsCtr;
+ else
+ newY -= stepsCtr;
+ stepsCtr = 0;
+ }
+ }
+ firstTime = false;
+ }
+
+ if (_yMoveTotalSteps != 0) {
+ _x = newX;
+ _y = newY;
+ _yMoveTotalSteps -= _ySteps;
+ if (_yMoveTotalSteps <= 0) {
+ _isBraking = true;
+ _yMoveTotalSteps = 0;
+ }
+ } else {
+ int distance = calcDistance(_destX, _destY, _x, _y);
+ _x = newX;
+ _y = newY;
+ if (newX > 20 && newX < 620 && newY > 20 && newY < 460) {
+ _exitDirection = 0;
+ _inMainArea = true;
+ } else if (_inMainArea) {
+ _destX = pathPoint(_pathPoints->size() - 1).x;
+ _destY = pathPoint(_pathPoints->size() - 1).y;
+ _inMainArea = false;
+ if (_x <= 20)
+ _exitDirection = 1;
+ else if (_x >= 620)
+ _exitDirection = 3;
+ else if (_y <= 20)
+ _exitDirection = 2;
+ else if (_y >= 460)
+ _exitDirection = 4;
+ if (_exitDirection != 0 && _isBraking) {
+ _isBraking = false;
+ _steps = 11;
+ }
+ }
+ if ((distance < 20 && _exitDirection == 0 && _lastDistance < distance) ||
+ (_exitDirection == 0 && _lastDistance + 20 < distance))
+ _isBraking = true;
+ if (distance < _lastDistance)
+ _lastDistance = distance;
+ if (_currPointIndex == (int)_pathPoints->size() - 1) {
+ _isBraking = true;
+ _yMoveTotalSteps = 0;
+ sendMessage(this, 0x1019, 0);
+ sendMessage(_parentScene, 0x2006, 0);
+ }
+ }
+
+}
+
+void AsCommonCar::suMoveToPrevPoint() {
+ int16 newX = _x, newY = _y;
+
+ if (_currPointIndex == 0 && _stepError == 0) {
+ _yMoveTotalSteps = 0;
+ sendMessage(this, 0x1019, 0);
+ sendMessage(_parentScene, 0x2005, 0);
+ return;
+ }
+
+ if (_isBraking) {
+ if (_steps <= 0) {
+ sendMessage(this, 0x1019, 0);
+ return;
+ } else
+ _steps--;
+ } else if (_steps < 11)
+ _steps++;
+
+ bool firstTime = true;
+ _ySteps = _steps;
+ int stepsCtr = _steps;
+
+ while (stepsCtr > 0) {
+ if (_stepError == 0)
+ _currPointIndex--;
+ NPoint pt1;
+ NPoint pt2 = pathPoint(_currPointIndex);
+ if (_currPointIndex + 1 >= (int)_pathPoints->size())
+ pt1 = pathPoint(0);
+ else
+ pt1 = pathPoint(_currPointIndex + 1);
+ int16 deltaX = ABS(pt1.x - pt2.x);
+ int16 deltaY = ABS(pt1.y - pt2.y);
+ if (deltaX >= deltaY) {
+ _newMoveDirection = 4;
+ if (pt1.x < pt2.x)
+ _newMoveDirection = 2;
+ if (_stepError == 0)
+ _stepError = deltaX;
+ if (stepsCtr > _stepError) {
+ stepsCtr -= _stepError;
+ _stepError = 0;
+ if (_currPointIndex == 0)
+ stepsCtr = 0;
+ newX = pathPoint(_currPointIndex).x;
+ newY = pathPoint(_currPointIndex).y;
+ } else {
+ _stepError -= stepsCtr;
+ if (pt1.x >= pt2.x)
+ newX -= stepsCtr;
+ else
+ newX += stepsCtr;
+ if (pt1.y >= pt2.y)
+ newY = pt2.y + (deltaY * _stepError) / deltaX;
+ else
+ newY = pt2.y - (deltaY * _stepError) / deltaX;
+ stepsCtr = 0;
+ }
+ } else {
+ _newMoveDirection = 1;
+ if (pt1.y < pt2.y)
+ _newMoveDirection = 3;
+ if (firstTime) {
+ if (pt1.y >= pt2.y) {
+ stepsCtr -= 4;
+ if (stepsCtr < 0)
+ stepsCtr = 0;
+ } else {
+ stepsCtr += 7;
+ }
+ _ySteps = stepsCtr;
+ }
+ if (_stepError == 0)
+ _stepError = deltaY;
+ if (stepsCtr > _stepError) {
+ stepsCtr -= _stepError;
+ _stepError = 0;
+ if (_currPointIndex == 0)
+ stepsCtr = 0;
+ newX = pathPoint(_currPointIndex).x;
+ newY = pathPoint(_currPointIndex).y;
+ } else {
+ _stepError -= stepsCtr;
+ if (pt1.x >= pt2.x)
+ newX = pt2.x + (deltaX * _stepError) / deltaY;
+ else
+ newX = pt2.x - (deltaX * _stepError) / deltaY;
+ if (pt1.y >= pt2.y)
+ newY -= stepsCtr;
+ else
+ newY += stepsCtr;
+ stepsCtr = 0;
+ }
+ }
+ firstTime = false;
+ }
+
+ if (_yMoveTotalSteps != 0) {
+ _x = newX;
+ _y = newY;
+ _yMoveTotalSteps -= _ySteps;
+ if (_yMoveTotalSteps <= 0) {
+ _isBraking = true;
+ _yMoveTotalSteps = 0;
+ }
+ } else {
+ int distance = calcDistance(_destX, _destY, _x, _y);
+ _x = newX;
+ _y = newY;
+ if (newX > 20 && newX < 620 && newY > 20 && newY < 460) {
+ _exitDirection = 0;
+ _inMainArea = true;
+ } else if (_inMainArea) {
+ _destX = pathPoint(0).x;
+ _destY = pathPoint(0).y;
+ _inMainArea = false;
+ if (_x <= 20)
+ _exitDirection = 1;
+ else if (_x >= 620)
+ _exitDirection = 3;
+ else if (_y <= 20)
+ _exitDirection = 2;
+ else if (_y >= 460)
+ _exitDirection = 4;
+ if (_exitDirection != 0 && _isBraking) {
+ _isBraking = false;
+ _steps = 11;
+ }
+ }
+ if ((distance < 20 && _exitDirection == 0 && _lastDistance < distance) ||
+ (_exitDirection == 0 && _lastDistance + 20 < distance))
+ _isBraking = true;
+ if (distance < _lastDistance)
+ _lastDistance = distance;
+ if (_currPointIndex == 0 && _stepError == 0) {
+ _isBraking = true;
+ _yMoveTotalSteps = 0;
+ sendMessage(this, 0x1019, 0);
+ sendMessage(_parentScene, 0x2005, 0);
+ }
+ }
+
+}
+
+void AsCommonCar::updateSound() {
+ int maxSoundCounter = 0;
+ _soundCounter++;
+ if (_steps != 0 && !_isIdle) {
+ if (_currMoveDirection == 1)
+ maxSoundCounter = 18 - _steps;
+ else if (_currMoveDirection == 3) {
+ maxSoundCounter = 5 - _steps;
+ if (maxSoundCounter < 1)
+ maxSoundCounter = 1;
+ } else
+ maxSoundCounter = 14 - _steps;
+ } else
+ maxSoundCounter = 21;
+ if (_soundCounter >= maxSoundCounter) {
+ sendMessage(_parentScene, 0x200D, 0);
+ _soundCounter = 0;
+ }
+}
+
+AsCommonIdleCarLower::AsCommonIdleCarLower(NeverhoodEngine *vm, int16 x, int16 y)
+ : AnimatedSprite(vm, 0x1209E09F, 1100, x, y) {
+
+ setDoDeltaX(1);
+ startAnimation(0x1209E09F, 1, -1);
+ _newStickFrameIndex = 1;
+}
+
+AsCommonIdleCarFull::AsCommonIdleCarFull(NeverhoodEngine *vm, int16 x, int16 y)
+ : AnimatedSprite(vm, 0x1209E09F, 100, x, y) {
+
+ setDoDeltaX(1);
+ _newStickFrameIndex = 0;
+}
+
+AsCommonCarConnector::AsCommonCarConnector(NeverhoodEngine *vm, AsCommonCar *asCar)
+ : AnimatedSprite(vm, 1100), _asCar(asCar) {
+
+ createSurface1(0x60281C10, 150);
+ startAnimation(0x60281C10, -1, -1);
+ _newStickFrameIndex = STICK_LAST_FRAME;
+ SetUpdateHandler(&AsCommonCarConnector::update);
+}
+
+void AsCommonCarConnector::update() {
+ _x = _asCar->getX();
+ _y = _asCar->getY();
+ AnimatedSprite::update();
+}
+
+void Tracks::findTrackPoint(NPoint pt, int &minMatchTrackIndex, int &minMatchDistance,
+ DataResource &dataResource) {
+ const uint trackCount = size();
+ minMatchTrackIndex = -1;
+ minMatchDistance = 640;
+ for (uint trackIndex = 0; trackIndex < trackCount; trackIndex++) {
+ NPointArray *pointList = dataResource.getPointArray((*this)[trackIndex]->trackPointsName);
+ for (uint pointIndex = 0; pointIndex < pointList->size(); pointIndex++) {
+ NPoint testPt = (*pointList)[pointIndex];
+ int distance = calcDistance(testPt.x, testPt.y, pt.x, pt.y);
+ if (distance < minMatchDistance) {
+ minMatchTrackIndex = trackIndex;
+ minMatchDistance = distance;
+ }
+ }
+ }
+}
+
+} // End of namespace Neverhood
diff --git a/engines/neverhood/modules/module1600_sprites.h b/engines/neverhood/modules/module1600_sprites.h
new file mode 100644
index 0000000000..13fcf6cdbc
--- /dev/null
+++ b/engines/neverhood/modules/module1600_sprites.h
@@ -0,0 +1,119 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+#ifndef NEVERHOOD_MODULES_MODULE1600_SPRITES_H
+#define NEVERHOOD_MODULES_MODULE1600_SPRITES_H
+
+#include "neverhood/neverhood.h"
+#include "neverhood/module.h"
+#include "neverhood/scene.h"
+
+namespace Neverhood {
+
+class AsCommonCar : public AnimatedSprite {
+public:
+ AsCommonCar(NeverhoodEngine *vm, Scene *parentScene, int16 x, int16 y);
+ ~AsCommonCar();
+ void setPathPoints(NPointArray *pathPoints);
+protected:
+ Scene *_parentScene;
+ NPointArray *_pathPoints;
+ int _newMoveDirection;
+ int _currMoveDirection;
+ int _exitDirection;
+ int _currPointIndex;
+ bool _hasAgainDestPoint;
+ NPoint _againDestPoint;
+ bool _hasAgainDestPointIndex;
+ int _againDestPointIndex;
+ bool _inMainArea;
+ bool _isBraking;
+ bool _isBusy;
+ bool _isIdle;
+ bool _isMoving;
+ bool _rectFlag;
+ int _idleCounter;
+ int _idleCounterMax;
+ int _steps;
+ int _stepError;
+ int _lastDistance;
+ int _yMoveTotalSteps;
+ int _ySteps;
+ int _newDeltaXType;
+ int _soundCounter;
+ int _turnMoveStatus;
+ int16 _destX, _destY;
+ NPoint pathPoint(uint index) { return (*_pathPoints)[index]; }
+ void update();
+ void upIdle();
+ uint32 handleMessage(int messageNum, const MessageParam &param, Entity *sender);
+ uint32 hmAnimation(int messageNum, const MessageParam &param, Entity *sender);
+ uint32 hmLeaveCar(int messageNum, const MessageParam &param, Entity *sender);
+ void stCarAtHome();
+ void updateTurnMovement();
+ void updateMovement();
+ void stEnterCar();
+ void stLeaveCar();
+ void stLeanForwardIdle();
+ void evIdleDone();
+ void stIdleBlink();
+ void stUpdateMoveDirection();
+ void stTurnCar();
+ void moveToNextPoint();
+ void stBrakeMoveToNextPoint();
+ void stTurnCarMoveToNextPoint();
+ void moveToPrevPoint();
+ void stBrakeMoveToPrevPoint();
+ void stTurnCarMoveToPrevPoint();
+ void evTurnCarDone();
+ void suMoveToNextPoint();
+ void suMoveToPrevPoint();
+ void updateSound();
+};
+
+class AsCommonIdleCarLower : public AnimatedSprite {
+public:
+ AsCommonIdleCarLower(NeverhoodEngine *vm, int16 x, int16 y);
+};
+
+class AsCommonIdleCarFull : public AnimatedSprite {
+public:
+ AsCommonIdleCarFull(NeverhoodEngine *vm, int16 x, int16 y);
+};
+
+class AsCommonCarConnector : public AnimatedSprite {
+public:
+ AsCommonCarConnector(NeverhoodEngine *vm, AsCommonCar *asCar);
+protected:
+ AsCommonCar *_asCar;
+ void update();
+};
+
+class Tracks : public Common::Array<TrackInfo*> {
+public:
+ void findTrackPoint(NPoint pt, int &minMatchTrackIndex, int &minMatchDistance,
+ DataResource &dataResource);
+};
+
+} // End of namespace Neverhood
+
+#endif /* NEVERHOOD_MODULES_MODULE1600_SPRITES_H */
diff --git a/engines/neverhood/modules/module2500.cpp b/engines/neverhood/modules/module2500.cpp
index b6066599ec..bda85e54d2 100644
--- a/engines/neverhood/modules/module2500.cpp
+++ b/engines/neverhood/modules/module2500.cpp
@@ -21,6 +21,7 @@
*/
#include "neverhood/modules/module1600.h"
+#include "neverhood/modules/module1600_sprites.h"
#include "neverhood/modules/module2500.h"
#include "neverhood/modules/module2500_sprites.h"
#include "neverhood/modules/module2700.h"
diff --git a/engines/neverhood/modules/module2500.h b/engines/neverhood/modules/module2500.h
index 33464cfdaa..de6226ef0c 100644
--- a/engines/neverhood/modules/module2500.h
+++ b/engines/neverhood/modules/module2500.h
@@ -26,11 +26,10 @@
#include "neverhood/neverhood.h"
#include "neverhood/module.h"
#include "neverhood/scene.h"
+#include "neverhood/modules/module1600_sprites.h" // for Tracks
namespace Neverhood {
-// Module2500
-
class Module2500 : public Module {
public:
Module2500(NeverhoodEngine *vm, Module *parentModule, int which);
@@ -45,7 +44,6 @@ protected:
};
class AsCommonCar;
-class Tracks;
class Scene2501 : public Scene {
public:
diff --git a/engines/neverhood/modules/module2700.cpp b/engines/neverhood/modules/module2700.cpp
index 69e21dd31d..d05f142f77 100644
--- a/engines/neverhood/modules/module2700.cpp
+++ b/engines/neverhood/modules/module2700.cpp
@@ -22,7 +22,7 @@
#include "neverhood/gamemodule.h"
#include "neverhood/modules/module1000.h"
-#include "neverhood/modules/module1600.h"
+#include "neverhood/modules/module1600_sprites.h"
#include "neverhood/modules/module2700.h"
#include "neverhood/modules/module2700_sprites.h"
diff --git a/engines/neverhood/modules/module2700.h b/engines/neverhood/modules/module2700.h
index 5e42eea94f..97b4f1cbea 100644
--- a/engines/neverhood/modules/module2700.h
+++ b/engines/neverhood/modules/module2700.h
@@ -26,6 +26,7 @@
#include "neverhood/neverhood.h"
#include "neverhood/module.h"
#include "neverhood/scene.h"
+#include "neverhood/modules/module1600_sprites.h" // for Tracks
namespace Neverhood {
@@ -49,7 +50,6 @@ protected:
};
class AsCommonCar;
-class Tracks;
class Scene2701 : public Scene {
public: