aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--engines/neverhood/gamemodule.cpp2
-rw-r--r--engines/neverhood/klayman.cpp264
-rw-r--r--engines/neverhood/klayman.h29
-rw-r--r--engines/neverhood/module2800.cpp133
-rw-r--r--engines/neverhood/module2800.h18
5 files changed, 442 insertions, 4 deletions
diff --git a/engines/neverhood/gamemodule.cpp b/engines/neverhood/gamemodule.cpp
index a424d53556..62fe2ada2a 100644
--- a/engines/neverhood/gamemodule.cpp
+++ b/engines/neverhood/gamemodule.cpp
@@ -303,7 +303,7 @@ void GameModule::startup() {
createModule(2700, -1);
#endif
#if 1
- _vm->gameState().sceneNum = 2;
+ _vm->gameState().sceneNum = 5;
createModule(2800, -1);
#endif
}
diff --git a/engines/neverhood/klayman.cpp b/engines/neverhood/klayman.cpp
index 010c2e4ef0..4178bec3a7 100644
--- a/engines/neverhood/klayman.cpp
+++ b/engines/neverhood/klayman.cpp
@@ -650,8 +650,7 @@ void Klayman::startWalkToX(int16 x, bool flag) {
_destX = x;
} else if (flag) {
_destX = x;
- error("// TODO AnimatedSprite_GotoState(&Klayman::sub421550));");
- // TODO AnimatedSprite_GotoState(&Klayman::sub421550);
+ GotoState(&Klayman::sub421550);
} else {
_destX = x;
GotoState(&Klayman::stStartWalking);
@@ -1239,6 +1238,104 @@ void Klayman::sub421880() {
SetSpriteUpdate(&Klayman::spriteUpdate41F230);
}
+void Klayman::sub420F60() {
+ if (!stStartAction(AnimationCallback(&Klayman::sub420F60))) {
+ _status2 = 2;
+ _acceptInput = false;
+ startAnimation(0x3F28E094, 0, -1);
+ SetUpdateHandler(&Klayman::update);
+ SetMessageHandler(&Klayman::handleMessage41E6C0);
+ SetSpriteUpdate(NULL);
+ NextState(&Klayman::sub420FB0);
+ }
+}
+
+void Klayman::sub420FB0() {
+ _acceptInput = false;
+ startAnimation(0x3A28C094, 0, -1);
+ SetUpdateHandler(&Klayman::update);
+ SetMessageHandler(&Klayman::handleMessage41E6C0);
+ SetSpriteUpdate(NULL);
+}
+
+uint32 Klayman::handleMessage41E6C0(int messageNum, const MessageParam &param, Entity *sender) {
+ uint32 messageResult = handleMessage41D480(messageNum, param, sender);
+ switch (messageNum) {
+ case 0x100D:
+ if (param.asInteger() == 0x4AB28209) {
+ sendMessage(_attachedSprite, 0x482A, 0);
+ sendMessage(_attachedSprite, 0x480F, 0);
+ } else if (param.asInteger() == 0x88001184) {
+ sendMessage(_attachedSprite, 0x482B, 0);
+ }
+ break;
+ }
+ return messageResult;
+}
+
+void Klayman::sub421110() {
+ if (!stStartAction(AnimationCallback(&Klayman::sub421110))) {
+ _status2 = 1;
+ _acceptInput = false;
+ startAnimation(0x1A38A814, 0, -1);
+ SetUpdateHandler(&Klayman::update);
+ SetMessageHandler(&Klayman::handleMessage41E750);
+ SetSpriteUpdate(NULL);
+ }
+}
+
+uint32 Klayman::handleMessage41E750(int messageNum, const MessageParam &param, Entity *sender) {
+ uint32 messageResult = handleMessage41D480(messageNum, param, sender);
+ switch (messageNum) {
+ case 0x100D:
+ if (param.asInteger() == 0x02B20220)
+ _soundResource1.play(0xC5408620);
+ else if (param.asInteger() == 0x0A720138)
+ _soundResource1.play(0xD4C08010);
+ else if (param.asInteger() == 0x03020231)
+ _soundResource1.play(0xD4C08010);
+ else if (param.asInteger() == 0xB613A180)
+ _soundResource1.play(0x44051000);
+ else if (param.asInteger() == 0x67221A03)
+ _soundResource1.play(0x44051000);
+ else if (param.asInteger() == 0x038A010B)
+ _soundResource1.play(0x00018040);
+ else if (param.asInteger() == 0x422B0280)
+ _soundResource1.play(0x166FC6E0);
+ else if (param.asInteger() == 0x925A0C1E)
+ _soundResource1.play(0x40E5884D);
+ break;
+ }
+ return messageResult;
+}
+
+void Klayman::sub4215E0() {
+ _status2 = 0;
+ _isWalking = true;
+ _acceptInput = true;
+ SetUpdateHandler(&Klayman::update);
+ SetMessageHandler(&Klayman::handleMessage41EB70);
+ SetSpriteUpdate(&Klayman::spriteUpdate41F300);
+ NextState(&Klayman::stUpdateWalking);
+ FinalizeState(&Klayman::stStartWalkingDone);
+ startAnimation(0x5A2CBC00, 0, -1);
+}
+
+void Klayman::sub421550() {
+ if (!stStartActionFromIdle(AnimationCallback(&Klayman::sub421550))) {
+ _status2 = 0;
+ _isWalking = true;
+ _acceptInput = true;
+ setDoDeltaX(_destX < _x ? 1 : 0);
+ startAnimation(0x272C1199, 0, -1);
+ SetUpdateHandler(&Klayman::update);
+ SetMessageHandler(&Klayman::hmStartWalking);
+ SetSpriteUpdate(&Klayman::suWalkingTestExit);
+ FinalizeState(&Klayman::stStartWalkingDone);
+ NextState(&Klayman::sub4215E0);
+ }
+}
+
void Klayman::sub41CC40(int16 x1, int16 x2) {
if (_x > x1) {
if (_x == x1 + x2) {
@@ -5254,4 +5351,167 @@ void KmScene2805::sub4048D0() {
startAnimation(0xD82A4094, 0, -1);
}
+KmScene2806::KmScene2806(NeverhoodEngine *vm, Entity *parentScene, int16 x, int16 y,
+ bool flag, NRect *clipRects, uint clipRectsCount)
+ : Klayman(vm, parentScene, x, y, 1000, 1000),
+ _soundRes1(vm), _soundRes2(vm), _soundRes3(vm), _soundRes4(vm), _soundRes5(vm) {
+ // Empty
+
+ if (flag) {
+ // TODO Maybe? Don't know. Set Klayman clip rects
+ _soundRes1.load(0x58E0C341);
+ _soundRes2.load(0x40A00342);
+ _soundRes3.load(0xD0A1C348);
+ _soundRes4.load(0x166FC6E0);
+ _soundRes5.load(0x00018040);
+ }
+
+ _dataResource.load(0x98182003);
+
+}
+
+uint32 KmScene2806::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 0x4804:
+ startWalkToX(440, true);
+ break;
+ case 0x480D:
+ GotoState(&Klayman::sub420F60);
+ break;
+ case 0x4816:
+ if (param.asInteger() == 0) {
+ GotoState(&Klayman::stPressButtonSide);
+ }
+ break;
+ case 0x4817:
+ setDoDeltaX(param.asInteger());
+ gotoNextStateExt();
+ break;
+ case 0x4818:
+ startWalkToX(_dataResource.getPoint(param.asInteger()).x, false);
+ break;
+ case 0x4831:
+ GotoState(&KmScene2806::sub40F780);
+ break;
+ case 0x4832:
+ if (param.asInteger() == 1) {
+ GotoState(&KmScene2806::sub40F7C0);
+ } else {
+ GotoState(&Klayman::sub421110);
+ }
+ break;
+ }
+ return 0;
+}
+
+uint32 KmScene2806::handleMessage40F1F0(int messageNum, const MessageParam &param, Entity *sender) {
+ uint32 messageResult = handleMessage41D480(messageNum, param, sender);
+ switch (messageNum) {
+ case 0x1008:
+ if (_flag1) {
+ startAnimationByHash(0x1C388C04, 0x004A2148, 0);
+ messageResult = 0;
+ } else
+ _flag2 = true;
+ break;
+ case 0x100D:
+ if (param.asInteger() == 0x0002418E)
+ sendMessage(_parentScene, 0x2000, 0);
+ else if (param.asInteger() == 0x924090C2) {
+ _flag1 = true;
+ if (_flag2) {
+ startAnimationByHash(0x1C388C04, 0x004A2148, 0);
+ messageResult = 0;
+ }
+ } else if (param.asInteger() == 0x004A2148)
+ _flag1 = false;
+ else if (param.asInteger() == 0x02B20220)
+ _soundResource1.play(0xC5408620);
+ else if (param.asInteger() == 0x0A720138)
+ _soundResource1.play(0xD4C08010);
+ else if (param.asInteger() == 0x03020231)
+ _soundResource1.play(0xD4C08010);
+ else if (param.asInteger() == 0xB613A180)
+ _soundResource1.play(0x44051000);
+ else if (param.asInteger() == 0x67221A03)
+ _soundResource1.play(0x44051000);
+ else if (param.asInteger() == 0x038A010B)
+ _soundResource1.play(0x00018040);
+ else if (param.asInteger() == 0x422B0280)
+ _soundResource1.play(0x166FC6E0);
+ else if (param.asInteger() == 0x925A0C1E)
+ _soundResource1.play(0x40E5884D);
+ else if (param.asInteger() == 0x00020814)
+ _soundResource1.play(0x786CC6D0);
+ else if (param.asInteger() == 0x06020500)
+ _soundResource1.play(0x1069C0E1);
+ else if (param.asInteger() == 0x02128C00)
+ _soundResource1.play(0x5068C4C3);
+ else if (param.asInteger() == 0x82022030)
+ _soundResource1.play(0x5C48C0E8);
+ break;
+ }
+ return messageResult;
+}
+
+uint32 KmScene2806::handleMessage40F570(int messageNum, const MessageParam &param, Entity *sender) {
+ uint32 messageResult = handleMessage41D480(messageNum, param, sender);
+ switch (messageNum) {
+ case 0x100D:
+ if (param.asInteger() == 0x32180101)
+ _soundResource1.play(0x405002D8);
+ else if (param.asInteger() == 0x0A2A9098)
+ _soundResource1.play(0x0460E2FA);
+ else if (param.asInteger() == 0xD00A0C0C)
+ _soundRes1.play();
+ else if (param.asInteger() == 0x04121920)
+ _soundRes2.play();
+ else if (param.asInteger() == 0x030B4480)
+ _soundRes3.play();
+ else if (param.asInteger() == 0x422B0280)
+ _soundRes4.play();
+ else if (param.asInteger() == 0x038A010B)
+ _soundRes5.play();
+ else if (param.asInteger() == 0x67221A03)
+ _soundResource1.play(0x44051000);
+ else if (param.asInteger() == 0x02B20220)
+ _soundResource1.play(0xC5408620);
+ else if (param.asInteger() == 0x925A0C1E)
+ _soundResource1.play(0x40E5884D);
+ else if (param.asInteger() == 0x03020231)
+ _soundResource1.play(0xD4C08010);
+ else if (param.asInteger() == 0x08040840)
+ setDoDeltaX(2);
+ break;
+ }
+ return messageResult;
+}
+
+void KmScene2806::sub40F780() {
+ _status2 = 0;
+ _acceptInput = false;
+ SetUpdateHandler(&Klayman::update);
+ SetSpriteUpdate(&AnimatedSprite::updateDeltaXY);
+ SetMessageHandler(&KmScene2806::handleMessage40F570);
+ startAnimation(0x2838C010, 0, -1);
+}
+
+void KmScene2806::sub40F7C0() {
+ _status2 = 1;
+ _acceptInput = false;
+ _flag1 = false;
+ _flag2 = false;
+ SetUpdateHandler(&Klayman::update);
+ SetSpriteUpdate(&AnimatedSprite::updateDeltaXY);
+ SetMessageHandler(&KmScene2806::handleMessage40F1F0);
+ startAnimation(0x1C388C04, 0, -1);
+}
+
} // End of namespace Neverhood
diff --git a/engines/neverhood/klayman.h b/engines/neverhood/klayman.h
index ab7ccb6050..27d92984a2 100644
--- a/engines/neverhood/klayman.h
+++ b/engines/neverhood/klayman.h
@@ -30,7 +30,8 @@
namespace Neverhood {
-// TODO: This code is horrible and weird and a lot of stuff needs renaming once a better name is found
+// TODO This code is horrible and weird and a lot of stuff needs renaming once a better name is found
+// TODO Also the methods should probably rearranged and be grouped together more consistently
class Klayman;
@@ -150,6 +151,13 @@ public:
void sub421900();
void sub4218C0();
void sub421880();
+ void sub420F60();
+ void sub420FB0();
+ uint32 handleMessage41E6C0(int messageNum, const MessageParam &param, Entity *sender);
+ void sub421110();
+ uint32 handleMessage41E750(int messageNum, const MessageParam &param, Entity *sender);
+ void sub4215E0();
+ void sub421550();
protected:
Entity *_parentScene;
@@ -585,6 +593,25 @@ protected:
void sub4048D0();
};
+class KmScene2806 : public Klayman {
+public:
+ KmScene2806(NeverhoodEngine *vm, Entity *parentScene, int16 x, int16 y,
+ bool flag, NRect *clipRects, uint clipRectsCount);
+protected:
+ SoundResource _soundRes1;
+ SoundResource _soundRes2;
+ SoundResource _soundRes3;
+ SoundResource _soundRes4;
+ SoundResource _soundRes5;
+ bool _flag1;
+ bool _flag2;
+ uint32 xHandleMessage(int messageNum, const MessageParam &param);
+ uint32 handleMessage40F1F0(int messageNum, const MessageParam &param, Entity *sender);
+ uint32 handleMessage40F570(int messageNum, const MessageParam &param, Entity *sender);
+ void sub40F780();
+ void sub40F7C0();
+};
+
} // End of namespace Neverhood
#endif /* NEVERHOOD_KLAYMAN_H */
diff --git a/engines/neverhood/module2800.cpp b/engines/neverhood/module2800.cpp
index 417e3f5dc8..793fc748be 100644
--- a/engines/neverhood/module2800.cpp
+++ b/engines/neverhood/module2800.cpp
@@ -86,6 +86,10 @@ void Module2800::createScene(int sceneNum, int which) {
// TODO Music18hList_stop(0xD2FA4D14, 0, 2);
_childObject = new Scene2805(_vm, this, which);
break;
+ case 5:
+ // TODO Music18hList_play(0xD2FA4D14, 0, 2, 1);
+ _childObject = new Scene2806(_vm, this, which);
+ break;
case 25:
// TODO Music18hList_play(0xD2FA4D14, 0, 2, 1);
if (getGlobalVar(0x190A1D18))
@@ -145,6 +149,13 @@ void Module2800::updateScene() {
createScene(11, 1);
}
break;
+ case 5:
+ if (_moduleResult == 1) {
+ createScene(27, 0);
+ } else {
+ createScene(2, 2);
+ }
+ break;
case 25:
createScene(2, 5);
break;
@@ -595,4 +606,126 @@ uint32 Scene2805::handleMessage(int messageNum, const MessageParam &param, Entit
return 0;
}
+Scene2806::Scene2806(NeverhoodEngine *vm, Module *parentModule, int which)
+ : Scene(vm, parentModule, true) {
+
+ Sprite *tempSprite;
+
+ _surfaceFlag = true;
+ SetMessageHandler(&Scene2806::handleMessage);
+ SetUpdateHandler(&Scene2806::update);
+
+ loadDataResource(0x98182003);
+ loadHitRectList();
+
+ _pointList = _dataResource.getPointArray(0x3606A422);
+
+ insertMouse433(0x22114C13);
+ setBackground(0xC1B22110);
+ setPalette(0xC1B22110);
+
+ _sprite1 = insertStaticSprite(0xA21F82CB, 1100);
+ _clipRects[0].x1 = _sprite1->getDrawRect().x;
+ _clipRects[0].y1 = _sprite1->getDrawRect().y;
+ _clipRects[0].x2 = _sprite1->getDrawRect().x2();
+ _clipRects[0].y2 = _sprite1->getDrawRect().y2();
+
+ _sprite2 = insertStaticSprite(0x92035301, 1100);
+ _clipRects[1].y2 = _sprite2->getDrawRect().y2();
+
+ _sprite3 = insertStaticSprite(0x3182220E, 1100);
+
+ _sprite4 = insertStaticSprite(0x72090342, 1100);
+ _clipRects[1].x1 = _sprite4->getDrawRect().x;
+ _clipRects[1].y1 = _sprite4->getDrawRect().y;
+
+ _fieldEC = true;
+
+ tempSprite = insertStaticSprite(0xD2012C02, 1100);
+ _clipRects[2].x1 = tempSprite->getDrawRect().x;
+ _clipRects[2].y2 = tempSprite->getDrawRect().y2();
+ _clipRects[3].y1 = tempSprite->getDrawRect().y2();
+ _clipRects[1].x2 = tempSprite->getDrawRect().x2();
+
+ tempSprite = insertStaticSprite(0x72875F42, 1100);
+ _clipRects[3].x1 = tempSprite->getDrawRect().x;
+
+ insertStaticSprite(0x0201410A, 1100);
+ insertStaticSprite(0x72875F42, 1100);
+
+ // TODO _class469 = insertSprite<Class469>();
+
+ _clipRects[2].y1 = 0;
+ _clipRects[3].y2 = 480;
+ _clipRects[2].x2 = 640;
+ _clipRects[3].x2 = 640;
+
+ if (which < 0) {
+ insertKlayman<KmScene2806>(441, 423, false, _clipRects, 4);
+ setMessageList(0x004AF098);
+ } else if (which == 1) {
+ insertKlayman<KmScene2806>(378, 423, false, _clipRects, 4);
+ setMessageList(0x004AF098);
+ } else if (which == 2) {
+ insertKlayman<KmScene2806>(378, 423, false, _clipRects, 4);
+ setMessageList(0x004AF0C8);
+ } else if (which == 3) {
+ insertKlayman<KmScene2806>(378, 423, true, _clipRects, 4);
+ setMessageList(0x004AF0A0);
+ setGlobalVar(0x1860C990, 0);
+ } else {
+ insertKlayman<KmScene2806>(670, 423, false, _clipRects, 4);
+ setMessageList(0x004AF090);
+ }
+
+ _pointIndex = -1;
+ findClosestPoint();
+
+}
+
+uint32 Scene2806::handleMessage(int messageNum, const MessageParam &param, Entity *sender) {
+ Scene::handleMessage(messageNum, param, sender);
+ switch (messageNum) {
+ case 0x100D:
+ if (param.asInteger() == 0x44262B12) {
+ setMessageList(0x004AF0E0);
+ }
+ break;
+ case 0x2000:
+ // TODO sendMessage(_class469, 0x2000, 0);
+ break;
+ }
+ return 0;
+}
+
+void Scene2806::update() {
+ Scene::update();
+ findClosestPoint();
+}
+
+void Scene2806::findClosestPoint() {
+
+ static const uint32 kScene2806PaletteFileHashes[] = {
+ 0x48052508,
+ 0x01139404,
+ 0x01138C04,
+ 0x01138004,
+ 0x01138604,
+ 0x086B8890
+ };
+
+ int16 x = MIN<int16>(_klayman->getX(), 639);
+ int index = 1;
+
+ while (index < (int)_pointList->size() && (*_pointList)[index].x < x)
+ ++index;
+ --index;
+
+ if (_pointIndex != index) {
+ _pointIndex = index;
+ _palette->addPalette(kScene2806PaletteFileHashes[index], 0, 64, 0);
+ }
+
+}
+
} // End of namespace Neverhood
diff --git a/engines/neverhood/module2800.h b/engines/neverhood/module2800.h
index 54b893bb5d..b672866543 100644
--- a/engines/neverhood/module2800.h
+++ b/engines/neverhood/module2800.h
@@ -87,6 +87,24 @@ protected:
uint32 handleMessage(int messageNum, const MessageParam &param, Entity *sender);
};
+class Scene2806 : public Scene {
+public:
+ Scene2806(NeverhoodEngine *vm, Module *parentModule, int which);
+protected:
+ NPointArray *_pointList;
+ int _pointIndex;
+ NRect _clipRects[4];
+ bool _fieldEC;
+ Sprite *_sprite1;
+ Sprite *_sprite2;
+ Sprite *_sprite3;
+ Sprite *_sprite4;
+ // TODO class469
+ uint32 handleMessage(int messageNum, const MessageParam &param, Entity *sender);
+ void update();
+ void findClosestPoint();
+};
+
} // End of namespace Neverhood
#endif /* NEVERHOOD_MODULE2800_H */