diff options
author | johndoe123 | 2011-09-23 15:21:24 +0000 |
---|---|---|
committer | Willem Jan Palenstijn | 2013-05-08 20:39:41 +0200 |
commit | 236ca705e8082184aae61aae5e2d561d09b7043c (patch) | |
tree | 0d3331033f138aea2333cbb3bbda84e6f1cccfb0 | |
parent | 2445e6aba8e9724737a069eb4e018f8e60015aac (diff) | |
download | scummvm-rg350-236ca705e8082184aae61aae5e2d561d09b7043c.tar.gz scummvm-rg350-236ca705e8082184aae61aae5e2d561d09b7043c.tar.bz2 scummvm-rg350-236ca705e8082184aae61aae5e2d561d09b7043c.zip |
NEVERHOOD: Add Module1600 and Scene1608 (stuff will be renamed later)
-rw-r--r-- | engines/neverhood/gamemodule.cpp | 19 | ||||
-rw-r--r-- | engines/neverhood/klayman.cpp | 89 | ||||
-rw-r--r-- | engines/neverhood/klayman.h | 8 | ||||
-rw-r--r-- | engines/neverhood/module.cpp | 4 | ||||
-rw-r--r-- | engines/neverhood/module.h | 1 | ||||
-rw-r--r-- | engines/neverhood/module.mk | 1 | ||||
-rw-r--r-- | engines/neverhood/module1600.cpp | 1387 | ||||
-rw-r--r-- | engines/neverhood/module1600.h | 176 | ||||
-rw-r--r-- | engines/neverhood/scene.cpp | 4 | ||||
-rw-r--r-- | engines/neverhood/scene.h | 30 |
10 files changed, 1716 insertions, 3 deletions
diff --git a/engines/neverhood/gamemodule.cpp b/engines/neverhood/gamemodule.cpp index 4d1c27d4df..854a5cc1fe 100644 --- a/engines/neverhood/gamemodule.cpp +++ b/engines/neverhood/gamemodule.cpp @@ -29,6 +29,7 @@ #include "neverhood/module1300.h" #include "neverhood/module1400.h" #include "neverhood/module1500.h" +#include "neverhood/module1600.h" #include "neverhood/module1700.h" #include "neverhood/module1800.h" #include "neverhood/module2000.h" @@ -275,8 +276,9 @@ void GameModule::startup() { createModule(1000, -1); #endif #if 1 - _vm->gameState().sceneNum = 8; - createModule(1100, -1); + _vm->gameState().sceneNum = 7; + _vm->gameState().which = 1; + createModule(1600, -1); #endif } @@ -309,6 +311,10 @@ void GameModule::createModule(int moduleNum, int which) { setGlobalVar(0x91080831, 0x00F10114); _childObject = new Module1500(_vm, this, which, true); break; + case 1600: + setGlobalVar(0x91080831, 0x01A008D8); + _childObject = new Module1600(_vm, this, which); + break; case 1700: setGlobalVar(0x91080831, 0x04212331); _childObject = new Module1700(_vm, this, which); @@ -379,6 +385,15 @@ void GameModule::updateModule() { case 1500: createModule(1000, 0); break; + case 1600: + if (_moduleResult == 1) { + createModule(1400, 0); + } else if (_moduleResult == 2) { + createModule(1700, 0); + } else { + createModule(2100, 0); + } + break; case 1700: if (_moduleResult == 1) { createModule(2900, 3); diff --git a/engines/neverhood/klayman.cpp b/engines/neverhood/klayman.cpp index 4916056ab0..27ef84acb2 100644 --- a/engines/neverhood/klayman.cpp +++ b/engines/neverhood/klayman.cpp @@ -282,7 +282,7 @@ void Klayman::sub421350() { SetMessageHandler(&Klayman::handleMessage41D360); _counter3 = 0; _counterMax = 8; - _counter3Max = _vm->_rnd->getRandomNumber(64) + 24; + _counter3Max = _vm->_rnd->getRandomNumber(64 - 1) + 24; } void Klayman::update41D1C0() { @@ -3719,6 +3719,93 @@ uint32 KmScene1404::xHandleMessage(int messageNum, const MessageParam ¶m) { return 0; } +KmScene1608::KmScene1608(NeverhoodEngine *vm, Entity *parentScene, int16 x, int16 y) + : Klayman(vm, parentScene, x, y, 1000, 1000), _flag1(false) { +} + +uint32 KmScene1608::xHandleMessage(int messageNum, const MessageParam ¶m) { + switch (messageNum) { + case 0x2032: + _flag1 = param.asInteger() != 0; + break; + case 0x4001: + case 0x4800: + sub41C930(param.asPoint().x, false); + break; + case 0x4004: + if (_flag1) + setCallback2(AnimationCallback(&Klayman::sub421350)); + else + setCallback2(AnimationCallback(&Klayman::sub41FC80)); + break; + case 0x4812: + if (param.asInteger() == 2) { + setCallback2(AnimationCallback(&Klayman::sub420060)); + } else if (param.asInteger() == 1) { + setCallback2(AnimationCallback(&Klayman::sub41FFF0)); + } else { + setCallback2(AnimationCallback(&Klayman::sub41FF80)); + } + break; + case 0x4817: + setDoDeltaX(param.asInteger()); + sub41C7B0(); + break; + case 0x481B: + if (param.asPoint().y != 0) { + sub41CC40(param.asPoint().y, param.asPoint().x); + } else { + sub41CCE0(param.asPoint().x); + } + break; + case 0x481D: + if (_flag1) + setCallback2(AnimationCallback(&Klayman::sub4214D0)); + break; + case 0x481E: + if (_flag) + setCallback2(AnimationCallback(&Klayman::sub421510)); + break; + case 0x481F: + if (param.asInteger() == 1) { + setCallback2(AnimationCallback(&Klayman::sub4208B0)); + } else if (param.asInteger() == 0) { + setCallback2(AnimationCallback(&Klayman::sub420870)); + } else if (param.asInteger() == 4) { + setCallback2(AnimationCallback(&Klayman::sub420930)); + } else if (param.asInteger() == 3) { + setCallback2(AnimationCallback(&Klayman::sub4208F0)); + } else { + setCallback2(AnimationCallback(&Klayman::sub420830)); + } + break; + case 0x482D: + setDoDeltaX(_x > (int16)param.asInteger() ? 1 : 0); + sub41C7B0(); + break; + case 0x4834: + setCallback2(AnimationCallback(&Klayman::sub421160)); + break; + case 0x4835: + sendMessage(_parentScene, 0x2032, 1); + _flag1 = true; + setCallback2(AnimationCallback(&Klayman::sub4212C0)); + break; + case 0x4836: + sendMessage(_parentScene, 0x2032, 0); + _flag1 = false; + setCallback2(AnimationCallback(&Klayman::sub421310)); + break; + case 0x483F: + sub41CD00(param.asInteger()); + break; + case 0x4840: + sub41CD70(param.asInteger()); + break; + } + return 0; +} + // KmScene1705 KmScene1705::KmScene1705(NeverhoodEngine *vm, Entity *parentScene, int16 x, int16 y) diff --git a/engines/neverhood/klayman.h b/engines/neverhood/klayman.h index 7b3530c93d..84cb05acf5 100644 --- a/engines/neverhood/klayman.h +++ b/engines/neverhood/klayman.h @@ -413,6 +413,14 @@ protected: uint32 xHandleMessage(int messageNum, const MessageParam ¶m); }; +class KmScene1608 : public Klayman { +public: + KmScene1608(NeverhoodEngine *vm, Entity *parentScene, int16 x, int16 y); +protected: + bool _flag1; + uint32 xHandleMessage(int messageNum, const MessageParam ¶m); +}; + class KmScene1705 : public Klayman { public: KmScene1705(NeverhoodEngine *vm, Entity *parentScene, int16 x, int16 y); diff --git a/engines/neverhood/module.cpp b/engines/neverhood/module.cpp index 79197ed04b..5be9a6321f 100644 --- a/engines/neverhood/module.cpp +++ b/engines/neverhood/module.cpp @@ -110,4 +110,8 @@ bool Module::updateChild() { return true; } +void Module::leaveModule(uint32 result) { + sendMessage(_parentModule, 0x1009, result); +} + } // End of namespace Neverhood diff --git a/engines/neverhood/module.h b/engines/neverhood/module.h index 2f6ce69d3a..57a42c623b 100644 --- a/engines/neverhood/module.h +++ b/engines/neverhood/module.h @@ -62,6 +62,7 @@ protected: void createSmackerScene(uint32 fileHash, bool doubleSurface, bool flag1, bool canAbort); void createSmackerScene(const uint32 *fileHashList, bool doubleSurface, bool flag1, bool canAbort); bool updateChild(); + void leaveModule(uint32 result); }; } // End of namespace Neverhood diff --git a/engines/neverhood/module.mk b/engines/neverhood/module.mk index bbbbb02c01..5a597fb3e2 100644 --- a/engines/neverhood/module.mk +++ b/engines/neverhood/module.mk @@ -17,6 +17,7 @@ MODULE_OBJS = \ module1300.o \ module1400.o \ module1500.o \ + module1600.o \ module1700.o \ module1800.o \ module2000.o \ diff --git a/engines/neverhood/module1600.cpp b/engines/neverhood/module1600.cpp new file mode 100644 index 0000000000..a23e7101b4 --- /dev/null +++ b/engines/neverhood/module1600.cpp @@ -0,0 +1,1387 @@ +/* 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/module1600.h" +#include "neverhood/gamemodule.h" +#include "neverhood/module1200.h" +#include "neverhood/module2200.h" + +namespace Neverhood { + +Module1600::Module1600(NeverhoodEngine *vm, Module *parentModule, int which) + : Module(vm, parentModule) { + + if (which < 0) { + createScene(_vm->gameState().sceneNum, -1); + } else if (which == 1) { + createScene(4, 1); + } else if (which == 2) { + createScene(5, 0); + } else if (which == 3) { + createScene(6, 1); + } else if (which == 4) { + createScene(1, 0); + } else { + createScene(0, 0); + } + + // TODO Sound1ChList_addSoundResources(0x1A008D8, dword_4B3BB0, true); + // TODO Sound1ChList_setSoundValuesMulti(dword_4B3BB0, true, 50, 600, 5, 150); + // TODO Sound1ChList_sub_407C70(0x1A008D8, 0x41861371, 0x43A2507F, 0); + +} + +Module1600::~Module1600() { + // TODO Sound1ChList_sub_407A50(0x1A008D8); +} + +void Module1600::createScene(int sceneNum, int which) { + debug("Module1600::createScene(%d, %d)", sceneNum, which); + _vm->gameState().sceneNum = sceneNum; + switch (_vm->gameState().sceneNum) { + case 0: + createNavigationScene(0x004B39D0, which); + break; + case 1: + createNavigationScene(0x004B3A30, which); + break; + case 2: + createNavigationScene(0x004B3A60, which); + break; + case 3: + createNavigationScene(0x004B3A90, which); + break; + case 4: + createNavigationScene(0x004B3B20, which); + break; + case 5: + createNavigationScene(0x004B3B50, which); + break; + case 6: + createNavigationScene(0x004B3B80, which); + break; + case 7: + _childObject = new Scene1608(_vm, this, which); + break; + case 8: +//TODO _childObject = new Scene1609(_vm, this, which); + break; + case 1001: + if (getGlobalVar(0xA0808898) == 1) { + createSmackerScene(0x80050200, true, true, false); + } else if (getGlobalVar(0xA0808898) == 2) { + createSmackerScene(0x80090200, true, true, false); + } else { + createSmackerScene(0x80000200, true, true, false); + } + if (getGlobalVar(0xA0808898) >= 2) + setGlobalVar(0xA0808898, 0); + else + incGlobalVar(0xA0808898, +1); + break; + } + SetUpdateHandler(&Module1600::updateScene); + _childObject->handleUpdate(); +} + +void Module1600::updateScene() { + if (!updateChild()) { + switch (_vm->gameState().sceneNum) { + case 0: + if (_moduleResult == 0) + createScene(2, 0); + else if (_moduleResult == 1) + createScene(1, 0); + else if (_moduleResult == 2) + leaveModule(4); + break; + case 1: + if (_moduleResult == 0) + createScene(1001, -1); + else if (_moduleResult == 1) + createScene(0, 3); + break; + case 2: + if (_moduleResult == 0) + createScene(3, 0); + else if (_moduleResult == 1) + createScene(0, 2); + break; + case 3: + if (_moduleResult == 0) + createScene(5, 0); + else if (_moduleResult == 2) + createScene(6, 0); + else if (_moduleResult == 3) + createScene(2, 1); + else if (_moduleResult == 4) + createScene(4, 0); + break; + case 4: + if (_moduleResult == 0) + leaveModule(1); + else if (_moduleResult == 1) + createScene(3, 1); + break; + case 5: + if (_moduleResult == 0) + leaveModule(2); + else if (_moduleResult == 1) + createScene(3, 3); + break; + case 6: + if (_moduleResult == 0) + createScene(8, -1); + else if (_moduleResult == 1) + createScene(3, 5); + break; + case 7: + createScene(6, 1); + break; + case 8: + if (_moduleResult == 0) + createScene(6, 0); + else + createScene(7, 0); + break; + case 1001: + createScene(1, 0); + break; + } + } +} + +Class521::Class521(NeverhoodEngine *vm, Scene *parentScene, int16 x, int16 y) + : AnimatedSprite(vm, 1000), _parentScene(parentScene) { + + SetUpdateHandler(&Class521::update); + SetMessageHandler(&Class521::handleMessage); + SetSpriteCallback(NULL); + + // TODO createSurface2(200, dword_4AF4C0); + createSurface(200, 640, 480); //TODO: Remove once the line above is done + _x = x; + _y = y; + + _field100 = 0; + _exitDirection = 0; + _currPointIndex = 0; + _againDestPtFlag = 0; + _stepError = 0; + _againDestPointFlag = 0; + _steps = 0; + _flag10E = 0; + _moreY = 0; + _flag10F = 0; + _flag113 = 0; + _flag114 = 1; + _flag11A = 0; + _newDeltaXType = -1; + _field11E = 0; + _pathPoints = NULL; + _rectList = NULL; + + setFileHash(0xD4220027, 0, -1); + setDoDeltaX(getGlobalVar(0x21E60190)); + +} + +Class521::~Class521() { + if (_callback1Cb == AnimationCallback(&Class521::sub45D620)) { + setGlobalVar(0x21E60190, !getGlobalVar(0x21E60190)); + } +} + +void Class521::setPathPoints(NPointArray *pathPoints) { + _pathPoints = pathPoints; +} + +void Class521::update() { + if (_newDeltaXType >= 0) { + setDoDeltaX(_newDeltaXType); + _newDeltaXType = -1; + } + AnimatedSprite::update(); + if (_againDestPtFlag && _moreY == 0 && !_flag10F) { + _againDestPtFlag = 0; + _againDestPointFlag = 0; + sendPointMessage(this, 0x2004, _againDestPt); + } else if (_againDestPointFlag && _moreY == 0 && !_flag10F) { + _againDestPointFlag = 0; + sendMessage(this, 0x2003, _againDestPointIndex); + } + sub45CE10(); + sub45E0A0(); +} + +void Class521::update45C790() { + Class521::update(); + if (++_idleCounter >= _idleCounterMax) + sub45D050(); + sub45E0A0(); +} + +uint32 Class521::handleMessage(int messageNum, const MessageParam ¶m, Entity *sender) { + uint32 messageResult = Sprite::handleMessage(messageNum, param, sender); + switch (messageNum) { + case 0x1019: + SetSpriteCallback(NULL); + break; + /* NOTE: Implemented in setPathPoints + case 0x2000: + case 0x2001: + */ + 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 (_moreY <= 0 && !_flag10F) { + _someX = pathPoint(newPointIndex).x; + _someY = pathPoint(newPointIndex).y; + if (_currPointIndex < newPointIndex) { + moveToNextPoint(); + } else if (_currPointIndex == newPointIndex && _stepError == 0) { + if (_currPointIndex == 0) { + _moreY = 0; + sendMessage(_parentScene, 0x2005, 0); + } else if (_currPointIndex == (int)_pathPoints->size()) { + _moreY = 0; + sendMessage(_parentScene, 0x2006, 0); + } + } else { + moveToPrevPoint(); + } + } else { + _againDestPointFlag = 1; + _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 (_moreY <= 0 && !_flag10F) { + // 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; + _someX = pt.x; + _someY = pt.y; + minMatchDistance = calcDistance(_someX, _someY, _x, _y) + 1; + for (int i = _currPointIndex + 1; i < (int)_pathPoints->size(); i++) { + distance = calcDistance(_someX, _someY, pathPoint(i).x, pathPoint(i).y); + if (distance >= minMatchDistance) + break; + minMatchDistance = distance; + minMatchIndex = i; + } + for (int i = _currPointIndex; i >= 0; i--) { + distance = calcDistance(_someX, _someY, pathPoint(i).x, pathPoint(i).y); + if (distance >= minMatchDistance) + break; + minMatchDistance = distance; + minMatchIndex = i; + } + if (minMatchIndex == -1) { + if (_currPointIndex == 0) { + moveToPrevPoint(); + } else { + SetSpriteCallback(NULL); + } + } else { + if (minMatchIndex > _currPointIndex) { + moveToNextPoint(); + } else { + moveToPrevPoint(); + } + } + } else { + _againDestPtFlag = 1; + _againDestPt = pt; + } + } + break; + case 0x2007: + _moreY = param.asInteger(); + _steps = 0; + _flag10E = 0; + SetSpriteCallback(&Class521::suMoveToPrevPoint); + _lastDistance = 640; + break; + case 0x2008: + _moreY = param.asInteger(); + _steps = 0; + _flag10E = 0; + SetSpriteCallback(&Class521::suMoveToNextPoint); + _lastDistance = 640; + break; + case 0x2009: + sub45CF80(); + break; + case 0x200A: + sub45CFB0(); + break; + /* NOTE: Implemented in setRectList + case 0x200B: + case 0x200C: + */ + case 0x200E: + sub45D180(); + break; + case 0x200F: + sub45CD00(); + _newDeltaXType = param.asInteger(); + break; + } + return messageResult; +} + +uint32 Class521::handleMessage45CC30(int messageNum, const MessageParam ¶m, Entity *sender) { + uint32 messageResult = Class521::handleMessage(messageNum, param, sender); + switch (messageNum) { + case 0x100D: + if (_flag10F && param.asInteger() == 0x025424A2) { + removeCallbacks(); + } + break; + case 0x3002: + removeCallbacks(); + break; + } + return messageResult; +} + +uint32 Class521::handleMessage45CCA0(int messageNum, const MessageParam ¶m, Entity *sender) { + switch (messageNum) { + case 0x2009: + sub45CF80(); + break; + case 0x3002: + sendMessage(_parentScene, 0x200A, 0); + SetMessageHandler(&Class521::handleMessage); + break; + } + return 0; +} + +void Class521::sub45CD00() { + bool doDeltaX = _doDeltaX; + SetSpriteCallback(NULL); + _againDestPtFlag = 0; + _againDestPointFlag = 0; + _flag10E = 0; + _flag10F = 0; + _flag113 = 0; + _flag114 = 0; + _flag11A = 0; + _rectList = NULL; + SetMessageHandler(&Class521::handleMessage45CC30); + SetAnimationCallback3(&Class521::sub45CFE0); + setFileHash(0x35698F78, 0, -1); + SetMessageHandler(&Class521::handleMessage45CC30); + SetUpdateHandler(&Class521::update45C790); + setCallback1(AnimationCallback(&Class521::sub45D040)); + setDoDeltaX(doDeltaX ? 1 : 0); + _currMoveDirection = 0; + _newMoveDirection = 0; + _steps = 0; + _idleCounter = 0; + _idleCounterMax = _vm->_rnd->getRandomNumber(64 - 1) + 24; +} + +void Class521::sub45CDC0() { + if (_value112 == 1) { + _lastDistance = 640; + _flag113 = 0; + _flag10E = 0; + SetSpriteCallback(&Class521::suMoveToNextPoint); + } else if (_value112 == 2) { + _lastDistance = 640; + _flag113 = 0; + _flag10E = 0; + SetSpriteCallback(&Class521::suMoveToPrevPoint); + } +} + +void Class521::sub45CE10() { + if (_flag10E && !_flag113 && !_flag10F) { + removeCallbacks(); + _flag114 = 0; + _flag113 = 1; + setFileHash(0x192ADD30, 0, -1); + SetMessageHandler(&Class521::handleMessage45CC30); + SetUpdateHandler(&Class521::update); + SetAnimationCallback3(&Class521::sub45CFE0); + } else if (!_flag10E && _steps && _flag113) { + removeCallbacks(); + _flag113 = 0; + setFileHash(0x9966B138, 0, -1); + SetMessageHandler(&Class521::handleMessage45CC30); + SetUpdateHandler(&Class521::update); + SetAnimationCallback3(&Class521::sub45D100); + } else { + bool flag = false; + uint index = 0; + if (_rectList && _rectList->size() > 0) { + while (index < _rectList->size()) { + NRect r = (*_rectList)[index]; + if (_x >= r.x1 && _x <= r.x2 && _y >= r.y1 && _y <= r.y2) + break; + } + if (index < _rectList->size() && !_flag11A) + flag = true; + _flag11A = index < _rectList->size(); + } + if (flag) { + removeCallbacks(); + sub45D0A0(); + } else if (_newMoveDirection != _currMoveDirection && _flag114 && !_flag10F) { + removeCallbacks(); + _currMoveDirection = _newMoveDirection; + sub45D100(); + } + } +} + +void Class521::sub45CF80() { + setFileHash(0xA86A9538, 0, -1); + SetMessageHandler(&Class521::handleMessage45CC30); + SetUpdateHandler(&Class521::update); + SetAnimationCallback3(&Class521::sub45CFE0); +} + +void Class521::sub45CFB0() { + setFileHash(0xA86A9538, -1, -1); + _playBackwards = true; + SetMessageHandler(&Class521::handleMessage45CCA0); + SetUpdateHandler(&Class521::update); +} + +void Class521::sub45CFE0() { + setFileHash(0x35698F78, 0, -1); + SetMessageHandler(&Class521::handleMessage); + SetUpdateHandler(&Class521::update45C790); + setCallback1(AnimationCallback(&Class521::sub45D040)); + _idleCounter = 0; + _currMoveDirection = 0; + _newMoveDirection = 0; + _steps = 0; + _idleCounterMax = _vm->_rnd->getRandomNumber(64 - 1) + 24; +} + +void Class521::sub45D040() { + SetUpdateHandler(&Class521::update); +} + +void Class521::sub45D050() { + setFileHash(0xB579A77C, 0, -1); + SetMessageHandler(&Class521::handleMessage45CC30); + SetUpdateHandler(&Class521::update); + SetAnimationCallback3(&Class521::sub45CFE0); + _idleCounter = 0; + _idleCounterMax = _vm->_rnd->getRandomNumber(64 - 1) + 24; +} + +void Class521::sub45D0A0() { + _flag10F = 1; + removeCallbacks(); + setFileHash(0x9C220DA4, 0, -1); + SetMessageHandler(&Class521::handleMessage45CC30); + SetUpdateHandler(&Class521::update); + setCallback1(AnimationCallback(&Class521::sub45D0E0)); +} + +void Class521::sub45D0E0() { + _flag10F = 0; + _newMoveDirection = 0; + sub45D100(); +} + +void Class521::sub45D100() { + _flag114 = 1; + if (_currMoveDirection == 1) { + setFileHash(0xD4AA03A4, 0, -1); + } else if (_currMoveDirection == 3) { + setFileHash(0xD00A1364, 0, -1); + } else if ((_currMoveDirection == 2 && _doDeltaX) || (_currMoveDirection == 4 && !_doDeltaX)) { + sub45D180(); + } else { + setFileHash(0xD4220027, 0, -1); + } + setGlobalVar(0x21E60190, _doDeltaX ? 1 : 0); +} + +void Class521::sub45D180() { + _flag10F = 1; + removeCallbacks(); + setFileHash(0xF46A0324, 0, -1); + _value112 = 0; + SetMessageHandler(&Class521::handleMessage45CC30); + SetUpdateHandler(&Class521::update); + setCallback1(AnimationCallback(&Class521::sub45D620)); + sub45CDC0(); +} + +void Class521::moveToNextPoint() { + if (_currPointIndex >= (int)_pathPoints->size() - 1) { + _moreY = 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) && nextPt.x >= currPt.x && + (_currMoveDirection == 4 || _currMoveDirection == 2)) { + if (_currMoveDirection == 4) + _currMoveDirection = 2; + else if (_currMoveDirection == 2) + _currMoveDirection = 4; + if (_flag113) + sub45D390(); + else + sub45D350(); + } else { + if (_steps == 0) { + removeCallbacks(); + _flag113 = 0; + setFileHash(0x9966B138, 0, -1); + SetMessageHandler(&Class521::handleMessage45CC30); + SetUpdateHandler(&Class521::update); + SetAnimationCallback3(&Class521::sub45D100); + } + _flag10E = 0; + SetSpriteCallback(&Class521::suMoveToNextPoint); + _lastDistance = 640; + } + } +} + +void Class521::sub45D350() { + removeCallbacks(); + _flag10F = 1; + _flag10E = 1; + setFileHash(0x192ADD30, 0, -1); + SetMessageHandler(&Class521::handleMessage45CC30); + SetUpdateHandler(&Class521::update); + SetAnimationCallback3(&Class521::sub45D390); +} + +void Class521::sub45D390() { + removeCallbacks(); + _flag10F = 1; + setFileHash(0xF46A0324, 0, -1); + SetMessageHandler(&Class521::handleMessage45CC30); + SetUpdateHandler(&Class521::update); + setCallback1(AnimationCallback(&Class521::sub45D620)); + _value112 = 1; + sub45CDC0(); +} + +void Class521::moveToPrevPoint() { + if (_currPointIndex == 0 && _stepError == 0) { + _moreY = 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) && currPt.x >= prevPt.x && + (_currMoveDirection == 2 || _currMoveDirection == 4)) { + if (_currMoveDirection == 2) + _currMoveDirection = 4; + else if (_currMoveDirection == 4) + _currMoveDirection = 2; + if (_flag113) + sub45D5D0(); + else + sub45D580(); + } else { + if (_steps == 0) { + removeCallbacks(); + _flag113 = 0; + setFileHash(0x9966B138, 0, -1); + SetMessageHandler(&Class521::handleMessage45CC30); + SetUpdateHandler(&Class521::update); + SetAnimationCallback3(&Class521::sub45D100); + } + _flag10E = 0; + SetSpriteCallback(&Class521::suMoveToPrevPoint); + _lastDistance = 640; + } + } +} + +void Class521::sub45D580() { + _flag10F = 1; + _flag10E = 1; + setCallback1(NULL); + setFileHash(0x192ADD30, 0, -1); + SetMessageHandler(&Class521::handleMessage45CC30); + SetUpdateHandler(&Class521::update); + SetAnimationCallback3(&Class521::sub45D5D0); +} + +void Class521::sub45D5D0() { + _flag10F = 1; + setCallback1(NULL); + setFileHash(0xF46A0324, 0, -1); + SetMessageHandler(&Class521::handleMessage45CC30); + SetUpdateHandler(&Class521::update); + setCallback1(AnimationCallback(&Class521::sub45D620)); + _value112 = 2; + sub45CDC0(); +} + +void Class521::sub45D620() { + _flag10F = 0; + _newMoveDirection = 0; + setDoDeltaX(2); + sub45D100(); +} + +void Class521::suMoveToNextPoint() { + int16 newX = _x, newY = _y; + + if (_currPointIndex >= (int)_pathPoints->size()) { + _moreY = 0; + sendMessage(this, 0x1019, 0); + sendMessage(_parentScene, 0x2006, 0); + return; + } + + if (_flag10E) { + if (_steps <= 0) { + sendMessage(this, 0x1019, 0); + return; + } else { + _steps--; + } + } else if (_steps < 11) { + _steps++; + } + + bool firstTime = true; + _anotherY = _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; + } + _anotherY = 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 (_moreY != 0) { + _x = newX; + _y = newY; + _moreY -= _anotherY; + if (_moreY <= 0) { + _flag10E = 1; + _moreY = 0; + } + } else { + int distance = calcDistance(_someX, _someY, _x, _y); + _x = newX; + _y = newY; + if (newX > 20 && newX < 620 && newY > 20 && newY < 460) { + _exitDirection = 0; + _field100 = 1; + } else if (_field100) { + _someX = pathPoint(_pathPoints->size() - 1).x; + _someY = pathPoint(_pathPoints->size() - 1).y; + _field100 = 0; + 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 && _flag10E) { + _flag10E = 0; + _steps = 11; + } + } + if ((distance < 20 && _exitDirection == 0 && _lastDistance < distance) || + (_exitDirection == 0 && _lastDistance + 20 < distance)) + _flag10E = 1; + if (distance < _lastDistance) + _lastDistance = distance; + if (_currPointIndex == (int)_pathPoints->size() - 1) { + _flag10E = 1; + _moreY = 0; + sendMessage(this, 0x1019, 0); + sendMessage(_parentScene, 0x2006, 0); + } + } + +} + +void Class521::suMoveToPrevPoint() { + int16 newX = _x, newY = _y; + + if (_currPointIndex == 0 && _stepError == 0) { + _moreY = 0; + sendMessage(this, 0x1019, 0); + sendMessage(_parentScene, 0x2005, 0); + return; + } + + if (_flag10E) { + if (_steps <= 0) { + sendMessage(this, 0x1019, 0); + return; + } else { + _steps--; + } + } else if (_steps < 11) { + _steps++; + } + + bool firstTime = true; + _anotherY = _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; + } + _anotherY = 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 (_moreY != 0) { + _x = newX; + _y = newY; + _moreY -= _anotherY; + if (_moreY <= 0) { + _flag10E = 1; + _moreY = 0; + } + } else { + int distance = calcDistance(_someX, _someY, _x, _y); + _x = newX; + _y = newY; + if (newX > 20 && newX < 620 && newY > 20 && newY < 460) { + _exitDirection = 0; + _field100 = 1; + } else if (_field100) { + _someX = pathPoint(0).x; + _someY = pathPoint(0).y; + _field100 = 0; + 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 && _flag10E) { + _flag10E = 0; + _steps = 11; + } + } + if ((distance < 20 && _exitDirection == 0 && _lastDistance < distance) || + (_exitDirection == 0 && _lastDistance + 20 < distance)) + _flag10E = 1; + if (distance < _lastDistance) + _lastDistance = distance; + if (_currPointIndex == 0 && _stepError == 0) { + _flag10E = 1; + _moreY = 0; + sendMessage(this, 0x1019, 0); + sendMessage(_parentScene, 0x2005, 0); + } + } + +} + +void Class521::sub45E0A0() { + // TODO +} + +int Class521::calcDistance(int16 x1, int16 y1, int16 x2, int16 y2) { + int16 deltaX = ABS(x1 - x2); + int16 deltaY = ABS(y1 - y2); + return sqrt(deltaX * deltaX + deltaY * deltaY); +} + +Class546::Class546(NeverhoodEngine *vm, Scene *parentScene) + : AnimatedSprite(vm, 0x08C80144, 900, 320, 240), _soundResource(vm), + _parentScene(parentScene) { + + setVisible(false); + SetMessageHandler(&Class546::handleMessage); + setFileHash1(); +} + +uint32 Class546::handleMessage(int messageNum, const MessageParam ¶m, Entity *sender) { + uint32 messageResult = Sprite::handleMessage(messageNum, param, sender); + switch (messageNum) { + case 0x3002: + removeCallbacks(); + break; + case 0x4808: + sub44D710(); + break; + case 0x4809: + sub44D790(); + break; + } + return messageResult; +} + +void Class546::sub44D710() { + setFileHash(0x08C80144, 0, -1); + setVisible(true); + SetAnimationCallback3(&Class546::sub44D760); + _soundResource.play(calcHash("fxDoorOpen23")); +} + +void Class546::sub44D760() { + sendMessage(_parentScene, 0x2033, 0); + setFileHash1(); + setVisible(false); +} + +void Class546::sub44D790() { + setFileHash(0x08C80144, -1, -1); + setVisible(true); + SetAnimationCallback3(&Class546::sub44D7F0); + _soundResource.play(calcHash("fxDoorClose23")); +} + +void Class546::sub44D7F0() { + sendMessage(_parentScene, 0x2034, 0); + setFileHash1(); +} + +Class547::Class547(NeverhoodEngine *vm, int16 x, int16 y) + : AnimatedSprite(vm, 0x1209E09F, 1100, x, y) { + + setDoDeltaX(1); + setFileHash(0x1209E09F, 1, -1); + _newHashListIndex = 1; +} + +Class548::Class548(NeverhoodEngine *vm, int16 x, int16 y) + : AnimatedSprite(vm, 0x1209E09F, 100, x, y) { + + setDoDeltaX(1); + _newHashListIndex = 0; +} + +Class518::Class518(NeverhoodEngine *vm, Class521 *class521) + : AnimatedSprite(vm, 1100), _class521(class521) { + + SetUpdateHandler(&Class518::update); + createSurface1(0x60281C10, 150); + setFileHash(0x60281C10, -1, -1); + _newHashListIndex = -2; +} + +void Class518::update() { + _x = _class521->getX(); + _y = _class521->getY(); + AnimatedSprite::update(); +} + +Scene1608::Scene1608(NeverhoodEngine *vm, Module *parentModule, int which) + : Scene(vm, parentModule, true), _class521(NULL), _countdown1(0) { + + setGlobalVar(0x21E60190, 1); + + _surfaceFlag = true; + SetMessageHandler(&Scene1608::handleMessage44D2A0); + + _class545 = insertSprite<Class545>(this, 1, 1100, 198, 220); + _vm->_collisionMan->addSprite(_class545); + + if (which < 0) { + if (_vm->gameState().which == 1) + which = 1; + else { + setRectList(0x004B47D0); + insertKlayman<KmScene1608>(380, 438); + _klayman2 = _klayman; + _flag4 = false; + _class546 = insertSprite<Class546>(this); + _sprite1 = insertStaticSprite(0x7D0404E8, 1100); + setMessageList(0x004B46A8); + setBackground(0x10080E01); + setPalette(0x10080E01); + _asTape = insertSprite<AsScene1201Tape>(this, 13, 1100, 412, 443, 0x9148A011); + _vm->_collisionMan->addSprite(_asTape); + _klayman->setClipRect(_sprite1->getDrawRect().x, 0, 640, 480); + SetUpdateHandler(&Scene1608::update44CE90); + insertMouse433(0x80E05108); + insertStaticSprite(0x4B18F868, 1200); + } + } else if (which == 0) { + _vm->gameState().which = 0; + setRectList(0x004B47D0); + insertKlayman<KmScene1608>(0, 438); + _klayman2 = _klayman; + _flag4 = false; + setMessageList(0x004B46B0); + setBackground(0x10080E01); + setPalette(0x10080E01); + _asTape = insertSprite<AsScene1201Tape>(this, 13, 1100, 412, 443, 0x9148A011); + _vm->_collisionMan->addSprite(_asTape); + insertMouse433(0x80E05108); + _sprite1 = insertStaticSprite(0x7D0404E8, 1100); + _class546 = insertSprite<Class546>(this); + _klayman->setClipRect(_sprite1->getDrawRect().x, 0, 640, 480); + SetUpdateHandler(&Scene1608::update44CE90); + sendMessage(_class546, 0x4808, 0); + insertStaticSprite(0x4B18F868, 1200); + } else if (which == 2) { + _vm->gameState().which = 1; + _dataResource.load(0x003C0492); + _roomPathPoints = _dataResource.getPointArray(calcHash("meArchroArchRoomPath")); + setBackground(0x98001604); + setPalette(0x98001604); + _palette->addPalette("paPodRed", 65, 31, 65); + insertMouse433(0x01600988); + _sprite2 = insertStaticSprite(0x491F38A8, 1100); + _class521 = createSprite<Class521>(this, 375, 227); // Create but don't add to the sprite list yet + _class547 = insertSprite<Class547>(375, 227); + _class548 = insertSprite<Class548>(375, 227); + _class521->setVisible(false); + if (getGlobalVar(0xC0418A02)) { + insertKlayman<KmScene1608>(373, 220); + _klayman->setDoDeltaX(1); + } else { + insertKlayman<KmScene1608>(283, 220); + } + _klayman2 = _klayman; + setMessageList(0x004B47A8); + SetMessageHandler(&Scene1608::handleMessage44D3C0); + SetUpdateHandler(&Scene1608::update44CED0); + // NOTE: Setting the point array was handled by messages 0x2000 (array) and 0x2001 (count) in the original + _class521->setPathPoints(_roomPathPoints); + sendMessage(_class521, 0x2002, _roomPathPoints->size() - 1); + _sprite3 = insertStaticSprite(0xB47026B0, 1100); + _rect1.set(_sprite3->getDrawRect().x, _sprite3->getDrawRect().y, 640, _sprite2->getDrawRect().y2()); + _rect3.set(_sprite2->getDrawRect().x, _sprite3->getDrawRect().y, 640, _sprite2->getDrawRect().y2()); + _rect2 = _rect1; + _rect2.y2 = 215; + _klayman->setClipRect(_rect1); + _class521->setClipRect(_rect1); + _class547->setClipRect(_rect1); + _class548->setClipRect(_rect1); + _asTape = insertSprite<AsScene1201Tape>(this, 13, 1100, 412, 443, 0x9148A011); + _vm->_collisionMan->addSprite(_asTape); + insertSprite<Class518>(_class521)->setClipRect(_rect1); + _flag4 = false; + _flag2 = false; + _flag1 = 0; + setRectList(0x004B4810); + } + + // NOTE: Not in the else because 'which' is set to 1 in the true branch + if (which == 1) { + _vm->gameState().which = 1; + _dataResource.load(0x003C0492); + _roomPathPoints = _dataResource.getPointArray(calcHash("meArchroArchRoomPath")); + setBackground(0x98001604); + setPalette(0x98001604); + _palette->addPalette("paPodRed", 65, 31, 65); + insertMouse433(0x01600988); + _class521 = insertSprite<Class521>(this, 375, 227); + _class547 = insertSprite<Class547>(375, 227); + _class548 = insertSprite<Class548>(375, 227); + _sprite2 = insertStaticSprite(0x491F38A8, 1100); + _klayman2 = createSprite<KmScene1608>(this, 439, 220); // Special Klayman handling... + sendMessage(_klayman2, 0x2032, 1); + _klayman2->setDoDeltaX(1); + SetMessageHandler(&Scene1608::handleMessage44D470); + SetUpdateHandler(&Scene1608::update44D1E0); + _class547->setVisible(false); + _class548->setVisible(false); + // NOTE: Setting the point array was handled by messages 0x2000 (array) and 0x2001 (count) in the original + _class521->setPathPoints(_roomPathPoints); + sendMessage(_class521, 0x2002, 0); + sendMessage(_class521, 0x2008, 90); + _sprite3 = insertStaticSprite(0xB47026B0, 1100); + _rect1.set(_sprite3->getDrawRect().x, _sprite3->getDrawRect().y, 640, _sprite2->getDrawRect().y2()); + _rect3.set(_sprite2->getDrawRect().x, _sprite3->getDrawRect().y, 640, _sprite2->getDrawRect().y2()); + _rect2 = _rect1; + _rect2.y2 = 215; + _klayman2->setClipRect(_rect1); + _class521->setClipRect(_rect1); + _class547->setClipRect(_rect1); + _class548->setClipRect(_rect1); + _asTape = insertSprite<AsScene1201Tape>(this, 13, 1100, 412, 443, 0x9148A011); + // ... _vm->_collisionMan->addSprite(_asTape); + insertSprite<Class518>(_class521)->setClipRect(_rect1); + _flag4 = true; + _flag2 = true; + _flag1 = 0; + } + + _palette->addPalette("paKlayRed", 0, 64, 0); + +} + +Scene1608::~Scene1608() { + setGlobalVar(0xC0418A02, _klayman2->isDoDeltaX() ? 1 : 0); + // Weird + if (_flag4) { + delete _klayman2; + } else { + delete _class521; + } +} + +void Scene1608::update44CE90() { + Scene::update(); + if (_countdown1 != 0 && (--_countdown1 == 0)) { + leaveScene(0); + } +} + +void Scene1608::update44CED0() { + Scene::update(); + if (_flag1 == 1) { + removeSurface(_klayman->getSurface()); + removeEntity(_klayman); + addSprite(_class521); + _flag4 = true; + clearRectList(); + SetUpdateHandler(&Scene1608::update44CFE0); + SetMessageHandler(&Scene1608::handleMessage44D510); + _class547->setVisible(false); + _class548->setVisible(false); + _class521->setVisible(true); + sendMessage(_class521, 0x2009, 0); + _class521->handleUpdate(); + _klayman = NULL; + _flag1 = 0; + } + if (_klayman2->getX() <= 375) { + _klayman2->setClipRect(_rect1); + } else { + _klayman2->setClipRect(_rect2); + } +} + +void Scene1608::update44CFE0() { + Scene::update(); + if (_mouseClicked) { + if (_mouseClickPos.x <= 329 && _class521->getX() == 375 && _class521->getY() == 227) { + sendMessage(_class521, 0x200A, 0); + SetUpdateHandler(&Scene1608::update44D0C0); + } else { + sendPointMessage(_class521, 0x2004, _mouseClickPos); + SetMessageHandler(&Scene1608::handleMessage44D470); + SetUpdateHandler(&Scene1608::update44D1E0); + } + _mouseClicked = false; + } + if (_klayman2->getX() <= 375) { + _klayman2->setClipRect(_rect1); + } else { + _klayman2->setClipRect(_rect2); + } +} + +void Scene1608::update44D0C0() { + Scene::update(); + if (_flag1 == 2) { + _klayman = _klayman2; + removeSurface(_class521->getSurface()); + removeEntity(_class521); + addSprite(_klayman); + _flag4 = false; + SetMessageHandler(&Scene1608::handleMessage44D3C0); + SetUpdateHandler(&Scene1608::update44CED0); + setRectList(0x004B4810); + _class547->setVisible(true); + _class548->setVisible(true); + _class521->setVisible(false); + setMessageList(0x004B4748); + runMessageList(); + _klayman->handleUpdate(); + _flag1 = 0; + } + if (_klayman2->getX() <= 375) { + _klayman2->setClipRect(_rect1); + } else { + _klayman2->setClipRect(_rect2); + } +} + +void Scene1608::update44D1E0() { + Scene::update(); + if (_mouseClicked) { + sendPointMessage(_class521, 0x2004, _mouseClickPos); + _mouseClicked = false; + } + if (_class521->getX() < 300) { + if (_flag2) { + _flag2 = false; + _class521->setClipRect(_rect1); + if (!_class521->isDoDeltaX()) + sendMessage(_class521, 0x200E, 0); + } + } else if (!_flag2) { + _flag2 = true; + _class521->setClipRect(_rect3); + } +} + +uint32 Scene1608::handleMessage44D2A0(int messageNum, const MessageParam ¶m, Entity *sender) { + Scene::handleMessage(messageNum, param, sender); + switch (messageNum) { + case 0x100D: + if (param.asInteger() == 0x20250B1A) { + clearRectList(); + _klayman->setVisible(false); + showMouse(false); + _sprite1->setVisible(false); + sendMessage(_class546, 0x4809, 0); + _countdown1 = 28; + } + break; + case 0x200D: + sendMessage(_parentModule, 0x200D, 0); + break; + case 0x4826: + if (sender == _asTape) { + sendEntityMessage(_klayman2, 0x1014, _asTape); + setMessageList(0x004B4770); + } else if (sender == _class545) { + setMessageList(0x004B46C8); + } + break; + } + return 0; +} + +uint32 Scene1608::handleMessage44D3C0(int messageNum, const MessageParam ¶m, Entity *sender) { + Scene::handleMessage(messageNum, param, sender); + switch (messageNum) { + case 0x100D: + if (param.asInteger() == 0x60842040) { + _flag1 = true; + } + break; + case 0x200D: + sendMessage(_parentModule, 0x200D, 0); + break; + case 0x4826: + if (sender == _class545) { + sendEntityMessage(_klayman2, 0x1014, _class545); + setMessageList(0x004B4760); + } + break; + } + return 0; +} + +uint32 Scene1608::handleMessage44D470(int messageNum, const MessageParam ¶m, Entity *sender) { + Scene::handleMessage(messageNum, param, sender); + switch (messageNum) { + case 0x2005: + leaveScene(1); + break; + case 0x2006: + SetMessageHandler(&Scene1608::handleMessage44D510); + SetUpdateHandler(&Scene1608::update44CFE0); + sendMessage(_class521, 0x200F, 1); + break; + case 0x200D: + sendMessage(_parentModule, 0x200D, 0); + break; + } + return 0; +} + +uint32 Scene1608::handleMessage44D510(int messageNum, const MessageParam ¶m, Entity *sender) { + Scene::handleMessage(messageNum, param, sender); + switch (messageNum) { + case 0x200A: + _flag1 = 2; + break; + case 0x200D: + sendMessage(_parentModule, 0x200D, 0); + break; + } + return 0; +} + +} // End of namespace Neverhood diff --git a/engines/neverhood/module1600.h b/engines/neverhood/module1600.h new file mode 100644 index 0000000000..9af1a19b39 --- /dev/null +++ b/engines/neverhood/module1600.h @@ -0,0 +1,176 @@ +/* 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_MODULE1600_H +#define NEVERHOOD_MODULE1600_H + +#include "neverhood/neverhood.h" +#include "neverhood/module.h" +#include "neverhood/scene.h" + +namespace Neverhood { + +// Module1600 + +class Module1600 : public Module { +public: + Module1600(NeverhoodEngine *vm, Module *parentModule, int which); + virtual ~Module1600(); +protected: + void createScene(int sceneNum, int which); + void updateScene(); +}; + +class Class521 : public AnimatedSprite { +public: + Class521(NeverhoodEngine *vm, Scene *parentScene, int16 x, int16 y); + ~Class521(); + void setPathPoints(NPointArray *pathPoints); +protected: + Scene *_parentScene; + NPointArray *_pathPoints; + NRectArray *_rectList; + int _newMoveDirection; + int _currMoveDirection; + int _exitDirection; + int _currPointIndex; + NPoint _againDestPt; + int _againDestPtFlag; + int _steps; + int _stepError; + int _idleCounter; + int _idleCounterMax; + int _lastDistance; + int _field100; + int _againDestPointFlag; + int _flag10E; + int _moreY; + int _flag10F; + int _flag113; + int _flag114; + int _flag11A; + int _newDeltaXType; + int _field11E; + int _againDestPointIndex; + int _value112; + int _anotherY; + int16 _someX, _someY; + NPoint pathPoint(uint index) { return (*_pathPoints)[index]; } + void update(); + void update45C790(); + uint32 handleMessage(int messageNum, const MessageParam ¶m, Entity *sender); + uint32 handleMessage45CC30(int messageNum, const MessageParam ¶m, Entity *sender); + uint32 handleMessage45CCA0(int messageNum, const MessageParam ¶m, Entity *sender); + void sub45CD00(); + void sub45CDC0(); + void sub45CE10(); + void sub45CF80(); + void sub45CFB0(); + void sub45CFE0(); + void sub45D040(); + void sub45D050(); + void sub45D0A0(); + void sub45D0E0(); + void sub45D100(); + void sub45D180(); + void moveToNextPoint(); + void sub45D350(); + void sub45D390(); + void moveToPrevPoint(); + void sub45D580(); + void sub45D5D0(); + void sub45D620(); + void suMoveToNextPoint(); + void suMoveToPrevPoint(); + void sub45E0A0(); + int calcDistance(int16 x1, int16 y1, int16 x2, int16 y2); +}; + +class Class546 : public AnimatedSprite { +public: + Class546(NeverhoodEngine *vm, Scene *parentScene); +protected: + Scene *_parentScene; + SoundResource _soundResource; + uint32 handleMessage(int messageNum, const MessageParam ¶m, Entity *sender); + void sub44D710(); + void sub44D760(); + void sub44D790(); + void sub44D7F0(); +}; + +class Class547 : public AnimatedSprite { +public: + Class547(NeverhoodEngine *vm, int16 x, int16 y); +}; + +class Class548 : public AnimatedSprite { +public: + Class548(NeverhoodEngine *vm, int16 x, int16 y); +}; + +class Class518 : public AnimatedSprite { +public: + Class518(NeverhoodEngine *vm, Class521 *class521); +protected: + Class521 *_class521; + void update(); +}; + +class Scene1608 : public Scene { +public: + Scene1608(NeverhoodEngine *vm, Module *parentModule, int which); + ~Scene1608(); +protected: + Class521 *_class521; + Sprite *_class545; + Sprite *_class546; + Sprite *_class547; + Sprite *_class548; + Sprite *_sprite1; + Sprite *_sprite2; + Sprite *_sprite3; + Sprite *_asTape; + Klayman *_klayman2; + NRect _rect1; + NRect _rect2; + NRect _rect3; + int _flag1; + bool _flag2; + bool _flag3; + bool _flag4; + int _countdown1; + NPointArray *_roomPathPoints; + void update44CE90(); + void update44CED0(); + void update44CFE0(); + void update44D0C0(); + void update44D1E0(); + uint32 handleMessage44D2A0(int messageNum, const MessageParam ¶m, Entity *sender); + uint32 handleMessage44D3C0(int messageNum, const MessageParam ¶m, Entity *sender); + uint32 handleMessage44D470(int messageNum, const MessageParam ¶m, Entity *sender); + uint32 handleMessage44D510(int messageNum, const MessageParam ¶m, Entity *sender); +}; + +} // End of namespace Neverhood + +#endif /* NEVERHOOD_MODULE1600_H */ diff --git a/engines/neverhood/scene.cpp b/engines/neverhood/scene.cpp index 441ee1e291..9a588f283f 100644 --- a/engines/neverhood/scene.cpp +++ b/engines/neverhood/scene.cpp @@ -274,6 +274,10 @@ void Scene::update() { } +void Scene::leaveScene(uint32 result) { + sendMessage(_parentModule, 0x1009, result); +} + uint32 Scene::handleMessage(int messageNum, const MessageParam ¶m, Entity *sender) { switch (messageNum) { case 0: // mouse moved diff --git a/engines/neverhood/scene.h b/engines/neverhood/scene.h index 09d34b5734..e962266168 100644 --- a/engines/neverhood/scene.h +++ b/engines/neverhood/scene.h @@ -64,6 +64,7 @@ public: void changeMouseCursor(uint32 fileHash); SmackerPlayer *addSmackerPlayer(SmackerPlayer *smackerPlayer); void update(); + void leaveScene(uint32 result); // Some crazy templated functions to make the logic code smaller/simpler (imo!) // insertKlayman template<class T> @@ -123,6 +124,35 @@ public: T* insertSprite(Arg1 arg1, Arg2 arg2, Arg3 arg3, Arg4 arg4, Arg5 arg5, Arg6 arg6) { return (T*)addSprite(new T(_vm, arg1, arg2, arg3, arg4, arg5, arg6)); } + // createSprite + template<class T> + T* createSprite() { + return new T(_vm); + } + template<class T, class Arg1> + T* createSprite(Arg1 arg1) { + return new T(_vm, arg1); + } + template<class T, class Arg1, class Arg2> + T* createSprite(Arg1 arg1, Arg2 arg2) { + return new T(_vm, arg1, arg2); + } + template<class T, class Arg1, class Arg2, class Arg3> + T* createSprite(Arg1 arg1, Arg2 arg2, Arg3 arg3) { + return new T(_vm, arg1, arg2, arg3); + } + template<class T, class Arg1, class Arg2, class Arg3, class Arg4> + T* createSprite(Arg1 arg1, Arg2 arg2, Arg3 arg3, Arg4 arg4) { + return new T(_vm, arg1, arg2, arg3, arg4); + } + template<class T, class Arg1, class Arg2, class Arg3, class Arg4, class Arg5> + T* createSprite(Arg1 arg1, Arg2 arg2, Arg3 arg3, Arg4 arg4, Arg5 arg5) { + return new T(_vm, arg1, arg2, arg3, arg4, arg5); + } + template<class T, class Arg1, class Arg2, class Arg3, class Arg4, class Arg5, class Arg6> + T* createSprite(Arg1 arg1, Arg2 arg2, Arg3 arg3, Arg4 arg4, Arg5 arg5, Arg6 arg6) { + return new T(_vm, arg1, arg2, arg3, arg4, arg5, arg6); + } protected: Module *_parentModule; Common::Array<Entity*> _entities; |