diff options
-rw-r--r-- | engines/kyra/lol.cpp | 524 | ||||
-rw-r--r-- | engines/kyra/module.mk | 1 | ||||
-rw-r--r-- | engines/kyra/sequences_lol.cpp | 557 |
3 files changed, 558 insertions, 524 deletions
diff --git a/engines/kyra/lol.cpp b/engines/kyra/lol.cpp index c37e4b45f4..8811774849 100644 --- a/engines/kyra/lol.cpp +++ b/engines/kyra/lol.cpp @@ -823,530 +823,6 @@ uint8 *LoLEngine::getTableEntry(uint8 *buffer, uint16 id) { return buffer + READ_LE_UINT16(buffer + (id<<1)); } -#pragma mark - Intro - -void LoLEngine::setupPrologueData(bool load) { - debugC(9, kDebugLevelMain, "LoLEngine::setupPrologueData(%d)", load); - - static const char * const fileListCD[] = { - "GENERAL.PAK", "INTROVOC.PAK", "STARTUP.PAK", "INTRO1.PAK", - "INTRO2.PAK", "INTRO3.PAK", "INTRO4.PAK", "INTRO5.PAK", - "INTRO6.PAK", "INTRO7.PAK", "INTRO8.PAK", "INTRO9.PAK", 0 - }; - - static const char * const fileListFloppyExtracted[] = { - "INTRO.PAK", "INTROVOC.PAK", 0 - }; - - static const char * const fileListFloppy[] = { - "INTRO.PAK", "INTROVOC.CMP", 0 - }; - - const char * const *fileList = _flags.isTalkie ? fileListCD : - (_flags.useInstallerPackage ? fileListFloppy : fileListFloppyExtracted); - - - char filename[32]; - for (uint i = 0; fileList[i]; ++i) { - filename[0] = '\0'; - - if (_flags.isTalkie) { - strcpy(filename, _languageExt[_lang]); - strcat(filename, "/"); - } - - strcat(filename, fileList[i]); - - if (load) { - if (!_res->loadPakFile(filename)) - error("Couldn't load file: '%s'", filename); - } else { - _res->unloadPakFile(filename); - } - } - - _screen->clearPage(0); - _screen->clearPage(3); - - if (load) { - _chargenWSA = new WSAMovie_v2(this, _screen); - assert(_chargenWSA); - - //_charSelection = -1; - _charSelectionInfoResult = -1; - - _selectionAnimFrames[0] = _selectionAnimFrames[2] = 0; - _selectionAnimFrames[1] = _selectionAnimFrames[3] = 1; - - memset(_selectionAnimTimers, 0, sizeof(_selectionAnimTimers)); - memset(_screen->getPalette(1), 0, 768); - } else { - delete _chargenWSA; _chargenWSA = 0; - - if (!_res->loadFileList("FILEDATA.FDT")) - error("Couldn't load file list: 'FILEDATA.FDT'"); - - uint8 *pal = _screen->getPalette(0); - memset(pal, 0, 768); - _screen->setScreenPalette(pal); - - // TODO: We need to check if the SYSEX events of intro and ingame differ. - // If they differ, we really need to setup the proper ingame SYSEX when starting - // the game. But the proper place to do it would not be in this function. - /*if (_sound->getMusicType() == Sound::kMidiMT32 || _sound->getSfxType() == Sound::kMidiMT32) { - _sound->loadSoundFile("LOLSYSEX"); - _sound->playTrack(0); - - while (_sound->isPlaying() && !shouldQuit()) - delay(10); - }*/ - - if (shouldQuit()) - return; - - _eventList.clear(); - } -} - -void LoLEngine::showIntro() { - debugC(9, kDebugLevelMain, "LoLEngine::showIntro()"); - - uint8 *pal = _screen->getPalette(0); - memset(pal, 0, 768); - _screen->setScreenPalette(pal); - - TIM *intro = _tim->load("LOLINTRO.TIM", &_timIntroOpcodes); - - _screen->loadFont(Screen::FID_8_FNT, "NEW8P.FNT"); - _screen->loadFont(Screen::FID_INTRO_FNT, "INTRO.FNT"); - _screen->setFont(Screen::FID_8_FNT); - - _tim->resetFinishedFlag(); - _tim->setLangData("LOLINTRO.DIP"); - - _screen->hideMouse(); - - uint32 palNextFadeStep = 0; - while (!_tim->finished() && !shouldQuit() && !skipFlag()) { - updateInput(); - _tim->exec(intro, false); - _screen->checkedPageUpdate(8, 4); - - if (_tim->_palDiff) { - if (palNextFadeStep < _system->getMillis()) { - _tim->_palDelayAcc += _tim->_palDelayInc; - palNextFadeStep = _system->getMillis() + ((_tim->_palDelayAcc >> 8) * _tickLength); - _tim->_palDelayAcc &= 0xFF; - - if (!_screen->fadePalStep(_screen->getPalette(0), _tim->_palDiff)) { - _screen->setScreenPalette(_screen->getPalette(0)); - _tim->_palDiff = 0; - } - } - } - - _system->delayMillis(10); - _screen->updateScreen(); - } - _screen->showMouse(); - _sound->voiceStop(); - _sound->beginFadeOut(); - - _eventList.clear(); - - _tim->unload(intro); - _tim->clearLangData(); - - for (int i = 0; i < TIM::kWSASlots; i++) - _tim->freeAnimStruct(i); - - _screen->fadePalette(_screen->getPalette(1), 30, 0); -} - -int LoLEngine::chooseCharacter() { - debugC(9, kDebugLevelMain, "LoLEngine::chooseCharacter()"); - - _tim->setLangData("LOLINTRO.DIP"); - - _screen->loadFont(Screen::FID_9_FNT, "FONT9P.FNT"); - - _screen->loadBitmap("ITEMICN.SHP", 3, 3, 0); - _screen->setMouseCursor(0, 0, _screen->getPtrToShape(_screen->getCPagePtr(3), 0)); - - while (!_screen->isMouseVisible()) - _screen->showMouse(); - - _screen->loadBitmap("CHAR.CPS", 2, 2, _screen->getPalette(0)); - _screen->loadBitmap("BACKGRND.CPS", 4, 4, _screen->getPalette(0)); - - if (!_chargenWSA->open("CHARGEN.WSA", 1, 0)) - error("Couldn't load CHARGEN.WSA"); - _chargenWSA->setX(113); - _chargenWSA->setY(0); - _chargenWSA->setDrawPage(2); - _chargenWSA->displayFrame(0, 0, 0, 0); - - _screen->setFont(Screen::FID_9_FNT); - _screen->_curPage = 2; - - for (int i = 0; i < 4; ++i) - _screen->fprintStringIntro(_charPreviews[i].name, _charPreviews[i].x + 16, _charPreviews[i].y + 36, 0xC0, 0x00, 0x9C, 0x120); - - for (int i = 0; i < 4; ++i) { - _screen->fprintStringIntro("%d", _charPreviews[i].x + 21, _charPreviews[i].y + 48, 0x98, 0x00, 0x9C, 0x220, _charPreviews[i].attrib[0]); - _screen->fprintStringIntro("%d", _charPreviews[i].x + 21, _charPreviews[i].y + 56, 0x98, 0x00, 0x9C, 0x220, _charPreviews[i].attrib[1]); - _screen->fprintStringIntro("%d", _charPreviews[i].x + 21, _charPreviews[i].y + 64, 0x98, 0x00, 0x9C, 0x220, _charPreviews[i].attrib[2]); - } - - _screen->fprintStringIntro(_tim->getCTableEntry(51), 36, 173, 0x98, 0x00, 0x9C, 0x20); - _screen->fprintStringIntro(_tim->getCTableEntry(53), 36, 181, 0x98, 0x00, 0x9C, 0x20); - _screen->fprintStringIntro(_tim->getCTableEntry(55), 36, 189, 0x98, 0x00, 0x9C, 0x20); - - _screen->copyRegion(0, 0, 0, 0, 320, 200, 2, 0, Screen::CR_NO_P_CHECK); - _screen->_curPage = 0; - - _screen->fadePalette(_screen->getPalette(0), 30, 0); - - bool kingIntro = true; - while (!shouldQuit()) { - if (kingIntro) - kingSelectionIntro(); - - if (_charSelection < 0) - processCharacterSelection(); - - if (shouldQuit()) - break; - - if (_charSelection == 100) { - kingIntro = true; - _charSelection = -1; - continue; - } - - _screen->copyRegion(0, 0, 0, 0, 112, 120, 4, 0, Screen::CR_NO_P_CHECK); - _screen->updateScreen(); - _screen->showMouse(); - - if (selectionCharInfo(_charSelection) == -1) { - _charSelection = -1; - kingIntro = false; - } else { - break; - } - } - - if (shouldQuit()) - return -1; - - uint32 waitTime = _system->getMillis() + 420 * _tickLength; - while (waitTime > _system->getMillis() && !skipFlag() && !shouldQuit()) { - updateInput(); - _system->delayMillis(10); - } - - // HACK: Remove all input events - _eventList.clear(); - - _tim->clearLangData(); - - return _charSelection; -} - -void LoLEngine::kingSelectionIntro() { - debugC(9, kDebugLevelMain, "LoLEngine::kingSelectionIntro()"); - - _screen->copyRegion(0, 0, 0, 0, 112, 120, 4, 0, Screen::CR_NO_P_CHECK); - int y = 38; - - _screen->fprintStringIntro(_tim->getCTableEntry(57), 8, y, 0x32, 0x00, 0x9C, 0x20); - _screen->fprintStringIntro(_tim->getCTableEntry(58), 8, y + 10, 0x32, 0x00, 0x9C, 0x20); - _screen->fprintStringIntro(_tim->getCTableEntry(59), 8, y + 20, 0x32, 0x00, 0x9C, 0x20); - _screen->fprintStringIntro(_tim->getCTableEntry(60), 8, y + 30, 0x32, 0x00, 0x9C, 0x20); - _screen->fprintStringIntro(_tim->getCTableEntry(61), 8, y + 40, 0x32, 0x00, 0x9C, 0x20); - - _sound->voicePlay("KING01"); - - _chargenWSA->setX(113); - _chargenWSA->setY(0); - _chargenWSA->setDrawPage(0); - - int index = 4; - while (_sound->voiceIsPlaying("KING01") && _charSelection == -1 && !shouldQuit() && !skipFlag()) { - index = MAX(index, 4); - - _chargenWSA->displayFrame(_chargenFrameTable[index], 0, 0, 0); - _screen->copyRegion(_selectionPosTable[_selectionChar1IdxTable[index]*2+0], _selectionPosTable[_selectionChar1IdxTable[index]*2+1], _charPreviews[0].x, _charPreviews[0].y, 32, 32, 4, 0); - _screen->copyRegion(_selectionPosTable[_selectionChar2IdxTable[index]*2+0], _selectionPosTable[_selectionChar2IdxTable[index]*2+1], _charPreviews[1].x, _charPreviews[1].y, 32, 32, 4, 0); - _screen->copyRegion(_selectionPosTable[_selectionChar3IdxTable[index]*2+0], _selectionPosTable[_selectionChar3IdxTable[index]*2+1], _charPreviews[2].x, _charPreviews[2].y, 32, 32, 4, 0); - _screen->copyRegion(_selectionPosTable[_selectionChar4IdxTable[index]*2+0], _selectionPosTable[_selectionChar4IdxTable[index]*2+1], _charPreviews[3].x, _charPreviews[3].y, 32, 32, 4, 0); - _screen->updateScreen(); - - uint32 waitEnd = _system->getMillis() + 7 * _tickLength; - while (waitEnd > _system->getMillis() && _charSelection == -1 && !shouldQuit() && !skipFlag()) { - _charSelection = getCharSelection(); - _system->delayMillis(10); - } - - index = (index + 1) % 22; - } - - resetSkipFlag(); - - _chargenWSA->displayFrame(0x10, 0, 0, 0); - _screen->updateScreen(); - _sound->voiceStop("KING01"); -} - -void LoLEngine::kingSelectionReminder() { - debugC(9, kDebugLevelMain, "LoLEngine::kingSelectionReminder()"); - - _screen->copyRegion(0, 0, 0, 0, 112, 120, 4, 0, Screen::CR_NO_P_CHECK); - int y = 48; - - _screen->fprintStringIntro(_tim->getCTableEntry(62), 8, y, 0x32, 0x00, 0x9C, 0x20); - _screen->fprintStringIntro(_tim->getCTableEntry(63), 8, y + 10, 0x32, 0x00, 0x9C, 0x20); - - _sound->voicePlay("KING02"); - - _chargenWSA->setX(113); - _chargenWSA->setY(0); - _chargenWSA->setDrawPage(0); - - int index = 0; - while (_sound->voiceIsPlaying("KING02") && _charSelection == -1 && !shouldQuit() && index < 15) { - _chargenWSA->displayFrame(_chargenFrameTable[index+9], 0, 0, 0); - _screen->copyRegion(_selectionPosTable[_reminderChar1IdxTable[index]*2+0], _selectionPosTable[_reminderChar1IdxTable[index]*2+1], _charPreviews[0].x, _charPreviews[0].y, 32, 32, 4, 0); - _screen->copyRegion(_selectionPosTable[_reminderChar2IdxTable[index]*2+0], _selectionPosTable[_reminderChar2IdxTable[index]*2+1], _charPreviews[1].x, _charPreviews[1].y, 32, 32, 4, 0); - _screen->copyRegion(_selectionPosTable[_reminderChar3IdxTable[index]*2+0], _selectionPosTable[_reminderChar3IdxTable[index]*2+1], _charPreviews[2].x, _charPreviews[2].y, 32, 32, 4, 0); - _screen->copyRegion(_selectionPosTable[_reminderChar4IdxTable[index]*2+0], _selectionPosTable[_reminderChar4IdxTable[index]*2+1], _charPreviews[3].x, _charPreviews[3].y, 32, 32, 4, 0); - _screen->updateScreen(); - - uint32 waitEnd = _system->getMillis() + 8 * _tickLength; - while (waitEnd > _system->getMillis() && !shouldQuit()) { - _charSelection = getCharSelection(); - _system->delayMillis(10); - } - - index = (index + 1) % 22; - } - - _sound->voiceStop("KING02"); -} - -void LoLEngine::kingSelectionOutro() { - debugC(9, kDebugLevelMain, "LoLEngine::kingSelectionOutro()"); - - _sound->voicePlay("KING03"); - - _chargenWSA->setX(113); - _chargenWSA->setY(0); - _chargenWSA->setDrawPage(0); - - int index = 0; - while (_sound->voiceIsPlaying("KING03") && !shouldQuit() && !skipFlag()) { - index = MAX(index, 4); - - _chargenWSA->displayFrame(_chargenFrameTable[index], 0, 0, 0); - _screen->updateScreen(); - - uint32 waitEnd = _system->getMillis() + 8 * _tickLength; - while (waitEnd > _system->getMillis() && !shouldQuit() && !skipFlag()) { - updateInput(); - _system->delayMillis(10); - } - - index = (index + 1) % 22; - } - - resetSkipFlag(); - - _chargenWSA->displayFrame(0x10, 0, 0, 0); - _screen->updateScreen(); - _sound->voiceStop("KING03"); -} - -void LoLEngine::processCharacterSelection() { - debugC(9, kDebugLevelMain, "LoLEngine::processCharacterSelection()"); - - _charSelection = -1; - while (!shouldQuit() && _charSelection == -1) { - uint32 nextKingMessage = _system->getMillis() + 900 * _tickLength; - - while (nextKingMessage > _system->getMillis() && _charSelection == -1 && !shouldQuit()) { - updateSelectionAnims(); - _charSelection = getCharSelection(); - _system->delayMillis(10); - } - - if (_charSelection == -1) - kingSelectionReminder(); - } -} - -void LoLEngine::updateSelectionAnims() { - debugC(9, kDebugLevelMain, "LoLEngine::updateSelectionAnims()"); - - for (int i = 0; i < 4; ++i) { - if (_system->getMillis() < _selectionAnimTimers[i]) - continue; - - const int index = _selectionAnimIndexTable[_selectionAnimFrames[i] + i * 2]; - _screen->copyRegion(_selectionPosTable[index*2+0], _selectionPosTable[index*2+1], _charPreviews[i].x, _charPreviews[i].y, 32, 32, 4, 0); - - int delayTime = 0; - if (_selectionAnimFrames[i] == 1) - delayTime = _rnd.getRandomNumberRng(0, 31) + 80; - else - delayTime = _rnd.getRandomNumberRng(0, 3) + 10; - - _selectionAnimTimers[i] = _system->getMillis() + delayTime * _tickLength; - _selectionAnimFrames[i] = (_selectionAnimFrames[i] + 1) % 2; - } - - _screen->updateScreen(); -} - -int LoLEngine::selectionCharInfo(int character) { - debugC(9, kDebugLevelMain, "LoLEngine::selectionCharInfo(%d)", character); - if (character < 0) - return -1; - - char filename[16]; - char vocFilename[6]; - strcpy(vocFilename, "000X0"); - - switch (character) { - case 0: - strcpy(filename, "FACE09.SHP"); - vocFilename[3] = 'A'; - break; - - case 1: - strcpy(filename, "FACE01.SHP"); - vocFilename[3] = 'M'; - break; - - case 2: - strcpy(filename, "FACE08.SHP"); - vocFilename[3] = 'K'; - break; - - case 3: - strcpy(filename, "FACE05.SHP"); - vocFilename[3] = 'C'; - break; - - default: - break; - }; - - _screen->loadBitmap(filename, 9, 9, 0); - _screen->copyRegion(0, 122, 0, 122, 320, 78, 4, 0, Screen::CR_NO_P_CHECK); - _screen->copyRegion(_charPreviews[character].x - 3, _charPreviews[character].y - 3, 8, 127, 38, 38, 2, 0); - - static const uint8 charSelectInfoIdx[] = { 0x1D, 0x22, 0x27, 0x2C }; - const int idx = charSelectInfoIdx[character]; - - _screen->fprintStringIntro(_tim->getCTableEntry(idx+0), 50, 127, 0x53, 0x00, 0xCF, 0x20); - _screen->fprintStringIntro(_tim->getCTableEntry(idx+1), 50, 137, 0x53, 0x00, 0xCF, 0x20); - _screen->fprintStringIntro(_tim->getCTableEntry(idx+2), 50, 147, 0x53, 0x00, 0xCF, 0x20); - _screen->fprintStringIntro(_tim->getCTableEntry(idx+3), 50, 157, 0x53, 0x00, 0xCF, 0x20); - _screen->fprintStringIntro(_tim->getCTableEntry(idx+4), 50, 167, 0x53, 0x00, 0xCF, 0x20); - - _screen->fprintStringIntro(_tim->getCTableEntry(69), 100, 168, 0x32, 0x00, 0xCF, 0x20); - - selectionCharInfoIntro(vocFilename); - if (_charSelectionInfoResult == -1) { - while (_charSelectionInfoResult == -1) { - _charSelectionInfoResult = selectionCharAccept(); - _system->delayMillis(10); - } - } - - if (_charSelectionInfoResult != 1) { - _charSelectionInfoResult = -1; - _screen->copyRegion(0, 122, 0, 122, 320, 78, 2, 0, Screen::CR_NO_P_CHECK); - _screen->updateScreen(); - return -1; - } - - _screen->copyRegion(48, 127, 48, 127, 272, 60, 4, 0, Screen::CR_NO_P_CHECK); - _screen->hideMouse(); - _screen->copyRegion(48, 127, 48, 160, 272, 35, 4, 0, Screen::CR_NO_P_CHECK); - _screen->copyRegion(0, 0, 0, 0, 112, 120, 4, 0, Screen::CR_NO_P_CHECK); - - _screen->fprintStringIntro(_tim->getCTableEntry(64), 3, 28, 0x32, 0x00, 0x9C, 0x20); - _screen->fprintStringIntro(_tim->getCTableEntry(65), 3, 38, 0x32, 0x00, 0x9C, 0x20); - _screen->fprintStringIntro(_tim->getCTableEntry(66), 3, 48, 0x32, 0x00, 0x9C, 0x20); - _screen->fprintStringIntro(_tim->getCTableEntry(67), 3, 58, 0x32, 0x00, 0x9C, 0x20); - _screen->fprintStringIntro(_tim->getCTableEntry(68), 3, 68, 0x32, 0x00, 0x9C, 0x20); - - resetSkipFlag(); - kingSelectionOutro(); - return character; -} - -void LoLEngine::selectionCharInfoIntro(char *file) { - debugC(9, kDebugLevelMain, "LoLEngine::selectionCharInfoIntro(%p)", (const void *)file); - int index = 0; - file[4] = '0'; - - while (_charSelectionInfoResult == -1 && !shouldQuit()) { - if (!_sound->voicePlay(file)) - break; - - int i = 0; - while (_sound->voiceIsPlaying(file) && _charSelectionInfoResult == -1 && !shouldQuit()) { - _screen->drawShape(0, _screen->getPtrToShape(_screen->getCPagePtr(9), _charInfoFrameTable[i]), 11, 130, 0, 0); - _screen->updateScreen(); - - uint32 nextFrame = _system->getMillis() + 8 * _tickLength; - while (nextFrame > _system->getMillis() && _charSelectionInfoResult == -1) { - _charSelectionInfoResult = selectionCharAccept(); - _system->delayMillis(10); - } - - i = (i + 1) % 32; - } - - _sound->voiceStop(file); - file[4] = ++index + '0'; - } - - _screen->drawShape(0, _screen->getPtrToShape(_screen->getCPagePtr(9), 0), 11, 130, 0, 0); - _screen->updateScreen(); -} - -int LoLEngine::getCharSelection() { - int inputFlag = checkInput(0, false) & 0xCF; - removeInputTop(); - - if (inputFlag == 200) { - for (int i = 0; i < 4; ++i) { - if (_charPreviews[i].x <= _mouseX && _mouseX <= _charPreviews[i].x + 31 && - _charPreviews[i].y <= _mouseY && _mouseY <= _charPreviews[i].y + 31) - return i; - } - } - - return -1; -} - -int LoLEngine::selectionCharAccept() { - int inputFlag = checkInput(0, false) & 0xCF; - removeInputTop(); - - if (inputFlag == 200) { - if (88 <= _mouseX && _mouseX <= 128 && 180 <= _mouseY && _mouseY <= 194) - return 1; - if (196 <= _mouseX && _mouseX <= 236 && 180 <= _mouseY && _mouseY <= 194) - return 0; - } - - return -1; -} - bool LoLEngine::addCharacter(int id) { int numChars = countActiveCharacters(); if (numChars == 4) diff --git a/engines/kyra/module.mk b/engines/kyra/module.mk index e427ee1b43..fa7fa25ce7 100644 --- a/engines/kyra/module.mk +++ b/engines/kyra/module.mk @@ -52,6 +52,7 @@ MODULE_OBJS := \ script_tim.o \ seqplayer.o \ sequences_lok.o \ + sequences_lol.o \ sequences_v2.o \ sequences_hof.o \ sequences_mr.o \ diff --git a/engines/kyra/sequences_lol.cpp b/engines/kyra/sequences_lol.cpp new file mode 100644 index 0000000000..e3c4850d87 --- /dev/null +++ b/engines/kyra/sequences_lol.cpp @@ -0,0 +1,557 @@ +/* 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. + * + * $URL$ + * $Id$ + * + */ + +#include "kyra/lol.h" +#include "kyra/screen_lol.h" +#include "kyra/resource.h" + +namespace Kyra { + +#pragma mark - Intro + +void LoLEngine::setupPrologueData(bool load) { + debugC(9, kDebugLevelMain, "LoLEngine::setupPrologueData(%d)", load); + + static const char * const fileListCD[] = { + "GENERAL.PAK", "INTROVOC.PAK", "STARTUP.PAK", "INTRO1.PAK", + "INTRO2.PAK", "INTRO3.PAK", "INTRO4.PAK", "INTRO5.PAK", + "INTRO6.PAK", "INTRO7.PAK", "INTRO8.PAK", "INTRO9.PAK", 0 + }; + + static const char * const fileListFloppyExtracted[] = { + "INTRO.PAK", "INTROVOC.PAK", 0 + }; + + static const char * const fileListFloppy[] = { + "INTRO.PAK", "INTROVOC.CMP", 0 + }; + + const char * const *fileList = _flags.isTalkie ? fileListCD : + (_flags.useInstallerPackage ? fileListFloppy : fileListFloppyExtracted); + + + char filename[32]; + for (uint i = 0; fileList[i]; ++i) { + filename[0] = '\0'; + + if (_flags.isTalkie) { + strcpy(filename, _languageExt[_lang]); + strcat(filename, "/"); + } + + strcat(filename, fileList[i]); + + if (load) { + if (!_res->loadPakFile(filename)) + error("Couldn't load file: '%s'", filename); + } else { + _res->unloadPakFile(filename); + } + } + + _screen->clearPage(0); + _screen->clearPage(3); + + if (load) { + _chargenWSA = new WSAMovie_v2(this, _screen); + assert(_chargenWSA); + + //_charSelection = -1; + _charSelectionInfoResult = -1; + + _selectionAnimFrames[0] = _selectionAnimFrames[2] = 0; + _selectionAnimFrames[1] = _selectionAnimFrames[3] = 1; + + memset(_selectionAnimTimers, 0, sizeof(_selectionAnimTimers)); + memset(_screen->getPalette(1), 0, 768); + } else { + delete _chargenWSA; _chargenWSA = 0; + + if (!_res->loadFileList("FILEDATA.FDT")) + error("Couldn't load file list: 'FILEDATA.FDT'"); + + uint8 *pal = _screen->getPalette(0); + memset(pal, 0, 768); + _screen->setScreenPalette(pal); + + // TODO: We need to check if the SYSEX events of intro and ingame differ. + // If they differ, we really need to setup the proper ingame SYSEX when starting + // the game. But the proper place to do it would not be in this function. + /*if (_sound->getMusicType() == Sound::kMidiMT32 || _sound->getSfxType() == Sound::kMidiMT32) { + _sound->loadSoundFile("LOLSYSEX"); + _sound->playTrack(0); + + while (_sound->isPlaying() && !shouldQuit()) + delay(10); + }*/ + + if (shouldQuit()) + return; + + _eventList.clear(); + } +} + +void LoLEngine::showIntro() { + debugC(9, kDebugLevelMain, "LoLEngine::showIntro()"); + + uint8 *pal = _screen->getPalette(0); + memset(pal, 0, 768); + _screen->setScreenPalette(pal); + + TIM *intro = _tim->load("LOLINTRO.TIM", &_timIntroOpcodes); + + _screen->loadFont(Screen::FID_8_FNT, "NEW8P.FNT"); + _screen->loadFont(Screen::FID_INTRO_FNT, "INTRO.FNT"); + _screen->setFont(Screen::FID_8_FNT); + + _tim->resetFinishedFlag(); + _tim->setLangData("LOLINTRO.DIP"); + + _screen->hideMouse(); + + uint32 palNextFadeStep = 0; + while (!_tim->finished() && !shouldQuit() && !skipFlag()) { + updateInput(); + _tim->exec(intro, false); + _screen->checkedPageUpdate(8, 4); + + if (_tim->_palDiff) { + if (palNextFadeStep < _system->getMillis()) { + _tim->_palDelayAcc += _tim->_palDelayInc; + palNextFadeStep = _system->getMillis() + ((_tim->_palDelayAcc >> 8) * _tickLength); + _tim->_palDelayAcc &= 0xFF; + + if (!_screen->fadePalStep(_screen->getPalette(0), _tim->_palDiff)) { + _screen->setScreenPalette(_screen->getPalette(0)); + _tim->_palDiff = 0; + } + } + } + + _system->delayMillis(10); + _screen->updateScreen(); + } + _screen->showMouse(); + _sound->voiceStop(); + _sound->beginFadeOut(); + + _eventList.clear(); + + _tim->unload(intro); + _tim->clearLangData(); + + for (int i = 0; i < TIM::kWSASlots; i++) + _tim->freeAnimStruct(i); + + _screen->fadePalette(_screen->getPalette(1), 30, 0); +} + +int LoLEngine::chooseCharacter() { + debugC(9, kDebugLevelMain, "LoLEngine::chooseCharacter()"); + + _tim->setLangData("LOLINTRO.DIP"); + + _screen->loadFont(Screen::FID_9_FNT, "FONT9P.FNT"); + + _screen->loadBitmap("ITEMICN.SHP", 3, 3, 0); + _screen->setMouseCursor(0, 0, _screen->getPtrToShape(_screen->getCPagePtr(3), 0)); + + while (!_screen->isMouseVisible()) + _screen->showMouse(); + + _screen->loadBitmap("CHAR.CPS", 2, 2, _screen->getPalette(0)); + _screen->loadBitmap("BACKGRND.CPS", 4, 4, _screen->getPalette(0)); + + if (!_chargenWSA->open("CHARGEN.WSA", 1, 0)) + error("Couldn't load CHARGEN.WSA"); + _chargenWSA->setX(113); + _chargenWSA->setY(0); + _chargenWSA->setDrawPage(2); + _chargenWSA->displayFrame(0, 0, 0, 0); + + _screen->setFont(Screen::FID_9_FNT); + _screen->_curPage = 2; + + for (int i = 0; i < 4; ++i) + _screen->fprintStringIntro(_charPreviews[i].name, _charPreviews[i].x + 16, _charPreviews[i].y + 36, 0xC0, 0x00, 0x9C, 0x120); + + for (int i = 0; i < 4; ++i) { + _screen->fprintStringIntro("%d", _charPreviews[i].x + 21, _charPreviews[i].y + 48, 0x98, 0x00, 0x9C, 0x220, _charPreviews[i].attrib[0]); + _screen->fprintStringIntro("%d", _charPreviews[i].x + 21, _charPreviews[i].y + 56, 0x98, 0x00, 0x9C, 0x220, _charPreviews[i].attrib[1]); + _screen->fprintStringIntro("%d", _charPreviews[i].x + 21, _charPreviews[i].y + 64, 0x98, 0x00, 0x9C, 0x220, _charPreviews[i].attrib[2]); + } + + _screen->fprintStringIntro(_tim->getCTableEntry(51), 36, 173, 0x98, 0x00, 0x9C, 0x20); + _screen->fprintStringIntro(_tim->getCTableEntry(53), 36, 181, 0x98, 0x00, 0x9C, 0x20); + _screen->fprintStringIntro(_tim->getCTableEntry(55), 36, 189, 0x98, 0x00, 0x9C, 0x20); + + _screen->copyRegion(0, 0, 0, 0, 320, 200, 2, 0, Screen::CR_NO_P_CHECK); + _screen->_curPage = 0; + + _screen->fadePalette(_screen->getPalette(0), 30, 0); + + bool kingIntro = true; + while (!shouldQuit()) { + if (kingIntro) + kingSelectionIntro(); + + if (_charSelection < 0) + processCharacterSelection(); + + if (shouldQuit()) + break; + + if (_charSelection == 100) { + kingIntro = true; + _charSelection = -1; + continue; + } + + _screen->copyRegion(0, 0, 0, 0, 112, 120, 4, 0, Screen::CR_NO_P_CHECK); + _screen->updateScreen(); + _screen->showMouse(); + + if (selectionCharInfo(_charSelection) == -1) { + _charSelection = -1; + kingIntro = false; + } else { + break; + } + } + + if (shouldQuit()) + return -1; + + uint32 waitTime = _system->getMillis() + 420 * _tickLength; + while (waitTime > _system->getMillis() && !skipFlag() && !shouldQuit()) { + updateInput(); + _system->delayMillis(10); + } + + // HACK: Remove all input events + _eventList.clear(); + + _tim->clearLangData(); + + return _charSelection; +} + +void LoLEngine::kingSelectionIntro() { + debugC(9, kDebugLevelMain, "LoLEngine::kingSelectionIntro()"); + + _screen->copyRegion(0, 0, 0, 0, 112, 120, 4, 0, Screen::CR_NO_P_CHECK); + int y = 38; + + _screen->fprintStringIntro(_tim->getCTableEntry(57), 8, y, 0x32, 0x00, 0x9C, 0x20); + _screen->fprintStringIntro(_tim->getCTableEntry(58), 8, y + 10, 0x32, 0x00, 0x9C, 0x20); + _screen->fprintStringIntro(_tim->getCTableEntry(59), 8, y + 20, 0x32, 0x00, 0x9C, 0x20); + _screen->fprintStringIntro(_tim->getCTableEntry(60), 8, y + 30, 0x32, 0x00, 0x9C, 0x20); + _screen->fprintStringIntro(_tim->getCTableEntry(61), 8, y + 40, 0x32, 0x00, 0x9C, 0x20); + + _sound->voicePlay("KING01"); + + _chargenWSA->setX(113); + _chargenWSA->setY(0); + _chargenWSA->setDrawPage(0); + + int index = 4; + while (_sound->voiceIsPlaying("KING01") && _charSelection == -1 && !shouldQuit() && !skipFlag()) { + index = MAX(index, 4); + + _chargenWSA->displayFrame(_chargenFrameTable[index], 0, 0, 0); + _screen->copyRegion(_selectionPosTable[_selectionChar1IdxTable[index]*2+0], _selectionPosTable[_selectionChar1IdxTable[index]*2+1], _charPreviews[0].x, _charPreviews[0].y, 32, 32, 4, 0); + _screen->copyRegion(_selectionPosTable[_selectionChar2IdxTable[index]*2+0], _selectionPosTable[_selectionChar2IdxTable[index]*2+1], _charPreviews[1].x, _charPreviews[1].y, 32, 32, 4, 0); + _screen->copyRegion(_selectionPosTable[_selectionChar3IdxTable[index]*2+0], _selectionPosTable[_selectionChar3IdxTable[index]*2+1], _charPreviews[2].x, _charPreviews[2].y, 32, 32, 4, 0); + _screen->copyRegion(_selectionPosTable[_selectionChar4IdxTable[index]*2+0], _selectionPosTable[_selectionChar4IdxTable[index]*2+1], _charPreviews[3].x, _charPreviews[3].y, 32, 32, 4, 0); + _screen->updateScreen(); + + uint32 waitEnd = _system->getMillis() + 7 * _tickLength; + while (waitEnd > _system->getMillis() && _charSelection == -1 && !shouldQuit() && !skipFlag()) { + _charSelection = getCharSelection(); + _system->delayMillis(10); + } + + index = (index + 1) % 22; + } + + resetSkipFlag(); + + _chargenWSA->displayFrame(0x10, 0, 0, 0); + _screen->updateScreen(); + _sound->voiceStop("KING01"); +} + +void LoLEngine::kingSelectionReminder() { + debugC(9, kDebugLevelMain, "LoLEngine::kingSelectionReminder()"); + + _screen->copyRegion(0, 0, 0, 0, 112, 120, 4, 0, Screen::CR_NO_P_CHECK); + int y = 48; + + _screen->fprintStringIntro(_tim->getCTableEntry(62), 8, y, 0x32, 0x00, 0x9C, 0x20); + _screen->fprintStringIntro(_tim->getCTableEntry(63), 8, y + 10, 0x32, 0x00, 0x9C, 0x20); + + _sound->voicePlay("KING02"); + + _chargenWSA->setX(113); + _chargenWSA->setY(0); + _chargenWSA->setDrawPage(0); + + int index = 0; + while (_sound->voiceIsPlaying("KING02") && _charSelection == -1 && !shouldQuit() && index < 15) { + _chargenWSA->displayFrame(_chargenFrameTable[index+9], 0, 0, 0); + _screen->copyRegion(_selectionPosTable[_reminderChar1IdxTable[index]*2+0], _selectionPosTable[_reminderChar1IdxTable[index]*2+1], _charPreviews[0].x, _charPreviews[0].y, 32, 32, 4, 0); + _screen->copyRegion(_selectionPosTable[_reminderChar2IdxTable[index]*2+0], _selectionPosTable[_reminderChar2IdxTable[index]*2+1], _charPreviews[1].x, _charPreviews[1].y, 32, 32, 4, 0); + _screen->copyRegion(_selectionPosTable[_reminderChar3IdxTable[index]*2+0], _selectionPosTable[_reminderChar3IdxTable[index]*2+1], _charPreviews[2].x, _charPreviews[2].y, 32, 32, 4, 0); + _screen->copyRegion(_selectionPosTable[_reminderChar4IdxTable[index]*2+0], _selectionPosTable[_reminderChar4IdxTable[index]*2+1], _charPreviews[3].x, _charPreviews[3].y, 32, 32, 4, 0); + _screen->updateScreen(); + + uint32 waitEnd = _system->getMillis() + 8 * _tickLength; + while (waitEnd > _system->getMillis() && !shouldQuit()) { + _charSelection = getCharSelection(); + _system->delayMillis(10); + } + + index = (index + 1) % 22; + } + + _sound->voiceStop("KING02"); +} + +void LoLEngine::kingSelectionOutro() { + debugC(9, kDebugLevelMain, "LoLEngine::kingSelectionOutro()"); + + _sound->voicePlay("KING03"); + + _chargenWSA->setX(113); + _chargenWSA->setY(0); + _chargenWSA->setDrawPage(0); + + int index = 0; + while (_sound->voiceIsPlaying("KING03") && !shouldQuit() && !skipFlag()) { + index = MAX(index, 4); + + _chargenWSA->displayFrame(_chargenFrameTable[index], 0, 0, 0); + _screen->updateScreen(); + + uint32 waitEnd = _system->getMillis() + 8 * _tickLength; + while (waitEnd > _system->getMillis() && !shouldQuit() && !skipFlag()) { + updateInput(); + _system->delayMillis(10); + } + + index = (index + 1) % 22; + } + + resetSkipFlag(); + + _chargenWSA->displayFrame(0x10, 0, 0, 0); + _screen->updateScreen(); + _sound->voiceStop("KING03"); +} + +void LoLEngine::processCharacterSelection() { + debugC(9, kDebugLevelMain, "LoLEngine::processCharacterSelection()"); + + _charSelection = -1; + while (!shouldQuit() && _charSelection == -1) { + uint32 nextKingMessage = _system->getMillis() + 900 * _tickLength; + + while (nextKingMessage > _system->getMillis() && _charSelection == -1 && !shouldQuit()) { + updateSelectionAnims(); + _charSelection = getCharSelection(); + _system->delayMillis(10); + } + + if (_charSelection == -1) + kingSelectionReminder(); + } +} + +void LoLEngine::updateSelectionAnims() { + debugC(9, kDebugLevelMain, "LoLEngine::updateSelectionAnims()"); + + for (int i = 0; i < 4; ++i) { + if (_system->getMillis() < _selectionAnimTimers[i]) + continue; + + const int index = _selectionAnimIndexTable[_selectionAnimFrames[i] + i * 2]; + _screen->copyRegion(_selectionPosTable[index*2+0], _selectionPosTable[index*2+1], _charPreviews[i].x, _charPreviews[i].y, 32, 32, 4, 0); + + int delayTime = 0; + if (_selectionAnimFrames[i] == 1) + delayTime = _rnd.getRandomNumberRng(0, 31) + 80; + else + delayTime = _rnd.getRandomNumberRng(0, 3) + 10; + + _selectionAnimTimers[i] = _system->getMillis() + delayTime * _tickLength; + _selectionAnimFrames[i] = (_selectionAnimFrames[i] + 1) % 2; + } + + _screen->updateScreen(); +} + +int LoLEngine::selectionCharInfo(int character) { + debugC(9, kDebugLevelMain, "LoLEngine::selectionCharInfo(%d)", character); + if (character < 0) + return -1; + + char filename[16]; + char vocFilename[6]; + strcpy(vocFilename, "000X0"); + + switch (character) { + case 0: + strcpy(filename, "FACE09.SHP"); + vocFilename[3] = 'A'; + break; + + case 1: + strcpy(filename, "FACE01.SHP"); + vocFilename[3] = 'M'; + break; + + case 2: + strcpy(filename, "FACE08.SHP"); + vocFilename[3] = 'K'; + break; + + case 3: + strcpy(filename, "FACE05.SHP"); + vocFilename[3] = 'C'; + break; + + default: + break; + }; + + _screen->loadBitmap(filename, 9, 9, 0); + _screen->copyRegion(0, 122, 0, 122, 320, 78, 4, 0, Screen::CR_NO_P_CHECK); + _screen->copyRegion(_charPreviews[character].x - 3, _charPreviews[character].y - 3, 8, 127, 38, 38, 2, 0); + + static const uint8 charSelectInfoIdx[] = { 0x1D, 0x22, 0x27, 0x2C }; + const int idx = charSelectInfoIdx[character]; + + _screen->fprintStringIntro(_tim->getCTableEntry(idx+0), 50, 127, 0x53, 0x00, 0xCF, 0x20); + _screen->fprintStringIntro(_tim->getCTableEntry(idx+1), 50, 137, 0x53, 0x00, 0xCF, 0x20); + _screen->fprintStringIntro(_tim->getCTableEntry(idx+2), 50, 147, 0x53, 0x00, 0xCF, 0x20); + _screen->fprintStringIntro(_tim->getCTableEntry(idx+3), 50, 157, 0x53, 0x00, 0xCF, 0x20); + _screen->fprintStringIntro(_tim->getCTableEntry(idx+4), 50, 167, 0x53, 0x00, 0xCF, 0x20); + + _screen->fprintStringIntro(_tim->getCTableEntry(69), 100, 168, 0x32, 0x00, 0xCF, 0x20); + + selectionCharInfoIntro(vocFilename); + if (_charSelectionInfoResult == -1) { + while (_charSelectionInfoResult == -1) { + _charSelectionInfoResult = selectionCharAccept(); + _system->delayMillis(10); + } + } + + if (_charSelectionInfoResult != 1) { + _charSelectionInfoResult = -1; + _screen->copyRegion(0, 122, 0, 122, 320, 78, 2, 0, Screen::CR_NO_P_CHECK); + _screen->updateScreen(); + return -1; + } + + _screen->copyRegion(48, 127, 48, 127, 272, 60, 4, 0, Screen::CR_NO_P_CHECK); + _screen->hideMouse(); + _screen->copyRegion(48, 127, 48, 160, 272, 35, 4, 0, Screen::CR_NO_P_CHECK); + _screen->copyRegion(0, 0, 0, 0, 112, 120, 4, 0, Screen::CR_NO_P_CHECK); + + _screen->fprintStringIntro(_tim->getCTableEntry(64), 3, 28, 0x32, 0x00, 0x9C, 0x20); + _screen->fprintStringIntro(_tim->getCTableEntry(65), 3, 38, 0x32, 0x00, 0x9C, 0x20); + _screen->fprintStringIntro(_tim->getCTableEntry(66), 3, 48, 0x32, 0x00, 0x9C, 0x20); + _screen->fprintStringIntro(_tim->getCTableEntry(67), 3, 58, 0x32, 0x00, 0x9C, 0x20); + _screen->fprintStringIntro(_tim->getCTableEntry(68), 3, 68, 0x32, 0x00, 0x9C, 0x20); + + resetSkipFlag(); + kingSelectionOutro(); + return character; +} + +void LoLEngine::selectionCharInfoIntro(char *file) { + debugC(9, kDebugLevelMain, "LoLEngine::selectionCharInfoIntro(%p)", (const void *)file); + int index = 0; + file[4] = '0'; + + while (_charSelectionInfoResult == -1 && !shouldQuit()) { + if (!_sound->voicePlay(file)) + break; + + int i = 0; + while (_sound->voiceIsPlaying(file) && _charSelectionInfoResult == -1 && !shouldQuit()) { + _screen->drawShape(0, _screen->getPtrToShape(_screen->getCPagePtr(9), _charInfoFrameTable[i]), 11, 130, 0, 0); + _screen->updateScreen(); + + uint32 nextFrame = _system->getMillis() + 8 * _tickLength; + while (nextFrame > _system->getMillis() && _charSelectionInfoResult == -1) { + _charSelectionInfoResult = selectionCharAccept(); + _system->delayMillis(10); + } + + i = (i + 1) % 32; + } + + _sound->voiceStop(file); + file[4] = ++index + '0'; + } + + _screen->drawShape(0, _screen->getPtrToShape(_screen->getCPagePtr(9), 0), 11, 130, 0, 0); + _screen->updateScreen(); +} + +int LoLEngine::getCharSelection() { + int inputFlag = checkInput(0, false) & 0xCF; + removeInputTop(); + + if (inputFlag == 200) { + for (int i = 0; i < 4; ++i) { + if (_charPreviews[i].x <= _mouseX && _mouseX <= _charPreviews[i].x + 31 && + _charPreviews[i].y <= _mouseY && _mouseY <= _charPreviews[i].y + 31) + return i; + } + } + + return -1; +} + +int LoLEngine::selectionCharAccept() { + int inputFlag = checkInput(0, false) & 0xCF; + removeInputTop(); + + if (inputFlag == 200) { + if (88 <= _mouseX && _mouseX <= 128 && 180 <= _mouseY && _mouseY <= 194) + return 1; + if (196 <= _mouseX && _mouseX <= 236 && 180 <= _mouseY && _mouseY <= 194) + return 0; + } + + return -1; +} + +} // end of namespace Kyra + |