aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorjohndoe1232011-07-26 08:38:19 +0000
committerWillem Jan Palenstijn2013-05-08 20:39:34 +0200
commitbfd71cff6e73c0be6b2d66f7f71921094f42ca09 (patch)
tree01acbaf984c307fb7e7978706ac78d023e758ce7
parent04d2b9a4028d1f6ac7c5c5e4a6cc95f8532e9cdf (diff)
downloadscummvm-rg350-bfd71cff6e73c0be6b2d66f7f71921094f42ca09.tar.gz
scummvm-rg350-bfd71cff6e73c0be6b2d66f7f71921094f42ca09.tar.bz2
scummvm-rg350-bfd71cff6e73c0be6b2d66f7f71921094f42ca09.zip
NEVERHOOD: New modules Module1200, Module1400, Module1700 and Module1800
- Implement CollisionMan::removeSprite
-rw-r--r--engines/neverhood/blbarchive.cpp3
-rw-r--r--engines/neverhood/collisionman.cpp9
-rw-r--r--engines/neverhood/diskplayerscene.cpp563
-rw-r--r--engines/neverhood/diskplayerscene.h110
-rw-r--r--engines/neverhood/gamemodule.cpp97
-rw-r--r--engines/neverhood/gamemodule.h6
-rw-r--r--engines/neverhood/graphics.cpp9
-rw-r--r--engines/neverhood/klayman.cpp520
-rw-r--r--engines/neverhood/klayman.h56
-rw-r--r--engines/neverhood/module.mk4
-rw-r--r--engines/neverhood/module1200.cpp631
-rw-r--r--engines/neverhood/module1200.h103
-rw-r--r--engines/neverhood/module1400.cpp1439
-rw-r--r--engines/neverhood/module1400.h242
-rw-r--r--engines/neverhood/module1700.cpp359
-rw-r--r--engines/neverhood/module1700.h80
-rw-r--r--engines/neverhood/module1800.cpp300
-rw-r--r--engines/neverhood/module1800.h63
-rw-r--r--engines/neverhood/navigationscene.cpp9
-rw-r--r--engines/neverhood/navigationscene.h6
-rw-r--r--engines/neverhood/palette.cpp7
-rw-r--r--engines/neverhood/palette.h5
-rw-r--r--engines/neverhood/resource.cpp15
-rw-r--r--engines/neverhood/resource.h1
-rw-r--r--engines/neverhood/resourceman.cpp4
-rw-r--r--engines/neverhood/scene.cpp9
-rw-r--r--engines/neverhood/scene.h3
-rw-r--r--engines/neverhood/smackerplayer.cpp46
-rw-r--r--engines/neverhood/smackerplayer.h4
-rw-r--r--engines/neverhood/sprite.cpp11
-rw-r--r--engines/neverhood/sprite.h6
31 files changed, 4561 insertions, 159 deletions
diff --git a/engines/neverhood/blbarchive.cpp b/engines/neverhood/blbarchive.cpp
index 2e29485d58..6a047cab46 100644
--- a/engines/neverhood/blbarchive.cpp
+++ b/engines/neverhood/blbarchive.cpp
@@ -105,12 +105,11 @@ void BlbArchive::load(uint index, byte *buffer, uint32 size) {
byte *BlbArchive::getEntryExtData(uint index) {
BlbArchiveEntry &entry = _entries[index];
- return _extData && entry.extDataOfs != 0 ? &_extData[entry.extDataOfs - 1] : NULL;
+ return (_extData && entry.extDataOfs != 0) ? &_extData[entry.extDataOfs - 1] : NULL;
}
Common::SeekableReadStream *BlbArchive::createStream(uint index) {
const BlbArchiveEntry &entry = _entries[index];
- //debug("entry.offset = %08X; entry.offset + entry.diskSize = %08X", entry.offset, entry.offset + entry.diskSize);
return new Common::SafeSubReadStream(&_fd, entry.offset, entry.offset + entry.diskSize);
}
diff --git a/engines/neverhood/collisionman.cpp b/engines/neverhood/collisionman.cpp
index 87ec0cdcad..4296b91a10 100644
--- a/engines/neverhood/collisionman.cpp
+++ b/engines/neverhood/collisionman.cpp
@@ -52,7 +52,7 @@ void CollisionMan::setHitRects(HitRectList *hitRects) {
}
void CollisionMan::clearHitRects() {
- _hitRects = 0;
+ _hitRects = NULL;
}
HitRect *CollisionMan::findHitRectAtPos(int16 x, int16 y) {
@@ -82,7 +82,12 @@ void CollisionMan::addSprite(Sprite *sprite) {
}
void CollisionMan::removeSprite(Sprite *sprite) {
- // TODO
+ for (uint index = 0; index < _sprites.size(); index++) {
+ if (_sprites[index] == sprite) {
+ _sprites.remove_at(index);
+ break;
+ }
+ }
}
void CollisionMan::clearSprites() {
diff --git a/engines/neverhood/diskplayerscene.cpp b/engines/neverhood/diskplayerscene.cpp
new file mode 100644
index 0000000000..dd2c837dbd
--- /dev/null
+++ b/engines/neverhood/diskplayerscene.cpp
@@ -0,0 +1,563 @@
+/* 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/diskplayerscene.h"
+#include "neverhood/mouse.h"
+
+namespace Neverhood {
+
+// TODO: Maybe move hash tables into neverhood.dat
+
+static const uint32 kDiskplayerPaletteFileHashes[] = {
+ 0x03B78240,
+ 0x34B32B08,
+ 0x4F2569D4,
+ 0x07620590,
+ 0x38422401
+};
+
+static const byte kDiskplayerInitArray[] = {
+ 2, 1, 4, 5, 3, 11, 8, 6, 7, 9, 10, 17, 16, 18, 19, 20, 15, 14, 13, 12
+};
+
+static const uint32 kDiskplayerSmackerFileHashes[] = {
+ 0x010A2810,
+ 0x020A2810,
+ 0x040A2810,
+ 0x080A2810,
+ 0x100A2810,
+ 0x200A2810,
+ 0x400A2810,
+ 0x800A2810,
+ 0x000A2811,
+ 0x010C2810,
+ 0x020C2810,
+ 0x040C2810,
+ 0x080C2810,
+ 0x100C2810,
+ 0x200C2810,
+ 0x400C2810,
+ 0x800C2810,
+ 0x000C2811,
+ 0x000C2812,
+ 0x02002810,
+ 0x04002810
+};
+
+static const uint32 kDiskplayerSlotFileHashes1[] = {
+ 0x81312280,
+ 0x01312281,
+ 0x01312282,
+ 0x01312284,
+ 0x01312288,
+ 0x01312290,
+ 0x013122A0,
+ 0x013122C0,
+ 0x01312200,
+ 0x82312280,
+ 0x02312281,
+ 0x02312282,
+ 0x02312284,
+ 0x02312288,
+ 0x02312290,
+ 0x023122A0,
+ 0x023122C0,
+ 0x02312200,
+ 0x02312380,
+ 0x04312281
+};
+
+static const uint32 kDiskplayerSlotFileHashes2[] = {
+ 0x90443A00,
+ 0x90443A18,
+ 0x90443A28,
+ 0x90443A48,
+ 0x90443A88,
+ 0x90443B08,
+ 0x90443808,
+ 0x90443E08,
+ 0x90443208,
+ 0xA0443A00,
+ 0xA0443A18,
+ 0xA0443A28,
+ 0xA0443A48,
+ 0xA0443A88,
+ 0xA0443B08,
+ 0xA0443808,
+ 0xA0443E08,
+ 0xA0443208,
+ 0xA0442A08,
+ 0xC0443A18
+};
+
+static const uint32 kDiskplayerSlotFileHashes3[] = {
+ 0x10357320,
+ 0x10557320,
+ 0x10957320,
+ 0x11157320,
+ 0x12157320,
+ 0x14157320,
+ 0x18157320,
+ 0x00157320,
+ 0x30157320,
+ 0x1035B320,
+ 0x1055B320,
+ 0x1095B320,
+ 0x1115B320,
+ 0x1215B320,
+ 0x1415B320,
+ 0x1815B320,
+ 0x0015B320,
+ 0x3015B320,
+ 0x5015B320,
+ 0x10543320
+};
+
+static const uint32 kDiskplayerSlotFileHashes4[] = {
+ 0xDC8020E4,
+ 0xDC802164,
+ 0xDC802264,
+ 0xDC802464,
+ 0xDC802864,
+ 0xDC803064,
+ 0xDC800064,
+ 0xDC806064,
+ 0xDC80A064,
+ 0xDC8020E7,
+ 0xDC802167,
+ 0xDC802267,
+ 0xDC802467,
+ 0xDC802867,
+ 0xDC803067,
+ 0xDC800067,
+ 0xDC806067,
+ 0xDC80A067,
+ 0xDC812067,
+ 0xDC802161
+};
+
+Class494::Class494(NeverhoodEngine *vm)
+ : AnimatedSprite(vm, 1100) {
+
+ createSurface1(0x100B90B4, 1200);
+ _x = 211;
+ _y = 195;
+ setFileHash(0x100B90B4, 0, -1);
+ _newHashListIndex = 0;
+ _needRefresh = true;
+ updatePosition();
+ _surface->setVisible(false);
+}
+
+uint32 Class494::handleMessage(int messageNum, const MessageParam &param, Entity *sender) {
+ uint32 messageResult = Sprite::handleMessage(messageNum, param, sender);
+ switch (messageNum) {
+ case 0x3002:
+ removeCallbacks();
+ break;
+ }
+ return messageResult;
+}
+
+void Class494::sub43BE00() {
+ setFileHash1();
+ SetUpdateHandler(&AnimatedSprite::update);
+ SetMessageHandler(&Sprite::handleMessage);
+ _surface->setVisible(false);
+}
+
+void Class494::sub43BE20() {
+ setFileHash(0x100B90B4, 0, -1);
+ SetUpdateHandler(&AnimatedSprite::update);
+ SetMessageHandler(&Class494::handleMessage);
+ SetAnimationCallback3(&Class494::sub43BE00);
+ _surface->setVisible(true);
+}
+
+DiskplayerPlayButton::DiskplayerPlayButton(NeverhoodEngine *vm, DiskplayerScene *diskplayerScene)
+ : StaticSprite(vm, 1400), _soundResource1(vm), _soundResource2(vm),
+ _diskplayerScene(diskplayerScene), _isPlaying(false) {
+
+ _spriteResource.load2(0x24A4A664);
+ createSurface(400, _spriteResource.getDimensions().width, _spriteResource.getDimensions().height);
+ _drawRect.x = 0;
+ _drawRect.y = 0;
+ _drawRect.width = _spriteResource.getDimensions().width;
+ _drawRect.height = _spriteResource.getDimensions().height;
+ _deltaRect.x = 0;
+ _deltaRect.y = 0;
+ _deltaRect.width = _spriteResource.getDimensions().width;
+ _deltaRect.height = _spriteResource.getDimensions().height;
+ _x = _spriteResource.getPosition().x;
+ _y = _spriteResource.getPosition().y;
+ _surface->setVisible(false);
+ processDelta();
+ _needRefresh = true;
+ StaticSprite::update();
+ _soundResource1.load(0x44043000);
+ _soundResource2.load(0x44045000);
+ SetMessageHandler(&DiskplayerPlayButton::handleMessage);
+}
+
+uint32 DiskplayerPlayButton::handleMessage(int messageNum, const MessageParam &param, Entity *sender) {
+ uint32 messageResult = 0;
+ Sprite::handleMessage(messageNum, param, sender);
+ switch (messageNum) {
+ case 0x1011:
+ if (!_diskplayerScene->getFlag3()) {
+ if (_isPlaying) {
+ _diskplayerScene->sendMessage(0x2001, 0, this);
+ release();
+ } else {
+ _diskplayerScene->sendMessage(0x2000, 0, this);
+ press();
+ }
+ }
+ StaticSprite::update();
+ messageResult = 1;
+ break;
+ }
+ return messageResult;
+}
+
+void DiskplayerPlayButton::press() {
+ if (!_isPlaying) {
+ _surface->setVisible(true);
+ StaticSprite::update();
+ _soundResource1.play();
+ _isPlaying = true;
+ }
+}
+
+void DiskplayerPlayButton::release() {
+ if (_isPlaying) {
+ _surface->setVisible(false);
+ StaticSprite::update();
+ _soundResource2.play();
+ _isPlaying = false;
+ }
+}
+
+DiskplayerSlot::DiskplayerSlot(NeverhoodEngine *vm, DiskplayerScene *diskplayerScene, int elementIndex, int value)
+ : Entity(vm, 0), _diskplayerScene(diskplayerScene), _soundResource(vm), _elementIndex(elementIndex),
+ _value(value), _flag2(false), _flag(false), _countdown(0), _initialCountdown(2),
+ _inactiveSlot(NULL), _appearSlot(NULL), _activeSlot(NULL) {
+
+ if (value != 0 && elementIndex < 20) {
+ _inactiveSlot = _diskplayerScene->addSprite(new StaticSprite(_vm, kDiskplayerSlotFileHashes1[_elementIndex], 1100));
+ _appearSlot = _diskplayerScene->addSprite(new StaticSprite(_vm, kDiskplayerSlotFileHashes2[_elementIndex], 1000));
+ _activeSlot = _diskplayerScene->addSprite(new StaticSprite(_vm, kDiskplayerSlotFileHashes3[_elementIndex], 1100));
+ _inactiveSlot->getSurface()->setVisible(false);
+ _appearSlot->getSurface()->setVisible(false);
+ _activeSlot->getSurface()->setVisible(false);
+ _soundResource.load(0x46210074);
+ // TODO sound panning stuff
+ } else if (elementIndex != 20) {
+ _activeSlot = _diskplayerScene->addSprite(new StaticSprite(_vm, kDiskplayerSlotFileHashes4[_elementIndex], 1100));
+ _activeSlot->getSurface()->setVisible(false);
+ }
+ SetUpdateHandler(&DiskplayerSlot::update);
+}
+
+void DiskplayerSlot::update() {
+ if (_countdown != 0 && (--_countdown == 0)) {
+ if (_flag) {
+ if (_inactiveSlot) {
+ _inactiveSlot->getSurface()->setVisible(true);
+ }
+ if (_activeSlot) {
+ _activeSlot->getSurface()->setVisible(false);
+ }
+ _countdown = _initialCountdown / 2;
+ } else {
+ if (_inactiveSlot) {
+ _inactiveSlot->getSurface()->setVisible(false);
+ }
+ if (_activeSlot) {
+ _activeSlot->getSurface()->setVisible(true);
+ }
+ _countdown = _initialCountdown;
+ }
+ _flag = !_flag;
+ }
+}
+
+void DiskplayerSlot::appear() {
+ if (_inactiveSlot) {
+ _inactiveSlot->getSurface()->setVisible(true);
+ }
+ if (_appearSlot) {
+ _appearSlot->getSurface()->setVisible(true);
+ }
+ if (_inactiveSlot) {
+ _soundResource.play();
+ }
+}
+
+void DiskplayerSlot::play() {
+ if (!_flag2) {
+ if (_inactiveSlot) {
+ _inactiveSlot->getSurface()->setVisible(false);
+ }
+ if (_activeSlot) {
+ _activeSlot->getSurface()->setVisible(true);
+ }
+ _flag = true;
+ _countdown = 0;
+ }
+}
+
+void DiskplayerSlot::activate() {
+ if (!_flag2) {
+ _countdown = _initialCountdown;
+ }
+}
+
+void DiskplayerSlot::stop() {
+ if (!_flag2) {
+ if (_inactiveSlot) {
+ _inactiveSlot->getSurface()->setVisible(true);
+ }
+ if (_activeSlot) {
+ _activeSlot->getSurface()->setVisible(false);
+ }
+ _flag = false;
+ _countdown = 0;
+ }
+}
+
+DiskplayerScene::DiskplayerScene(NeverhoodEngine *vm, Module *parentModule, int which)
+ : Scene(vm, parentModule, true), _which(which), _diskIndex(0), _appearCountdown(0), _tuneInCountdown(0),
+ _fullFlag(false), _flag3(false), _inputDisabled(true), _updateStatus(0) {
+
+ int count = 0;
+
+ _surfaceFlag = true;
+
+ _background = addBackground(new DirtyBackground(_vm, 0x8A000044, 0, 0));
+ _palette = new Palette(_vm, kDiskplayerPaletteFileHashes[_which]);
+ _playButton = new DiskplayerPlayButton(_vm, this);
+ addSprite(_playButton);
+ _vm->_collisionMan->addSprite(_playButton);
+ _class494 = new Class494(_vm);
+ addSprite(_class494);
+
+ // DEBUG: Give all disks
+ for (int i = 0; i < 19; i++) {
+ setSubVar(0x02720344, i, 1);
+ }
+
+ for (int i = 0; i < 20; i++) {
+ _diskAvailable[i] = 0;
+ if (getSubVar(0x02720344, i))
+ count++;
+ }
+
+ for (int i = 0; i < count; i++) {
+ _diskAvailable[kDiskplayerInitArray[i] - 1] = 1;
+ }
+
+ for (int i = 0; i < 20; i++) {
+ _diskSlots[i] = new DiskplayerSlot(_vm, this, i, _diskAvailable[i]);
+ addEntity(_diskSlots[i]);
+ }
+
+ _fullFlag = count == 20;
+
+ if (_fullFlag && !getGlobalVar(0xC0780812))
+ _flag3 = true;
+
+ _flag4 = _flag3;
+
+ _class650 = new DiskplayerSlot(_vm, this, 20, 0);
+ addEntity(_class650);
+
+ _mouseCursor = addSprite(new Mouse435(_vm, 0x000408A8, 20, 620));
+ _mouseCursor->getSurface()->setVisible(false);
+
+ _smackerPlayer = new SmackerPlayer(_vm, this, 0x08288103, false, true);
+ addEntity(_smackerPlayer);
+ addSurface(_smackerPlayer->getSurface());
+ _smackerPlayer->setDrawPos(154, 86);
+ // TODO _smackerPlayer->gotoFrame(0);
+
+ _palette->usePalette();
+
+ SetMessageHandler(&DiskplayerScene::handleMessage);
+ SetUpdateHandler(&DiskplayerScene::update);
+ _appearCountdown = 6;
+
+}
+
+void DiskplayerScene::update() {
+ Scene::update();
+
+ debug("_updateStatus = %d", _updateStatus);
+
+ if (_updateStatus == 1) {
+ if (_smackerPlayer->getFrameNumber() == _smackerPlayer->getFrameCount() - 1) {
+ if (_diskAvailable[_diskIndex]) {
+ playDisk();
+ } else {
+ playStatic();
+ }
+ }
+ } else if (_updateStatus == 2) {
+ if (_smackerPlayer->getFrameNumber() == _smackerPlayer->getFrameCount() - 1) {
+ _diskSlots[_diskIndex]->stop();
+ _diskIndex++;
+ if (_fullFlag) {
+ if (_diskIndex == 20) {
+ if (_flag3) {
+ playDisk();
+ _updateStatus = 3;
+ } else {
+ _diskIndex = 0;
+ stop();
+ }
+ } else {
+ playDisk();
+ }
+ } else {
+ if (_diskIndex == 20) {
+ _diskIndex = 0;
+ stop();
+ } else {
+ tuneIn();
+ }
+ }
+ }
+ } else if (_updateStatus == 3) {
+ if (_smackerPlayer->getFrameNumber() == 133) {
+ _class494->sub43BE20();
+ setGlobalVar(0xC0780812, 1);
+ } else if (_smackerPlayer->getFrameNumber() == _smackerPlayer->getFrameCount() - 1) {
+ for (int i = 0; i < 20; i++) {
+ _diskSlots[i]->setFlag2(false);
+ _diskSlots[i]->stop();
+ }
+ _diskIndex = 0;
+ stop();
+ _mouseCursor->getSurface()->setVisible(true);
+ _flag3 = false;
+ }
+ }
+
+ if (_appearCountdown != 0 && (--_appearCountdown == 0)) {
+ _diskSlots[_diskIndex]->appear();
+ if (_flag3) {
+ _diskSlots[_diskIndex]->activate();
+ _diskSlots[_diskIndex]->setFlag2(true);
+ }
+ _diskIndex++;
+ while (_diskAvailable[_diskIndex] == 0 && _diskIndex < 19)
+ _diskIndex++;
+ if (_diskIndex < 20) {
+ _appearCountdown = 1;
+ } else {
+ _diskIndex = 0;
+ _inputDisabled = false;
+ if (_flag3) {
+ _playButton->press();
+ _tuneInCountdown = 2;
+ } else {
+ _mouseCursor->getSurface()->setVisible(true);
+ _diskSlots[_diskIndex]->activate();
+ }
+ }
+ }
+
+ if (_tuneInCountdown != 0 && (--_tuneInCountdown == 0)) {
+ playDisk();
+ }
+
+}
+
+uint32 DiskplayerScene::handleMessage(int messageNum, const MessageParam &param, Entity *sender) {
+ uint32 messageResult = 0;
+ Scene::handleMessage(messageNum, param, sender);
+ if (!_inputDisabled) {
+ switch (messageNum) {
+ case 0x0001:
+ // TODO: Debug/Cheat
+ if (param.asPoint().x <= 20 || param.asPoint().x >= 620) {
+ _parentModule->sendMessage(0x1009, 0, this);
+ } else if (!_flag3 &&
+ param.asPoint().x > 38 && param.asPoint().x < 598 &&
+ param.asPoint().y > 400 && param.asPoint().y < 460) {
+
+ _diskSlots[_diskIndex]->stop();
+ _diskIndex = (param.asPoint().x - 38) / 28;
+ _diskSlots[_diskIndex]->activate();
+ if (_updateStatus == 2) {
+ if (_diskAvailable[_diskIndex]) {
+ playDisk();
+ } else {
+ playStatic();
+ }
+ }
+ }
+ break;
+ // case 0x000D: TODO: Debug/Cheat
+ case 0x2000:
+ tuneIn();
+ break;
+ case 0x2001:
+ stop();
+ break;
+ }
+ }
+ return messageResult;
+}
+
+void DiskplayerScene::stop() {
+ _smackerPlayer->open(0x08288103, true);
+ _palette->usePalette();
+ _playButton->release();
+ _updateStatus = 0;
+ _diskSlots[_diskIndex]->activate();
+}
+
+void DiskplayerScene::tuneIn() {
+ _smackerPlayer->open(0x900001C1, false);
+ _palette->usePalette();
+ _playButton->release();
+ _updateStatus = 1;
+ _diskSlots[_diskIndex]->activate();
+}
+
+void DiskplayerScene::playDisk() {
+ _smackerPlayer->open(kDiskplayerSmackerFileHashes[_diskIndex], false);
+ _palette->usePalette();
+ _updateStatus = 2;
+ _diskSlots[_diskIndex]->play();
+}
+
+void DiskplayerScene::playStatic() {
+ _smackerPlayer->open(0x90000101, false);
+ _palette->usePalette();
+ _playButton->release();
+ _updateStatus = 2;
+ _diskSlots[_diskIndex]->activate();
+}
+
+} // End of namespace Neverhood
diff --git a/engines/neverhood/diskplayerscene.h b/engines/neverhood/diskplayerscene.h
new file mode 100644
index 0000000000..7969a7a03b
--- /dev/null
+++ b/engines/neverhood/diskplayerscene.h
@@ -0,0 +1,110 @@
+/* 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.
+ *
+ */
+
+#ifndef NEVERHOOD_DISKPLAYERSCENE_H
+#define NEVERHOOD_DISKPLAYERSCENE_H
+
+#include "neverhood/neverhood.h"
+#include "neverhood/resourceman.h"
+#include "neverhood/scene.h"
+#include "neverhood/smackerplayer.h"
+
+namespace Neverhood {
+
+class DiskplayerScene;
+
+class Class494 : public AnimatedSprite {
+public:
+ Class494(NeverhoodEngine *vm);
+ void sub43BE20();
+protected:
+ uint32 handleMessage(int messageNum, const MessageParam &param, Entity *sender);
+ void sub43BE00();
+};
+
+class DiskplayerPlayButton : public StaticSprite {
+public:
+ DiskplayerPlayButton(NeverhoodEngine *vm, DiskplayerScene *diskplayerScene);
+ void press();
+ void release();
+protected:
+ DiskplayerScene *_diskplayerScene;
+ SoundResource _soundResource1;
+ SoundResource _soundResource2;
+ bool _isPlaying;
+ uint32 handleMessage(int messageNum, const MessageParam &param, Entity *sender);
+};
+
+class DiskplayerSlot : public Entity {
+public:
+ DiskplayerSlot(NeverhoodEngine *vm, DiskplayerScene *diskplayerScene, int elementIndex, int value);
+ void activate();
+ void stop();
+ void appear();
+ void play();
+ void setFlag2(bool value) { _flag2 = value; }
+protected:
+ DiskplayerScene *_diskplayerScene;
+ SoundResource _soundResource;
+ Sprite *_inactiveSlot;
+ Sprite *_appearSlot;
+ Sprite *_activeSlot;
+ int _elementIndex;
+ int _initialCountdown;
+ int _countdown;
+ bool _flag2;
+ int _value;
+ bool _flag;
+ void update();
+};
+
+class DiskplayerScene : public Scene {
+public:
+ DiskplayerScene(NeverhoodEngine *vm, Module *parentModule, int which);
+ bool getFlag3() const { return _flag3; }
+protected:
+ SmackerPlayer *_smackerPlayer;
+ DiskplayerPlayButton *_playButton;
+ Class494 *_class494;
+ DiskplayerSlot *_diskSlots[20];
+ DiskplayerSlot *_class650;
+ int _updateStatus;
+ byte _diskAvailable[20];
+ bool _flag4;
+ int _which;
+ int _diskIndex;
+ int _appearCountdown;
+ int _tuneInCountdown;
+ bool _fullFlag;
+ bool _inputDisabled;
+ bool _flag3;
+ void update();
+ uint32 handleMessage(int messageNum, const MessageParam &param, Entity *sender);
+ void stop();
+ void tuneIn();
+ void playDisk();
+ void playStatic();
+};
+
+} // End of namespace Neverhood
+
+#endif /* NEVERHOOD_DISKPLAYERSCENE_H */
diff --git a/engines/neverhood/gamemodule.cpp b/engines/neverhood/gamemodule.cpp
index 95a6a5f48a..02ae2a7cac 100644
--- a/engines/neverhood/gamemodule.cpp
+++ b/engines/neverhood/gamemodule.cpp
@@ -25,7 +25,10 @@
#include "neverhood/graphics.h"
#include "neverhood/module1000.h"
#include "neverhood/module1200.h"
+#include "neverhood/module1400.h"
#include "neverhood/module1500.h"
+#include "neverhood/module1700.h"
+#include "neverhood/module1800.h"
#include "neverhood/module2300.h"
namespace Neverhood {
@@ -110,8 +113,13 @@ void GameModule::startup() {
// TODO: Displaying of error text probably not needed in ScummVM
// createModule1500(0); // Logos and intro video //Real
// createModule1000(-1);
-// createModule2300(0);
- createModule1200(0);
+// createModule2300(2);
+ _vm->gameState().sceneNum = 6;
+ //createModule1200(-1);
+ //createModule1800(-1);
+ //createModule1700(-1);
+ //createModule1700(1);
+ createModule1400(-1);
}
void GameModule::createModule1000(int which) {
@@ -149,6 +157,7 @@ void GameModule::updateModule1200() {
delete _childObject;
_childObject = NULL;
if (_field20 == 1) {
+ error("// TODO createModule2600(0);");
// TODO createModule2600(0);
// TODO _childObject->handleUpdate();
} else {
@@ -158,6 +167,29 @@ void GameModule::updateModule1200() {
}
}
+void GameModule::createModule1400(int which) {
+ setGlobalVar(0x91080831, 0x00AD0012);
+ _childObject = new Module1400(_vm, this, which);
+ SetUpdateHandler(&GameModule::updateModule1400);
+}
+
+void GameModule::updateModule1400() {
+ if (!_childObject)
+ return;
+ _childObject->handleUpdate();
+ if (_done) {
+ _done = false;
+ delete _childObject;
+ _childObject = NULL;
+ if (_field20 == 1) {
+ error("WEIRD!");
+ } else {
+ // TODO createModule1600(1);
+ // TODO _childObject->handleUpdate();
+ }
+ }
+}
+
void GameModule::createModule1500(int which) {
_someFlag1 = false;
setGlobalVar(0x91080831, 0x00F10114);
@@ -178,6 +210,61 @@ void GameModule::updateModule1500() {
}
}
+void GameModule::createModule1700(int which) {
+ setGlobalVar(0x91080831, 0x04212331);
+ _childObject = new Module1700(_vm, this, which);
+ SetUpdateHandler(&GameModule::updateModule1700);
+}
+
+void GameModule::updateModule1700() {
+ if (!_childObject)
+ return;
+ _childObject->handleUpdate();
+ if (_done) {
+ _done = false;
+ delete _childObject;
+ _childObject = NULL;
+ debug("Module1700 done; _field20 = %d", _field20);
+ if (_field20 == 1) {
+ // TODO createModule2900(3);
+ // TODO _childObject->handleUpdate();
+ } else {
+ // TODO createModule1600(2);
+ // TODO _childObject->handleUpdate();
+ }
+ }
+}
+
+void GameModule::createModule1800(int which) {
+ setGlobalVar(0x91080831, 0x04A14718);
+ _childObject = new Module1800(_vm, this, which);
+ SetUpdateHandler(&GameModule::updateModule1800);
+}
+
+void GameModule::updateModule1800() {
+ if (!_childObject)
+ return;
+ _childObject->handleUpdate();
+ if (_done) {
+ _done = false;
+ delete _childObject;
+ _childObject = NULL;
+ if (_field20 == 1) {
+ // TODO GameState_clear();
+ // TODO GameModule_handleKeyEscape();
+ } else if (_field20 == 2) {
+ // TODO createModule2700(0);
+ // TODO _childObject->handleUpdate();
+ } else if (_field20 == 3) {
+ // TODO createModule3000(3);
+ // TODO _childObject->handleUpdate();
+ } else {
+ // TODO createModule2800(0);
+ // TODO _childObject->handleUpdate();
+ }
+ }
+}
+
void GameModule::createModule2300(int which) {
setGlobalVar(0x91080831, 0x1A214010);
_childObject = new Module2300(_vm, this, which);
@@ -223,13 +310,11 @@ void GameModule::updateModule2300() {
}
void GameModule::createModule2400(int which) {
- debug("createModule2400");
- _vm->_system->quit();
+ error("createModule2400");
}
void GameModule::createModule3000(int which) {
- debug("createModule3000");
- _vm->_system->quit();
+ error("createModule3000");
}
} // End of namespace Neverhood
diff --git a/engines/neverhood/gamemodule.h b/engines/neverhood/gamemodule.h
index d95c31e47d..344a78ff60 100644
--- a/engines/neverhood/gamemodule.h
+++ b/engines/neverhood/gamemodule.h
@@ -53,8 +53,14 @@ protected:
void updateModule1000();
void createModule1200(int which);
void updateModule1200();
+ void createModule1400(int which);
+ void updateModule1400();
void createModule1500(int which);
void updateModule1500();
+ void createModule1700(int which);
+ void updateModule1700();
+ void createModule1800(int which);
+ void updateModule1800();
void createModule2200(int which);
void createModule2300(int which);
void updateModule2300();
diff --git a/engines/neverhood/graphics.cpp b/engines/neverhood/graphics.cpp
index e46d4eaf86..204e38628d 100644
--- a/engines/neverhood/graphics.cpp
+++ b/engines/neverhood/graphics.cpp
@@ -43,7 +43,7 @@ BaseSurface::BaseSurface(NeverhoodEngine *vm, int priority, int16 width, int16 h
_clipRect.x2 = 640;
_clipRect.y2 = 480;
_surface = new Graphics::Surface();
- _surface->create(width, height, Graphics::PixelFormat::createFormatCLUT8());
+ _surface->create(_sysRect.width, _sysRect.height, Graphics::PixelFormat::createFormatCLUT8());
}
BaseSurface::~BaseSurface() {
@@ -51,7 +51,6 @@ BaseSurface::~BaseSurface() {
}
void BaseSurface::draw() {
- debug(8, "BaseSurface::draw()");
if (_surface && _visible && _drawRect.width > 0 && _drawRect.height > 0) {
// TODO: _sysRect alternate drawing code (is that used?)
_vm->_screen->drawSurface2(_surface, _drawRect, _clipRect, _transparent);
@@ -223,9 +222,9 @@ void unpackSpriteRle(byte *source, int width, int height, byte *dest, int destPi
skip = READ_LE_UINT16(source);
copy = READ_LE_UINT16(source + 2);
source += 4;
- if (!flipX)
+ if (!flipX) {
memcpy(dest + skip, source, copy);
- else {
+ } else {
byte *flipDest = dest + width - skip - 1;
for (int xc = 0; xc < copy; xc++) {
*flipDest-- = source[xc];
@@ -247,8 +246,6 @@ void unpackSpriteRleRepl(byte *source, int width, int height, byte *dest, int de
// TODO: Flip Y
- debug("unpackSpriteRleRepl(%d, %d)", oldColor, newColor);
-
int16 rows, chunks;
int16 skip, copy;
diff --git a/engines/neverhood/klayman.cpp b/engines/neverhood/klayman.cpp
index 91de87d7f5..b24e3eb6b4 100644
--- a/engines/neverhood/klayman.cpp
+++ b/engines/neverhood/klayman.cpp
@@ -266,6 +266,172 @@ uint32 Klayman::handleMessage41EFE0(int messageNum, const MessageParam &param, E
return messageResult;
}
+void Klayman::sub421350() {
+ _status2 = 0;
+ _flagE5 = true;
+ setFileHash(0x582EC138, 0, -1);
+ _counter = 0;
+ SetSpriteCallback(NULL);
+ SetUpdateHandler(&Klayman::update41D1C0);
+ SetMessageHandler(&Klayman::handleMessage41D360);
+ _counter3 = 0;
+ _counterMax = 8;
+ _counter3Max = _vm->_rnd->getRandomNumber(64) + 24;
+}
+
+void Klayman::update41D1C0() {
+ update();
+ _counter++;
+ if (_counter >= _counterMax) {
+ _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))();
+ _counterMax = _vm->_rnd->getRandomNumber(128) + 24;
+ break;
+ }
+ randomValue -= _table[_tableCount].value;
+ }
+ }
+ } else {
+ _counter3++;
+ if (_counter3 >= _counter3Max) {
+ _counter3 = 0;
+ _counter3Max = _vm->_rnd->getRandomNumber(64) + 24;
+ sub4213F0();
+ }
+ }
+}
+
+void Klayman::sub4213F0() {
+ _status2 = 0;
+ _flagE5 = true;
+ setFileHash(0x5C24C018, 0, -1);
+ SetUpdateHandler(&Klayman::update);
+ SetMessageHandler(&Klayman::handleMessage41D480);
+ SetSpriteCallback(NULL);
+ SetAnimationCallback3(&Klayman::sub4213B0);
+}
+
+void Klayman::sub4213B0() {
+ _status2 = 0;
+ _flagE5 = true;
+ setFileHash(0x5C24C018, 0, -1);
+ SetUpdateHandler(&Klayman::update41D1C0);
+ SetMessageHandler(&Klayman::handleMessage41D360);
+ SetSpriteCallback(NULL);
+}
+
+void Klayman::sub420060() {
+ setDoDeltaX(((Sprite*)_attachedSprite)->getX() < _x ? 1 : 0);
+ if (!sub41CEB0(AnimationCallback(&Klayman::sub420060))) {
+ _status2 = 1;
+ _flagE5 = false;
+ setFileHash(0x1449C169, 0, -1);
+ SetUpdateHandler(&Klayman::update);
+ SetMessageHandler(&Klayman::handleMessage41D4C0);
+ SetSpriteCallback(NULL);
+ }
+}
+
+void Klayman::sub41FFF0() {
+ setDoDeltaX(((Sprite*)_attachedSprite)->getX() < _x ? 1 : 0);
+ if (!sub41CEB0(AnimationCallback(&Klayman::sub41FFF0))) {
+ _status2 = 1;
+ _flagE5 = false;
+ setFileHash(0x0018C032, 0, -1);
+ SetUpdateHandler(&Klayman::update);
+ SetMessageHandler(&Klayman::handleMessage41D640);
+ SetSpriteCallback(NULL);
+ }
+}
+
+uint32 Klayman::handleMessage41D640(int messageNum, const MessageParam &param, Entity *sender) {
+ uint32 messageResult = handleMessage41D480(messageNum, param, sender);
+ switch (messageNum) {
+ case 0x100D:
+ if (param.asInteger() == 0xC1380080) {
+ if (_attachedSprite) {
+ _attachedSprite->sendMessage(0x4806, 0, this);
+ _soundResource1.play(0xC8004340);
+ }
+ } else if (param.asInteger() == 0x02B20220) {
+ _soundResource1.play(0xC5408620);
+ } else if (param.asInteger() == 0x03020231) {
+ _soundResource1.play(0xD4C08010);
+ } else if (param.asInteger() == 0x67221A03) {
+ _soundResource1.play(0x44051000);
+ } else if (param.asInteger() == 0x925A0C1E) {
+ _soundResource1.play(0x40E5884D);
+ }
+ break;
+ }
+ return messageResult;
+}
+
+void Klayman::sub4214D0() {
+ _status2 = 0;
+ _flagE5 = false;
+ setFileHash(0xD229823D, 0, -1);
+ SetUpdateHandler(&Klayman::update);
+ SetMessageHandler(&Klayman::handleMessage41D480);
+ SetSpriteCallback(NULL);
+}
+
+void Klayman::sub421510() {
+ _status2 = 0;
+ _flagE5 = false;
+ setFileHash(0x9A2801E0, 0, -1);
+ SetUpdateHandler(&Klayman::update);
+ SetMessageHandler(&Klayman::handleMessage41D480);
+ SetSpriteCallback(NULL);
+}
+
+void Klayman::sub421160() {
+ if (!sub41CEB0(AnimationCallback(&Klayman::sub421160))) {
+ _status2 = 2;
+ _flagE5 = false;
+ setFileHash(0x004AA310, 0, -1);
+ SetUpdateHandler(&Klayman::update);
+ SetMessageHandler(&Klayman::handleMessage41EC70);
+ SetSpriteCallback(&Klayman::spriteUpdate41F230);
+ }
+}
+
+void Klayman::sub4212C0() {
+ if (!sub41CEB0(AnimationCallback(&Klayman::sub4212C0))) {
+ _status2 = 0;
+ _flagE5 = false;
+ setFileHash(0x392A0330, 0, -1);
+ SetUpdateHandler(&Klayman::update);
+ SetMessageHandler(&Klayman::handleMessage41EAB0);
+ SetSpriteCallback(&Klayman::spriteUpdate41F230);
+ }
+}
+
+uint32 Klayman::handleMessage41EAB0(int messageNum, const MessageParam &param, Entity *sender) {
+ uint32 messageResult = handleMessage41D480(messageNum, param, sender);
+ switch (messageNum) {
+ case 0x100D:
+ if (param.asInteger() == 0x001A2832) {
+ _soundResource1.play(0xC0E4884C);
+ }
+ break;
+ }
+ return messageResult;
+}
+
+void Klayman::sub421310() {
+ _status2 = 0;
+ _flagE5 = false;
+ setFileHash(0x913AB120, 0, -1);
+ SetUpdateHandler(&Klayman::update);
+ SetMessageHandler(&Klayman::handleMessage41D480);
+ SetSpriteCallback(&Klayman::spriteUpdate41F230);
+}
+
/////////////////////////////////////////////////////////////////
void Klayman::sub41D320(uint32 fileHash, AnimationCb callback) {
@@ -460,7 +626,6 @@ uint32 Klayman::handleMessage41F140(int messageNum, const MessageParam &param, E
void Klayman::sub41C930(int16 x, bool flag) {
debug("Klayman::sub41C930(%d, %d)", x, flag);
int16 xdiff = ABS(x - _x);
- debug("xdiff = %d", xdiff);
if (x == _x) {
_x4 = x;
if (!_flagE1 && !_flagE2 && !_flagE3) {
@@ -623,7 +788,7 @@ void Klayman::sub41FB40() {
_status2 = 1;
_flagE2 = true;
_flagE5 = true;
- setDoDeltaX(_x4 < _x);
+ setDoDeltaX(_x4 < _x ? 1 : 0);
setFileHash(0x5C48C506, 0, -1);
SetUpdateHandler(&Klayman::update);
SetMessageHandler(&Klayman::handleMessage41DD80);
@@ -688,10 +853,7 @@ void Klayman::sub41F950() {
_status2 = 0;
_flagE1 = true;
_flagE5 = true;
-
- debug("222222222222222222222 x = %d; x4 = %d", _x, _x4);
-
- setDoDeltaX(_x4 < _x);
+ setDoDeltaX(_x4 < _x ? 1 : 0);
setFileHash(0x242C0198, 0, -1);
SetUpdateHandler(&Klayman::update);
SetMessageHandler(&Klayman::handleMessage41EC70);
@@ -823,9 +985,6 @@ void Klayman::spriteUpdate41F320() {
sendMessage(0x1019, 0, this);
} else {
HitRect *hitRectPrev = _vm->_collisionMan->findHitRectAtPos(_x, _y);
-
- debug("xxxxxxxxxxxxxxxxxxxxxxxxx xdelta = %d", xdelta);
-
_x += xdelta;
if (_field114) {
error("_field114");
@@ -876,7 +1035,7 @@ uint32 Klayman::handleMessage41E210(int messageNum, const MessageParam &param, E
}
void Klayman::sub41FF80() {
- setDoDeltaX(((Sprite*)_attachedSprite)->getX() < _x);
+ setDoDeltaX(((Sprite*)_attachedSprite)->getX() < _x ? 1 : 0);
if (!sub41CEB0(AnimationCallback(&Klayman::sub41FF80))) {
_status2 = 1;
_flagE5 = false;
@@ -985,28 +1144,22 @@ void Klayman::sub41CD00(int16 x) {
void Klayman::sub41CC40(int16 x1, int16 x2) {
if (_x > x1) {
if (_x == x1 + x2) {
- debug("sub41CC40 #1");
_x4 = x1 + x2;
setCallback2(NULL);
sub41C7B0();
} else if (_x < x1 + x2) {
- debug("sub41CC40 #2");
sub41CAC0(x1 + x2);
} else {
- debug("sub41CC40 #3");
sub41C930(x1 + x2, false);
}
} else {
if (_x == x1 - x2) {
- debug("sub41CC40 #4");
_x4 = x1 - x2;
setCallback2(NULL);
sub41C7B0();
} else if (_x > x1 - x2) {
- debug("sub41CC40 #5");
sub41CAC0(x1 - x2);
} else {
- debug("sub41CC40 #6");
sub41C930(x1 - x2, false);
}
}
@@ -1044,7 +1197,7 @@ void Klayman::sub41FBC0() {
_status2 = 2;
_flagE3 = true;
_flagE5 = true;
- setDoDeltaX(_x4 >= _x);
+ setDoDeltaX(_x4 >= _x ? 1 : 0);
setFileHash(0x08B28116, 0, -1);
SetUpdateHandler(&Klayman::update);
SetMessageHandler(&Klayman::handleMessage41DF10);
@@ -1641,6 +1794,68 @@ void Klayman::spriteUpdate41F5A0() {
AnimatedSprite::updateDeltaXY();
}
+void Klayman::sub420600() {
+ setDoDeltaX(((Sprite*)_attachedSprite)->getX() < _x ? 1 : 0);
+ _flagE4 = false;
+ _flagE5 = true;
+ setFileHash2(0x0C1CA072, 0x01084280, 0);
+ SetUpdateHandler(&Klayman::update);
+ SetSpriteCallback(&Klayman::spriteUpdate41F230);
+ SetMessageHandler(&Klayman::handleMessage41D970);
+}
+
+void Klayman::sub420660() {
+ _attachedSprite->sendMessage(0x4807, 0, this);
+}
+
+uint32 Klayman::handleMessage41D970(int messageNum, const MessageParam &param, Entity *sender) {
+ switch (messageNum) {
+ case 0x100D:
+ if (param.asInteger() == 0x01084280) {
+ if (_attachedSprite)
+ _attachedSprite->sendMessage(0x480B, _doDeltaX ? 1 : 0, this);
+ } else if (param.asInteger() == 0x02421405) {
+ if (_flagE4 && _attachedSprite->hasMessageHandler() && _attachedSprite->sendMessage(0x480C, _doDeltaX ? 1 : 0, this) != 0) {
+ sub4205C0();
+ } else {
+ setCallback1(AnimationCallback(&Klayman::sub420660));
+ SetMessageHandler(&Klayman::handleMessage41D480);
+ }
+ } else if (param.asInteger() == 0x32180101) {
+ _soundResource1.play(0x405002D8);
+ } else if (param.asInteger() == 0x0A2A9098) {
+ _soundResource1.play(0x0460E2FA);
+ }
+ break;
+ case 0x480A:
+ _flagE4 = true;
+ return 0;
+ }
+ return handleMessage41D480(messageNum, param, sender);
+}
+
+void Klayman::sub4205C0() {
+ _flagE4 = false;
+ _flagE5 = true;
+ setFileHash2(0x0C1CA072, 0x01084280, 0);
+ SetUpdateHandler(&Klayman::update);
+ SetSpriteCallback(&Klayman::spriteUpdate41F230);
+ SetMessageHandler(&Klayman::handleMessage41D970);
+}
+
+void Klayman::sub420550() {
+ setDoDeltaX(((Sprite*)_attachedSprite)->getX() < _x ? 1 : 0);
+ if (!sub41CEB0(AnimationCallback(&Klayman::sub420550))) {
+ _status2 = 2;
+ _flagE4 = false;
+ _flagE5 = true;
+ setFileHash(0x0C1CA072, 0, -1);
+ SetUpdateHandler(&Klayman::update);
+ SetSpriteCallback(&Klayman::spriteUpdate41F230);
+ SetMessageHandler(&Klayman::handleMessage41D970);
+ }
+}
+
//##############################################################################
// KmScene1001
@@ -1705,7 +1920,7 @@ uint32 KmScene1001::xHandleMessage(int messageNum, const MessageParam &param) {
}
break;
case 0x482D:
- setDoDeltaX(_x > (int16)param.asInteger());
+ setDoDeltaX(_x > (int16)param.asInteger() ? 1 : 0);
sub41C7B0();
break;
case 0x4836:
@@ -2401,7 +2616,7 @@ uint32 KmScene1201::xHandleMessage(int messageNum, const MessageParam &param) {
}
break;
case 0x4817:
- setDoDeltaX(param.asInteger() != 0 ? 1 : 0);
+ setDoDeltaX(param.asInteger());
sub41C7B0();
break;
case 0x481B:
@@ -2563,4 +2778,271 @@ void KmScene1201::sub40E040() {
}
}
+// KmScene1401
+
+KmScene1401::KmScene1401(NeverhoodEngine *vm, Entity *parentScene, int16 x, int16 y)
+ : Klayman(vm, parentScene, x, y, 1000, 1000) {
+
+ // Empty
+}
+
+uint32 KmScene1401::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 0x480A:
+ if (param.asInteger() == 1) {
+ setCallback2(AnimationCallback(&Klayman::sub420600));
+ } else {
+ setCallback2(AnimationCallback(&Klayman::sub420550));
+ }
+ 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 0x481B:
+ if (param.asPoint().y != 0) {
+ sub41CC40(param.asPoint().y, param.asPoint().x);
+ } else {
+ sub41CCE0(param.asPoint().x);
+ }
+ break;
+ case 0x481F:
+ if (param.asInteger() == 1) {
+ setCallback2(AnimationCallback(&Klayman::sub420930));
+ } else if (param.asInteger() == 0) {
+ setCallback2(AnimationCallback(&Klayman::sub4208F0));
+ } else {
+ setCallback2(AnimationCallback(&Klayman::sub420830));
+ }
+ break;
+ case 0x482D:
+ setDoDeltaX(_x > (int16)param.asInteger() ? 1 : 0);
+ sub41C7B0();
+ break;
+ case 0x482E:
+ if (param.asInteger() == 1) {
+ setCallback2(AnimationCallback(&Klayman::sub421030));
+ } else {
+ setCallback2(AnimationCallback(&Klayman::sub420FE0));
+ }
+ break;
+ case 0x482F:
+ if (param.asInteger() == 1) {
+ setCallback2(AnimationCallback(&Klayman::sub4210C0));
+ } else {
+ setCallback2(AnimationCallback(&Klayman::sub421070));
+ }
+ break;
+ }
+ return 0;
+}
+
+// KmScene1402
+
+KmScene1402::KmScene1402(NeverhoodEngine *vm, Entity *parentScene, int16 x, int16 y)
+ : Klayman(vm, parentScene, x, y, 1000, 1000) {
+
+ SetFilterY(&Sprite::defFilterY);
+}
+
+uint32 KmScene1402::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 0x480A:
+ if (param.asInteger() == 1) {
+ setCallback2(AnimationCallback(&Klayman::sub420600));
+ } else {
+ setCallback2(AnimationCallback(&Klayman::sub420550));
+ }
+ break;
+ case 0x4817:
+ setDoDeltaX(param.asInteger());
+ sub41C7B0();
+ 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;
+ }
+ return 0;
+}
+
+// KmScene1705
+
+KmScene1705::KmScene1705(NeverhoodEngine *vm, Entity *parentScene, int16 x, int16 y)
+ : Klayman(vm, parentScene, x, y, 1000, 1000), _flag(false) {
+
+ // Empty
+}
+
+uint32 KmScene1705::xHandleMessage(int messageNum, const MessageParam &param) {
+ uint32 messageResult = 0;
+ switch (messageNum) {
+ case 0x2000:
+ _flag = param.asInteger() != 0;
+ messageResult = 1;
+ break;
+ case 0x4001:
+ case 0x4800:
+ sub41C930(param.asPoint().x, false);
+ break;
+ case 0x4004:
+ if (_flag) {
+ setCallback2(AnimationCallback(&Klayman::sub421350));
+ } else {
+ setCallback2(AnimationCallback(&Klayman::sub41FC80));
+ }
+ break;
+ case 0x4803:
+ setCallback2(AnimationCallback(&KmScene1705::sub468A80));
+ 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 0x4817:
+ setDoDeltaX(param.asInteger());
+ sub41C7B0();
+ break;
+ case 0x481B:
+ if (param.asPoint().y != 0) {
+ sub41CC40(param.asPoint().y, param.asPoint().x);
+ } else {
+ sub41CCE0(param.asPoint().x);
+ }
+ break;
+ case 0x481D:
+ if (_flag) {
+ setCallback2(AnimationCallback(&Klayman::sub4214D0));
+ }
+ break;
+ case 0x481E:
+ if (_flag) {
+ setCallback2(AnimationCallback(&Klayman::sub421510));
+ }
+ break;
+ case 0x481F:
+ if (param.asInteger() == 1) {
+ setCallback2(AnimationCallback(&Klayman::sub4208B0));
+ } else if (param.asInteger() == 0) {
+ setCallback2(AnimationCallback(&Klayman::sub420870));
+ } else if (param.asInteger() == 4) {
+ setCallback2(AnimationCallback(&Klayman::sub420930));
+ } else if (param.asInteger() == 3) {
+ setCallback2(AnimationCallback(&Klayman::sub4208F0));
+ } else {
+ setCallback2(AnimationCallback(&Klayman::sub420830));
+ }
+ break;
+ case 0x4834:
+ setCallback2(AnimationCallback(&Klayman::sub421160));
+ break;
+ case 0x4835:
+ _parentScene->sendMessage(0x2000, 1, this);
+ _flag = true;
+ setCallback2(AnimationCallback(&Klayman::sub4212C0));
+ break;
+ case 0x4836:
+ _parentScene->sendMessage(0x2000, 0, this);
+ _flag = false;
+ setCallback2(AnimationCallback(&Klayman::sub421310));
+ break;
+ case 0x483D:
+ sub468AD0();
+ break;
+ case 0x483E:
+ sub468B10();
+ break;
+ }
+ return messageResult;
+}
+
+uint32 KmScene1705::handleMessage4689A0(int messageNum, const MessageParam &param, Entity *sender) {
+ uint32 messageResult = handleMessage41D480(messageNum, param, sender);
+ switch (messageNum) {
+ case 0x100D:
+ if (param.asInteger() == 0x4E0A2C24) {
+ _soundResource1.play(0x85B10BB8);
+ } else if (param.asInteger() == 0x4E6A0CA0) {
+ _soundResource1.play(0xC5B709B0);
+ }
+ break;
+ }
+ return messageResult;
+}
+
+void KmScene1705::spriteUpdate468A30() {
+ updateDeltaXY();
+ HitRect *hitRect = _vm->_collisionMan->findHitRectAtPos(_x, _y + 10);
+ if (hitRect->type == 0x5001) {
+ _y = hitRect->rect.y1;
+ processDelta();
+ sendMessage(0x1019, 0, this);
+ }
+}
+
+void KmScene1705::sub468A80() {
+ _status2 = 2;
+ _flagE5 = false;
+ setFileHash2(0xB93AB151, 0x40A100F8, 0);
+ SetUpdateHandler(&Klayman::update);
+ SetSpriteCallback(&KmScene1705::spriteUpdate468A30);
+ SetMessageHandler(&Klayman::handleMessage41D360);
+ SetAnimationCallback3(&Klayman::sub420420);
+}
+
+void KmScene1705::sub468AD0() {
+ _status2 = 0;
+ _flagE5 = false;
+ setFileHash(0x5E0A4905, 0, -1);
+ SetUpdateHandler(&Klayman::update);
+ SetSpriteCallback(NULL);
+ SetMessageHandler(&KmScene1705::handleMessage4689A0);
+}
+
+void KmScene1705::sub468B10() {
+ _status2 = 0;
+ _flagE5 = false;
+ setFileHash(0xD86E4477, 0, -1);
+ SetUpdateHandler(&Klayman::update);
+ SetSpriteCallback(NULL);
+ SetMessageHandler(&KmScene1705::handleMessage4689A0);
+}
+
} // End of namespace Neverhood
diff --git a/engines/neverhood/klayman.h b/engines/neverhood/klayman.h
index 3682d75e69..5cb11abd10 100644
--- a/engines/neverhood/klayman.h
+++ b/engines/neverhood/klayman.h
@@ -85,6 +85,20 @@ public:
void sub4207A0();
void sub4207F0();
void sub420F20();
+ void sub421350();
+ void sub4213F0();
+ void sub4213B0();
+ void sub420060();
+ void sub41FFF0();
+ void sub4214D0();
+ void sub421510();
+ void sub421160();
+ void sub4212C0();
+ void sub421310();
+ void sub420600();
+ void sub420660();
+ void sub4205C0();
+ void sub420550();
void spriteUpdate41F250();
void spriteUpdate41F5F0();
@@ -95,6 +109,11 @@ public:
uint32 handleMessage41D360(int messageNum, const MessageParam &param, Entity *sender);
uint32 handleMessage41D480(int messageNum, const MessageParam &param, Entity *sender);
+ void setKlaymanTable(const KlaymanTableItem *table, int tableCount);
+ void setKlaymanTable1();
+ void setKlaymanTable2();
+ void setKlaymanTable3();
+
protected:
Entity *_parentScene;
Entity *_attachedSprite;
@@ -129,11 +148,6 @@ protected:
virtual void xUpdate();
virtual uint32 xHandleMessage(int messageNum, const MessageParam &param);
- void setKlaymanTable(const KlaymanTableItem *table, int tableCount);
- void setKlaymanTable1();
- void setKlaymanTable2();
- void setKlaymanTable3();
-
void sub41FD40();
void sub41FD90();
uint32 handleMessage41EB10(int messageNum, const MessageParam &param, Entity *sender);
@@ -210,6 +224,11 @@ protected:
uint32 handleMessage41E490(int messageNum, const MessageParam &param, Entity *sender);
uint32 handleMessage41E290(int messageNum, const MessageParam &param, Entity *sender);
uint32 handleMessage41E2F0(int messageNum, const MessageParam &param, Entity *sender);
+ 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);
+
+ void update41D1C0();
};
@@ -287,6 +306,33 @@ protected:
void sub40E040();
};
+class KmScene1401 : public Klayman {
+public:
+ KmScene1401(NeverhoodEngine *vm, Entity *parentScene, int16 x, int16 y);
+protected:
+ uint32 xHandleMessage(int messageNum, const MessageParam &param);
+};
+
+class KmScene1402 : public Klayman {
+public:
+ KmScene1402(NeverhoodEngine *vm, Entity *parentScene, int16 x, int16 y);
+protected:
+ uint32 xHandleMessage(int messageNum, const MessageParam &param);
+};
+
+class KmScene1705 : public Klayman {
+public:
+ KmScene1705(NeverhoodEngine *vm, Entity *parentScene, int16 x, int16 y);
+protected:
+ bool _flag;
+ uint32 xHandleMessage(int messageNum, const MessageParam &param);
+ uint32 handleMessage4689A0(int messageNum, const MessageParam &param, Entity *sender);
+ void spriteUpdate468A30();
+ void sub468A80();
+ void sub468AD0();
+ void sub468B10();
+};
+
} // End of namespace Neverhood
#endif /* NEVERHOOD_KLAYMAN_H */
diff --git a/engines/neverhood/module.mk b/engines/neverhood/module.mk
index 17424765e0..0b3b10c2f8 100644
--- a/engines/neverhood/module.mk
+++ b/engines/neverhood/module.mk
@@ -5,6 +5,7 @@ MODULE_OBJS = \
blbarchive.o \
collisionman.o \
detection.o \
+ diskplayerscene.o \
gamemodule.o \
gamevars.o \
graphics.o \
@@ -12,7 +13,10 @@ MODULE_OBJS = \
module.o \
module1000.o \
module1200.o \
+ module1400.o \
module1500.o \
+ module1700.o \
+ module1800.o \
module2300.o \
mouse.o \
navigationscene.o \
diff --git a/engines/neverhood/module1200.cpp b/engines/neverhood/module1200.cpp
index eef543385c..7a09b5f060 100644
--- a/engines/neverhood/module1200.cpp
+++ b/engines/neverhood/module1200.cpp
@@ -76,8 +76,8 @@ void Module1200::createScene1201(int which) {
void Module1200::createScene1202(int which) {
_vm->gameState().sceneNum = 1;
- //_childObject = new Scene1202(_vm, this, which);
- //SetUpdateHandler(&Module1200::updateScene1202);
+ _childObject = new Scene1202(_vm, this, which);
+ SetUpdateHandler(&Module1200::updateScene1202);
}
void Module1200::createScene1203(int which) {
@@ -161,7 +161,7 @@ static const NPoint kScene1201PointArray[] = {
{493, 174}
};
-static const uint32 kScene1201SsScene1201TntFileHashList1[] = {
+static const uint32 kScene1201TntFileHashList1[] = {
0x2098212D,
0x1600437E,
0x1600437E,
@@ -182,7 +182,7 @@ static const uint32 kScene1201SsScene1201TntFileHashList1[] = {
0xDA460476
};
-static const uint32 kScene1201SsScene1201TntFileHashList2[] = {
+static const uint32 kScene1201TntFileHashList2[] = {
0x3040C676,
0x10914448,
0x10914448,
@@ -209,7 +209,7 @@ SsScene1201Tnt::SsScene1201Tnt(NeverhoodEngine *vm, uint32 elemIndex, uint32 poi
int16 x = kScene1201PointArray[pointIndex].x;
int16 y = kScene1201PointArray[pointIndex].y;
if (x < 300) {
- _spriteResource.load2(kScene1201SsScene1201TntFileHashList1[elemIndex]);
+ _spriteResource.load2(kScene1201TntFileHashList1[elemIndex]);
_x = _spriteResource.getPosition().x;
_y = _spriteResource.getPosition().y;
_drawRect.x = 0;
@@ -217,7 +217,7 @@ SsScene1201Tnt::SsScene1201Tnt(NeverhoodEngine *vm, uint32 elemIndex, uint32 poi
_drawRect.width = _spriteResource.getDimensions().width;
_drawRect.height = _spriteResource.getDimensions().height;
} else {
- _spriteResource.load2(kScene1201SsScene1201TntFileHashList2[elemIndex]);
+ _spriteResource.load2(kScene1201TntFileHashList2[elemIndex]);
_x = x;
_y = y;
_drawRect.x = -(_spriteResource.getDimensions().width / 2);
@@ -307,14 +307,14 @@ void Class466::sub40D380() {
_newHashListIndex = -2;
}
-Class468::Class468(NeverhoodEngine *vm, Sprite *klayman, bool flag)
+AsScene1201RightDoor::AsScene1201RightDoor(NeverhoodEngine *vm, Sprite *klayman, bool flag)
: AnimatedSprite(vm, 1100), _soundResource(vm), _klayman(klayman), _countdown(0) {
- createSurface1(100, 0xD088AC30);
+ createSurface1(0xD088AC30, 100);
_x = 320;
_y = 240;
- SetUpdateHandler(&Class468::update);
- SetMessageHandler(&Class468::handleMessage);
+ SetUpdateHandler(&AsScene1201RightDoor::update);
+ SetMessageHandler(&AsScene1201RightDoor::handleMessage);
_newHashListIndex = -2;
if (flag) {
setFileHash(0xD088AC30, -1, -1);
@@ -326,14 +326,14 @@ Class468::Class468(NeverhoodEngine *vm, Sprite *klayman, bool flag)
}
}
-void Class468::update() {
+void AsScene1201RightDoor::update() {
if (_countdown != 0 && (--_countdown == 0)) {
sub40D830();
}
AnimatedSprite::update();
}
-uint32 Class468::handleMessage(int messageNum, const MessageParam &param, Entity *sender) {
+uint32 AsScene1201RightDoor::handleMessage(int messageNum, const MessageParam &param, Entity *sender) {
uint32 messageResult = Sprite::handleMessage(messageNum, param, sender);
switch (messageNum) {
case 0x3002:
@@ -346,22 +346,22 @@ uint32 Class468::handleMessage(int messageNum, const MessageParam &param, Entity
return messageResult;
}
-void Class468::sub40D7E0() {
+void AsScene1201RightDoor::sub40D7E0() {
setFileHash(0xD088AC30, 0, -1);
_newHashListIndex = -2;
_surface->setVisible(true);
_soundResource.play(calcHash("fxDoorOpen20"));
}
-void Class468::sub40D830() {
+void AsScene1201RightDoor::sub40D830() {
setFileHash(0xD088AC30, -1, -1);
_playBackwards = true;
_surface->setVisible(true);
_soundResource.play(calcHash("fxDoorClose20"));
- SetAnimationCallback3(&Class468::sub40D880);
+ SetAnimationCallback3(&AsScene1201RightDoor::sub40D880);
}
-void Class468::sub40D880() {
+void AsScene1201RightDoor::sub40D880() {
setFileHash1();
_surface->setVisible(false);
}
@@ -394,14 +394,14 @@ uint32 Class464::handleMessage(int messageNum, const MessageParam &param, Entity
return messageResult;
}
-Class463::Class463(NeverhoodEngine *vm, Scene *parentScene, Sprite *class466, bool flag)
+AsScene1201TntMan::AsScene1201TntMan(NeverhoodEngine *vm, Scene *parentScene, Sprite *class466, bool flag)
: AnimatedSprite(vm, 1100), _soundResource(vm), _parentScene(parentScene), _class466(class466),
_flag(false) {
-
- //TODO_field_F0 = -1;
+
+ flag = false;
SetUpdateHandler(&AnimatedSprite::update);
- SetMessageHandler(&Class463::handleMessage);
+ SetMessageHandler(&AsScene1201TntMan::handleMessage);
createSurface(990, 106, 181);
_x = 201;
if (flag) {
@@ -413,11 +413,11 @@ Class463::Class463(NeverhoodEngine *vm, Scene *parentScene, Sprite *class466, bo
}
}
-Class463::~Class463() {
+AsScene1201TntMan::~AsScene1201TntMan() {
// TODO Sound1ChList_sub_407AF0(0x01D00560);
}
-uint32 Class463::handleMessage(int messageNum, const MessageParam &param, Entity *sender) {
+uint32 AsScene1201TntMan::handleMessage(int messageNum, const MessageParam &param, Entity *sender) {
uint32 messageResult = Sprite::handleMessage(messageNum, param, sender);
switch (messageNum) {
case 0x100D:
@@ -441,8 +441,8 @@ uint32 Class463::handleMessage(int messageNum, const MessageParam &param, Entity
}
-uint32 Class463::handleMessage40CCD0(int messageNum, const MessageParam &param, Entity *sender) {
- uint32 messageResult = Class463::handleMessage(messageNum, param, sender);
+uint32 AsScene1201TntMan::handleMessage40CCD0(int messageNum, const MessageParam &param, Entity *sender) {
+ uint32 messageResult = AsScene1201TntMan::handleMessage(messageNum, param, sender);
switch (messageNum) {
case 0x3002:
removeCallbacks();
@@ -451,37 +451,37 @@ uint32 Class463::handleMessage40CCD0(int messageNum, const MessageParam &param,
return messageResult;
}
-void Class463::spriteUpdate40CD10() {
+void AsScene1201TntMan::spriteUpdate40CD10() {
_x = _sprite->getX() + 100;
}
-void Class463::sub40CD30() {
+void AsScene1201TntMan::sub40CD30() {
setFileHash(0x654913D0, 0, -1);
- SetMessageHandler(&Class463::handleMessage);
+ SetMessageHandler(&AsScene1201TntMan::handleMessage);
SetSpriteCallback(NULL);
}
-void Class463::sub40CD60() {
+void AsScene1201TntMan::sub40CD60() {
setFileHash(0x356803D0, 0, -1);
- SetMessageHandler(&Class463::handleMessage40CCD0);
+ SetMessageHandler(&AsScene1201TntMan::handleMessage40CCD0);
SetSpriteCallback(&AnimatedSprite::updateDeltaXY);
- SetAnimationCallback3(&Class463::sub40CD30);
+ SetAnimationCallback3(&AsScene1201TntMan::sub40CD30);
}
-void Class463::sub40CD90() {
+void AsScene1201TntMan::sub40CD90() {
// TODO Sound1ChList_addSoundResource(0x01D00560, 0x4B044624, true);
// TODO Sound1ChList_playLooping(0x4B044624);
_flag = true;
setFileHash(0x85084190, 0, -1);
- SetMessageHandler(&Class463::handleMessage);
- SetSpriteCallback(&Class463::spriteUpdate40CD10);
+ SetMessageHandler(&AsScene1201TntMan::handleMessage);
+ SetSpriteCallback(&AsScene1201TntMan::spriteUpdate40CD10);
_newHashListIndex = -2;
}
-Class465::Class465(NeverhoodEngine *vm, Sprite *class463)
- : AnimatedSprite(vm, 1200), _class463(class463) {
+Class465::Class465(NeverhoodEngine *vm, Sprite *asTntMan)
+ : AnimatedSprite(vm, 1200), _asTntMan(asTntMan) {
- createSurface1(995, 0x828C0411);
+ createSurface1(0x828C0411, 995);
SetUpdateHandler(&Class465::update);
SetMessageHandler(&Sprite::handleMessage);
SetSpriteCallback(&Class465::spriteUpdate40D150);
@@ -504,8 +504,251 @@ void Class465::update() {
}
void Class465::spriteUpdate40D150() {
- _x = _class463->getX() - 18;
- _y = _class463->getY() - 158;
+ _x = _asTntMan->getX() - 18;
+ _y = _asTntMan->getY() - 158;
+}
+
+AsScene1201Match::AsScene1201Match(NeverhoodEngine *vm, Scene *parentScene)
+ : AnimatedSprite(vm, 1100), _soundResource(vm), _parentScene(parentScene) {
+
+ createSurface(1100, 57, 60);
+ SetUpdateHandler(&AsScene1201Match::update);
+ SetMessageHandler(&AsScene1201Match::handleMessage40C2D0);
+ SetSpriteCallback(&AnimatedSprite::updateDeltaXY);
+
+ switch (getGlobalVar(0x0112090A)) {
+ case 0:
+ _x = 521;
+ _y = 112;
+ _status = 0;
+ sub40C4C0();
+ break;
+ case 1:
+ _x = 521;
+ _y = 112;
+ _status = 2;
+ sub40C470();
+ _soundResource.load(0xD00230CD);
+ break;
+ case 2:
+ setDoDeltaX(1);
+ _x = 403;
+ _y = 337;
+ _status = 0;
+ sub40C4F0();
+ break;
+ }
+}
+
+void AsScene1201Match::update() {
+ if (_countdown != 0 && (--_countdown == 0)) {
+ removeCallbacks();
+ }
+ updateAnim();
+ handleSpriteUpdate();
+ updatePosition();
+}
+
+uint32 AsScene1201Match::handleMessage40C2D0(int messageNum, const MessageParam &param, Entity *sender) {
+ uint32 messageResult = Sprite::handleMessage(messageNum, param, sender);
+ switch (messageNum) {
+ case 0x100D:
+ if (param.asInteger() == 0x86668011) {
+ _soundResource.play();
+ }
+ break;
+ }
+ return messageResult;
+}
+
+uint32 AsScene1201Match::handleMessage40C320(int messageNum, const MessageParam &param, Entity *sender) {
+ uint32 messageResult = handleMessage40C2D0(messageNum, param, sender);
+ switch (messageNum) {
+ case 0x3002:
+ removeCallbacks();
+ break;
+ }
+ return messageResult;
+}
+
+uint32 AsScene1201Match::handleMessage40C360(int messageNum, const MessageParam &param, Entity *sender) {
+ uint32 messageResult = handleMessage40C2D0(messageNum, param, sender);
+ switch (messageNum) {
+ case 0x1011:
+ _parentScene->sendMessage(0x2001, 0, this);
+ messageResult = 1;
+ break;
+ case 0x4806:
+ _surface->setVisible(false);
+ setGlobalVar(0x0112090A, 3);
+ break;
+ }
+ return messageResult;
+}
+
+void AsScene1201Match::sub40C3E0() {
+ setFileHash(0x00842374, 0, -1);
+ SetMessageHandler(&AsScene1201Match::handleMessage40C320);
+ if (_status == 0) {
+ SetAnimationCallback3(&AsScene1201Match::sub40C420);
+ } else {
+ SetAnimationCallback3(&AsScene1201Match::sub40C470);
+ }
+}
+
+void AsScene1201Match::sub40C420() {
+ setGlobalVar(0x0112090A, 2);
+ _x -= 199;
+ _y += 119;
+ setFileHash(0x018D0240, 0, -1);
+ SetMessageHandler(&AsScene1201Match::handleMessage40C320);
+ SetAnimationCallback3(&AsScene1201Match::sub40C4F0);
+}
+
+void AsScene1201Match::sub40C470() {
+ setFileHash(0x00842374, 0, -1);
+ SetMessageHandler(&AsScene1201Match::handleMessage40C2D0);
+ _newHashListIndex = 0;
+ if (_status != 0) {
+ _countdown = 36;
+ _status--;
+ SetAnimationCallback3(&AsScene1201Match::sub40C3E0);
+ }
+}
+
+void AsScene1201Match::sub40C4C0() {
+ setFileHash(0x00842374, 0, -1);
+ SetMessageHandler(&AsScene1201Match::handleMessage40C360);
+ _newHashListIndex = 0;
+}
+
+void AsScene1201Match::sub40C4F0() {
+ setDoDeltaX(1);
+ _x = 403;
+ _y = 337;
+ setFileHash(0x00842374, 0, -1);
+ SetMessageHandler(&AsScene1201Match::handleMessage40C360);
+ _newHashListIndex = 0;
+}
+
+AsScene1201Creature::AsScene1201Creature(NeverhoodEngine *vm, Scene *parentScene, Sprite *klayman)
+ : AnimatedSprite(vm, 900), _soundResource(vm), _parentScene(parentScene), _klayman(klayman),
+ _flag(false) {
+
+ createSurface(1100, 203, 199);
+ SetUpdateHandler(&AsScene1201Creature::update);
+ SetMessageHandler(&AsScene1201Creature::handleMessage40C710);
+ _x = 540;
+ _y = 320;
+ sub40C8E0();
+ _countdown3 = 2;
+}
+
+void AsScene1201Creature::update() {
+ bool oldFlag = _flag;
+ _flag = _x >= 385;
+ if (_flag != oldFlag)
+ sub40C8E0();
+ if (_countdown1 != 0 && (--_countdown1 == 0)) {
+ removeCallbacks();
+ }
+ updateAnim();
+ handleSpriteUpdate();
+ updatePosition();
+}
+
+uint32 AsScene1201Creature::handleMessage40C710(int messageNum, const MessageParam &param, Entity *sender) {
+ uint32 messageResult = Sprite::handleMessage(messageNum, param, sender);
+ switch (messageNum) {
+ case 0x100D:
+ if (param.asInteger() == 0x02060018) {
+ _soundResource.play(0xCD298116);
+ }
+ break;
+ case 0x2004:
+ setCallback2(AnimationCallback(&AsScene1201Creature::sub40C960));
+ break;
+ case 0x2006:
+ setCallback2(AnimationCallback(&AsScene1201Creature::sub40C9B0));
+ break;
+ }
+ return messageResult;
+}
+
+uint32 AsScene1201Creature::handleMessage40C7B0(int messageNum, const MessageParam &param, Entity *sender) {
+ uint32 messageResult = handleMessage40C710(messageNum, param, sender);
+ switch (messageNum) {
+ case 0x100D:
+ if (param.asInteger() == 0x02421405) {
+ if (_countdown2 != 0 && (--_countdown2 == 0)) {
+ sub40C990();
+ }
+ }
+ break;
+ case 0x3002:
+ removeCallbacks();
+ break;
+ }
+ return messageResult;
+}
+
+uint32 AsScene1201Creature::handleMessage40C830(int messageNum, const MessageParam &param, Entity *sender) {
+ uint32 messageResult = Sprite::handleMessage(messageNum, param, sender);
+ switch (messageNum) {
+ case 0x100D:
+ if (param.asInteger() == 0x02060018) {
+ _soundResource.play(0xCD298116);
+ _parentScene->sendMessage(0x4814, 0, this);
+ _klayman->sendMessage(0x4814, 0, this);
+ }
+ break;
+ case 0x3002:
+ removeCallbacks();
+ break;
+ }
+ return messageResult;
+}
+
+void AsScene1201Creature::sub40C8E0() {
+ _countdown3--;
+ if (_countdown3 == 0)
+ _countdown3 = 3;
+ setFileHash(0x08081513, 0, -1);
+ SetMessageHandler(&AsScene1201Creature::handleMessage40C710);
+ SetAnimationCallback3(&AsScene1201Creature::sub40C930);
+ _countdown1 = 36;
+}
+
+void AsScene1201Creature::sub40C930() {
+ if (!_flag) {
+ setFileHash(0xCA287133, 0, -1);
+ SetMessageHandler(&AsScene1201Creature::handleMessage40C7B0);
+ SetAnimationCallback3(&AsScene1201Creature::sub40C8E0);
+ }
+}
+
+void AsScene1201Creature::sub40C960() {
+ setFileHash(0x08081513, 0, -1);
+ SetMessageHandler(&AsScene1201Creature::handleMessage40C710);
+ SetAnimationCallback3(&AsScene1201Creature::sub40C9E0);
+ _countdown1 = 48;
+}
+
+void AsScene1201Creature::sub40C990() {
+ setFileHash2(0x0B6E13FB, 0x01084280, 0);
+}
+
+void AsScene1201Creature::sub40C9B0() {
+ setFileHash(0xCA287133, 0, -1);
+ SetMessageHandler(&AsScene1201Creature::handleMessage40C830);
+ SetAnimationCallback3(&AsScene1201Creature::sub40C8E0);
+ _countdown1 = 0;
+}
+
+void AsScene1201Creature::sub40C9E0() {
+ setFileHash(0x5A201453, 0, -1);
+ SetMessageHandler(&AsScene1201Creature::handleMessage40C710);
+ _countdown1 = 0;
}
AsScene1201LeftDoor::AsScene1201LeftDoor(NeverhoodEngine *vm, Sprite *klayman)
@@ -543,7 +786,8 @@ void AsScene1201LeftDoor::sub40D590() {
}
Scene1201::Scene1201(NeverhoodEngine *vm, Module *parentModule, int which)
- : Scene(vm, parentModule, true), _flag(false) {
+ : Scene(vm, parentModule, true), _flag(false), _asMatch(NULL), _asTntMan(NULL),
+ _asCreature(NULL), _class466(NULL), _asLeftDoor(NULL), _asRightDoor(NULL), _asTape(NULL) {
int16 topY1, topY2, topY3, topY4;
int16 x1, x2;
@@ -589,12 +833,12 @@ Scene1201::Scene1201(NeverhoodEngine *vm, Module *parentModule, int which)
tempSprite = addSprite(new StaticSprite(_vm, 0x04063110, 500));
topY4 = tempSprite->getY() + 1;
- _class466 = addSprite(new Class466(_vm, getGlobalVar(0x000CF819) && which != 1 ? 1 : 0));
+ _class466 = addSprite(new Class466(_vm, getGlobalVar(0x000CF819) && which != 1));
_class466->getSurface()->getClipRect().x1 = 0;
_class466->getSurface()->getClipRect().y1 = topY4;
_class466->getSurface()->getClipRect().x2 = 640;
_class466->getSurface()->getClipRect().y2 = 480;
-
+
addSprite(new StaticSprite(_vm, 0x400B04B0, 1200));
tempSprite = addSprite(new StaticSprite(_vm, 0x40295462, 1200));
@@ -644,31 +888,31 @@ Scene1201::Scene1201(NeverhoodEngine *vm, Module *parentModule, int which)
_background = addBackground(new DirtyBackground(_vm, 0x4019A2C4, 0, 0));
_palette = new Palette(_vm, 0x4019A2C4);
_palette->usePalette();
- _class468 = NULL;
+ _asRightDoor = NULL;
} else {
_background = addBackground(new DirtyBackground(_vm, 0x40206EC5, 0, 0));
_palette = new Palette(_vm, 0x40206EC5);
_palette->usePalette();
- _class468 = addSprite(new Class468(_vm, _klayman, which - 2 != 1)); // CHECKME???
+ _asRightDoor = addSprite(new AsScene1201RightDoor(_vm, _klayman, which == 2));
}
if (getGlobalVar(0x000CF819)) {
addSprite(new StaticSprite(_vm, 0x10002ED8, 500));
if (!getGlobalVar(0x0A18CA33)) {
- Class463 *class463;
- class463 = new Class463(_vm, this, _class466, which - 1 != 1);
- class463->getSurface()->getClipRect().x1 = x1;
- class463->getSurface()->getClipRect().y1 = 0;
- class463->getSurface()->getClipRect().x2 = x2;
- class463->getSurface()->getClipRect().y2 = 480;
- _vm->_collisionMan->addSprite(_class463);
- _class463 = addSprite(class463);
- tempSprite = addSprite(new Class465(_vm, _class463));
+ AsScene1201TntMan *asTntMan;
+ asTntMan = new AsScene1201TntMan(_vm, this, _class466, which == 1);
+ asTntMan->getSurface()->getClipRect().x1 = x1;
+ asTntMan->getSurface()->getClipRect().y1 = 0;
+ asTntMan->getSurface()->getClipRect().x2 = x2;
+ asTntMan->getSurface()->getClipRect().y2 = 480;
+ _vm->_collisionMan->addSprite(asTntMan);
+ _asTntMan = addSprite(asTntMan);
+ tempSprite = addSprite(new Class465(_vm, _asTntMan));
tempSprite->getSurface()->getClipRect().x1 = x1;
tempSprite->getSurface()->getClipRect().y1 = 0;
tempSprite->getSurface()->getClipRect().x2 = x2;
tempSprite->getSurface()->getClipRect().y2 = 480;
- class463->setRepl(64, 0);
+ asTntMan->setRepl(64, 0);
}
uint32 tntIndex = 1;
@@ -741,22 +985,20 @@ Scene1201::Scene1201(NeverhoodEngine *vm, Module *parentModule, int which)
setGlobalVar(0x0112090A, 1);
}
- _class461 = NULL;
+ _asMatch = NULL;
-#if 0
if (getGlobalVar(0x0112090A) < 3) {
- _class461 = addSprite(new Class461(_vm, this));
- _vm->_collisionMan->addSprite(_class461);
+ _asMatch = addSprite(new AsScene1201Match(_vm, this));
+ _vm->_collisionMan->addSprite(_asMatch);
}
if (getGlobalVar(0x0A310817) && !getGlobalVar(0x0A18CA33)) {
- _class462 = addSprite(new Class462(_vm, this, _klayman));
- _class462->getSurface()->getClipRect().x1 = x1;
- _class462->getSurface()->getClipRect().y1 = 0;
- _class462->getSurface()->getClipRect().x2 = x2;
- _class462->getSurface()->getClipRect().y2 = 480;
+ _asCreature = addSprite(new AsScene1201Creature(_vm, this, _klayman));
+ _asCreature->getSurface()->getClipRect().x1 = x1;
+ _asCreature->getSurface()->getClipRect().y1 = 0;
+ _asCreature->getSurface()->getClipRect().x2 = x2;
+ _asCreature->getSurface()->getClipRect().y2 = 480;
}
-#endif
}
@@ -765,8 +1007,8 @@ Scene1201::~Scene1201() {
void Scene1201::update() {
Scene::update();
- if (_class461 && getGlobalVar(0x0112090A)) {
- deleteSprite(&_class461);
+ if (_asMatch && getGlobalVar(0x0112090A)) {
+ deleteSprite(&_asMatch);
}
}
@@ -777,12 +1019,12 @@ uint32 Scene1201::handleMessage(int messageNum, const MessageParam &param, Entit
case 0x100D:
if (param.asInteger() == 0x07053000) {
_flag = true;
- _class462->sendMessage(0x2004, 0, this);
+ _asCreature->sendMessage(0x2004, 0, this);
} else if (param.asInteger() == 0x140E5744) {
- _class462->sendMessage(0x2005, 0, this);
+ _asCreature->sendMessage(0x2005, 0, this);
} else if (param.asInteger() == 0x40253C40) {
_messageListFlag = false;
- _class462->sendMessage(0x2006, 0, this);
+ _asCreature->sendMessage(0x2006, 0, this);
} else if (param.asInteger() == 0x090EB048) {
if (_klayman->getX() < 572) {
setMessageList2(0x004AEC90);
@@ -795,17 +1037,17 @@ uint32 Scene1201::handleMessage(int messageNum, const MessageParam &param, Entit
if (!getGlobalVar(0x0112090A)) {
setMessageList2(0x004AECB0);
} else {
- _klayman->sendEntityMessage(0x1014, _class461, this);
+ _klayman->sendEntityMessage(0x1014, _asMatch, this);
setMessageList2(0x004AECC0);
}
break;
case 0x2002:
if (getGlobalVar(0x20A0C516)) {
- _klayman->sendEntityMessage(0x1014, _class463, this);
+ _klayman->sendEntityMessage(0x1014, _asTntMan, this);
setMessageList2(0x004AECF0);
} else if (getGlobalVar(0x0112090A) == 3) {
- _klayman->sendEntityMessage(0x1014, _class463, this);
- if (_klayman->getX() > _class463->getX()) {
+ _klayman->sendEntityMessage(0x1014, _asTntMan, this);
+ if (_klayman->getX() > _asTntMan->getX()) {
setMessageList(0x004AECD0);
} else {
setMessageList(0x004AECE0);
@@ -822,10 +1064,253 @@ uint32 Scene1201::handleMessage(int messageNum, const MessageParam &param, Entit
}
break;
case 0x4829:
- _class468->sendMessage(0x4829, 0, this);
+ _asRightDoor->sendMessage(0x4829, 0, this);
+ break;
+ }
+ return messageResult;
+}
+
+// Scene1202
+
+static const uint32 kScene1202Table[] = {
+ 1, 2, 0, 4, 5, 3, 7, 8, 6, 10, 11, 9, 13, 14, 12, 16, 17, 15
+};
+
+static const NPoint kScene1202Points[] = {
+ {203, 140},
+ {316, 212},
+ {277, 264},
+ {176, 196},
+ {275, 159},
+ {366, 212},
+ {230, 195},
+ {412, 212},
+ {368, 263},
+ {204, 192},
+ {365, 164},
+ {316, 262},
+ {191, 255},
+ {280, 213},
+ {406, 266},
+ {214, 254},
+ {316, 158},
+ {402, 161}
+};
+
+static const uint32 kScene1202FileHashes[] = {
+ 0x1AC00B8,
+ 0x1AC14B8,
+ 0x1AC14B8,
+ 0x1AC30B8,
+ 0x1AC14B8,
+ 0x1AC14B8,
+ 0x1AC00B8,
+ 0x1AC14B8,
+ 0x1AC14B8,
+ 0x1AC90B8,
+ 0x1AC18B8,
+ 0x1AC18B8,
+ 0x1AC30B8,
+ 0x1AC14B8,
+ 0x1AC14B8,
+ 0x1AC50B8,
+ 0x1AC14B8,
+ 0x1AC14B8
+};
+
+AsScene1202TntItem::AsScene1202TntItem(NeverhoodEngine *vm, Scene *parentScene, int index)
+ : AnimatedSprite(vm, 900), _parentScene(parentScene), _index(index) {
+
+ int positionIndex;
+
+ SetUpdateHandler(&AnimatedSprite::update);
+ SetMessageHandler(&AsScene1202TntItem::handleMessage453FE0);
+ positionIndex = getSubVar(0x10055D14, _index);
+ createSurface(900, 37, 67);
+ _x = kScene1202Points[positionIndex].x;
+ _y = kScene1202Points[positionIndex].y;
+ sub4540A0();
+}
+
+uint32 AsScene1202TntItem::handleMessage453FE0(int messageNum, const MessageParam &param, Entity *sender) {
+ uint32 messageResult = Sprite::handleMessage(messageNum, param, sender);
+ switch (messageNum) {
+ case 0x1011:
+ _parentScene->sendMessage(0x2000, _index, this);
+ messageResult = 1;
+ break;
+ case 0x2001:
+ _index2 = (int)param.asInteger();
+ sub4540D0();
break;
}
return messageResult;
}
+uint32 AsScene1202TntItem::handleMessage454060(int messageNum, const MessageParam &param, Entity *sender) {
+ uint32 messageResult = Sprite::handleMessage(messageNum, param, sender);
+ switch (messageNum) {
+ case 0x3002:
+ removeCallbacks();
+ break;
+ }
+ return messageResult;
+}
+
+void AsScene1202TntItem::sub4540A0() {
+ setFileHash(kScene1202FileHashes[_index], 0, -1);
+ SetMessageHandler(&AsScene1202TntItem::handleMessage453FE0);
+ _newHashListIndex = 0;
+}
+
+void AsScene1202TntItem::sub4540D0() {
+ setFileHash(kScene1202FileHashes[_index], 0, -1);
+ SetMessageHandler(&AsScene1202TntItem::handleMessage454060);
+ SetAnimationCallback3(&AsScene1202TntItem::sub454100);
+}
+
+void AsScene1202TntItem::sub454100() {
+ _x = kScene1202Points[_index2].x;
+ _y = kScene1202Points[_index2].y;
+ setFileHash(kScene1202FileHashes[_index], 6, -1);
+ SetMessageHandler(&AsScene1202TntItem::handleMessage454060);
+ SetAnimationCallback3(&AsScene1202TntItem::sub454160);
+ _playBackwards = true;
+}
+
+void AsScene1202TntItem::sub454160() {
+ _parentScene->sendMessage(0x2002, _index, this);
+ sub4540A0();
+}
+
+Scene1202::Scene1202(NeverhoodEngine *vm, Module *parentModule, int which)
+ : Scene(vm, parentModule, true), _paletteResource(vm), _soundResource1(vm),
+ _soundResource2(vm), _soundResource3(vm), _soundResource4(vm),
+ _flag(true), _soundFlag(false), _counter(0), _index(-1) {
+
+ Palette2 *palette2;
+
+ SetMessageHandler(&Scene1202::handleMessage453C10);
+ SetUpdateHandler(&Scene1202::update);
+
+ _surfaceFlag = true;
+
+ _background = addBackground(new DirtyBackground(_vm, 0x60210ED5, 0, 0));
+
+ palette2 = new Palette2(_vm, 0x60210ED5);
+ palette2->usePalette();
+ _palette = palette2;
+ addEntity(_palette);
+
+ _paletteResource.load(0x60250EB5);
+ _paletteResource.copyPalette(_paletteData);
+
+ _mouseCursor = addSprite(new Mouse435(_vm, 0x10ED160A, 20, 620));
+
+ for (int i = 0; i < 18; i++) {
+ _asTntItems[i] = addSprite(new AsScene1202TntItem(_vm, this, i));
+ _vm->_collisionMan->addSprite(_asTntItems[i]);
+ }
+
+ addSprite(new StaticSprite(_vm, 0x8E8419C1, 1100));
+
+ if (getGlobalVar(0x000CF819)) {
+ SetMessageHandler(&Scene1202::handleMessage453D90);
+ }
+
+ _soundResource1.play(0x40106542);
+ _soundResource2.load(0x40005446);
+ _soundResource2.load(0x40005446);
+ _soundResource2.load(0x68E25540);
+
+}
+
+Scene1202::~Scene1202() {
+ if (isSolved()) {
+ setGlobalVar(0x000CF819, 1);
+ }
+}
+
+void Scene1202::update() {
+ Scene::update();
+ if (_soundFlag) {
+ if (!_soundResource4.isPlaying()) {
+ _parentModule->sendMessage(0x1009, 0, this);
+ }
+ } else if (_counter == 0 && isSolved()) {
+ SetMessageHandler(&Scene1202::handleMessage453D90);
+ setGlobalVar(0x000CF819, 1);
+ doPaletteEffect();
+ _soundResource4.play();
+ _soundFlag = true;
+ } else if (_index >= 0 && _counter == 0) {
+ int index2 = kScene1202Table[_index];
+ _asTntItems[_index]->sendMessage(0x2001, getSubVar(0x10055D14, index2), this);
+ _asTntItems[index2]->sendMessage(0x2001, getSubVar(0x10055D14, _index), this);
+ int temp = getSubVar(0x10055D14, index2);
+ setSubVar(0x10055D14, index2, getSubVar(0x10055D14, _index));
+ setSubVar(0x10055D14, _index, temp);
+ _counter = 2;
+ _index = -1;
+ if (_flag) {
+ _soundResource2.play();
+ } else {
+ _soundResource3.play();
+ }
+ _flag = !_flag;
+ }
+}
+
+uint32 Scene1202::handleMessage453C10(int messageNum, const MessageParam &param, Entity *sender) {
+ uint32 messageResult = 0;
+ Scene::handleMessage(messageNum, param, sender);
+ switch (messageNum) {
+ case 0x0001:
+ // TODO: Debug/Cheat stuff
+ if ((param.asPoint().x <= 20 || param.asPoint().x >= 620) && !_soundFlag) {
+ _parentModule->sendMessage(0x1009, 0, this);
+ }
+ break;
+ case 0x000D:
+ if (param.asInteger() == 0x14210006) {
+ // TODO: Debug/Cheat stuff
+ messageResult = 1;
+ }
+ break;
+ case 0x2000:
+ _index = (int)param.asInteger();
+ break;
+ case 0x2002:
+ _counter--;
+ break;
+ }
+ return messageResult;
+}
+
+uint32 Scene1202::handleMessage453D90(int messageNum, const MessageParam &param, Entity *sender) {
+ Scene::handleMessage(messageNum, param, sender);
+ switch (messageNum) {
+ case 0x0001:
+ if (param.asPoint().x <= 20 || param.asPoint().x >= 620) {
+ _parentModule->sendMessage(0x1009, 0, this);
+ }
+ break;
+ }
+ return 0;
+}
+
+bool Scene1202::isSolved() {
+ return
+ getSubVar(0x10055D14, 0) == 0 && getSubVar(0x10055D14, 3) == 3 &&
+ getSubVar(0x10055D14, 6) == 6 && getSubVar(0x10055D14, 9) == 9 &&
+ getSubVar(0x10055D14, 12) == 12 && getSubVar(0x10055D14, 15) == 15;
+}
+
+void Scene1202::doPaletteEffect() {
+#if 0 // TODO
+ Palette2 *palette2 = (Palette2*)_palette;
+ palette2->startFadeToPalette(24);
+#endif
+}
+
} // End of namespace Neverhood
diff --git a/engines/neverhood/module1200.h b/engines/neverhood/module1200.h
index 2a8a933b59..3ffed442d9 100644
--- a/engines/neverhood/module1200.h
+++ b/engines/neverhood/module1200.h
@@ -70,9 +70,9 @@ protected:
void sub40D380();
};
-class Class468 : public AnimatedSprite {
+class AsScene1201RightDoor : public AnimatedSprite {
public:
- Class468(NeverhoodEngine *vm, Sprite *klayman, bool flag);
+ AsScene1201RightDoor(NeverhoodEngine *vm, Sprite *klayman, bool flag);
protected:
SoundResource _soundResource;
Sprite *_klayman;
@@ -91,10 +91,10 @@ protected:
uint32 handleMessage(int messageNum, const MessageParam &param, Entity *sender);
};
-class Class463 : public AnimatedSprite {
+class AsScene1201TntMan : public AnimatedSprite {
public:
- Class463(NeverhoodEngine *vm, Scene *parentScene, Sprite *class466, bool flag);
- virtual ~Class463();
+ AsScene1201TntMan(NeverhoodEngine *vm, Scene *parentScene, Sprite *class466, bool flag);
+ virtual ~AsScene1201TntMan();
protected:
Scene *_parentScene;
Sprite *_class466;
@@ -111,14 +111,56 @@ protected:
class Class465 : public AnimatedSprite {
public:
- Class465(NeverhoodEngine *vm, Sprite *class463);
+ Class465(NeverhoodEngine *vm, Sprite *asTntMan);
~Class465();
protected:
- Sprite *_class463;
+ Sprite *_asTntMan;
void update();
void spriteUpdate40D150();
};
+class AsScene1201Match : public AnimatedSprite {
+public:
+ AsScene1201Match(NeverhoodEngine *vm, Scene *parentScene);
+protected:
+ Scene *_parentScene;
+ SoundResource _soundResource;
+ int _countdown;
+ int _status;
+ void update();
+ uint32 handleMessage40C2D0(int messageNum, const MessageParam &param, Entity *sender);
+ uint32 handleMessage40C320(int messageNum, const MessageParam &param, Entity *sender);
+ uint32 handleMessage40C360(int messageNum, const MessageParam &param, Entity *sender);
+ void sub40C3E0();
+ void sub40C420();
+ void sub40C470();
+ void sub40C4C0();
+ void sub40C4F0();
+};
+
+class AsScene1201Creature : public AnimatedSprite {
+public:
+ AsScene1201Creature(NeverhoodEngine *vm, Scene *parentScene, Sprite *klayman);
+protected:
+ Scene *_parentScene;
+ Sprite *_klayman;
+ SoundResource _soundResource;
+ int _countdown1;
+ int _countdown2;
+ int _countdown3;
+ bool _flag;
+ void update();
+ uint32 handleMessage40C710(int messageNum, const MessageParam &param, Entity *sender);
+ uint32 handleMessage40C7B0(int messageNum, const MessageParam &param, Entity *sender);
+ uint32 handleMessage40C830(int messageNum, const MessageParam &param, Entity *sender);
+ void sub40C8E0();
+ void sub40C930();
+ void sub40C960();
+ void sub40C990();
+ void sub40C9B0();
+ void sub40C9E0();
+};
+
class AsScene1201LeftDoor : public AnimatedSprite {
public:
AsScene1201LeftDoor(NeverhoodEngine *vm, Sprite *klayman);
@@ -144,18 +186,57 @@ public:
protected:
// TODO ResourceTable _resourceTable1;
// TODO ResourceTable _resourceTable2;
- Sprite *_class461;
- Sprite *_class463;
- Sprite *_class462;
+ Sprite *_asMatch;
+ Sprite *_asTntMan;
+ Sprite *_asCreature;
Sprite *_class466;
Sprite *_asLeftDoor;
- Sprite *_class468;
+ Sprite *_asRightDoor;
Sprite *_asTape;
bool _flag;
void update();
uint32 handleMessage(int messageNum, const MessageParam &param, Entity *sender);
};
+// Scene1202
+
+class AsScene1202TntItem : public AnimatedSprite {
+public:
+ AsScene1202TntItem(NeverhoodEngine *vm, Scene *parentScene, int index);
+protected:
+ Scene *_parentScene;
+ int _index, _index2;
+ uint32 handleMessage453FE0(int messageNum, const MessageParam &param, Entity *sender);
+ uint32 handleMessage454060(int messageNum, const MessageParam &param, Entity *sender);
+ void sub4540A0();
+ void sub4540D0();
+ void sub454100();
+ void sub454160();
+};
+
+class Scene1202 : public Scene {
+public:
+ Scene1202(NeverhoodEngine *vm, Module *parentModule, int which);
+ virtual ~Scene1202();
+protected:
+ SoundResource _soundResource1;
+ SoundResource _soundResource2;
+ SoundResource _soundResource3;
+ SoundResource _soundResource4;
+ PaletteResource _paletteResource;
+ Sprite *_asTntItems[18];
+ int _counter;
+ int _index;
+ byte _paletteData[1024];
+ bool _soundFlag;
+ bool _flag;
+ void update();
+ uint32 handleMessage453C10(int messageNum, const MessageParam &param, Entity *sender);
+ uint32 handleMessage453D90(int messageNum, const MessageParam &param, Entity *sender);
+ bool isSolved();
+ void doPaletteEffect();
+};
+
} // End of namespace Neverhood
#endif /* NEVERHOOD_MODULE1200_H */
diff --git a/engines/neverhood/module1400.cpp b/engines/neverhood/module1400.cpp
new file mode 100644
index 0000000000..7d618f5319
--- /dev/null
+++ b/engines/neverhood/module1400.cpp
@@ -0,0 +1,1439 @@
+/* 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/module1400.h"
+#include "neverhood/module1000.h"
+#include "neverhood/diskplayerscene.h"
+#include "neverhood/navigationscene.h"
+
+namespace Neverhood {
+
+Module1400::Module1400(NeverhoodEngine *vm, Module *parentModule, int which)
+ : Module(vm, parentModule) {
+
+ debug("Create Module1400(%d)", which);
+
+ // TODO Music18hList_add(0x00AD0012, 0x06333232);
+ // TODO Music18hList_add(0x00AD0012, 0x624A220E);
+
+ if (which < 0) {
+ switch (_vm->gameState().sceneNum) {
+ case 1:
+ createScene1402(-1);
+ break;
+ case 2:
+ createScene1403(-1);
+ break;
+ case 3:
+ createScene1404(-1);
+ break;
+ case 4:
+ createScene1405(-1);
+ break;
+ case 5:
+ createScene1406(-1);
+ break;
+ case 6:
+ createScene1407(-1);
+ break;
+ default:
+ createScene1401(-1);
+ }
+ } else {
+ createScene1401(0);
+ }
+
+}
+
+Module1400::~Module1400() {
+ // TODO Music18hList_deleteGroup(0x00AD0012);
+}
+
+void Module1400::createScene1401(int which) {
+ _vm->gameState().sceneNum = 0;
+ // TODO Music18hList_play(0x06333232, 0, 2, 1);
+ _childObject = new Scene1401(_vm, this, which);
+ SetUpdateHandler(&Module1400::updateScene1401);
+}
+
+void Module1400::createScene1402(int which) {
+ _vm->gameState().sceneNum = 1;
+ // TODO Music18hList_stop(0x06333232, 0, 2);
+ // TODO Music18hList_stop(0x624A220E, 0, 2);
+ _childObject = new Scene1402(_vm, this, which);
+ SetUpdateHandler(&Module1400::updateScene1402);
+}
+
+void Module1400::createScene1403(int which) {
+ _vm->gameState().sceneNum = 2;
+ // TODO Music18hList_stop(0x06333232, 0, 2);
+ // TODO Music18hList_play(0x624A220E, 0, 2, 1);
+ // TODO _childObject = new Scene1403(_vm, this, which);
+ SetUpdateHandler(&Module1400::updateScene1403);
+}
+
+void Module1400::createScene1404(int which) {
+ _vm->gameState().sceneNum = 3;
+ // TODO Music18hList_play(0x06333232, 0, 2, 1);
+ // TODO _childObject = new Scene1404(_vm, this, which);
+ SetUpdateHandler(&Module1400::updateScene1404);
+}
+
+void Module1400::createScene1405(int which) {
+ _vm->gameState().sceneNum = 4;
+ // TODO Music18hList_play(0x06333232, 0, 2, 1);
+ // TODO _childObject = new Scene1405(_vm, this, which);
+ SetUpdateHandler(&Module1400::updateScene1405);
+}
+
+void Module1400::createScene1406(int which) {
+ _vm->gameState().sceneNum = 5;
+ // TODO Music18hList_stop(0x06333232, 0, 2);
+ _childObject = new DiskplayerScene(_vm, this, 2);
+ SetUpdateHandler(&Module1400::updateScene1405);
+}
+
+void Module1400::createScene1407(int which) {
+ _vm->gameState().sceneNum = 6;
+ // TODO Music18hList_stop(0x06333232, 0, 2);
+ _childObject = new Scene1407(_vm, this, which);
+ SetUpdateHandler(&Module1400::updateScene1407);
+}
+
+void Module1400::updateScene1401() {
+ _childObject->handleUpdate();
+ if (_done) {
+ _done = false;
+ delete _childObject;
+ _childObject = NULL;
+ if (_field20 == 1) {
+ createScene1402(0);
+ _childObject->handleUpdate();
+ } else if (_field20 == 2) {
+ createScene1404(0);
+ _childObject->handleUpdate();
+ } else {
+ _parentModule->sendMessage(0x1009, 0, this);
+ }
+ }
+}
+
+void Module1400::updateScene1402() {
+ _childObject->handleUpdate();
+ if (_done) {
+ _done = false;
+ delete _childObject;
+ _childObject = NULL;
+
+ debug("Scene1402: _field20 = %d", _field20);
+
+ if (_field20 == 1) {
+ createScene1403(0);
+ _childObject->handleUpdate();
+ } else if (_field20 == 2) {
+ createScene1407(-1);
+ _childObject->handleUpdate();
+ } else {
+ createScene1401(1);
+ _childObject->handleUpdate();
+ }
+ }
+}
+
+void Module1400::updateScene1403() {
+ _childObject->handleUpdate();
+ if (_done) {
+ _done = false;
+ delete _childObject;
+ _childObject = NULL;
+ createScene1402(1);
+ _childObject->handleUpdate();
+ }
+}
+
+void Module1400::updateScene1404() {
+ _childObject->handleUpdate();
+ if (_done) {
+ _done = false;
+ delete _childObject;
+ _childObject = NULL;
+ if (_field20 == 1) {
+ createScene1405(0);
+ _childObject->handleUpdate();
+ } else if (_field20 == 2) {
+ createScene1406(-1);
+ _childObject->handleUpdate();
+ } else {
+ createScene1401(2);
+ _childObject->handleUpdate();
+ }
+ }
+}
+
+void Module1400::updateScene1405() {
+ _childObject->handleUpdate();
+ if (_done) {
+ _done = false;
+ delete _childObject;
+ _childObject = NULL;
+ createScene1404(1);
+ _childObject->handleUpdate();
+ }
+}
+
+void Module1400::updateScene1406() {
+ _childObject->handleUpdate();
+ if (_done) {
+ _done = false;
+ delete _childObject;
+ _childObject = NULL;
+ createScene1404(2);
+ _childObject->handleUpdate();
+ }
+}
+
+void Module1400::updateScene1407() {
+ _childObject->handleUpdate();
+ if (_done) {
+ _done = false;
+ delete _childObject;
+ _childObject = NULL;
+ createScene1402(2);
+ _childObject->handleUpdate();
+ }
+}
+
+// Scene1401
+
+Class525::Class525(NeverhoodEngine *vm)
+ : AnimatedSprite(vm, 1100), _soundResource1(vm), _soundResource2(vm),
+ _countdown1(0), _countdown2(0) {
+
+ // TODO createSurface3(900, dword_4B6768);
+ createSurface(900, 640, 480); //TODO: Remeove once the line above is done
+ _x = 454;
+ _y = 217;
+ SetUpdateHandler(&Class525::update4662A0);
+ SetMessageHandler(&Class525::handleMessage466320);
+ setFileHash(0x4C210500, 0, -1);
+}
+
+Class525::~Class525() {
+ // TODO Sound1ChList_sub_407AF0(0x01104C08);
+}
+
+void Class525::update4662A0() {
+ AnimatedSprite::update();
+ if (_countdown1 != 0 && (--_countdown1 == 0)) {
+ sub466460();
+ }
+ if (_countdown2 != 0 && (--_countdown2 == 0)) {
+ // TODO Sound1ChList_addSoundResource(0x01104C08, 0x4A116437, true);
+ // TODO Sound1ChList_playLooping(0x4A116437);
+ }
+}
+
+void Class525::update466300() {
+ AnimatedSprite::update();
+ if (_countdown1 != 0) {
+ _countdown1--;
+ }
+}
+
+uint32 Class525::handleMessage466320(int messageNum, const MessageParam &param, Entity *sender) {
+ uint32 messageResult = Sprite::handleMessage(messageNum, param, sender);
+ switch (messageNum) {
+ case 0x100D:
+ if (param.asInteger() == 0x0A8A1490) {
+ _soundResource2.play(0x6AB6666F);
+ }
+ break;
+ case 0x2000:
+ _countdown1 = 70;
+ _countdown2 = 8;
+ sub466420();
+ break;
+ case 0x483A:
+ sub4664B0();
+ break;
+ }
+ return messageResult;
+}
+
+uint32 Class525::handleMessage4663C0(int messageNum, const MessageParam &param, Entity *sender) {
+ uint32 messageResult = Sprite::handleMessage(messageNum, param, sender);
+ switch (messageNum) {
+ case 0x3002:
+ if (_countdown1 != 0) {
+ sub466420();
+ } else {
+ sub466460();
+ }
+ SetMessageHandler(&Class525::handleMessage466320);
+ SetUpdateHandler(&Class525::update4662A0);
+ break;
+ }
+ return messageResult;
+}
+
+void Class525::sub466420() {
+ setFileHash(0x4C240100, 0, -1);
+ _soundResource1.play(0x4A30063F);
+}
+
+void Class525::sub466460() {
+ // TODO Sound1ChList_deleteSoundByHash(0x4A116437);
+ _soundResource1.play(0x4A120435);
+ setFileHash(0x4C210500, 0, -1);
+}
+
+void Class525::sub4664B0() {
+ setFileHash(0x6C210810, 0, -1);
+ SetMessageHandler(&Class525::handleMessage4663C0);
+ SetUpdateHandler(&Class525::update466300);
+}
+
+Class526::Class526(NeverhoodEngine *vm, Sprite *class525)
+ : AnimatedSprite(vm, 1100), _soundResource(vm), _class525(class525) {
+
+ // TODO createSurface3(100, dword_4B6778);
+ createSurface(100, 640, 480); //TODO: Remeove once the line above is done
+ _x = 478;
+ _y = 433;
+ SetUpdateHandler(&AnimatedSprite::update);
+ SetMessageHandler(&Class526::handleMessage);
+ setFileHash(0xA282C472, 0, -1);
+}
+
+uint32 Class526::handleMessage(int messageNum, const MessageParam &param, Entity *sender) {
+ uint32 messageResult = Sprite::handleMessage(messageNum, param, sender);
+ switch (messageNum) {
+ case 0x100D:
+ if (param.asInteger() == 0x66382026) {
+ _soundResource.play(0x0CD84468);
+ } else if (param.asInteger() == 0x6E28061C) {
+ _soundResource.play(0x78C8402C);
+ } else if (param.asInteger() == 0x462F0410) {
+ _soundResource.play(0x60984E28);
+ }
+ break;
+ case 0x4839:
+ sub466770();
+ break;
+ }
+ return messageResult;
+}
+
+void Class526::spriteUpdate466720() {
+ AnimatedSprite::updateDeltaXY();
+ if (_rect.y1 <= 150) {
+ _soundResource.play(0x0E32247F);
+ setFileHash1();
+ SetSpriteCallback(NULL);
+ SetMessageHandler(NULL);
+ _surface->setVisible(false);
+ }
+}
+
+void Class526::sub466770() {
+ setFileHash(0x34880040, 0, -1);
+ SetSpriteCallback(&Class526::spriteUpdate466720);
+}
+
+Class527::Class527(NeverhoodEngine *vm, Sprite *class526)
+ : AnimatedSprite(vm, 1100), _soundResource(vm), _class526(class526) {
+
+ // TODO createSurface3(200, dword_4B6768);
+ createSurface(200, 640, 480); //TODO: Remeove once the line above is done
+ _x = 427;
+ _y = 433;
+ SetUpdateHandler(&AnimatedSprite::update);
+ SetMessageHandler(&Class527::handleMessage);
+ setFileHash(0x461A1490, 0, -1);
+}
+
+uint32 Class527::handleMessage(int messageNum, const MessageParam &param, Entity *sender) {
+ uint32 messageResult = Sprite::handleMessage(messageNum, param, sender);
+ switch (messageNum) {
+ case 0x4839:
+ sub466970();
+ break;
+ }
+ return messageResult;
+}
+
+void Class527::spriteUpdate466920() {
+ AnimatedSprite::updateDeltaXY();
+ if (_rect.y1 <= 150) {
+ _soundResource.play(0x18020439);
+ setFileHash1();
+ SetSpriteCallback(NULL);
+ SetMessageHandler(NULL);
+ _surface->setVisible(false);
+ }
+}
+
+void Class527::sub466970() {
+ setFileHash(0x103B8020, 0, -1);
+ SetSpriteCallback(&Class527::spriteUpdate466920);
+}
+
+Class528::Class528(NeverhoodEngine *vm, Sprite *klayman, bool flag)
+ : AnimatedSprite(vm, 1100), _soundResource(vm), _klayman(klayman), _countdown(0) {
+
+ _x = 320;
+ _y = 240;
+ createSurface1(100, 0x04551900);
+ SetUpdateHandler(&Class528::update);
+ SetMessageHandler(&Class528::handleMessage);
+ _newHashListIndex = -2;
+ if (flag) {
+ _flag = true;
+ setFileHash(0x04551900, -1,- 1);
+ _countdown = 48;
+ } else {
+ _flag = false;
+ setFileHash1();
+ _surface->setVisible(false);
+ }
+}
+
+void Class528::update() {
+ if (_countdown != 0 && (--_countdown == 0)) {
+ sub466C50();
+ }
+ AnimatedSprite::update();
+}
+
+
+uint32 Class528::handleMessage(int messageNum, const MessageParam &param, Entity *sender) {
+ uint32 messageResult = Sprite::handleMessage(messageNum, param, sender);
+ switch (messageNum) {
+ case 0x2001:
+ if (_flag)
+ _countdown = 168;
+ messageResult = _flag ? 1 : 0;
+ break;
+ case 0x3002:
+ removeCallbacks();
+ break;
+ case 0x4808:
+ _countdown = 168;
+ if (_flag)
+ sub466BF0();
+ break;
+ }
+ return messageResult;
+}
+
+void Class528::sub466BF0() {
+ _flag = true;
+ _surface->setVisible(true);
+ setFileHash(0x04551900, 0, -1);
+ _newHashListIndex = -2;
+ _soundResource.play(calcHash("fxDoorOpen24"));
+}
+
+void Class528::sub466C50() {
+ _flag = false;
+ _surface->setVisible(true);
+ setFileHash(0x04551900, -1, -1);
+ _soundResource.play(calcHash("fxDoorClose24"));
+ _playBackwards = true;
+ SetAnimationCallback3(&Class528::sub466CB0);
+}
+
+void Class528::sub466CB0() {
+ setFileHash1();
+ _surface->setVisible(false);
+}
+
+static const Class489Item kClass489Items[] = {
+ {{154, 453}, 4, 2, 0, -1, 0, 1},
+ {{104, 391}, 4, -1, -1, -1, 1, 1},
+ {{ 22, 447}, 6, -1, -1, -1, 1, 1},
+ {{112, 406}, 2, -1, -1, -1, 1, 0},
+ {{262, 433}, 1, 1, 0, -1, 0, 0}
+};
+
+Class489::Class489(NeverhoodEngine *vm, Scene *parentScene, Sprite *klayman, Sprite *class525)
+ : AnimatedSprite(vm, 1100), _parentScene(parentScene), _klayman(klayman), _class525(class525),
+ _soundResource1(vm), _soundResource2(vm), _soundResource3(vm) {
+
+ _class489Item = &kClass489Items[getGlobalVar(0x04A105B3)];
+ // TODO createSurface3(990, dword_4B26D8);
+ createSurface(990, 640, 480); //TODO: Remeove once the line above is done
+ setFileHash(0x10E3042B, 0, -1);
+ SetUpdateHandler(&AnimatedSprite::update);
+ SetMessageHandler(&Class489::handleMessage);
+ _x = getGlobalVar(0x04A10F33) * 108 + _class489Item->point.x;
+ _flag = true;
+ sub434C80();
+ setDoDeltaX(1);
+ if ((int8)getGlobalVar(0x04A10F33) == _class489Item->varIndex2) {
+ sub434E90();
+ }
+ _soundResource3.load(0xC8C2507C);
+}
+
+Class489::~Class489() {
+ // TODO Sound1ChList_sub_407AF0(0x05331081);
+}
+
+uint32 Class489::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 0x4807:
+ setGlobalVar(0x04A10F33, (_x - _class489Item->point.x) / 108);
+ if ((int8)getGlobalVar(0x04A10F33) == _class489Item->varIndex2) {
+ sub434E60();
+ } else {
+ sub434DD0();
+ }
+ break;
+ case 0x480B:
+ if (param.asInteger() != 1) {
+ if ((int8)getGlobalVar(0x04A10F33) < _class489Item->varIndex1) {
+ incGlobalVar(0x04A10F33, 1);
+ }
+ } else if (getGlobalVar(0x04A10F33) > 0) {
+ incGlobalVar(0x04A10F33, -1);
+ }
+ sub434DF0();
+ break;
+ case 0x480C:
+ if (param.asInteger() != 1) {
+ messageResult = (int8)getGlobalVar(0x04A10F33) < _class489Item->varIndex1 ? 1 : 0;
+ } else {
+ messageResult = getGlobalVar(0x04A10F33) > 0 ? 1 : 0;
+ }
+ break;
+ case 0x482A:
+ _parentScene->sendMessage(0x1022, 990, this);
+ break;
+ case 0x482B:
+ _parentScene->sendMessage(0x1022, 1010, this);
+ break;
+ case 0x4828:
+ sub435040();
+ break;
+ }
+ return messageResult;
+}
+
+uint32 Class489::handleMessage4348E0(int messageNum, const MessageParam &param, Entity *sender) {
+ uint32 messageResult = Sprite::handleMessage(messageNum, param, sender);
+ switch (messageNum) {
+ case 0x1011:
+ if (param.asPoint().x - _x >= 17 && param.asPoint().x - _x <= 56 &&
+ param.asPoint().y - _y >= -120 && param.asPoint().y - _y <= -82) {
+ _parentScene->sendMessage(0x4826, 1, this);
+ } else {
+ _parentScene->sendMessage(0x4826, 0, this);
+ }
+ messageResult = 1;
+ break;
+ case 0x4807:
+ _parentScene->sendMessage(0x4807, 0, this);
+ sub434F80();
+ break;
+ case 0x480B:
+ if (param.asInteger() != 1) {
+ if ((int8)getGlobalVar(0x04A10F33) < _class489Item->varIndex1) {
+ incGlobalVar(0x04A10F33, 1);
+ }
+ } else if (getGlobalVar(0x04A10F33) > 0) {
+ incGlobalVar(0x04A10F33, -1);
+ }
+ sub434FF0();
+ break;
+ case 0x480C:
+ if (param.asInteger() != 1) {
+ messageResult = (int8)getGlobalVar(0x04A10F33) < _class489Item->varIndex1 ? 1 : 0;
+ } else {
+ messageResult = getGlobalVar(0x04A10F33) > 0 ? 1 : 0;
+ }
+ break;
+ case 0x480F:
+ sub434EC0();
+ break;
+ case 0x482A:
+ _parentScene->sendMessage(0x1022, 990, this);
+ break;
+ case 0x482B:
+ _parentScene->sendMessage(0x1022, 1010, this);
+ break;
+ }
+ return messageResult;
+}
+
+uint32 Class489::handleMessage434B20(int messageNum, const MessageParam &param, Entity *sender) {
+ uint32 messageResult = Sprite::handleMessage(messageNum, param, sender);
+ switch (messageNum) {
+ case 0x3002:
+ removeCallbacks();
+ break;
+ }
+ return messageResult;
+}
+
+void Class489::spriteUpdate434B60() {
+ if (_x <= _klayman->getX())
+ _x = _klayman->getX() - 100;
+ else
+ _x = _klayman->getX() + 100;
+ sub434C80();
+ if (_remX == _x) {
+ if (getGlobalVar(0x04A10F33) == 0 && _class489Item->flag4 != 0) {
+ _parentScene->sendMessage(0x1019, 0, this);
+ incGlobalVar(0x04A105B3, -1);
+ setGlobalVar(0x04A10F33, kClass489Items[getGlobalVar(0x04A105B3)].varIndex1);
+ } else if ((int8)getGlobalVar(0x04A10F33) == _class489Item->varIndex1 && _class489Item->flag != 0) {
+ _parentScene->sendMessage(0x1019, 1, this);
+ incGlobalVar(0x04A105B3, +1);
+ setGlobalVar(0x04A10F33, 0);
+ }
+ }
+ Sprite::processDelta();
+}
+
+void Class489::sub434C80() {
+
+ bool soundFlag = false;
+
+ _y = _class489Item->point.y;
+
+ if (_class489Item->index1 != -1) {
+ int16 elX = _class489Item->index1 * 108 + _class489Item->point.x;
+ if (elX - 20 < _x && elX + 20 > _x) {
+ soundFlag = true;
+ _y = _class489Item->point.y + 10;
+ }
+ }
+
+ if (_class489Item->flag2 != -1) {
+ int16 elX = _class489Item->index1 * 108 + _class489Item->point.x;
+ if (elX - 20 < _x && elX + 20 > _x) {
+ soundFlag = true;
+ _y = _class489Item->point.y + 10;
+ }
+ }
+
+ if (_class489Item->varIndex2 != -1) {
+ int16 elX = _class489Item->varIndex2 * 108 + _class489Item->point.x;
+ if (elX - 20 < _x && elX + 20 > _x) {
+ soundFlag = true;
+ _y = _class489Item->point.y + 10;
+ }
+ }
+
+ if (_flag) {
+ if (!soundFlag) {
+ _flag = false;
+ }
+ } else if (soundFlag) {
+ _soundResource2.play(0x5440E474);
+ _flag = true;
+ }
+
+}
+
+void Class489::sub434D80() {
+ AnimatedSprite::updateDeltaXY();
+ if (_rect.y1 <= 150) {
+ _class525->sendMessage(0x483A, 0, this);
+ setFileHash1();
+ SetMessageHandler(&Sprite::handleMessage);
+ SetSpriteCallback(NULL);
+ _surface->setVisible(false);
+ }
+}
+
+void Class489::sub434DD0() {
+ SetSpriteCallback(NULL);
+ SetMessageHandler(&Class489::handleMessage);
+ setFileHash(0x10E3042B, 0, -1);
+}
+
+void Class489::sub434DF0() {
+ _remX = getGlobalVar(0x04A10F33) * 108 + _class489Item->point.x;
+ setFileHash(0x14A10137, 0, -1);
+ SetSpriteCallback(&Class489::spriteUpdate434B60);
+ SetMessageHandler(&Class489::handleMessage);
+ _soundResource2.play(0xEC008474);
+}
+
+void Class489::sub434E60() {
+ SetSpriteCallback(NULL);
+ SetMessageHandler(&Class489::handleMessage434B20);
+ setFileHash(0x80C32213, 0, -1);
+ SetAnimationCallback3(&Class489::sub434E90);
+}
+
+void Class489::sub434E90() {
+ SetSpriteCallback(NULL);
+ SetMessageHandler(&Class489::handleMessage4348E0);
+ setFileHash(0xD23B207F, 0, -1);
+}
+
+void Class489::sub434EC0() {
+ setFileHash(0x50A80517, 0, -1);
+ SetMessageHandler(&Class489::handleMessage434B20);
+ SetSpriteCallback(NULL);
+ SetAnimationCallback3(&Class489::sub434F40);
+ setGlobalVar(0x12A10DB3, 1);
+ _soundResource1.play(0xCC4A8456);
+ // TODO Sound1ChList_addSoundResource(0x05331081, 0xCE428854, true);
+ // TODO Sound1ChList_playLooping(0xCE428854);
+}
+
+void Class489::sub434F40() {
+ _parentScene->sendMessage(0x480F, 0, this);
+ setFileHash(0xD833207F, 0, -1);
+ SetSpriteCallback(NULL);
+ SetMessageHandler(&Class489::handleMessage4348E0);
+}
+
+void Class489::sub434F80() {
+ setFileHash(0x50A94417, 0, -1);
+ SetSpriteCallback(NULL);
+ SetMessageHandler(&Class489::handleMessage434B20);
+ SetAnimationCallback3(&Class489::sub434E90);
+ setGlobalVar(0x12A10DB3, 0);
+ _soundResource1.play(0xCC4A8456);
+ // TODO Sound1ChList_deleteSoundByHash(0xCE428854);
+}
+
+void Class489::sub434FF0() {
+ _remX = getGlobalVar(0x04A10F33) * 108 + _class489Item->point.x;
+ setFileHash(0x22CB4A33, 0, -1);
+ SetSpriteCallback(&Class489::spriteUpdate434B60);
+ SetMessageHandler(&Class489::handleMessage434B20);
+ SetAnimationCallback3(&Class489::sub434DF0);
+}
+
+void Class489::sub435040() {
+ setGlobalVar(0x04A105B3, 4);
+ setGlobalVar(0x04A10F33, 0);
+ SetSpriteCallback(&Class489::sub434D80);
+ SetMessageHandler(&Sprite::handleMessage);
+ setFileHash(0x708D4712, 0, -1);
+ _soundResource3.play();
+}
+
+Scene1401::Scene1401(NeverhoodEngine *vm, Module *parentModule, int which)
+ : Scene(vm, parentModule, true), _flag(false), _class427(NULL), _class489(NULL),
+ _class525(NULL), _class526(NULL), _class527(NULL), _class528(NULL),
+ _sprite1(NULL), _sprite2(NULL), _sprite3(NULL), _ssButton(NULL) {
+
+ SetMessageHandler(&Scene1401::handleMessage);
+ SetUpdateHandler(&Scene1401::update);
+ setRectList(0x004B6758);
+ _surfaceFlag = true;
+
+ _background = addBackground(new DirtyBackground(_vm, 0x08221FA5, 0, 0));
+ _palette = new Palette(_vm, 0x08221FA5);
+ _palette->usePalette();
+ _mouseCursor = addSprite(new Mouse433(_vm, 0x21FA108A, NULL));
+
+ // TODO _class427 = addSprite(new Class427(_vm, this, 0x980F3124, 0x12192892, 100, 0));
+ _class525 = addSprite(new Class525(_vm));
+
+ if (!getGlobalVar(0x01023818)) {
+ _class526 = addSprite(new Class526(_vm, _class525));
+ _class527 = addSprite(new Class527(_vm, _class525));
+ }
+
+ _sprite3 = addSprite(new StaticSprite(_vm, 0xA82BA811, 1100));
+ addSprite(new StaticSprite(_vm, 0x0A116C60, 1100));
+ _ssButton = addSprite(new SsCommonButtonSprite(_vm, this, 0xB84B1100, 100, 0));
+ _sprite1 = addSprite(new StaticSprite(_vm, 0x38EA100C, 1005));
+ _sprite2 = addSprite(new StaticSprite(_vm, 0x98D0223C, 1200));
+ _sprite2->getSurface()->setVisible(false);
+
+ if (which < 0) {
+ _klayman = new KmScene1401(_vm, this, 380, 447);
+ setMessageList(0x004B65C8);
+ _sprite1->getSurface()->setVisible(false);
+ } else if (which == 1) {
+ _klayman = new KmScene1401(_vm, this, 0, 447);
+ setMessageList(0x004B65D0);
+ _sprite1->getSurface()->setVisible(false);
+ } else if (which == 2) {
+ _klayman = new KmScene1401(_vm, this, 660, 447);
+ setMessageList(0x004B65D8);
+ _sprite1->getSurface()->setVisible(false);
+ } else {
+ _klayman = new KmScene1401(_vm, this, 290, 413);
+ setMessageList(0x004B65E8);
+ _sprite1->getSurface()->setVisible(false);
+ }
+ addSprite(_klayman);
+
+ if (getGlobalVar(0x04A105B3) == 2) {
+ _class489 = addSprite(new Class489(_vm, this, _klayman, _class525));
+ _vm->_collisionMan->addSprite(_class489);
+ if (getGlobalVar(0x04A10F33) == 6) {
+ _klayman->sendEntityMessage(0x1014, _class489, this);
+ _klayman->setX(_class489->getX() + 100);
+ _klayman->processDelta();
+ setMessageList(0x004B6670);
+ } else if (getGlobalVar(0x04A10F33) == 0) {
+ _klayman->sendEntityMessage(0x1014, _class489, this);
+ _klayman->setX(_class489->getX() - 100);
+ _klayman->processDelta();
+ setMessageList(0x004B6670);
+ }
+ _class489->getSurface()->getClipRect().x1 = _sprite3->getSurface()->getDrawRect().x;
+ _class489->getSurface()->getClipRect().y1 = _sprite2->getSurface()->getDrawRect().y;
+ _class489->getSurface()->getClipRect().x2 = 640;
+ _class489->getSurface()->getClipRect().y2 = 480;
+ }
+
+ _klayman->getSurface()->getClipRect().x1 = _sprite3->getSurface()->getDrawRect().x;
+ _klayman->getSurface()->getClipRect().y1 = 0;
+ _klayman->getSurface()->getClipRect().x2 = 640;
+ _klayman->getSurface()->getClipRect().y2 = 480;
+
+ if (which == 0 && _class489 && _class489->hasMessageHandler()) {
+ _class489->sendMessage(0x482B, 0, this);
+ }
+
+ _class528 = addSprite(new Class528(_vm, _klayman, which == 1));
+
+}
+
+void Scene1401::update() {
+ Scene::update();
+ if (_class489 && !_flag && _class489->getY() < 360) {
+ _sprite2->getSurface()->setVisible(true);
+ _flag = true;
+ } else {
+ _sprite2->getSurface()->setVisible(false);
+ }
+}
+
+uint32 Scene1401::handleMessage(int messageNum, const MessageParam &param, Entity *sender) {
+ Scene::handleMessage(messageNum, param, sender);
+ switch (messageNum) {
+ case 0x100D:
+ if (param.asInteger() == 0x02144CB1) {
+ _klayman->sendEntityMessage(0x1014, _class427, this);
+ } else if (param.asInteger() == 0x402064D8) {
+ _klayman->sendEntityMessage(0x1014, _ssButton, this);
+ } else if (param.asInteger() == 0x01C66840) {
+ if (_class528->hasMessageHandler() && _class528->sendMessage(0x2001, 0, this) != 0) {
+ setMessageList(0x004B6690);
+ } else {
+ setMessageList(0x004B66B0);
+ }
+ }
+ break;
+ case 0x1019:
+ if (param.asInteger() != 0) {
+ _parentModule->sendMessage(0x1009, 2, this);
+ } else {
+ _parentModule->sendMessage(0x1009, 1, this);
+ }
+ break;
+ case 0x480B:
+ if (sender == _class427) {
+ _class525->sendMessage(0x2000, 0, this);
+ if (!getGlobalVar(0x01023818)) {
+ _class526->sendMessage(0x4839, 0, this);
+ _class527->sendMessage(0x4839, 0, this);
+ setGlobalVar(0x01023818, 1);
+ }
+ if (_class489 && _class489->getX() > 404 && _class489->getX() < 504) {
+ _class489 ->sendMessage(0x4839, 0, this);
+ }
+ } else if (sender == _ssButton) {
+ _ssButton->sendMessage(0x4808, 0, this);
+ }
+ break;
+ case 0x4826:
+ if (sender == _class489) {
+ if (_class489->sendMessage(0x480C, _klayman->getX() > _class489->getX() ? 1 : 0, this) != 0) {
+ _klayman->sendEntityMessage(0x1014, _class489, this);
+ setMessageList2(0x004B6658);
+ } else {
+ setMessageList2(0x004B65F0);
+ }
+ }
+ break;
+ case 0x482A:
+ _sprite1->getSurface()->setVisible(true);
+ if (_class489) {
+ _class489->sendMessage(0x482B, 0, this);
+ }
+ break;
+ case 0x482B:
+ _sprite1->getSurface()->setVisible(false);
+ if (_class489) {
+ _class489->sendMessage(0x482A, 0, this);
+ }
+ break;
+ }
+ return 0;
+}
+
+// Scene1402
+
+Class454::Class454(NeverhoodEngine *vm, uint32 fileHash, int surfacePriority)
+ : StaticSprite(vm, fileHash, surfacePriority) {
+
+ SetFilterY(&Sprite::defFilterY);
+ SetUpdateHandler(&StaticSprite::update);
+
+}
+
+Class482::Class482(NeverhoodEngine *vm, Scene *parentScene, int which)
+ : AnimatedSprite(vm, 1100), _parentScene(parentScene), _soundResource1(vm),
+ _soundResource2(vm) {
+
+ // TODO createSurface3(900, dword_4B6768);
+ createSurface(900, 640, 480); //TODO: Remeove once the line above is done
+
+ SetFilterY(&Sprite::defFilterY);
+ SetUpdateHandler(&AnimatedSprite::update);
+ SetMessageHandler(&Class482::handleMessage);
+ _x = 279;
+ _y = 270;
+ if (which == 2) {
+ setFileHash(0x20060259, 0, -1);
+ _soundResource1.play(0x419014AC);
+ _soundResource2.load(0x61901C29);
+ } else if (which == 1) {
+ setFileHash(0x210A0213, 0, -1);
+ _soundResource1.play(0x41809C6C);
+ } else {
+ setFileHash(0x20060259, 0, -1);
+ _soundResource2.load(0x61901C29);
+ _newHashListIndex = -2;
+ }
+}
+
+uint32 Class482::handleMessage(int messageNum, const MessageParam &param, Entity *sender) {
+ uint32 messageResult = Sprite::handleMessage(messageNum, param, sender);
+ switch (messageNum) {
+ case 0x2002:
+ _soundResource2.play();
+ setFileHash(0x20060259, -1, -1);
+ _playBackwards = true;
+ SetAnimationCallback3(&Class482::sub428530);
+ break;
+ case 0x3002:
+ removeCallbacks();
+ break;
+ }
+ return messageResult;
+}
+
+void Class482::sub428500() {
+ _parentScene->sendMessage(0x2000, 0, this);
+ setFileHash1();
+ _surface->setVisible(false);
+}
+
+void Class482::sub428530() {
+ _parentScene->sendMessage(0x2001, 0, this);
+ setFileHash1();
+ _surface->setVisible(false);
+}
+
+void Class482::sub428560() {
+ _parentScene->sendMessage(0x2003, 0, this);
+ setFileHash1();
+}
+
+Scene1402::Scene1402(NeverhoodEngine *vm, Module *parentModule, int which)
+ : Scene(vm, parentModule, true), _flag(false), _class482(NULL), _class489(NULL) {
+
+ SetMessageHandler(&Scene1402::handleMessage);
+
+ _background = addBackground(new Background(_vm, 0x231482F0, 0, 0));
+ _background->getSurface()->getDrawRect().y = -10;
+ // TODO g_screen->field_26 = 0;
+ _palette = new Palette(_vm, 0x231482F0);
+ _palette->addPalette(0x91D3A391, 0, 64, 0);
+ _palette->usePalette();
+ _mouseCursor = addSprite(new Mouse433(_vm, 0x482F4239, NULL));
+
+ _class454_1 = addSprite(new Class454(_vm, 0x15402D64, 1100));
+ _class454_2 = addSprite(new Class454(_vm, 0x10A02120, 1100));
+ _class454_3 = addSprite(new Class454(_vm, 0x60882BE0, 1100));
+
+ if (getGlobalVar(0x70A1189C))
+ setRectList(0x004B0C48);
+ else
+ setRectList(0x004B0C98);
+
+ if (which < 0) {
+ _klayman = new KmScene1402(_vm, this, 377, 391);
+ setMessageList(0x004B0B48);
+ if (!getGlobalVar(0x70A1189C)) {
+ _class482 = addSprite(new Class482(_vm, this, 0));
+ }
+ } else if (which == 1) {
+ _klayman = new KmScene1402(_vm, this, 42, 391);
+ setMessageList(0x004B0B50);
+ } else if (which == 2) {
+ _klayman = new KmScene1402(_vm, this, 377, 391);
+ setMessageList(0x004B0B60);
+ _klayman->setDoDeltaX(1);
+ if (getGlobalVar(0x70A1189C)) {
+ _class482 = addSprite(new Class482(_vm, this, 1));
+ clearRectList();
+ _mouseCursor->getSurface()->setVisible(false);
+ sub428220();
+ } else {
+ _class482 = addSprite(new Class482(_vm, this, 0));
+ }
+ } else {
+ _klayman = new KmScene1402(_vm, this, 513, 391);
+ setMessageList(0x004B0B58);
+ if (!getGlobalVar(0x70A1189C)) {
+ _class482 = addSprite(new Class482(_vm, this, 2));
+ sub428220();
+ }
+ }
+ addSprite(_klayman);
+
+ if (_class482) {
+ _class482->getSurface()->getClipRect().x1 = 0;
+ _class482->getSurface()->getClipRect().y1 = 0;
+ _class482->getSurface()->getClipRect().x2 = 640;
+ _class482->getSurface()->getClipRect().y2 = _class454_3->getSurface()->getDrawRect().y + _class454_3->getSurface()->getDrawRect().height;
+ }
+
+ if (getGlobalVar(0x4A105B3) == 1) {
+ _class489 = addSprite(new Class489(_vm, this, _klayman, 0));
+ _vm->_collisionMan->addSprite(_class489);
+ if (getGlobalVar(0x4A10F33) == 4) {
+ _klayman->sendEntityMessage(0x1014, _class489, this);
+ _klayman->setX(_class489->getX() + 100);
+ _klayman->processDelta();
+ setMessageList(0x004B0BD0);
+ } else if (getGlobalVar(0x4A10F33) == 0) {
+ _klayman->sendEntityMessage(0x1014, _class489, this);
+ _klayman->setX(_class489->getX() - 100);
+ _klayman->processDelta();
+ setMessageList(0x004B0BD0);
+ }
+ _class489->getSurface()->getClipRect().x1 = _class454_1->getSurface()->getDrawRect().x;
+ _class489->getSurface()->getClipRect().y1 = 0;
+ _class489->getSurface()->getClipRect().x2 = _class454_2->getSurface()->getDrawRect().x;
+ _class489->getSurface()->getClipRect().y2 = _class454_3->getSurface()->getDrawRect().y + _class454_3->getSurface()->getDrawRect().height;
+ }
+
+ _klayman->getSurface()->getClipRect().x1 = _class454_1->getSurface()->getDrawRect().x;
+ _klayman->getSurface()->getClipRect().y1 = 0;
+ _klayman->getSurface()->getClipRect().x2 = _class454_2->getSurface()->getDrawRect().x + _class454_2->getSurface()->getDrawRect().width;
+ _klayman->getSurface()->getClipRect().y2 = _class454_3->getSurface()->getDrawRect().y + _class454_3->getSurface()->getDrawRect().height;
+
+}
+
+void Scene1402::update() {
+ if (_flag) {
+ _background->getSurface()->getDrawRect().y = _vm->_rnd->getRandomNumber(10) - 10;
+ // TODO g_screen->field_26 = -10 - _background->getSurface()->getDrawRect().y;
+ } else {
+ _background->getSurface()->getDrawRect().y = -10;
+ // TODO g_screen->field_26 = 0;
+ SetUpdateHandler(&Scene::update);
+ }
+ Scene::update();
+ if (_class482) {
+ _class482->getSurface()->getClipRect().x1 = 0;
+ _class482->getSurface()->getClipRect().y1 = 0;
+ _class482->getSurface()->getClipRect().x2 = 640;
+ _class482->getSurface()->getClipRect().y2 = _class454_3->getSurface()->getDrawRect().y + _class454_3->getSurface()->getDrawRect().height;
+ }
+ _klayman->getSurface()->getClipRect().x1 = _class454_1->getSurface()->getDrawRect().x;
+ _klayman->getSurface()->getClipRect().y1 = 0;
+ _klayman->getSurface()->getClipRect().x2 = _class454_2->getSurface()->getDrawRect().x + _class454_2->getSurface()->getDrawRect().width;
+ _klayman->getSurface()->getClipRect().y2 = _class454_3->getSurface()->getDrawRect().y + _class454_3->getSurface()->getDrawRect().height;
+}
+
+uint32 Scene1402::handleMessage(int messageNum, const MessageParam &param, Entity *sender) {
+ Scene::handleMessage(messageNum, param, sender);
+ switch (messageNum) {
+ case 0x100D:
+ if (param.asInteger() == 0x00F43389) {
+ if (getGlobalVar(0x70A1189C)) {
+ _parentModule->sendMessage(0x1009, 0, this);
+ } else {
+ clearRectList();
+ _klayman->getSurface()->setVisible(false);
+ _mouseCursor->getSurface()->setVisible(false);
+ _class482->sendMessage(0x2002, 0, this);
+ sub428220();
+ }
+ }
+ break;
+ case 0x1019:
+ if (param.asInteger()) {
+ _parentModule->sendMessage(0x1009, 0, this);
+ } else {
+ _parentModule->sendMessage(0x1009, 1, this);
+ }
+ break;
+ case 0x2000:
+ sub428230();
+ _mouseCursor->getSurface()->setVisible(true);
+ setRectList(0x004B0C48);
+ break;
+ case 0x2001:
+ sub428230();
+ _parentModule->sendMessage(0x1009, 0, this);
+ break;
+ case 0x2003:
+ sub428230();
+ break;
+ case 0x4826:
+ if (sender == _class489) {
+ if (_class489->sendMessage(0x408C, _klayman->getX() > _class489->getX() ? 1 : 0, this) != 0) {
+ _klayman->sendEntityMessage(0x1014, _class489, this);
+ setMessageList2(0x004B0BB8);
+ } else {
+ setMessageList2(0x004B0B68);
+ }
+ }
+ }
+ return 0;
+}
+
+void Scene1402::sub428220() {
+ _flag = true;
+ SetUpdateHandler(&Scene1402::update);
+}
+
+void Scene1402::sub428230() {
+ _flag = false;
+}
+
+// Scene1407
+
+static const int16 kScene1407MouseFloorY[] = {
+ 106, 150, 191, 230, 267, 308, 350, 395
+};
+
+static const struct {
+ int16 x;
+ int16 floorIndex;
+ int16 sectionIndex;
+ int16 nextHoleIndex;
+} kScene1407MouseHoles[] = {
+ {125, 0, 0, 7},
+ {452, 7, 21, 0},
+ {337, 4, 11, 4},
+ {286, 6, 17, 6},
+ {348, 6, 17, 39},
+ {536, 6, 18, 42},
+ {111, 1, 3, 18},
+ {203, 1, 3, 38},
+ {270, 1, 3, 9},
+ {197, 5, 14, 3},
+ {252, 5, 14, 35},
+ {297, 5, 14, 7},
+ {359, 5, 14, 8},
+ {422, 4, 12, 26},
+ {467, 4, 12, 2},
+ {539, 4, 12, 40},
+ {111, 5, 13, 17},
+ {211, 0, 1, 20},
+ {258, 0, 1, 11},
+ {322, 0, 1, 16},
+ { 99, 6, 16, 31},
+ {142, 6, 16, 27},
+ {194, 6, 16, 12},
+ {205, 2, 6, 45},
+ {264, 2, 6, 10},
+ { 98, 4, 10, 2},
+ {152, 4, 10, 37},
+ {199, 4, 10, 13},
+ {258, 4, 10, 16},
+ {100, 7, 19, 43},
+ {168, 7, 19, 23},
+ {123, 3, 8, 14},
+ {181, 3, 8, 39},
+ {230, 3, 8, 28},
+ {292, 3, 8, 22},
+ {358, 3, 8, 36},
+ {505, 3, 9, 44},
+ {400, 2, 7, 34},
+ {454, 2, 7, 32},
+ {532, 2, 7, 46},
+ {484, 5, 15, 25},
+ {529, 5, 15, 30},
+ {251, 7, 20, 48},
+ {303, 7, 20, 21},
+ {360, 7, 20, 33},
+ {503, 0, 2, 5},
+ {459, 1, 4, 19},
+ {530, 1, 4, 42},
+ {111, 2, 5, 47},
+ {442, 6, 18, 1}
+};
+
+static const struct {
+ int16 x1, x2;
+ int16 goodHoleIndex;
+} kScene1407MouseSections[] = {
+ {100, 149, 0},
+ {182, 351, 17},
+ {430, 524, 45},
+ { 89, 293, 7},
+ {407, 555, 47},
+ { 89, 132, 48},
+ {178, 303, 23},
+ {367, 551, 38},
+ {105, 398, 31},
+ {480, 537, 36},
+ { 84, 275, 27},
+ {318, 359, 2},
+ {402, 560, 15},
+ { 91, 132, 16},
+ {179, 400, 10},
+ {461, 552, 41},
+ { 86, 218, 21},
+ {267, 376, 4},
+ {420, 560, 49},
+ { 77, 188, 30},
+ {237, 394, 44},
+ {438, 515, 5}
+};
+
+AsScene1407Mouse::AsScene1407Mouse(NeverhoodEngine *vm, Scene *parentScene)
+ : AnimatedSprite(vm, 1100), _parentScene(parentScene), _currSectionIndex(0) {
+
+ // TODO createSurface3(100, dword_4B05B0);
+ createSurface(100, 640, 480); //TODO: Remeove once the line above is done
+
+ SetUpdateHandler(&AnimatedSprite::update);
+ _x = 108;
+ _y = 106;
+ stIdleLookAtGoodHole();
+}
+
+void AsScene1407Mouse::suWalkTo() {
+ int16 xdelta = _walkDestX - _x;
+ if (xdelta > _deltaX)
+ xdelta = _deltaX;
+ else if (xdelta < -_deltaX)
+ xdelta = -_deltaX;
+ _deltaX = 0;
+ if (_walkDestX == _x) {
+ sendMessage(0x1019, 0, this);
+ } else {
+ _x += xdelta;
+ processDelta();
+ }
+}
+
+void AsScene1407Mouse::upGoThroughHole() {
+ if (_countdown != 0 && (--_countdown == 0)) {
+ SetUpdateHandler(&AnimatedSprite::update);
+ removeCallbacks();
+ }
+ AnimatedSprite::update();
+}
+
+uint32 AsScene1407Mouse::handleMessage(int messageNum, const MessageParam &param, Entity *sender) {
+ uint32 messageResult = Sprite::handleMessage(messageNum, param, sender);
+ switch (messageNum) {
+ case 0x0001:
+ {
+ int16 mouseX = param.asPoint().x;
+ int16 mouseY = param.asPoint().y;
+ int holeIndex;
+ for (holeIndex = 0; holeIndex < 50; holeIndex++) {
+ int16 holeX = kScene1407MouseHoles[holeIndex].x;
+ int16 holeY = kScene1407MouseFloorY[kScene1407MouseHoles[holeIndex].floorIndex];
+ if (mouseX >= holeX - 14 && mouseX <= holeX + 14 && mouseY >= holeY - 36 && mouseY <= holeY)
+ break;
+ }
+ if (holeIndex < 50 && kScene1407MouseHoles[holeIndex].sectionIndex == _currSectionIndex) {
+ _nextHoleIndex = kScene1407MouseHoles[holeIndex].nextHoleIndex;
+ _walkDestX = kScene1407MouseHoles[holeIndex].x;
+ stWalkToHole();
+ } else {
+ if (mouseX < kScene1407MouseSections[_currSectionIndex].x1) {
+ _walkDestX = kScene1407MouseSections[_currSectionIndex].x1;
+ } else if (mouseX > kScene1407MouseSections[_currSectionIndex].x2) {
+ _walkDestX = kScene1407MouseSections[_currSectionIndex].x2;
+ } else {
+ _walkDestX = mouseX;
+ }
+ stWalkToDest();
+ }
+ }
+ break;
+ case 0x1019:
+ removeCallbacks();
+ break;
+ case 0x2001:
+ {
+ // Reset the position
+ // Find the nearest hole and go through it, and exit at the first hole
+ int16 distance = 640;
+ int matchIndex = 50;
+ for (int index = 0; index < 50; index++) {
+ if (kScene1407MouseHoles[index].sectionIndex == _currSectionIndex) {
+ if (ABS(kScene1407MouseHoles[index].x - _x) < distance) {
+ matchIndex = index;
+ distance = ABS(kScene1407MouseHoles[index].x - _x);
+ }
+ }
+ }
+ if (matchIndex < 50) {
+ _nextHoleIndex = 0;
+ _walkDestX = kScene1407MouseHoles[matchIndex].x;
+ stWalkToHole();
+ }
+ }
+ break;
+ }
+ return messageResult;
+}
+
+void AsScene1407Mouse::stIdleLookAtGoodHole() {
+ setDoDeltaX(kScene1407MouseHoles[kScene1407MouseSections[_currSectionIndex].goodHoleIndex].x < _x ? 1 : 0);
+ setFileHash(0x72215194, 0, -1);
+ SetSpriteCallback(NULL);
+ SetMessageHandler(&AsScene1407Mouse::handleMessage);
+}
+
+void AsScene1407Mouse::stWalkToDest() {
+ if (_walkDestX != _x) {
+ setDoDeltaX(_walkDestX < _x ? 1 : 0);
+ setFileHash(0x22291510, 0, -1);
+ SetSpriteCallback(&AsScene1407Mouse::suWalkTo);
+ SetMessageHandler(&AsScene1407Mouse::handleMessage);
+ SetAnimationCallback3(&AsScene1407Mouse::stIdleLookAtGoodHole);
+ }
+}
+
+void AsScene1407Mouse::stWalkToHole() {
+ setDoDeltaX(_walkDestX < _x ? 1 : 0);
+ setFileHash(0x22291510, 0, -1);
+ SetSpriteCallback(&AsScene1407Mouse::suWalkTo);
+ SetMessageHandler(&AsScene1407Mouse::handleMessage);
+ SetAnimationCallback3(&AsScene1407Mouse::stGoThroughHole);
+}
+
+void AsScene1407Mouse::stGoThroughHole() {
+ setFileHash(0x72215194, 0, -1);
+ SetSpriteCallback(NULL);
+ SetMessageHandler(NULL);
+ SetUpdateHandler(&AsScene1407Mouse::upGoThroughHole);
+ SetAnimationCallback3(&AsScene1407Mouse::stArriveAtHole);
+ _surface->setVisible(false);
+ _countdown = 12;
+}
+
+void AsScene1407Mouse::stArriveAtHole() {
+ _currSectionIndex = kScene1407MouseHoles[_nextHoleIndex].sectionIndex;
+ _x = kScene1407MouseHoles[_nextHoleIndex].x;
+ _y = kScene1407MouseFloorY[kScene1407MouseHoles[_nextHoleIndex].floorIndex];
+ if (_nextHoleIndex == 1) {
+ _parentScene->sendMessage(0x2000, 0, this);
+ _walkDestX = 512;
+ stWalkToDest();
+ _surface->setVisible(true);
+ } else {
+ _walkDestX = _x + 14;
+ stWalkToDest();
+ _surface->setVisible(true);
+ }
+}
+
+Scene1407::Scene1407(NeverhoodEngine *vm, Module *parentModule, int which)
+ : Scene(vm, parentModule, true), _soundResource(vm), _puzzleSolvedCountdown(0),
+ _resetButtonCountdown(0) {
+
+ _surfaceFlag = true;
+
+ SetMessageHandler(&Scene1407::handleMessage);
+ SetUpdateHandler(&Scene1407::update);
+
+ _background = addBackground(new DirtyBackground(_vm, 0x00442225, 0, 0));
+ _palette = new Palette(_vm, 0x00442225);
+ _palette->usePalette();
+ _mouseCursor = addSprite(new Mouse435(_vm, 0x4222100C, 20, 620));
+
+ _asMouse = addSprite(new AsScene1407Mouse(_vm, this));
+ _ssResetButton = addSprite(new StaticSprite(_vm, 0x12006600, 100));
+ _ssResetButton->getSurface()->setVisible(false);
+
+}
+
+void Scene1407::update() {
+ Scene::update();
+ if (_puzzleSolvedCountdown != 0 && (--_puzzleSolvedCountdown == 0)) {
+ _parentModule->sendMessage(0x1009, 1, this);
+ } else if (_resetButtonCountdown != 0 && (--_resetButtonCountdown == 0)) {
+ _ssResetButton->getSurface()->setVisible(false);
+ }
+}
+
+uint32 Scene1407::handleMessage(int messageNum, const MessageParam &param, Entity *sender) {
+ Scene::handleMessage(messageNum, param, sender);
+ switch (messageNum) {
+ case 0x0001:
+ if (_puzzleSolvedCountdown == 0) {
+ // TODO: Debug/Cheat stuff
+ if (param.asPoint().x <= 20 || param.asPoint().x >= 620) {
+ // Exit scene
+ _parentModule->sendMessage(0x1009, 0, this);
+ } else if (param.asPoint().x >= 75 && param.asPoint().x <= 104 &&
+ param.asPoint().y >= 62 && param.asPoint().y <= 90) {
+ // The reset button was clicked
+ _asMouse->sendMessage(0x2001, 0, this);
+ _ssResetButton->getSurface()->setVisible(true);
+ _soundResource.play(0x44045000);
+ _resetButtonCountdown = 12;
+ } else {
+ // Handle the mouse
+ _asMouse->sendMessage(messageNum, param, this);
+ }
+ }
+ break;
+ case 0x000D:
+ // TODO: Debug/Cheat stuff
+ break;
+ case 0x2000:
+ // The mouse got the cheese (nomnom)
+ setGlobalVar(0x70A1189C, 1);
+ _soundResource.play(0x68E25540);
+ _mouseCursor->getSurface()->setVisible(false);
+ _puzzleSolvedCountdown = 72;
+ break;
+ }
+ return 0;
+}
+
+} // End of namespace Neverhood
diff --git a/engines/neverhood/module1400.h b/engines/neverhood/module1400.h
new file mode 100644
index 0000000000..433dc413f5
--- /dev/null
+++ b/engines/neverhood/module1400.h
@@ -0,0 +1,242 @@
+/* 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.
+ *
+ */
+
+#ifndef NEVERHOOD_MODULE1400_H
+#define NEVERHOOD_MODULE1400_H
+
+#include "neverhood/neverhood.h"
+#include "neverhood/module.h"
+#include "neverhood/scene.h"
+
+namespace Neverhood {
+
+class Module1400 : public Module {
+public:
+ Module1400(NeverhoodEngine *vm, Module *parentModule, int which);
+ virtual ~Module1400();
+protected:
+ void createScene1401(int which);
+ void createScene1402(int which);
+ void createScene1403(int which);
+ void createScene1404(int which);
+ void createScene1405(int which);
+ void createScene1406(int which);
+ void createScene1407(int which);
+ void updateScene1401();
+ void updateScene1402();
+ void updateScene1403();
+ void updateScene1404();
+ void updateScene1405();
+ void updateScene1406();
+ void updateScene1407();
+};
+
+// Scene1401
+
+class Class525 : public AnimatedSprite {
+public:
+ Class525(NeverhoodEngine *vm);
+ virtual ~Class525();
+protected:
+ int _countdown1;
+ int _countdown2;
+ SoundResource _soundResource1;
+ SoundResource _soundResource2;
+ void update4662A0();
+ void update466300();
+ uint32 handleMessage466320(int messageNum, const MessageParam &param, Entity *sender);
+ uint32 handleMessage4663C0(int messageNum, const MessageParam &param, Entity *sender);
+ void sub466420();
+ void sub466460();
+ void sub4664B0();
+};
+
+class Class526 : public AnimatedSprite {
+public:
+ Class526(NeverhoodEngine *vm, Sprite *class525);
+protected:
+ Sprite *_class525;
+ SoundResource _soundResource;
+ uint32 handleMessage(int messageNum, const MessageParam &param, Entity *sender);
+ void spriteUpdate466720();
+ void sub466770();
+};
+
+class Class527 : public AnimatedSprite {
+public:
+ Class527(NeverhoodEngine *vm, Sprite *class526);
+protected:
+ Sprite *_class526;
+ SoundResource _soundResource;
+ uint32 handleMessage(int messageNum, const MessageParam &param, Entity *sender);
+ void spriteUpdate466920();
+ void sub466970();
+};
+
+class Class528 : public AnimatedSprite {
+public:
+ Class528(NeverhoodEngine *vm, Sprite *klayman, bool flag);
+protected:
+ Sprite *_klayman;
+ SoundResource _soundResource;
+ int _countdown;
+ bool _flag;
+ void update();
+ uint32 handleMessage(int messageNum, const MessageParam &param, Entity *sender);
+ void sub466BF0();
+ void sub466C50();
+ void sub466CB0();
+};
+
+struct Class489Item {
+ NPoint point;
+ int8 varIndex1;
+ int8 varIndex2;
+ int8 index1;
+ int8 flag2;
+ int8 flag4;
+ int8 flag;
+};
+
+class Class489 : public AnimatedSprite {
+public:
+ Class489(NeverhoodEngine *vm, Scene *parentScene, Sprite *klayman, Sprite *class525);
+ virtual ~Class489();
+protected:
+ Scene *_parentScene;
+ Sprite *_klayman;
+ Sprite *_class525;
+ const Class489Item *_class489Item;
+ SoundResource _soundResource1;
+ SoundResource _soundResource2;
+ SoundResource _soundResource3;
+ int16 _remX;
+ bool _flag;
+ uint32 handleMessage(int messageNum, const MessageParam &param, Entity *sender);
+ uint32 handleMessage4348E0(int messageNum, const MessageParam &param, Entity *sender);
+ uint32 handleMessage434B20(int messageNum, const MessageParam &param, Entity *sender);
+ void spriteUpdate434B60();
+ void sub434C80();
+ void sub434D80();
+ void sub434DD0();
+ void sub434DF0();
+ void sub434E60();
+ void sub434E90();
+ void sub434EC0();
+ void sub434F40();
+ void sub434F80();
+ void sub434FF0();
+ void sub435040();
+};
+
+class Scene1401 : public Scene {
+public:
+ Scene1401(NeverhoodEngine *vm, Module *parentModule, int which);
+protected:
+ bool _flag;
+ Sprite *_class427;
+ Sprite *_class489;
+ Sprite *_class525;
+ Sprite *_class526;
+ Sprite *_class527;
+ Sprite *_class528;
+ Sprite *_sprite1;
+ Sprite *_sprite2;
+ Sprite *_sprite3;
+ Sprite *_ssButton;
+ void update();
+ uint32 handleMessage(int messageNum, const MessageParam &param, Entity *sender);
+};
+
+// Scene1402
+
+class Class454 : public StaticSprite {
+public:
+ Class454(NeverhoodEngine *vm, uint32 fileHash, int surfacePriority);
+};
+
+class Class482 : public AnimatedSprite {
+public:
+ Class482(NeverhoodEngine *vm, Scene *parentScene, int which);
+protected:
+ Scene *_parentScene;
+ SoundResource _soundResource1;
+ SoundResource _soundResource2;
+ uint32 handleMessage(int messageNum, const MessageParam &param, Entity *sender);
+ void sub428500();
+ void sub428530();
+ void sub428560();
+};
+
+class Scene1402 : public Scene {
+public:
+ Scene1402(NeverhoodEngine *vm, Module *parentModule, int which);
+protected:
+ Sprite *_class454_1;
+ Sprite *_class454_2;
+ Sprite *_class454_3;
+ Sprite *_class482;
+ Sprite *_class489;
+ bool _flag;
+ void update();
+ uint32 handleMessage(int messageNum, const MessageParam &param, Entity *sender);
+ void sub428220();
+ void sub428230();
+};
+
+// Scene1407
+
+class AsScene1407Mouse : public AnimatedSprite {
+public:
+ AsScene1407Mouse(NeverhoodEngine *vm, Scene *parentScene);
+protected:
+ Scene *_parentScene;
+ int16 _walkDestX;
+ int16 _currSectionIndex;
+ int16 _nextHoleIndex;
+ int _countdown;
+ uint32 handleMessage(int messageNum, const MessageParam &param, Entity *sender);
+ void suWalkTo();
+ void upGoThroughHole();
+ void stIdleLookAtGoodHole();
+ void stWalkToDest();
+ void stWalkToHole();
+ void stGoThroughHole();
+ void stArriveAtHole();
+};
+
+class Scene1407 : public Scene {
+public:
+ Scene1407(NeverhoodEngine *vm, Module *parentModule, int which);
+protected:
+ SoundResource _soundResource;
+ Sprite *_asMouse;
+ Sprite *_ssResetButton;
+ int _puzzleSolvedCountdown;
+ int _resetButtonCountdown;
+ void update();
+ uint32 handleMessage(int messageNum, const MessageParam &param, Entity *sender);
+};
+
+} // End of namespace Neverhood
+
+#endif /* NEVERHOOD_MODULE1400_H */
diff --git a/engines/neverhood/module1700.cpp b/engines/neverhood/module1700.cpp
new file mode 100644
index 0000000000..3289173dfb
--- /dev/null
+++ b/engines/neverhood/module1700.cpp
@@ -0,0 +1,359 @@
+/* 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/module1700.h"
+#include "neverhood/navigationscene.h"
+
+namespace Neverhood {
+
+Module1700::Module1700(NeverhoodEngine *vm, Module *parentModule, int which)
+ : Module(vm, parentModule), _soundResource(vm) {
+
+ debug("Create Module1700(%d)", which);
+
+ // TODO Music18hList_add(0x04212331);
+ // TODO Sound1ChList_addSoundResources(0x04212331, dword_4AE930, true);
+ // TODO Sound1ChList_setSoundValuesMulti(dword_4AE930, 1, 50, 600, 5, 150);
+ // TODO Sound1ChList_sub_407C70(0x04212331, 0x41861371, 0x43A2507F, 0);
+
+ if (which < 0) {
+ switch (_vm->gameState().sceneNum) {
+ case 0:
+ createScene1701(-1);
+ break;
+ case 1:
+ createScene1702(-1);
+ break;
+ case 2:
+ createScene1703(-1);
+ break;
+ case 3:
+ createScene1704(-1);
+ break;
+ default:
+ createScene1705(-1);
+ }
+ } else if (which == 0) {
+ createScene1701(-1);
+ } else if (which == 1) {
+ createScene1705(1);
+ } else {
+ createScene1705(3);
+ }
+
+}
+
+Module1700::~Module1700() {
+ // TODO Sound1ChList_sub_407A50(0x04212331);
+}
+
+void Module1700::createScene1701(int which) {
+ SmackerScene *smackerScene;
+ _vm->gameState().sceneNum = 0;
+ // TODO Sound1ChList_setSoundValuesMulti(dword_4AE930, 0, 0, 0, 0, 0);
+ smackerScene = new SmackerScene(_vm, this, true, true, false);
+ smackerScene->setFileHash(0x3028A005);
+ smackerScene->nextVideo();
+ _childObject = smackerScene;
+ SetUpdateHandler(&Module1700::updateScene1701);
+}
+
+void Module1700::createScene1702(int which) {
+ _vm->gameState().sceneNum = 1;
+ _childObject = new NavigationScene(_vm, this, 0x004AE8B8, which, NULL);
+ SetUpdateHandler(&Module1700::updateScene1702);
+}
+
+void Module1700::createScene1703(int which) {
+ _vm->gameState().sceneNum = 2;
+ _childObject = new NavigationScene(_vm, this, 0x004AE8E8, which, NULL);
+ SetUpdateHandler(&Module1700::updateScene1703);
+}
+
+void Module1700::createScene1704(int which) {
+ SmackerScene *smackerScene;
+ _vm->gameState().sceneNum = 3;
+ // TODO Sound1ChList_setSoundValuesMulti(dword_4AE930, 0, 0, 0, 0, 0);
+ smackerScene = new SmackerScene(_vm, this, true, true, false);
+ smackerScene->setFileHash(0x01190041);
+ smackerScene->nextVideo();
+ _childObject = smackerScene;
+ SetUpdateHandler(&Module1700::updateScene1701);
+}
+
+void Module1700::createScene1705(int which) {
+ _vm->gameState().sceneNum = 4;
+ // TODO Sound1ChList_setSoundValuesMulti(dword_4AE930, 0, 0, 0, 0, 0);
+ // TODO Music18hList_play(0x31114225, 0, 2, 1);
+ _childObject = new Scene1705(_vm, this, which);
+ SetUpdateHandler(&Module1700::updateScene1705);
+}
+
+void Module1700::updateScene1701() {
+ _childObject->handleUpdate();
+ if (_done) {
+ _done = false;
+ delete _childObject;
+ _childObject = NULL;
+ if (_vm->gameState().sceneNum == 3) {
+ createScene1705(0);
+ _childObject->handleUpdate();
+ } else {
+ // TODO Sound1ChList_setSoundValuesMulti(dword_4AE930, 1, 0, 0, 0);
+ createScene1702(0);
+ _childObject->handleUpdate();
+ }
+ }
+}
+
+void Module1700::updateScene1702() {
+ _childObject->handleUpdate();
+ if (_done) {
+ _done = false;
+ delete _childObject;
+ _childObject = NULL;
+ if (_field20 == 0) {
+ createScene1703(0);
+ _childObject->handleUpdate();
+ } else if (_field20 == 1) {
+ createScene1702(1);
+ _childObject->handleUpdate();
+ }
+ }
+}
+
+void Module1700::updateScene1703() {
+ _childObject->handleUpdate();
+ if (_done) {
+ _done = false;
+ delete _childObject;
+ _childObject = NULL;
+ if (_field20 == 0) {
+ createScene1704(-1);
+ _childObject->handleUpdate();
+ } else if (_field20 == 1) {
+ createScene1702(1);
+ _childObject->handleUpdate();
+ } else if (_field20 == 2) {
+ if (!_soundResource.isPlaying()) {
+ // TODO _soundResource.setVolume(60);
+ _soundResource.play(0x58B45E58);
+ }
+ createScene1703(2);
+ _childObject->handleUpdate();
+ }
+ }
+}
+
+void Module1700::updateScene1705() {
+ _childObject->handleUpdate();
+ if (_done) {
+ _done = false;
+ delete _childObject;
+ _childObject = NULL;
+ _parentModule->sendMessage(0x1009, 1, this);
+ }
+}
+
+// Scene1705
+
+static const uint32 kScene1705FileHashes[] = {
+ 0x910EA801,
+ 0x920EA801,
+ 0x940EA801,
+ 0x980EA801,
+ 0x800EA801,
+ 0xB00EA801,
+ 0xD00EA801,
+ 0x100EA801,
+ 0x900EA800,
+ 0xD10EA801,
+ 0x110EA801,
+ 0x910EA800
+};
+
+Class602::Class602(NeverhoodEngine *vm, uint32 fileHash, int index)
+ : StaticSprite(vm, fileHash, 100) {
+
+ _x = _spriteResource.getPosition().x + index * 30;
+ _y = _spriteResource.getPosition().y + 160;
+ StaticSprite::update();
+}
+
+Class606::Class606(NeverhoodEngine *vm, Scene *parentScene, int index, int surfacePriority, int16 x, int16 y, uint32 fileHash)
+ : StaticSprite(vm, fileHash, surfacePriority, x - 24, y - 4), _parentScene(parentScene), _index(index) {
+
+ if (!getSubVar(0x02038314, _index) && !getSubVar(0x02720344, _index)) {
+ SetMessageHandler(&Class606::handleMessage);
+ } else {
+ _surface->setVisible(false);
+ SetMessageHandler(NULL);
+ }
+ _deltaRect = _drawRect;
+ _deltaRect.x -= 4;
+ _deltaRect.y -= 8;
+ _deltaRect.width += 8;
+ _deltaRect.height += 16;
+ Sprite::processDelta();
+}
+
+uint32 Class606::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(0x02038314, _index, 1);
+ _surface->setVisible(false);
+ SetMessageHandler(NULL);
+ break;
+ }
+ return messageResult;
+}
+
+Scene1705::Scene1705(NeverhoodEngine *vm, Module *parentModule, int which)
+ : Scene(vm, parentModule, true), _paletteArea(1) {
+
+ Palette2 *palette2;
+ Sprite *tempSprite;
+
+ setGlobalVar(0xE7498218, 1);
+ // TODO _vm->initVarsScene1705();
+
+ SetMessageHandler(&Scene1705::handleMessage);
+ SetUpdateHandler(&Scene1705::update);
+
+ _vm->_collisionMan->setHitRects(0x004B69D8);
+
+ _surfaceFlag = true;
+
+ _background = addBackground(new DirtyBackground(_vm, 0x03118226, 0, 0));
+
+ palette2 = new Palette2(_vm, 0x03118226);
+ palette2->addPalette(0x91D3A391, 0, 64, 0);
+ palette2->copyBasePalette(0, 256, 0);
+ palette2->usePalette();
+ _palette = palette2;
+ addEntity(_palette);
+
+ _mouseCursor = addSprite(new Mouse433(_vm, 0x18222039, NULL));
+
+ addSprite(new Class602(_vm, kScene1705FileHashes[getSubVar(0x0A4C0A9A, 0)], 0));
+ addSprite(new Class602(_vm, kScene1705FileHashes[getSubVar(0x0A4C0A9A, 1)], 1));
+ addSprite(new Class602(_vm, kScene1705FileHashes[getSubVar(0x0A4C0A9A, 2)], 2));
+
+ _sprite = addSprite(new StaticSprite(_vm, 0x31313A22, 1100));
+
+ _class606 = addSprite(new Class606(_vm, this, 15, 1100, 238, 439, 0x02363852));
+ _vm->_collisionMan->addSprite(_class606);
+
+ which = 4;
+
+ if (which < 0) {
+ _klayman = new KmScene1705(_vm, this, 231, 434);
+ setMessageList(0x004B69E8);
+ sendMessage(0x2000, 0, this);
+ _klayman->getSurface()->getClipRect().x1 = 0;
+ _klayman->getSurface()->getClipRect().y1 = 0;
+ _klayman->getSurface()->getClipRect().x2 = _sprite->getSurface()->getDrawRect().x + _sprite->getSurface()->getDrawRect().width;
+ _klayman->getSurface()->getClipRect().y2 = 480;
+ } else if (which == 1) {
+ _klayman = new KmScene1705(_vm, this, 431, 434);
+ _klayman->sendMessage(0x2000, 1, this);
+ setMessageList(0x004B6A08);
+ sendMessage(0x2000, 1, this);
+ _klayman->getSurface()->getClipRect().x1 = 0;
+ _klayman->getSurface()->getClipRect().y1 = 0;
+ _klayman->getSurface()->getClipRect().x2 = _sprite->getSurface()->getDrawRect().x + _sprite->getSurface()->getDrawRect().width;
+ _klayman->getSurface()->getClipRect().y2 = 480;
+ } else if (which == 2) {
+ _klayman = new KmScene1705(_vm, this, 431, 434);
+ _klayman->sendMessage(0x2000, 1, this);
+ setMessageList(0x004B6AA0);
+ sendMessage(0x2000, 1, this);
+ _klayman->getSurface()->getClipRect().x1 = 0;
+ _klayman->getSurface()->getClipRect().y1 = 0;
+ _klayman->getSurface()->getClipRect().x2 = _sprite->getSurface()->getDrawRect().x + _sprite->getSurface()->getDrawRect().width;
+ _klayman->getSurface()->getClipRect().y2 = 480;
+ } else if (which == 3) {
+ _klayman = new KmScene1705(_vm, this, 431, 434);
+ _klayman->sendMessage(0x2000, 1, this);
+ setMessageList(0x004B6A18);
+ sendMessage(0x2000, 1, this);
+ _klayman->getSurface()->getClipRect().x1 = 0;
+ _klayman->getSurface()->getClipRect().y1 = 0;
+ _klayman->getSurface()->getClipRect().x2 = _sprite->getSurface()->getDrawRect().x + _sprite->getSurface()->getDrawRect().width;
+ _klayman->getSurface()->getClipRect().y2 = 480;
+ } else {
+ _klayman = new KmScene1705(_vm, this, 231, 74);
+ _klayman->sendMessage(0x2000, 0, this);
+ setMessageList(0x004B69F0);
+ sendMessage(0x2000, 0, this);
+ tempSprite = addSprite(new StaticSprite(_vm, 0x30303822, 1100));
+ _klayman->getSurface()->getClipRect().x1 = 0;
+ _klayman->getSurface()->getClipRect().y1 = tempSprite->getSurface()->getDrawRect().y;
+ _klayman->getSurface()->getClipRect().x2 = _sprite->getSurface()->getDrawRect().x + _sprite->getSurface()->getDrawRect().width;
+ _klayman->getSurface()->getClipRect().y2 = 480;
+ }
+
+ addSprite(_klayman);
+
+}
+
+void Scene1705::update() {
+ Scene::update();
+ if (_klayman->getX() < 224 && _paletteArea != 0) {
+ ((Palette2*)_palette)->addPalette(0xF2210C15, 0, 64, 0);
+ ((Palette2*)_palette)->startFadeToPalette(12);
+ _paletteArea = 0;
+ } else if (_klayman->getX() >= 224 && _paletteArea == 0) {
+ ((Palette2*)_palette)->addPalette(0x91D3A391, 0, 64, 0);
+ ((Palette2*)_palette)->startFadeToPalette(12);
+ _paletteArea = 1;
+ }
+}
+
+uint32 Scene1705::handleMessage(int messageNum, const MessageParam &param, Entity *sender) {
+ Scene::handleMessage(messageNum, param, sender);
+ switch (messageNum) {
+ case 0x2000:
+ if (param.asInteger()) {
+ setRectList(0x004B6B40);
+ _klayman->setKlaymanTable3();
+ } else {
+ setRectList(0x004B6B30);
+ _klayman->setKlaymanTable1();
+ }
+ break;
+ case 0x4826:
+ if (sender == _class606 && _klayman->getX() <= 318) {
+ _klayman->sendEntityMessage(0x1014, sender, this);
+ setMessageList(0x004B6AC0);
+ }
+ break;
+ }
+ return 0;
+}
+
+} // End of namespace Neverhood
diff --git a/engines/neverhood/module1700.h b/engines/neverhood/module1700.h
new file mode 100644
index 0000000000..0fefa72122
--- /dev/null
+++ b/engines/neverhood/module1700.h
@@ -0,0 +1,80 @@
+/* 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.
+ *
+ */
+
+#ifndef NEVERHOOD_MODULE1700_H
+#define NEVERHOOD_MODULE1700_H
+
+#include "neverhood/neverhood.h"
+#include "neverhood/module.h"
+#include "neverhood/scene.h"
+#include "neverhood/smackerscene.h"
+
+namespace Neverhood {
+
+class Module1700 : public Module {
+public:
+ Module1700(NeverhoodEngine *vm, Module *parentModule, int which);
+ virtual ~Module1700();
+protected:
+ SoundResource _soundResource;
+ void update();
+ void createScene1701(int which);
+ void createScene1702(int which);
+ void createScene1703(int which);
+ void createScene1704(int which);
+ void createScene1705(int which);
+ void updateScene1701();
+ void updateScene1702();
+ void updateScene1703();
+ void updateScene1705();
+};
+
+// Scene1705
+
+class Class602 : public StaticSprite {
+public:
+ Class602(NeverhoodEngine *vm, uint32 fileHash, int index);
+};
+
+class Class606 : public StaticSprite {
+public:
+ Class606(NeverhoodEngine *vm, Scene *parentScene, int index, int surfacePriority, int16 x, int16 y, uint32 fileHash);
+protected:
+ Scene *_parentScene;
+ int _index;
+ uint32 handleMessage(int messageNum, const MessageParam &param, Entity *sender);
+};
+
+class Scene1705 : public Scene {
+public:
+ Scene1705(NeverhoodEngine *vm, Module *parentModule, int which);
+protected:
+ Sprite *_sprite;
+ Sprite *_class606;
+ int _paletteArea;
+ void update();
+ uint32 handleMessage(int messageNum, const MessageParam &param, Entity *sender);
+};
+
+} // End of namespace Neverhood
+
+#endif /* NEVERHOOD_MODULE1700_H */
diff --git a/engines/neverhood/module1800.cpp b/engines/neverhood/module1800.cpp
new file mode 100644
index 0000000000..2a4d89cead
--- /dev/null
+++ b/engines/neverhood/module1800.cpp
@@ -0,0 +1,300 @@
+/* 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/module1800.h"
+#include "neverhood/navigationscene.h"
+#include "neverhood/smackerscene.h"
+
+#include "neverhood/diskplayerscene.h"
+
+namespace Neverhood {
+
+Module1800::Module1800(NeverhoodEngine *vm, Module *parentModule, int which)
+ : Module(vm, parentModule) {
+
+ debug("Create Module1800(%d)", which);
+
+ // TODO Sound1ChList_addSoundResources(0x04A14718, dword_4AFE70);
+ // TODO Sound1ChList_setSoundValuesMulti(dword_4AFE70, 1, 50, 600, 10, 150);
+ // TODO Sound1ChList_sub_407C70(0x04A14718, 0x8A382B55, 0x0C242F1D, 0);
+
+ if (which < 0) {
+ switch (_vm->gameState().sceneNum) {
+ case 0:
+ createScene1801(-1);
+ break;
+ case 1:
+ createScene1802(-1);
+ break;
+ case 2:
+ createScene1803(-1);
+ break;
+ default:
+ case 3:
+ createScene1804(-1);
+ break;
+ case 4:
+ createScene1805(-1);
+ break;
+ case 5:
+ createScene1806(-1);
+ break;
+ case 6:
+ createScene1807(-1);
+ break;
+ case 7:
+ createScene1808(-1);
+ break;
+ case 8:
+ createScene1809(-1);
+ break;
+ }
+ } else if (which == 2) {
+ createScene1806(0);
+ } else if (which == 3) {
+ createScene1801(0);
+ } else {
+ createScene1804(1);
+ }
+
+}
+
+Module1800::~Module1800() {
+ // TODO Sound1ChList_sub_407A50(0x04A14718);
+}
+
+void Module1800::createScene1801(int which) {
+ static const byte kNavigationTypes[] = {1, 0, 2, 0};
+ _vm->gameState().sceneNum = 0;
+#if 0
+ _childObject = new NavigationScene(_vm, this, 0x004AFD38, which, kNavigationTypes);
+#endif
+ _childObject = new DiskplayerScene(_vm, this, 3);
+ SetUpdateHandler(&Module1800::updateScene1801);
+}
+
+void Module1800::createScene1802(int which) {
+ static const byte kNavigationTypes[] = {5};
+ _vm->gameState().sceneNum = 1;
+ _childObject = new NavigationScene(_vm, this, 0x004AFD98, which, kNavigationTypes);
+ SetUpdateHandler(&Module1800::updateScene1802);
+}
+
+void Module1800::createScene1803(int which) {
+ SmackerScene *smackerScene;
+ _vm->gameState().sceneNum = 2;
+ smackerScene = new SmackerScene(_vm, this, true, true, false);
+ smackerScene->setFileHash(0x006C0085);
+ smackerScene->nextVideo();
+ _childObject = smackerScene;
+ SetUpdateHandler(&Module1800::updateScene1803);
+}
+
+void Module1800::createScene1804(int which) {
+ _vm->gameState().sceneNum = 3;
+ _childObject = new NavigationScene(_vm, this, 0x004AFDB0, which, NULL);
+ SetUpdateHandler(&Module1800::updateScene1804);
+}
+
+void Module1800::createScene1804b(int which) {
+ SmackerScene *smackerScene;
+ _vm->gameState().sceneNum = 3;
+ smackerScene = new SmackerScene(_vm, this, true, true, false);
+ smackerScene->setFileHash(0x0A840C01);
+ smackerScene->nextVideo();
+ _childObject = smackerScene;
+ SetUpdateHandler(&Module1800::updateScene1803);
+}
+
+void Module1800::createScene1805(int which) {
+ _vm->gameState().sceneNum = 4;
+ _childObject = new NavigationScene(_vm, this, 0x004AFDE0, which, NULL);
+ SetUpdateHandler(&Module1800::updateScene1805);
+}
+
+void Module1800::createScene1806(int which) {
+ _vm->gameState().sceneNum = 5;
+ _childObject = new NavigationScene(_vm, this, 0x004AFE40, which, NULL);
+ SetUpdateHandler(&Module1800::updateScene1806);
+}
+
+void Module1800::createScene1807(int which) {
+ SmackerScene *smackerScene;
+ _vm->gameState().sceneNum = 6;
+ smackerScene = new SmackerScene(_vm, this, true, true, false);
+ smackerScene->setFileHash(0x08D84010);
+ smackerScene->nextVideo();
+ _childObject = smackerScene;
+ SetUpdateHandler(&Module1800::updateScene1803);
+ // TODO Sound1ChList_sub_407A50(0x04A14718);
+}
+
+void Module1800::createScene1808(int which) {
+ SmackerScene *smackerScene;
+ _vm->gameState().sceneNum = 7;
+ // TODO Sound1ChList_setSoundValuesMulti(dword_4AFE70, 0, 0, 0, 0, 0);
+ smackerScene = new SmackerScene(_vm, this, true, true, false);
+ smackerScene->setFileHash(0x0168B121);
+ smackerScene->nextVideo();
+ _childObject = smackerScene;
+ SetUpdateHandler(&Module1800::updateScene1803);
+}
+
+void Module1800::createScene1809(int which) {
+#if 0 // TODO
+ _vm->gameState().sceneNum = 8;
+ _childObject = new CreditsScene(_vm, this, 0);
+ SetUpdateHandler(&Module1800::updateScene1809);
+#endif
+}
+
+void Module1800::updateScene1801() {
+ _childObject->handleUpdate();
+#if 0 // TODO
+ NavigationScene *navigationScene = (NavigationScene*)_childObject;
+ if (navigationScene->soundFlag1 && navigationScene->index == 2) {
+ // TODO Sound1ChList_sub_4080B0(false);
+ }
+#endif
+ if (_done) {
+ _done = false;
+ delete _childObject;
+ _childObject = NULL;
+ if (_field20 == 1) {
+ createScene1805(0);
+ _childObject->handleUpdate();
+ } else if (_field20 == 2) {
+ createScene1802(-1);
+ _childObject->handleUpdate();
+ } else if (_field20 == 3) {
+ createScene1804(0);
+ _childObject->handleUpdate();
+ }
+ }
+}
+
+void Module1800::updateScene1802() {
+ _childObject->handleUpdate();
+ if (_done) {
+ int areaType = ((NavigationScene*)_childObject)->getNavigationAreaType();
+ _done = false;
+ delete _childObject;
+ _childObject = NULL;
+ if (areaType == 3) {
+ createScene1808(-1);
+ } else {
+ createScene1803(-1);
+ }
+ _childObject->handleUpdate();
+ }
+}
+
+void Module1800::updateScene1803() {
+ _childObject->handleUpdate();
+ if (_done) {
+ _done = false;
+ delete _childObject;
+ _childObject = NULL;
+ if (_field20 == 2) {
+ createScene1801(2);
+ _childObject->handleUpdate();
+ } else if (_field20 == 3) {
+ _parentModule->sendMessage(0x1009, 0, this);
+ } else if (_field20 == 6) {
+ createScene1809(-1);
+ _childObject->handleUpdate();
+ } else if (_field20 == 7) {
+ _parentModule->sendMessage(0x1009, 3, this);
+ }
+ }
+}
+
+void Module1800::updateScene1804() {
+ _childObject->handleUpdate();
+ if (_done) {
+ _done = false;
+ delete _childObject;
+ _childObject = NULL;
+ if (_field20 == 0) {
+ createScene1804b(-1);
+ _childObject->handleUpdate();
+ } else if (_field20 == 1) {
+ createScene1801(1);
+ _childObject->handleUpdate();
+ }
+ }
+}
+
+void Module1800::updateScene1805() {
+ _childObject->handleUpdate();
+ if (_done) {
+ _done = false;
+ delete _childObject;
+ _childObject = NULL;
+ if (_field20 == 0) {
+ createScene1807(-1);
+ _childObject->handleUpdate();
+ } else if (_field20 == 1) {
+ createScene1806(0);
+ _childObject->handleUpdate();
+ } else if (_field20 == 2) {
+ createScene1801(3);
+ _childObject->handleUpdate();
+ } else if (_field20 == 3) {
+ createScene1805(3);
+ _childObject->handleUpdate();
+ }
+ }
+}
+
+void Module1800::updateScene1806() {
+ _childObject->handleUpdate();
+ if (_done) {
+ _done = false;
+ delete _childObject;
+ _childObject = NULL;
+ if (_field20 == 0) {
+ _parentModule->sendMessage(0x1009, 2, this);
+ } else if (_field20 == 1) {
+ createScene1805(3);
+ _childObject->handleUpdate();
+ }
+ }
+ if (_field24 >= 0) {
+ if (_field24 == 1) {
+ // TODO _resourceTable.setResourceList(ex_sub_42EDA0(0), true);
+ }
+ _field24 = -1;
+ }
+}
+
+void Module1800::updateScene1809() {
+ _childObject->handleUpdate();
+ if (_done) {
+ _done = false;
+ delete _childObject;
+ _childObject = NULL;
+ _parentModule->sendMessage(0x1009, 1, this);
+ // TODO GameState stuff
+ }
+}
+} // End of namespace Neverhood
diff --git a/engines/neverhood/module1800.h b/engines/neverhood/module1800.h
new file mode 100644
index 0000000000..13d4790a8c
--- /dev/null
+++ b/engines/neverhood/module1800.h
@@ -0,0 +1,63 @@
+/* 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.
+ *
+ */
+
+#ifndef NEVERHOOD_MODULE1800_H
+#define NEVERHOOD_MODULE1800_H
+
+#include "neverhood/neverhood.h"
+#include "neverhood/module.h"
+#include "neverhood/scene.h"
+
+namespace Neverhood {
+
+// Module1800
+
+class Module1800 : public Module {
+public:
+ Module1800(NeverhoodEngine *vm, Module *parentModule, int which);
+ virtual ~Module1800();
+protected:
+ // TODO ResourceTable _resourceTable;
+ void createScene1801(int which);
+ void createScene1802(int which);
+ void createScene1803(int which);
+ void createScene1804(int which);
+ void createScene1804b(int which);
+ void createScene1805(int which);
+ void createScene1806(int which);
+ void createScene1807(int which);
+ void createScene1808(int which);
+ void createScene1809(int which);
+ void updateScene1801();
+ void updateScene1802();
+ void updateScene1803();
+ void updateScene1804();
+ void updateScene1805();
+ void updateScene1806();
+ void updateScene1807();
+ void updateScene1808();
+ void updateScene1809();
+};
+
+} // End of namespace Neverhood
+
+#endif /* NEVERHOOD_MODULE1800_H */
diff --git a/engines/neverhood/navigationscene.cpp b/engines/neverhood/navigationscene.cpp
index f6be668b3c..7bc1551250 100644
--- a/engines/neverhood/navigationscene.cpp
+++ b/engines/neverhood/navigationscene.cpp
@@ -25,7 +25,7 @@
namespace Neverhood {
-NavigationScene::NavigationScene(NeverhoodEngine *vm, Module *parentModule, uint32 navigationListId, int navigationIndex, byte *itemsTypes)
+NavigationScene::NavigationScene(NeverhoodEngine *vm, Module *parentModule, uint32 navigationListId, int navigationIndex, const byte *itemsTypes)
: Scene(vm, parentModule, true), _itemsTypes(itemsTypes), _navigationIndex(navigationIndex), _smackerDone(false),
_soundFlag1(false), _soundFlag2(false), _smackerFileHash(0), _interactive(true), _done(false) {
@@ -64,8 +64,11 @@ NavigationScene::~NavigationScene() {
// TODO Sound1ChList_sub_408110(0);
}
-byte NavigationScene::getNavigationAreaType() {
- return 0; // TODO
+int NavigationScene::getNavigationAreaType() {
+ NPoint mousePos;
+ mousePos.x = _mouseCursor->getX();
+ mousePos.y = _mouseCursor->getY();
+ return _mouseCursor->sendPointMessage(0x2064, mousePos, this);
}
void NavigationScene::update() {
diff --git a/engines/neverhood/navigationscene.h b/engines/neverhood/navigationscene.h
index 08aefb7cc4..c37a7fc178 100644
--- a/engines/neverhood/navigationscene.h
+++ b/engines/neverhood/navigationscene.h
@@ -31,9 +31,9 @@ namespace Neverhood {
class NavigationScene : public Scene {
public:
- NavigationScene(NeverhoodEngine *vm, Module *parentModule, uint32 navigationListId, int navigationIndex, byte *itemsTypes);
+ NavigationScene(NeverhoodEngine *vm, Module *parentModule, uint32 navigationListId, int navigationIndex, const byte *itemsTypes);
virtual ~NavigationScene();
- byte getNavigationAreaType();
+ int getNavigationAreaType();
protected:
SmackerPlayer *_smackerPlayer;
bool _smackerDone;
@@ -44,7 +44,7 @@ protected:
bool _soundFlag1;
bool _soundFlag2;
bool _done;
- byte *_itemsTypes;
+ const byte *_itemsTypes;
void update();
uint32 handleMessage(int messageNum, const MessageParam &param, Entity *sender);
void createMouseCursor();
diff --git a/engines/neverhood/palette.cpp b/engines/neverhood/palette.cpp
index e186d3814f..28fa81b87a 100644
--- a/engines/neverhood/palette.cpp
+++ b/engines/neverhood/palette.cpp
@@ -160,7 +160,6 @@ void Palette2::update() {
if (_status == 1) {
Palette::update();
} else if (_status == 2) {
- debug("... _palCounter = %d", _palCounter);
if (_palCounter > 1) {
for (int i = 0; i < 256; i++) {
fadeColor(_palette + i * 4, _basePalette[i * 4 + 0], _basePalette[i * 4 + 1], _basePalette[i * 4 + 2]);
@@ -174,6 +173,12 @@ void Palette2::update() {
}
}
+void Palette2::copyBasePalette(int toIndex, int count, int fromIndex) {
+ if (toIndex + count > 256)
+ count = 256 - toIndex;
+ memcpy(_basePalette + toIndex * 4, _palette + fromIndex * 4, count * 4);
+}
+
void Palette2::addPalette(uint32 fileHash, int toIndex, int count, int fromIndex) {
PaletteResource paletteResource(_vm);
if (toIndex + count > 256)
diff --git a/engines/neverhood/palette.h b/engines/neverhood/palette.h
index e3d95aa7f6..01f63e8e7e 100644
--- a/engines/neverhood/palette.h
+++ b/engines/neverhood/palette.h
@@ -38,7 +38,7 @@ public:
Palette(NeverhoodEngine *vm, const char *filename);
// Create from resource with fileHash
Palette(NeverhoodEngine *vm, uint32 fileHash);
- ~Palette();
+ virtual ~Palette();
void usePalette();
void addPalette(const char *filename, int toIndex, int count, int fromIndex);
void addPalette(uint32 fileHash, int toIndex, int count, int fromIndex);
@@ -60,7 +60,8 @@ public:
Palette2(NeverhoodEngine *vm);
// TODO: Other ctors
Palette2(NeverhoodEngine *vm, uint32 fileHash);
- ~Palette2();
+ virtual ~Palette2();
+ void copyBasePalette(int toIndex, int count, int fromIndex);
void addPalette(uint32 fileHash, int toIndex, int count, int fromIndex);
void startFadeToPalette(int counter);
public:
diff --git a/engines/neverhood/resource.cpp b/engines/neverhood/resource.cpp
index 44fef14ebe..39824de7f9 100644
--- a/engines/neverhood/resource.cpp
+++ b/engines/neverhood/resource.cpp
@@ -313,6 +313,21 @@ void AnimResource::setRepl(byte oldColor, byte newColor) {
_replNewColor = newColor;
}
+NDimensions AnimResource::loadSpriteDimensions(uint32 fileHash) {
+ NDimensions dimensions;
+ byte *resDimensions = _vm->_res->getResourceExtDataByHash(fileHash);
+ if (resDimensions) {
+ dimensions.width = READ_LE_UINT16(resDimensions + 0);
+ dimensions.height = READ_LE_UINT16(resDimensions + 2);
+ } else {
+ dimensions.width = 0;
+ dimensions.height = 0;
+ }
+ return dimensions;
+}
+
+// MouseCursorResource
+
MouseCursorResource::MouseCursorResource(NeverhoodEngine *vm)
: _cursorSprite(vm), _cursorNum(4), _currFileHash(0) {
diff --git a/engines/neverhood/resource.h b/engines/neverhood/resource.h
index 5d8d5ca13d..a7d5e6c761 100644
--- a/engines/neverhood/resource.h
+++ b/engines/neverhood/resource.h
@@ -91,6 +91,7 @@ public:
int16 getFrameIndex(uint32 frameHash);
void setReplEnabled(bool value) { _replEnabled = value; }
void setRepl(byte oldColor, byte newColor);
+ NDimensions loadSpriteDimensions(uint32 fileHash);
protected:
NeverhoodEngine *_vm;
int _resourceHandle;
diff --git a/engines/neverhood/resourceman.cpp b/engines/neverhood/resourceman.cpp
index 28f0994cb1..0538f58e87 100644
--- a/engines/neverhood/resourceman.cpp
+++ b/engines/neverhood/resourceman.cpp
@@ -135,8 +135,8 @@ byte *ResourceMan::getResourceExtData(int resourceHandle) {
}
byte *ResourceMan::getResourceExtDataByHash(uint32 fileHash) {
- ResourceFileEntry *entry = findEntry(fileHash);
- return _archives[entry->archiveIndex]->getEntryExtData(entry->entryIndex);
+ ResourceFileEntry *entry = findEntrySimple(fileHash);
+ return entry ? _archives[entry->archiveIndex]->getEntryExtData(entry->entryIndex) : NULL;
}
byte *ResourceMan::loadResource(int resourceHandle, bool moveToFront) {
diff --git a/engines/neverhood/scene.cpp b/engines/neverhood/scene.cpp
index 43f1ca79bc..d725cedb99 100644
--- a/engines/neverhood/scene.cpp
+++ b/engines/neverhood/scene.cpp
@@ -88,14 +88,16 @@ void Scene::draw() {
if (_smackerPlayer->getSurface())
_smackerPlayer->getSurface()->draw();
} else {
+#if 0
if (_surfaceFlag) {
// TODO g_screen->copyDirtyRects();
for (Common::Array<BaseSurface*>::iterator iter = _surfaces.begin(); iter != _surfaces.end(); iter++)
(*iter)->addDirtyRect();
// TODO g_screen->addDirtyRects();
}
+#endif
for (Common::Array<BaseSurface*>::iterator iter = _surfaces.begin(); iter != _surfaces.end(); iter++) {
- debug(4, "priority = %d", (*iter)->getPriority());
+ //debug(4, "priority = %d", (*iter)->getPriority());
(*iter)->draw();
}
}
@@ -501,6 +503,11 @@ void Scene::setRectList(RectList *rectList) {
_rectType = 1;
}
+void Scene::clearRectList() {
+ _rectList = NULL;
+ _rectType = 1;
+}
+
void Scene::loadDataResource(uint32 fileHash) {
_dataResource.load(fileHash);
if (_klayman)
diff --git a/engines/neverhood/scene.h b/engines/neverhood/scene.h
index 47114053b0..65326c310f 100644
--- a/engines/neverhood/scene.h
+++ b/engines/neverhood/scene.h
@@ -50,6 +50,7 @@ public:
void setSurfacePriority(BaseSurface *surface, int priority);
void deleteSprite(Sprite **sprite);
Background *addBackground(Background *background);
+ void update();
protected:
Module *_parentModule;
Common::Array<Entity*> _entities;
@@ -89,7 +90,6 @@ protected:
bool _prevVisible;
int _messageValue;
// TODO 000000CF field_CF db ?
- void update();
uint32 handleMessage(int messageNum, const MessageParam &param, Entity *sender);
void smackerUpdate();
uint32 smackerHandleMessage(int messageNum, const MessageParam &param, Entity *sender);
@@ -102,6 +102,7 @@ protected:
void runMessageList();
void setRectList(uint32 id);
void setRectList(RectList *rectList);
+ void clearRectList();
void messageList402220();
void loadDataResource(uint32 fileHash);
};
diff --git a/engines/neverhood/smackerplayer.cpp b/engines/neverhood/smackerplayer.cpp
index f0b30084cc..66e7a58746 100644
--- a/engines/neverhood/smackerplayer.cpp
+++ b/engines/neverhood/smackerplayer.cpp
@@ -69,12 +69,10 @@ void SmackerDoubleSurface::draw() {
SmackerPlayer::SmackerPlayer(NeverhoodEngine *vm, Scene *scene, uint32 fileHash, bool doubleSurface, bool flag)
: Entity(vm, 0), _scene(scene), _doubleSurface(doubleSurface), _dirtyFlag(false), _flag2(false),
- _palette(NULL), _smackerDecoder(NULL), _smackerSurface(NULL), _stream(NULL), _smackerFirst(true) {
-
- debug("_smackerSurface = %p", (void*)_smackerSurface);
+ _palette(NULL), _smackerDecoder(NULL), _smackerSurface(NULL), _stream(NULL), _smackerFirst(true),
+ _drawX(-1), _drawY(-1) {
SetUpdateHandler(&SmackerPlayer::update);
-
open(fileHash, flag);
}
@@ -121,14 +119,31 @@ void SmackerPlayer::close() {
}
void SmackerPlayer::gotoFrame(uint frameNumber) {
+ // TODO?
+}
+
+uint32 SmackerPlayer::getFrameCount() {
+ return _smackerDecoder ? _smackerDecoder->getFrameCount() : 0;
+}
+
+uint32 SmackerPlayer::getFrameNumber() {
+ return _smackerDecoder ? _smackerDecoder->getCurFrame() : 0;
}
uint SmackerPlayer::getStatus() {
return 0;
}
-void SmackerPlayer::update() {
+void SmackerPlayer::setDrawPos(int16 x, int16 y) {
+ _drawX = x;
+ _drawY = y;
+ if (_smackerSurface) {
+ _smackerSurface->getDrawRect().x = _drawX;
+ _smackerSurface->getDrawRect().y = _drawY;
+ }
+}
+void SmackerPlayer::update() {
debug(8, "SmackerPlayer::update()");
if (!_smackerDecoder)
@@ -144,15 +159,18 @@ void SmackerPlayer::update() {
const Graphics::Surface *smackerFrame = _smackerDecoder->decodeNextFrame();
if (_smackerFirst) {
- if (_doubleSurface) {
- _smackerSurface->getDrawRect().x = 320 - _smackerDecoder->getWidth();
- _smackerSurface->getDrawRect().y = 240 - _smackerDecoder->getHeight();
- _smackerSurface->setSmackerFrame(smackerFrame);
- } else {
- _smackerSurface->getDrawRect().x = (640 - _smackerDecoder->getWidth()) / 2;
- _smackerSurface->getDrawRect().y = (480 - _smackerDecoder->getHeight()) / 2;
- _smackerSurface->setSmackerFrame(smackerFrame);
+ _smackerSurface->setSmackerFrame(smackerFrame);
+ if (_drawX < 0 || _drawY < 0) {
+ if (_doubleSurface) {
+ _drawX = 320 - _smackerDecoder->getWidth();
+ _drawY = 240 - _smackerDecoder->getHeight();
+ } else {
+ _drawX = (640 - _smackerDecoder->getWidth()) / 2;
+ _drawY = (480 - _smackerDecoder->getHeight()) / 2;
+ }
}
+ _smackerSurface->getDrawRect().x = _drawX;
+ _smackerSurface->getDrawRect().y = _drawY;
_smackerFirst = false;
}
@@ -164,7 +182,6 @@ void SmackerPlayer::update() {
_dirtyFlag = true;
if (_smackerDecoder->hasDirtyPalette()) {
- debug("updatePalette()");
updatePalette();
}
@@ -179,7 +196,6 @@ void SmackerPlayer::update() {
}
}
-
}
void SmackerPlayer::updatePalette() {
diff --git a/engines/neverhood/smackerplayer.h b/engines/neverhood/smackerplayer.h
index 2262277956..6579bb4add 100644
--- a/engines/neverhood/smackerplayer.h
+++ b/engines/neverhood/smackerplayer.h
@@ -55,7 +55,10 @@ public:
void open(uint32 fileHash, bool keepLastFrame);
void close();
void gotoFrame(uint frameNumber);
+ uint32 getFrameCount();
+ uint32 getFrameNumber();
uint getStatus();
+ void setDrawPos(int16 x, int16 y);
protected:
Scene *_scene;
Palette *_palette;
@@ -67,6 +70,7 @@ protected:
bool _keepLastFrame;
bool _flag2;
bool _dirtyFlag;
+ int _drawX, _drawY;
void update();
void updatePalette();
};
diff --git a/engines/neverhood/sprite.cpp b/engines/neverhood/sprite.cpp
index d0a6628d75..ee6e7aa942 100644
--- a/engines/neverhood/sprite.cpp
+++ b/engines/neverhood/sprite.cpp
@@ -93,6 +93,11 @@ void Sprite::createSurface(int surfacePriority, int16 width, int16 height) {
_surface = new BaseSurface(_vm, surfacePriority, width, height);
}
+int16 Sprite::defFilterY(int16 y) {
+ // TODO return y - g_screen->field_26;
+ return y;
+}
+
// StaticSprite
StaticSprite::StaticSprite(NeverhoodEngine *vm, int objectPriority)
@@ -209,7 +214,6 @@ AnimatedSprite::AnimatedSprite(NeverhoodEngine *vm, uint32 fileHash, int surface
_x = x;
_y = y;
setFileHash(fileHash, 0, -1);
-
}
void AnimatedSprite::init() {
@@ -428,10 +432,7 @@ void AnimatedSprite::updateFrameInfo() {
}
void AnimatedSprite::createSurface1(uint32 fileHash, int surfacePriority) {
- NDimensions dimensions;
- // TODO dimensions = getAnimatedSpriteDimensions(fileHash);
- dimensions.width = 640;
- dimensions.height = 480;
+ NDimensions dimensions = _animResource.loadSpriteDimensions(fileHash);
_surface = new BaseSurface(_vm, surfacePriority, dimensions.width, dimensions.height);
}
diff --git a/engines/neverhood/sprite.h b/engines/neverhood/sprite.h
index 18c9ae32da..86165f3440 100644
--- a/engines/neverhood/sprite.h
+++ b/engines/neverhood/sprite.h
@@ -48,12 +48,15 @@ public:
bool checkCollision(NRect &rect);
int16 getX() const { return _x; }
int16 getY() const { return _y; }
+ void setX(int16 value) { _x = value; }
+ void setY(int16 value) { _y = value; }
uint16 getFlags() const { return _flags; }
bool isDoDeltaX() const { return _doDeltaX; }
bool isDoDeltaY() const { return _doDeltaY; }
NRect& getRect() { return _rect; }
uint32 handleMessage(int messageNum, const MessageParam &param, Entity *sender);
void loadDataResource(uint32 fileHash);
+ int16 defFilterY(int16 y);
protected:
void (Sprite::*_spriteUpdateCb)();
Common::String _spriteUpdateCbName; // For debugging purposes
@@ -71,7 +74,6 @@ protected:
uint16 _flags;
//0000004A field4A dw ? // seems to be unused except in ctor
DataResource _dataResource;
- //void update();
void createSurface(int surfacePriority, int16 width, int16 height);
void handleSpriteUpdate() {
if (_spriteUpdateCb)
@@ -91,10 +93,10 @@ public:
StaticSprite(NeverhoodEngine *vm, const char *filename, int surfacePriority, int16 x = kDefPosition, int16 y = kDefPosition, int16 width = 0, int16 height = 0);
StaticSprite(NeverhoodEngine *vm, uint32 fileHash, int surfacePriority, int16 x = kDefPosition, int16 y = kDefPosition, int16 width = 0, int16 height = 0);
void load(uint32 fileHash, bool dimensions, bool position);
+ void update();
protected:
SpriteResource _spriteResource;
void init(uint32 fileHash, int surfacePriority, int16 x, int16 y, int16 width, int16 height);
- void update();
};
#define SetAnimationCallback1(callback) _callback1Cb = static_cast <void (AnimatedSprite::*)(void)> (callback); debug("SetAnimationCallback1(" #callback ")"); _callback1CbName = #callback