aboutsummaryrefslogtreecommitdiff
path: root/engines/neverhood/klayman.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'engines/neverhood/klayman.cpp')
-rw-r--r--engines/neverhood/klayman.cpp457
1 files changed, 457 insertions, 0 deletions
diff --git a/engines/neverhood/klayman.cpp b/engines/neverhood/klayman.cpp
new file mode 100644
index 0000000000..49c60932c1
--- /dev/null
+++ b/engines/neverhood/klayman.cpp
@@ -0,0 +1,457 @@
+/* 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/klayman.h"
+#include "neverhood/resourceman.h"
+
+namespace Neverhood {
+
+static const KlaymanTableItem klaymanTable1[] = {
+ {1, &Klayman::sub41FD30},
+ {1, &Klayman::sub41FDA0},
+ {1, &Klayman::sub41FDF0},
+ {1, &Klayman::sub41FE60},
+ {1, &Klayman::sub41FEB0}
+};
+
+static const KlaymanTableItem klaymanTable2[] = {
+ {1, &Klayman::sub41FD30},
+ {1, &Klayman::sub41FDA0},
+ {1, &Klayman::sub41FE60},
+ {1, &Klayman::sub41FEB0}
+};
+
+#if 0
+static const KlaymanTableItem klaymanTable3[] = {
+ {1, &Klayman::sub421430},
+ {1, &Klayman::sub421480}
+};
+#endif
+
+Klayman::Klayman(NeverhoodEngine *vm, Entity *parentScene, int16 x, int16 y, int surfacePriority, int objectPriority)
+ : AnimatedSprite(vm, objectPriority), _soundResource1(vm), _soundResource2(vm),
+ _counterMax(0), _counter(0), _flagE4(false), _counter3Max(0), _flagF8(false), _counter1(0),
+ _counter2(0), /*_field118(0), */_status2(0), _flagE5(true), _attachedSprite(NULL), _flagE1(false),
+ _status(1), _parentScene(parentScene), _flagE2(false), _flagE3(false), _flagF6(false), _flagF7(false),
+ _flagFA(false), _statusE0(0) /*, _field114(0)*/, _resourceHandle(-1), _soundFlag(false) {
+
+ // TODO
+ createSurface(surfacePriority, 320, 200);
+ _x = x;
+ _y = y;
+ _x4 = x;
+ _y4 = y;
+ _flags = 2;
+ setKlaymanTable1();
+ sub41FC80();
+ SetUpdateHandler(&Klayman::update);
+}
+
+void Klayman::xUpdate() {
+}
+
+uint32 Klayman::xHandleMessage(int messageNum, const MessageParam &param) {
+ return 0;
+}
+
+void Klayman::update() {
+}
+
+void Klayman::setKlaymanTable(const KlaymanTableItem *table, int tableCount) {
+ _table = table;
+ _tableCount = tableCount;
+ _tableMaxValue = 0;
+ for (int i = 0; i < tableCount; i++) {
+ _tableMaxValue += table[i].value;
+ }
+}
+
+void Klayman::setKlaymanTable1() {
+ setKlaymanTable(klaymanTable1, ARRAYSIZE(klaymanTable1));
+}
+
+void Klayman::setKlaymanTable2() {
+ setKlaymanTable(klaymanTable2, ARRAYSIZE(klaymanTable2));
+}
+
+void Klayman::setKlaymanTable3() {
+ // TODO setKlaymanTable(klaymanTable3, ARRAYSIZE(klaymanTable3));
+}
+
+void Klayman::sub41FD30() {
+ sub41D320(0x5B20C814, AnimationCallback(&Klayman::sub41FD40));
+}
+
+void Klayman::sub41FD40() {
+ _status2 = 1;
+ _flagE5 = true;
+ setFileHash(0x5B20C814, 0, -1);
+ SetUpdateHandler(&Klayman::update);
+ SetMessageHandler(&Klayman::handleMessage41EB10);
+ SetSpriteCallback(NULL);
+ SetAnimationCallback3(&Klayman::sub41FCF0);
+ // TODO AnimatedSprite_setCallback1(AnimationCallback(&Klayman::sub41FD90));
+}
+
+uint32 Klayman::handleMessage41EB10(int messageNum, const MessageParam &param, Entity *sender) {
+ uint32 messageResult = handleMessage41D480(messageNum, param, sender);
+ switch (messageNum) {
+ case 0x100D:
+ if (param._integer == 0x04DBC02C) {
+#if 0
+ _soundResource1.set(0x44528AA1);
+ _soundResource1.load();
+ _soundResource1.play(false);
+#endif
+ }
+ break;
+ }
+ return messageResult;
+}
+
+void Klayman::sub41FD90() {
+ // TODO _soundResource1.stop(0);
+}
+
+void Klayman::sub41FDA0() {
+ sub41D320(0xD122C137, AnimationCallback(&Klayman::sub41FDB0));
+}
+
+void Klayman::sub41FDB0() {
+ _status2 = 1;
+ _flagE5 = true;
+ setFileHash(0xD122C137, 0, -1);
+ SetUpdateHandler(&Klayman::update);
+ SetMessageHandler(&Klayman::handleMessage41E980);
+ SetSpriteCallback(NULL);
+ SetAnimationCallback3(&Klayman::sub41FCF0);
+}
+
+uint32 Klayman::handleMessage41E980(int messageNum, const MessageParam &param, Entity *sender) {
+ uint32 messageResult = handleMessage41D480(messageNum, param, sender);
+ switch (messageNum) {
+ case 0x100D:
+ if (param._integer == 0x808A0008) {
+#if 0
+ _soundResource1.set(0xD948A340);
+ _soundResource1.load();
+ _soundResource1.play(false);
+#endif
+ }
+ break;
+ }
+ return messageResult;
+}
+
+void Klayman::sub41FDF0() {
+ sub41D320(0x543CD054, AnimationCallback(&Klayman::sub41FE00));
+}
+
+void Klayman::sub41FE00() {
+ _status2 = 1;
+ _flagE5 = true;
+ setFileHash(0x543CD054, 0, -1);
+ SetUpdateHandler(&Klayman::update);
+ SetMessageHandler(&Klayman::handleMessage41E9E0);
+ SetSpriteCallback(NULL);
+ SetAnimationCallback3(&Klayman::sub41FCF0);
+ // TODO AnimatedSprite_setCallback1(AnimationCallback(&Klayman::sub41FE50));
+}
+
+void Klayman::sub41FE50() {
+ // TODO _soundResource1.stop(0);
+}
+
+uint32 Klayman::handleMessage41E9E0(int messageNum, const MessageParam &param, Entity *sender) {
+ uint32 messageResult = handleMessage41D480(messageNum, param, sender);
+ switch (messageNum) {
+ case 0x100D:
+ if (param._integer == 0x5A0F0104) {
+#if 0
+ _soundResource1.set(0x7970A100);
+ _soundResource1.load();
+ _soundResource1.play(false);
+#endif
+ } else if (param._integer == 0x9A9A0109) {
+#if 0
+ _soundResource1.set(0xD170CF04);
+ _soundResource1.load();
+ _soundResource1.play(false);
+#endif
+ } else if (param._integer == 0x989A2169) {
+#if 0
+ _soundResource1.set(0xD073CF14);
+ _soundResource1.load();
+ _soundResource1.play(false);
+#endif
+ }
+ break;
+ }
+ return messageResult;
+}
+
+void Klayman::sub41FE60() {
+ sub41D320(0x40A0C034, AnimationCallback(&Klayman::sub41FE70));
+}
+
+void Klayman::sub41FE70() {
+ _status2 = 1;
+ _flagE5 = true;
+ setFileHash(0x40A0C034, 0, -1);
+ SetUpdateHandler(&Klayman::update);
+ SetMessageHandler(&Klayman::handleMessage41EF80);
+ SetSpriteCallback(NULL);
+ SetAnimationCallback3(&Klayman::sub41FCF0);
+}
+
+uint32 Klayman::handleMessage41EF80(int messageNum, const MessageParam &param, Entity *sender) {
+ uint32 messageResult = handleMessage41D480(messageNum, param, sender);
+ switch (messageNum) {
+ case 0x100D:
+ if (param._integer == 0x0D2A0288) {
+#if 0
+ _soundResource1.set(0xD192A368);
+ _soundResource1.load();
+ _soundResource1.play(false);
+#endif
+ }
+ break;
+ }
+ return messageResult;
+}
+
+void Klayman::sub41FEB0() {
+ sub41D320(0x5120E137, AnimationCallback(&Klayman::sub41FEC0));
+}
+
+void Klayman::sub41FEC0() {
+ _status2 = 1;
+ _flagE5 = true;
+ setFileHash(0x5120E137, 0, -1);
+ SetUpdateHandler(&Klayman::update);
+ SetMessageHandler(&Klayman::handleMessage41EFE0);
+ SetSpriteCallback(NULL);
+ SetAnimationCallback3(&Klayman::sub41FCF0);
+}
+
+uint32 Klayman::handleMessage41EFE0(int messageNum, const MessageParam &param, Entity *sender) {
+ uint32 messageResult = handleMessage41D480(messageNum, param, sender);
+ switch (messageNum) {
+ case 0x100D:
+ if (param._integer == 0xC006000C) {
+#if 0
+ _soundResource1.set(0x9D406340);
+ _soundResource1.load();
+ _soundResource1.play(false);
+#endif
+ } else if (param._integer == 0x2E4A2940) {
+#if 0
+ _soundResource1.set(0x53A4A1D4);
+ _soundResource1.load();
+ _soundResource1.play(false);
+#endif
+ } else if (param._integer == 0xAA0A0860) {
+#if 0
+ _soundResource1.set(0x5BE0A3C6);
+ _soundResource1.load();
+ _soundResource1.play(false);
+#endif
+ } else if (param._integer == 0xC0180260) {
+#if 0
+ _soundResource1.set(0x5D418366);
+ _soundResource1.load();
+ _soundResource1.play(false);
+#endif
+ }
+ break;
+ }
+ return messageResult;
+}
+
+/////////////////////////////////////////////////////////////////
+
+void Klayman::sub41D320(uint32 fileHash, AnimationCb callback) {
+ _resourceHandle = _vm->_res->useResource(fileHash);
+ if (_resourceHandle != -1) {
+ // TODO _vm->_res->moveToFront(_resourceHandle);
+ SetAnimationCallback3(callback);
+ SetUpdateHandler(&Klayman::update41D2B0);
+ }
+}
+
+void Klayman::update41D2B0() {
+ // TODO Check if this odd stuff is needed or just some cache optimization
+ if (_vm->_res->isResourceDataValid(_resourceHandle)) {
+ sub41C7B0();
+ // TODO _vm->_res->moveToBack(_resourceHandle);
+ _vm->_res->unuseResource(_resourceHandle);
+ _resourceHandle = -1;
+ } else {
+ // TODO _vm->_res->moveToFront(_resourceHandle);
+ }
+ update();
+}
+
+bool Klayman::sub41CF10(AnimationCb callback) {
+ if (_status2 != 2)
+ return false;
+ _status2 = 1;
+ setFileHash(0x9A7020B8, 0, -1);
+ SetUpdateHandler(&Klayman::update);
+ SetMessageHandler(&Klayman::handleMessage41F140);
+ SetSpriteCallback(NULL);
+ SetAnimationCallback3(callback);
+ _flagE5 = false;
+ return true;
+}
+
+void Klayman::sub41C7B0() {
+ if (_callback1Cb) {
+ (this->*_callback1Cb)();
+ _callback1Cb = NULL;
+ }
+ if (_callback3Cb) {
+ AnimationCb cb = _callback3Cb;
+ _callback3Cb = NULL;
+ (this->*cb)();
+#if 0 // TODO
+ } else if (_callbackList) {
+ removeCallbackList();
+#endif
+ } else {
+ _parentScene->sendMessage(0x1006, 0, this);
+ }
+}
+
+void Klayman::sub41C770() {
+ _flagFA = false;
+ _status = 1;
+}
+
+void Klayman::sub41C790() {
+ if (_flagFA)
+ _status = 0;
+}
+
+void Klayman::sub41FC80() {
+ if (!sub41CF10(AnimationCallback(&Klayman::sub41FC80))) {
+ setFileHash(0x5420E254, 0, -1);
+ _counter = 0;
+ _counter3 = 0;
+ _counter3Max = _vm->_rnd->getRandomNumber(64) + 24;
+ SetUpdateHandler(&Klayman::update41D0F0);
+ SetMessageHandler(&Klayman::handleMessage41D360);
+ SetSpriteCallback(NULL);
+ }
+}
+
+void Klayman::update41D0F0() {
+ update();
+ _counter++;
+ if (_counter >= 720) {
+ _counter = 0;
+ if (_table) {
+ int randomValue = _vm->_rnd->getRandomNumber(_tableMaxValue);
+ for (int i = 0; i < _tableCount; i++) {
+ if (randomValue < _table[_tableCount].value) {
+ (this->*(_table[_tableCount].callback))();
+ break;
+ }
+ randomValue -= _table[_tableCount].value;
+ }
+ }
+ } else {
+ _counter3++;
+ if (_counter3 >= _counter3Max) {
+ _counter3 = 0;
+ _counter3Max = _vm->_rnd->getRandomNumber(64) + 24;
+ sub41FF00();
+ }
+ }
+}
+
+uint32 Klayman::handleMessage41D360(int messageNum, const MessageParam &param, Entity *sender) {
+ Sprite::handleMessage(messageNum, param, sender);
+ uint32 messageResult = xHandleMessage(messageNum, param);
+ switch (messageNum) {
+ case 0x1008:
+ messageResult = _flagE5;
+ break;
+ case 0x1014:
+ _attachedSprite = param._entity;
+ break;
+ case 0x1019:
+ sub41C7B0();
+ break;
+ case 0x101C:
+ sub41C770();
+ break;
+ case 0x1021:
+ sub41C790();
+ break;
+ case 0x481C:
+ _status = param._integer;
+ _flagFA = true;
+ messageResult = 1;
+ break;
+ case 0x482C:
+ if (param._integer != 0) {
+ // TODO _rectResource.getRectangle2(param._integer, &_field118, &_field114,);
+ } else {
+ // TODO _field114 = 0;
+ }
+ break;
+ }
+ return messageResult;
+}
+
+void Klayman::sub41FF00() {
+ setFileHash(0x5900C41E, 0, -1);
+ _status2 = 1;
+ _flagE5 = true;
+ SetUpdateHandler(&Klayman::update);
+ SetMessageHandler(&Klayman::handleMessage41D480);
+ SetSpriteCallback(NULL);
+ SetAnimationCallback3(&Klayman::sub41FCF0);
+}
+
+uint32 Klayman::handleMessage41D480(int messageNum, const MessageParam &param, Entity *sender) {
+ uint32 messageResult = handleMessage41D360(messageNum, param, sender);
+ switch (messageNum) {
+ case 0x3002:
+ sub41C7B0();
+ break;
+ }
+ return messageResult;
+}
+
+void Klayman::sub41FCF0() {
+ _status2 = 1;
+ _flagE5 = true;
+ setFileHash(0x5420E254, 0, -1);
+ SetUpdateHandler(&Klayman::update41D0F0);
+ SetMessageHandler(&Klayman::handleMessage41D360);
+ SetSpriteCallback(NULL);
+}
+
+
+} // End of namespace Neverhood