diff options
Diffstat (limited to 'kyra/sequences.cpp')
-rw-r--r-- | kyra/sequences.cpp | 968 |
1 files changed, 968 insertions, 0 deletions
diff --git a/kyra/sequences.cpp b/kyra/sequences.cpp new file mode 100644 index 0000000000..1ac3574a47 --- /dev/null +++ b/kyra/sequences.cpp @@ -0,0 +1,968 @@ +/* ScummVM - Scumm Interpreter + * Copyright (C) 2005-2006 The ScummVM project + * + * 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. + * + * $Header$ + * + */ + +#include "kyra/kyra.h" +#include "kyra/seqplayer.h" +#include "kyra/screen.h" +#include "kyra/resource.h" +#include "kyra/sound.h" +#include "kyra/sprites.h" +#include "kyra/wsamovie.h" +#include "kyra/animator.h" +#include "kyra/text.h" + +#include "common/system.h" +#include "common/savefile.h" + +namespace Kyra { + +void KyraEngine::seq_demo() { + debug(9, "KyraEngine::seq_demo()"); + + snd_playTheme(MUSIC_INTRO, 2); + + loadBitmap("START.CPS", 7, 7, _screen->_currentPalette); + _screen->copyRegion(0, 0, 0, 0, 320, 200, 6, 0); + _system->copyRectToScreen(_screen->getPagePtr(0), 320, 0, 0, 320, 200); + _screen->fadeFromBlack(); + waitTicks(60); + _screen->fadeToBlack(); + + _screen->clearPage(0); + loadBitmap("TOP.CPS", 7, 7, NULL); + loadBitmap("BOTTOM.CPS", 5, 5, _screen->_currentPalette); + _screen->copyRegion(0, 91, 0, 8, 320, 103, 6, 0); + _screen->copyRegion(0, 0, 0, 111, 320, 64, 6, 0); + _system->copyRectToScreen(_screen->getPagePtr(0), 320, 0, 0, 320, 200); + _screen->fadeFromBlack(); + + _seq->playSequence(_seq_WestwoodLogo, true); + waitTicks(60); + + _seq->playSequence(_seq_KyrandiaLogo, true); + + _screen->fadeToBlack(); + _screen->clearPage(2); + _screen->clearPage(0); + + _seq->playSequence(_seq_Demo1, true); + + _screen->clearPage(0); + _seq->playSequence(_seq_Demo2, true); + + _screen->clearPage(0); + _seq->playSequence(_seq_Demo3, true); + + _screen->clearPage(0); + _seq->playSequence(_seq_Demo4, true); + + _screen->clearPage(0); + loadBitmap("FINAL.CPS", 7, 7, _screen->_currentPalette); + _screen->_curPage = 0; + _screen->copyRegion(0, 0, 0, 0, 320, 200, 6, 0); + _system->copyRectToScreen(_screen->getPagePtr(0), 320, 0, 0, 320, 200); + _screen->fadeFromBlack(); + waitTicks(60); + _screen->fadeToBlack(); + _sound->stopMusic(); +} + +void KyraEngine::seq_intro() { + debug(9, "KyraEngine::seq_intro()"); + if (_features & GF_TALKIE) { + _res->loadPakFile("INTRO.VRM"); + } + + static const IntroProc introProcTable[] = { + &KyraEngine::seq_introLogos, + &KyraEngine::seq_introStory, + &KyraEngine::seq_introMalcolmTree, + &KyraEngine::seq_introKallakWriting, + &KyraEngine::seq_introKallakMalcolm + }; + + Common::InSaveFile *in; + if ((in = _saveFileMan->openForLoading(getSavegameFilename(0)))) { + delete in; + _skipIntroFlag = true; + } else + _skipIntroFlag = false; + + _seq->setCopyViewOffs(true); + _screen->setFont(Screen::FID_8_FNT); + snd_playTheme(MUSIC_INTRO, 2); + snd_setSoundEffectFile(MUSIC_INTRO); + _text->setTalkCoords(144); + for (int i = 0; i < ARRAYSIZE(introProcTable) && !seq_skipSequence(); ++i) { + (this->*introProcTable[i])(); + } + _text->setTalkCoords(136); + waitTicks(30); + _seq->setCopyViewOffs(false); + _sound->stopMusic(); + if (_features & GF_TALKIE) { + _res->unloadPakFile("INTRO.VRM"); + } + res_unloadResources(RES_INTRO | RES_OUTRO); +} + +void KyraEngine::seq_introLogos() { + debug(9, "KyraEngine::seq_introLogos()"); + _screen->clearPage(0); + loadBitmap("TOP.CPS", 7, 7, NULL); + loadBitmap("BOTTOM.CPS", 5, 5, _screen->_currentPalette); + _screen->_curPage = 0; + _screen->copyRegion(0, 91, 0, 8, 320, 103, 6, 0); + _screen->copyRegion(0, 0, 0, 111, 320, 64, 6, 0); + _system->copyRectToScreen(_screen->getPagePtr(0), 320, 0, 0, 320, 200); + _screen->fadeFromBlack(); + + if (_seq->playSequence(_seq_WestwoodLogo, _skipIntroFlag)) { + _screen->fadeToBlack(); + _screen->clearPage(0); + return; + } + waitTicks(60); + if (_seq->playSequence(_seq_KyrandiaLogo, _skipIntroFlag)) { + _screen->fadeToBlack(); + _screen->clearPage(0); + return; + } + _screen->fillRect(0, 179, 319, 199, 0); + + int y1 = 8; + int h1 = 175; + int y2 = 176; + int h2 = 0; + _screen->copyRegion(0, 91, 0, 8, 320, 103, 6, 2); + _screen->copyRegion(0, 0, 0, 111, 320, 64, 6, 2); + do { + if (h1 > 0) { + _screen->copyRegion(0, y1, 0, 8, 320, h1, 2, 0); + } + ++y1; + --h1; + if (h2 > 0) { + _screen->copyRegion(0, 64, 0, y2, 320, h2, 4, 0); + } + --y2; + ++h2; + _screen->updateScreen(); + waitTicks(1); + } while (y2 >= 64); + + _seq->playSequence(_seq_Forest, true); +} + +void KyraEngine::seq_introStory() { + debug(9, "KyraEngine::seq_introStory()"); + _screen->clearPage(3); + _screen->clearPage(0); + if ((_features & GF_ENGLISH) && (_features & GF_TALKIE)) { + loadBitmap("TEXT_ENG.CPS", 3, 3, 0); + } else if (_features & GF_GERMAN) { + loadBitmap("TEXT_GER.CPS", 3, 3, 0); + } else if (_features & GF_FRENCH) { + loadBitmap("TEXT_FRE.CPS", 3, 3, 0); + } else if (_features & GF_SPANISH) { + loadBitmap("TEXT_SPA.CPS", 3, 3, 0); + } else if ((_features & GF_ENGLISH) && (_features & GF_FLOPPY)) { + loadBitmap("TEXT.CPS", 3, 3, 0); + } else { + warning("no story graphics file found"); + } + _screen->copyRegion(0, 0, 0, 0, 320, 200, 3, 0); + _screen->updateScreen(); + waitTicks(360); +} + +void KyraEngine::seq_introMalcolmTree() { + debug(9, "KyraEngine::seq_introMalcolmTree()"); + _screen->_curPage = 0; + _screen->clearPage(3); + _seq->playSequence(_seq_MalcolmTree, true); +} + +void KyraEngine::seq_introKallakWriting() { + debug(9, "KyraEngine::seq_introKallakWriting()"); + _seq->makeHandShapes(); + _screen->setAnimBlockPtr(5060); + _screen->_charWidth = -2; + _screen->clearPage(3); + _seq->playSequence(_seq_KallakWriting, true); +} + +void KyraEngine::seq_introKallakMalcolm() { + debug(9, "KyraEngine::seq_introKallakMalcolm()"); + _screen->clearPage(3); + _seq->playSequence(_seq_KallakMalcolm, true); +} + +void KyraEngine::seq_createAmuletJewel(int jewel, int page, int noSound, int drawOnly) { + debug(9, "seq_createAmuletJewel(%d, %d, %d, %d)", jewel, page, noSound, drawOnly); + static const uint16 specialJewelTable[] = { + 0x167, 0x162, 0x15D, 0x158, 0x153, 0xFFFF + }; + static const uint16 specialJewelTable1[] = { + 0x14F, 0x154, 0x159, 0x15E, 0x163, 0xFFFF + }; + static const uint16 specialJewelTable2[] = { + 0x150, 0x155, 0x15A, 0x15F, 0x164, 0xFFFF + }; + static const uint16 specialJewelTable3[] = { + 0x151, 0x156, 0x15B, 0x160, 0x165, 0xFFFF + }; + static const uint16 specialJewelTable4[] = { + 0x152, 0x157, 0x15C, 0x161, 0x166, 0xFFFF + }; + if (!noSound) + snd_playSoundEffect(0x5F); + _screen->hideMouse(); + if (!drawOnly) { + for (int i = 0; specialJewelTable[i] != 0xFFFF; ++i) { + _screen->drawShape(page, _shapes[4+specialJewelTable[i]], _amuletX2[jewel], _amuletY2[jewel], 0, 0); + _screen->updateScreen(); + delayWithTicks(3); + } + + const uint16 *opcodes = 0; + switch (jewel - 1) { + case 0: + opcodes = specialJewelTable1; + break; + + case 1: + opcodes = specialJewelTable2; + break; + + case 2: + opcodes = specialJewelTable3; + break; + + case 3: + opcodes = specialJewelTable4; + break; + } + + if (opcodes) { + for (int i = 0; opcodes[i] != 0xFFFF; ++i) { + _screen->drawShape(page, _shapes[4+opcodes[i]], _amuletX2[jewel], _amuletY2[jewel], 0, 0); + _screen->updateScreen(); + delayWithTicks(3); + } + } + } + _screen->drawShape(page, _shapes[327+jewel], _amuletX2[jewel], _amuletY2[jewel], 0, 0); + _screen->updateScreen(); + _screen->showMouse(); + setGameFlag(0x55+jewel); +} + +void KyraEngine::seq_brandonHealing() { + debug(9, "seq_brandonHealing()"); + if (!(_deathHandler & 8)) + return; + if (_currentCharacter->sceneId == 210) { + if (_beadStateVar == 4 || _beadStateVar == 6) + return; + } + _screen->hideMouse(); + checkAmuletAnimFlags(); + assert(_healingShapeTable); + setupShapes123(_healingShapeTable, 22, 0); + setBrandonAnimSeqSize(3, 48); + snd_playSoundEffect(0x53); + for (int i = 123; i <= 144; ++i) { + _currentCharacter->currentAnimFrame = i; + animRefreshNPC(0); + delayWithTicks(8); + } + for (int i = 125; i >= 123; --i) { + _currentCharacter->currentAnimFrame = i; + animRefreshNPC(0); + delayWithTicks(8); + } + resetBrandonAnimSeqSize(); + _currentCharacter->currentAnimFrame = 7; + animRefreshNPC(0); + freeShapes123(); + _screen->showMouse(); +} + +void KyraEngine::seq_brandonHealing2() { + debug(9, "seq_brandonHealing2()"); + _screen->hideMouse(); + checkAmuletAnimFlags(); + assert(_healingShape2Table); + setupShapes123(_healingShape2Table, 30, 0); + resetBrandonPoisonFlags(); + setBrandonAnimSeqSize(3, 48); + snd_playSoundEffect(0x50); + for (int i = 123; i <= 152; ++i) { + _currentCharacter->currentAnimFrame = i; + animRefreshNPC(0); + delayWithTicks(8); + } + resetBrandonAnimSeqSize(); + _currentCharacter->currentAnimFrame = 7; + animRefreshNPC(0); + freeShapes123(); + _screen->showMouse(); + assert(_poisonGone); + if (_features & GF_TALKIE) { + snd_voiceWaitForFinish(); + snd_playVoiceFile(2010); + } + characterSays(_poisonGone[0], 0, -2); + if (_features & GF_TALKIE) { + snd_voiceWaitForFinish(); + snd_playVoiceFile(2011); + } + characterSays(_poisonGone[1], 0, -2); +} + +void KyraEngine::seq_poisonDeathNow(int now) { + debug(9, "seq_poisonDeathNow(%d)", now); + if (!(_brandonStatusBit & 1)) + return; + ++_poisonDeathCounter; + if (now) + _poisonDeathCounter = 2; + if (_poisonDeathCounter >= 2) { + snd_playWanderScoreViaMap(1, 1); + assert(_thePoison); + if (_features & GF_TALKIE) { + snd_voiceWaitForFinish(); + snd_playVoiceFile(7000); + } + characterSays(_thePoison[0], 0, -2); + if (_features & GF_TALKIE) { + snd_voiceWaitForFinish(); + snd_playVoiceFile(7001); + } + characterSays(_thePoison[1], 0, -2); + seq_poisonDeathNowAnim(); + _deathHandler = 3; + } else { + assert(_thePoison); + if (_features & GF_TALKIE) { + snd_voiceWaitForFinish(); + snd_playVoiceFile(7002); + } + characterSays(_thePoison[2], 0, -2); + if (_features & GF_TALKIE) { + snd_voiceWaitForFinish(); + snd_playVoiceFile(7004); + } + characterSays(_thePoison[3], 0, -2); + } +} + +void KyraEngine::seq_poisonDeathNowAnim() { + debug(9, "seq_poisonDeathNowAnim()"); + _screen->hideMouse(); + checkAmuletAnimFlags(); + assert(_posionDeathShapeTable); + setupShapes123(_posionDeathShapeTable, 20, 0); + setBrandonAnimSeqSize(8, 48); + + _currentCharacter->currentAnimFrame = 124; + animRefreshNPC(0); + delayWithTicks(30); + + _currentCharacter->currentAnimFrame = 123; + animRefreshNPC(0); + delayWithTicks(30); + + for (int i = 125; i <= 139; ++i) { + _currentCharacter->currentAnimFrame = i; + animRefreshNPC(0); + delayWithTicks(8); + } + + delayWithTicks(60); + + for (int i = 140; i <= 142; ++i) { + _currentCharacter->currentAnimFrame = i; + animRefreshNPC(0); + delayWithTicks(8); + } + + delayWithTicks(60); + + resetBrandonAnimSeqSize(); + freeShapes123(); + _animator->restoreAllObjectBackgrounds(); + _currentCharacter->x1 = _currentCharacter->x2 = -1; + _currentCharacter->y1 = _currentCharacter->y2 = -1; + _animator->preserveAllBackgrounds(); + _screen->showMouse(); +} + +void KyraEngine::seq_playFluteAnimation() { + debug(9, "seq_playFluteAnimation()"); + _screen->hideMouse(); + checkAmuletAnimFlags(); + setupShapes123(_fluteAnimShapeTable, 36, 0); + setBrandonAnimSeqSize(3, 75); + for (int i = 123; i <= 130; ++i) { + _currentCharacter->currentAnimFrame = i; + animRefreshNPC(0); + delayWithTicks(2); + } + + int delayTime = 0, soundType = 0; + if (queryGameFlag(0x85)) { + snd_playSoundEffect(0x63); + delayTime = 9; + soundType = 3; + } else if (!queryGameFlag(0x86)) { + snd_playSoundEffect(0x61); + delayTime = 2; + soundType = 1; + setGameFlag(0x86); + } else { + snd_playSoundEffect(0x62); + delayTime = 2; + soundType = 2; + } + + for (int i = 131; i <= 158; ++i) { + _currentCharacter->currentAnimFrame = i; + animRefreshNPC(0); + delayWithTicks(delayTime); + } + + for (int i = 126; i >= 123; --i) { + _currentCharacter->currentAnimFrame = i; + animRefreshNPC(0); + delayWithTicks(delayTime); + } + resetBrandonAnimSeqSize(); + _currentCharacter->currentAnimFrame = 7; + animRefreshNPC(0); + freeShapes123(); + _screen->showMouse(); + + if (soundType == 1) { + assert(_fluteString); + if (_features & GF_TALKIE) { + snd_voiceWaitForFinish(); + snd_playVoiceFile(1000); + } + characterSays(_fluteString[0], 0, -2); + } else if (soundType == 2) { + assert(_fluteString); + if (_features & GF_TALKIE) { + snd_voiceWaitForFinish(); + snd_playVoiceFile(1001); + } + characterSays(_fluteString[1], 0, -2); + } +} + +void KyraEngine::seq_winterScroll1() { + debug(9, "seq_winterScroll1()"); + _screen->hideMouse(); + checkAmuletAnimFlags(); + assert(_winterScrollTable); + assert(_winterScroll1Table); + assert(_winterScroll2Table); + setupShapes123(_winterScrollTable, 7, 0); + setBrandonAnimSeqSize(5, 66); + + for (int i = 123; i <= 129; ++i) { + _currentCharacter->currentAnimFrame = i; + animRefreshNPC(0); + delayWithTicks(8); + } + + freeShapes123(); + snd_playSoundEffect(0x20); + setupShapes123(_winterScroll1Table, 35, 0); + + for (int i = 123; i <= 146; ++i) { + _currentCharacter->currentAnimFrame = i; + animRefreshNPC(0); + delayWithTicks(8); + } + + if (_currentCharacter->sceneId == 41 && !queryGameFlag(0xA2)) { + snd_playSoundEffect(0x20); + _sprites->_anims[0].play = false; + _animator->sprites()[0].active = 0; + _sprites->_anims[1].play = true; + _animator->sprites()[1].active = 1; + setGameFlag(0xA2); + } + + for (int i = 147; i <= 157; ++i) { + _currentCharacter->currentAnimFrame = i; + animRefreshNPC(0); + delayWithTicks(8); + } + + if (_currentCharacter->sceneId == 117 && !queryGameFlag(0xB3)) { + for (int i = 0; i <= 7; ++i) { + _sprites->_anims[i].play = false; + _animator->sprites()[i].active = 0; + } + uint8 tmpPal[768]; + memcpy(tmpPal, _screen->_currentPalette, 768); + memcpy(&tmpPal[684], palTable2()[0], 60); + _screen->fadePalette(tmpPal, 72); + memcpy(&_screen->_currentPalette[684], palTable2()[0], 60); + _screen->setScreenPalette(_screen->_currentPalette); + setGameFlag(0xB3); + } else { + delayWithTicks(120); + } + + freeShapes123(); + setupShapes123(_winterScroll2Table, 4, 0); + + for (int i = 123; i <= 126; ++i) { + _currentCharacter->currentAnimFrame = i; + animRefreshNPC(0); + delayWithTicks(8); + } + + resetBrandonAnimSeqSize(); + _currentCharacter->currentAnimFrame = 7; + animRefreshNPC(0); + freeShapes123(); + _screen->showMouse(); +} + +void KyraEngine::seq_winterScroll2() { + debug(9, "seq_winterScroll2()"); + _screen->hideMouse(); + checkAmuletAnimFlags(); + assert(_winterScrollTable); + setupShapes123(_winterScrollTable, 7, 0); + setBrandonAnimSeqSize(5, 66); + + for (int i = 123; i <= 128; ++i) { + _currentCharacter->currentAnimFrame = i; + animRefreshNPC(0); + delayWithTicks(8); + } + + delayWithTicks(120); + + for (int i = 127; i >= 123; --i) { + _currentCharacter->currentAnimFrame = i; + animRefreshNPC(0); + delayWithTicks(8); + } + + resetBrandonAnimSeqSize(); + _currentCharacter->currentAnimFrame = 7; + animRefreshNPC(0); + freeShapes123(); + _screen->showMouse(); +} + +void KyraEngine::seq_makeBrandonInv() { + debug(9, "seq_makeBrandonInv()"); + if (_deathHandler == 8) + return; + + if (_currentCharacter->sceneId == 210) { + if (_beadStateVar == 4 || _beadStateVar == 6) + return; + } + + _screen->hideMouse(); + checkAmuletAnimFlags(); + _brandonStatusBit |= 0x20; + setTimerCountdown(18, 2700); + _brandonStatusBit |= 0x40; + snd_playSoundEffect(0x77); + _brandonInvFlag = 0; + while (_brandonInvFlag <= 0x100) { + animRefreshNPC(0); + delayWithTicks(10); + _brandonInvFlag += 0x10; + } + _brandonStatusBit &= 0xFFBF; + _screen->showMouse(); +} + +void KyraEngine::seq_makeBrandonNormal() { + debug(9, "seq_makeBrandonNormal()"); + _screen->hideMouse(); + _brandonStatusBit |= 0x40; + snd_playSoundEffect(0x77); + _brandonInvFlag = 0x100; + while (_brandonInvFlag >= 0) { + animRefreshNPC(0); + delayWithTicks(10); + _brandonInvFlag -= 0x10; + } + _brandonInvFlag = 0; + _brandonStatusBit &= 0xFF9F; + _screen->showMouse(); +} + +void KyraEngine::seq_makeBrandonNormal2() { + debug(9, "seq_makeBrandonNormal2()"); + _screen->hideMouse(); + assert(_brandonToWispTable); + setupShapes123(_brandonToWispTable, 26, 0); + setBrandonAnimSeqSize(5, 48); + _brandonStatusBit &= 0xFFFD; + snd_playSoundEffect(0x6C); + for (int i = 138; i >= 123; --i) { + _currentCharacter->currentAnimFrame = i; + animRefreshNPC(0); + delayWithTicks(8); + } + setBrandonAnimSeqSize(4, 48); + _currentCharacter->currentAnimFrame = 7; + animRefreshNPC(0); + if (_currentCharacter->sceneId >= 229 && _currentCharacter->sceneId <= 245) { + _screen->fadeSpecialPalette(31, 234, 13, 4); + } else if (_currentCharacter->sceneId >= 118 && _currentCharacter->sceneId <= 186) { + _screen->fadeSpecialPalette(14, 228, 15, 4); + } + freeShapes123(); + _screen->showMouse(); +} + +void KyraEngine::seq_makeBrandonWisp() { + debug(9, "seq_makeBrandonWisp()"); + if (_deathHandler == 8) + return; + + if (_currentCharacter->sceneId == 210) { + if (_beadStateVar == 4 || _beadStateVar == 6) + return; + } + _screen->hideMouse(); + checkAmuletAnimFlags(); + assert(_brandonToWispTable); + setupShapes123(_brandonToWispTable, 26, 0); + setBrandonAnimSeqSize(5, 48); + snd_playSoundEffect(0x6C); + for (int i = 123; i <= 138; ++i) { + _currentCharacter->currentAnimFrame = i; + animRefreshNPC(0); + delayWithTicks(8); + } + _brandonStatusBit |= 2; + if (_currentCharacter->sceneId >= 109 && _currentCharacter->sceneId <= 198) { + setTimerCountdown(14, 18000); + } else { + setTimerCountdown(14, 7200); + } + _brandonDrawFrame = 113; + _brandonStatusBit0x02Flag = 1; + _currentCharacter->currentAnimFrame = 113; + animRefreshNPC(0); + _animator->updateAllObjectShapes(); + if (_currentCharacter->sceneId >= 229 && _currentCharacter->sceneId <= 245) { + _screen->fadeSpecialPalette(30, 234, 13, 4); + } else if (_currentCharacter->sceneId >= 118 && _currentCharacter->sceneId <= 186) { + _screen->fadeSpecialPalette(14, 228, 15, 4); + } + freeShapes123(); + _screen->showMouse(); +} + +void KyraEngine::seq_dispelMagicAnimation() { + debug(9, "seq_dispelMagicAnimation()"); + if (_deathHandler == 8) + return; + if (_currentCharacter->sceneId == 210) { + if (_beadStateVar == 4 || _beadStateVar == 6) + return; + } + _screen->hideMouse(); + if (_currentCharacter->sceneId == 210 && _currentCharacter->sceneId < 160) + _currentCharacter->facing = 3; + if (_malcolmFlag == 7 && _beadStateVar == 3) { + _beadStateVar = 6; + _unkEndSeqVar5 = 2; + _malcolmFlag = 10; + } + checkAmuletAnimFlags(); + setGameFlag(0xEE); + assert(_magicAnimationTable); + setupShapes123(_magicAnimationTable, 5, 0); + setBrandonAnimSeqSize(8, 49); + snd_playSoundEffect(0x15); + for (int i = 123; i <= 127; ++i) { + _currentCharacter->currentAnimFrame = i; + animRefreshNPC(0); + delayWithTicks(8); + } + + delayWithTicks(120); + + for (int i = 127; i >= 123; --i) { + _currentCharacter->currentAnimFrame = i; + animRefreshNPC(0); + delayWithTicks(10); + } + resetBrandonAnimSeqSize(); + _currentCharacter->currentAnimFrame = 7; + animRefreshNPC(0); + freeShapes123(); + _screen->showMouse(); +} + +void KyraEngine::seq_fillFlaskWithWater(int item, int type) { + debug(9, "seq_fillFlaskWithWater(%d, %d)", item, type); + int newItem = -1; + static const uint8 flaskTable1[] = { 0x46, 0x48, 0x4A, 0x4C }; + static const uint8 flaskTable2[] = { 0x47, 0x49, 0x4B, 0x4D }; + + if (item >= 60 && item <= 77) { + assert(_flaskFull); + if (_features & GF_TALKIE) { + snd_voiceWaitForFinish(); + snd_playVoiceFile(8006); + } + characterSays(_flaskFull[0], 0, -2); + } else if (item == 78) { + assert(type >= 0 && type < ARRAYSIZE(flaskTable1)); + newItem = flaskTable1[type]; + } else if (item == 79) { + assert(type >= 0 && type < ARRAYSIZE(flaskTable2)); + newItem = flaskTable2[type]; + } + + if (newItem == -1) + return; + + _screen->hideMouse(); + setMouseItem(newItem); + _screen->showMouse(); + _itemInHand = newItem; + assert(_fullFlask); + assert(type < _fullFlask_Size && type >= 0); + if (_features & GF_TALKIE) { + snd_voiceWaitForFinish(); + static const uint16 voiceEntries[] = { + 0x1F40, 0x1F41, 0x1F42, 0x1F45 + }; + assert(type < ARRAYSIZE(voiceEntries)); + snd_playVoiceFile(voiceEntries[type]); + } + characterSays(_fullFlask[type], 0, -2); +} + +void KyraEngine::seq_playDrinkPotionAnim(int unk1, int unk2, int flags) { + debug(9, "KyraEngine::seq_playDrinkPotionAnim(%d, %d, %d)", unk1, unk2, flags); + // XXX + _screen->hideMouse(); + checkAmuletAnimFlags(); + _currentCharacter->facing = 5; + animRefreshNPC(0); + assert(_drinkAnimationTable); + setupShapes123(_drinkAnimationTable, 9, flags); + setBrandonAnimSeqSize(5, 54); + + for (int i = 123; i <= 131; ++i) { + _currentCharacter->currentAnimFrame = i; + animRefreshNPC(0); + delayWithTicks(5); + } + snd_playSoundEffect(0x34); + for (int i = 0; i < 2; ++i) { + _currentCharacter->currentAnimFrame = 130; + animRefreshNPC(0); + delayWithTicks(7); + _currentCharacter->currentAnimFrame = 131; + animRefreshNPC(0); + delayWithTicks(7); + } + + if (unk2) { + // XXX + } + + for (int i = 131; i >= 123; --i) { + _currentCharacter->currentAnimFrame = i; + animRefreshNPC(0); + delayWithTicks(5); + } + + resetBrandonAnimSeqSize(); + _currentCharacter->currentAnimFrame = 7; + animRefreshNPC(0); + freeShapes123(); + _screen->showMouse(); +} + +int KyraEngine::seq_playEnd() { + debug(9, "KyraEngine::seq_playEnd()"); + if (_endSequenceSkipFlag) { + return 0; + } + if (_deathHandler == 8) { + return 0; + } + _screen->_curPage = 2; + if (_endSequenceNeedLoading) { + snd_playWanderScoreViaMap(50, 1); + setupPanPages(); + _finalA = new WSAMovieV1(this); + assert(_finalA); + _finalA->open("finala.wsa", 1, 0); + _finalB = new WSAMovieV1(this); + assert(_finalB); + _finalB->open("finalb.wsa", 1, 0); + _finalC = new WSAMovieV1(this); + assert(_finalC); + _endSequenceNeedLoading = 0; + _finalC->open("finalc.wsa", 1, 0); + _screen->_curPage = 0; + _beadStateVar = 0; + _malcolmFlag = 0; + // wired stuff with _unkEndSeqVar2 which needs timer handling + _screen->copyRegion(312, 0, 312, 0, 8, 136, 0, 2); + } + if (handleMalcolmFlag()) { + _beadStateVar = 0; + _malcolmFlag = 12; + handleMalcolmFlag(); + handleBeadState(); + closeFinalWsa(); + if (_deathHandler == 8) { + _screen->_curPage = 0; + checkAmuletAnimFlags(); + seq_brandonToStone(); + waitTicks(60); + return 1; + } else { + _endSequenceSkipFlag = 1; + if (_text->printed()) { + _text->restoreTalkTextMessageBkgd(2, 0); + } + _screen->_curPage = 0; + _screen->hideMouse(); + _screen->fadeSpecialPalette(32, 228, 20, 60); + waitTicks(60); + loadBitmap("GEMHEAL.CPS", 3, 3, _screen->_currentPalette); + _screen->setScreenPalette(_screen->_currentPalette); + _screen->shuffleScreen(8, 8, 304, 128, 2, 0, 1, 0); + uint32 nextTime = _system->getMillis() + 120 * _tickLength; + _finalA = new WSAMovieV1(this); + assert(_finalA); + _finalA->open("finald.wsa", 1, 0); + _finalA->_x = _finalA->_y = 8; + _finalA->_drawPage = 0; + while (_system->getMillis() < nextTime) {} + snd_playSoundEffect(0x40); + for (int i = 0; i < 22; ++i) { + while (_system->getMillis() < nextTime) {} + if (i == 4) { + snd_playSoundEffect(0x3E); + } else if (i == 20) { + snd_playSoundEffect(0x0E); + } + nextTime = _system->getMillis() + 8 * _tickLength; + _finalA->displayFrame(i); + _screen->updateScreen(); + } + delete _finalA; + _finalA = 0; + seq_playEnding(); + return 1; + } + } else { + handleBeadState(); + _screen->bitBlitRects(); + _screen->updateScreen(); + _screen->_curPage = 0; + } + return 0; +} + +void KyraEngine::seq_brandonToStone() { + debug(9, "KyraEngine::seq_brandonToStone()"); + _screen->hideMouse(); + assert(_brandonStoneTable); + setupShapes123(_brandonStoneTable, 14, 0); + setBrandonAnimSeqSize(5, 51); + for (int i = 123; i <= 136; ++i) { + _currentCharacter->currentAnimFrame = i; + animRefreshNPC(0); + delayWithTicks(8); + } + resetBrandonAnimSeqSize(); + freeShapes123(); + _screen->showMouse(); +} + +void KyraEngine::seq_playEnding() { + debug(9, "KyraEngine::seq_playEnding()"); + _screen->hideMouse(); + res_unloadResources(RES_INGAME); + res_loadResources(RES_OUTRO); + loadBitmap("REUNION.CPS", 3, 3, _screen->_currentPalette); + _screen->copyRegion(8, 8, 8, 8, 304, 128, 2, 0); + _screen->_curPage = 0; + // XXX + assert(_homeString); + drawSentenceCommand(_homeString[0], 179); + _screen->_curPage = 0; + _screen->fadeToBlack(); + _seq->playSequence(_seq_Reunion, false); + _screen->fadeToBlack(); + _screen->showMouse(); + seq_playCredits(); +} + +void KyraEngine::seq_playCredits() { + debug(9, "KyraEngine::seq_playCredits()"); + static const uint8 colorMap[] = { 0, 0, 0xC, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; + _screen->hideMouse(); + uint32 sz = 0; + if (_features & GF_FLOPPY) { + _screen->loadFont(Screen::FID_CRED6_FNT, _res->fileData("CREDIT6.FNT", &sz)); + _screen->loadFont(Screen::FID_CRED8_FNT, _res->fileData("CREDIT8.FNT", &sz)); + } + loadBitmap("CHALET.CPS", 2, 2, _screen->_currentPalette); + _screen->setScreenPalette(_screen->_currentPalette); + _screen->setCurPage(0); + _screen->clearCurPage(); + _screen->copyRegion(8, 8, 8, 8, 304, 128, 2, 0); + _screen->setTextColorMap(colorMap); + _screen->_charWidth = -1; + snd_playWanderScoreViaMap(53, 1); + // delete + _screen->updateScreen(); + // XXX + waitTicks(120); // wait until user presses escape normally + _screen->fadeToBlack(); + _screen->clearCurPage(); + _screen->showMouse(); +} + +bool KyraEngine::seq_skipSequence() const { + debug(9, "KyraEngine::seq_skipSequence()"); + return _quitFlag || _abortIntroFlag; +} + +} // end of namespace Kyra |