aboutsummaryrefslogtreecommitdiff
path: root/engines
diff options
context:
space:
mode:
authorjohndoe1232011-08-31 13:15:55 +0000
committerWillem Jan Palenstijn2013-05-08 20:39:35 +0200
commit31457e11aa423e9350d08e6bc5663eccfdd448bd (patch)
tree7eb1f40e8ce3d5621ba0c4606be1fdbe10e524d7 /engines
parent9273c2e97ab90068faf01df246f89d939804ee79 (diff)
downloadscummvm-rg350-31457e11aa423e9350d08e6bc5663eccfdd448bd.tar.gz
scummvm-rg350-31457e11aa423e9350d08e6bc5663eccfdd448bd.tar.bz2
scummvm-rg350-31457e11aa423e9350d08e6bc5663eccfdd448bd.zip
NEVERHOOD: Implement Scene2203
Diffstat (limited to 'engines')
-rw-r--r--engines/neverhood/gamemodule.cpp2
-rw-r--r--engines/neverhood/klayman.cpp97
-rw-r--r--engines/neverhood/klayman.h9
-rw-r--r--engines/neverhood/module2200.cpp254
-rw-r--r--engines/neverhood/module2200.h38
5 files changed, 393 insertions, 7 deletions
diff --git a/engines/neverhood/gamemodule.cpp b/engines/neverhood/gamemodule.cpp
index 9d9a97a943..daa0555c84 100644
--- a/engines/neverhood/gamemodule.cpp
+++ b/engines/neverhood/gamemodule.cpp
@@ -242,7 +242,7 @@ void GameModule::startup() {
createModule2000(-1);
#endif
#if 1
- _vm->gameState().sceneNum = 1;
+ _vm->gameState().sceneNum = 2;
createModule2200(-1);
#endif
}
diff --git a/engines/neverhood/klayman.cpp b/engines/neverhood/klayman.cpp
index 50dd23101c..8eab4a2e36 100644
--- a/engines/neverhood/klayman.cpp
+++ b/engines/neverhood/klayman.cpp
@@ -1765,6 +1765,17 @@ uint32 Klayman::handleMessage41E2F0(int messageNum, const MessageParam &param, E
return messageResult;
}
+void Klayman::sub420750() {
+ if (!sub41CEB0(AnimationCallback(&Klayman::sub420750))) {
+ _status2 = 2;
+ _flagE5 = false;
+ setFileHash(0x5CCCB330, 0, -1);
+ SetUpdateHandler(&Klayman::update);
+ SetSpriteCallback(&Klayman::spriteUpdate41F230);
+ SetMessageHandler(&Klayman::handleMessage41DD20);
+ }
+}
+
void Klayman::sub4207A0() {
if (!sub41CEB0(AnimationCallback(&Klayman::sub4207A0))) {
_status2 = 2;
@@ -1997,6 +2008,20 @@ uint32 Klayman::handleMessage41DB90(int messageNum, const MessageParam &param, E
return handleMessage41D480(messageNum, param, sender);
}
+uint32 Klayman::handleMessage41DD20(int messageNum, const MessageParam &param, Entity *sender) {
+ uint32 messageResult = handleMessage41D480(messageNum, param, sender);
+ switch (messageNum) {
+ case 0x100D:
+ if (param.asInteger() == 0x040D4186) {
+ if (_attachedSprite) {
+ _attachedSprite->sendMessage(0x4808, 0, this);
+ }
+ }
+ break;
+ }
+ return messageResult;
+}
+
//##############################################################################
// KmScene1001
@@ -3498,4 +3523,76 @@ uint32 KmScene2201::xHandleMessage(int messageNum, const MessageParam &param) {
return 0;
}
+KmScene2203::KmScene2203(NeverhoodEngine *vm, Entity *parentScene, int16 x, int16 y)
+ : Klayman(vm, parentScene, x, y, 1000, 1000) {
+ // Empty
+}
+
+uint32 KmScene2203::xHandleMessage(int messageNum, const MessageParam &param) {
+ switch (messageNum) {
+ case 0x4001:
+ case 0x4800:
+ sub41C930(param.asPoint().x, false);
+ break;
+ case 0x4004:
+ 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 0x4816:
+ if (param.asInteger() == 1) {
+ setCallback2(AnimationCallback(&Klayman::sub420120));
+ } else if (param.asInteger() == 2) {
+ setCallback2(AnimationCallback(&Klayman::sub420170));
+ }else {
+ setCallback2(AnimationCallback(&Klayman::sub4200D0));
+ }
+ break;
+ case 0x4817:
+ setDoDeltaX(param.asInteger());
+ sub41C7B0();
+ break;
+ case 0x4818:
+ sub41C930(_dataResource.getPoint(param.asInteger()).x, false);
+ break;
+ case 0x4819:
+ setCallback2(AnimationCallback(&Klayman::sub420750));
+ break;
+ case 0x481A:
+ setCallback2(AnimationCallback(&Klayman::sub420680));
+ break;
+ case 0x481B:
+ if (param.asPoint().y != 0) {
+ sub41CC40(param.asPoint().y, param.asPoint().x);
+ } else {
+ sub41CCE0(param.asPoint().x);
+ }
+ break;
+ case 0x481D:
+ setCallback2(AnimationCallback(&Klayman::sub4207A0));
+ break;
+ case 0x481E:
+ setCallback2(AnimationCallback(&Klayman::sub4207F0));
+ break;
+ case 0x482D:
+ setDoDeltaX(_x > (int16)param.asInteger() ? 1 : 0);
+ sub41C7B0();
+ break;
+ case 0x483F:
+ sub41CD00(param.asInteger());
+ break;
+ case 0x4840:
+ sub41CD70(param.asInteger());
+ break;
+ }
+ return 0;
+}
+
} // End of namespace Neverhood
diff --git a/engines/neverhood/klayman.h b/engines/neverhood/klayman.h
index 1c02f1e9cf..8ca56cc5d9 100644
--- a/engines/neverhood/klayman.h
+++ b/engines/neverhood/klayman.h
@@ -82,6 +82,7 @@ public:
void sub421070();
void sub420420();
void sub420ED0();
+ void sub420750();
void sub4207A0();
void sub4207F0();
void sub420F20();
@@ -237,6 +238,7 @@ protected:
uint32 handleMessage41D640(int messageNum, const MessageParam &param, Entity *sender);
uint32 handleMessage41EAB0(int messageNum, const MessageParam &param, Entity *sender);
uint32 handleMessage41D970(int messageNum, const MessageParam &param, Entity *sender);
+ uint32 handleMessage41DD20(int messageNum, const MessageParam &param, Entity *sender);
void update41D1C0();
@@ -377,6 +379,13 @@ protected:
uint32 xHandleMessage(int messageNum, const MessageParam &param);
};
+class KmScene2203 : public Klayman {
+public:
+ KmScene2203(NeverhoodEngine *vm, Entity *parentScene, int16 x, int16 y);
+protected:
+ uint32 xHandleMessage(int messageNum, const MessageParam &param);
+};
+
} // End of namespace Neverhood
#endif /* NEVERHOOD_KLAYMAN_H */
diff --git a/engines/neverhood/module2200.cpp b/engines/neverhood/module2200.cpp
index e9cb8fa8f6..23f8d73f58 100644
--- a/engines/neverhood/module2200.cpp
+++ b/engines/neverhood/module2200.cpp
@@ -204,6 +204,10 @@ void Module2200::createScene2202(int which) {
}
void Module2200::createScene2203(int which) {
+ // TODO Music18hList_play(0x601C908C, 0, 2, 1);
+ _vm->gameState().sceneNum = 2;
+ _childObject = new Scene2203(_vm, this, which);
+ SetUpdateHandler(&Module2200::updateScene2203);
}
void Module2200::createScene2204(int which) {
@@ -368,6 +372,22 @@ void Module2200::updateScene2202() {
}
void Module2200::updateScene2203() {
+ _childObject->handleUpdate();
+ if (_done) {
+ _done = false;
+ delete _childObject;
+ _childObject = NULL;
+ if (_field20 == 1) {
+ createScene2205(0);
+ _childObject->handleUpdate();
+ } else if (_field20 == 2) {
+ createScene2204(0);
+ _childObject->handleUpdate();
+ } else {
+ createScene2201(1);
+ _childObject->handleUpdate();
+ }
+ }
}
void Module2200::updateScene2204() {
@@ -782,10 +802,8 @@ SsScene2202PuzzleTile::SsScene2202PuzzleTile(NeverhoodEngine *vm, Scene *parentS
: StaticSprite(vm, 900), _soundResource1(vm), _soundResource2(vm), _parentScene(parentScene),
_value(value), _tileIndex(tileIndex), _isMoving(false) {
- debug("#1 _value = %d; _tileIndex = %d", _value, _tileIndex);
SetUpdateHandler(&SsScene2202PuzzleTile::update);
SetMessageHandler(&SsScene2202PuzzleTile::handleMessage);
- debug("#2");
_spriteResource.load2(kSsScene2202PuzzleTileFileHashes2[_value]);
if (_tileIndex >= 0 && _tileIndex <= 2) {
createSurface(100, 128, 128);
@@ -794,7 +812,6 @@ SsScene2202PuzzleTile::SsScene2202PuzzleTile(NeverhoodEngine *vm, Scene *parentS
} else {
createSurface(500, 128, 128);
}
- debug("#3");
_drawRect.x = -(_spriteResource.getDimensions().width / 2);
_drawRect.y = -(_spriteResource.getDimensions().height / 2);
_drawRect.width = _spriteResource.getDimensions().width;
@@ -807,7 +824,6 @@ SsScene2202PuzzleTile::SsScene2202PuzzleTile(NeverhoodEngine *vm, Scene *parentS
StaticSprite::update();
_soundResource1.load(0x40958621);
_soundResource2.load(0x51108241);
- debug("LOAD OK");
}
void SsScene2202PuzzleTile::update() {
@@ -913,9 +929,9 @@ void SsScene2202PuzzleTile::moveTile(int16 newTileIndex) {
setSubVar(0x484498D0, _tileIndex, (uint32)-1);
setSubVar(0x484498D0, newTileIndex, (uint32)_value);
-
+
_tileIndex = newTileIndex;
-
+
_errValue = 0;
_counterDirection = false;
_counter = 0;
@@ -1133,4 +1149,230 @@ bool Scene2202::testIsSolved() {
getSubVar(0x484498D0, 8) == 7;
}
+static const uint32 kClass545FileHashes[] = {
+ 0x2450D850,
+ 0x0C9CE8D0,
+ 0x2C58A152
+};
+
+Class545::Class545(NeverhoodEngine *vm, Scene *parentScene, int index, int surfacePriority, int16 x, int16 y)
+ : AnimatedSprite(vm, kClass545FileHashes[index], surfacePriority, x, y), _parentScene(parentScene), _index(index) {
+
+ if (!getSubVar(0x0090EA95, _index) && !getSubVar(0x08D0AB11, _index)) {
+ SetMessageHandler(&Class545::handleMessage);
+ } else {
+ _surface->setVisible(false);
+ SetMessageHandler(NULL);
+ }
+}
+
+uint32 Class545::handleMessage(int messageNum, const MessageParam &param, Entity *sender) {
+ uint32 messageResult = Sprite::handleMessage(messageNum, param, sender);
+ switch (messageNum) {
+ case 0x1011:
+ _parentScene->sendMessage(0x4826, 0, this);
+ messageResult = 1;
+ break;
+ case 0x4806:
+ setSubVar(0x0090EA95, _index, 1);
+ _surface->setVisible(false);
+ SetMessageHandler(NULL);
+ }
+ return messageResult;
+}
+
+static const uint32 kAsScene2203DoorFileHashes[] = {
+ 0x7868AE10,
+ 0x1A488110
+};
+
+AsScene2203Door::AsScene2203Door(NeverhoodEngine *vm, Scene *parentScene, int index)
+ : AnimatedSprite(vm, 1100), _soundResource(vm), _parentScene(parentScene),
+ _index(index) {
+
+ SetUpdateHandler(&AnimatedSprite::update);
+ SetMessageHandler(&AsScene2203Door::handleMessage);
+ _x = 320;
+ _y = 240;
+ createSurface1(kAsScene2203DoorFileHashes[_index], 900);
+ if (getGlobalVar(0x9A500914) == _index) {
+ setFileHash(kAsScene2203DoorFileHashes[_index], -1, -1);
+ _newHashListIndex = -2;
+ } else {
+ setFileHash(kAsScene2203DoorFileHashes[_index], 0, -1);
+ _newHashListIndex = 0;
+ }
+}
+
+uint32 AsScene2203Door::handleMessage(int messageNum, const MessageParam &param, Entity *sender) {
+ uint32 messageResult = Sprite::handleMessage(messageNum, param, sender);
+ switch (messageNum) {
+ case 0x1011:
+ if (_index == getGlobalVar(0x9A500914))
+ _parentScene->sendMessage(0x2002, 0, this);
+ else
+ _parentScene->sendMessage(0x2001, 0, this);
+ messageResult = 1;
+ break;
+ case 0x2000:
+ _otherDoor = (Sprite*)param.asEntity();
+ break;
+ case 0x3002:
+ if (_index == getGlobalVar(0x9A500914))
+ _parentScene->sendMessage(0x4808, 0, this);
+ setFileHash1();
+ break;
+ case 0x4808:
+ setGlobalVar(0x9A500914, _index);
+ _otherDoor->sendMessage(0x4809, 0, this);
+ openDoor();
+ break;
+ case 0x4809:
+ closeDoor();
+ _parentScene->sendMessage(0x2003, 0, this);
+ break;
+ }
+ return messageResult;
+}
+
+void AsScene2203Door::openDoor() {
+ _soundResource.play(0x341014C4);
+ setFileHash(kAsScene2203DoorFileHashes[_index], 1, -1);
+}
+
+void AsScene2203Door::closeDoor() {
+ setFileHash(kAsScene2203DoorFileHashes[_index], -1, -1);
+ _playBackwards = true;
+ _newHashListIndex = 0;
+}
+
+Scene2203::Scene2203(NeverhoodEngine *vm, Module *parentModule, int which)
+ : Scene(vm, parentModule, true) {
+
+ if (getGlobalVar(0xC0780812) && !getGlobalVar(0x13382860))
+ setGlobalVar(0x13382860, 1);
+
+ SetMessageHandler(&Scene2203::handleMessage);
+ _surfaceFlag = true;
+
+ _background = addBackground(new DirtyBackground(_vm, 0x82C80334, 0, 0));
+ _palette = new Palette(_vm, 0x82C80334);
+ _palette->usePalette();
+ _mouseCursor = addSprite(new Mouse433(_vm, 0x80330824, NULL));
+
+ _vm->_collisionMan->setHitRects(0x004B8320);
+
+ if (getGlobalVar(0x13382860) == 1) {
+ _class545 = addSprite(new Class545(_vm, this, 2, 1100, 282, 432));
+ _vm->_collisionMan->addSprite(_class545);
+ }
+
+ _asTape = addSprite(new AsScene1201Tape(_vm, this, 1, 1100, 435, 432, 0x9148A011));
+ _vm->_collisionMan->addSprite(_asTape);
+
+ _asLeftDoor = addSprite(new AsScene2203Door(_vm, this, 0));
+ _asRightDoor = addSprite(new AsScene2203Door(_vm, this, 1));
+
+ _ssSmallLeftDoor = addSprite(new StaticSprite(_vm, 0x542CC072, 1100));
+ _ssSmallRightDoor = addSprite(new StaticSprite(_vm, 0x0A2C0432, 1100));
+
+ _leftDoorClipRect.x1 = _ssSmallLeftDoor->getSurface()->getDrawRect().x;
+ _leftDoorClipRect.y1 = 0;
+ _leftDoorClipRect.x2 = 640;
+ _leftDoorClipRect.y2 = 480;
+
+ _rightDoorClipRect.x1 = 0;
+ _rightDoorClipRect.y1 = 0;
+ _rightDoorClipRect.x2 = _ssSmallRightDoor->getSurface()->getDrawRect().x + _ssSmallRightDoor->getSurface()->getDrawRect().width;
+ _rightDoorClipRect.y2 = 480;
+
+ _asLeftDoor->sendEntityMessage(0x2000, _asRightDoor, this);
+ _asRightDoor->sendEntityMessage(0x2000, _asLeftDoor, this);
+
+ _vm->_collisionMan->addSprite(_asLeftDoor);
+ _vm->_collisionMan->addSprite(_asRightDoor);
+
+ if (which < 0) {
+ _klayman = new KmScene2203(_vm, this, 200, 427);
+ setMessageList(0x004B8340);
+ } else if (which == 1) {
+ _klayman = new KmScene2203(_vm, this, 640, 427);
+ setMessageList(0x004B8350);
+ } else if (which == 2) {
+ if (getGlobalVar(0xC0418A02)) {
+ _klayman = new KmScene2203(_vm, this, 362, 427);
+ _klayman->setDoDeltaX(1);
+ } else {
+ _klayman = new KmScene2203(_vm, this, 202, 427);
+ }
+ setMessageList(0x004B8358);
+ } else {
+ _klayman = new KmScene2203(_vm, this, 0, 427);
+ setMessageList(0x004B8348);
+ }
+ addSprite(_klayman);
+
+ if (getGlobalVar(0x9A500914)) {
+ _ssSmallLeftDoor->getSurface()->setVisible(false);
+ _klayman->getSurface()->getClipRect() = _rightDoorClipRect;
+ } else {
+ _ssSmallRightDoor->getSurface()->setVisible(false);
+ _klayman->getSurface()->getClipRect() = _leftDoorClipRect;
+ }
+
+ setRectList(0x004B8420);
+
+}
+
+Scene2203::~Scene2203() {
+ setGlobalVar(0xC0418A02, _klayman->isDoDeltaX() ? 1 : 0);
+}
+
+uint32 Scene2203::handleMessage(int messageNum, const MessageParam &param, Entity *sender) {
+ uint32 messageResult = Scene::handleMessage(messageNum, param, sender);
+ switch (messageNum) {
+ case 0x2001:
+ _klayman->sendEntityMessage(0x1014, sender, this);
+ if (sender == _asLeftDoor) {
+ setMessageList2(0x004B83B0);
+ } else {
+ setMessageList2(0x004B83C8);
+ }
+ break;
+ case 0x2002:
+ if (sender == _asLeftDoor) {
+ setMessageList2(0x004B8370);
+ } else {
+ setMessageList2(0x004B8360);
+ }
+ break;
+ case 0x2003:
+ if (sender == _asLeftDoor) {
+ _ssSmallLeftDoor->getSurface()->setVisible(false);
+ } else {
+ _ssSmallRightDoor->getSurface()->setVisible(false);
+ }
+ break;
+ case 0x4808:
+ if (sender == _asLeftDoor) {
+ _ssSmallLeftDoor->getSurface()->setVisible(true);
+ _klayman->getSurface()->getClipRect() = _leftDoorClipRect;
+ } else {
+ _ssSmallRightDoor->getSurface()->setVisible(true);
+ _klayman->getSurface()->getClipRect() = _rightDoorClipRect;
+ }
+ break;
+ case 0x4826:
+ if (sender == _asTape) {
+ _klayman->sendEntityMessage(0x1014, _asTape, this);
+ setMessageList(0x004B83E0);
+ } else if (sender == _class545) {
+ _klayman->sendEntityMessage(0x1014, _class545, this);
+ setMessageList(0x004B83F0);
+ }
+ break;
+ }
+ return messageResult;
+}
+
} // End of namespace Neverhood
diff --git a/engines/neverhood/module2200.h b/engines/neverhood/module2200.h
index d7f41d6f20..6a0634f600 100644
--- a/engines/neverhood/module2200.h
+++ b/engines/neverhood/module2200.h
@@ -246,6 +246,44 @@ protected:
bool testIsSolved();
};
+class Class545 : public AnimatedSprite {
+public:
+ Class545(NeverhoodEngine *vm, Scene *parentScene, int index, int surfacePriority, int16 x, int16 y);
+protected:
+ Scene *_parentScene;
+ int _index;
+ uint32 handleMessage(int messageNum, const MessageParam &param, Entity *sender);
+};
+
+class AsScene2203Door : public AnimatedSprite {
+public:
+ AsScene2203Door(NeverhoodEngine *vm, Scene *parentScene, int index);
+protected:
+ Scene *_parentScene;
+ SoundResource _soundResource;
+ Sprite *_otherDoor;
+ int _index;
+ uint32 handleMessage(int messageNum, const MessageParam &param, Entity *sender);
+ void openDoor();
+ void closeDoor();
+};
+
+class Scene2203 : public Scene {
+public:
+ Scene2203(NeverhoodEngine *vm, Module *parentModule, int which);
+ ~Scene2203();
+protected:
+ Sprite *_asLeftDoor;
+ Sprite *_asRightDoor;
+ Sprite *_ssSmallLeftDoor;
+ Sprite *_ssSmallRightDoor;
+ Sprite *_asTape;
+ Sprite *_class545;
+ NRect _leftDoorClipRect;
+ NRect _rightDoorClipRect;
+ uint32 handleMessage(int messageNum, const MessageParam &param, Entity *sender);
+};
+
} // End of namespace Neverhood
#endif /* NEVERHOOD_MODULE2200_H */