aboutsummaryrefslogtreecommitdiff
path: root/engines
diff options
context:
space:
mode:
authorjohndoe1232012-09-14 10:51:36 +0000
committerWillem Jan Palenstijn2013-05-08 20:43:41 +0200
commit7c2aa2a22556c84fa8ec1d5f6993dfc8c47fb0c3 (patch)
treeba03ee9d31bba6fb3f084c747acbba764d2defd6 /engines
parent49f39b0da2bee93e8425c0686f7cc26df443a35f (diff)
downloadscummvm-rg350-7c2aa2a22556c84fa8ec1d5f6993dfc8c47fb0c3.tar.gz
scummvm-rg350-7c2aa2a22556c84fa8ec1d5f6993dfc8c47fb0c3.tar.bz2
scummvm-rg350-7c2aa2a22556c84fa8ec1d5f6993dfc8c47fb0c3.zip
NEVERHOOD: Implement Scene2402
Diffstat (limited to 'engines')
-rw-r--r--engines/neverhood/gamemodule.cpp2
-rw-r--r--engines/neverhood/klayman.cpp86
-rw-r--r--engines/neverhood/klayman.h8
-rw-r--r--engines/neverhood/module2400.cpp266
-rw-r--r--engines/neverhood/module2400.h49
5 files changed, 409 insertions, 2 deletions
diff --git a/engines/neverhood/gamemodule.cpp b/engines/neverhood/gamemodule.cpp
index d657307256..dcc0995440 100644
--- a/engines/neverhood/gamemodule.cpp
+++ b/engines/neverhood/gamemodule.cpp
@@ -354,7 +354,7 @@ void GameModule::startup() {
createModule(2500, -1);
#endif
#if 1
- _vm->gameState().sceneNum = 0;
+ _vm->gameState().sceneNum = 1;
createModule(2400, -1);
#endif
}
diff --git a/engines/neverhood/klayman.cpp b/engines/neverhood/klayman.cpp
index 9a6e4fe1a1..17124e58ad 100644
--- a/engines/neverhood/klayman.cpp
+++ b/engines/neverhood/klayman.cpp
@@ -5282,7 +5282,7 @@ uint32 KmScene2401::xHandleMessage(int messageNum, const MessageParam &param) {
break;
case 0x4833:
if (param.asInteger() == 1)
- GotoState(&Klayman::stWonderAboutHalf);
+ GotoState(&Klayman::stWonderAbout);
else {
_spitPipeIndex = sendMessage(_parentScene, 0x2000, 0);
GotoState(&KmScene2401::stTrySpitIntoPipe);
@@ -5359,6 +5359,90 @@ void KmScene2401::stContSpitIntoPipe() {
SetSpriteUpdate(NULL);
}
+KmScene2402::KmScene2402(NeverhoodEngine *vm, Entity *parentScene, int16 x, int16 y)
+ : Klayman(vm, parentScene, x, y, 1000, 1000) {
+ // Empty
+}
+
+uint32 KmScene2402::xHandleMessage(int messageNum, const MessageParam &param) {
+ uint32 messageResult = 0;
+ switch (messageNum) {
+ case 0x4001:
+ case 0x4800:
+ startWalkToX(param.asPoint().x, false);
+ break;
+ case 0x4004:
+ if (!getGlobalVar(0x92603A79))
+ GotoState(&KmScene2402::sub415840);
+ else
+ GotoState(&Klayman::stTryStandIdle);
+ break;
+ case 0x4804:
+ if (param.asInteger() != 0) {
+ _destX = param.asInteger();
+ GotoState(&Klayman::stWalking);
+ } else {
+ GotoState(&Klayman::stPeekWall);
+ }
+ break;
+ case 0x4812:
+ GotoState(&Klayman::stPickUpGeneric);
+ break;
+ case 0x4816:
+ if (param.asInteger() == 1) {
+ GotoState(&Klayman::stTurnPressButton);
+ } else if (param.asInteger() == 2) {
+ GotoState(&Klayman::stStampFloorButton);
+ } else {
+ GotoState(&Klayman::stPressButtonSide);
+ }
+ break;
+ case 0x4817:
+ setDoDeltaX(param.asInteger());
+ gotoNextStateExt();
+ break;
+ case 0x481B:
+ if (param.asPoint().y != 0) {
+ sub41CC40(param.asPoint().y, param.asPoint().x);
+ } else {
+ sub41CCE0(param.asPoint().x);
+ }
+ break;
+ case 0x481F:
+ if (param.asInteger() == 0) {
+ GotoState(&Klayman::stWonderAboutHalf);
+ } else if (param.asInteger() == 1) {
+ GotoState(&Klayman::stWonderAboutAfter);
+ } else if (param.asInteger() == 3) {
+ GotoState(&Klayman::stTurnToUseHalf);
+ } else if (param.asInteger() == 4) {
+ GotoState(&Klayman::stTurnAwayFromUse);
+ } else {
+ GotoState(&Klayman::stWonderAbout);
+ }
+ break;
+ case 0x483F:
+ startSpecialWalkRight(param.asInteger());
+ break;
+ case 0x4840:
+ startSpecialWalkLeft(param.asInteger());
+ break;
+ }
+ return messageResult;
+}
+
+void KmScene2402::sub415840() {
+ if (_x > 260)
+ setDoDeltaX(1);
+ _status2 = 0;
+ _acceptInput = true;
+ startAnimation(0xD820A114, 0, -1);
+ _newStickFrameIndex = 10;
+ SetUpdateHandler(&Klayman::update);
+ SetMessageHandler(&Klayman::handleMessage41D360);
+ SetSpriteUpdate(NULL);
+}
+
KmScene2501::KmScene2501(NeverhoodEngine *vm, Entity *parentScene, int16 x, int16 y)
: Klayman(vm, parentScene, x, y, 1000, 1000), _isSittingInTeleporter(false) {
// Empty
diff --git a/engines/neverhood/klayman.h b/engines/neverhood/klayman.h
index fdf9b6e9b4..7593bf1e3b 100644
--- a/engines/neverhood/klayman.h
+++ b/engines/neverhood/klayman.h
@@ -595,6 +595,14 @@ protected:
void stContSpitIntoPipe();
};
+class KmScene2402 : public Klayman {
+public:
+ KmScene2402(NeverhoodEngine *vm, Entity *parentScene, int16 x, int16 y);
+protected:
+ uint32 xHandleMessage(int messageNum, const MessageParam &param);
+ void sub415840();
+};
+
class KmScene2501 : public Klayman {
public:
KmScene2501(NeverhoodEngine *vm, Entity *parentScene, int16 x, int16 y);
diff --git a/engines/neverhood/module2400.cpp b/engines/neverhood/module2400.cpp
index 4febe7429f..1c52d68db8 100644
--- a/engines/neverhood/module2400.cpp
+++ b/engines/neverhood/module2400.cpp
@@ -49,6 +49,10 @@ void Module2400::createScene(int sceneNum, int which) {
// TODO Music18hList_stop(0xB110382D, 0, 0);
_childObject = new Scene2401(_vm, this, which);
break;
+ case 1:
+ // TODO Music18hList_play(0xB110382D, 0, 2, 1);
+ _childObject = new Scene2402(_vm, this, which);
+ break;
}
SetUpdateHandler(&Module2400::updateScene);
_childObject->handleUpdate();
@@ -63,6 +67,14 @@ void Module2400::updateScene() {
else
leaveModule(0);
break;
+ case 1:
+ if (_moduleResult == 1)
+ createScene(5, 0);
+ else if (_moduleResult == 2)
+ createScene(7, -1);
+ else
+ createScene(0, 1);
+ break;
}
}
}
@@ -497,5 +509,259 @@ void Scene2401::playPipeSound(uint32 fileHash) {
_soundResource2.play(fileHash);
_soundToggle = !_soundToggle;
}
+
+static const uint32 kScene2402FileHashes[] = {
+ 0xD0910020,
+ 0xD0910038,
+ 0xD0910008,
+ 0xD0910068,
+ 0xD09100A8
+};
+
+AsScene2402Door::AsScene2402Door(NeverhoodEngine *vm, Scene *parentScene, bool isOpen)
+ : AnimatedSprite(vm, 1100), _parentScene(parentScene), _isOpen(isOpen), _soundResource(vm) {
+
+ SetUpdateHandler(&AsScene2402Door::update);
+ SetMessageHandler(&AsScene2402Door::handleMessage);
+ createSurface1(0x80495831, 100);
+ _x = 320;
+ _y = 240;
+ _newStickFrameIndex = -2;
+ if (_isOpen) {
+ startAnimation(0x80495831, -1, -1);
+ _countdown = 48;
+ } else {
+ stopAnimation();
+ setVisible(false);
+ }
+}
+
+void AsScene2402Door::update() {
+ if (_isOpen && _countdown != 0 && (--_countdown) == 0) {
+ _isOpen = false;
+ setVisible(true);
+ startAnimation(0x80495831, -1, -1);
+ _playBackwards = true;
+ _soundResource.play(calcHash("fxDoorClose38"));
+ NextState(&AsScene2402Door::stDoorClosingFinished);
+ }
+ AnimatedSprite::update();
+}
+
+uint32 AsScene2402Door::handleMessage(int messageNum, const MessageParam &param, Entity *sender) {
+ uint32 messageResult = Sprite::handleMessage(messageNum, param, sender);
+ switch (messageNum) {
+ case 0x2000:
+ if (_isOpen)
+ _countdown = 144;
+ messageResult = _isOpen ? 1 : 0;
+ break;
+ case 0x3002:
+ gotoNextState();
+ break;
+ case 0x4808:
+ _countdown = 144;
+ _isOpen = true;
+ setVisible(true);
+ startAnimation(0x80495831, 0, -1);
+ _newStickFrameIndex = -2;
+ _soundResource.play(calcHash("fxDoorOpen38"));
+ break;
+ }
+ return messageResult;
+}
+
+void AsScene2402Door::stDoorClosingFinished() {
+ sendMessage(_parentScene, 0x2001, 0);
+ setVisible(false);
+}
+
+AsScene2402TV::AsScene2402TV(NeverhoodEngine *vm, Klayman *klayman)
+ : AnimatedSprite(vm, 1100), _klayman(klayman), _countdown1(0), _countdown2(0),
+ _soundResource(vm) {
+
+ createSurface(100, 640, 480); // TODO Use correct size from the two hashes
+ SetMessageHandler(&Sprite::handleMessage);
+ _x = 260;
+ _y = 210;
+ setDoDeltaX(1);
+
+ if (!getGlobalVar(0x92603A79)) {
+ _soundResource.load(0x58208810);
+ _countdown1 = 48;
+ startAnimation(0x4919397A, 0, -1);
+ _newStickFrameIndex = 0;
+ SetUpdateHandler(&AsScene2402TV::upWait);
+ } else {
+ int16 frameIndex;
+ if (_klayman->getX() > 320)
+ _currFrameIndex = 29;
+ frameIndex = CLIP<int16>((_klayman->getX() - _x + 150) / 10, 0, 29);
+ startAnimation(0x050A0103, frameIndex, -1);
+ _newStickFrameIndex = frameIndex;
+ _countdown1 = 0;
+ SetUpdateHandler(&AsScene2402TV::upFocusKlayman);
+ }
+
+}
+
+AsScene2402TV::~AsScene2402TV() {
+ // TODO Sound1ChList_sub_407AF0(0x01520123);
+}
+
+void AsScene2402TV::upWait() {
+ if (_countdown1 != 0 && (--_countdown1) == 0) {
+ startAnimation(0x4919397A, 0, -1);
+ SetMessageHandler(&AsScene2402TV::hmJoke);
+ NextState(&AsScene2402TV::stJokeFinished);
+ }
+ AnimatedSprite::update();
+}
+
+void AsScene2402TV::upFocusKlayman() {
+ int16 frameIndex = CLIP<int16>((_klayman->getX() - _x + 150) / 10, 0, 29);
+ if (frameIndex != _currFrameIndex) {
+ if (frameIndex > _currFrameIndex) {
+ _currFrameIndex++;
+ } else if (frameIndex < _currFrameIndex) {
+ _currFrameIndex--;
+ }
+ startAnimation(0x050A0103, _currFrameIndex, -1);
+ _newStickFrameIndex = _currFrameIndex;
+ if (_countdown2 == 0) {
+ // TODO Sound1ChList_addSoundResource(0x01520123, 0xC42D4528, true);
+ // TODO Sound1ChList_playLooping(0xC42D4528);
+ }
+ _countdown2 = 5;
+ } else if (_countdown2 != 0 && (--_countdown2 == 0)) {
+ // TODO Sound1ChList_deleteSoundByHash(0xC42D4528);
+ }
+ AnimatedSprite::update();
+}
+
+void AsScene2402TV::stJokeFinished() {
+ setGlobalVar(0x92603A79, 1);
+ startAnimation(0x050A0103, 0, -1);
+ _newStickFrameIndex = 0;
+ SetUpdateHandler(&AsScene2402TV::upFocusKlayman);
+}
+
+uint32 AsScene2402TV::hmJoke(int messageNum, const MessageParam &param, Entity *sender) {
+ uint32 messageResult = Sprite::handleMessage(messageNum, param, sender);
+ switch (messageNum) {
+ case 0x100D:
+ if (param.asInteger() == 0x431EA0B0) {
+ _soundResource.play();
+ }
+ break;
+ case 0x3002:
+ gotoNextState();
+ break;
+ }
+ return messageResult;
+}
+
+Scene2402::Scene2402(NeverhoodEngine *vm, Module *parentModule, int which)
+ : Scene(vm, parentModule, true), _countdown(0), _soundToggle(false),
+ _soundResource1(vm), _soundResource2(vm) {
+
+ _surfaceFlag = true;
+ SetMessageHandler(&Scene2402::handleMessage);
+ SetUpdateHandler(&Scene2402::update);
+
+ setRectList(0x004AF900);
+ setBackground(0x81660220);
+ setPalette(0x81660220);
+ insertMouse433(0x6022481E);
+ _asTape = insertSprite<AsScene1201Tape>(this, 9, 1100, 286, 409, 0x9148A011);
+ _vm->_collisionMan->addSprite(_asTape);
+ _ssButton = insertSprite<SsCommonButtonSprite>(this, 0x15288120, 100, 0);
+
+ if (which < 0) {
+ insertKlayman<KmScene2402>(198, 404);
+ setMessageList(0x004AF7C8);
+ } else if (which == 1) {
+ insertKlayman<KmScene2402>(660, 404);
+ setMessageList(0x004AF7D8);
+ } else if (which == 2) {
+ insertKlayman<KmScene2402>(409, 404);
+ _klayman->setDoDeltaX(getGlobalVar(0xC0418A02) ? 1 : 0);
+ setMessageList(0x004AF888);
+ } else {
+ insertKlayman<KmScene2402>(0, 404);
+ setMessageList(0x004AF7D0);
+ }
+
+ _sprite1 = insertStaticSprite(0x081A60A8, 1100);
+ _ssDoorFrame = (StaticSprite*)insertStaticSprite(0x406C0AE0, 1100);
+ _klayman->setClipRect(_ssDoorFrame->getDrawRect().x, 0, 639, _sprite1->getDrawRect().y2());
+ _asDoor = insertSprite<AsScene2402Door>(this, which == 1/*CHECKME or != ?*/);
+ insertSprite<AsScene2402TV>(_klayman);
+ insertStaticSprite(0x3A01A020, 200);
+
+}
+
+Scene2402::~Scene2402() {
+ setGlobalVar(0xC0418A02, _klayman->isDoDeltaX() ? 1 : 0);
+}
+
+void Scene2402::update() {
+ if (_countdown != 0 && (--_countdown) == 0) {
+ if (_pipeStatus >= 10) {
+ sendMessage(_asDoor, 0x4808, 0);
+ _ssDoorFrame->load(0x00B415E0, true, true);
+ _ssDoorFrame->update();
+ } else if (_pipeStatus >= 5) {
+ _countdown = 8;
+ playPipeSound(kScene2402FileHashes[getSubVar(0x0800547C, _pipeStatus - 5)]);
+ } else {
+ _countdown = _pipeStatus == 4 ? 16 : 8;
+ playPipeSound(kScene2402FileHashes[getSubVar(0x90405038, _pipeStatus)]);
+ }
+ _pipeStatus++;
+ }
+ Scene::update();
+}
+
+uint32 Scene2402::handleMessage(int messageNum, const MessageParam &param, Entity *sender) {
+ uint32 messageResult = Scene::handleMessage(messageNum, param, sender);
+ switch (messageNum) {
+ case 0x100D:
+ if (param.asInteger() == 0x402064D8) {
+ sendEntityMessage(_klayman, 0x1014, _ssButton);
+ } else if (param.asInteger() == 0x01C66840) {
+ if (sendMessage(_asDoor, 0x2000, 0))
+ setMessageList(0x004AF800);
+ else
+ setMessageList(0x004AF818);
+ }
+ break;
+ case 0x2001:
+ _ssDoorFrame->load(0x406C0AE0, true, true);
+ _ssDoorFrame->update();
+ break;
+ case 0x480B:
+ if (sender == _ssButton) {
+ _pipeStatus = 0;
+ _countdown = 8;
+ }
+ break;
+ case 0x4826:
+ if (sender == _asTape) {
+ sendEntityMessage(_klayman, 0x1014, _asTape);
+ setMessageList(0x004AF890);
+ }
+ break;
+ }
+ return messageResult;
+}
+void Scene2402::playPipeSound(uint32 fileHash) {
+ if (_soundToggle)
+ _soundResource1.play(fileHash);
+ else
+ _soundResource2.play(fileHash);
+ _soundToggle = !_soundToggle;
+}
+
} // End of namespace Neverhood
diff --git a/engines/neverhood/module2400.h b/engines/neverhood/module2400.h
index c8cdb664c8..4367901672 100644
--- a/engines/neverhood/module2400.h
+++ b/engines/neverhood/module2400.h
@@ -29,6 +29,7 @@
#include "neverhood/gamemodule.h"
#include "neverhood/module1000.h"
#include "neverhood/module1100.h"
+#include "neverhood/module1200.h"
#include "neverhood/module2100.h"
namespace Neverhood {
@@ -110,6 +111,54 @@ protected:
void playPipeSound(uint32 fileHash);
};
+class AsScene2402Door : public AnimatedSprite {
+public:
+ AsScene2402Door(NeverhoodEngine *vm, Scene *parentScene, bool isOpen);
+protected:
+ Scene *_parentScene;
+ int _countdown;
+ bool _isOpen;
+ SoundResource _soundResource;
+ void update();
+ uint32 handleMessage(int messageNum, const MessageParam &param, Entity *sender);
+ void stDoorClosingFinished();
+};
+
+class AsScene2402TV : public AnimatedSprite {
+public:
+ AsScene2402TV(NeverhoodEngine *vm, Klayman *klayman);
+ virtual ~AsScene2402TV();
+protected:
+ Klayman *_klayman;
+ int _countdown1;
+ int _countdown2;
+ SoundResource _soundResource;
+ void upWait();
+ void upFocusKlayman();
+ void stJokeFinished();
+ uint32 hmJoke(int messageNum, const MessageParam &param, Entity *sender);
+};
+
+class Scene2402 : public Scene {
+public:
+ Scene2402(NeverhoodEngine *vm, Module *parentModule, int which);
+ virtual ~Scene2402();
+protected:
+ Sprite *_sprite1;
+ Sprite *_asDoor;
+ Sprite *_ssButton;
+ Sprite *_asTape;
+ StaticSprite *_ssDoorFrame;
+ int _pipeStatus;
+ int _countdown;
+ bool _soundToggle;
+ SoundResource _soundResource1;
+ SoundResource _soundResource2;
+ void update();
+ uint32 handleMessage(int messageNum, const MessageParam &param, Entity *sender);
+ void playPipeSound(uint32 fileHash);
+};
+
} // End of namespace Neverhood
#endif /* NEVERHOOD_MODULE2400_H */