aboutsummaryrefslogtreecommitdiff
path: root/engines/neverhood/diskplayerscene.cpp
diff options
context:
space:
mode:
authorjohndoe1232011-07-26 08:38:19 +0000
committerWillem Jan Palenstijn2013-05-08 20:39:34 +0200
commitbfd71cff6e73c0be6b2d66f7f71921094f42ca09 (patch)
tree01acbaf984c307fb7e7978706ac78d023e758ce7 /engines/neverhood/diskplayerscene.cpp
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
Diffstat (limited to 'engines/neverhood/diskplayerscene.cpp')
-rw-r--r--engines/neverhood/diskplayerscene.cpp563
1 files changed, 563 insertions, 0 deletions
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