aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--engines/neverhood/gamemodule.cpp2
-rw-r--r--engines/neverhood/klayman.cpp104
-rw-r--r--engines/neverhood/klayman.h8
-rw-r--r--engines/neverhood/module2800.cpp269
-rw-r--r--engines/neverhood/module2800.h49
5 files changed, 431 insertions, 1 deletions
diff --git a/engines/neverhood/gamemodule.cpp b/engines/neverhood/gamemodule.cpp
index e9a58385e4..32082835e9 100644
--- a/engines/neverhood/gamemodule.cpp
+++ b/engines/neverhood/gamemodule.cpp
@@ -328,7 +328,7 @@ void GameModule::startup() {
createModule(2700, -1);
#endif
#if 1
- _vm->gameState().sceneNum = 21;
+ _vm->gameState().sceneNum = 11;
createModule(2800, -1);
#endif
}
diff --git a/engines/neverhood/klayman.cpp b/engines/neverhood/klayman.cpp
index 5ca535460d..3e8c007339 100644
--- a/engines/neverhood/klayman.cpp
+++ b/engines/neverhood/klayman.cpp
@@ -2266,6 +2266,18 @@ void Klayman::sub421270() {
}
}
+void Klayman::sub420460() {
+ if (!stStartAction(AnimationCallback(&Klayman::sub420460))) {
+ _status2 = 0;
+ _acceptInput = false;
+ startAnimation(0x00AB8C10, 0, -1);
+ SetUpdateHandler(&Klayman::update);
+ SetMessageHandler(&Klayman::handleMessage41E5F0);
+ SetSpriteUpdate(&Klayman::spriteUpdate41F920);
+ sendMessage(_attachedSprite, 0x482B, 0);
+ }
+}
+
//##############################################################################
// KmScene1001
@@ -5891,4 +5903,96 @@ uint32 KmScene2810::xHandleMessage(int messageNum, const MessageParam &param) {
return 0;
}
+KmScene2812::KmScene2812(NeverhoodEngine *vm, Entity *parentScene, int16 x, int16 y)
+ : Klayman(vm, parentScene, x, y, 1000, 1000) {
+ // Empty
+}
+
+uint32 KmScene2812::xHandleMessage(int messageNum, const MessageParam &param) {
+ switch (messageNum) {
+ case 0x4001:
+ case 0x4800:
+ startWalkToX(param.asPoint().x, false);
+ break;
+ case 0x4004:
+ GotoState(&Klayman::stTryStandIdle);
+ break;
+ case 0x4805:
+ _destY = param.asInteger();
+ debug("_destY = %d", _destY);
+ GotoState(&Klayman::sub420460);
+ break;
+ case 0x4812:
+ if (param.asInteger() == 2)
+ GotoState(&Klayman::stPickUpNeedle);
+ else if (param.asInteger() == 1)
+ GotoState(&Klayman::sub41FFF0);
+ else
+ GotoState(&Klayman::stPickUpGeneric);
+ break;
+ case 0x4817:
+ setDoDeltaX(param.asInteger());
+ gotoNextStateExt();
+ break;
+ case 0x481A:
+ GotoState(&Klayman::stInsertDisk);
+ break;
+ case 0x481B:
+ if (param.asPoint().y != 0)
+ sub41CC40(param.asPoint().y, param.asPoint().x);
+ else
+ sub41CCE0(param.asPoint().x);
+ break;
+ case 0x481D:
+ GotoState(&Klayman::stTurnToUse);
+ break;
+ case 0x481E:
+ GotoState(&Klayman::stReturnFromUse);
+ break;
+ case 0x4820:
+ sendMessage(_parentScene, 0x2001, 0);
+ GotoState(&Klayman::stContinueClimbLadderUp);
+ break;
+ case 0x4821:
+ sendMessage(_parentScene, 0x2001, 0);
+ _destY = param.asInteger();
+ GotoState(&Klayman::stStartClimbLadderDown);
+ break;
+ case 0x4822:
+ sendMessage(_parentScene, 0x2001, 0);
+ _destY = param.asInteger();
+ GotoState(&Klayman::stStartClimbLadderUp);
+ break;
+ case 0x4823:
+ sendMessage(_parentScene, 0x2002, 0);
+ GotoState(&Klayman::stClimbLadderHalf);
+ break;
+ case 0x482D:
+ setDoDeltaX(_x > (int16)param.asInteger() ? 1 : 0);
+ gotoNextStateExt();
+ break;
+ case 0x482E:
+ if (param.asInteger() == 1) {
+ GotoState(&Klayman::stWalkToFrontNoStep);
+ } else {
+ GotoState(&Klayman::stWalkToFront);
+ }
+ break;
+ case 0x482F:
+ if (param.asInteger() == 1) {
+ GotoState(&Klayman::stTurnToFront);
+ } else {
+ GotoState(&Klayman::stTurnToBack);
+ }
+ break;
+ case 0x483F:
+ startSpecialWalkRight(param.asInteger());
+ break;
+ case 0x4840:
+ startSpecialWalkLeft(param.asInteger());
+ break;
+ }
+ return 0;
+}
+
} // End of namespace Neverhood
diff --git a/engines/neverhood/klayman.h b/engines/neverhood/klayman.h
index f36e27abd4..18791ff623 100644
--- a/engines/neverhood/klayman.h
+++ b/engines/neverhood/klayman.h
@@ -167,6 +167,7 @@ public:
uint32 handleMessage41F1D0(int messageNum, const MessageParam &param, Entity *sender);
void sub421270();
+ void sub420460();
protected:
Entity *_parentScene;
@@ -655,6 +656,13 @@ protected:
uint32 xHandleMessage(int messageNum, const MessageParam &param);
};
+class KmScene2812 : public Klayman {
+public:
+ KmScene2812(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/module2800.cpp b/engines/neverhood/module2800.cpp
index b28babeb37..2bf023cdd7 100644
--- a/engines/neverhood/module2800.cpp
+++ b/engines/neverhood/module2800.cpp
@@ -25,6 +25,7 @@
#include "neverhood/module1000.h"
#include "neverhood/module1200.h"
#include "neverhood/module1700.h"
+#include "neverhood/module2200.h"
#include "neverhood/diskplayerscene.h"
namespace Neverhood {
@@ -114,6 +115,10 @@ void Module2800::createScene(int sceneNum, int which) {
// TODO Music18hList_play(0xD2FA4D14, 0, 2, 1);
_childObject = new Scene2808(_vm, this, 1);
break;
+ case 11:
+ // TODO Music18hList_play(0xD2FA4D14, 0, 2, 1);
+ _childObject = new Scene2812(_vm, this, which);
+ break;
case 12:
// TODO Music18hList_play(0xD2FA4D14, 0, 2, 1);
_childObject = new Class152(_vm, this, 0x0000A245, 0x0A241008);
@@ -293,6 +298,16 @@ void Module2800::updateScene() {
case 10:
createScene(8, _moduleResult);
break;
+ case 11:
+ if (_moduleResult == 1)
+ createScene(4, 0);
+ else if (_moduleResult == 2)
+ createScene(26, 0);
+ else if (_moduleResult == 3)
+ createScene(9, 5);
+ else
+ createScene(9, 1);
+ break;
case 12:
createScene(9, 11);
break;
@@ -2486,6 +2501,260 @@ uint32 Scene2810::handleMessage(int messageNum, const MessageParam &param, Entit
return messageResult;
}
+AsScene2812Winch::AsScene2812Winch(NeverhoodEngine *vm)
+ : AnimatedSprite(vm, 1100) {
+
+ createSurface1(0x20DA08A0, 1200);
+ SetUpdateHandler(&AnimatedSprite::update);
+ SetMessageHandler(&AsScene2812Winch::handleMessage);
+ setVisible(false);
+ _x = 280;
+ _y = 184;
+}
+
+AsScene2812Winch::~AsScene2812Winch() {
+ // TODO Sound1ChList_sub_407AF0(0x00B000E2);
+}
+
+uint32 AsScene2812Winch::handleMessage(int messageNum, const MessageParam &param, Entity *sender) {
+ uint32 messageResult = Sprite::handleMessage(messageNum, param, sender);
+ switch (messageNum) {
+ case 0x2000:
+ startAnimation(0x20DA08A0, 0, -1);
+ setVisible(true);
+ // TODO Sound1ChList_addSoundResource(0x00B000E2, 0xC874EE6C, true);
+ // TODO Sound1ChList_playLooping(0xC874EE6C);
+ break;
+ case 0x3002:
+ startAnimation(0x20DA08A0, 7, -1);
+ break;
+ }
+ return messageResult;
+}
+
+AsScene2812Rope::AsScene2812Rope(NeverhoodEngine *vm, Scene *parentScene)
+ : AnimatedSprite(vm, 1100), _parentScene(parentScene) {
+
+ createSurface(990, 68, 476);
+ SetUpdateHandler(&AnimatedSprite::update);
+ SetMessageHandler(&AsScene2812Rope::handleMessage);
+ SetSpriteUpdate(&AnimatedSprite::updateDeltaXY);
+ startAnimation(0xAE080551, 0, -1);
+ _x = 334;
+ _y = 201;
+}
+
+uint32 AsScene2812Rope::handleMessage(int messageNum, const MessageParam &param, Entity *sender) {
+ uint32 messageResult = Sprite::handleMessage(messageNum, param, sender);
+ switch (messageNum) {
+ case 0x4806:
+ setDoDeltaX(((Sprite*)sender)->isDoDeltaX() ? 1 : 0);
+ sub413E00();
+ break;
+ case 0x482A:
+ sendMessage(_parentScene, 0x1022, 990);
+ break;
+ case 0x482B:
+ sendMessage(_parentScene, 0x1022, 1010);
+ break;
+ }
+ return messageResult;
+}
+
+uint32 AsScene2812Rope::handleMessage413DC0(int messageNum, const MessageParam &param, Entity *sender) {
+ uint32 messageResult = Sprite::handleMessage(messageNum, param, sender);
+ switch (messageNum) {
+ case 0x3002:
+ gotoNextState();
+ break;
+ }
+ return messageResult;
+}
+
+void AsScene2812Rope::sub413E00() {
+ sendMessage(_parentScene, 0x4806, 0);
+ startAnimation(0x9D098C23, 0, -1);
+ SetMessageHandler(&AsScene2812Rope::handleMessage413DC0);
+}
+
+AsScene2812TrapDoor::AsScene2812TrapDoor(NeverhoodEngine *vm)
+ : AnimatedSprite(vm, 0x805D0029, 100, 320, 240), _soundResource(vm) {
+
+ SetMessageHandler(&AsScene2812TrapDoor::handleMessage);
+ _newStickFrameIndex = 0;
+}
+
+uint32 AsScene2812TrapDoor::handleMessage(int messageNum, const MessageParam &param, Entity *sender) {
+ uint32 messageResult = Sprite::handleMessage(messageNum, param, sender);
+ switch (messageNum) {
+ case 0x2000:
+ startAnimation(0x805D0029, 0, -1);
+ _soundResource.play(0xEA005F40);
+ _newStickFrameIndex = -2;
+ break;
+ }
+ return messageResult;
+}
+
+Scene2812::Scene2812(NeverhoodEngine *vm, Module *parentModule, int which)
+ : Scene(vm, parentModule, true), _palStatus(0) {
+
+ if (getGlobalVar(0xC0780812) && getGlobalVar(0x13382860) == 0)
+ setGlobalVar(0x13382860, 3);
+
+ _surfaceFlag = true;
+ SetMessageHandler(&Scene2812::handleMessage);
+ SetUpdateHandler(&Scene2812::update);
+
+ setRectList(0x004AF700);
+
+ setBackground(0x03600606);
+ setPalette(0x03600606);
+ addEntity(_palette);
+ _palette->addBasePalette(0x03600606, 0, 256, 0);
+
+ _sprite1 = insertStaticSprite(0x0C06C860, 1100);
+ insertMouse433(0x0060203E);
+
+ if (getGlobalVar(0x13382860) == 3) {
+ _class545 = insertSprite<Class545>(this, 2, 1100, 474, 437);
+ _vm->_collisionMan->addSprite(_class545);
+ }
+
+ _class606 = insertSprite<Class606>(this, 6, 1100, 513, 437, 0xA1361863);
+ _vm->_collisionMan->addSprite(_class606);
+
+ _asWinch = insertSprite<AsScene2812Winch>();
+ _asTrapDoor = insertSprite<AsScene2812TrapDoor>();
+ _asRope = insertSprite<AsScene2812Rope>(this);
+
+ _sprite2 = insertStaticSprite(0x08478078, 1100);
+ _sprite3 = insertStaticSprite(0x2203B821, 1100);
+ _sprite4 = insertStaticSprite(0x08592134, 1100);
+
+ if (which < 0) {
+ _flag1 = false;
+ insertKlayman<KmScene2812>(272, 432);
+ setMessageList(0x004AF560);
+ _sprite1->setVisible(false);
+ _klayman->setClipRect(_sprite4->getDrawRect().x, 0, 640, _sprite3->getDrawRect().y2());
+ } else if (which == 1) {
+ _flag1 = false;
+ insertKlayman<KmScene2812>(338, 398);
+ setMessageList(0x004AF588);
+ setPalStatus1(1);
+ _klayman->setClipRect(_sprite1->getDrawRect().x, 0, _sprite1->getDrawRect().x2(), _sprite3->getDrawRect().y2());
+ } else if (which == 2) {
+ _flag1 = false;
+ if (getGlobalVar(0xC0418A02)) {
+ insertKlayman<KmScene2812>(554, 432);
+ _klayman->setDoDeltaX(1);
+ } else {
+ insertKlayman<KmScene2812>(394, 432);
+ }
+ setMessageList(0x004AF5F0);
+ _sprite1->setVisible(false);
+ _klayman->setClipRect(_sprite4->getDrawRect().x, 0, 640, _sprite3->getDrawRect().y2());
+ } else {
+ _flag1 = true;
+ insertKlayman<KmScene2812>(150, 582);
+ setMessageList(0x004AF568);
+ setPalStatus2(1);
+ _sprite1->setVisible(false);
+ _klayman->setClipRect(_sprite4->getDrawRect().x, 0, 640, _sprite3->getDrawRect().y2());
+ }
+
+ _asRope->setClipRect(0, _sprite2->getDrawRect().y, 640, _sprite3->getDrawRect().y2());
+
+}
+
+void Scene2812::update() {
+ if (_klayman->getX() < 220)
+ setPalStatus2(0);
+ else if (_klayman->getX() < 240)
+ setPalStatus0(0);
+ Scene::update();
+}
+
+uint32 Scene2812::handleMessage(int messageNum, const MessageParam &param, Entity *sender) {
+ uint32 messageResult = Scene::handleMessage(messageNum, param, sender);
+ switch (messageNum) {
+ case 0x100D:
+ if (param.asInteger() == 0x0004269B)
+ sendEntityMessage(_klayman, 0x1014, _asRope);
+ break;
+ case 0x2001:
+ _flag1 = true;
+ setRectList(0x004AF710);
+ _klayman->setClipRect(_sprite4->getDrawRect().x, 0, 640, _sprite4->getDrawRect().y2());
+ break;
+ case 0x2002:
+ _flag1 = false;
+ setRectList(0x004AF700);
+ _klayman->setClipRect(_sprite4->getDrawRect().x, 0, 640, _sprite3->getDrawRect().y2());
+ break;
+ case 0x4806:
+ sendMessage(_asWinch, 0x2000, 0);
+ sendMessage(_asTrapDoor, 0x2000, 0);
+ break;
+ case 0x4826:
+ if (sender == _class606 && !_flag1) {
+ sendEntityMessage(_klayman, 0x1014, _class606);
+ setMessageList(0x004AF658);
+ } else if (sender == _class545 && !_flag1) {
+ sendEntityMessage(_klayman, 0x1014, _class545);
+ setMessageList(0x004AF668);
+ }
+ break;
+ case 0x482A:
+ setPalStatus1(0);
+ _sprite1->setVisible(true);
+ _klayman->setClipRect(_sprite1->getDrawRect().x, 0, _sprite1->getDrawRect().x2(), _sprite3->getDrawRect().y2());
+ break;
+ case 0x482B:
+ setPalStatus0(false);
+ _sprite1->setVisible(false);
+ _klayman->setClipRect(_sprite4->getDrawRect().x, 0, 640, _sprite3->getDrawRect().y2());
+ break;
+ }
+ return messageResult;
+}
+
+void Scene2812::setPalStatus0(int fadeTime) {
+ if (_palStatus != 0) {
+ _palStatus = 0;
+ setPalStatus(fadeTime);
+ }
+}
+
+void Scene2812::setPalStatus1(int fadeTime) {
+ if (_palStatus != 1) {
+ _palStatus = 1;
+ setPalStatus(fadeTime);
+ }
+}
+
+void Scene2812::setPalStatus2(int fadeTime) {
+ if (_palStatus != 2) {
+ _palStatus = 2;
+ setPalStatus(fadeTime);
+ }
+}
+
+void Scene2812::setPalStatus(int fadeTime) {
+ if (_palStatus == 0)
+ _palette->addBasePalette(0x05D30F11, 0, 64, 0);
+ else if (_palStatus == 1)
+ _palette->addBasePalette(0x92CA2C9B, 0, 64, 0);
+ else if (_palStatus == 2)
+ _palette->addBasePalette(0x381F92C5, 0, 64, 0);
+ if (fadeTime > 0) {
+ _palette->startFadeToPalette(0);
+ } else {
+ _palette->startFadeToPalette(12);
+ }
+}
+
Scene2822::Scene2822(NeverhoodEngine *vm, Module *parentModule, int which)
: Scene(vm, parentModule, true), _countdown(0), _scrollIndex(0),
_soundResource1(vm), _soundResource2(vm), _soundResource3(vm) {
diff --git a/engines/neverhood/module2800.h b/engines/neverhood/module2800.h
index 4a7224da1a..9daf820e21 100644
--- a/engines/neverhood/module2800.h
+++ b/engines/neverhood/module2800.h
@@ -395,6 +395,55 @@ protected:
void sub406650();
};
+class AsScene2812Winch : public AnimatedSprite {
+public:
+ AsScene2812Winch(NeverhoodEngine *vm);
+ virtual ~AsScene2812Winch();
+protected:
+ uint32 handleMessage(int messageNum, const MessageParam &param, Entity *sender);
+};
+
+class AsScene2812Rope : public AnimatedSprite {
+public:
+ AsScene2812Rope(NeverhoodEngine *vm, Scene *parentScene);
+protected:
+ Scene *_parentScene;
+ uint32 handleMessage(int messageNum, const MessageParam &param, Entity *sender);
+ uint32 handleMessage413DC0(int messageNum, const MessageParam &param, Entity *sender);
+ void sub413E00();
+};
+
+class AsScene2812TrapDoor : public AnimatedSprite {
+public:
+ AsScene2812TrapDoor(NeverhoodEngine *vm);
+protected:
+ SoundResource _soundResource;
+ uint32 handleMessage(int messageNum, const MessageParam &param, Entity *sender);
+};
+
+class Scene2812 : public Scene {
+public:
+ Scene2812(NeverhoodEngine *vm, Module *parentModule, int which);
+protected:
+ Sprite *_asWinch;
+ Sprite *_asTrapDoor;
+ Sprite *_asRope;
+ Sprite *_sprite3;
+ Sprite *_sprite2;
+ Sprite *_sprite4;
+ Sprite *_class606;
+ Sprite *_class545;
+ Sprite *_sprite1;
+ bool _flag1;
+ int _palStatus;
+ void update();
+ uint32 handleMessage(int messageNum, const MessageParam &param, Entity *sender);
+ void setPalStatus0(int fadeTime);
+ void setPalStatus1(int fadeTime);
+ void setPalStatus2(int fadeTime);
+ void setPalStatus(int fadeTime);
+};
+
class Scene2822 : public Scene {
public:
Scene2822(NeverhoodEngine *vm, Module *parentModule, int which);