From b408b94bf1e188da7202895eab547f08cfa30450 Mon Sep 17 00:00:00 2001 From: Filippos Karapetis Date: Sat, 5 Oct 2013 14:52:48 +0300 Subject: NEVERHOOD: Split sprites from their scenes in module 1600 --- engines/neverhood/module.mk | 1 + engines/neverhood/modules/module1600.cpp | 822 +--------------------- engines/neverhood/modules/module1600.h | 88 +-- engines/neverhood/modules/module1600_sprites.cpp | 850 +++++++++++++++++++++++ engines/neverhood/modules/module1600_sprites.h | 119 ++++ engines/neverhood/modules/module2500.cpp | 1 + engines/neverhood/modules/module2500.h | 4 +- engines/neverhood/modules/module2700.cpp | 2 +- engines/neverhood/modules/module2700.h | 2 +- 9 files changed, 977 insertions(+), 912 deletions(-) create mode 100644 engines/neverhood/modules/module1600_sprites.cpp create mode 100644 engines/neverhood/modules/module1600_sprites.h (limited to 'engines/neverhood') 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 ¶m, 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 ¶m, 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 ¶m, 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 ¶m, Entity *sender); - uint32 hmAnimation(int messageNum, const MessageParam ¶m, Entity *sender); - uint32 hmLeaveCar(int messageNum, const MessageParam ¶m, 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 { -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 ¶m, 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 ¶m, 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 ¶m, 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 ¶m, Entity *sender); + uint32 hmAnimation(int messageNum, const MessageParam ¶m, Entity *sender); + uint32 hmLeaveCar(int messageNum, const MessageParam ¶m, 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 { +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: -- cgit v1.2.3