Ticket #8901: lol_intro_v1.patch

File lol_intro_v1.patch, 58.9 KB (added by lordhoto, 13 years ago)

Patch against r33333

  • kyra_v1.h

     
    6464enum {
    6565        GI_KYRA1 = 0,
    6666        GI_KYRA2 = 1,
    67         GI_KYRA3 = 2
     67        GI_KYRA3 = 2,
     68        GI_LOL = 4
    6869};
    6970
    7071struct AudioDataStruct {
  • screen_lol.cpp

     
     1/* ScummVM - Graphic Adventure Engine
     2 *
     3 * ScummVM is the legal property of its developers, whose names
     4 * are too numerous to list here. Please refer to the COPYRIGHT
     5 * file distributed with this source distribution.
     6 *
     7 * This program is free software; you can redistribute it and/or
     8 * modify it under the terms of the GNU General Public License
     9 * as published by the Free Software Foundation; either version 2
     10 * of the License, or (at your option) any later version.
     11
     12 * This program is distributed in the hope that it will be useful,
     13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
     14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
     15 * GNU General Public License for more details.
     16
     17 * You should have received a copy of the GNU General Public License
     18 * along with this program; if not, write to the Free Software
     19 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
     20 *
     21 * $URL$
     22 * $Id$
     23 *
     24 */
     25
     26#include "kyra/screen_lol.h"
     27#include "kyra/lol.h"
     28
     29namespace Kyra {
     30
     31Screen_LoL::Screen_LoL(LoLEngine *vm, OSystem *system) : Screen_v2(vm, system), _vm(vm) {
     32}
     33
     34void Screen_LoL::setScreenDim(int dim) {
     35        debugC(9, kDebugLevelScreen, "Screen_LoL::setScreenDim(%d)", dim);
     36        assert(dim < _screenDimTableCount);
     37        _curDim = &_screenDimTable[dim];
     38}
     39
     40const ScreenDim *Screen_LoL::getScreenDim(int dim) {
     41        debugC(9, kDebugLevelScreen, "Screen_LoL::getScreenDim(%d)", dim);
     42        assert(dim < _screenDimTableCount);
     43        return &_screenDimTable[dim];
     44}
     45
     46void Screen_LoL::fprintStringIntro(const char *format, int x, int y, uint8 c1, uint8 c2, uint8 c3, uint16 flags, ...) {
     47        debugC(9, kDebugLevelScreen, "Screen_LoL::fprintStringIntro('%s', %d, %d, %d, %d, %d, %d, ...)", format, x, y, c1, c2, c3, flags);
     48        char buffer[400];
     49
     50        va_list args;
     51        va_start(args, flags);
     52        vsprintf(buffer, format, args);
     53        va_end(args);
     54       
     55        if ((flags & 0x0F00) == 0x100)
     56                x -= getTextWidth(buffer) >> 1;
     57        if ((flags & 0x0F00) == 0x200)
     58                x -= getTextWidth(buffer);
     59
     60        if ((flags & 0x00F0) == 0x20) {
     61                printText(buffer, x-1, y, c3, c2);
     62                printText(buffer, x, y+1, c3, c2);
     63        }
     64
     65        printText(buffer, x, y, c1, c2);
     66}
     67
     68const ScreenDim Screen_LoL::_screenDimTable[] = {
     69        { 0x00, 0x00, 0x28, 0xC8, 0xC7, 0xCF, 0x00, 0x00 }
     70};
     71
     72const int Screen_LoL::_screenDimTableCount = ARRAYSIZE(Screen_LoL::_screenDimTable);
     73
     74} // end of namespace Kyra
     75
  • lol.cpp

    Property changes on: screen_lol.cpp
    ___________________________________________________________________
    Added: svn:mime-type
       + text/plain
    Added: svn:keywords
       + Date Rev Author URL Id
    Added: svn:eol-style
       + native
    
     
     1/* ScummVM - Graphic Adventure Engine
     2 *
     3 * ScummVM is the legal property of its developers, whose names
     4 * are too numerous to list here. Please refer to the COPYRIGHT
     5 * file distributed with this source distribution.
     6 *
     7 * This program is free software; you can redistribute it and/or
     8 * modify it under the terms of the GNU General Public License
     9 * as published by the Free Software Foundation; either version 2
     10 * of the License, or (at your option) any later version.
     11
     12 * This program is distributed in the hope that it will be useful,
     13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
     14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
     15 * GNU General Public License for more details.
     16
     17 * You should have received a copy of the GNU General Public License
     18 * along with this program; if not, write to the Free Software
     19 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
     20 *
     21 * $URL$
     22 * $Id$
     23 *
     24 */
     25
     26#include "kyra/lol.h"
     27#include "kyra/screen_lol.h"
     28#include "kyra/resource.h"
     29#include "kyra/sound.h"
     30
     31#include "common/endian.h"
     32
     33namespace Kyra {
     34
     35LoLEngine::LoLEngine(OSystem *system, const GameFlags &flags) : KyraEngine_v1(system, flags) {
     36        _screen = 0;
     37       
     38        switch (_flags.lang) {
     39        case Common::EN_ANY:
     40        case Common::EN_USA:
     41        case Common::EN_GRB:
     42                _lang = 0;
     43                break;
     44
     45        case Common::FR_FRA:
     46                _lang = 1;
     47                break;
     48
     49        case Common::DE_DEU:
     50                _lang = 2;
     51                break;
     52
     53        default:
     54                warning("unsupported language, switching back to English");
     55                _lang = 0;
     56                break;
     57        }
     58       
     59        _chargenWSA = 0;
     60}
     61
     62LoLEngine::~LoLEngine() {
     63        setupPrologueData(false);
     64
     65        delete _screen;
     66        delete _tim;
     67       
     68        for (Common::Array<const TIMOpcode*>::iterator i = _timIntroOpcodes.begin(); i != _timIntroOpcodes.end(); ++i)
     69                delete *i;
     70        _timIntroOpcodes.clear();
     71}
     72
     73Screen *LoLEngine::screen() {
     74        return _screen;
     75}
     76
     77int LoLEngine::init() {
     78        _screen = new Screen_LoL(this, _system);
     79        assert(_screen);
     80        _screen->setResolution();
     81
     82        KyraEngine_v1::init();
     83       
     84        _tim = new TIMInterpreter(this, _screen, _system);
     85        assert(_tim);
     86       
     87        _screen->setAnimBlockPtr(10000);
     88        _screen->setScreenDim(0);
     89
     90        return 0;
     91}
     92
     93int LoLEngine::go() {
     94        setupPrologueData(true);
     95        showIntro();
     96        _sound->playTrack(6);
     97        /*int character = */chooseCharacter();
     98        _sound->playTrack(1);
     99        _screen->fadeToBlack();
     100        setupPrologueData(false);
     101
     102        return 0;
     103}
     104
     105#pragma mark - Input
     106
     107int LoLEngine::checkInput(Button *buttonList, bool mainLoop) {
     108        debugC(9, kDebugLevelMain, "LoLEngine::checkInput(%p, %d)", (const void*)buttonList, mainLoop);
     109        updateInput();
     110
     111        int keys = 0;
     112        int8 mouseWheel = 0;
     113
     114        while (_eventList.size()) {
     115                Common::Event event = *_eventList.begin();
     116                bool breakLoop = false;
     117
     118                switch (event.type) {
     119                case Common::EVENT_KEYDOWN:
     120                        /*if (event.kbd.keycode >= '1' && event.kbd.keycode <= '9' &&
     121                                        (event.kbd.flags == Common::KBD_CTRL || event.kbd.flags == Common::KBD_ALT) && mainLoop) {
     122                                const char *saveLoadSlot = getSavegameFilename(9 - (event.kbd.keycode - '0') + 990);
     123
     124                                if (event.kbd.flags == Common::KBD_CTRL) {
     125                                        loadGame(saveLoadSlot);
     126                                        _eventList.clear();
     127                                        breakLoop = true;
     128                                } else {
     129                                        char savegameName[14];
     130                                        sprintf(savegameName, "Quicksave %d", event.kbd.keycode - '0');
     131                                        saveGame(saveLoadSlot, savegameName);
     132                                }
     133                        } else if (event.kbd.flags == Common::KBD_CTRL) {
     134                                if (event.kbd.keycode == 'd')
     135                                        _debugger->attach();
     136                        }*/
     137                        break;
     138
     139                case Common::EVENT_MOUSEMOVE: {
     140                        Common::Point pos = getMousePos();
     141                        _mouseX = pos.x;
     142                        _mouseY = pos.y;
     143                        } break;
     144
     145                case Common::EVENT_LBUTTONDOWN:
     146                case Common::EVENT_LBUTTONUP: {
     147                        Common::Point pos = getMousePos();
     148                        _mouseX = pos.x;
     149                        _mouseY = pos.y;
     150                        keys = (event.type == Common::EVENT_LBUTTONDOWN ? 199 : (200 | 0x800));
     151                        breakLoop = true;
     152                        } break;
     153
     154                case Common::EVENT_WHEELUP:
     155                        mouseWheel = -1;
     156                        break;
     157
     158                case Common::EVENT_WHEELDOWN:
     159                        mouseWheel = 1;
     160                        break;
     161
     162                default:
     163                        break;
     164                }
     165
     166                //if (_debugger->isAttached())
     167                //      _debugger->onFrame();
     168
     169                if (breakLoop)
     170                        break;
     171
     172                _eventList.erase(_eventList.begin());
     173        }
     174
     175        return /*gui_v2()->processButtonList(buttonList, keys | 0x8000, mouseWheel)*/keys;
     176}
     177
     178void LoLEngine::updateInput() {
     179        Common::Event event;
     180
     181        while (_eventMan->pollEvent(event)) {
     182                switch (event.type) {
     183                case Common::EVENT_QUIT:
     184                        _quitFlag = true;
     185                        break;
     186
     187                case Common::EVENT_KEYDOWN:
     188                        if (event.kbd.keycode == '.' || event.kbd.keycode == Common::KEYCODE_ESCAPE)
     189                                _eventList.push_back(Event(event, true));
     190                        else if (event.kbd.keycode == 'q' && event.kbd.flags == Common::KBD_CTRL)
     191                                _quitFlag = true;
     192                        else
     193                                _eventList.push_back(event);
     194                        break;
     195
     196                case Common::EVENT_LBUTTONDOWN:
     197                        _eventList.push_back(Event(event, true));
     198                        break;
     199
     200                case Common::EVENT_MOUSEMOVE:
     201                        _screen->updateScreen();
     202                        // fall through
     203
     204                case Common::EVENT_LBUTTONUP:
     205                case Common::EVENT_WHEELUP:
     206                case Common::EVENT_WHEELDOWN:
     207                        _eventList.push_back(event);
     208                        break;
     209
     210                default:
     211                        break;
     212                }
     213        }
     214}
     215
     216void LoLEngine::removeInputTop() {
     217        if (!_eventList.empty())
     218                _eventList.erase(_eventList.begin());
     219}
     220
     221bool LoLEngine::skipFlag() const {
     222        for (Common::List<Event>::const_iterator i = _eventList.begin(); i != _eventList.end(); ++i) {
     223                if (i->causedSkip)
     224                        return true;
     225        }
     226        return false;
     227}
     228
     229void LoLEngine::resetSkipFlag(bool removeEvent) {
     230        for (Common::List<Event>::iterator i = _eventList.begin(); i != _eventList.end(); ++i) {
     231                if (i->causedSkip) {
     232                        if (removeEvent)
     233                                _eventList.erase(i);
     234                        else
     235                                i->causedSkip = false;
     236                        return;
     237                }
     238        }
     239}
     240
     241#pragma mark - Intro
     242
     243void LoLEngine::setupPrologueData(bool load) {
     244        static const char * const fileList[] = {
     245                "xxx/general.pak",
     246                "xxx/introvoc.pak",
     247                "xxx/startup.pak",
     248                "xxx/intro1.pak",
     249                "xxx/intro2.pak",
     250                "xxx/intro3.pak",
     251                "xxx/intro4.pak",
     252                "xxx/intro5.pak",
     253                "xxx/intro6.pak",
     254                "xxx/intro7.pak",
     255                "xxx/intro8.pak",
     256                "xxx/intro9.pak"
     257        };
     258
     259        char filename[32];
     260        for (uint i = 0; i < ARRAYSIZE(fileList); ++i) {
     261                strcpy(filename, fileList[i]);
     262                memcpy(filename, _languageExt[_lang], 3);
     263
     264                if (load) {
     265                        if (!_res->loadPakFile(filename))
     266                                error("Couldn't load file: '%s'", filename);
     267                } else {
     268                        _res->unloadPakFile(filename);
     269                }
     270        }
     271       
     272        if (load) {
     273                _chargenWSA = new WSAMovie_v2(this, _screen);
     274                assert(_chargenWSA);
     275
     276                _charSelection = -1;
     277                _charSelectionInfoResult = -1;
     278
     279                _selectionAnimFrames[0] = _selectionAnimFrames[2] = 0;
     280                _selectionAnimFrames[1] = _selectionAnimFrames[3] = 1;
     281
     282                memset(_selectionAnimTimers, 0, sizeof(_selectionAnimTimers));
     283                memset(_screen->getPalette(1), 0, 768);
     284        } else {
     285                delete _chargenWSA; _chargenWSA = 0;
     286        }
     287}
     288
     289void LoLEngine::showIntro() {
     290        debugC(9, kDebugLevelMain, "LoLEngine::showIntro()");
     291
     292        TIM *intro = _tim->load("LOLINTRO.TIM", &_timIntroOpcodes);
     293
     294        _screen->loadFont(Screen::FID_8_FNT, "NEW8P.FNT");
     295        _screen->loadFont(Screen::FID_INTRO_FNT, "INTRO.FNT");
     296        _screen->setFont(Screen::FID_8_FNT);
     297
     298        _tim->resetFinishedFlag();
     299        _tim->setLangData("LOLINTRO.DIP");
     300
     301        _screen->hideMouse();
     302
     303        uint32 palNextFadeStep = 0;
     304        while (!_tim->finished() && !_quitFlag && !skipFlag()) {
     305                updateInput();
     306                _tim->exec(intro, false);
     307                _screen->checkedPageUpdate(8, 4);
     308
     309                if (_tim->_palDiff) {
     310                        if (palNextFadeStep < _system->getMillis()) {
     311                                _tim->_palDelayAcc += _tim->_palDelayInc;
     312                                palNextFadeStep = _system->getMillis() + ((_tim->_palDelayAcc >> 8) * _tickLength);
     313                                _tim->_palDelayAcc &= 0xFF;
     314
     315                                if (!_screen->fadePalStep(_screen->getPalette(0), _tim->_palDiff)) {
     316                                        _screen->setScreenPalette(_screen->getPalette(0));
     317                                        _tim->_palDiff = 0;
     318                                }
     319                        }
     320                }
     321
     322                _system->delayMillis(10);
     323                _screen->updateScreen();
     324        }
     325        _screen->showMouse();
     326        _sound->voiceStop();
     327       
     328        // HACK: Remove all input events
     329        _eventList.clear();
     330       
     331        _tim->unload(intro);
     332        _tim->clearLangData();
     333       
     334        _screen->fadePalette(_screen->getPalette(1), 30, 0);
     335}
     336
     337int LoLEngine::chooseCharacter() {
     338        debugC(9, kDebugLevelMain, "LoLEngine::chooseCharacter()");
     339
     340        _tim->setLangData("LOLINTRO.DIP");
     341       
     342        _screen->loadFont(Screen::FID_9_FNT, "FONT9P.FNT");
     343
     344        _screen->loadBitmap("ITEMICN.SHP", 3, 3, 0);
     345        _screen->setMouseCursor(0, 0, _screen->getPtrToShape(_screen->getCPagePtr(3), 0));
     346
     347        while (!_screen->isMouseVisible())
     348                _screen->showMouse();
     349
     350        _screen->loadBitmap("CHAR.CPS", 2, 2, _screen->getPalette(0));
     351        _screen->loadBitmap("BACKGRND.CPS", 4, 4, _screen->getPalette(0));
     352       
     353        if (!_chargenWSA->open("CHARGEN.WSA", 1, 0))
     354                error("Couldn't load CHARGEN.WSA");
     355        _chargenWSA->setX(113);
     356        _chargenWSA->setY(0);
     357        _chargenWSA->setDrawPage(2);
     358        _chargenWSA->displayFrame(0, 0, 0, 0);
     359
     360        _screen->setFont(Screen::FID_9_FNT);
     361        _screen->_curPage = 2;
     362       
     363        for (int i = 0; i < 4; ++i)
     364                _screen->fprintStringIntro(_charPreviews[i].name, _charPreviews[i].x + 16, _charPreviews[i].y + 36, 0xC0, 0x00, 0x9C, 0x120);
     365
     366        for (int i = 0; i < 4; ++i) {
     367                _screen->fprintStringIntro("%d", _charPreviews[i].x + 21, _charPreviews[i].y + 48, 0x98, 0x00, 0x9C, 0x220, _charPreviews[i].attrib[0]);
     368                _screen->fprintStringIntro("%d", _charPreviews[i].x + 21, _charPreviews[i].y + 56, 0x98, 0x00, 0x9C, 0x220, _charPreviews[i].attrib[1]);
     369                _screen->fprintStringIntro("%d", _charPreviews[i].x + 21, _charPreviews[i].y + 64, 0x98, 0x00, 0x9C, 0x220, _charPreviews[i].attrib[2]);
     370        }
     371       
     372        _screen->fprintStringIntro(_tim->getCTableEntry(51), 36, 173, 0x98, 0x00, 0x9C, 0x20);
     373        _screen->fprintStringIntro(_tim->getCTableEntry(53), 36, 181, 0x98, 0x00, 0x9C, 0x20);
     374        _screen->fprintStringIntro(_tim->getCTableEntry(55), 36, 189, 0x98, 0x00, 0x9C, 0x20);
     375       
     376        _screen->copyRegion(0, 0, 0, 0, 320, 200, 2, 0, Screen::CR_NO_P_CHECK);
     377        _screen->_curPage = 0;
     378       
     379        _screen->fadePalette(_screen->getPalette(0), 30, 0);
     380       
     381        bool kingIntro = true;
     382        while (!_quitFlag) {
     383                if (kingIntro)
     384                        kingSelectionIntro();
     385
     386                if (_charSelection < 0)
     387                        processCharacterSelection();
     388
     389                if (_quitFlag)
     390                        break;
     391
     392                if (_charSelection == 100) {
     393                        kingIntro = true;
     394                        _charSelection = -1;
     395                        continue;
     396                }
     397
     398                _screen->copyRegion(0, 0, 0, 0, 112, 120, 4, 0, Screen::CR_NO_P_CHECK);
     399                _screen->updateScreen();
     400                _screen->showMouse();
     401
     402                if (selectionCharInfo(_charSelection) == -1) {
     403                        _charSelection = -1;
     404                        kingIntro = false;
     405                } else {
     406                        break;
     407                }
     408        }
     409
     410        if (_quitFlag)
     411                return -1;
     412
     413        uint32 waitTime = _system->getMillis() + 420 * _tickLength;
     414        while (waitTime > _system->getMillis() && !skipFlag() && !_quitFlag) {
     415                updateInput();
     416                _system->delayMillis(10);
     417        }
     418
     419        // HACK: Remove all input events
     420        _eventList.clear();
     421
     422        _tim->clearLangData();
     423
     424        return _charSelection;
     425}
     426
     427void LoLEngine::kingSelectionIntro() {
     428        debugC(9, kDebugLevelMain, "LoLEngine::kingSelectionIntro()");
     429       
     430        _screen->copyRegion(0, 0, 0, 0, 112, 120, 4, 0, Screen::CR_NO_P_CHECK);
     431        int y = 38;
     432       
     433        _screen->fprintStringIntro(_tim->getCTableEntry(57), 8, y, 0x32, 0x00, 0x9C, 0x20);
     434        _screen->fprintStringIntro(_tim->getCTableEntry(58), 8, y + 10, 0x32, 0x00, 0x9C, 0x20);
     435        _screen->fprintStringIntro(_tim->getCTableEntry(59), 8, y + 20, 0x32, 0x00, 0x9C, 0x20);
     436        _screen->fprintStringIntro(_tim->getCTableEntry(60), 8, y + 30, 0x32, 0x00, 0x9C, 0x20);
     437        _screen->fprintStringIntro(_tim->getCTableEntry(61), 8, y + 40, 0x32, 0x00, 0x9C, 0x20);
     438
     439        _sound->voicePlay("KING01");
     440       
     441        _chargenWSA->setX(113);
     442        _chargenWSA->setY(0);
     443        _chargenWSA->setDrawPage(0);
     444       
     445        int index = 4;
     446        while (_sound->voiceIsPlaying("KING01") && _charSelection == -1 && !_quitFlag && !skipFlag()) {
     447                index = MAX(index, 4);
     448
     449                _chargenWSA->displayFrame(_chargenFrameTable[index], 0, 0, 0);
     450                _screen->copyRegion(_selectionPosTable[_selectionChar1IdxTable[index]*2+0], _selectionPosTable[_selectionChar1IdxTable[index]*2+1], _charPreviews[0].x, _charPreviews[0].y, 32, 32, 4, 0);
     451                _screen->copyRegion(_selectionPosTable[_selectionChar2IdxTable[index]*2+0], _selectionPosTable[_selectionChar2IdxTable[index]*2+1], _charPreviews[1].x, _charPreviews[1].y, 32, 32, 4, 0);
     452                _screen->copyRegion(_selectionPosTable[_selectionChar3IdxTable[index]*2+0], _selectionPosTable[_selectionChar3IdxTable[index]*2+1], _charPreviews[2].x, _charPreviews[2].y, 32, 32, 4, 0);
     453                _screen->copyRegion(_selectionPosTable[_selectionChar4IdxTable[index]*2+0], _selectionPosTable[_selectionChar4IdxTable[index]*2+1], _charPreviews[3].x, _charPreviews[3].y, 32, 32, 4, 0);
     454                _screen->updateScreen();
     455
     456                uint32 waitEnd = _system->getMillis() + 7 * _tickLength;
     457                while (waitEnd > _system->getMillis() && _charSelection == -1 && !_quitFlag && !skipFlag()) {
     458                        _charSelection = getCharSelection();
     459                        _system->delayMillis(10);
     460                }
     461
     462                index = (index + 1) % 22;
     463        }
     464       
     465        resetSkipFlag();
     466       
     467        _chargenWSA->displayFrame(0x10, 0, 0, 0);
     468        _screen->updateScreen();
     469        _sound->voiceStop("KING01");
     470}
     471
     472void LoLEngine::kingSelectionReminder() {
     473        debugC(9, kDebugLevelMain, "LoLEngine::kingSelectionReminder()");
     474       
     475        _screen->copyRegion(0, 0, 0, 0, 112, 120, 4, 0, Screen::CR_NO_P_CHECK);
     476        int y = 48;
     477       
     478        _screen->fprintStringIntro(_tim->getCTableEntry(62), 8, y, 0x32, 0x00, 0x9C, 0x20);
     479        _screen->fprintStringIntro(_tim->getCTableEntry(63), 8, y + 10, 0x32, 0x00, 0x9C, 0x20);
     480       
     481        _sound->voicePlay("KING02");
     482       
     483        _chargenWSA->setX(113);
     484        _chargenWSA->setY(0);
     485        _chargenWSA->setDrawPage(0);
     486       
     487        int index = 0;
     488        while (_sound->voiceIsPlaying("KING02") && _charSelection == -1 && !_quitFlag && index < 15) {
     489                _chargenWSA->displayFrame(_chargenFrameTable[index+9], 0, 0, 0);
     490                _screen->copyRegion(_selectionPosTable[_reminderChar1IdxTable[index]*2+0], _selectionPosTable[_reminderChar1IdxTable[index]*2+1], _charPreviews[0].x, _charPreviews[0].y, 32, 32, 4, 0);
     491                _screen->copyRegion(_selectionPosTable[_reminderChar2IdxTable[index]*2+0], _selectionPosTable[_reminderChar2IdxTable[index]*2+1], _charPreviews[1].x, _charPreviews[1].y, 32, 32, 4, 0);
     492                _screen->copyRegion(_selectionPosTable[_reminderChar3IdxTable[index]*2+0], _selectionPosTable[_reminderChar3IdxTable[index]*2+1], _charPreviews[2].x, _charPreviews[2].y, 32, 32, 4, 0);
     493                _screen->copyRegion(_selectionPosTable[_reminderChar4IdxTable[index]*2+0], _selectionPosTable[_reminderChar4IdxTable[index]*2+1], _charPreviews[3].x, _charPreviews[3].y, 32, 32, 4, 0);
     494                _screen->updateScreen();
     495
     496                uint32 waitEnd = _system->getMillis() + 8 * _tickLength;
     497                while (waitEnd > _system->getMillis() && !_quitFlag) {
     498                        _charSelection = getCharSelection();
     499                        _system->delayMillis(10);
     500                }
     501
     502                index = (index + 1) % 22;
     503        }
     504
     505        _sound->voiceStop("KING02");
     506}
     507
     508void LoLEngine::kingSelectionOutro() {
     509        debugC(9, kDebugLevelMain, "LoLEngine::kingSelectionOutro()");
     510
     511        _sound->voicePlay("KING03");
     512
     513        _chargenWSA->setX(113);
     514        _chargenWSA->setY(0);
     515        _chargenWSA->setDrawPage(0);
     516
     517        int index = 0;
     518        while (_sound->voiceIsPlaying("KING03") && !_quitFlag && !skipFlag()) {
     519                index = MAX(index, 4);
     520
     521                _chargenWSA->displayFrame(_chargenFrameTable[index], 0, 0, 0);
     522                _screen->updateScreen();
     523
     524                uint32 waitEnd = _system->getMillis() + 8 * _tickLength;
     525                while (waitEnd > _system->getMillis() && !_quitFlag && !skipFlag()) {
     526                        updateInput();
     527                        _system->delayMillis(10);
     528                }
     529
     530                index = (index + 1) % 22;
     531        }
     532
     533        resetSkipFlag();
     534
     535        _chargenWSA->displayFrame(0x10, 0, 0, 0);
     536        _screen->updateScreen();
     537        _sound->voiceStop("KING03");
     538}
     539
     540void LoLEngine::processCharacterSelection() {
     541        debugC(9, kDebugLevelMain, "LoLEngine::processCharacterSelection()");
     542       
     543        _charSelection = -1;
     544        while (!_quitFlag && _charSelection == -1) {
     545                uint32 nextKingMessage = _system->getMillis() + 900 * _tickLength;
     546
     547                while (nextKingMessage > _system->getMillis() && _charSelection == -1 && !_quitFlag) {
     548                        updateSelectionAnims();
     549                        _charSelection = getCharSelection();
     550                        _system->delayMillis(10);
     551                }
     552
     553                if (_charSelection == -1)
     554                        kingSelectionReminder();
     555        }
     556}
     557
     558void LoLEngine::updateSelectionAnims() {
     559        debugC(9, kDebugLevelMain, "LoLEngine::updateSelectionAnims()");
     560
     561        for (int i = 0; i < 4; ++i) {
     562                if (_system->getMillis() < _selectionAnimTimers[i])
     563                        continue;
     564
     565                const int index = _selectionAnimIndexTable[_selectionAnimFrames[i] + i * 2];
     566                _screen->copyRegion(_selectionPosTable[index*2+0], _selectionPosTable[index*2+1], _charPreviews[i].x, _charPreviews[i].y, 32, 32, 4, 0);
     567
     568                int delayTime = 0;
     569                if (_selectionAnimFrames[i] == 1)
     570                        delayTime = _rnd.getRandomNumberRng(0, 31) + 80;
     571                else
     572                        delayTime = _rnd.getRandomNumberRng(0, 3) + 10;
     573
     574                _selectionAnimTimers[i] = _system->getMillis() + delayTime * _tickLength;
     575                _selectionAnimFrames[i] = (_selectionAnimFrames[i] + 1) % 2;
     576        }
     577
     578        _screen->updateScreen();
     579}
     580
     581int LoLEngine::selectionCharInfo(int character) {
     582        debugC(9, kDebugLevelMain, "LoLEngine::selectionCharInfo(%d)", character);
     583        if (character < 0)
     584                return -1;
     585
     586        char filename[16];
     587        char vocFilename[6];
     588        strcpy(vocFilename, "000X0");
     589
     590        switch (character) {
     591        case 0:
     592                strcpy(filename, "face09.shp");
     593                vocFilename[3] = 'A';
     594                break;
     595       
     596        case 1:
     597                strcpy(filename, "face01.shp");
     598                vocFilename[3] = 'M';
     599                break;
     600       
     601        case 2:
     602                strcpy(filename, "face08.shp");
     603                vocFilename[3] = 'K';
     604                break;
     605       
     606        case 3:
     607                strcpy(filename, "face05.shp");
     608                vocFilename[3] = 'C';
     609                break;
     610       
     611        default:
     612                break;
     613        };
     614
     615        _screen->loadBitmap(filename, 9, 9, 0);
     616        _screen->copyRegion(0, 122, 0, 122, 320, 78, 4, 0, Screen::CR_NO_P_CHECK);
     617        _screen->copyRegion(_charPreviews[character].x - 3, _charPreviews[character].y - 3, 8, 127, 38, 38, 2, 0);
     618
     619        static const uint8 charSelectInfoIdx[] = { 0x1D, 0x22, 0x27, 0x2C };
     620        const int idx = charSelectInfoIdx[character];
     621
     622        _screen->fprintStringIntro(_tim->getCTableEntry(idx+0), 50, 127, 0x53, 0x00, 0xCF, 0x20);
     623        _screen->fprintStringIntro(_tim->getCTableEntry(idx+1), 50, 137, 0x53, 0x00, 0xCF, 0x20);
     624        _screen->fprintStringIntro(_tim->getCTableEntry(idx+2), 50, 147, 0x53, 0x00, 0xCF, 0x20);
     625        _screen->fprintStringIntro(_tim->getCTableEntry(idx+3), 50, 157, 0x53, 0x00, 0xCF, 0x20);
     626        _screen->fprintStringIntro(_tim->getCTableEntry(idx+4), 50, 167, 0x53, 0x00, 0xCF, 0x20);
     627       
     628        _screen->fprintStringIntro(_tim->getCTableEntry(69), 100, 168, 0x32, 0x00, 0xCF, 0x20);
     629       
     630        selectionCharInfoIntro(vocFilename);
     631        if (_charSelectionInfoResult == -1) {
     632                while (_charSelectionInfoResult == -1) {
     633                        _charSelectionInfoResult = selectionCharAccept();
     634                        _system->delayMillis(10);
     635                }
     636        }
     637       
     638        if (_charSelectionInfoResult != 1) {
     639                _charSelectionInfoResult = -1;
     640                _screen->copyRegion(0, 122, 0, 122, 320, 78, 2, 0, Screen::CR_NO_P_CHECK);
     641                _screen->updateScreen();
     642                return -1;
     643        }
     644
     645        _screen->copyRegion(48, 127, 48, 127, 272, 60, 4, 0, Screen::CR_NO_P_CHECK);
     646        _screen->hideMouse();
     647        _screen->copyRegion(48, 127, 48, 160, 272, 35, 4, 0, Screen::CR_NO_P_CHECK);
     648        _screen->copyRegion(0, 0, 0, 0, 112, 120, 4, 0, Screen::CR_NO_P_CHECK);
     649
     650        _screen->fprintStringIntro(_tim->getCTableEntry(64), 3, 28, 0x32, 0x00, 0x9C, 0x20);
     651        _screen->fprintStringIntro(_tim->getCTableEntry(65), 3, 38, 0x32, 0x00, 0x9C, 0x20);
     652        _screen->fprintStringIntro(_tim->getCTableEntry(66), 3, 48, 0x32, 0x00, 0x9C, 0x20);
     653        _screen->fprintStringIntro(_tim->getCTableEntry(67), 3, 58, 0x32, 0x00, 0x9C, 0x20);
     654        _screen->fprintStringIntro(_tim->getCTableEntry(68), 3, 68, 0x32, 0x00, 0x9C, 0x20);
     655
     656        resetSkipFlag();
     657        kingSelectionOutro();   
     658        return character;
     659}
     660
     661void LoLEngine::selectionCharInfoIntro(char *file) {
     662        debugC(9, kDebugLevelMain, "LoLEngine::selectionCharInfoIntro(%p)", (const void *)file);
     663        int index = 0;
     664        file[4] = '0';
     665       
     666        while (_charSelectionInfoResult == -1 && !_quitFlag) {
     667                if (!_sound->voicePlay(file))
     668                        break;
     669
     670                int i = 0;
     671                while (_sound->voiceIsPlaying(file) && _charSelectionInfoResult == -1 && !_quitFlag) {
     672                        _screen->drawShape(0, _screen->getPtrToShape(_screen->getCPagePtr(9), _charInfoFrameTable[i]), 11, 130, 0, 0);
     673                        _screen->updateScreen();
     674
     675                        uint32 nextFrame = _system->getMillis() + 8 * _tickLength;
     676                        while (nextFrame > _system->getMillis() && _charSelectionInfoResult == -1) {
     677                                _charSelectionInfoResult = selectionCharAccept();
     678                                _system->delayMillis(10);
     679                        }
     680
     681                        i = (i + 1) % 32;
     682                }
     683
     684                _sound->voiceStop(file);
     685                file[4] = ++index + '0';
     686        }
     687
     688        _screen->drawShape(0, _screen->getPtrToShape(_screen->getCPagePtr(9), 0), 11, 130, 0, 0);
     689        _screen->updateScreen();
     690}
     691
     692int LoLEngine::getCharSelection() {
     693        int inputFlag = checkInput() & 0xCF;
     694        removeInputTop();
     695
     696        if (inputFlag == 200) {
     697                for (int i = 0; i < 4; ++i) {
     698                        if (_charPreviews[i].x <= _mouseX && _mouseX <= _charPreviews[i].x + 31 &&
     699                                _charPreviews[i].y <= _mouseY && _mouseY <= _charPreviews[i].y + 31)
     700                                return i;
     701                }
     702        }
     703       
     704        return -1;
     705}
     706
     707int LoLEngine::selectionCharAccept() {
     708        int inputFlag = checkInput() & 0xCF;
     709        removeInputTop();
     710       
     711        if (inputFlag == 200) {
     712                if (88 <= _mouseX && _mouseX <= 128 && 180 <= _mouseY && _mouseY <= 194)
     713                        return 1;
     714                if (196 <= _mouseX && _mouseX <= 236 && 180 <= _mouseY && _mouseY <= 194)
     715                        return 0;
     716        }
     717       
     718        return -1;
     719}
     720
     721#pragma mark - Opcodes
     722
     723typedef Common::Functor2Mem<const TIM *, const uint16 *, int, LoLEngine> TIMOpcodeLoL;
     724#define SetTimOpcodeTable(x) timTable = &x;
     725#define OpcodeTim(x) timTable->push_back(new TIMOpcodeLoL(this, &LoLEngine::x))
     726#define OpcodeTimUnImpl() timTable->push_back(new TIMOpcodeLoL(this, 0))
     727
     728void LoLEngine::setupOpcodeTable() {
     729        Common::Array<const TIMOpcode*> *timTable = 0;
     730
     731        SetTimOpcodeTable(_timIntroOpcodes);
     732       
     733        // 0x00
     734        OpcodeTim(tlol_setupPaletteFade);
     735        OpcodeTimUnImpl();
     736        OpcodeTim(tlol_loadPalette);
     737        OpcodeTim(tlol_setupPaletteFadeEx);
     738       
     739        // 0x04
     740        OpcodeTim(tlol_processWsaFrame);
     741        OpcodeTim(tlol_displayText);
     742        OpcodeTimUnImpl();
     743        OpcodeTimUnImpl();
     744}
     745
     746#pragma mark -
     747
     748int LoLEngine::tlol_setupPaletteFade(const TIM *tim, const uint16 *param) {
     749        debugC(3, kDebugLevelScriptFuncs, "LoLEngine::t2_playSoundEffect(%p, %p) (%d)", (const void*)tim, (const void*)param, param[0]);
     750        _screen->getFadeParams(_screen->getPalette(0), param[0], _tim->_palDelayInc, _tim->_palDiff);
     751        _tim->_palDelayAcc = 0;
     752        return 1;
     753}
     754
     755int LoLEngine::tlol_loadPalette(const TIM *tim, const uint16 *param) {
     756        debugC(3, kDebugLevelScriptFuncs, "LoLEngine::tlol_loadPalette(%p, %p) (%d)", (const void*)tim, (const void*)param, param[0]);
     757        const char *palFile = (const char *)(tim->text + READ_LE_UINT16(tim->text + (param[0]<<1)));
     758        _res->loadFileToBuf(palFile, _screen->getPalette(0), 768);
     759        return 1;
     760}
     761
     762int LoLEngine::tlol_setupPaletteFadeEx(const TIM *tim, const uint16 *param) {
     763        debugC(3, kDebugLevelScriptFuncs, "LoLEngine::tlol_setupPaletteFadeEx(%p, %p) (%d)", (const void*)tim, (const void*)param, param[0]);
     764        memcpy(_screen->getPalette(0), _screen->getPalette(1), 768);
     765
     766        _screen->getFadeParams(_screen->getPalette(0), param[0], _tim->_palDelayInc, _tim->_palDiff);
     767        _tim->_palDelayAcc = 0;
     768        return 1;
     769}
     770
     771int LoLEngine::tlol_processWsaFrame(const TIM *tim, const uint16 *param) {
     772        debugC(3, kDebugLevelScriptFuncs, "LoLEngine::tlol_processWsaFrame(%p, %p) (%d, %d, %d, %d, %d)",
     773                (const void*)tim, (const void*)param, param[0], param[1], param[2], param[3], param[4]);
     774        TIMInterpreter::Animation *anim = (TIMInterpreter::Animation *)tim->wsa[param[0]].anim;
     775        const int frame = param[1];
     776        const int x2 = param[2];
     777        const int y2 = param[3];
     778        const int factor = MAX<int>(0, (int16)param[4]);
     779       
     780        const int x1 = anim->x;
     781        const int y1 = anim->y;
     782       
     783        int w1 = anim->wsa->width();
     784        int h1 = anim->wsa->height();
     785        int w2 = (w1 * factor) / 100;
     786        int h2 = (h1 * factor) / 100;
     787       
     788        anim->wsa->setDrawPage(2);
     789        anim->wsa->setX(x1);
     790        anim->wsa->setY(y1);
     791        anim->wsa->displayFrame(frame, anim->wsaCopyParams & 0xF0FF, 0, 0);
     792        _screen->wsaFrameAnimationStep(x1, y1, x2, y2, w1, h1, w2, h2, 2, 8, 0);
     793        _screen->checkedPageUpdate(8, 4);
     794        _screen->updateScreen();
     795
     796        return 1;
     797}
     798
     799int LoLEngine::tlol_displayText(const TIM *tim, const uint16 *param) {
     800        debugC(3, kDebugLevelScriptFuncs, "LoLEngine::tlol_displayText(%p, %p) (%d, %d)", (const void*)tim, (const void*)param, param[0], (int16)param[1]);
     801        _tim->displayText(param[0], param[1]);
     802        return 1;
     803}
     804
     805#pragma mark - Static Resource
     806
     807const char * const LoLEngine::_languageExt[] = {
     808        "ENG",
     809        "FRE",
     810        "GER"
     811};
     812
     813const LoLEngine::CharacterPrev LoLEngine::_charPreviews[] = {
     814        { "Ak\'shel", 0x060, 0x7F, { 0x0F, 0x08, 0x05 } },
     815        {  "Michael", 0x09A, 0x7F, { 0x06, 0x0A, 0x0F } },
     816        {   "Kieran", 0x0D4, 0x7F, { 0x08, 0x06, 0x08 } },
     817        {   "Conrad", 0x10F, 0x7F, { 0x0A, 0x0C, 0x0A } }
     818};
     819
     820const uint8 LoLEngine::_chargenFrameTable[] = {
     821        0x00, 0x01, 0x02, 0x03, 0x04,
     822        0x05, 0x04, 0x03, 0x02, 0x01,
     823        0x00, 0x00, 0x01, 0x02, 0x03,
     824        0x04, 0x05, 0x06, 0x07, 0x08,
     825        0x09, 0x0A, 0x0B, 0x0C, 0x0D,
     826        0x0E, 0x0F, 0x10, 0x11, 0x12
     827};
     828
     829const uint16 LoLEngine::_selectionPosTable[] = {
     830        0x6F, 0x00, 0x8F, 0x00, 0xAF, 0x00,  0xCF, 0x00,
     831        0xEF, 0x00, 0x6F, 0x20, 0x8F, 0x20,  0xAF, 0x20,
     832        0xCF, 0x20, 0xEF, 0x20, 0x6F, 0x40,  0x8F, 0x40,
     833        0xAF, 0x40, 0xCF, 0x40, 0xEF, 0x40, 0x10F, 0x00
     834};
     835
     836const uint8 LoLEngine::_selectionChar1IdxTable[] = {
     837        0, 0, 5, 5, 5, 5, 5, 5,
     838        5, 5, 5, 0, 0, 5, 5, 5,
     839        5, 5, 5, 5, 0, 0, 5, 5,
     840        5, 5, 5
     841};
     842
     843const uint8 LoLEngine::_selectionChar2IdxTable[] = {
     844        1, 1, 6, 6, 1, 1, 6, 6,
     845        6, 6, 6, 6, 6, 1, 1, 6,
     846        6, 6, 1, 1, 6, 6, 6, 6,
     847        6, 6, 6
     848};
     849
     850const uint8 LoLEngine::_selectionChar3IdxTable[] = {
     851        2, 2, 7, 7, 7, 7, 2, 2,
     852        7, 7, 7, 7, 7, 7, 7, 2,
     853        2, 7, 7, 7, 7, 2, 2, 7,
     854        7, 7, 7
     855};
     856
     857const uint8 LoLEngine::_selectionChar4IdxTable[] = {
     858        3, 3, 8, 8, 8, 8, 3, 3,
     859        8, 8, 3, 3, 8, 8, 8, 8,
     860        8, 8, 8, 8, 8, 3, 3, 8,
     861        8, 8, 8
     862};
     863
     864const uint8 LoLEngine::_reminderChar1IdxTable[] = {
     865        4, 4, 4, 5, 5, 5, 5, 5,
     866        5, 5, 5, 5, 5, 5, 5, 5,
     867        5
     868};
     869
     870const uint8 LoLEngine::_reminderChar2IdxTable[] = {
     871        9, 9, 9, 6, 6, 6, 6, 6,
     872        6, 6, 6, 6, 6, 6, 6, 6,
     873        6
     874};
     875
     876const uint8 LoLEngine::_reminderChar3IdxTable[] = {
     877        0xE, 0xE, 0xE, 0x7, 0x7, 0x7, 0x7, 0x7,
     878        0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7,
     879        0x7
     880};
     881
     882const uint8 LoLEngine::_reminderChar4IdxTable[] = {
     883        0xF, 0xF, 0xF, 0x8, 0x8, 0x8, 0x8, 0x8,
     884        0x8, 0x8, 0x8, 0x8, 0x8, 0x8, 0x8, 0x8,
     885        0x8
     886};
     887
     888const uint8 LoLEngine::_selectionAnimIndexTable[] = {
     889        0, 5, 1, 6, 2, 7, 3, 8
     890};
     891
     892const uint8 LoLEngine::_charInfoFrameTable[] = {
     893        0x0, 0x7, 0x8, 0x9, 0xA, 0xB, 0xA, 0x9,
     894        0x8, 0x7, 0x0, 0x0, 0x7, 0x8, 0x9, 0xA,
     895        0xB, 0xA, 0x9, 0x8, 0x7, 0x0, 0x0, 0x7,
     896        0x8, 0x9, 0xA, 0xB, 0xA, 0x9, 0x8, 0x7
     897};
     898
     899} // end of namespace Kyra
     900
  • screen_v2.h

    Property changes on: lol.cpp
    ___________________________________________________________________
    Added: svn:mime-type
       + text/plain
    Added: svn:keywords
       + Date Rev Author URL Id
    Added: svn:eol-style
       + native
    
     
    4040        void copyWsaRect(int x, int y, int w, int h, int dimState, int plotFunc, const uint8 *src,
    4141                                        int unk1, const uint8 *unkPtr1, const uint8 *unkPtr2);
    4242
     43        void checkedPageUpdate(int srcPage, int dstPage);
     44
    4345        // palette handling
    4446        uint8 *generateOverlay(const uint8 *palette, uint8 *buffer, int color, uint16 factor);
    4547        void applyOverlay(int x, int y, int w, int h, int pageNum, const uint8 *overlay);
  • script_tim.h

     
    3030
    3131#include "common/array.h"
    3232#include "common/func.h"
     33#include "common/str.h"
    3334
    3435namespace Kyra {
    3536
     37class WSAMovie_v2;
     38class Screen_v2;
    3639struct TIM;
    3740typedef Common::Functor2<const TIM*, const uint16*, int> TIMOpcode;
    3841
     
    5255                uint32 lastTime;
    5356                uint32 nextTime;
    5457
     58                const uint16 *loopIp;
     59
    5560                const uint16 *avtl;
    5661        } func[kCountFuncs];
    5762
     63        enum {
     64                kWSASlots = 10
     65        };
     66
     67        struct WSASlot {
     68                void *anim;
     69
     70                int16 x, y;
     71                uint16 wsaFlags;
     72                uint16 offscreen;
     73        } wsa[kWSASlots];
     74
    5875        uint16 *avtl;
    5976        uint8 *text;
    6077
     
    6380
    6481class TIMInterpreter {
    6582public:
    66         TIMInterpreter(KyraEngine_v1 *vm, OSystem *system);
     83        struct Animation {
     84                WSAMovie_v2 *wsa;
     85                int16 x, y;
     86                uint16 wsaCopyParams;
     87        };
    6788
     89        TIMInterpreter(KyraEngine_v1 *vm, Screen_v2 *screen, OSystem *system);
     90        ~TIMInterpreter();
     91
    6892        TIM *load(const char *filename, const Common::Array<const TIMOpcode*> *opcodes);
    6993        void unload(TIM *&tim) const;
     94       
     95        void setLangData(const char *filename);
     96        void clearLangData() { delete[] _langData; _langData = 0; }
     97       
     98        const char *getCTableEntry(uint idx) const;
    7099
    71100        void resetFinishedFlag() { _finished = false; }
    72101        bool finished() const { return _finished; }
     
    74103        void exec(TIM *tim, bool loop);
    75104        void stopCurFunc() { if (_currentTim) cmd_stopCurFunc(0); }
    76105
    77         void play(const char *filename);
    78106        void refreshTimersAfterPause(uint32 elapsedTime);
     107       
     108        void displayText(uint16 textId, int16 flags);
     109        void setupTextPalette(uint index, int fadePalette);
     110
     111        int _palDelayInc, _palDiff, _palDelayAcc;
    79112private:
    80113        KyraEngine_v1 *_vm;
     114        Screen_v2 *_screen;
    81115        OSystem *_system;
    82116
    83117        TIM *_currentTim;
     
    85119
    86120        bool _finished;
    87121       
     122        Common::String _vocFiles[120];
     123       
     124        Animation _animations[TIM::kWSASlots];
     125       
     126        Animation *initAnimStruct(int index, const char *filename, int x, int y, int, int offscreenBuffer, uint16 wsaFlags);
     127       
     128        char _audioFilename[32];
     129       
     130        uint8 *_langData;
     131        char *getTableEntry(uint idx);
     132        bool _textDisplayed;
     133        uint8 *_textAreaBuffer;
     134
    88135        int execCommand(int cmd, const uint16 *param);
    89136
    90137        typedef int (TIMInterpreter::*CommandProc)(const uint16 *);
     
    98145
    99146        int cmd_initFunc0(const uint16 *param);
    100147        int cmd_stopCurFunc(const uint16 *param);
     148        int cmd_initWSA(const uint16 *param);
     149        int cmd_uninitWSA(const uint16 *param);
    101150        int cmd_initFunc(const uint16 *param);
    102151        int cmd_stopFunc(const uint16 *param);
     152        int cmd_wsaDisplayFrame(const uint16 *param);
     153        int cmd_displayText(const uint16 *param);
     154        int cmd_loadVocFile(const uint16 *param);
     155        int cmd_unloadVocFile(const uint16 *param);
     156        int cmd_playVocFile(const uint16 *param);
     157        int cmd_loadSoundFile(const uint16 *param);
     158        int cmd_playMusicTrack(const uint16 *param);
     159        int cmd_setLoopIp(const uint16 *param);
     160        int cmd_continueLoop(const uint16 *param);
     161        int cmd_resetLoopIp(const uint16 *param);
    103162        int cmd_resetAllRuntimes(const uint16 *param);
    104163        int cmd_execOpcode(const uint16 *param);
    105164        int cmd_initFuncNow(const uint16 *param);
  • lol.h

     
     1/* ScummVM - Graphic Adventure Engine
     2 *
     3 * ScummVM is the legal property of its developers, whose names
     4 * are too numerous to list here. Please refer to the COPYRIGHT
     5 * file distributed with this source distribution.
     6 *
     7 * This program is free software; you can redistribute it and/or
     8 * modify it under the terms of the GNU General Public License
     9 * as published by the Free Software Foundation; either version 2
     10 * of the License, or (at your option) any later version.
     11
     12 * This program is distributed in the hope that it will be useful,
     13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
     14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
     15 * GNU General Public License for more details.
     16
     17 * You should have received a copy of the GNU General Public License
     18 * along with this program; if not, write to the Free Software
     19 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
     20 *
     21 * $URL$
     22 * $Id$
     23 *
     24 */
     25 
     26#ifndef KYRA_LOL_H
     27#define KYRA_LOL_H
     28
     29#include "kyra/kyra_v1.h"
     30#include "kyra/script_tim.h"
     31
     32#include "common/list.h"
     33
     34namespace Kyra {
     35
     36class Screen_LoL;
     37class WSAMovie_v2;
     38struct Button;
     39
     40class LoLEngine : public KyraEngine_v1 {
     41public:
     42        LoLEngine(OSystem *system, const GameFlags &flags);
     43        ~LoLEngine();
     44       
     45        Screen *screen();
     46private:
     47        Screen_LoL *_screen;
     48        TIMInterpreter *_tim;
     49
     50        int init();
     51        int go();
     52
     53        // input
     54        void updateInput();
     55        int checkInput(Button *buttonList = 0, bool mainLoop = false);
     56        void removeInputTop();
     57
     58        int _mouseX, _mouseY;
     59
     60        struct Event {
     61                Common::Event event;
     62                bool causedSkip;
     63
     64                Event() : event(), causedSkip(false) {}
     65                Event(Common::Event e) : event(e), causedSkip(false) {}
     66                Event(Common::Event e, bool skip) : event(e), causedSkip(skip) {}
     67
     68                operator Common::Event() const { return event; }
     69        };
     70        Common::List<Event> _eventList;
     71
     72        virtual bool skipFlag() const;
     73        virtual void resetSkipFlag(bool removeEvent = true);
     74
     75        // intro
     76        void setupPrologueData(bool load);
     77
     78        void showIntro();
     79       
     80        struct CharacterPrev {
     81                const char *name;
     82                int x, y;
     83                int attrib[3];
     84        };
     85       
     86        static const CharacterPrev _charPreviews[];
     87
     88        WSAMovie_v2 *_chargenWSA;
     89        static const uint8 _chargenFrameTable[];
     90        int chooseCharacter();
     91
     92        void kingSelectionIntro();
     93        void kingSelectionReminder();
     94        void kingSelectionOutro();
     95        void processCharacterSelection();
     96        void updateSelectionAnims();
     97        int selectionCharInfo(int character);
     98        void selectionCharInfoIntro(char *file);
     99       
     100        int getCharSelection();
     101        int selectionCharAccept();
     102       
     103        int _charSelection;
     104        int _charSelectionInfoResult;
     105       
     106        uint32 _selectionAnimTimers[4];
     107        uint8 _selectionAnimFrames[4];
     108        static const uint8 _selectionAnimIndexTable[];
     109       
     110        static const uint16 _selectionPosTable[];
     111
     112        static const uint8 _selectionChar1IdxTable[];
     113        static const uint8 _selectionChar2IdxTable[];
     114        static const uint8 _selectionChar3IdxTable[];
     115        static const uint8 _selectionChar4IdxTable[];
     116       
     117        static const uint8 _reminderChar1IdxTable[];
     118        static const uint8 _reminderChar2IdxTable[];
     119        static const uint8 _reminderChar3IdxTable[];
     120        static const uint8 _reminderChar4IdxTable[];
     121       
     122        static const uint8 _charInfoFrameTable[];
     123
     124        // timer
     125        void setupTimers() {}
     126
     127        // sound
     128        void snd_playVoiceFile(int) { /* XXX */ }
     129
     130        // opcode
     131        void setupOpcodeTable();
     132
     133        Common::Array<const TIMOpcode*> _timIntroOpcodes;
     134        int tlol_setupPaletteFade(const TIM *tim, const uint16 *param);
     135        int tlol_loadPalette(const TIM *tim, const uint16 *param);
     136        int tlol_setupPaletteFadeEx(const TIM *tim, const uint16 *param);
     137        int tlol_processWsaFrame(const TIM *tim, const uint16 *param);
     138        int tlol_displayText(const TIM *tim, const uint16 *param);
     139       
     140        // translation
     141        int _lang;
     142
     143        static const char * const _languageExt[];
     144       
     145        // unneeded
     146        void setWalkspeed(uint8) {}
     147        void setHandItem(uint16) {}
     148        void removeHandItem() {}
     149        bool lineIsPassable(int, int) { return false; }
     150};
     151
     152} // end of namespace Kyra
     153
     154#endif
     155
  • staticres.cpp

    Property changes on: lol.h
    ___________________________________________________________________
    Added: svn:mime-type
       + text/plain
    Added: svn:keywords
       + Date Rev Author URL Id
    Added: svn:eol-style
       + native
    
     
    287287        } else if (_vm->game() == GI_KYRA3) {
    288288                _builtIn = 0;
    289289                _filenameTable = kyra3StaticRes;
     290        } else if (_vm->game() == GI_LOL) {
     291                return true;
    290292        } else {
    291                 error("unknown game ID");
     293                error("StaticResource: Unknown game ID");
    292294        }
    293295
    294296        char errorBuffer[100];
  • module.mk

     
    2121        kyra_v2.o \
    2222        kyra_hof.o \
    2323        kyra_mr.o \
     24        lol.o \
    2425        resource.o \
    2526        saveload.o \
    2627        saveload_lok.o \
     
    3334        scene_mr.o \
    3435        screen.o \
    3536        screen_lok.o \
     37        screen_lol.o \
    3638        screen_v2.o \
    3739        screen_hof.o \
    3840        screen_mr.o \
  • script_tim.cpp

     
    2626#include "kyra/script_tim.h"
    2727#include "kyra/script.h"
    2828#include "kyra/resource.h"
     29#include "kyra/sound.h"
     30#include "kyra/wsamovie.h"
    2931
    3032#include "common/endian.h"
    3133
    3234namespace Kyra {
    3335
    34 TIMInterpreter::TIMInterpreter(KyraEngine_v1 *vm, OSystem *system) : _vm(vm), _system(system), _currentTim(0) {
     36TIMInterpreter::TIMInterpreter(KyraEngine_v1 *vm, Screen_v2 *screen, OSystem *system) : _vm(vm), _screen(screen), _system(system), _currentTim(0) {
    3537#define COMMAND(x) { &TIMInterpreter::x, #x }
    3638#define COMMAND_UNIMPL() { 0, 0 }
    3739#define cmd_return(n) cmd_return_##n
     
    3941                // 0x00
    4042                COMMAND(cmd_initFunc0),
    4143                COMMAND(cmd_stopCurFunc),
    42                 COMMAND_UNIMPL(),
    43                 COMMAND_UNIMPL(),
     44                COMMAND(cmd_initWSA),
     45                COMMAND(cmd_uninitWSA),
    4446                // 0x04
    4547                COMMAND(cmd_initFunc),
    4648                COMMAND(cmd_stopFunc),
     49                COMMAND(cmd_wsaDisplayFrame),
    4750                COMMAND_UNIMPL(),
    48                 COMMAND_UNIMPL(),
    4951                // 0x08
     52                COMMAND(cmd_loadVocFile),
     53                COMMAND(cmd_unloadVocFile),
     54                COMMAND(cmd_playVocFile),
    5055                COMMAND_UNIMPL(),
    51                 COMMAND_UNIMPL(),
    52                 COMMAND_UNIMPL(),
    53                 COMMAND_UNIMPL(),
    5456                // 0x0C
     57                COMMAND(cmd_loadSoundFile),
     58                COMMAND(cmd_return(1)),
     59                COMMAND(cmd_playMusicTrack),
    5560                COMMAND_UNIMPL(),
    56                 COMMAND_UNIMPL(),
    57                 COMMAND_UNIMPL(),
    58                 COMMAND_UNIMPL(),
    5961                // 0x10
     62                COMMAND(cmd_return(1)),
     63                COMMAND(cmd_return(1)),
    6064                COMMAND_UNIMPL(),
    6165                COMMAND_UNIMPL(),
    62                 COMMAND_UNIMPL(),
    63                 COMMAND_UNIMPL(),
    6466                // 0x14
    65                 COMMAND_UNIMPL(),
    66                 COMMAND_UNIMPL(),
    67                 COMMAND_UNIMPL(),
     67                COMMAND(cmd_setLoopIp),
     68                COMMAND(cmd_continueLoop),
     69                COMMAND(cmd_resetLoopIp),
    6870                COMMAND(cmd_resetAllRuntimes),
    6971                // 0x18
    7072                COMMAND(cmd_return(1)),
     
    8082
    8183        _commands = commandProcs;
    8284        _commandsSize = ARRAYSIZE(commandProcs);
     85       
     86        memset(&_animations, 0, sizeof(_animations));
     87        _langData = 0;
     88        _textDisplayed = false;
     89        _textAreaBuffer = new uint8[320*40];
     90        assert(_textAreaBuffer);
     91       
     92        _palDelayInc = _palDiff = _palDelayAcc = 0;
    8393}
    8494
     95TIMInterpreter::~TIMInterpreter() {
     96        delete[] _langData;
     97        delete[] _textAreaBuffer;
     98}
     99
    85100TIM *TIMInterpreter::load(const char *filename, const Common::Array<const TIMOpcode*> *opcodes) {
    86101        if (!_vm->resource()->exists(filename))
    87102                return 0;
     
    139154        tim = 0;
    140155}
    141156
     157void TIMInterpreter::setLangData(const char *filename) {
     158        delete[] _langData;
     159        _langData = _vm->resource()->fileData(filename, 0);
     160}
     161
    142162void TIMInterpreter::exec(TIM *tim, bool loop) {
    143163        if (!tim)
    144164                return;
     
    175195                                        _currentTim->procFunc = _currentFunc;
    176196                                        break;
    177197
     198                                case 22:
     199                                        cur.loopIp = 0;
     200                                        break;
     201
    178202                                default:
    179203                                        break;
    180204                                }
     
    201225        }
    202226}
    203227
     228void TIMInterpreter::displayText(uint16 textId, int16 flags) {
     229        char *text = getTableEntry(textId);
     230
     231        if (_textDisplayed) {
     232                _screen->copyBlockToPage(0, 0, 160, 320, 40, _textAreaBuffer);
     233                _textDisplayed = false;
     234        }
     235
     236        if (!text)
     237                return;
     238        if (!text[0])
     239                return;
     240
     241        char filename[16];
     242        memset(filename, 0, sizeof(filename));
     243
     244        if (text[0] == '$') {
     245                const char *end = strchr(text+1, '$');
     246                if (end)
     247                        memcpy(filename, text+1, end-1-text);
     248        }
     249
     250        if (filename[0])
     251                _vm->sound()->voicePlay(filename);
     252
     253        if (text[0] == '$')
     254                text = strchr(text + 1, '$') + 1;
     255
     256        setupTextPalette((flags < 0) ? 1 : flags, 0);
     257
     258        if (flags < 0) {
     259                static const uint8 colorMap[] = { 0x00, 0xF0, 0xFE, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
     260
     261                _screen->setFont(Screen::FID_8_FNT);
     262                _screen->setTextColorMap(colorMap);
     263                _screen->_charWidth = -2;
     264        }
     265
     266        _screen->_charOffset = -4;
     267        _screen->copyRegionToBuffer(0, 0, 160, 320, 40, _textAreaBuffer);
     268        _textDisplayed = true;
     269
     270        char backupChar = 0;
     271        char *str = text;
     272        int heightAdd = 0;
     273
     274        while (str[0]) {
     275                char *nextLine = strchr(str, '\r');
     276
     277                backupChar = 0;
     278                if (nextLine) {
     279                        backupChar = nextLine[0];
     280                        nextLine[0] = '\0';
     281                }
     282
     283                int width = _screen->getTextWidth(str);
     284
     285                if (flags >= 0)
     286                        _screen->printText(str, (320 - width) >> 1, 160 + heightAdd, 0xF0, 0x00);
     287                else
     288                        _screen->printText(str, (320 - width) >> 1, 188, 0xF0, 0x00);
     289
     290                heightAdd += _screen->getFontHeight();
     291                str += strlen(str);
     292
     293                if (backupChar) {
     294                        nextLine[0] = backupChar;
     295                        ++str;
     296                }
     297        }
     298
     299        _screen->_charOffset = 0;
     300
     301        if (flags < 0) {
     302                static const uint8 colorMap[] = { 0x00, 0xF0, 0xF1, 0xF2, 0xF3, 0xF4, 0xF5, 0xF6, 0xF7, 0xF8, 0xF9, 0xFA, 0x00, 0x00, 0x00, 0x00 };
     303
     304                _screen->setFont(Screen::FID_INTRO_FNT);
     305                _screen->setTextColorMap(colorMap);
     306                _screen->_charWidth = 0;
     307        }
     308}
     309
     310void TIMInterpreter::setupTextPalette(uint index, int fadePalette) {
     311        static const uint16 palTable[] = {
     312                0x00, 0x00, 0x00,
     313                0x64, 0x64, 0x64,
     314                0x61, 0x51, 0x30,
     315                0x29, 0x48, 0x64,
     316                0x00, 0x4B, 0x3B,
     317                0x64, 0x1E, 0x1E,
     318        };
     319
     320        for (int i = 0; i < 15; ++i) {
     321                uint8 *palette = _screen->getPalette(0) + (240 + i) * 3;
     322
     323                uint8 c1 = (((15 - i) << 2) * palTable[index*3+0]) / 100;
     324                uint8 c2 = (((15 - i) << 2) * palTable[index*3+1]) / 100;
     325                uint8 c3 = (((15 - i) << 2) * palTable[index*3+2]) / 100;
     326
     327                palette[0] = c1;
     328                palette[1] = c2;
     329                palette[2] = c3;
     330        }
     331       
     332        if (!fadePalette && !_palDiff) {
     333                _screen->setScreenPalette(_screen->getPalette(0));
     334        } else {
     335                _screen->getFadeParams(_screen->getPalette(0), fadePalette, _palDelayInc, _palDiff);
     336                _palDelayAcc = 0;
     337        }
     338}
     339
     340TIMInterpreter::Animation *TIMInterpreter::initAnimStruct(int index, const char *filename, int x, int y, int, int offscreenBuffer, uint16 wsaFlags) {
     341        Animation *anim = &_animations[index];
     342        anim->x = x;
     343        anim->y = y;
     344        anim->wsaCopyParams = wsaFlags;
     345
     346        uint16 wsaOpenFlags = ((wsaFlags & 0x10) != 0) ? 2 : 0;
     347
     348        char file[32];
     349        snprintf(file, 32, "%s.WSA", filename);
     350       
     351        if (_vm->resource()->exists(file)) {
     352                anim->wsa = new WSAMovie_v2(_vm, _screen);
     353                assert(anim->wsa);
     354
     355                anim->wsa->open(file, wsaOpenFlags, (index == 1) ? _screen->getPalette(0) : 0);
     356        }
     357       
     358        if (anim->wsa && anim->wsa->opened()) {
     359                if (x == -1)
     360                        anim->x = x = 0;
     361                if (y == -1)
     362                        anim->y = y = 0;
     363
     364                if (wsaFlags & 2) {
     365                        _screen->fadePalette(_screen->getPalette(1), 15, 0);
     366                        _screen->clearPage(8);
     367                        _screen->checkedPageUpdate(8, 4);
     368                        _screen->updateScreen();
     369                }
     370
     371                if (wsaFlags & 4) {
     372                        snprintf(file, 32, "%s.CPS", filename);
     373
     374                        if (_vm->resource()->exists(file)) {
     375                                _screen->loadBitmap(file, 3, 3, _screen->getPalette(0));
     376                                _screen->copyRegion(0, 0, 0, 0, 320, 200, 2, 8, Screen::CR_NO_P_CHECK);
     377                                _screen->checkedPageUpdate(8, 4);
     378                                _screen->updateScreen();
     379                        }
     380
     381                        anim->wsa->setX(x);
     382                        anim->wsa->setY(y);
     383                        anim->wsa->setDrawPage(0);
     384                        anim->wsa->displayFrame(0, 0, 0, 0);
     385                }
     386
     387                if (wsaFlags & 2)
     388                        _screen->fadePalette(_screen->getPalette(0), 30, 0);
     389        } else {
     390                if (wsaFlags & 2) {
     391                        _screen->fadePalette(_screen->getPalette(1), 15, 0);
     392                        _screen->clearPage(8);
     393                        _screen->checkedPageUpdate(8, 4);
     394                        _screen->updateScreen();
     395                }
     396
     397                snprintf(file, 32, "%s.CPS", filename);
     398
     399                if (_vm->resource()->exists(file)) {
     400                        _screen->loadBitmap(file, 3, 3, _screen->getPalette(0));
     401                        _screen->copyRegion(0, 0, 0, 0, 320, 200, 2, 8, Screen::CR_NO_P_CHECK);
     402                        _screen->checkedPageUpdate(8, 4);
     403                        _screen->updateScreen();
     404                }
     405
     406                if (wsaFlags & 2)
     407                        _screen->fadePalette(_screen->getPalette(0), 30, 0);
     408        }
     409       
     410        return anim;
     411}
     412
     413char *TIMInterpreter::getTableEntry(uint idx) {
     414        if (!_langData)
     415                return 0;
     416        else
     417                return (char *)(_langData + READ_LE_UINT16(_langData + (idx<<1)));
     418}
     419
     420const char *TIMInterpreter::getCTableEntry(uint idx) const {
     421        if (!_langData)
     422                return 0;
     423        else
     424                return (const char *)(_langData + READ_LE_UINT16(_langData + (idx<<1)));
     425}
     426
    204427int TIMInterpreter::execCommand(int cmd, const uint16 *param) {
    205428        if (cmd < 0 || cmd >= _commandsSize) {
    206429                warning("Calling unimplemented TIM command %d from file '%s'", cmd, _currentTim->filename);
     
    212435                return 0;
    213436        }
    214437
    215         debugC(5, kDebugLevelScript, "TIMInterpreter::%s(%p)", _commands[cmd].desc, (const void*)param);
     438        debugC(5, kDebugLevelScript, "TIMInterpreter::%s(%p)", _commands[cmd].desc, (const void* )param);
    216439        return (this->*_commands[cmd].proc)(param);
    217440}
    218441
    219442int TIMInterpreter::cmd_initFunc0(const uint16 *param) {
     443        for (int i = 0; i < TIM::kWSASlots; ++i)
     444                memset(&_currentTim->wsa[i], 0, sizeof(TIM::WSASlot));
     445
    220446        _currentTim->func[0].ip = _currentTim->func[0].avtl;
    221447        _currentTim->func[0].lastTime = _system->getMillis();
    222448        return 1;
     
    230456        return -2;
    231457}
    232458
     459int TIMInterpreter::cmd_initWSA(const uint16 *param) {
     460        const int index = param[0];
     461
     462        TIM::WSASlot &slot = _currentTim->wsa[index];
     463       
     464        slot.x = int16(param[2]);
     465        slot.y = int16(param[3]);
     466        slot.offscreen = param[4];
     467        slot.wsaFlags = param[5];
     468        const char *filename = (const char *)(_currentTim->text + READ_LE_UINT16(_currentTim->text + (param[1]<<1)));
     469       
     470        slot.anim = initAnimStruct(index, filename, slot.x, slot.y, 10, slot.offscreen, slot.wsaFlags);
     471        return 1;
     472}
     473
     474int TIMInterpreter::cmd_uninitWSA(const uint16 *param) {
     475        const int index = param[0];
     476
     477        TIM::WSASlot &slot = _currentTim->wsa[index];
     478       
     479        if (!slot.anim)
     480                return 0;
     481       
     482        Animation &anim = _animations[index];
     483       
     484        if (slot.offscreen) {
     485                delete anim.wsa;
     486                anim.wsa = 0;
     487                slot.anim = 0;
     488        } else {
     489                //XXX
     490
     491                delete anim.wsa;
     492                memset(&anim, 0, sizeof(Animation));
     493                memset(&slot, 0, sizeof(TIM::WSASlot));
     494        }
     495       
     496        return 1;
     497}
     498
    233499int TIMInterpreter::cmd_initFunc(const uint16 *param) {
    234500        uint16 func = *param;
    235501        assert(func < TIM::kCountFuncs);
     
    247513        return 1;
    248514}
    249515
     516int TIMInterpreter::cmd_wsaDisplayFrame(const uint16 *param) {
     517        Animation &anim = _animations[param[0]];
     518        const int frame = param[1];
     519       
     520        anim.wsa->setX(anim.x);
     521        anim.wsa->setY(anim.y);
     522        anim.wsa->setDrawPage((anim.wsaCopyParams & 0x4000) != 0 ? 2 : 8);
     523        anim.wsa->displayFrame(frame, anim.wsaCopyParams & 0xF0FF, 0, 0);
     524        return 1;
     525}
     526
     527int TIMInterpreter::cmd_displayText(const uint16 *param) {
     528        displayText(param[0], param[1]);
     529        return 1;
     530}
     531
     532int TIMInterpreter::cmd_loadVocFile(const uint16 *param) {
     533        const int stringId = param[0];
     534        const int index = param[1];
     535
     536        _vocFiles[index] = (const char *)(_currentTim->text + READ_LE_UINT16(_currentTim->text + (stringId << 1)));
     537        for (int i = 0; i < 4; ++i)
     538                _vocFiles[index].deleteLastChar();
     539        return 1;
     540}
     541
     542int TIMInterpreter::cmd_unloadVocFile(const uint16 *param) {
     543        const int index = param[0];
     544        _vocFiles[index].clear();
     545        return 1;
     546}
     547
     548int TIMInterpreter::cmd_playVocFile(const uint16 *param) {
     549        const int index = param[0];
     550        const int volume = (param[1] * 255) / 100;
     551
     552        if (index < ARRAYSIZE(_vocFiles) && !_vocFiles[index].empty())
     553                _vm->sound()->voicePlay(_vocFiles[index].c_str()/*, volume*/, true);
     554        else
     555                _vm->snd_playSoundEffect(index, volume);
     556       
     557        return 1;
     558}
     559
     560int TIMInterpreter::cmd_loadSoundFile(const uint16 *param) {
     561        const char *file = (const char *)(_currentTim->text + READ_LE_UINT16(_currentTim->text + (param[0]<<1)));
     562       
     563        static char * fileList[] = { 0 };
     564        fileList[0] = _audioFilename;
     565        static AudioDataStruct audioList = { fileList, 1, 0, 0 };
     566
     567        strncpy(_audioFilename, file, sizeof(_audioFilename));
     568
     569        _vm->sound()->setSoundList(&audioList);
     570        _vm->sound()->loadSoundFile(0);
     571        return 1;
     572}
     573
     574int TIMInterpreter::cmd_playMusicTrack(const uint16 *param) {
     575        _vm->sound()->playTrack(param[0]);
     576        return 1;
     577}
     578
     579int TIMInterpreter::cmd_setLoopIp(const uint16 *param) {
     580        _currentTim->func[_currentFunc].loopIp = _currentTim->func[_currentFunc].ip;
     581        return 1;
     582}
     583
     584int TIMInterpreter::cmd_continueLoop(const uint16 *param) {
     585        TIM::Function &func = _currentTim->func[_currentFunc];
     586       
     587        if (!func.loopIp)
     588                return -2;
     589
     590        func.ip = func.loopIp;
     591
     592        uint16 factor = param[0];
     593        if (factor) {
     594                const uint32 random = _vm->_rnd.getRandomNumberRng(0, 0x8000);
     595                uint32 waitTime = (random * factor) / 0x8000;
     596                func.nextTime += waitTime * _vm->tickLength();
     597        }
     598       
     599        return 1;
     600}
     601
     602int TIMInterpreter::cmd_resetLoopIp(const uint16 *param) {
     603        _currentTim->func[_currentFunc].loopIp = 0;
     604        return 1;
     605}
     606
    250607int TIMInterpreter::cmd_resetAllRuntimes(const uint16 *param) {
    251608        for (int i = 0; i < TIM::kCountFuncs; ++i) {
    252609                if (_currentTim->func[i].ip)
     
    256613}
    257614
    258615int TIMInterpreter::cmd_execOpcode(const uint16 *param) {
     616        const uint16 opcode = *param++;
     617
    259618        if (!_currentTim->opcodes) {
    260                 warning("Trying to execute TIM opcode without opcode list");
     619                warning("Trying to execute TIM opcode %d without opcode list (file '%s')", opcode, _currentTim->filename);
     620                fflush(stderr); fflush(stdout);
    261621                return 0;
    262622        }
    263623
    264         uint16 opcode = *param++;
    265624        if (opcode > _currentTim->opcodes->size()) {
    266625                warning("Calling unimplemented TIM opcode(0x%.02X/%d) from file '%s'", opcode, opcode, _currentTim->filename);
    267626                return 0;
    268627        }
    269628
     629        if (!(*_currentTim->opcodes)[opcode]->isValid()) {
     630                warning("Calling unimplemented TIM opcode(0x%.02X/%d) from file '%s'", opcode, opcode, _currentTim->filename);
     631                fflush(stderr);
     632                return 0;
     633        }
     634
    270635        return (*(*_currentTim->opcodes)[opcode])(_currentTim, param);
    271636}
    272637
  • detection.cpp

     
    2626#include "kyra/kyra_lok.h"
    2727#include "kyra/kyra_hof.h"
    2828#include "kyra/kyra_mr.h"
     29#include "kyra/lol.h"
    2930
    3031#include "common/config-manager.h"
    3132#include "common/advancedDetector.h"
     
    6465#define KYRA3_CD_INS_FLAGS FLAGS(false, false, true, false, true, false, Kyra::GI_KYRA3)
    6566#define KYRA3_CD_FAN_FLAGS(x, y) FLAGS_FAN(x, y, false, false, true, false, true, false, Kyra::GI_KYRA3)
    6667
     68#define LOL_CD_FLAGS FLAGS(false, false, true, false, false, false, Kyra::GI_LOL)
     69
    6770const KYRAGameDescription adGameDescs[] = {
    6871        {
    6972                {
     
    700703                },
    701704                KYRA3_CD_FAN_FLAGS(Common::IT_ITA, Common::FR_FRA)
    702705        },
     706       
     707        // Lands of Lore CD
     708        {
     709                {
     710                        "lol",
     711                        "CD",
     712                        {
     713                                { "GENERAL.PAK", 0, "05a4f588fb81dc9c0ef1f2ec20d89e24", -1 },
     714                                { "L01.PAK", 0, "759a0ac26808d77ea968bd392355ba1d", -1 },
     715                                { 0, 0, 0, 0 }
     716                        },
     717                        Common::EN_ANY,
     718                        Common::kPlatformPC,
     719                        Common::ADGF_DROPLANGUAGE | Common::ADGF_CD
     720                },
     721                LOL_CD_FLAGS
     722        },
     723       
     724        {
     725                {
     726                        "lol",
     727                        "CD",
     728                        {
     729                                { "GENERAL.PAK", 0, "05a4f588fb81dc9c0ef1f2ec20d89e24", -1 },
     730                                { "L01.PAK", 0, "759a0ac26808d77ea968bd392355ba1d", -1 },
     731                                { 0, 0, 0, 0 }
     732                        },
     733                        Common::DE_DEU,
     734                        Common::kPlatformPC,
     735                        Common::ADGF_DROPLANGUAGE | Common::ADGF_CD
     736                },
     737                LOL_CD_FLAGS
     738        },
     739       
     740        {
     741                {
     742                        "lol",
     743                        "CD",
     744                        {
     745                                { "GENERAL.PAK", 0, "05a4f588fb81dc9c0ef1f2ec20d89e24", -1 },
     746                                { "L01.PAK", 0, "759a0ac26808d77ea968bd392355ba1d", -1 },
     747                                { 0, 0, 0, 0 }
     748                        },
     749                        Common::FR_FRA,
     750                        Common::kPlatformPC,
     751                        Common::ADGF_DROPLANGUAGE | Common::ADGF_CD
     752                },
     753                LOL_CD_FLAGS
     754        },
     755       
    703756        { AD_TABLE_END_MARKER, FLAGS(0, 0, 0, 0, 0, 0, 0) }
    704757};
    705758
     
    707760        { "kyra1", "The Legend of Kyrandia" },
    708761        { "kyra2", "The Legend of Kyrandia: The Hand of Fate" },
    709762        { "kyra3", "The Legend of Kyrandia: Malcolm's Revenge" },
     763        { "lol", "Lands of Lore: The Throne of Chaos" },
    710764        { 0, 0 }
    711765};
    712766
     
    779833        case Kyra::GI_KYRA3:
    780834                *engine = new Kyra::KyraEngine_MR(syst, flags);
    781835                break;
     836        case Kyra::GI_LOL:
     837                *engine = new Kyra::LoLEngine(syst, flags);
     838                break;
    782839        default:
    783840                res = false;
    784841                warning("Kyra engine: unknown gameID");
  • sound_adlib.cpp

     
    235235        // * One for instruments, starting at offset 500.
    236236
    237237        uint8 *getProgram(int progId) {
     238                uint16 offset = READ_LE_UINT16(_soundData + 2 * progId);
     239                //TODO: Check in LoL CD Adlib driver
     240                if (offset == 0xFFFF)
     241                        return 0;
    238242                return _soundData + READ_LE_UINT16(_soundData + 2 * progId);
    239243        }
    240244
     
    12821286                return 0;
    12831287
    12841288        uint8 *ptr = getProgram(value);
     1289        //TODO: Check in LoL CD Adlib driver
     1290        if (!ptr)
     1291                return 0;
    12851292        uint8 chan = *ptr++;
    12861293        uint8 priority = *ptr++;
    12871294
     
    22132220SoundAdlibPC::SoundAdlibPC(KyraEngine_v1 *vm, Audio::Mixer *mixer)
    22142221        : Sound(vm, mixer), _driver(0), _trackEntries(), _soundDataPtr(0) {
    22152222        memset(_trackEntries, 0, sizeof(_trackEntries));
    2216         _v2 = (_vm->gameFlags().gameID == GI_KYRA2);
     2223        _v2 = (_vm->gameFlags().gameID == GI_KYRA2) || (_vm->gameFlags().gameID == GI_LOL);
    22172224        _driver = new AdlibDriver(mixer, _v2);
    22182225        assert(_driver);
    22192226
  • kyra_hof.cpp

     
    230230        _gui = new GUI_HoF(this);
    231231        assert(_gui);
    232232        _gui->initStaticData();
    233         _tim = new TIMInterpreter(this, _system);
     233        _tim = new TIMInterpreter(this, _screen, _system);
    234234        assert(_tim);
    235235
    236236        if (_flags.isDemo && !_flags.isTalkie) {
  • screen_v2.cpp

     
    485485        return (w1 == -1) ? false : true;
    486486}
    487487
     488void Screen_v2::checkedPageUpdate(int srcPage, int dstPage) {
     489        debugC(9, kDebugLevelScreen, "Screen_v2::checkedPageUpdate(%d, %d)", srcPage, dstPage);
     490       
     491        const uint32 *src = (const uint32 *)getPagePtr(srcPage);
     492        uint32 *dst = (uint32 *)getPagePtr(dstPage);
     493        uint32 *page0 = (uint32 *)getPagePtr(0);
     494       
     495        bool updated = false;
     496       
     497        for (int y = 0; y < 200; ++y) {
     498                for (int x = 0; x < 80; ++x, ++src, ++dst, ++page0) {
     499                        if (*src != *dst) {
     500                                updated = true;
     501                                *dst = *page0 = *src;
     502                        }
     503                }
     504        }
     505
     506        if (updated)
     507                addDirtyRect(0, 0, 320, 200);
     508}
     509
    488510} // end of namespace Kyra
    489511
  • resource.cpp

     
    5555        if (!dir.exists() || !dir.isDirectory())
    5656                error("invalid game path '%s'", dir.getPath().c_str());
    5757
    58         if (!loadPakFile(StaticResource::staticDataFilename()) || !StaticResource::checkKyraDat()) {
    59                 Common::String errorMessage = "You're missing the '" + StaticResource::staticDataFilename() + "' file or it got corrupted, (re)get it from the ScummVM website";
    60                 _vm->GUIErrorMessage(errorMessage);
    61                 error(errorMessage.c_str());
     58        if (_vm->game() != GI_LOL) {
     59                if (!loadPakFile(StaticResource::staticDataFilename()) || !StaticResource::checkKyraDat()) {
     60                        Common::String errorMessage = "You're missing the '" + StaticResource::staticDataFilename() + "' file or it got corrupted, (re)get it from the ScummVM website";
     61                        _vm->GUIErrorMessage(errorMessage);
     62                        error(errorMessage.c_str());
     63                }
    6264        }
    6365
    6466        if (_vm->game() == GI_KYRA1) {
     
    99101                loadFileList("FILEDATA.FDT");
    100102
    101103                return true;
     104        } else if (_vm->game() == GI_LOL) {
     105                return true;
    102106        }
    103107
    104108        FSList fslist;
  • screen_lol.h

     
     1/* ScummVM - Graphic Adventure Engine
     2 *
     3 * ScummVM is the legal property of its developers, whose names
     4 * are too numerous to list here. Please refer to the COPYRIGHT
     5 * file distributed with this source distribution.
     6 *
     7 * This program is free software; you can redistribute it and/or
     8 * modify it under the terms of the GNU General Public License
     9 * as published by the Free Software Foundation; either version 2
     10 * of the License, or (at your option) any later version.
     11
     12 * This program is distributed in the hope that it will be useful,
     13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
     14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
     15 * GNU General Public License for more details.
     16
     17 * You should have received a copy of the GNU General Public License
     18 * along with this program; if not, write to the Free Software
     19 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
     20 *
     21 * $URL$
     22 * $Id$
     23 *
     24 */
     25
     26#ifndef KYRA_SCREEN_LOL_H
     27#define KYRA_SCREEN_LOL_H
     28
     29#include "kyra/screen_v2.h"
     30
     31namespace Kyra {
     32
     33class LoLEngine;
     34
     35class Screen_LoL : public Screen_v2 {
     36public:
     37        Screen_LoL(LoLEngine *vm, OSystem *system);
     38       
     39        void setScreenDim(int dim);
     40        const ScreenDim *getScreenDim(int dim);
     41
     42        void fprintStringIntro(const char *format, int x, int y, uint8 c1, uint8 c2, uint8 c3, uint16 flags, ...);
     43private:
     44        LoLEngine *_vm;
     45
     46        static const ScreenDim _screenDimTable[];
     47        static const int _screenDimTableCount;
     48};
     49
     50} // end of namespace Kyra
     51
     52#endif
     53