From bfd71cff6e73c0be6b2d66f7f71921094f42ca09 Mon Sep 17 00:00:00 2001 From: johndoe123 Date: Tue, 26 Jul 2011 08:38:19 +0000 Subject: NEVERHOOD: New modules Module1200, Module1400, Module1700 and Module1800 - Implement CollisionMan::removeSprite --- engines/neverhood/diskplayerscene.cpp | 563 ++++++++++++++++++++++++++++++++++ 1 file changed, 563 insertions(+) create mode 100644 engines/neverhood/diskplayerscene.cpp (limited to 'engines/neverhood/diskplayerscene.cpp') 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 ¶m, 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 ¶m, 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 ¶m, 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 -- cgit v1.2.3